Bots Home
|
Create an App
Dorothy's Ultra Fembot - Show 2
Author:
dorothy
Description
Source Code
Launch Bot
Current Users
Created by:
Dorothy
/** Name: Dorothy's Ultra Fembot Author: chelsea2950 Current version 1.0 Created 11/29/2018 Last Updated 12/2/2018 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 I know he 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 (whispers) 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 User Group icons next to name 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 = [ // *** Tip Count and Leaderboard {name: 'enableLeaderboard', label: 'Display the leaderboard in the chat (top 5 tippers in current session)?', 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: 'leaderInterval', label: 'Leaderboard display interval (minutes):', type: 'int', minValue: 1, maxValue: 60, defaultValue: 5}, {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'}, // *** Messages and Notifications {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?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'notifierMessage', label: 'Enter the notification message you would like to display.', type: 'str', minLength: 1, maxLength: 1000, defaultValue: 'Please treat others with kindness!'}, {name: 'notifierInterval', label: 'Notification display interval (minutes):', type: 'int', minValue: 1, maxValue: 60, defaultValue: 5}, {name: 'noticeColor', label: 'Background color used for Notifier Highlighting (cnh and cndh commands):', type: 'choice', choice1: 'Yellow', choice2: 'Green', choice3: 'Blue', choice4: 'Red', choice5: 'Purple', defaultValue: 'Blue'}, // *** Chat Controls {name: 'silenceList', label: 'Enter the names of any users you would like to ensure can never chat in your room. 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: '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: 'enableVIPList', label: 'Enable VIP List Privileges (PMs, Ticket Shows).', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {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}, // *** External Fan Club List {name: 'enableExtFans', label: 'Enable External Fan Club Privileges (PMs, Ticket Shows).', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {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}, // *** Blocked Word List {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', required: false}, // *** Tip Menu {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: 'str',label: 'Choose your text color for the single menu or part 1 of the split menu using the hex code (default is red/pink #F10060)',required: false,defaultValue: '#F10060'}, {name: 'menubgcolor1',type: 'str',label: 'Choose the background color for the above using the hex code (default is white #FFFFFF)',required: false,defaultValue: '#FFFFFF'}, {name: 'menutxtcolor2',type: 'str',required: false,label: 'Choose your text color for part 2 of the split menu using the hex code (default is again red/pink #F10060)',defaultValue: '#F10060'}, {name: 'menubgcolor2',type: 'str',required: false,label: 'Choose the background color for the above using the hex code (default is again white #FFFFFF)',defaultValue: '#FFFFFF'}, {name: 'menuitem1',type: 'str',defaultValue: 'Menu Item 1',label: "Tip Menu Item 1 "}, {name: 'menuitemprice1',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 50,label: 'Item 1 price'}, {name: 'menuitem2',type: 'str',required: false,label: 'Tip Menu Item 2'}, {name: 'menuitemprice2',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 2 price'}, {name: 'menuitem3',type: 'str',required: false,label: 'Tip Menu Item 3'}, {name: 'menuitemprice3',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 3 price'}, {name: 'menuitem4',type: 'str',required: false,label: 'Tip Menu Item 4'}, {name: 'menuitemprice4',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,required: false,label: 'Item 4 price'}, {name: 'menuitem5',type: 'str',required: false,label: 'Tip Menu Item 5'}, {name: 'menuitemprice5',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 0,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: '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: 'str',label: 'Choose your text color for the positions menu using the hex code (default is red/pink #F10060)',required: false,defaultValue: '#F10060'}, {name: 'posMenuBgColor',type: 'str',label: 'Choose the background color for the above using the hex code (default is white #FFFFFF)',required: false,defaultValue: '#FFFFFF'}, {name: 'posMenuItem1',type: 'str',defaultValue: 'Doggy Style',label: "Positions Tip Menu Item 1 "}, {name: 'posMenuItemPrice1',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 99,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: 99,required: false,label: 'Positions Item 2 price'}, {name: 'posMenuItem3',type: 'str',required: false,defaultValue: 'Missionary',label: 'Positions Tip Menu Item 3'}, {name: 'posMenuItemPrice3',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 99,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: 99,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: 99,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: 99,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: 99,required: false,label: 'Positions Item 7 price'}, {name: 'posMenuItem8',type: 'str',required: false,defaultValue: 'Doggy Style POV',label: 'Positions Tip Menu Item 8'}, {name: 'posMenuItemPrice8',type: 'int',minValue: 0,maxValue: 99999,defaultValue: 99,required: false,label: 'Positions Item 8 price'}, // *** Token Poll {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: "poll_title",type: "str",minLength: 1,maxLength: 255,label: "Poll Title (what will people be voting for?)"}, {name: "board_interval",type: "int",minValue: 2,default: 3,label: "Display Interval for Token Pol vote summary (in minutes)"}, {name: "poll_mode",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: "poll_count",type: "int",minValue: 1,default: 15,label: "Per above choice for Poll Type, choose value for X (in minutes or votes) "}, {name: "aggresiveTimer",type: "choice",label: "When the timer is about to end, how often do you want it to post in chat",choice1: 'At 1 min left',choice2: 'Every 15 seconds under 1 min',choice3: 'Every 15 and 5,4,3,2,1 seconds left',defaultValue: 'Every 15 and 5,4,3,2,1 seconds left'}, {name: "pollTxtColor",type: "choice",label: "Poll text color",choice1: "White",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Blue",choice5: "Dark Pink",choice6: "Dark Red",choice7: "Dark Green",choice8: "Dark Purple",choice9: "Dark Orange",choice10: "Dark Grey",choice11: "Light Blue",choice12: "Light Pink",choice13: "Light Red",choice14: "Light Green",choice15: "Light Purple",choice16: "Light Orange",choice17: "Light Grey",choice18: "Indigo",choice19: "Custom",defaultValue: "White"}, {name: "pollCustTxtColor",type: "str",minLength: 1,maxLength: 7,label: "If you picked custom text color. (Hex color codes start with #):",defaultValue: "#FFFFFF",required: false}, {name: "pollBgColor",type: "choice",label: "Poll background color",choice1: "White",choice2: "Black",choice3: "Dark Grey",choice4: "Dark Blue",choice5: "Dark Pink",choice6: "Dark Red",choice7: "Dark Green",choice8: "Dark Purple",choice9: "Dark Orange",choice10: "Dark Grey",choice11: "Light Blue",choice12: "Light Pink",choice13: "Light Red",choice14: "Light Green",choice15: "Light Purple",choice16: "Light Orange",choice17: "Light Grey",choice18: "Indigo",choice19: "Custom",defaultValue: "Indigo"}, {name: "pollCustBgColor",type: "str",minLength: 1,maxLength: 7,label: "If you picked custom background color in the previous setting:",defaultValue: "#0629AC",required: false}, {name: "optFanClub",type: "choice",choice1: "Yes",choice2: "No",defaultValue: "No",label: "Fan club members vote counts double?"}, {name: "opt_keepalive",type: "choice",choice1: "Yes",choice2: "No",defaultValue: "No",label: "When on a timer, keep the poll alive if people are tipping?"}, {name: "opt_modadd",type: "choice",choice1: "Yes",choice2: "No",defaultValue: "Yes",label: "Allow a moderator to add or remove votes?"}, {name: "opt1_label",type: "str",minLength: 1,maxLength: 255,label: "Option 1"}, {name: "opt1_tokens",type: "int",minValue: 1,default: 10,label: "Option 1 tokens"}, {name: "opt2_label",type: "str",minLength: 1,maxLength: 255,label: "Option 2"}, {name: "opt2_tokens",type: "int",minValue: 1,default: 11,label: "Option 2 tokens"}, {name: "opt3_label",type: "str",minLength: 1,maxLength: 255,label: "Option 3",required: false}, {name: "opt3_tokens",type: "int",minValue: 0,default: 0,label: "Option 3 tokens",required: false}, {name: "opt4_label",type: "str",minLength: 1,maxLength: 255,label: "Option 4",required: false}, {name: "opt4_tokens",type: "int",minValue: 0,default: 0,label: "Option 4 tokens",required: false}, {name: "opt5_label",type: "str",minLength: 1,maxLength: 255,label: "Option 5",required: false}, {name: "opt5_tokens",type: "int",minValue: 0,default: 0,label: "Option 5 tokens",required: false}, {name: "opt6_label",type: "str",minLength: 1,maxLength: 255,label: "Option 6",required: false}, {name: "opt6_tokens",type: "int",minValue: 0,default: 0,label: "Option 6 tokens",required: false}, {name: "opt7_label",type: "str",minLength: 1,maxLength: 255,label: "Option 7",required: false}, {name: "opt7_tokens",type: "int",minValue: 0,default: 0,label: "Option 7 tokens",required: false}, {name: "opt8_label",type: "str",minLength: 1,maxLength: 255,label: "Option 8",required: false}, {name: "opt8_tokens",type: "int",minValue: 0,default: 0,label: "Option 8 tokens",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 startTime = 0; var timerDuration = 0; var timeAdded = 0; var notifierToggle = 0; var tipMenuToggle = 0; var posTipMenuToggle = 0; var tokenPollToggle = 0; var leaderToggle = 0; var tipCountToggle = 0; var numberOfTippers = 0; var firstlb = 0; var leaderTimer = 0; var num = 0; // **** 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: "", posMenuToken: 1, posTipMenuPrice: [], posTipMenuItem: [], posInitToken: true, posTxtColor: "", posBgColor: "", posMenuLength: 0, posRequesters: [], posRequest: [], }; // Substitutes for CB settings and inputs */ var notifierMessage = cb.settings.notifierMessage; var BC = cb.room_slug; /* Create 'BC' shortcut for broadcaster name */ var leaderInt = parseInt(cb.settings.leaderInterval) * 60000; // Arrays */ var tipCountArray = []; var niceListArray = []; var silenceListArray = []; var ninjaListArray = []; var VIPListArray = []; var extFanListArray = []; var wordListArray = []; var pmArray = []; var moderatorList = { name: [], type: [] } var tipperList = { name: [], amount: [] }; var blockedWords = []; 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("-"); /* Dash line */ // ************ Variables for Token Poll // For colours. var pollforeground; var pollbackground; var pollwarnLight = "#FF0000"; var pollwarnDark = "#FFFFFF"; // To pick what type of poll var pollType; // Option on the board var optVotes = [0, 0, 0, 0, 0, 0, 0, 0]; var optLabels = [cb.settings.opt1_label, cb.settings.opt2_label, cb.settings.opt3_label, cb.settings.opt4_label, cb.settings.opt5_label, cb.settings.opt6_label, cb.settings.opt7_label, cb.settings.opt8_label]; var optTokens = [cb.settings.opt1_tokens, cb.settings.opt2_tokens, cb.settings.opt3_tokens, cb.settings.opt4_tokens, cb.settings.opt5_tokens, cb.settings.opt6_tokens, cb.settings.opt7_tokens, cb.settings.opt8_tokens]; // Options about voting var fanDouble = (cb.settings.optFanClub === "Yes"); var modAdd = (cb.settings.opt_modadd === "Yes"); var tokensLength = optTokens.length; //Stuff about time var startTime; var stopTime; var minsRemain = cb.settings.poll_count; var secsRemain = 60; var votesRemain = cb.settings.poll_count; var pollRunning = false; var aliveWarned = false; var timeAddedB = false; var timeAddedT = false; var pollShow = false; var nline = 0; } { // *********************************** Start Functions ************************************** { function populateTipCountArray(user) { tipCountArray[numberOfTippers] = []; tipCountArray[numberOfTippers][0] = user; tipCountArray[numberOfTippers][1] = 0; numberOfTippers++; } function populateTipperList(user, tip) { tipperList.name.push(user); tipperList.amount.push(tip); } function findTipper(user) { for (var i = 0; i < tipCountArray.length; i++) { if(tipCountArray[i][0] == user) { break; } } if (i == tipCountArray.length) { populateTipCountArray(user); findTipper(user); } return i; } function displayTipCount(user, message) { var m = '|' + tipCountArray[findTipper(user)][1] + '| ' + message; return m; } function displayGroupIcon(group, message) { switch (group) { case "mods": { var m = cb.settings.iconMods + message; break; } case "fans": { var m = cb.settings.iconFans + message; break; } case "extfans": { var m = cb.settings.iconExtFans + message; break; } case "VIP": { var m = cb.settings.iconVIP + message; break; } } return m; } function setRoomSubject(newSubject, user) { cb.changeRoomSubject(newSubject); cb.sendNotice(user + ' has updated the room title to "' + newSubject + '".', '', green); } function sendLeaderboard() { if(firstlb == 0) { leaderTimer = leaderInt - 30000; firstlb = 1 } else { leaderTimer = leaderInt; } cb.setTimeout(leaderboardTimer, leaderTimer); } function leaderboardTimer() { if(leaderboardToggle == 1) { sortTippers(); var outString = ""; for (var i = 1; i <= 5; i++) { if (tipperList.name[i - 1] == null) outString += " " + i + ". empty" + "\n"; else outString += " " + i + ". " + '"' + tipperList.name[i - 1] + '"' + ": " + tipperList.amount[i - 1] + "\n"; } cb.sendNotice(dashLine + "\n\u2606 \u2606 \u2606 LEADERBOARD \u2606 \u2606 \u2606\n" + outString + dashLine, "", '#d1eaee', '#111111', "bold"); sendLeaderboard(); } } function showLeaderBoard(from, group) { if(leaderboardToggle == 1) { sortTippers(); var outString = ""; for (var i = 1; i <= 5; i++) { if (tipperList.name[i - 1] == null) outString += " " + i + ". empty" + "\n"; else outString += " " + i + ". " + '"' + tipperList.name[i - 1] + '"' + ": " + tipperList.amount[i - 1] + "\n"; } cb.sendNotice(dashLine + "\n\u2606 \u2606 \u2606 LEADERBOARD \u2606 \u2606 \u2606\n" + outString + dashLine, from, '#d1eaee', '#111111', "bold", group); } else { cb.sendNotice('The broadcaster has decided not to use the Leaderboard feature.',from,green); } } function sortTippers() { var swapped, temp1, temp2; do { swapped = false; for (var i = 0; i < tipperList.amount.length - 1; i++) { if (tipperList.amount[i] < tipperList.amount[i + 1]) { temp1 = tipperList.amount[i]; temp2 = tipperList.name[i]; tipperList.amount[i] = tipperList.amount[i + 1]; tipperList.amount[i + 1] = temp1; tipperList.name[i] = tipperList.name[i + 1]; tipperList.name[i + 1] = temp2; swapped = true; } } } while (swapped); } function showTippers(from,group,num) { sortTippers(); var outString = ""; for (var i = 1; i <= num; i++) { if (tipperList.name[i - 1] == null) outString += "\u25ba " + i + ". --" + "\n"; else outString += "\u25ba " + i + ". " + '"' + tipperList.name[i - 1] + '"' + ": " + tipperList.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; } } function populateNiceArray(user) { if (!cbjs.arrayContains(niceListArray, user)) niceListArray.push(user); else return; } function populateSilenceArray(user) { if (!cbjs.arrayContains(silenceListArray, user)) silenceListArray.push(user); else return; } function populateNinjaArray(user) { if (!cbjs.arrayContains(ninjaListArray, user)) ninjaListArray.push(user); else return; } function populatePMArray(user) { pmArray[numPMs] = new Array; pmArray[numPMs][0] = user; pmArray[numPMs][1] = ''; numPMs++; } function findPM(user) { for(var i = 0; i < pmArray.length; i++) { if(pmArray[i][0] == user) { break; } } if(i == pmArray.length) { populatePMArray(user); findPM(user); } return i; } 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); } } function ninja(user, mod) { 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) { populateNinjaArray(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); } } function unninja(user, mod) { 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 silence(user, mod) { if(cbjs.arrayContains(silenceListArray,user)) { cb.sendNotice(user + ' has already been silenced.', mod, green); } else if(!cbjs.arrayContains(moderatorList,user) && user != cb.room_slug) { populateSilenceArray(user); cb.sendNotice('You have added ' + user + ' to the silence list.', 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); } } function unsilence(user, mod) { if(cbjs.arrayContains(silenceListArray,user)) { cbjs.arrayRemove(silenceListArray,user); cb.sendNotice('You have removed ' + user + ' from the silence list.', 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 startTimer(t, mod) { //there is no timer already running if(startTime == 0 && timeAdded == 0) { //verify a valid option was sent with /startclock if(t >= 0 && t.toString().indexOf('.') == -1) { timerDuration = t; //notice of timer start if(mod != null) { cb.sendNotice(mod + ' has set a timer for ' + timerDuration + ' minutes!','',green); } var millis = timerDuration * 60000; var fifteenMinutes = millis - 900000; var tenMinutes = millis - 600000; var fiveMinutes = millis - 300000; var fourMinutes = millis - 240000; var threeMinutes = millis - 180000; var twoMinutes = millis - 120000; var oneMinute = millis - 60000; var thirtySeconds = millis - 30000; cb.setTimeout(timer,millis); if(fifteenMinutes > 0) { cb.setTimeout(fifteenMinuteWarning,fifteenMinutes); } if(tenMinutes > 0) { cb.setTimeout(tenMinuteWarning,tenMinutes); } if(fiveMinutes > 0) { cb.setTimeout(fiveMinuteWarning,fiveMinutes); } if(fourMinutes > 0) { cb.setTimeout(fourMinuteWarning,fourMinutes); } if(threeMinutes > 0) { cb.setTimeout(threeMinuteWarning,threeMinutes); } if(twoMinutes > 0) { cb.setTimeout(twoMinuteWarning,twoMinutes); } if(oneMinute > 0) { cb.setTimeout(oneMinuteWarning,oneMinute); } if(thirtySeconds > 0) { cb.setTimeout(thirtySecondWarning,thirtySeconds); } startTime = new Date(); } else if(t != null) { cb.sendNotice(t + ' is not a valid option for /startclock.\nType /fbhelp startclock to see how to use the /startclock command.',mod,green); } else if(t == null) { cb.sendNotice('You did not enter a valid option for /startclock.\nType /fbhelp startclock to see how to use the /startclock command.',mod,green); } } else if(startTime != 0 && timeAdded != 0 && mod == null) { timeAdded = 0; timerDuration = t; var millis = timerDuration * 60000; var fifteenMinutes = millis - 900000; var tenMinutes = millis - 600000; var fiveMinutes = millis - 300000; var fourMinutes = millis - 240000; var threeMinutes = millis - 180000; var twoMinutes = millis - 120000; var oneMinute = millis - 60000; var thirtySeconds = millis - 30000; cb.setTimeout(timer,millis); if(fifteenMinutes > 0) { cb.setTimeout(fifteenMinuteWarning,fifteenMinutes); } if(tenMinutes > 0) { cb.setTimeout(tenMinuteWarning,tenMinutes); } if(fiveMinutes > 0) { cb.setTimeout(fiveMinuteWarning,fiveMinutes); } if(fourMinutes > 0) { cb.setTimeout(fourMinuteWarning,fourMinutes); } if(threeMinutes > 0) { cb.setTimeout(threeMinuteWarning,threeMinutes); } if(twoMinutes > 0) { cb.setTimeout(twoMinuteWarning,twoMinutes); } if(oneMinute > 0) { cb.setTimeout(oneMinuteWarning,oneMinute); } if(thirtySeconds > 0) { cb.setTimeout(thirtySecondWarning,thirtySeconds); } } else if(startTime != 0 && timeAdded == 0 || startTime != 0 && timeAdded != 0 && mod != null) { cb.sendNotice('There is a timer running already.', mod, green); } } function timer() { //check to see if /addClock has been used if(timeAdded == 0) { cb.sendNotice('\u23f0 ' + 'Time is up!','', yellow, '', "bold"); startTime = 0; timerDuration = 0; } else { if(timeAdded == 5) { cb.sendNotice('\u23f1 ' + 'There are 5 minutes remaining!','',yellow, '', "bold"); } startTimer(timeAdded); } } function fifteenMinuteWarning() { if(timeAdded == 0) { cb.sendNotice('\u23f1 ' + 'There are 15 minutes remaining!','', yellow, '', "bold"); } } function tenMinuteWarning() { if(timeAdded == 0) { cb.sendNotice('\u23f1 ' + 'There are 10 minutes remaining!','',yellow, '', "bold"); } } function fiveMinuteWarning() { if(timeAdded == 0) { cb.sendNotice('\u23f1 ' + 'There are 5 minutes remaining!','',yellow, '', "bold"); } } function fourMinuteWarning() { if(timeAdded == 0) { cb.sendNotice('\u23f1 ' + 'There are 4 minutes remaining!','',yellow, '', "bold"); } } function threeMinuteWarning() { if(timeAdded == 0) { cb.sendNotice('\u23f1 ' + 'There are 3 minutes remaining!','',yellow, '', "bold"); } } function twoMinuteWarning() { if(timeAdded == 0) { cb.sendNotice('\u23f1 ' + 'There are 2 minutes remaining!','',yellow, '', "bold"); } } function oneMinuteWarning() { if(timeAdded == 0) { cb.sendNotice('\u23f1 ' + 'There is 1 minute remaining!','',red, '', "bold"); } } function thirtySecondWarning() { if(timeAdded == 0) { cb.sendNotice('\u23f1 ' + 'There are 30 seconds remaining!', '', red, '', "bold"); } } function timeLeft(user) { if(startTime != 0) { var currentTime = new Date(); var timeLeft = startTime.getHours()*3600 + startTime.getMinutes()*60 + startTime.getSeconds() + timerDuration*60 - currentTime.getHours()*3600 - currentTime.getMinutes()*60 - currentTime.getSeconds(); var hours = timeLeft/3600; hours = Math.floor(hours); var minutes = (timeLeft-hours*3600)/60; minutes = Math.floor(minutes); var seconds = timeLeft-hours*3600-minutes*60; minutes += timeAdded; //fix numbers after timeAdded if(hours < 0) { hours = 0; minutes = 0; } if(hours > 0) { if(hours > 9) { if(minutes > 9 && seconds > 9) { cb.sendNotice('Time Remaining: ' + hours + ':' + minutes + ':' + seconds,user,yellow); } else if(minutes > 9 && seconds <= 9) { cb.sendNotice('Time Remaining: ' + hours + ':' + minutes + ':0' + seconds,user,yellow); } else if(minutes <= 9 && seconds > 9) { cb.sendNotice('Time Remaining: ' + hours + ':' + minutes + ':' + seconds,user,yellow); } else if(minutes <= 9 && seconds <= 9) { cb.sendNotice('Time Remaining: ' + hours + ':' + minutes + ':0' + seconds,user,yellow); } } else { if(minutes > 9 && seconds > 9) { cb.sendNotice('Time Remaining: 0' + hours + ':' + minutes + ':' + seconds,user,yellow); } else if(minutes > 9 && seconds <= 9) { cb.sendNotice('Time Remaining: 0' + hours + ':' + minutes + ':0' + seconds,user,yellow); } else if(minutes <= 9 && seconds > 9) { cb.sendNotice('Time Remaining: 0' + hours + ':' + minutes + ':' + seconds,user,yellow); } else if(minutes <= 9 && seconds <= 9) { cb.sendNotice('Time Remaining: 0' + hours + ':' + minutes + ':0' + seconds,user,yellow); } } } else if(hours == 0 && minutes > 0) { if(minutes > 9 && seconds > 9) { cb.sendNotice('Time Remaining: 00:' + minutes + ':' + seconds,user,yellow); } else if(minutes > 9 && seconds <= 9) { cb.sendNotice('Time Remaining: 00:' + minutes + ':0' + seconds,user,yellow); } else if(minutes <= 9 && seconds > 9) { cb.sendNotice('Time Remaining: 00:0' + minutes + ':' + seconds,user,yellow); } else if(minutes <= 9 && seconds <= 9) { cb.sendNotice('Time Remaining: 00:0' + minutes + ':0' + seconds,user,yellow); } } else if(hours == 0 && minutes == 0 && seconds > 0) { if(seconds > 9) { cb.sendNotice('\u25ba ' + 'Time Remaining: 00:00' + ':' + seconds, user, yellow, '', "bold"); } else { cb.sendNotice('\u25ba ' + 'Time Remaining: 00:00' + ':0' + seconds, user, yellow, '', "bold"); } } else { cb.sendNotice('hours: ' + hours + '\nminutes: ' + minutes + '\nseconds: ' + seconds); } } else { cb.sendNotice('There is no timer running.', user, yellow); } } function addTime(t, mod) { if(t > 0 && t.toString().indexOf('.') == -1) { if(startTime != 0) { timeAdded = parseInt(t); if(timeAdded == 1) { cb.sendNotice(mod + ' has has added 1 minute to the timer!','',yellow); } else { cb.sendNotice(mod + ' has has added ' + timeAdded + ' minutes to the timer!','',yellow); } } else { cb.sendNotice('There is no timer running.',mod,yellow); } } else if(t != null) { cb.sendNotice(t + ' is not a valid option for /addclock.\nType /fbhelp addclock to see how to use /addclock.',mod,green); } else if(t == null) { cb.sendNotice('You did not enter a valid option for /addclock.\nType /fbhelp addclock to see how to use /addclock.',mod,green); } } function sendPublicNotice (message, user, type, color) { if (message != null) { if (message != "" || message != " " || message != "\u00a0") { if (color == "red") { switch (type) { case "div": cb.sendNotice(dashLine + "\n\u25ba " + message.capitalize() + "\n" + dashLine, "", "", "#d10", "bold"); break; case "divh": cb.sendNotice(dashLine + "\n\u25ba " + message.capitalize() + "\n" + dashLine, "", "#fee", "#d10", "bold"); break; case "h": cb.sendNotice("\u25ba " + message.capitalize(), "", "#fee", "#d10", "bold"); break; case "": cb.sendNotice("\u25ba " + message.capitalize(), "", "", "#d10", "bold"); break; } } else if (color == "default") { switch (type) { case "div": cb.sendNotice(dashLine + "\n\u25ba " + message.capitalize() + "\n" + dashLine, "", "", "#306", "bold"); break; case "divh": cb.sendNotice(dashLine + "\n\u25ba " + message.capitalize() + "\n" + dashLine, "", "#eef", "#306", "bold"); break; case "h": cb.sendNotice("\u25ba " + message.capitalize(), "", "#eef", "#306", "bold"); break; case "": cb.sendNotice("\u25ba " + message.capitalize(), "", "", "#306", "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"); } } var TMgreenB = "#d9eccc"; /* Highlighting used for tm */ var BCpurpleB = "#f3e0f1"; /* Highlighting used for bc */ var TBMblueB = "#dff1f3"; /* Highlighting used for tbm */ var PMredB = "#f4e7e1"; /* Highlighting used for pm */ var TMgreenF = "#253b16"; /* Highlighting used for tm */ var BCpurpleF = "#3e183a"; /* Highlighting used for bc */ var TBMblueF = "#16383b"; /* Highlighting used for tbm */ var PMredF = "#894e33"; /* Highlighting 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, PMredB, PMredF, "bold"); cb.sendNotice('\u261b ' + 'You to ' + dest + ': ' + message, user, PMredB, PMredF, "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 sendReply(message, from) { if(pmArray[findPM(from)][1] != '') { var fullmsg = from + ': '; var msg = ''; //build the message 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); } } function setNoticeColor (message, user) { if (message != null) { noticeColor = message cb.sendNotice("Notice Highlight Color has been set to " + message, user, green); } else { cb.sendNotice("No color was selected.\nType a color and try again.", user, green); } } function showNotifier() { cb.setTimeout(notifierTimer,cb.settings.notifierInterval*60000); } function notifierTimer() { if(notifierToggle == 1) { cb.sendNotice("\u25ba " + notifierMessage, '', noticeColor, '', "bold"); showNotifier(); } } function nice(user,mod,ar) { if(ar == 'a') { if(!cbjs.arrayContains(niceListArray,user)) { populateNiceArray(user); cb.sendNotice('You have added ' + user + ' to the nice list.', 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(ar == 'r') { if(cbjs.arrayContains(niceListArray,user)) { cbjs.arrayRemove(niceListArray,user); cb.sendNotice('You have removed ' + user + ' from the nice list.', 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 setNotifierToggle(option, mod) { if(option == 'on') { if(notifierToggle == 1) { cb.sendNotice('The Notifier toggle is already turned on.',mod,green); } else { notifierToggle = 1; 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 setLeaderToggle(option, mod) { if(option == 'on') { if(leaderboardToggle == 1) { cb.sendNotice('The Leaderboard display is already turned on.',mod,green); } else { leaderboardToggle = 1; 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 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 { tipCountToggle = 1; cb.sendNotice('You have turned on the Tip Menu.',mod,green); } } else if(option == 'off') { if(tipCountToggle == 0) { cb.sendNotice('The Tip Menu is already turned off.',mod,green); } else { tipCountToggle = 0; cb.sendNotice('You have turned off the Tip Menu.',mod,green); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /usetipmenu.\nType /fbhelp tipmenu to see how to use /usetipmenu.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /usetipmenu.\nType /fbhelp tipmenu to see how to use /usetipmenu.',mod,green); } } function initMenu() { let maxItems = 30; TIPMENU.txtColor1 = colorChecker(cb.settings.menutxtcolor1, '#F10060', "Tip Menu text color 1"); TIPMENU.bgColor1 = colorChecker(cb.settings.menubgcolor1, '#FFFFFF', "Tip Menu background color 1"); if (cb.settings.listSplit === 'Split the list in 2') { TIPMENU.txtColor2 = colorChecker(cb.settings.menutxtcolor2, '#F10060', "Tip Menu text color 2"); TIPMENU.bgColor2 = colorChecker(cb.settings.menubgcolor2, '#FFFFFF', "Tip Menu background color 2"); } displayMenuTimer(); setSepChar(); 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]); } } cb.sendNotice('Type /fbhelp to see all the commands.', "", "", "", 'bold'); 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 colorChecker(c, d, s) { if (typeof c !== "undefined") { if ((c.length == 3 || c.length == 6) && /^[0-9A-F]+$/i.test(c)) { return "#" + c; } else if ((c.length == 4 || c.length == 7) && /^#[0-9A-F]+$/i.test(c)) { return c; } else { cb.sendNotice("BAMA - Error while setting " + s + ". It has to be in a HEX format. Using default value: " + d + ".", cb.room_slug, "#FFFFFF", "#FF0000", 'bold'); return (d); } } return (d); } 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); } } else if(option == 'off') { if(posTipMenuToggle == 0) { cb.sendNotice('The Positions Tip Menu is already disabled.',mod,green); } else { posTipMenuToggle = 0; cb.sendNotice('You have disabled the Positions Tip Menu.',mod,green); } } else if(option != null) { cb.sendNotice(option + ' is not a valid option for /usepostipmenu.\nType /fbhelp tipmenu to see how to use /usepostipmenu.',mod,green); } else if(option == null) { cb.sendNotice('You did not enter a valid option for /usepostipmenu.\nType /fbhelp tipmenu to see how to use /usepostipmenu.',mod,green); } } function initPosMenu() { let maxItems = 30; POSTIPMENU.posTxtColor = colorChecker(cb.settings.posMenuTxtColor, '#F10060', "Tip Menu text color"); POSTIPMENU.posBgColor = colorChecker(cb.settings.posMenuBgColor, '#FFFFFF', "Tip Menu background color"); 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.posMenu !== 'Positions Tip Menu: \n' && !POSTIPMENU.posInitToken) { cb.sendNotice(POSTIPMENU.posMenu, '', POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor, 'bold'); POSTIPMENU.posMenuToken = 2; } 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 += " "; } // *************************** Token Poll Functions ************************ function setTokenPollToggle(option, mod) { if(option == 'on') { if(tokenPollToggle == 1) { cb.sendNotice('The Token Poll is already enabled.', mod, green); } else { tokenPollToggle = 1; cb.sendNotice('You have enabled the Token Poll.', mod, green); pollmsg("b", "", u + " has enabled the Token Poll feature. You can now vote in the poll."); initTokenPoll(); } } else if(option == 'off') { if(tokenPollToggle == 0) { cb.sendNotice('The Token Poll is already disabled.', mod, green); } else { tokenPollToggle = 0; cb.sendNotice('You have disabled the Token Poll.', mod, green); pollmsg("b", "", u + " 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 checkColor(c) { switch (c) { case "White": return "#FFFFFF"; case "Indigo": return "#3C6478"; case "Black": return "#000000"; case "Dark Blue": return "#0629AC"; case "Dark Pink": return "#FF6680"; case "Dark Green": return "#009900"; case "Dark Red": return "#cc0000"; case "Dark Purple": return "#3d003d"; case "Dark Grey": return "#737373"; case "Dark Orange": return "#ff9933"; case "Light Blue": return "#33cccc"; case "Light Pink": return "#FFE6EA"; case "Light Green": return "#99FF99"; case "Light Red": return "#ff4d4d"; case "Light Purple": return "#df80ff"; case "Light Orange": return "#ffcc99"; case "Light Grey": return "#e6e6e6"; default: if (/^#[0-9A-F]{6}$/i.test(c)) { return c; } else if (/^[0-9A-F]{6}$/i.test(c)) { return ('#' + c); } else { return ('default'); } } } function initTokenPoll() { switch (cb.settings.poll_mode) { 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); } if (cb.settings.pollTxtColor === "Custom") { pollforeground = checkColor(cb.settings.pollCustTxtColor); if (pollforeground === "default") { cb.sendNotice("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 = checkColor(cb.settings.pollTxtColor); } if (cb.settings.pollBgColor === "Custom") { pollbackground = checkColor(cb.settings.pollCustBgColor); if (pollbackground === 'default') { cb.sendNotice("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 = checkColor(cb.settings.pollBgColor); } pollRunning = true; sanitizeBoard(); showBoard(); initPollTimer(); cb.setTimeout(news, cb.settings.board_interval * 60 * 500); } function showBoard(u) { if(tokenPollToggle == 1) { if (timeAddedB && !pollShow) { cb.setTimeout(showBoard, timeCal() % 60000); timeAddedB = false; return; } if (pollShow) { pollShow = false; // flag if the poll was asked by a user. } let pollresponse1 = "---------- Token Poll board" + ("" === u ? " (sent to all)" : "") + ": ----------\n"; let pollresponse2 = cb.settings.poll_title; if (!pollRunning) { showWinner(u); return; } let ids = []; for (let i = 0; i < optVotes.length; i++) { ids.push({ "votes": optVotes[i], "id": i }); } ids.sort(function(a, b) { return b.votes - a.votes; }); for (let j = 0; j < ids.length; j++) { if (0 != optTokens[ids[j].id]) { pollresponse2 += "\n - " + optLabels[ids[j].id] + " [" + optVotes[ ids[j].id] + " vote" + (optVotes[ids[j].id] > 1 ? "s" : "")+"]: " + optTokens[ids[j].id] + " tokens"; } } let pollresponse3 = ""; switch (pollType) { case "Timer": pollresponse3 = timeLeft() + "\n"; break; case "Vote": pollresponse3 = votesRemain + " vote" + (votesRemain > 1 ? "s" : "") + " remaining before poll closes\n"; break; case "Goal": pollresponse3 = "First option to " + cb.settings.poll_count + " 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) { // we were triggered by a timeout u = ""; cb.setTimeout(showBoard, cb.settings.board_interval * 60 * 1000); } cb.sendNotice(pollresponse1 + pollresponse2, u, pollbackground, pollforeground, "bold"); cb.sendNotice(pollresponse3, u, pollbackground, pollforeground); } } function sanitizeBoard() { for (let i = 1; i < tokensLength; i++) { // start at option 2 if (0 !== optTokens[i] && optLabels[i] === "") { // make sure no option labels are left blank pollmsg("bm", "", "Label for option " + (i + 1) + " is blank -- removing from poll board!"); optTokens[i] = 0; continue; } for (let j = 0; j < i; j++) { // check all options before this one if (0 != optTokens[i] && optTokens[i] === optTokens[j]) { // make sure we don't have two options with the same token amounts pollmsg("bm", "", "Token amount for option " + (i + 1) + " is not unique -- removing from poll board!"); optTokens[i] = 0; optLabels[i] = ""; break; } else if (0 !== optTokens[i] && optLabels[i] === optLabels[j]) { // make sure we don't have two options with the same label pollmsg("bm", "", "Label for option " + (i + 1) + " is not unique -- removing from poll board!"); optTokens[i] = 0; optLabels[i] = ""; break; } } } } function showWinner(u) { let options = []; for (let i = 0; i < tokensLength; i++) { options[i] = i; } options.sort(function(a, b) { return optVotes[b] - optVotes[a]; }); let win_count = 1; for (let j = 1; j < tokensLength; j++) { if (optVotes[options[j]] != optVotes[options[0]]) { break; } if (0 != optTokens[options[j]]) { win_count++; } } let pollresponse1 = '---------- Token Poll has ended! ----------\n'; let pollresponse2 = 'Winner' + (win_count > 1 ? 's (' + win_count + '-way tie)' : '') + ':'; for (let k = 0; k < win_count; k++) { if (optTokens[options[k]] != 0) { pollresponse2 += "\n - " + optLabels[options[k]] + ": " + optVotes[options[k]] + " votes"; } } cb.sendNotice(pollresponse1 + pollresponse2, u, pollbackground, pollforeground, 'bold'); } function showLead() { let options = []; let leadOpt = []; for (let i = 0; i < tokensLength; i++) { options[i] = i; } options.sort(function(a, b) { return optVotes[b] - optVotes[a]; }); if (optVotes[options[0] ] > 0 ){ leadOpt.push(optLabels[options[0]]); for (let j = 1; j < tokensLength; j++) { if (optVotes[options[j]] != optVotes[options[0]]) { break; } if (0 != optTokens[options[j]]) { leadOpt.push(optLabels[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 = optLabels[options[0]] + " is in the lead by " + (optVotes[options[0]] - optVotes[options[1]]) + " vote" + ((optVotes[options[0]] - optVotes[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) { //joins all with "and" but no commas //example: "bob and sam" outStr = arr.join(' '+andor+' '); } else if (arr.length > 2) { //joins all with commas, but last one gets ", and" (oxford comma!) //example: "bob, joe, and sam" outStr = arr.slice(0, -1).join(', ') + ', '+andor+' ' + arr.slice(-1); } return outStr; } function checkPollEnd() { switch (pollType) { case "Never": return; case "Timer": if (secsRemain < 1) { pollRunning = false; } break; case "Vote": if (votesRemain < 1) { pollRunning = false; } break; case "Goal": for (let i = 0; i < tokensLength; i++) { if (optVotes[i] >= cb.settings.poll_count) { pollRunning = false; } } break; } if (tokenPollToggle == 1 && !pollRunning) { showWinner(""); } } function timeCal() { startTime = new Date(); return stopTime - startTime.getTime(); } function timeLeft() { var timeLeft = timeCal(); var milliseconds = timeLeft % 1000; var seconds = ((timeLeft - milliseconds) % 60000); var minutes = ((timeLeft - seconds - milliseconds) % 3600000); var hours = (timeLeft - 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 { startTime = new Date(); stopTime = new Date(startTime.getTime() + cb.settings.poll_count * 60000); tickTimer(); } } function tickTimer() { if (!pollRunning || pollType !== "Timer") { return; } if (timeAddedT) { var timeLeft = timeCal(); var msecsLeft = (timeLeft % 60000); minsRemain = (timeLeft - msecsLeft) % 3600000 / 60000; timeAddedT = false; cb.setTimeout(tickTimer, msecsLeft); } else { minsRemain--; if (minsRemain > 0) { cb.setTimeout(tickTimer, 60 * 1000); } else { secsRemain = 60; cb.sendNotice("1 minute remaining to vote!!!", "", pollbackground, pollforeground); tockTimer(); } } } function tockTimer() { if (!pollRunning || pollType !== "Timer") { return; } // If it is higher than 1, guess that someone added time. if (minsRemain > 0) { tickTimer(); } else { secsRemain--; checkPollEnd(); if (cb.settings.aggresiveTimer === "Every 15 seconds under 1 min") { switch (secsRemain) { case 45: case 30: case 15: cb.sendNotice(secsRemain + " second" + (secsRemain > 1 ? "s" : "") + " remaining to vote!!!", "", pollbackground, pollforeground); } } else if (cb.settings.aggresiveTimer === "Every 15 and 5,4,3,2,1 seconds left") { switch (secsRemain) { case 45: case 30: case 15: case 5: case 4: case 3: case 2: case 1: cb.sendNotice(secsRemain + " second" + (secsRemain > 1 ? "s" : "") + " remaining to vote!!!", "", pollbackground, pollforeground); } } else { // do nothing } if (secsRemain > 0) { cb.setTimeout(tockTimer, 1000); } } } 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 \n You can use "!endpoll" to end the poll if needed.'); pollmsg("m", "", 'The broadcaster enabled to keep the poll alive if users are still voting. \n The poll might be kept alive indefinitely \n You can use "!endpoll" to end the poll if needed.'); if (minsRemain < 2 && pollRunning) { cb.setTimeout(aliveWarning, 60000); } aliveWarned = true; } function news() { if (!pollRunning) { showWinner(''); } else { let newsList = [ "Token Poll is on. Type /poll to see the options." ]; if (fanDouble) { newsList.push("Fan club members currently get two votes for the price of one!"); } newsList.push(showLead()); pollmsg("", "", newsList[nline]); nline += 1; if (nline >= newsList.length) { nline = 0; } } cb.setTimeout(news, 120000); } 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); 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, "#FFFFFF", "#0629AC"); break; default: cb.sendNotice("Token Poll - " + m, u, pollbackground, pollforeground); break; } } // *********************************** 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 commands', from); cb.sendNotice('',from,green); cb.sendNotice('commands' + '\messaging' + '\tipmenu' + '\tokenpoll' + '\nabout' ,from); cb.sendNotice('',from,green); break; } case 'commands': { valid = 1; cb.sendNotice('Fembot Command List',from,green); cb.sendNotice('Type "/fbhelp X", where "X" is one of the following commands, for more detailed information.\nEx: /fbhelp silencelevel',from); cb.sendNotice('',from,green); cb.sendNotice( 'Chat Control:' + '\n/silencelevel' + '\n/graphiclevel' + '\n/ninja' + '\n/unninja' + '\n/ninjalist' + '\n/silence' + '\n/unsilence' + '\n/silencelist' + '\nTimer Functions:' + '\n/startclock' + '\n/addclock' + '\n/timeleft' + '\nNotices:' + '\n/cn' + '\n/cnd' + '\n/cnh' + '\n/cndh' + '\n/chgnotecolor' + '\n/newsubject' + '\n/notifiermessage' + '\n/usenotifier' + '\nNice List:' + '\n/addnice' + '\n/rmvnice' + '\n/nicelist' + '\nLeaders and Tippers:' + '\n/leaders' + '\n/useleaderboard' + '\n/usetipcount' + '\n/tippers' ,from); cb.sendNotice('',from,green); break; } case 'messaging': { valid = 1; cb.sendNotice('Ultra Fembot help for Messaging Commands:',from,green); cb.sendNotice( '\n/pm' + '\n/reply' + '\n/bc' + '\n/tm' + '\n/tbm' ,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 chat. Available to any user, 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.' + '\n/tipmenurmv Y: Will removed any item labeled "Y" regardless of price.' + '\n/posmenurequests: Show recent tip 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.' + '\n/posmenurmv Y: Will removed 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( '\n/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/vote 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 commad.' + '\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 '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, ' + '\nthe "Ultra Fembot" also adds fancier features such as a Tip Menu, VIP list, 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; } case 'silencelevel': { valid = 1; cb.sendNotice('/silencelevel Help',from,green); cb.sendNotice('/silencelevel is a command that 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.' + '\nThe chat ability of broadcasters, moderators, and fan club members is unaffected by the Silence Level.' ,from); cb.sendNotice('',from,green); break; } case 'graphiclevel': { valid = 1; cb.sendNotice('/graphiclevel Help',from,green); cb.sendNotice('/graphiclevel is a command that 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.' + '\nThe graphiclevel does not affect the ability of broadcasters, moderators, and fan club members from posting graphics.' ,from); cb.sendNotice('',from,green); break; } case 'ninja': { valid = 1; cb.sendNotice('/ninja Help',from,green); cb.sendNotice('/ninja is a command that is usable by moderators and broadcasters.' + '\nThe syntax for using silence is "/ninja x", where x is the username of 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.' ,from); cb.sendNotice('',from,green); break; } case 'unninja': { valid = 1; cb.sendNotice ('/unninja Help' ,from,green ); cb.sendNotice ( '/unninja is a command that 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 without notification.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'ninjalist': { valid = 1; cb.sendNotice ('/ninjalist Help' ,from,green ); cb.sendNotice ( '/ninjalist is a command that is usable by moderators and broadcasters.' + '\nUsing this command will display the list of users that has been silenced without notification using the /ninja command.' + '\nUsers can be removed from this list by running the command /unninja.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'silence': { valid = 1; cb.sendNotice ('/silence Help' ,from,green ); cb.sendNotice ( '/silence is a command that is usable by moderators and broadcasters.' + '\nThe syntax for using silence is "/silence x", where x is the username of 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.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'unsilence': { valid = 1; cb.sendNotice ('/unsilence Help' ,from,green ); cb.sendNotice ( '/unsilence is a command that is usable by moderators and broadcasters.' + '\nThe syntax for using unsilence is "/unsilence x", where x is the username of the user you want to unsilence.' + '\nunsilence grants chat privileges back to a user who was previously silenced.' + '\nNOTE: /unsilence cannot undo the effect of Chaturbate\'s silence for 6 hours feature!' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'silencelist': { valid = 1; cb.sendNotice ('/silencelist Help' ,from,green ); cb.sendNotice ( '/silencelist is a command that is usable by moderators and broadcasters.' + '\nUsing this command will display the list of users that has been silenced using the /silence command.' + '\nUsers can be removed from this list by running the command /unsilence.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'startclock': { valid = 1; cb.sendNotice ('/startclock Help' ,from,green ); cb.sendNotice ( '/startclock is a command that is usable by moderators and broadcasters.' + '\nThe syntax for using the command is "/startclock t", where t is the desired duration of the clock timer in minutes.' + '\n/startclock will accept whole numbers only.' + '\nThe timer will make announcements at 15, 10, 5, 4, 3, 2, 1 minutes and 30 seconds remaining.' + '\n/addclock can be used to add time to a currently running timer.' + '\n/timeleft can be used to display the amount of time remaining on the timer.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'addclock': { valid = 1; cb.sendNotice ('/addclock Help' ,from,green ); cb.sendNotice ( '/addclock is a command that is usable by moderators and broadcasters.' + '\nThe syntax for using addclock is "/addclock t", where t is the amount of time you want to add in minutes.' + '\n/addclock will accept whole numbers only.' + '\nSee the help section for startclock for more information on timers.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'timeleft': { valid = 1; cb.sendNotice ('/timeleft Help' ,from,green ); cb.sendNotice ( '/timeleft is a command that is usable by everyone.' + '\nThe syntax for using timeleft is /timeleft' + '\n/timeleft will display the amount of time left on the timer in the format 00:00:00' + '\nSee the help section for startclock for more information on timers.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'pm': { valid = 1; cb.sendNotice ('/pm Help' ,from,green ); cb.sendNotice ( '/pm is a command that is usable by everyone.' + '\nThe syntax for using PMs is "/pm x y", where x is the username of the user you want to send a pm and y is the message you want to send.' + '\nA PM is a private message that will be sent in the main chat window.' + '\nOther related command is /reply.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'reply': { valid = 1; cb.sendNotice ('/reply Help' ,from,green ); cb.sendNotice ( '/reply is a command that is usable by everyone.' + '\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.' + '\nOther related command is /pm.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'bc': { valid = 1; cb.sendNotice ('/bc Help' ,from,green ); cb.sendNotice ( '/bc is a command that is usable by moderators to send a PM specifically to the broadcaster.' + '\nA PM is a private message that will be sent in the main chat window.' + '\nThe syntax for using this type of PM is "/bc y", where y is the message you want to send.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'tm': { valid = 1; cb.sendNotice ('/tm Help' ,from,green ); cb.sendNotice ( '/tm is a command that is usable by moderators and the broadcaster to send a PM to the moderator group as a whole.' + '\nA PM is a private message that will be sent in the main chat window.' + '\nThe syntax for using this type of PM is "/tm y", where y is the message you want to send.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'tbm': { valid = 1; cb.sendNotice ('/tbm Help' ,from,green ); cb.sendNotice ( '/tbm is a command that is usable by moderators and the broadcaster to send a PM to the moderator group plus the broadcaster.' + '\nA PM is a private message that will be sent in the main chat window.' + '\nThe syntax for using this type of PM is "/tbm y", where y is the message you want to send.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'cn': { valid = 1; cb.sendNotice ('/cn Help' ,from,green ); cb.sendNotice ( '/cn is a command that 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 y" or /cn r y", where y is the message you want to send, and r is an optional indicator to change the color ' + 'of the notice text from the default black to red.' + '\nThis is the plain notification - there are variations on the notification to use dash separators with /cnd, to use highlighting with /cnh, ' + 'or to use both dashes and highlighting with /cndh.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'cnh': { valid = 1; cb.sendNotice ('/cnh Help' ,from,green ); cb.sendNotice ( '/cnh is a command that is usable by moderators and the broadcaster to post a one-time notice in the chat with highlighting.' + '\nThe syntax for using this type of notice is "/cnh y" or /cnh r y", where y is the message you want to send, and r is an optional indicator to change the color ' + 'of the notice text from the default black to red.' + '\nThis is the highlighted notification - there are variations on the notification to use dash separators with /cnd, to use no additional formatting with /cn, ' + 'or to use both dashes and highlighting with /cndh.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'cnd': { valid = 1; cb.sendNotice ('/cnd Help' ,from,green ); cb.sendNotice ( '/cnd is a command that is usable by moderators and the broadcaster to post a one-time notice in the chat with dash separators.' + '\nThe syntax for using this type of notice is "/cnd y" or /cnd r y", where y is the message you want to send, and r is an optional indicator to change the color ' + 'of the notice text from the default black to red.' + '\nThis is the dash separator notification - there are variations on the notification to use no additional formatting with /cn, to use highlighting with /cnh, ' + 'or to use both dashes and highlighting with /cndh.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'cndh': { valid = 1; cb.sendNotice ('/cndh Help' ,from,green ); cb.sendNotice ( '/cndh is a command that is usable by moderators and the broadcaster to post a one-time notice in the chat with both highlighting and dash separators.' + '\nThe syntax for using this type of notice is "/cndh y" or /cndh r y", where y is the message you want to send, and r is an optional indicator to change the color ' + 'of the notice text from the default black to red.' + '\nThis is the plain notification - there are variations on the notification to use dash separators with /cnd, to use highlighting with /cnh, ' + 'or to use no additional formatting with /cn.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'usenotifier': { valid = 1; cb.sendNotice ('/usenotifier Help' ,from,green ); cb.sendNotice ( '/usenotifier is a command that 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. ' + '\nThe command /notifiermessage can be used to change the actual content of the notification message, overriding what was configured.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'notifiermessage': { valid = 1; cb.sendNotice ('/notifiermessage Help' ,from,green ); cb.sendNotice ( '/notifiermessage is a command that is usable by moderators and broadcasters to update the notification message that posts periodically in the chat.' + '\nThe syntax for using the command is /notifiermessage x, where x is up to 1000 characters of text for the notification.' + '\nThe command /usenotifier can be used to toggle on or off the display of the message in the chat, overriding what was configured.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'addnice': { valid = 1; cb.sendNotice ('/addnice Help' ,from,green ); cb.sendNotice ( '/addnice is a command that is usable by moderators and room hosts.' + '\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.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'rmvnice': { valid = 1; cb.sendNotice ('/rmvnice Help' ,from,green ); cb.sendNotice ( '/rmvnice is a command that 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.' + '\nSee the help section for nicelist for more information on the nice list.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'nicelist': { cb.sendNotice ('The Nice List' ,from,green ); cb.sendNotice ( '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 ); valid = 1; break; } case 'fbhelp': { valid = 1; cb.sendNotice ('/fbhelp Help' ,from,green ); cb.sendNotice ( '/fbhelp is a command that is usable by everyone.' + '\nThe syntax for using fbhelp is "/fbhelp x", where x is the subsection of the help menu that you want to access.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'leaders': { valid = 1; cb.sendNotice ('/leaders Help' ,from,green ); cb.sendNotice ( '/leaders is a command that is usable by everyone with the default delivery of sending 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.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'useleaderboard': { valid = 1; cb.sendNotice ('/useleaderboard Help' ,from,green ); cb.sendNotice ( '/useleaderboard is a command that is usable by moderators and broadcasters to toggle the display of the top five tippers in a leaderboard.' + '\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.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'usetipcount': { valid = 1; cb.sendNotice ('/usetipcount Help' ,from,green ); cb.sendNotice ( '/usetipcount is a command that 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 .' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'tippers': { valid = 1; cb.sendNotice ('/tippers Help' ,from,green ); cb.sendNotice ( '/tippers is a command that is usable by moderators and broadcasters with the default delivery of sending the list 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".' + '\nThis command triggers the display of the top 25 tippers of the current session.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'chgnotecolor': { valid = 1; cb.sendNotice ('/chgnotecolor Help' ,from,green ); cb.sendNotice ( '/chgnotecolor is a command that is usable by moderators and broadcasters to change the color used to highlight notices in the chat. The available colors are ' + 'red, green, yellow, blue, and purple.' + '\nThis affects the recurring notifier and the on-demand chat notices displayed using "/cnh" and "/cndh".' + '\nThe syntax for using leaderboard is "/chgnotecolor x" where x is one of these colors.' + '\nThis setting overrides what was initially set by the broadcaster when they enabled the bot. The default color is blue.' ,from ); cb.sendNotice ( '' ,from,green ); break; } case 'newsubject': { valid = 1; cb.sendNotice ('/new subject Help' ,from,green ); cb.sendNotice ( '/newsubject is a command that is usable by moderators and broadcasters to update the room title. ' + '\nThe syntax for using leaderboard is "/newsubject x" where x is the new subject text.' ,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 ninjad = 0; var silenced = 0; var symbolString = '~`!@#$%^&*()_-+={[}]|\\:;"\'<,>.?/'; var m = msg.m; var u = msg.user; var isMod = msg.is_mod; var isBC = (u == BC); 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) { 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 commands" to see a full list of the available commands.', msg['user'], 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 commands" to see a full list of the available commands.', msg['user'], green); } break; } case '/ninja': { cmd = 1; if(isMod || isBC) { ninja(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 '/unninja': { cmd = 1; if (isMod || isBC) { unninja(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 '/silence': { cmd = 1; if (isMod || isBC) { silence(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 '/unsilence': { cmd = 1; if (isMod || isBC) { unsilence(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 '/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; } 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; } case '/startclock': { cmd = 1; if (isMod || isBC) { startTimer(commandVar1, 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 '/addclock': { cmd = 1; if (isMod || isBC) { addTime(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 '/timeleft': { cmd = 1; timeLeft(u); break; } case '/addnice': { cmd = 1; if (isMod || isBC) { nice(message[1], u,'a'); } break; } case '/rmvnice': { cmd = 1; if (isMod || isBC) { nice(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; } 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 '/extfanlist': { cmd = 1; if (isMod || isBC) { cb.sendNotice('Users currently on the Nice 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 '/wordlist': { cmd = 1; if (isMod || isBC) { 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); } 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 '/cn': { cmd = 1; if (isMod || isBC) { if (message[1] == "r") { if (ntc2 != null && (ntc2 != "" || ntc2 != " " || ntc2 != "\u00a0")) sendPublicNotice(ntc2, u, "", "red"); else cb.sendNotice("You can't send a blank message.\nThe correct syntax for this command is " + '"/cn r message"' + ".", u, "#fee"); } else if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "", "default"); } 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 (message[1] == "r") { if (ntc2 != null && (ntc2 != "" || ntc2 != " " || ntc2 != "\u00a0")) sendPublicNotice(ntc2, u, "h", "red"); else cb.sendNotice("You can't send a blank message.\nThe correct syntax for this command is " + '"/cnh r message"' + ".", u, "#fee"); } else if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "h", "default"); } 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 (message[1] == "r") { if (ntc2 != null && (ntc2 != "" || ntc2 != " " || ntc2 != "\u00a0")) sendPublicNotice(ntc2, u, "div", "red"); else cb.sendNotice("You can't send a blank message.\nThe correct syntax for this command is " + '"/cnd r message"' + ".", u, "#fee"); } else if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "div", "default"); } 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 (message[1] == "r") { if (ntc2 != null && (ntc2 != "" || ntc2 != " " || ntc2 != "\u00a0")) sendPublicNotice(ntc2, u, "divh", "red"); else cb.sendNotice("You can't send a blank message.\nThe correct syntax for this command is " + '"/cndh r message"' + ".", u, "#fee"); } else if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "divh", "default"); } 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; } case "/bc": { cmd = 1; if (isMod) { 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) { 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 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") { break; } sendReply(message, msg['user']); msg['background'] = green; break; } case '/fbhelp': { cmd = 1; help(message[1],msg['user']); break; } 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 '/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 '/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; } case '/notifiermessage': { 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 { notifierMessage = msg['m'].substring(16).trim(); cb.sendNotice('You have set the notifier message to: ' + notifierMessage,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 '/chgnotecolor': { cmd = 1; if (isMod || isBC) { setNoticeColor(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 '/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; } //********* Tip Menu Commands case "/tipmenu": { cmd = 1; m.background = '#d9d9d9'; if (isMod && message[0] === "/tipmenu") { u = ''; } cb.sendNotice(TIPMENU.tipMenu, u, TIPMENU.bgColor1, TIPMENU.txtColor1, 'bold'); break; } case '/usemenu': { cmd = 1; if (isMod || isBC) { setTipMenuToggle(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 "/tipmenurequests": { cmd = 1; m.background = '#d9d9d9'; if (isMod && message[0] === '/tipmenurequest') { u = ''; } 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('**** Here are the last 0 requests! :p', 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, u, 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 "/postipmenu": { cmd = 1; m.background = '#d9d9d9'; if (isMod) { u = ''; } cb.sendNotice(POSTIPMENU.posTipMenu, u, POSTIPMENU.posBgColor, POSTIPMENU.posTxtColor, 'bold'); break; } case '/useposmenu': { cmd = 1; if (isMod || isBC) { setPosTipMenuToggle(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 "/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 - " + u + ' added the option "' + poslabel + '" for ' + newPosItemPrice + ' tokens the positions 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 needs to 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! Every options that match "' + itemPrice + '" will be removed from the positions menu.', 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 notification - " + (u === cb.room_slug ? "You" : u) + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '" from the positions menu.', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice("Positions Tip Menu notification - " + u + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '" from the positions menu.', "", "#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 notification - " + (u === cb.room_slug ? "You" : u) + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '" from the positions menu.', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice("Positions Tip Menu notification - " + u + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '" from the positions menu.', "", "#FFFFFF", "#FF0000", "bold", "red"); menuSanitize(); } } if (!poslabelFound) { cb.sendNotice("Positions Tip Menu - Unable find item " + poslabel + "(" + posItemPrice + ") on the positions 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. 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 notification - " + (u === cb.room_slug ? "You" : u) + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '" from the positions menu.', cb.room_slug, "#FFFFFF", "#FF0000", "bold"); cb.sendNotice("Positions Tip Menu notification - " + u + ' removed the option "' + POSTIPMENU.posTipMenuItem[i] + '" from the positions menu.', "", "#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) { m.background = '#d9d9d9'; pollShow = true; 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) { m.background = '#d9d9d9'; 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) { m.background = '#d9d9d9'; if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } pollmsg("a", "", u + " has restarted the poll, voting has resumed."); if (!pollRunning) { pollRunning = true; } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/vote": { cmd = 1; if (tokenPollToggle == 1) { var amount; m.background = '#d9d9d9'; if (!isMod && !isBC) { pollmsg("nm", u, ""); break; } if (!modAdd && u !== cb.room_slug) { 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, "Haha very funny, now make a decision."); break; } if (!commandVar1) { pollmsg("", u, "Not a valid choice\n !vote needs to have a value (the token amount for that option). ex: /vote 10 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 < tokensLength; i++) { if (commandVar1 === optTokens[i]) { pollmsg("a", u, u + " has " + (amount > 0 ? "added" : "removed") + " " + (amount < 0 ? -amount : amount) + " vote" + (amount === 1 || amount === -1 ? "" : "s") + " for " + optLabels[i]); optVotes[i] += amount; voteFail = false; if (pollType === "Vote") { votesRemain -= amount; } checkPollEnd(); break; } } if (voteFail) { pollmsg("w", u, "Not a valid choice. \n X needs to match a tip amount on the poll."); break; } } } else { cb.sendNotice('The Token Poll is disabled.', u, green); } break; } case "/polloptadd": { cmd = 1; if (tokenPollToggle == 1) { var label; 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 is the amount the viewers will tip to vote for this selection."); break; } if (!message[2]) { pollmsg("w", u, "You must include a label for this voting selection in the second variable."); break; } for (let i = 2; i < message.length; i++) { if (i === 2) { label = message[i]; } else { label += " " + message[i]; } } pollmsg("bm", u, u + ' added the option "' + label + '" to the poll.'); optLabels.push(label); optTokens.push(commandVar1); optVotes.push(0); tokensLength++; sanitizeBoard(); } } 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 iused to select the poll item that will be removed based on the price."); break; } for (let i = 1; i < tokensLength - 1; i++) { if (optTokens[i] === commandVar1) { optTokens[i] = 0; pollmsg("bm", u, u + ' removed the option "' + optLabels[i] + '" from the poll.'); } } } } 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 (minsRemain >= 1) { pollmsg("w", u, 'A timer is already running, please use "/polladdtime X" to add time to timer. \nThe poll will end in ' + minsRemain + ' minute' + (minsRemain > 1 ? 's' : '')); } else if (secsRemain >= 1) { pollmsg("w", u, 'Timer is already running, use "/polladdtime" to change the remaining time. \nThe poll will end in ' + secsRemain + ' seconds' + (secsRemain > 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 (pollType !== "Timer") { pollType = "Timer"; startTime = new Date(); stopTime = new Date(startTime.getTime() + commandVar1 * 60000); minsRemain = commandVar1; pollmsg("bm", u, u + " " + (commandVar1 > 0 ? "added " : "removed ") + commandVar1 + " minute" + (commandVar1 === 1 || commandVar1 === -1 ? "" : "s") + " to the timer."); timeAddedB = true; timeAddedT = true; cb.sendNotice("The poll will end in " + minsRemain + " minute" + (minsRemain > 1 ? "s" : ""), "", pollbackground, pollforeground); tickTimer(); 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(timeLeft(), u, pollbackground, pollforeground); 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 (minsRemain + 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 { stopTime = new Date(stopTime.getTime() + commandVar1 * 60000); pollmsg("bm", u, u + " " + (commandVar1 > 0 ? "added " : "removed ") + (commandVar1 > 0 ? commandVar1 : -commandVar1) + " minute" + (commandVar1 === 1 || commandVar1 === -1 ? "" : "s") + " to the timer."); timeAddedB = true; timeAddedT = true; } } 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"; 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; } } if(message[0] == '/startshow' || message[0] == '/stopshow' || message[0] == '/showend' || message[0] == '/showover' || message[0] == '/add' || message[0] == '/ctprice' || message[0] == '/starttimer' || message[0] == '/addtime' || message[0] == '/rmv' || message[0] == '/tipmenu' || message[0] == '/ctnd' || message[0] == '/ctsubject' || message[0] == '/endpoll' || 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(cbjs.arrayContains(silenceListArray,msg['user']) && silenced == 0) { msg['X-Spam'] = true; silenced = 1; cb.sendNotice('Your message was not sent because you have been silenced',msg['user'],green); } if(cbjs.arrayContains(ninjaListArray,msg['user']) && ninjad == 0) { msg['X-Spam'] = true; ninjad = 1; } if(silenceLevel > 0 && !msg['is_mod'] && msg['user'] != cb.room_slug && !cbjs.arrayContains(niceListArray,msg['user']) && !msg['in_fanclub'] && silenced == 0) { switch(silenceLevel) { case 1: if(!msg['has_tokens']) { msg['X-Spam'] = true; silenced = 1; cb.sendNotice('Your message was not sent because the silence level has been set to only allow members with tokens to chat. \nType "/fbhelp silencelevel" to see how the various silence levels work.',msg['user'],green); } break; case 2: if(parseInt(tipCountArray[findTipper(msg['user'])][1]) == 0) { msg['X-Spam'] = true; silenced = 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. \nType "/fbhelp silencelevel" to see how the various silence levels work.',msg['user'],green); } break; case 3: if(parseInt(tipCountArray[findTipper(msg['user'])][1]) < 10) { msg['X-Spam'] = true; silenced = 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. \nType "/fbhelp silencelevel" to see how the various silence levels work.',msg['user'],green); } break; } } if(graphicLevel > 0 && !msg['is_mod'] && msg['user'] != cb.room_slug && !cbjs.arrayContains(niceListArray,msg['user']) && !msg['in_fanclub'] && silenced == 0) { switch(graphicLevel) { case 1: if(!msg['has_tokens']) { for(var i = 0; i < message.length; i++) { if(message[i].charAt(0) == ':') { msg['X-Spam'] = true; cb.sendNotice('Your message was not displayed because the graphic level has been set to ' + graphicLevel + '.\nType "/fbhelp graphiclevel to see how the various graphic levels work.',msg['user'],green); } } } break; case 2: if(parseInt(tipCountArray[findTipper(msg['user'])][1]) == 0) { for(var i = 0; i < message.length; i++) { if(message[i].charAt(0) == ':') { msg['X-Spam'] = true; cb.sendNotice('Your message was not displayed because the graphic level has been set to ' + graphicLevel + './nType "/fbhelp graphiclevel to see how the various graphic levels work.',msg['user'],green); } } } break; case 3: if(parseInt(tipCountArray[findTipper(msg['user'])][1]) < 10) { for(var i = 0; i < message.length; i++) { if(message[i].charAt(0) == ':') { msg['X-Spam'] = true; cb.sendNotice('Your message was not displayed because the graphic level has been set to ' + graphicLevel + './nType "/fbhelp graphiclevel to see how the various graphic levels work.',msg['user'],green); } } } break; } } if(msg['m'] == msg['m'].toUpperCase() && msg['m'].toUpperCase() != msg['m'].toLowerCase() && !msg['is_mod'] && msg['user'] != cb.room_slug) { for(var i = 0; i < msg['m'].length; i++) { if(symbolString.indexOf(msg['m'].charAt(i)) == -1) { msg['m'] = msg['m'].toLowerCase(); cb.sendNotice('Please do not send messages in all CAPS.', msg['user'], green); break; } } } if(groupIconToggle == 1 && message[0].charAt(0) != "/") { if (isMod) { group = 'mods'; msg['m'] = displayGroupIcon(group, msg['m']); } if (isFan) { group = 'fans'; msg['m'] = displayGroupIcon(group, msg['m']); } if (cbjs.arrayContains(extFanListArray, u)) { group = 'extfans'; msg['m'] = displayGroupIcon(group, msg['m']); } if (cbjs.arrayContains(VIPListArray, u)) { group = 'VIP'; msg['m'] = displayGroupIcon(group, msg['m']); } } if(tipCountToggle == 1 && parseInt(tipCountArray[findTipper(msg['user'])][1]) > 0 && message[0].charAt(0) != "/") { msg['m'] = displayTipCount(msg['user'],msg['m']); } 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); } // **** 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'); } // **** 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; // ***** Tipper List tipCountArray[findTipper(u)][1] += tipAmount; if (!cbjs.arrayContains(tipperList.name, u)) { populateTipperList(u, tipAmount); } else { var index = tipperList.name.indexOf(u); tipperList.amount[index] += 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'); } } // ***** Token Poll if (isFan && fanDouble) { voteAmount = 2; pollmsg('', u, 'Since you are a member of the fan club, your votes will be doubled.'); } for (let i = 0; i < tokensLength; i++) { if(tokenPollToggle == 1 && pollRunning) { if (tipAmount === optTokens[i]) { optVotes[i] += voteAmount; if (voteAmount === 1) { cb.sendNotice(u + " voted for " + optLabels[i], "", pollbackground, pollforeground); } else { cb.sendNotice(u + " voted " + voteAmount + " time" + (voteAmount === 1 ? "" : "s") + " for " + optLabels[i], "", pollbackground, pollforeground); } if (pollType === "Vote") { votesRemain -= voteAmount; } if (pollType === "Timer" && cb.settings.opt_keepalive === "Yes" && minsRemain < 1) { minsRemain++; if (aliveWarned) { aliveWarning(); } } checkPollEnd(); } } } }); } // *********************************** Initialize ************************************** { if(initialize == 0) { if(cb.settings.enableLeaderboard == 'Yes') { leaderboardToggle = 1; sendLeaderboard(); } if(cb.settings.enableNotifier == 'Yes') { notifierToggle = 1; showNotifier(); } 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.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.wordBlockList != '' && cb.settings.wordBlockList != null) { var n = cb.settings.wordBlockList; wordListArray = n.split(','); } if(cb.settings.extFanList != '' && cb.settings.extFanList != null) { var n = cb.settings.extFanList; extFanListArray = n.split(','); } if(cb.settings.VIPList != '' && cb.settings.VIPList != null) { var n = cb.settings.VIPList; VIPListArray = n.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- 2024. All Rights Reserved.