Bots Home
|
Create an App
BlondiesRoom
Author:
entomy
Description
Source Code
Launch Bot
Current Users
Created by:
Entomy
/** * Manages and applies discounts */ var discount; /** * Manages and applies discounts */ (function (discount) { "use strict"; /** * Fanclub discount percentage * This should be within 0~1 */ discount.fanclub = 0; /** * Moderator discount percentage * This should be within 0~1 */ discount.moderator = 0; /** * Apply the appropriate discount to the specified item, returning the discounted cost * @param item Item to discount * @param user User information for calculating discount */ function apply(item, user) { // CB uses different property names for the same thing on different types; this is confusing // These two values are assigned from whatever is approriate, to make the actual code easier to read var in_fanclub = user.hasOwnProperty("from_user_in_fanclub") ? user.from_user_in_fanclub : user.in_fanclub; var is_mod = user.hasOwnProperty("from_user_is_mod") ? user.from_user_is_mod : user.is_mod; // If user has no applicable discount, don't bother calculating it if (!in_fanclub && !is_mod) return item.cost; // Calculate the user discount based on whatever discount is appropriate and higher if (discount.fanclub >= discount.moderator) { if (in_fanclub) return Math.floor(item.cost * (1 - discount.fanclub)); else if (is_mod) return Math.floor(item.cost * (1 - discount.moderator)); } else if (discount.moderator > discount.fanclub) { if (is_mod) return Math.floor(item.cost * (1 - discount.moderator)); else if (in_fanclub) return Math.floor(item.cost * (1 - discount.fanclub)); } return item.cost; } discount.apply = apply; })(discount || (discount = {})); /** * Provides aliases for emblem emotes */ var emblems; /** * Provides aliases for emblem emotes */ (function (emblems) { "use strict"; emblems.arrow = " :arrow16 "; emblems.ballot = " :ballot16 "; emblems.bb8 = " :miniBB-8 "; emblems.blank = " :blank16 "; emblems.bronzemedal = " :bronzemedal16c "; emblems.coppermedal = " :coppermedal16 "; emblems.crown = " :crown16 "; emblems.gavel = " :gavel16 "; emblems.goldmedal = " :goldmedal16 "; emblems.hitachi = " :hitachi16 "; emblems.notice = " :notice16 "; emblems.silvermedal = " :silvermedal16 "; emblems.song = " :song16 "; emblems.timer = " :timer16 "; emblems.tinmedal = " :tinmedal16 "; emblems.tipmenu = " :tipmenu16 "; emblems.token = " :token12 "; emblems.trusted = " :trusted16 "; emblems.whisper = " :whisper16 "; emblems.whispermod = " :whispermod16 "; })(emblems || (emblems = {})); /** * Manages the high tipper */ var hightip; /** * Manages the high tipper */ (function (hightip) { "use strict"; /** * The actual tipper */ var slot; /** * Compare the tip against the highest tip, replacing it if greater * This is single tip only, so no tipper lookup should ever occur * @param tip Tip to compare */ function compare(tip) { if (slot == null || tip.amount > slot.tipped) { slot = new tipper(tip.from_user, tip.amount); } } hightip.compare = compare; /** * Print the help menu for hightip * @param message Requesting message */ function help(message) { notice.add("/hightip --Get the highest single tipper"); notice.post(message.user); } hightip.help = help; /** * Load the state string * @param state State string */ function load(state) { var tipped = state.split(" ")[0]; var name = state.split(" ")[1]; slot = new tipper(name, Number(tipped)); } hightip.load = load; /** * Get the name of the high tipper */ function name() { return slot == null ? null : slot.name; } hightip.name = name; /** * Get the amount tipped during this show */ function tipped() { return slot == null ? null : slot.tipped; } hightip.tipped = tipped; /** * Try to parse a valid command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/hightip": notice.send(slot.tipped + " " + slot.name, message.user); return true; default: return false; } } hightip.tryParse = tryParse; })(hightip || (hightip = {})); /** * Handles the leaderboard */ var leaderboard; /** * Handles the leaderboard */ (function (leaderboard) { "use strict"; /** * Number, in minutes, between rotations */ leaderboard.lapse = 10; /** * Default size of the leaderboard */ leaderboard.size = 5; /** * Prints the help for the leaderboard * @param message Requesting message */ function help(message) { notice.add("/leaderboard --Print the leaderboard"); notice.post(message.user); message['X-Spam'] = true; } leaderboard.help = help; /** * Is the tipper in the leaderboard position? * This function technically will work beyond the leaderboard, but why would you bother? * @param pos Leaderboard position * @param tipper Tipper to check */ function isPos(pos, tipper) { return tippers.top(pos)[pos - 1] === tipper; } leaderboard.isPos = isPos; /** * Print the leaderboard to chat * @param slots Amount of slots to print * @param sendTo User to send to */ function print(slots, sendTo) { if (slots === void 0) { slots = leaderboard.size; } if (sendTo === void 0) { sendTo = ""; } var top = tippers.top(slots); if (top != null && top.length != 0) notice.add("===== Leaderboard ====="); if (top[0] != null && top[0].tipped != 0) notice.add(emblems.goldmedal + top[0].name + " " + top[0].tipped); if (top[1] != null && top[1].tipped != 0) notice.add(emblems.silvermedal + top[1].name + " " + top[1].tipped); if (top[2] != null && top[2].tipped != 0) notice.add(emblems.bronzemedal + top[2].name + " " + top[2].tipped); if (top[3] != null && top[3].tipped != 0) notice.add(emblems.tinmedal + top[3].name + " " + top[3].tipped); if (top[4] != null && top[4].tipped != 0) notice.add(emblems.coppermedal + top[4].name + " " + top[4].tipped); notice.post(sendTo); } /** * Rotate the leaderboard * @param slots Amount of slots to print */ function rotate(slots) { if (slots === void 0) { slots = leaderboard.size; } print(slots); cb.setTimeout(rotate, leaderboard.lapse * 60 * 1000); } leaderboard.rotate = rotate; /** * Try to parse a leaderboard command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/leaderboard": print(leaderboard.size, message.user); return true; default: return false; } } leaderboard.tryParse = tryParse; })(leaderboard || (leaderboard = {})); /** * Represents a tipmenu item */ var menuitem = (function () { /** * Create a new menu item * @param name Name of the item * @param cost Cost of the item * @param handler Handler function when this item is tipped for * @param params Parameters for the handler function */ function menuitem(name, cost, handler) { var params = []; for (var _i = 3; _i < arguments.length; _i++) { params[_i - 3] = arguments[_i]; } this.name = name; this.cost = cost; this.handler = handler; this.params = params; } /** * Handle the item, if it has a handler * This will not call the handler if one is not assigned */ menuitem.prototype.handle = function (tip) { if (this.handler != null) { this.handler(tip, this.params); } }; return menuitem; }()); /** * Represents a tipmenu section */ var menusection = (function () { function menusection(name) { var items = []; for (var _i = 1; _i < arguments.length; _i++) { items[_i - 1] = arguments[_i]; } /** * The actual items of the section */ this.items = []; this.name = name; this.items = items; } /** * Add the item to the section * @param name Name of the item * @param cost Cost of the item * @param handler Handler for when the item is tipped for */ menusection.prototype.add = function (name, cost, handler) { var params = []; for (var _i = 3; _i < arguments.length; _i++) { params[_i - 3] = arguments[_i]; } this.items[this.items.length] = new menuitem(name, cost, handler, params); }; /** * Clear the menu of all items */ menusection.prototype.clear = function () { this.items = []; }; /** * Delete the item from the section * @param name Name of the item */ menusection.prototype.del = function (name) { this.items = cbjs.arrayRemove(this.items, this.lookup(name)); }; /** * List all items in the section */ menusection.prototype.list = function () { return this.items; }; /** * Lookup the item * @param name Name of the item to get */ menusection.prototype.lookup = function (name) { for (var _i = 0, _a = this.items; _i < _a.length; _i++) { var item = _a[_i]; if (item.name.toLowerCase() === name.toLowerCase()) { return item; } } return null; }; /** * Print this section to chat */ menusection.prototype.print = function (user, limit, discounted) { if (discounted === void 0) { discounted = false; } notice.add("=====" + this.name + "====="); var price; for (var _i = 0, _a = this.items; _i < _a.length; _i++) { var item = _a[_i]; price = discounted ? discount.apply(item, user) : item.cost; if (limit != null && price >= limit) continue; notice.add(price + emblems.token + item.name); } notice.apply(emblems.tipmenu); notice.post(user.user); }; return menusection; }()); /** * Manages notices, especially buffering notices */ var notice; /** * Manages notices, especially buffering notices */ (function (notice_1) { "use strict"; /** * Color to use in notices, if none specified */ notice_1.color = "#000000"; /** * Buffer of notices that haven't been posted */ var buffer = []; /** * Add the notice to the buffer * @param notice Notice to add */ function add(notice) { buffer[buffer.length] = notice; } notice_1.add = add; /** * Add the notices to the buffer * @param notices Notices to add */ function adds() { var notices = []; for (var _i = 0; _i < arguments.length; _i++) { notices[_i] = arguments[_i]; } for (var _a = 0, notices_1 = notices; _a < notices_1.length; _a++) { var notice_2 = notices_1[_a]; add(notice_2); } } notice_1.adds = adds; /** * Apply the emblem to each notice in the buffer * @param emblem Emblem to apply */ function apply(emblem) { for (var _i = 0, buffer_1 = buffer; _i < buffer_1.length; _i++) { var notice_3 = buffer_1[_i]; notice_3 = emblem + notice_3; } } notice_1.apply = apply; /** * Clear the buffer */ function clear() { buffer = []; } notice_1.clear = clear; /** * Print the help menu for notices * @param message Requesting message */ function help(message) { if (permissions.isAtLeastModerator(message)) { add("/note,notice <Message> --Send a notice to chat"); post(message.user); } } notice_1.help = help; /** * Post all notices in the buffer * @param to User to send to * @param textcolor Color of the text * @param weight Weight of the font * @param autoclear Clear the buffer automatically */ function post(to, textcolor, weight, autoclear) { if (to === void 0) { to = ""; } if (textcolor === void 0) { textcolor = notice_1.color; } if (weight === void 0) { weight = "bold"; } if (autoclear === void 0) { autoclear = true; } var message = buffer.join("\n"); cb.sendNotice(message, to, "#FFFFFF", textcolor, weight); if (autoclear) clear(); } notice_1.post = post; /** * Post all notices in the buffer * @param to Group to send to * @param textcolor Color of the text * @param weight Weight of the font */ function postGroup(to, textcolor, weight, autoclear) { if (textcolor === void 0) { textcolor = notice_1.color; } if (weight === void 0) { weight = "bold"; } if (autoclear === void 0) { autoclear = true; } var message = buffer.join("\n"); cb.sendNotice(message, "", "#FFFFFF", textcolor, weight, to); if (autoclear) clear(); } notice_1.postGroup = postGroup; /** * Send a notice * @param message Message to send * @param to User to send to * @param textcolor Color of the text * @param weight Weight of the font */ function send(message, to, textcolor, weight) { if (to === void 0) { to = ""; } if (textcolor === void 0) { textcolor = notice_1.color; } if (weight === void 0) { weight = "bold"; } cb.sendNotice(message, to, "#FFFFFF", textcolor, weight); } notice_1.send = send; /** * Send a notice * @param message Message to send * @param to Group to send to * @param textcolor Color of the text * @param weight Weight of the font */ function sendGroup(message, to, textcolor, weight) { if (textcolor === void 0) { textcolor = notice_1.color; } if (weight === void 0) { weight = "bold"; } cb.sendNotice(message, "", "#FFFFFF", textcolor, weight, to); } notice_1.sendGroup = sendGroup; /** * Try to parse a valid notice command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { if (permissions.isAtLeastModerator(message)) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/note": case "/notice": send(emblems.notice + m.join(" ")); return true; default: return false; } } return false; } notice_1.tryParse = tryParse; })(notice || (notice = {})); /** * Provides permissions checking * A lot of these are provided by the object anyways, are are implemented for the sake of orthogonality * This is solely for permissions purposes, the levels are: * broadcaster > trusted user > moderator > fanclub > tipped tons > tipped alot > tipped > has tokens > gray */ var permissions; /** * Provides permissions checking * A lot of these are provided by the object anyways, are are implemented for the sake of orthogonality * This is solely for permissions purposes, the levels are: * broadcaster > trusted user > moderator > fanclub > tipped tons > tipped alot > tipped > has tokens > gray */ (function (permissions) { "use strict"; /** * List of trusted users; users with elevated permissions */ var trusted = []; /** * Trust the users * @param users Users to trust */ function entrust() { var users = []; for (var _i = 0; _i < arguments.length; _i++) { users[_i] = arguments[_i]; } for (var _a = 0, users_1 = users; _a < users_1.length; _a++) { var user_1 = users_1[_a]; trusted[trusted.length] = user_1; } } permissions.entrust = entrust; /** * Remove trust of the users * @param users Users to detrust */ function detrust() { var users = []; for (var _i = 0; _i < arguments.length; _i++) { users[_i] = arguments[_i]; } for (var _a = 0, users_2 = users; _a < users_2.length; _a++) { var user_2 = users_2[_a]; trusted = cbjs.arrayRemove(trusted, user_2); } } permissions.detrust = detrust; /** * Is the user the broadcaster? * @param user User to check */ function isBroadcaster(user) { return user.user === cb.room_slug; } permissions.isBroadcaster = isBroadcaster; /** * Is the user a trusted user? * @param user User to check */ function isTrusted(user) { return cbjs.arrayContains(trusted, user.user); } permissions.isTrusted = isTrusted; /** * Is the user at least a trusted user? * @param user User to check */ function isAtLeastTrusted(user) { return isBroadcaster(user) || isTrusted(user); } permissions.isAtLeastTrusted = isAtLeastTrusted; /** * Is the user a moderator? * @param user User to check */ function isModerator(user) { return user.is_mod; } permissions.isModerator = isModerator; /** * Is the user at least a moderator? * @param user User to check */ function isAtLeastModerator(user) { return isAtLeastTrusted(user) || isModerator(user); } permissions.isAtLeastModerator = isAtLeastModerator; /** * Is the user in the fanclub? * @param user User to check */ function isInFanclub(user) { return user.in_fanclub; } permissions.isInFanclub = isInFanclub; /** * Is the user at least in the fanclub? * @param user User to check */ function isAtLeastInFanclub(user) { return isAtLeastModerator(user) || isInFanclub(user); } permissions.isAtLeastInFanclub = isAtLeastInFanclub; /** * Has the user tipped tons recently? * @param user User to check */ function hasTippedTons(user) { return user.tipped_tons_recently; } permissions.hasTippedTons = hasTippedTons; /** * Has the user at least tipped tons recently? * @param user User to check */ function hasAtLeastTippedTons(user) { return isAtLeastInFanclub(user) || hasTippedTons(user); } permissions.hasAtLeastTippedTons = hasAtLeastTippedTons; /** * Has the user tipped alot recently? * @param user User to check */ function hasTippedAlot(user) { return user.tipped_alot_recently; } permissions.hasTippedAlot = hasTippedAlot; /** * Has the user at least tipped alot recently? * @param user User to check */ function hasAtLeastTippedAlot(user) { return hasAtLeastTippedTons(user) || hasTippedAlot(user); } permissions.hasAtLeastTippedAlot = hasAtLeastTippedAlot; /** * Has the user tipped recently? * @param user User to check */ function hasTipped(user) { return user.tipped_recently; } permissions.hasTipped = hasTipped; /** * Has the user at least tipped recently? * @param user User to check */ function hasAtLeastTipped(user) { return hasAtLeastTippedAlot(user) || hasTipped(user); } permissions.hasAtLeastTipped = hasAtLeastTipped; /** * Does the user have tokens? * @param user User to check */ function hasTokens(user) { return user.has_tokens; } permissions.hasTokens = hasTokens; /** * Does the user at least have tokens? * @param user User to check */ function hasAtLeastTokens(user) { return hasAtLeastTipped(user) || hasTokens(user); } permissions.hasAtLeastTokens = hasAtLeastTokens; /** * Prints the help for permissions * @param message Requesting message */ function help(message) { if (permissions.isAtLeastTrusted(message)) { notice.add("/trust,trusted"); } if (permissions.isBroadcaster(message)) { notice.add(emblems.blank + "add <User>+ --Entrust the users"); notice.add(emblems.blank + "del,delete,rem,remove <User>+ --Detrust the users"); } if (permissions.isAtLeastTrusted(message)) { notice.add(emblems.blank + "list --List all trusted users"); notice.post(message.user); } } permissions.help = help; /** * Try to parse a permissions command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { if (permissions.isBroadcaster(message)) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/detrust": for (var _i = 0, m_1 = m; _i < m_1.length; _i++) { var user_3 = m_1[_i]; detrust(user_3); } return true; case "/entrust": for (var _a = 0, m_2 = m; _a < m_2.length; _a++) { var user_4 = m_2[_a]; entrust(user_4); } return true; case "/trust": case "/trusted": if (m.length === 0) return false; var operation = m.shift().toLowerCase(); switch (operation) { case "add": for (var _b = 0, m_3 = m; _b < m_3.length; _b++) { var user_5 = m_3[_b]; entrust(user_5); } return true; case "del": case "delete": case "rem": case "remove": for (var _c = 0, m_4 = m; _c < m_4.length; _c++) { var user_6 = m_4[_c]; detrust(user_6); } return true; case "help": help(message); return true; case "list": notice.send(trusted.join(", "), message.user); return true; default: return false; } } } return false; } permissions.tryParse = tryParse; })(permissions || (permissions = {})); /** * Manages rotating notices */ var rotater; /** * Manages rotating notices */ (function (rotater) { "use strict"; /** * Number, in minutes, between notices */ rotater.lapse = 3; /** * Notices in rotation */ var pool = []; /** * Index of the notice pool; current position */ var n = 0; /** * Add a notice to rotation * @param notice Notice to add */ function add(message) { pool[pool.length] = message; notice.send(emblems.notice + "'" + message + "' has been added to rotation"); } rotater.add = add; /** * Delete a notice from rotation * @param notice Notice literal or position to delete */ function del(message) { if (typeof message === "string") { pool = cbjs.arrayRemove(pool, message); notice.send(emblems.notice + "'" + message + "' has been removed from rotation"); } else if (typeof message === "number") { notice.send(emblems.notice + "'" + pool[message - 1] + "' has been removed from rotation"); pool = cbjs.arrayRemove(pool, pool[message - 1]); } } rotater.del = del; /** * Print the help menu for rotating notices * @param message Requesting message */ function help(message) { notice.add("/rotater,rotating,rotation"); if (permissions.isAtLeastModerator(message)) { notice.add(emblems.blank + "add <Message> --Add the notice to rotation"); } if (permissions.isAtLeastTrusted(message)) { notice.add(emblems.blank + "del,delete (<Message> | <Position>) --Delete the notice from rotation"); } notice.add(emblems.blank + "list,print --List all notices in rotation"); notice.post(message.user); notice.clear(); } rotater.help = help; /** * List all notices in rotation */ function list() { return pool; } rotater.list = list; function print(user) { var i = 0; for (var _i = 0, pool_1 = pool; _i < pool_1.length; _i++) { var note = pool_1[_i]; notice.add(++i + ") " + note); } notice.post(user.user); notice.clear(); } rotater.print = print; /** * Rotate and post notice */ function rotate() { notice.send(emblems.notice + pool[n++]); n %= pool.length; cb.setTimeout(rotate, rotater.lapse * 60 * 1000); } /** * Start the rotater */ function start() { cb.setTimeout(rotate, rotater.lapse * 60 * 1000); } rotater.start = start; /** * Try to parse a rotater command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/rotater": case "/rotating": case "/rotation": // Command is valid, break out break; default: return false; } if (m.length === 0) return false; var operation = m.shift().toLowerCase(); switch (operation) { case "add": if (permissions.isAtLeastModerator(message)) { rotater.add(m.join(" ")); return true; } return false; case "del": case "delete": if (permissions.isAtLeastTrusted(message)) { var pos = m.shift(); if (isNaN(Number(pos))) { // pos isn't actually a position, so put it back m.unshift(pos); rotater.del(m.join(" ")); } else { rotater.del(Number(pos)); } return true; } return false; case "help": help(message); return true; case "list": case "print": print(message); return true; default: return false; } } rotater.tryParse = tryParse; })(rotater || (rotater = {})); /** * Manages song requests */ var songqueue; /** * Manages song requests */ (function (songqueue) { "use strict"; /** * The actual queue of song requests */ var queue = []; /** * Add the song to the queue * @param user Who tipped for the request * @param song Song requested */ function add(user, song) { queue[queue.length] = new songrequest(user, song); notice.send(emblems.song + "'" + song + "' queued", cb.room_slug); } songqueue.add = add; /** * Get the next song from the queue * Returns null if no more songs */ function get() { if (queue.length === 0) return null; else return queue.shift(); } songqueue.get = get; /** * Print the help menu for the song queue * @param message Requesting message */ function help(message) { if (permissions.isBroadcaster(message)) { notice.add("/song"); notice.add(emblems.blank + "next --Get the next song from the queue"); notice.post(message.user); notice.clear(); } } songqueue.help = help; /** * Try to parse a song command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/song": // Command is valid, break out break; default: return false; } if (m.length === 0) return false; var operation = m.shift().toLowerCase(); switch (operation) { case "help": help(message); return true; case "next": if (permissions.isBroadcaster(message)) { var request = get(); if (request == null) { notice.send(emblems.song + "No songs in queue"); } else { notice.send(emblems.song + request.user + ": " + request.song); } return true; } return false; default: return false; } } songqueue.tryParse = tryParse; })(songqueue || (songqueue = {})); /** * Represents a song request */ var songrequest = (function () { function songrequest(user, song) { this.user = user; this.song = song; } return songrequest; }()); var tipmenu; (function (tipmenu) { "use strict"; /** * The specials menu section */ tipmenu.specials = new menusection("Specials"); /** * Specials command handler */ var special; (function (special) { /** * Print the help messages for the special manager * @param message Requesting message */ function help(message) { if (permissions.isAtLeastTrusted(message)) { notice.add("/special,specials"); notice.add(emblems.blank + "add <Cost> <Name> --Add the special to the menu"); notice.add(emblems.blank + "clr,clear --Clear all specials"); notice.add(emblems.blank + "del,delete <Name> --Delete the special from the menu"); notice.post(message.user); } } special.help = help; /** * Try to parse a specials command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { if (!permissions.isAtLeastTrusted(message)) return false; var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/special": case "/specials": // Command is valid, break out break; default: return false; } if (m.length === 0) return false; var operation = m.shift().toLowerCase(); var name; // This is assigned while parsing operations switch (operation) { case "add": var cost = m.shift(); if (isNaN(Number(cost))) { // Cost wasn't at the beginning, try finding it at the end m.unshift(cost); cost = m.pop(); if (isNaN(Number(cost))) return false; // No cost found, not a valid command } // We've found the cost, the rest is the name name = m.join(" "); tipmenu.specials.add(name, Number(cost)); notice.send(emblems.tipmenu + "'" + name + "' added as a special for " + cost + emblems.token); return true; case "clr": case "clear": tipmenu.specials.clear(); notice.send(emblems.tipmenu + "All specials have been removed"); return true; case "del": case "delete": name = m.join(" "); tipmenu.specials.del(name); notice.send(emblems.tipmenu + "'" + name + "' has been removed from the specials"); return true; case "help": help(message); return true; default: return false; } } special.tryParse = tryParse; })(special = tipmenu.special || (tipmenu.special = {})); })(tipmenu || (tipmenu = {})); /** * Calculates various stats */ var stats; /** * Calculates various stats */ (function (stats) { "use strict"; function meanHalves(sendTo) { notice.add("Upper Mean: " + tippers.meanUpper()); notice.add("Lower Mean: " + tippers.meanLower()); notice.post(sendTo); } stats.meanHalves = meanHalves; function medianTip(sendTo) { notice.add("Median Tip: " + tippers.median()); notice.post(sendTo); } stats.medianTip = medianTip; function showDuration(sendTo) { var duration = timers.showDuration(); notice.add("Show Duration: " + duration[0] + ":" + duration[1] + ":" + duration[2]); notice.post(sendTo); } stats.showDuration = showDuration; function tippersTotal(sendTo) { notice.add("Tippers Total: " + tippers.count); notice.post(sendTo); } stats.tippersTotal = tippersTotal; function tokensPerHour(sendTo) { var duration = timers.showDuration(); var minutes = duration[0] * 60 + duration[1]; var rate = (tippers.tipped() / minutes) * 60; notice.add("Tokens Per Hour: " + rate); notice.post(sendTo); } stats.tokensPerHour = tokensPerHour; function tokensPerTipper(sendTo) { notice.add("Tokens Per Tipper: " + tippers.tipped() / tippers.count()); notice.post(sendTo); } stats.tokensPerTipper = tokensPerTipper; function tokensTotal(sendTo) { notice.add("Tokens Total: " + tippers.tipped()); notice.post(sendTo); } stats.tokensTotal = tokensTotal; })(stats || (stats = {})); /** * Tallies items within the various managers */ var tallier; /** * Tallies items within the various managers */ (function (tallier) { "use strict"; /** * The actual tallies */ var tallies = []; /** * Add to the tally * @param item Item to add * @param amount Amount to add */ function add(item, amount) { if (amount === void 0) { amount = 1; } var tally = lookup(item); if (tally == null) { tallies[tallies.length] = [item, amount]; } else { tally[1] += amount; } } tallier.add = add; /** * Clear the tallies */ function clear() { tallies = []; } tallier.clear = clear; /** * Calculate the highest tip */ function highest() { if (tallies == null || tallies === []) return null; var high = [null, 0]; for (var _i = 0, tallies_1 = tallies; _i < tallies_1.length; _i++) { var tally = tallies_1[_i]; if (tally[1] > high[1]) high = tally; } return high; } tallier.highest = highest; /** * Lookup the item, and return its tally, if any, null otherwise * @param item Item to look for */ function lookup(item) { for (var _i = 0, tallies_2 = tallies; _i < tallies_2.length; _i++) { var tally = tallies_2[_i]; if (tally[0] === item) return tally; } return null; } tallier.lookup = lookup; })(tallier || (tallier = {})); /** * Represents a teamate, a tipper belonging to a team */ var teamate = (function () { function teamate(tipper, points) { if (points === void 0) { points = 0; } this.tipper = tipper; this.points = points; } teamate.prototype.name = function () { return this.tipper.name; }; teamate.prototype.tipped = function () { return this.tipper.tipped; }; return teamate; }()); /** * Represents a team */ var team = (function () { function team(emblem) { /** Members of the team */ this.members = []; this.emblem = ""; this.emblem = emblem; } /** * Add a user to the team * Because of a lack of data persistance, this is only temporary * @param user User to add */ team.prototype.add = function (user, points) { if (points === void 0) { points = 0; } // See if the user is already a tipper var tipper = tippers.lookup(user); if (tipper === null) { // The user isn't a tipper, so create a dummy entry tippers.dummy(user); tipper = tippers.lookup(user); } // Add the tipper, and their points, to the team this.members[this.members.length] = new teamate(tipper, points); }; /** * Add the users to the team * Because of a lack of data persistance, this is only temporary * @param users Users to add */ team.prototype.adds = function (users) { if (typeof users[0] === "string") { for (var _i = 0, _a = users; _i < _a.length; _i++) { var user_7 = _a[_i]; this.add(user_7); } } else { for (var _b = 0, _c = users; _b < _c.length; _b++) { var user_8 = _c[_b]; this.add(user_8[0], user_8[1]); } } }; /** * Apply the team emblem to a message if a member * @param message Message to apply emblem */ team.prototype.apply = function (message) { if (this.isMember(message.user)) { return this.emblem + message.m; } else { return message.m; } }; /** * Delete the user from the team * @param user User to remove */ team.prototype.del = function (user) { cbjs.arrayRemove(this.members, this.lookup(user)); }; /** * Delete the users from the team * @param user Users to remove */ team.prototype.dels = function (users) { for (var _i = 0, users_3 = users; _i < users_3.length; _i++) { var user_9 = users_3[_i]; cbjs.arrayRemove(this.members, this.lookup(user_9)); } }; /** * Is the user a member of this team? * @param user User to check */ team.prototype.isMember = function (user) { for (var _i = 0, _a = this.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.name() == user) return true; } return false; }; /** * The number of members in the team */ team.prototype.length = function () { return this.members.length; }; /** * List the users in this team */ team.prototype.list = function (withPoints) { if (withPoints === void 0) { withPoints = false; } this.sort(); var result = []; if (withPoints) { var points = void 0; for (var _i = 0, _a = this.members; _i < _a.length; _i++) { var member = _a[_i]; points = member.points + member.tipped(); result[result.length] = "[" + points + "] " + member.name(); } } else { for (var _b = 0, _c = this.members; _b < _c.length; _b++) { var member = _c[_b]; result[result.length] = member.name(); } } return result; }; /** * Load the state string into the team * This is used to implement a sort of data persistance, although it must be managed by the user * @param state State string of the team */ team.prototype.load = function (state) { var users = state.trim().split(","); var name; var points; for (var _i = 0, users_4 = users; _i < users_4.length; _i++) { var user_10 = users_4[_i]; name = user_10.trim().split(" ")[0]; points = Number(user_10.trim().split(" ")[1]); this.add(name, points); } }; /** * Lookup the specified user * @param name Name to lookup */ team.prototype.lookup = function (name) { for (var _i = 0, _a = this.members; _i < _a.length; _i++) { var member = _a[_i]; if (member.name() == name) { return member; } } return null; }; /** * Save the state string for the team * This is used to implement a sort of data persistance, although it must be managed by the user */ team.prototype.save = function () { this.sort(); var state = ""; for (var _i = 0, _a = this.members; _i < _a.length; _i++) { var member = _a[_i]; state += member.name() + " " + (member.points + member.tipped()) + ", "; } state = state.substring(0, state.length - 2); //Removes the trailing comma return state; }; /** * Sort the team by points, most first */ team.prototype.sort = function () { this.members = this.members.sort(function (a, b) { return (b.points + b.tipped()) - (a.points + a.tipped()); }); }; /** * Get the total points of this team */ team.prototype.points = function () { var result; for (var _i = 0, _a = this.members; _i < _a.length; _i++) { var member = _a[_i]; result += member.points; } return result; }; return team; }()); /** * Handles tickets */ var tickets; /** * Handles tickets */ (function (tickets) { "use strict"; /** * Cost for a ticket * Tickets aren't sold if this is null */ tickets.saleprice = null; /** * Prints the help for the ticket handler * @param message Requesting message */ function help(message) { notice.add("/ticket,tickets"); if (permissions.isAtLeastModerator(message)) { notice.add(emblems.blank + "holders --List all ticket holders"); } if (permissions.isAtLeastTrusted(message)) { notice.add(emblems.blank + "issue,give <names>+ --Issue a ticket to all specified users"); notice.add(emblems.blank + "revoke <names>+ --Revoke tickets from all specified users"); notice.add(emblems.blank + "sale,sell <cost> --Start selling tickets for the specified cost"); notice.add(emblems.blank + "start show [<message>] --Start the ticket show, with optional message to show non-ticket holders"); notice.add(emblems.blank + "stop sale,sell --Stop selling tickets"); notice.add(emblems.blank + "stop show --Stop the ticket show"); } } tickets.help = help; /** * Get all ticket holders */ function holders() { return cb.limitCam_allUsersWithAccess(); } tickets.holders = holders; /** * Is the user a ticket holder? * @param name Username to check */ function is_holder(name) { return cb.limitCam_userHasAccess(name); } tickets.is_holder = is_holder; /** * Issue a ticket to the specified users * @param name Names of the user */ function issue() { var names = []; for (var _i = 0; _i < arguments.length; _i++) { names[_i] = arguments[_i]; } cb.limitCam_addUsers(names); } tickets.issue = issue; /** * Revoke the ticket of the specified users * @param name Name of the users */ function revoke() { var names = []; for (var _i = 0; _i < arguments.length; _i++) { names[_i] = arguments[_i]; } cb.limitCam_removeUsers(names); } tickets.revoke = revoke; /** * Revoke all tickets */ function revokeAll() { cb.limitCam_removeAllUsers(); } tickets.revokeAll = revokeAll; /** * Start sale of tickets */ function startSales(cost) { tickets.saleprice = cost; } tickets.startSales = startSales; /** * Start the ticket show * @param message Message to show non-ticket holders */ function startShow(message) { if (message === void 0) { message = "Buy a ticket into the show for " + tickets.saleprice + " tokens"; } cb.limitCam_start(message); } tickets.startShow = startShow; /** * Stop sale of tickets */ function stopSales() { tickets.saleprice = null; } tickets.stopSales = stopSales; /** * Stop the ticket show */ function stopShow() { cb.limitCam_stop(); } tickets.stopShow = stopShow; /** * Try to parse a leaderboard command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/ticket": case "/tickets": // Command is valid, break out break; default: return false; } if (m.length === 0) return false; var operation = m.shift().toLowerCase(); switch (operation) { case "help": help(message); return true; case "holders": notice.send(holders().join(", "), message.user); return true; case "issue": case "give": for (var _i = 0, m_5 = m; _i < m_5.length; _i++) { var user_11 = m_5[_i]; issue(user_11); } notice.send("Tickets issued for: " + m, message.user); return true; case "revoke": for (var _a = 0, m_6 = m; _a < m_6.length; _a++) { var user_12 = m_6[_a]; revoke(user_12); } notice.send("Tickets revoked for: " + m, message.user); return true; case "sale": case "sell": var cost = m.shift(); if (isNaN(Number(cost))) { notice.send("'" + cost + "' wasn't recognized as a number", message.user); return false; } startSales(Number(cost)); notice.send("Ticket sales have started for " + tickets.saleprice + emblems.token); return true; case "start": if (m.length === 0) return false; operation = m.shift().toLowerCase(); switch (operation) { case "show": if (m.length === 0) { startShow(); } else { startShow(m.join(" ")); } return true; default: return false; } case "stop": if (m.length === 0) return false; operation = m.shift().toLowerCase(); switch (operation) { case "sale": case "sell": stopSales(); return true; case "show": stopShow(); return true; default: return false; } default: return false; } } tickets.tryParse = tryParse; })(tickets || (tickets = {})); /** * Represents a timer */ var timer = (function () { /** * Create a new timer * @param name Name of the timer * @param duration Duration of the timer, in seconds * @param delay Delay before the timer starts, in seconds */ function timer(name, duration, delay, onStart, onStop, onTick) { if (delay === void 0) { delay = 0; } this.name = name; this.duration = duration; this.remaining = duration; this.delay = delay; this.onStart = onStart; this.onStop = onStop; this.onTick = onTick; } /** * Extend the timer * @param seconds Seconds to extend by */ timer.prototype.extend = function (seconds) { this.duration += seconds; this.remaining += seconds; notice.send(emblems.timer + "'" + this.name + "' extended with " + seconds + "sec"); }; /** * Is the timer active? * This is true whether the timer is delayed or running * A timer is only inactive when it has stopped */ timer.prototype.isActive = function () { return this.delay > 0 || this.remaining > 0; }; /** * Is the timer currently delayed? */ timer.prototype.isDelayed = function () { return this.delay > 0; }; /** * Is the timer currently running? */ timer.prototype.isRunning = function () { return this.remaining < this.duration && this.remaining > 0; }; /** * Perform one tick of the timer, and call any events necessary */ timer.prototype.tick = function () { // Check event conditions if (this.delay === 0 && this.remaining === this.duration) { notice.send(emblems.timer + "'" + this.name + "' started with " + this.duration / 60 + "min"); if (this.onStart != null) this.onStart(); } else if (this.delay === 0 && this.remaining === 0) { notice.send(emblems.timer + "'" + this.name + "' has expired"); if (this.onStop != null) this.onStop(); } else if (this.delay === 0 && this.remaining % 60 === 0) { notice.send(emblems.timer + "'" + this.name + "' has " + this.remaining / 60 + "min remaining"); } // Time down as necessary if (this.delay > 0) { this.delay--; } else if (this.remaining > 0) { if (this.onTick != null) this.onTick(); this.remaining--; } }; return timer; }()); /** * Manages timers */ var timers; /** * Manages timers */ (function (timers) { "use strict"; /** * Pool of running timers */ var pool = []; /** * Duration of the show, in seconds */ var showtime = 0; /** * Add the timer to the pool * @param name Name of the timer * @param duration Duration to run for, in seconds * @param delay Delay before start, in seconds * @param onStart Function to call on start * @param onStop function to call on stop */ function add(name, duration, delay, onStart, onStop, onTick) { if (delay === void 0) { delay = 0; } pool[pool.length] = new timer(name, duration, delay, onStart, onStop, onTick); if (delay > 0) { notice.send(emblems.timer + "'" + name + "' will start in " + delay + "s"); } } timers.add = add; /** * Clear the pool of all timers */ function clear() { pool = []; } timers.clear = clear; /** * Delete the specified timer without properly stopping it * @param name Timer name or position to delete */ function del(timer) { if (typeof timer === "number") { notice.send(emblems.timer + "'" + pool[timer].name + "' has been removed"); pool = cbjs.arrayRemove(pool, pool[timer]); } else if (typeof timer === "string") { if (cbjs.arrayContains(pool, lookup(timer))) { notice.send(emblems.timer + "'" + timer + "' has been removed"); pool = cbjs.arrayRemove(pool, lookup(timer)); } } } timers.del = del; /** * Extend the timer by duration * @param name Name of the timer * @param duration Duration, in seconds, to extend run for */ function extend(name, duration) { var timer = lookup(name); if (timer != null) { timer.extend(duration); } } timers.extend = extend; /** * Prints the help menu for timers * @param message Requesting message */ function help(message) { if (permissions.isAtLeastModerator(message)) { notice.add("/timer,timers"); notice.add(emblems.blank + "add,start <Duration> <Name> --Add and start the timer"); } if (permissions.isAtLeastTrusted(message)) { notice.add(emblems.blank + "clr,clear --Clear and stop all timers"); notice.add(emblems.blank + "del,delete (<Name> | <Position>) --Delete the timer without any stop events"); notice.add(emblems.blank + "ext,extend <Duration> <Name> --Extend the timer"); } notice.add(emblems.blank + "list,print --List all active timers"); if (permissions.isAtLeastTrusted(message)) { notice.add(emblems.blank + "stop (<Name | <Position>) --Stop the timer next tick"); } notice.post(message.user); } timers.help = help; /** * List all active timers */ function list() { return pool; } timers.list = list; /** * Lookup the timer in the pool, null if not found * @param name Name to lookup */ function lookup(name) { for (var _i = 0, pool_2 = pool; _i < pool_2.length; _i++) { var timer_1 = pool_2[_i]; if (timer_1.name.toLowerCase() == name.toLowerCase()) { return timer_1; } } return null; } timers.lookup = lookup; /** * Get the current duration of the show * This is formatted time: [hours, minutes, seconds] */ function showDuration() { var hours = 0; var minutes = 0; var seconds = showtime; while (seconds >= 3600) { seconds -= 3600; hours += 1; } while (seconds >= 60) { seconds -= 60; minutes += 1; } return [hours, minutes, seconds]; } timers.showDuration = showDuration; /** * Start the timers */ function start() { cb.setTimeout(tick, 1000); } timers.start = start; /** * Set the timer to stop next tick * @param timer Timer to stop */ function stop(timer) { if (typeof timer === "number") { if (pool[timer] != null) pool[timer].remaining = 0; } else if (typeof timer === "string") { var t = lookup(timer); if (t != null) { t.remaining = 0; } } } timers.stop = stop; /** * Count down one interval */ function tick() { var keep = []; showtime += 1; for (var _i = 0, pool_3 = pool; _i < pool_3.length; _i++) { var timer_2 = pool_3[_i]; if (timer_2.isActive()) keep[keep.length] = timer_2; timer_2.tick(); } if (pool !== keep) { pool = keep; } cb.setTimeout(tick, 1000); } /** * Try to parse a timer command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); cb.log("command: " + command); switch (command) { case "/timer": case "/timers": // Command is valid, break out break; default: return false; } if (m.length === 0) return false; var operation = m.shift().toLowerCase(); cb.log("operation: " + operation); var name; // This is assigned while parsing operations var duration; // This is assigned while parsing operations var pos; // This is assigned while parsing operations switch (operation) { case "add": case "start": duration = m.shift(); if (isNaN(Number(duration))) { // Duration wasn't at the beginning, try finding it at the end m.unshift(duration); duration = m.pop(); if (isNaN(Number(duration))) return false; // No duration found, not a valid command } // We've found the duration, the rest is the name name = m.join(" "); timers.add(name, Number(duration) * 60); return true; case "clr": case "clear": timers.clear(); return true; case "del": case "delete": pos = m.shift(); if (isNaN(Number(pos))) { // pos isn't actually a position, so put it back m.unshift(pos); timers.del(m.join(" ")); } else { timers.del(Number(pos) - 1); } return true; case "ext": case "extend": duration = m.shift(); if (isNaN(Number(duration))) { // Duration wasn't at the beginning, try finding it at the end m.unshift(duration); duration = m.pop(); if (isNaN(Number(duration))) return false; // No duration found, not a valid command } // We've found the duration, the rest is the name name = m.join(" "); timers.extend(name, Number(duration) * 60); return true; case "help": help(message); return true; case "list": case "print": var i = 0; for (var _i = 0, pool_4 = pool; _i < pool_4.length; _i++) { var timer_3 = pool_4[_i]; notice.add(++i + ") '" + timer_3.name + "' with " + timer_3.remaining + "s"); } notice.apply(emblems.timer); notice.post(message.user); return true; case "stop": pos = m.shift(); if (isNaN(Number(pos))) { // pos isn't actually a position, so put it back m.unshift(pos); timers.stop(m.join(" ")); } else { timers.stop(Number(pos) - 1); } return true; default: return false; } } timers.tryParse = tryParse; })(timers || (timers = {})); /** * Represents a tipper; a user who as tipped */ var tipper = (function () { function tipper(name, tipped) { this.name = name; this.tipped = tipped; } return tipper; }()); /** * Manages and records tippers */ var tippers; /** * Manages and records tippers */ (function (tippers) { "use strict"; /** * All the tippers this show */ var pool = []; /** * Add the tip, incrementing an existing tipper, or adding a new one * @param tip Tip to add */ function add(tip) { var candidate = lookup(tip.from_user); if (candidate == null) { pool[pool.length] = new tipper(tip.from_user, 0); candidate = pool[pool.length - 1]; } candidate.tipped += tip.amount; } tippers.add = add; /** * Get the total amount of tippers */ function count() { return pool.length; } tippers.count = count; /** * Adds a dummy tipper * This creates an entry in the tippers manager, with no tip amount, which is necessary for teams * This should never, ever, be called outside of initialization * @param name Name of the tipper */ function dummy(name) { pool[pool.length] = new tipper(name, 0); } tippers.dummy = dummy; /** * Lookup the user, null if not found * @param user User to look up */ function lookup(user) { for (var _i = 0, pool_5 = pool; _i < pool_5.length; _i++) { var tipper_1 = pool_5[_i]; if (tipper_1.name === user) return tipper_1; } return null; } tippers.lookup = lookup; /** * Return the mean of the lower half */ function meanLower() { sort(); var lower = pool.slice(0, pool.length); var total = 0; for (var _i = 0, lower_1 = lower; _i < lower_1.length; _i++) { var tipper_2 = lower_1[_i]; total += tipper_2.tipped; } return total / lower.length; } tippers.meanLower = meanLower; /** * Return the mean of the upper half */ function meanUpper() { sort(); var upper = pool.slice(pool.length / 2, pool.length); var total = 0; for (var _i = 0, upper_1 = upper; _i < upper_1.length; _i++) { var tipper_3 = upper_1[_i]; total += tipper_3.tipped; } return total / upper.length; } tippers.meanUpper = meanUpper; /** * Return the median tip */ function median() { sort(); if (pool[Math.floor(pool.length / 2)] == null) { return NaN; } else { return pool[Math.floor(pool.length / 2)].tipped; } } tippers.median = median; /** * Sort the tippers, highest first */ function sort() { pool = pool.sort(function (a, b) { return b.tipped - a.tipped; }); } tippers.sort = sort; /** * Return the specified amount of top tippers * This is used to fetch a leaderboard, although it has other uses * @param amount Amount of tippers from the top to get */ function top(amount) { sort(); return pool.slice(0, amount); } tippers.top = top; /** * Get the total amount tipped */ function tipped() { var total = 0; for (var _i = 0, pool_6 = pool; _i < pool_6.length; _i++) { var tipper_4 = pool_6[_i]; total += tipper_4.tipped; } return total; } tippers.tipped = tipped; })(tippers || (tippers = {})); /** * Tracks viewers for stats purposes * Don't take the gender stats too seriously: people lie. This is just a curiousity. */ var viewers; /** * Tracks viewers for stats purposes * Don't take the gender stats too seriously: people lie. This is just a curiousity. */ (function (viewers) { "use strict"; viewers.current = 0; viewers.withTokens = 0; viewers.inFanclub = 0; viewers.claimMale = 0; viewers.claimFemale = 0; viewers.claimTrans = 0; viewers.claimCouple = 0; function enter(user) { viewers.current += 1; if (user.has_tokens) viewers.withTokens += 1; if (user.in_fanclub) viewers.inFanclub += 1; if (user.gender == "m") viewers.claimMale += 1; if (user.gender == "f") viewers.claimFemale += 1; if (user.gender == "s") viewers.claimTrans += 1; if (user.gender == "c") viewers.claimTrans += 1; } viewers.enter = enter; function leave(user) { viewers.current -= 1; if (user.has_tokens) viewers.withTokens -= 1; if (user.in_fanclub) viewers.inFanclub -= 1; if (user.gender == "m") viewers.claimMale -= 1; if (user.gender == "f") viewers.claimFemale -= 1; if (user.gender == "s") viewers.claimTrans -= 1; if (user.gender == "c") viewers.claimTrans -= 1; } viewers.leave = leave; })(viewers || (viewers = {})); /** * Manages votes and ballots */ var votes; /** * Manages votes and ballots */ (function (votes) { "use strict"; /** * The cast votes */ var casts = []; /** * The current ballot */ var ballot = []; /** * Cast or change a vote, validating it in the process * @param username Username of the voter * @param choice Choice voting for */ function cast(username, choice) { for (var _i = 0, ballot_1 = ballot; _i < ballot_1.length; _i++) { var ch = ballot_1[_i]; if (ch.toLowerCase() === choice.toLowerCase()) { casts[casts.length] = [username, choice]; notice.send(emblems.ballot + "Vote cast"); return; } } notice.send(emblems.ballot + "Your vote for '" + choice + "' was not recognized among the valid options", username); } votes.cast = cast; /** * Clear the cast votes and ballot */ function clear() { casts = []; ballot = []; } votes.clear = clear; /** * Print the help messages for voting * @param message Requesting message */ function help(message) { if (permissions.hasAtLeastTokens(message)) { notice.add("/vote <Choice> --Cast a vote for the choice"); } if (permissions.isAtLeastModerator(message)) { notice.add(emblems.blank + "start,ballot <Choice>,+ --Start voting among the specified choices"); notice.add(emblems.blank + "stop,end,tally --Stop voting, tally results, and declare the winner"); } notice.post(message.user); } votes.help = help; /** * Lookup a vote cast by the user, null if not found * @param username Username to look for */ function lookup(username) { for (var _i = 0, casts_1 = casts; _i < casts_1.length; _i++) { var cast_1 = casts_1[_i]; if (cast_1[0] === username) return cast_1; } return null; } votes.lookup = lookup; /** * Start a ballot with the specified choices * @param choices Ballot choices */ function start(choices) { clear(); ballot = choices; notice.add("A ballot has started between the following:"); for (var _i = 0, choices_1 = choices; _i < choices_1.length; _i++) { var choice = choices_1[_i]; notice.add(choice); } notice.apply(emblems.ballot); notice.post(); notice.clear(); } votes.start = start; /** * Stop voting, count the votes, and report the winner */ function stop() { if (casts == null || casts === []) { notice.send(emblems.ballot + "No votes have been cast"); return; } for (var _i = 0, casts_2 = casts; _i < casts_2.length; _i++) { var cast_2 = casts_2[_i]; tallier.add(cast_2[1]); } var highest = tallier.highest(); notice.send(emblems.ballot + "Winner is: '" + highest[0] + "' with " + highest[1] + " votes"); clear(); tallier.clear(); } votes.stop = stop; /** * Try to parse a vote command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/vote": case "/voting": // Command is valid, break out break; default: return false; } if (m.length === 0) return false; var operation = m.shift().toLowerCase(); switch (operation) { case "help": help(message); return true; case "start": case "ballot": if (!permissions.isAtLeastModerator(message)) return false; var choices = m.join(" ").split(","); for (var _i = 0, choices_2 = choices; _i < choices_2.length; _i++) { var choice = choices_2[_i]; choice = choice.trim(); } start(choices); return true; case "stop": case "end": case "tally": if (!permissions.isAtLeastModerator(message)) return false; stop(); return true; default: if (!permissions.hasAtLeastTokens(message)) return false; m.unshift(operation); cast(message.user, m.join(" ")); return true; } } votes.tryParse = tryParse; })(votes || (votes = {})); /** * Implements whispers */ var whisper; /** * Implements whispers */ (function (whisper) { "use strict"; /** * Print the help messages for whispers * @param message Requesting message */ function help(message) { if (permissions.hasAtLeastTokens(message)) { notice.add("/w,whisper"); notice.add(emblems.blank + "model <Message> --Send a message to the model"); notice.add(emblems.blank + "mod,mods,moderator,moderators <Message> --Send a message to all moderators"); notice.add(emblems.blank + "<User> <Message> --Send a message to the user"); notice.post(message.user); notice.clear(); } } whisper.help = help; /** * Do model whisper specific stuff * @param message Requesting message * @param m Remaining message */ function model(message, m) { // While not the case elsewhere, this command uses the permissions level to color the whisper, not just permit it. if (permissions.isTrusted(message)) notice.send(emblems.whisper + message.user + ": " + m, cb.room_slug, "#802080", "bolder"); else if (permissions.isModerator(message)) notice.send(emblems.whisper + message.user + ": " + m, cb.room_slug, "#802020", "bolder"); else if (permissions.isInFanclub(message)) notice.send(emblems.whisper + message.user + ": " + m, cb.room_slug, "#208020"); else if (permissions.hasTokens(message)) notice.send(emblems.whisper + message.user + ": " + m, cb.room_slug, "#808080"); } /** * Do mod whisper specific stuff * @param message Requesting message * @param m Remaining message */ function mods(message, m) { notice.add(emblems.whispermod + message.user + ": " + m); notice.post(cb.room_slug, "#802020", "bolder", false); notice.postGroup("red", "#802020", "bolder", false); notice.clear(); } /** * Try to parse a specials command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/model": model(message, m.join(" ")); notice.send(emblems.whisper + "Sent to: " + cb.room_slug, message.user); return true; case "/mod": case "/mods": case "/moderator": case "/moderators": mods(message, m.join(" ")); notice.send(emblems.whispermod + "Sent to all moderators", message.user); return true; case "/w": case "/whisper": // Command is valid but needs further parsing, break out break; default: return false; } if (m.length === 0) return false; var target = m.shift().toLowerCase(); switch (target) { case "help": //Not actually a target, but an option, so print help and return help(message); return true; case "model": model(message, m.join(" ")); notice.send(emblems.whisper + "Sent to: " + cb.room_slug, message.user); return true; case "mod": case "mods": case "moderator": case "moderators": mods(message, m.join(" ")); notice.send(emblems.whispermod + "Sent to all moderators", message.user); return true; default: if (target.toLowerCase() === cb.room_slug) model(message, m.join(" ")); else notice.send(emblems.whisper + message.user + ": " + m.join(" "), target, "#808080", "normal"); notice.send(emblems.whisper + "Sent to: " + target, message.user); return true; } } whisper.tryParse = tryParse; })(whisper || (whisper = {})); var teams; (function (teams) { teams.trainers = new team(" :Pokemontrainersbb "); teams.naughty = new team(" :naughty24 "); teams.nice = new team(" :nice24 "); /** * Print the help menu for teams * @param message Requesting message */ function help(message) { if (permissions.isAtLeastTrusted(message)) { notice.add("/team,teams --List the teams"); notice.add(emblems.blank + "<team> --List all users in the specified team"); notice.add(emblems.blank + "<team> add <user>+ --Add all users to the specified team"); notice.post(message.user); } } teams.help = help; /** * Try to parse a teams command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { if (!permissions.isAtLeastTrusted(message)) return false; var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/team": case "/teams": if (m.length === 0) { notice.send("Teams: trainers, naughty, nice", message.user); } else { var team_1 = m.shift().toLowerCase(); var operation = void 0; switch (team_1) { case "trainers": if (m.length === 0) { for (var _i = 0, _a = teams.trainers.list(); _i < _a.length; _i++) { var user_13 = _a[_i]; notice.send(user_13, message.user); } return true; } else { operation = m.shift().toLowerCase(); switch (operation) { case "add": teams.trainers.adds(m); notice.send("Added users", message.user); return true; default: return false; } } case "naughty": if (m.length === 0) { for (var _b = 0, _c = teams.naughty.list(); _b < _c.length; _b++) { var user_14 = _c[_b]; notice.send(user_14, message.user); } return true; } else { operation = m.shift().toLowerCase(); switch (operation) { case "add": teams.naughty.adds(m); notice.send("Added users", message.user); return true; default: return false; } } case "nice": if (m.length === 0) { for (var _d = 0, _e = teams.nice.list(); _d < _e.length; _d++) { var user_15 = _e[_d]; notice.send(user_15, message.user); } return true; } else { operation = m.shift().toLowerCase(); switch (operation) { case "add": teams.nice.adds(m); notice.send("Added users", message.user); return true; default: return false; } } default: notice.send("For teams, found '" + team_1 + "', but expected one of: trainers, naughty, nice", message.user); return false; } } default: return false; } } teams.tryParse = tryParse; })(teams || (teams = {})); var cb; (function (cb) { cb.settings_choices = [ { name: "anal", label: "Anal Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "pussy", label: "Pussy Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "spanks", label: "Spank Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "workout", label: "Workout Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "custPic", label: "Custom Picture", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "custVid", label: "Custom Video", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "pantySale", label: "Panty Sale", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "sockSale", label: "Sock Sale", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "colaban", label: "Colabanned Days", type: "int", defaultValue: 0, required: true, }, { name: "cumban", label: "Cumbanned Days", type: "int", defaultValue: 0, required: true, }, { name: "trainers", label: "Pokemon Trainers", type: "str", required: false, }, { name: "teamnaughty", label: "Team Naughty", type: "str", required: false, }, { name: "teamnice", label: "Team Nice", type: "str", required: false, }, { name: "htom", label: "High Tip of the Month", type: "str", required: true, }, { name: "trusted", label: "Trusted Users", type: "str", required: true, }, ]; })(cb || (cb = {})); var stats; (function (stats) { "use strict"; /** * Prints the help for stats * @param message Requesting message */ function help(message) { if (permissions.isAtLeastTrusted(message)) { notice.add("/stats,statistics --Get all calculated stats"); notice.post(message.user); message['X-Spam'] = true; } } stats.help = help; /** * Print all the stats * @param message Requesting message */ function print(message) { stats.showDuration(message.user); stats.tokensTotal(message.user); stats.tippersTotal(message.user); stats.tokensPerHour(message.user); stats.tokensPerTipper(message.user); stats.meanHalves(message.user); stats.medianTip(message.user); listViewers(message.user); listBans(message.user); } stats.print = print; function listBans(sendTo) { notice.add("Cola Ban: " + tipmenu.flags.colaban); notice.add("Cum Ban: " + tipmenu.flags.cumban); notice.post(sendTo); } stats.listBans = listBans; function listViewers(sendTo) { notice.add("Viewers (Signed In): " + viewers.current); notice.add("Viewers (With Tokens): " + viewers.withTokens); notice.post(sendTo); } stats.listViewers = listViewers; /** * Try to parse a stats command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { if (permissions.isAtLeastTrusted(message)) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/stats": case "/statistcs": print(message); return true; default: return false; } } return false; } stats.tryParse = tryParse; })(stats || (stats = {})); var handlers; (function (handlers) { function ballGag() { var timer = timers.lookup("Ball Gag"); if (timer != null) { timer.extend(5 * 60); } else { timers.add("Ball Gag", 5 * 60, 45); } } handlers.ballGag = ballGag; function ballGagMute() { var timer = timers.lookup("Ball Gag with Mute"); if (timer != null) { timer.extend(5 * 60); } else { timers.add("Ball Gag with Mute", 5 * 60, 45); } } handlers.ballGagMute = ballGagMute; function bjDildo() { var timer = timers.lookup("BJ Dildo"); if (timer != null) { timer.extend(3 * 60); } else { timers.add("BJ Dildo", 3 * 60, 45); } } handlers.bjDildo = bjDildo; function buttplug() { var timer = timers.lookup("Buttplug"); if (timer != null) { timer.extend(30 * 60); } else { timers.add("Buttplug", 30 * 60, 60, function () { tipmenu.flags.anal = false; tipmenu.build(); }, function () { tipmenu.flags.anal = true; tipmenu.build(); }); } } handlers.buttplug = buttplug; function colaBan(amount) { tipmenu.flags.colaban += Number(amount); tipmenu.build(); } handlers.colaBan = colaBan; function collar() { var timer = timers.lookup("Collar"); if (timer != null) { timer.extend(3 * 60); } else { timers.add("Collar", 3 * 60, 60); } } handlers.collar = collar; function cumBan(amount) { tipmenu.flags.cumban += Number(amount); tipmenu.build(); } handlers.cumBan = cumBan; function fingerPussy() { var timer = timers.lookup("Finger Pussy"); if (timer != null) { timer.extend(3 * 60); } else { timers.add("Finger Pussy", 3 * 60, 30); } } handlers.fingerPussy = fingerPussy; function hitachi() { var timer = timers.lookup("Hitachi"); if (timer != null) { timer.extend(3 * 60); } else { timers.add("Hitachi", 3 * 60, 45); } } handlers.hitachi = hitachi; function dildoPussy() { var timer = timers.lookup("Dildo Pussy"); if (timer != null) { timer.extend(3 * 60); } else { timers.add("Dildo Pussy", 3 * 60, 45); } } handlers.dildoPussy = dildoPussy; function nipClamps() { var timer = timers.lookup("Nip Clamps"); if (timer != null) { timer.extend(5 * 60); } else { timers.add("Nip Clamps", 5 * 60, 45); } } handlers.nipClamps = nipClamps; function pantygag() { var timer = timers.lookup("Panty Gag"); if (timer != null) { timer.extend(5 * 60); } else { timers.add("Panty Gag", 5 * 60, 45); } } handlers.pantygag = pantygag; function teamNaughty(tip) { if (teams.naughty.isMember(tip.from_user)) { return; } else { teams.naughty.add(tip.from_user); } teams.nice.del(tip.from_user); } handlers.teamNaughty = teamNaughty; function teamNice(tip) { if (teams.nice.isMember(tip.from_user)) { return; } else { teams.nice.add(tip.from_user); } teams.naughty.del(tip.from_user); } handlers.teamNice = teamNice; function trainer(tip) { if (teams.trainers.isMember(tip.from_user)) { return; } else { teams.trainers.add(tip.from_user); } } handlers.trainer = trainer; })(handlers || (handlers = {})); var tipmenu; (function (tipmenu) { /** * Flags which control what is active in the tipmenu */ var flags; (function (flags) { flags.colaban = 0; flags.cumban = 0; flags.anal = false; flags.spanks = false; flags.pussy = false; flags.workout = false; flags.customPic = false; flags.customVid = false; flags.pantySale = false; flags.sockSale = false; })(flags = tipmenu.flags || (tipmenu.flags = {})); tipmenu.naughty = new menusection("Naughty"); tipmenu.nice = new menusection("Nice"); tipmenu.anal = new menusection("Anal"); tipmenu.funny = new menusection("Funny"); tipmenu.workout = new menusection("Workout"); tipmenu.merchandise = new menusection("Merchandise"); /** * Build the tipmenu with whatever is assigned in flags */ function build() { tipmenu.naughty.clear(); tipmenu.nice.clear(); tipmenu.anal.clear(); tipmenu.funny.clear(); tipmenu.workout.clear(); tipmenu.merchandise.clear(); // Build Naughty Section if (flags.spanks) { tipmenu.naughty.add("2 Hand Spanks (Ass)", 10); tipmenu.naughty.add("2 Panty Spanks (Pussy)", 12); tipmenu.naughty.add("2 Hand Spanks (Pussy)", 14); tipmenu.naughty.add("2 Paddle Spanks (Ass)", 15); tipmenu.naughty.add("2 Whip Spanks (Ass)", 20); tipmenu.naughty.add("2 Paddle Spanks (Pussy)", 22); tipmenu.naughty.add("2 Crop Spanks (Ass)", 27); tipmenu.naughty.add("2 Spoon Spanks (Ass)", 36); tipmenu.naughty.add("2 Wooden Paddle Spanks (Ass)", 47); } tipmenu.naughty.add("Nip Clamps (5min)", 74, handlers.nipClamps); tipmenu.naughty.add("Wear a Collar (3min)", 99, handlers.collar); tipmenu.naughty.add("Panty Gag (5min)", 129, handlers.pantygag); tipmenu.naughty.add("Ball Gag (5min)", 135, handlers.ballGag); tipmenu.naughty.add("Add Clothing", 140); tipmenu.naughty.add("Gag Ball & Mute (5min)", 150, handlers.ballGagMute); tipmenu.naughty.add("Touch Ban (10min)", 165); if (flags.spanks) { tipmenu.naughty.add("50 Hand Spanks (Ass)", 225); tipmenu.naughty.add("50 Paddle Spanks (Ass)", 301); tipmenu.naughty.add("50 Whip Spanks (Ass)", 460); tipmenu.naughty.add("50 Crop Spanks (Ass)", 502); tipmenu.naughty.add("50 Spoon Spanks (Ass)", 598); tipmenu.naughty.add("50 Wooden Paddle Spanks (Ass)", 898); } tipmenu.naughty.add("Cola Ban (1day)", 444, handlers.colaBan, +1); tipmenu.naughty.add("Cola Ban (1wk)", 3000, handlers.colaBan, +7); tipmenu.naughty.add("Cum Deny (1day)", 1696, handlers.cumBan, +1); tipmenu.naughty.add("Cum Deny (1wk)", 10000, handlers.cumBan, +7); // Build Nice Section tipmenu.nice.add("Simple Request", 5); tipmenu.nice.add("Flash (Foot)", 30); tipmenu.nice.add("Flash (Specify)", 50); tipmenu.nice.add("Lotion Body Part", 60); tipmenu.nice.add("BJ Dildo", 101, handlers.bjDildo); if (flags.pussy) { tipmenu.nice.add("Finger Pussy (3min)", 110, handlers.fingerPussy); } tipmenu.nice.add("Remove Clothing", 145); if (flags.pussy) { tipmenu.nice.add("Dildo Pussy (3min)", 200, handlers.dildoPussy); tipmenu.nice.add("Hitachi (3min)", 299, handlers.hitachi); } tipmenu.nice.add("InstaNaked", 1501); if (flags.cumban <= 0) { tipmenu.nice.add("InstaCum", 1750); } if (flags.colaban > 0) { tipmenu.nice.add("Cola Reverse (1day)", 433, handlers.colaBan, -1); tipmenu.nice.add("Cola Reverse (1wk)", 2990, handlers.colaBan, -7); } if (flags.cumban > 0) { tipmenu.nice.add("Cum Reverse (1day)", 3686, handlers.cumBan, -1); tipmenu.nice.add("Cum Reverse (1wk)", 10001, handlers.cumBan, -7); } // Build Anal Section if (flags.anal) { tipmenu.anal.add("Small Buttplug (30min)", 300, handlers.buttplug); tipmenu.anal.add("Foxtail Buttplug (30min)", 325, handlers.buttplug); tipmenu.anal.add("Flower Buttplug (30min)", 400, handlers.buttplug); tipmenu.anal.add("Medium Buttplug (30min)", 499, handlers.buttplug); } // Build Funny Section tipmenu.funny.add("Perv Tax", 4); tipmenu.funny.add("Fap Tax", 6); tipmenu.funny.add("Princess Tax", 7); tipmenu.funny.add("Asshole Tax", 8); tipmenu.funny.add("Song Request", 35); tipmenu.funny.add("Weird Game Pull", 40); tipmenu.funny.add("Talk Like a Grey", 45); tipmenu.funny.add("Weird Game Addition", 105); // Build Workout Section if (flags.workout) { tipmenu.workout.add("10 Jumping Jacks", 16); tipmenu.workout.add("10 Hip Thrusts", 33); tipmenu.workout.add("10 Squats", 44); tipmenu.workout.add("50 Jumping Jacks", 70); tipmenu.workout.add("50 Hip Thrusts", 161); tipmenu.workout.add("50 Squats", 202); } // Build Merchandise Section tipmenu.merchandise.add("Snap Chat (1mo)", 115); tipmenu.merchandise.add("Snap Chat (3mo)", 250); tipmenu.merchandise.add("Snap Chat (6mo)", 525); tipmenu.merchandise.add("Team Nice (1mo)", 122, handlers.teamNice); tipmenu.merchandise.add("Team Nice (life)", 1222, handlers.teamNice); tipmenu.merchandise.add("Team Naughty (1mo)", 121, handlers.teamNaughty); tipmenu.merchandise.add("Team Naughty (life)", 1221, handlers.teamNaughty); tipmenu.merchandise.add("Pokémon Trainer (1mo)", 225, handlers.trainer); tipmenu.merchandise.add("Pokémon Trainer (3mo)", 425, handlers.trainer); tipmenu.merchandise.add("Pokémon Trainer (6mo)", 725, handlers.trainer); if (flags.customPic) { tipmenu.merchandise.add("Custom Photoset", 260); } if (flags.customVid) { tipmenu.merchandise.add("Custom Video (max 5min)", 600); tipmenu.merchandise.add("Custom Video (max 15min)", 1250); } if (flags.pantySale) { tipmenu.merchandise.add("Dirty Panties", 800); tipmenu.merchandise.add("Dirty Panties with Pics", 1050); } if (flags.customVid && flags.pantySale) { tipmenu.merchandise.add("Dirty Panties with Video", 1100); } if (flags.sockSale) { tipmenu.merchandise.add("Sweaty Socks", 501); tipmenu.merchandise.add("Pussy Juice Socks with Pics", 650); tipmenu.merchandise.add("Pussy Juice Socks with Video", 701); } tipmenu.merchandise.add("Pussy Juice Pops", 555); tipmenu.merchandise.add("Pussy Juice Pops with Video", 850); } tipmenu.build = build; /** * Print the help messages for tipmenu * @param message Requesting message */ function help(message) { notice.add("/tipmenu --Get the entire tipmenu"); notice.add(emblems.blank + "<Section>+ --Get only the specified sections"); notice.add(emblems.blank + "limit <Cost> --Get all items lesser or equal to the specified cost"); if (permissions.isAtLeastTrusted(message)) { notice.add(emblems.blank + "set (<Flag> <Level>)+ --Set each specified flag to level, and rebuild the tipmenu"); } notice.post(message.user); } tipmenu.help = help; /** * Attempt to match the tip to an item in the menu * @param tip Tip to match */ function match(tip) { var price; for (var _i = 0, _a = tipmenu.specials.list(); _i < _a.length; _i++) { var item = _a[_i]; price = item.cost; if (tip.amount === price) return item; } for (var _b = 0, _c = tipmenu.naughty.list(); _b < _c.length; _b++) { var item = _c[_b]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _d = 0, _e = tipmenu.nice.list(); _d < _e.length; _d++) { var item = _e[_d]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _f = 0, _g = tipmenu.nice.list(); _f < _g.length; _f++) { var item = _g[_f]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _h = 0, _j = tipmenu.anal.list(); _h < _j.length; _h++) { var item = _j[_h]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _k = 0, _l = tipmenu.funny.list(); _k < _l.length; _k++) { var item = _l[_k]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _m = 0, _o = tipmenu.workout.list(); _m < _o.length; _m++) { var item = _o[_m]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _p = 0, _q = tipmenu.merchandise.list(); _p < _q.length; _p++) { var item = _q[_p]; price = item.cost; if (tip.amount === price) return item; } return null; } tipmenu.match = match; /** * Print the tipmenu to chat * The default flags is not an error, the snapchat section is not printed by default * @param message Requesting message * @param flags Controls which sections are printed */ function print(message, limit, flags) { if (limit === void 0) { limit = null; } if (flags === void 0) { flags = [true, true, true, true, true, true]; } if (flags[0]) tipmenu.specials.print(message, limit); if (flags[1]) tipmenu.naughty.print(message, limit, true); if (flags[2]) tipmenu.nice.print(message, limit, true); if (flags[3]) tipmenu.anal.print(message, limit, true); if (flags[4]) tipmenu.funny.print(message, limit, true); if (flags[5]) tipmenu.workout.print(message, limit, true); if (flags[6]) tipmenu.merchandise.print(message, limit); } tipmenu.print = print; /** * Try to parse a tipmenu command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/tipmenu": if (m.length === 0) { print(message); return true; } else { var sections = [false, false, false, false, false, false]; var setmode = false; var word = void 0; var level = void 0; while (m.length !== 0) { word = m.shift().toLowerCase(); switch (word) { case "limit": if (m.length === 0) return false; var limit = m.shift(); if (isNaN(Number(limit))) return false; print(message, Number(limit)); return true; case "anal": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": flags.anal = true; tipmenu.build(); notice.send(emblems.tipmenu + "Anal items are now active"); continue; case "off": flags.anal = false; tipmenu.build(); notice.send(emblems.tipmenu + "Anal items are no longer active"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | on)", message.user); return false; } } sections[3] = true; break; case "funny": sections[4] = true; break; case "merchandise": sections[6] = true; break; case "naughty": sections[1] = true; break; case "nice": sections[2] = true; break; case "panty": case "panties": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": flags.pantySale = true; tipmenu.build(); notice.send(emblems.tipmenu + "Panties are now for sale"); continue; case "off": flags.pantySale = false; tipmenu.build(); notice.send(emblems.tipmenu + "Panties are no longer for sale"); continue; default: notice.send("For '" + word + ", found '" + level + "', but expected a level of (off | on)", message.user); return false; } } break; case "pic": case "pics": case "picture": case "pictures": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": flags.customPic = true; tipmenu.build(); notice.send(emblems.tipmenu + "Custom Pictures are now for sale"); continue; case "off": flags.customPic = false; tipmenu.build(); notice.send(emblems.tipmenu + "Custom Pictures are no longer for sale"); continue; default: notice.send("For '" + word + ", found '" + level + "', but expected a level of (off | on)", message.user); return false; } } break; case "pussy": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": flags.pussy = true; tipmenu.build(); notice.send(emblems.tipmenu + "Pussy items are now active"); continue; case "off": flags.pussy = false; tipmenu.build(); notice.send(emblems.tipmenu + "Pussy items are no longer active"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | on)", message.user); return false; } } break; case "set": if (permissions.isAtLeastTrusted(message)) { setmode = true; } break; case "sock": case "socks": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": flags.sockSale = true; tipmenu.build(); notice.send(emblems.tipmenu + "Socks are now for sale"); continue; case "off": flags.sockSale = false; tipmenu.build(); notice.send(emblems.tipmenu + "Socks are no longer for sale"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | on)", message.user); return false; } } break; case "spank": case "spanks": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": flags.spanks = true; tipmenu.build(); notice.send(emblems.tipmenu + "Spank items are now active"); continue; case "off": flags.pussy = false; tipmenu.build(); notice.send(emblems.tipmenu + "Spank items are no longer active"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | on)", message.user); return false; } } break; case "special": case "specials": sections[0] = true; break; case "vid": case "vids": case "video": case "videos": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": flags.customVid = true; tipmenu.build(); notice.send(emblems.tipmenu + "Custom Videos are now for sale"); continue; case "off": flags.customVid = false; tipmenu.build(); notice.send(emblems.tipmenu + "Custom Videos are no longer for sale"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | on)", message.user); return false; } } case "workout": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": flags.workout = true; tipmenu.build(); notice.send(emblems.tipmenu + "Workout items are now active"); continue; case "off": flags.workout = false; tipmenu.build(); notice.send(emblems.tipmenu + "Workout items are no longer active"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | on)", message.user); return false; } } sections[5] = true; break; default: break; } } print(message, null, sections); for (var _i = 0, sections_1 = sections; _i < sections_1.length; _i++) { var flag = sections_1[_i]; if (flag) return true; } return false; } default: return false; } } tipmenu.tryParse = tryParse; })(tipmenu || (tipmenu = {})); /** * Misc. room stuff */ var room; /** * Misc. room stuff */ (function (room) { /** * Prints the full help menu * @param message Requesting message */ function help(message) { hightip.help(message); notice.help(message); permissions.help(message); rotater.help(message); songqueue.help(message); tipmenu.special.help(message); stats.help(message); teams.help(message); tickets.help(message); timers.help(message); tipmenu.help(message); votes.help(message); whisper.help(message); } /** * Try to parse a room command, returning true if a valid command is found * @param message Requesting message */ function tryParse(message) { var m = message.m.split(" "); if (m.length === 0) return false; var command = m.shift().toLowerCase(); switch (command) { case "/room": if (m.length === 0) return false; var command_1 = m.shift().toLowerCase(); switch (command_1) { case "help": break; default: return false; } // This deliberately falls through case "/roomhelp": help(message); return true; } return false; } room.tryParse = tryParse; })(room || (room = {})); cb.onEnter(function (user) { notice.adds("Welcome to my room!", "To see available commands, enter /roomhelp in chat", "Check out the tip menu with /tipmenu"); notice.apply(emblems.notice); notice.post(user.user); viewers.enter(user); if (permissions.isAtLeastInFanclub(user) && !tickets.is_holder(user.user)) { tickets.issue(user.user); } }); cb.onLeave(function (user) { if (hightip.name() != null && hightip.name() === user.user) { notice.send(emblems.notice + "King " + hightip.name() + " has left... Quick, steal the" + emblems.crown); } viewers.leave(user); }); cb.onMessage(function (message) { // Mark a message as spam if a foreslash is found at the begining if (message.m.trim().charAt(0) === "/") message['X-Spam'] = true; /** Whether a valid command has been found while parsing */ var validCommand = false; // Attempt to parse a command // This is goal-directed parsing, essentially, JavaScript just doesn't have any good syntax for it // While a command has not been found, keep trying to parse commands // When a command has been found, mark it as spam, which in turn avoids further attempts at parsing if (!validCommand) { validCommand = hightip.tryParse(message); } if (!validCommand) { validCommand = leaderboard.tryParse(message); } if (!validCommand) { validCommand = notice.tryParse(message); } if (!validCommand) { validCommand = permissions.tryParse(message); } if (!validCommand) { validCommand = room.tryParse(message); } if (!validCommand) { validCommand = rotater.tryParse(message); } if (!validCommand) { validCommand = songqueue.tryParse(message); } if (!validCommand) { validCommand = tipmenu.special.tryParse(message); } if (!validCommand) { validCommand = stats.tryParse(message); } if (!validCommand) { validCommand = teams.tryParse(message); } if (!validCommand) { validCommand = tickets.tryParse(message); } if (!validCommand) { validCommand = timers.tryParse(message); } if (!validCommand) { validCommand = tipmenu.tryParse(message); } if (!validCommand) { validCommand = votes.tryParse(message); } if (!validCommand) { validCommand = whisper.tryParse(message); } // A command was found, even if invalid, so return if (message['X-Spam'] || validCommand) return message; // Apply team/user emblems message.m = teams.trainers.apply(message); message.m = teams.naughty.apply(message); message.m = teams.nice.apply(message); if (message.user === "dyls011") message.m = " :dylsdildo " + message.m; if (message.user === "entomy") message.m = " :mini-grumpycat " + message.m; if (message.user === "cutelilpiggy") message.m = " :grumpypig " + message.m; // Apply tip amount var tipper = tippers.lookup(message.user); if (tipper !== null && tipper.tipped !== 0) { message.m = "[" + tipper.tipped + "] " + message.m; } // Return the message return message; }); cb.onTip(function (tip) { tippers.add(tip); hightip.compare(tip); var match = tipmenu.match(tip); if (match != null) { notice.send(emblems.tipmenu + tip.from_user + " has tipped for " + match.name); match.handle(tip); } if (tickets.saleprice != null && tip.amount == tickets.saleprice) { tickets.issue(tip.from_user); } }); /** * Initialization code */ { notice.color = "#802060"; discount.fanclub = 0.10; timers.start(); if (cb.settings.htom !== undefined) { hightip.load(cb.settings.htom); } rotater.add(" :ashbangertwitter "); rotater.add("Check me out on ManyVids: BlondieBanger.ManyVids.com"); rotater.add("Check out the tipmenu with: /tipmenu"); rotater.add("Join the fanclub to receive a discount of: " + discount.fanclub * 100 + "%"); rotater.add("Join Team Naughty for 121 " + emblems.token + " or Team Nice for 122 " + emblems.token + ". Look at the bio for info."); rotater.add("High Tip of the Month receives a custom video. Currently: " + hightip.name() + " with " + hightip.tipped() + emblems.token); rotater.start(); leaderboard.rotate(5); tipmenu.flags.colaban = cb.settings.colaban; tipmenu.flags.cumban = cb.settings.cumban; tipmenu.flags.anal = cb.settings.anal == "on"; tipmenu.flags.customPic = cb.settings.custPic == "on"; tipmenu.flags.customVid = cb.settings.custVid == "on"; tipmenu.flags.pantySale = cb.settings.pantySale == "on"; tipmenu.flags.pussy = cb.settings.pussy == "on"; tipmenu.flags.sockSale = cb.settings.sockSale == "on"; tipmenu.flags.spanks = cb.settings.spanks == "on"; tipmenu.flags.workout = cb.settings.workout == "on"; tipmenu.build(); if (cb.settings.trainers !== undefined) { for (var _i = 0, _a = cb.settings.trainers.split(" "); _i < _a.length; _i++) { var member = _a[_i]; teams.trainers.add(member); } } if (cb.settings.teamnaughty !== undefined) { for (var _b = 0, _c = cb.settings.teamnaughty.split(" "); _b < _c.length; _b++) { var member = _c[_b]; teams.naughty.add(member); } } if (cb.settings.teamnice !== undefined) { for (var _d = 0, _e = cb.settings.teamnice.split(" "); _d < _e.length; _d++) { var member = _e[_d]; teams.nice.add(member); } } if (cb.settings.trusted !== undefined) { for (var _f = 0, _g = cb.settings.trusted.split(" "); _f < _g.length; _f++) { var member = _g[_f]; permissions.entrust(member); } } }
© Copyright Chaturbate 2011- 2024. All Rights Reserved.