Bots Home
|
Create an App
LOVENSE KATY IS THAAAA SHIT
Author:
caitlynlove
Description
Source Code
Launch Bot
Current Users
Created by:
Caitlynlove
/** Name: Dorothy's Ultra Fembot Author: chelsea2950 Current version 1.3 Created 11/29/2018 Last Updated 12/18/2018 (see description for change log) This ultrabot is intended to provide more experienced cammers with a single tool to provide most common bot functions. I've borrowed some existing features from many places/bots including 18yearold, allinone and ultrabot for most, so credit to those who have gone before for all your hard work (britney and justin, alice and shaggy, lund, acrazyguy, and I'm sure many others). Special thanks to 4science for the Tip Menu and Token Polls (which were built off work by badbadbubba and NotThatFrank). However, this bot is also intended to be transparent and not automatically add people to your modlist and ticket show lists and give other special rights without permission. Main features from the Easy Fembot are: Messaging for mods and broadcasters Private Messages to other users Silence Level and Graphic Level Leaderboard Nice List Tip Count next to name Silence individual users Silence individual users without notification (ninja) Added features in this bot: Tip Menu Positions Tip Menu Token Poll VIP List External FanClub List Blocked word list Additional Notifiers (up to 5 rotating) User Group icons next to name (mods, CB fan club, external fan club, VIP list) Color control of most messaging Ticket prep function (disable regular tip menu, enable positions menu and token poll) Lush Menu Media Contact List Note that I've made 3 copies of the bot, as I expect that people may want to create 2 or 3 versions that they can save for deifferent types of shows. For example, all of the tip menus and token polls may be different between a couples show, solo show, and shark week show, so by having three separate bots you can configure and save, you don't have to change the setup when you switch between shows, just swap out the bot. The primary bot is this one, secondary bots are "Dorothy's Ultra Fembot - Show 2" and "Dorothy's Ultra Fembot - Show 3". **/ // prototype functions { String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1); } String.prototype.repeat = function (number) { return new Array(number + 1).join(this); } String.prototype.equals = function (str) { var m = new RegExp(str); return this.match(m) != null; } String.prototype.equalsIgnoreCase = function (str) { var m = new RegExp(str, "i"); return this.match(m) != null; } } {cb.settings_choices = [ // *** Messages and Notifications {name: 'dummy1', label: '************* Notifications and Messages **************', type: 'choice',required: false}, {name: 'enableEntryMessage', label: 'Display notification to users when they enter?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'entryMessage', label: 'Enter the message to display', type: 'str', minLength: 1, maxLength: 1000, defaultValue: 'Welcome to my room!'}, {name: 'enableNotifier', label: 'Would you like to periodicaly send a message to the room? Up to 5 messages can be displayed in rotation according to the interval specified below', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'notifierMessage1', label: 'Enter the first notification message you would like to display.', type: 'str', minLength: 1, maxLength: 1000, defaultValue: 'Please treat others with kindness!'}, {name: 'notifierMessage2', label: 'Notification Message #2', required: false,type: 'str', minLength: 1, maxLength: 1000}, {name: 'notifierMessage3', label: 'Notification Message #3', required: false,type: 'str', minLength: 1, maxLength: 1000}, {name: 'notifierMessage4', label: 'Notification Message #4', required: false,type: 'str', minLength: 1, maxLength: 1000}, {name: 'notifierMessage5', label: 'Notification Message #5', required: false,type: 'str', minLength: 1, maxLength: 1000}, {name: 'notifierInterval', label: 'Notification display interval (minutes)', type: 'int', minValue: 1, maxValue: 60, defaultValue: 5}, {name: 'notifiersTextColor', label: 'Text color used for Notification Messages 1-5 and Chat Notices /cn, /cnh, /cnd, /cndh)', type: 'choice', choice1: "White/No Color",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Red",choice5: "Dark Orange",choice6: "Dark Green",choice7: "Dark Aqua",choice8: "Dark Blue",choice9: "Dark Purple",choice10: "Dark Pink",choice11: "Custom",defaultValue: "Dark Aqua"}, {name: 'notifiersTextCustColor',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom text color in the previous setting, enter the hex color (6character hex color codes including the # prefix)",required: false}, {name: 'notifiersBgColor', label: 'Background highlight color used for Notification Messages 1-5 and Chat Notices (/cn, /cnh, /cnd, /cndh)', type: 'choice', choice1: "White/No Color",choice2: "Light Yellow",choice3: "Light Blue",choice4: "Light Pink",choice5: "Light Red",choice6: "Light Green",choice7: "Light Purple",choice8: "Light Orange",choice9: "Light Grey",choice10: "Light Aqua",choice11: "Custom",defaultValue: "Light Aqua"}, {name: 'notifiersBgCustColor', type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom background highlight color in the previous setting, enter the hex color (6character hex color codes including the # prefix)",required: false}, // *** Tip Count and Leaderboard {name: 'dummy2', label: '************ Tip Count and Leaderboard ****************', type: 'choice',required: false}, {name: 'enableSubjectChange', label: 'Allow moderators to change Room Subject. Note that if an app or bot is running that updates the room title, it will always override on next update', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'enableTipCount', label: 'Display user tip count as prefix in messages?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'enableTipLeaderIcons', label: 'Display icon for the top 3 tippers as prefix in messages? If yes, enter a value for positions 1-3 below.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'tipLeaderGif1', type: 'str',defaultValue: ':crowngold',required: false,label: 'Choose the icon to be displayed for the top tipper of the current session (optional). It can be a gif or a string of text/special characters (&!&). If using a gif, make sure to start it with the colon (:) as it would be typed in the chat'}, {name: 'tipLeaderGif2', type: 'str',defaultValue: ':mtlhfu2',required: false,label: 'Choose the icon to be displayed for the second highest tipper of the current session (optional). It can be a gif or a string of text/special characters (&!&). If using a gif, make sure to start it with the colon (:) as it would be typed in the chat'}, {name: 'tipLeaderGif3', type: 'str',defaultValue: ':mtlhfu3 ',required: false,label: 'Choose the icon to be displayed for the third highest tipper of the current session (optional). It can be a gif or a string of text/special characters (&!&). If using a gif, make sure to start it with the colon (:) as it would be typed in the chat'}, {name: 'enableLeaderboard', label: 'Display the leaderboard in the chat (top 5 tippers in current session)?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'leaderInterval', label: 'Leaderboard display interval (minutes)', type: 'int', minValue: 1, maxValue: 60, defaultValue: 5}, {name: 'leaderTextColor', label: 'Text color used for Leaderboard', type: 'choice', choice1: "White/No Color",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Red",choice5: "Dark Orange",choice6: "Dark Green",choice7: "Dark Aqua",choice8: "Dark Blue",choice9: "Dark Purple",choice10: "Dark Pink",choice11: "Custom",defaultValue: "Dark Blue"}, {name: 'leaderTextCustColor',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom text color in the previous setting, enter the hex color (6character hex color codes including the # prefix)",required: false}, {name: 'leaderBgColor', label: 'Background color used for Leaderboard', type: 'choice', choice1: "White/No Color",choice2: "Light Yellow",choice3: "Light Blue",choice4: "Light Pink",choice5: "Light Red",choice6: "Light Green",choice7: "Light Purple",choice8: "Light Orange",choice9: "Light Grey",choice10: "Light Aqua",choice11: "Custom",defaultValue: "Light Blue"}, {name: 'leaderBgCustColor', type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom background highlight color in the previous setting, enter the hex color (6character hex color codes including the # prefix)",required: false}, // *** Chat Controls {name: 'dummy3', label: '**************** Chat Controls ************************', type: 'choice',required: false}, {name: 'silenceList', label: 'Enter the names of any users you would like to ensure cannot chat in your room. User IDs should be separated by commas and without spaces:', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '', required: false}, {name: 'ninjaList', label: 'Enter the names of any users you would like to ensure cannot chat in your room, but do not want them to be notified of being silenced. This for those users who may tip sometimes, but you really do not want to listen to their comments unles it is in a tip note. User IDs should be separated by commas and without spaces:', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '', required: false}, {name: 'niceList', label: 'Enter the names of any users you would like to grant voice and graphic usage privileges regardless of the silence and graphic levels (permanent nice list). User IDs should be separated by commas and without spaces', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '', required: false}, {name: 'enablePMs', label: 'Allow users to PM in chat', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, // *** User Icons {name: 'dummy4', label: '**************** User Group Icons *********************', type: 'choice',required: false}, {name: 'enableGroupIcons', label: 'Enable group icons (gifs) to be displayed in front of a user name for the mod, Fanclub, external Fanclub, and VIP list groups', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'iconMods', type: 'str',defaultValue: ':moderatorbadge',required: false,label: 'Choose the personalized icon to be displayed for the moderator group of users (optional). It can be a gif or a string of text/special characters (&!&). If using a gif, make sure to start it with the colon (:) as it would be typed in the chat'}, {name: 'iconFans', type: 'str',defaultValue: ':fanclubfist4',required: false,label: 'Choose the personalized icon to be displayed for the chaturbate fanclub group of users (optional)'}, {name: 'iconExtFans', type: 'str',defaultValue: ':fanclub-lana2',required: false,label: 'Choose the personalized icon to be displayed for the external fanclub group of users (optional)'}, {name: 'iconVIP', type: 'str',defaultValue: ':VIPCookie',required: false,label: 'Choose the personalized icon to be displayed for the VIP group of users (optional).'}, // *** VIP List {name: 'dummy5', label: '******************** VIP List *************************', type: 'choice',required: false}, {name: 'enableVIPList', label: 'Enable VIP List Privileges (PMs, Ticket Shows).', type: 'choice', choice1: 'PMs', choice2: 'Ticket Shows', choice3: 'PMs and Ticket Shows', choice4: 'None', defaultValue: 'None'}, {name: 'VIPList', label: 'Enter the names of any VIP users you would like to grant special privileges (ability to PM and free or discounted access to ticket shows). Users should be separated by a comma with no spaces', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '', required: false}, {name: 'announceVIP', label: 'Display announcement when VIPs enter the room?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, // *** External Fan Club List {name: 'dummy6', label: '**************** External Fan Club ********************', type: 'choice',required: false}, {name: 'enableExtFans', label: 'Enable External Fan Club Privileges (PMs, Ticket Shows).', type: 'choice', choice1: 'PMs', choice2: 'Ticket Shows', choice3: 'PMs and Ticket Shows', choice4: 'None', defaultValue: 'None'}, {name: 'extFanList', label: 'Enter the names of any External Fan Club members you would like to grant special privileges (ability to PM and free or discounted access to ticket shows). Users should be separated by a comma with no spaces', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '', required: false}, {name: 'announceExtFans', label: 'Display announcement when external Fan Club members enter the room?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, // *** Blocked Word List {name: 'dummy7', label: '**************** Blocked Word List ********************', type: 'choice',required: false}, {name: 'enableWordList', label: 'Enable Blocked Word List.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'wordBlockList', label: 'Enter the words you would like to block in the chat. Words should be separated by a comma with no spaces.', type: 'str', minLength: 1, maxLength: 1000, defaultValue: 'cunt,bitch,slut,c2c,cumslut,chatur.,[http://sexmap.', required: false}, // *** Tip Menu {name: 'dummy8', label: '******************* Tip Menu **************************', type: 'choice',required: false}, {name: 'enableTipMenu', label: 'Enable the Tip Menu at the start of the show? Note you can also turn the tip menu on and off during the show using the "/usemenu on" and "/usemenu off" commands.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'chatNotice',type: 'choice',choice1: 'Display the full menu',choice2: 'Only display the short notice',defaultValue: 'Display the full menu',label: "Do you want the notice to display the actual Tip Menu or only the short notice that users can view the menu using the command '/tipmenu'?"}, {name: 'menuDspInt',type: 'str',defaultValue: 3,label: 'Tip Menu display interval. Decimals are ok as long as they are greater than 1. For example, 1.5 = one minute 30 second intervals.'}, {name: 'listSort',type: 'choice',choice1: 'Do not sort the list',choice2: 'Ascending',choice3: 'Descending',defaultValue: 'Ascending',label: "Sort the items in the tip menu by price?"}, {name: 'listSplit',type: 'choice',choice1: 'Do not split the list',choice2: 'Split the list in 2',defaultValue: 'Do not split the list',label: "Should the menu be split into two sections? (will only be valid if more than 8 entries)"}, {name: 'sepchar', type: 'choice',choice1: 'Vertical Bar',choice2: 'Hearts',choice3: 'Glitter',choice4: 'Flowers',choice5: 'Bow',choice6: 'Hearts2',choice7: 'Smiley',choice8: 'Text Heart',choice9: 'Text Diamond',choice10: 'Text Star',choice11: 'Custom',defaultValue: 'Vertical Bar',label: "Choose your separator character to appear between menu items. You can also use a specific gif by entering one in the next setting below, which will override this setting"}, {name: 'sepcharcustom',type: 'str',defaultValue: ':heart2',required: false,label: 'Choose your custom separator (optional). It can be a gif or a string of text/special characters (&!&). If using a gif, make sure to start it with the colon (:) as it would be typed in the chat'}, {name: 'menutxtcolor1',type: 'choice',label: 'Choose your text color for the single menu or part 1 of the split menu',required: false,choice1: "White/No Color",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Red",choice5: "Dark Orange",choice6: "Dark Green",choice7: "Dark Aqua",choice8: "Dark Blue",choice9: "Dark Purple",choice10: "Dark Pink",choice11: "Custom",defaultValue: "Dark Orange"}, {name: 'menuCustTxtColor1',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom text color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: 'menubgcolor1',label: 'Choose the background color for the above',required: false,type: 'choice', choice1: "White/No Color",choice2: "Light Yellow",choice3: "Light Blue",choice4: "Light Pink",choice5: "Light Red",choice6: "Light Green",choice7: "Light Purple",choice8: "Light Orange",choice9: "Light Grey",choice10: "Light Aqua",choice11: "Custom",defaultValue: "White/No Color"}, {name: 'menuCustBgColor1',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom background highlight color in the previous setting, enter the hex color (6character hex color codes including the # prefix)",required: false}, {name: 'menutxtcolor2',type: 'choice',label: 'Choose your text color for part 2 of the split menu',required: false,choice1: "White/No Color",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Red",choice5: "Dark Orange",choice6: "Dark Green",choice7: "Dark Aqua",choice8: "Dark Blue",choice9: "Dark Purple",choice10: "Dark Pink",choice11: "Custom",defaultValue: "Dark Green"}, {name: 'menuCustTxtColor2',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom text color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: 'menubgcolor2',label: 'Choose the background color for the above',required: false,type: 'choice', choice1: "White/No Color",choice2: "Light Yellow",choice3: "Light Blue",choice4: "Light Pink",choice5: "Light Red",choice6: "Light Green",choice7: "Light Purple",choice8: "Light Orange",choice9: "Light Grey",choice10: "Light Aqua",choice11: "Custom",defaultValue: "White/No Color"}, {name: 'menuCustBgColor2',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom background highlight color in the previous setting, enter the hex color (6character hex color codes including the # prefix)",required: false}, {name: 'menuitem1',type: 'str',defaultValue: 'Menu Item 1',label: "Tip Menu Item 1 "}, {name: 'menuitemprice1',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 11,label: 'Item 1 price'}, {name: 'menuitem2',type: 'str',required: false,defaultValue: 'Menu Item 2',label: 'Tip Menu Item 2'}, {name: 'menuitemprice2',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 17,required: false,label: 'Item 2 price'}, {name: 'menuitem3',type: 'str',required: false,defaultValue: 'Menu Item 3',label: 'Tip Menu Item 3'}, {name: 'menuitemprice3',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 29,required: false,label: 'Item 3 price'}, {name: 'menuitem4',type: 'str',required: false,defaultValue: 'Menu Item 4',label: 'Tip Menu Item 4'}, {name: 'menuitemprice4',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 34,required: false,label: 'Item 4 price'}, {name: 'menuitem5',type: 'str',required: false,defaultValue: 'Menu Item 5',label: 'Tip Menu Item 5'}, {name: 'menuitemprice5',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 55,required: false,label: 'Item 5 price'}, {name: 'menuitem6',type: 'str',required: false,label: 'Tip Menu Item 6'}, {name: 'menuitemprice6',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 6 price'}, {name: 'menuitem7',type: 'str',required: false,label: 'Tip Menu Item 7'}, {name: 'menuitemprice7',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 7 price'}, {name: 'menuitem8',type: 'str',required: false,label: 'Tip Menu Item 8'}, {name: 'menuitemprice8',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 8 price'}, {name: 'menuitem9',type: 'str',required: false,label: 'Tip Menu Item 9'}, {name: 'menuitemprice9',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 9 price'}, {name: 'menuitem10',type: 'str',required: false,label: 'Tip Menu Item 10'}, {name: 'menuitemprice10',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 10 price'}, {name: 'menuitem11',type: 'str',required: false,label: 'Tip Menu Item 11'}, {name: 'menuitemprice11',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 11 price'}, {name: 'menuitem12',type: 'str',required: false,label: 'Tip Menu Item 12'}, {name: 'menuitemprice12',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 12 price'}, {name: 'menuitem13',type: 'str',required: false,label: 'Tip Menu Item 13'}, {name: 'menuitemprice13',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 13 price'}, {name: 'menuitem14',type: 'str',required: false,label: 'Tip Menu Item 14'}, {name: 'menuitemprice14',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 14 price'}, {name: 'menuitem15',type: 'str',required: false,label: 'Tip Menu Item 15'}, {name: 'menuitemprice15',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 15 price'}, {name: 'menuitem16',type: 'str',required: false,label: 'Tip Menu Item 16'}, {name: 'menuitemprice16',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 16 price'}, {name: 'menuitem17',type: 'str',required: false,label: 'Tip Menu Item 17'}, {name: 'menuitemprice17',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 17 price'}, {name: 'menuitem18',type: 'str',required: false,label: 'Tip Menu Item 18'}, {name: 'menuitemprice18',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 18 price'}, {name: 'menuitem19',type: 'str',required: false,label: 'Tip Menu Item 19'}, {name: 'menuitemprice19',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 19 price'}, {name: 'menuitem20',type: 'str',required: false,label: 'Tip Menu Item 20'}, {name: 'menuitemprice20',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 20 price'}, {name: 'menuitem21',type: 'str',required: false,label: 'Tip Menu Item 21'}, {name: 'menuitemprice21',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 21 price'}, {name: 'menuitem22',type: 'str',required: false,label: 'Tip Menu Item 22'}, {name: 'menuitemprice22',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 22 price'}, {name: 'menuitem23',type: 'str',required: false,label: 'Tip Menu Item 23'}, {name: 'menuitemprice23',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 23 price'}, {name: 'menuitem24',type: 'str',required: false,label: 'Tip Menu Item 24'}, {name: 'menuitemprice24',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 24 price'}, {name: 'menuitem25',type: 'str',required: false,label: 'Tip Menu Item 25'}, {name: 'menuitemprice25',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 25 price'}, {name: 'menuitem26',type: 'str',required: false,label: 'Tip Menu Item 26'}, {name: 'menuitemprice26',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 26 price'}, {name: 'menuitem27',type: 'str',required: false,label: 'Tip Menu Item 27'}, {name: 'menuitemprice27',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 27 price'}, {name: 'menuitem28',type: 'str',required: false,label: 'Tip Menu Item 28'}, {name: 'menuitemprice28',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 28 price'}, {name: 'menuitem29',type: 'str',required: false,label: 'Tip Menu Item 29'}, {name: 'menuitemprice29',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 29 price'}, {name: 'menuitem30',type: 'str',required: false,label: 'Tip Menu Item 30'}, {name: 'menuitemprice30',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 30 price'}, // *** Positions Tip Menu {name: 'dummy9', label: '***************** Positions Menu **********************', type: 'choice',required: false}, {name: 'enablePosTipMenu', label: 'Enable the Positions Tip Menu at the start of the show? Note you can also turn the positions tip menu on and off during the show using the "/useposmenu on" and "/useposmenu off" commands.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'posMenuInterval',type: 'str',defaultValue: 3,label: 'Positions Tip Menu display interval. Decimals are ok as long as they are greater than 1. For example, 1.5 = one minute 30 second intervals.'}, {name: 'posListSort',type: 'choice',choice1: 'Do not sort the list',choice2: 'Ascending',choice3: 'Descending',defaultValue: 'Ascending',label: "Sort the items in the positions menu by price?"}, {name: 'posSepChar', type: 'choice',choice1: 'Vertical Bar',choice2: 'Hearts',choice3: 'Glitter',choice4: 'Flowers',choice5: 'Bow',choice6: 'Hearts2',choice7: 'Smiley',choice8: 'Text Heart',choice9: 'Text Diamond',choice10: 'Text Star',choice11: 'Custom',defaultValue: 'Vertical Bar',label: "Choose your separator character to appear between menu items. You can also use a specific gif by entering one in the next setting below, which will override this setting."}, {name: 'posSepCharCustom',type: 'str',defaultValue: ':heart2',required: false,label: 'Choose your custom separator (optional). It can be a gif or a string of text/special characters (&!&). If using a gif, make sure to start it with the colon (:) as it would be typed in the chat'}, {name: 'posMenuTxtColor',type: 'choice',label: 'Choose your text color for the positions menu',required: false,choice1: "White/No Color",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Red",choice5: "Dark Orange",choice6: "Dark Green",choice7: "Dark Aqua",choice8: "Dark Blue",choice9: "Dark Purple",choice10: "Dark Pink",choice11: "Custom",defaultValue: "Dark Pink"}, {name: 'posMenuCustTxtColor',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom text color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: 'posMenuBgColor',label: 'Choose your background color for the positions menu',required: false,type: 'choice', choice1: "White/No Color",choice2: "Light Yellow",choice3: "Light Blue",choice4: "Light Pink",choice5: "Light Red",choice6: "Light Green",choice7: "Light Purple",choice8: "Light Orange",choice9: "Light Grey",choice10: "Light Aqua",choice11: "Custom",defaultValue: "Light Pink"}, {name: 'posMenuCustBgColor',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom background highlight color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: 'posMenuItem1',type: 'str',defaultValue: 'Missionary',label: "Positions Tip Menu Item 1 "}, {name: 'posMenuItemPrice1',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 101,label: 'Positions Item 1 price'}, {name: 'posMenuItem2',type: 'str',required: false,defaultValue: 'Doggy Style',label: 'Positions Tip Menu Item 2'}, {name: 'posMenuItemPrice2',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 102,required: false,label: 'Positions Item 2 price'}, {name: 'posMenuItem3',type: 'str',required: false,defaultValue: 'Doggy Style POV',label: 'Positions Tip Menu Item 3'}, {name: 'posMenuItemPrice3',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 103,required: false,label: 'Positions Item 3 price'}, {name: 'posMenuItem4',type: 'str',required: false,defaultValue: 'Cowgirl facing cam',label: 'Positions Tip Menu Item 4'}, {name: 'posMenuItemPrice4',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 104,required: false,label: 'Positions Item 4 price'}, {name: 'posMenuItem5',type: 'str',required: false,defaultValue: 'Cowgirl, back to cam',label: 'Positions Tip Menu Item 5'}, {name: 'posMenuItemPrice5',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 105,required: false,label: 'Positions Item 5 price'}, {name: 'posMenuItem6',type: 'str',required: false,defaultValue: 'Reverse cowgirl facing cam',label: 'Positions Tip Menu Item 6'}, {name: 'posMenuItemPrice6',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 106,required: false,label: 'Positions Item 6 price'}, {name: 'posMenuItem7',type: 'str',required: false,defaultValue: 'Reverse cowgirl, back to cam',label: 'Positions Tip Menu Item 7'}, {name: 'posMenuItemPrice7',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 107,required: false,label: 'Positions Item 7 price'}, {name: 'posMenuItem8',type: 'str',required: false,defaultValue: 'Position 8',label: 'Positions Tip Menu Item 8'}, {name: 'posMenuItemPrice8',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 108,required: false,label: 'Positions Item 8 price'}, // *** Token Poll {name: 'dummy10', label: '******************** Token Poll ***********************', type: 'choice',required: false}, {name: 'enableTokenPoll', label: 'Enable the Token Poll at start of show? Note you can also turn the token poll on and off during the show using the "/usepoll on" and "/usepoll off" commands.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: "pollTitle",type: "str",minLength: 1,maxLength: 255,default: 'Token Poll',label: "Poll Title (what will people be voting for?)"}, {name: "pollInterval",type: "int",minValue: 1,default: 2,label: "Display Interval for Token Pol vote summary (in minutes)"}, {name: "pollMode",type: "choice",label: "Type of Poll - will it be ended manually by the mod or broadcaster (default), use a timer, or go until a certain number of total votes or votes for one choice?",choice1: 'Ends by Mod/Broadcaster command',choice2: 'Ends after X minutes',choice3: 'Ends after X votes',choice4: 'Ends when one option reaches X votes',defaultValue: 'Ends by Mod/Broadcaster command'}, {name: "pollCount",type: "int",minValue: 1,default: 15,label: "Per above choice for Poll Type, choose value for X (in minutes or votes) "}, {name: "pollTxtColor",type: "choice",label: "Poll text color",choice1: "White/No Color",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Red",choice5: "Dark Orange",choice6: "Dark Green",choice7: "Dark Aqua",choice8: "Dark Blue",choice9: "Dark Purple",choice10: "Dark Pink",choice11: "Custom",defaultValue: "Dark Green"}, {name: "pollCustTxtColor",type: "str",minLength: 1,maxLength: 7,label: "If you picked a custom text color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: "pollBgColor",label: "Poll background color",type: 'choice', choice1: "White/No Color",choice2: "Light Yellow",choice3: "Light Blue",choice4: "Light Pink",choice5: "Light Red",choice6: "Light Green",choice7: "Light Purple",choice8: "Light Orange",choice9: "Light Grey",choice10: "Light Aqua",choice11: "Custom",defaultValue: "Light Green"}, {name: "pollCustBgColor",type: "str",minLength: 1,maxLength: 7,label: "If you picked a custom background highlight color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: "pollFanClubDouble",type: "choice",choice1: "Yes",choice2: "No",defaultValue: "No",label: "Fan club members vote counts double?"}, {name: "pollKeepalive",type: "choice",choice1: "Yes",choice2: "No",defaultValue: "No",label: "When using a Poll Timer, when the timer remaining drops below 30 seconds, keep the poll alive by adding 30 more seconds if people are tipping?"}, {name: "pollModAdd",type: "choice",choice1: "Yes",choice2: "No",defaultValue: "Yes",label: "Allow a moderator to add or remove votes?"}, {name: 'dummypoll', label: 'For Poll options below, you can configure up to 8 voting options below by setting the name of the choice and the associated price. Please ensure the price does not overlap with other menu options, ticket show prices, etc. The first two poll choices are required.', type: 'choice',required: false}, {name: "pollOptLabel1",type: "str",minLength: 1,maxLength: 255,default: 'on boobs',label: "Option 1"}, {name: "pollOptTokens1",type: "int",minValue: 1,default: 11,label: "Option 1 tokens"}, {name: "pollOptLabel2",type: "str",minLength: 1,maxLength: 255,default: 'on face',label: "Option 2"}, {name: "pollOptTokens2",type: "int",minValue: 1,default: 12,label: "Option 2 tokens"}, {name: "pollOptLabel3",type: "str",minLength: 1,maxLength: 255,label: "Option 3",required: false}, {name: "pollOptTokens3",type: "int",minValue: 1,label: "Option 3 tokens",required: false}, {name: "pollOptLabel4",type: "str",minLength: 1,maxLength: 255,label: "Option 4",required: false}, {name: "pollOptTokens4",type: "int",minValue: 1,label: "Option 4 tokens",required: false}, {name: "pollOptLabel5",type: "str",minLength: 1,maxLength: 255,label: "Option 5",required: false}, {name: "pollOptTokens5",type: "int",minValue: 1,label: "Option 5 tokens",required: false}, {name: "pollOptLabel6",type: "str",minLength: 1,maxLength: 255,label: "Option 6",required: false}, {name: "pollOptTokens6",type: "int",minValue: 1,label: "Option 6 tokens",required: false}, {name: "pollOptLabel7",type: "str",minLength: 1,maxLength: 255,label: "Option 7",required: false}, {name: "pollOptTokens7",type: "int",minValue: 1,label: "Option 7 tokens",required: false}, {name: "pollOptLabel8",type: "str",minLength: 1,maxLength: 255,label: "Option 8",required: false}, {name: "pollOptTokens8",type: "int",minValue: 1,label: "Option 8 tokens",required: false}, // *** Ticket Show Support {name: 'dummy11', label: '****************** Ticket Shows ***********************', type: 'choice',required: false}, {name: 'prepticketTipMenuOff', label: 'Enable the /prepticket command to turn off the Tip Menu?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'prepticketPosMenuOn', label: 'Enable the /prepticket command to turn on the Positions Tip Menu?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'prepticketStartPoll', label: 'Enable the /prepticket command to start the Token Poll?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'startPollTimerWithShow', label: 'A common approach is to start the Poll under "Manual End" mode before the entering the ticket show and then once the show is started, also start a timer for the poll. This setting controls whether the CrazyTicket /startshow comamnd will also switch the poll from Manual End mode to Timer mode, and the setting below defines how long after /startshow to end the timer.', type: 'choice', choice1: 'Yes, switch to timed poll at show start', choice2: 'No, do not change poll', defaultValue: 'No, do not change poll'}, {name: 'startPollMinAfterShow',type: 'int', minValue: 1, maxValue: 60,required: false, defaultValue: 10,label: 'If the above setting switches the Poll to "Timer" mode, define the number of minutes to use for the poll timer after /startshow'}, {name: 'endPosMenuWithShow', label: 'Turn off the Positions menu when the show is finished (either /showend or /stopshow will end it)', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'prepticketAddVIP', label: 'Enable the /prepticket command to add VIP Members to the ticket show (if granted ticket show privileges)?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'prepticketAddExtFC', label: 'Enable the /prepticket command to add External Fan Club Members to the ticket show (if granted ticket show privileges)?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'ticketModAdd', label: 'Allow moderators to use the commands to add top tippers to the Ticket Show.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'prepticketStartTlist', label: 'Enable the /prepticket command to start the Backup Ticket List? When this is enabled, ticket purchases for CrazyTicket will be backed up in the ultrabot in case CrazyTicket Fails.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: "tlistPrice",type: "int",minValue: 1,required: false,label: "If the Backup List will be turned on and you know the ticket price at the time of starting the ultrabot, define the ticket price at which tippers should be added. Otherwise, price can be updated during show with /tlistprice [xxx]."}, {name: "numberFromLB",type: "int",minValue: 1,maxValue: 10,required: false, defaultValue: 3,label: "Number of entries from the leaderboard to add to a ticket show (Top 3, Top 5, etc). Defaults to Top 3 if not set. Set this number or the minimum tip amount to add."}, {name: "amountFromLB",type: "str",minLength: 1,maxLength: 6,required: false, defaultValue: 1000,label: "Minimum total tip amount to be used to grant a free ticket to a ticket show. Defaults to 1000 if not set. Set this number or the number of top tippers."}, // *** Lush Tip Menu {name: 'dummy12', label: '***************** Lush Tip Menu ***********************', type: 'choice',required: false}, {name: 'enableLushMenu', label: 'Enable the Lush Tip Menu at the start of the show? Note you can also turn the lush menu on and off during the show using the "/uselushmenu on" and "/uselushmenu off" commands. Also, this only displays the lush tipping options, it does not control the lush itself, that is done through the lush app. You can also use the chrome extension to publish the lush config directly to the chat in place of this menu.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'lushMenuInterval',type: 'str',defaultValue: 3,label: 'Lush Tip Menu display interval. Decimals are ok as long as they are greater than 1. For example, 1.5 = one minute 30 second intervals.'}, {name: 'lushMenuTxtColor',type: 'choice',label: 'Choose your text color for the Lush menu',required: false,choice1: "White/No Color",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Red",choice5: "Dark Orange",choice6: "Dark Green",choice7: "Dark Aqua",choice8: "Dark Blue",choice9: "Dark Purple",choice10: "Dark Pink",choice11: "Custom",defaultValue: "Dark Pink"}, {name: 'lushMenuCustTxtColor',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom text color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: 'lushMenuBgColor',label: 'Choose your background color for the Lush menu',required: false,type: 'choice', choice1: "White/No Color",choice2: "Light Yellow",choice3: "Light Blue",choice4: "Light Pink",choice5: "Light Red",choice6: "Light Green",choice7: "Light Purple",choice8: "Light Orange",choice9: "Light Grey",choice10: "Light Aqua",choice11: "Custom",defaultValue: "Light Pink"}, {name: 'lushMenuCustBgColor',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom background highlight color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: 'dummy13', label: 'Lush Level Heading only: Use the default as a template and set the text in the options below to match the configuration in the lush control panel, leave an entry blank to skip display of a level', type: 'choice',required: false}, {name: 'lushMenuLevel1',type: 'str',label: "Level 1 Message",defaultValue: 'Level 1 (Tip 1-14) : 5 seconds on LOW vibrations',required: false}, {name: 'lushMenuLevel2',type: 'str',label: "Level 2 Message",defaultValue: 'Level 2 (Tip 15-30) : 5 seconds on MEDIUM vibrations',required: false}, {name: 'lushMenuLevel3',type: 'str',label: "Level 3 Message",defaultValue: 'Level 3 (Tip 31-49) : 10 seconds on MEDIUM vibrations',required: false}, {name: 'lushMenuLevel4',type: 'str',label: "Level 4 Message",defaultValue: 'Level 4 (Tip 50-74) : 15 seconds on MEDIUM vibrations',required: false}, {name: 'lushMenuLevel5',type: 'str',label: "Level 5 Message",defaultValue: 'Level 5 (Tip 75-99) : 30 seconds on HIGH vibrations',required: false}, {name: 'lushMenuLevel6',type: 'str',label: "Level 6 Message",defaultValue: 'Level 6 (Tip 100-249): 30 seconds on HIGH vibrations',required: false}, {name: 'lushMenuLevel7',type: 'str',label: "Level 7 Message",defaultValue: 'Level 7 (Tip 250-499): 1 Minute on HIGH vibrations',required: false}, {name: 'lushMenuLevel8',type: 'str',label: "Level 8 Message",defaultValue: 'Level 8 (Tip 500+) : 5 Minutes on HIGH vibrations',required: false}, {name: 'lushMenuLevel9',type: 'str',label: "Random Level Message",defaultValue: 'Random Level - Tip 70 to get a random level!',required: false}, {name: 'lushMenuLevel10',type: 'str',label: "Pattern Level 1 Message",defaultValue: 'Pattern 1 - Tip 115 for a wave pattern for 30 seconds',required: false}, {name: 'lushMenuLevel11',type: 'str',label: "Pattern Level 2 Message",defaultValue: 'Pattern 2 - Tip 116 for a block wave pattern for 30 seconds',required: false}, {name: 'lushMenuLevel12',type: 'str',label: "Pattern Level 3 Message",defaultValue: 'Pattern 3 - Tip 117 for a pulse pattern for 30 seconds',required: false}, {name: 'lushMenuLevel13',type: 'str',label: "Pattern Level 4 Message",defaultValue: 'Pattern 4 - Tip 118 for a constant high pattern for 30 seconds',required: false}, // *** Media Platforms {name: 'dummy14', label: '******************* Media List *************************', type: 'choice',required: false}, {name: 'enableMediaNotice',label: 'Enable the posting of your contact info and media platforms detailed below? Note you can also turn the notice on and off during the show using the "/usemedia on" and "/usemedia off" commands.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'mediaListInterval',type: 'int',minValue: 1,maxValue: 15,required: false, defaultValue: 5,label: 'Time interval for displaying the Media List'}, {name: 'mediaListIntro',type: 'str',minLength: 1,maxLength: 255,label: "Enter the Text you would like to show at the beginning of the media list to introduce the list to the user",required: false, defaultValue: 'Contact info is below for scheduling privates, shopping on amazon wishlist, and staying in touch through my various social media platforms:'}, {name: 'mediaListTxtColor',type: 'choice',label: 'Choose your text color for the Media List',required: false,choice1: "White/No Color",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Red",choice5: "Dark Orange",choice6: "Dark Green",choice7: "Dark Aqua",choice8: "Dark Blue",choice9: "Dark Purple",choice10: "Dark Pink",choice11: "Custom",defaultValue: "Dark Pink"}, {name: 'mediaListCustTxtColor',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom text color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: 'mediaListBgColor',label: 'Choose your background color for the Media List',required: false,type: 'choice', choice1: "White/No Color",choice2: "Light Yellow",choice3: "Light Blue",choice4: "Light Pink",choice5: "Light Red",choice6: "Light Green",choice7: "Light Purple",choice8: "Light Orange",choice9: "Light Grey",choice10: "Light Aqua",choice11: "Custom",defaultValue: "Light Pink"}, {name: 'mediaListCustBgColor',type: 'str',minLength: 1,maxLength: 7,label: "If you picked a custom background highlight color in the previous setting, enter the hex color (6character hex color codes including the # prefix):",required: false}, {name: 'mediaListText1',type: 'str',label: "Text for Item 1",defaultValue: 'E-mail Address',required: false}, {name: 'mediaListItem1',type: 'str',label: "Item 1",defaultValue: 'abc@email.com',required: false}, {name: 'mediaListText2',type: 'str',label: "Text for Item 2",defaultValue: 'Personal Website',required: false}, {name: 'mediaListItem2',type: 'str',label: "Item 2",defaultValue: 'http://abc.web.com',required: false}, {name: 'mediaListText3',type: 'str',label: "Text for Item 3",defaultValue: 'Twitter ID',required: false}, {name: 'mediaListItem3',type: 'str',label: "Item 3",defaultValue: ':twitter_30x30 @Twitter',required: false}, {name: 'mediaListText4',type: 'str',label: "Text for Item 4",defaultValue: 'Instagram ID',required: false}, {name: 'mediaListItem4',type: 'str',label: "Item 4",defaultValue: ':inst_30x30 @Instagram',required: false}, {name: 'mediaListText5',type: 'str',label: "Text for Item 5",defaultValue: 'Public Snapchat ID',required: false}, {name: 'mediaListItem5',type: 'str',label: "Item 5",defaultValue: ':snapchat_30x30 @snapID',required: false}, {name: 'mediaListText6',type: 'str',label: "Text for Item 6",defaultValue: 'Amazon Wishlist',required: false}, {name: 'mediaListItem6',type: 'str',label: "Item 6",defaultValue: ':AmazonWLSml http://amazon.com/user',required: false}, {name: 'mediaListText7',type: 'str',label: "Text for Item 7",defaultValue: 'Manyv!ds ID',required: false}, {name: 'mediaListItem7',type: 'str',label: "Item 7",defaultValue: ':manyvids_10 @manyv!ds',required: false}, {name: 'mediaListText8',type: 'str',label: "Text for Item 8",defaultValue: 'External Fan Club',required: false}, {name: 'mediaListItem8',type: 'str',label: "Item 8",defaultValue: 'fanclub_30x30 http://fancentro.com/user',required: false}, {name: 'mediaListText9',type: 'str',label: "Text for Item 9",defaultValue: 'Misc Link 1',required: false}, {name: 'mediaListItem9',type: 'str',label: "Item 9",defaultValue: 'Insert Link 1',required: false}, {name: 'mediaListText10',type: 'str',label: "Text for Item 10",defaultValue: 'Misc Link 2',required: false}, {name: 'mediaListItem10',type: 'str',label: "Item 10",defaultValue: 'Insert Link 2',required: false}, {name: 'mediaListText11',type: 'str',label: "Text for Item 11",defaultValue: 'Misc Link 3',required: false}, {name: 'mediaListItem11',type: 'str',label: "Item 11",defaultValue: 'Insert Link 3',required: false}, {name: 'mediaListText12',type: 'str',label: "Text for Item 12",defaultValue: 'Misc Link 4',required: false}, {name: 'mediaListItem12',type: 'str',label: "Item 12",defaultValue: 'Insert Link 4',required: false} ]; } { // *********************************** Variables and Arrays ************************************** var initialize = 0; /* Used to run initialization once */ var numberOfModerators = 1; /* Count of entries in moderator array */ var silenceLevel = 0; /* Default to everyone can chat */ var graphicLevel = 1; /* Default to grays cannot post graphics */ var numPMs = 0; var timerStart = 0; /* captured time when the timer was started, used to calculate time left */ var clockStartTime = 0; var clockStopTime = 0; var timerDuration = 0; var clockTimeAdded = 0; var clockMinsRemain = 0; var clockSecsRemain = 0; var clockSkipMin = false; var clockSkipSec = false; var notifierToggle = 0; var tipMenuToggle = 0; var posTipMenuToggle = 0; var tokenPollToggle = 0; var lushMenuToggle = 0; var leaderboardToggle = 0; var tipCountToggle = 0; var groupIconsToggle = 0; var tlistToggle = 0; var mediaToggle = 0; var tipLeaderIconsToggle = 0; var numberOfTippers = 0; var firstlb = 0; var firstmedia = 0; var leaderTimer = 0; var num = 0; var tlistPrice = 0; var notifierMessage1 = cb.settings.notifierMessage1; var notifierMessage2 = cb.settings.notifierMessage2; var notifierMessage3 = cb.settings.notifierMessage3; var notifierMessage4 = cb.settings.notifierMessage4; var notifierMessage5 = cb.settings.notifierMessage5; var BC = cb.room_slug; var leaderInt = parseInt(cb.settings.leaderInterval) * 60000; var green = "#a2dfac"; /* Used for general messaging from fembot */ var purple = "#e2a2ea"; var yellow = "#f4d599"; /* Used for clock countdown */ var red = "#f4c1bc"; /* Used for last 2 minutes of clock countdown */ var blue = "#0099ff"; var HLgreen = "#91c970"; /* Green notice highlighting */ var HLpurple = "#e2a2ea"; /* Purple notice highlighting */ var HLyellow = "#fcff9b"; /* Yellow notice highlighting */ var HLred = "#ff6d69"; /* Red notice highlighting */ var HLblue = "#81bcff"; /* Blue notice highlighting */ var dashLine = new Array(61).join("-"); var mediaListItem1 = cb.settings.mediaListItem1; var mediaListItem2 = cb.settings.mediaListItem2; var mediaListItem3 = cb.settings.mediaListItem3; var mediaListItem4 = cb.settings.mediaListItem4; var mediaListItem5 = cb.settings.mediaListItem5; var mediaListItem6 = cb.settings.mediaListItem6; var mediaListItem7 = cb.settings.mediaListItem7; var mediaListItem8 = cb.settings.mediaListItem8; var mediaListItem9 = cb.settings.mediaListItem9; var mediaListItem10 = cb.settings.mediaListItem10; var mediaListItem11 = cb.settings.mediaListItem11; var mediaListItem12 = cb.settings.mediaListItem12; var mediaListText1 = cb.settings.mediaListText1; var mediaListText2 = cb.settings.mediaListText2; var mediaListText3 = cb.settings.mediaListText3; var mediaListText4 = cb.settings.mediaListText4; var mediaListText5 = cb.settings.mediaListText5; var mediaListText6 = cb.settings.mediaListText6; var mediaListText7 = cb.settings.mediaListText7; var mediaListText8 = cb.settings.mediaListText8; var mediaListText9 = cb.settings.mediaListText9; var mediaListText10 = cb.settings.mediaListText10; var mediaListText11 = cb.settings.mediaListText11; var mediaListText12 = cb.settings.mediaListText12; var ticketModAdd = (cb.settings.ticketModAdd === "Yes"); // Arrays */ var niceListArray = []; var silenceListArray = []; var ninjaListArray = []; var VIPListArray = []; var extFanListArray = []; var wordListArray = []; var MessageArray = []; var pmArray = []; var tlistArray = []; var moderatorList = { name: [], type: [] }; var tipCountArray = { name: [], amount: [] }; // **** Tip Menu Variables var TIPMENU = { menuDspIntTime: 0, sepChar: "| ", tipMenu: "", menuPart1: "", menuPart2: "", menuToken: 1, tipMenuPrice: [], tipMenuItem: [], initToken: true, txtColor1: "", bgColor1: "", txtColor2: "", bgColor2: "", menuLength: 0, requesters: [], request: [], }; var POSTIPMENU = { posMenuDspIntTime: 0, posSepChar: "| ", posTipMenu: "", posTipMenuPrice: [], posTipMenuItem: [], posInitToken: true, posTxtColor: "", posBgColor: "", posMenuLength: 0, posRequesters: [], posRequest: [], }; var LUSHMENU = { lushMenuDspIntTime: 0, lushMenu: "", lushMenuLevel: [], lushInitToken: true, lushTxtColor: "", lushBgColor: "", lushMenuLength: 0, }; // ************ Variables for Token Poll var pollwarnLight = "#FF0000"; var pollwarnDark = "#FFFFFF"; var pollType; var fanDouble = (cb.settings.pollFanClubDouble === "Yes"); var pollModAdd = (cb.settings.pollModAdd === "Yes"); var pollStartTime; var pollStopTime; var pollMinsRemain = cb.settings.pollCount; var pollSecsRemain = 60; var votesRemain = cb.settings.pollCount; var pollRunning = false; var aliveWarned = false; var nline = 0; var pollOptLabel1 = cb.settings.pollOptLabel1; var pollOptLabel2 = cb.settings.pollOptLabel2; var pollOptLabel3 = cb.settings.pollOptLabel3; var pollOptLabel4 = cb.settings.pollOptLabel4; var pollOptLabel5 = cb.settings.pollOptLabel5; var pollOptLabel6 = cb.settings.pollOptLabel6; var pollOptLabel7 = cb.settings.pollOptLabel7; var pollOptLabel8 = cb.settings.pollOptLabel8; var pollOptTokens1 = cb.settings.pollOptTokens1; var pollOptTokens2 = cb.settings.pollOptTokens2; var pollOptTokens3 = cb.settings.pollOptTokens3; var pollOptTokens4 = cb.settings.pollOptTokens4; var pollOptTokens5 = cb.settings.pollOptTokens5; var pollOptTokens6 = cb.settings.pollOptTokens6; var pollOptTokens7 = cb.settings.pollOptTokens7; var pollOptTokens8 = cb.settings.pollOptTokens8; var pollArrayAmount = []; var pollArrayLabel = []; var pollArrayVotes = []; var pollSkipMin = false; var pollSkipSec = false; } { // *********************************** Functions ************************************** { // Generic function to set the hex color code based on the setting literal value function checkTextColor(color) { switch (color) { case "White/No color": return "#FFFFFF"; case "Black": return "#000000"; case "Dark Blue": return "#0629AC"; case "Dark Pink": return "#FF6680"; case "Dark Green": return "#006600"; case "Dark Red": return "#cc0000"; case "Dark Purple": return "#3d003d"; case "Dark Grey": return "#737373"; case "Dark Orange": return "#e77400"; case "Dark Aqua": return "#006767"; default: if (/^#[0-9A-F]{6}$/i.test(color)) { return color; } else if (/^[0-9A-F]{6}$/i.test(color)) { return ('#' + color); } else { return ("default"); } } } function checkBgColor(color) { switch (color) { case "White/No color": return "#FFFFFF"; case "Light Aqua": return "#adeaea"; case "Light Pink": return "#FFE6EA"; case "Light Green": return "#94e594"; case "Light Red": return "#ff9a9a"; case "Light Purple": return "#f2cdff"; case "Light Orange": return "#ffd9b3"; case "Light Grey": return "#e6e6e6"; case "Light Blue": return "#d1eaee"; case "Light Yellow": return "#ffff94" default: if (/^#[0-9A-F]{6}$/i.test(color)) { return color; } else if (/^[0-9A-F]{6}$/i.test(color)) { return ('#' + color); } else { return ("default"); } } } //********** Tip Count Functions ************** function populateTipCountArray(user,tip) { tipCountArray.name.push(user); tipCountArray.amount.push(tip); } function findTipper(user) { for (var i = 0; i < tipCountArray.name.length; i++) { if(tipCountArray.name[i] == user) { break; } } return i; } //********** Room Subject Function ************** function setRoomSubject(newSubject, user) { cb.changeRoomSubject(newSubject); cb.sendNotice(user + ' has updated the room title to "' + newSubject + '".', "", "", "bold"); } //********** Leaderboard Functions ************** function setLeaderToggle(option, mod) { if(option == 'on') { if(leaderboardToggle == 1) { cb.sendNotice('The Leaderboard display is already turned on.',mod,green); } else { leaderboardToggle = 1; sendLeaderboard(); cb.sendNotice('You have turned on the Leaderboard display.',mod,green); } } else if(option == 'off') { if(leaderboardToggle == 0) { cb.sendNotice('The Leaderboard display is already turned off.',mod,green); } else { leaderboardToggle = 0; cb.sendNotice('You have turned off the Leaderboard display.',mod,green); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /useleaderboard.\nType /fbhelp useleaderboard to see how to use /useleaderboard.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /useleaderboard.\nType /fbhelp useleaderboard to see how to use /useleaderboard.',mod,green); } } function sendLeaderboard() { if(firstlb == 0) { leaderTimer = leaderInt - 30000; firstlb = 1 } else { leaderTimer = leaderInt; } cb.setTimeout(leaderboardTimer, leaderTimer); } function leaderboardTimer() { if(leaderboardToggle == 1) { sortTippers(); setLeaderBoardColors(); var outString = ""; for (var i = 1; i <= 5; i++) { if (tipCountArray.name[i - 1] == null) outString += " " + i + ". empty" + "\n"; else outString += " " + i + ". " + '"' + tipCountArray.name[i - 1] + '"' + ": " + tipCountArray.amount[i - 1] + "\n"; } cb.sendNotice("\u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 LEADERBOARD \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606\n" + outString + "\u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606", "", leaderBgColor, leaderTextColor, "bold"); sendLeaderboard(); } } function showLeaderBoard(from, group) { if(leaderboardToggle == 1) { sortTippers(); setLeaderBoardColors(); var outString = ""; for (var i = 1; i <= 5; i++) { if (tipCountArray.name[i - 1] == null) outString += " " + i + ". empty" + "\n"; else outString += " " + i + ". " + '"' + tipCountArray.name[i - 1] + '"' + ": " + tipCountArray.amount[i - 1] + "\n"; } cb.sendNotice("\u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 LEADERBOARD \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606\n" + outString + "\u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606 \u2606", from, leaderBgColor, leaderTextColor, "bold", group); } else { cb.sendNotice('The broadcaster has decided not to use the Leaderboard feature.',from,green); } } function setLeaderBoardColors() { if (cb.settings.leaderTextColor == "Custom") { leaderTextColor = checkTextColor(cb.settings.leaderTextCustomColor); if (noticeTextColor == "default") { cb.sendNotice("Leaderboard - Error while setting the text color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); leaderTextColor = '#FFFFFF'; } } else { leaderTextColor = checkTextColor(cb.settings.leaderTextColor); } if (cb.settings.leaderBgColor == "Custom") { leaderBgColor = checkBgColor(cb.settings.leaderBgCustomColor); if (leaderBgColor == "default") { cb.sendNotice("Leaderboard - Error while setting the background color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); leaderBgColor = '#FFFFFF'; } } else { leaderBgColor = checkBgColor(cb.settings.leaderBgColor); } } function sortTippers() { var swapped, temp1, temp2; do { swapped = false; for (var i = 0; i < tipCountArray.amount.length ; i++) { if (tipCountArray.amount[i] < tipCountArray.amount[i + 1]) { temp1 = tipCountArray.amount[i]; temp2 = tipCountArray.name[i]; tipCountArray.amount[i] = tipCountArray.amount[i + 1]; tipCountArray.amount[i + 1] = temp1; tipCountArray.name[i] = tipCountArray.name[i + 1]; tipCountArray.name[i + 1] = temp2; swapped = true; } } } while (swapped); } function showTippers(from,group,num) { sortTippers(); var outString = ""; for (var i = 1; i <= num; i++) { if (tipCountArray.name[i - 1] == null) outString += "\u25ba " + i + ". --" + "\n"; else outString += "\u25ba " + i + ". " + '"' + tipCountArray.name[i - 1] + '"' + ": " + tipCountArray.amount[i - 1] + "\n"; } cb.sendNotice(dashLine + "\n\u25ba \u25ba \u25ba ALL TIPPERS \u25c4 \u25c4 \u25c4\n" + outString + dashLine, from, "", '#111111', "bold",group); } function populateModeratorArray(user,type) { if (!cbjs.arrayContains(moderatorList, user, type)) { moderatorList.name.push(user); moderatorList.type.push(type); } else { return; } } //********** Chat Control Functions ************** function setSilenceLevel(s, mod) { if(parseInt(s) >= 0 && parseInt(s) <= 3) { silenceLevel = parseInt(s); cb.sendNotice('The silence level has been set to ' + s + '.', cb.room_slug, green); cb.sendNotice('The silence level has been set to ' + s + '.', "", green, "", "", "red"); switch(parseInt(s)) { case 0: cb.sendNotice('All members can talk in chat.', cb.room_slug, green); cb.sendNotice('All members can talk in chat.', "", green, "", "", "red"); break; case 1: cb.sendNotice('Only members with tokens can talk in chat.', cb.room_slug, green); cb.sendNotice('Only members with tokens can talk in chat.', "", green, "", "", "red"); break; case 2: cb.sendNotice('Only members who have tipped can talk in chat.', cb.room_slug, green); cb.sendNotice('Only members who have tipped can talk in chat.', "", green, "", "", "red"); break; case 3: cb.sendNotice('Only members who have tipped at least 10 tokens can talk in chat.', cb.room_slug, green); cb.sendNotice('Only members who have tipped at least 10 tokens can talk in chat.', "", green, "", "", "red"); break; } } else { cb.sendNotice(s + ' is not a valid setting.\nType "/fbhelp silencelevel" to see how to use /silencelevel.',mod,green); } } function setGraphicLevel(s, mod) { if(parseInt(s) >= 0 && parseInt(s) <= 3) { graphicLevel = parseInt(s); cb.sendNotice('The graphic level has been set to ' + s + '.', cb.room_slug, green); cb.sendNotice('The graphic level has been set to ' + s + '.', "", green, "", "", "red"); switch(parseInt(s)) { case 0: cb.sendNotice('All members can use graphics in chat.',BC,green); cb.sendNotice('All members can use graphics in chat.', "", green, "", "", "red"); break; case 1: cb.sendNotice('Only members with tokens can use graphics in chat.', BC, green); cb.sendNotice('Only members with tokens can use graphics in chat.', "", green, "", "", "red"); break; case 2: cb.sendNotice('Only members who have tipped can use graphics in chat.', BC, green); cb.sendNotice('Only members who have tipped can use graphics in chat.', "", green, "", "", "red"); break; case 3: cb.sendNotice('Only members who have tipped at least 10 tokens can use graphics in chat.', BC, green); cb.sendNotice('Only members who have tipped at least 10 tokens can use graphics in chat.', "", green, "", "", "red"); break; } } else { cb.sendNotice(s + ' is not a valid setting.\nType "/fbhelp graphiclevel" to see how to use /graphiclevel.', mod, green); } } //********** List Maintenance Functions ************** function addRmvNinja(user, mod, mode) { if (mode == 'a') { if(cbjs.arrayContains(ninjaListArray,user)) { cb.sendNotice(user + ' has already been added to the ninja list.', mod, green); } else if(!cbjs.arrayContains(moderatorList,user) && user != cb.room_slug) { ninjaListArray.push(user); cb.sendNotice('You have added ' + user + ' to the ninja list.', mod, green); } if(user == cb.room_slug) { cb.sendNotice(user + ' is the broadcaster and cannot be ninja\'d.', mod, green); } } else if (mode == 'r') { if(cbjs.arrayContains(ninjaListArray,user)) { cbjs.arrayRemove(ninjaListArray,user); cb.sendNotice('You have removed ' + user + ' from the ninja list.', mod, green); } else { cb.sendNotice(user + ' is not on the ninja list.', mod, green); } } } function addRmvSilence(user, mod, mode) { if (mode == 'a') { if(cbjs.arrayContains(silenceListArray,user)) { cb.sendNotice(user + ' has already been silenced.', mod, green); } else if(!cbjs.arrayContains(moderatorList,user) && user != cb.room_slug) { silenceListArray.push(user); cb.sendNotice('You have added ' + user + ' to the silence list. Note this is only applied during this session, permanent silence list changes must be made to list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); cb.sendNotice('You have been silenced due to rudeness, demands or otherwise inappropriate behavior. In the future, you can avoid this by being nice and not making demands.', user, green); } if(user == cb.room_slug) { cb.sendNotice(user + ' is the broadcaster and cannot be silenced.', mod, green); } } else if (mode == 'r') { if(cbjs.arrayContains(silenceListArray,user)) { cbjs.arrayRemove(silenceListArray,user); cb.sendNotice('You have removed ' + user + ' from the silence list. Note this is only applied during this session, permanent silence list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); cb.sendNotice('You have been unsilenced by ' + mod + '. Please be nice and don\'t make demands.', user, green); } else { cb.sendNotice(user + ' is not currently silenced.', mod, green); } } } function addRmvWord(word, mod, mode) { if (mode == 'a') { if(cbjs.arrayContains(wordListArray,word)) { cb.sendNotice(word + ' has already been added to the Blocked Word list.', mod, green); } else { wordListArray.push(word); cb.sendNotice('You have added "' + word + '" to the Blocked Word list. Note this is only applied during this session, permanent word list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); } } else if (mode == 'r') { if(cbjs.arrayContains(wordListArray,word)) { cbjs.arrayRemove(wordListArray,word); cb.sendNotice('You have removed "' + word + '" from the Blocked Word list. Note this is only applied during this session, permanent word list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); } else { cb.sendNotice(word + ' is not on the Blocked Word list.', mod, green); } } } function addRmvVIP(user, mod, mode) { if (mode == 'a') { if(cbjs.arrayContains(VIPListArray,user)) { cb.sendNotice(user + ' has already been added to the VIP list.', mod, green); } else { VIPListArray.push(user); cb.sendNotice('You have added ' + user + ' to the VIP list. Note this is only applied during this session, permanent VIP list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); cb.sendNotice('Congratulations! You have been added to the VIP list!', user, green); } } else if (mode == 'r') { if(cbjs.arrayContains(VIPListArray,user)) { cbjs.arrayRemove(VIPListArray,user); cb.sendNotice('You have removed ' + user + ' from the VIP list. Note this is only applied during this session, permanent VIP list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); } else { cb.sendNotice(user + ' is not on the VIP list.', mod, green); } } } function addRmvExtFan(user, mod, mode) { if(mode == 'a') { if(cbjs.arrayContains(extFanListArray,user)) { cb.sendNotice(user + ' has already been added to the External Fan Club list.', mod, green); } else { extFanListArray.push(user); cb.sendNotice('You have added ' + user + ' to the External Fan Club list. Note this is only applied during this session, permanent External Fan Club list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); cb.sendNotice('Congratulations! You have been added to the External Fan Club list!', user, green); } } else if(mode == 'r') { if(cbjs.arrayContains(extFanListArray,user)) { cbjs.arrayRemove(extFanListArray,user); cb.sendNotice('You have removed ' + user + ' from the External Fan Club list. Note this is only applied during this session, permanent Fan Club list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); } else { cb.sendNotice(user + ' is not on the External Fan Club list.', mod, green); } } } function addRmvNice(user, mod, mode) { if(mode == 'a') { if(!cbjs.arrayContains(niceListArray,user)) { niceListArray.push(user); cb.sendNotice('You have added ' + user + ' to the nice list. Note this is only applied during this session, permanent nice list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); cb.sendNotice(mod + ' has added you to the nice list. You will be able to chat and use graphcs regardless of the global room settings. Thank you for being nice!',user,green); } else { cb.sendNotice(user + ' is already on the nice list.', mod, green); } } else if(mode == 'r') { if(cbjs.arrayContains(niceListArray,user)) { cbjs.arrayRemove(niceListArray,user); cb.sendNotice('You have removed ' + user + ' from the nice list. Note this is only applied during this session, permanent nice list changes must be made to the list defined when starting the ultrabot. This list should also be saved to a separate document.', mod, green); cb.sendNotice(mod + ' has removed you from the nice list.', user, green); } else { cb.sendNotice(user + ' is not on the nice list.', mod, green); } } } function populateNiceListArray(user) { if (!cbjs.arrayContains(niceListArray, user)) niceListArray.push(user); else return; } function populateWordListArray(word) { if (!cbjs.arrayContains(wordListArray, word)) wordListArray.push(word); else return; } function populateVIPListArray(user) { if (!cbjs.arrayContains(VIPListArray, user)) VIPListArray.push(user); else return; } function populateExtFanListArray(user) { if (!cbjs.arrayContains(extFanListArray, user)) extFanListArray.push(user); else return; } //********** Timer Functions ************** function clockTimerMin() { if (!clockSkipMin) { switch (clockMinsRemain) { case 120: case 90: case 60: case 45: case 30: case 20: case 15: case 10: case 9: case 8: case 7: case 6: case 5: case 4: case 3: case 2: cb.sendNotice("\u23f1 \u23f1 \u23f1 There are " + clockMinsRemain + " minutes left on the timer \u23f1 \u23f1 \u23f1", "", yellow, "", "bold"); } clockMinsRemain--; if (clockMinsRemain > 0) { cb.setTimeout(clockTimerMin, 60000); } else { clockSecsRemain = 60; cb.sendNotice("\u23f1 \u23f1 \u23f1 There is 1 minute left on the timer!! \u23f1 \u23f1 \u23f1", "", red, "", "bold"); clockTimerSec(); } } else { clockSkipMin = false; } } function clockTimerSec() { if (!clockSkipSec) { if (clockMinsRemain > 0) { cb.setTimeout(clockTimerMin, clockSecsRemain*1000); } else { clockSecsRemain--; if (clockSecsRemain < 1) { cb.sendNotice("\u23f0 \u23f0 \u23f0 Time is up! \u23f0 \u23f0 \u23f0", "", yellow, "", "bold"); } else { switch (clockSecsRemain) { case 45: case 30: case 15: case 5: case 4: case 3: case 2: case 1: cb.sendNotice("\u23f1 \u23f1 \u23f1 There are " + clockSecsRemain + " second" + (clockSecsRemain > 1 ? "s" : "") + " left on the timer \u23f1 \u23f1 \u23f1", "", red, "", "bold"); } } if (clockSecsRemain > 0) { cb.setTimeout(clockTimerSec, 1000); } } } else { clockSkipSec = false; } } function clockAddTime(clocktimetoadd, u) { clockStopTime = new Date(clockStopTime.getTime() + clocktimetoadd * 60000); cb.sendNotice(u + " has added " + clocktimetoadd + " minute" + (clocktimetoadd === 1 || clocktimetoadd === -1 ? "" : "s") + " to the timer.",cb.room_slug,"","", "bold"); cb.sendNotice(clocktimetoadd + " minute" + (clocktimetoadd === 1 || clocktimetoadd === -1 ? "" : "s") + " have been added to the timer. " + timeLeft(),"",yellow,"", "bold"); clockMinsRemain = clockMinsRemain + clocktimetoadd; if (clockMinsRemain < 1) { clockSkipMin = true; clockTimeLeft = clockTimeCal(); clockMS = clockTimeLeft % 1000; clockSeconds = ((clockTimeLeft - clockMS) % 60000) / 1000; clockSecsRemain = clockSeconds; clockTimerSec(); } return; } function clockTimeCal() { clockStartTime = new Date(); return clockStopTime - clockStartTime.getTime(); } function stopClockTimer(mod) { clockStopTime = new Date(); if (clockMinsRemain > 0 || clockSecsRemain > 0) { clockMinsRemain = 0; clockSecsRemain = 0; clockSkipMin = true; clockSkipSec = true; } if(mod != null) { cb.sendNotice(mod + ' has stopped the timer.',"",yellow,"", "bold"); } } function timeLeft(user) { var clockTimeLeft = clockTimeCal(); var clockMS = clockTimeLeft % 1000; var clockSeconds = ((clockTimeLeft - clockMS) % 60000); var clockMinutes = ((clockTimeLeft - clockSeconds - clockMS) % 3600000); var clockHours = (clockTimeLeft - clockMinutes - clockSeconds - clockMS); clockSeconds = clockSeconds / 1000; clockMinutes = clockMinutes / 60000; clockHours = clockHours / 3600000; if (clockHours > 0) { return clockHours + " hour" + (clockHours > 1 ? "s" : "") + " and " + clockMinutes + " minute" + (clockMinutes > 1 ? "s" : "") + " remaining to vote."; } else if (clockMinutes > 0 && clockSeconds === 0) { return clockMinutes + " minute" + (clockMinutes > 1 ? "s" : "") + " remaining on the timer."; } else if (clockMinutes > 0) { return clockMinutes + " minute" + (clockMinutes > 1 ? "s" : "") + " and " + clockSeconds + " second" + (clockSeconds > 1 ? "s" : "") + " remaining on the timer."; } else { return clockSeconds + " second" + (clockSeconds > 1 ? "s" : "") + " remaining on the timer."; } } //********** Chat Notice Functions ************** function sendPublicNotice (message, user, type) { if (message != null) { if (message != "" || message != " " || message != "\u00a0") { setNoticeColor(); switch (type) { case "div": cb.sendNotice(dashLine + "\n\u25ba " + message.capitalize() + "\n" + dashLine, "", "", noticeTextColor, "bold"); break; case "divh": cb.sendNotice(dashLine + "\n\u25ba " + message.capitalize() + "\n" + dashLine, "", noticeBgColor, noticeTextColor, "bold"); break; case "h": cb.sendNotice("\u25ba " + message.capitalize(), "", noticeBgColor, noticeTextColor, "bold"); break; case "": cb.sendNotice("\u25ba " + message.capitalize(), "", "", noticeTextColor, "bold"); break; } } else { cb.sendNotice("You can't send a blank message.\nType a message and try again.", user, "#fee"); } } else { cb.sendNotice("You can't send a blank message.\nType a message and try again.", user, "#fee"); } } //********** PM Functions ************** var TMgreenB = "#d2f8d2"; /* Background Highlighting used for tm */ var TMgreenF = "#007e00"; /* Text Color used for tm */ var BCpurpleB = "#f3e0f1"; /* Background Highlighting used for bc */ var BCpurpleF = "#752d6e"; /* Text Color used for bc */ var TBMblueB = "#dff1f3"; /* Background Highlighting used for tbm */ var TBMblueF = "#1a1aff"; /* Text Color used for tbm */ var PMaquaB = "#f2ebd4"; /* Background Highlighting used for pm */ var PMaquaF = "#008181"; /* Text Color used for pm */ function sendPrivateNotice (message, user, type, dest) { if (message != null) { if (message != '' || message != ' ' || message != '\u00a0') { switch (type) { case 'tm': if (user == cb.room_slug) { cb.sendNotice('\u261b You to mods: ' + message, cb.room_slug, TMgreenB, TMgreenF, "bold"); cb.sendNotice('\u261b ' + cb.room_slug + ' to mods: ' + message, "", TMgreenB, TMgreenF, "bold", "red"); } else { cb.sendNotice('\u261b ' + user + ' to mods: ' + message, "", TMgreenB, TMgreenF, "bold", "red"); } break; case 'bc': cb.sendNotice('\u261b ' + user + ' to you: ' + message, cb.room_slug, BCpurpleB, BCpurpleF, "bold"); cb.sendNotice('\u261b ' + 'You to ' + cb.room_slug + ': ' + message, user, BCpurpleB, BCpurpleF, "bold"); break; case 'tbm': if (user == cb.room_slug) { cb.sendNotice('\u261b You to mods: ' + message, cb.room_slug, TBMblueB, TBMblueF, "bold"); cb.sendNotice('\u261b ' + cb.room_slug + ' to mods: ' + message, "", TBMblueB, TBMblueF, "bold", "red"); } else { cb.sendNotice('\u261b ' + user + ' to ' + cb.room_slug + ' and mods: ' + message, "", TBMblueB, TBMblueF, "bold", "red"); cb.sendNotice('\u261b ' + user + ' to you and mods: ' + message, cb.room_slug, TBMblueB, TBMblueF, "bold"); } break; case 'pm': if (dest != null && (dest != "" || dest != " " || dest != "\u00a0")) { cb.sendNotice('\u261b ' + user + ': ' + message, dest, PMaquaB, PMaquaF, "bold"); cb.sendNotice('\u261b ' + 'You to ' + dest + ': ' + message, user, PMaquaB, PMaquaF, "bold"); pmArray[findPM(dest)][1] = user; } else { cb.sendNotice("You didn't specify who should receive the message.\nPlease enter a username and try again."); } break; } } else { cb.sendNotice("You can't send a blank message.\nType a message and try again.", user, green); } } else { cb.sendNotice("You can't send a blank message.\nType a message and try again.", user, green); } } function findPM(user) { for(var i = 0; i < pmArray.length; i++) { if(pmArray[i][0] == user) { break; } } if(i == pmArray.length) { pmArray[numPMs] = new Array; pmArray[numPMs][0] = user; pmArray[numPMs][1] = ''; numPMs++; findPM(user); } return i; } function sendReply(message, from) { if(pmArray[findPM(from)][1] != '') { var fullmsg = from + ': '; var msg = ''; for(var i = 1; i < message.length; i++) { if(i == 1) { msg += message[i]; fullmsg += message[i]; } else { msg += ' ' + message[i]; fullmsg += ' ' + message[i]; } } replyTo = pmArray[findPM(from)][1] pmArray[findPM(replyTo)][1] = from; cb.sendNotice('\u261b ' + fullmsg, replyTo, PMredB, PMredF, "bold"); cb.sendNotice('\u261b You to ' + replyTo + ': ' + msg, from, PMredB, PMredF, "bold"); } else { cb.sendNotice("No one has PM'd you.", from, green); } } //********** Notifier Functions ************** function showNotifier() { cb.setTimeout(notifierTimer,cb.settings.notifierInterval*60000); } function setNoticeColor() { if (cb.settings.notifiersTextColor == "Custom") { noticeTextColor = checkTextColor(cb.settings.notifiersTextCustColor); if (noticeTextColor == "default") { cb.sendNotice("Notifiers - Error while setting the text color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); noticeTextColor = "#FFFFFF"; } } else { noticeTextColor = checkTextColor(cb.settings.notifiersTextColor); } if (cb.settings.notifiersBgColor == "Custom") { noticeBgColor = checkBgColor(cb.settings.notifiersBgCustColor); if (noticeBgColor == "default") { cb.sendNotice("Notifiers - Error while setting the background color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); noticeBgColor = "#FFFFFF"; } } else { noticeBgColor = checkBgColor(cb.settings.notifiersBgColor); } } function notifierTimer() { if(notifierToggle == 1) { setNoticeColor(); rotcnt++; if (rotcnt > 5) { rotcnt = 1; } switch (rotcnt) { case (1): { if(notifierMessage1 == '' || notifierMessage1 == null || rotcnt > 5) { rotcnt = 0; } else { cb.sendNotice("\u25ba " + notifierMessage1, '', noticeBgColor, noticeTextColor, "bold"); } } break; case (2): { if(notifierMessage2 == '' || notifierMessage2 == null || rotcnt > 5) { rotcnt = 0; } else { cb.sendNotice("\u25ba " + notifierMessage2, '', noticeBgColor, noticeTextColor, "bold"); } } break; case (3): { if(notifierMessage3 == '' || notifierMessage3 == null || rotcnt > 5) { rotcnt = 0; } else { cb.sendNotice("\u25ba " + notifierMessage3, '', noticeBgColor, noticeTextColor, "bold"); } } break; case (4): { if(notifierMessage4 == '' || notifierMessage4 == null || rotcnt > 5) { rotcnt = 0; } else { cb.sendNotice("\u25ba " + notifierMessage4, '', noticeBgColor, noticeTextColor, "bold"); } } break; case (5): { if(notifierMessage5 == '' || notifierMessage5 == null || rotcnt > 5) { rotcnt = 0; } else { cb.sendNotice("\u25ba " + notifierMessage5, '', noticeBgColor, noticeTextColor, "bold"); } } break; } showNotifier(); } } function setNotifierToggle(option, mod) { if(option == 'on') { if(notifierToggle == 1) { cb.sendNotice('The Notifier toggle is already turned on.',mod,green); } else { notifierToggle = 1; rotcnt = 0; notifierTimer(); cb.sendNotice('You have turned on the Notifier toggle.',mod,green); } } else if(option == 'off') { if(notifierToggle == 0) { cb.sendNotice('The Notifier toggle is already turned off.',mod,green); } else { notifierToggle = 0; cb.sendNotice('You have turned off the Notifier toggle.',mod,green); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /usenotifier.\nType /fbhelp notifier to see how to use /usenotifier.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /usenotifier.\nType /fbhelp notifier to see how to use /usenotifier.',mod,green); } } function setTipCountToggle(option, mod) { if(option == 'on') { if(tipCountToggle == 1) { cb.sendNotice('The Tip Count display is already turned on.',mod,green); } else { tipCountToggle = 1; cb.sendNotice('You have turned on the Tip Count display.',mod,green); } } else if(option == 'off') { if(tipCountToggle == 0) { cb.sendNotice('The Tip Count display is already turned off.',mod,green); } else { tipCountToggle = 0; cb.sendNotice('You have turned off the Tip Count display.',mod,green); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /usetipcount.\nType /fbhelp usetipcount to see how to use /usetipcount.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /usetipcount.\nType /fbhelp usetipcount to see how to use /usetipcount.',mod,green); } } // *************************** Tip Menu Functions ************************ function setTipMenuToggle(option, mod) { if(option == 'on') { if(tipMenuToggle == 1) { cb.sendNotice('The Tip Menu is already turned on.',mod,green); } else { tipMenuToggle = 1; initMenu(); cb.sendNotice('You have turned on the Tip Menu.',mod,green); cb.sendNotice(' ' + mod + ' has enabled the Tip Menu. You control the action by tipping for selections from the menu!',"",green,"","bold"); } } else if(option == 'off') { if(tipMenuToggle == 0) { cb.sendNotice('The Tip Menu is already turned off.',mod,green); } else { tipMenuToggle = 0; TIPMENU.tipMenuPrice = []; TIPMENU.tipMenuItem = []; cb.sendNotice('You have turned off the Tip Menu.',mod,green); cb.sendNotice(' ' + mod + ' has disabled the Tip Menu. You can no longer tip for selections from the menu.',"",green,"","bold"); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /usemenu.\nType /fbhelp tipmenu to see how to use /usemenu.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /usemenu.\nType /fbhelp tipmenu to see how to use /usemenu.',mod,green); } } function initMenu() { if (cb.settings.menutxtcolor1 == "Custom") { TIPMENU.txtColor1 = checkTextColor(cb.settings.menuCustTxtColor1); if (TIPMENU.txtColor1 == "default") { cb.sendNotice("Tip Menu - Error while setting the text color, it has to be in a HEX format, such as #0629AC. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); TIPMENU.txtColor1 = '#0629AC'; } } else { TIPMENU.txtColor1 = checkTextColor(cb.settings.menutxtcolor1); } if (cb.settings.menubgcolor1 == "Custom") { TIPMENU.bgColor1 = checkBgColor(cb.settings.menuCustBgColor1); if (TIPMENU.bgColor1 == 'default') { cb.sendNotice("Tip Menu - Error while setting the background color. It has to be in a HEX format, such as #FFFFFF. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); TIPMENU.bgColor1 = '#FFFFFF'; } } else { TIPMENU.bgColor1 = checkBgColor(cb.settings.menubgcolor1); } if (cb.settings.listSplit == 'Split the list in 2') { if (cb.settings.menutxtcolor2 === "Custom") { TIPMENU.txtColor2 = checkTextColor(cb.settings.menuCustTxtColor2); if (TIPMENU.txtColor2 == "default") { cb.sendNotice("Tip Menu part 2 - Error while setting the text color for second half of menu, it has to be in a HEX format, such as #0629AC. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); TIPMENU.txtColor2 = '#0629AC'; } } else { TIPMENU.txtColor2 = checkTextColor(cb.settings.menutxtcolor2); } if (cb.settings.menubgcolor2 == "Custom") { TIPMENU.bgColor2 = checkBgColor(cb.settings.menuCustBgColor2); if (TIPMENU.bgColor2 == 'default') { cb.sendNotice("Tip Menu part 2 - Error while setting the background color for second half of menu, it has to be in a HEX format, such as #FFFFFF. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); TIPMENU.bgColor2 = '#FFFFFF'; } } else { TIPMENU.bgColor2 = checkBgColor(cb.settings.menubgcolor2); } } displayMenuTimer(); setSepChar(); let maxItems = 30; for (let j = 0; j <= maxItems; j++) { if (cb.settings['menuitem' + j] !== '' && cb.settings['menuitemprice' + j] > 0) { if (cbjs.arrayContains(TIPMENU.tipMenuPrice, cb.settings['menuitemprice' + j])) { cb.sendNotice("Tip Menu - " + cb.settings['menuitemprice' + j] + " is already on the menu. It is recommended to have different price for each item.", cb.room_slug, "#FFFFFF", "#FF0000"); } TIPMENU.tipMenuPrice.push(cb.settings['menuitemprice' + j]); TIPMENU.tipMenuItem.push(cb.settings['menuitem' + j]); } } menuSanitize(); displayMenu(); } function displayMenu() { if(tipMenuToggle == 1) { if (cb.settings.chatNotice === 'Only display the short notice' && !TIPMENU.initToken) { cb.sendNotice('Tip menu is active. To see the full tip menu type: /tipmenu', '', TIPMENU.bgColor1, TIPMENU.txtColor1, "bold"); } else if (TIPMENU.menuPart1 !== 'Tip Menu Part 1: \n' && !TIPMENU.initToken) { if (TIPMENU.menuToken === 1) { cb.sendNotice(TIPMENU.menuPart1, '', TIPMENU.bgColor1, TIPMENU.txtColor1, "bold"); TIPMENU.menuToken = 2; } else if (TIPMENU.menuToken === 2) { cb.sendNotice(TIPMENU.menuPart2, '', TIPMENU.bgColor2, TIPMENU.txtColor2, "bold"); TIPMENU.menuToken = 1; } } else if (TIPMENU.tipMenu !== 'Tip Menu: ') { cb.sendNotice(TIPMENU.tipMenu, '', TIPMENU.bgColor1, TIPMENU.txtColor1, "bold"); if (TIPMENU.initToken) { TIPMENU.initToken = false; } } else { cb.sendNotice("Something went wrong with the menu.", '', "#FFFFFF", "#FF0000", "bold"); } cb.setTimeout(displayMenu, TIPMENU.menuDspIntTime); } } function displayMenuTimer() { let timer = parseFloat(cb.settings.menuDspInt); if (timer < 1) { cb.sendNotice("Tip Menu - Time lapse is to short. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); timer = 3; } timer *= 60000; timer = parseInt(timer); TIPMENU.menuDspIntTime = timer; } function menuSanitize() { TIPMENU.tipMenu = 'Tip Menu: '; TIPMENU.menuPart1 = 'Tip Menu Part 1: \n'; TIPMENU.menuPart2 = 'Tip Menu Part 2: \n'; let menuArray = []; let menuArray1 = []; let menuArray2 = []; let sorted = []; let menuL = TIPMENU.tipMenuPrice.length; for (let i = 0; i < menuL; i++) { sorted.push({ "prices": TIPMENU.tipMenuPrice[i], "id": i }); } if (cb.settings.listSort !== 'Do not sort the list') { sorted.sort(function(a, b) { return a.prices - b.prices; }); if (cb.settings.listSort === 'Descending') { sorted.reverse(); } } for (let j = 0; j < sorted.length; j++) { if (TIPMENU.tipMenuPrice[sorted[j].id] !== 0) { menuArray.push(TIPMENU.tipMenuItem[sorted[j].id] + ' (' + TIPMENU.tipMenuPrice[sorted[j].id] + ') '); } } TIPMENU.tipMenu += menuArray.join(TIPMENU.sepChar); if (cb.settings.listSplit === 'Split the list in 2') { if (menuArray.length < 8) { cb.sendNotice("Tip Menu - Error - The menu has less than 8 items, it will not be split.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); } else { let msglength1 = 0; let msgHalf = (TIPMENU.tipMenu.length - 9) / 2; for (let k = 0; k < sorted.length; k++) { if (TIPMENU.tipMenuPrice[sorted[k].id] !== 0) { if (msglength1 < msgHalf) { menuArray1.push(TIPMENU.tipMenuItem[sorted[k].id] + ' (' + TIPMENU.tipMenuPrice[sorted[k].id] + ') '); msglength1 = menuArray1.join(TIPMENU.sepChar).length; } else { menuArray2.push(TIPMENU.tipMenuItem[sorted[k].id] + ' (' + TIPMENU.tipMenuPrice[sorted[k].id] + ') '); } } } TIPMENU.menuPart1 += menuArray1.join(TIPMENU.sepChar) + '\n To see the full menu type /tipmenu.'; TIPMENU.menuPart2 += menuArray2.join(TIPMENU.sepChar) + '\n To see the full menu type /tipmenu.'; } } TIPMENU.menuLength = TIPMENU.tipMenuPrice.length; if (TIPMENU.tipMenu === 'Tip Menu: ') { cb.sendNotice('Error - No menu items found', '', '', TIPMENU.txtColor1, "bold"); } } function setSepChar() { switch (cb.settings.sepchar) { case "Custom": { if (cb.settings.sepcharcustom) { TIPMENU.sepChar = cb.settings.sepcharcustom; } else { TIPMENU.sepChar = "|"; } } break; case "Hearts": { TIPMENU.sepChar = ':heart2'; } break; case "Glitter": { TIPMENU.sepChar = ':pixelglitter'; } break; case "Flowers": { TIPMENU.sepChar = ':tinyflower2'; } break; case "Bow": { TIPMENU.sepChar = ':bluebow'; } break; case "Hearts2": { TIPMENU.sepChar = ':Hearts2'; } break; case "Smiley": { TIPMENU.sepChar = ':smile'; } break; case "Text Heart": { TIPMENU.sepChar = '\u2665'; } break; case "Text Diamond": { TIPMENU.sepChar = '\u2666'; } break; case "Text Star": { TIPMENU.sepChar = '\u2605'; } break; default: TIPMENU.sepChar = "|"; } TIPMENU.sepChar += " "; } // *************************** Positions Tip Menu Functions ************************ function setPosTipMenuToggle(option, mod) { if(option == 'on') { if(posTipMenuToggle == 1) { cb.sendNotice('The Positions Tip Menu is already enabled.',mod,green); } else { posTipMenuToggle = 1; cb.sendNotice('You have enabled the Positions Tip Menu.',mod,green); cb.sendNotice(' ' + mod + ' has enabled the Positions Tip Menu. You control the action by tipping for your favorite position!',"",green,"","bold"); initPosMenu(); } } else if(option == 'off') { if(posTipMenuToggle == 0) { cb.sendNotice('The Positions Tip Menu is already disabled.',mod,green); } else { posTipMenuToggle = 0; POSTIPMENU.posTipMenuPrice = []; POSTIPMENU.posTipMenuItem = []; cb.sendNotice('You have disabled the Positions Tip Menu.',mod,green); cb.sendNotice(' ' + mod + ' has disabled the Positions Tip Menu. You can no longer tip for positions.',"",green,"","bold"); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /useposmenu.\nType /fbhelp positions to see how to use /usepostipmenu.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /useposmenu.\nType /fbhelp positions to see how to use /usepostipmenu.',mod,green); } } function initPosMenu() { let maxItems = 30; if (cb.settings.posMenuTxtColor === "Custom") { POSTIPMENU.posTxtColor = checkTextColor(cb.settings.posMenuCustTxtColor); if (POSTIPMENU.posTxtColor === "default") { cb.sendNotice("Positions Menu - Error while setting the text color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); POSTIPMENU.posTxtColor = '#FFFFFF'; } } else { POSTIPMENU.posTxtColor = checkTextColor(cb.settings.posMenuTxtColor); } if (cb.settings.posMenuBgColor === "Custom") { POSTIPMENU.posBgColor = checkBgColor(cb.settings.posMenuCustBgColor); if (POSTIPMENU.posBgColor === 'default') { cb.sendNotice("Positions Menu - Error while setting the background color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); POSTIPMENU.posBgColor = '#0629AC'; } } else { POSTIPMENU.posBgColor = checkBgColor(cb.settings.posMenuBgColor); } displayPosMenuTimer(); setPosSepChar(); for (let j = 0; j <= maxItems; j++) { if (cb.settings['posMenuItem' + j] !== '' && cb.settings['posMenuItemPrice' + j] > 0) { if (cbjs.arrayContains(POSTIPMENU.posTipMenuPrice, cb.settings['posMenuItemPrice' + j])) { cb.sendNotice("Positions Tip Menu - " + cb.settings['posMenuItemPrice' + j] + " is already on the menu. It is recommended to have different price for each item.", cb.room_slug, "#FFFFFF", "#FF0000"); } POSTIPMENU.posTipMenuPrice.push(cb.settings['posMenuItemPrice' + j]); POSTIPMENU.posTipMenuItem.push(cb.settings['posMenuItem' + j]); } } cb.sendNotice('Type /fbhelp tipmenu to see all the Tip menu commands.', "", "", "", "bold"); posMenuSanitize(); displayPosMenu(); } function displayPosMenu() { if(posTipMenuToggle == 1) { if (cb.settings.posChatNotice === 'Only display the short notice' && !POSTIPMENU.posInitToken) { cb.sendNotice('Positions Tip menu is active. To see the full tip menu type: /postipmenu', '', POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor, "bold"); } else if (POSTIPMENU.posTipMenu !== 'Positions Tip Menu: \n' && !POSTIPMENU.posInitToken) { cb.sendNotice(POSTIPMENU.posTipMenu, '', POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor, "bold"); } else if (POSTIPMENU.posTipMenu !== 'Positions Tip Menu: ') { cb.sendNotice(POSTIPMENU.posTipMenu, '', POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor, "bold"); if (POSTIPMENU.posInitToken) { POSTIPMENU.posInitToken = false; } } else { cb.sendNotice("Something went wrong with the positions menu.", '', "#FFFFFF", "#FF0000", "bold"); } cb.setTimeout(displayPosMenu, POSTIPMENU.posMenuDspIntTime); } } function displayPosMenuTimer() { let postimer = parseFloat(cb.settings.posMenuInterval); if (postimer < 1) { cb.sendNotice("Positions Tip Menu - Time interval is less than 1 minute. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); postimer = 3; } postimer *= 60000; postimer = parseInt(postimer); POSTIPMENU.posMenuDspIntTime = postimer; } function posMenuSanitize() { POSTIPMENU.posTipMenu = 'Positions Tip Menu: '; let posMenuArray = []; let posSorted = []; let posMenuL = POSTIPMENU.posTipMenuPrice.length; for (let i = 0; i < posMenuL; i++) { posSorted.push({ "posprices": POSTIPMENU.posTipMenuPrice[i], "posid": i }); } if (cb.settings.posListSort !== 'Do not sort the list') { posSorted.sort(function(a, b) { return a.posprices - b.posprices; }); if (cb.settings.posListSort === 'Descending') { posSorted.reverse(); } } for (let j = 0; j < posSorted.length; j++) { if (POSTIPMENU.posTipMenuPrice[posSorted[j].posid] !== 0) { posMenuArray.push(POSTIPMENU.posTipMenuItem[posSorted[j].posid] + ' (' + POSTIPMENU.posTipMenuPrice[posSorted[j].posid] + ') '); } } POSTIPMENU.posTipMenu += posMenuArray.join(POSTIPMENU.posSepChar); POSTIPMENU.posMenuLength = POSTIPMENU.posTipMenuPrice.length; if (POSTIPMENU.posTipMenu === 'Positions Tip Menu: ') { cb.sendNotice('Error - No positions menu items found', '', '', POSTIPMENU.posTxtColor, "bold"); } } function setPosSepChar() { switch (cb.settings.posSepChar) { case "Custom": { if (cb.settings.posSepCharCustom) { POSTIPMENU.posSepChar = cb.settings.posSepCharCustom; } else { POSTIPMENU.posSepChar = "|"; } } break; case "Hearts": { POSTIPMENU.posSepChar = ':heart2'; } break; case "Glitter": { POSTIPMENU.posSepChar = ':pixelglitter'; } break; case "Flowers": { POSTIPMENU.posSepChar = ':tinyflower2'; } break; case "Bow": { POSTIPMENU.posSepChar = ':bluebow'; } break; case "Hearts2": { POSTIPMENU.posSepChar = ':Hearts2'; } break; case "Smiley": { POSTIPMENU.posSepChar = ':smile'; } break; case "Text Heart": { POSTIPMENU.posSepChar = '\u2665'; } break; case "Text Diamond": { POSTIPMENU.posSepChar = '\u2666'; } break; case "Text Star": { POSTIPMENU.posSepChar = '\u2605'; } break; default: POSTIPMENU.posSepChar = "|"; } POSTIPMENU.posSepChar += " "; } // *************************** Lush Menu Functions ************************ function setLushMenuToggle(option, mod) { if(option == 'on') { if(lushMenuToggle == 1) { cb.sendNotice('The Lush Menu is already enabled.',mod,green); } else { lushMenuToggle = 1; cb.sendNotice('You have enabled the Lush Menu.',mod,green); cb.sendNotice(' ' + mod + ' has enabled the Lush Menu. Use the tip ranges on the menu to make the lush vibrate!',"",green,"","bold"); initLushMenu(); } } else if(option == 'off') { if(lushMenuToggle == 0) { cb.sendNotice('The Lush Menu is already disabled.',mod,green); } else { lushMenuToggle = 0; LUSHMENU.lushMenuLevel = []; // cb.cancelTimeout(displayLushMenu); cb.sendNotice('You have disabled the Lush Menu.',mod,green); cb.sendNotice(' ' + mod + ' has disabled the Lush Menu.',"",green,"","bold"); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /uselushmenu.\nType /fbhelp tipmenu to see how to use /uselushmenu.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /uselushmenu.\nType /fbhelp tipmenu to see how to use /uselushmenu.',mod,green); } } function initLushMenu() { if (cb.settings.lushMenuTxtColor === "Custom") { LUSHMENU.lushTxtColor = checkTextColor(cb.settings.lushMenuCustTxtColor); if (LUSHMENU.lushTxtColor === "default") { cb.sendNotice("Lush Menu - Error while setting the text color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); LUSHMENU.lushTxtColor = '#FFFFFF'; } } else { LUSHMENU.lushTxtColor = checkTextColor(cb.settings.lushMenuTxtColor); } if (cb.settings.lushMenuBgColor === "Custom") { LUSHMENU.lushBgColor = checkBgColor(cb.settings.lushMenuCustBgColor); if (LUSHMENU.lushBgColor === 'default') { cb.sendNotice("Lush Menu - Error while setting the background color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); LUSHMENU.lushBgColor = '#0629AC'; } } else { LUSHMENU.lushBgColor = checkBgColor(cb.settings.lushMenuBgColor); } displayLushMenuTimer(); for (let j = 0; j <= 13; j++) { if (cb.settings['lushMenuLevel' + j] !== '') { LUSHMENU.lushMenuLevel.push(cb.settings['lushMenuLevel' + j]); } } cb.sendNotice('Type /fbhelp lush to see all the Lush menu commands.', "", "", "", "bold"); LUSHMENU.lushMenu = ':lushsm \u2665 :lushsm \u2665 :lushsm LUSH MENU :lushsm \u2665 :lushsm \u2665 :lushsm '; LUSHMENU.lushMenu += LUSHMENU.lushMenuLevel.join('\n'); displayLushMenu(); } function displayLushMenu() { if(lushMenuToggle == 1) { if (cb.settings.lushChatNotice === 'Only display the short notice') { cb.sendNotice('Lush menu is active. To see the full menu type: /lushmenu', '', LUSHMENU.lushBgColor, LUSHMENU.lushTxtColor, "bold"); } else { cb.sendNotice(LUSHMENU.lushMenu, '', LUSHMENU.lushBgColor, LUSHMENU.lushTxtColor, "bold"); } cb.setTimeout(displayLushMenu, LUSHMENU.lushMenuDspIntTime); } } function displayLushMenuTimer() { let lushtimer = parseFloat(cb.settings.lushMenuInterval); if (lushtimer < 1) { cb.sendNotice("Lush Menu - Time interval is less than 1 minute. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); lushtimer = 3; } lushtimer *= 60000; lushtimer = parseInt(lushtimer); LUSHMENU.lushMenuDspIntTime = lushtimer; } // *************************** Token Poll Functions ************************ function setTokenPollToggle(option, mod) { setPollColors(); if(option == 'on') { if(tokenPollToggle == 1) { cb.sendNotice('The Token Poll is already enabled.', mod, green); } else { tokenPollToggle = 1; initTokenPoll(); cb.sendNotice('You have enabled the Token Poll.', mod, green); pollmsg("a", "", mod + " has enabled the Token Poll feature. You can now vote in the poll."); } } else if(option == 'off') { if(tokenPollToggle == 0) { cb.sendNotice('The Token Poll is already disabled.', mod, green); } else { tokenPollToggle = 0; pollArrayAmount = []; pollArrayLabel = []; pollArrayVotes = []; cb.sendNotice('You have disabled the Token Poll.', mod, green); pollmsg("a", "", mod + " has disabled the Token Poll feature. Voting will no longer be tracked."); pollRunning = false; } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /usepoll.\nType /fbhelp tokenpoll to see how to use /usepoll.', mod, green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /usepoll.\nType /fbhelp tokenpoll to see how to use /usepoll.', mod, green); } } function initTokenPoll() { switch (cb.settings.pollMode) { case "Ends by Mod/Broadcaster command": pollType = "Never"; break; case "Ends after X minutes": pollType = "Timer"; break; case "Ends after X votes": pollType = "Vote"; break; case "Ends when one option reaches x votes": pollType = "Goal"; break; default: cb.sendNotice("Error in determining the poll type", "", pollbackground, pollforeground); } setPollColors(); pollRunning = true; buildPollBoard(); showBoard(); initPollTimer(); cb.setTimeout(displayPoll, 30000); } function setPollColors() { if (cb.settings.pollTxtColor === "Custom") { pollforeground = checkTextColor(cb.settings.pollCustTxtColor); if (pollforeground === "default") { cb.sendNotice("Token Poll - Error while setting the font color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); pollforeground = '#FFFFFF'; } } else { pollforeground = checkTextColor(cb.settings.pollTxtColor); } if (cb.settings.pollBgColor === "Custom") { pollbackground = checkBgColor(cb.settings.pollCustBgColor); if (pollbackground === 'default') { cb.sendNotice("Token Poll - Error while setting the background color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); pollbackground = '#0629AC'; } } else { pollbackground = checkBgColor(cb.settings.pollBgColor); } } function buildPollBoard() { for (let i = 1; i <= 8; i++) { var oktoadd = 1; if(this["pollOptTokens"+i] != '' && this["pollOptTokens"+i] != null) { if(this["pollOptLabel"+i] != '' && this["pollOptLabel"+i] != null) { for (let j = 0; j < i-1; j++) { if (pollArrayAmount[j] === this["pollOptTokens"+i]) { pollmsg("bm", "", "Tip Price Amount for option " + i + " is not unique, it is not added to the board."); oktoadd = 0; break; } else if (pollArrayLabel[j] === this["pollOptLabel"+i]) { pollmsg("bm", "", "Label for option " + i + " is not unique, it is not added to the board."); oktoadd = 0; break; } } if(oktoadd == 1) { populatePollArray(this["pollOptLabel"+i],this["pollOptTokens"+i],0); } } else { pollmsg("bm", "", "Label for option " + i + " is blank or null, not added to board."); } } } } function populatePollArray(label, amount, votes) { if (!cbjs.arrayContains(pollArrayAmount, amount) && !cbjs.arrayContains(pollArrayLabel, label)) { var pollindex = pollArrayAmount.length; pollArrayLabel[pollindex] = label; pollArrayAmount[pollindex] = amount; pollArrayVotes[pollindex] = votes; } else { pollmsg("bm", "", "Tip Price Amount or Label for option " + label + " is not unique, it is not added to the board."); return; } } function showBoard(u) { if(tokenPollToggle == 1) { let pollresponse1 = "\u26A1 \u26A1 \u26A1 \u26A1 Token Poll board \u26A1 \u26A1 \u26A1 \u26A1" + ("" === u ? " (sent to all)" : "") + "\n"; let pollresponse2 = "\u25c7 \u25c7 \u25c7 \u25c7 \u25c7 \u25c7 " + cb.settings.pollTitle + " \u25c7 \u25c7 \u25c7 \u25c7 \u25c7 \u25c7"; let ids = []; for (let i = 0; i < pollArrayAmount.length; i++) { ids.push({ "votes": pollArrayVotes[i], "id": i }); } ids.sort(function(a, b) { return b.votes - a.votes; }); for (let j = 0; j < ids.length; j++) { if (0 != pollArrayAmount[ids[j].id]) { pollresponse2 += "\n \u23E9 " + pollArrayLabel[ids[j].id] + " (Price = " + pollArrayAmount[ids[j].id] + " tokens): " + pollArrayVotes[ids[j].id] + " vote" + (pollArrayVotes[ids[j].id] != 1 ? "s" : ""); } } let pollresponse3 = ""; switch (pollType) { case "Timer": break; case "Vote": pollresponse3 = votesRemain + " vote" + (votesRemain > 1 ? "s" : "") + " remaining before poll closes\n"; break; case "Goal": pollresponse3 = "First option to " + cb.settings.pollCount + " votes wins!\n"; break; } pollresponse3 += "Simply tip the shown token amounts to register your vote. Type /poll at any time to see the poll board."; if (u === undefined && pollRunning) { u = ""; cb.setTimeout(showBoard, cb.settings.pollInterval * 60000); } cb.sendNotice(pollresponse1 + pollresponse2, u, pollbackground, pollforeground, "bold"); cb.sendNotice(pollresponse3, u, "", pollforeground); } } function showWinner(u) { let options = []; for (let i = 0; i < pollArrayAmount.length; i++) { options[i] = i; } options.sort(function(a, b) { return pollArrayVotes[b] - pollArrayVotes[a]; }); let win_count = 1; for (let j = 1; j < pollArrayAmount.length; j++) { if (pollArrayVotes[options[j]] != pollArrayVotes[options[0]]) { break; } if (0 != pollArrayAmount[options[j]]) { win_count++; } } let pollresponse1 = '\u23f0 \u23f0 \u23f0 Token Poll has ended! \u23f0 \u23f0 \u23f0 \n'; let pollresponse2 = 'Winner' + (win_count > 1 ? 's (' + win_count + '-way tie)' : '') + ':'; for (let k = 0; k < win_count; k++) { if (pollArrayAmount[options[k]] != 0) { pollresponse2 += "\n \u23E9 " + pollArrayLabel[options[k]] + ": " + pollArrayVotes[options[k]] + " votes"; } } cb.sendNotice(pollresponse1 + pollresponse2, u, pollbackground, pollforeground, "bold"); } function showLead() { let options = []; let leadOpt = []; for (let i = 0; i < pollArrayAmount.length; i++) { options[i] = i; } options.sort(function(a, b) { return pollArrayVotes[b] - pollArrayVotes[a]; }); if (pollArrayVotes[options[0] ] > 0 ){ leadOpt.push(pollArrayLabel[options[0]]); for (let j = 1; j < pollArrayAmount.length; j++) { if (pollArrayVotes[options[j]] != pollArrayVotes[options[0]]) { break; } if (0 != pollArrayAmount[options[j]]) { leadOpt.push(pollArrayLabel[options[j]]); } } } let pollresponse1; let leadCount = leadOpt.length; if (leadCount === 0){ pollresponse1 = "No votes yet, be sure to vote for your favorite! Type /poll at any time to see all the options."; } else if (leadCount === 1) { pollresponse1 = pollArrayLabel[options[0]] + " is in the lead by " + (pollArrayVotes[options[0]] - pollArrayVotes[options[1]]) + " vote" + ((pollArrayVotes[options[0]] - pollArrayVotes[options[1]]) === 1 ? "" : "s") + "."; } else{ pollresponse1 = "We have a " + leadCount + "-way tie between " + formatArray(leadOpt,"and") + "."; } return pollresponse1; } function formatArray(arr,andor){ let outStr = ""; if (arr.length === 1) { outStr = arr[0]; } else if (arr.length === 2) { outStr = arr.join(' '+andor+' '); } else if (arr.length > 2) { outStr = arr.slice(0, -1).join(', ') + ', '+andor+' ' + arr.slice(-1); } return outStr; } function checkPollEnd() { switch (pollType) { case "Never": return; case "Timer": if (pollSecsRemain < 1) { pollRunning = false; } break; case "Vote": if (votesRemain < 1) { pollRunning = false; } break; case "Goal": for (let i = 0; i < pollArrayAmount.length; i++) { if (pollArrayVotes[i] >= cb.settings.pollCount) { pollRunning = false; } } break; } if (tokenPollToggle == 1 && !pollRunning) { showWinner(""); } } function timeCal() { pollStartTime = new Date(); return pollStopTime - pollStartTime.getTime(); } function pollTimeLeft() { var pollTimeLeft = timeCal(); var milliseconds = pollTimeLeft % 1000; var seconds = ((pollTimeLeft - milliseconds) % 60000); var minutes = ((pollTimeLeft - seconds - milliseconds) % 3600000); var hours = (pollTimeLeft - minutes - seconds - milliseconds); seconds = seconds / 1000; minutes = minutes / 60000; hours = hours / 3600000; if (hours > 0) { return hours + " hour" + (hours > 1 ? "s" : "") + " and " + minutes + " minute" + (minutes > 1 ? "s" : "") + " remaining to vote."; } else if (minutes > 0 && seconds === 0) { return minutes + " minute" + (minutes > 1 ? "s" : "") + " remaining to vote!"; } else if (minutes > 0) { return minutes + " minute" + (minutes > 1 ? "s" : "") + " and " + seconds + " second" + (seconds > 1 ? "s" : "") + " remaining to vote!"; } else { return seconds + " second" + (seconds > 1 ? "s" : "") + " remaining to vote!!!"; } } function initPollTimer() { if (!pollRunning || pollType !== "Timer") { return; } else { pollStartTime = new Date(); pollStopTime = new Date(pollStartTime.getTime() + cb.settings.pollCount * 60000); pollTimerMin(); } } function pollAddTime(timetoadd, u) { pollStopTime = new Date(pollStopTime.getTime() + timetoadd * 60000); pollmsg("bm", u, u + " has added " + timetoadd + " minute" + (timetoadd === 1 || timetoadd === -1 ? "" : "s") + " to the token poll timer."); pollmsg("a", u, timetoadd + " minute" + (timetoadd === 1 || timetoadd === -1 ? "" : "s") + " have been added to the token poll timer. " + pollTimeLeft()); pollMinsRemain = pollMinsRemain + timetoadd; return; } function pollSwitchToTimer(timetoadd, u) { pollType = "Timer"; pollStartTime = new Date(); pollStopTime = new Date(pollStartTime.getTime() + timetoadd * 60000); pollmsg("bm", u, u + " set a token poll timer for " + timetoadd + " minute" + (timetoadd === 1 || timetoadd === -1 ? "" : "s")); cb.sendNotice("A token poll timer has been set for " + timetoadd + " minute" + (timetoadd === 1 || timetoadd === -1 ? "" : "s"), "", pollbackground, pollforeground, "bold"); pollMinsRemain = timetoadd; pollTimerMin(); return; } function pollTimerMin() { if(!pollSkipMin) { if (!pollRunning || pollType !== "Timer") { return; } switch (pollMinsRemain) { case 15: case 10: case 9: case 8: case 7: case 6: case 5: case 4: case 3: case 2: cb.sendNotice("\u231A \u231A \u231A " + pollMinsRemain + " minutes remaining to vote!!! \u231A \u231A \u231A", "", pollbackground, pollforeground, "bold"); } pollMinsRemain--; if (pollMinsRemain > 0) { cb.setTimeout(pollTimerMin, 60000); } else { pollSecsRemain = 60; cb.sendNotice("\u231A \u231A \u231A 1 minute remaining to vote!!! \u231A \u231A \u231A", "", pollbackground, pollforeground, "bold"); pollTimerSec(); } // return; } else { pollSkipMin = false; } } function pollTimerSec() { if(!pollSkipSec) { if (!pollRunning || pollType !== "Timer") { return; } if (pollMinsRemain > 0) { cb.setTimeout(pollTimerMin, pollSecsRemain*1000); } else { pollSecsRemain--; checkPollEnd(); switch (pollSecsRemain) { case 45: case 30: case 15: case 5: case 4: case 3: case 2: case 1: cb.sendNotice("\u231A \u231A \u231A " + pollSecsRemain + " second" + (pollSecsRemain > 1 ? "s" : "") + " remaining to vote!!! \u231A \u231A \u231A", "", pollbackground, pollforeground, "bold"); } if (pollSecsRemain > 0) { cb.setTimeout(pollTimerSec, 1000); } } // return; } else { pollSkipSec = false; } } function pollStopTimer() { pollStopTime = new Date(); if (pollMinsRemain > 0 || pollSecsRemain > 0) { pollMinsRemain = 0; pollSecsRemain = 0; pollSkipMin = true; pollSkipSec = true; } } function aliveWarning() { if (!pollRunning || pollType !== "Timer") { return; } pollmsg("b", "", 'You enable to keep the poll alive if users are still voting. \n The poll might be kept alive indefinitely unless /endpoll is used'); pollmsg("m", "", 'The broadcaster has configured the poll to stay alive if users are still voting. \n The poll might be kept alive indefinitely, unless /endpoll is used'); if (pollMinsRemain < 2 && pollRunning) { cb.setTimeout(aliveWarning, 60000); } aliveWarned = true; } function displayPoll() { if (tokenPollToggle == 1) { if (!pollRunning) { } else { let pollNotice = ["a poll is currently running, type '/poll' to see the current votes and the amounts to tip for each choice."]; if (fanDouble) { pollNotice.push("Fan club members currently get two votes for the price of one!"); } pollNotice.push(showLead()); pollmsg("", "", pollNotice[nline]); nline += 1; if (nline >= pollNotice.length) { nline = 0; } } cb.setTimeout(displayPoll, 90000); } } function pollmsg(to, u, m) { switch (to) { case "b": cb.sendNotice("Token Poll to Broadcaster - " + m, cb.room_slug, pollwarnDark, pollwarnLight, "bold"); break; case "m": cb.sendNotice("Token Poll to mods - " + m, "", pollbackground, pollforeground, "bold", "red"); break; case "bm": cb.sendNotice("Token Poll to Broadcaster - " + m, cb.room_slug, pollwarnDark, pollwarnLight, "bold"); cb.sendNotice("Token Poll to mods - " + m, "", pollbackground, pollforeground, "bold", "red"); break; case "a": // cb.sendNotice("Token Poll to Broadcaster - " + m, cb.room_slug, pollwarnDark, pollwarnLight, "bold"); // cb.sendNotice("Token Poll to mods - " + m, "", pollwarnDark, pollwarnLight, "bold", "red"); cb.sendNotice("Token Poll - " + m, "", pollbackground, pollforeground, "bold"); break; case "nm": cb.sendNotice("Token Poll - This command only works for broadcasters and mods", u, pollwarnDark, pollwarnLight, "bold"); break; case "w": cb.sendNotice("Token Poll - " + m, u, pollwarnDark, pollwarnLight, "bold"); break; case "s": cb.sendNotice(m, u, "#e6e6e6", "#737373"); break; case "n": cb.sendNotice("Token Poll - " + m, u, pollbackground, pollforeground); break; default: cb.sendNotice("Token Poll - " + m, u, pollbackground, pollforeground, "bold"); break; } } // *********************************** Ticket Show Functions ************************************** function prepticketshow(mod) { // Start the token poll if(cb.settings.prepticketStartPoll == 'Yes' && tokenPollToggle == 0) { setTokenPollToggle("on",mod); } // Swap out the menus if(cb.settings.prepticketTipMenuOff == 'Yes' && tipMenuToggle == 1) { setTipMenuToggle("off",mod); } if(cb.settings.prepticketPosMenuOn == 'Yes' && posTipMenuToggle == 0) { setPosTipMenuToggle("on",mod); } // Turn on the backup ticket list if(cb.settings.prepticketStartTlist == 'Yes' && tlistToggle == 0) { setTlistToggle("on",mod); if (tlistPrice <= 0) { cb.sendNotice('Note the back up list ticket price value is not set, use /tlistprice [amount] to set the initial price (should match the Ticket Show price).', mod, green); } } // Add VIP and Fanclub to ticket show startedAdd = 0; newmessage = ''; if(cb.settings.prepticketAddVIP == 'Yes') { if(cb.settings.enableVIPList == 'Ticket Shows' || cb.settings.enableVIPList == 'PMs and Ticket Shows') { if(VIPListArray.length > 0) { newmessage = '/add ' + cbjs.arrayJoin(VIPListArray, ', '); startedAdd = 1; for (let j = 0; j < VIPListArray.length; j++) { updateTicketBackupList("add", VIPListArray[j]); cb.sendNotice('VIP user ' + VIPListArray[j] + ' added to the backup list.', mod); } } else { cb.sendNotice('No VIP List entries to add.', mod, green); } } else { cb.sendNotice('VIP List not enabled for Ticket Shows.', mod, green); } } if(cb.settings.prepticketAddExtFC == 'Yes') { if(cb.settings.enableExtFans == 'Ticket Shows' || cb.settings.enableExtFans == 'PMs and Ticket Shows') { if(extFanListArray.length > 0) { if(startedAdd == 0) { newmessage = '/add ' + cbjs.arrayJoin(extFanListArray, ', '); } else { newmessage += ', ' + cbjs.arrayJoin(extFanListArray, ', '); } for (let j = 0; j < extFanListArray.length; j++) { updateTicketBackupList("add", extFanListArray[j]); cb.sendNotice('Ext Fan Club user ' + extFanListArray[j] + ' added to the backup list.', mod); } } else { cb.sendNotice('No External Fan Club List entries to add.', mod, green); } } else { cb.sendNotice('External Fan Club List not enabled for Ticket Shows.', mod, green); } } } function addFromLeaderboard(mode, num) { sortTippers(); addLBstring = ''; switch(mode) { case "num": { for (var LBi = 1; LBi <= num; LBi++) { if (tipCountArray.name[LBi - 1] != null && tipCountArray.name[LBi - 1] != "") { if (LBi > 1) { addLBstring += ', '; } addLBstring += tipCountArray.name[LBi - 1]; } else { return(addLBstring); } } break; } case "amt": { for (var LBi = 1; LBi <= 99; LBi++) { if (tipCountArray.name[LBi - 1] != null && tipCountArray.name[LBi - 1] != "" && tipCountArray.amount[LBi - 1] >= num) { if (LBi > 1) { addLBstring += ', '; } addLBstring += tipCountArray.name[LBi - 1]; } else { return(addLBstring); } } break; } } } function updateTicketBackupList(mode,user,amount) { switch(mode) { case "add": { if(!cbjs.arrayContains(tlistArray,user)) { tlistArray.push(user); } break; } case "rmv": { if(cbjs.arrayContains(tlistArray,user)) { cbjs.arrayRemove(tlistArray,user); } break; } case "addtip": { if (amount >= tlistPrice) { if (tlistPrice > 0) { tlistArray.push(user); } else { cb.sendNotice('Warning: Backup list enabled and user not added to backup list. The back up list ticket price value not set, use /tlistprice [amount] to set the initial price (should match the Ticket Show price).', cb.room_slug, green); } } break; } } } function setTlistPrice(amount) { tlistPrice = parseInt(amount); } function setTlistToggle(option, mod) { if(option == 'on') { if(tlistToggle == 1) { cb.sendNotice('The Backup Ticket List is already enabled.',mod,green); } else { tlistToggle = 1; cb.sendNotice('You have enabled the Backup Ticket List.',mod,green); } } else if(option == 'off') { if(tlistToggle == 0) { cb.sendNotice('The Backup Ticket List is already disabled.',mod,green); } else { tlistToggle = 0; cb.sendNotice('You have disabled the Backup Ticket List.',mod,green); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /usetlist.\nType /fbhelp usetipcount to see how to use /usetipcount.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /usetipcount.\nType /fbhelp usetipcount to see how to use /usetipcount.',mod,green); } } // *********************************** Media Display Function ************************************** function setMediaToggle(option, mod) { if(option == 'on') { if(mediaToggle == 1) { cb.sendNotice('The Media List is already enabled.', mod, green); } else { mediaToggle = 1; sendMediaList(); cb.sendNotice('You have enabled the Media List.', mod, green); } } else if(option == 'off') { if(mediaToggle == 0) { cb.sendNotice('The Media List is already disabled.', mod, green); } else { mediaToggle = 0; // cb.cancelTimeout(sendMediaList); cb.sendNotice('You have disabled the Media List.', mod, green); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /usemedia, the option should be "on" or "off".', mod, green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /usemedia, the option should be "on" or "off".', mod, green); } } function setMediaColors() { if (cb.settings.mediaListTxtColor === "Custom") { mediaforeground = checkTextColor(cb.settings.mediaListCustTxtColor); if (mediaforeground === "default") { cb.sendNotice("Media List - Error while setting the font color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); mediaforeground = '#FFFFFF'; } } else { mediaforeground = checkTextColor(cb.settings.mediaListTxtColor); } if (cb.settings.mediaListBgColor === "Custom") { mediabackground = checkBgColor(cb.settings.mediaListCustBgColor); if (mediabackground === 'default') { cb.sendNotice("Media List - Error while setting the background color. It has to be in a HEX format. Using default value.", cb.room_slug, "#FFFFFF", "#FF0000", "bold"); mediabackground = '#0629AC'; } } else { mediabackground = checkBgColor(cb.settings.mediaListBgColor); } } function sendMediaList() { if(firstmedia == 0) { mediaTimer = leaderInt - 20000; firstmedia = 1 } else { mediaTimer = leaderInt; } cb.setTimeout(mediaListTimer, mediaTimer); } function mediaListTimer() { if(mediaToggle == 1) { setMediaColors(); showMedia(""); sendMediaList(); } } function showMedia(sendto) { cb.sendNotice('Media Info : ' + cb.settings.mediaListIntro, sendto, mediabackground, mediaforeground, "bold"); for (let j = 1; j <= 12; j++) { if(this["mediaListItem"+j] != '' && this["mediaListItem"+j] != null) { cb.sendNotice(this["mediaListText"+j] + ' : ' + this["mediaListItem"+j], sendto, mediabackground, mediaforeground); } } } // *********************************** Help Function ************************************** function help(option,from) { var valid = 0; if(option == null){option = '';} switch(option) { case '': { valid = 1; cb.sendNotice('Fembot Help Menu', from, green); cb.sendNotice('Type /fbhelp [X], where [X] is one of the following choices, for more detailed information.\nEx: /fbhelp messaging to see the submenu for messaging related commands.', from); cb.sendNotice('',from,green); cb.sendNotice( 'messaging (/pm, /reply, /bc, /tm, /tbm)' + '\nchatcontrol (/silencelevel, /graphiclevel, /ninja, /unninja, /ninjalist, /silence, /unsilence, /silencelist)' + '\ntipmenu (/tipmenu, /tipmenurequests, /tipmenuadd, /tipmenurmv, /usemenu)' + '\npositions (/posmenu, /posmenurequests, /posmenuadd, /posmenurmv, /useposmenu)' + '\ntimer (/startclock, /addtoclock, /timeleft /stopclock)' + '\nnotices (/cn, /cnh, /cnd, /cndh, /usenotifier, /chgmsg1.../chgmsg5, /dspmsg, /leaders, /useleaderboard, /usetipcount, /tippers)' + '\ntokenpoll (/poll, /usepoll, /endpoll, /restartpoll, /addvote, /polloptadd, /polloptrmv, /pollstarttimer, /polladdtime, /pollstoptimer, /pollleader)' + '\nnicelist (/addnice, /rmvnice, /nicelist)' + '\nviplist (/addvip, /rmvvip, /viplist, /exportvip)' + '\nfanlist (/addfan, /rmvfan, /fanlist, /exportfans)' + '\nwordlist (/addword, /rmvword, /wordlist)' + '\nother (/newsubject, /dumpsettings)' + '\ntickets (/prepticket, /add, /del, /dsptlist, /usetlist, /ctprice, /tlistprice, /exptlist, /addlbtop, /addlbamt)' + '\nlush (/lushmenu, /uselushmenu' + '\nmedia (/mediamenu, /usemedia' + '\nabout' ,from); cb.sendNotice('',from,green); break; } case 'other': { valid = 1; cb.sendNotice('Fembot Command List',from,green); cb.sendNotice('',from,green); cb.sendNotice( 'Other Commands' + '\n/newsubject [X]: Update the room subject to a new value [X].' + '\n/dumpsettings: Send a list of all of the fembot settings defined when the current bot session was started to tehe chat... mainly for troubleshooting.' ,from); cb.sendNotice('',from,green); break; } case 'tickets': { valid = 1; cb.sendNotice('Fembot Command List',from,green); cb.sendNotice('',from,green); cb.sendNotice( 'Ticket Show Support Commands' + '\n/prepticket: Prepare for a ticket show by disabling the regular Tip Menu if running, enabling the Positions Menu, and enabling the Token Poll.' + '\nThis command will also add the VIP List and External Fan Club list to the ticket show if enabled.' + '\n/usetlist [on/off]: Toggle the setting for whether the Backup Ticket List tracking is "on" or "off". Overrides the initial setting to turn it on or off during the show.' + '\n/add [user]: This is actually the crazyticket command being executed to manually add a user to the show, and the additional update is made here to also add them to the Backup list.' + '\n/del [user]: This is actually the crazyticket command being executed to manually remove a user from the show, and the additional update is made here to also remove them from the Backup list.' + '\n/dsptlist: Display the Backup Ticket list.' + '\n/ctprice [newamount]: This is actually the crazyticket command being executed to manually change the ticket price, and the additional update is made here to also update the price used for the Backup list.' + '\nUsers are added to the backup list anytime they tip more than the amount currently defined as the show price, so it needs to be kept up to date as it is changed in Crazyticket.' + '\n/tlistprice [newamount]: This can be used outside of the /ctprice command being used to set the comparison amount for adding people to the Backup list.' + '\nThis would commonly be used if turning on the Backup list without the price being set on the initial configuration screen, it can be updated when the ticket app is started.' + '\n/exptlist: Export the backup ticket list by creating the /add command to add all backup list members to crazyticket.' + '\n/addlbtop [X]: Add the top [X] tippers from the leaderboard to the ticket show. Available only to broadcasters, and if configured, moderators as well. Check the top tippers using /leaders or /tippers before using this command to ensure the appropriate users are being added.' + '\n/addlbamt [X]: Add the tippers from the leaderboard who have tipped at least [X] amount to the ticket show. Available only to broadcasters, and if configured, moderators as well. Check the top tippers using /leaders or /tippers before using this command to ensure the appropriate users are being added.' ,from); cb.sendNotice('',from,green); break; } case 'messaging': { valid = 1; cb.sendNotice('Ultra Fembot help for Messaging Commands:',from,green); cb.sendNotice( 'pm: This command is usable by moderators and broadcasters to send a PM to a specific user in the main chat window.' + '\nThe syntax for using PMs is "/pm [X] [Y]", where [X] is the username of the user you want to send the message to, and [Y] is the message you want to send.' + '\nA related command is /reply.' + '\n/reply: This command is usable by everyone once they have received a PM from a moderator or broadcaster.' + '\nThe syntax for replying to a PM is "/reply [X]", where [X] is message that you want to PM to the user who most recently sent a PM to you.' + '\nYou should be careful using this to ensure the last person that PM\'d you is the person you are intending to reply to.' + '\nAlternatvely, a new PM can be sent using the /pm command rather than reply if you are not sure who last PM\'d you.' + '\n/bc: This command is usable by moderators to send a PM specifically to the broadcaster.' + '\nThe syntax for using this type of PM is "/bc [X]", where [X] is the message you want to send.' + '\n/tm: This command that is usable by moderators and the broadcaster to send a PM to the moderator group as a whole.' + '\nThe syntax for using this type of PM is "/tm [X]", where [X] is the message you want to send.' + '\n/tbm: This command is usable by moderators and the broadcaster to send a PM to the moderator group plus the broadcaster.' + '\nThe syntax for using this type of PM is "/tbm [X]", where [X] is the message you want to send.' ,from); cb.sendNotice('',from,green); break; } case 'timer': { valid = 1; cb.sendNotice('Ultra Fembot help for Timer Commands:',from,green); cb.sendNotice( '/startclock: This command is usable by moderators and broadcasters to start a timer in the room. This timer is not tied to any specific function, just a countdown.' + '\nThe syntax for using the command is "/startclock [T]", where [T] is the desired duration of the countdown timer in minutes. The function will accept whole numbers only.' + '\nThe timer will make announcements at 15, 10, 5, 4, 3, 2, 1 minutes and 30 seconds remaining. The function /addtoclock can be used to add time to a currently running timer.' + '\n/addtoclock: This command is usable by moderators and broadcasters to add time to (or subtract time from) an existing countdown.' + '\nThe syntax for using addtoclock is "/addtoclock [T]", where [T] is the amount of time you want to add in minutes. The command will accept positive or negative whole numbers only. Negative numbers can be used to subtract time from the clock.' + '\n/timeleft: This command will display the amount of time left in the countdown.' + '\n/stopclock: This command will end the countdown timer.' ,from); cb.sendNotice('',from,green); break; } case 'notices': { valid = 1; cb.sendNotice('Ultra Fembot help for Chat Notice Commands:',from,green); cb.sendNotice( 'cn: This command is usable by moderators and the broadcaster to post a one-time notice in the chat.' + '\nThe syntax for using this type of notice is "/cn [X]", where [X] is the message you want to send.' + '\nThis is the plain notification without any separators or highlighting.' + '\n/cnd: This command is usable by moderators and the broadcaster to post a one-time notice in the chat.' + '\nThe syntax for using this type of notice is "/cnd [X]", where [X] is the message you want to send.' + '\nThis notification includes a dash separator before and after the message, but no highlighting.' + '\n/cnh: This command is usable by moderators and the broadcaster to post a one-time notice in the chat.' + '\nThe syntax for using this type of notice is "/cnh [X]", where [X] is the message you want to send.' + '\nThis notification includes highlighting, but no separators.' + '\n/cndh: This command is usable by moderators and the broadcaster to post a one-time notice in the chat.' + '\nThe syntax for using this type of notice is "/cndh [X]", where [X] is the message you want to send.' + '\nThis notification includes both separators and highlighting.' + '\n/usenotifier: This command is usable by moderators and broadcasters to toggle on or off the display of the periodic notification message defined by the broadcaster.' + '\nThe syntax for using notifier is /usenotifier [X], where [X] is either "on" or "off".' + '\n/chgmsg1: Change the text of the message slotted in Notifier 1. Notifications must be enabled for the message to display.' + '\nThe syntax for using command is /chgmsg1 [X], where [X] is the new message that should be displayed.' + '\n/chgmsg2: Change the text of the message slotted in Notifier 1. Notifications must be enabled for the message to display.' + '\nThe syntax for using command is /chgmsg2 [X], where [X] is the new message that should be displayed.' + '\n/chgmsg3: Change the text of the message slotted in Notifier 1. Notifications must be enabled for the message to display.' + '\nThe syntax for using command is /chgmsg3 [X], where [X] is the new message that should be displayed.' + '\n/chgmsg4: Change the text of the message slotted in Notifier 1. Notifications must be enabled for the message to display.' + '\nThe syntax for using command is /chgmsg4 [X], where [X] is the new message that should be displayed.' + '\n/chgmsg5: Change the text of the message slotted in Notifier 1. Notifications must be enabled for the message to display.' + '\nThe syntax for using command is /chgmsg5 [X], where [X] is the new message that should be displayed.' + '\n/dspmsg [X]: Display the message slotted in position [X], where [X] can be the integers 1-5 or "all".' + '\n/leaders: This command is usable by everyone with the default delivery of displaying the tip leader list only to the requesting user. The leaderboard can also be ' + 'sent to the general chat for all to see, or to the broadcaster or mods specifically.' + '\nThe syntax for using leaderboard is "/leaders" to send to yourself. Moderators and broadcasters can use "/leaders all", "/leaders mods" or "/leaders bc".' + '\nThis command triggers the display of the top 5 tippers of the current session, regardless of the setting for periodic display of the leaderboard.' + '\n/useleaderboard [X]: This command is usable by moderators and broadcasters to toggle the display of the leaderboard in the chat per the defined interval.' + '\nThe syntax for using the leaderboard toggle is /useleaderboard [X], where [X] is either "on" or "off".' + '\nThe interval for the display is still controlled by the configuration settings when enabling the bot.' + '\n/usetipcount [X]: This command is usable by moderators and broadcasters to toggle the display of the user\'s tip count at the beginning of their chat messages.' + '\nThe syntax for using the tip count toggle is /usetipcount [X], where [X] is either "on" or "off".' + '\nNote that enabling and disabling this will not control whether the token tip counts are tracked, only whether they are displayed.' + '\n/tippers: This command that is usable by moderators and broadcasters to trigger the display of the top 25 tippers of the current session with the default delivery displaying ' + 'the tip leader list only to the requesting user. The leaderboard can also be sent to the general chat for all to see, or to the broadcaster or mods specifically.' + '\nThe syntax for using leaderboard is "/tippers" to send to yourself. Moderators and broadcasters can use "/leaders all", "/leaders mods" or "/leaders bc".' ,from); cb.sendNotice('',from,green); break; } case 'chatcontrol': { valid = 1; cb.sendNotice('Ultra Fembot help for Chat Control Commands:',from,green); cb.sendNotice( '\n/silencelevel: This command is used by moderators and broadcasters to control who is able to chat in the room.' + '\nThe syntax for using silencelevel is "/silencelevel [X]", where [X] is a number from 0 to 3.' + '\nSetting the Silence Level to 0 will grant chat privileges to all users, ' + 'setting it to 1 will remove chat privileges from users without tokens, ' + 'setting it to 2 will remove chat privileges from users who have not tipped, ' + 'and setting it to 3 will remove chat privileges from users who have not tipped at least 10 tokens.' + '\nThe default setting for /silencelevel is 0. The chat ability of broadcasters, moderators, and fan club members is unaffected by the Silence Level.' + '\n/graphiclevel: This command is used by moderators and broadcasters to control who is able to post graphics or gifs in the room.' + '\nThe syntax for using graphiclevel is "/graphiclevel [X]", where [X] is a number from 0 to 3.' + '\nSetting the Graphic Level to 0 will grant graphic usage privileges to all users, ' + 'setting it to 1 will revoke graphic usage privileges from users who do not have tokens, ' + 'setting it to 2 will revoke graphic usage privileges from users who have not tipped, ' + 'and setting it to 3 will revoke graphic usage privileges from users who have not tipped at least 10 tokens.' + '\nThe default setting for /graphiclevel is 1. The graphiclevel does not affect the ability of broadcasters, moderators, and fan club members from posting graphics.' + '\n/ninja: This command is usable by moderators and broadcasters.' + '\nThe syntax for using silence is "/ninja [X]", where [X] is the user you want to silence without notification.' + '\nThe effect of the /ninja feature is similar the /silence feature except that the user is not notified.' + '\nThe effect of /ninja can be reversed by running the command /unninja.' + '\n/unninja: This command is usable by moderators and broadcasters.' + '\nThe syntax for using unninja is "/unninja [X]", where [X] is the username of the user you want to remove from the ninja list.' + '\nunninja grants chat privileges back to a user who was previously silenced by ninja.' + '\n/ninjalist: This command is usable by moderators and broadcasters.' + '\nUsing this command will display the list of users that has been silenced using the /ninja command.' + '\nUsers can be removed from this list by running the command /unninja.' + '\n/silence: The syntax for using silence is "/silence [X]", where [X] is the user you want to silence.' + '\nThe effect of the /silence feature is similar the Chaturbate silence feature when you click on a user\'s name and select silence for 6 hrs, ' + 'except that it lasts for the duration of the current session. Also, the user is notified of being silenced, differentiating it from the /ninja function.' + '\nThe effect of /silence can be reversed by running the command /unsilence.' + '\n/unsilence: This command is usable by moderators and broadcasters to grant chat privileges back to a user who was previously silenced.' + '\nThe syntax for using unsilence is "/unsilence [X]", where [X] is the username of the user you want to unsilence.' + '\nNOTE: /unsilence cannot undo the effect of Chaturbate\'s silence for 6 hours feature!' + '\n/silencelist: This is a command that is usable by moderators and broadcasters to display the list of users that has been silenced using the /silence command.' ,from); cb.sendNotice('',from,green); break; } case 'tipmenu': { valid = 1; cb.sendNotice('Ultra Fembot help for Tip Menu Commands:',from,green); cb.sendNotice( '\n/tipmenu: Display the tip menu in the chat. Available to any user, menu only shown to the user that requests it.' + '\n/usemenu [on/off]: Toggle the setting for whether the Tip Menu is "on" or "off". Overrides the initial setting to turn the Tip Menu on or off during the show.' + '\n/useposmenu [on/off]: Toggle the setting for whether the Positions Tip Menu is "on" or "off". Overrides the initial setting to turn the Positions Tip Menu on or off during the show.' + '\n/tipmenurequests: Show recent tip menu requests, defaults to a maximum of the 10 most recent when no quantity is entered.' + '\n/tipmenurequests X: Show the last "X" requests.' + '\n/tipmenurequests all: Show all the requests, maximum of 50.' + '\n/tipmenuadd X Y: Add an item name "Y" with a price of "X" tokens to the menu.' + '\n/tipmenurmv X: Removes every item with a price of "X" tokens from the tip menu.' + '\n/tipmenurmv Y: Will remove any item labeled "Y" regardless of price from the tip menu.' ,from); cb.sendNotice('',from,green); break; } case 'positions': { valid = 1; cb.sendNotice('Ultra Fembot help for Tip Menu Commands:',from,green); cb.sendNotice( '\n/posmenu: Display the positions tip menu in the chat. Available to any user, menu only shown to the user that requests it.' + '\n/useposmenu [on/off]: Toggle the setting for whether the Positions Tip Menu is "on" or "off". Overrides the initial setting to turn the Positions Tip Menu on or off during the show.' + '\n/posmenurequests: Show recent positions menu requests, defaults to a maximum of the 10 most recent.' + '\n/posmenuadd X Y: Add an item name "Y" with a price of "X" tokens to the positions menu.' + '\n/posmenurmv X: Removes every item from the positions menu with a price of "X" tokens from the positions menu.' + '\n/posmenurmv Y: Will remove any item labeled "Y" regardless of price from the positions menu.' ,from); cb.sendNotice('',from,green); break; } case 'tokenpoll': { valid = 1; cb.sendNotice('Ultra Fembot help for Token Poll Commands:',from,green); cb.sendNotice( '/poll: (all users) Display the current poll results board in the chat for the requesting user. Displayed to all when requested by moderators.' + '\n/usepoll [on/off]: (mods/bc only) Toggle the setting for whether the Token Poll is "on" or "off". Overrides the initial setting to turn the Token Poll on or off during the show.' + '\n/endpoll: (mods/bc only) When running under manual control, end the poll and display the winner.' + '\n/restartpoll: (mods/bc only) If the poll is accidentally ended, or suspended, it can be restarted using this command.' + '\n/addvote X Y: (mods/bc only) Add or remove "Y" number of votes to the poll item with a price of "X". If "Y" is not specified, defaults to one vote added or removed. Number can be shown as negative (-2) to remove votes. Moderators have to be enabled to use this command.' + '\n/polloptadd X Y: (mods/bc only) Add an item named "Y" with a price of "X" tokens to the poll.' + '\n/polloptrmv Y: (mods/bc only) Will remove any item labeled "Y" from the token poll.' + '\n/pollstarttimer X: (mods/bc only) Starts a timer for "X" minutes for the poll when run under timed mode. Poll will automatically end when time runs out.' + '\n/polladdtime X: (mods/bc only) Adds "X" minutes to the poll timer if a timer is running.' + '\n/pollstoptimer: (mods/bc only) Ends the timer if running under timed mode.' + '\n/pollleader: (all users) Post the poll leader message to the chat for the requesting user. Displayed to all when requested by moderators.' ,from); cb.sendNotice('',from,green); break; } case 'nicelist': { valid = 1; cb.sendNotice('Ultra Fembot help for Timer Commands:',from,green); cb.sendNotice( '/addnice: This command is usable by moderators and broadcasters.' + '\nThe syntax for using addnice is "/addnice x", where x is the username of the user you want to add to the nice list.' + '\nAdding a user to the nice list guarantees that user voice and graphic usage privileges regardless of the silence and graphic level settings. ' + 'Using /silence will still silence a user on the nice list.' + '\nUsers can be removed from the nice list by using the command /rmvnice.' + '\nSee the help sections for silencelevel and graphiclevel for more information on the global settings or the help section for nicelist for more information on the nice list.' + '\n/rmvnice: This command is usable by moderators and broadcasters.' + '\nThe syntax for using this command is "/rmvnice x", where x is the username of the user you want to remove from the nice list.' + '\n/nicelist: Sometimes, there are nice or polite users you would like to allow to chat even when they don\'t have tokens or haven\'t tipped. ' + 'When the silence level is elevated, usually these users are no longer able to chat, but adding them to the nice list allows them to still chat despite the silence level.' + 'Users can be added to the nice list using the command /addnice [user] where [user] is the user name that should be added.' + 'Likewise users can be removed from the nice list using the command /rmvnice [user] where [user] is the user name that should be removed' + 'The list of users currently in the nice list can be displayed using the command /nicelist.' ,from); cb.sendNotice('',from,green); break; } case 'viplist': { valid = 1; cb.sendNotice('Ultra Fembot help for VIP List Commands:',from,green); cb.sendNotice( '/addvip: This command is usable by broadcasters only.' + '\nThe syntax for using the command is "/addvip [X]", where [X] is the user you want to add to the VIP list.' + '\nAdding a user to the VIP list gives them a badge icon in the chat, PM ability, and includes them in the export list sent to the ticket show. ' + '\nUsers can be removed from the VIP list by using the command /rmvvip.' + '\n/rmvvip: This command is usable by broadcasters only.' + '\nThe syntax for using this command is "/rmvvip [X]", where [X] is the user you want to remove from the VIP list.' + '\n/viplist: Displays the list of users currently in the VIP list.' + '\n/exportvip: Displays the list of users currently in the VIP list in a format that can easily be repasted in the chat to add users to a ticket show.' + '\nNote that this logic will also be executed using the /prepticket command.' ,from); cb.sendNotice('',from,green); break; } case 'fanlist': { valid = 1; cb.sendNotice('Ultra Fembot help for External Fan Club List Commands:',from,green); cb.sendNotice( '/addfan: This command is usable by broadcasters only.' + '\nThe syntax for using the command is "/addvip [X]", where [X] is the user you want to add to the External Fan Club list.' + '\nAdding a user to the External Fan Club list gives them a badge icon in the chat, PM ability, and includes them in the export list sent to the ticket show. ' + '\nUsers can be removed from the External Fan Club list by using the command /rmvfan.' + '\n/rmvfan: This command is usable by broadcasters only.' + '\nThe syntax for using this command is "/rmvfan [X]", where [X] is the user you want to remove from the External Fan Club list.' + '\n/fanlist: Displays the list of users currently in the External Fan Club list.' + '\n/exportfan: Displays the list of users currently in the External Fan Club list in a format that can easily be repasted in the chat to add users to a ticket show.' + '\nNote that this logic will also be executed using the /prepticket command.' ,from); cb.sendNotice('',from,green); break; } case 'wordlist': { valid = 1; cb.sendNotice('Ultra Fembot help for Blocked Word List Commands:',from,green); cb.sendNotice( '/addword: This command is usable by broadcasters and moderators only.' + '\nThe syntax for using the command is "/addword [X]", where [X] is the word you want to add to the Blocked Word list.' + '\nAdding a word to the Blocked Word list will cause a message containing that word to be blocked and not posted to the chat.' + '\nWords can be removed from the Blocked Word list by using the command /rmvword.' + '\n/rmvword: This command is usable by broadcasters and moderators only.' + '\nThe syntax for using this command is "/rmvword [X]", where [X] is the word you want to remove from the Blocked Word list.' + '\n/wordlist: Displays the list of words currently in the Blocked Word list, available to all users.' ,from); cb.sendNotice('',from,green); break; } case 'lush': { valid = 1; cb.sendNotice('Ultra Fembot help for Lush Menu Commands:',from,green); cb.sendNotice( '\n/lushmenu: Display the lush menu in chat. Available to any user, only shown to the user that requests it.' + '\n/uselushmenu [on/off]: Toggle the setting for whether the Lush Menu is "on" or "off", and displays at the defined interval. Overrides the initial setting to turn the Lush Menu on or off during the show.' ,from); cb.sendNotice('',from,green); break; } case 'media': { valid = 1; cb.sendNotice('Ultra Fembot help for Media List Commands:',from,green); cb.sendNotice( '\n/media: Display the media list in chat. Available to any user, only shown to the user that requests it.' + '\n/usemedia [on/off]: Toggle the setting for whether the Media List is "on" or "off", and displays at the defined interval. Overrides the initial setting to turn the Lush Menu on or off during the show.' ,from); cb.sendNotice('',from,green); break; } case 'about': { valid = 1; cb.sendNotice('About the Ultra Fembot',from,green); cb.sendNotice('Dorothy\'s Ultra Fembot was written by chelsea2950 mostly based on several existing bots with some tweaks and improvements.' + '\nComments, suggestions, requests, and bug reports can be made by either tweeting @thechelsea2950, or by posting comments on bot help page.' + '\nThe purpose of this Ultra Bot is to serve as one tool that experienced cammers can use for most of the common functions needed during a show. ' + '\nWhereas the "Easy Fembot" contains basic features such as Private Messaging, Leader Board, Silencing users, Silence Level, Graphic Level, Nice List and Notifier, ' + 'the "Ultra Fembot" also adds fancier features such as a Tip Menu, VIP list, Token Poll, icons by user group, blocked wordlist, and additional notifiers. ' + '\nSee the help details for each command for more information on these features.' ,from); cb.sendNotice('',from,green); break; } } if(valid == 0) { cb.sendNotice(option + ' is not a valid subsection of the help menu. Type "/fbhelp" to access the main help menu.',from,green); } } } } // ******************************* Upon user entry of a Message ************************************** { cb.onMessage(function (msg) { var message = msg['m'].split(' '); var cmd = 0; var silencedmsg = 0; var symbolString = '~`!@#$%^&*()_-+={[}]|\\:;"\'<,>.?/'; var listRegExp = /[,\s]+/; var m = msg.m; var u = msg.user; var isMod = msg.is_mod; var isFan = msg.in_fanclub; var isBC = (u == BC); var isExtFan = cbjs.arrayContains(extFanListArray,u); var isVIP = cbjs.arrayContains(VIPListArray,u); var isNinjaSilenced = cbjs.arrayContains(ninjaListArray, u); var isNice = cbjs.arrayContains(niceListArray, u); var isSilenced = cbjs.arrayContains(silenceListArray, u); var command = message[0] var commandVar1 = parseInt(message[1]); var commandVar2 = parseInt(message[2]); if(message[0].charAt(0) == '/') { msg['X-Spam'] = true; var ntc = null; for (var i = 1; i < message.length; i++) { if (i == 1) ntc = message[i]; else ntc += " " + message[i]; } var ntc2 = null; for (var i = 2; i < message.length; i++) { if (i == 2) ntc2 = message[i]; else ntc2 += " " + message[i]; } var cmdval = null; for (var i = 1; i < message.length; i++) { if (i == 1) cmdval = message[i]; else cmdval += " " + message[i]; } switch(command) { //******** Chat Control Commands *********** case '/silencelevel': { cmd = 1; if(isMod || isBC) { setSilenceLevel(message[1], u); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp" to see a full list of the available commands.', u, green); } break; } case '/graphiclevel': { cmd = 1; if(isMod || isBC) { setGraphicLevel(message[1], u); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp" to see a full list of the available commands.', u, green); } break; } //******** Timer Commands *********** case '/startclock': { cmd = 1; if (isMod || isBC) { if (clockMinsRemain >= 1 || clockSecsRemain >= 1) { cb.sendNotice('A timer is already running, you can type /stopclock to end the current timer or /addtoclock X to add time, where X is the time to add in minutes.', u, green); break; } if (!commandVar1) { cb.sendNotice('Invalid command, you need to specify the starting point for the timer in minutes. Example: use "/startclock 10" to start a 10 minute timer', u, green); break; } commandVar1 = parseInt(commandVar1) if (isNaN (commandVar1)) { cb.sendNotice('Invalid value, the time entered must be a numeric value in minutes. Example: use "/startclock 10" to start a 10 minute timer.', u, green); break; } if (commandVar1 > 120) { cb.sendNotice('The time specified is greater than 2 hours, please use a smaller value.', u, green); break; } clockStartTime = new Date(); clockStopTime = new Date(clockStartTime.getTime() + commandVar1 * 60000); clockMinsRemain = commandVar1; clockTimeAdded = false; cb.sendNotice(u + " has started a timer for " + clockMinsRemain + " minute" + (clockMinsRemain > 1 ? "s" : ""), "", green, "", "bold"); clockTimerMin(); break; } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', u, green); } break; } case '/addtoclock': { cmd = 1; if (isMod || isBC) { if (!commandVar1) { cb.sendNotice('Invalid command, you need to specify the amount of time to add to the timer in minutes. Example: use "/addtoclock 3" to add 3 minutes to the timer.', u, green); } else if ((clockMinsRemain + 1) + commandVar1 <= 0) { cb.sendNotice('The time to subtract is greater than the amount of time left. You can use "/stopclock" to stop the timer.'); } else if ((clockMinsRemain + 1) + commandVar1 > 120) { cb.sendNotice('The added time will increase the timer to greater than 2 hours, please use a smaller value.'); } else { if (clockMinsRemain >= 1 || clockSecsRemain >= 1) { clockAddTime(commandVar1, u); break; } else { cb.sendNotice('A timer is not running.', msg['user'], green); } } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp timer" to see a full list of the timer related commands.', u,green); } break; } case '/timeleft': { cmd = 1; if (isMod || isBC) { if (clockMinsRemain >= 1 || clockSecsRemain >= 1) { cb.sendNotice(timeLeft(), "", yellow, "", "bold"); } else { cb.sendNotice('A timer is not running.', msg['user'], green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp" to see a full list of the available commands.', u, green); } break; } case '/stopclock': { cmd = 1; if (isMod || isBC) { if (clockMinsRemain >= 1 || clockSecsRemain >= 1) { stopClockTimer(u); } else { cb.sendNotice('A timer is not running.', msg['user'], green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp" to see a full list of the available commands.', u, green); } break; } //******** Ninja Commands *********** case '/ninja': { cmd = 1; if(isMod || isBC) { addRmvNinja(message[1], u, 'a'); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } case '/unninja': { cmd = 1; if (isMod || isBC) { addRmvNinja(message[1], u, 'r'); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } case '/ninjalist': { cmd = 1; if (isMod || isBC) { cb.sendNotice('Users currently on the Ninja List: ' + ninjaListArray.length, u, green); cb.sendNotice((ninjaListArray.length > 0 == true ? cbjs.arrayJoin(ninjaListArray, ', ') : 'No users.'), u); cb.sendNotice('End of List', u, green); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } //******** Silence List Commands *********** case '/silence': { cmd = 1; if (isMod || isBC) { addRmvSilence(message[1], u, 'a'); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } case '/unsilence': { cmd = 1; if (isMod || isBC) { addRmvSilence(message[1], u, 'r'); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } case '/silencelist': { cmd = 1; if (isMod || isBC) { cb.sendNotice('Users currently on the Silence List: ' + silenceListArray.length, u, green); cb.sendNotice((silenceListArray.length > 0 == true ? cbjs.arrayJoin(silenceListArray, ', ') : 'No users.'), u); cb.sendNotice('End of List', u, green); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } //******** VIP Commands *********** case '/addvip': { cmd = 1; if (isBC) { if (cmdval != null) { var cmdvalsplit = cmdval.split(listRegExp); if (cmdvalsplit.length > 1) { cb.sendNotice("Adding multiple users to the VIP list.", u, green); for (var i = 0; i < cmdvalsplit.length; i++) { if (cmdvalsplit[i] != "") { if (!cbjs.arrayContains(VIPListArray, cmdvalsplit[i])) { populateVIPListArray(cmdvalsplit[i]); cb.sendNotice("Added " + cmdvalsplit[i] + " to the list.", u); cb.sendNotice(u + " has added you to the VIP list.", cmdvalsplit[i], "#efe"); } else { cb.sendNotice(cmdvalsplit[i] + " is already on the list. Skipping.", u); } } } cb.sendNotice("All users were added and notified.", u, green) cb.sendNotice(u + " has added multiple users to the VIP list.\n" + "Users added: " + cbjs.arrayJoin(cmdvalsplit, ", "), "", green, "", "normal", "red"); } else { var cmdvalsingle = message[1]; addRmvVIP(cmdvalsingle, u, 'a'); } } else { cb.sendNotice("You didn't specify what user(s) you want to add to the External Fan Club list.", u, green); } } else { cb.sendNotice('Only broadcasters are able to use that command.', u, green); } break; } case '/rmvvip': { cmd = 1; if(isBC) { addRmvVIP(message[1], u, 'r'); } else { cb.sendNotice('Only broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } case '/viplist': { cmd = 1; if (isMod || isBC) { cb.sendNotice('Users currently on the VIP List: ' + VIPListArray.length, u, green); cb.sendNotice((VIPListArray.length > 0 == true ? cbjs.arrayJoin(VIPListArray, ', ') : 'No users.'), u); cb.sendNotice('End of List', u, green); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', u, green); } break; } case '/exportvip': { cmd = 1; if (VIPListArray.length > 0) { if (isMod || isBC) { msg['m'] = '/add ' + cbjs.arrayJoin(VIPListArray, ', '); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', u, green); } } else { cb.sendNotice('Cannot export, there are no users in the VIP List.', u, green); } break; } //******** External Fan Club Commands *********** case '/addfan': { cmd = 1; if (isBC) { if (cmdval != null) { var cmdvalsplit = cmdval.split(listRegExp); if (cmdvalsplit.length > 1) { cb.sendNotice("Adding multiple users to the External Fan Club list.", u, green); for (var i = 0; i < cmdvalsplit.length; i++) { if (cmdvalsplit[i] != "") { if (!cbjs.arrayContains(extFanListArray, cmdvalsplit[i])) { populateExtFanListArray(cmdvalsplit[i]); cb.sendNotice("Added " + cmdvalsplit[i] + " to the list.", u); cb.sendNotice(u + " has added you to the External Fan Club list.", cmdvalsplit[i], "#efe"); } else { cb.sendNotice(cmdvalsplit[i] + " is already on the list. Skipping.", u); } } } cb.sendNotice("All users were added and notified.", u, green) cb.sendNotice(u + " has added multiple users to the External Fan Club list.\n" + "Users added: " + cbjs.arrayJoin(cmdvalsplit, ", "), "", green, "", "normal", "red"); } else { var cmdvalsingle = message[1]; addRmvExtFan(cmdvalsingle, u, 'a'); } } else { cb.sendNotice("You didn't specify what user(s) you want to add to the External Fan Club list.", u, green); } } else { cb.sendNotice('Only broadcasters are able to use that command.', u, green); } break; } case '/rmvfan': { cmd = 1; if(isBC) { addRmvExtFan(message[1], u, 'r'); } else { cb.sendNotice('Only broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } case '/fanlist': { cmd = 1; if (isMod || isBC) { cb.sendNotice('Users currently in the External Fan Club List: ' + extFanListArray.length, u, green); cb.sendNotice((extFanListArray.length > 0 == true ? cbjs.arrayJoin(extFanListArray, ', ') : 'No users.'), u); cb.sendNotice('End of List', u, green); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', u, green); } break; } case '/exportfans': { cmd = 1; if (extFanListArray.length > 0 == true) { if (isMod || isBC) { msg['m'] = '/add ' + cbjs.arrayJoin(extFanListArray, ', '); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', u, green); } } else { cb.sendNotice('Cannot export, there are no users in the External Fan Club List.', u, green); } break; } //******** Blocked Word List Commands *********** case '/addword': { cmd = 1; if (isMod || isBC ) { if (cmdval != null) { var cmdvalsplit = cmdval.split(listRegExp); if (cmdvalsplit.length > 1) { cb.sendNotice("Adding multiple words to the Blocked Word list.", u, green); for (var i = 0; i < cmdvalsplit.length; i++) { if (cmdvalsplit[i] != "") { if (!cbjs.arrayContains(wordListArray, cmdvalsplit[i])) { populateWordListArray(cmdvalsplit[i]); cb.sendNotice("Added " + cmdvalsplit[i] + " to the list.", u); } else { cb.sendNotice(cmdvalsplit[i] + " is already on the list. Skipping.", u); } } } cb.sendNotice("All words were added.", u, green) cb.sendNotice(u + " has added multiple words to the Blocked Word list.\n" + "Words added: " + cbjs.arrayJoin(cmdvalsplit, ", "), "", green, "", "normal", "red"); } else { var cmdvalsingle = message[1]; addRmvWord(cmdvalsingle, u, 'a'); } } else { cb.sendNotice("You didn't specify what word(s) you want to add to the Blocked Word list.", u, green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp" to see a full list of the available commands.', u, green); } break; } case '/rmvword': { cmd = 1; if(isMod || isBC) { addRmvWord(message[1], u, 'r'); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } case '/wordlist': { cmd = 1; cb.sendNotice('Words currently on the Blocked Word List: ' + wordListArray.length, u, green); cb.sendNotice((wordListArray.length > 0 == true ? cbjs.arrayJoin(wordListArray, ', ') : 'No users.'), u); cb.sendNotice('End of List', u, green); break; } //******** Nice List Commands *********** case '/addnice': { cmd = 1; if (isMod || isBC ) { if (cmdval != null) { var cmdvalsplit = cmdval.split(listRegExp); if (cmdvalsplit.length > 1) { cb.sendNotice("Adding multiple users to the nice list.", u, green); for (var i = 0; i < cmdvalsplit.length; i++) { if (cmdvalsplit[i] != "") { if (!cbjs.arrayContains(niceListArray, cmdvalsplit[i])) { populateNiceListArray(cmdvalsplit[i]); cb.sendNotice("Added " + cmdvalsplit[i] + " to the list.", u); cb.sendNotice(u + " has added you to the nice list.", cmdvalsplit[i], "#efe"); } else { cb.sendNotice(cmdvalsplit[i] + " is already on the list. Skipping.", u); } } } cb.sendNotice("All users were added and notified.", u, green) cb.sendNotice(u + " has added multiple users to the nice list.\n" + "Users added: " + cbjs.arrayJoin(cmdvalsplit, ", "), "", green, "", "normal", "red"); } else { var cmdvalsingle = message[1]; addRmvNice(cmdvalsingle, u, 'a'); } } else { cb.sendNotice("You didn't specify who you want to add to the nice list.", u, green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp" to see a full list of the available commands.', u, green); } break; } case '/rmvnice': { cmd = 1; if (isMod || isBC) { addRmvNice(message[1], u, 'r'); } break; } case '/nicelist': { cmd = 1; if (isMod || isBC) { cb.sendNotice('Users currently on the Nice List: ' + niceListArray.length, u, green); cb.sendNotice((niceListArray.length > 0 == true ? cbjs.arrayJoin(niceListArray, ', ') : 'No users.'), u); cb.sendNotice('End of List', u, green); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', u, green); } break; } //******** Chat Notice Commands *********** case '/cn': { cmd = 1; if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, ""); } else { cb.sendNotice("You can\'t send a blank message.\n" + "The correct syntax for this command is " + '"/cn message"' + ".", u, "#fee"); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', u, green); } break; } case "/cnh": { cmd = 1; if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "h"); } else { cb.sendNotice("You cannot send a blank message.\n" + "The correct syntax for this command is " + '"/cnh message"' + ".", u, "#fee"); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.', msg['user'], green); } break; } case "/cnd": { cmd = 1; if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "div"); } else { cb.sendNotice("You cannot send a blank message.\n" + "The correct syntax for this command is " + '"/cnd message"' + ".", u, "#fee"); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/ubhelp commands" to see a full list of the available commands.', u, green); } break; } case "/cndh": { cmd = 1; if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "divh"); } else { cb.sendNotice("You cannot send a blank message.\n" + "The correct syntax for this command is " + '"/cndh message"' + ".", u, "#fee"); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/ubhelp commands" to see a full list of the available commands.', u, green); } break; } //******** Private Message Commands *********** case "/bc": { cmd = 1; if (isMod || (isVIP && (cb.settings.enableVIPList == 'PMs' || cb.settings.enableVIPList == 'PMs and Ticket Shows')) || (isExtFan && (cb.settings.enableExtFans == 'PMs' || cb.settings.enableExtFans == 'PMs and Ticket Shows'))) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPrivateNotice(ntc, u, "bc", "default"); } else { cb.sendNotice("You cannot send a blank message.\nThe correct syntax for this command is " + '"/bc message"' + ".", u, "#fee"); } } else { cb.sendNotice('Only moderators are able to use that command.\nType "/ubhelp commands" to see a full list of the available commands.', u, green); } break; } case "/tm": { cmd = 1; if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPrivateNotice(ntc, u, "tm"); } else { cb.sendNotice("You cannot send a blank message.\nThe correct syntax for this command is " + '"/tm message"' + ".", u, "#fee"); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/ubhelp commands" to see a full list of the available commands.', u, green); } break; } case "/tbm": { cmd = 1; if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPrivateNotice(ntc, u, "tbm", "default"); } else { cb.sendNotice("You cannot send a blank message.\nThe correct syntax for this command is " + '"/tbm message"' + ".", u, "#fee"); } } else { cb.sendNotice('Only moderators are able to use that command.\nType "/ubhelp commands" to see a full list of the available commands.', u, green); } break; } case '/pm': { cmd = 1; if (cb.settings.enablePMs == "Yes") { if (isMod || isBC || (isVIP && (cb.settings.enableVIPList == 'PMs' || cb.settings.enableVIPList == 'PMs and Ticket Shows')) || (isExtFan && (cb.settings.enableExtFans == 'PMs' || cb.settings.enableExtFans == 'PMs and Ticket Shows'))) { if (ntc2 != null && (ntc2 != "" || ntc2 != " " || ntc2 != "\u00a0")) { sendPrivateNotice(ntc2, u, "pm", message[1]); } else { cb.sendNotice('You cannot send a blank message.\nThe correct syntax for this command is ' + '"/pm user message"' + '.', u, '#fee'); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/ubhelp commands" to see a full list of the available commands.', u, green); } } else { cb.sendNotice('That command has not been enabled by the broadcaster.', u, green); } break; } case '/reply': { cmd = 1; if (cb.settings.enablePMs == "Yes") { sendReply(message, msg['user']); break; } else { cb.sendNotice('That command has not been enabled by the broadcaster.', u, green); } } //******** Tip Leader Commands *********** case '/leaders': { cmd = 1; if (isMod || isBC) { switch (message[1]) { case "all": cb.sendNotice( "SENT TO ALL:", u, '#111111', '#d1eaee', "bold"); showLeaderBoard("", ""); break; case "tbm": cb.sendNotice( "SENT TO BROADCASTER and MODS:", u, '#111111', '#d1eaee', "bold"); showLeaderBoard("", "red");showLeaderBoard(BC,''); break; case "mods": cb.sendNotice( "SENT TO MODS:", u, '#111111', '#d1eaee', "bold"); showLeaderBoard("", "red"); break; case "bc": cb.sendNotice( "SENT TO YOU BY: "+u, BC, '#111111', '#d1eaee' , "bold"); cb.sendNotice( "SENT TO BROADCASTER:", u, '#111111', '#d1eaee', "bold"); showLeaderBoard(BC, ""); break; default: cb.sendNotice( "SENT TO ONLY YOU:", u, '#111111', '#d1eaee', "bold"); showLeaderBoard(u, ""); break; } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/ubhelp commands" to see a full list of the available commands.', u, green); } break; } case '/tippers': { cmd = 1; if (isMod || isBC) { if (ntc2 != null && (ntc2 != "" || ntc2 != " " || ntc2 != "\u00a0")) { if (ntc2 > 100) { cb.sendNotice('List cannot exceed 100, defaulting to 100.', u, green); num = 100 } num = ntc2; } else { num = 20 } switch (ntc) { case "all": cb.sendNotice( "SENT TO ALL:", u, '#111111', '#d1eaee' , "bold"); showTippers("", "", num); break; case "tbm": cb.sendNotice( "SENT TO BROADCASTER and MODS:", u, '#111111', '#d1eaee' , "bold"); showTippers("", "red", num);showTippers(cb.room_slug,''); break; case "mods": cb.sendNotice( "SENT TO MODS:", u, '#111111', '#d1eaee' , "bold"); showTippers("", "red", num); break; case "bc": cb.sendNotice( "SENT TO YOU BY: "+u, cb.room_slug, '#111111', lbback , "bold"); cb.sendNotice( "SENT TO BROADCASTER:", u, '#111111', '#d1eaee' , "bold"); showTippers(cb.room_slug, "", num); break; default: cb.sendNotice( "SENT TO ONLY YOU:", u, '#111111', '#d1eaee' , "bold"); showTippers(u, "", num); break; } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/ubhelp commands" to see a full list of the available commands.', u, green); } break; } case '/useleaderboard': { cmd = 1; if (isMod || isBC) { setLeaderToggle(message[1],msg['user']) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case '/usetipcount': { cmd = 1; if (isMod || isBC) { setTipCountToggle(message[1],msg['user']) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } //********* Notifier Commands case '/usenotifier': { cmd = 1; if (isMod || isBC) { setNotifierToggle(message[1],msg['user']) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case '/chgmsg1': { cmd = 1; if (isMod || isBC) { if(message[1] == '' || message[1] == null) { cb.sendNotice('You must enter a new message for the notifier feature. If you want to disable the notifications, enter /usenotifier off.',msg['user'],green) } else { notifierMessage1 = msg['m'].substring(8).trim(); cb.sendNotice('You have set the Notifier 1 message to: ' + notifierMessage1,msg['user'],green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case '/chgmsg2': { cmd = 1; if (isMod || isBC) { if(message[1] == '' || message[1] == null) { cb.sendNotice('You must enter a new message for the notifier feature. If you want to disable the notifications, enter /usenotifier off.',msg['user'],green) } else { notifierMessage2 = msg['m'].substring(8).trim(); cb.sendNotice('You have set the Notifier 2 message to: ' + notifierMessage2,msg['user'],green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case '/chgmsg3': { cmd = 1; if (isMod || isBC) { if(message[1] == '' || message[1] == null) { cb.sendNotice('You must enter a new message for the notifier feature. If you want to disable the notifications, enter /usenotifier off.',msg['user'],green) } else { notifierMessage3 = msg['m'].substring(8).trim(); cb.sendNotice('You have set the Notifier 3 message to: ' + notifierMessage3,msg['user'],green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case '/chgmsg4': { cmd = 1; if (isMod || isBC) { if(message[1] == '' || message[1] == null) { cb.sendNotice('You must enter a new message for the notifier feature. If you want to disable the notifications, enter /usenotifier off.',msg['user'],green) } else { notifierMessage4 = msg['m'].substring(8).trim(); cb.sendNotice('You have set the Notifier 4 message to: ' + notifierMessage4,msg['user'],green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case '/chgmsg5': { cmd = 1; if (isMod || isBC) { if(message[1] == '' || message[1] == null) { cb.sendNotice('You must enter a new message for the notifier feature. If you want to disable the notifications, enter /usenotifier off.',msg['user'],green) } else { notifierMessage5 = msg['m'].substring(8).trim(); cb.sendNotice('You have set the Notifier 5 message to: ' + notifierMessage5,msg['user'],green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case '/dspmsg': { cmd = 1; if (isMod || isBC) { setNoticeColor(); switch(message[1]) { case('1'): { if(notifierMessage1 == '' || notifierMessage1 == null) { cb.sendNotice('Notifier 1 Message is blank.', msg['user'], green) } else { cb.sendNotice('\u25ba ' + notifierMessage1, "", noticeBgColor, noticeTextColor, "bold"); } break; } case('2'): { if(notifierMessage2 == '' || notifierMessage2 == null) { cb.sendNotice('Notifier 2 Message is blank.', msg['user'], green) } else { cb.sendNotice('\u25ba ' + notifierMessage2, "", noticeBgColor, noticeTextColor, "bold"); } break; } case('3'): { if(notifierMessage3 == '' || notifierMessage3 == null) { cb.sendNotice('Notifier 3 Message is blank.', msg['user'], green) } else { cb.sendNotice('\u25ba ' + notifierMessage3, "", noticeBgColor, noticeTextColor, "bold"); } break; } case('4'): { if(notifierMessage4 == '' || notifierMessage4 == null) { cb.sendNotice('Notifier 4 Message is blank.', msg['user'], green) } else { cb.sendNotice('\u25ba ' + notifierMessage4, "", noticeBgColor, noticeTextColor, "bold"); } break; } case('5'): { if(notifierMessage5 == '' || notifierMessage5 == null) { cb.sendNotice('Notifier 5 Message is blank.', msg['user'], green) } else { cb.sendNotice('\u25ba ' + notifierMessage5, "", noticeBgColor, noticeTextColor, "bold"); } break; } case('all'): { for (let j = 1; j <= 5; j++) { if(this["notifierMessage"+j] != '' && this["notifierMessage"+j] != null) { cb.sendNotice(j + ". " + this["notifierMessage"+j], "", noticeBgColor, noticeTextColor, "bold"); } } break; } default: { cb.sendNotice('Invalid message slot, values must be 1-5 or "all".\nType "/fbhelp notices" to see a full list of the notice related commands.',msg['user'],green); break; } } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp notices" to see a full list of the notice related commands.',msg['user'],green); } break; } //********* Change Subject Command case '/newsubject': { cmd = 1; if (isMod || isBC) { newSubject = msg['m'].substring(12).trim() setRoomSubject(newSubject,msg['user']) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } //********* Ticket Show Support Commands case '/prepticket': { cmd = 1; if (isMod || isBC) { prepticketshow(msg['user']) if(newmessage != '' && newmessage != null) { msg['m'] = newmessage; } cb.sendNotice('Ticket show prep has been completed.', u, green); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp tickets" to see a full list of the ticket show related commands.',msg['user'],green); } break; } case '/add': { cmd = 1; if (isMod || isBC) { if (tlistToggle == 1) { if(message[1] == '' || message[1] == null) { updateTicketBackupList("add", msg['user']); cb.sendNotice('User ' + msg['user'] + ' has been added to the Backup Ticket List.', u, green); } else { updateTicketBackupList("add", message[1]); cb.sendNotice('User ' + message[1] + ' has been added to the Backup Ticket List.', u, green); } } else { cb.sendNotice('Note: User not added to backup ticket list, the Backup List is disabled.',msg['user'],green); } } break; } case '/startshow': { cmd = 1; if (isMod || isBC) { if (cb.settings.startPollTimerWithShow == 'Yes, switch to timed poll at show start') { if(pollRunning && pollType == 'Timer' && (pollMinsRemain > 0 || pollSecsRemain > 0)) { cb.sendNotice('Note: Poll timer not started with /startshow as it is already running. You can adjust the time remaining with the "/polladdtime [X]" command.', u, green); } else { timetoadd = parseInt(cb.settings.startPollMinAfterShow) if (timetoadd <= 0) { timetoadd = 10; cb.sendNotice('No setting defined for token poll end timer, defaulting to 10 min.', u, green); } pollSwitchToTimer(timetoadd, u); } } else { cb.sendNotice('Note: Poll Timer not started with /startshow per configuration.', u,green); } } break; } case '/showend': case '/stopshow': { cmd = 1; if (isMod || isBC) { if (cb.settings.endPosMenuWithShow == 'Yes') { setPosTipMenuToggle("off", u); } } break; } case '/del': { cmd = 1; if (isMod || isBC) { if (tlistToggle == 1) { updateTicketBackupList("rmv", message[1]); cb.sendNotice('User ' + message[1] + ' has been removed from the Backup Ticket List.', u, green); } } break; } case '/tlist': case '/dsptlist': { cmd = 1; if (tlistToggle == 1) { if (isMod || isBC) { cb.sendNotice('Users currently on the Backup Ticket List: ' + tlistArray.length, u, green); cb.sendNotice((tlistArray.length > 0 == true ? cbjs.arrayJoin(tlistArray, ', ') : 'No users.'), u); cb.sendNotice('End of List', u, green); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.', u, green); } } else { cb.sendNotice('The Backup Ticket List is disabled.\nType "/fbhelp tickets" to see a full list of the available commands related to ticket shows.', u, green); } break; } case '/ctprice': { cmd = 1; if (tlistToggle == 1) { if (isMod || isBC) { setTlistPrice(message[1]); cb.sendNotice('The Backup Ticket List Price has been updated to ' + message[1] + ' tokens, all tips of at least this amount will add a user to the Backup Ticket List.', u, green); } } break; } case '/tlistprice': { cmd = 1; if (tlistToggle == 1) { if (isMod || isBC) { setTlistPrice(message[1]); cb.sendNotice('The Backup Ticket List Price has been updated to ' + message[1] + ' tokens, all tips of at least this amount will add a user to the Backup Ticket List.', u, green); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.', u, green); } } else { cb.sendNotice('The Backup Ticket List is disabled.\nType "/fbhelp tickets" to see a full list of the available commands related to ticket shows.', u, green); } break; } case '/exptlist': { cmd = 1; if (tlistToggle == 1) { if (isMod || isBC) { if (tlistArray.length > 0) { msg['m'] = '/add ' + cbjs.arrayJoin(tlistArray, ', '); cb.sendNotice('The users from the backup ticket list have been added to the ticket show, which assumes CrazyTicket is already running, and this user has authority to the /add command.', u, green); } else { cb.sendNotice('No Backup Ticket List to add.', u, green); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } } else { cb.sendNotice('Backup Ticket List is disabled.\nType "/fbhelp tickets" to see a full list of the available commands related to ticket shows.', u, green); } break; } case '/addlbtop': { cmd = 1; LBi = 0; if (isBC || (isMod && ticketModAdd)) { numLB = parseInt(message[1]) if(isNaN(numLB)) { cb.sendNotice('The value entered for the number of tippers from the leaderboard is not numeric, please try again.', u, green); break; } if (numLB <= 0) { numLB = parseInt(cb.settings(numberFromLB)); } if (numLB <= 0) { numLB = 3; cb.sendNotice('No setting defined for number of entries to add, defaulting to top 3.', u, green); } addFromLeaderboard("num", numLB); if (addLBstring != '') { msg['m'] = "/add " + addLBstring; cb.sendNotice('The top ' + numLB + ' tippers from the Leaderboard have been added to the ticket show (assumes CrazyTicket is already running, and this user has authority to the /add command).', u, green); } else { cb.sendNotice('No Leaderboard entries to add.', u, green); } } else { cb.sendNotice('Only broadcasters and moderators (if configured) are able to use that command.\nType "/fbhelp tickets" to see a full list of the ticket show related commands.',u ,green); } break; } case '/addlbamt': { cmd = 1; LBi = 0; if (isBC || (isMod && ticketModAdd)) { amtLB = parseInt(message[1]) if (isNaN(amtLB)) { cb.sendNotice('The value entered for the tip amount is not numeric, please try again.', u, green); break; } if (amtLB <= 0) { amtLB = parseInt(cb.settings(amountFromLB)); } if (amtLB <= 0) { amtLB = 1000; cb.sendNotice('No setting defined for minimum tip amount to add, defaulting to 1000 tokens.', u, green); } addFromLeaderboard("amt", amtLB); if (addLBstring != '') { msg['m'] = "/add " + addLBstring; cb.sendNotice('Users who have tipped more than ' + amtLB + ' during this session have been added to the ticket show (assumes CrazyTicket is already running, and this user has authority to the /add command).', u, green); } else { cb.sendNotice('No qualifying tippers to add.', u, green); } } else { cb.sendNotice('Only broadcasters and moderators (if configured) are able to use that command.\nType "/fbhelp tickets" to see a full list of the ticket show related commands.',u ,green); } break; } case '/usetlist': { cmd = 1; if (isMod || isBC) { setTlistToggle(message[1],u) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp tickets" to see a full list of the ticket show related commands.',msg['user'],green); } break; } //********* Tip Menu Commands case "/tipmenu": { cmd = 1; m.background = '#d9d9d9'; if (tipMenuToggle == 1) { if (isMod || isBC) { u = ''; } cb.sendNotice(TIPMENU.tipMenu, u, TIPMENU.bgColor1, TIPMENU.txtColor1, "bold"); } else { cb.sendNotice('The Tip Menu has not been enabled.', u, green); } break; } case '/usemenu': { cmd = 1; if (isMod || isBC) { setTipMenuToggle(message[1],u) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case "/tipmenurequests": { cmd = 1; m.background = '#d9d9d9'; touser = msg['user']; if (isMod) { touser = ""; } let rL = TIPMENU.request.length; if (rL === 0) { cb.sendNotice("There is no request at the moment.", u, TIPMENU.bgColor1, TIPMENU.txtColor1); } else { let cmdInt1 = parseInt(message['1']); if (cmdInt1 <= 0) { cb.sendNotice('There have been no requests.', u, TIPMENU.bgColor1, TIPMENU.txtColor1); } else { let noticeMsg; let rS = 0; if (message['1'] === "all" || message['1'] === "All") { cmdInt1 = rL; } else if (cmdInt1 === undefined || isNaN(cmdInt1)) { cmdInt1 = 10; rS = rL - 10; } if (rL <= cmdInt1) { noticeMsg = '**** Here is the list of all the requests! ****\n'; cmdInt1 = rL; rS = 0; } else if (rL > 50) { noticeMsg = '**** Here is are the last 50 requests! ****\n'; rS = rL - 50; } else { noticeMsg = '**** Here ' + (cmdInt1 === 1 ? "is the last" : "are the last " + cmdInt1) + ' request' + (cmdInt1 === 1 ? "" : "s") + '! **** \n'; rS = rL - cmdInt1; } for (let i = rS; i < rL; i++) { noticeMsg += 'Request #' + (i + 1) + ': ' + TIPMENU.requesters[i] + ' requested ' + TIPMENU.request[i] + '\n'; } noticeMsg += '**************************************'; cb.sendNotice(noticeMsg, touser, TIPMENU.bgColor1, TIPMENU.txtColor1); } } break; } case "/tipmenuadd": { cmd = 1; m.background = '#d9d9d9'; if (!isMod && !isBC) { cb.sendNotice("Only mods and broadcasters can use this command.", u, "#FFFFFF", "#FF0000"); } else { let label; let newItemPrice = parseInt(message['1']); if (newItemPrice <= 0 || isNaN(newItemPrice)) { cb.sendNotice('The correct format is "/menuadd X item" where X has to be a number over 0. This is the amount the viewers will tip for it.', u, "#FFFFFF", "#FF0000"); return; } if (!message[2]) { cb.sendNotice("You need to include a label for that option.", u, "#FFFFFF", "#FF0000"); return; } for (let j = 2; j < message.length; j++) { if (j === 2) { label = message[j]; } else { label += " " + message[j]; } } cb.sendNotice("Tip menu to Broadcaster - " + (u === cb.room_slug ? "You" : u) + ' added the option "' + label + '" for ' + newItemPrice + ' tokens to the menu.', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice("Tip menu to mods - " + u + ' added the option "' + label + '" for ' + newItemPrice + ' tokens the menu.', "", "#FFFFFF", "#FF0000", "bold", "red"); if (cbjs.arrayContains(TIPMENU.tipMenuPrice, newItemPrice)) { cb.sendNotice("Tip Menu - " + newItemPrice + " is already on the menu. It is recommended to have different price for each item.", u, "#FFFFFF", "#FF0000"); } TIPMENU.tipMenuPrice.push(newItemPrice); TIPMENU.tipMenuItem.push(label); menuSanitize(); } break; } case "/tipmenurmv": { cmd = 1; m.background = '#d9d9d9'; if (!isMod && !isBC) { cb.sendNotice("Only mods and broadcasters can use this command.", u, "#FFFFFF", "#FF0000"); } else { let itemPrice = parseInt(message['1']); let label; let s = 2; if (isNaN(itemPrice)) { s = 1; } for (let i = s; i < message.length; i++) { if (i === s) { label = message[i]; } else { label += " " + message[i]; } } if (itemPrice <= 0) { cb.sendNotice("Error! Price must be greater than 0.", "", "#FFFFFF", "#FF0000", "bold"); return; } if (itemPrice > 0) { if (cbjs.arrayContains(TIPMENU.tipMenuPrice, itemPrice)) { if (!message[2]) { cb.sendNotice('Tip menu - No label was found! Every options that match "' + itemPrice + '" will be removed from the menu.', u, "#FFFFFF", "#FF0000", "bold"); for (let i = 0; i < TIPMENU.menuLength; i++) { if (itemPrice === TIPMENU.tipMenuPrice[i]) { TIPMENU.tipMenuPrice[i] = 0; cb.sendNotice("Tip menu to Broadcaster - " + (u === cb.room_slug ? "You" : u) + ' removed the option "' + TIPMENU.tipMenuItem[i] + '" from the menu.', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice("Tip menu to mods - " + u + ' removed the option "' + TIPMENU.tipMenuItem[i] + '" from the menu.', "", "#FFFFFF", "#FF0000", "bold", "red"); } } menuSanitize(); } else { let labelFound = false; for (let i = 0; i < TIPMENU.menuLength; i++) { if (itemPrice === TIPMENU.tipMenuPrice[i] && label === TIPMENU.tipMenuItem[i]) { labelFound = true; TIPMENU.tipMenuPrice[i] = 0; cb.sendNotice("Tip menu to Broadcaster - " + (u === cb.room_slug ? "You" : u) + ' removed the option "' + TIPMENU.tipMenuItem[i] + '" from the menu.', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice("Tip menu to mods - " + u + ' removed the option "' + TIPMENU.tipMenuItem[i] + '" from the menu.', "", "#FFFFFF", "#FF0000", "bold", "red"); menuSanitize(); } } if (!labelFound) { cb.sendNotice("Tip menu - Unable find item " + label + "(" + itemPrice + ") on the menu. Skipping.", u, "#FFFFFF", "#FF0000", "bold"); } } } else { cb.sendNotice("Tip menu - Unable find any item at " + itemPrice + " tokens on the menu.", u, "#FFFFFF", "#FF0000", "bold"); } } else { if (!label) { cb.sendNotice('Tip menu - Unable to process. Use "/tipmenurmv X Label". Where X is the amount of tokens and label is the name of the item.', u, "#FFFFFF", "#FF0000", "bold"); } else if (cbjs.arrayContains(TIPMENU.tipMenuItem, label)) { for (let i = 0; i < TIPMENU.menuLength; i++) { if (label === TIPMENU.tipMenuItem[i]) { TIPMENU.tipMenuPrice[i] = 0; cb.sendNotice("Tip menu to Broadcaster - " + (u === cb.room_slug ? "You" : u) + ' removed the option "' + TIPMENU.tipMenuItem[i] + '" from the menu.', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice("Tip menu to mods - " + u + ' removed the option "' + TIPMENU.tipMenuItem[i] + '" from the menu.', "", "#FFFFFF", "#FF0000", "bold", "red"); } } menuSanitize(); } else { cb.sendNotice("Tip menu - Unable find item " + label + " on the menu. Skipping.", u, "#FFFFFF", "#FF0000", "bold"); } } } break; } //********* Positions Tip Menu Commands case "/posmenu": { cmd = 1; if (tipMenuToggle == 1) { if (isMod) { u = ''; } cb.sendNotice(POSTIPMENU.posTipMenu, u, POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor, "bold"); } else { cb.sendNotice('The Positions Tip Menu has not been enabled.', u, green); } break; } case '/useposmenu': { cmd = 1; if (isMod || isBC) { setPosTipMenuToggle(message[1], u) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.', u,green); } break; } case "/posmenurequests": { cmd = 1; m.background = '#d9d9d9'; if (isMod) { u = ''; } let posrL = POSTIPMENU.posRequest.length; if (posrL === 0) { cb.sendNotice("There is no request at the moment.", u, POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor); } else { let cmdInt1 = 10; let posNoticeMsg; let posrS = 0; if (posrL <= cmdInt1) { posNoticeMsg = '**** Here is the list of the requests! ****\n'; cmdInt1 = posrL; posrS = 0; } else if (posrL > 10) { posNoticeMsg = '**** Here is are the last 10 requests! ****\n'; posrS = posrL - 10; } for (let i = posrS; i < posrL; i++) { posNoticeMsg += 'Position Request #' + (i + 1) + ': ' + POSTIPMENU.posRequesters[i] + ' requested ' + POSTIPMENU.posRequest[i] + '\n'; } posNoticeMsg += '**************************************'; cb.sendNotice(posNoticeMsg, u, POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor); } break; } case "/posmenuadd": { cmd = 1; m.background = '#d9d9d9'; if (!isMod && !isBC) { cb.sendNotice("Only mods and broadcasters can use this command.", u, "#FFFFFF", "#FF0000"); } else { let poslabel; let newPosItemPrice = parseInt(message['1']); if (newPosItemPrice <= 0 || isNaN(newPosItemPrice)) { cb.sendNotice('No price was given. The correct format is "/postipmenuadd X Y" where X has to be a number greater than 0. This is the amount the viewers will tip for item.', u, "#FFFFFF", "#FF0000"); return; } if (!message[2]) { cb.sendNotice('No position was given. The correct format is "/postipmenuadd X Y" where Y has to be the name of the position being added.', u, "#FFFFFF", "#FF0000"); return; } for (let j = 2; j < message.length; j++) { if (j === 2) { poslabel = message[j]; } else { poslabel += " " + message[j]; } } cb.sendNotice('Position Tip menu notification - ' + (u === cb.room_slug ? "You" : u) + ' added the option "' + poslabel + '" for ' + newPosItemPrice + ' tokens to the positions menu.', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice('Position Tip menu notification - The option "' + poslabel + '" for ' + newPosItemPrice + ' tokens was added to the Positions Tip Menu.', "", "#FFFFFF", "#FF0000", "bold", "red"); if (cbjs.arrayContains(POSTIPMENU.posTipMenuPrice, newPosItemPrice)) { cb.sendNotice("Positions Tip Menu - " + newPosItemPrice + " is already on the positions menu. It is recommended to have different price for each item.", u, "#FFFFFF", "#FF0000"); } POSTIPMENU.posTipMenuPrice.push(newPosItemPrice); POSTIPMENU.posTipMenuItem.push(poslabel); posMenuSanitize(); } break; } case "/posmenurmv": { cmd = 1; m.background = '#d9d9d9'; if (!isMod && !isBC) { cb.sendNotice("Only mods and broadcasters can use this command.", u, "#FFFFFF", "#FF0000"); } else { let posItemPrice = parseInt(message['1']); let poslabel; let s = 2; if (isNaN(posItemPrice)) { s = 1; } for (let i = s; i < message.length; i++) { if (i === s) { poslabel = message[i]; } else { poslabel += " " + message[i]; } } if (posItemPrice <= 0) { cb.sendNotice("Positions Tip menu - Error! Price to be removed must be greater than 0.", "", "#FFFFFF", "#FF0000", "bold"); } if (posItemPrice > 0) { if (cbjs.arrayContains(POSTIPMENU.posTipMenuPrice, posItemPrice)) { if (!message[2]) { cb.sendNotice('Positions Tip Menu - No position name was provided, all options that match the "' + posItemPrice + '" token price will be removed.', u, "#FFFFFF", "#FF0000", "bold"); for (let i = 0; i < POSTIPMENU.posMenuLength; i++) { if (posItemPrice === POSTIPMENU.posTipMenuPrice[i]) { POSTIPMENU.posTipMenuPrice[i] = 0; cb.sendNotice('Positions Tip Menu - ' + (u === cb.room_slug ? "You" : u) + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '".', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice('Positions Tip Menu - The option "' + POSTIPMENU.posTipMenuItem[i] + '" was removed.', "", "#FFFFFF", "#FF0000", "bold", "red"); } } posMenuSanitize(); } else { let poslabelFound = false; for (let i = 0; i < POSTIPMENU.posMenuLength; i++) { if (posItemPrice === POSTIPMENU.posTipMenuPrice[i] && label === POSTIPMENU.posTipMenuItem[i]) { poslabelFound = true; POSTIPMENU.posTipMenuPrice[i] = 0; cb.sendNotice('Positions Tip Menu - ' + (u === cb.room_slug ? "You" : u) + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '".', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice('Positions Tip Menu - The option "' + POSTIPMENU.posTipMenuItem[i] + '" was removed.', "", "#FFFFFF", "#FF0000", "bold", "red"); menuSanitize(); } } if (!poslabelFound) { cb.sendNotice('Positions Tip Menu - Unable find item ' + poslabel + '(' + posItemPrice + ') on the menu. Skipping.', u, "#FFFFFF", "#FF0000", "bold"); } } } else { cb.sendNotice('Positions Tip Menu - Unable find any item at ' + posItemPrice + ' tokens on the positions menu.', u, "#FFFFFF", "#FF0000", "bold"); } } else { if (!poslabel) { cb.sendNotice('Positions Tip Menu - Unable to process command. Use "/postipmenurmv X Y". Where X is the tip amount and Y is the name of the position.', u, "#FFFFFF", "#FF0000", "bold"); } else if (cbjs.arrayContains(POSTIPMENU.posTipMenuItem, poslabel)) { for (let i = 0; i < POSTIPMENU.posMenuLength; i++) { if (poslabel === POSTIPMENU.posTipMenuItem[i]) { POSTIPMENU.posTipMenuPrice[i] = 0; cb.sendNotice('Positions Tip Menu - ' + (u === cb.room_slug ? "You" : u) + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '".', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice('Positions Tip Menu - The option "' + POSTIPMENU.posTipMenuItem[i] + '" was removed.', "", "#FFFFFF", "#FF0000", "bold", "red"); } } posMenuSanitize(); } else { cb.sendNotice('Positions Tip Menu - Unable find item ' + poslabel + ' on the positions menu. Skipping.', u, "#FFFFFF", "#FF0000", "bold"); } } } break; } //********* Token Poll Commands case '/usepoll': { cmd = 1; if (isMod || isBC) { setTokenPollToggle(message[1], u) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } case "/poll": { cmd = 1; if (tokenPollToggle == 1) { if (isMod) { u = ""; } if (pollRunning) { showBoard(u); } else { showWinner(u); } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/endpoll": { cmd = 1; if (tokenPollToggle == 1) { if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } pollmsg("a", "", u + " has ended the poll. No more votes will be counted."); if (pollRunning) { pollRunning = false; } showWinner(""); } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/restartpoll": { cmd = 1; if (tokenPollToggle == 1) { if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } pollmsg("a", "", u + " has restarted the poll, voting has resumed."); if (!pollRunning) { pollRunning = true; pollType = "Never"; } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/addvote": { cmd = 1; if (tokenPollToggle == 1) { var amount; if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } if (isMod && !pollModAdd) { pollmsg("", u, "The broadcaster has disabled this function for mods."); break; } if (isMod || isBC) { var voteFail = true; if (!pollRunning) { pollmsg("", u, "The poll is not running, no need to vote."); break; } if (commandVar1 === 0 || commandVar2 === 0) { pollmsg("", u, 'Invalid Entry - The tip price amount and added vote amount cannot be zero. \n ex: "/addvote 10 1" will add 1 vote for the poll option with a price of 10'); break; } if (!commandVar1) { pollmsg("", u, 'Invalid Entry - A tip price amount must be specified to add votes to. \n ex: "/addvote 10 1" will add 1 vote for the poll option with a price of 10'); break; } if (!commandVar2) { amount = 1; } else { amount = commandVar2; } for (let i = 0; i < pollArrayAmount.length; i++) { if (commandVar1 === pollArrayAmount[i]) { pollmsg("a", u, u + " has " + (amount > 0 ? "added" : "removed") + " " + (amount < 0 ? -amount : amount) + " vote" + (amount === 1 || amount === -1 ? "" : "s") + " for " + pollArrayLabel[i]); pollArrayVotes[i] += amount; voteFail = false; if (pollType === "Vote") { votesRemain -= amount; } checkPollEnd(); break; } } if (voteFail) { pollmsg("w", u, 'Invalid Entry - That tip price amount is not currently in the poll. \n The first variable needs to match a tip amount on the poll, the second variable is the number of votes to add.\n ex: "/addvote 10 1" will add 1 vote for the poll option with a price of 10'); break; } } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/polloptadd": { cmd = 1; if (tokenPollToggle == 1) { var label; var oktoadd = 1; if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } if (isMod || isBC) { if (commandVar1 <= 0 || isNaN(commandVar1)) { pollmsg("w", u, "The first variable has be be a number greater than 0. This is the amount the viewers will tip to vote for this selection."); var oktoadd = 0; break; } if (!message[2]) { pollmsg("w", u, "You must include a label for this voting selection in the second variable."); var oktoadd = 0; break; } if (pollArrayAmount.length >= 8) { pollmsg("w", u, "There are already 8 entries in the poll, no more can be added."); var oktoadd = 0; break; } for (let j = 0; j < pollArrayAmount.length; j++) { if (pollArrayAmount[j] === commandVar1) { pollmsg("bm", "", "Tip Price Amount specified is already used in the poll, and will not be added to the board. Please try again with a unique tip amount."); var oktoadd = 0; break; } } for (let j = 0; j < TIPMENU.tipMenuPrice.length; j++) { if (TIPMENU.tipMenuPrice[j] === commandVar1) { pollmsg("bm", "", "Token Poll Amount specified is already used in the Tip Menu. Token Poll option has been added, but it will overlap with " + TIPMENU.tipMenuItem[j] + " so it is recommended to change the price of one or ensure the tip menu is off."); break; } } for (let i = 2; i < message.length; i++) { if (i === 2) { label = message[i]; } else { label += " " + message[i]; } } for (let j = 0; j < pollArrayLabel.length; j++) { if (pollArrayLabel[j] === label) { pollmsg("bm", "", "The Poll Option Label specified is already used in the poll, and will not be added to the board. Please try again with a unique label value."); var oktoadd = 0; break; } } if(oktoadd == 1) { populatePollArray(label,commandVar1,0); pollmsg("bm", u, u + ' added the option "' + label + '" to the poll.'); } } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/polloptrmv": { cmd = 1; if (tokenPollToggle == 1) { m.background = '#d9d9d9'; if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } if (isMod || isBC) { if (commandVar1 <= 0 || isNaN(commandVar1)) { pollmsg("w", u, "The first variable has be be a number greater than 0. This value is used to select the poll item that will be removed based on the price."); break; } if (pollArrayAmount.length <= 2) { pollmsg("w", u, "There are only 2 entries in the poll, no more can be removed."); break; } for (let i = 0; i < pollArrayAmount.length; i++) { if (pollArrayAmount[i] === commandVar1) { pollmsg("bm", u, u + ' removed the option "' + pollArrayLabel[i] + '" from the poll.'); cbjs.arrayRemove(pollArrayAmount, pollArrayAmount[i]); cbjs.arrayRemove(pollArrayLabel, pollArrayLabel[i]); pollArrayVotes[i] = 'dummy'; cbjs.arrayRemove(pollArrayVotes, 'dummy'); } } } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/pollstarttimer": { cmd = 1; if (tokenPollToggle == 1) { m.background = '#d9d9d9'; if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } if (!pollRunning) { pollmsg("w", u, "The poll is not running, unable to start a timer."); break; } if (pollType === "Timer") { if (pollMinsRemain >= 1) { pollmsg("w", u, 'A timer is already running, please use "/polladdtime [X]" to add time to timer. \nThe poll will end in ' + pollMinsRemain + ' minute' + (pollMinsRemain > 1 ? 's' : '')); } else if (pollSecsRemain >= 1) { pollmsg("w", u, 'Timer is already running, use "/polladdtime [X]" to change the remaining time. \nThe poll will end in ' + pollSecsRemain + ' seconds' + (pollSecsRemain > 1 ? 's' : '')); } break; } if (!commandVar1) { pollmsg("w", u, 'Invalid command, you need to specify the starting point for the timer in minutes. Example: use "/pollstarttimer 10" to start a 10 minute timer'); break; } if (commandVar1 > 60) { pollmsg("w", u, 'The time specified is greater than 60 minutes, please use a smaller value.'); break; } commandVar1 = parseInt(commandVar1) if (isNaN (commandVar1)) { pollmsg("w", u, 'Invalid value, the time entered must be a numeric value in minutes. Example: use "/pollstarttimer 10" to start a 10 minute timer'); break; } if (pollType !== "Timer") { pollSwitchToTimer(commandVar1, u); break; } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/polltimeleft": { cmd = 1; if (tokenPollToggle == 1) { m.background = '#d9d9d9'; if (!pollRunning) { showWinner(u); break; } if (pollType === "Timer") { cb.sendNotice(pollTimeLeft(), u, pollbackground, pollforeground, "bold"); break; } else { if (isMod || isBC) { pollmsg("", u, 'Timer is not running. If you want to start a timer use "/pollstarttimer X"'); } else { pollmsg("", u, "Timer is not running."); } break; } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/polladdtime": { cmd = 1; if (tokenPollToggle == 1) { m.background = '#d9d9d9'; if (!isMod && !isBC) { pollmsg("nm", u, ""); } else if (!pollRunning) { pollmsg("w", u, "The poll is not running, no need to add time."); } else if (!commandVar1) { pollmsg("w", u, 'Invalid command, you need to specify the amount of time to add to the timer in minutes. Example: use "/polladdtime 3" to add 3 minutes to the timer'); } else if (pollType !== "Timer") { pollmsg("w", u, 'The poll is currently configured for vote count or manual end, a timer is not valid in this mode.'); } else if (pollMinsRemain + commandVar1 <= 0) { pollmsg("w", u, 'The value is over the amount of time left. You can use "/endpoll" to stop the poll and pick the winner.'); } else if (pollMinsRemain + commandVar1 > 60) { pollmsg("w", u, 'The added time will increase the timer to greater than 60 minutes, please use a smaller value.'); } else { pollAddTime(commandVar1, u); break; } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/pollleader": { cmd = 1; if (tokenPollToggle == 1) { m.background = '#d9d9d9'; if (!pollRunning) { showWinner(u); break; } if (!isMod) { pollmsg("n", u, showLead()); break; } if (isMod) { pollmsg("", "", showLead()); break; } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/pollstoptimer": { cmd = 1; if (tokenPollToggle == 1) { if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } if (!pollRunning) { pollmsg("w", u, "The poll is not running, there is no timer running."); break; } if (pollType !== "Timer") { pollmsg("w", u, "A timer is not for this poll mode. Ignoring command."); break; } else if (pollType === "Timer") { pollType = "Never"; pollStopTimer(); pollmsg("a", u, "The timer has been canceled, switching modes to manual end. The poll will go on until stopped by the broadcaster or moderator.", "", pollbackground, pollforeground); break; } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } //********* Lush Menu Commands case "/lushmenu": { cmd = 1; if (lushMenuToggle == 1) { m.background = '#d9d9d9'; if (isMod) { u = ''; } cb.sendNotice(LUSHMENU.lushMenu, u, LUSHMENU.lushBgColor, LUSHMENU.lushTxtColor, "bold"); } else { cb.sendNotice('The Lush Menu is disabled.', u, green); } break; } case '/uselushmenu': { cmd = 1; if (isMod || isBC) { setLushMenuToggle(message[1], u) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.\nType "/fbhelp commands" to see a full list of the available commands.',msg['user'],green); } break; } //********* Media List settings case "/media": { cmd = 1; setMediaColors(); if (isMod || isBC) { sendto = ""; } else { sendto = u; } showMedia(sendto); break; } case '/usemedia': { cmd = 1; if (isMod || isBC) { setMediaToggle(message[1], u) } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.', u, green); } break; } //********* Help Menu case '/fbhelp': { cmd = 1; help(message[1],msg['user']); break; } //********* Dump config settings case "/dumpsettings": { cmd = 1; if (isMod || isBC) { cb.sendNotice( 'Dump of all current settings:' + '\n**************** Notices Controls ************************' + '\nenableEntryMessage :' + cb.settings.enableEntryMessage + '\nentryMessage :' + cb.settings.entryMessage + '\nenableNotifier :' + cb.settings.enableNotifier + '\nnotifierMessage1 :' + cb.settings.notifierMessage1 + '\nnotifierMessage2 :' + cb.settings.notifierMessage2 + '\nnotifierMessage3 :' + cb.settings.notifierMessage3 + '\nnotifierMessage4 :' + cb.settings.notifierMessage4 + '\nnotifierMessage5 :' + cb.settings.notifierMessage5 + '\nnotifierInterval :' + cb.settings.notifierInterval + '\nnotifiersTextColor :' + cb.settings.notifiersTextColor + '\nnotifiersTextCustColor :' + cb.settings.notifiersTextCustColor + '\nnotifiersBgColor :' + cb.settings.notifiersBgColor + '\nnotifiersBgCustColor :' + cb.settings.notifiersBgCustColor + '\n**************** Tip Leaders Controls ************************' + '\nenableSubjectChange :' + cb.settings.enableSubjectChange + '\nenableTipCount :' + cb.settings.enableTipCount + '\nenableTipLeaderIcons :' + cb.settings.enableTipLeaderIcons + '\nenableLeaderboard :' + cb.settings.enableLeaderboard + '\nleaderInterval :' + cb.settings.leaderInterval + '\nleaderTextColor :' + cb.settings.leaderTextColor + '\nleaderTextCustColor :' + cb.settings.leaderTextCustColor + '\nleaderBgColor :' + cb.settings.leaderBgColor + '\nleaderBgCustColor :' + cb.settings.leaderBgCustColor + '\n**************** Chat Controls ************************' + '\nsilenceList :' + cb.settings.silenceList + '\nninjaList :' + cb.settings.ninjaList + '\nniceList :' + cb.settings.niceList + '\nenablePMs :' + cb.settings.enablePMs + '\n**************** User Group Icons *********************' + '\nenableGroupIcons :' + cb.settings.enableGroupIcons + '\niconMods :' + cb.settings.iconMods + '\niconFans :' + cb.settings.iconFans + '\niconExtFans :' + cb.settings.iconExtFans + '\niconVIP :' + cb.settings.iconVIP + '\n******************** VIP List *************************' + '\nenableVIPList :' + cb.settings.enableVIPList + '\nVIPList :' + cb.settings.VIPList + '\nannounceVIP :' + cb.settings.announceVIP + '\n**************** External Fan Club ********************' + '\nenableExtFans :' + cb.settings.enableExtFans + '\nextFanList :' + cb.settings.extFanList + '\nannounceExtFans :' + cb.settings.announceExtFans + '\n**************** Blocked Word List ********************' + '\nenableWordList :' + cb.settings.enableWordList + '\nwordBlockList :' + cb.settings.wordBlockList + '\n******************* Tip Menu **************************' + '\nenableTipMenu :' + cb.settings.enableTipMenu + '\nchatNotice :' + cb.settings.chatNotice + '\nmenuDspInt :' + cb.settings.menuDspInt + '\nlistSort :' + cb.settings.listSort + '\nlistSplit :' + cb.settings.listSplit + '\nsepchar :' + cb.settings.sepchar + '\nsepcharcustom :' + cb.settings.sepcharcustom + '\nmenutxtcolor1 :' + cb.settings.menutxtcolor1 + '\nmenuCustTxtColor1 :' + cb.settings.menuCustTxtColor1 + '\nmenubgcolor1 :' + cb.settings.menubgcolor1 + '\nmenuCustBgColor1 :' + cb.settings.menuCustBgColor1 + '\nmenutxtcolor2 :' + cb.settings.menutxtcolor2 + '\nmenuCustTxtColor2 :' + cb.settings.menuCustTxtColor2 + '\nmenubgcolor2 :' + cb.settings.menubgcolor2 + '\nmenuCustBgColor2 :' + cb.settings.menuCustBgColor2 + '\nmenuitem1 :' + cb.settings.menuitem1 + '\nmenuitemprice1 :' + cb.settings.menuitemprice1 + '\nmenuitem2 :' + cb.settings.menuitem2 + '\nmenuitemprice2 :' + cb.settings.menuitemprice2 + '\nmenuitem3 :' + cb.settings.menuitem3 + '\nmenuitemprice3 :' + cb.settings.menuitemprice3 + '\nmenuitem4 :' + cb.settings.menuitem4 + '\nmenuitemprice4 :' + cb.settings.menuitemprice4 + '\nmenuitem5 :' + cb.settings.menuitem5 + '\nmenuitemprice5 :' + cb.settings.menuitemprice5 + '\nmenuitem6 :' + cb.settings.menuitem6 + '\nmenuitemprice6 :' + cb.settings.menuitemprice6 + '\nmenuitem7 :' + cb.settings.menuitem7 + '\nmenuitemprice7 :' + cb.settings.menuitemprice7 + '\nmenuitem8 :' + cb.settings.menuitem8 + '\nmenuitemprice8 :' + cb.settings.menuitemprice8 + '\nmenuitem9 :' + cb.settings.menuitem9 + '\nmenuitemprice9 :' + cb.settings.menuitemprice9 + '\nmenuitem10 :' + cb.settings.menuitem10 + '\nmenuitemprice10 :' + cb.settings.menuitemprice10 + '\nmenuitem11 :' + cb.settings.menuitem11 + '\nmenuitemprice11 :' + cb.settings.menuitemprice11 + '\nmenuitem12 :' + cb.settings.menuitem12 + '\nmenuitemprice12 :' + cb.settings.menuitemprice12 + '\nmenuitem13 :' + cb.settings.menuitem13 + '\nmenuitemprice13 :' + cb.settings.menuitemprice13 + '\nmenuitem14 :' + cb.settings.menuitem14 + '\nmenuitemprice14 :' + cb.settings.menuitemprice14 + '\nmenuitem15 :' + cb.settings.menuitem15 + '\nmenuitemprice15 :' + cb.settings.menuitemprice15 + '\nmenuitem16 :' + cb.settings.menuitem16 + '\nmenuitemprice16 :' + cb.settings.menuitemprice16 + '\nmenuitem17 :' + cb.settings.menuitem17 + '\nmenuitemprice17 :' + cb.settings.menuitemprice17 + '\nmenuitem18 :' + cb.settings.menuitem18 + '\nmenuitemprice18 :' + cb.settings.menuitemprice18 + '\nmenuitem19 :' + cb.settings.menuitem19 + '\nmenuitemprice19 :' + cb.settings.menuitemprice19 + '\nmenuitem20 :' + cb.settings.menuitem20 + '\nmenuitemprice20 :' + cb.settings.menuitemprice20 + '\nmenuitem21 :' + cb.settings.menuitem21 + '\nmenuitemprice21 :' + cb.settings.menuitemprice21 + '\nmenuitem22 :' + cb.settings.menuitem22 + '\nmenuitemprice22 :' + cb.settings.menuitemprice22 + '\nmenuitem23 :' + cb.settings.menuitem23 + '\nmenuitemprice23 :' + cb.settings.menuitemprice23 + '\nmenuitem24 :' + cb.settings.menuitem24 + '\nmenuitemprice24 :' + cb.settings.menuitemprice24 + '\nmenuitem25 :' + cb.settings.menuitem25 + '\nmenuitemprice25 :' + cb.settings.menuitemprice25 + '\nmenuitem26 :' + cb.settings.menuitem26 + '\nmenuitemprice26 :' + cb.settings.menuitemprice26 + '\nmenuitem27 :' + cb.settings.menuitem27 + '\nmenuitemprice27 :' + cb.settings.menuitemprice27 + '\nmenuitem28 :' + cb.settings.menuitem28 + '\nmenuitemprice28 :' + cb.settings.menuitemprice28 + '\nmenuitem29 :' + cb.settings.menuitem29 + '\nmenuitemprice29 :' + cb.settings.menuitemprice29 + '\nmenuitem30 :' + cb.settings.menuitem30 + '\nmenuitemprice30 :' + cb.settings.menuitemprice30 + '\n***************** Positions Menu **********************' + '\nenablePosTipMenu :' + cb.settings.enablePosTipMenu + '\nposMenuInterval :' + cb.settings.posMenuInterval + '\nposListSort :' + cb.settings.posListSort + '\nposSepChar :' + cb.settings.posSepChar + '\nposSepCharCustom :' + cb.settings.posSepCharCustom + '\nposMenuTxtColor :' + cb.settings.posMenuTxtColor + '\nposMenuCustTxtColor :' + cb.settings.posMenuCustTxtColor + '\nposMenuBgColor :' + cb.settings.posMenuBgColor + '\nposMenuCustBgColor :' + cb.settings.posMenuCustBgColor + '\nposMenuItem1 :' + cb.settings.posMenuItem1 + '\nposMenuItemPrice1 :' + cb.settings.posMenuItemPrice1 + '\nposMenuItem2 :' + cb.settings.posMenuItem2 + '\nposMenuItemPrice2 :' + cb.settings.posMenuItemPrice2 + '\nposMenuItem3 :' + cb.settings.posMenuItem3 + '\nposMenuItemPrice3 :' + cb.settings.posMenuItemPrice3 + '\nposMenuItem4 :' + cb.settings.posMenuItem4 + '\nposMenuItemPrice4 :' + cb.settings.posMenuItemPrice4 + '\nposMenuItem5 :' + cb.settings.posMenuItem5 + '\nposMenuItemPrice5 :' + cb.settings.posMenuItemPrice5 + '\nposMenuItem6 :' + cb.settings.posMenuItem6 + '\nposMenuItemPrice6 :' + cb.settings.posMenuItemPrice6 + '\nposMenuItem7 :' + cb.settings.posMenuItem7 + '\nposMenuItemPrice7 :' + cb.settings.posMenuItemPrice7 + '\nposMenuItem8 :' + cb.settings.posMenuItem8 + '\nposMenuItemPrice8 :' + cb.settings.posMenuItemPrice8 + '\n******************** Token Poll ***********************' + '\nenableTokenPoll :' + cb.settings.enableTokenPoll + '\npollTitle :' + cb.settings.pollTitle + '\npollInterval :' + cb.settings.pollInterval + '\npollMode :' + cb.settings.pollMode + '\npollCount :' + cb.settings.pollCount + '\npollTxtColor :' + cb.settings.pollTxtColor + '\npollCustTxtColor :' + cb.settings.pollCustTxtColor + '\npollBgColor :' + cb.settings.pollBgColor + '\npollCustBgColor :' + cb.settings.pollCustBgColor + '\npollFanClubDouble :' + cb.settings.pollFanClubDouble + '\npollKeepalive :' + cb.settings.pollKeepalive + '\npollModAdd :' + cb.settings.pollModAdd + '\npollOptLabel1 :' + cb.settings.pollOptLabel1 + '\npollOptTokens1 :' + cb.settings.pollOptTokens1 + '\npollOptLabel2 :' + cb.settings.pollOptLabel2 + '\npollOptTokens2 :' + cb.settings.pollOptTokens2 + '\npollOptLabel3 :' + cb.settings.pollOptLabel3 + '\npollOptTokens3 :' + cb.settings.pollOptTokens3 + '\npollOptLabel4 :' + cb.settings.pollOptLabel4 + '\npollOptTokens4 :' + cb.settings.pollOptTokens4 + '\npollOptLabel5 :' + cb.settings.pollOptLabel5 + '\npollOptTokens5 :' + cb.settings.pollOptTokens5 + '\npollOptLabel6 :' + cb.settings.pollOptLabel6 + '\npollOptTokens6 :' + cb.settings.pollOptTokens6 + '\npollOptLabel7 :' + cb.settings.pollOptLabel7 + '\npollOptTokens7 :' + cb.settings.pollOptTokens7 + '\npollOptLabel8 :' + cb.settings.pollOptLabel8 + '\npollOptTokens8 :' + cb.settings.pollOptTokens8 + '\n****************** Ticket Shows ***********************' + '\nprepticketTipMenuOff :' + cb.settings.prepticketTipMenuOff + '\nprepticketPosMenuOn :' + cb.settings.prepticketPosMenuOn + '\nprepticketStartPoll :' + cb.settings.prepticketStartPoll + '\nstartPollTimerWithShow :' + cb.settings.startPollTimerWithShow + '\nstartPollMinAfterShow :' + cb.settings.startPollMinAfterShow + '\nprepticketAddVIP :' + cb.settings.prepticketAddVIP + '\nprepticketAddExtFC :' + cb.settings.prepticketAddExtFC + '\nticketModAdd :' + cb.settings.ticketModAdd + '\nenabletlist :' + cb.settings.enabletlist + '\ntlistPrice :' + cb.settings.tlistPrice + '\nnumberFromLB :' + cb.settings.numberFromLB + '\namountFromLB :' + cb.settings.amountFromLB + '\n***************** Lush Tip Menu ***********************' + '\nenableLushMenu :' + cb.settings.enableLushMenu + '\nlushMenuInterval :' + cb.settings.lushMenuInterval + '\nlushMenuTxtColor :' + cb.settings.lushMenuTxtColor + '\nlushMenuCustTxtColor :' + cb.settings.lushMenuCustTxtColor + '\nlushMenuBgColor :' + cb.settings.lushMenuBgColor + '\nlushMenuCustBgColor :' + cb.settings.lushMenuCustBgColor + '\nlushMenuLevel1 :' + cb.settings.lushMenuLevel1 + '\nlushMenuLevel2 :' + cb.settings.lushMenuLevel2 + '\nlushMenuLevel3 :' + cb.settings.lushMenuLevel3 + '\nlushMenuLevel4 :' + cb.settings.lushMenuLevel4 + '\nlushMenuLevel5 :' + cb.settings.lushMenuLevel5 + '\nlushMenuLevel6 :' + cb.settings.lushMenuLevel6 + '\nlushMenuLevel7 :' + cb.settings.lushMenuLevel7 + '\nlushMenuLevel8 :' + cb.settings.lushMenuLevel8 + '\nlushMenuLevel9 :' + cb.settings.lushMenuLevel9 + '\nlushMenuLevel10 :' + cb.settings.lushMenuLevel10 + '\nlushMenuLevel11 :' + cb.settings.lushMenuLevel11 + '\nlushMenuLevel12 :' + cb.settings.lushMenuLevel12 + '\nlushMenuLevel13 :' + cb.settings.lushMenuLevel13 ,msg['user']); cb.sendNotice('',msg['user'],green); break; } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.',msg['user'],green); } } //********* End of Expected commands } if(message[0] == '/stopshow' || message[0] == '/showend' || message[0] == '/showover' || message[0] == '/starttimer' || message[0] == '/addtime' || message[0] == '/ctn' || message[0] == '/ctnd' || message[0] == '/ctnh' || message[0] == '/ctndh' || message[0] == '/ctsubject' || message[0] == '/tickets') { cmd = 1; } if(cmd == 0) { cb.sendNotice(message[0] + ' is not a command.\nType /fbhelp commands to see a full list of the available commands.', msg['user'], green); } } if(isNinjaSilenced) { silencedmsg = 1; } if(isSilenced && silencedmsg == 0) { silencedmsg = 1; cb.sendNotice('Your message was not sent because you have been silenced',u,green); } if(silenceLevel > 0 && !isMod && !isBC && !isNice && !isFan && !isVIP && !isExtFan && silencedmsg == 0) { switch(silenceLevel) { case 1: if(!msg['has_tokens']) { silencedmsg = 1; cb.sendNotice('Your message was not sent because the silence level has been set to only allow members with tokens to chat.',u,green); } break; case 2: if(!cbjs.arrayContains(tipCountArray.name,u)) { silencedmsg = 1; cb.sendNotice('Your message was not sent because the silence level has been set to only allow members who have tipped at least 1 token to chat.',u,green); } break; case 3: if(cbjs.arrayContains(tipCountArray.name,u)) { if(parseInt(tipCountArray.amount[findTipper(msg['user'])]) < 10) { silencedmsg = 1; cb.sendNotice('Your message was not sent because the silence level has been set to only allow members who have tipped at least 10 tokens to chat.',u,green); } } else { silencedmsg = 1; cb.sendNotice('Your message was not sent because the silence level has been set to only allow members who have tipped at least 10 tokens to chat.',u,green); } break; } } if(graphicLevel > 0 && !isMod && !isBC && !isNice && !isFan && !isVIP && !isExtFan && silencedmsg == 0) { switch(graphicLevel) { case 1: if(!msg['has_tokens']) { for(var i = 0; i < message.length; i++) { if(message[i].charAt(0) == ':') { silencedmsg = 1; cb.sendNotice('Your message was not displayed because the graphic level has been set to only allow users with tokens to use graphics.',msg['user'],green); } } } break; case 2: if(parseInt(tipCountArray.amount[findTipper(u)]) == 0) { for(var i = 0; i < message.length; i++) { if(message[i].charAt(0) == ':') { silencedmsg = 1; cb.sendNotice('Your message was not displayed because the graphic level has been set to only allow users who have tipped to use graphics.',msg['user'],green); } } } break; case 3: if(cbjs.arrayContains(tipCountArray.name,u)) { if(parseInt(tipCountArray.amount[findTipper(msg['user'])]) < 10) { for(var i = 0; i < message.length; i++) { if(message[i].charAt(0) == ':') { silencedmsg = 1; cb.sendNotice('Your message was not displayed because the graphic level has been set to only allow members who have tipped at least 10 tokens to use graphics.',msg['user'],green); } } } } else { silencedmsg = 1; cb.sendNotice('Your message was not sent because the graphic level has been set to only allow members who have tipped at least 10 tokens to use graphics.',msg['user'],green); } break; } } // ********** Convert to lower case var caps = /[A-Z][A-Z]+/; if (!isMod && !isBC) { if (caps.test(m)) { m = m.toLowerCase(); msg['m'] = m; cb.sendNotice('Message converted to lower case, please do not type in all CAPS!',msg['user'],green); } } // ********** Suppress messages containing blocked word if (!isMod && !isBC) { if(cb.settings.enableWordList == 'Yes' && wordListArray.length > 0) { var d = msg['m']; MessageArray = d.split(' '); for (var i = 0; i < MessageArray.length; i++) { if (cbjs.arrayContains(wordListArray, MessageArray[i])) { silencedmsg = 1; cb.sendNotice('Your message was not displayed because it contains words in the blocked word list. Please refrain from rude language. You can view blocked words with the command /wordlist.',msg['user'],green); } } } } // ********** Add message prefix if needed if(message[0].charAt(0) != "/" && message[0].charAt(0) != "!") { grp = null; posn = 0; tipcount = 0; if(tipCountToggle == 1 && cbjs.arrayContains(tipCountArray.name,msg['user'])) { tipcount = parseInt(tipCountArray.amount[findTipper(msg['user'])]); } if(groupIconsToggle == 1) { if (isMod) { grp = "mods"; } else if (isFan) { grp = "fans"; } else if (cbjs.arrayContains(extFanListArray,msg['user'])) { grp = "extfans"; } else if (cbjs.arrayContains(VIPListArray,msg['user'])) { grp = "VIP"; } } if (tipLeaderIconsToggle == 1 && cbjs.arrayContains(tipCountArray.name,u)) { sortTippers(); for (var i = 1; i <= tipCountArray.name.length; i++) { if(tipCountArray.name[i-1] == u) { break; } } lbposn = i; if (lbposn >= 1 && lbposn <= 3) { posn = lbposn; } } if (tipcount > 0 || grp != null || posn > 0) { pfxgrpicon = null; pfxcount = null; pfxtipleader = null; switch (grp) { case "mods": pfxgrpicon = cb.settings.iconMods; break; case "fans": pfxgrpicon = cb.settings.iconFans; break; case "extfans": pfxgrpicon = cb.settings.iconExtFans; break; case "VIP": pfxgrpicon = cb.settings.iconVIP; break; } switch (posn) { case 1: pfxtipleader = cb.settings.tipLeaderGif1; break; case 2: pfxtipleader = cb.settings.tipLeaderGif2; break; case 3: pfxtipleader = cb.settings.tipLeaderGif3; break; } if (tipcount > 0) { pfxcount = '|' + tipCountArray.amount[findTipper(msg['user'])] + '| '; } msg.m = (pfxgrpicon != null ? pfxgrpicon + " " : "") + (pfxtipleader != null ? pfxtipleader + " " : "") + (pfxcount != null ? pfxcount : "") + msg.m; } } if(silencedmsg == 1) { msg['X-Spam'] = true; } return msg; }); } // *********************************** Actions on user entering ************************************** { cb.onEnter(function(user) { // Variables var u = user.user; var isMod = (cb.room_slug === u || user.is_mod); var isFan = user.in_fanclub; var menuMsgOnEnter = 'Hello ' + u + ', a Tip Menu is currently active in this room. Menu may display periodically or you can see the menu at anytime by typing "/tipmenu".'; var posmenuMsgOnEnter = 'The Positions Tip Menu is currently active in this room. Menu may display periodically or you can see the menu at anytime by typing "/postipmenu".'; var pollMsgOnEnter = 'Hello ' + u + ', a Token Poll is currently active in this room.'; if(isMod && !cbjs.arrayContains(moderatorList,user)) { populateModeratorArray(user['user'], "mod"); } // **** General Entry Message if(cb.settings.enableEntryMessage == 'Yes') { cb.sendNotice(cb.settings.entryMessage,user['user'],green,"","bold"); } // **** Tip Menu Message if(tipMenuToggle == 1) { if (isMod) { menuMsgOnEnter += ' Type "/fbhelp tipmenu" to see all the commands.'; } cb.sendNotice(menuMsgOnEnter, u, TIPMENU.bgColor1, TIPMENU.txtColor1, "bold"); } // **** Positions Menu Message if(posTipMenuToggle == 1) { cb.sendNotice(posmenuMsgOnEnter, u, POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor, "bold"); } // **** Lush Menu Message if(lushMenuToggle == 1) { cb.sendNotice('Welcome, the Lush is active, please use the Lush Tip Menu Ranges to control the toy.', u, LUSHMENU.lushBgColor, LUSHMENU.lushTxtColor, "bold"); } // **** Announce VIPs if(cb.settings.announceVIP == 'Yes' && cbjs.arrayContains(VIPListArray,u)) { temptextcolor = checkTextColor("Dark Blue"); tempbgcolor = checkBgColor("Light Blue"); cb.sendNotice('Welcome VIP member ' + u + ' to our room!', '', tempbgcolor, temptextcolor, "bold"); }'announceVIP' // **** Announce External Fan Club members if(cb.settings.announceExtFans == 'Yes' && cbjs.arrayContains(extFanListArray,u)) { temptextcolor = checkTextColor("Dark Green"); tempbgcolor = checkBgColor("Light Green"); cb.sendNotice('Welcome Fan Club member ' + u + ' to our room!', '', tempbgcolor, temptextcolor, "bold"); }'announceVIP' // **** Token Poll Message if(tokenPollToggle == 1) { if (isMod) { pollMsgOnEnter += ' Type "/fbhelp tokenpoll" to see all the commands.'; } if (isFan && fanDouble) { pollMsgOnEnter += ' Fan Club members get double vote today!'; } cb.sendNotice(pollMsgOnEnter, u, pollbackground, pollforeground, "bold"); } }); } // *********************************** Actions upon tipping ************************************** { cb.onTip(function (tip) { var tipAmount = Number.parseInt(tip.amount, 10); var u = tip.from_user var isFan = tip.from_user_in_fanclub; var voteAmount = 1; // ***** Tip Count Array if (!cbjs.arrayContains(tipCountArray.name, u)) { populateTipCountArray(u,tipAmount); } else { tipCountArray.amount[findTipper(u)] += tipAmount; } // ***** Tip Menu for (let i = 0; i < TIPMENU.menuLength; i++) { if (tipAmount === TIPMENU.tipMenuPrice[i]) { TIPMENU.requesters.push(tip.from_user); TIPMENU.request.push(TIPMENU.tipMenuItem[i]); cb.sendNotice(u + ' tipped for ' + TIPMENU.tipMenuItem[i], '', TIPMENU.bgColor1, TIPMENU.txtColor1, "bold"); } } for (let i = 0; i < POSTIPMENU.posMenuLength; i++) { if (tipAmount === POSTIPMENU.posTipMenuPrice[i]) { POSTIPMENU.posRequesters.push(tip.from_user); POSTIPMENU.posRequest.push(POSTIPMENU.posTipMenuItem[i]); cb.sendNotice(u + ' tipped for ' + POSTIPMENU.posTipMenuItem[i], '', POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor, "bold"); } } // ***** Lush Menu // // for (let i = 0; i < LUSHMENU.lushMenuLevel; i++) { // if (tipAmount <= LUSHMENU.lushLevelPrice[i]) { // cb.sendNotice(u + ' tipped for ' + LUSHMENU.lushMenuLevel[i], '', LUSHMENU.lushBgColor, LUSHMENU.lushTxtColor, "bold"); // } // } // // ***** Ticket Show Backup List if (tlistToggle == 1 && !cbjs.arrayContains(tlistArray,u)) { updateTicketBackupList("addtip", u, tipAmount); } // ***** Token Poll if (isFan && fanDouble && tokenPollToggle == 1) { voteAmount = 2; pollmsg('', u, 'Since you are a member of the fan club, your votes will be doubled.'); } for (let i = 0; i < pollArrayAmount.length; i++) { if(tokenPollToggle == 1 && pollRunning) { if (tipAmount === pollArrayAmount[i]) { pollArrayVotes[i] += voteAmount; if (voteAmount === 1) { cb.sendNotice(u + " voted for " + pollArrayLabel[i], "", pollbackground, pollforeground, "bold"); } else { cb.sendNotice(u + " voted " + voteAmount + " time" + (voteAmount === 1 ? "" : "s") + " for " + pollArrayLabel[i], "", pollbackground, pollforeground, "bold"); } if (pollType === "Vote") { votesRemain -= voteAmount; } if (pollType === "Timer" && cb.settings.pollKeepalive === "Yes" && pollSecsRemain < 30) { pollStopTime = new Date(pollStopTime.getTime() + 30000); pollSecsRemain = pollSecsRemain + 30; cb.sendNotice('The token poll timer is set to keep alive with continued voting, 30 seconds have been added to the timer. Now ' + pollTimeLeft(), "", pollbackground, pollforeground, "bold"); if (aliveWarned) { aliveWarning(); } } checkPollEnd(); } } } }); } // *********************************** Initialize ************************************** { if(initialize == 0) { if(cb.settings.enableLeaderboard == 'Yes') { leaderboardToggle = 1; sendLeaderboard(); } if(cb.settings.enableNotifier == 'Yes') { notifierToggle = 1; rotcnt = 0; notifierTimer(); } if(cb.settings.enableTipCount == 'Yes') { tipCountToggle = 1; } if(cb.settings.niceList != '' && cb.settings.niceList != null) { var n = cb.settings.niceList; niceListArray = n.split(','); } if(cb.settings.silenceList != '' && cb.settings.silenceList != null) { var n = cb.settings.silenceList; silenceListArray = n.split(','); } if(cb.settings.ninjaList != '' && cb.settings.ninjaList != null) { var n = cb.settings.ninjaList; ninjaListArray = n.split(','); } if(cb.settings.tlistPrice != null) { let tlistPrice = parseInt(cb.settings.tlistPrice); } if(cb.settings.noticeColor != '' && cb.settings.niceList != null) { switch(cb.settings.noticeColor) { case 'Red': noticeColor = HLred; break; case 'Yellow': noticeColor = HLyellow; break; case 'Green': noticeColor = HLgreen; break; case 'Blue': noticeColor = HLblue; break; case 'Purple': noticeColor = HLpurple; break; } } if(cb.settings.enableTipMenu == 'Yes') { tipMenuToggle = 1; initMenu(); } if(cb.settings.enablePosTipMenu == 'Yes') { posTipMenuToggle = 1; initPosMenu(); } if(cb.settings.enableTokenPoll == 'Yes') { tokenPollToggle = 1; initTokenPoll(); } if(cb.settings.enableLushMenu == 'Yes') { lushMenuToggle = 1; initLushMenu(); } if(cb.settings.enableGroupIcons == 'Yes') { groupIconsToggle = 1; } if(cb.settings.enableTipLeaderIcons == 'Yes') { tipLeaderIconsToggle = 1; } if(cb.settings.enableMediaNotice == 'Yes') { mediaToggle = 1; sendMediaList(); } if(cb.settings.wordBlockList != '' && cb.settings.wordBlockList != null) { var a = cb.settings.wordBlockList; wordListArray = a.split(','); } if(cb.settings.extFanList != '' && cb.settings.extFanList != null) { var b = cb.settings.extFanList; extFanListArray = b.split(','); } if(cb.settings.VIPList != '' && cb.settings.VIPList != null) { var c = cb.settings.VIPList; VIPListArray = c.split(','); } populateModeratorArray(cb.room_slug, "bc"); cb.sendNotice('Grey users are unable to use graphics by default. If you would like grey users to be able to use graphics, type "/graphiclevel 0" to enable.', cb.room_slug, green); initialize = 1; } }
© Copyright Chaturbate 2011- 2026. All Rights Reserved.