Bots Home
|
Create an App
test_maevebot2
Author:
maevebot2
Description
Source Code
Launch Bot
Current Users
Created by:
Maevebot2
/****************************************************** ******************************************************* * Name: MaeveBot 2.0 * Author: Maeve * Version: 2.0.2(1/6/2018) * * Merging of: * Bomb Bot Ultra 1.6.3 (1/14/15) * Sophie's Tips 1.0.0 (02-03-2016) * Sophie's Stones ********** * 2.0.1 ********** - updated all notices to used notifyTheme to use the theme highlights - removed the final blank line from the leaderboard - made tip menu item 1 and price 1 no longer be required ********** * 2.0.2 ********** Fixed bug on message when fanclub was disabled ****************************************************** *****************************************************/ /****************************************************** ******************************************************* * Name: Bomb Bot Ultra * Author: adambomb01 * Version: 1.6.3 (1/14/15) * * Based on: * Ultra Bot by britney_and_justin * ScottBot by scottp13 ******************************************************* ********** * 1.6.3 ********** - Refined wordlist - Fixed a bug in which some of the commands would crash the bot if sent without any attributes. - emods now get relevant notifications (i.e. "silence") as well ********** * 1.6.2 ********** - Added 5-second delay to /silencelast command if a new mod tries to use it. (This avoids accidental "overflow" when multiple mods are using the command.) ********** * 1.6.1 ********** - Disables tip titles and king's crown for messages starting with '!' (Since some apps -- notably Keno -- use this as a command.) - Refined wordlist ********** * 1.6 ********** - Added "/addword" command (Adds a word to the custom wordlist mid-show) - New lines in /addnotice are now working - Fixed some false positives for "Workaround" on the wordlist - Added to wordlist ********** * 1.5 ********** - Added "/silencelast" ("/sl") command - Added to wordlist - Change silence/graphic levels to: * 0 - Everyone * 1 - Colors Only * 2 - Dark Blues and up * 3 - Users who have tipped * 4 - Mods and fans only ********** * 1.4 ********** - Added "custom wordlist" feature - Added "/stoptimer" command - Made timer code more efficient - Separated the color scheme. Bot features now use blue to differentiate from personalized notices, which can be whatever color the user chooses - Added highlight for all commands - Added "/tiptotal" command - Commands are now case-insensitive ********** * 1.3 ********** - Added "custom wordlist" feature - Added wordlist level choice for regular and custom wordlists (Can apply to everyone or just greys) - Added option for new line in notes and welcome message - Added "/addnotice", "/removenotice", "/shownotices", and "/noticetimer" commands for rotating notifier ********** * 1.2 ********** - Reorganized launch screen - Added "prevent sticky keys" feature - Added "rotating notices" feature - Updated color scheme ********** * 1.1 ********** - Mods can now toggle Blocked Message notices on and off using /blocknotice x, where x is "on" or "off" - Fixed leaderboard, notifier, and king tipper spam toggles (They were broken in Ultra Bot) - Added to grey wordlist - Blocks any grey messages over 500 characters in length to prevent spam - Blocks any 1-character grey messages - Disallows sexually explicit words in grey messages shorter than 4 words ********** * 1.0 ********** - First version. Includes basic Ultra Bot features, plus: - Grey wordlist - On-demand notices - New silence/graphic/ignore level of '4' (nobody but mods and fans -- mainly useful for whispers) ************************************************** ***** BRAND SPANKIN' NEW FEATURES **************** ************************************************** ===== Grey Wordlist - Blocks annoying and abusive behavior from greys (words, sticky keys, etc.) - Multiple variations of blocked words will get flagged. This includes sticky key variations and, where possible, spaced out variations. - Non-grey users can be manually added to the "grey list," which will subject their messages to the same scrutiny as greys, including wordlist, capitalization, and graphic levels. This can be useful when you have users who are tipping, but whose messages are annoying or abusive. It essentially acts as an enforced warning level before silencing or banning the user. - A user without tokens who has tipped will not be subject to the grey wordlist (Unless added to it manually) - Broadcaster can choose whether to notify sender if their message gets blocked based on wordlist. (By default, the sender is NOT notified. This seems to make things run more smoothly, because the abusive senders assume the message went through and they don't feel the need to try again and again with different variations) ===== Notice - Allows broadcaster and moderator to send on-demand notices to the room using /note, /n, or /notice ************************************************** ***** CHANGES TO EXISTING ULTRA BOT FEATURES ***** ************************************************** ===== Whispers - Added whisper level of '4' (Accepts whispers from no one other than fan club and mods) - Set the broadcaster's default whisper level to '4'. (This is intended to prevent abuse of the "whisper" feature) - Whispers are subject to a user's wordlist and graphic level restrictions. - Users who have been silenced using the /silence command will not be able to send whispers either. (This mimics Chaturbate's behavior with PMs) ===== Silencing + Silence/Graphic Levels - Removed messages sent to silenced user (This makes silencing stealth to the silenced user) - Fixed graphic and silence levels so that a level of '1' (members with tokens) will also include a user without tokens who has tipped ===== Convert Capital Letters to Lowercase - Updated the code so that uppercase image codes are not taken into account. - Option to apply capitalization restrictions to greys only. This is now the default. ===== Dick List - This feature has been removed since it wasn't being utilized. (If Ultra Bot starts using it, I will re-add it.) ********** TO DO LIST ********** - Set (or turn off) welcome message on demand - Wildcard silence (Silence based on partial name match) - Allow broadcaster to choose wordlists by category, and choose who it applies to - Add option to throttle grey messages (i.e. no more than two every 20 seconds or something -- configurable by broadcaster) - See about preventing multiple error messages (i.e. silence level AND wordlist.) I think I can do this by setting a messageSquelched variable and testing whether it's true along the way. If so, do a break(); within the onMessage function. This already works for graphiclevel and silencelevel. Let's see what he did there - /donotwant for crown ****************************************************** *****************************************************/ /* Title: "Sophie's Tips" bot Modified by s0ckm0nk3y Version 1.0.0 (02-03-2016) Added 30 lines, only first 10 lines show in notice Author: badbadbubba Version: 1.0.0 (06/01/2014) Version: 1.0.0b Added options to choose different separator characters This bot displays a tip menu in a single line notice. Please keep menu items as concise as possible. Odd values for tip menu items will make each unique eg 21 tokens for flash tits, 22 tokens to flash ass. */ /************************************************************************************************************************************ ***** App Launch Settings *********************************************************************************************************** ************************************************************************************************************************************/ cb.settings_choices = [ /**** 1. Customize ****/ //{name: 'colorscheme', // label: '1.) PERSONALIZATION ........................................... Color Scheme:', // type: 'choice', choice1: 'Custom (Please define below)', choice2: 'Pink', choice3: 'Orange', choice4: 'Red', choice5: 'Green', choice6: 'Teal', choice7: 'Grey', choice8: 'Purple' , required: false}, {name: 'darkcolor', label: '[Customize] Text Color (Hex #):', type: 'str', defaultValue: '#000033', required: false}, {name: 'lightcolor', label: 'Highlight color (Hex #):', type: 'str', defaultValue: '#FFFFFF', required: false}, {name: 'invalidToggle', label: 'Send error message for invalid commands?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, /**** 2. Notices ****/ {name: 'notifierSpam', label: '[Notices] Use this feature?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'notifierTimer', label: 'Interval (in mins):', type: 'int', minValue: 1, maxValue: 60, defaultValue: 4, required: false}, {name: 'enterMessage', label: 'Welcome Message (none=disabled):', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - Leave blank in busy rooms, as it can cause CB bots to crash]', required: false}, {name: 'spamMessage1', label: 'Notice #1', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - use {newline} for line break]', required: false}, {name: 'spamMessage2', label: 'Notice #2', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - use {newline} for line break]', required: false}, {name: 'spamMessage3', label: 'Notice #3', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - use {newline} for line break]', required: false}, {name: 'spamMessage4', label: 'Notice #4', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - use {newline} for line break]', required: false}, {name: 'spamMessage5', label: 'Notice #5', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - use {newline} for line break]', required: false}, {name: 'spamMessage6', label: 'Notice #6', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - use {newline} for line break]', required: false}, {name: 'spamMessage7', label: 'Notice #7', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - use {newline} for line break]', required: false}, {name: 'spamMessage8', label: 'Notice #8', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - use {newline} for line break]', required: false}, /**** 3. ROOM CONTROL ****/ {name: 'roomControlmods', label: '[Room Control] Do mods have room control permission?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'defaultCapsLevel', label: 'Caps Lock?:', type: 'choice', choice1: '0 - (Everyone)', choice2: '1 - (Color names only)', choice3: '2 - (Users who have tipped)', choice4: '3 - (Mods & Fans/Faves)', choice5: '4 - (Just Mods)', defaultValue: '1 - (Color names only)', required: false}, {name: 'defaultStickyLevel', label: 'Sticky Keys?:', type: 'choice', choice1: '0 - (Everyone)', choice2: '1 - (Color names only)', choice3: '2 - (Users who have tipped)', choice4: '3 - (Mods & Fans/Faves)', choice5: '4 - (Just Mods)', defaultValue: '1 - (Color names only)', required: false}, {name: 'defaultGraphicLevel', label: 'Graphic Level?:', type: 'choice', choice1: '0 - (Everyone)', choice2: '1 - (Color names only)', choice3: '2 - (Users who have tipped)', choice4: '3 - (Mods & Fans/Faves)', choice5: '4 - (Just Mods)', defaultValue: '1 - (Color names only)', required: false}, {name: 'defaultSilenceLevel', label: 'Silence Level?:', type: 'choice', choice1: '0 - (Everyone)', choice2: '1 - (Color names only)', choice3: '2 - (Users who have tipped)', defaultValue: '0 - (Everyone)', required: false}, {name: 'niceList', label: 'Nice List (exempt users):', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - Exact usernames, separated by commas]', required: false}, {name: 'silenceList', label: 'Silence List (b& users):', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '[Optional - Exact usernames, separated by commas]', required: false}, /**** 4. CUSTOM WORDLIST ****/ {name: 'customWordlistToggle', label: '[Blocked Wordlist] Use this feature?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'customWordlistExempt', label: 'Who is exempt?:', type: 'choice', choice1: 'broadcaster only', choice2: 'broadcaster/mods', choice3: 'broadcaster/mods/faves', choice4: 'colors only', defaultValue: 'broadcaster only', required: false}, {name: 'customWordlistNotify', label: 'Who to notify?:', type: 'choice', choice1: 'broadcaster only', choice2: 'broadcaster/mods', choice3: 'just mods', choice4: 'all parties', defaultValue: 'broadcaster only', required: false}, {name: 'customWordlist', label: 'Blocked Wordlist:', type: 'str', minLength: 1, maxLength: 3000, defaultValue: '[Optional - Exact words or phrases, separated by commas]', required: false}, /**** 7, LEADERBOARD ****/ {name: 'leaderBoard', label: '[Leaderboard] Use this feature?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'leaderBoardTimer', label: 'Interval (in mins):', type: 'int', minValue: 1, maxValue: 60, defaultValue: 10, required: false}, {name: 'leaderBoardSize', label: 'Users shown in notice?:', type: 'choice', choice1: '3', choice2: '5', defaultValue: '3', required: false}, /**** 6. KING TIPPER ****/ {name: 'kingTipper', label: '[King Tipper] Use this feature?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'kingTipperTimer', label: 'Interval (in mins):', type: 'int', minValue: 1, maxValue: 60, defaultValue: 10, required: false}, {name: 'kingMin', label: 'Minimum tip amount to become King:', type: 'int', minValue: 1, maxValue: 1000, defaultValue: 25, required: false}, /**** 10. TIP TITLES ****/ {name: 'tipTitles', label: '[Tipper Recognition] Display users\' tip totals as titles?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'notifierTip', label: 'Show message when a user tips?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No', required: false}, {name: 'tipMessageMin', label: 'Minimum tip to trigger message:', type: 'int', minValue: 1, maxValue: 1000000, defaultValue: 15, required: false}, {name: 'tipMessage', label: 'Message:', type: 'str', minLength: 1, maxLength: 1000, defaultValue: 'Thank you for tipping, {username}!', required: false}, /**** 12. TIP MENU ****/ {name: 'tipMenu', label: '[Tip Menu] Use this feature?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'chat_ad', type:'int', minValue: 1, maxValue: 999, defaultValue: 1, label: 'Interval (in mins):'}, {name: 'sepchar',label: "Separator character:", type: 'str', defaultValue: '|', required: false}, {name: 'tipMenuLength', label: 'Items included in notice:', type: 'int', minValue: 1, maxValue: 30, defaultValue: 10, required: true}, {name:'item1', type:'str', required: false, label:'Item 1',}, {name:'item1price', type:'int', required: false,label:'Item 1 Price'}, {name:'item2', type:'str', required: false, label:'Item 2',}, {name:'item2price', type:'int', required: false, label:'Item 2 Price'}, {name:'item3', type:'str', required: false, label:'Item 3',}, {name:'item3price', type:'int', required: false, label:'Item 3 Price'}, {name:'item4', type:'str', required: false, label:'Item 4',}, {name:'item4price', type:'int', required: false, label:'Item 4 Price'}, {name:'item5', type:'str', required: false, label:'Item 5',}, {name:'item5price', type:'int', required: false, label:'Item 5 Price'}, {name:'item6', type:'str', required: false, label:'Item 6',}, {name:'item6price', type:'int', required: false, label:'Item 6 Price'}, {name:'item7', type:'str', required: false, label:'Item 7',}, {name:'item7price', type:'int', required: false, label:'Item 7 Price'}, {name:'item8', type:'str', required: false, label:'Item 8',}, {name:'item8price', type:'int', required: false, label:'Item 8 Price'}, {name:'item9', type:'str', required: false, label:'Item 9',}, {name:'item9price', type:'int', required: false, label:'Item 9 Price'}, {name:'item10', type:'str', required: false, label:'Item 10',}, {name:'item10price', type:'int', required: false, label:'Item 10 Price'}, {name:'item11', type:'str', required: false, label:'Item 11',}, {name:'item11price', type:'int', required: false, label:'Item 11 Price'}, {name:'item12', type:'str', required: false, label:'Item 12',}, {name:'item12price', type:'int', required: false, label:'Item 12 Price'}, {name:'item13', type:'str', required: false, label:'Item 13',}, {name:'item13price', type:'int', required: false, label:'Item 13 Price'}, {name:'item14', type:'str', required: false, label:'Item 14',}, {name:'item14price', type:'int', required: false, label:'Item 14 Price'}, {name:'item15', type:'str', required: false, label:'Item 15',}, {name:'item15price', type:'int', required: false, label:'Item 15 Price'}, {name:'item16', type:'str', required: false, label:'Item 16',}, {name:'item16price', type:'int', required: false, label:'Item 16 Price'}, {name:'item17', type:'str', required: false, label:'Item 17',}, {name:'item17price', type:'int', required: false, label:'Item 17 Price'}, {name:'item18', type:'str', required: false, label:'Item 18',}, {name:'item18price', type:'int', required: false, label:'Item 18 Price'}, {name:'item19', type:'str', required: false, label:'Item 19',}, {name:'item19price', type:'int', required: false, label:'Item 19 Price'}, {name:'item20', type:'str', required: false, label:'Item 20',}, {name:'item20price', type:'int', required: false, label:'Item 20 Price'}, {name:'item21', type:'str', required: false, label:'Item 21',}, {name:'item21price', type:'int', required: false, label:'Item 21 Price'}, {name:'item22', type:'str', required: false, label:'Item 22',}, {name:'item22price', type:'int', required: false, label:'Item 22 Price'}, {name:'item23', type:'str', required: false, label:'Item 23',}, {name:'item23price', type:'int', required: false, label:'Item 23 Price'}, {name:'item24', type:'str', required: false, label:'Item 24',}, {name:'item24price', type:'int', required: false, label:'Item 24 Price'}, {name:'item25', type:'str', required: false, label:'Item 25',}, {name:'item25price', type:'int', required: false, label:'Item 25 Price'}, {name:'item26', type:'str', required: false, label:'Item 26',}, {name:'item26price', type:'int', required: false, label:'Item 26 Price'}, {name:'item27', type:'str', required: false, label:'Item 27',}, {name:'item27price', type:'int', required: false, label:'Item 27 Price'}, {name:'item28', type:'str', required: false, label:'Item 28',}, {name:'item28price', type:'int', required: false, label:'Item 28 Price'}, {name:'item29', type:'str', required: false, label:'Item 29',}, {name:'item29price', type:'int', required: false, label:'Item 29 Price'}, {name:'item30', type:'str', required: false, label:'Item 30',}, {name:'item30price', type:'int', required: false, label:'Item 30 Price'}, // {name:'noticecolor', type:'str', label:'Notice color (html code default red #FF0000)', defaultValue: '#FF0000'}, /**** 5. WHISPERS ****/ {name: 'whisperToggle', label: '[Whispers] Use this feature?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'roomWhisperLevel', label: 'General Whisper Level?:', type: 'choice', choice1: '0 - (Everyone)', choice2: '1 - (Color names only)', choice3: '2 - (Dark blue names and higher)', choice4: '3 - (Users who have tipped)', choice5: '4 - (Only mods and fans)', defaultValue: '0 - (Everyone)', required: false}, {name: 'hostWhisperLevel', label: 'Broadcaster Whisper Level?:', type: 'choice', choice1: '0 - (Everyone)', choice2: '1 - (Color names only)', choice3: '2 - (Dark blue names and higher)', choice4: '3 - (Users who have tipped)', choice5: '4 - (Only mods and fans)', defaultValue: '4 - (Only mods and fans)', required: false}, /**** 13. FAN CLUB 1 ****/ {name: 'fanClub1', label: '[Faves] Enable Fan Club?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'fanClub1mods', label: 'Mods can control fanclubs:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name:'fanClub1color', type:'str', required: false, label:'Text Color (Hex #):',defaultValue: '#000033'}, {name:'fanClub1hilite', type:'str', required: false, label:'Highlight color (Hex #):',defaultValue: '#FFFFFF'}, {name:'fanClub1name', type:'str', required: false, label:'Fanclub Name (blank= disabled):'}, {name:'fanClub1title', type:'str', required: false, label:'Title of Members:'}, {name:'fanClub1tag', type:'str', required: false, label:'Tag (e.g. [member] or :icon) (blank= none):'}, {name:'fanClub1price', type:'int', minValue: 0, maxValue: 999999, defaultValue: 1111, label: 'Single tip price to join (0 = manual only):'}, {name: 'fanClub1tipping',label: 'Larger single tip grants entry?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name:'fanClub1Cumulative', type:'int', minValue: 0, maxValue: 999999, defaultValue: 2000, label: 'Cumulative tip price to join (0= manual only):'}, {name:'fanClub1members',label: 'Fanclub Members (separated by spaces or comma):', type: 'str', minLength: 0, maxLength: 30000, required: false}, /**** 15. USER TITLES ****/ {name: 'userTitles', label: '[Custom Titles] Use this feature?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name: 'userTitlemods', label: 'Mods can control titles:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name:'usercolor', type:'str', required: false, label:'Text Color (Hex #):',defaultValue: '#000033'}, {name:'userhilite', type:'str', required: false, label:'Highlight color (Hex #):',defaultValue: '#FFFFFF'}, {name:'user1name', type:'str', required: false, label:'[User Titles 1]: Username (empty=disabled):',}, {name:'user1title', type:'str', required: false, label:'[User Titles 1]: Custom Title (empty = none):'}, {name:'user2name', type:'str', required: false, label:'[User Titles 2]: Username (empty=disabled):',}, {name:'user2title', type:'str', required: false, label:'[User Titles 2]: Custom Title (empty = none):'}, {name:'user3name', type:'str', required: false, label:'[User Titles 3]: Username (empty=disabled):',}, {name:'user3title', type:'str', required: false, label:'[User Titles 3]: Custom Title (empty = none):'}, {name:'user4name', type:'str', required: false, label:'[User Titles 4]: Username (empty=disabled):',}, {name:'user4title', type:'str', required: false, label:'[User Titles 4]: Custom Title (empty = none):'}, {name:'user5name', type:'str', required: false, label:'[User Titles 5]: Username (empty=disabled):',}, {name:'user5title', type:'str', required: false, label:'[User Titles 5]: Custom Title (empty = none):'}, {name: 'custCommands', label: '[Custom Commands] Use this feature?:', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes', required: false}, {name:'bio', type:'str', required: false, label:'/bio',defaultValue: '{newline} Please read the Bio'}, {name:'dontmmm', type:'str', required: false, label:'/dontmmm',defaultValue: "{newline} Please Don't mmm at me"}, {name:'dirty', type:'str', required: false, label:'/dirty',defaultValue: '{newline} Please keep dirty talk in tip notes'}, {name:'follow', type:'str', required: false, label:'/follow',defaultValue: '{newline} Please follow me'}, {name:'manyvids', type:'str', required: false, label:'/manyvids',defaultValue: '{newline} Please check out my Manyvids profile'}, {name:'amazon', type:'str', required: false, label:'/amazon',defaultValue: '{newline} Please check out my Amazon wishlist'}, {name:'location', type:'str', required: false, label:'/location',defaultValue: '{newline} Please don\'t ask where I\'m from'}, ] /************************************************************************************************************************************ ***** Global Variables ************************************************************************************************************** ************************************************************************************************************************************/ var roomHost = cb.room_slug; // Name of the broadcaster var dev = dev = '\x6d\x69\x6e\x78\x79\x6d\x61\x65\x76\x65'; var tipArray = new Array; var tipArraySorted = true; var tipTotal = 0; var tipNote = ''; var modArray = new Array; // array of mods modArray[0] = roomHost; var emodArray = new Array; // [i] = User's name, list of users who have been given emergency mod powers emodArray[0] = dev; var modAndEmodArray = new Array; // array of mods and emods modAndEmodArray[0] = dev; var modBlockMsgArray = new Array; // [i] = Mod/user's name, list of mods who should see the Blocked Message notices modBlockMsgArray[0] = roomHost; // add roomhost as first entry and just skip them when iterating for notices if the host doesn't want to see var lastBlocked = new Array; // username of user that was last blocked by the app var niceArray = new Array; // [i] = user's name, list of users who have been added to the nice list var greyArray = new Array; // [i] = user's name, list of users who have been added to the grey list var silenceArray = new Array; // [i] = User's name, list of users who have been silenced var lastToUseSL = null; // name of mod who used the /silencelast cmmand within the last 5 seconds var lastToGetSLed = null; // name of the person silenced with the /silencelast command within the last 5 seconds var ignoreArray = new Array; // [i][0] = user's name, [i][1] = user's ignore level, [i][j>1] = person on the user's ignore list var numIgnorers = 0; // number of users who have added people to their ignore lists var whisArray = new Array; // [i][0] = user's name, [i][1] = user who most recently whispered user [i][0] var numWhis = 0; // number of users stored in whisArray var whis = ''; // most recent whisper var silenceLevel = 0; var graphicLevel = 1; var capsLevel = 1; var stickyLevel = 1; var startTime = 0; // the time the timer was started. it is used to calculate time left var timerDuration = 0; // length of the timer in minutes var timerTimeout = 0; var oneTimeout = 0; var fiveTimeout = 0; var timeRemaining = 0; var currentKing = ''; // holds the user name of the current king var kingTip = 0; // holds the value of the king tipper's tip total var kingMin = parseInt(cb.settings.kingMin); // minimum amount for king tipper to register var kingTimer = parseInt(cb.settings.kingTipperTimer); // user defined interval for king spam var kingTimeout = 0; // setTimeOut that will be used later for king spam var ldrArray = [['',0],['',0],['',0]]; // array that holds the top 3 tippers' names and tip totals var ldrTimer = parseInt(cb.settings.leaderBoardTimer); // user defined interval for leader spam var ldrTimeout = 0; // setTimeOut that will be used later for leaderboard spam var initialize = 0; // runs init() once only var kingTipperSpam = 0; // facilitates command to toggle king tipper spam var notifierSpamTGL = 0; // facilitates command to toggle notifier spam var leaderboardSpam = 0; // facilitates command to toggle leaderboard spam var noticeArray = []; // Array of rotating notices var noticeNum = 0; // Index into rotating notices var notifierTimer = parseInt(cb.settings.notifierTimer); // user defined interval for leader spam var notifierTimeout = 0; var customWordlistRegex = ''; // Regular expression for custom wordlist var minuteMS = parseInt(60000); // one minute in milliseconds // var minuteMS = parseInt(1000); // make it quicker for debug //Sophie's tips variables var separator_char = " "; //colors and styles var black = "#000033"; // CB default black -- Not true black var white = "#FFFFFF"; var purple_dark = "#993377"; var purple_light = "#DDBBCC"; var green_dark = "#007700"; var green_light = "#CCEEAA"; var teal_dark = "#009999"; var teal_light = "#BBEEEE"; var pink_dark = "#EE4499"; var pink_light = "#FFCCEE"; var red_dark = "#BB2222"; var red_light = "#FFCCCC"; var orange = "#DC5500"; var orange_dark = "#FF8833"; var orange_light = "#FFDDCC"; var grey_dark = "#666666"; var grey_light = "#DDDDDD"; var yellow_dark = "#EEAA00"; var yellow_light = "#FFFF55"; var mod_orange = "#DC5500"; var bb_dark = "#2A6F91" var bb_light = "#C2DCEB"; var bb_lt_light = "#EEF5FA"; var bb_lt_dark = "#8BB2C6"; var error_dark = red_dark; var error_light = red_light; var success_dark = green_dark; var success_light = green_light; var theme_dark = purple_dark; var theme_light = purple_light; var bullets = ' \u2022 \u2022 \u2022 '; var crown = ':smallCrown'; //colors from stones var yellow = "#FFEE33"; var pink = "#FF00EE"; var purple = "#660099'"; var orange = '#DC5500'; var red = '#DC0000'; var green = '#009900'; var blue = '#000099'; var cyan = '#6699AA'; var grey = '#494949'; //Variables to emulate Sophie's Stones var club1Array ; var club1OrigArray ; var titlesArray =new Array; var NUM_TITLES = 10; var maxFanclubLength = 30000; // set to same as fanClub1members max length in the control panel var modsCanChangeFanclub1=0; var modsCanChangeUserTitles=0; /************************************************************************************************************************************ ***** Functions ********************************************************************************************************************* ************************************************************************************************************************************/ // FUNCTION ==> PURPOSE // findTipper ==> finds and returns the index of a user // emodArrayPopulate ==> adds users to the emodArray // niceArrayPopulate ==> adds users to the niceArray // greyArrayPopulate ==> adds users to the greyArray // notify ==> shorthand for sending notices to the mods and broadcaster // setSilenceLevel ==> called when /silencelevel is used. sets silenceLevel // setGraphicLevel ==> called when /graphiclevel is used. sets graphiclevel // silence ==> called when /silence is used. adds a user to the silenceArray // unsilence ==> called when /unsilence is used. removes a user from the silenceArray // startTimer ==> called when /starttimer is used. starts a timer for t minutes // timer ==> called from startTimer. it's the actual timer // fiveMinuteWarning ==> called from startTimer. if t > 5, sounds a warning at 5 minutes remaining // oneMinuteWarning ==> called from startTimer. if t > 2, sounds a warning at 1 minute remaining // timeLeft ==> called when /timeleft is used. sends the user a notice with the time remaining // addTime ==> called when /addtime is used. adds t minutes to the timer, if one is running // sendNote ==> called when /note is used. sends a notification to the room // sendWhisper ==> called when /whisper or an alias of /whisper is used. sends a private message to a user in chat // ignoreUser ==> called when /ignore is used. adds a member to the user's ignore list // unignoreUser ==> called when /unignore is used. removes a member from the user's ignore list // setIgnoreLevel ==> called when /ignorelevel is used. sets ignoreLevel for the user // setTipTitles ==> called from onMessage. appends the user's tips to the beginning of the message // emod ==> called when /emod is used. adds or removes a user from the emodArray // kingSpam ==> spams "tip x to be king" every 5 minutes if the user setting allows it // kingSpamTimer ==> the actual timer for kingSpam // theLeaderBoard ==> creates the elements for the leaderboard // ldrSpam ==> spams the leaderboard every 5 minutes // ldrSpamTimer ==> the actual timer for ldrSpam // showLeaderBoard ==> called when /leaderboard is used. shows the leaderboard // notifierSpam ==> called from init, starts the timer for notifer spam // notiferSpamTimer ==> the actual timer for notifierSpam // nice ==> called from /addnice and /removenice. adds and removes users from the niceArray // grey ==> called from /addgrey and /removegrey. adds and removes users from the greyArray // kingSpamToggle ==> called when /kingspam is used. toggles the spam // notifierSpamToggle ==> called when /notifierspam is used. toggles the spam // colorChecker ==> verifies the color code is valid // chatAd ==> shows tip menu in chat (from Sophie's Tips) // club1ArrayPopulate ==> adds users to the club1Array (from Sophie's Stones) // titleArrayPopulate ==> adds users to the titleArray (from Sophie's Stones) function appTimeout(func, msec) { cb['setTimeout'](func, msec < 1000 ? 1000 : msec); // cb.setTimeout doesn't like timeout values less than 1000 } var setTimeout = function setTimeout(func, delay) { if (!(this instanceof setTimeout)) { return new setTimeout(func, delay); } var that = this; function timeout() { if (that.cancelled) { return; } func(); } appTimeout(timeout, delay); }; var clearTimeout = function clearTimeout(timeout) { if (timeout != null) { timeout.cancelled = true; } }; // var setInterval = function setInterval(func, delay) { // if (!(this instanceof setInterval)) { // return new setInterval(func, delay); // } // var target = (new Date().valueOf()) + delay; // var that = this; // function tick() { // if (that.stopped) { // return; // } // target += delay; // func(); // appTimeout(tick, target - (new Date().valueOf())); // } // appTimeout(tick, delay); // }; // var clearInterval = function clearInterval(interval) { // if (interval != null) { // interval.stopped = true; // } // }; function addTip(user, amount) { // Add tip to the tipper list, returning the user's updated total. // Using this feature is optional, so nTotal must be updated separately. var i; var index = -1; // Adding a tip means the list is no longer sorted tipArraySorted = false; // See if this user already has an entry for (i = 0; i < tipArray.length; i += 1) { if (tipArray[i].sUser === user) { index = i; break; } } if (index < 0) { // User is not in list so add them tipArray.push({sUser: user, nTotal: amount}); return amount; } else { // Update the user's tip total tipArray[index].nTotal += amount; return tipArray[index].nTotal; } } function sortTipArray() { // Sort the tipper list if necessary if (!tipArraySorted) { tipArray.sort(function(a, b) { // Reverse sort on tip totals return b.nTotal - a.nTotal; }); tipArraySorted = true; } } function getUserTotal(user) { var i; for (i = 0; i < tipArray.length; i += 1) { if (tipArray[i].sUser === user) { return tipArray[i].nTotal; } } return 0; } function findTipper(user) { var i; for (i = 0; i < tipArray.length; i += 1) { if (tipArray[i].sUser == user) { return i; } } return -1; } function modArrayPopulate(user) { if(!cbjs.arrayContains(modArray,user)) { modArray.push(user); } } function modArrayDepopulate(user) { if(cbjs.arrayContains(modArray,user)) { cbjs.arrayRemove(modArray,user); } } function emodArrayPopulate(user) { if(!cbjs.arrayContains(emodArray,user)) { emodArray.push(user); } } function emodArrayDepopulate(user) { if(cbjs.arrayContains(emodArray,user)) { cbjs.arrayRemove(emodArray,user); } } function modAndEmodArrayPopulate(user) { if(!cbjs.arrayContains(modAndEmodArray,user)) { modAndEmodArray.push(user); } } function modAndEmodArrayDepopulate(user) { if(cbjs.arrayContains(modAndEmodArray,user)) { cbjs.arrayRemove(modAndEmodArray,user); } } function modBlockMsgArrayPopulate(user) { if(!cbjs.arrayContains(modBlockMsgArray,user)) { modBlockMsgArray.push(user); } } function modBlockMsgArrayDepopulate(user) { if(cbjs.arrayContains(modBlockMsgArray,user)) { cbjs.arrayRemove(modBlockMsgArray,user); } } function niceArrayPopulate(user) { niceArray.push(user); } function niceArrayDepopulate(user) { cbjs.arrayRemove(niceArray,user); } function greyArrayPopulate(user) { greyArray.push(user); } function greyArrayDepopulate(user) { cbjs.arrayRemove(greyArray,user); } function silenceArrayPopulate(user) { silenceArray.push(user); } function silenceArrayDepopulate(user) { cbjs.arrayRemove(silenceArray,user); } function ignoreArrayPopulate(user) { ignoreArray[numIgnorers] = new Array; ignoreArray[numIgnorers][0] = user; if (cb.settings.roomWhisperLevel) { ignoreArray[numIgnorers][1] = parseInt(cb.settings.roomWhisperLevel.charAt(0)); } else { ignoreArray[numIgnorers][1] = 0; } numIgnorers++; } function findIgnorer(user) { for(i = 0; i < ignoreArray.length; i++) { if(ignoreArray[i][0] == user) { break; } } if(i == ignoreArray.length) { ignoreArrayPopulate(user); findIgnorer(user); } return i; } function whisArrayPopulate(user) { whisArray[numWhis] = new Array; whisArray[numWhis][0] = user; whisArray[numWhis][1] = ''; numWhis++; } function findWhisper(user) { //find the index of the user for(var i = 0; i < whisArray.length; i++) { if(whisArray[i][0] == user) { break; } } //the user is not in the array. add him and call findWhisper if(i == whisArray.length) { whisArrayPopulate(user); findWhisper(user); } return i; } function notify(message, u, bg, c, w) { if (bg == null) { bg = bb_light; } if (c == null) { c = bb_dark; } if (w == null) { w = 'bold'; // leave at '' for normal } if (u == 'onlyMods') { cb.sendNotice(message,'',bg,c,w,'red'); } else if (u == 'modsAndEmods') { for (mod = 0; mod < modAndEmodArray.length; mod++) { thisMod = modAndEmodArray[mod]; cb.sendNotice(message,thisMod,bg,c,w); } } else if (u == 'roomHost') { cb.sendNotice(message,roomHost,bg,c,w); } else if (u == 'modsAndHost') { cb.sendNotice(message,'',bg,c,w,'red'); cb.sendNotice(message,roomHost,bg,c,w); } else if (u == null) { cb.sendNotice(message,'',bg,c,w); } else { cb.sendNotice(message,u,bg,c,w); } } function notifyBold(message, u, bg, c) { if (bg == null) { bg = bb_dark; } if (c == null) { c = white; } notify(message, u, bg, c, 'bold'); } function notifyPlain(message, u, c) { bg = white; if (c == null) { c = bb_dark; } notify(message, u, bg, c); } function notifyTheme(message, u, bg, c) { if (bg == null) { bg = theme_light; } if (c == null) { c = theme_dark; } notify(message, u, bg, c, 'bold'); } function notifyThemeBold(message, u, bg, c) { if (bg == null) { bg = theme_dark; } if (c == null) { c = white; } notify(message, u, bg, c, 'bold'); } function notifyThemePlain(message, u, c) { bg = white; if (c == null) { c = theme_dark; } notify(message, u, bg, c); } function notifyError(message, u) { notify(message, u, error_light, error_dark); } function notifyErrorBold(message, u) { notify(message, u, error_dark, white); } function levelConditions(l) { //I think I can do this with an array variable instead. var condition; switch(parseInt(l)) { case 0: condition = 'Everyone'; break; case 1: condition = 'Only \"color\" names'; break; case 2: condition = 'Only members who have tipped in the room'; break; case 3: condition = 'Only mods and fanclub members and faves'; break; case 4: condition = 'Just mods'; break; } return condition; } function setSilenceLevel(l, mod) { if(parseInt(l) >= 0 && parseInt(l) <= 2) { silenceLevel = parseInt(l); var silenceLevelMessage = 'The silence level has been set to ' + l + '.\n'; silenceLevelMessage += levelConditions(l) + ' can talk in chat.'; notify(silenceLevelMessage, 'modsAndHost'); } else if(l) { notifyError('"' + l + '" is not a valid silence level.\nType "/bombhelp\xa0silencelevel" to see how to use /silencelevel.', mod); } else { notifyError('You did not enter a valid silence level.\nType "/bombhelp\xa0silencelevel" to see how to use /silencelevel.', mod); } } function setGraphicLevel(l, mod) { if(parseInt(l) >= 0 && parseInt(l) <= 4) { graphicLevel = parseInt(l); var graphicLevelMessage = 'The graphic level has been set to ' + l + '.\n'; graphicLevelMessage += levelConditions(l) + ' can use graphics in chat.'; notify(graphicLevelMessage, 'modsAndHost'); } else if(l) { notifyError('"' + l + '" is not a valid graphic level.\nType "/bombhelp\xa0graphiclevel" to see how to use /graphiclevel.', mod); } else { notifyError('You did not enter a valid graphic level.\nType "/bombhelp\xa0graphiclevel" to see how to use /graphiclevel.', mod); } } function setIgnoreLevel(l, user) { if(parseInt(l) >= 0 && parseInt(l) <= 4) { ignoreArray[findIgnorer(user)][1] = l; var ignoreMessage = 'You have set your whisper ignore level to ' + l + '.\n'; ignoreMessage += levelConditions(l) + ' can send you whispers.\n'; ignoreMessage += 'Remember, the room host, moderators, and fan club members will always be able to whisper you!'; notify(ignoreMessage, user); } else if(l) { notifyError('"' + l + '" is not a valid ignore level.\nType "/bombhelp\xa0ignorelevel" to see how to use /ignorelevel.', user); } else { notifyError('You did not enter a valid ignore level.\nType "/bombhelp\xa0ignorelevel" to see how to use /ignorelevel.', user); } } function silence(user, mod) { if (user == mod) { notifyError('You can not silence yourself.', mod); } else if (user == roomHost) { notifyError('You can not silence the broadcaster.', mod); } else if (cbjs.arrayContains(modArray, user)) { notifyError('Broadcaster must revoke ' + user + '\'s moderator status before silencing.', mod); } else if (cbjs.arrayContains(emodArray, user)) { notifyError('You must revoke ' + user +'\'s emergency moderator status before silencing. (Type "/emod remove ' + user + '")', mod); } else if (cbjs.arrayContains(niceArray, user)) { notifyError('You must remove ' + user +' from the nice list before silencing. (Type "/removenice ' + user + '")', mod); } else { if(user) { user = user.toLowerCase(); } if(user == null) { notify('You must specify a user to silence.', mod); } else if(!cbjs.arrayContains(silenceArray,user)) { silenceArrayPopulate(user); var silenceMessage = mod + ' has silenced ' + user + '.'; notify(silenceMessage, 'modsAndEmods'); // notify(mod + ' has silenced you.', user); } else { notifyError(user + ' has already been silenced.', mod); } } } function unsilence(user, mod) { if(user) { user = user.toLowerCase(); } if(user == null) { notify('You must specify a user to unsilence.', mod); } else if(cbjs.arrayContains(silenceArray,user)) { cbjs.arrayRemove(silenceArray,user); var unsilenceMessage = mod + ' has unsilenced ' + user + '.'; notify(unsilenceMessage, 'modsAndEmods'); // notify(mod + ' has unsilenced you.', user); } else { notifyError(user + ' does not need to be unsilenced.', mod); } } function silenceLast(mod) { if (lastBlocked.length) { if (lastToUseSL == null || lastToUseSL == mod) { //if the person is using it for the first time in at least 5 seconds, or it's the same person again u = lastBlocked.pop(); lastToUseSL = mod; lastToGetSLed = u; silence(u,mod); cb.setTimeout(function() { lastToUseSL = null; lastToGetSLed = null; }, 5000); } else { notifyError(lastToUseSL + ' has just silenced ' + lastToGetSLed + ' using the /silencelast command. Please wait at least 5 seconds before using this command again.', mod); } } else { notifyError('The bot has not automatically silenced anyone yet, or they have all been silenced already.', mod); } } function setTimer(sec) { clearTimeout(fiveTimeout); clearTimeout(oneTimeout); clearTimeout(timerTimeout); if (sec == 0) { startTime = 0; return; } // 5 minute warning if (sec > 300) { fiveTimeout = setTimeout(function() { notifyThemeBold('Five minutes remaining!'); }, (sec-300)*1000); } // 1 minute warning if (sec > 60) { oneTimeout = setTimeout(function() { notifyThemeBold('One minute remaining!'); }, (sec-60)*1000); } timerTimeout = setTimeout(function() { notifyThemeBold(bullets + ' Timer is up! ' + bullets); startTime = 0; }, sec*1000); } function startTimer(min, mod) { var t = parseInt(min); var sec = t*60; if (startTime == 0) { if(t > 0 && t.toString().indexOf('.') == -1) { timeRemaining = sec; timerDuration = sec; startTime = new Date(); setTimer(sec); if(mod != null) { notifyThemeBold(mod + ' has set a timer for ' + t + ' minutes!'); } } else if(min != null) { notifyError('\'' + min + '\' is not a valid option for /starttimer.\nType "/bombhelp\xa0starttimer" to see how to use /starttimer.',mod); } else if(min == null) { notifyError('You did not enter a valid option for /starttimer.\nType "/bombhelp\xa0starttimer" to see how to use /starttimer.',mod); } } else { if(mod != null) { notifyError('There is a timer running already.',mod); } } } function addTime(min, mod) { t = parseInt(min); var sec = t*60; if(t > 0 && t.toString().indexOf('.') == -1) { if (startTime != 0) { startTime.setSeconds(startTime.getSeconds() + sec); var currentTime = new Date(); timeRemaining = startTime.getHours()*3600 + startTime.getMinutes()*60 + startTime.getSeconds() + timerDuration - currentTime.getHours()*3600 - currentTime.getMinutes()*60 - currentTime.getSeconds(); setTimer(timeRemaining); notifyThemeBold(mod + ' has has added ' + t + ' minute' + (t == 1 ? '' : 's') + ' to the timer!'); } else { notifyError('There is no timer running.',mod); } } else if(min != null) { notifyError('\'' + min + '\' is not a valid option for /addtime.\nType "/bombhelp\xa0addtime" to see how to use /addtime.',mod); } else if(min == null) { notifyError('You did not enter a valid option for /addtime.\nType "/bombhelp\xa0addtime" to see how to use /addtime.',mod); } } function stopTimer(mod) { if (startTime != 0) { setTimer(0); notifyThemeBold(mod + ' has has cancelled the timer.'); } else { notifyError('There is no timer running.',mod); } } function doubleDigit(num) { return ("0" + num).slice(-2); } function timeLeft(user) { if(startTime != 0) { var currentTime = new Date(); timeRemaining = startTime.getHours()*3600 + startTime.getMinutes()*60 + startTime.getSeconds() + timerDuration - currentTime.getHours()*3600 - currentTime.getMinutes()*60 - currentTime.getSeconds(); var hours = doubleDigit(Math.floor(timeRemaining/3600)); var minutes = doubleDigit(Math.floor((timeRemaining-hours*3600)/60)); var seconds = doubleDigit(timeRemaining-hours*3600-minutes*60); notify('Time Remaining: ' + hours + ':' + minutes + ':' + seconds, user); } else { notifyError('There is no timer running.',user); } } function sendNote(message,from) { message = message.split(/\s+/g); //turn the message into an array var m = ''; //build the message for(var i = 0; i < message.length; i++) { if(message[i].match(/^((\\|\/)n(ote)*|\{newline\})$/ig)) { m += '\n'; } else { m += ' ' + message[i]; } } notifyTheme(m); } function doWhisper(message, recipient, from, reply) { whis = ':bb-lightbubble [Whisper from: ' + from + ']\xa0 '; var w = null; var p; //position where message starts (2 in a whisper, 1 in a reply) if (reply == true) { p = 1; } else { p = 2; } cb.log(p); //build the message for(var i = p; i < message.length; i++) { if(i == p) { w = message[i]; } else { w += ' ' + message[i]; } } whisArray[findWhisper(recipient)][1] = from; if(recipient) { if (w) { notifyBold((whis + w).trim(),recipient); } else { notifyError('You did not specify a message.', from); } } } function textReplaceWhisper(message, from, reply) { var recipient = null; var m = null; //message var p; //position where message starts (2 in a whisper, 1 in a reply) if (reply == true) { recipient = whisArray[findWhisper(from)][1]; p = 1; } else { recipient = message[1]; p = 2; } if (recipient) { //build the message for(var i = p; i < message.length; i++) { if(i == p) { m = message[i]; } else { m += ' ' + message[i]; } } if (m) { m = ':bb-darkbubble [Whisper to: ' + recipient.toLowerCase() + ']\xa0 ' + m; } } if (!recipient || !m) { if (reply == true) { m = 'Reply not sent.'; } else { m = 'Whisper not sent.'; } } return m; } function sendWhisper(message, from, mod, whisperLevel) { var recipient; if (message[1]) { recipient = message[1].toLowerCase(); } else { notifyError('You did not enter a whisper recipient.',from); } if(recipient != from) { if(cbjs.arrayContains(silenceArray,from)) { notifyError('You do not have whispering privileges. Your message was not sent.',from) } else if(!cbjs.arrayContains(ignoreArray[findIgnorer(recipient)],from) || mod) { switch(parseInt(ignoreArray[findIgnorer(recipient)][1])) { case 0: doWhisper(message, recipient, from); break; case 1: if(whisperLevel > 1 || mod) { doWhisper(message, recipient, from); } else { notifyError(recipient + ' is ignoring whispers from greys.',from); } break; case 2: if(whisperLevel > 2 || mod) { doWhisper(message, recipient, from); } else { notifyError(recipient + ' is ignoring whispers from greys and light blues who haven\'t tipped in the room.',from); } break; case 3: if(whisperLevel > 3 || mod) { doWhisper(message, recipient, from); } else { notifyError(recipient + ' is ignoring whispers from all members who haven\'t tipped in the room.',from); } break; case 4: if(mod) { doWhisper(message, recipient, from); } else { notifyError(recipient + ' is ignoring whispers.',from); } break; } } else { notifyError(recipient + ' is ignoring whispers from you. Your message was not sent.',from) } } else { notifyError('Talking to yourself is a little odd...',from); } } function sendReply(message, from) { var recipient = whisArray[findWhisper(from)][1]; if(cbjs.arrayContains(silenceArray,from)) { notifyError('You do not have whispering privileges. Your message was not sent.',from) } if(!cbjs.arrayContains(ignoreArray[findIgnorer(recipient)],from)) { if(recipient != '') { doWhisper(message, recipient, from, true); } else { notifyError('No one has whispered you.',from); } } else { notifyError(recipient + ' is ignoring whispers from you. Your message was not sent.',from) } } function ignoreUser(user, from) { if(cbjs.arrayContains(ignoreArray[findIgnorer(from)],user)) { if(user == from) { notifyError('You can\'t ignore yourself. You may want to consult a therapist.',from); } else { notifyError('You are already ignoring that user\'s whispers.',from); } } else if(user) { ignoreArray[findIgnorer(from)][ignoreArray[findIgnorer(from)].length] = user; notify('You are now ignoring whispers from ' + user + '.',from); notify('Remember, the room host, moderators, and fan club members will always be able to whisper you!',user); } else { notifyError('You did not specify a user to ignore. Type "/bombhelp\xa0ignore" to see how to use /ignore.',from); } } function unignoreUser(user,from) { if(user == from) { notifyError('My, you are an odd one, aren\'t you?', from); } else if(cbjs.arrayContains(ignoreArray[findIgnorer(from)],user)) { cbjs.arrayRemove(ignoreArray[findIgnorer(from)],user); notify('You are no longer ignoring whispers from ' + user, from); } else if(user) { notifyError(user + ' is not being ignored. There is no need to unignore ' + user, from); } else { notifyError('You did not specify a user to unignore. Type "/bombhelp\xa0unignore" to see how to use /unignore.',from); } } function setTipTitles(user, message) { var prefix = ''; if(cb.settings.kingTipper == 'Yes' && user == currentKing) { prefix = crown + ' '; } var m = prefix + '|' + getUserTotal(user) + '| ' + message; return m; } function emod(ar,user,from) { if(user) { user = user.toLowerCase(); } if(ar == 'add') { if(!cbjs.arrayContains(emodArray,user)) { emodArrayPopulate(user); modAndEmodArrayPopulate(user); if (cb.settings.wordlistShowModerators == 'Yes') { modBlockMsgArrayPopulate(user); } notify('Emergency moderator powers have been granted to ' + user,from); notify('You have been granted emergency moderator powers by ' + from,user); } else { notifyError(user + ' has already been granted emergency moderator powers.',from); } } else if(ar == 'remove') { if(cbjs.arrayContains(emodArray,user)) { emodArrayDepopulate(user); // modAndEmodArrayDepopulate(user); // modBlockMsgArrayDepopulate(user); notify('Emergency moderator powers have been removed from ' + user,from); notify('Your emergency moderator powers have been removed by ' + from,user); } else { notifyError(user + ' has not been granted emergency moderator powers.',from); } } else if(ar) { notifyError(ar + ' is not a valid option for /emod. Type "/bombhelp\xa0emod" to see how to use /emod.',from); } else { notifyError('You did not enter a valid option for /emod. Type "/bombhelp\xa0emod" to see how to use /emod.',from); } } function blockNotice(ar,user) { if(ar == 'on') { if(!cbjs.arrayContains(modBlockMsgArray,user)) { modBlockMsgArrayPopulate(user); notify('You have turned ON Blocked Message notices. To turn them back off again, type: /blocknotice\xa0off',user); } else { notifyError('Your Blocked Message notices are already turned on',user); } } else if(ar == 'off') { if(cbjs.arrayContains(modBlockMsgArray,user)) { modBlockMsgArrayDepopulate(user); notify('You have turned OFF Blocked Message notices. To turn them back on again, type: /blocknotice\xa0on',user); } else { notifyError('Your Blocked Message notices are already turned off',user); } } else if(ar) { notifyError(ar + ' is not a valid option for /blocknotice. Type "/bombhelp\xa0blocknotice" to see how to use /blocknotice.',user); } else { notifyError('You did not enter a valid option for /blocknotice. Type "/bombhelp\xa0blocknotice" to see how to use /blocknotice.',user); } } function kingSpam() { clearTimeout(kingTimeout); kingTimeout = setTimeout(kingSpamTimer,kingTimer*minuteMS); } function kingSpamTimer() { if(kingTip < kingMin) { var supplant = kingMin; } else { var supplant = kingTip + 1; } if(kingTipperSpam == 1) { notifyTheme(crown + ' Tip a total of ' + supplant + ' to become the new King! ' + crown); kingSpam(); } } function showLeaders(places, to) { var i; var theLeaders = ''; if (!tipArray.length) { notifyError('No tips yet', to); return; } sortTipArray(); for (i = 0; i < places && i < tipArray.length; i += 1) { theLeaders += (i ? '\n' : '') + (i + 1) + '.\xa0\xa0' + tipArray[i].sUser + '\xa0\xa0(' + tipArray[i].nTotal + ' tokens)'; } cb.setTimeout(function() { notifyThemeBold(bullets + 'Leader Board' + bullets, to); }, 500); // make sure this happens AFTER command is sent cb.setTimeout(function() { //notifyTheme(theLeaders + '\n', to); remove blank line at end of leaderboard notifyTheme(theLeaders , to); }, 1500); // wait a second to hopefully make this show up in the proper order } function ldrSpam() { clearTimeout(ldrTimeout); ldrTimeout = setTimeout(ldrSpamTimer,ldrTimer*minuteMS); } function ldrSpamTimer() { if(cb.settings.leaderBoard == 'Yes' && leaderboardSpam == 1) { if (tipArray.length) { showLeaders(cb.settings.leaderBoardSize, ''); } ldrSpam(); } } function showLeaderBoard(from) { if(cb.settings.leaderBoard == 'Yes') { showLeaders(cb.settings.leaderBoardSize, from); } else { notifyError('The room host has decided not to use the Leaderboard feature.',from); } } function notifierSpam() { notifierTimeout = setTimeout(function() { if(notifierSpamTGL == 1) { if (noticeArray.length) { sendRotating(); notifierSpam(); } } }, notifierTimer*minuteMS); } // function notifierSpamTimer() { // if(notifierSpamTGL == 1) { // if (!isBlank(notifierMessage)) { // notify(notifierMessage); // notifierSpam(); // } // } // } function addNotice(m) { if (!isBlank(m)) { m = m.replace(/((\\|\/)n|\{newline\})/ig, "\n"); noticeArray.push(m); } } function parseRotating() { // Parse setup screen for rotating notices addNotice(cb.settings.spamMessage1); addNotice(cb.settings.spamMessage2); addNotice(cb.settings.spamMessage3); addNotice(cb.settings.spamMessage4); addNotice(cb.settings.spamMessage5); addNotice(cb.settings.spamMessage6); addNotice(cb.settings.spamMessage7); addNotice(cb.settings.spamMessage8); } function sendRotating() { // Send the next rotating notice if (noticeArray.length) { // Since we pushed, there should be no gaps, even if there were some // in the GUI. But check that it's valid, just in case. if (noticeArray[noticeNum]) { notifyTheme(noticeArray[noticeNum]); } noticeNum += 1; if (noticeNum >= noticeArray.length) { noticeNum = 0; } } } function parseWordlist() { if (!isBlank(cb.settings.customWordlist)) { customWordlistRegex = cb.settings.customWordlist.replace(/^(\s|,|\|)+|(\s|,|\|)+$/gm, ''); //trim leading/trailing spaces, commas, or pipes from string customWordlistRegex = customWordlistRegex.replace(/\s*(,|\|)\s*/gm, '|'); // replace commas or pipes surrounded by spaces with pipes customWordlistRegex = customWordlistRegex.replace(/[^\w|\s]/gm, ' '); // replace anything that's not a letter or a pipe with a space customWordlistRegex = customWordlistRegex.replace(/(\w)/gm, '$1+' ); //add a + between each letter customWordlistRegex = customWordlistRegex.replace(/\s+/gm, '\\s*' ); // replace spaces with \s* } } function doWordlist(msg) { var m = msg.trim().replace(/([^\w\s\u0027\u2019\[\]]|_)/ig, ' '); // Reusable RegEx //split demandverbs into sex demandverbs and "wanna" demand verbs? var demandverbs = '\\b(w+a+n|g+o+i*n|n+e+e+d|(c+a+n+|m+a+y+)\\s(i+|w+e+|[^\\s]*u+)|l+e+t*s*\\s*m+e+(\\s*(s+e+e+|c+))*|g+i+(m+|v+e+)\\s*m+e|p+l+a+y\\w*\\s*w|p+u+t|e+a+t|s+h+o+w|m+o+r+e|f+l+a+s+h|f+e+e+l|r+i+d+e|s+l+i+d|t+a+k+e+\so+u+t|o+p+e+n|c+l+o+s|c+u+m|s+h+a+k|d+o+g+(y|i)|s+p+(a|u)+n+k|s+q+u*e*z|p+o+u+n+d|s+h+o+v+e|s+m+a+c+k|f+i+n+g+e+r|b+l+o+w|(f|s)+u+c*k|f+c+k|l+i+c+k|k+i+s+s|m+a+s+t\\w*b+a+t|w+a+n+k|j+e+r+k|(j+|w+h*)a+c+k)\\w*\\b'; var girlyparts = '\\b(p+u+s|v+a+(g|j)|t+w+a+t|k+i+t+t|(c|s)+l+i+t|l+i+p|b+o+b|n+i+p|t+i+t|[^w\\s]*h+o+l+e|c+u+n+t|f+i+n+g+e+r|m+o+u+t+h|t+o+n+g+u|t+o*u+n+g|a+r+m+\\s*p+i+t)\\w*\\b' + '|'; girlyparts += '\\b(a+s+s|b+u+t+t|m+u+f+f|b+o+o+t+(y|i)|a+n+u+s|l+e+g+s*)\\b'; var guyparts = '\\b(d+i+c+k|b+o+n+e+r|c+o+c*(c|k)|p+e+n+i+s|m+e+a+t|bbc)\\w*\\b'; var toys = '\\b(d+i+l+d+o|t+o+y|b+u+t+t+\s*p+l+u+g|v+i+b|h*i*t+a+c+h+i)\\w*\\b' var naked = '\\b(n+a*k+e*d+|n+u+d+e+|b+a+r+e+)\\b'; var clothing = '(c+l+o+t+h|b+r+a+|(p+a+n+t+(i|y)*|s+(h|k)+i+r+t|d+r+e+s|s+t*o+(c+k|x)|s+h+o+e)\\w*\\b)'; var removeit = '(r+e+m+o+v+e+|t+a+k+e\\s*o+f+f+)'; var tmi_iam = '\\b(i+.{0,1}a*m+|i+|a+m+|i+s+|s+o+)\\b'; var tmi_adj = '\\b(h+a*r+d|w+e+t|h+o+r+n|t+h+i+c+k)\\w*\\b'; var tmi_intent = '\\b((l+o+v+e|l+u+v|g+o+i+n)\\w*\\s*(2+|t+o+)|l+e+(t|m)+\\s*m+e+|m+a+y+|c+a+n+)\\b' + '|'; tmi_intent += '\\b(g+o+t+|w+a+n|g+o+n|w+i+s+h)\\w*\\b'; var tmi_verb = '\\b(m+a+s+t\\w*b+a+t|w+a+n+k|j+e+r+k|(j+|w+h*)a+c+k|t+a+s+t|e+a+t|c+u+m|i+n+s+i+d+e|s+m+e+l+l|s+n+i+f+f|l+i+c+k|(f|s)+u+c*k|f+c+k)\\w*\\b'; var tmi_cum = '\\b(c+u+m|s+e+m+e+n|s+p+e+r+m|b+u+s+t.*n+u+t)\\w*\\b'; // Workaround (Block anything people try to space out to get around rules) var list_workaround = new RegExp('((^|\\s)[^\\s]\\s[^\\s]\\s[^\\s]($|\\s))', 'i'); // this matches 3 or more single spaced-out characters // No sexual words in a REALLY short message var list_directness = new RegExp('\\b(' + girlyparts + '|' + guyparts + '|' + demandverbs + '|' + naked + '|' + tmi_verb + '|' + tmi_cum + '|p+l+e*a*i*(s|z)+e*)\\b', 'i'); // Non-English characters var non_english = new RegExp('[^\\x00-\\xAE\\u2000-\\u206F]'); // BB var list_bb = new RegExp('\\b(b+(a|e)*b+(y|e)*)\\b', 'i'); // Rude var list_rude = new RegExp('\\b(h+o+e+s*)\\b|'+ '(c+u+n+t|s+l+u+t|s+k+a+n+k|w+h+o+r+e|b+i+t+c+h|n+i+g+g+e+r|t+r+a+n+n+(y|i))' , 'i'); // Sticky/Annoying var list_annoying = new RegExp('\\b([a-g|i-z]*(h+u+)*m+m+h*|u+f+)\\b', 'i'); // Spam var list_spam = new RegExp('(s+k+(y|i)*p+e|s+k+y*p|(f+r+e+e|unlimited).*t+o+k+e+n|t+o+k+e+n.*(f+r+e+e|generator)|erotimo|freecambook|webcam23|hotjenny|fucktubate|gaysexrooms|fastsexnow|alva lanus|Delorge942|Glasford597|sk .*y p e|\\[LEAK(ED)*\\]|SwipeGirls|pornmeds)', 'i'); // Demands var list_demands = new RegExp('\\b('+ 'p+\\s*m+|p+v+t|p+l+e*a*i*(s|z)+|a+n+a+l+|(m+a+s+t\\w*b|s+q\\w*r+t|f+i+s+t|q+u*e+a*f+)\\w*|' + '(' + demandverbs + '|p+l+e*a*i*(s|z)+e*)\\s*(i+t+|(t+h+|d+)a+t+|.*(y*o*u+r*|(f+o*r+|4+)*\\s*m+(y|e|i)+|' + girlyparts + '|' + guyparts + '|' + toys + ')|p+l+e*a*i*(s|z)+e*)|'+ '(' + girlyparts + '|' + guyparts + '|' + toys + '|' + naked + '|g+e+t+|m+(y|e|i)+|p+l+e*a*i*(s|z)+e*).*(' + demandverbs + '|' + naked + '|p+l+e*a*i*(s|z)+e*)' + ')\\b|' + '(' + removeit + '.*' + clothing + ')|(' + clothing + '.*' + removeit + ')|(t+a+k+e.*' + clothing + '.*o+f+f)|' + '(z+o+o+m|s+p+r+e+a+d|f+a+r+t|c+2+c|(w+a+t+c+h|l+o+o+k|o+p+e+n|v+i+e+w|c+l+i+c+k).*(c+a+m|p+r+o+f|r+o+o+m)\\w*)' , 'i'); // TMI var list_tmi = new RegExp('\\b('+ '\\d\\s*(i+n|c+m)\\w*|'+ '(' + demandverbs + ').*(' + tmi_cum +')|' + '(' + tmi_iam + ').*(' + tmi_adj +')|' + '(' + tmi_adj +').*f+o*r+\\s*y*o*u+r*|' + '(' + tmi_iam + '|' + tmi_intent + '|m+(y|e|i)+).*(' + tmi_verb + '|' + tmi_cum + '|' + guyparts +'|\\bs+i+s\\w*)' + ')\\b|' + '(s+t+r+o+k|t+h+r+o+b|c+i+r+c+u+m)' , 'i'); // Feet var list_feet = new RegExp('\\b(s+o+l+e+s*|t+o+e+s*)\\b|' + '(f+e+e+t|p+e+d+i+c+u|f+o+t+j+o+b)' , 'i'); // Creepy var list_creepy = new RegExp('(d+a+d|(s+t+e+p+)*d+a+u+g+h+t+e+r)' , 'i'); // Poo/Pee var list_poopee = new RegExp('\\b(p+o+o+p*\\w*|p+e+e+(i+n+g)*)\\b|' + '(t+u+r+d|e+n+e+m+a|d+e+f+e+c+a+t|(s+h+i+t|c+r+a+p|p+i+s+s+)\\w*\\s*(o|i)+n)' , 'i'); var reason = null; //convert to .match instead? can possibly use more regular-looking regex // .indexOf might be fastest switch(true) { case msg.length <= 1 || msg.length > 500 : reason = 'Length'; break; case m.search(list_workaround) != -1 : reason = 'Workaround'; break; case m.search(list_directness) != -1 && (msg.match(/\s+/gi)||[]).length < 3 : reason = 'Directness'; break; case m.search(non_english) != -1 : reason = 'Non-English'; break; case m.search(list_bb) != -1 : reason = 'BB'; break; case m.search(list_rude) != -1 : reason = 'Rudeness'; break; case m.search(list_annoying) != -1 : reason = 'Annoying'; break; case m.search(list_spam) != -1 : reason = 'Spam'; break; case m.search(list_demands) != -1 : reason = 'Demands'; break; case m.search(list_tmi) != -1 : reason = 'TMI'; break; case m.search(list_feet) != -1 : reason = 'Feet'; break; case m.search(list_creepy) != -1 : reason = 'Creepy'; break; case m.search(list_poopee) != -1 : reason = 'Poo/Pee'; break; } return reason; } function doCustomWordlist(m, u) { // Remove everything but alphanumeric characters to evaluate it var m = m.replace(/[^\w]|_/ig, ''); // Custom Wordlist var customwordlist = new RegExp('(' + customWordlistRegex + ')', 'i'); if ( m.search(customwordlist) != -1 || u.replace(/[^\w]|\d|_/ig, '').search(customwordlist) != -1 ) { return 'blocked'; } } function addWord(m) { cb.settings.customWordlist += ','+m; parseWordlist(); } function niceList(user,mod,ar) { if(user) { user = user.toLowerCase(); if(ar == 'a') { if(!cbjs.arrayContains(niceArray,user)) { niceArrayPopulate(user); notify('You have added ' + user + ' to the nice list.', mod); notify(mod + ' has added you to the nice list. You will be able to chat and use graphics regardless of the global room settings. Thank you for being nice!',user); } else { notifyError(user + ' is already on the nice list.', mod); } } else if(ar == 'r') { if(cbjs.arrayContains(niceArray,user)) { niceArrayDepopulate(user); notify('You have removed ' + user + ' from the nice list.', mod); notify(mod + ' has removed you from the nice list.', user); } else { notifyError(user + ' is not on the nice list.', mod); } } } else { notifyError('Uh oh. You didn\'t specify a user.\nType "/bombhelp\xa0nicelist" to see how to use the nice list.',mod); } } function greyList(user,mod,ar) { if(user) { user = user.toLowerCase(); if(ar == 'a') { if(!cbjs.arrayContains(greyArray,user)) { greyArrayPopulate(user); notify('You have added ' + user + ' to the grey list.', mod); } else { notifyError(user + ' is already on the grey list.', mod); } } else if(ar == 'r') { if(cbjs.arrayContains(greyArray,user)) { greyArrayDepopulate(user); notify('You have removed ' + user + ' from the grey list.', mod); } else { notifyError(user + ' is not on the grey list.', mod); } } } else { notifyError('Uh oh. You didn\'t specify a user.\nType "/bombhelp\xa0greylist" to see how to use the grey list.',mod); } } function kingSpamToggle(option, mod) { if(cb.settings.kingTipper != 'Yes') { notifyError('The room host has decided not to use the King Tipper feature',mod); } else if(option == 'on') { if(kingTipperSpam == 1) { notifyError('The King Tipper spam is already turned on.',mod); } else { kingTipperSpam = 1; kingSpam(); notify('You have turned on King Tipper spam.',mod); } } else if(option == 'off') { if(kingTipperSpam == 0) { notifyError('The King Tipper spam is already turned off.',mod); } else { kingTipperSpam = 0; notify('You have turned off the King Tipper spam.',mod); } } else if(option != null) { notifyError(option + ' is not a valid option for /kingspam.\nType "/bombhelp\xa0kingspam" to see how to use /kingspam.',mod); } else if(option == null) { notifyError('You did not enter a valid option for /kingspam.\nType "/bombhelp\xa0kingspam" to see how to use /kingspam.',mod); } } function notifierSpamToggle(option, mod) { if(option == 'on') { if(notifierSpamTGL == 1) { notifyError('The Notifier spam is already turned on.',mod); } else { notifierSpamTGL = 1; notify('You have turned on the Notifier spam.',mod); } } else if(option == 'off') { if(notifierSpamTGL == 0) { notifyError('The Notifier spam is already turned off.',mod); } else { notifierSpamTGL = 0; notify('You have turned off the Notifier spam.',mod); } } else if(option != null) { notifyError(option + ' is not a valid option for /notifierspam.\nType "/bombhelp\xa0notifierspam" to see how to use /notifierspam.',mod); } else if(option == null) { notifyError('You did not enter a valid option for /notifierspam.\nType "/bombhelp\xa0notifierspam" to see how to use /notifierspam.',mod); } } function leaderboardSpamToggle(option, mod) { if(option == 'on') { if(leaderboardSpam == 1) { notifyError('The Leaderboard spam is already turned on.',mod); } else { leaderboardSpam = 1; ldrSpam(); notify('You have turned on the Leaderboard spam.',mod); } } else if(option == 'off') { if(leaderboardSpam == 0) { notifyError('The Leaderboard spam is already turned off.',mod); } else { leaderboardSpam = 0; notify('You have turned off the Leaderboard spam.',mod); } } else if(option != null) { notifyError(option + ' is not a valid option for /leaderboardspam.\nType "/bombhelp\xa0leaderboardspam" to see how to use /leaderboardspam.',mod); } else if(option == null) { notifyError('You did not enter a valid option for /leaderboardspam.\nType "/bombhelp\xa0leaderboardspam" to see how to use /leaderboardspam.',mod); } } function isBlank(cbsetting) { var s; if(cbsetting) { s = cbsetting.trim(); } if(s == null || s == '' || s.substr(0,9) == '[Optional') { return true; } else { return false; } } function isValidColor(color) { var c = color; var cString = '0123456789abcdefABCDEF'; var valid = true; if (c.charAt(0) == '#') { c = c.substr(1); } if (c && c.length == 6) { for(var i = 0; i < 6; i++) { if(cString.indexOf(c.charAt(i)) == -1) { valid = false; } else { } } } else { valid = false; } if(valid) { return true; } else { notifyErrorBold('"' + color + '" is not a valid color option.', roomHost); notifyError( 'Use color-hex.com to find the code for the color you want.\n' + 'Reverting to default color.', roomHost); return false; } } function setColor() { var c = cb.settings.colorscheme; var t = cb.settings.darkcolor; var b = cb.settings.lightcolor; var textvalid = true; var bgvalid = true; if (c && c.substr(0,6) == 'Custom') { if(isBlank(b) && isBlank(t)) { notifyErrorBold('Whoops. You selected a custom color scheme but you didn\'t fill in the colors. Reverted to default color scheme.', roomHost); } else if (isBlank(t)) { notifyErrorBold('Whoops. You selected a custom color scheme but you didn\'t select a text color. Reverted to default color scheme.', roomHost); } else if (isBlank(b) && !isBlank(t)) { if (t && t.charAt(0) != '#') { t = '#' + t; } if (isValidColor(t)) { theme_dark = t; theme_light = white; } } else if (!isBlank(b) && !isBlank(t) ) { if (t && t.charAt(0) != '#') { t = '#' + t; } if (b && b.charAt(0) != '#') { b = '#' + b; } if (isValidColor(t) && isValidColor(b)) { theme_dark = t; theme_light = b; } } } else { if (!isBlank(t) || !isBlank(b)) { notifyErrorBold('You defined custom colors, but your color scheme is set to "' + c +'". In order to use your custom colors, please set your color scheme to "Custom"', roomHost); } if (c == 'Purple') { theme_dark = purple_dark; theme_light = purple_light; } else if (c == 'Pink') { theme_dark = pink_dark; theme_light = pink_light; } else if (c == 'Orange') { theme_dark = orange_dark; theme_light = orange_light; } else if (c == 'Red') { theme_dark = red_dark; theme_light = red_light; } else if (c == 'Green') { theme_dark = green_dark; theme_light = green_light; } else if (c == 'Teal') { theme_dark = teal_dark; theme_light = teal_light; } else if (c == 'Grey') { theme_dark = grey_dark; theme_light = grey_light; } } } function help(option,from) { var valid = 0; if(option == null){ option = ''; } switch(option) { case '': { valid = 1; notifyBold('Bomb Bot Ultra Help Menu',from); notify( 'Type "/bombhelp\xa0x", where x is one of the following choices, for more detailed information.' + '\nEx: /bombhelp\xa0commands' ,from); notifyPlain( 'commands\n' + 'nicelist\n' + 'greylist\n' + 'about' ,from); break; } case 'commands': { valid = 1; notifyBold('Bomb Bot Ultra Command List',from); notify( 'Type "/bombhelp\xa0x", where x is one of the following commands, for more detailed information.' + '\nEx: /bombhelp\xa0silencelevel' ,from); notifyPlain( '/silencelevel\n' + '/graphiclevel\n' + '/silence\n' + '/unsilence\n' + '/starttimer\n' + '/addtime\n' + '/timeleft\n' + '/note\n' + '/whisper\n' + '/reply\n' + '/ignore\n' + '/unignore\n' + '/ignorelevel\n' + '/emod\n' + '/addnice\n' + '/removenice\n' + '/addgrey\n' + '/removegrey\n' + '/leaderboard\n' + '/kingspam\n' + '/usertitle\n' + '/fanclub1\n' + '/modfanclub1\n' + '/modusers\n' + '/tipmenu\n' + '/notice1\n' + '/bio\n' + '/dontmmm\n'+ '/dirty\n' + '/follow\n' + '/manyvids\n' + '/amazon\n' // + '\n/notifierspam' ,from); break; } case 'nicelist': { notifyBold('The Nice List',from); notify('Sometimes, there are users whose comments are desirable, but they either do not have tokens or do not tip frequently. ' + 'When rooms get rowdy, hosts and mods are forced to do things like silence users without tokens or who have not tipped and those groups often includes the users whose comments hosts would like to see. ' + 'To fix this problem, hosts and mods can add users to the Nice List. ' + 'Users who are on the nice list can send messages regardless of the global silence setting.',from); valid = 1; break; } case 'greylist': { valid = 1; notifyBold('The "Grey" List',from); notify('Sometimes, there are users whose comments are annoying, in spite of the fact that they may have tokens or even tip. ' + 'It isn\'t always desireable to silence these people entirely, especially if they\'ve been tipping, but it can be useful to apply the same word list restrictions that apply to greys, so that the more annoying messages don\'t get through to the room. ' + 'To fix this problem, hosts and mods can add users to the "Grey" List. ' + 'Users who are on the grey list will have their messages subjected to the wordlists that apply to greys.',from); notify('',from); break; } case 'about': { valid = 1; notifyBold('About Bomb Bot Ultra',from); notify('Bomb Bot Ultra is a fork of Ultra Bot, with continuing development by Adambomb01.' + '\nUltra Bot was written by Justin of the Chaturbate couple britney_and_justin.' + '\nComments, suggestions, requests, and bug reports can be communicated by either tweeting @adambomb01, ' + 'or by posting comments on Bomb Bot Ultra\'s page at chaturbate.com/bots.' + '\nThe purpose of Bomb Bot Ultra is to make the lives of hosts and mods as easy as possible. ' + 'It adds popular features such as King Tipper, Leaderboard, and Notifier, pre-silences abusive messages, ' + 'grants quite a bit of power to moderators, and allows private messages to be sent in the main chat window.',from); notify('',from); break; } case 'silencelevel': { valid = 1; notifyBold('/silencelevel Help',from); notify('/silencelevel is a command that is usable by moderators and room hosts.' + '\nThe syntax for using silencelevel is "/silencelevel\xa0x", where x is a number between 0 and 2.' + '\nSetting the Silence Level to 0 will grant voice privileges to all users, ' + 'setting it to 1 will revoke voice privileges from greys, ' + 'setting it to 2 will revoke voice privileges from users who have not tipped, ' + '\nThe default setting for /silencelevel is 0.' + '\nRoom hosts, moderators, and fan club members are unaffected by the Silence Level.',from); notify('',from); break; } case 'graphiclevel': { valid = 1; notifyBold('/graphiclevel Help',from); notify('/graphiclevel is a command that is usable by moderators and room hosts.' + '\nThe syntax for using graphiclevel is "/graphiclevel\xa0x", where x is a number between 0 and 3.' + '\nSetting the Graphic Level to 0 will grant graphic privileges to all users, ' + 'setting it to 1 will revoke graphic privileges from greys, ' + 'setting it to 2 will revoke graphic privileges from users who have not tipped, ' + 'setting it to 3 will revoke graphic privileges from users who are not mods, fanclub members, or faves, ' + 'and setting it to 4 will revoke graphic privileges from everyone other than mods.' + '\nThe default setting for /graphiclevel is 1.' + '\nRoom hosts, moderators, and fan club members are unaffected by the Graphic Level.',from); notify('',from); break; } case 'silence': { valid = 1; notifyBold('/silence Help',from); notify('/silence is a command that is usable by moderators and room hosts.' + '\nThe syntax for using silence is "/silence x", where x is the username of the user you want to silence.' + '\nThe effect of /silence is the same as Chaturbate\'s silence feature, ' + 'except that it lasts for the duration of the current session instead of for six hours.' + '\nThe effect of /silence can be reversed by using the command /unsilence.',from); notify('',from); break; } case 'unsilence': { valid = 1; notifyBold('/unsilence Help',from); notify('/unsilence is a command that is usable by moderators and room hosts.' + '\nThe syntax for using unsilence is "/unsilence x", where x is the username of the user you want to unsilence.' + '\nunsilence simply grants voice privileges back to a user who was previously silenced.' + '\nNOTE: /unsilence WILL NOT undo the effect of Chaturbate\'s silence feature!' + '\n/unsilence WILL ONLY reverse the effect of /silence!',from); notify('',from); break; } case 'starttimer': { valid = 1; notifyBold('/starttimer Help',from); notify('/starttimer is a command that is usable by moderators and room hosts.' + '\nThe syntax for using starttimer is "/starttimer x", where x is the desired duration of the timer in minutes.' + '\n/starttimer will accept whole numbers only.' + '\nThe timer will make announcements at five minutes remaining and at one minute remaining.' + '\n/addtime 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); notify('',from); break; } case 'addtime': { valid = 1; notifyBold('/addtime Help',from); notify('/addtime is a command that is usable by moderators and room hosts.' + '\nThe syntax for using addtime is "/addtime\xa0x", where x is the amount of time you want to add in minutes.' + '\n/addtime will accept whole numbers only.' + '\nSee the help section for starttimer for more information on timers.',from); notify('',from); break; } case 'timeleft': { valid = 1; notifyBold('/timeleft Help',from); notify('/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 starttimer for more information on timers.',from); notify('',from); break; } case 'note': { valid = 1; notifyBold('/note Help',from); notify('/note is a command that is usable by moderators and room hosts.' + '\nThe syntax for using note is "/note\xa0x", where x is the message you want to send.' + '\n/note, /notice, and /n are all available commands that will send a notice.' + '\nA note is a public notification that will be sent to everyone in the main chat window.',from); notify('',from); break; } case 'whisper': { valid = 1; notifyBold('/whisper Help',from); notify('/whisper is a command that is usable by everyone.' + '\nThe syntax for using whisper is "/whisper\xa0x\xa0y", where x is the username of the user you want to send a whisper and y is the message you want to send.' + '\n/whisper, /w, /tell, /t, and /pm are all available commands that will send a whisper.' + '\nA whisper is a private message that will be sent in the main chat window.' + '\nOther related commands are /reply, /ignore, /unignore, and /ignorelevel.',from); notify('',from); break; } case 'reply': { valid = 1; notifyBold('/reply Help',from); notify('/reply is a command that is usable by everyone.' + '\nThe syntax for using whisper is "/reply\xa0x", where x is message that you want to whisper to the user who most recently sent a whisper to you.' + '\n/reply and /r are available commands that will send a whisper in reply.' + '\nSee the help section for whisper for more information on whispers.' + '\nOther related commands are /whisper, /ignore, /unignore, and /ignorelevel.',from); notify('',from); break; } case 'ignore': { valid = 1; notifyBold('/ignore Help',from); notify('/ignore is a command that is usable by everyone.' + '\nThe syntax for using ignore is "/ignore\xa0x", where x is the user from whom you wish to ignore whispers.' + '\nIgnoring a user will prevent him from sending you whispers, but it will not prevent him from talking normally in chat.' + '\n/unignore will reverse the effect of /ignore.' + '\nSee the help section for whisper for more information on whispers.' + '\nOther related commands are /whisper, /reply, /unignore, and /ignorelevel.',from); notify('',from); break; } case 'unignore': { valid = 1; notifyBold('/unignore Help',from); notify('/unignore is a command that is usable by everyone.' + '\nThe syntax for using unignore is "/unignore\xa0x", where x is the user you wish to remove from your ignore list.' + '\nSee the help section for ignore for more information on ignoring users.' + '\nSee the help section for whisper for more information on whispers.' + '\nOther related commands are /whisper, /reply, /ignore, and /ignorelevel.',from); notify('',from); break; } case 'ignorelevel': { valid = 1; notifyBold('/ignorelevel Help',from); notify('/ignorelevel is a command that determines which users you accept whispers from. It is usable by everyone.' + '\nThe syntax for using ignorelevel is "/ignorelevel\xa0x", where x is a number between 0 and 4.' + '\nSetting it to 0 will allow all users to send you whispers.' + '\nSetting it to 1 will prevent greys from sending you whispers.' + '\nSetting it to 2 will prevent greys and light blues from sending you whispers.' + '\nSetting it to 3 will prevent users who have not tipped in the room from sending you whispers.' + '\nSetting it to 4 will prevent all users from sending you whispers.' + '\nModerators and fan club members can send whispers regardless of whisper level.' + '\nThe default setting for /ignorelevel is 4 for the broadcaster, and 0 for everyone else. (This broadcaster\'s level is set higher by default to prevent abuse of this feature.)' + '\nSee the help section for whisper for more information on whispers' + '\nOther related commands are /whisper, /reply, /ignore, and /unignore.',from); notify('',from); break; } case 'emod': { valid = 1; notifyBold('/emod Help',from); notify('/emod is a command that is usable by moderators and room hosts.' + '\nThe syntax for using emod is "/emod\xa0x\xa0y", where x is either "add" or "remove" and y is the username of the user you want to either grant or revoke emergency moderator powers.' + '\n/emod allows moderators to quickly grant other users access to moderator-only commands in the event that he is having difficulty controlling the room by himself.' + '\nEmergency moderators have access to all moderator-only commands with the exceptions of /emod, /addnice, and /removenice.',from); notify('',from); break; } case 'blocknotice': { valid = 1; notifyBold('/blocknotice Help',from); notify('/blocknotice is a command that is usable by moderators and room hosts.' + '\nThe syntax for using blocknotice is "/blocknotice\xa0x", where x is either "on" or "off".' + '\n/blocknotice toggles the blocked message notices that appear by default for moderators when the wordlist is being used' + '\nThe blocked message notifications are toggled on a per-user basis. (Toggling it for yourself does not toggle it for everyone.)',from); notify('',from); break; } case 'addnice': { valid = 1; notifyBold('/addnice Help',from); notify('/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, graphic, and ignore level settings. ' + 'Using /silence or /ignore will still silence or ignore a user on the nice list.' + '\nUsers can be removed from the nice list by using the command /removenice.' + '\nSee the help sections for silencelevel, graphiclevel, and ignorelevel for more information on the global settings or the help section for nicelist for more information on the nice list.',from); notify('',from); break; } case 'removenice': { valid = 1; notifyBold('/removenice Help',from); notify('/removenice is a command that is usable by moderators and room hosts.' + '\nThe syntax for using removenice is "/removenice 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); notify('',from); break; } case 'addgrey': case 'addgray': { valid = 1; notifyBold('/addgrey Help',from); notify('/addgrey is a command that is usable by moderators and room hosts.' + '\nThe syntax for using addgrey is "/addgrey x", where x is the username of the user you want to add to the grey list.' + '\nAdding a user to the grey list subjects them to the same wordlists that apply to greys. ' + '\nUsers can be removed from the grey list by using the command /removegrey.' + '\nSee the help section for greylist for more information on the grey list.',from); notify('',from); break; } case 'removegrey': case 'removegray': { valid = 1; notifyBold('/removegrey Help',from); notify('/removegrey is a command that is usable by moderators and room hosts.' + '\nThe syntax for using removegrey is "/removegrey x", where x is the username of the user you want to remove from the grey list.' + '\nSee the help section for greylist for more information on the grey list.',from); notify('',from); break; } case 'bombhelp': case 'ubhelp': { valid = 1; notifyBold('/bombhelp\xa0Help',from); notify('/bombhelp\xa0is a command that is usable by everyone.' + '\nThe syntax for using bombhelp is "/bombhelp\xa0x", where x is the subsection of the help menu that you want to access.',from); notify('',from); break; } case 'leaderboard': { valid = 1; notifyBold('/leaderboard Help',from); notify('/leaderboard is a command that is usable by everyone.' + '\nThe syntax for using leaderboard is "/leaderboard".' + '\n/leaderboard shows the top tippers of the current session.',from); notify('',from); break; } case 'kingspam': { valid = 1; notifyBold('/kingspam Help',from); notify('/kingspam is a command that is usable by moderators and room hosts.' + '\nThe syntax for using kingspam is /kingspam x, where x is either on or off. ' + 'Using this command toggles the spamming of the message "Tip x to become the new King!"',from); notify('',from); break; } // case 'notifierspam': { // valid = 1; // notifyBold('/notifierspam Help',from); // notify('/notifierspam is a command that is usable by moderators and room hosts.' + // '\nThe syntax for using notifierspam is /notifierspam x, where x is either on or off. ' + // 'Using this command toggles the spamming of the periodic message defined by the host.',from); // notify('',from); // break; // } case 'leaderboardspam': { valid = 1; notifyBold('/leaderboardspam Help',from); notify('/leaderboardspam is a command that is usable by moderators and room hosts.' + '\nThe syntax for using leaderboardspam is /leaderboardspam x, where x is either on or off. ' + 'Using this command toggles the spamming of the top tippers.',from); notify('',from); break; } case 'usertitle': { valid = 1; notifyBold('/usertitle Help',from); notify('/usertitle is a command that is usable by moderators and room hosts.' + '\nThe syntax for using usertitle is "/usertitle x y", where x is the username of the user you want and y is the custom title.' + '\nThis will prepend the title specified as y before every post by user x ' + '\nTo remove a title just leave the title blank, for example "/usertitle x" ',from); notify('',from); break; } case 'fanclub1': { valid = 1; notifyBold('/fanclub1 Help',from); notify('/fanclub1 is a command that is usable by moderators and room hosts.' + '\nTo add a user to fanclub1 manually use the following syntax "/fanclub1 add x", where x is the username you want to add.' + '\nTo remove a user to fanclub1 manually use the following syntax "/fanclub1 rem x", where x is the username you want to remove.' + '\nTo list all users in fanclub1 so that you can copy/paste it into the config panel type "/fanclub1 list" .' + '\nTo list only the users added to fanclub1 while the bot was running type "/fanclub1 new" ',from); notify('',from); break; } case 'modfanclub1': { valid = 1; notifyBold('/modfanclub1 Help',from); notify('/modfanclub1 is a command that is usable by room hosts.' + '\nThe syntax for using modfanclub1 is /modfanclub1 x, where x is either on or off. ' + 'Using this command toggles the ability of mods to modify the fanclub1 users.',from); notify('',from); break; } case 'modusers': { valid = 1; notifyBold('/modusers Help',from); notify('/modusers is a command that is usable by room hosts.' + '\nThe syntax for using modusers is /modusers x, where x is either on or off. ' + 'Using this command toggles the ability of mods to set custom titles and colors for users.',from); notify('',from); break; } case 'tipmenu': { valid = 1; notifyBold('/tipmenu Help',from); notify('/tipmenu is a command that is usable moderators and room hosts.' + '\nThe syntax for using tipmenu is /tipmenu \n' + 'This commmand sends the short tip menu as a notice to all users.',from); notify('',from); break; } case 'notice1': { valid = 1; notifyBold('/notice1 Help',from); notify('/notice1 is a command that is usable moderators and room hosts.' + '\nThe syntax for using notice1 is /notice1 \n' + 'This commmand sends the first notice defined in the rotating notices to all users. If they are defined in the bot config panel, /notice2 through /notice8 will send the other notices.',from); notify('',from); break; } case 'bio': { valid = 1; notifyBold('/bio Help',from); notify('/bio is a command that is usable moderators and room hosts.' + '\nThe syntax for using bio is /bio \n' + 'If enabled and configured this command sends a notice to the room suggesting they read the bio',from); notify('',from); break; } case 'dontmmm': { valid = 1; notifyBold('/dontmmm Help',from); notify('/dontmmm is a command that is usable moderators and room hosts.' + '\nThe syntax for using dontmmm is /dontmmm \n' + 'If enabled and configured this command sends a notice to the room telling them not to mmm at the model',from); notify('',from); break; } case 'dirty': { valid = 1; notifyBold('/dirty Help',from); notify('/dirty is a command that is usable moderators and room hosts.' + '\nThe syntax for using dirty is /dirty \n' + 'If enabled and configured this command sends a notice to the room telling them keep dirty talk in tip notes',from); notify('',from); break; } case 'follow': { valid = 1; notifyBold('/follow Help',from); notify('/follow is a command that is usable moderators and room hosts.' + '\nThe syntax for using follow is /follow \n' + 'If enabled and configured this command sends a notice to the room asking them to follow the room host',from); notify('',from); break; } case 'manyvids': { valid = 1; notifyBold('/manyvids Help',from); notify('/manyvids is a command that is usable moderators and room hosts.' + '\nThe syntax for using manyvids is /manyvids \n' + 'If enabled and configured this command sends a notice to the room pointing them to the models manyvids profile',from); notify('',from); break; } case 'amazon': { valid = 1; notifyBold('/amazon Help',from); notify('/amazon is a command that is usable moderators and room hosts.' + '\nThe syntax for using amazon is /amazon \n' + 'If enabled and configured this command sends a notice to the room pointing them to the models amazon wishlist',from); notify('',from); break; } case 'location': { valid = 1; notifyBold('/location Help',from); notify('/location is a command that is usable moderators and room hosts.' + '\nThe syntax for using location is /location \n' + 'If enabled and configured this command sends a notice to the room asking them to not ask about location',from); notify('',from); break; } } if(valid == 0) { notifyError(option + ' is not a valid subsection of the help menu. Type "/bombhelp" to access the main help menu.',from); } } function chatAd() { var msg = 'Tip Menu: '; for (i=1;i<=cb.settings.tipMenuLength;i++) { if (parseInt(cb.settings['item' + i + 'price'])>0) { if (i>=2) { msg += separator_char; } msg += cb.settings['item' + i] + '(' + parseInt(cb.settings['item' + i + 'price']) + ') '; } } notifyTheme(msg) //notifyThemeBold(msg) //cb.sendNotice(msg,'','',cb.settings['noticecolor'],'bold'); cb.setTimeout(chatAd, (cb.settings.chat_ad * 60000)); } function setFanclub1Titles(msg) { if (cbjs.arrayContains(club1Array,msg['user'])) { if(cb.settings.fanClub1tag) { msg['m']=cb.settings.fanClub1tag + ' ' + msg['m']; } if (cb.settings.fanClub1colors === 'Yes') { if(cb.settings.fanClub1color) { msg['c'] = cb.settings.fanClub1color; } if(cb.settings.fanClub1hilite) { msg['background'] = cb.settings.fanClub1hilite; } } } } function setCustomTitles(msg) { var numTitles = titlesArray.length; for (var i = 0; i < numTitles; i++) { if(titlesArray[i].sName === msg['user']){ if(titlesArray[i].sTitle) { msg['m']=titlesArray[i].sTitle + ' ' + msg['m']; } if (cb.settings.userTitlecolors === 'Yes') { if(titlesArray[i].sColor) { msg['c'] = titlesArray[i].sColor; } if(titlesArray[i].sHighlight) { msg['background'] = titlesArray[i].sHighlight; } } } } } function FanclubLengthNotice(fanclub,u) { var nearlyFullThreshold=100; // start warning when club only has this many characters left. if (fanclub === 'fanclub1') { var clublength = club1Array.join(',').length; var remainingFanclubSpace = maxFanclubLength-clublength; if (remainingFanclubSpace < 0) { notifyError('Fanclub1 is over capactity, '+clublength+' of '+maxFanclubLength+' characters\nEither delete old members or save them elsewhere and update the maximum length',u); }else if (remainingFanclubSpace <= nearlyFullThreshold ) { notifyError('Fanclub1 is nearly full, only '+remainingFanclubSpace+' of '+maxFanclubLength+' characters left\nYou may need to delete old membersor modify the bot to allow larger fanclubs',u); }else{ notify('Fanclub1 is using '+clublength+' of '+maxFanclubLength+' characters',u); } } } /************************************************************************************************************************************ ***** onMessage ********************************************************************************************************************* ************************************************************************************************************************************/ cb.onMessage(function (msg) { var silenced = 0; //1 = user is already silenced var messageBlocked = 0; // used to determine whether a message gets blocked based on wordlist var graphicsBlocked = 0; // used to determine whether a user can use graphics var imageReplaced = 0; var symbolString = '~`!@#$%^&*()_-+={[}]|\\:;"\'<,>.?/'; // Message vars var msgString = msg['m'].trim(); var isCommand = (msgString.charAt(0) == '/'); var isKenoCmd = (msgString.charAt(0) == '!'); var message = msgString.split(/\s+/g); //turn the message into an array // User vars var u = msg.user; var hasTipped = findTipper(u) > -1 && Number.parseInt(tipArray[findTipper(u)].nTotal) > 0; var isHost = (u == cb.room_slug); var isDev = (u == dev); var isMod = msg.is_mod; var isFan = msg.in_fanclub; //2.0.2 bugfix if(cb.settings.fanClub1 === 'Yes' && cb.settings.fanClub1name){ var isFave = cbjs.arrayContains(club1Array, u); }else{ var isFave = false } var isEmod = cbjs.arrayContains(emodArray, u); var isNice = cbjs.arrayContains(niceArray, u); var isGreyish = cbjs.arrayContains(greyArray, u); var isSilenced = cbjs.arrayContains(silenceArray, u); var isGrey = (!msg.has_tokens && !hasTipped && !msg.tipped_recently); // technically MAY include some light blues who have tipped down to zero, but i don't think so var isBlueUp = (msg.tipped_recently || hasTipped); // Add mod to modArray if(isMod) { if (!cbjs.arrayContains(modArray,u)) { modArrayPopulate(u); modAndEmodArrayPopulate(u); if(cb.settings.wordlistShowModerators == 'Yes') { modBlockMsgArrayPopulate(u); } } } // Silencing if(isSilenced && !(isHost || isMod || isEmod || isNice || isDev) && silenced == 0) { msg['X-Spam'] = true; silenced = 1; // notifyError('Your message was not sent because you have been silenced. Be nice and don\'t make demands.',u); } // Silence Levels function doSilenceLevel(level) { var silenceNotice = 'I\'m sorry, but the silence level has been set to ' + level + '. Your message was not sent.\n'; silenceNotice += 'For more information about silence levels, type "/bombhelp silencelevel"\n'; silenceNotice += 'Please enjoy the show :smile'; msg['X-Spam'] = true; silenced = 1; notifyError(silenceNotice,u); } if(silenceLevel > 0 && !(isHost || isMod || isEmod || isFan || isFave || isNice || isDev) && silenced == 0) { switch(silenceLevel) { case 1: if(isGrey) { doSilenceLevel(silenceLevel); } break; case 2: if(!hasTipped) { doSilenceLevel(silenceLevel); } break; } } function replaceImage() { for(var i = 0; i < message.length; i++) { if(message[i].charAt(0) == ':') { if(!message[i].match(/^(:(-?|o?)(\)|\(|}|{|P|D|3|b|O|0|S|X|\$|\/|\\|\||\*))$/ig)) { // common emoticons that begin with a ":" character //replace images msg['m'] = msg['m'].replace(/:[^\s]+/g, function (match) { return '[IMG: ' + match.slice(1) + ']'; }); msg['X-Spam'] = true; return true; imageReplaced = 1; } else { return false; } } } } // Graphic Levels function doGraphicLevel(level) { var graphicNotice = 'I\'m sorry, but the graphic level has been set to ' + level + '. Your message was not sent.\n'; graphicNotice += 'For more information about graphic levels, type "/bombhelp graphiclevel"\n'; graphicNotice += 'Please enjoy the show :smile'; if (replaceImage()) { notifyError(graphicNotice,u); graphicsBlocked = 1; } } if(graphicLevel > 0 && !(isHost || isMod || isEmod || isFan || isFave || isNice || isDev) && silenced == 0) { switch(graphicLevel) { case 1: if(isGrey || isGreyish) { doGraphicLevel(graphicLevel); } break; case 2: if(!hasTipped || isGreyish) { doGraphicLevel(graphicLevel); } break; case 3: doGraphicLevel(graphicLevel); break; case 4: doGraphicLevel(graphicLevel); break; } }else if( graphicLevel > 0 && silenced == 0 ){ // level 3 is handled by the if above, so only need to restrict for level 4 switch (graphicLevel) { case 4: if (!(isHost || isMod || isEmod)) { doGraphicLevel(graphicLevel); } break; } } // Blocked Wordlists function blockMessage(reason) { msg['X-Spam'] = true; messageBlocked = 1; if(!isCommand && !isSilenced && silenced == 0) { silenced = 1; // //replace images -- we may not want to see the images they unsuccessfully try to use if (imageReplaced == 0) { replaceImage(); } var blockedmsg = msg['m']; for (mod = 0; mod < modBlockMsgArray.length; mod++) { thisMod = modBlockMsgArray[mod]; notifyErrorBold(bullets + 'MESSAGE BLOCKED: ' + reason + bullets, thisMod); notifyError(msg['user']+': '+blockedmsg.substring(0, 500), thisMod); } if(cb.settings.customWordlistNotify == 'all parties') { notifyError('Your message was not sent because it was flagged by the wordlist. Be nice and don\'t make demands.',u); } lastBlocked.push(msg['user']); if (lastBlocked.length == 10) { lastBlocked.shift(); } } } function isCustomWordExempt() { isExempt = true; switch (cb.settings.customWordlistExempt) { case "broadcaster only": if (!isHost) { isExempt = false; } break; case "broadcaster/mods": if (!(isHost || isMod || isEmod)){ isExempt = false; } break; case "broadcaster/mods/faves": if (!(isHost || isMod || isEmod || isFan || isFave || isNice || isDev)){ isExempt = false; } return true; break; case "colors only": if (isGrey || isGreyish) { isExempt = false; } break; } return isExempt; } //if(!(isHost || isMod || isEmod || isFan || isNice)) { // Custom wordlist stuff if (cb.settings.customWordlistToggle == 'Yes' && customWordlistRegex != '') { if (!isCustomWordExempt()) { if (doCustomWordlist(msgString, u) == 'blocked') { blockMessage('Wordlist'); } } } // Regular wordlist stuff - deactivate bombbot defaults per request //if(cb.settings.wordlistToggle == 'Yes') { // if (isGrey || isGreyish || cb.settings.wordlistLevel == 'Everyone') { // var blocked = doWordlist(msgString); // if (blocked) { // blockMessage(blocked); // } // } //} //} // Commands if(isCommand) { msg['X-Spam'] = true; //Don't send message to chat msg['background'] = bb_lt_light; msg['c'] = bb_lt_dark; var validCmd = 0; var command; // Slash + first word is the command var param; // Anything after the first word is the parameter var split_index; // Postion of the first space character // Split split_index = msgString.indexOf(' '); // Find first space character if (split_index > -1) { // Message might have a parameter (could just be padding) command = msgString.substr(0, split_index).toLowerCase(); // substr (start index, length) param = msgString.substring(split_index + 1).trim(); // Could be empty } else { // Message is a command only command = msgString.toLowerCase(); param = null; } // Host commands if (validCmd == 0 && (isHost || isDev) ) { validCmd = 1; switch(command) { case '/modfanclub1': { if (param) { switch (param){ case 'on': { modsCanChangeFanclub1 = 1; notify('You have granted the ability to your Mods to add/remove users from fanclub1',u); break; } case 'off': { modsCanChangeFanclub1 = 0; notify('You have revoked the ability from your Mods to add/remove users from fanclub1',u); break; } default : { notifyError('Allowed options for /modfanclub1 are "on" and "off"',u); break; } } }else{ if (modsCanChangeFanclub1) { notify('Mods currently are allowed to add/remove users in fanclub1',u); }else{ notify('Mods currently are NOT allowed to add/remove users in fanclub1',u); } } break; } case '/modusers': { if (param) { switch (param){ case 'on': { modsCanChangeUserTitles = 1; notify('You have granted the ability to your Mods to set custom titles on users',u); break; } case 'off': { modsCanChangeUserTitles = 0; notify('You have revoked the ability from your Mods to set custom titles on users',u); break; } default : { notifyError('Allowed options for /modusers are "on" and "off"',u); break; } } }else{ if (modsCanChangeUserTitles) { notify('Mods currently are allowed to set custom titles on users',u); }else{ notify('Mods currently are NOT allowed to set custom titles on users',u); } } break; } default: { validCmd = 0; break; } } } // Host and Mod commands if(validCmd == 0 && (isHost || isMod || isDev)) { validCmd = 1; switch(command) { case '/note': case '/notice': case '/n': { if (param) { sendNote(param, u); msg['m'] = bullets + 'NOTICE SENT' + bullets; msg['c'] = theme_dark; } else { notifyError('Uh oh! You didn\'t write a note',u); } break; } case '/emod': { emod(message[1],message[2],u); break; } case '/tiptotal': { notify('Total tips: ' + tipTotal + ' tokens',u) break; } //fill in code for usertitle,color,highlight case '/usertitle':{ if (isHost || modsCanChangeUserTitles ) { if (param) { paramArray = [param]; if (/\s+/.test(param)) { //check if there are more than one word in the parameters paramArray = param.match(/^(\S+)\s(.*)/).slice(1); //split the user from the rest of the title } var numtitlesArray = titlesArray.length; var hasCustomSettings=false; for (var i = 0 ; i < numtitlesArray ; i++) { if (titlesArray[i].sName == paramArray[0]) { hasCustomSettings=true; if (paramArray.length == 1) { titlesArray[i].sTitle = ''; titlesArray[i].sColor = null; titlesArray[i].sHighlight = null; notify('The title for '+paramArray[0]+' has been removed',u); }else{ titlesArray[i].sTitle = paramArray[1]; notify('The title for '+paramArray[0]+' has been set to "'+paramArray[1]+'"',u); } } } if (!hasCustomSettings) { var title = paramArray[1]; var color = cb.settings.usercolor; var highlight = cb.settings.userhilite;; titlesArray.push({'sName':paramArray[0],'sTitle':title,'sColor':color,'sHighlight':highlight}); notify('The title for '+paramArray[0]+' has been created and set to "'+paramArray[1]+'"',u); } }else{ notifyError('No username specified.',u); } } break; } case '/fanclub1': { if (isHost || modsCanChangeFanclub1) { if (param) { paramArray = param.split(/\s+/); switch (paramArray[0]){ case 'join': case 'add': case '+':{ //todo add check if user is in room if(paramArray[1]){ if (cbjs.arrayContains(club1Array,paramArray[1])) { cb.sendNotice("User " + paramArray[1] + " was already in fanclub1.",u,success_light,success_dark); }else{ club1Array.push(paramArray[1]); cb.sendNotice("User " + paramArray[1] + " was added to fanclub1.",u,success_light,success_dark); var message = paramArray[1]; message += ' joined the '; message += cb.settings.fanClub1name message += 's!'; notifyBold(message); } }else{ cb.sendNotice("No username specified.",u,error_light,error_dark); } break; } case 'leave': case 'remove': case 'delete': case 'del': case 'rm': case '-':{ if(paramArray[1]){ if (cbjs.arrayContains(club1Array,paramArray[1])) { cbjs.arrayRemove(club1Array, paramArray[1]); cb.sendNotice("User " + paramArray[1] + " was removed from fanclub1.",u,success_light,success_dark); var message = paramArray[1]; message += ' was removed from the '; message += cb.settings.fanClub1name message += 's!'; notifyBold(message); }else{ cb.sendNotice("User " + paramArray[1] + " was not found in fanclub1." + "Did you spell the name correctly?",u,error_light,error_dark); } }else{ cb.sendNotice("No username specified.",u,error_light,error_dark); } break; } case 'list': case '':{ var members = club1Array.join(','); FanclubLengthNotice('fanclub1',u); cb["sendNotice"](members,u,'','','normal',''); break; } case 'new':{ var newMembers = 'No new members were added'; var club1AddedArray = new Array; var numClub1Members = club1Array.length; for (var i = 0; i < numClub1Members; i++) { if (!cbjs.arrayContains(club1OrigArray,club1Array[i])) { club1AddedArray.push(club1Array[i]); } } if (club1AddedArray.length > 0) { newMembers = club1AddedArray.join(','); } cb["sendNotice"](newMembers,u,'','','normal',''); break; } default: { cb.sendNotice('Unknown fanclub command: "' + paramArray[0] + '"',u,error_light,error_dark); break; } } }else{ var members = club1Array.join(','); FanclubLengthNotice('fanclub1',u); cb["sendNotice"](members,u,'','','normal',''); } } break; } default: { validCmd = 0; break; } } } // Host, Mod, and Emod commands if(validCmd == 0 && (isHost || isMod || isEmod || isDev)) { validCmd = 1; switch(command) { case '/blocknotice': { if (isHost) { blockNotice(param,u); }else if (cb.settings.wordlistShowModerators == 'Yes') { blockNotice(param,u); } break; } case '/silencelevel': { setSilenceLevel(param,u); break; } case '/greysoff': case '/greyoff': case '/graysoff': case '/grayoff': case '/silencegreys': case '/silencegrays': { setSilenceLevel(1,u); break; } case '/greyson': case '/greyon': case '/grayson': case '/grayon': case '/unsilencegreys': case '/unsilencegrays': { setSilenceLevel(0,u); break; } case '/graphiclevel': { setGraphicLevel(param,u); break; } case '/silence': { silence(param,u); break; } case '/unsilence': { unsilence(param,u); break; } case '/silencelast': case '/sl': { silenceLast(u); break; } case '/addnice': { niceList(param,u,'a'); break; } case '/removenice': { niceList(param,u,'r'); break; } case '/addgrey': case '/addgray': { greyList(param,u,'a'); break; } case '/removegrey': case '/removegray': { greyList(param,u,'r'); break; } case '/starttimer': { startTimer(param,u); break; } case '/addtime': { addTime(param,u); break; } case '/stoptimer': case '/endtimer': { stopTimer(u); break; } case '/kingspam': { kingSpamToggle(param,u) break; } case '/notifierspam': { notifierSpamToggle(param,u) break; } case '/leaderboardspam': { leaderboardSpamToggle(param,u) break; } // case '/notifiermessage': { // if(message[1] == '' || message[1] == null) { // notifyError('You must enter a new message for the notifier feature. If you want to disable the notifications, enter /notifierspam off.',u); // } // else { // notifierMessage = msg['m'].substring(16).trim(); // notify('You have set the notifier spam message to: ' + notifierMessage,u); // } // break; // } case '/shownotices': { var noticeString = ''; if (noticeArray.length) { for (var i = 0; i < noticeArray.length; i++) { if (i > 0) { noticeString += '\n-------------------------\n'; } noticeString += '\u2022 Rotating Notice #' + (i + 1) + ': \n'; noticeString += noticeArray[i]; } notifyPlain(noticeString,u); } else { notifyPlain('There are no rotating notices set.',u); } break; } case '/removenotice': case '/removenote': { var n = parseInt(param); if (n > 0 && n <= (noticeArray.length)) { noticeArray.splice((n-1), 1); notify('You have removed notice #' + n,u); } else if(param) { notifyError('\'' + param + '\' is not a valid notice.',u); } else { notifyError('You did not enter a valid notice.',u); } break; } case '/addnotice': case '/addnote': { var noticeArrayLength = noticeArray.length; if(param) { addNotice(param); if (!noticeArrayLength) { sendRotating(); notifierSpam(); } notify('You have successfully added a new notice!',u); } else { notifyError('You did not enter a valid notice.',u); } break; } case '/addword': { if(param) { addWord(param); notify('You have successfully added \'' + param + '\' to the custom wordlist!',u); } else { notifyError('You did not enter a valid word.',u); } break; } case '/noticetimer': { var n = parseInt(param); if (n > 0) { notifierTimer = n; // clearTimeout(notifierTimeout); // notifierSpam(); notify('Rotating notices will now display every ' + n + ' minutes.',u); } else if (param) { notifyError('\'' + param + '\' is not a valid value for /noticetimer.',u); } else { notifyError('You did not enter a valid value for /noticetimer.',u); } break; } case '/tipmenu': { if (cb.settings.tipMenu === 'Yes') { chatAd(); } break; } case '/notice1':{ if (noticeArray[0]) { notifyTheme(noticeArray[0]); } break; } case '/notice2':{ if (noticeArray[1]) { notifyTheme(noticeArray[1]); } break; } case '/notice3':{ if (noticeArray[2]) { notifyTheme(noticeArray[2]); } break; } case '/notice4':{ if (noticeArray[3]) { notifyTheme(noticeArray[3]); } break; } case '/notice5':{ if (noticeArray[4]) { notifyTheme(noticeArray[4]); } break; } case '/notice6':{ if (noticeArray[5]) { notifyTheme(noticeArray[5]); } break; } case '/notice7':{ if (noticeArray[6]) { notifyTheme(noticeArray[6]); } break; } case '/notice8':{ if (noticeArray[7]) { notifyTheme(noticeArray[7]); } break; } case '/bio': { if (cb.settings.custCommands == 'Yes') { if (!isBlank(cb.settings.bio)) { var bioMessage = cb.settings.bio.replace(/{newline}/gi, "\n"); notifyTheme(bioMessage); } }else{ notify("The room host has not enabled the custom commands",u) } break; } case '/dontmmm': { if (cb.settings.custCommands == 'Yes') { if (!isBlank(cb.settings.dontmmm)) { var dontmmmMessage = cb.settings.dontmmm.replace(/{newline}/gi, "\n"); notifyTheme(dontmmmMessage); } }else{ notify("The room host has not enabled the custom commands",u) } break; } case '/dirty': { if (cb.settings.custCommands == 'Yes') { if (!isBlank(cb.settings.dirty)) { var dirtyMessage = cb.settings.dirty.replace(/{newline}/gi, "\n"); notifyTheme(dirtyMessage); } }else{ notify("The room host has not enabled the custom commands",u) } break; } case '/follow': { if (cb.settings.custCommands == 'Yes') { if (!isBlank(cb.settings.follow)) { var followMessage = cb.settings.follow.replace(/{newline}/gi, "\n"); notifyTheme(followMessage); } }else{ notify("The room host has not enabled the custom commands",u) } break; } case '/manyvids': { if (cb.settings.custCommands == 'Yes') { if (!isBlank(cb.settings.manyvids)) { var manyvidsMessage = cb.settings.manyvids.replace(/{newline}/gi, "\n"); notifyTheme(manyvidsMessage); } }else{ notify("The room host has not enabled the custom commands",u) } break; } case '/amazon': { if (cb.settings.custCommands == 'Yes') { if (!isBlank(cb.settings.amazon)) { var amazonMessage = cb.settings.amazon.replace(/{newline}/gi, "\n"); notifyTheme(amazonMessage); } }else{ notify("The room host has not enabled the custom commands",u) } break; } case '/location': { if (cb.settings.custCommands == 'Yes') { if (!isBlank(cb.settings.location)) { var locationMessage = cb.settings.location.replace(/{newline}/gi, "\n"); notifyTheme(locationMessage); } }else{ notify("The room host has not enabled the custom commands",u) } break; } default: { validCmd = 0; break; } } } // Everybody else commands if (validCmd == 0) { validCmd = 1; switch(command) { case '/bombhelp': case '/ubhelp': { help(param,u); break; } case '/leaderboard': { showLeaderBoard(u); break; } case '/timeleft': { timeLeft(msg['user']); break; } case '/whisper': case '/w': case '/tell': case '/t': case '/pm': case '/reply': case '/r': case '/ignorelevel': case '/ignore': case '/unignore': { if(cb.settings.whisperToggle.substr(0,2) == 'No') { notifyError('The broadcaster has disabled the "whisper" feature',u); } else if (command.match(/\b(whisper|w|tell|t|pm)\b/ig)) { var whisperLevel; if(isGrey && silenced == 0) { whisperLevel = 1; } else if(!isBlueUp && silenced == 0) { whisperLevel = 2; } else if(!hasTipped && silenced == 0) { whisperLevel = 3; } else { whisperLevel = 4; } if(isHost || isMod || isEmod || isFan || isNice || isDev) { sendWhisper(message,u,true,whisperLevel); msg['m'] = textReplaceWhisper(message,u); msg['background'] = bb_light; msg['c'] = bb_dark; } else if (messageBlocked == 0 && graphicsBlocked == 0) { sendWhisper(message,u,false,whisperLevel); msg['m'] = textReplaceWhisper(message,u); msg['background'] = bb_light; msg['c'] = bb_dark; } else { msg['m'] = 'Whisper not sent.'; msg['background'] = '#EEE'; msg['c'] = '#AAA'; } } else if (command.match(/\b(reply|r)\b/ig)) { if (messageBlocked == 0 && graphicsBlocked == 0) { sendReply(message,u); msg['m'] = textReplaceWhisper(message,u,true); msg['background'] = bb_light; msg['c'] = bb_dark; } else { msg['m'] = 'Reply not sent.'; msg['background'] = '#EEE'; msg['c'] = '#AAA'; } } else if (command == ('/ignorelevel')) { setIgnoreLevel(param,u); } else if (command == ('/ignore')) { ignoreUser(param,u); } else if (command == ('/unignore')) { unignoreUser(param,u); } break; } //debugging command to show variables case '/showvar': { if(isDev) { var v = param; function showVar(){ this.debug = function(sVar){ try { notifyPlain(eval(sVar), dev); } catch (e) { notifyPlain('no such variable', dev); } } } var displayVar = new showVar(); displayVar.debug(v); } else { validCmd = 0; } break; } default: { validCmd = 0; break; } } } if (validCmd == 0) { msg['background'] = '#EEE'; msg['c'] = '#AAA'; //Give Permission notice if (command.match(/\b(note|notice|n|emod|addnice|removenice|addgrey|addgray|removegrey|removegray|tiptotal|blocknotice|silencelevel|greysoff|greyoff|greyson|greyon|graphiclevel|silence|unsilence|starttimer|addtime|stoptimer|endtimer|kingspam|notifierspam|leaderboardspam|shownotices|removenotice|removenote|addnotice|addnote|noticetimer)\b/ig)) { notifyError('Only moderators and broadcasters are able to use the "' + command + '" command.\nType "/bombhelp\xa0commands" to see a full list of the available commands.',u); } //Make sure it doesn't call errors for common commands used by other apps/bots else if (command.match(/\b(b|p|lb|rewards|prizes|winners|startshow|showtimeleft|printtime|addshowtime|adduser|changegoal|hide|unhide|selltickets|uacommands|luhelp|levels)\b/ig)) { // do nothing } //Otherwise, it means the user entered an invalid command else if(cb.settings.invalidToggle == 'Yes') { notifyError('"' + command + '" is not a valid command.\nType "/bombhelp\xa0commands" to see a full list of the available commands.',u); } } } // Caps Levels function doCapsLevel(level) { if(msg['m'] == msg['m'].toUpperCase() && msg['m'].toUpperCase() != msg['m'].toLowerCase()) { for(var i = 0; i < msg['m'].length; i++) { if(symbolString.indexOf(msg['m'].charAt(i)) == -1) { msg['m'] = msg['m'].replace(/[^\s]+/g, function (match) { return match.indexOf(':') === 0 ? match : match.toLowerCase(); }); } } } } if(capsLevel > 0 && !(isHost || isMod || isEmod || isFan || isFave || isNice || isDev) && silenced == 0) { switch(capsLevel) { case 1:{ if(isGrey || isGreyish) { doCapsLevel(capsLevel); } break; } case 2:{ if(!hasTipped || isGreyish) { doCapsLevel(capsLevel); } break; } case 3:{ doCapsLevel(capsLevel); break; } case 4:{ doCapsLevel(capsLevel); break; } } }else if(capsLevel > 0 && silenced == 0 ){ // level 3 is handled by the if above, so only need to restrict for level 4 switch (capsLevel) { case 4:{ if (!(isHost || isMod || isEmod)) { doCapsLevel(capsLevel); } break; } } } // Sticky Levels function doStickyLevel(level) { if(msg['m'].match(/(.)\1{3,}/ig)) { message = msg['m'].trim().split(/\s+/g); // make sure we're working with the current version of our message var m = ''; for(var i = 0; i < message.length; i++) { if(i >= 0) { m += ' '; } if ((message[i].charAt(0) == ':')) { m += message[i]; } else { m += message[i].replace(/(.)\1{3,}/ig, '$1$1$1'); } } msg['m'] = m; } } if(stickyLevel > 0 && !(isHost || isMod || isEmod || isFan || isFave || isNice || isDev) && silenced == 0) { switch(stickyLevel) { case 1:{ if(isGrey || isGreyish) { doStickyLevel(stickyLevel); } break; } case 2:{ if(!hasTipped || isGreyish) { doStickyLevel(stickyLevel); } break; } case 3:{ doStickyLevel(stickyLevel); break; } case 4:{ doStickyLevel(stickyLevel); break; } } }else if (stickyLevel > 0 && silenced == 0 ){ // level 3 is handled by the if above, so only need to restrict for level 4 switch (stickyLevel) { case 4:{ if (!(isHost || isMod || isEmod)) { doStickyLevel(stickyLevel); } break; } } } //tip titles, if turned on, as well as king's crown if(cb.settings.tipTitles == 'Yes' && hasTipped && !isCommand && !isKenoCmd) { msg['m'] = setTipTitles(msg['user'],msg['m']); } if(cb.settings.fanClub1 === 'Yes' && !isCommand && !isKenoCmd) { setFanclub1Titles(msg); } if(cb.settings.userTitles === 'Yes' && !isCommand && !isKenoCmd) { setCustomTitles(msg); } return msg; }); /************************************************************************************************************************************ ***** onTip ************************************************************************************************************************* ************************************************************************************************************************************/ cb.onTip(function (tip) { var thisTip = parseInt(tip['amount']); var thisTipper = tip['from_user']; var userTotal = addTip(thisTipper, thisTip); tipNote = tip['message']; tipTotal += thisTip; if(cb.settings.notifierTip.substr(0,2) != 'No' && thisTip >= cb.settings.tipMessageMin) { var to = ''; tipMessage = cb.settings.tipMessage.replace('{username}', thisTipper); if(cb.settings.notifierTip == 'Privately to tipper only') { to = thisTipper; } notify(tipMessage,to,yellow_light,mod_orange); } if(cb.settings.kingTipper == 'Yes') { if (thisTipper == currentKing) { kingTip = userTotal; // current king, new total } else if (userTotal > kingTip && userTotal >= kingMin) { // New king currentKing = thisTipper; kingTip = userTotal; notifyTheme(crown + ' We have a new ' + (tip['from_user_gender'] === 'f' ? 'Queen' : 'King') + '! All hail ' + thisTipper + '! ' + crown, ''); } } if(cb.settings.tipMenu != 'No'){ for (var i = 1; i <= 30; i++) { if (thisTip == parseInt(cb.settings['item' + i + 'price'])) { cb.sendNotice(tip['from_user'] + ' tipped for ' + cb.settings['item' + i],'','',cb.settings['noticecolor'],'bold'); } } } if (cb.settings.fanClub1 != 'No') { //if fanClub1 is enabled in the config if (cb.settings.fanClub1name) { //club must be named to be active var impossibleTip = 1000000 // number larger than possible in a single tip per CB var singleTip = cb.settings.fanClub1price == 0 ? impossibleTip : cb.settings.fanClub1price var cumulativeTip = cb.settings.fanClub1Cumulative == 0 ? impossibleTip : cb.settings.fanClub1Cumulative //a bug casue there is not CB limit on cumulative tips, but if they tip that much dont they deserve to be in the fanclub? if (thisTip == singleTip || ((thisTip >= singleTip) && (cb.settings.fanClub1tipping == 'Yes')) || userTotal >= cumulativeTip ) { //user has tipped enough for entry into the fanclub, so check if they are already in the club if (!cbjs.arrayContains(club1Array, thisTipper)) { //add them club1Array.push(thisTipper); var message = thisTipper; message += ' joined the '; message += cb.settings.fanClub1name message += 's!'; notifyBold(message); FanclubLengthNotice('fanclub1',cb.room_slug); } } } } }); /************************************************************************************************************************************ ***** onLeave *********************************************************************************************************************** ************************************************************************************************************************************/ cb.onLeave(function(user) { var u = user['user']; // Send fanclub notices if(cb.settings.fanClub1 === 'Yes' && cb.settings.fanClub1name){ if (cbjs.arrayContains(club1Array,u)) { notifyBold(cb.settings.fanClub1title + ' ' + u + ' left the room.'); } } }); /************************************************************************************************************************************ ***** onEnter *********************************************************************************************************************** ************************************************************************************************************************************/ cb.onEnter(function(user) { var u = user['user']; if (!isBlank(cb.settings.enterMessage)) { var enterMessage = cb.settings.enterMessage.replace(/{newline}/gi, "\n"); notifyTheme(enterMessage,u); } // Add mod to modArray if(user['is_mod']) { if (!cbjs.arrayContains(modArray,u)) { modArrayPopulate(u); modAndEmodArrayPopulate(u); if(cb.settings.wordlistShowModerators == 'Yes') { modBlockMsgArrayPopulate(u); } } if(cb.settings.wordlistToggle == 'Yes') { //Send notice to moderators as they enter notifyErrorBold(bullets + 'Bomb Bot Ultra - MODERATOR NOTICE' + bullets,u); var modMessage = 'Welcome to ' + cb.room_slug + '\'s room. ' + cb.room_slug + ' is running Bomb Bot Ultra. This bot automatically blocks certain messages that contain words and phrases that are deemed abusive, inappropriate, or annoying.\n'; if (cbjs.arrayContains(modBlockMsgArray,u)) { modMessage += 'Your blocked message notices are currently ON. To stop seeing them, type: /blocknotice\xa0off.\n'; } else { modMessage += 'Your blocked message notices are currently OFF. To see them again, type: /blocknotice\xa0on.\n'; } modMessage += 'To silence an abusive user using the bot, type: /silence\xa0[username]'; notifyError(modMessage,u); } } // Send fanclub notices if(cb.settings.fanClub1 === 'Yes' && cb.settings.fanClub1name){ if (cbjs.arrayContains(club1Array,u)) { notifyBold(cb.settings.fanClub1title + ' ' + u + ' entered the room.'); } } }); /************************************************************************************************************************************ ***** Initialize ******************************************************************************************************************** ************************************************************************************************************************************/ if(initialize == 0) { cb.settings.colorscheme = 'Custom'; setColor(); cb.settings.wordlistToggle = 'Yes'; if(cb.settings.wordlistToggle == 'Yes') { parseWordlist(); } if(cb.settings.defaultSilenceLevel) { silenceLevel = parseInt(cb.settings.defaultSilenceLevel.charAt(0)); } if(cb.settings.defaultGraphicLevel) { graphicLevel = parseInt(cb.settings.defaultGraphicLevel.charAt(0)); } if(cb.settings.defaultCapsLevel) { capsLevel = parseInt(cb.settings.defaultCapsLevel.charAt(0)); } if(cb.settings.defaultStickyLevel) { stickyLevel = parseInt(cb.settings.defaultStickyLevel.charAt(0)); } if(cb.settings.notifierSpam == 'Yes') { parseRotating(); notifierSpamTGL = 1; cb.setTimeout(function() { sendRotating(); notifierSpam(); // random amount of time not more than chosen interval }, Math.floor((Math.random() * notifierTimer) + 1)*minuteMS); } if(cb.settings.kingTipper == 'Yes') { kingTipperSpam = 1; cb.setTimeout(function() { kingSpamTimer(); // random amount of time not more than chosen interval, plus 20 seconds }, Math.floor((Math.random() * kingTimer) + 1)*minuteMS/3); } if(cb.settings.leaderBoard == 'Yes') { leaderboardSpam = 1; cb.setTimeout(function() { ldrSpamTimer(); // random amount of time not more than chosen interval, plus 40 seconds }, Math.floor((Math.random() * ldrTimer) + 1)*minuteMS*2/3); } if(!isBlank(cb.settings.silenceList)) { var s = cb.settings.silenceList.replace(/\s+/g, ''); silenceArray = s.replace(/^,+|,+$/g,'').split(','); } if(!isBlank(cb.settings.niceList)) { var n = cb.settings.niceList.replace(/\s+/g, ''); niceArray = n.replace(/^,+|,+$/g,'').split(','); } if(!isBlank(cb.settings.greyList)) { var g = cb.settings.greyList.replace(/\s+/g, ''); greyArray = g.replace(/^,+|,+$/g,'').split(','); } if(!isBlank(cb.settings.hostWhisperLevel)) { ignoreArray[findIgnorer(cb.room_slug)][1] = parseInt(cb.settings.hostWhisperLevel.charAt(0)); // setting whisper ignore level for broadcaster } if(cb.settings.wordlistToggle == 'Yes') { //Send notice to moderators notifyErrorBold(bullets + 'Bomb Bot Ultra - MODERATOR NOTICE' + bullets,'onlyMods'); var modMessage = cb.room_slug + ' has just started Bomb Bot Ultra. This bot automatically blocks certain messages that contain words and phrases that are deemed abusive, inappropriate, or annoying.\n'; if(cb.settings.wordlistShowModerators == 'Yes') { modMessage += 'Your blocked message notices are currently ON. To stop seeing them, type: /blocknotice\xa0off.\n'; } else { modMessage += 'Your blocked message notices are currently OFF. To see them again, type: /blocknotice\xa0on.\n'; } modMessage += 'To silence an abusive user using the bot, type: /silence\xa0[username]'; notifyError(modMessage,'onlyMods'); if(cb.settings.wordlistShowBroadcaster == 'Yes') { notifyErrorBold(bullets + 'Bomb Bot Ultra - BROADCASTER NOTICE' + bullets,'roomHost'); // var modMessage = cb.room_slug + ' has just started Bomb Bot Ultra. This bot automatically blocks certain messages that contain words and phrases that are deemed abusive, inappropriate, or annoying.\n'; var modMessage = 'You have chosen to see blocked message notices. This has the potential to be distracting. It is recommended that let your moderators handle these blocked messages instead.\n'; modMessage += 'To stop seeing them, type "/blocknotice\xa0off"\n'; modMessage += 'Or set "Notify broadcaster" to "No" under Section 3 of the bot launch screen.'; // modMessage += 'To silence an abusive user using the bot, type: /silence\xa0[username]'; notifyError(modMessage,'roomHost'); } } if (cb.settings.tipMenu === 'Yes') { if (cb.settings['sepchar'] ) { separator_char = cb.settings['sepchar']+" "; } } //Initalize Tip Menu if(cb.settings.tipMenu === 'Yes'){ cb.setTimeout(chatAd, (cb.settings.chat_ad * 60000)); } //Initialize fanclubs and custom titles if (cb.settings.fanClub1 === 'Yes') { if(!isBlank(cb.settings.fanClub1members)) { var f1 = cb.settings.fanClub1members.replace(/\s+/g, ','); club1Array = f1.replace(/,+/g,',').split(','); club1OrigArray = f1.replace(/,+/g,',').split(','); }else{ club1Array = new Array; club1OrigArray = new Array } //clean "Notice:" if copy pasted list if (cbjs.arrayContains(club1Array,'Notice:')) { cbjs.arrayRemove(club1Array,'Notice:') } if (cbjs.arrayContains(club1OrigArray,'Notice:')) { cbjs.arrayRemove(club1OrigArray,'Notice:') } } cb.settings.fanClub1colors = 'Yes'; if (cb.settings.userTitles === 'Yes') { for (var i = 1 ; i <= NUM_TITLES ; i++) { var customUser = cb.settings['user' + i + 'name']; if (customUser) { var title = cb.settings['user' + i + 'title']; var color = cb.settings['usercolor']; var highlight = cb.settings['userhilite']; if (color) { //TODO add support for named colors if (!isValidColor(color)) { notifyError('Invalid color ' + color + ' for Users Title '+i,'roomHost'); } } if (highlight) { //TODO add support for named colors if (!isValidColor(highlight)) { notifyError('Invalid highlight color ' + highlight + ' for Users Title '+i,'roomHost'); } } titlesArray.push({'sName':customUser,'sTitle':title,'sColor':color,'sHighlight':highlight}); } } } cb.settings.userTitlecolors = 'Yes'; // setup mod control of fanclubs and custom titles if (cb.settings.fanClub1mods === 'Yes') { modsCanChangeFanclub1 = 1; } if (cb.settings.userTitlemods === 'Yes') { modsCanChangeUserTitles = 1; } switch (cb.settings.customWordlistNotify) { case 'broadcaster only':{ cb.settings.wordlistShowBroadcaster = 'Yes'; cb.settings.wordlistShowModerators = 'No'; break; } case 'broadcaster/mods':{ cb.settings.wordlistShowBroadcaster = 'Yes'; cb.settings.wordlistShowModerators = 'Yes'; break; } case 'just mods':{ modBlockMsgArrayDepopulate(cb.room_slug); cb.settings.wordlistShowBroadcaster = 'No'; cb.settings.wordlistShowModerators = 'Yes'; break; } case 'all parties':{ cb.settings.wordlistShowBroadcaster = 'Yes'; cb.settings.wordlistShowModerators = 'Yes'; break; } } if(cb.settings.wordlistShowBroadcaster == 'Yes') { modBlockMsgArrayPopulate(cb.room_slug); } //Initialize initialize = 1; }
© Copyright Chaturbate 2011- 2024. All Rights Reserved.