Bots Home
|
Create an App
Dorothy's Ticket Show2
Author:
dorothy
Description
Source Code
Launch Bot
Current Users
Created by:
Dorothy
/** Name: Dorothy's Ticket Show Author: chelsea2950 Current version 1.0 Created 02/15/2019 Last Updated 2/15/2019 (see description for change log) **/ // prototype functions { String.prototype.capitalize = function() { return this.charAt(0).toUpperCase() + this.slice(1); } String.prototype.repeat = function (number) { return new Array(number + 1).join(this); } String.prototype.equals = function (str) { var m = new RegExp(str); return this.match(m) != null; } String.prototype.equalsIgnoreCase = function (str) { var m = new RegExp(str, "i"); return this.match(m) != null; } } { var dummycounter = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15' ]; var backgroundArray = { menu: ['Cube Wave', 'Hearts', 'Snow', 'Aquarium', 'Snakeskin', 'Pastels', 'Clouds', 'Lava Lamp', 'Light Blue', 'Moon', 'personalized - CumCreamery', 'personalized - Liv n Drew', 'Blue Bars', 'Valentines Pink Bars', 'Valentines 2 Hearts' ], command: ['cubewave', 'hearts', 'snow', 'aquarium', 'snakeskin', 'pastels', 'clouds', 'lavalamp', 'lightblue', 'moon', 'cumcreamery', 'livanddrew', 'bluegradient', 'valentines1', 'valentines2' ], devfile: ['17606e52-2215-403d-b052-46a936ca9f92','add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', '3f73f647-504a-4f9a-8e64-86cc89890955', 'e8692639-7f53-4ce4-8eb6-7e33de58f0e0', '3a6f6a1a-6ebf-4c7b-a391-84084ad3685b', '0ea7c580-424b-4ecb-8231-cd21d5721a10', 'a2c0ce0e-ee37-4723-a44d-c826f0b10c13' ], livefile: ['9478eff1-b042-4d33-ad91-f8427b98cad8','18994a59-8a72-44c4-ba3b-ab9e835460b8', '18a37566-956a-4e84-a668-2dc32bcf6963', 'e2632788-9b57-48b3-8b63-1880c39efa0d', '80a94656-e4b5-4217-adf3-5a7386dc4023', '8c0b2b81-cb3e-4fb7-9ae3-4f2656c90e4d', 'b3dcdf85-a351-4f50-a686-5a553657981f', '8da93470-9c6a-47c4-83e6-858907d4f84d', '2311527c-85cb-44a0-87d9-adc3097b53d8', '1b53854d-dd02-4e7e-a9cb-fd0e38255cf1', '87983935-461f-418b-a140-36b790fb1bcf', '51864982-fa61-466f-9de6-367461031eb9', 'a0ad9443-e8df-4286-9f95-ea5f51931b9f', 'f228e2e6-8d58-49f4-b9a4-4662de7290c0', '2a63550e-d6f8-4182-bf35-3a61b24067e5' ] }; var fontSize = 12; var customPanel = false; } {cb.settings_choices = [ {name: 'intro', label: '******************* INTRODUCTION ********************* Latest Updt: 02/14/2019 (version 1.1) See Change Log ********************************************************* Welcome to Dorothy\'s Ticket Show App. Note that moderators can be given significant privileges by this App, so please make sure you assign moderators you can trust, or turn off the moderator command authority. When using this Ultra App in combination with Dorothy\'s Ultra Fembot, be sure to set the ticket show type there to "Dorothy\'s UltraApp". Ticket show Pre-sales and backup ticket list as well as all of the automated features around menus, polls, adding users from leaderboard, etc are also maintined in the Ultra Fembot. Also, you can see the full list of commands for the App by typing "/tickethelp" in the chat (no quotes). It is expected that you would be using an Ultrabot such as Dorothy\'s Ultra Fembot alongside this for features such as Chat Control and Tipper Count/Leader features, so this app only executes the ticket show. Please enjoy using the App and feel free to say hello if you see me around, or DM me on twitter @thechelsea2950 if you have questions. Thank you! - chelsea', type: 'choice',required: false}, {name: 'enableEntryMessage', label: 'Display a notification to users when they enter?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'entryMessage', label: 'Enter the message to display. A note regarding the current App Feature running will be appended to this message so you do not need to restate that', type: 'str',required: false, minLength: 1, maxLength: 1000, defaultValue: 'Welcome! Dorothys Ultra App is currently running for for the broadcaster to manage goal shows and ticket shows.'}, {name: 'allowModsAuthority', label: 'Allow moderators to have authority to broadcaster commands across all App Features? Note there are separate controls later for ticket show additions and price changes. It is usually ok to give moderators general authority with this setting, however they will have authority to perform actions such as manually adding tips to goals, start and ending ticket shows, and changing goal thresholds', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'ticketRoomSubjectSfx', label: 'Title? -- Description of the show to appear as part of the room title (optional). You can include hashtags for keywords you want to be searchable', type:'str', minLength: 1,maxLength: 100, required: false, defaultValue: 'Hidden Sex Show! Token Poll for cumshot!'}, {name: 'ticketShowPrice', label: 'Ticket Show Price? -- The Hidden Show feature cannot be enabled without a price defined. Discounted price for Fan Club is defined later below', type: 'int',minValue: 1,maxValue: 300,defaultValue: 69,required: false}, {name: 'ticketShowStartMode', label: 'Start Mode? -- Which mode is used for determining when to start the show? This setting works in combination with the next setting below to define what will trigger the start of show, and whether it starts automatically', type: 'choice', choice1: 'Start Show Anytime', choice2: 'Start Show after Timer', choice3: 'Start Show after Ticket Goal', choice4: 'Start Show after Token Goal', defaultValue: 'Start Show Anytime'}, {name: 'ticketShowStartAuto', label: 'AutoStart? -- If using a timer or goal to determine start of show, does the Broadcaster (or moderator) start the show manually with the /startshow command, or does the show start automatically when timer runs out or goal is reached?', type: 'choice', choice1: 'Start from Command', choice2: 'Automated Start', defaultValue: 'Start from Command'}, {name: 'ticketShowGoal', label: 'Goal Amount? -- If using a goal for the total sales before starting the show, set goal amount here (in terms of tickets or tokens based on type of show start goal defined above). When using a timed start, this setting is not used', type: 'int',minValue: 1,maxValue: 5000,defaultValue: 1000,required: false}, {name: 'ticketShowStartTimer', label: 'Default Timer -- If the start mode is set for using an automatic timer, define the number of minutes for the countdown to show start here. Timer will start immediately upon starting the broadcast, or when the Hidden Ticket Show feature is turned on later. For manual timer control, start the show in "Start Show Anytime" mode, turn off "Autostart", and use "/ticketstarttimer" to do a countdown', type: 'int',minValue: 1,maxValue: 120,defaultValue: 15,required: false}, {name: 'ticketShowFreeFC', label: 'Give a free ticket to CB Fanclub members?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'ticketShowFreeMods', label: 'Give a free ticket to moderators?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'ticketShowPriceFC', label: 'Discounted Price for a ticket to the show for CB Fan Club members if not set for a free ticket above. If no price is set, the Fanc Club ticket price is the same as regular viewers. This value is not used if the above setting grants them a free ticket.', type: 'int',minValue: 1,maxValue: 300,defaultValue: 35,required: false}, {name: 'ticketShowModsAdd', label: 'Allow moderators to use the "add" and "remove" commands? Note that enabling this will allow them to add themselves to a show even if the above setting for giving them a free ticket is set to "No". This setting overrides the general setting for mod authority specifically for the ticket show "/add" functions.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'ticketShowModsChgPrice', label: 'Allow moderators to change the price of a ticket? This setting overrides the general setting for mod authority specifically for the ticket show price functions', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'ticketShowAfterNotice', label: 'Message to display in the Room Subject and Notice after the show has ended', type:'str',minLength: 1,maxLength: 100,required: false,defaultValue: 'After show hangout, please follow us on twitter @yourusername.'}, {name: 'ticketShowReducePriceWarn', label: 'Late addition Ticket Show Sale? -- Reduce Ticket Price by this amount when the /showwarn command is used to indicate the show is nearly over. Set to 0 to not use this feature. Note this is the price reduction, not the actual new price', type: 'int',minValue: 0,maxValue: 300,defaultValue: 0,required: false}, {name: 'ticketShowEnableOT', label: 'Use OT List? -- Enable Outstanding Ticket feature so users can save their ticket for use in a later show. Note that the broadcaster must still record the user names and enter them in the OTS list below. Can also be used for granting free tickets to viewers for a future show in place of a refund if there was a problem with a show, or user bought at the last second and missed the show.', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'ticketShowOTList', label: 'OT List -- If the Outstanding Ticket feature is enabled above, enter the names of any viewers you would like to grant a ticket to a future show. The user will be notified when they enter that they have a free ticket, and if they choose to use it, the broadcaster is notified so they can remove them from the list before next show. The format should be a comma separated list (user1,user2,user3)', type: 'str', minLength: 1, maxLength: 1000, defaultValue: '', required: false}, {name: 'ticketShowAllowGift', label: 'Gifting Allowed? -- Allow users to buy additional tickets they can use as gifts to other users', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'ticketShowTextColor',label: 'Text color for chat notices related to the Ticket Show App',type: 'choice',choice1: 'White/No Color',choice2: 'Black',choice3: 'Dark Grey',choice4: 'Dark Red',choice5: 'Dark Orange',choice6: 'Dark Green',choice7: 'Dark Aqua',choice8: 'Dark Blue',choice9: 'Dark Purple',choice10: 'Dark Pink',choice11: 'Custom',defaultValue: 'Dark Blue'}, {name: 'ticketShowCustomTextColor', label: 'If you picked a custom text color in the previous setting, enter the hex color (6 character hex color codes including the # prefix, such as #FFFFFF):', type: 'str', minLength: 1, maxLength: 7, required: false}, {name: 'ticketShowBgColor',label: 'Background/Highlight color for chat notices related to the Ticket Show App', type: 'choice', choice1: 'White/No Color',choice2: 'Light Yellow',choice3: 'Light Blue',choice4: 'Light Pink',choice5: 'Light Red',choice6: 'Light Green',choice7: 'Light Purple',choice8: 'Light Orange',choice9: 'Light Grey',choice10: 'Light Aqua',choice11: 'Custom',defaultValue: 'Light Aqua'}, {name: 'ticketShowCustomBgColor', label: 'If you picked a custom text color in the previous setting, enter the hex color (6 character hex color codes including the # prefix, such as #FFFFFF):', type: 'str', minLength: 1, maxLength: 7, required: false}, {name: 'showTotals', label: 'Show the total tips so far for the current app in the draw panel?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'fembotRunning', label: 'Are you using Dorothy\'s Fembot alongside the Ticket Show App? If not, you should be! :) This setting is used to suppress error messages from the Ticket Show App for invalid commands as it is expected the Fembot will handle errors (so you don\'t get the same error twice)', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {name: 'panelBackground', label: 'Which background panel type would you like to display? Note you cannot use the personalized background unless they are for your room, it will use the default if they are selected', type: 'choice', choice1: 'default - no image', choice2: backgroundArray.menu[0], choice3: backgroundArray.menu[1], choice4: backgroundArray.menu[2], choice5: backgroundArray.menu[3], choice6: backgroundArray.menu[4], choice7: backgroundArray.menu[5], choice8: backgroundArray.menu[6], choice9: backgroundArray.menu[7], choice10: backgroundArray.menu[8], choice11: backgroundArray.menu[9], choice12: backgroundArray.menu[10], choice13: backgroundArray.menu[11], choice14: backgroundArray.menu[12], choice15: backgroundArray.menu[13], choice16: backgroundArray.menu[14], defaultValue: 'default - no image'}, {name: 'panelTextColor',label: 'Text color for the panel text',type: 'choice',choice1: 'White/No Color',choice2: 'Black',choice3: 'Dark Grey',choice4: 'Dark Red',choice5: 'Dark Orange',choice6: 'Dark Green',choice7: 'Dark Aqua',choice8: 'Dark Blue',choice9: 'Dark Purple',choice10: 'Dark Pink',choice11: 'Dark Gold',choice12: 'Dark Teal',choice13: 'Dark Brown',choice14: 'Dark Bronze',choice15: 'Dark Periwinkle',choice16: 'Dark Fuschia',choice17: 'Dark Lime',choice18: 'Dark Plum',choice19: 'Custom',defaultValue: 'Dark Blue'}, {name: 'panelCustomTextColor', label: 'If you picked a custom text color in the previous setting, enter the hex color (6 character hex color codes including the # prefix, such as #FFFFFF):', type: 'str', minLength: 1, maxLength: 7, required: false} ]; } { // *********************************** Variables and Arrays ************************************** var initialize = 0; var numberOfModerators = 1; var timerStart = 0; var chatMsgToggle = 0; var groupTipToggle = 0; var BC = cb.room_slug; var whichApp = ''; var currentGoal = 1; var currentGoalTips = 0; var currentGoalTotal = 0; var currentSessionTotal = 0; var currentGoalRecycleCnt = 0; var totalGoalLevels = 0; var currentGoalLevel = 1; var currentGoalCountAmt = 0; var sequenceTotalTipsGoal = 0; var currentAppTotalGoal = 0; var currentAppTotalCounter = 0; var currentAppTotalSequence = 0; var currentAppTotalTipJar = 0; var currentAppTotalTicket = 0; var currentAppTotalNone = 0; var tipJarRunning = false; var tipJarWaiting = false; var goalSubjectText = cb.settings.progressiveRoomSubjectSfx; var counterSubjectText = cb.settings.goalcounterRoomSubjectSfx; var sequenceSubjectText = cb.settings.tipsequenceRoomSubjectSfx; var tipjarSubjectText = cb.settings.tipjarRoomSubjectSfx; var ticketSubjectText = cb.settings.ticketRoomSubjectSfx; var ticketStartMode = ""; var ticketModeAuto = ""; var ticketShowTotalTips = 0; var ticketShowTotalTickets = 0; var ticketStartTime = 0; var ticketStopTime = 0; var ticketTimeAdded = 0; var ticketMinsRemain = 0; var ticketSecsRemain = 0; var ticketPriceFC = cb.settings.ticketShowPriceFC; var ticketModAdd = (cb.settings.ticketModAdd === "Yes"); var ticketShowGoal = parseInt(cb.settings.ticketShowGoal); var ticketShowOtToggle = 0; var ticketPrice = cb.settings.ticketShowPrice; var newTicketMode = ''; var yellow = "#f4d599"; // Used for clock countdown var red = "#f4c1bc"; // Used for last 2 minutes of clock countdown var ticketHolderBgColor = '#e8fbe8' // Light green highlighting for ticket show buyers var dashLine80 = new Array(80).join("-"); var dashLine60 = new Array(60).join("-"); var dashLine70 = new Array(70).join("-"); var dashLine90 = new Array(90).join("-"); var backgroundImage = ''; var textColor = 'black'; var leftjust1 = 20; var leftjust2 = 20; var leftjust3 = 20; var topjust1 = 5; var topjust2 = 28; var topjust3 = 51; // Arrays */ var fanClubList = []; var ticketShowViewerList = []; var moderatorList = {name: [], type: []}; var tipCountArray = {name: [], amount: []}; var otChangesArray = {name: [], type: []}; var ticketShowExtraTickets = {name: [], count: []}; var drawpanel = {panel: {}}; } { // *********************************** Functions ************************************** { // Generic functions to set the color or separator characters function checkTextColor(color) { switch (color) { case "White/No color": return "#FFFFFF"; case "Black": return "#000000"; case "Dark Blue": return "#0629AC"; case "Dark Pink": return "#FF6680"; case "Dark Green": return "#006600"; case "Dark Red": return "#cc0000"; case "Dark Purple": return "#3d003d"; case "Dark Grey": return "#737373"; case "Dark Orange": return "#e77400"; case "Dark Aqua": return "#006767"; case "Dark Gold": return "#998100"; case "Dark Teal": return "#003f1f"; case "Dark Brown": return "#582c00"; case "Dark Bronze": return "#a56728"; case "Dark Periwinkle": return "#155bd7"; case "Dark Fuschia": return "#d6155c"; case "Dark Lime": return "#6b790c"; case "Dark Plum": return "#7f13bf"; default: if (/^#[0-9A-F]{6}$/i.test(color)) { return color; } else if (/^[0-9A-F]{6}$/i.test(color)) { return ('#' + color); } else { return ("default"); } } } function checkBgColor(color) { switch (color) { case "White/No color": return "#FFFFFF"; case "Light Aqua": return "#adeaea"; case "Light Pink": return "#FFE6EA"; case "Light Green": return "#94e594"; case "Light Red": return "#ff9a9a"; case "Light Purple": return "#f2cdff"; case "Light Orange": return "#ffd9b3"; case "Light Grey": return "#e6e6e6"; case "Light Blue": return "#d1eaee"; case "Light Yellow": return "#ffff94" case "Cream": return "#f9f6ed" case "Light Bronze": return "#ebccad"; case "Light Periwinkle": return "#d7e4fb"; case "Light Teal": return "#d7fbee"; case "Light Fuschia": return "#fbd7e4"; case "Light Lime": return "#ecf6a7"; case "Light Plum": return "#e3c0f9"; default: if (/^#[0-9A-F]{6}$/i.test(color)) { return color; } else if (/^[0-9A-F]{6}$/i.test(color)) { return ('#' + color); } else { return ("default"); } } } //********** Build Moderator Array ************** function populateModeratorArray(user,type) { if (!cbjs.arrayContains(moderatorList,user,type)) { moderatorList.name.push(user); moderatorList.type.push(type); } else { return; } } function populateFanClubArray(user) { if (!cbjs.arrayContains(fanClubList,user)) { fanClubList.push(user); } else { return; } } //********** Tipper List ************** function findTipper(user) { for (var i = 0; i < tipCountArray.name.length; i++) { if(tipCountArray.name[i] == user) { break; } } return i; } // *********************************** Length of show ************************************** function clockTimeCal() { timeNow = new Date(); return timeNow - ultraAppStartTime.getTime(); } function timeOnline() { var timeElapsed = clockTimeCal(); var clockMS = timeElapsed % 1000; var clockSeconds = ((timeElapsed - clockMS) % 60000); var clockMinutes = ((timeElapsed - clockSeconds - clockMS) % 3600000); var clockHours = (timeElapsed - clockMinutes - clockSeconds - clockMS); clockSeconds = clockSeconds / 1000; clockMinutes = clockMinutes / 60000; clockHours = clockHours / 3600000; if (clockHours > 0) { return clockHours + " hour" + (clockHours > 1 ? "s" : "") + " and " + clockMinutes + " minute" + (clockMinutes > 1 ? "s" : ""); } else if (clockMinutes > 0 && clockSeconds === 0) { return clockMinutes + " minute" + (clockMinutes > 1 ? "s" : ""); } else if (clockMinutes > 0) { return clockMinutes + " minute" + (clockMinutes > 1 ? "s" : "") + " and " + clockSeconds + " second" + (clockSeconds > 1 ? "s" : ""); } else { return clockSeconds + " second" + (clockSeconds > 1 ? "s" : ""); } } //********** Record Tip and Track Goal Progress ************** function recordTip(tipAmount,tipBy,isFan) { currentAppTotalTicket += tipAmount; currentSessionTotal += tipAmount; if (!ticketShowEnded && !ticketSalesEnded && !cb.limitCam_userHasAccess(tipBy)) { if (isFan && tipAmount >= ticketPriceFC) { addRmvTicket('addtip', tipBy, 'fan', tipAmount); } else if (tipAmount >= ticketPrice) { addRmvTicket('addtip', tipBy, 'common', tipAmount); } } else if (!ticketShowEnded && !ticketSalesEnded && cb.limitCam_userHasAccess(tipBy) && cb.settings.ticketShowAllowGift === 'Yes') { if (tipAmount >= ticketPrice) { addRmvTicket('addextra', tipBy, 'common', tipAmount); } } ticketShowGoalProgress(tipAmount); cb.drawPanel(); } function getTopTipper() { var swapped, temp1, temp2; do { swapped = false; for (var i = 0; i < tipCountArray.amount.length ; i++) { if (tipCountArray.amount[i] < tipCountArray.amount[i + 1]) { temp1 = tipCountArray.amount[i]; temp2 = tipCountArray.name[i]; tipCountArray.amount[i] = tipCountArray.amount[i + 1]; tipCountArray.amount[i + 1] = temp1; tipCountArray.name[i] = tipCountArray.name[i + 1]; tipCountArray.name[i + 1] = temp2; swapped = true; } } } while (swapped); return tipCountArray.name[0]; } function changeRoomSubject() { if (showStage == 'ticketsales') { newsubject = 'ULTRA APP TICKET SHOW SALES [' + ticketPrice + ' tokens]: ' + ticketSubjectText; } else if (showStage == 'ticketshow') { newsubject = 'ULTRA APP TICKET SHOW -- IN PROGRESS [' + ticketPrice + ' tokens]: ' + ticketSubjectText; } else if (showStage == 'showwarn') { newsubject = 'ULTRA APP TICKET SHOW -- ENDING SOON [' + ticketPrice + ' tokens]: ' + ticketSubjectText; } else if (showStage == 'showfinale') { newsubject = 'ULTRA APP TICKET SHOW -- SALES ENDED: ' + ticketSubjectText; } else if (showStage == 'aftershow') { newsubject = 'ULTRA APP TICKET SHOW HAS ENDED: ' + ticketSubjectText; } else { newsubject = 'ULTRA APP TICKET SHOW'; } cb.changeRoomSubject(newsubject); } //********** Goal Bar ************** function goalBar(current,total) { if (current > 0 && total > 0) { percent = Math.round(100*(current/total)); } else { percent = 0; } bar = ''; full = '\u25C6'; half = '\u25C8'; empty = '\u25C7'; a = (percent - (percent % 10)) / 10; b = (percent % 10) > 0 ? 1 : 0; c = 10 - (a + b); bar += charRepeat(full, a); (b === 1 ? bar += half : bar += ""); bar += charRepeat(empty, c) return bar; } function charRepeat(d, e) { var string = ""; for (var index = 1; index <= e; index++) { string += d } return string; } // *********************************** Ultra App Ticket Show Functions ************************************** function setTicketShowToggle(option, sendto) { if(option == 'on') { initTicketShow(sendto); cb.sendNotice(dashLine90 + '\n* ' + sendto + ' has started ticket sales for the Ultra App Ticket Show.\n* Tickets are ' + ticketPrice + ' tokens.\n' + dashLine90, '', ticketBgColor, ticketTxtColor, 'bold'); cb.sendNotice('***Warning Regarding the Ticket Show***: Do not deactivate or restart the Ultra App once ticket sales have started without saving the ticket show list or you will lose the list of ticket holders.\n* If you are using Dorothy\'s Ultra Fembot alongside this app, it can save a backup ticket list for you if configured to do so.\n* If it is necessary to restart, please save the ticket list first (use /tickets to view and then copy) and then add those users back to the show once restarted (/addtickets).',cb.room_slug,yellow); if (cb.settings.ticketShowAllowGift === 'Yes') { cb.sendNotice(dashLine90 + '\n* The Broadcaster has enabled the the gifting of tickets. \n* You can buy extra tickets and gift them to others using the command "/giftticket user" \n* You can also give away your own ticket using the command "/givemyticketto user".\n' + dashLine90, '', ticketBgColor, ticketTxtColor, 'bold'); } } else if(option == 'off') { if (cb.limitCam_isRunning()) { cb.sendNotice('The show is still hidden, please end the hidden show and return to a public broadcast using the command "/stopshow" before disabling the Ticket Show or changing the current app.',sendto,yellow); } else { if (ticketMinsRemain > 0 || ticketSecsRemain > 0) { stopTicketTimer(); } ticketSkipNotice = true; cb.sendNotice('You have disabled the Ultra App Ticket Show feature. The ticket list and outstanding ticket list are still intact.', sendto, yellow); cb.sendNotice(dashLine70 + '\n* ' + sendto + ' has ended the UltraApp Ticket Show Feature.\n' + dashLine70, '', ticketBgColor, ticketTxtColor, 'bold'); } } } function initTicketShow(sendto) { whichApp = 'ticket'; ticketShowColors(); showStage = 'ticketsales'; changeRoomSubject(); ticketSkipMin = false; ticketSkipSec = false; setTicketMode('init',sendto); ticketSkipNotice = false; ticketShowEnded = false; ticketSalesEnded = false; countTicketsSold = 0; loadFreeTickets(); if (cb.settings.ticketShowEnableOT == 'Yes') { setTicketShowOtToggle('on',sendto) } cb.drawPanel(); } function ticketShowColors() { ticketNoticesTxtColor = checkTextColor("Dark Red"); ticketNoticesBgColor = checkBgColor("Cream"); ticketTxtColorFan = checkTextColor("Black"); ticketBgColorFan = checkBgColor("Light Green"); ticketTxtColorVIP = checkTextColor("Black"); ticketBgColorVIP = checkBgColor("Light Purple"); ticketTxtColorMod = checkTextColor("Black"); ticketBgColorMod = checkBgColor("Light Red"); if (cb.settings.ticketShowTextColor == 'Custom') { ticketTxtColor = checkTextColor(cb.settings.ticketShowCustomTextColor); if (ticketTxtColor == 'default') { cb.sendNotice('Ticket Show - Error while setting the text color. It has to be in a HEX format. Using default value.', cb.room_slug, yellow, '', 'bold'); ticketTxtColor = '#FFFFFF'; } } else { ticketTxtColor = checkTextColor(cb.settings.ticketShowTextColor); } if (cb.settings.ticketShowBgColor == 'Custom') { ticketBgColor = checkBgColor(cb.settings.ticketShowCustomBgColor); if (ticketBgColor == 'default') { cb.sendNotice('Ticket Show - Error while setting the background color. It has to be in a HEX format. Using default value.', cb.room_slug, yellow, '', 'bold'); ticketBgColor = '#FFFFFF'; } } else { ticketBgColor = checkBgColor(cb.settings.ticketShowBgColor); } } function setTicketShowOtToggle(option, sendto) { if(option == 'on') { if(ticketShowOtToggle == 1) { cb.sendNotice('The Outstanding Ticket feature is already enabled.',sendto,yellow); } else { ticketShowOtToggle = 1; cb.sendNotice(dashLine90 + '\n* ' + sendto + ' has started the Outstanding Ticket (OT) feature.\n* You can save your ticket if you have to leave before the show starts.\n* Use the command "/saveticket" to save it.\n* (By saving your ticket you will be REMOVED from the current show\'s list).\n* You can view the OT List with the command "/otlist".\n* You can redeem an outstanding ticket with the command "/useticket".\n' + dashLine90, '', ticketBgColor, ticketTxtColor, 'bold'); cb.sendNotice('***Notice Regarding Outstanding Tickets***: The Outstanding tickets added and removed during the show must be made permanent by updating the list on the App Launch page.\n* The list can be viewed using the command "/otlist".\n* The changes for the current session can be seen using "/otchanges".\n* It is recommended to save the list externally and update the OT list before the next show.\n* Changes made during the show are not saved beyond the current session.',cb.room_slug,yellow); } } else if(option == 'off') { if(ticketShowOtToggle == 0) { cb.sendNotice('The Outstanding Ticket feature is already disabled.',sendto,yellow); } else { ticketShowOtToggle = 0; cb.sendNotice('You have disabled the Outstanding Ticket (OT) feature.\n* The outstanding ticket list is still intact, but no more tickets will be sold.\n* The list can be viewed using the command "/otlist".\n* The changes for the current session can be seen using "/otchanges" \n* Be sure to update these entries into the OT List on the App Launch Page, they cannot be saved automatically.',sendto,yellow); } } } function setTicketPrice(amount,sendto,announce) { ticketPrice = parseInt(amount); if (announce === 'yes') { ticketPriceChangeNotice(ticketPrice); } } function ticketPriceChangeNotice(price) { cb.sendNotice(':ticket_red_small \u2724 \u2749 \u2724 \u2749 \u2724 \u2749 :ticket_red_small \u2724 \u2749 \u2724 \u2749 \u2724 \u2749 :ticket_red_small \n' + '\u21D2 . . . . Ticket Show Price Updated!!!. . . . . \u21D0 \n' + '\u21D2 . . . . Tickets are now ' + ticketPrice + ' tokens!!! . . . . . \u21D0 \n' + ':ticket_red_small \u2724 \u2749 \u2724 \u2749 \u2724 \u2749 :ticket_red_small \u2724 \u2749 \u2724 \u2749 \u2724 \u2749 :ticket_red_small' , "", ticketNoticesBgColor, ticketNoticesTxtColor, "bold"); } function loadFreeTickets() { if (cb.settings.ticketShowFreeMods === 'Yes') { for (let i = 0; i < moderatorList.name.length; i++) { if (!cb.limitCam_userHasAccess(moderatorList.name[i]) && moderatorList.type[i] != 'bc') { addRmvTicket('add',moderatorList.name[i],'mod'); } } } if (cb.settings.ticketShowFreeFC === 'Yes') { for (let i = 0; i < fanClubList.length; i++) { if (!cb.limitCam_userHasAccess(fanClubList[i])) { addRmvTicket('add',fanClubList[i],'fan'); } } } } function setTicketMode(startmode,automode,sendto) { if (startmode === 'init') { if (cb.settings.ticketShowStartMode === 'Start Show Anytime') { newTicketMode = 'manual'; } else if (cb.settings.ticketShowStartMode === 'Start Show after Timer') { newTicketMode = 'timer'; } else if (cb.settings.ticketShowStartMode === 'Start Show after Ticket Goal') { newTicketMode = 'ticketgoal'; } else if (cb.settings.ticketShowStartMode === 'Start Show after Token Goal') { newTicketMode = 'tokengoal'; } if (cb.settings.ticketShowStartAuto === 'Start from Command') { newTicketAuto = 'bc'; } else if (cb.settings.ticketShowStartAuto === 'Automated Start') { newTicketAuto = 'auto'; } } else { if(startmode != '' && startmode != null) { newTicketMode = startmode; } else { newTicketMode = ticketStartMode; } if(automode != '' && automode != null) { newTicketAuto = automode; } else { newTicketAuto = ticketModeAuto; } } if (ticketStartMode == 'timer' && newTicketMode != 'timer') { if (ticketMinsRemain > 0 || ticketSecsRemain > 0) { stopTicketTimer(sendto); } } if (newTicketMode == 'manual') { ticketStartMode = 'manual'; ticketModeAuto = 'bc'; cb.sendNotice('Ticket Show start mode is set to "Manual", the show will be started by the broadcaster or moderator.','', ticketBgColor, ticketTxtColor, 'bold'); } else if (newTicketMode == 'timer') { if (cb.settings.ticketShowStartTimer >= 1) { ticketStartMode = 'timer'; ticketTimeAmt = cb.settings.ticketShowStartTimer; if (newTicketAuto == 'auto') { ticketAutoTimer(ticketTimeAmt); ticketModeAuto = 'auto'; cb.sendNotice('Ticket Show start mode is set to "Automatic timer" with a duration of ' + ticketTimeAmt + ' minutes. The Ticket Show will start automatically when the timer runs out.','', ticketBgColor, ticketTxtColor, 'bold'); } else { ticketModeAuto = 'bc'; cb.sendNotice('Ticket Show start mode is set to "Broadcaster managed timer". The broadcaster will set a timer and start the show when the timer runs out.','', ticketBgColor, ticketTxtColor, 'bold'); } } else { ticketStartMode = 'manual'; ticketModeAuto = 'bc'; ticketIncAmt = cb.settings.ticketIncreasePerIncrement; cb.sendNotice('Ticket Show start is set to manual mode. Mode was requested for automatic timer, but the timer was not set on the start page. You can restart the bot and update the missing time, or continue and start the show manually at the end of a timer or at a time of your choosing.', sendto, yellow); } } else if (newTicketMode == 'tokengoal') { if (cb.settings.ticketShowGoal >= 1) { ticketStartMode = 'tokengoal'; ticketShowGoalTokens = cb.settings.ticketShowGoal; if (newTicketAuto == 'auto') { ticketModeAuto = 'auto'; cb.sendNotice('Ticket Show start mode is set to "Automatic at token goal." There will be a short 2 minute countdown started once the goal is met for total tip amount (' + ticketShowGoalTokens + ' tokens), and then the show will start automatically.','', ticketBgColor, ticketTxtColor, 'bold'); } else { ticketModeAuto = 'bc'; cb.sendNotice('Ticket Show start mode is set to "Broadcaster managed token goal". The broadcaster will start the show once the goal is met for the total tips (' + ticketShowGoalTokens + ' tokens).','', ticketBgColor, ticketTxtColor, 'bold'); } } else { ticketStartMode = 'manual'; ticketModeAuto = 'bc'; ticketIncAmt = cb.settings.ticketIncreasePerIncrement; cb.sendNotice('Ticket Show start is set to manual mode. Mode was requested for automatic goal start, but the goal was not set on the start page. You can restart the bot and update the missing goal, update the goal using the command "/chgticketgoal [amt]" and then change the mode using "/chgticketmode goal", or continue and start the show manually at the end of a timer or at a time of your choosing.', sendto, yellow); } } else if (newTicketMode == 'ticketgoal') { if (cb.settings.ticketShowGoal >= 1) { ticketStartMode = 'ticketgoal'; ticketShowGoalTickets = cb.settings.ticketShowGoal; if (newTicketAuto == 'auto') { ticketModeAuto = 'auto'; cb.sendNotice('Ticket Show start mode is set to "Automatic at ticket goal." There will be a short 2 minute countdown started once the goal is met for tickets sold (' + ticketShowGoalTickets + ' tickets), and then the show will start automatically.','', ticketBgColor, ticketTxtColor, 'bold'); } else { ticketModeAuto = 'bc'; cb.sendNotice('Ticket Show start mode is set to "Broadcaster managed ticket goal". The broadcaster will start the show once the goal is met for tickets sold (' + ticketShowGoalTickets + ' tickets).','', ticketBgColor, ticketTxtColor, 'bold'); } } else { ticketStartMode = 'manual'; ticketModeAuto = 'bc'; ticketIncAmt = cb.settings.ticketIncreasePerIncrement; cb.sendNotice('Ticket Show start is set to manual mode. Mode was requested for automatic goal start, but the goal was not set on the start page. You can restart the bot and update the missing goal, update the goal using the command "/chgticketgoal [amt]" and then change the mode using "/chgticketmode goal", or continue and start the show manually at the end of a timer or at a time of your choosing.', sendto, yellow); } } cb.drawPanel(); } function setTicketAuto(automode) { if (automode == 'bc') { ticketModeAuto = 'bc'; } else if (automode == 'auto') { ticketModeAuto = 'auto'; } } function startTicketShowTimer(numtimer) { ticketMinsRemain = numtimer; ticketStartMode = 'timer'; ticketAutoTimer(ticketMinsRemain); cb.drawPanel(); } function ticketAutoTimer(addtime) { if (ticketModeAuto == 'auto') { cb.sendNotice('An automatic timer was started, ticket show price will be ' + ticketPrice + ' tokens.', "", ticketBgColor, ticketTxtColor, "bold"); } else if (ticketModeAuto == 'bc') { cb.sendNotice('A timer was started to provide an countdown to approximate showtime. \n The broadcaster will start the show after the timer runs out.', "", ticketBgColor, ticketTxtColor, "bold"); } ticketMinsRemain = addtime; ticketSecsRemain = 0; ticketStartTime = new Date(); ticketStopTime = new Date(ticketStartTime.getTime() + ticketMinsRemain * 60000); ticketTimerMin(); } function ticketTimerMin() { ticketSeconds = ticketCheckMin(); if (ticketSkipMin === false && ticketStartMode == 'timer' && whichApp == 'ticket' && (ticketSeconds >= 55 || ticketSeconds == 0)) { switch (ticketMinsRemain) { case 120: case 90: case 60: case 45: case 30: case 20: case 15: case 10: case 9: case 8: case 7: case 6: case 5: case 4: case 3: case 2: cb.drawPanel(); cb.sendNotice('\u23f1 \u23f1 \u23f1 There are ' + ticketMinsRemain + ' minutes left on the timer to buy a ticket for ' + ticketPrice + ' tokens before the show starts! \u23f1 \u23f1 \u23f1', "", yellow, "", "bold"); } ticketMinsRemain--; if (ticketMinsRemain > 0) { cb.setTimeout(ticketTimerMin, 60000); } else { ticketSecsRemain = 60; cb.drawPanel(); cb.sendNotice('\u23f1 \u23f1 \u23f1 There is 1 minute left on the timer to buy a ticket for ' + ticketPrice + ' tokens before the show starts!! \u23f1 \u23f1 \u23f1', "", red, "", "bold"); ticketTimerSec(); } } else { if (ticketSkipMin === true) { ticketSkipMin = false; } } } function ticketCheckMin() { var ticketTimeLeft = ticketTimeCal(); var ticketMS = ticketTimeLeft % 1000; var ticketSeconds = ((ticketTimeLeft - ticketMS) % 60000); ticketSeconds = ticketSeconds / 1000; return ticketSeconds; } function ticketTimerSec() { if (!ticketSkipSec && ticketStartMode == 'timer' && whichApp == 'ticket') { if (ticketMinsRemain > 0) { cb.setTimeout(ticketTimerMin, ticketSecsRemain*1000); } else { ticketSecsRemain--; if (ticketSecsRemain < 1) { cb.drawPanel(); if (ticketStartMode = 'timer' && ticketModeAuto == 'auto') { cb.sendNotice("\u23f0 \u23f0 \u23f0 Time is up! Ticket Show is starting! \u23f0 \u23f0 \u23f0", "", ticketNoticesBgColor, ticketNoticesTxtColor, "bold"); startTicketShow(cb.room_slug); } else { cb.sendNotice("\u23f0 \u23f0 \u23f0 Time is up! Broadcaster will be starting the show! \u23f0 \u23f0 \u23f0", "", ticketNoticesBgColor, ticketNoticesTxtColor, "bold"); } } else { switch (ticketSecsRemain) { case 30: case 10: case 5: case 4: case 3: case 2: case 1: cb.drawPanel(); cb.sendNotice('\u23f1 \u23f1 \u23f1 There are ' + ticketSecsRemain + ' second' + (ticketSecsRemain > 1 ? "s" : "") + ' left! \u23f1 \u23f1 \u23f1', "", red, "", "bold"); } } if (ticketSecsRemain > 0) { cb.setTimeout(ticketTimerSec, 1000); } } } else { ticketSkipSec = false; } } function ticketAddTime(tickettimetoadd, u) { ticketStopTime = new Date(ticketStopTime.getTime() + tickettimetoadd * 60000); cb.sendNotice(u + " has added " + tickettimetoadd + " minute" + (tickettimetoadd === 1 || tickettimetoadd === -1 ? "" : "s") + " to the timer.",cb.room_slug,"","", "bold"); cb.sendNotice(tickettimetoadd + " minute" + (tickettimetoadd === 1 || tickettimetoadd === -1 ? "" : "s") + " have been added to the timer. Now " + ticketTimeLeft(),"",yellow,"", "bold"); ticketMinsRemain = ticketMinsRemain + tickettimetoadd; if (ticketMinsRemain < 1) { ticketSkipMin = true; ticketTimeLeft = ticketTimeCal(); ticketMS = ticketTimeLeft % 1000; ticketSeconds = ((ticketTimeLeft - ticketMS) % 60000) / 1000; ticketSecsRemain = ticketSeconds; ticketTimerSec(); } cb.drawPanel(); return; } function ticketTimeCal() { ticketStartTime = new Date(); return ticketStopTime - ticketStartTime.getTime(); } function stopTicketTimer(mod) { ticketStopTime = new Date(); if (ticketMinsRemain > 0 || ticketSecsRemain > 0) { ticketSkipMin = true; ticketSkipSec = true; } ticketMinsRemain = 0; ticketSecsRemain = 0; if(mod != null && mod != '') { cb.sendNotice(mod + ' has stopped the ticket show timer.',"",yellow,"", "bold"); } cb.drawPanel(); } function ticketTimeLeft(user) { var ticketTimeLeft = ticketTimeCal(); var ticketMS = ticketTimeLeft % 1000; var ticketSeconds = ((ticketTimeLeft - ticketMS) % 60000); var ticketMinutes = ((ticketTimeLeft - ticketSeconds - ticketMS) % 3600000); var ticketHours = (ticketTimeLeft - ticketMinutes - ticketSeconds - ticketMS); ticketSeconds = ticketSeconds / 1000; ticketMinutes = ticketMinutes / 60000; ticketHours = ticketHours / 3600000; if (ticketHours > 0) { return ticketHours + " hour" + (ticketHours > 1 ? "s" : "") + " and " + ticketMinutes + " minute" + (ticketMinutes > 1 ? "s" : "") + " remaining on the ticket show timer."; } else if (ticketMinutes > 0 && ticketSeconds === 0) { return ticketMinutes + " minute" + (ticketMinutes > 1 ? "s" : "") + " remaining on the ticket show timer."; } else if (ticketMinutes > 0) { return ticketMinutes + " minute" + (ticketMinutes > 1 ? "s" : "") + " and " + ticketSeconds + " second" + (ticketSeconds > 1 ? "s" : "") + " remaining on the ticket show timer."; } else { return ticketSeconds + " second" + (ticketSeconds > 1 ? "s" : "") + " remaining on the ticket show timer."; } } function ticketTimeLeftPanel() { var ticketTimeLeft = ticketTimeCal(); var ticketMS = ticketTimeLeft % 1000; var ticketSeconds = ((ticketTimeLeft - ticketMS) % 60000); var ticketMinutes = ((ticketTimeLeft - ticketSeconds - ticketMS) % 3600000); var ticketHours = (ticketTimeLeft - ticketMinutes - ticketSeconds - ticketMS); ticketSeconds = ticketSeconds / 1000; ticketMinutes = ticketMinutes / 60000; if (ticketMinutes > 0) { return 'Less than ' + (ticketMinutes+1) + ' min rem'; } else { return 'Less than ' + (ticketSeconds) + ' sec rem';; } } function addRmvTicket(mode,user,usertype,tipamount) { switch(mode) { case 'add': { cb.limitCam_addUsers([user]); if (!cbjs.arrayContains(ticketShowViewerList,user)) { ticketShowViewerList.push(user); } if (usertype === 'fan') { cb.sendNotice('Fan Club member ' + user + ' has been added to the ticket show list.', "", ticketBgColorFan, ticketTxtColorFan, "bold"); } else if (usertype === 'vip') { cb.sendNotice('VIP List member ' + user + ' has been added to the ticket show list.', "", ticketBgColorVIP, ticketTxtColorVIP, "bold"); } else if (usertype === 'mod') { cb.sendNotice('Moderator ' + user + ' has been added to the ticket show list.', "", ticketBgColorMod, ticketTxtColorMod, "bold"); } else { cb.sendNotice(user + ' has been added to the ticket show list.', "", ticketBgColor, ticketTxtColor, "bold"); } countTicketsSold ++; break; } case 'rmv': { cb.limitCam_removeUsers([user]); if (cbjs.arrayContains(ticketShowViewerList,user)) { ticketShowViewerList.pop(user); } cb.sendNotice(user + ' has been removed from the ticket show list.', "", ticketBgColor, ticketTxtColor, "bold"); countTicketsSold --; break; } case 'addtip': { cb.limitCam_addUsers([user]); if (!cbjs.arrayContains(ticketShowViewerList,user)) { ticketShowViewerList.push(user); } cb.sendNotice('Welcome ' + user + ', you have been added to the ticket show list.', "", ticketBgColor, ticketTxtColor, "bold"); countTicketsSold ++; if (tipamount >= (2*ticketPrice)) { addRmvTicket('addextra', user, 'common', (tipamount - ticketPrice)); } break; } case 'addextra': { var numtickets = Math.floor(parseInt(tipamount / ticketPrice)); if (numtickets > 0) { if (!cbjs.arrayContains(ticketShowExtraTickets.name,user)) { ticketShowExtraTickets.name.push(user); ticketShowExtraTickets.count.push(numtickets); } else { index = ticketShowExtraTickets.name.indexOf(user); ticketShowExtraTickets.count[index] = ticketShowExtraTickets.count[index] + numtickets; } cb.sendNotice(user + ', you have purchased ' + numtickets + ' extra tickets to the show. You can gift these to other users with the command "/giftticket user". Each time you use the command uses up one of your extra tickets. Please make sure to spell the user name right, gifted tickets cannot be recovered if they are gifted incorrectly.', user, ticketBgColor, ticketTxtColor, "bold"); } break; } } } function giftTicket(fromuser,touser) { cb.limitCam_addUsers([touser]); if (!cbjs.arrayContains(ticketShowViewerList,touser)) { ticketShowViewerList.push(touser); } cb.sendNotice('Welcome ' + touser + ', ' + fromuser + ' has gifted you a ticket to the show!', '', ticketBgColor, ticketTxtColor, 'bold'); countTicketsSold ++; cb.drawPanel(); } function giveAwayTicket(fromuser,touser) { cb.limitCam_addUsers([touser]); cb.limitCam_removeUsers([fromuser]); if (!cbjs.arrayContains(ticketShowViewerList,touser)) { ticketShowViewerList.push(touser); } if (cbjs.arrayContains(ticketShowViewerList,fromuser)) { ticketShowViewerList.pop(fromuser); } cb.sendNotice('Welcome ' + touser + ', ' + fromuser + ' has gifted you a ticket to the show!', '', ticketBgColor, ticketTxtColor, 'bold'); cb.drawPanel(); } function addRmvOutstandingTicket(mode,user) { switch(mode) { case "add": { outstandingTicketArray.push(user); populateOtChangesArray(user,'add'); break; } case "rmv": { cbjs.arrayRemove(outstandingTicketArray,user); populateOtChangesArray(user,'rmv'); break; } } } function populateOtChangesArray(user,type) { if (cbjs.arrayContains(otChangesArray.name,user)) { index = otChangesArray.name.indexOf(user); if (otChangesArray.type[index] != type) { otChangesArray.name.push(user); otChangesArray.type.push(type); } else { return; } } else { otChangesArray.name.push(user); otChangesArray.type.push(type); } } function ticketShowGoalProgress(tipAmount) { ticketShowTotalTips = ticketShowTotalTips + tipAmount; ticketShowTotalTickets++; if (ticketStartMode === 'tokengoal' && ticketShowTotalTips >= ticketShowGoalTokens) { cb.sendNotice(dashLine80 + '\n :siren1 \u25C8 \u25C8 \u25C8 The ticket show Tip goal has been met!! \u25C8 \u25C8 \u25C8 :siren1 \n \u25C8 \u25C8 \u25C8 Starting a 2 minute timer for automatic start of show! \u25C8 \u25C8 \u25C8 \n' + dashLine80, '', ticketNoticesBgColor, ticketNoticesTxtColor, 'bold'); ticketStartMode = 'timer'; ticketAutoTimer(2); } else if (ticketStartMode === 'ticketgoal' && ticketShowTotalTickets >= ticketShowGoalTickets) { cb.sendNotice(dashLine80 + '\n :siren1 \u25C8 \u25C8 The ticket show Ticket goal has been met!! \u25C8 \u25C8 :siren1 \n \u25C8 \u25C8 \u25C8 Starting a 2 minute timer for automatic start of show! \u25C8 \u25C8 \u25C8 \n' + dashLine80, '', ticketNoticesBgColor, ticketNoticesTxtColor, 'bold'); ticketStartMode = 'timer'; ticketAutoTimer(2); } } function startTicketShow(startedby) { var nowTime = new Date(); cb.sendNotice(dashLine60 + '\n :siren1 :siren1 :siren1 ' + startedby + ' has started the show! :siren1 :siren1 :siren1 \n' + dashLine60,'',ticketBgColor, ticketNoticesTxtColor, 'bold'); cb.sendNotice('*** REMINDER: Please do not deactivate the Hidden Ticket Show feature until after you end your show with the "/stopshow" command.', cb.room_slug, ticketBgColor, ticketTxtColor, 'bold'); cb.limitCam_start('Ultra App Ticket Show\n\nHidden Cam show in progress. Tip ' + ticketPrice + ' tokens to unlock the screen!'); showStage = 'ticketshow'; changeRoomSubject(); if (ticketMinsRemain > 0 || ticketSecsRemain > 0) { stopTicketTimer(); } hiddenTime = Date.now(); cb.drawPanel(); } function restartTicketShow(startedby) { var nowTime = new Date(); cb.sendNotice(dashLine80 + '\n :siren1 \u25C8 \u25C8 \u25C8 ' + startedby + ' has restarted the ticket show! \u25C8 \u25C8 \u25C8 :siren1 \n \u25C8 \u25C8 \u25C8 All current ticket holders still have access. \u25C8 \u25C8 \u25C8 \n \u25C8 \u25C8 \u25C8 Ticket sales are open, price is ' + ticketPrice + ' tokens. \u25C8 \u25C8 \u25C8 \n' + dashLine80,'',ticketBgColor, ticketNoticesTxtColor, 'bold'); cb.limitCam_start('Ultra App Ticket Show\n\nHidden Cam show in progress. Tip ' + ticketPrice + ' tokens to unlock the screen!'); showstage = 'ticketshow'; changeRoomSubject(); ticketShowEnded = false; ticketSalesEnded = false; if (ticketMinsRemain > 0 || ticketSecsRemain > 0) { stopTicketTimer(); } hiddenTime = Date.now(); cb.drawPanel(); } function warnShowEnding(by) { showStage = 'showwarn'; changeRoomSubject(); if (cb.settings.ticketShowReducePriceWarn > 0) { ticketPrice = ticketPrice - cb.settings.ticketShowReducePriceWarn; changeRoomSubject(); cb.sendNotice(dashLine90 + '\n :siren1 \u25C8 \u25C8 \u25C8 ' + by + ' has indicated the show is nearly finished. \u25C8 \u25C8 \u25C8 :siren1 \n \u25C8 \u25C8 It is not recommended to buy a ticket, but sales are still open. \u25C8 \u25C8 \n \u25B7 \u25B7 \u25B7 \u25B7 \u25B7 The Ticket Price has been reduced to ' + ticketPrice + ' tokens! \u25C1 \u25C1 \u25C1 \u25C1 \u25C1 \n' + dashLine90,'',ticketBgColor,ticketNoticesTxtColor,'bold'); } else { cb.sendNotice(dashLine90 + '\n :siren1 \u25C8 \u25C8 \u25C8 ' + by + ' has indicated the show is nearly finished. \u25C8 \u25C8 \u25C8 :siren1 \n \u25C8 \u25C8 It is not recommended to buy a ticket, but sales are still open. \u25C8 \u25C8 \n' + dashLine90,'',ticketBgColor,ticketNoticesTxtColor,'bold'); } cb.drawPanel(); } function stopTicketSales(stoppedby) { cb.sendNotice(dashLine70 + '\n :siren1 :siren1 :siren1 \u25B7 \u25B7 ' + stoppedby + ' has ended ticket sales. \u25C1 \u25C1 :siren1 :siren1 :siren1 \n' + dashLine70,'',ticketBgColor,ticketNoticesTxtColor,'bold'); showStage = 'showfinale'; changeRoomSubject(); ticketSkipNotice = true; ticketSalesEnded = true; cb.drawPanel(); } function stopTicketShow(stoppedby) { cb.sendNotice(dashLine60 + '\n :siren1 \u25C8 \u25C8 \u25C8 ' + stoppedby + ' has ended the show \u25C8 \u25C8 \u25C8 :siren1 \n \u25C8 \u25C8 \u25C8 \u25C8 Ticket Show length ' + ((Date.now() - hiddenTime)/60000).toFixed(2) + ' minutes. \u25C8 \u25C8 \u25C8 \u25C8 \n' + dashLine60,'',ticketBgColor,ticketNoticesTxtColor,'bold'); cb.limitCam_stop(); cb.sendNotice(dashLine70 + '\n :siren1 :siren1 :siren1 The broadcast is returning to Public Chat. :siren1 :siren1 :siren1 \n' + dashLine70, '',ticketBgColor,ticketNoticesTxtColor,'bold'); hiddenTime = 0; ticketSkipNotice = true; ticketShowEnded = true; ticketSalesEnded = true; showStage = 'aftershow'; ticketSubjectText = cb.settings.ticketShowAfterNotice; changeRoomSubject(); cb.drawPanel(); } function useTicket(user) { addRmvOutstandingTicket('rmv',user); cb.limitCam_addUsers([user]); if (!cbjs.arrayContains(ticketShowViewerList,user)) { ticketShowViewerList.push(user); } cb.drawPanel(); } function saveTicket(user) { addRmvOutstandingTicket('add',user); cb.limitCam_removeUsers([user]); if (cbjs.arrayContains(ticketShowViewerList,user)) { ticketShowViewerList.pop(user); } cb.drawPanel(); } function getShowTime(u) { cb.sendNotice(' \u25C8 \u25C8 \u25C8 Hidden Cam show in progress for ' + ((Date.now() - hiddenTime)/60000).toFixed(2) + ' minutes. \u2724 \u2749 \u2724 ', u, ticketBgColor,ticketTxtColor,'bold'); } function sendPublicNotice (message, user, type) { if (message != null) { if (message != '' || message != ' ' || message != '\u00a0') { switch (type) { case 'div': cb.sendNotice(dashLine80 + '\n\u25ba ' + message.capitalize() + '\n' + dashLine80, '', '', ticketNoticesTxtColor, 'bold'); break; case 'divh': cb.sendNotice(dashLine80 + '\n\u25ba ' + message.capitalize() + '\n' + dashLine80, '', ticketBgColor,ticketNoticesTxtColor, 'bold'); break; case 'h': cb.sendNotice("\u25ba " + message.capitalize(), '', ticketBgColor,ticketNoticesTxtColor, 'bold'); break; case '': cb.sendNotice('\u25ba ' + message.capitalize(), '', '', ticketNoticesTxtColor, 'bold'); break; } } else { cb.sendNotice('You can\'t send a blank message. Type a message and try again.', user, yellow); } } else { cb.sendNotice('You can\'t send a blank message. Type a message and try again.', user, yellow); } } function customizePanelText(newcolor,sendto) { if (!newcolor && cb.settings.panelTextColor == 'Custom') { textcolorchk = checkTextColor(cb.settings.panelCustomTextColor); if (textcolorchk == 'default') { cb.sendNotice('Draw Panel Text Color - Error while setting the text color. It has to be in a HEX format.', sendto, yellow, ''); } else { textColor = textcolorchk; cb.drawPanel(); } } else if (newcolor) { textcolorchk = checkTextColor(newcolor); if (textcolorchk == 'default') { cb.sendNotice('Draw Panel Text Color - Error while setting the text color. It has to be in a HEX format.', sendto, yellow, ''); } else { textColor = textcolorchk; cb.drawPanel(); } } else { textColor = checkTextColor(cb.settings.panelTextColor); cb.drawPanel(); } } function customizePanelBackground(newbackground,sendto) { customPanel = false; if (cbjs.arrayContains(backgroundArray.command,newbackground)) { index = backgroundArray.command.indexOf(newbackground); if (cb.room_slug == 'dorothy') { backgroundImage = backgroundArray.devfile[index]; customPanel = true; currentPanel = newbackground; cb.drawPanel(); } else { menuname = backgroundArray.menu[index]; if (menuname.substring(0,12) == 'personalized') { if (newbackground == cb.room_slug) { backgroundImage = backgroundArray.livefile[index]; customPanel = true; currentPanel = newbackground; cb.drawPanel(); } else { cb.sendNotice('You have requested a personalized background, but you are not the room owner for that background, please choose again.', sendto, yellow, ''); } } else { backgroundImage = backgroundArray.livefile[index]; customPanel = true; currentPanel = newbackground; cb.drawPanel(); } } } else { cb.sendNotice('Invalid background name. The valid names are: \n' + cbjs.arrayJoin(backgroundArray.command, ', '), sendto, yellow, ''); } } // *********************************** Help Function ************************************** function helpCommon(option,from) { if(option == null){option = '';} cb.sendNotice('Dorothys Ticket Show App Help Menu', from, yellow); cb.sendNotice('',from,yellow); cb.sendNotice( 'There are no help commands available for general users.' ,from); cb.sendNotice('',from,yellow); } function helpModBC(option,from) { var valid = 0; if(option == null){option = '';} switch(option) { case '': { valid = 1; cb.sendNotice('Dorothys Ultra App Help Menu for Broadcasters and Moderators', from, yellow); cb.sendNotice('Type /uahelp [menu], where [menu] is one of the following choices, for more detailed information.\nEx: "/uahelp goals" to see the submenu for the Progressive Goal Show related commands.', from); cb.sendNotice('',from,yellow); cb.sendNotice( 'all : (/chgapp, /stats, /addtips, /listgoals (/lg))' + '\nticketshow : (see full command list in submenu)' ,from); cb.sendNotice('',from,yellow); break; } case 'all': { valid = 1; cb.sendNotice('Ultra App Command List',from,yellow); cb.sendNotice('',from,yellow); cb.sendNotice( 'Ultra App General Commands - these are used across all app features. The primary command noted below is the /chgapp command, which lets you switch between each of the 5 apps that are built into the UltraApp so far. You can switch at any time, but you if you change in the middle of a goal, you cancel any open goals in that app when you do. Total tipping and time online stats are also kept and can be accessed anytime. ' + '\n/chgpanelbg [imagename]: Change the background of the drawpanel to one of the valid images. Images are updated regularly, so you can see the current list by entering this command with no parameter and the error message will show the current valid choices. Note that you can also see the images by going to the "Source Code" tab for the app and clicking the link for "App Images".' + '\n/chgpaneltext [newcolor]: Change the color of the text in the drawpanel to either a hex code (#0000ff) or the exact text of one of the color choices from the menu ("Dark Green", "Dark Red", etc). You can lookup hex codes for any color on a site such as Color-hexa: https://www.colorhexa.com/' ,from); cb.sendNotice('',from,yellow); break; } case 'ticketshow': { valid = 1; cb.sendNotice('Ultra App Command List',from,yellow); cb.sendNotice('',from,yellow); cb.sendNotice( 'Ultra App Ticket Show Commands - they are used specifically for the Ultra App Ticket show' + '\n/useshow (or /useticketshow) [on/off]: (mods/bc only) Toggle the setting for whether the Ultra App Ticket Show feature is "on" or "off". Overrides the initial setting, and allows you to turn the Ticket Show feature on or off during the show. Note that turning the show off will suspend the display of the notice, and tips will no longer buy a ticket, however, the existing ticket purchases are kept until the Ultra App is restarted.' + '\n/tickets : (mods/bc only) Display the list of users that have bought a ticket. If the parameter of "alpha" is added, the list is displayed alphabetically. Note that viewers can be added back to the show using the /add or /addticket commands and pasting the list that is shown from the /tickets command. ' + '\n/useot [on/off]: (mods/bc only) Toggle the setting for whether the Outstanding Ticket feature of the Ticket Show is "on" or "off". Overrides the initial setting, and allows you to turn the Outstanding Ticket usage feature on or off during the show. .' + '\n/otlist : (all users) Display the list of outstanding ticket holders, can be used by anyone if the Outstanding Ticket feature is enabled.' + '\n/otchanges : (mods/bc only) ** IMPORTANT when using the OT feature ** Displays a list of tickets that have been saved or used during the current session so the permanent list can be updated.' + '\n/saveticket: (all ticket buyers) If the broadcaster has enabled Outstanding Tickets (and is tracking them) - If you have bought a ticket and will not be able to stay for the show, you can save it for a future show. You will no longer be able to see the current show. IMPORTANT: If in the same session, the ticket will be available automatically. However for future shows or if the broadcaster restarts the bot, the broadcaster must add the saved tickets to the outstanding ticket list to be able to use them with /useticket. ' + '\n/useticket: (all users with an outstanding ticket) If the broadcaster has enabled Outstanding Tickets (and is tracking them) - Redeem an outstanding ticket and use it for access to this show. You can use the command /otlist to view the list of outstanding ticket holders if the broadcaster has enabled this feature.' + '\n/addot : (mods, bc if granted privileges) If the outstanding ticket feature is in use, the broadcaster can manually give a user an outstanding ticket. Moderators can also add if they have authority. The addition still must be made permanent by updating the launch page outstanding ticket list.' + '\n/rmvot : (mods/bc only) Remove a user from the outstanding ticket list within the current show. The removal still must be made permanent by updating the launch page outstanding ticket list.' + '\n/addticket or (/add) [user]: (bc only, moderator when granted privileges) Manually add a user to the ticket show list. Can be a specific user or a list of users separated by a comma. Note that /add is the CrazyTicket command but also works with the Ultra App Ticket show.' + '\n/rmvticket (or /del or /delticket) [user]: (mods/bc only) Manually remove a specific user from the ticket show list, only used for one user at a time. ' + '\n/startshow: (mods/bc only) Start the ticket show when not set to automatic start. Once started, the show will only be visible to ticket holders. Hint: start the show when you are in a good position for the preview pic to be frozen that will attract more ticket buyers. Note that /startshow is the CrazyTicket command but also works with the Ultra App Ticket show.' + '\n/showwarn (or /showover): (mods/bc only) Display a warning that the show will be ending soon and ticket purchases are allowed but not recommended. If configured, this can also end the positions menu, and reduce the ticket price. Note that /showover is the CrazyTicket command but also works with the Ultra App Ticket show.' + '\n/showend (or /stopsales): (mods/bc only) Suspend ticket sales, no more automatic ticket purchases can be made. Recommended to always do this once you are less than a few minutes from the end of the show so people do not buy at the last second and are disappointed by getting a short show. If configured, this can also end the positions menu, and reduce the ticket price. Note that /showend is the CrazyTicket command but also works with the Ultra App Ticket show.' + '\n/stopshow: (mods/bc only) End the hidden show and return to a public broadcast.' + '\n/newticketshow: (mods/bc only) Completely refresh the ticket show to start a brand new show. This will remove all the ticket holders from the list, and re-initialize all settings using the configuration from the launch page.' + '\n/restartshow: (mods/bc only) Go back into hidden cam mode if the show was accidentally ended too soon, or the broadcaster wanted to go back to public to sell more tickets. The ticket holder list and all settings are kept intact.' + '\n/ticketprice (or /ctprice, or /chgticketprice) [newprice]: (mods/bc only) Update the ticket price to the [newprice]. Note that /ctprice is the CrazyTicket command but also works with the Ultra App Ticket show.' + '\n/starttimer (or /ticketstarttimer, or /starttickettimer) [time]: (mods/bc only) Start a [time] minute timer for the raffle drawing when in "timer" mode with the drawing to be triggered by the /raffledrawing command. The timer will count down but not automatically perform the drawing (unless set to automatic mode but the auto-timer was ended, and this is a restart of that timer)' + '\n/addtime (or /ticketaddtime, or /addtickettime) [time]: (mods/bc only) Add [time] minutes to the timer for either automatic or manual drawing mode. The [time] value can be a negative number to subtract time, but cannot be greater than the remaining time.' + '\n/stoptimer (or /ticketstoptimer, or /stoptickettimer): (mods/bc only) Stop the raffle timer for either automatic or manual drawing mode.' + '\n/tickettimeleft : (mods/bc only) Display the time left on the ticket show countdown for either automatic or manual starting mode.' + '\n/showtime : (all users) Display a message showing how long the current show has been hidden.' + '\n/chgticketmode [manual/timer/ticketgoal/tokengoal]: (mods/bc only) Switch between the modes being used to determine when to start the ticket show. If switching from a timer show to a non-timer show, the timer will be ended. Ticket count and Tip Count are being tracked regardless of mode, so switching to a "goal" mode should not require starting progress at 0.' + '\n/chgticketmodeauto [auto/bc]: (mods/bc only) Switch between the modes being used to define if the show starts automatically when a goal is reached or timer expires, or if the broadcaster or mods still control the start of the show. ' + '\n/giftticket [user]: (all users, once you have extra tickets) If the "gifting" feature is enabled, when you tip enough to buy extra tickets, you can gift those tickets to other users using this command. Each time you gift, it removes one of your "extra" tickets. You can only gift extra tickets with this command, to give away your own ticket, you can use /givemyticketto as noted below. Be sure to type the user name correctly for the person you are gifting to, extra tickets cannot be recovered once they are gifted. This can be done before and during the show.' + '\n/givemyticketto [user]: (all ticket buyers) If you cannot stay for a show, and outstanding ticket feature is no used to allow saving your ticket, you can give your ticket to another user. This can only be done before the show starts, and you will be removed from the ticket show list!' + '\n/ticketsubject (or /ctsubject) [newsubject]: (mods/bc only) Change the room description/subject/title to a new value. This keeps the standard ticket show formatting and only changes the configurable part of the subject.' + '\n/addlbtop [X]: (bc/mods) Add the top [X] number of tippers for the current session to the ticket show. Moderators may only use this if allowed per configuration. This can be used with the Ultra App Ticket show or in support of CrazyTicket. The /add command is executed, which will add them to the show if the user executing them has authority to the /add command' + '\n/addlbamt [X]: (bc/mods) Add tippers who have tipped at least [X] number of tokens for the current session to the ticket show. Moderators may only use this if allowed per configuration. This can be used with the Ultra App Ticket show or in support of CrazyTicket. The /add command is executed, which will add them to the show if the user executing them has authority to the /add command' + '\n/ctn: (bc/mods) Post a one-time notice in the chat. The syntax for using this type of notice is "/cn [X]", where [X] is the message you want to send. This is the plain notification without any separators or highlighting.' + '\n/ctnd: (bc/mods) Post a one-time notice in the chat. The syntax for using this type of notice is "/cnd [X]", where [X] is the message you want to send. This notification includes a dash separator before and after the message, but no highlighting.' + '\n/ctnh: (bc/mods) Post a one-time notice in the chat. The syntax for using this type of notice is "/cnh [X]", where [X] is the message you want to send. This notification includes highlighting, but no separators.' + '\n/ctndh: (bc/mods) Post a one-time notice in the chat. The syntax for using this type of notice is "/cndh [X]", where [X] is the message you want to send. This notification includes both separators and highlighting.' ,from); cb.sendNotice('',from,yellow); break; } } if(valid == 0) { cb.sendNotice(option + ' is not a valid subsection of the help menu. Type "/uahelp" to access the main help menu.',from,yellow); } } } } // ******************************* Upon user entry of a Message ************************************** { cb.onMessage(function (msg) { var message = msg['m'].split(' '); var cmd = 0; var symbolString = '~`!@#$%^&*()_-+={[}]|\\:;"\'<,>.?/'; var listRegExp = /[,\s]+/; var listRegExpSpc = /[,]+/; var m = msg.m; var u = msg.user; var isMod = msg.is_mod; var isFan = msg.in_fanclub; var isBC = (u === cb.room_slug); var BC = cb.room_slug; var command = message[0] var commandVar1 = parseInt(message[1]); var commandVar2 = parseInt(message[2]); var commandVar3 = parseInt(message[3]); if(message[0].charAt(0) == '/') { msg['X-Spam'] = true; msg['X-Spam'] = true; var ntc = null; for (var i = 1; i < message.length; i++) { if (i == 1) ntc = message[i]; else ntc += " " + message[i]; } var ntc2 = null; for (var i = 2; i < message.length; i++) { if (i == 2) ntc2 = message[i]; else ntc2 += " " + message[i]; } var cmdval = null; for (var i = 1; i < message.length; i++) { if (i == 1) cmdval = message[i]; else cmdval += " " + message[i]; } if(isMod) { populateModeratorArray(u, "mod"); } if(isFan) { populateFanClubArray(u); } switch(command) { //********* General App Commands case '/chgpanelbg': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (message[1]) { newBg = message[1].toLowerCase(); customizePanelBackground(newBg,u); } else { cb.sendNotice('The /chgpanelbg command requires the entry of a parameter following the command, such as "/chgpanelbg lavalamp". The valid formats are: \n' + cbjs.arrayJoin(backgroundArray.command, ', '), u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/chgpaneltext': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { newcolor = msg['m'].substring(14).trim(); if (newcolor) { customizePanelText(newcolor,u); } else { cb.sendNotice('The /chgpaneltext command requires the entry of a parameter following the command, which represents either the color name or the color hex code, such as "/chgpaneltext blue" or "/chgpaneltext #0000ff".' , u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } //********* Hidden Ticket Show Commands case '/tickets': { cmd = 1; if (whichApp === 'ticket') { if (isMod || isBC) { var ticketlist = cb.limitCam_allUsersWithAccess(); if (ticketlist.length > 0) { if (message[1] === 'a' || message[1] === 'A' || message[1] === 'alpha') { ticketlist.sort(); cb.sendNotice('Alphabetic listing of users currently with access to the Hidden Ticket Show : ', u, yellow); cb.sendNotice(cbjs.arrayJoin(ticketlist, ', '), u); cb.sendNotice('End of List', u, yellow); } else { cb.sendNotice('Users currently with access to the Hidden Ticket Show, in order of when added (use the "alpha" qualifier for a sorted list): ', u, yellow); cb.sendNotice(cbjs.arrayJoin(ticketlist, ', '), u); cb.sendNotice('End of List', u, yellow); } } else { cb.sendNotice('No ticket buyers yet.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } break; } case '/useot': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if(message[1] != null && message[1] != 'on' && message[1] != 'off') { cb.sendNotice('The value ' + message[1] + ' is not a valid option for /useot, please try again.', u, yellow); } else if(message[1] == null) { cb.sendNotice('You did not enter a valid option for /useot, please try again.', u, yellow); } else { setTicketShowOtToggle(message[1], u); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case "/otlist": { cmd = 1; if (whichApp === 'ticket') { if (ticketShowOtToggle == 1) { cb.sendNotice('Users currently on the Outstanding Ticket List: ' + outstandingTicketArray.length, u, yellow); cb.sendNotice((outstandingTicketArray.length > 0 == true ? cbjs.arrayJoin(outstandingTicketArray, ', ') : 'No outstanding ticket holders.'), u); cb.sendNotice('End of List', u, yellow); } else { cb.sendNotice('The Ticket Show Outstanding Ticket feature is disabled.', u, yellow); } break; } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } } case "/otchanges": { cmd = 1; if (whichApp === 'ticket') { if (isMod || isBC) { if (otChangesArray.name.length > 0) { cb.sendNotice('Listing of Changes to the Outstanding Ticket List : ', u, yellow); outString = ""; for (var i = 0; i < otChangesArray.name.length; i++) { if (otChangesArray.name[i] == null) { break } else { outString += (i > 0 ? "," : "") + otChangesArray.name[i] + "(" + otChangesArray.type[i] + ")"; } } cb.sendNotice(outString, u); cb.sendNotice('End of List', u, yellow); } else { cb.sendNotice('No entries have been added to the Outstanding Ticket Change list.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/ctprice': case '/chgticketprice': case '/ticketprice': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.ticketShowModsChgPrice === 'Yes')) { numprice = parseInt(message[1]) if (isNaN(numprice)) { cb.sendNotice('The value entered for the ticket price is not numeric, please try again.', u, yellow); break; } else if (numprice < 1 || numprice > 1000) { cb.sendNotice('The value entered for the ticket price is outside allowable values from 1 to 500, please try again.', u, yellow); } else { setTicketPrice(numprice,u,'yes'); cb.sendNotice('The Hidden Ticket Show price has been updated to ' + numprice + ' tokens, all tips of at least this amount will add a user to the Ticket Show List. You can view the ticket list with the command "/tickets".', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/starttickettimer': case '/ticketstarttimer': case '/starttimer': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { numtimer = parseInt(message[1]) if(isNaN(numtimer)) { cb.sendNotice('The value entered for the minutes to use for the timer is not numeric, please try again.', u, yellow); break; } else if(numtimer < 1 || numtimer > 120) { cb.sendNotice('The value entered for the minutes to use for the ticket show timer is outside allowable values from 1 to 120 (up to 2 hrs), please try again.', u, yellow); } else { startTicketShowTimer(numtimer); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/addtickettime': case '/ticketaddtime': case '/addtime': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { numtimer = parseInt(message[1]) if(isNaN(numtimer)) { cb.sendNotice('The value entered for the minutes to add to the ticket show start timer is not numeric, please try again.', u, yellow); } else if(numtimer < -60 || numtimer > 60) { cb.sendNotice('The value entered for the minutes to add to the ticket show start timer is outside allowable values from -60 to 60, please try again. Negative numbers can be used to subtract time.', u, yellow); } else if(numtimer = 0) { cb.sendNotice('Cannot add zero time.', u, yellow); } else if(numtimer < 0 && Math.abs(numtimer) > ticketMinsRemain) { cb.sendNotice('The value entered for the minutes to subtract is greater than the remaining time on the timer, please try again. Negative numbers can be used to subtract time.', u, yellow); } else { ticketAddTime(numtimer, u); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/ticketstoptime': case '/ticketstoptimer': case '/stoptimer': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (ticketMinsRemain > 0 || ticketSecsRemain > 0) { stopTicketTimer(u); } else { cb.sendNotice('A ticket timer is not currently running.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/add': case '/addticket': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.ticketShowModsAdd === 'Yes')) { if (cmdval != null) { var cmdvalsplit = cmdval.split(listRegExp); if (cmdvalsplit.length > 1) { cb.sendNotice("Adding multiple users to the ticket show list.", u, yellow); for (var i = 0; i < cmdvalsplit.length; i++) { if (cmdvalsplit[i] != "") { if (!cb.limitCam_userHasAccess(cmdvalsplit[i])) { addRmvTicket("add", cmdvalsplit[i]); cb.sendNotice("Added " + cmdvalsplit[i] + " to the ticket show list.", u); cb.sendNotice(u + " has added you to the ticket show list.", cmdvalsplit[i], yellow); } else { cb.sendNotice(cmdvalsplit[i] + " is already on the ticket show list. Skipping.", u); } } } cb.sendNotice("All users were added and notified.", u, yellow) cb.sendNotice(u + " has added multiple users to the ticket show list.\n" + "Users added: " + cbjs.arrayJoin(cmdvalsplit, ", "), "", yellow, "", "normal", "red"); } else { if (!cb.limitCam_userHasAccess(message[1])) { addRmvTicket("add", message[1]); } else { cb.sendNotice('Note: User ' + message[1] + ' is already in the Ticket Show List.', u, yellow); } } } else { if (!cb.limitCam_userHasAccess(u)) { addRmvTicket("add", u); } else { cb.sendNotice('Note: User ' + u + ' is already in the Ticket Show List.', u, yellow); } } } else { cb.sendNotice('You do not have authority to use the /addticket command.', u, yellow); } } break; } case '/del': case '/delticket': case '/rmvticket': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.ticketShowModsAdd === 'Yes')) { if(message[1] != '' && message[1] != null) { if (cb.limitCam_userHasAccess(message[1])) { addRmvTicket("rmv", message[1]); cb.sendNotice('User ' + message[1] + ' has been removed from the Ticket Show List.', '', ticketBgColor, ticketTxtColor, "bold"); } else { cb.sendNotice('Note: User is not in the Ticket Show List.', u, yellow); } } else { cb.sendNotice('No user was specified for the /rmvticket command.', u, yellow); } } else { cb.sendNotice('You do not have authority to use the /rmvticket command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/giftticket': { cmd = 1; if (whichApp === 'ticket') { if (cb.settings.ticketShowAllowGift == 'Yes') { if (cbjs.arrayContains(ticketShowExtraTickets.name,u)) { index = ticketShowExtraTickets.name.indexOf(u); if (ticketShowExtraTickets.count[index] > 0) { giftTicket(u,message[1]); ticketShowExtraTickets.count[index]--; cb.sendNotice('You have gifted a ticket to ' + message[1] + '. Thank you for your generosity.', u, yellow, '', 'bold'); cb.sendNotice('Moderators: ' + u + ' has gifted a ticket to ' + message[1] + '.', '', yellow, '', '', 'red'); cb.sendNotice('Broadcaster: ' + u + ' has gifted a ticket to ' + message[1] + '.', BC, yellow); } else { cb.sendNotice('Sorry, you do not have any extra tickets remaining.', u, yellow); } } else { cb.sendNotice('Sorry, you have not purchased any extra tickets.', u, yellow); } } else { cb.sendNotice('Sorry, the broadcaster has not enabled the use of gifting tickets for this show.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/givemyticketto': { cmd = 1; if (whichApp === 'ticket') { if (cb.settings.ticketShowAllowGift == 'Yes') { if (cb.limitCam_userHasAccess(u) && showStage === 'ticketsales') { giveAwayTicket(u,message[1]); cb.sendNotice('You have gifted your ticket to ' + message[1] + '. You will now be removed from the show. Thank you for your generosity.',u,yellow,'','bold'); cb.sendNotice('Mods: ' + u + ' has gifted their own ticket to ' + message[1] + '.', '', yellow, '', '', 'red'); cb.sendNotice('Broadcaster: ' + u + ' has gifted their own ticket to ' + message[1] + '.', BC, yellow); } else { cb.sendNotice('Sorry, you do not have a ticket purchased or the show has already started.', u, yellow); } } else { cb.sendNotice('Sorry, the broadcaster has not enabled the gifting of tickets for this show.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/chgticketmode': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { newTicketMode = message[1].toLowerCase(); if (newTicketMode != 'manual' && newTicketMode != 'timer' && newTicketMode != 'ticketgoal' && newTicketMode != 'tokengoal') { cb.sendNotice('The value entered for the new mode is not valid, please try again using a value of "manual", "timer", "ticketgoal", or "tokengoal".', u, yellow); } else { if (newTicketMode === ticketStartMode) { cb.sendNotice('The value entered for the new mode is the same as the existing mode, command ignored.', u, yellow); } else { setTicketMode(newTicketMode,u); } } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/chgtktauto': case '/chgticketmodeauto': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { newTicketAuto = message[1].toLowerCase(); if (newTicketAuto != 'bc' && newTicketAuto != 'auto') { cb.sendNotice('The value entered for the new mode is not valid, please try again using a value of "bc" or "auto".', u, yellow); } else if (newTicketAuto === 'auto' && ticketStartMode === 'manual') { cb.sendNotice('The mode cannot be changed to "auto" unless there is a goal or timer being used to define when the show will start. Show is currently to be started at broadcaster discretion.', u, yellow); } else if (newTicketAuto === ticketModeAuto) { cb.sendNotice('The value entered for the new mode is the same as the existing mode, command ignored.', u, yellow); } else { setTicketAuto(newTicketAuto); if (newTicketAuto === 'bc') { cb.sendNotice('You have updated the ticket show starting mode from automatic to requiring command entry from the broadcaster or moderator.', u, yellow); } else if (newTicketAuto === 'bc') { cb.sendNotice('You have updated the ticket show starting mode to automatic, the show will start when the goal is met or the timer expires.', u, yellow); } } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/tickettimeleft': { cmd = 1; if (whichApp === 'ticket') { if (ticketMinsRemain >= 1 || ticketSecsRemain >= 1) { cb.sendNotice(ticketTimeLeft(), "", yellow, "", "bold"); } else { cb.sendNotice('A Hidden Ticket Show timer is not running.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/showtime': { cmd = 1; if (whichApp === 'ticket') { if (cb.limitCam_isRunning()) { getShowTime(u); } else { cb.sendNotice('The ticket show is not running, it has not yet started or already finished.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/useticket': { cmd = 1; if (whichApp === 'ticket') { if (cb.settings.enableHiddenShowOT == 'Yes') { if (!cb.limitCam_userHasAccess(u) && cbjs.arrayContains(outstandingTicketArray,u)) { useTicket(u); cb.sendNotice('Your outstanding ticket has been redeemed and you have been added to the ticket holders list for this show.', u, yellow, '', 'bold'); cb.sendNotice('Broadcaster: ' + u + ' has used their outstanding ticket. They should be removed from the permanent OT list on the bot start page.', BC, yellow); cb.sendNotice('Mods: ' + u + ' has used their outstanding ticket. The broadcaster has been notified to remove them from the permanent OT list on the bot start page.', '', yellow, '', '', 'red'); } else { cb.sendNotice('Sorry, you have no outstanding ticket available.', u, yellow); } } else { cb.sendNotice('Sorry, the broadcaster has not enabled the use of outstanding tickets for this show.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/saveticket': { cmd = 1; if (whichApp === 'ticket') { if (cb.settings.enableHiddenShowOT == 'Yes') { if (cb.limitCam_userHasAccess(u) && showStage === 'ticketsales') { saveTicket(u); cb.sendNotice('Your ticket from this show has been saved and you have been removed from the ticket list for this show.', u, yellow, '', 'bold'); cb.sendNotice('Broadcaster: ' + u + ' has saved their ticket from this show to the outstanding ticket list. They should be added from the permanent OT list on the bot start page upon next restart.', BC, yellow); cb.sendNotice('Mods: ' + u + ' has saved their ticket from this show to the outstanding ticket list. The broadcaster has been notified to add them to the permanent OT list on the bot start page.', '', yellow, '', '', 'red'); } else { cb.sendNotice('Sorry, you have no ticket purchase to save, or the show has already started.', u, yellow); } } else { cb.sendNotice('Sorry, the broadcaster has not enabled the ability to save an outstanding tickets for this show.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/addot': { cmd = 1; if (whichApp === 'ticket') { if (cb.settings.enableHiddenShowOT == 'Yes') { if (isBC || (isMod && cb.settings.ticketShowModsAdd === 'Yes')) { if(message[1] != '' && message[1] != null) { if (!cbjs.arrayContains(outstandingTicketArray,message[1])) { addRmvOutstandingTicket("add", message[1]); cb.sendNotice('User ' + message[1] + ' has been added to the Outstanding Ticket List.', u, yellow); } else { cb.sendNotice('Cannot add, user is already in the Outstanding Ticket List.', u, yellow); } } } } else { cb.sendNotice('Sorry, the broadcaster has not enabled the outstanding ticket show feature.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/rmvot': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.ticketShowModsAdd === 'Yes')) { if(message[1] != '' && message[1] != null) { if (cbjs.arrayContains(outstandingTicketArray,message[1])) { addRmvOutstandingTicket("rmv", message[1]); cb.sendNotice('User ' + message[1] + ' has been removed from the Outstanding Ticket List.', u, yellow); } else { cb.sendNotice('Cannot remove, user is not in the Outstanding Ticket List.', u, yellow); } } } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/startshow': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (!cb.limitCam_isRunning() && ticketShowEnded === false) { startTicketShow(u); } else if (!cb.limitCam_isRunning() && ticketShowEnded === true) { cb.sendNotice('The Hidden Cam show was already started and stopped, please use the command "/restartshow" to resume the hidden show.', u, yellow); } else { cb.sendNotice('The Hidden Cam show is already underway.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/showover': case '/showwarn': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (cb.limitCam_isRunning()) { if (showStage === 'ticketshow') { warnShowEnding(u); } else { cb.sendNotice('The /showwarn or /showover command is used for a first warning. The show has already progressed past the point this command should be used. To end the show and return to a public broadcast, use the /stopshow command.', u, yellow); } } else { cb.sendNotice('The Hidden Cam show has not been started or has already ended.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/showend': case '/stopsales': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (cb.limitCam_isRunning()) { if (cb.settings.endPosMenuWithShow == 'Yes' && posTipMenuToggle == 1) { setPosTipMenuToggle('off', u); } stopTicketSales(u); } else { cb.sendNotice('The Hidden Cam show has not been started or has already ended.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/stopshow': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (cb.limitCam_isRunning()) { if (cb.settings.endPosMenuWithShow == 'Yes' && posTipMenuToggle == 1) { setPosTipMenuToggle('off', u); } stopTicketShow(u); } else { cb.sendNotice('The Hidden Cam show has not been started or has already ended.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/ticketsubject': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { ticketSubjectText = msg['m'].substring(15).trim(); if (ticketSubjectText != '' && ticketSubjectText != null) { changeRoomSubject(); } else { cb.sendNotice('No value was specified for the new room subject suffix.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/ctsubject': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { ticketSubjectText = msg['m'].substring(11).trim(); if (ticketSubjectText != '' && ticketSubjectText != null) { changeRoomSubject(); } else { cb.sendNotice('No value was specified for the new room subject suffix.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/newticketshow': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (!cb.limitCam_isRunning()) { ticketlist = cb.limitCam_allUsersWithAccess(); if (ticketlist.length > 0) { cb.sendNotice('In case the ticket show was reset by mistake, the previous ticket list is displayed below so they can be added back to the show using the /addticket command : ', cb.room_slug, yellow); cb.sendNotice(cbjs.arrayJoin(ticketlist, ', '), cb.room_slug); cb.sendNotice('End of List', cb.room_slug, yellow); if (isMod) { cb.sendNotice('In case the ticket show was reset by mistake, the previous ticket list is displayed below so they can be added back to the show using the /addticket command : ', u, yellow); cb.sendNotice(cbjs.arrayJoin(ticketlist, ', '), u); cb.sendNotice('End of List', u, yellow); } } else { cb.sendNotice('No ticket buyers in the previous ticket list.', u, yellow); } initTicketShow(u,ticketPrice); cb.limitCam_removeAllUsers(); while (ticketShowViewerList.length > 0) viewerList.pop(); } else { cb.sendNotice('A Hidden Cam show is still running. The /newticketshow command can be used to start a brand new ticket show. The ticket list is cleared but the outstanding ticket list and changes list remains intact.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/restartshow': { cmd = 1; if (whichApp === 'ticket') { if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (!cb.limitCam_isRunning()) { restartTicketShow(u); } else { cb.sendNotice('A Hidden Cam show is already running. The /restartshow command can be used to resume a hidden show that was ended prematurely or accidentally. All settings remain the same and the ticket list stays intact.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case '/ctn': { cmd = 1; if (whichApp === 'ticket') { if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, ""); } else { cb.sendNotice('You cannot send a blank message. The correct syntax for this command is "/ctn [message]".', u, yellow); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case "/ctnh": { cmd = 1; if (whichApp === 'ticket') { if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "h"); } else { cb.sendNotice('You cannot send a blank message. The correct syntax for this command is "/ctnh [message]".', u, yellow); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case "/ctnd": { cmd = 1; if (whichApp === 'ticket') { if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "div"); } else { cb.sendNotice('You cannot send a blank message. The correct syntax for this command is "/ctnd [message]".', u, yellow); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } case "/ctndh": { cmd = 1; if (whichApp === 'ticket') { if (isMod || isBC) { if (ntc != null && (ntc != "" || ntc != " " || ntc != "\u00a0")) { sendPublicNotice(ntc, u, "divh"); } else { cb.sendNotice('You cannot send a blank message. The correct syntax for this command is "/ctndh [message]".', u, yellow); } } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.', u, yellow); } } else { cb.sendNotice('The UltraApp Ticket Show feature is not running.', u, yellow); } break; } //********* Help Menu case '/tickethelp': { cmd = 1; if (isMod || isBC) { helpModBC(message[1],u); } else { helpCommon(message[1],u); } break; } } //********* End of Expected commands if (message[0] == '/usegraylock' || message[0] == '/chggraytime' || message[0] == '/fbhelp' || message[0] == '/expps' || message[0] == '/pslist' || message[0] == '/subject' || message[0] == '/check' || message[0] == '/pass' || message[0] == '/plist' || message[0] == '/plistw' || message[0] == '/email' || message[0] == '/newshow' || message[0] == '/useraffle' || message[0] == '/uselushmenu' || message[0] == '/usemedia' || message[0] == '/pm' || message[0] == '/reply' || message[0] == '/bc' || message[0] == '/tm' || message[0] == '/tbm' || message[0] == '/silencelevel' || message[0] == '/graphiclevel' || message[0] == '/ninja' || message[0] == '/unninja' || message[0] == '/ninjalist' || message[0] == '/silence' || message[0] == '/unsilence' || message[0] == '/silencelist' || message[0] == '/tipmenu' || message[0] == '/tipmenurequests' || message[0] == '/tipmenuadd' || message[0] == '/tipmenurmv' || message[0] == '/usemenu' || message[0] == '/posmenu' || message[0] == '/posmenurequests' || message[0] == '/posmenuadd' || message[0] == '/posmenurmv' || message[0] == '/useposmenu' || message[0] == '/startclock' || message[0] == '/addtoclock' || message[0] == '/timeleft' || message[0] == '/stopclock' || message[0] == '/cn' || message[0] == '/cnh' || message[0] == '/cnd' || message[0] == '/cndh' || message[0] == '/usenotifier' || message[0] == '/chgmsg1' || message[0] == '/chgmsg2' || message[0] == '/chgmsg3' || message[0] == '/chgmsg4' || message[0] == '/chgmsg5' || message[0] == '/dspmsg' || message[0] == '/leaders' || message[0] == '/useleaderboard' || message[0] == '/usetipcount' || message[0] == '/tippers' || message[0] == '/poll' || message[0] == '/usepoll' || message[0] == '/endpoll' || message[0] == '/restartpoll' || message[0] == '/addvote' || message[0] == '/polloptadd' || message[0] == '/polloptrmv' || message[0] == '/pollstarttimer' || message[0] == '/polladdtime' || message[0] == '/pollstoptimer' || message[0] == '/pollleader' || message[0] == '/addnice' || message[0] == '/rmvnice' || message[0] == '/nicelist' || message[0] == '/addvip' || message[0] == '/rmvvip' || message[0] == '/viplist' || message[0] == '/exportvip' || message[0] == '/addfan' || message[0] == '/rmvfan' || message[0] == '/fanlist' || message[0] == '/exportfans' || message[0] == '/addword' || message[0] == '/rmvword' || message[0] == '/wordlist' || message[0] == '/newsubject' || message[0] == '/dumpsettings' || message[0] == '/checkcolor' || message[0] == '/prepticket' || message[0] == '/dsptlist' || message[0] == '/usetlist' || message[0] == '/exptlist' || message[0] == '/addlbtop' || message[0] == '/addlbamt' || message[0] == '/useticketshow' || message[0] == '/usepresale' || message[0] == '/presalelist' || message[0] == '/presaleprice' || message[0] == '/presalepricetimer' || message[0] == '/presalestarttimer' || message[0] == '/presalestoptimer' || message[0] == '/presaleaddtime' || message[0] == '/exppresale' || message[0] == '/addpresale' || message[0] == '/rmvpresale' || message[0] == '/chgpresalemode' || message[0] == '/presaletimeleft)' || message[0] == '/lushmenu' || message[0] == '/uselushmenu' || message[0] == '/chgtoy' || message[0] == '/uselush' || message[0] == '/usedomi' || message[0] == '/usenora' || message[0] == '/media' || message[0] == '/usemedia' || message[0] == '/prizes' || message[0] == '/usedice' || message[0] == '/chgdiceprice' || message[0] == '/dicerolls' || message[0] == '/usealltime' || message[0] == 'top10' || message[0] == '/alltime' || message[0] == '/startprivate' || message[0] == '/stopprivate' || message[0] == '/useraffle' || message[0] == '/entries' || message[0] == '/raffletickets' || message[0] == '/raffleentries' || message[0] == '/previousentries' || message[0] == '/resetraffle' || message[0] == '/clearraffle' || message[0] == '/addraffletkt' || message[0] == '/rmvraffletkt' || message[0] == '/addraffleprize' || message[0] == '/rmvraffleprize' ||message[0] == '/raffleprizes' || message[0] == '/setraffleprice' || message[0] == '/raffledrawing' || message[0] == '/rafflestarttimer' || message[0] == '/startraffletimer' || message[0] == '/raffleaddtime' || message[0] == '/addraffletime' || message[0] == '/rafflestoptimer' || message[0] == '/stopraffletimer' || message[0] == '/raffletimeleft' || message[0] == '/chgrafflemode') { cmd = 1; } if (cb.settings.fembotRunning != 'Yes') { if (cmd == 0) { cb.sendNotice(message[0] + ' is not a recognized UltraApp command (although it may just be a command for another app or bot).\nType "/uahelp" to see a full list of the available UltraApp commands.', u, yellow); } } } // Highlight background for Ticket show users if (whichApp == 'ticket' && cb.limitCam_userHasAccess(u)) { msg['background'] = ticketHolderBgColor; } return msg; }); } // *********************************** Actions on user entering ************************************** { cb.onEnter(function(user) { // Variables var u = user.user; var isMod = user.is_mod; var isBC = (u === cb.room_slug); var isFan = user.in_fanclub; var isNotGray = user.has_tokens; // for testing gray/fanclub user functions on testbed //if (u == 'dorothyuser2'){ // isNotGray = false; // isFan = true; //} // if(isMod) { populateModeratorArray(u, "mod"); } if(isFan) { populateFanClubArray(u); } if(cb.limitCam_userHasAccess(u)) { if (!cbjs.arrayContains(ticketShowViewerList,u)) { ticketShowViewerList.push(u); } } // **** Ticket Show functions and message if (whichApp === 'ticket') { if (cb.limitCam_isRunning()) { getShowTime(u); if (!cb.limitCam_userHasAccess(u)) { if (showStage == 'ticketshow') { cb.sendNotice(dashLine80 + '\nTicket Show is in progress, broadcaster has not indicated Show Finale.\nThe ticket price is ' + ticketPrice + ' tokens.\n' + dashLine80, u, ticketBgColor,ticketTxtColor,'bold'); if (ticketShowOtToggle == 1) { cb.sendNotice(dashLine80 + '\n* The Broadcaster has enabled the Outstanding Ticket Feature. \n* You can use the command "/otlist" to see if you have an outstanding ticket. \n* You can use a saved outstanding ticket with the command "/useticket". \n* You can also save your ticket for a future show using the command "/saveticket" if the show has not staretd yet.\n' + dashLine80, u, ticketBgColor, ticketTxtColor, 'bold'); } } else if (showStage === 'showwarn') { cb.sendNotice(dashLine90 + '\nTicket Show in progress but broadcaster has indicated show is nearly over. \nBuying a ticket is not recommended, but you may still buy one for ' + ticketPrice + ' tokens.\n' + dashLine90, u, ticketBgColor,ticketTxtColor,'bold'); } else if (showStage === 'showfinale') { cb.sendNotice(dashLine90 + '\nTicket Show in progress but broadcaster has indicated show is nearly over. \nTicket Sales have been suspended, you can no longer buy a ticket. \nBroadcaster may be returning to public chat shortly.\n' + dashLine90, u, ticketBgColor,ticketTxtColor,'bold'); } } } else { if (showStage == 'ticketsales') { if (cb.limitCam_userHasAccess(u)) { cb.sendNotice(dashLine80 + '\nWelcome! You have a ticket to the show and the show has not yet started.\n' + dashLine80, u, ticketBgColor, ticketTxtColor, "bold"); } else { cb.sendNotice(dashLine80 + '\nTicket Show sales are active and show has not yet started. \nThe ticket price is ' + ticketPrice + ' tokens.\n' + dashLine80, u, ticketBgColor, ticketTxtColor, "bold"); } if (cb.settings.hiddenShowAllowGift === 'Yes') { cb.sendNotice(dashLine80 + '\n* The Broadcaster has enabled the the gifting of tickets. \n* If you purchase extra tickets, you can gift them to others using the command "/giftticket user" \n* You can also choose to give away your own ticket using the command "/givemyticketto user".\n' + dashLine80, u, ticketBgColor, ticketTxtColor, 'bold'); } if (ticketShowOtToggle == 1) { cb.sendNotice(dashLine80 + '\n* The Broadcaster has enabled the Outstanding Ticket Feature. \n* You can use the command "/otlist" to see if you have an outstanding ticket. \n* You can use a saved outstanding ticket with the command "/useticket". \n* You can also save your ticket for a future show using the command "/saveticket" if the show has not started yet.\n' + dashLine80, u, ticketBgColor, ticketTxtColor, 'bold'); } } else if (showStage == 'aftershow' || ticketShowEnded === true) { cb.sendNotice(dashLine60 + '\nThe Ticket Show is over.\n' + dashLine60, u, ticketBgColor, ticketTxtColor, 'bold'); } } if (!cb.limitCam_userHasAccess(u)) { if (isMod) { if (cb.settings.ticketShowFreeMods == 'Yes') { addRmvTicket('add',u,'mod'); cb.sendNotice(dashLine80 + '\n* You\'ve automatically been added to the ticket show because you\'re a moderator! \n' + dashLine80, u, ticketBgColor, ticketTxtColor, 'bold'); } cb.sendNotice(dashLine80 + '\n* Moderators: The UltraApp Ticket Show feature is enabled. \nType "/uahelp ticketshow" to see details on available commands for this feature. \n' + dashLine80, u, ticketBgColor, ticketTxtColor, 'bold'); } if (isFan) { if (cb.settings.ticketShowFreeFC == 'Yes') { addRmvTicket('add',u,'fan'); cb.sendNotice(dashLine80 + '\n* You\'ve automatically been added to the ticket list because you\'re in the fan club! \n' + dashLine80, u, ticketBgColor, ticketTxtColor, 'bold'); } else { cb.sendNotice(dashLine80 + '\n* As a fan club member, you can buy a ticket to the show for ' + cb.settings.ticketShowPriceFC + ' tokens. \n' + dashLine80, u, ticketBgColor, ticketTxtColor, 'bold'); } } } } }); } // *********************************** Actions upon leaving ************************************** { cb.onLeave(function(user) { var u = user.user; if (whichApp === 'ticket') { if (cbjs.arrayContains(ticketShowViewerList,u)) { cbjs.arrayRemove(ticketShowViewerList,u); } } }); } // *********************************** Actions upon Draw Panel ************************************** cb.onDrawPanel(function (user) { var panel = {}; if (customPanel) { panel.template = 'image_template'; panel.row1_label = "row1_label"; panel.row1_value = "row1_value"; panel.row2_label = "row2_label"; panel.row2_value = "row2_value"; panel.row3_label = "row3_label"; panel.row3_value = "row3_value"; } else { panel.template = '3_rows_11_21_31'; } if (showStage === 'ticketsales') { if (cb.settings.showTotals == 'Yes') { leftjust3 = 20; } else { leftjust3 = 65; } if (ticketStartMode == 'ticketgoal') { panel.row1_value = 'Start Mode: Ticket Goal \u25FE Progress: ' + ticketShowTotalTickets + ' / ' + ticketShowGoalTickets + ' tickets'; leftjust1 = 20; panel.row2_value = 'Ticket Holders: ' + countTicketsSold + ' \u25FE Viewers: ' + ticketShowViewerList.length; leftjust2 = 45; panel.row3_value = 'Ticket Price: ' + ticketPrice + ' tokens ' + (cb.settings.showTotals == 'Yes' ? (' \u25FE Total Tips: ' + currentAppTotalTicket) : ''); } else if (ticketStartMode == 'tokengoal') { panel.row1_value = 'Start Mode: Token Goal \u25FE Progress: ' + ticketShowTotalTips + ' / ' + ticketShowGoalTokens + ' tokens'; leftjust1 = 20; panel.row2_value = 'Ticket Holders: ' + countTicketsSold + ' \u25FE Viewers: ' + ticketShowViewerList.length; leftjust2 = 45; panel.row3_value = 'Ticket Price: ' + ticketPrice + ' tokens ' + (cb.settings.showTotals == 'Yes' ? (' \u25FE Total Tips: ' + currentAppTotalTicket) : ''); } else if (ticketStartMode == 'timer') { panel.row1_value = 'Start Mode: Timer (' + ((ticketSecsRemain > 0 || ticketMinsRemain > 0) ? ticketTimeLeftPanel() : 'Timer not yet started') + ')'; leftjust1 = 20; panel.row2_value = 'Ticket Holders: ' + countTicketsSold + ' \u25FE Viewers: ' + ticketShowViewerList.length; leftjust2 = 45; panel.row3_value = 'Ticket Price: ' + ticketPrice + ' tokens ' + (cb.settings.showTotals == 'Yes' ? (' \u25FE Total Tips: ' + currentAppTotalTicket) : ''); } else { panel.row1_value = 'Start Mode: Manual'; leftjust1 = 75; panel.row2_value = 'Ticket Holders: ' + countTicketsSold; leftjust2 = 78; panel.row3_value = 'Ticket Price: ' + ticketPrice + ' tokens ' + (cb.settings.showTotals == 'Yes' ? (' \u25FE Total Tips: ' + currentAppTotalTicket) : ''); } } else { panel.row1_value = 'Ticket Holders: ' + countTicketsSold; leftjust1 = 65; panel.row2_value = 'Viewers: ' + ticketShowViewerList.length; leftjust2 = 75; panel.row3_value = 'Ticket Price: ' + ticketPrice + ' tokens ' + (cb.settings.showTotals == 'Yes' ? (' \u25FE Total Tips: ' + currentAppTotalTicket) : ''); if (cb.settings.showTotals == 'Yes') { leftjust3 = 20; } else { leftjust3 = 65; } } panel.layers = [ {'type': 'image', 'fileID': backgroundImage}, { 'type': 'text', 'text': panel.row1_value, 'top': topjust1, 'left': leftjust1, 'font-size': fontSize, 'font-weight': 'bold', 'color': textColor, }, { 'type': 'text', 'text': panel.row2_value, 'top': topjust2, 'left': leftjust2, 'font-size': fontSize, 'font-weight': 'bold', 'color': textColor, }, { 'type': 'text', 'text': panel.row3_value, 'top': topjust3, 'left': leftjust3, 'font-size': fontSize, 'font-weight': 'bold', 'color': textColor, }, ] return panel; }); // *********************************** Actions upon tipping ************************************** { cb.onTip (function (tip) { var tipAmount = Number.parseInt(tip.amount, 10); var u = tip.from_user var isFan = tip.from_user_in_fanclub; var voteAmount = 1; // ***** Tip Count Array if (!cbjs.arrayContains(tipCountArray.name, u)) { tipCountArray.name.push(u); tipCountArray.amount.push(tipAmount); } else { tipCountArray.amount[findTipper(u)] += tipAmount; } // ***** Record tip for goal progress and track total stats recordTip(tipAmount,u,isFan); }); } // *********************************** Initialize ************************************** { if (initialize == 0) { var BC = cb.room_slug; // *** Init Feature if (cb.settings.ticketShowPrice <= 0) { cb.sendNotice('Unable to start the Ultra App Ticket Show feature, a ticket price was not set on the start page. You can either set the price now using the command "/ticketprice [amt]" where [amt] is in the price in tokens, or restart the bot and set the price. The Ticket Show feature can be enabled after setting a price using the command "/chgapp ticketshow". ', BC, yellow); setAppFeature('none', BC); } else { setTicketShowToggle('on', BC); } //*** Init OT List for Ticket Show if(cb.settings.ticketShowOTList != '' && cb.settings.ticketShowOTList != null) { var n = cb.settings.ticketShowOTList; outstandingTicketArray = n.split(','); } //*** Set Panel if (cb.settings.panelBackground != 'default - no image' && cbjs.arrayContains(backgroundArray.menu,cb.settings.panelBackground)) { newbackground = backgroundArray.command[backgroundArray.menu.indexOf(cb.settings.panelBackground)]; customizePanelBackground(newbackground,BC); customizePanelText('',BC); } else { customPanel = false; cb.sendNotice('A custom panel background was chosen but it does not exist, using the default panel background.', BC, yellow); } cb.drawPanel(); populateModeratorArray(BC, "bc"); initialize = 1; } }
© Copyright Chaturbate 2011- 2024. All Rights Reserved.