Apps Home
|
Create an App
tip goals de mazi
Author:
conju1
Description
Source Code
Launch App
Current Users
Created by:
Conju1
/** This app is a minimally modified version of Dorothy's Tip Goals 1.0 by chelsea2950 All credits for the original code in this app go to chelsea2950 Name: Dorothy's Tip Goals Author: chelsea2950 Current version 1.0 Created 02/19/2019 Last Updated 2/19/2019 (see description for change log) This app is intended to provide cammers with a tip goal app for both single goal shows and multiple progressive goals. It does not, however, include things that I would expect to be managed by my Fembot, such as chat control and tracking tip leaders, etc. The source for this app will always remain open and unobfuscated. Features of this app: - Single & Progressive Goals - Ability to skip goals, restart goals, manually add tokens to the current goal - Keep track of your stats for the goal show - Flexible backgrounds and text colors in the draw panel **/ // 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', 'Christmas 1' ], command: ['cubewave', 'hearts', 'snow', 'aquarium', 'snakeskin', 'pastels', 'clouds', 'lavalamp', 'lightblue', 'moon', 'cumcreamery', 'livanddrew', 'bluegradient', 'valentines1', 'valentines2', 'xmas1' ], devfile: ['add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', 'add', 'add' ], livefile: ['809658f7-92be-4d3e-ba34-52da3a5a4b5d','56c61a44-8f7e-4fa7-aec3-1c5014901668', 'd2b04b2b-8a50-4774-b59f-db60dc508d52', '769ab1c7-cf54-440a-b068-3aa63f2d4e2d', 'd078bed1-0d97-4835-91aa-7e0afa8c5351', 'cf9c4af4-2fe3-45a7-bbad-f9668773f9b7', '51c32ede-98da-4ef7-be05-f3af87f8a161', '124cf05b-2e6a-4c5b-81f5-36dd91e49dfa', '294562e6-ba51-4649-a04c-e5b0ee3d811c', '375b178b-e7c0-48aa-aad2-c0aca4a43daa', '7dfaf9d0-5557-49a2-9a35-167ffb5c0bfc', '7749bfd4-92eb-429b-988f-06c9499a2e37', 'f5b35cbe-76ed-407a-8d8a-dc63949c20cf', 'bbce8243-8fb6-4003-b10a-a939fac21035', 'b3843415-a843-4d32-b6ff-e123eea66402', 'c3d7f97b-7bf2-47aa-b661-e1768927ef75' ] }; var fontSize = 12; var customPanel = false; } {cb.settings_choices = [ {name: 'intro', label: '********************** INTRODUCTION ************************* Latest Updt: 02/19/2019 (version 1.0) See Change Log ************************************************************** Welcome to Dorothy\'s Tip Goals App. You can set up below a single goal or multiple progressive goals that the App will advance through as goals are reached (multi-goal). Note that Moderators can be given significant privileges by this App, so if granting them access to broadcaster commands, please make sure you assign moderators you can trust. You can see the full list of broadcaster and moderator commands for the App by typing "/goalshelp" 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. Please enjoy using the Tip Goals 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}, // *** General Settings {name: 'general', label: '*********************************************************** ******************* GENERAL SETUP ********************** *********************************************************** ', type: 'choice',required: false}, {name: 'allowModsAuthority', label: 'Allow moderators to have authority to broadcaster commands? It is usually ok to give trusted moderators general authority with this setting to help them run your show, however they will have authority to perform actions such as manually adding tips to goals, and changing goal thresholds, so make sure your moderator is trustworthy', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes'}, {name: 'allowModsStats', label: 'Allow moderators to use the "/stats" command to see current show time online and tip totals', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No'}, {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 Tip Goals App? This setting is used to suppress error messages from the Tip Goals 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: 'progressiveGoalTextColor',label: 'Text color for chat notices related to the Progressive Goal 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: '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 Green'}, {name: 'progressiveGoalCustomTextColor', 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: 'progressiveGoalBgColor',label: 'Background/Highlight color for chat notices related to the Progressive Goal 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: 'Light Teal',choice12: 'Cream',choice13: 'Light Bronze',choice14: 'Light Periwinkle',choice15: 'Light Fuschia',choice16: 'Light Lime',choice17: 'Light Plum',choice18: 'Custom',defaultValue: 'Light Green'}, {name: 'progressiveGoalCustomBgColor', 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: '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], choice17: backgroundArray.menu[15], defaultValue: backgroundArray.menu[0]}, {name: 'panelTextColor',label: 'Text color for the panel text (if a custom background is used)',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}, // *** Single or Progressive Goals {name: 'progressivegoals', label: '************************************************************* ************************ GOAL SETUP ************************* ************************************************************* You can set up a Single goal or multiple goals. Each goal amount is specific to that goal, it is not the cumulative total. Please clear out the descriptions and amounts for the goals that are not being used. If doing a single goal, you can recycle the goal multiple times using the "/restartgoal" command', type: 'choice',required: false}, {name: 'progressiveRoomSubjectSfx', label: 'Title? -- Enter any show description text or hashtags you would like appended to the individual goal descriptions shown in the room title', type: 'str',required: false, minLength: 1, maxLength: 100, defaultValue: 'Sex Show at Final Goal #couple #goals'}, {name: 'progressiveAutoNext', label: 'Once the current goal is reached, automatically start next goal, or require manual start of a goal with the "/next" command? Note that with manual start, tips that exceed the current goal are not counted toward the next goal. With auto-start, the excess amount is rolled over to the next goal.', type: 'choice', choice1: 'Auto-start next', choice2: 'Manually start next', defaultValue: 'Auto-start next'}, {name: 'progressiveGoalDescription1', label: 'Goal #1 Description', type: 'str', minLength: 1, maxLength: 100, defaultValue: 'Goal #1 Name'}, {name: 'progressiveGoalAmount1', label: 'Goal #1 amount', type: 'int', minValue: 1, maxValue: 100000, defaultValue: 500}, {name: 'progressiveGoalDescription2', label: 'Goal #2 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount2', label: 'Goal #2 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription3', label: 'Goal #3 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount3', label: 'Goal #3 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription4', label: 'Goal #4 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount4', label: 'Goal #4 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription5', label: 'Goal #5 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount5', label: 'Goal #5 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription6', label: 'Goal #6 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount6', label: 'Goal #6 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription7', label: 'Goal #7 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount7', label: 'Goal #7 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription8', label: 'Goal #8 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount8', label: 'Goal #8 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription9', label: 'Goal #9 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount9', label: 'Goal #9 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription10', label: 'Goal #10 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount10', label: 'Goal #10 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription11', label: 'Goal #11 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount11', label: 'Goal #11 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription12', label: 'Goal #12 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount12', label: 'Goal #12 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription13', label: 'Goal #13 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount13', label: 'Goal #13 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription14', label: 'Goal #14 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount14', label: 'Goal #14 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription15', label: 'Goal #15 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount15', label: 'Goal #15 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription16', label: 'Goal #16 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount16', label: 'Goal #16 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription17', label: 'Goal #17 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount17', label: 'Goal #17 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription18', label: 'Goal #18 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount18', label: 'Goal #18 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription19', label: 'Goal #19 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount19', label: 'Goal #19 amount', type: 'int',required: false, minValue: 1, maxValue: 100000}, {name: 'progressiveGoalDescription20', label: 'Goal #20 Description', type: 'str',required: false, minLength: 1, maxLength: 100}, {name: 'progressiveGoalAmount20', label: 'Goal #20 amount', type: 'int',required: false, minValue: 1, maxValue: 100000} ]; } { // *********************************** Variables and Arrays ************************************** var initialize = 0; var BC = cb.room_slug; var currentGoal = 1; var currentGoalTips = 0; var currentGoalTotal = 0; var currentSessionTotal = 0; var currentAppTotalGoal = 0; function startsWith(source, str) { //return source.substring(0, str.length) === str; //return source.toLowerCase().indexOf(str.toLowerCase()) !== -1; return source.toLowerCase().includes(str); } var goalSubjectText = cb.settings.progressiveRoomSubjectSfx; var progressiveGoalDescription1 = cb.settings.progressiveGoalDescription1; var progressiveGoalDescription2 = cb.settings.progressiveGoalDescription2; var progressiveGoalDescription3 = cb.settings.progressiveGoalDescription3; var progressiveGoalDescription4 = cb.settings.progressiveGoalDescription4; var progressiveGoalDescription5 = cb.settings.progressiveGoalDescription5; var progressiveGoalDescription6 = cb.settings.progressiveGoalDescription6; var progressiveGoalDescription7 = cb.settings.progressiveGoalDescription7; var progressiveGoalDescription8 = cb.settings.progressiveGoalDescription8; var progressiveGoalDescription9 = cb.settings.progressiveGoalDescription9; var progressiveGoalDescription10 = cb.settings.progressiveGoalDescription10; var progressiveGoalDescription11 = cb.settings.progressiveGoalDescription11; var progressiveGoalDescription12 = cb.settings.progressiveGoalDescription12; var progressiveGoalDescription13 = cb.settings.progressiveGoalDescription13; var progressiveGoalDescription14 = cb.settings.progressiveGoalDescription14; var progressiveGoalDescription15 = cb.settings.progressiveGoalDescription15; var progressiveGoalDescription16 = cb.settings.progressiveGoalDescription16; var progressiveGoalDescription17 = cb.settings.progressiveGoalDescription17; var progressiveGoalDescription18 = cb.settings.progressiveGoalDescription18; var progressiveGoalDescription19 = cb.settings.progressiveGoalDescription19; var progressiveGoalDescription20 = cb.settings.progressiveGoalDescription20; var progressiveGoalAmount1 = cb.settings.progressiveGoalAmount1; var progressiveGoalAmount2 = cb.settings.progressiveGoalAmount2; var progressiveGoalAmount3 = cb.settings.progressiveGoalAmount3; var progressiveGoalAmount4 = cb.settings.progressiveGoalAmount4; var progressiveGoalAmount5 = cb.settings.progressiveGoalAmount5; var progressiveGoalAmount6 = cb.settings.progressiveGoalAmount6; var progressiveGoalAmount7 = cb.settings.progressiveGoalAmount7; var progressiveGoalAmount8 = cb.settings.progressiveGoalAmount8; var progressiveGoalAmount9 = cb.settings.progressiveGoalAmount9; var progressiveGoalAmount10 = cb.settings.progressiveGoalAmount10; var progressiveGoalAmount11 = cb.settings.progressiveGoalAmount11; var progressiveGoalAmount12 = cb.settings.progressiveGoalAmount12; var progressiveGoalAmount13 = cb.settings.progressiveGoalAmount13; var progressiveGoalAmount14 = cb.settings.progressiveGoalAmount14; var progressiveGoalAmount15 = cb.settings.progressiveGoalAmount15; var progressiveGoalAmount16 = cb.settings.progressiveGoalAmount16; var progressiveGoalAmount17 = cb.settings.progressiveGoalAmount17; var progressiveGoalAmount18 = cb.settings.progressiveGoalAmount18; var progressiveGoalAmount19 = cb.settings.progressiveGoalAmount19; var progressiveGoalAmount20 = cb.settings.progressiveGoalAmount20; 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 dashLine60 = new Array(60).join("-"); var dashLine70 = new Array(70).join("-"); var dashLine80 = new Array(80).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 tipCountArray = {name: [], amount: []}; var progGoalArray = {desc: [], amt: [], recyc: []}; 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"); } } } function leftJustify(textstring,line) { textStringLength = textstring.length; if (fontSize == 11) { if (line == 1) { if (textStringLength < 4) { return 114; } else if (textStringLength < 6) { return 109; } else if (textStringLength < 8) { return 104; } else if (textStringLength < 10) { return 100; } else if (textStringLength < 12) { return 95; } else if (textStringLength < 14) { return 90; } else if (textStringLength < 16) { return 86; } else if (textStringLength < 18) { return 82; } else if (textStringLength < 20) { return 77; } else if (textStringLength < 22) { return 72; } else if (textStringLength < 24) { return 67; } else if (textStringLength < 26) { return 62; } else if (textStringLength < 28) { return 58; } else if (textStringLength < 30) { return 53; } else if (textStringLength < 32) { return 49; } else if (textStringLength < 34) { return 44; } else if (textStringLength < 37) { return 39; } else if (textStringLength < 40) { return 34; } else if (textStringLength < 42) { return 30; } else if (textStringLength < 44) { return 26; } else if (textStringLength < 47) { return 21; } else if (textStringLength < 49) { return 16; } else if (textStringLength < 51) { return 11; } else { return 7; } } else { if (textStringLength < 4) { return 114; } else if (textStringLength < 6) { return 110; } else if (textStringLength < 8) { return 105; } else if (textStringLength < 10) { return 100; } else if (textStringLength < 12) { return 97; } else if (textStringLength < 14) { return 93; } else if (textStringLength < 16) { return 88; } else if (textStringLength < 18) { return 83; } else if (textStringLength < 20) { return 79; } else if (textStringLength < 22) { return 74; } else if (textStringLength < 24) { return 71; } else if (textStringLength < 26) { return 66; } else if (textStringLength < 28) { return 61; } else if (textStringLength < 30) { return 57; } else if (textStringLength < 32) { return 53; } else if (textStringLength < 34) { return 48; } else if (textStringLength < 37) { return 44; } else if (textStringLength < 39) { return 39; } else if (textStringLength < 42) { return 34; } else if (textStringLength < 44) { return 29; } else if (textStringLength < 47) { return 24; } else if (textStringLength < 49) { return 19; } else if (textStringLength < 52) { return 14; } else { return 7; } } } else { if (line == 1) { if (textStringLength < 4) { return 113; } else if (textStringLength < 6) { return 108; } else if (textStringLength < 8) { return 103; } else if (textStringLength < 10) { return 99; } else if (textStringLength < 12) { return 94; } else if (textStringLength < 14) { return 89; } else if (textStringLength < 16) { return 84; } else if (textStringLength < 18) { return 80; } else if (textStringLength < 20) { return 75; } else if (textStringLength < 22) { return 70; } else if (textStringLength < 24) { return 65; } else if (textStringLength < 26) { return 60; } else if (textStringLength < 28) { return 55; } else if (textStringLength < 30) { return 50; } else if (textStringLength < 32) { return 46; } else if (textStringLength < 34) { return 41; } else if (textStringLength < 37) { return 36; } else if (textStringLength < 40) { return 31; } else if (textStringLength < 42) { return 26; } else if (textStringLength < 44) { return 22; } else if (textStringLength < 47) { return 17; } else if (textStringLength < 49) { return 12; } else if (textStringLength < 51) { return 7; } else { return 3; } } else { if (textStringLength < 4) { return 113; } else if (textStringLength < 6) { return 109; } else if (textStringLength < 8) { return 104; } else if (textStringLength < 10) { return 99; } else if (textStringLength < 12) { return 95; } else if (textStringLength < 14) { return 91; } else if (textStringLength < 16) { return 86; } else if (textStringLength < 18) { return 81; } else if (textStringLength < 20) { return 77; } else if (textStringLength < 22) { return 72; } else if (textStringLength < 24) { return 68; } else if (textStringLength < 26) { return 63; } else if (textStringLength < 28) { return 58; } else if (textStringLength < 30) { return 54; } else if (textStringLength < 32) { return 50; } else if (textStringLength < 34) { return 45; } else if (textStringLength < 37) { return 40; } else if (textStringLength < 39) { return 35; } else if (textStringLength < 42) { return 30; } else if (textStringLength < 44) { return 25; } else if (textStringLength < 47) { return 20; } else if (textStringLength < 49) { return 15; } else if (textStringLength < 52) { return 10; } else { return 3; } } } } //********** Build Fan Club Array ************** 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" : ""); } } // *********************************** Progressive Goal Functions ************************************** function initProgGoal(setby) { progGoalColors(); finalGoalMet = false; goalStop = false; goalPause = false; totalProgGoals = progGoalArray.desc.length; currentStaticSubject = ''; currentGoalTips = 0; currentGoal = 1; currentGoalDesc = progGoalArray.desc[currentGoal-1]; currentGoalTotal = progGoalArray.amt[currentGoal-1]; changeRoomSubject(); if (progGoalArray.desc.length <= 1) { cb.sendNotice(dashLine60 + '\n* ' + setby + ' has started the Tip Goals App.\n* There is a single goal for the show.\n' + dashLine60, '', progGoalBgColor, progGoalTxtColor, 'bold'); } else { cb.sendNotice(dashLine60 + '\n* ' + setby + ' has started the Tip Goals App.\n* There are ' + totalProgGoals + ' goals in the current show.\n' + dashLine60, '', progGoalBgColor, progGoalTxtColor, 'bold'); } recordTip(0,'bc',"",false); cb.drawPanel(); } function progGoalColors() { progGoalNoticesTxtColor = checkTextColor("Dark Red"); progGoalNoticesBgColor = checkBgColor("Cream"); if (cb.settings.progressiveGoalTextColor == 'Custom') { progGoalTxtColor = checkTextColor(cb.settings.progressiveGoalCustomTextColor); if (progGoalTxtColor == 'default') { cb.sendNotice('Progressive Goals - Error while setting the text color. It has to be in a HEX format. Using default value.', cb.room_slug, yellow, '', 'bold'); progGoalTxtColor = '#FFFFFF'; } } else { progGoalTxtColor = checkTextColor(cb.settings.progressiveGoalTextColor); } if (cb.settings.progressiveGoalBgColor == 'Custom') { progGoalBgColor = checkBgColor(cb.settings.progressiveGoalCustomBgColor); if (progGoalBgColor == 'default') { cb.sendNotice('Leaderboard - Error while setting the background color. It has to be in a HEX format. Using default value.', cb.room_slug, yellow, '', 'bold'); progGoalBgColor = '#FFFFFF'; } } else { progGoalBgColor = checkBgColor(cb.settings.progressiveGoalBgColor); } } function restartGoal() { currentGoal--; currentGoalTips = 0; finalGoalMet = false; nextGoal(); recordTip(0,'bc',"",false); cb.drawPanel(); } function resumeGoal() { //currentGoal--; //currentGoalTips = 0; finalGoalMet = false; goalStop = false; //nextGoal(); recordTip(0,'bc',"",false); cb.drawPanel(); } function updateGoal(goalnum) { currentGoalDesc = progGoalArray.desc[currentGoal-1]; currentGoalTotal = progGoalArray.amt[currentGoal-1]; changeRoomSubject(); cb.drawPanel(); } function stopGoals(setby) { finalGoalMet = true; goalStop = true; cb.drawPanel(); cb.sendNotice(dashLine60 + '\n* ' + setby + ' has disabled the Tip Goals App.\n* You can no longer tip towards the goals.\n' + dashLine60, '', progGoalBgColor, progGoalTxtColor, 'bold'); cb.changeRoomSubject('I have to go soon guys. The goals and tip menus are NOT active'); } function pauseGoals(setby) { finalGoalMet = true; goalStop = true; cb.drawPanel(); cb.sendNotice(dashLine60 + '\n* ' + setby + ' has disabled the Tip Goals App.\n* You can no longer tip towards the goals.\n' + dashLine60, '', progGoalBgColor, progGoalTxtColor, 'bold'); currentStaticSubject = 'The goals and tip menus are NOT active. '; cb.changeRoomSubject(currentStaticSubject + goalSubjectText); } function pauseGoalsOnly(setby) { finalGoalMet = true; goalStop = true; cb.drawPanel(); cb.sendNotice(dashLine60 + '\n* ' + setby + ' has disabled the Tip Goals App.\n* You can no longer tip towards the goals.\n' + dashLine60, '', progGoalBgColor, progGoalTxtColor, 'bold'); currentStaticSubject = 'The goals are NOT active. '; cb.changeRoomSubject(currentStaticSubject + goalSubjectText); } //********** Record Tip and Track Goal Progress ************** function recordTip(tipAmount,tipBy,tipnote,isFan) { if (tipBy != 'bc') { currentAppTotalGoal += tipAmount; if (!(startsWith(tipnote, 'just4mazi'))) { currentSessionTotal += tipAmount; } else { //cb.sendNotice('Thanks to ' + tipBy + '. This tip doesnt count for goal.','', '#FF9CFF', '', 'bolder'); cb.sendNotice('As requested, this tip does not apply to any active goal.','', '#FF9CFF', '', 'bolder'); } } if (!finalGoalMet) { savedCurrentGoalTips = currentGoalTips; if (!(startsWith(tipnote, 'just4mazi'))) { currentGoalTips += tipAmount; } if (currentGoalTips >= currentGoalTotal) { if (cb.settings.progressiveAutoNext == 'Auto-start next') { exceedGoal(tipAmount,tipBy); } else { goalComplete(); } } if (!(startsWith(tipnote, 'just4mazi'))) { if (!finalGoalMet) { newsubject = currentGoalDesc + ' [' + (currentGoalTotal-(currentGoalTips > currentGoalTotal ? currentGoalTotal : currentGoalTips)) + ' tokens left] '; newsubject += goalSubjectText; if (progGoalArray.desc.length >= (currentGoal + 1)) { newsubject += ' --- Next Goal: ' + progGoalArray.desc[currentGoal]; } else if (progGoalArray.desc.length > 1) { newsubject += ' --- This is the Last Goal!'; } } else { newsubject = 'All Goals Have Been Completed!!! '; currentStaticSubject = newsubject; newsubject += goalSubjectText; } cb.changeRoomSubject(newsubject); } } /* else if (!goalStop){ newsubject = 'All Goals Have Been Completed!!! '; currentStaticSubject = newsubject; newsubject += goalSubjectText; cb.changeRoomSubject(newsubject); } */ /* else { if (!(startsWith(tipnote, 'just4mazi'))) { newsubject = 'All Goals Have Been Completed!!! '; currentStaticSubject = newsubject; newsubject += goalSubjectText; cb.changeRoomSubject(newsubject); } } */ cb.drawPanel(); } function exceedGoal(tipAmount,tipBy) { excessTip = tipAmount - (currentGoalTotal - savedCurrentGoalTips); goalComplete(); if (!finalGoalMet) { nextGoal(); currentGoalTips = excessTip; if (currentGoalTips >= currentGoalTotal) { savedCurrentGoalTips = 0; exceedGoal(currentGoalTips); } } } function goalComplete() { if (progGoalArray.desc.length == 1) { cb.sendNotice(dashLine70 + '\n :CGGoal15 The Goal has been met!! :CGGoal15 \n' + dashLine70, '', progGoalBgColor, progGoalTxtColor, 'bold'); finalGoalMet = true; changeRoomSubject(); } else if ((currentGoal) < progGoalArray.desc.length) { cb.sendNotice(dashLine70 + '\n :CGGoal15 Goal #' + currentGoal + ' (' + progGoalArray.desc[currentGoal-1] + ') has been met!! :CGGoal15 \n' + dashLine70, '', progGoalBgColor, progGoalTxtColor, 'bold'); if (cb.settings.progressiveAutoNext != 'Auto-start next') { cb.sendNotice('The goal has been completed and per configuration the app is awaiting manual advance using the "/next" command', '', yellow, '', '', 'red') cb.sendNotice('The goal has been completed and per configuration the app is awaiting manual advance using the "/next" command', cb.room_slug, yellow, '', '') } } else if ((currentGoal) == progGoalArray.desc.length) { finalGoalMet = true; changeRoomSubject(); cb.sendNotice(dashLine70 + '\n :CGGoal15 Final Goal (' + progGoalArray.desc[currentGoal-1] + ') has been met!! :CGGoal15 \n *****' + getTopTipper() + ' was the top tipper!!! *****\n' + dashLine70, '', progGoalBgColor, progGoalTxtColor, 'bold'); } } function advanceGoal() { currentGoalTips = 0; goalComplete(); if (!finalGoalMet) { nextGoal(); } 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 nextGoal() { currentGoal++; currentGoalDesc = progGoalArray.desc[currentGoal-1]; currentGoalTotal = progGoalArray.amt[currentGoal-1]; changeRoomSubject(); } function changeRoomSubject() { /* if (!finalGoalMet) { newsubject = 'Current Goal: ' + currentGoalDesc + ' at ' + currentGoalTotal + ' tokens. '; newsubject += goalSubjectText; if (progGoalArray.desc.length >= (currentGoal + 1)) { newsubject += ' --- Next Goal: ' + progGoalArray.desc[currentGoal]; } else if (progGoalArray.desc.length > 1) { newsubject += ' --- This is the Last Goal!'; } } else { newsubject = 'All Goals Have Been Completed!!! '; currentStaticSubject = newsubject; newsubject += goalSubjectText; } cb.changeRoomSubject(newsubject); */ } function listGoals(group,reqby) { if (group == 'all') { outString = 'Goal List (sent to All) :'; sendto = ''; } else { outString = 'Goal List (sent to You) :'; sendto = reqby; } let i = 0; while (progGoalArray.amt[i] > 0 && progGoalArray.desc[i] != null && progGoalArray.desc[i] != '') { outString += '\nGoal #' + (i+1) + ' : ' + progGoalArray.desc[i] + ' (' + progGoalArray.amt[i] + ' tokens)'; i++; } if (i > 0) { cb.sendNotice(dashLine60 + '\n' + outString + '\n' + dashLine60, sendto, progGoalBgColor, progGoalTxtColor, 'bold'); } else { cb.sendNotice('There are no goals configured', reqby, yellow); } } //********** 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; } //********** Panel ************** 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 helpModBC(from) { cb.sendNotice('Tip Goals App Help',from,yellow); cb.sendNotice('You can setup a single goal, or multiple goals that will be progressed through in sequence as users tip. There is a configuration flag that defines if the app automatically moves from one goal to the next, or requires the use of the /next command to advance after the goal is met. If set to automatic advance, tips that exceed the goal will carry over to the next goal. If set to advance by command, the tips do not roll over.' + '\nBy default, the room subject will show the current goal amount and description, the next goal description and a configurable block of text that you can use to describe what happens at the last goal or after the goals, or even just put searchable hashtags to draw more people into the show. This room subject text can be edited using the "/setgoaltext" command as noted below.' + '\nAny changes you make are not stored permanently, they are only stored within the current session. They will be kept if you switch between app features, but not if you deactivate the app. ' + '\nAlso, you must keep the goals in sequence, and cannot add an entry that would leave an empty level. For example, if goal levels 1-3 are filled in, you can\'t add a level 5, you must add a level 4 first. ' ,from); cb.sendNotice('',from,yellow); cb.sendNotice('Tip Goals App Commands ' + '\n/stats : Display a listing of your time online (with the app running) and total tips while the App has been active.' + '\n/addtips [tokens] : This can be used to simulate users having tipped and advance the token count within a goal. Indicate the number of tokens you are adding as the [tokens] parameter, and note the value can be negative. You can add more than the current goal, but you cannot subtract less than has been tipped in the current goal.' + '\n/listgoals (also /lg) : List the current setup of the goals.' + '\n/restartgoal : If you\'d like to repeat a goal (common if you have a single goal you\'re recycling), you can use this command at any time to reset the tip count on the current goal to 0 (even if already complete)' + '\n/setgoal1, /setgoal2, /setgoal3...(thru /setgoal20) [goal] [description] : These are the commands that let you edit the goals for your show. Both the [goal] and [description] parameters must be entered every time and will update both values. Note this is also only a temporary change made within the session, it does not permanently update the launch page config.' + '\nThe 1-20 designation as part of the command identifies which entry you are modifying.' + '\nThe [goal] parameter is the new value you are setting for the goal amount. Even if you are not changing the goal (only changing the description, you must still enter the existing value for the goal.' + '\nThe [description] Parameter is the new value you are setting for the goal description. Even if you are not changing the description (only changing the goal amount), you must still enter the existing value for the description.' + '\nAn example of the syntax for this command would be "/setgoal4 400 Blow job", which would set goal 4 to be a Blow Job once you reach 400 tokens. ' + '\nNote that you can\'t make updates to the current goal or past goal, only future goals.' + '\n/rmvgoal [level] : Remove the goal entry for goal level of [level] (amount and description are both removed). Note this is also only a temporary change made within the session, it does not permanently update the launch page config. ' + '\n/setgoaltext [newsubject] : Update the text that is shown in the Room Subject between the current goal and the next goal.' + '\n/next : Used to advance to the next goal once the current goal is complete, when auto advance is turned off.' + '\n/skip : Advance to the next goal regardless of the status of the current goal.' + '\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); } } } // ******************************* 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(isFan) { populateFanClubArray(u); } switch(command) { //********* Tip Goal 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; } case '/next': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (finalGoalMet) { cb.sendNotice('Command cannot be used once all goals have been completed.', u, yellow); } else if (currentGoalTips < currentGoalTotal) { cb.sendNotice('Command cannot be used during goal, it should be used only to manually advance a goal once complete if the auto-advance is off. The /skip command can be used to bypass the rest of a goal.', u, yellow); } else { advanceGoal(); cb.sendNotice('You have manually advanced to the next goal.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/skip': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (finalGoalMet) { cb.sendNotice('Command cannot be used once all goals have been completed.', u, yellow); } else { advanceGoal(); cb.sendNotice('You have skipped the remainder of the current goal and advanced to the next.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/addtips': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (commandVar1 == 0 || isNaN(commandVar1)) { cb.sendNotice('The parameter is the tip amount to be added to the current tip count, and must be a positive or negative number other than 0. For example, use "/addtips 100" to simulate a user having tipped 100 tokens.',u,yellow); } else if (finalGoalMet) { cb.sendNotice('Command cannot be used once all goals, cycles or sequences have been completed.', u, yellow); } else if (commandVar1 < 0 && Math.abs(commandVar1) > currentGoalTips) { cb.sendNotice('You cannot subtract more tokens than have been tipped for the current goal.', u, yellow); } else { recordTip(commandVar1,'bc',"",isFan); if (commandVar1 > 0) { cb.sendNotice('You have added ' + commandVar1 + ' tokens.', u, yellow); } else { cb.sendNotice('You have subtracted ' + Math.abs(commandVar1) + ' tokens.', u, yellow); } } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/stats': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsStats == 'Yes')) { cb.sendNotice('Current Session Stats: \n \u21D2 Tip Goal App Time Online......... ' + timeOnline() + '\n \u21D2 Total Tips................................ ' + currentSessionTotal + ' tokens ($' + Number(currentSessionTotal*.05).toFixed(2) + ' @ 5 cents per token', u, yellow, '', 'bold'); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/lg': case '/listgoals': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { if (!message[1] || message[1] == 'all') { listGoals(message[1],u) } else { cb.sendNotice('Invalid parameter provided, the parameter should be left blank to send the list to only the requester, or can be set to "all" to send to the entire room.', u, yellow); } } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/resetapp': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { initProgGoal(u); cb.sendNotice('You have reset the App and started the goal show again at the first goal.', u, yellow); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use the "/resetapp" command.', u, yellow); } break; } case '/stopgoals': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { stopGoals(u) cb.sendNotice('You have stopped all goals.', u, yellow); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use the "/stopgoals" command.', u, yellow); } break; } case '/pausegoals': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { pauseGoalsOnly(u) cb.sendNotice('You have paused the goals.', u, yellow); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use the "/pausegoals" command.', u, yellow); } break; } case '/gohome': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { stopGoals(u) cb.sendNotice('You have stopped all goals.', u, yellow); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use the "/gohome" command.', u, yellow); } break; } case '/lunch': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { goalSubjectText = cb.settings.progressiveRoomSubjectSfx; pauseGoals(u) cb.sendNotice('You have paused the goals.', u, yellow); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use the "/lunch" command.', u, yellow); } break; } case '/uselushmenu': { cmd = 1; if (isMod || isBC) { if (message[1] == 'on') { goalSubjectText = '#lovense ' + cb.settings.progressiveRoomSubjectSfx; } else if (message[1] == 'off') { goalSubjectText = cb.settings.progressiveRoomSubjectSfx; } changeRoomSubject(); if (!finalGoalMet) { newsubject = currentGoalDesc + ' [' + (currentGoalTotal-(currentGoalTips > currentGoalTotal ? currentGoalTotal : currentGoalTips)) + ' tokens left] '; newsubject += goalSubjectText; if (progGoalArray.desc.length >= (currentGoal + 1)) { newsubject += ' --- Next Goal: ' + progGoalArray.desc[currentGoal]; } else if (progGoalArray.desc.length > 1) { newsubject += ' --- This is the Last Goal!'; } cb.changeRoomSubject(newsubject); } else if (!goalStop){ newsubject = 'All Goals Have Been Completed!!! '; newsubject += goalSubjectText; cb.changeRoomSubject(newsubject); } else { newsubject = currentStaticSubject; newsubject += goalSubjectText; cb.changeRoomSubject(newsubject); } //recordTip(0,'bc',"",false); } else { cb.sendNotice('Only moderators and broadcasters are able to use that command.',u,appNoticeColor); } break; } case '/restartgoal': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { restartGoal(); cb.sendNotice('You have restarted the current goal.', u, yellow); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/resumegoal': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { resumeGoal(); cb.sendNotice('You have resumed the current goal.', u, yellow); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/resume': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { resumeGoal(); cb.sendNotice('You have resumed the current goal.', u, yellow); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/setgoal1': case '/setgoal2': case '/setgoal3': case '/setgoal4': case '/setgoal5': case '/setgoal6': case '/setgoal7': case '/setgoal8': case '/setgoal9': case '/setgoal10': case '/setgoal11': case '/setgoal12': case '/setgoal13': case '/setgoal14': case '/setgoal15': case '/setgoal16': case '/setgoal17': case '/setgoal18': case '/setgoal19': case '/setgoal20': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { goalnum = parseInt(message[0].substring(8)); if (commandVar1 <= 0 || isNaN(commandVar1)) { cb.sendNotice('The first parameter is the new amount for goal ' + goalnum + ' and has be be a number greater than 0. For example, "/setgoal' + goalnum + ' 300 Shirt Off" to set goal ' + goalnum + ' to Shirt off at 300 tokens.', u, yellow); } else if (goalnum == currentGoal && commandVar1 < currentGoalTips) { cb.sendNotice('The current goal cannot be updated to an amount less than what has already been tipped for this goal. The "/restartgoal" command can be used to clear the current goal tip totals, but this is not recommended.', u, yellow); } else if (!message[2]) { cb.sendNotice('The second parameter is the description of goal ' + goalnum + ' (can be multiple words). For example, "/setjar' + goalnum + ' 300 Shirt Off" to set goal ' + goalnum + ' to Shirt off at 300 tokens.', u, yellow); } else if (goalnum > 1 && !progGoalArray.amt[goalnum-2] >= 1) { cb.sendNotice('You cannot skip goal levels. If setting a goal for level ' + goalnum + ', then level ' + (goalnum-1) + ' must already have a goal defined.', u, yellow); } else { for (let i = 2; i < message.length; i++) { if (i === 2) { label = message[i]; } else { label += " " + message[i]; } } progGoalArray.amt[goalnum-1] = commandVar1; progGoalArray.desc[goalnum-1] = label; updateGoal(goalnum); cb.sendNotice('Goal ' + goalnum + ' was added/updated to the amount of ' + commandVar1 + ' and a description of "' + label + '".', u, yellow); cb.sendNotice(u + ' added/updated Progressive Goal #' + goalnum + ' to the goal amount of ' + commandVar1 + ' and a description of "' + label + '".', '', yellow, '', '', 'red'); cb.sendNotice(u + ' added/updated Progressive Goal #' + goalnum + ' to the goal amount of ' + commandVar1 + ' and a description of "' + label + '".', cb.room_slug, yellow); } recordTip(0,'bc',"",false); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/rmvgoal': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { goalnum = message[1]; if (isNaN(goalnum) || goalnum < 1 || goalnum > 20) { cb.sendNotice('The first parameter is the goal level being removed, and musy be a number from 1 to 20 to indicate the goal level number that should be removed. For example, "/rmvgoal 3" will remove the goal and description info for level 3.', u, yellow); } else if (goalnum > progGoalArray.amt.length) { cb.sendNotice('There is no goal entry at level ' + goalnum + ', there are currently only entries up to goal level ' + progGoalArray.amt.length + '.', u, yellow); } else { progGoalArray.amt.splice((goalnum-1),1); progGoalArray.desc.splice((goalnum-1),1); updateGoal(goalnum); cb.sendNotice('Progressive Goal #' + goalnum + ' was removed from the goal list', u, yellow); cb.sendNotice(u + ' removed Progressive Goal #' + goalnum + ' from the goal list', '', yellow, '', '', 'red'); cb.sendNotice(u + ' removed Progressive Goal #' + goalnum + ' from the goal list', cb.room_slug, yellow); } recordTip(0,'bc',"",false); } else { cb.sendNotice('Only broadcasters and moderators with sufficient authority are able to use that command.', u, yellow); } break; } case '/setgoaltext': { cmd = 1; if (isBC || (isMod && cb.settings.allowModsAuthority == 'Yes')) { goalSubjectText = msg['m'].substring(13).trim() if (goalSubjectText != '' && goalSubjectText != null) { changeRoomSubject(); recordTip(0,'bc',"",false); } 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); } break; } //********* Help Menu case '/goalshelp': { cmd = 1; if (isMod || isBC) { helpModBC(u); } else { cb.sendNotice('Only broadcasters and moderators are able to use the help command, there are no commands available to general users.', u, yellow); } 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 Tip Goals 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); } } } 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(isFan) { populateFanClubArray(u); } // **** General Entry Message if(cb.settings.enableEntryMessage == 'Yes') { if (progGoalArray.desc.length <= 1) { cb.sendNotice(cb.settings.entryMessage + '\n* The Progressive Goal Feature is currently active, and there is a single goal set up for the show.', u, progGoalBgColor, progGoalTxtColor, 'bold'); } else { cb.sendNotice(cb.settings.entryMessage + '\n* The Progressive Goal Feature is currently active, and there are ' + totalProgGoals + ' goals set up for the show.', u, progGoalBgColor, progGoalTxtColor, 'bold'); } } }); } // *********************************** Actions upon leaving ************************************** { cb.onLeave(function(user) { var u = user.user; }); } // *********************************** 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 (!finalGoalMet) { panel.row1_value = currentGoalDesc + ': ' + (currentGoalTips > currentGoalTotal ? currentGoalTotal : currentGoalTips) + ' / ' + currentGoalTotal + ' \u25FE (' + (currentGoalTotal-(currentGoalTips > currentGoalTotal ? currentGoalTotal : currentGoalTips)) + ' left)'; leftjust1 = leftJustify(panel.row1_value,1); panel.row2_value = 'Progress: ' + goalBar((currentGoalTips > currentGoalTotal ? currentGoalTotal : currentGoalTips),currentGoalTotal) + ' (' + Math.floor((currentGoalTips > currentGoalTotal ? currentGoalTotal : currentGoalTips)/currentGoalTotal*100) + ' %)'; leftjust2 = 42; if (cb.settings.showTotals == 'Yes') { panel.row3_value = 'Total Goal Show Tips: ' + currentAppTotalGoal; } else { panel.row3_value = 'At Goal: ' + currentGoalDesc; } leftjust3 = leftJustify(panel.row3_value,3); } else if (!goalStop) { panel.row1_value = 'All Goals Completed!'; leftjust1 = leftJustify(panel.row1_value,1); panel.row2_value = 'Progress: ' + goalBar(100,100) + ' (100 %)'; leftjust2 = 42; if (cb.settings.showTotals == 'Yes') { panel.row3_value = 'Total Goal Show Tips: ' + currentAppTotalGoal; leftjust3 = leftJustify(panel.row3_value,3); } else { panel.row3_value = ''; } } else { panel.row1_value = 'Goals are NOT active'; leftjust1 = leftJustify(panel.row1_value,1); panel.row2_value = ''; leftjust2 = 42; if (cb.settings.showTotals == 'Yes') { panel.row3_value = 'Total Goal Show Tips: ' + currentAppTotalGoal; leftjust3 = leftJustify(panel.row3_value,3); } else { panel.row3_value = ''; } } if (panel.row1_value.length > 44) { panel.layers = [ {'type': 'image', 'fileID': backgroundImage}, { 'type': 'text', 'text': panel.row1_value, 'top': topjust1, 'left': leftjust1, 'font-size': 11, '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, }, ] } else { 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; var tipnote = tip['message'] // ***** 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,tipnote,isFan); }); } // *********************************** Initialize ************************************** { if (initialize == 0) { var BC = cb.room_slug; // *** Load Array for Progressive Goals for (let i = 1; i <= 20; i++) { goalDesc = this["progressiveGoalDescription"+i]; goalAmt = this["progressiveGoalAmount"+i]; goalRecyc = this["progressiveGoalRecycle"+i]; if(goalDesc != '' && goalDesc != null && goalAmt != '' && goalAmt != null) { progGoalArray.desc.push(goalDesc); progGoalArray.amt.push(goalAmt); progGoalArray.recyc.push(goalRecyc); } } //*** Initialize background if (cb.settings.panelBackground != 'default - no image') { if (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); } } else { customPanel = false; } initProgGoal(BC); ultraAppStartTime = new Date(); initialize = 1; } }
© Copyright Chaturbate 2011- 2024. All Rights Reserved.