Apps Home
|
Create an App
testingsomething
Author:
justasailor
Description
Source Code
Launch App
Current Users
Created by:
Justasailor
/* Name: Multi-Goal Author: mx2k6 Version History ============================================ v1.0 08/02/2013: First release v1.1 22/02/2013: Added /stats and /reset commands. See Description for more v1.2 08/03/2013: Added /skip (thanks to jcummings) v1.3 12/03/2013: Added /goals command for moderators and /upnext command for broadcasters. See Description for more v1.4 13/03/2013: Minor cleanup to make code more readable. Modified /upnext to actually use the broadcaster's message instead of chat notice v1.5 07/04/2013: Added some debugging code so I can get to the bottom of why chat commands don't always respond v1.6 13/04/2013: Fixed an embarrassing bug where all broadcaster and debug commands were ignored v1.7 20/04/2013: Tipper leaderboard now available on /stats output - see who your top 10 tippers are v1.8 21/04/2013: Goal timer function now available - /timer x now sets a countdown to when the goal needs tp be in by v1.9 05/05/2013: Stats junkies rejoice! /stats will now display an approximate token count per minute, to help you work out whether you'll make more tokens camming or flipping burgers. Also, tip goal king now stands out more! v1.10 05/05/2013: Now optionally highlight your highest total tipper (light purple currently - make suggestions people!) so the one who contributes the most can show off too! v1.11 05/05/2013: Timer stability improvements. Added timer debugging code. Type '/verbose' (broadcaster ONLY) to get precise dates and times of timer interval for when requesting support v1.12 18/05/2013: Clarified stats text relating to per minute figures. Changed highest tipper to no longer have a green "fanclub" name until such time as we can change the colour to a custom one v1.13 31/05/2013: Added ability for high tippers to "opt out" of being highlighted by typing "/donotwant" after they tip v1.14 05/06/2013: Added ability to directly manipulate tokens toward goals with /addtokens and /removetokens. See /help for more v1.15 02/07/2013: Timer now automatically clears if a goal is met rather than continuing on to zero v1.16 03/07/2013: Added a sixth goal... HOW MANY DO YOU PEOPLE NEED?!? Also, fixed a bug where total highest tipper got notified even when their highlight is disabled v1.17 04/07/2013: Allowed looping final goal if broadcaster chooses to v1.18 05/07/2013: Time's up message (when timer is in use) now uses a graphic to draw attention to it v1.19 19/07/2013: Notices (where applicable) now stand out more v1.20 10/08/2013: Colour schemes for the tipper highlights (thanks to ashley93bad, you're awesome man!), bug fixes for opt-out v1.21 17/08/2013: More colour schemes added v1.22 28/09/2013: Fixed an issue with /skip which could reduce ongoing goal token quantities. Added manual progression mode- app eats tips once each goal is met until superuser types /continue command Credits and Props ============================================ Based on the bog standard tip goal app, with multiple goals, tip goal king, goal timers, some random crap and less general suckfulness. */ var APP_VERSION = 1.22; var APP_DEBUG = false; var TOTAL_GOALS = 6; var time_started = null; //var cb = {}; // vars var cool = new Array(); var friendMembers = new Array(); var coolKids = new Array(); var tempStr = ""; var actual_total_tipped = 0; var total_tipped = 0; var current_total_tipped = 0; var goal_progression_halted = false; var high_tip_username = null; var high_tip_amount = 0; var high_total_username = null; var high_total_amount = 0; var low_tip_username = null; var low_tip_amount = 0; var last_tip_username = null; var last_tip_amount = 0; var high_tip_highlight_optout = false; var high_total_highlight_optout = false; var all_tippers = []; var subject_is_final = false; var current_goal = 1; var final_goal_met = false; var startup_time = null; var spit_verbose_output = false; var tipper_colours = { legacy: { high_tipper_colour: '#9F9', high_total_colour: '#CCF' }, sky: { high_tipper_colour: '#C2DFFF', high_total_colour: '#A1C2E7' }, pink: { high_tipper_colour: '#FAAFBE', high_total_colour: '#F9A7B0' }, forest: { high_tipper_colour: '#57E964', high_total_colour: '#54C571' }, ocean: { high_tipper_colour: '#80F7ED', high_total_colour: '#29DACB' }, amethyst: { high_tipper_colour: '#EC89FF', high_total_colour: '#C38ECE' }, sunshine: { high_tipper_colour: '#F1F170', high_total_colour: '#FFFF25' }, }; var goalSettings = []; for (var gSetting = 1; gSetting <= TOTAL_GOALS; gSetting++) { goalSettings.push({ name: 'goal_' + gSetting + '_tokens', label: 'Goal ' + gSetting + ' Token Amount', type: 'int', minValue: 1, defaultValue: 200, required: (gSetting === 1) }); goalSettings.push({ name: 'goal_' + gSetting + '_description', label: 'Goal ' + gSetting + ' Description', type: 'str', minLength: (gSetting === 1 ? 1 : 0), maxLength: 255, required: (gSetting === 1) }); } cb.settings_choices = [ {name: 'coolKidList', label: 'List of current Cool Kids, separated by space (and they need to be the CB username exactly)', type: 'str', minLength: 0, maxLength: 10240, required: false, defaultValue: 'justasailor theb1sh0p flyordie ikwydls2' }, { name: 'useCoolColor', type: 'choice', label: 'Change highlight color for Cool?', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes' }, { name: 'coolColor', label: 'Highlight color to use for Cool', type: 'choice', choice1: 'Green FF4500', choice2: 'Purple BA55D3', choice3: 'Orange FFA500', choice4: 'Blue 4169E1', choice5: 'Red FF0000', choice6: 'Yellow FFD700', defaultValue: 'Green FF4500' }, { name: 'useFriendColor', type: 'choice', label: 'Change text color for friends?', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes' }, { name: 'friendList', label: 'List of friends, separated by space (and they need to be the CB username exactly)', type: 'str', minLength: 0, maxLength: 10240, required: false, defaultValue: 'tablesalt90' }, { name: 'friendColor', label: 'Color to use for friends', type: 'choice', choice1: 'Green 078102', choice2: 'Purple 8B008B', choice3: 'Orange FF4500', choice4: 'Blue 0000CD', choice5: 'Red FF0000', defaultValue: 'Green 078102' }, { name: 'last_goal_loop', label: 'Loop Last Goal', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No' }, { name: 'finality_message', label: 'Final Goal Met Subject', type: 'str', minLength: 1, maxLength: 255, defaultValue: 'Goal reached! Thanks to all tippers!' }, { name: 'progression_mode', label: 'Progression Mode', type: 'choice', choice1: 'Automatic', choice2: 'Manual', defaultValue: 'Automatic' }, { name: 'tipper_colour_scheme', label: 'Tipper Highlight Colour Scheme', type: 'choice', choice1: 'Legacy', choice2: 'Sky', choice3: 'Ocean', choice4: 'Pink', choice5: 'Forest', choice6: 'Amethyst', choice7: 'Sunshine', defaultValue: 'Legacy' }, { name: 'highlight_goal_king', label: 'Highlight highest tipper', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes' }, { name: 'highlight_total_king', label: 'Highlight highest total tipper', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No' }, { name: 'show_timer_in_subject', label: 'Add time remaining to subject if running?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No' }, { name: 'mod_allow_broadcaster_cmd', label: 'Allow mods to use broadcaster commands?', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No' } ]; cb.settings_choices = goalSettings.concat(cb.settings_choices); var settings = { progression_mode_manual: false, goals: [], loop_last_goal: false, finality_message: 'Goal reached! Thanks to all tippers!', highlight_theme: 'legacy', highlight_highest_tipper: false, highlight_highest_total: false, timer_in_subject: false, allow_mod_superuser_cmd: false, goals_defined: 0, }; function verboseMessage(message, user) { debugLog("Verbose debug message: " + message); if (spit_verbose_output) { cb.chatNotice("[Verbose] " + message, user); } } function debugLog(message) { if (APP_DEBUG) cb.log(message); } var goalTimer = { secondsDown: 60, timeRemaining: 0, timerRunning: false, timerReallyRunning: false, spamMessage: "Time's running out! Only %time minutes left to tip to the goal!", timesUpMessage: ":timesup Sorry, this goal was not met.", hookOnTimer: function () { }, startTimer: function (minutes) { verboseMessage("Timer started at " + new Date().toString(), cb.room_slug); this.timeRemaining = minutes; this.timerRunning = true; this.timerReallyRunning = true; this.hookOnTimer(); this.announce(); cb.setTimeout(function () { goalTimer.onTimer(); }, 60000); }, stopTimer: function () { verboseMessage("Timer stopped at " + new Date().toString(), cb.room_slug); this.timerRunning = false; this.hookOnTimer(); }, onTimer: function () { this.timerReallyRunning = false; if (this.timerRunning) { verboseMessage("Timer interval reached at " + new Date().toString(), cb.room_slug); this.timeRemaining--; this.hookOnTimer(); this.announce(); if (this.timeRemaining === 0) { verboseMessage("Timer expired at " + new Date().toString(), cb.room_slug); this.timerRunning = false; } else { this.timerReallyRunning = true; cb.setTimeout(function () { goalTimer.onTimer(); }, 60000); } } }, getExtraText: function () { if (this.timerRunning) { return this.timeRemaining + " min left"; } else { return ""; } }, announce: function () { if (this.timeRemaining > 0 && !settings.timer_in_subject) { cb.chatNotice(this.spamMessage.replace("%time", this.timeRemaining), '', '#FFFFFF', '#FF0000', 'bold'); } else if (this.timeRemaining === 0) { cb.chatNotice(this.timesUpMessage, '', '#FFFFFF', '#FF0000', 'bold'); } } }; function getCurrentGoalDescription() { return settings.goals[current_goal].description; } function getPreviousGoalAmount() { return settings.goals[current_goal - 1].tokens; } function getCurrentGoalAmount() { return settings.goals[current_goal].tokens; } function getSumTotalGoal() { var totalGoal = 0;; for (var i = 1; i <= settings.goals_defined; i++) { totalGoal += settings.goals[i].tokens; } return totalGoal; } function getAllGoals() { var allGoals = ""; for (var i = 1; i <= settings.goals_defined; i++) { allGoals += settings.goals[i].description + ' (' + settings.goals[i].tokens + ' tokens)\n'; } allGoals += "-- Tokens if all goals met: " + getSumTotalGoal(); return allGoals; } function getLeaderBoard() { var leaderboard = ""; for (var idx = 0; idx < all_tippers.length && idx < 10; idx++) { if (all_tippers[idx] !== undefined) { leaderboard += all_tippers[idx].name + ' (' + all_tippers[idx].tokens + ')\n'; } } return leaderboard; } function getTokensPerMinute() { var now = new Date(); var timespan = now - time_started; var tokensPerMin = ((Math.round(actual_total_tipped * 10) / 10) / (Math.round(timespan / 1000 / 60 * 10) / 10)); return (Math.round(tokensPerMin * 10) / 10); } function getDollarsPerMinute() { return (0.05 * Math.floor(getTokensPerMinute())).toFixed(2); } function skipGoal() { current_goal++; current_total_tipped = 0; checkFinality(); updateRoomSubject(); cb.drawPanel(); } function continueProgression() { if (!settings.progression_mode_manual || !goal_progression_halted) return; goal_progression_halted = false; skipGoal(); } function getNextGoalAnnouncement() { return getGoalTokensRemaining() + " tokens to next goal: " + settings.goals[current_goal + 1].description; } function checkFinality() { if (current_goal > settings.goals_defined) { debugLog("Current goal is greater than goals defined"); if (settings.loop_last_goal) { current_goal--; final_goal_met = false; } else { final_goal_met = true; } } else { final_goal_met = false; } } function getGoalTokensRemaining() { var r = getCurrentGoalAmount() - current_total_tipped; return (r < 0) ? 0 : r; } function formatUsername(val) { return (val === null || val === undefined) ? "--" : val.substring(0, 12); } function updateRoomSubject() { var newSubject = ""; if (subject_is_final && final_goal_met) { return; } if (final_goal_met) { debugLog("Final goal met - notifying broadcaster and setting finality"); cb.chatNotice("Your final goal has been met! You can type '/reset' to start again from zero.", cb.room_slug, '#FFFFFF', '#FF0000', 'bold'); newSubject = settings.finality_message; subject_is_final = true; } else { newSubject = getCurrentGoalDescription() + " [" + getGoalTokensRemaining() + " tokens remaining]"; if (settings.timer_in_subject === "Yes" && goalTimer.timerRunning) { newSubject += " (" + goalTimer.getExtraText() + ")"; } subject_is_final = false; } debugLog("Changing subject to: " + newSubject); cb.changeRoomSubject(newSubject); } function recordTip(username, tokens, countsToActual) { var tipperFound = false; var dontSetSubject = false; total_tipped += tokens; current_total_tipped += tokens; if (countsToActual) { actual_total_tipped += tokens; last_tip_amount = tokens; last_tip_username = username; if (tokens > high_tip_amount) { if (high_tip_username !== username && settings.highlight_highest_tipper) { sendInfoMessage("You are now the highest tipper. If you do not want your name highlighted in chat, simply type the command '/donotwant' (without quotes) now", username); high_tip_highlight_optout = false; } high_tip_amount = tokens; high_tip_username = username; } if (tokens <= low_tip_amount || low_tip_amount == 0) { low_tip_amount = tokens; low_tip_username = username; } for (var idx = 0; idx < all_tippers.length; idx++) { if (all_tippers[idx].name == username) { tipperFound = true; all_tippers[idx].tokens += tokens; break; } } if (!tipperFound) { all_tippers.push({ name: username, tokens: tokens }); } all_tippers.sort(function (a, b) { return b.tokens - a.tokens; }); if (high_total_username !== all_tippers[0].name && settings.highlight_highest_total) { sendInfoMessage("You are now the highest total tipper. If you do not want your name highlighted in chat, simply type the command '/donotwant' (without quotes) now", all_tippers[0].name); high_total_highlight_optout = false; } high_total_username = all_tippers[0].name; high_total_amount = all_tippers[0].tokens; } if (!final_goal_met) { while (current_total_tipped >= getCurrentGoalAmount()) { if (current_total_tipped == getCurrentGoalAmount() && settings.progression_mode_manual) dontSetSubject = true; if (!settings.progression_mode_manual || current_goal == settings.goals_defined) { debugLog("Total tipped has exceeded current goal - incrementing step"); if (goalTimer.timerRunning) goalTimer.stopTimer(); current_total_tipped = current_total_tipped - getCurrentGoalAmount(); sendSuccessMessage("* Goal met: " + getCurrentGoalDescription(), cb.room_slug); current_goal++; checkFinality(); } else { debugLog("Total tipped has exceeded current goal, but we are halting as progression mode is manual"); if (goal_progression_halted) { dontSetSubject = true; } else { sendSuccessMessage("* Goal met: " + getCurrentGoalDescription() + " - type '/continue' to move on", cb.room_slug); } goal_progression_halted = true; current_total_tipped = getCurrentGoalAmount(); break; } if (final_goal_met) break; } } while (current_total_tipped < 0) { debugLog("Total subtracted has gone below zero [" + current_total_tipped + "] - decrementing step"); current_total_tipped = current_total_tipped + getPreviousGoalAmount(); sendSuccessMessage("* Goal unmet: " + getCurrentGoalDescription(), cb.room_slug); current_goal--; checkFinality(); } checkFinality(); cb.drawPanel(); if (!dontSetSubject) { updateRoomSubject(); } } function goalTimerOnTimer() { cb.drawPanel(); if (settings.timer_in_subject) { updateRoomSubject(); } } function reset() { debugLog("Resetting all goals"); low_tip_amount = 0; high_tip_amount = 0; last_tip_amount = 0; high_total_amount = 0; low_tip_username = null; high_tip_username = null; last_tip_username = null; high_total_username = null; current_goal = 1; total_tipped = 0; current_total_tipped = 0; final_goal_met = false; all_tippers = []; cb.drawPanel(); updateRoomSubject(); } cb.onTip(function (tip) { recordTip(tip.from_user, tip.amount, true); }); cb.onDrawPanel(function (user) { debugLog("Drawing panel (final_goal_met: " + final_goal_met + ")"); var panel = {}; if (final_goal_met) { panel = { 'template': '3_rows_of_labels', 'row1_label': 'Total Tips:', 'row1_value': total_tipped, 'row2_label': 'Highest Tip:', 'row2_value': formatUsername(high_tip_username) + ' (' + high_tip_amount + ')', 'row3_label': 'Latest Tip Received:', 'row3_value': formatUsername(last_tip_username) + ' (' + last_tip_amount + ')' }; } else { panel = { 'template': '3_rows_of_labels', 'row1_label': 'Tip Received / Goal (Total):', 'row1_value': current_total_tipped + ' / ' + getCurrentGoalAmount() + ' (' + total_tipped + ')', 'row2_label': 'Highest Tip:', 'row2_value': formatUsername(high_tip_username) + ' (' + high_tip_amount + ')', 'row3_label': 'Latest Tip Received:', 'row3_value': formatUsername(last_tip_username) + ' (' + last_tip_amount + ')' }; if (goalTimer.timerRunning) { panel.row3_label = 'Time Remaining:'; panel.row3_value = goalTimer.getExtraText(); } } return panel; }); function buildStatsOutput(includeExtraInfo) { var output = ""; output += "Sum total goal: " + getSumTotalGoal() + "\n"; output += "Total tipped so far: " + total_tipped + "\n"; output += "Total goal remaining: " + (getSumTotalGoal() - total_tipped) + "\n"; output += "Tokens/min: " + getTokensPerMinute() + "\n"; if (includeExtraInfo) { output += "Total actual tipped (disregarding resets): " + actual_total_tipped + "\n"; output += "Dollars/min (assuming $0.05/token): $" + getDollarsPerMinute() + "\n"; } output += "Disclaimer: per minute figures EXCLUDE private shows, group shows, and other non-tip token gains\n"; output += "=== Tip Stats ===\n"; output += "Highest total tips: " + high_total_amount + " from " + high_total_username + "\n"; output += "Awesomest tip: " + high_tip_amount + " from " + high_tip_username + "\n"; output += "Stingiest tip: " + low_tip_amount + " from " + low_tip_username + "\n"; output += "Most recent tip: " + last_tip_amount + " from " + last_tip_username + "\n"; output += "=== Leaderboard (Top 10) ==="; output += getLeaderBoard(); return output; } function buildHelp() { var broadcasterOnlyText = " (broadcaster only)"; if (settings.allow_mod_superuser_cmd === "Yes") { broadcasterOnlyText = ""; } var output = ""; output += "/stats - displays token statistics, including the sum total goal, amount so far, and misc information\n"; output += "/goals - displays all goals in in order\n"; output += "/upnext - announces the next goal to the room" + broadcasterOnlyText + "\n"; if (settings.progression_mode_manual) { output += "/continue - progresses on to the next goal\n"; } output += "/skip - skips the current goal, and moves onto the next one" + broadcasterOnlyText + "\n"; output += "/reset - resets goal status back to zero" + broadcasterOnlyText + "\n"; output += "/timer x - sets goal timer to x minutes" + broadcasterOnlyText + "\n"; output += "/timer stop - stops the running goal timer" + broadcasterOnlyText + "\n"; output += "/setcolors xxx - sets the colour scheme for high tipper highlighting" + broadcasterOnlyText + "\n"; output += "/addtokens x - Adds an x token tip to the goal, incrementing if necessary (broadcaster only)\n"; output += "/remove tokens x - Removes an x token tip from the goal, decrementing if necessary (broadcaster only)\n"; output += "=== For more help ===\n"; output += "View the CB app page: http://chaturbate.com/apps/app_details/tip-multi-goal/\n"; output += "Email the developer: c9max69" + "@" + "gmail.com"; return output; } function sendErrorMessage(message, username) { cb.chatNotice(message, username, '#FFFFFF', '#FF0000', 'bold'); } function sendInfoMessage(message, username) { cb.chatNotice(message, username, '#FFFFFF', '#000000', 'bold'); } function sendSuccessMessage(message, username) { cb.chatNotice(message, username, '#FFFFFF', '#00FF00', 'bold'); } cb.onMessage(function (msg) { var i = 0; var key = null; name = message['user']; msg = message['m']; commandProcessed = false; helpMsg = "Melloncollae and thier mods may use the following commands:\n /coolList = list of Cool Kids Members\n" + "/friendlist = list of friends that type in color\n /addfriend name = add name to the friend list (temp)\n" + "/addcrew name = add name to the cool kid list (temp, model only)\n" + "*** NOTE: To make names stick add them in the bot config."; var divStr = ""; var isMod = message['is_mod']; var isFan = message['in_fanclub']; var isModel = (name == cb.room_slug); var hasTokens = message['has_tokens']; var hasTipped = message['tipped_recently']; var isGrey = !(hasTokens || isMod || isModel || isFan); var modelName = cb.room_slug; // handle commands from model and mods if ( isModel || isMod) { if (msg.indexOf('/crewlist') > -1) { msg['X-Spam'] = true; message['background'] = '#FF4500'; message['c'] = '#000000'; message['m'] = "Let me fetch that list for ya " + name + "!"; showCrewMembers(); commandProcessed = true; } else { if (msg.indexOf('/friendlist') > -1) { msg['X-Spam'] = true; message['background'] = '#FF4500'; message['c'] = '#000000'; message['m'] = "Comming right up " + name + "!"; showFriendMembers(); commandProcessed = true; } else { if (msg.indexOf('/addfriend') > -1) { msg['X-Spam'] = true; newFriend = addFriend(msg); message['background'] = '#FF4500'; message['c'] = '#000000'; message['m'] = name + " just added " + newFriend + " to the friend list!"; commandProcessed = true; } else { if (msg.indexOf('/420help') > -1) { msg['X-Spam'] = true; divStr = makeDiv('*', 50, 50); cb.chatNotice(divStr + '\n Melloncollae\'s Cool Kids Bot\nCreated by tablesalt90\nModified by JustASailor\n' + divStr + '\n' + helpMsg + '\n' + divStr); } else { if (msg.indexOf('/addcrew') > -1) { if ( isModel ) { msg['X-Spam'] = true; newCrew = addCrew(msg); message['background'] = '#FF4500'; message['c'] = '#000000'; message['m'] = name + " just added " + newCrew + " to the Cool Kid Table!"; commandProcessed = true; } else { cb.chatNotice('Nice try ' + name + '! Only ' + modelName + ' can add peeps to the cool kid table!','','#FF0000'); } } } } } } } // process modifiers for friends and crew members if (!commandProcessed) { // color background/foreground and tag if crew member if ( isCool(name) ) { if ( useCoolColor ) { message['background'] = '#' + coolColor; message['c'] = '#000000'; } message['m'] = "[Cool Kid] " + message['m']; } // color foreground if friend if ( isFriend(name) ) { if ( useFriendColor ) { message['c'] = '#' + friendColor; } message['m'] = "[Friend] " + message['m']; } } /* Tip king highlighting */ if (settings.highlight_highest_total && msg.user === high_total_username && !high_total_highlight_optout) { msg.background = tipper_colours[settings.highlight_theme].high_total_colour; message['m'] = '[:king ]' + message['m']; } else if (settings.highlight_highest_tipper && msg.user === high_tip_username && !high_tip_highlight_optout) { msg.background = tipper_colours[settings.highlight_theme].high_tipper_colour; message['m'] = '[:king ]' + message['m']; } /* If it starts with a /, suppress that shit and assume it's a command */ if (msg.m.substring(0, 1) === "/") { msg["X-Spam"] = true; if (msg.user === cb.room_slug || msg.is_mod) { /* Broadcaster or mod commands */ if (msg.m.substring(1) === "stats") { debugLog("Stats command received from " + msg.user); sendInfoMessage("=== Goal Statistics ===", msg.user); cb.chatNotice(buildStatsOutput(isSuperuser(msg.user, msg.is_mod)), msg.user); } else if (msg.m.substring(1) === "goals") { debugLog("Goals command received from " + msg.user); sendInfoMessage("=== All Goals ===", msg.user); cb.chatNotice(getAllGoals(), msg.user); } else if (msg.m.substring(1) === "help") { debugLog("Help command received from " + msg.user); sendInfoMessage("=== Help ===", msg.user); cb.chatNotice(buildHelp(), msg.user); } } if (isSuperuser(msg.user, msg.is_mod)) { /* Broadcaster only commands, unless the option to allow mods to use them is enabled */ if (msg.m.substring(1) === "reset") { debugLog("Reset command received from " + msg.user); reset(); } else if (msg.m.substring(1) === "skip") { debugLog("Skip command received from " + msg.user); skipGoal(); } else if (msg.m.substring(1) === "upnext") { debugLog("Upnext command received from " + msg.user); sendSuccessMessage("* Your message has been eaten, and users have been informed of the next goal.", msg.user); msg.m = getNextGoalAnnouncement(); msg["X-Spam"] = false; } else if (msg.m.substring(1) === "continue") { debugLog("Continue command received from " + msg.user); continueProgression(); } else if (msg.m.substring(1, 6) === "timer") { debugLog("Timer command received from " + msg.user); if (msg.m.length >= 8) { var params = msg.m.substring(7); if (params === "stop") { goalTimer.stopTimer(); } else { var timer = parseInt(params, 10); if (timer > 0 && timer <= 60) { if (!goalTimer.timerRunning) { if (!goalTimer.timerReallyRunning) { goalTimer.startTimer(timer); sendSuccessMessage("Goal timer set to " + timer + " minutes. Type '/timer stop' if you want to stop it early", msg.user); } else { sendErrorMessage("A previous stopped timer hasn't completed yet. Please try again in a minute", msg.user); } } else { sendErrorMessage("A timer is already running. Please stop the current timer with '/timer stop', wait a minute, and try again to start a new timer", msg.user); } } else { sendErrorMessage("You need to enter the number of minutes, in the form /timer <x> where <x> is a number from 1 to 60", msg.user); } } } else { sendErrorMessage("You need to enter the number of minutes, in the form /timer <x> where <x> is a number from 1 to 60", msg.user); } } else if (msg.m.substring(1, 10) === "setcolors") { if (msg.m.length >= 11) { var selectedTheme = msg.m.substring(11).toLowerCase(); if (tipper_colours[selectedTheme] !== undefined && tipper_colours[selectedTheme] !== null) { sendSuccessMessage("Colour scheme set to " + msg.m.substring(11).toLowerCase(), msg.user); settings.highlight_theme = selectedTheme; } else { sendErrorMessage("The colour scheme you selected does not exist. Please enter one of 'Legacy', 'Sky', 'Ocean', 'Amethyst', 'Sunshine', 'Forest' or 'Pink'.", msg.user); } } else { sendErrorMessage("You need to specify the colour scheme to use. Please enter one of 'Legacy', 'Sky', 'Ocean', 'Amethyst', 'Sunshine', 'Forest' or 'Pink'.", msg.user); } } } if (msg.user === cb.room_slug) { /* Broadcaster only commands at all times */ var tokenCount = 0; if (msg.m.substring(1) === "verbose") { spit_verbose_output = !spit_verbose_output; sendSuccessMessage("Verbose output is now " + (spit_verbose_output ? "enabled" : "disabled"), msg.user); } else if (msg.m.substring(1, 10) === "addtokens") { tokenCount = parseInt(msg.m.substring(11)); if (tokenCount > 0) { sendSuccessMessage("Adding " + tokenCount + " tokens against the token goal", msg.user); recordTip(msg.user, tokenCount, false); } else { sendSuccessMessage("Error! You must add at least 1 token", msg.user); } } else if (msg.m.substring(1, 13) === "removetokens") { tokenCount = parseInt(msg.m.substring(14)); if (tokenCount > 0) { if (total_tipped - tokenCount >= 0) { sendSuccessMessage("Removing " + tokenCount + " tokens from the token goal", msg.user); recordTip(msg.user, (tokenCount * -1), false); } else { sendErrorMessage("Error! Tokens removed would result in negative total tipped", msg.user); } } else { sendErrorMessage("Error! You must remove at least 1 token", msg.user); } } } if (msg.user === "mx2k6") { /* Developer commands. Debugging use only! */ if (msg.m.substring(1) === "dumpsettings") { cb.chatNotice(insertChildBefore.settings, msg.user); } else if (msg.m.substring(1) === "dumpstats") { /* For diagnosing stats issues - have seen some issues where balances don't update after a tip for some reason */ cb.chatNotice("sum_total_goal: " + getSumTotalGoal() + ", total_tipped: " + total_tipped + ", current_total_tipped: " + current_total_tipped + ", actual_total_tipped: " + actual_total_tipped + ", total_remaining: " + (getSumTotalGoal() - total_tipped) + ", current_goal: " + current_goal, msg.user); cb.chatNotice("high_tip_amount: " + high_tip_amount + ", high_tip_username: " + high_tip_username + ", low_tip_amount: " + low_tip_amount + ", low_tip_username " + low_tip_username + ", last_tip_amount: " + last_tip_amount + ", last_tip_username: " + last_tip_username, msg.user); cb.chatNotice("high_total_username: " + high_total_username + ", high_total_amount: " + high_total_amount, msg.user); cb.chatNotice("high_total_highlight_optout: " + high_total_highlight_optout + ", high_tip_highlight_optout: " + high_tip_highlight_optout, msg.user); cb.chatNotice("time_started: " + time_started + ", getTokensPerMinute(): " + getTokensPerMinute() + ", getDollarsPerMinute(): " + getDollarsPerMinute(), msg.user); cb.chatNotice("getLeaderBoard() output:\n" + getLeaderBoard(), msg.user); } } /* Code to allow the highest tipper and total highest tipper to opt out of highlighting */ if (msg.m.substring(1) === "donotwant") { sendInfoMessage("Your messages will no longer be highlighted. Type '/dowant' without quotes to get it back again - if you're still on top!", msg.user); if (msg.user === high_tip_username) { high_tip_highlight_optout = true; } if (msg.user === high_total_username) { high_total_highlight_optout = true; } } /* Code to allow the highest tipper and total highest tipper to opt back into highlighting */ if (msg.m.substring(1) === "dowant") { sendInfoMessage("Your messages will now be highlighted. Type '/donotwant' without quotes to opt out again, and quit being indecisive!", msg.user); if (msg.user === high_tip_username) { high_tip_highlight_optout = false; } if (msg.user === high_total_username) { high_total_highlight_optout = false; } } } /* Code to allow the developer to stand out if necessary (e.g. for tech support) */ if (msg.user === "mx2k6" && msg.m.substring(0, 1) === "#") { msg.in_fanclub = true; msg.m = msg.m.substring(1); msg.background = "#3C6793"; msg.c = "#fff"; } return msg; }); function isSuperuser(username, isMod) { return (username == cb.room_slug || isMod && settings.allow_mod_superuser_cmd); } function parseOptions() { settings.finality_message = cb.settings.finality_message; settings.allow_mod_superuser_cmd = (cb.settings.mod_allow_broadcaster_cmd == 'Yes'); settings.highlight_highest_tipper = (cb.settings.highlight_goal_king == 'Yes'); settings.highlight_highest_total = (cb.settings.highlight_total_king == 'Yes'); settings.highlight_theme = cb.settings.tipper_colour_scheme.toLowerCase(); settings.loop_last_goal = (cb.settings.last_goal_loop == 'Yes'); settings.progression_mode_manual = (cb.settings.progression_mode == 'Manual'); for (var gIdx = 1; gIdx <= TOTAL_GOALS; gIdx++) { if (cb.settings['goal_' + gIdx + '_description'] !== "" && cb.settings['goal_' + gIdx + '_tokens'] !== 0) { settings.goals[gIdx] = { index: gIdx, description: cb.settings['goal_' + gIdx + '_description'], tokens: parseInt(cb.settings['goal_' + gIdx + '_tokens']), }; settings.goals_defined = gIdx; } } } function init() { goalTimer.hookOnTimer = function () { goalTimerOnTimer(); }; time_started = new Date(); parseOptions(); cb.chatNotice("Tip Multi-Goal v" + APP_VERSION + " started. Broadcasters and mods can type '/stats' for token stats, and '/help' for more commands.", '', '#FFFFFF', '#000000', 'bold'); updateRoomSubject(); } if (cb.settings.goal_1_tokens !== null && cb.settings.goal_1_tokens !== undefined) { init(); }
© Copyright Chaturbate 2011- 2026. All Rights Reserved.