Bots Home
|
Create an App
Tip Multi Goal V1
Author:
anonymdev
Description
Source Code
Launch Bot
Current Users
Created by:
Anonymdev
//////////////////////////////////////////////////////////////////////////////// // D J L O V E N S E T I P M U L T I - G O A L // by Smoker919 // // The safe, secure, and open version of DJ Lovense Tip Goal //////////////////////////////////////////////////////////////////////////////// // "smoker919" shall be identified as the author of this app and any forked versions of it. // Developers who fork versions of this app, either directly or from another forked version, may refer to themselves as the maintainers of their versions. // Classes ///////////////////////////////////////////////////////////////////// class AppImage { constructor(id, width, height) { this.id = id; this.width = width; this.height = height; } } class Theme { constructor( topRowTextColour, bottomRowTextColour, baseBackgroundImageId, overlayBackgroundImageId, tipBackgroundImageId, tipAnimatedImage, tipMiddleRowImage, tipReplacementAnimatedImages, animatedImages ) { this.topRowTextColour = topRowTextColour, this.bottomRowTextColour = bottomRowTextColour, this.baseBackgroundImageId = baseBackgroundImageId; this.overlayBackgroundImageId = overlayBackgroundImageId; this.tipBackgroundImageId = tipBackgroundImageId; this.tipAnimatedImage = tipAnimatedImage; this.tipMiddleRowImage = tipMiddleRowImage; this.tipReplacementAnimatedImages = tipReplacementAnimatedImages; this.animatedImages = animatedImages; } } class Goal { constructor(description, amount) { this.description = description; this.amount = amount; } } class Tip { constructor(username, isAnon, tokens) { this.username = username; this.isAnon = isAnon; this.tokens = tokens; } } // Constants /////////////////////////////////////////////////////////////////// // Do not change this!!! Change the next one instead. const APP_AUTHOR = 'smoker919'; // Change this to give yourself credit for any changes made in your forked version. const APP_MAINTAINER = 'smoker919'; const APP_NAME = 'DJ Lovense Tip Multi-Goal'; const TESTBED_VERSION = false; const PROGRESS_SQUARES = 12; const ANONYMOUS_USER = 'anonymous user'; const USERNAME_LETTERS = 'abcdefghijklmnopqrstuvwxyz'; // unicode const ZERO = '\u0030'; // 0 const ONE = '\u0031'; // 1 const TWO = '\u0032'; // 2 const THREE = '\u0033'; // 3 const FOUR = '\u0034'; // 4 const FIVE = '\u0035'; // 5 const SIX = '\u0036'; // 6 const SEVEN = '\u0037'; // 7 const EIGHT = '\u0038'; // 8 const NINE = '\u0039'; // 9 const NBSP = '\u00A0'; const EN_DASH = '\u2013'; // – const COMBINING_ENCLOSING_KEYCAP = '\u20E3'; const LIGHT_SHADE = '\u2591'; // ░ const RIGHT_POINTING_POINTER = '\u25BA'; // ► const LIGHTNING = '\u26A1'; // ⚡️ const WHITE_SQUARE = '\u2B1C'; // ⬜️ const CROSS_MARK = '\u274C'; // ❌ const VARIATION_SELECTOR_16 = '\uFE0F'; const MEDAL = '\u{1F3C5}'; // 🏅 const RIGHT_POINTING_HAND = '\u{1F449}'; // 👉 const PRINCESS = '\u{1F478}'; // 👸 const GEM_STONE = '\u{1F48E}'; // 💎 const FLASHING_LIGHT = '\u{1F6A8}'; // 🚨 const GREEN_SQUARE = '\u{1F7E9}'; // 🟩 const HEART = '\u2764' + VARIATION_SELECTOR_16; // ❤️ const WARNING = '\u26A0' + VARIATION_SELECTOR_16; // ⚠️ const KEYCAP_NUMBERS = [ ZERO + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, ONE + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, TWO + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, THREE + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, FOUR + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, FIVE + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, SIX + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, SEVEN + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, EIGHT + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, NINE + VARIATION_SELECTOR_16 + COMBINING_ENCLOSING_KEYCAP, ]; // fonts const BOLD = 'bold'; //spacing const LINE_ENDING = NBSP; // timings const GOAL_VIEW_DURATION = 35000; const LOVENSE_VIEW_DURATION = 5000; const LAST_TIP_VIEW_DURATION = 25000; const PRIVATE_VIEW_DURATION = 15000; const NEXT_GOAL_DELAY = 45000; const ANIMATED_IMAGE_DURATION = 10000; const MAX_DESCRIPTION_LENGTH_IN_GOAL_VIEW = 30; const NOTICE_BACKGROUNDS = [ 'linear-gradient(to right, rgb(0,255,255), rgb(153,255,153))', // aqua to green 'linear-gradient(to right, rgb(86,204,242), rgb(255,204,255))', // blue to pink 'linear-gradient(to right, rgb(151,150,240), rgb(251,199,212))', // purple to pink 'linear-gradient(to right, rgb(168,192,255) 40.0%, rgb(86,204,242) 60.0%)', // grey/purple to aqua blue 'linear-gradient(to right, rgb(176,196,222), rgb(204,235,255), rgb(165,254,203))', // grey/blue to blue to mint green 'linear-gradient(to right, rgb(255,204,255), rgb(255, 153, 204))', // pink to pink 'linear-gradient(to right, rgb(255,255,0), rgb(199,250,195))', // yellow to mint green 'linear-gradient(to right, rgb(255,255,0), rgb(255,153,204))' // yellow to pink ]; const TEST_COMMAND_REGEX = /^\/(test|test-anon) ([1-9][0-9]*)$/; const GOAL_COMPLETED_MESSAGE = GEM_STONE.repeat(24) + LINE_ENDING + '\n' + LIGHT_SHADE + '>>>GOAL COMPLETED!!!<<<'.split('').join(LIGHT_SHADE) + LIGHT_SHADE + LINE_ENDING + '\n:minions_hurra :goalcomplete-GR ' + LINE_ENDING + '\nThe goal of: [description] was completed!' + LINE_ENDING + '\n' + GEM_STONE.repeat(24) + LINE_ENDING; const NEXT_GOAL_MESSAGE = LIGHTNING.repeat(22) + LINE_ENDING + '\n' + EN_DASH.repeat(14) + ' NEXT GOAL ' + EN_DASH.repeat(18) + LINE_ENDING + '\n' + NBSP.repeat(13) + RIGHT_POINTING_POINTER + ' [description]: [amount]' + LINE_ENDING + '\n' + EN_DASH.repeat(42) + LINE_ENDING + '\n' + NBSP.repeat(13) + 'The next goal has been set!' + LINE_ENDING + '\n' + LIGHTNING.repeat(22) + LINE_ENDING; // Settings //////////////////////////////////////////////////////////////////// cb.settings_choices = [ { name: 'theme', type: 'choice', label: 'Theme', choice1: 'Baby Yoda', choice2: 'Daisy Flower', choice3: 'DJ Hello Kitty', choice4: 'Fluttershy', choice5: 'Galactic Orb', choice6: 'Harley Quinn', choice7: 'Milk, White Bear in Love', choice8: 'Pikachu', choice9: 'Pusheen the Cat', choice10: 'Qoobee the Dino', choice11: 'Rick (from Rick and Morty)', choice12: 'Santa Girl (Christmas!)', choice13: 'Spotty the Giraffe', choice14: 'Spyro the Dragon', choice15: 'Unikitty', choice16: 'Vampire Girl' }, { name: 'tags', type: 'str', label: 'Tags (appended to subject)' } ]; for (let i = 1; i <= 10; i++) { cb.settings_choices.push({ name: 'goal_' + i, type: 'str', label: 'Goal ' + i + ' (<description>: <amount>)', required: i === 1 }); } cb.settings_choices.push( { name: 'room_greeting', type: 'str', label: 'Room greeting (in subject after goal)', defaultValue: 'Welcome to my room!', required: false }, { name: 'change_subject_on_each_tip', type: 'choice', label: 'Change subject on each tip', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes' }, { name: 'show_private_is_open_message', type: 'choice', label: 'Show "Private is open!" message', choice1: 'Yes', choice2: 'No', defaultValue: 'Yes' } ); // Themes ////////////////////////////////////////////////////////////////////// // shared images const SPARKLES_BACKGROUND_IMAGE_ID = '779e14bf-8f4a-44e2-a79f-a064c3e66c1d'; const SNOW_BACKGROUND_IMAGE_ID = '3c26f764-cc35-4797-8552-613513f63f77'; const LUSH_IMAGE = new AppImage('514fc91f-9d1e-4d46-b927-1c2e0baa0fb3', 39, 38); const PINK_LOVENSE_LOGO_IMAGE = new AppImage('c23cc947-3255-433f-88e5-c9089d1914b6', 160, 20); const WHITE_LOVENSE_LOGO_IMAGE = new AppImage('399ee726-692d-409f-b629-926969783733', 156, 20); const THANK_YOU_IMAGE = new AppImage('132bf60d-00d7-427b-9097-316691dff817', 150, 22); const TOP_OVERLAY_IMAGE_ID = '8cab78f7-9588-4ff5-88ba-0dd20cff44e1'; const THEMES = { 'Baby Yoda': new Theme('', '', 'd97f3c0e-dc38-42ba-bc67-35de2319a7bd', SPARKLES_BACKGROUND_IMAGE_ID, '5b247c07-29f9-4604-ad8f-e34ccea04284', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('86094e43-6bf6-472e-9343-c03d74d0c708', 72, 69), new AppImage('ab90e294-e213-4767-a5b8-e022ef8c6c92', 66, 69), new AppImage('c40dfd83-2df7-4792-978d-059aa0de12dc', 69, 69) ], [ new AppImage('1086340a-9cb2-445d-8362-ee7d41fc0d21', 76, 69), new AppImage('43d91dc6-12ed-42f1-b52d-5a3ccf8a8a0a', 69, 69), new AppImage('5eead199-0a6f-47b9-bb4e-ac9ad64ba334', 69, 69), new AppImage('64b61ca5-a4c8-4a4f-b6a4-04a7871acdb9', 69, 69), new AppImage('7d4dcf92-785e-4c4e-9fd7-5d24f4862400', 72, 69), new AppImage('82b217ef-b326-4b23-80d6-1d5dacad6818', 69, 69), new AppImage('ad776199-269e-4d52-9b38-f0c7226d0080', 58, 69), new AppImage('c2f90997-f430-4dc2-874c-6c5fb5c0317b', 69, 69), new AppImage('cb73c3d8-cf6d-4d66-b3c4-e15feae20496', 74, 69) ] ), 'Daisy Flower': new Theme('', '', '2e4f3379-db49-4b6f-88b6-eb5ebd87fdaa', SPARKLES_BACKGROUND_IMAGE_ID, '5453924b-7b94-4b43-9e8f-c89360cfa293', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('1b11d64a-a2f8-49f9-ada9-519ab90cbd1e', 69, 69), new AppImage('7d405e67-b9bc-48f7-ba65-71803d666e8c', 69, 69) ], [ new AppImage('018fe13e-2a07-4ba3-9c48-7c7d2dad328c', 69, 69), new AppImage('17f0d657-50f5-450b-b97d-3b40c6a3786a', 69, 69), new AppImage('1ac99755-10f3-4731-904d-b258b85ddf5e', 69, 69), new AppImage('2f52de01-7677-44fe-9466-c7f9e343827b', 69, 69), new AppImage('30774aeb-1e44-4538-af08-1df40cdf762d', 69, 69), new AppImage('37a3d1b6-5b6a-4a99-9d14-debaace6a092', 69, 69), new AppImage('b2187101-7bb3-47b0-a229-cad7513da1bc', 69, 69), new AppImage('b9a36bfa-bfcd-4756-96d2-673b04e0a279', 69, 69), new AppImage('dcd15f86-fcea-4391-8783-970d1a221eb1', 69, 69), new AppImage('fe6f9bef-a592-4070-b6d9-784079923227', 69, 69) ] ), 'DJ Hello Kitty': new Theme('', '', 'd10e5605-81f1-40a1-9c72-16fb32e4185c', SPARKLES_BACKGROUND_IMAGE_ID, 'c957017a-a80c-48d5-9df0-6d49ea8e2001', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('f58ebae3-7c63-41e1-8e7c-a97fc1b96c24', 69, 69) ], [ new AppImage('14e0059a-bd52-4b2b-a608-68b7d6955d07', 69, 69), new AppImage('2046aa4e-2d73-4dbf-8f28-4f1d0544bf6a', 81, 69), new AppImage('4ab04a2c-49d8-4856-b9d9-0a6883fe1bff', 69, 69), new AppImage('76cc8362-2009-4c62-bdbb-e86032ca3a2c', 69, 69), new AppImage('82556b55-3708-4cac-ac20-86e65d892e59', 69, 69), new AppImage('8b837e29-909b-417e-8b7f-0c61422a8afe', 69, 69), new AppImage('9735158c-ad61-45fb-960e-e50abe6e69b5', 69, 69), new AppImage('b58b819b-656e-4cf7-94f1-429e6be772ed', 73, 69), new AppImage('c6737a69-6653-4e59-a598-57bd31a68a47', 72, 69), new AppImage('d53a2d92-baa0-42fd-8eb2-b75047869101', 71, 69) ] ), 'Fluttershy': new Theme('', '', '787c08a0-cc21-4955-8b7f-a6b340cccdaa', SNOW_BACKGROUND_IMAGE_ID, '5b247c07-29f9-4604-ad8f-e34ccea04284', new AppImage('b6f6118b-6785-4320-9968-9b2819281abf', 39, 39), THANK_YOU_IMAGE, [ new AppImage('db68eda8-4fda-4714-a0c2-999020d703a5', 79, 69) ], [ new AppImage('9635f050-ed7c-4efc-8fef-180d379f9d04', 70, 69) ] ), 'Galactic Orb': new Theme('', '', 'd10e5605-81f1-40a1-9c72-16fb32e4185c', SPARKLES_BACKGROUND_IMAGE_ID, 'c957017a-a80c-48d5-9df0-6d49ea8e2001', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('a2236743-05a4-46e3-95fc-7d9d25125134', 60, 69) ], [ new AppImage('a2236743-05a4-46e3-95fc-7d9d25125134', 60, 69) ] ), 'Harley Quinn': new Theme('', '', '2e4f3379-db49-4b6f-88b6-eb5ebd87fdaa', SPARKLES_BACKGROUND_IMAGE_ID, '5453924b-7b94-4b43-9e8f-c89360cfa293', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('c2b04597-f489-42da-9f00-1c2f74ec1e12', 69, 69) ], [ new AppImage('01455d46-cf0f-4c48-b72a-7e8aa9b824df', 69, 69), new AppImage('0d41840b-6225-495d-86a5-eebd0ee17fc5', 69, 69), new AppImage('2324e53f-3399-4ff8-a670-635abc4d27ee', 69, 69), new AppImage('29ead88b-ec6f-4185-bde1-4deb2d11c3ce', 69, 69), new AppImage('4423f691-34ff-494d-814d-6dc96c4acf47', 69, 69), new AppImage('467f75f7-4d43-48c5-a475-bae5985c8173', 69, 69), new AppImage('566d6911-32cf-4552-997f-cf6010df934b', 69, 69), new AppImage('a0347c9a-b72c-4dd3-b55d-17c8705d5fb8', 69, 69), new AppImage('bf069a27-a2a3-4e96-9814-fade3af011b1', 69, 69), new AppImage('e35eeedf-ff8e-4ca0-94a5-a09c1bf1981a', 69, 69) ] ), 'Milk, White Bear in Love': new Theme('', '', '815db6ea-88da-436d-bb35-befced3b0f45', SPARKLES_BACKGROUND_IMAGE_ID, 'f57911a2-512e-4fe1-9533-6a960bbed92c', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('1b41833d-dd0f-4d58-bee9-5acbc9edc391', 70, 69) ], [ new AppImage('14076af0-a076-4374-b4ee-fb33717fd21b', 77, 69), new AppImage('22e480e4-07ac-42b5-8fd3-ea36c8077dcd', 62, 69), new AppImage('36141ccf-d5d2-4c0f-8e79-4868ebf59df2', 66, 69), new AppImage('6c58440c-1759-4fd6-9089-092e576e0605', 65, 69), new AppImage('9b892ece-812b-4e17-b629-37450636bebf', 72, 69), new AppImage('bf29b674-db85-4e88-b594-562654fe6f4d', 67, 69), new AppImage('d9846d8a-bfc1-40f2-aaf6-db5c35422ace', 75, 69) ] ), 'Pikachu': new Theme('', '', '2e4f3379-db49-4b6f-88b6-eb5ebd87fdaa', SPARKLES_BACKGROUND_IMAGE_ID, '5453924b-7b94-4b43-9e8f-c89360cfa293', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('bab6a61e-ccda-410a-ac62-86efc97eed02', 70, 69) ], [ new AppImage('1118f4d5-cc09-4a8c-8619-2011cbb8e1ff', 69, 69), new AppImage('1a2493e9-0c56-4562-9958-f22409627f2f', 69, 69), new AppImage('42bae55b-93c1-4b5c-92ed-55f10cb694aa', 69, 69), new AppImage('4ad0f05f-caf9-4ee9-9669-04f08755b795', 69, 69), new AppImage('a961b7fb-8b4f-4389-92ba-b3b7aab89163', 69, 69), new AppImage('b6d89983-1cbc-471f-8de3-6a3140744228', 69, 69), new AppImage('ca5c97b5-493f-4072-b5a8-922cbfe35b02', 69, 69), new AppImage('dc9b23a6-a071-4d5f-ac31-8d6b7e2ba432', 69, 69) ] ), 'Pusheen the Cat': new Theme('', '', 'cf3dd7cd-f6ba-4aaa-b6d2-c2e9586773e6', SPARKLES_BACKGROUND_IMAGE_ID, '00c53504-951f-4f84-9768-d1894c1190b3', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('6ff82b2b-cb8c-49fd-b34e-9a03e208a5fc', 67, 69) ], [ new AppImage('1e6904ff-f948-4fbc-a45c-240b7c4bb513', 68, 69), new AppImage('2b0c3a58-f140-4a71-aa1c-39c6c21daaf0', 71, 69), new AppImage('63876598-69a8-4d07-a9a4-6877df123c59', 67, 69), new AppImage('81b3adc5-8a07-4fd3-a62c-131b94ccd36b', 69, 69), new AppImage('852ca3ca-a846-4b43-a342-49ec5e801336', 75, 69), new AppImage('89a8f944-adc8-4fc6-a0c9-5fdc4cb1cacb', 66, 69), new AppImage('beb57a67-250c-49e3-9092-5facf4659991', 75, 69) ] ), 'Qoobee the Dino': new Theme('', '', '2e4f3379-db49-4b6f-88b6-eb5ebd87fdaa', SPARKLES_BACKGROUND_IMAGE_ID, '5453924b-7b94-4b43-9e8f-c89360cfa293', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('b92d9255-a25c-4e58-b097-3713e90984f0', 69, 69), new AppImage('e49226e3-49bf-4193-8b89-4f65a1b6e264', 69, 69), new AppImage('ec251fc8-3f90-4922-833f-55bf1c65cf13', 69, 69) ], [ new AppImage('063a53a4-e1d2-4343-aecf-6a15018da6b8', 69, 69), new AppImage('12f14f8c-7b72-49fc-b8c7-c87ac34fbb1c', 70, 69), new AppImage('29f028db-4ea5-44fb-9823-40aa03b4ad3c', 69, 69), new AppImage('41eff579-fbe8-4a99-85d0-fc5412d7481b', 69, 69), new AppImage('5ed238cb-45c9-4370-8761-f128f7ceddcf', 67, 69), new AppImage('669e94f7-10cb-4bf5-ace1-51cb764a8d50', 69, 69), new AppImage('6a9c9987-6e97-4c30-a345-fdb889053f06', 67, 69), new AppImage('737b0ffd-ca34-4a33-ba23-0ca660224b0c', 70, 69), new AppImage('a55197aa-870f-47a1-8889-3c4af194b7ce', 70, 69), new AppImage('e5f1d90f-e627-4f26-b977-3fc4d6c0f9e7', 66, 69) ] ), 'Rick (from Rick and Morty)': new Theme('', '', 'e5027a40-eac8-4d71-940c-9097bf69999c', SPARKLES_BACKGROUND_IMAGE_ID, '58b29529-1f58-4438-9ea5-306e518bc7e4', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('393a6b7f-d4a2-4339-b760-55d8a96f7b51', 66, 69) ], [ new AppImage('04f71f9f-5fb8-40a0-a6ce-a465bed0c9de', 71, 69), new AppImage('1a8864aa-8396-44ec-a72e-249ba0c633d6', 72, 69), new AppImage('6ec54c8f-229a-4197-aa82-5cf65fc6c3d9', 51, 69), new AppImage('747639b3-8b96-4afd-bfae-5066cec8ef98', 72, 69), new AppImage('7b4f5b26-e643-4b71-af9d-72cf53e7b7b5', 68, 69), new AppImage('7fdba35b-91cc-4f2f-a21d-038f3a83c14a', 74, 69), new AppImage('82e41a6f-97a6-4263-8257-7860694f0226', 70, 69), new AppImage('88fadeaa-c836-487a-90dc-d9687624a1d0', 67, 69), new AppImage('dbb0d991-9524-401e-855a-dc7b8833bdeb', 69, 69) ] ), 'Santa Girl (Christmas!)': new Theme('', '', '5707b5c2-1258-4a53-91c4-94c699f7a7e5', SNOW_BACKGROUND_IMAGE_ID, '04eb33fd-81c4-4ca2-bde5-d62d335122ab', LUSH_IMAGE, WHITE_LOVENSE_LOGO_IMAGE, [ new AppImage('0025f787-af42-4368-ab1a-9862ef380674', 69, 69) ], [ new AppImage('0ef32cc0-011a-4bd6-81b2-1d10fd70bdae', 69, 69), new AppImage('2ee7d642-9a02-488a-b405-38dcd4925ded', 69, 69), new AppImage('6226b71a-10de-4f86-bf25-13594148eca6', 69, 69), new AppImage('74876e39-d077-44ea-a41f-7e1e8fd607f3', 69, 69), new AppImage('788ab1d8-6cc2-467e-9926-8358adae054b', 69, 69), new AppImage('8c0bffd5-7904-457f-b8dd-6bfdda0be6f2', 69, 69), new AppImage('8ca1f569-5e91-488a-b3a6-080929c72662', 69, 69), new AppImage('94ffd161-0a0a-412b-a929-b11fbeaca8c1', 69, 69), new AppImage('d1ce3b53-0df6-40bd-9b76-dd63532b0ddc', 69, 69) ] ), 'Spotty the Giraffe': new Theme('', '', 'd97f3c0e-dc38-42ba-bc67-35de2319a7bd', SPARKLES_BACKGROUND_IMAGE_ID, '5b247c07-29f9-4604-ad8f-e34ccea04284', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('76458bbb-d767-41c5-8c74-634c8693af42', 69, 69), new AppImage('92c2a409-35e5-4d4e-8d5c-7ac152035cf4', 69, 69), new AppImage('e6cdf071-728f-48b8-9909-36e2b503fce1', 69, 69) ], [ new AppImage('458faa2d-f5be-4388-9d81-03ea0e4f3c25', 69, 69), new AppImage('4dbee747-4ae1-4340-9204-00534de4730b', 69, 69), new AppImage('62f453e8-dc88-4dd3-b86e-9991490f3046', 69, 69), new AppImage('630affbd-0822-4fba-83b8-9e4225e0f9c4', 69, 69), new AppImage('c481ff28-cb7e-4012-b814-e34ada94cfe0', 69, 69), new AppImage('c4efa442-9f43-424e-a30d-774a2eb607e9', 69, 69) ] ), 'Spyro the Dragon': new Theme('', '', 'e5027a40-eac8-4d71-940c-9097bf69999c', SPARKLES_BACKGROUND_IMAGE_ID, '58b29529-1f58-4438-9ea5-306e518bc7e4', LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('4e36e4f7-856c-49c8-9943-59c4a8784f2b', 62, 69), new AppImage('7eaa3b02-610b-4d51-8f54-1676dbb5951f', 65, 69) ], [ new AppImage('d26c29a3-90c9-4b10-b352-8807792be325', 65, 69) ] ), 'Unikitty': new Theme('White', 'White', 'dc9c0399-9b12-4ef3-b1c0-c697556af3f5', SPARKLES_BACKGROUND_IMAGE_ID, null, new AppImage('4a07afb6-d3b5-4d19-83d3-502b9af4ad23', 50, 46), PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('27c3275c-167d-4b17-83a0-2da6df766f05', 72, 69) ], [ new AppImage('232fca18-d7d9-4c8f-a9d8-daf855b4ce7f', 69, 69), new AppImage('7138a12c-805e-480c-a5e8-8cea6555f078', 69, 69), new AppImage('add89166-1c11-42bd-b987-6572961b92e7', 69, 69), new AppImage('c9d5b089-5825-4d6e-9f78-537991885ea5', 69, 69), new AppImage('d3c786ad-be40-437d-86dd-8d135200e126', 69, 69) ] ), 'Vampire Girl': new Theme('White', 'rgb(249,40,128)', '6e9680d8-aefc-4e72-8ea0-71117ef5e216', SPARKLES_BACKGROUND_IMAGE_ID, null, LUSH_IMAGE, PINK_LOVENSE_LOGO_IMAGE, [ new AppImage('a3586d0d-4c99-4dd9-bd9c-302341ce11ba', 69, 69) ], [ new AppImage('072446aa-5021-48b4-b516-701ebaffcdeb', 69, 69), new AppImage('7a247f20-ab14-42d0-8d78-12dc8c2b6aea', 69, 69), new AppImage('d0ad648d-c9d8-4dba-bac5-6b9263b21053', 69, 69), new AppImage('d5036b5d-90e0-4c9c-a7c2-ae94f64308dd', 69, 69), new AppImage('dc648330-65cf-4f20-b7e0-6b78196a6752', 69, 69), new AppImage('dcc3005b-dca8-4f79-8ec1-14e3f445cad0', 69, 69), new AppImage('dd487922-240d-47e4-9d2b-f143c73dcf5d', 69, 69), new AppImage('e3e69d3b-8789-4365-876d-c7d89dac3f53', 69, 69), new AppImage('f0cd8e69-2ff9-47b6-97ea-f8093abd502e', 69, 69), new AppImage('fa25b064-56ea-43be-86c8-a6c653bb9261', 69, 69) ] ) }; // Variables /////////////////////////////////////////////////////////////////// // settings let theme; let tags; let goals; let roomGreeting; let changeSubjectOnEachTip; let showPrivateIsOpenMessage; // runtime state let currentGoalIndex = 0; let tokensReceivedForCurrentGoal = 0; let lastTip = null; let isReactingToTip = false; let currentReactingToTipTimeoutId = null; let currentAnimatedImage = null; let currentTipReplacementAnimatedImage = null; // treat these as binary states for now let showGoalInTopRow = true; let showLastTipInBottomRow = true; // Functions /////////////////////////////////////////////////////////////////// function randomInt(min, max, inclusive) { return min + Math.floor(Math.random() * (max - min + (inclusive ? 1 : 0))); } function randomElement(array) { return array[randomInt(0, array.length, false)]; } function log(message) { message = '[' + APP_NAME + '] ' + message; cb.log(message); cb.sendNotice(message, cb.room_slug); } function warn(message) { log(WARNING + ' ' + message); } function init() { theme = THEMES[String(cb.settings.theme)]; tags = String(cb.settings.tags).trim(); goals = parseGoalsFromSettings(); roomGreeting = String(cb.settings.room_greeting).trim(); changeSubjectOnEachTip = String(cb.settings.change_subject_on_each_tip) === 'Yes'; showPrivateIsOpenMessage = String(cb.settings.show_private_is_open_message) === 'Yes'; if (theme) { currentAnimatedImage = randomElement(theme.animatedImages); } cb.setTimeout(setNextAnimatedImage, ANIMATED_IMAGE_DURATION); updateRoomSubject(); cb.drawPanel(); cb.setTimeout(rotateTopRowView, GOAL_VIEW_DURATION); if (showPrivateIsOpenMessage) { cb.setTimeout(rotateBottomRowView, LAST_TIP_VIEW_DURATION); } } function parseGoalsFromSettings() { let goals = []; for (let i = 1; i <= 10; i++) { let goal = parseGoal(String(cb.settings['goal_' + i])); if (goal) { goals.push(goal); } } return goals; } function parseGoal(value) { if (!value) { return null; } let separatorIndex = value.lastIndexOf(':'); if (separatorIndex === 0) { warn('Invalid goal format: no description found: \'' + value + '\''); return null; } if (separatorIndex === -1) { warn('Invalid goal format: no amount found: \'' + value + '\''); return null; } let description = value.substring(0, separatorIndex).trim(); if (!description) { warn('Invalid goal format: no description found: \'' + value + '\''); return null; } let amount = parseInt(value.substring(separatorIndex + 1).trim()); if (isNaN(amount)) { warn('Invalid goal format: amount is not a number: \'' + value + '\''); return null; } return new Goal(description, amount); } function updateRoomSubject() { if (goals[currentGoalIndex]) { let newSubject = 'GOAL: ' + goals[currentGoalIndex].description; if (changeSubjectOnEachTip) { let tokensRemaining = goals[currentGoalIndex].amount - tokensReceivedForCurrentGoal; newSubject += ' [' + tokensRemaining + (tokensRemaining === 1 ? ' token' : ' tokens') + ' remaining]'; } if (roomGreeting) { newSubject += ' ' + roomGreeting; } if (tags) { newSubject += ' ' + tags; } cb.changeRoomSubject(newSubject); } } function setNextAnimatedImage() { currentAnimatedImage = randomElement(theme.animatedImages); cb.drawPanel(); cb.setTimeout(setNextAnimatedImage, ANIMATED_IMAGE_DURATION); } function rotateTopRowView() { showGoalInTopRow = !showGoalInTopRow; cb.drawPanel(); cb.setTimeout(rotateTopRowView, showGoalInTopRow ? GOAL_VIEW_DURATION : LOVENSE_VIEW_DURATION); } function rotateBottomRowView() { showLastTipInBottomRow = !showLastTipInBottomRow; cb.drawPanel(); cb.setTimeout(rotateBottomRowView, showLastTipInBottomRow ? LAST_TIP_VIEW_DURATION : PRIVATE_VIEW_DURATION); } // Handlers //////////////////////////////////////////////////////////////////// function onTipHandler(tip) { if (currentReactingToTipTimeoutId) { cb.cancelTimeout(currentReactingToTipTimeoutId); } lastTip = new Tip(tip.from_user, tip.is_anon_tip, tip.amount); isReactingToTip = true; currentTipReplacementAnimatedImage = randomElement(theme.tipReplacementAnimatedImages); let tokensRemaining = goals[currentGoalIndex].amount - tokensReceivedForCurrentGoal; if (tokensRemaining > 0) { tokensReceivedForCurrentGoal = Math.min(tokensReceivedForCurrentGoal + tip.amount, goals[currentGoalIndex].amount); if (changeSubjectOnEachTip) { updateRoomSubject(); } cb.drawPanel(); if (tokensReceivedForCurrentGoal === goals[currentGoalIndex].amount) { announceGoalCompleted(); if (currentGoalIndex < goals.length - 1) { cb.setTimeout(startNextGoal, NEXT_GOAL_DELAY); } } } else { cb.drawPanel(); } currentReactingToTipTimeoutId = cb.setTimeout(stopReactingToTip, getTipReactionDuration(tip.amount)); } function announceGoalCompleted() { let message = GOAL_COMPLETED_MESSAGE.replace('[description]', goals[currentGoalIndex].description); cb.sendNotice(message, '', randomElement(NOTICE_BACKGROUNDS), '', BOLD); } function startNextGoal() { currentGoalIndex++; tokensReceivedForCurrentGoal = 0; updateRoomSubject(); cb.drawPanel(); let message = NEXT_GOAL_MESSAGE .replace('[description]', goals[currentGoalIndex].description) .replace('[amount]', goals[currentGoalIndex].amount); cb.sendNotice(message, '', randomElement(NOTICE_BACKGROUNDS), '', BOLD); } function getTipReactionDuration(tokens) { // use the default Lovense levels if (tokens <= 9) { return 2000; } else if (tokens <= 49) { return 5000; } else if (tokens <= 99) { return 10000; } else if (tokens <= 300) { return 15000; } else { return 30000; } } function stopReactingToTip() { isReactingToTip = false; cb.drawPanel(); } function onDrawPanelHandler(user) { let layers = [ // static background image { type: 'image', fileID: theme.baseBackgroundImageId, left: 0, top: 0 }, // animated background image { type: 'image', fileID: theme.overlayBackgroundImageId, left: 0, top: 0 } ]; if (isReactingToTip) { layers.push( // tip replacement animated image { type: 'image', fileID: currentTipReplacementAnimatedImage.id, left: 270 - currentTipReplacementAnimatedImage.width, top: 0 }, // top row getTopRowLayer() ); // tip background image if (theme.tipBackgroundImageId) { layers.push({ type: 'image', fileID: theme.tipBackgroundImageId, left: 0, top: 23 }); } layers.push( // tip animated image { type: 'image', fileID: theme.tipAnimatedImage.id, left: (50 - theme.tipAnimatedImage.width) / 2, top: 23 + (46 - theme.tipAnimatedImage.height) / 2 }, // tip middle row image { type: 'image', fileID: theme.tipMiddleRowImage.id, left: 50 - 7, top: 23 + (23 - theme.tipMiddleRowImage.height) / 2 }, // bottom row { type: 'text', text: FLASHING_LIGHT + ' ' + (lastTip.isAnon ? ANONYMOUS_USER : lastTip.username) + ' buzzed!', color: theme.bottomRowTextColour, left: 50 + 8, top: 46 + 5 } ); } else { layers.push( // animated image { type: 'image', fileID: currentAnimatedImage.id, left: 270 - currentAnimatedImage.width, top: 0 }, // top row getTopRowLayer(), // middle row getMiddleRowLayer(), // bottom row getBottomRowLayer() ); } // top overlay image layers.push({ type: 'image', fileID: TOP_OVERLAY_IMAGE_ID, left: 0, top: 0 }); return { template: 'image_template', layers: layers }; } function getTopRowLayer() { return { type: 'text', text: showGoalInTopRow ? getGoalViewText() : PRINCESS + ' Hi, my Lovense is active!', color: theme.topRowTextColour, left: 5, top: 5 }; } function getMiddleRowLayer() { let percent = 100.0 * tokensReceivedForCurrentGoal / goals[currentGoalIndex].amount; let greenSquaresCount = Math.round(PROGRESS_SQUARES * percent / 100.0); return { type: 'text', text: GREEN_SQUARE.repeat(greenSquaresCount) + WHITE_SQUARE.repeat(PROGRESS_SQUARES - greenSquaresCount), left: 4, top: 23 + 5 }; } function getBottomRowLayer() { return { type: 'text', text: getBottomRowText(), color: theme.bottomRowTextColour, left: 5, top: 46 + 5 }; } function getBottomRowText() { if (goals[currentGoalIndex].amount - tokensReceivedForCurrentGoal === 0) { // overrides the basic views return MEDAL + MEDAL + ' GOAL COMPLETED! ' + MEDAL + MEDAL; } else if (showLastTipInBottomRow) { return getLastTipViewText(); } else { return 'Private is open!' + NBSP.repeat(9) + 'Click this link!' + NBSP.repeat(8) + RIGHT_POINTING_HAND.repeat(6); } } function getGoalViewText() { return tokensReceivedForCurrentGoal + ' / ' + goals[currentGoalIndex].amount + ': ' + maybeTruncateDescription(goals[currentGoalIndex].description); } function maybeTruncateDescription(description) { return description.length > MAX_DESCRIPTION_LENGTH_IN_GOAL_VIEW ? description.substring(0, MAX_DESCRIPTION_LENGTH_IN_GOAL_VIEW - 3) + '...' : description; } function getLastTipViewText() { if (lastTip) { return 'Last Tip: ' + HEART + ' ' + (lastTip.isAnon ? ANONYMOUS_USER : lastTip.username) + ': ' + lastTip.tokens.toString().split('').map(i => KEYCAP_NUMBERS[i]).join(''); } else { return 'Last Tip: ' + CROSS_MARK + CROSS_MARK + ' (your name here)'; } } function onMessageHandler(message) { // can only test on the testbed or in the app maintainer's room if (TESTBED_VERSION || cb.room_slug === APP_MAINTAINER) { let match = message.m.match(TEST_COMMAND_REGEX); if (match) { onTipHandler({ from_user: message.user, is_anon_tip: match[1] === 'test-anon', amount: parseInt(match[2]) }); } } } // Callbacks /////////////////////////////////////////////////////////////////// cb.onTip(onTipHandler); cb.onDrawPanel(onDrawPanelHandler) cb.onMessage(onMessageHandler); // Initialize the app ////////////////////////////////////////////////////////// init();
© Copyright Chaturbate 2011- 2026. All Rights Reserved.