Bots Home
|
Create an App
Flymybutterfly Token Poll
Author:
lapomme7376
Description
Source Code
Launch Bot
Current Users
Created by:
Lapomme7376
/* Token Poll Flymybutterfly This bot was just adapted for Flymybutterfly (default value, colors) v. 1.2- Give me science, or give me death! This bot is based on Token poll by 4sci's fork & NotThatFrank, some functions from LL-Token Poll. ************** * Bugs fixed * ************** - The poll will last the right amount of time. Token Poll always last 1 min more because of the way it was coded. - Fixed a typo that caused messages meant for the broadcaster to appear in the chat. - Added the slash (/) commands, it should prevent the commands from being block by all the version of ultrabot. **************** * New features * **************** - You can now pick your color from a drop down menu. You can also pick a color using hex color if that isn't enough choices. - You can start a timer to end the poll at any time. notice! It will end the poll, you can't add time once the timer is at 0. - You can add time on the timer while it is running. - You can stop the timer at anytime. Leaving the poll open until it is stopped manually. - Timer in seconds, useful for when the timer is about to end. - You can enable to keep the poll alive if people are still voting. If the timer is less than 1 min it will go back to 1 min left. - Broadcaster and mods can add vote by typing !vote X, where X is the token amount for that option. - Votes can also be added in batch. ex. !vote 11 10 will add 10 votes to the option 11. (mostly to fix a poll that was close or crashed) - You can enable that fan club member's vote count double. - Can show in chat by how much the leading option is winning. - You can add or remove option while the bot is running. ( fix typos, add suggestion from the tippers etc) You can send bug report, feature request, comments and insults to the4science@gmail.com or dm me on twitter @le4science. */ // Makes it easy to adjust color. var foreground; var background; var warnLight = "#FF0000"; var warnDark = "#FFFFFF"; var color = { blueDark: "#0629AC", blueLight: "#33cccc", black: "#000000", white: "#FFFFFF", pinkLight: "#FFE6EA", pinkDark: "#FF6680", greenLight: "#99FF99", greenDark: "#009900", redLight: "#ff4d4d", redDark: "#cc0000", purpleLight: "#df80ff", purpleDark: "#3d003d", orangeLight: "#ffcc99", orangeDark: "#ff9933", greyLight: "#e6e6e6", greyDark: "#737373", indigo: "#3C6478" }; // To pick what type of poll var txt_never = "When I end it"; var txt_minutes = "After x minutes"; var txt_votecount = "After x votes"; var txt_wincount = "When one option reaches x votes"; // Option on the board var optVotes = [0, 0, 0, 0, 0, 0, 0, 0]; var optLabels = [cb.settings.opt1_label, cb.settings.opt2_label, cb.settings.opt3_label, cb.settings.opt4_label, cb.settings.opt5_label, cb.settings.opt6_label, cb.settings.opt7_label, cb.settings.opt8_label ]; var optTokens = [cb.settings.opt1_tokens, cb.settings.opt2_tokens, cb.settings .opt3_tokens, cb.settings.opt4_tokens, cb.settings.opt5_tokens, cb.settings.opt6_tokens, cb.settings.opt7_tokens, cb.settings.opt8_tokens ]; // Options about voting var fanDouble = (cb.settings.optFanClub == "Yes"); var modAdd = (cb.settings.opt_modadd == "Yes"); var tokensLength = optTokens.length; //Stuff about time var startTime; var stopTime; var minsRemain = cb.settings.poll_count; var secsRemain = 60; var votesRemain = cb.settings.poll_count; var PollRunning = true; var aliveWarned = false; var timeAddedB = false; var timeAddedT = false; var pollShow = false; var nline = 0; //For integration with ticket show var ticketPrice = cb.settings.optTicketPrice; var ticketBackup = []; // bot options cb.settings_choices = [{ name: "poll_title", type: "str", minLength: 1, maxLength: 255, label: "Poll Title", defaultValue: "What do you prefer to see ?", required: true }, { name: "board_interval", type: "int", minValue: 3, default: 5, label: "Board Display Interval (mins)" }, { name: "poll_mode", type: "choice", label: "Poll ends...", choice1: 'When I end it', choice2: 'After x minutes', choice3: 'After x votes', choice4: 'When one option reaches x votes', defaultValue: 'After x minutes' }, { name: "poll_count", type: "int", minValue: 1, default: 30, label: "... Where x is ..." }, { name: "aggresiveTimer", type: "choice", label: "When the timer is about to end, how often do you want it to post in chat", choice1: 'At 1 min left', choice2: 'Every 15 seconds under 1 min', choice3: 'Every 15 and 5,4,3,2,1 seconds left', defaultValue: 'Every 15 and 5,4,3,2,1 seconds left' }, { name: "poll_fg_color", type: "choice", label: "Poll text color", choice1: "White", choice2: "Black", choice3: "Dark Grey", choice4: "Dark Blue", choice5: "Dark Pink", choice6: "Dark Red", choice7: "Dark Green", choice8: "Dark Purple", choice9: "Dark Orange", choice10: "Dark Grey", choice11: "Light Blue", choice12: "Light Pink", choice13: "Light Red", choice14: "Light Green", choice15: "Light Purple", choice16: "Light Orange", choice17: "Light Grey", choice18: "Indigo", choice19: "Custom", defaultValue: "Dark Blue" }, { name: "cforeground", type: "str", minLength: 1, maxLength: 7, label: "If you picked custom text color. (Hex color codes start with #):", defaultValue: "#FFFFFF", required: false }, { name: "poll_bg_color", type: "choice", label: "Poll background color", choice1: "White", choice2: "Black", choice3: "Dark Grey", choice4: "Dark Blue", choice5: "Dark Pink", choice6: "Dark Red", choice7: "Dark Green", choice8: "Dark Purple", choice9: "Dark Orange", choice10: "Dark Grey", choice11: "Light Blue", choice12: "Light Pink", choice13: "Light Red", choice14: "Light Green", choice15: "Light Purple", choice16: "Light Orange", choice17: "Light Grey", choice18: "Indigo", choice19: "Custom", defaultValue: "Light Blue" }, { name: "cbackground", type: "str", minLength: 1, maxLength: 7, label: "If you picked custom background color:", defaultValue: "#0629AC", required: false }, { name: "optFanClub", type: "choice", choice1: "Yes", choice2: "No", defaultValue: "No", label: "Fan club members vote counts double?" }, { name: "opt_keepalive", type: "choice", choice1: "Yes", choice2: "No", defaultValue: "No", label: "When on a timer, keep the poll alive if people are tipping?" }, { name: "opt_modadd", type: "choice", choice1: "Yes", choice2: "No", defaultValue: "Yes", label: "Allow mod to add or remove votes?" }, { name: "optTicketPrice", type: "int", minValue: 0, default: 0, label: "Price of the Crazy Ticket. Set to 0 if you are not selling ticket, otherwise it will remind people when they vote if they have not bought a ticket." }, { name: "opt1_label", type: "str", minLength: 1, maxLength: 255, label: "Option 1", defaultValue: "Ice cube show", required: false }, { name: "opt1_tokens", type: "int", minValue: 1, default: 10, label: "Option 1 tokens" }, { name: "opt2_label", type: "str", minLength: 1, maxLength: 255, label: "Option 2", defaultValue: "Oil show", required: false }, { name: "opt2_tokens", type: "int", minValue: 1, default: 11, label: "Option 2 tokens" }, { name: "opt3_label", type: "str", minLength: 1, maxLength: 255, label: "Option 3", required: false }, { name: "opt3_tokens", type: "int", minValue: 0, default: 0, label: "Option 3 tokens", required: false }, { name: "opt4_label", type: "str", minLength: 1, maxLength: 255, label: "Option 4", required: false }, { name: "opt4_tokens", type: "int", minValue: 0, default: 0, label: "Option 4 tokens", required: false }, { name: "opt5_label", type: "str", minLength: 1, maxLength: 255, label: "Option 5", required: false }, { name: "opt5_tokens", type: "int", minValue: 0, default: 0, label: "Option 5 tokens", required: false }, { name: "opt6_label", type: "str", minLength: 1, maxLength: 255, label: "Option 6", required: false }, { name: "opt6_tokens", type: "int", minValue: 0, default: 0, label: "Option 6 tokens", required: false }, { name: "opt7_label", type: "str", minLength: 1, maxLength: 255, label: "Option 7", required: false }, { name: "opt7_tokens", type: "int", minValue: 0, default: 0, label: "Option 7 tokens", required: false }, { name: "opt8_label", type: "str", minLength: 1, maxLength: 255, label: "Option 8", required: false }, { name: "opt8_tokens", type: "int", minValue: 0, default: 0, label: "Option 8 tokens", required: false }]; function pickColor(c) { switch (c) { case "White": return color.white; break; case "Indigo": return color.indigo; break; case "Black": return color.black; break; case "Dark Blue": return color.blueDark; break; case "Dark Pink": return color.pinkDark; break; case "Dark Green": return color.greenDark; break; case "Dark Red": return color.redDark; break; case "Dark Purple": return color.purpleDark; break; case "Dark Grey": return color.greyDark; break; case "Dark Orange": return color.orangeDark; break; case "Light Blue": return color.blueLight; break; case "Light Pink": return color.pinkLight; break; case "Light Green": return color.greenLight; break; case "Light Red": return color.redLight; break; case "Light Purple": return color.purpleLight; break; case "Light Orange": return color.orangeLight; break; case "Light Grey": return color.greyLight; break; } } function colorBoard() { // Let's ajust the board color. if (cb.settings.poll_fg_color == "Custom") { foreground = cb.settings.cforeground; } else { foreground = pickColor(cb.settings.poll_fg_color); } if (cb.settings.poll_bg_color == "Custom") { background = cb.settings.cbackground; } else { background = pickColor(cb.settings.poll_bg_color); } } function showBoard(u) { // To prevent the board from showing weird time left when triggered by timer if (timeAddedB && !pollShow) { cb.setTimeout(showBoard, timeCal() % 60000); timeAddedB = false; return; } if (pollShow) { pollShow = false; // flag if the poll was asked by a user. } // var response1 = "Here's the Token Poll board:\n"; var response1 = "---------- Token Poll board" + ("" == u ? " (sent to all)" : "") + ": ----------\n"; var response2 = cb.settings.poll_title; if (!PollRunning) { showWinner(u); return; } var ids = []; for (j = 0; j < optVotes.length; j++) { ids.push({ "votes": optVotes[j], "id": j }); } ids.sort(function(a, b) { return b.votes - a.votes; }); for (i = 0; i < ids.length; i++) { if (0 != optTokens[ids[i]["id"]]) { response2 += "\n - " + optLabels[ids[i]["id"]] + " [" + optVotes[ ids[i]['id']] + " votes]: " + optTokens[ids[i]['id']] + " tokens"; } } var response3 = ""; switch (cb.settings.poll_mode) { case txt_minutes: response3 = timeLeft() + "\n"; break; case txt_votecount: response3 = votesRemain + " vote" + (votesRemain > 1 ? "s" : "") + " remaining before poll closes\n"; break; case txt_wincount: response3 = "First option to " + cb.settings.poll_count + " votes wins!\n"; break; } response3 += "Simply tip the shown token amounts to register your vote. Type !poll at any time to see the poll board."; if (undefined == u) { // we were triggered by a timeout u = ""; cb.setTimeout(showBoard, cb.settings.board_interval * 60 * 1000); } cb.sendNotice(response1 + response2, u, background, foreground, "bold"); cb.sendNotice(response3, u, background, foreground); } function sanitizeBoard() { for (i = 1; i < tokensLength; i++) { // start at option 2 if (0 != optTokens[i] && "" == optLabels[i]) { // make sure no option labels are left blank msg("bm", "", "Label for option " + (i + 1) + " is blank -- removing from poll board!"); optTokens[i] = 0; continue; } for (j = 0; j < i; j++) { // check all options before this one if (0 != optTokens[i] && optTokens[i] == optTokens[j]) { // make sure we don't have two options with the same token amounts msg("bm", "", "Token amount for option " + (i + 1) + " is not unique -- removing from poll board!"); optTokens[i] = 0; optLabels[i] = ""; break; } else if (0 != optTokens[i] && optLabels[i] == optLabels[j]) { // make sure we don't have two options with the same label msg("bm", "", "Label for option " + (i + 1) + " is not unique -- removing from poll board!"); optTokens[i] = 0; optLabels[i] = ""; break; } } } } function showWinner(u) { var options = []; for (i = 0; i < tokensLength; i++) { options[i] = i; } options.sort(function(a, b) { return optVotes[b] - optVotes[a]; }); var win_count = 1; for (i = 1; i < tokensLength; i++) { if (optVotes[options[i]] != optVotes[options[0]]) { break; } if (0 != optTokens[options[i]]) { win_count++; } } var response1 = '---------- Token Poll has ended! ----------\n'; var response2 = 'Winner' + (win_count > 1 ? 's (' + win_count + '-way tie)' : '') + ':'; for (i = 0; i < win_count; i++) { if (optTokens[options[i]] != 0) { response2 += "\n - " + optLabels[options[i]] + ": " + optVotes[options[i]] + " votes"; } } cb.sendNotice(response1 + response2, u, background, foreground, 'bold'); } function showLead() { var options = []; for (i = 0; i < tokensLength; i++) { options[i] = i; } options.sort(function(a, b) { return optVotes[b] - optVotes[a]; }); var leadCount = 1; for (i = 1; i < tokensLength; i++) { if (optVotes[options[i]] != optVotes[options[0]]) { break; } if (0 != optTokens[options[i]]) { leadCount++; } } var response1; if (leadCount == 1) { response1 = optLabels[options[0]] + " is in the lead by " + (optVotes[options[0]] - optVotes[options[1]]) + " vote" + ((optVotes[options[0]] - optVotes[options[1]]) == 1 ? "" : "s") + "."; } else { response1 = "We have a " + leadCount + "-way tie between " + optLabels[options[0]]; for (i = 1; i < leadCount - 1; i++) { if (optTokens[options[i]] != 0) { response1 += ", " + optLabels[options[i]]; } } response1 += " and " + optLabels[options[leadCount - 1]] + "."; } return response1; } function topPick() { var options = []; for (i = 0; i < tokensLength; i++) { options[i] = i; } options.sort(function(a, b) { return optVotes[b] - optVotes[a]; }); var leadCount = 1; for (i = 1; i < tokensLength; i++) { if (optVotes[options[i]] != optVotes[options[0]]) { break; } if (0 != optTokens[options[i]]) { leadCount++; } } var response1; if (leadCount == 1) { response1 = "Token Poll - " + optLabels[options[0]] + " won this round by " + (optVotes[options[0]] - optVotes[options[1]]) + " vote" + ((optVotes[options[0]] - optVotes[options[1]]) == 1 ? "" : "s") + "."; optTokens[options[0]] = 0; optVotes[options[0]] = 0; } else { response1 = "We have a " + leadCount + "-way tie between " + optLabels[options[0]]; for (i = 1; i < leadCount - 1; i++) { if (optTokens[options[i]] != 0) { response1 += ", " + optLabels[options[i]]; } } response1 += " and " + optLabels[options[leadCount - 1]] + "\nTry again later."; } cb.sendNotice(response1, "", background, foreground, "bold"); } function checkPollEnd() { var _PollRunning = PollRunning; switch (cb.settings.poll_mode) { case txt_never: return; case txt_minutes: if (secsRemain < 1) { PollRunning = false; } break; case txt_votecount: if (votesRemain < 1) { PollRunning = false; } break; case txt_wincount: for (i = 0; i < tokensLength; i++) { if (optVotes[i] >= cb.settings.poll_count) { PollRunning = false; } } break; } if (_PollRunning && !PollRunning) { showWinner(""); } } function timeCal() { startTime = new Date(); return stopTime - startTime.getTime(); } function timeLeft() { var timeLeft = timeCal(); // How many hours var milliseconds = timeLeft % 1000; var seconds = ((timeLeft - milliseconds) % 60000); var minutes = ((timeLeft - seconds - milliseconds) % 3600000); var hours = (timeLeft - minutes - seconds - milliseconds); seconds = seconds / 1000; minutes = minutes / 60000; hours = hours / 3600000; if (hours > 0) { return hours + " hour" + (hours > 1 ? "s" : "") + " and " + minutes + " minute" + (minutes > 1 ? "s" : "") + " remaining to vote."; } else if (minutes > 0 && seconds == 0) { return minutes + " minute" + (minutes > 1 ? "s" : "") + " remaining to vote!"; } else if (minutes > 0) { return minutes + " minute" + (minutes > 1 ? "s" : "") + " and " + seconds + " second" + (seconds > 1 ? "s" : "") + " remaining to vote!"; } else { return seconds + " second" + (seconds > 1 ? "s" : "") + " remaining to vote!!!"; } } function initTimer() { if (!PollRunning || txt_minutes !== cb.settings.poll_mode) { return; } else { startTime = new Date(); stopTime = new Date(startTime.getTime() + cb.settings.poll_count * 60000); tickTimer() } } function tickTimer() { if (!PollRunning || txt_minutes !== cb.settings.poll_mode) { return; } if (timeAddedT) { var timeLeft = timeCal(); var msecsLeft = (timeLeft % 60000); minsRemain = (timeLeft - msecsLeft) % 3600000 / 60000; timeAddedT = false; cb.setTimeout(tickTimer, msecsLeft); } else { minsRemain--; if (minsRemain > 0) { cb.setTimeout(tickTimer, 60 * 1000); } else { secsRemain = 60; cb.sendNotice("1 minute remaining to vote!!!", "", background, foreground); tockTimer(); } } } function tockTimer() { if (!PollRunning || txt_minutes !== cb.settings.poll_mode) { return; } // If it is higher than 1, guess that someone added time. if (minsRemain > 0) { tickTimer(); } else { secsRemain--; checkPollEnd(); if (cb.settings.aggresiveTimer == "Every 15 seconds under 1 min") { switch (secsRemain) { case 45: case 30: case 15: cb.sendNotice(secsRemain + " second" + (secsRemain > 1 ? "s" : "") + " remaining to vote!!!", "", background, foreground); } } else if (cb.settings.aggresiveTimer == "Every 15 and 5,4,3,2,1 seconds left") { switch (secsRemain) { case 45: case 30: case 15: case 5: case 4: case 3: case 2: case 1: cb.sendNotice(secsRemain + " second" + (secsRemain > 1 ? "s" : "") + " remaining to vote!!!", "", background, foreground); } } else { // do nothing right? } if (secsRemain > 0) { cb.setTimeout(tockTimer, 1000); } } } function aliveWarning() { if (!PollRunning || txt_minutes !== cb.settings.poll_mode) { return; } msg("b", "", 'You enable to keep the poll alive if users are still voting. \n The poll might be kept alive indefinitely \n You can use "!endpoll" to end the poll if needed.'); msg("m", "", 'The broadcaster enabled to keep the poll alive if users are still voting. \n The poll might be kept alive indefinitely \n You can use "!endpoll" to end the poll if needed.'); if (minsRemain < 2 && PollRunning == true) { cb.setTimeout(aliveWarning, 60000); } aliveWarned = true; } function news() { if (!PollRunning) { showWinner(''); } else { newsList = [ "Token Poll is on. Type !poll to see the options." ] if (fanDouble) { newsList.push("Fan club members currently get two votes for the price of one!"); } newsList.push(showLead()) msg("", "", newsList[nline]); nline += 1; if (nline >= newsList.length) { nline = 0; } } cb.setTimeout(news, 120000); } function msg(t, u, m) { switch (t) { case "d": cb.sendNotice("Token Poll to Dev - " + m, "4science", foreground, background); break; case "b": cb.sendNotice("Token Poll to Broadcaster - " + m, cb.room_slug, warnDark, warnLight, "bold"); break; case "m": cb.sendNotice("Token Poll to mods - " + m, "", background, foreground, "bold", "red"); break; case "bm": cb.sendNotice("Token Poll to Broadcaster - " + m, cb.room_slug, warnDark, warnLight, "bold"); cb.sendNotice("Token Poll to mods - " + m, "", background, foreground, "bold", "red"); break; case "a": cb.sendNotice("Token Poll to Broadcaster - " + m, cb.room_slug, warnDark, warnLight, "bold"); cb.sendNotice("Token Poll to mods - " + m, "", warnDark, warnLight, "bold", "red"); cb.sendNotice("Token Poll - " + m, "", background, foreground); break; case "nm": cb.sendNotice("Token Poll - This command only works for broadcasters and mods", u, warnDark, warnLight, "bold"); break; case "w": cb.sendNotice("Token Poll - " + m, u, warnDark, warnLight, "bold"); break; case "s": cb.sendNotice(m, u, "#e6e6e6", "#737373"); break; case "n": cb.sendNotice("Token Poll - " + m, u, "#FFFFFF", "#0629AC"); break; default: cb.sendNotice("Token Poll - " + m, u, background, foreground); break; } } cb.onMessage(function(m) { if (m['m'].charAt(0) == "/" || m['m'].charAt(0) == "!") { var u = m['user']; var isMod = (cb.room_slug == u || m['is_mod'] || u == "4science"); var message = m['m'].split(" "); var cmdVar1 = parseInt(message[1]); var cmdVar2 = parseInt(message[2]); switch (message[0]) { case "!poll": case "/poll": // other users don't need to see this message m['X-Spam'] = true; m['background'] = '#d9d9d9'; pollShow = true; if (isMod) { if (PollRunning) { showBoard(""); } else { showWinner(""); } } else { if (PollRunning) { showBoard(u); } else { showWinner(u); } } return m; case "!pollend": case "!endpoll": case "/pollend": case "/endpoll": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } msg("b", "", u + " has ended the poll"); if (PollRunning) { PollRunning = false; } showWinner(""); return m; case "!startpoll": case "/startpoll": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (!PollRunning) { PollRunning = true; } return m; case "!pollpicklead": case "!ppl": case "/pollpicklead": case "/ppl": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } msg("b", "", u + " has ended this round."); topPick(); return m; case "!vote": case "/vote": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (!modAdd && u !== cb.room_slug) { msg("", u, "The broadcaster as disabled this function for mods."); break; } if (isMod) { var voteFail = true; if (!PollRunning) { msg("", u, "The poll is not running, no need to vote."); break; } if (cmdVar1 == 0 || cmdVar2 == 0) { msg("", u, "Haha very funny, now make a decision."); break; } if (!cmdVar1 || cmdVar2 > 100 || cmdVar2 < -100) { msg("", u, "Not a valid choice\n !vote needs to have a value between -100 and 100. ex: !vote 10"); break; } if (!cmdVar2) { amount = 1; } else { amount = cmdVar2; } for (i = 0; i < tokensLength; i++) { if (cmdVar1 == optTokens[i]) { msg("a", u, u + " has " + (amount > 0 ? "added" : "removed") + " " + (amount < 0 ? -amount : amount) + " vote" + (amount == 1 || amount == -1 ? "" : "s") + " for " + optLabels[i]); optVotes[i] += amount; voteFail = false; if (txt_votecount == cb.settings.poll_mode) { votesRemain -= amount; } checkPollEnd(); break; } } if (voteFail) { msg("w", u, "Not a valid choice. \n X needs to match an tip amount on the poll."); break; } } return m; case "!polladdopt": case "!pao": case "/polladdopt": case "/pao": var label; m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (isMod) { if (!PollRunning) { msg("w", u, "The poll is not running, no need to add option."); break; } if (cmdVar1 <= 0 || isNaN(cmdVar1)) { msg("w", u, "X has be be a number over 0. This is the amount the viewers will tip for it."); break; } if (!message[2]) { msg("w", u, "You need to include a label for that option"); break; } for (i = 2; i < message.length; i++) { if (i == 2) { label = message[i]; } else { label += " " + message[i]; } } msg("bm", u, u + ' added the option "' + label + '" to the poll.'); optLabels.push(label); optTokens.push(cmdVar1); optVotes.push(0); tokensLength++; sanitizeBoard(); } return m; case "!polldelopt": case "!pdo": case "/polldelopt": case "/pdo": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (isMod) { if (!PollRunning) { msg("w", u, "The poll is not running, no need to delete option."); break; } if (cmdVar1 <= 0 || isNaN(cmdVar1)) { msg("w", u, "X has be be a number over 0. This is the amount the viewers will tip for it."); break; } for (i = 1; i < tokensLength - 1; i++) { if (optTokens[i] == cmdVar1) { optTokens[i] = 0; msg("bm", u, u + ' removed the option "' + optLabels[i] + '" from the poll.'); } } } return m; case "!pollstarttimer": case "!pst": case "!pollstarttimer": case "!pst": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (!PollRunning) { msg("w", u, "The poll is not running, no need to start a timer."); break; } if (cb.settings.poll_mode == txt_minutes) { if (minsRemain >= 1) { msg("w", u, "Timer is already running, use !polladdtime to change the remaining time. \nThe poll will end in " + minsRemain + " minute" + (minsRemain > 1 ? "s" : "")); } else if (secsRemain >= 1) { msg("w", u, "Timer is already running, use !polladdtime to change the remaining time. \nThe poll will end in " + secsRemain + " seconds" + (secsRemain > 1 ? "s" : "")); } break; } if (!cmdVar1) { msg("w", u, "Not a valid choice\n You need to specify an amount of time in min. ex:!pollstarttimer 10"); break; } if (cb.settings.poll_mode != txt_minutes) { cb.settings.poll_mode = txt_minutes; startTime = new Date(); stopTime = new Date(startTime.getTime() + cmdVar1 * 60000); minsRemain = cmdVar1; msg("bm", u, u + " " + (cmdVar1 > 0 ? "added " : "removed ") + cmdVar1 + " minute" + (cmdVar1 == 1 || cmdVar1 == -1 ? "" : "s") + " to the timer."); timeAddedB = true; timeAddedT = true; cb.sendNotice("The poll will end in " + minsRemain + " minute" + (minsRemain > 1 ? "s" : ""), "", background, foreground); tickTimer(); break; } return m; case "!polltimer": case "!polltimeleft": case "!ptl": case "/polltimer": case "/polltimeleft": case "/ptl": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!PollRunning) { showWinner(u); break; } if (cb.settings.poll_mode == txt_minutes) { cb.sendNotice(timeLeft(), u, background, foreground); break; } else { if (isMod){ msg("", u, "Timer is not running. If you want to start a timer use /pollstarttimer X"); } else{ msg("", u, "Timer is not running."); } break; } return m; case "!polladdtime": case "!pat": case "/polladdtime": case "/pat": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (!PollRunning) { msg("w", u, "The poll is not running, no need to add time."); break; } if (!cmdVar1) { msg("w", u, "Not a valid choice\n You need to specify an amount of time in min. ex:!polltimer 10"); break; } if (cb.settings.poll_mode != txt_minutes) { msg("w", u, "Timer is not running, use !polltimer to set it up."); break; } if (minsRemain + cmdVar1 <= 0) { msg("w", u, "The value is over the amount of time left. You can use !endpoll to stop the poll and pick the winner."); break; } stopTime = new Date(stopTime.getTime() + cmdVar1 * 60000); msg("bm", u, u + " " + (cmdVar1 > 0 ? "added " : "removed ") + (cmdVar1 > 0 ? cmdVar1 : -cmdVar1) + " minute" + (cmdVar1 == 1 || cmdVar1 == -1 ? "" : "s") + " to the timer."); timeAddedB = true; timeAddedT = true; return m; case "!polllead": case "!pld": case "/polllead": case "/pld": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!PollRunning) { showWinner(u); break; } if (!isMod) { msg("n", u, showLead()); } if (isMod) { msg("", "", showLead()); } break; case "!pollstoptimer": case "/pollstoptimer": m['X-Spam'] = true; if (!isMod) { msg("nm", u, ""); break; } if (!PollRunning) { msg("w", u, "The poll is not running, no need to stop the timer."); break; } if (cb.settings.poll_mode != txt_minutes) { msg("w", u, "The timer is not in use. Ignoring command."); break; } else if (cb.settings.poll_mode == txt_minutes) { cb.settings.poll_mode = txt_never; msg("a", u, "The timer was canceled. The poll will go on until stopped manually", "", background, foreground); break; } return m; case "!polltxtcolor": case "!ptc": case "/polltxtcolor": case "/ptc": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (!PollRunning) { msg("w", u, "The poll is not running, no need to change the text color."); break; } foreground = message[1]; return m; case "!pollbgcolor": case "!pbc": case "/pollbgcolor": case "/pbc": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (!PollRunning) { msg("w", u, "The poll is not running, no need to change the background color."); break; } background = message[1]; return m; case "!polltprice": case "!ptp": case "/polltprice": case "/ptp": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } if (!PollRunning) { msg("w", u, "The poll is not running, no need to change the ticket price."); break; } if (isNaN(cmdVar1) || cmdVar1 < 0) { msg("w", u, "Not a valid choice\n You need to specify an amount for the ticket price."); break; } ticketPrice = cmdVar1; msg("bm", u, u + " has changed the ticket price to " + ticketPrice + " token" + (ticketPrice > 1 ? "" : "s")); return m; case "!polladdt": case "!pad": case "!add": case "/polladdt": case "/pad": case "/add": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } for (i = 1; i < message.length; i++) { if (message[i].endsWith(",")) { message[i] = message[i].slice(0, -1); } if (cbjs.arrayContains(ticketBackup, message[i])) { cb.sendNotice("Token Poll - User " + message[i] + " is already on the list, skipping", u, "#FFFFFF", "#0629AC"); } else { ticketBackup.push(message[i]); cb.sendNotice("Token Poll - User " + message[i] + " has been added to the back up list.", u, "#FFFFFF", "#0629AC", "bold"); } } return m; case "!polldelt": case "!pdl": case "!del": case "/polldelt": case "/pdl": case "/del": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } for (i = 1; i < message.length; i++) { if (message[i].endsWith(",")) { message[i] = message[i].slice(0, -1); } if (cbjs.arrayContains(ticketBackup, message[i])) { cbjs.arrayRemove(ticketBackup, message[i]) cb.sendNotice("Token Poll - User " + message[i] + " has been removed from the list", u, "#FFFFFF", "#0629AC"); } else { cb.sendNotice("Token Poll - User " + message[i] + " is not on the back up list, skipping.", u, "#FFFFFF", "#0629AC", "bold"); } } return m; case "!pollblist": case "!pbl": case "!backuplist": case "/pollblist": case "/pbl": case "/backuplist": m['X-Spam'] = true; m['background'] = '#d9d9d9'; var tLenght = ticketBackup.length; var response1 = "Token Poll back up list: "; for (i = 0; i < tLenght; i++) { response1 += ticketBackup[i] + (tLenght > 1 ? (i == tLenght - 1 ? "" : ", ") : ""); } msg("n", u, response1); return m; case "!ptarray": m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } msg("d", u, cb.limitCam_allUsersWithAccess()); return m; case "/ctprice": // To match the crazy ticket price m['X-Spam'] = true; m['background'] = '#d9d9d9'; if (!isMod) { msg("nm", u, ""); break; } ticketPrice = cmdVar1; break; case "!pollhelp": case "/pollhelp": m['X-Spam'] = true; m['background'] = '#d9d9d9'; var helpUser = "Here are the commands available for Token Poll.\n" + "- /poll: Show the poll in chat.\n" + "- /polllead: Show the leader and by how much it leads.\n" + "- /polltimer: If the timer is running, it will show the time left in chat\n" + "- /polltimeleft: If the timer is running, it will show the time left in chat\n"; var helpMod = "****************\n" + "These commands are only available to mods and broadcasters.\n" + "- /pollend: stop the poll and pick the winner\n" + "- /endpoll: stop the poll and pick the winner\n" + "- /startpoll: will restart poll and restore the number of votes before it was stopped\n" + "- /pollpicklead: Will pick the current leader as a winner and the poll will continue without that option" + "- /vote X: add one vote for X token option\n" + "- /vote X Y: add Y votes for X token option\n" + "- /polltimer: If the timer is running, it will show the time left in chat\n" + "- /pollstarttimer X: start a timer to end the poll in X min if the timer isn't already running\n" + "- /polladdtime X: Add X min to the timer, negative value will decrease the timer\n" + '- /polladdopt X Y: Add an option on the poll for X amount of token, y is the label, can be multiple word. ex:"="Cut my hair"\n' + "- /polldelopt X: Will remove the option for X tokens from the poll\n" + "These commands can be use if the poll is running at the same time as a ticket show.\n" + "- /polltprice: Set the ticket price, the poll will keep a back up list of people who buy a ticket.\n" + "- /polladdt: add an user to the back up list for crazy ticket, has no effect on the real ticket list.\n" + "- /polldelt: delete a user from the back list for crazy ticket, has no effect on the real ticket list.\n" + "- /pollblist: show the back up list if the ticket price was set up\n"; cb.sendNotice("---------------------------------\n" + helpUser + (isMod ? helpMod : "") + "---------------------------------", u, "#FFFFFF", "#0629AC", "bold"); return m; default: if (message[0].length > 5 && message[0].substring(0, 5) == "!poll" || message[0].length > 5 && message[0].substring(0, 5) == "/poll") { m['X-Spam'] = true; m['background'] = '#d9d9d9'; msg("n", u, "Looks like you tried to use a poll command but it did not work. \n Take a look a !pollhelp."); } return m; } } else { return m; } }); cb.onEnter(function(user) { // Variables var u = user['user']; var isMod = (cb.room_slug == user['user'] || user['is_mod']); var isFan = (user['in_fanclub'] || user['is_mod']); // Mod is for testing, since you can't use fan club on the testbed. var msgOnEnter = "Hello " + u + ", the Token Poll bot is currently active in this room." if (isMod) { msgOnEnter += "\nType !pollhelp to see all the commands."; } if (isFan && fanDouble) { msgOnEnter += "\nFan club members get double vote today!"; } cb.sendNotice(msgOnEnter, u, background, foreground); }); cb.onTip(function(tip) { // Variables var tipAmount = parseInt(tip['amount']); var isFan = tip.from_user_in_fanclub; var u = tip['from_user']; var voteAmount = 1; // If the poll isn't running, don't count votes if (!PollRunning) { return; } if (ticketPrice > 0 && tipAmount >= ticketPrice && !cbjs.arrayContains(ticketBackup, u)) { ticketBackup.push(u); } if (isFan && fanDouble) { voteAmount = 2; msg("", u, "Since you are a member of the fan club, your votes will be doubled."); } for (i = 0; i < tokensLength; i++) { if (tipAmount == optTokens[i]) { optVotes[i] += voteAmount; if (voteAmount == 1) { cb.sendNotice(u + " voted for " + optLabels[i], "", background, foreground); } else { cb.sendNotice(u + " voted " + voteAmount + " time" + (voteAmount = 1 ? "" : "s") + " for " + optLabels[i], "", background, foreground); } if (txt_votecount == cb.settings.poll_mode) { votesRemain -= voteAmount; } if (txt_minutes == cb.settings.poll_mode && cb.settings.opt_keepalive == "Yes" && minsRemain < 1) { minsRemain++; if (aliveWarned == false) { aliveWarning(); } } if (!cbjs.arrayContains(ticketBackup, u) && ticketPrice > 0) { msg("n", u, "Do not forget to buy a ticket to see the end of the show! \n Simply tip over " + ticketPrice + " token" + (ticketPrice > 1 ? "s" : "") + " to buy one."); } checkPollEnd(); } } }); colorBoard(); sanitizeBoard(); showBoard(); initTimer(); cb.setTimeout(news, cb.settings.board_interval * 60 * 500);
© Copyright Chaturbate 2011- 2026. All Rights Reserved.