Apps Home
|
Create an App
Tip
Author:
anonymous
Description
Source Code
Launch App
Current Users
Created by:
Anonymous
/* Name: #message me Author: 4pussylover321 Version History ============================================ v1.0 07/01/2014: First release v1.1 24/01/2014: Bug fixes v1.2 24/01/2014: Added /target x to allow changing goal target v1.3 26/01/2014: Added /hashes to display list of all who have tagged this round v1.4 14/02/2014: Fixed /reset not working v1.5 14/02/2014: Allow tokens to replace hashes on a 1:1 basis (independent of "message "!) v1.6 16/02/2014: Reversed order of text in panel to show remaining tags instead of counted tags v1.7 16/02/2014: Suppress completion messages while we're counting token hashes. Because SPAAAAAAM v1.8 09/03/2014: Possible fixes for annoying duplication when doing #hashes v1.9 05/06/2014: Fix for stats being a bit weird (undefined? UNDEFINED?), variable hashtag cost (default 1) and possible ignorance fix Limitations and Pains in my Ass ============================================ It's made of regex. I hate regex. Don't be surprised if it does awful, awful things. FYI, even I can't read that thing. I'm pretty sure it does SOMETHING, but I'm not entirely sure what. Possibly test for hashtags, possibly summon the four horsemen of the apocolypse. Who knows? */ var APP_VERSION = 1.9; var APP_DEBUG = false; var hashtagRegex = /(^|[^0-9A-Z&/]+)(#|\uFF03)([0-9A-Z_]*[A-Z_]+[a-z0-9_\\u00c0-\\u00d6\\u00d8-\\u00f6\\u00f8-\\u00ff]*)/ig; if ((cb == null || cb == undefined) && (cbjs == null || cbjs == undefined)) { var cb = { changeRoomSubject: function (new_subject) { }, drawPanel: function () { }, log: function (message) { }, onDrawPanel: function (func) { }, onEnter: function (func) { }, onLeave: function (func) { }, onMessage: function (func) { }, onTip: function (func) { }, room_slug: '', sendNotice: function (message, to_user, background, foreground, weight, to_group) { }, setTimeout: function (func, msec) { }, settings_choices: [], settings: {}, tipOptions: function (func) { }, limitCam_start: function (message, allowed_users) { }, limitCam_stop: function () { }, limitCam_addUsers: function (allowed_users) { }, limitCam_removeUsers: function (removed_users) { }, limitCam_removeAllUsers: function () { }, limitCam_userHasAccess: function (user) { }, limitCam_allUsersWithAccess: function () { }, limitCam_isRunning: function () { }, synthetic: true, }; var cbjs = {}; } String.prototype.format = function () { var newString = String(this); for (var idx = 0; idx < arguments.length; idx++) { newString = newString.replace('{' + idx + '}', arguments[idx]); } return String(newString); }; var game = { baseSubject: "", gameGoal: "", targetHashes: 0, countedHashes: 0, hashesCounted: [], tokensToSkip: 0, hashtagCost: 1, allowTokenReplacement: true , complete: false, suppressCompletion: false, checkCompletion: function () { if (this.countedHashes >= this.targetHashes && !this.complete) { this.complete = true; this.onGoalMet(); } }, addHashtag: function (user) { if (this.complete) return; if (!cbjs.arrayContains(game.hashesCounted, user)) { debugLog("HASH counted for " + user); this.hashesCounted.push(user); this.countedHashes++; if (!this.suppressCompletion) { this.onHashCounted(user); this.checkCompletion(); } } else { debugLog("Hash ignored for " + user + " due to duplication"); this.onHashIgnored(user); } }, addGhostHashtag: function(user, count) { if (this.complete) return; this.countedHashes += count; if (!cbjs.arrayContains(game.hashesCounted, user)) { debugLog("{0} GHOST HASHES counted for {1}".format(count, user)); this.hashesCounted.push(user); if (!this.suppressCompletion) { this.onHashCounted(user); this.checkCompletion(); } } else { debugLog("{0} GHOST HASHES counted for {1} who has already #ed!".format(count, user)); } }, onGoalMet: function () { }, onHashCounted: function (user) { }, onHashIgnored: function (user) { } }; cb.settings_choices = [ { name: 'base_subject', label: 'Subject (without goal description)', type: 'str', minLength: 1, maxLength: 255, defaultValue: '', }, { name: 'game_goal', label: 'What happens at goal', type: 'str', minLength: 1, maxLength: 255, defaultValue: '', }, { name: 'target_hashes', label: 'Target hashes', type: 'int', minValue: 1, maxValue: 100, defaultValue: 10, }, { name: 'tokens_to_skip', label: 'Tokens in single tip to skip', type: 'int', minValue: 0, maxValue: 2000, defaultValue: 0, }, { name: 'allow_token_replacement', label: 'Tokens can be tipped in place of hashes (1:1)', type: 'choice', choice1: 'Yes', choice2: 'No', defaultValue: 'No', }, { name: 'hashtag_cost', label: 'Cost per hashtag (if token replacement enabled)', type: 'int', minValue: 1, maxValue: 1000, defaultValue: 1, }, ]; function evaluateMessage(user, message) { if (hashtagRegex.test(message)) { game.addHashtag(user); } else if (message.indexOf("#") >= 0) { debugLog("Message from {0} contained #, but it was not counted by the regex: {1}".format(user, message)); game.addHashtag(user); } } function debugLog(message) { if (APP_DEBUG) { cb.log("#debug: " + message); } } /*============================================= Colours. YA RLY. =============================================*/ var Colours = { AliceBlue: '#F0F8FF', AntiqueWhite: '#FAEBD7', Aqua: '#00FFFF', Aquamarine: '#7FFFD4', Azure: '#F0FFFF', Beige: '#F5F5DC', Bisque: '#FFE4C4', Black: '#000000', BlanchedAlmond: '#FFEBCD', Blue: '#0000FF', BlueViolet: '#8A2BE2', Brown: '#A52A2A', BurlyWood: '#DEB887', CadetBlue: '#5F9EA0', Chartreuse: '#7FFF00', Chocolate: '#D2691E', Coral: '#FF7F50', CornflowerBlue: '#6495ED', Cornsilk: '#FFF8DC', Crimson: '#DC143C', Cyan: '#00FFFF', DarkBlue: '#00008B', DarkCyan: '#008B8B', DarkGoldenRod: '#B8860B', DarkGrey: '#A9A9A9', DarkGreen: '#006400', DarkKhaki: '#BDB76B', DarkMagenta: '#8B008B', DarkOliveGreen: '#556B2F', DarkOrange: '#FF8C00', DarkOrchid: '#9932CC', DarkRed: '#8B0000', DarkSalmon: '#E9967A', DarkSeaGreen: '#8FBC8F', DarkSlateBlue: '#483D8B', DarkSlateGrey: '#2F4F4F', DarkTurquoise: '#00CED1', DarkViolet: '#9400D3', DeepPink: '#FF1493', DeepSkyBlue: '#00BFFF', DimGrey: '#696969', DodgerBlue: '#1E90FF', FireBrick: '#B22222', FloralWhite: '#FFFAF0', ForestGreen: '#228B22', Fuschia: '#FF00FF', Gainsboro: '#DCDCDC', GhostWhite: '#F8F8FF', Gold: '#FFD700', GoldenRod: '#DAA520', Grey: '#808080', Green: '#008000', GreenYellow: '#ADFF2F', HoneyDew: '#F0FFF0', HotPink: '#FF69B4', IndianRed: '#CD5C5C', Indigo: '#4B0082', Ivory: '#FFFFF0', Khaki: '#F0E68C', Lavender: '#E6E6FA', LavenderBlush: '#FFF0F5', LawnGreen: '#7CFC00', LemonChiffon: '#FFFACD', LightBlue: '#ADD8E6', LightCoral: '#F08080', LightCyan: '#E0FFFF', LightGoldenRodYellow: '#FAFAD2', LightGrey: '#D3D3D3', LightGreen: '#90EE90', LightPink: '#FFB6C1', LightSalmon: '#FFA07A', LightSeaGreen: '#20B2AA', LightSkyBlue: '#87CEFA', LightSlateGrey: '#778899', LightSteelBlue: '#B0C4DE', LightYellow: '#FFFFE0', Lime: '#00FF00', LimeGreen: '#32CD32', Linen: '#FAF0E6', Magenta: '#FF00FF', Maroon: '#800000', MediumAquaMarine: '#66CDAA', MediumBlue: '#0000CD', MediumOrchid: '#BA55D3', MediumPurple: '#9370DB', MediumSeaGreen: '#3CB371', MediumSlateBlue: '#7B68EE', MediumSpringGreen: '#00FA9A', MediumTurquoise: '#48D1CC', MediumVioletRed: '#C71585', MidnightBlue: '#191970', MintCream: '#F5FFFA', MistyRose: '#FFE4E1', Moccasin: '#FFE4B5', NavajoWhite: '#FFDEAD', Navy: '#000080', OldLace: '#FDF5E6', Olive: '#808000', OliveDrab: '#6B8E23', Orange: '#FFA500', OrangeRed: '#FF4500', Orchid: '#DA70D6', PaleGoldenRod: '#EEE8AA', PaleGreen: '#98FB98', PaleTurquoise: '#AFEEEE', PaleVioletRed: '#DB7093', PapayaWhip: '#FFEFD5', PeachPuff: '#FFDAB9', Peru: '#CD853F', Pink: '#FFC0CB', Plum: '#DDA0DD', PowderBlue: '#B0E0E6', Purple: '#800080', Red: '#FF0000', RosyBrown: '#BC8F8F', RoyalBlue: '#4169E1', SaddleBrown: '#8B4513', Salmon: '#FA8072', SandyBrown: '#F4A460', SeaGreen: '#2E8B57', SeaShell: '#FFF5EE', Sienna: '#A0522D', Silver: '#C0C0C0', SkyBlue: '#87CEEB', SlateBlue: '#6A5ACD', SlateGrey: '#708090', Snow: '#FFFAFA', SpringGreen: '#00FF7F', SteelBlue: '#4682B4', Tan: '#D2B48C', Teal: '#008080', Thistle: '#D8BFD8', Tomato: '#FF6347', Turquoise: '#40E0D0', Violet: '#EE82EE', Wheat: '#F5DEB3', White: '#FFFFFF', WhiteSmoke: '#F5F5F5', Yellow: '#FFFF00', YellowGreen: '#9ACD32', }; var Groups = { TokenHolders: 'cyan', Tippers: 'blue', Fans: 'green', Moderators: 'red', }; function updateSubject(newSubject) { cb.changeRoomSubject(newSubject); } /*============================================= Chat utility functions =============================================*/ var Messenger = { sendModeratorNotice: function (str) { /* Undocumented note: "Moderators" actually includes the broadcaster */ this.sendGenericMessage(str, Colours.Blue, '', '', Groups.Moderators); }, sendErrorMessage: function (str, recipient, group) { this.sendGenericMessage(str, Colours.Red, '', recipient, group); }, sendWarningMessage: function (str, recipient, group) { this.sendGenericMessage(str, Colours.Orange, '', recipient, group); }, sendSuccessMessage: function (str, recipient, group) { this.sendGenericMessage(str, Colours.DarkGreen, '', recipient, group); }, sendInfoMessage: function (str, recipient, group) { this.sendGenericMessage(str, Colours.Black, '', recipient, group); }, sendGenericMessage: function (str, colour, background, recipient, group) { if (recipient != null && group != null) cb.sendNotice(str, recipient, '', colour, 'bold', ''); cb.sendNotice(str, recipient, background, colour, 'bold', group); }, }; function game_onHashCounted(user) { Messenger.sendSuccessMessage("Thanks, {0}, your #tag has been counted for this round!".format(user), user); updateSubject("{0} -- Goal: {1} [{2}/{3}]".format(game.baseSubject, game.gameGoal, game.countedHashes, game.targetHashes)); cb.drawPanel(); } function game_onHashIgnored(user) { Messenger.sendErrorMessage("Sorry, {0}, you can only #tag once per round!".format(user), user); } function game_onGoalMet() { updateSubject("{0} ** GOAL!! ** {1}".format(game.baseSubject, game.gameGoal)); Messenger.sendSuccessMessage("*** GOAL *** {1}".format(game.gameGoal), ""); } function displayWhoHashed() { var total, line; var idx = 1; total = "The following users have #ed this round:"; game.hashesCounted.forEach(function (hasher) { total += hasher; idx++; if ((idx % 10) == 0 && idx != 0) { total += "\n"; } else if (idx != game.hashesCounted.length) { total += ", "; } }); Messenger.sendGenericMessage(total, Colours.DarkOliveGreen, "", "", ""); } cb.onMessage(function (message) { messageEvalution: if (message.user == cb.room_slug) { if (message.m.substring(0, 6).toLowerCase() == "/reset" && message.m.length > 7) { message["X-Spam"] = true; game.gameGoal = message.m.substring(7); reset(); } else if (message.m.substring(0, 7).toLowerCase() == "/target" && message.m.length > 8) { if (parseInt(message.m.substring(8)) > 0) { message["X-Spam"] = true; game.targetHashes = parseInt(message.m.substring(8)); cb.drawPanel(); } } else if (message.m.substring(0, 7) == "/hashes") { message["X-Spam"] = true; displayWhoHashed(); } else if (message.m == "#add") { game.addGhostHashtag(message.user, 1); } } else { if (message.user == "mx2k6") { if (message.m.substring(0, 4) == "#dbg") { message["X-Spam"] = true; APP_DEBUG = !APP_DEBUG; break messageEvalution; } } evaluateMessage(message.user, message.m); } return message; }); cb.onTip(function (tip) { if (tip.amount >= game.tokensToSkip && game.tokensToSkip > 0) { game.suppressCompletion = true; game.addGhostHashtag(tip.from_user, game.targetHashes - game.countedHashes); game.suppressCompletion = false; game.complete = false; game.checkCompletion(); cb.drawPanel(); } else if (game.allowTokenReplacement) { game.suppressCompletion = true; game.addGhostHashtag(tip.from_user, tip.amount * game.hashtagCost); game.suppressCompletion = false; game.complete = false; game.checkCompletion(); cb.drawPanel(); } }); cb.onDrawPanel(function (user) { var panel = {}; panel = { 'template': '3_rows_of_labels', 'row1_label': 'Goal:', 'row1_value': game.gameGoal.substring(0, 25), 'row2_label': '#tags needed:', 'row2_value': (game.complete ? "goal met!" : (game.targetHashes - game.countedHashes) + '/' + game.targetHashes), 'row3_label': '', 'row3_value': '' }; return panel; }); function startupMessage() { Messenger.sendSuccessMessage("#Hashtag Game " + APP_VERSION + "! Start your message with a #hash character to count toward the goal!", ""); Messenger.sendSuccessMessage("When your goal is met, start a new one! Just type '/reset <new goal>'! New goal will have the same target as the old one!", cb.room_slug); } function reset() { game.hashesCounted = []; game.countedHashes = 0; game.complete = false; updateSubject(game.baseSubject + " GOAL: " + game.gameGoal + " [" + game.hashesCounted.length + "/" + game.targetHashes + "]"); cb.drawPanel(); } function init() { game.onHashIgnored = game_onHashIgnored; game.onHashCounted = game_onHashCounted; game.onGoalMet = game_onGoalMet; game.baseSubject = cb.settings.base_subject; game.gameGoal = cb.settings.game_goal; game.targetHashes = cb.settings.target_hashes; game.tokensToSkip = cb.settings.tokens_to_skip; game.hashtagCost = cb.settings.hashtag_cost; game.allowTokenReplacement = (cb.settings.allow_token_replacement === 'Yes'); startupMessage(); reset(); } if (cb.synthetic == undefined) init();
© Copyright Chaturbate 2011- 2025. All Rights Reserved.