Bots Home
|
Create an App
MitzysRoom
Author:
thursty
Description
Source Code
Launch Bot
Current Users
Created by:
Thursty
/** * 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 "hatchery" * This is a sort of progressional system for emblems, the more you tip, the further you progress. * It's so called because it was created to "hatch" baby lizards from eggs. */ var hatchery; /** * Manages the "hatchery" * This is a sort of progressional system for emblems, the more you tip, the further you progress. * It's so called because it was created to "hatch" baby lizards from eggs. */ (function (hatchery) { "use strict"; hatchery.level1 = ""; hatchery.level2 = ""; hatchery.level3 = ""; hatchery.level4 = ""; hatchery.level5 = ""; hatchery.level6 = ""; hatchery.level7 = ""; hatchery.level8 = ""; hatchery.level9 = ""; hatchery.level10 = ""; /** * Apply a hatchery emblem if applicable * @param message Requesting message */ function apply(message) { var tipper = tippers.lookup(message.user); if (tipper == null) return message.m; if (tipper.tipped >= hatchery.progression * 10) return hatchery.level10 + message.m; else if (tipper.tipped >= hatchery.progression * 9) return hatchery.level9 + message.m; else if (tipper.tipped >= hatchery.progression * 8) return hatchery.level8 + message.m; else if (tipper.tipped >= hatchery.progression * 7) return hatchery.level7 + message.m; else if (tipper.tipped >= hatchery.progression * 6) return hatchery.level6 + message.m; else if (tipper.tipped >= hatchery.progression * 5) return hatchery.level5 + message.m; else if (tipper.tipped >= hatchery.progression * 4) return hatchery.level4 + message.m; else if (tipper.tipped >= hatchery.progression * 3) return hatchery.level3 + message.m; else if (tipper.tipped >= hatchery.progression * 2) return hatchery.level2 + message.m; else if (tipper.tipped >= hatchery.progression) return hatchery.level1 + message.m; else return message.m; } hatchery.apply = apply; })(hatchery || (hatchery = {})); /** * 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, params) { if (params === void 0) { params = this.params; } if (this.handler != null) { this.handler(tip, 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, type) { if (type === void 0) { type = requesttype.play; } queue[queue.length] = new songrequest(user, song, type); switch (type) { case requesttype.dance: notice.send(emblems.song + "Dance: '" + song + "' queued", cb.room_slug); break; case requesttype.karaoke: notice.send(emblems.song + "Karaoke: '" + song + "' queued", cb.room_slug); break; case requesttype.play: notice.send(emblems.song + "Song: '" + song + "' queued", cb.room_slug); break; } } 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 { switch (request.type) { case requesttype.dance: notice.send(emblems.song + request.user + ":Dance: " + request.song); break; case requesttype.karaoke: notice.send(emblems.song + request.user + ":Karaoke: " + request.song); break; case requesttype.play: notice.send(emblems.song + request.user + ":Play: " + request.song); break; } } return true; } return false; default: return false; } } songqueue.tryParse = tryParse; })(songqueue || (songqueue = {})); /** Represents the type of song request */ var requesttype; /** Represents the type of song request */ (function (requesttype) { requesttype[requesttype["dance"] = 0] = "dance"; requesttype[requesttype["karaoke"] = 1] = "karaoke"; requesttype[requesttype["play"] = 2] = "play"; })(requesttype || (requesttype = {})); /** * Represents a song request */ var songrequest = (function () { function songrequest(user, song, type) { if (type === void 0) { type = requesttype.play; } this.user = user; this.song = song; this.type = type; } 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(emblems.notice + "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(); notice.send(emblems.notice + "Ticket sales have stopped"); 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(); 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(); 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 if (message.user === cb.room_slug) { notice.send(emblems.whisper + message.user + ": " + m.join(" "), target, "#804020"); } 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 tipmenu; (function (tipmenu) { /** * Holds the various sections of the tipmenu */ var sections; (function (sections) { sections.taxes = new menusection("Taxes", new menuitem("Fap Tax", 9), new menuitem("Princess Tax", 12)); sections.anal = new menusection("Anal"); sections.clothes = new menusection("Clothes"); sections.dance = new menusection("Dance"); sections.gags = new menusection("Gags and Mute"); sections.games = new menusection("Fun and Games"); sections.misc = new menusection("Misc."); sections.oral = new menusection("Oral"); sections.pussy = new menusection("Pussy"); sections.spanks = new menusection("Spanks"); sections.wet = new menusection("Wet and Cold"); sections.fitness = new menusection("Fitness"); sections.merchandise = new menusection("Merchandise", new menuitem("Panties From The Show", 1111)); })(sections = tipmenu.sections || (tipmenu.sections = {})); })(tipmenu || (tipmenu = {})); /** * Misc. room stuff */ var room; /** * Misc. room stuff */ (function (room) { /** * Prints the full help menu * @param message Requesting message */ function help(message) { notice.help(message); permissions.help(message); rotater.help(message); songqueue.help(message); tipmenu.special.help(message); stats.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 = {})); 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); } stats.print = print; function listViewers(sendTo) { notice.add("Viewers (Signed In): " + viewers.current); notice.add("Viewers (With Tokens): " + viewers.withTokens); notice.add("Viewers (Claimed Male): " + viewers.claimMale); notice.add("Viewers (Claimed Female): " + viewers.claimFemale); notice.add("Viewers (Claimed Trans): " + viewers.claimTrans); notice.add("Viewers (Claimed Couple): " + viewers.claimCouple); 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 = {})); 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); }); 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 = timers.tryParse(message); } if (!validCommand) { validCommand = tipmenu.tryParse(message); } if (!validCommand) { validCommand = votes.tryParse(message); } if (!validCommand) { validCommand = whisper.tryParse(message); } if (message['X-Spam'] || validCommand) return message; // Replace "bb" with :miniBB-8 message.m = message.m.replace(/\bbb\b/ig, " :miniBB-8 "); // Apply Emblems if (permissions.isTrusted(message)) { message.m = " :mm1pk " + message.m; } else if (teams.models.isMember(message.user)) { message.m = teams.models.apply(message); } else if (permissions.isModerator(message)) { message.m = " :mm1r " + message.m; } else if (permissions.isInFanclub(message)) { message.m = " :mm1y " + message.m; } else { message.m = hatchery.apply(message); } // Apply Tip Amount if (tippers.lookup(message.user) !== null) { message.m = "[" + tippers.lookup(message.user).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); } }); var tipmenu; (function (tipmenu) { var anal; (function (anal) { anal[anal["off"] = 0] = "off"; anal[anal["small"] = 1] = "small"; anal[anal["medium"] = 2] = "medium"; anal[anal["large"] = 3] = "large"; anal[anal["xlarge"] = 4] = "xlarge"; })(anal = tipmenu.anal || (tipmenu.anal = {})); ; var clothes; (function (clothes) { clothes[clothes["off"] = 0] = "off"; clothes[clothes["on"] = 1] = "on"; })(clothes = tipmenu.clothes || (tipmenu.clothes = {})); ; var dance; (function (dance) { dance[dance["off"] = 0] = "off"; dance[dance["on"] = 1] = "on"; })(dance = tipmenu.dance || (tipmenu.dance = {})); ; var fitness; (function (fitness) { fitness[fitness["off"] = 0] = "off"; fitness[fitness["on"] = 1] = "on"; })(fitness = tipmenu.fitness || (tipmenu.fitness = {})); ; var gags; (function (gags) { gags[gags["off"] = 0] = "off"; gags[gags["ball"] = 1] = "ball"; gags[gags["ballclamp"] = 2] = "ballclamp"; gags[gags["chode"] = 3] = "chode"; gags[gags["peener"] = 4] = "peener"; })(gags = tipmenu.gags || (tipmenu.gags = {})); ; var games; (function (games) { games[games["off"] = 0] = "off"; games[games["on"] = 1] = "on"; })(games = tipmenu.games || (tipmenu.games = {})); ; var ice; (function (ice) { ice[ice["off"] = 0] = "off"; ice[ice["on"] = 1] = "on"; })(ice = tipmenu.ice || (tipmenu.ice = {})); ; var misc; (function (misc) { misc[misc["off"] = 0] = "off"; misc[misc["on"] = 1] = "on"; })(misc = tipmenu.misc || (tipmenu.misc = {})); ; var oral; (function (oral) { oral[oral["off"] = 0] = "off"; oral[oral["blowjob"] = 1] = "blowjob"; oral[oral["deepthroat"] = 2] = "deepthroat"; })(oral = tipmenu.oral || (tipmenu.oral = {})); ; var pussy; (function (pussy) { pussy[pussy["off"] = 0] = "off"; pussy[pussy["showOnly"] = 1] = "showOnly"; pussy[pussy["noShowPlay"] = 2] = "noShowPlay"; pussy[pussy["fullPlay"] = 3] = "fullPlay"; })(pussy = tipmenu.pussy || (tipmenu.pussy = {})); ; var shower; (function (shower) { shower[shower["off"] = 0] = "off"; shower[shower["on"] = 1] = "on"; })(shower = tipmenu.shower || (tipmenu.shower = {})); ; var spanks; (function (spanks) { spanks[spanks["off"] = 0] = "off"; spanks[spanks["ass"] = 1] = "ass"; spanks[spanks["pussy"] = 2] = "pussy"; })(spanks = tipmenu.spanks || (tipmenu.spanks = {})); ; /** * Flags which control what is active in the tipmenu */ var flags; (function (flags) { flags.anal = tipmenu.anal.off; flags.buttplug = tipmenu.anal.off; flags.clothes = tipmenu.clothes.off; flags.dance = tipmenu.dance.off; flags.fitness = tipmenu.fitness.off; flags.gags = tipmenu.gags.off; flags.gagged = tipmenu.gags.off; flags.gagsban = false; flags.games = tipmenu.games.off; flags.ice = tipmenu.ice.off; flags.misc = tipmenu.misc.off; flags.mute = false; flags.oral = tipmenu.oral.off; flags.plugged = false; flags.pussy = tipmenu.pussy.off; flags.shenanigansban = false; flags.shower = tipmenu.shower.off; flags.spanks = tipmenu.spanks.off; flags.spanksban = false; })(flags = tipmenu.flags || (tipmenu.flags = {})); })(tipmenu || (tipmenu = {})); var cb; (function (cb) { cb.settings_choices = [ { name: "anal", label: "Anal Items", type: "choice", choice1: "x-large", choice2: "large", choice3: "medium", choice4: "small", choice5: "off", defaultValue: "medium", required: true, }, { name: "buttplug", label: "Buttplug Wear Items", type: "choice", choice1: "x-large", choice2: "large", choice3: "medium", choice4: "small", choice5: "off", defaultValue: "medium", required: true, }, { name: "clothes", label: "Clothes Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "dance", label: "Dance Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "fitness", label: "Fitness Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "off", required: true, }, { name: "gags", label: "Gag Items", type: "choice", choice1: "peener", choice2: "chode", choice3: "ballclamp", choice4: "ball", choice5: "off", defaultValue: "ballclamp", required: true, }, { name: "games", label: "Game Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "ice", label: "Ice Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "off", required: true, }, { name: "misc", label: "Misc. Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "on", required: true, }, { name: "oral", label: "Oral Items", type: "choice", choice1: "deepthroat", choice2: "blowjob", choice3: "off", defaultValue: "blowjob", required: true, }, { name: "pussy", label: "Pussy Items", type: "choice", choice1: "full play", choice2: "no-show play", choice3: "show only", choice4: "off", defaultValue: "full play", required: true, }, { name: "shower", label: "Shower Items", type: "choice", choice1: "on", choice2: "off", defaultValue: "off", required: true, }, { name: "spanks", label: "Spank Items", type: "choice", choice1: "pussy", choice2: "ass", choice3: "off", defaultValue: "off", required: true, }, ]; })(cb || (cb = {})); var teams; (function (teams) { teams.models = new team(" :mm1b "); teams.models.adds(["thursty", "mitzylover"]); })(teams || (teams = {})); var handlers; (function (handlers) { function addButtPlug() { tipmenu.flags.plugged = true; tipmenu.build(); } handlers.addButtPlug = addButtPlug; function ballgag() { var timer = timers.lookup("Ballgag"); if (timer != null) { timer.extend(2 * 60); } else { timers.add("Ballgag", 2 * 60, 30, function () { tipmenu.flags.gagged = tipmenu.gags.ball; tipmenu.build(); }, function () { tipmenu.flags.gagged = tipmenu.gags.off; tipmenu.build(); }); } } handlers.ballgag = ballgag; function ballgagclamps() { var timer = timers.lookup("Ballgag with Clamps"); if (timer != null) { timer.extend(2 * 60); } else { timers.add("Ballgag with Clamps", 2 * 60, 30, function () { tipmenu.flags.gagged = tipmenu.gags.ballclamp; tipmenu.build(); }, function () { tipmenu.flags.gagged = tipmenu.gags.off; tipmenu.build(); }); } } handlers.ballgagclamps = ballgagclamps; function chodegag() { var timer = timers.lookup("Chodegag"); if (timer != null) { timer.extend(2 * 60); } else { timers.add("Chodegag", 2 * 60, 30, function () { tipmenu.flags.gagged = tipmenu.gags.chode; tipmenu.build(); }, function () { tipmenu.flags.gagged = tipmenu.gags.off; tipmenu.build(); }); } } handlers.chodegag = chodegag; function coldshower() { var timer = timers.lookup("Cold Shower"); if (timer != null) { timer.extend(60); } else { timers.add("Cold Shower", 60, 15); } } handlers.coldshower = coldshower; function danceRequest(tip) { songqueue.add(tip.from_user, tip.message, requesttype.dance); } handlers.danceRequest = danceRequest; function gagban() { var timer = timers.lookup("Gag Ban"); if (timer != null) { timer.extend(15 * 60); } else { timers.add("Gag Ban", 15 * 60, 0, function () { tipmenu.flags.gagsban = true; tipmenu.build(); }, function () { tipmenu.flags.gagsban = false; tipmenu.build(); }); } } handlers.gagban = gagban; function iceplay() { var timer = timers.lookup("Ice Play"); if (timer != null) { timer.extend(2 * 60); } else { timers.add("Ice Play", 2 * 60, 60); } } handlers.iceplay = iceplay; function karaokeRequest(tip) { songqueue.add(tip.from_user, tip.message, requesttype.karaoke); } handlers.karaokeRequest = karaokeRequest; function mute() { var timer = timers.lookup("Mute"); if (timer != null) { timer.extend(20 * 60); } else { timers.add("Mute", 20 * 60, 0, function () { tipmenu.flags.mute = true; tipmenu.build(); }, function () { tipmenu.flags.mute = false; tipmenu.build(); }); } } handlers.mute = mute; function nipplesuckers() { var timer = timers.lookup("Nipple Clamps"); if (timer != null) { timer.extend(5 * 60); } else { timers.add("Nipple Clamps", 5 * 60, 30); } } handlers.nipplesuckers = nipplesuckers; function lushcontrol() { var timer = timers.lookup("Lush Control"); if (timer != null) { timer.extend(5 * 60); } else { timers.add("Lush Control", 5 * 60, 30); } } handlers.lushcontrol = lushcontrol; function hitachil() { var timer = timers.lookup("Hitachi Low"); if (timer != null) { timer.extend(1 * 60); } else { timers.add("Hitachi Low", 1 * 60, 30); } } handlers.hitachil = hitachil; function hitachih() { var timer = timers.lookup("Hitachi High"); if (timer != null) { timer.extend(1 * 60); } else { timers.add("Hitachi High", 1 * 60, 30); } } handlers.hitachih = hitachih; function peenergag() { var timer = timers.lookup("Peenergag"); if (timer != null) { timer.extend(5 * 60); } else { timers.add("Peenergag", 2 * 60, 30, function () { tipmenu.flags.gagged = tipmenu.gags.peener; tipmenu.build(); }, function () { tipmenu.flags.gagged = tipmenu.gags.off; tipmenu.build(); }); } } handlers.peenergag = peenergag; function pussyplay() { var timer = timers.lookup("Pussy Play"); if (timer != null) { timer.extend(2 * 60); } else { timers.add("Pussy Play", 2 * 60, 30); } } handlers.pussyplay = pussyplay; function removeButtPlug() { tipmenu.flags.plugged = false; tipmenu.build(); } handlers.removeButtPlug = removeButtPlug; function shenanigansban() { tipmenu.flags.shenanigansban = true; tipmenu.build(); } handlers.shenanigansban = shenanigansban; function songRequest(tip) { songqueue.add(tip.from_user, tip.message, requesttype.play); } handlers.songRequest = songRequest; function spanksban() { var timer = timers.lookup("Spank Ban"); if (timer != null) { timer.extend(15 * 60); } else { timers.add("Spank Ban", 15 * 60, 0, function () { tipmenu.flags.spanksban = true; tipmenu.build(); }, function () { tipmenu.flags.spanksban = false; tipmenu.build(); }); } } handlers.spanksban = spanksban; function unmute() { timers.stop("Mute"); tipmenu.build(); } handlers.unmute = unmute; })(handlers || (handlers = {})); var tipmenu; (function (tipmenu) { /** * Build the tipmenu with whatever is assigned in flags */ function build() { tipmenu.sections.anal.clear(); tipmenu.sections.clothes.clear(); tipmenu.sections.dance.clear(); tipmenu.sections.fitness.clear(); tipmenu.sections.gags.clear(); tipmenu.sections.games.clear(); tipmenu.sections.misc.clear(); tipmenu.sections.oral.clear(); tipmenu.sections.pussy.clear(); tipmenu.sections.spanks.clear(); tipmenu.sections.wet.clear(); if (tipmenu.flags.shenanigansban) { return; } // Build Anal Section if (tipmenu.flags.anal > tipmenu.anal.off && !tipmenu.flags.plugged) { tipmenu.sections.anal.add("Finger in the Booty", 80); } if (tipmenu.flags.plugged) { tipmenu.sections.anal.add("Remove Plug (off cam)", 170, handlers.removeButtPlug); } if (tipmenu.flags.anal >= tipmenu.anal.small) { if (tipmenu.flags.plugged) { tipmenu.sections.anal.add("Change Butt Plug (Small)", 175); } else { tipmenu.sections.anal.add("Add Butt Plug (Small)", 303, handlers.addButtPlug); } } if (tipmenu.flags.buttplug >= tipmenu.anal.small) { tipmenu.sections.anal.add("Wear Butt Plug Off Cam (Small)", 805); } if (tipmenu.flags.anal > tipmenu.anal.off && !tipmenu.flags.plugged) { tipmenu.sections.anal.add("Butt Play (2min)", 325); } if (tipmenu.flags.anal >= tipmenu.anal.medium) { if (tipmenu.flags.plugged) { tipmenu.sections.anal.add("Change Butt Plug (Medium)", 355); } else { tipmenu.sections.anal.add("Add Butt Plug (Medium)", 505, handlers.addButtPlug); } } if (tipmenu.flags.buttplug >= tipmenu.anal.medium) { tipmenu.sections.anal.add("Wear Butt Plug Off Cam (Medium)", 1005); } if (tipmenu.flags.anal >= tipmenu.anal.large) { if (tipmenu.flags.plugged) { tipmenu.sections.anal.add("Change Butt Plug (Large)", 555); } else { tipmenu.sections.anal.add("Add Butt Plug (Large)", 705, handlers.addButtPlug); } } if (tipmenu.flags.buttplug >= tipmenu.anal.large) { tipmenu.sections.anal.add("Wear Butt Plug Off Cam (Large)", 1705); } if (tipmenu.flags.anal >= tipmenu.anal.xlarge) { if (tipmenu.flags.plugged) { tipmenu.sections.anal.add("Change Butt Plug (X-Large)", 705); } else { tipmenu.sections.anal.add("Add Butt Plug (X-Large)", 955, handlers.addButtPlug); } } if (tipmenu.flags.buttplug >= tipmenu.anal.xlarge) { tipmenu.sections.anal.add("Wear Butt Plug Off Cam (X-Large)", 1955); } // Build Clothes Section if (tipmenu.flags.clothes == tipmenu.clothes.on) { tipmenu.sections.clothes.add("Change Accessory", 74); tipmenu.sections.clothes.add("Remove Accessory", 79); tipmenu.sections.clothes.add("Add Accessory", 84); tipmenu.sections.clothes.add("Change Clothing (1 item)", 185); tipmenu.sections.clothes.add("Remove Clothing (1 item)", 215); tipmenu.sections.clothes.add("Add Clothing (1 item)", 225); tipmenu.sections.clothes.add("Change Outfit", 485); tipmenu.sections.clothes.add("Remove Outfit", 515); tipmenu.sections.clothes.add("Add Outfit", 525); } // Build Dance Section if (tipmenu.flags.dance == tipmenu.dance.on) { tipmenu.sections.dance.add("Sexy Dancing", 82, handlers.danceRequest); tipmenu.sections.dance.add("Strip Tease", 545, handlers.danceRequest); } // Build Fitness Section if (tipmenu.flags.fitness == tipmenu.fitness.on) { tipmenu.sections.fitness.add("Jumping Jack", 10); tipmenu.sections.fitness.add("Squat", 12); } // Build Gags & Mute Section if (tipmenu.flags.gags >= tipmenu.gags.ball && !tipmenu.flags.gagsban) { if (tipmenu.flags.gagged == tipmenu.gags.ball) { tipmenu.sections.gags.add("Extend Ballgag (2min)", 208, handlers.ballgag); } else if (tipmenu.flags.gagged == tipmenu.gags.off) { tipmenu.sections.gags.add("Ballgag (2min)", 208, handlers.ballgag); } } if (tipmenu.flags.mute) { tipmenu.sections.gags.add("Unmute", 302, handlers.unmute); } if (tipmenu.flags.gags >= tipmenu.gags.ballclamp && !tipmenu.flags.gagsban) { if (tipmenu.flags.gagged == tipmenu.gags.ballclamp) { tipmenu.sections.gags.add("Extend Ballgag (2min)", 248, handlers.ballgagclamps); } else if (tipmenu.flags.gagged == tipmenu.gags.off) { tipmenu.sections.gags.add("Ballgag with Clamps (2min)", 308, handlers.ballgagclamps); } } if (!tipmenu.flags.mute) { tipmenu.sections.gags.add("Mute", 301, handlers.mute); } if (tipmenu.flags.gags >= tipmenu.gags.chode && !tipmenu.flags.gagsban) { if (tipmenu.flags.gagged == tipmenu.gags.chode) { tipmenu.sections.gags.add("Extend Chodegag (2min)", 358, handlers.chodegag); } else if (tipmenu.flags.gagged == tipmenu.gags.off) { tipmenu.sections.gags.add("Chodegag (2min)", 358, handlers.chodegag); } } if (tipmenu.flags.gags > tipmenu.gags.off) { if (!tipmenu.flags.gagsban) { tipmenu.sections.gags.add("Gag Ban (15min)", 668, handlers.gagban); } else { tipmenu.sections.gags.add("Extend Gag Ban (15min)", 668, handlers.gagban); } } // Build Fun and Games Section if (tipmenu.flags.games == tipmenu.games.on) { tipmenu.sections.games.add("Fuck One, Marry One, Kill One", 16); tipmenu.sections.games.add("Truth or Dare", 66); tipmenu.sections.games.add("Song Request", 25, handlers.songRequest); if (!tipmenu.flags.mute) { tipmenu.sections.games.add("Reading", 159); } } // Build Misc. Section if (tipmenu.flags.pussy >= tipmenu.pussy.showOnly) { tipmenu.sections.misc.add("Flash (Specify)", 65); } if (tipmenu.flags.pussy >= tipmenu.pussy.showOnly) { tipmenu.sections.misc.add("Doggy Spread", 75); } else if (tipmenu.flags.pussy < tipmenu.pussy.showOnly) { tipmenu.sections.misc.add("Flash (Specify, no pussy today)", 30); } if (tipmenu.flags.misc == tipmenu.misc.on) { tipmenu.sections.misc.add("Shake Tits", 5); tipmenu.sections.misc.add("Play With Nipples", 60); tipmenu.sections.misc.add("Lick Nipples", 70); tipmenu.sections.misc.add("View Cam (5 Mins)", 78); tipmenu.sections.misc.add("Nipple Clamps (5min)", 124, handlers.nipplesuckers); tipmenu.sections.misc.add("Hitachi Play (1 min Low)", 126, handlers.hitachil); tipmenu.sections.misc.add("Oil/Lotion (Specify)", 165); tipmenu.sections.misc.add("Hitachi Play(1 min High)", 226, handlers.hitachih); tipmenu.sections.misc.add("Lush Control (5min)", 550, handlers.lushcontrol); } if (!tipmenu.flags.shenanigansban) { tipmenu.sections.misc.add("Undo Button", 2626, handlers.shenanigansban); } // Build Oral Section if (tipmenu.flags.oral >= tipmenu.oral.deepthroat) { tipmenu.sections.oral.add("Deepthroat Attempt", 36); } if (tipmenu.flags.oral >= tipmenu.oral.blowjob) { tipmenu.sections.oral.add("BJ Dildo", 141); } // Build Pussy Section if (tipmenu.flags.pussy == tipmenu.pussy.fullPlay) { tipmenu.sections.pussy.add("Taste Self", 69); tipmenu.sections.pussy.add("Pussy Play (2min)", 245, handlers.pussyplay); tipmenu.sections.pussy.add("InstaCum", 298); if (tipmenu.flags.anal > tipmenu.anal.off) { tipmenu.sections.pussy.add("InstaCum with Anal", 700); } } else if (tipmenu.flags.pussy == tipmenu.pussy.noShowPlay) { tipmenu.sections.pussy.add("Pussy Play (over panties) (2min)", 245, handlers.pussyplay); tipmenu.sections.pussy.add("InstaCum (over panties)", 298); if (tipmenu.flags.anal > tipmenu.anal.off) { tipmenu.sections.pussy.add("InstaCum with Anal (over panties)", 700); } } // Build Spanks Section if (tipmenu.flags.spanks >= tipmenu.spanks.ass && !tipmenu.flags.spanksban) { tipmenu.sections.spanks.add("1 Hand Spanks", 15); tipmenu.sections.spanks.add("5 Hand Spanks", 42); tipmenu.sections.spanks.add("Spank Ban", 1400); } if (tipmenu.flags.spanks >= tipmenu.spanks.pussy && !tipmenu.flags.spanksban) { tipmenu.sections.spanks.add("3 Pussy Spanks", 68); } if (tipmenu.flags.spanks >= tipmenu.spanks.ass && !tipmenu.flags.spanksban) { tipmenu.sections.spanks.add("2 Paddle Spanks", 72); } if (tipmenu.flags.spanks > tipmenu.spanks.off) { if (tipmenu.flags.spanksban) { tipmenu.sections.spanks.add("Extend Spank Ban (15min)", 402, handlers.spanksban); } else { tipmenu.sections.spanks.add("Spank Ban (15min)", 402, handlers.spanksban); } } // Build Wet and Cold Section if (tipmenu.flags.ice == tipmenu.ice.on) { tipmenu.sections.wet.add("Ice Play (Specify) (2min)", 88, handlers.iceplay); } if (tipmenu.flags.ice == tipmenu.ice.on && tipmenu.flags.shower == tipmenu.shower.on) { tipmenu.sections.wet.add("Cold Shower (1min)", 575, handlers.coldshower); } if (tipmenu.flags.shower == tipmenu.shower.on) { tipmenu.sections.wet.add("Shower Show", 1000); } } 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.sections.taxes.list(); _b < _c.length; _b++) { var item = _c[_b]; price = item.cost; if (tip.amount === price) return item; } for (var _d = 0, _e = tipmenu.sections.anal.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.sections.clothes.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.sections.dance.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.sections.fitness.list(); _k < _l.length; _k++) { var item = _l[_k]; price = item.cost; if (tip.amount === price) return item; } for (var _m = 0, _o = tipmenu.sections.gags.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.sections.games.list(); _p < _q.length; _p++) { var item = _q[_p]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _r = 0, _s = tipmenu.sections.misc.list(); _r < _s.length; _r++) { var item = _s[_r]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _t = 0, _u = tipmenu.sections.oral.list(); _t < _u.length; _t++) { var item = _u[_t]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _v = 0, _w = tipmenu.sections.pussy.list(); _v < _w.length; _v++) { var item = _w[_v]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _x = 0, _y = tipmenu.sections.spanks.list(); _x < _y.length; _x++) { var item = _y[_x]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _z = 0, _0 = tipmenu.sections.wet.list(); _z < _0.length; _z++) { var item = _0[_z]; price = discount.apply(item, tip); if (tip.amount === price) return item; } for (var _1 = 0, _2 = tipmenu.sections.merchandise.list(); _1 < _2.length; _1++) { var item = _2[_1]; price = item.cost; if (tip.amount === price) return item; } return null; } tipmenu.match = match; /** * Print the tipmenu to chat * @param message Requesting message */ function print(message, limit, flags) { if (limit === void 0) { limit = null; } if (flags === void 0) { flags = [true, true, true, true, true, true, true, true, true, true, true, true, true, true]; } if (flags[0]) tipmenu.specials.print(message, limit); if (flags[1]) tipmenu.sections.taxes.print(message, limit); if (flags[2]) tipmenu.sections.anal.print(message, limit, true); if (flags[3]) tipmenu.sections.clothes.print(message, limit, true); if (flags[4]) tipmenu.sections.dance.print(message, limit, true); if (flags[5]) tipmenu.sections.fitness.print(message, limit, true); if (flags[6]) tipmenu.sections.gags.print(message, limit, true); if (flags[7]) tipmenu.sections.games.print(message, limit, true); if (flags[8]) tipmenu.sections.misc.print(message, limit, true); if (flags[9]) tipmenu.sections.oral.print(message, limit, true); if (flags[10]) tipmenu.sections.pussy.print(message, limit, true); if (flags[11]) tipmenu.sections.spanks.print(message, limit, true); if (flags[12]) tipmenu.sections.wet.print(message, limit, true); if (flags[13]) tipmenu.sections.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 { // Generally, this assumes it's parsing a list of sections to print. However, it does check if a flag setter is being used. var sections_1 = [false, false, false, false, false, false, false, false, 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 "shenanigan": case "shenanigans": if (permissions.isAtLeastTrusted(message)) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": tipmenu.flags.shenanigansban = false; tipmenu.build(); notice.send(emblems.tipmenu + "Shenanigans Ban lifted"); return true; case "off": tipmenu.flags.shenanigansban = true; tipmenu.build(); notice.send(emblems.tipmenu + "Shenanigans Ban enforced"); return true; default: m.unshift(level); break; } } break; case "special": case "specials": sections_1[0] = true; break; case "tax": case "taxes": sections_1[1] = true; break; case "anal": case "ass": case "butt": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "xl": case "xlarge": case "x-large": tipmenu.flags.anal = tipmenu.anal.xlarge; tipmenu.build(); notice.send(emblems.tipmenu + "Anal items up to x-large are now active"); continue; case "large": tipmenu.flags.anal = tipmenu.anal.large; tipmenu.build(); notice.send(emblems.tipmenu + "Anal items up to large are now active"); continue; case "medium": tipmenu.flags.anal = tipmenu.anal.medium; tipmenu.build(); notice.send(emblems.tipmenu + "Anal items up to medium are now active"); continue; case "small": tipmenu.flags.anal = tipmenu.anal.small; tipmenu.build(); notice.send(emblems.tipmenu + "Anal items up to small are now active"); continue; case "off": tipmenu.flags.anal = tipmenu.anal.off; 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 | small | medium | large | x-large)", message.user); return false; } } sections_1[2] = true; break; case "buttplug": case "plugged": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "true": case "yes": tipmenu.flags.plugged = true; tipmenu.build(); continue; case "false": case "no": tipmenu.flags.plugged = false; tipmenu.build(); continue; default: notice.send("For '" + word + "', found '" + level + ", but expected a level of (no | yes)", message.user); return false; } } break; case "clothes": case "clothing": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": tipmenu.flags.clothes = tipmenu.clothes.on; tipmenu.build(); notice.send(emblems.tipmenu + "Clothes items are now active"); continue; case "off": tipmenu.flags.clothes = tipmenu.clothes.off; tipmenu.build(); notice.send(emblems.tipmenu + "Clothes 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_1[3] = true; break; case "dance": case "dancing": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": tipmenu.flags.dance = tipmenu.dance.on; tipmenu.build(); notice.send(emblems.tipmenu + "Dance items are now active"); continue; case "off": tipmenu.flags.dance = tipmenu.dance.off; tipmenu.build(); notice.send(emblems.tipmenu + "Dance 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_1[4] = true; break; case "excercise": case "excercises": case "fitness": case "workout": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": tipmenu.flags.fitness = tipmenu.fitness.on; tipmenu.build(); notice.send(emblems.tipmenu + "Fitness items are now active"); continue; case "off": tipmenu.flags.fitness = tipmenu.fitness.off; tipmenu.build(); notice.send(emblems.tipmenu + "Fitness 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_1[5] = true; break; case "gag": case "gags": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "peener": tipmenu.flags.gags = tipmenu.gags.peener; tipmenu.build(); notice.send(emblems.tipmenu + "Gag and Mute items up to peenergag are now active"); continue; case "chode": tipmenu.flags.gags = tipmenu.gags.chode; tipmenu.build(); notice.send(emblems.tipmenu + "Gag and Mute items up to chodegag are now active"); continue; case "ball": case "ballgag": tipmenu.flags.gags = tipmenu.gags.ballclamp; tipmenu.build(); notice.send(emblems.tipmenu + "Gag and Mute items up to ballgags are now active"); continue; case "off": tipmenu.flags.gags = tipmenu.gags.off; tipmenu.build(); notice.send(emblems.tipmenu + "Gag and Mute items are no longer active"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | ball | panty | chode | peener", message.user); return false; } } sections_1[6] = true; break; case "game": case "games": case "fun": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": tipmenu.flags.games = tipmenu.games.on; tipmenu.build(); notice.send(emblems.tipmenu + "Fun and Games items are now active"); continue; case "off": tipmenu.flags.games = tipmenu.games.off; tipmenu.build(); notice.send(emblems.tipmenu + "Fun and Games 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_1[7] = true; break; case "misc": case "misc.": if (setmode) { if (m.length === 0) return false; level = m.shift().toLocaleLowerCase(); switch (level) { case "on": tipmenu.flags.misc = tipmenu.misc.on; tipmenu.build(); notice.send(emblems.tipmenu + "Misc. items are now active"); continue; case "off": tipmenu.flags.misc = tipmenu.misc.off; tipmenu.build(); notice.send(emblems.tipmenu + "Misc. 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_1[8] = true; break; case "oral": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "deepthroat": tipmenu.flags.oral = tipmenu.oral.deepthroat; tipmenu.build(); notice.send(emblems.tipmenu + "Oral items up to deepthroat are now active"); continue; case "blowjob": tipmenu.flags.oral = tipmenu.oral.blowjob; tipmenu.build(); notice.send(emblems.tipmenu + "Oral items up to blowjob are now active"); continue; case "off": tipmenu.flags.oral = tipmenu.oral.off; tipmenu.build(); notice.send(emblems.tipmenu + "Oral items are no longer active"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | blowjob | deepthroat)", message.user); return false; } } sections_1[9] = true; break; case "pussy": case "vagina": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "full": case "fullplay": case "full-play": tipmenu.flags.pussy = tipmenu.pussy.fullPlay; tipmenu.build(); notice.send(emblems.tipmenu + "Pussy items up to full play are now active"); continue; case "noshow": case "no-show": tipmenu.flags.pussy = tipmenu.pussy.noShowPlay; tipmenu.build(); notice.send(emblems.tipmenu + "Pussy items up to no-show play are now active"); continue; case "showonly": tipmenu.flags.pussy = tipmenu.pussy.showOnly; tipmenu.build(); notice.send(emblems.tipmenu + "Pussy items up to show-only are now active"); continue; case "off": tipmenu.flags.pussy = tipmenu.pussy.off; 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 | showonly | noshow | full)"); return false; } } sections_1[10] = true; break; case "set": if (permissions.isAtLeastTrusted(message)) { setmode = true; } break; case "shenanigans": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": tipmenu.flags.shenanigansban = false; tipmenu.build(); notice.send(emblems.tipmenu + "Shenanigans ban has been lifted"); continue; case "off": tipmenu.flags.shenanigansban = true; tipmenu.build(); notice.send(emblems.tipmenu + "Shenanigans ban has been placed"); continue; } } break; case "spank": case "spanks": case "spanking": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "pussy": tipmenu.flags.spanks = tipmenu.spanks.pussy; tipmenu.build(); notice.send(emblems.tipmenu + "Spank items up to pussy are now active"); continue; case "ass": tipmenu.flags.spanks = tipmenu.spanks.ass; tipmenu.build(); notice.send(emblems.tipmenu + "Spank items up to ass are now active"); continue; case "off": tipmenu.flags.spanks = tipmenu.spanks.off; 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 | ass | pussy)"); return false; } } sections_1[11] = true; break; case "wet": case "water": case "shower": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": tipmenu.flags.shower = tipmenu.shower.on; tipmenu.build(); notice.send(emblems.tipmenu + "Shower items are now active"); continue; case "off": tipmenu.flags.shower = tipmenu.shower.off; tipmenu.build(); notice.send(emblems.tipmenu + "Shower items are no longer active"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | on)"); return false; } } // This deliberately falls through case "ice": case "cold": if (setmode) { if (m.length === 0) return false; level = m.shift().toLowerCase(); switch (level) { case "on": tipmenu.flags.ice = tipmenu.ice.on; tipmenu.build(); notice.send(emblems.tipmenu + "Ice items are now active"); continue; case "off": tipmenu.flags.ice = tipmenu.ice.off; tipmenu.build(); notice.send(emblems.tipmenu + "Ice items are no longer active"); continue; default: notice.send("For '" + word + "', found '" + level + "', but expected a level of (off | on)"); return false; } } sections_1[12] = true; break; case "merchandise": sections_1[13] = true; break; default: break; } } print(message, null, sections_1); for (var _i = 0, sections_2 = sections_1; _i < sections_2.length; _i++) { var section = sections_2[_i]; if (section) return true; } return false; } default: return false; } } tipmenu.tryParse = tryParse; })(tipmenu || (tipmenu = {})); /** * Initialization Code */ { notice.color = "#206080"; permissions.entrust("mitzybelle", "thursty_2233", "thirsty026"); discount.fanclub = 0.10; discount.moderator = 0.25; timers.start(); rotater.add("Follow me on twitter: :twitterbird @MitzyBelle"); rotater.add("Check out the tipmenu with: /tipmenu"); rotater.add("Join the fanclub to receive a discount of: " + discount.fanclub * 100 + "%"); rotater.add("Get Sexy Snaps From Mitzy! Snaps for life available for 500 tks in the bio!"); rotater.add("Check out the tipmenu with: /tipmenu"); rotater.add(":tipfollowvote"); rotater.add(":biogodown7a"); rotater.add("Become one of :mm1p Mitzy's Monsters! Join the fan club, or tip to hatch your own monster! :mm1b") rotater.start(); hatchery.progression = 50; hatchery.level1 = " :hatch1 "; hatchery.level2 = " :hatch2 "; hatchery.level3 = " :hatch3 "; hatchery.level4 = " :hatch4 "; hatchery.level5 = " :hatch5 "; hatchery.level6 = " :hatch6 "; hatchery.level7 = " :hatch7 "; hatchery.level8 = " :hatch8 "; hatchery.level9 = " :hatch9 "; hatchery.level10 = " :mm1g "; leaderboard.rotate(3); switch (cb.settings.anal) { case "x-large": tipmenu.flags.anal = tipmenu.anal.xlarge; break; case "large": tipmenu.flags.anal = tipmenu.anal.large; break; case "medium": tipmenu.flags.anal = tipmenu.anal.medium; break; case "small": tipmenu.flags.anal = tipmenu.anal.small; break; case "off": tipmenu.flags.anal = tipmenu.anal.off; break; } switch (cb.settings.clothes) { case "on": tipmenu.flags.clothes = tipmenu.clothes.on; break; case "off": tipmenu.flags.clothes = tipmenu.clothes.off; break; } switch (cb.settings.dance) { case "on": tipmenu.flags.dance = tipmenu.dance.on; break; case "off": tipmenu.flags.dance = tipmenu.dance.off; break; } switch (cb.settings.fitness) { case "on": tipmenu.flags.fitness = tipmenu.fitness.on; break; case "off": tipmenu.flags.fitness = tipmenu.fitness.off; break; } switch (cb.settings.gags) { case "peener": tipmenu.flags.gags = tipmenu.gags.peener; break; case "chode": tipmenu.flags.gags = tipmenu.gags.chode; break; case "ballclamp": tipmenu.flags.gags = tipmenu.gags.ballclamp; break; case "ball": tipmenu.flags.gags = tipmenu.gags.ball; break; case "off": tipmenu.flags.gags = tipmenu.gags.off; break; } switch (cb.settings.games) { case "on": tipmenu.flags.games = tipmenu.games.on; break; case "off": tipmenu.flags.games = tipmenu.games.off; break; } switch (cb.settings.ice) { case "on": tipmenu.flags.ice = tipmenu.ice.on; break; case "off": tipmenu.flags.ice = tipmenu.ice.off; break; } switch (cb.settings.misc) { case "on": tipmenu.flags.misc = tipmenu.misc.on; break; case "off": tipmenu.flags.misc = tipmenu.misc.off; break; } switch (cb.settings.oral) { case "deepthroat": tipmenu.flags.oral = tipmenu.oral.deepthroat; break; case "blowjob": tipmenu.flags.oral = tipmenu.oral.blowjob; break; case "off": tipmenu.flags.oral = tipmenu.oral.off; break; } switch (cb.settings.pussy) { case "full play": tipmenu.flags.pussy = tipmenu.pussy.fullPlay; break; case "no-show play": tipmenu.flags.pussy = tipmenu.pussy.noShowPlay; break; case "show only": tipmenu.flags.pussy = tipmenu.pussy.showOnly; break; case "off": tipmenu.flags.pussy = tipmenu.pussy.off; break; } switch (cb.settings.shower) { case "on": tipmenu.flags.shower = tipmenu.shower.on; break; case "off": tipmenu.flags.shower = tipmenu.shower.off; break; } switch (cb.settings.spanks) { case "pussy": tipmenu.flags.spanks = tipmenu.spanks.pussy; break; case "ass": tipmenu.flags.spanks = tipmenu.spanks.ass; break; case "off": tipmenu.flags.spanks = tipmenu.spanks.off; break; }tipmenu.build(); }
© Copyright Chaturbate 2011- 2024. All Rights Reserved.