Bots Home
|
Create an App
KashMoniy Room Bot
Author:
moniyapp
Description
Source Code
Launch Bot
Current Users
Created by:
Moniyapp
// Top Tippers Today // Author: asdfghjkl28 var OWNER_FLAG = 32; var MODERATOR_FLAG = 16; var FANCLUB_FLAG = 8; var DKBLUE_FLAG = 4; var LTBLUE_FLAG = 2; var GREY_FLAG = 1; var topn = { commands: {}, registerCommand: function (command, helpText, owner, moderator, fanclub, dkblue, ltblue, grey, method) { "use strict"; this.commands[command] = {method: method, helpText: helpText, perms: this.bool2Perm(owner, moderator, fanclub, dkblue, ltblue, grey)}; }, checkCommand: function (msg) { "use strict"; var m = msg.m; var u = msg.user; if (m[0] === '/') { // don't print commands msg['X-Spam'] = true; // Remove trailing spaces m = m.replace(/\s+$/, ''); // Find command parameters var commandParts = m.split(/\s+/); var commandName = commandParts.shift(); // cb.log(u + ' issued command: ' + commandName); if (this.commands[commandName] && (this.commands[commandName].perms & this.msg2Perm(msg))) { // cb.log(u + " allowed to run command:" + commandName); msg = this.commands[commandName].method(msg, commandParts); // Only don't print if it is a command we handle return msg; } else { return false; } } else { return false; } }, bool2Perm: function (owner, moderator, fanclub, dkblue, ltblue, grey) { "use strict"; var perms = 0; perms = owner ? perms | OWNER_FLAG : perms; perms = moderator ? perms | MODERATOR_FLAG : perms; perms = fanclub ? perms | FANCLUB_FLAG : perms; perms = dkblue ? perms | DKBLUE_FLAG : perms; perms = ltblue ? perms | LTBLUE_FLAG : perms; perms = grey ? perms | GREY_FLAG : perms; return perms; }, msg2Perm: function (msg) { "use strict"; var perms = 0; perms = msg.user === cb.room_slug ? perms | OWNER_FLAG : perms; perms = msg.is_mod ? perms | MODERATOR_FLAG : perms; perms = msg.in_fanclub ? perms | FANCLUB_FLAG : perms; perms = msg.tipped_recently ? perms | DKBLUE_FLAG : perms; perms = msg.has_tokens ? perms | LTBLUE_FLAG : perms; perms = perms === 0 ? perms | GREY_FLAG : perms; return perms; }, name: "Top tippers today bot", // Useful globals wordBoundary: "(\\s|\\b)", // Data structures for tippers and settings tippers: {}, numberToShow: 3, interval: 5 * 60000, topNTippers: [], topNString: 'No tippers yet', topNCurrentCount: 0, changeThreshold: 0, lastNotice: new Date().getTime() } ; // CB app settings cb.settings_choices = [ {name: 'nShow', label: 'Number of top tippers to show', type: 'int', minValue: 1, maxValue: 10, defaultValue: 3, required: true}, {name: 'timer', label: 'Interval between displaying top tippers (minutes)', type: 'int', minValue: 1, defaultValue: 5, required: false} ]; // c: message color // m: the message text // user: username of message sender // f: message font // in_fanclub: is the user in the broadcasters fan club // has_tokens: does the user have at least 1 token // is_mod: is the user a moderator // tipped_recently: is the user a dark blue? // gender: m (male), f (female), s (shemale), or c (couple) cb.onMessage(function (msg) { "use strict"; return topn.onMessage(msg); }); cb.onTip(function (tip) { "use strict"; topn.onTip(tip); }); //cb.onEnter(function (user) { // "use strict"; // topn.onEnter(user); //}); // Main on message callback function topn.onMessage = function (msg) { "use strict"; var newMsg = topn.checkCommand(msg); if (newMsg) { return newMsg; } return msg; } ; topn.onTip = function (tip) { "use strict"; var amountTipped = parseInt(tip.amount, 10); var username = tip.from_user; if (!topn.tippers[username]) { topn.tippers[username] = {name: username, tips: 0, hightip: 0}; } if (!topn.tippers[username].tips) { topn.tippers[username].tips = 0; } if (!topn.tippers[username].hightip) { topn.tippers[username].hightip = 0; } topn.tippers[username].tips += amountTipped; topn.tippers[username].tiptime = new Date().getTime(); if (topn.tippers[username].tips > topn.changeThreshold) { topn.checkHighTippers(); } }; topn.checkHighTippers = function () { var ij = 0; var newHighTippers = objectToArray(topn.tippers); // newHighTippers.sort(dynamicSort('-tips')); newHighTippers.sort(dynamicSortMultiple('-tips','tiptime')); var topN = newHighTippers.slice(0, topn.numberToShow); topn.topNCurrentCount = topN.length; if (topn.topNCurrentCount == topn.numberToShow) { cb.log("ChangeThreshold changed: " + topn.changeThreshold); topn.changeThreshold = topN[topN.length - 1].tips; } // var top3Strings = []; // for (ij = 0; ij < topN.length; ij++) { // top3Strings[ij] = topN[ij].name + ": " + topN[ij].tips; // } topn.topNString = ''; for (ij = 0; ij < topN.length; ij++) { topn.topNString += "\n" + topN[ij].name + ": " + topN[ij].tips; } topn.showTopTippers(); }; topn.showTopTippers = function () { if (topn.topNCurrentCount > 0) { cb.chatNotice('Top ' + topn.numberToShow + ' tippers this session:' + topn.topNString); topn.lastNotice = new Date().getTime(); } }; topn.intervalPrinter = function () { var now = new Date().getTime(); var gap = now - topn.lastNotice; if (gap >= topn.interval) { // Last time we showed the list was more than the interval ago topn.showTopTippers(); cb.setTimeout(topn.intervalPrinter, topn.interval); } else { // Last time was more recent than the interval, so set new timer for the remaining time cb.setTimeout(topn.intervalPrinter, topn.interval - gap); } }; // c: message color // m: the message text // user: username of message sender // f: message font // in_fanclub: is the user in the broadcasters fan club // has_tokens: does the user have at least 1 token // is_mod: is the user a moderator // tipped_recently: is the user a dark blue? // gender: m (male), f (female), s (shemale), or c (couple) topn.usage = function (msg) { "use strict"; var u = msg.user; cb.chatNotice('Available commands:', u); var msgPerms = topn.msg2Perm(msg); for (var key in topn.commands) { if (topn.commands[key].perms & msgPerms) { // Command allowed for this user cb.chatNotice(key + topn.commands[key].helpText, u); } } }; topn.grabSettings = function () { "use strict"; if (cb.settings.timer) { topn.interval = cb.settings.timer * 60000; } if (cb.settings.nShow) { topn.numberToShow = cb.settings.nShow; } }; topn.wrapText = function (item, pre, suf) { "use strict"; return pre + item + suf; }; topn.init = function () { "use strict"; this.grabSettings(); this.registerCommand('/ttthelp', ' - show this help message', true, true, true, true, true, true, function (msg, commandParts) { topn.usage(msg); return msg; }); // this.registerCommand('/ttlist', ' - print list of all tippers', true, true, true, true, true, true, function (msg, commandParts) { // topn.printBannedItemsMessage(msg.user); // return msg; // // }); cb.chatNotice('The ' + topn.name + ' tracks all of today\'s tippers and lists the top ' + topn.numberToShow); cb.chatNotice('To see the available commands, type /ttthelp into the chat window', cb.room_slug); cb.chatNotice('The ' + topn.name + ' was written by asdfghjkl28. If you like the bot, you can thank him by tipping your favourite model.'); cb.setTimeout(topn.intervalPrinter, topn.interval); }; topn.init(); // Start Helper functions section function dynamicSort(property) { var sortOrder = 1; if (property[0] === "-") { sortOrder = -1; property = property.substr(1, property.length - 1); } var sortfunc = function (a, b) { if (typeof a[property] === "undefined") { if (typeof b[property] === "undefined") { // both undef return 0; } else { // b ok, a undef return -1; } } if (typeof b[property] === "undefined") { if (typeof a[property] === "undefined") { // both undef return 0; } else { // a ok, b undef return 1; } } var result = (a[property] < b[property]) ? -1 : (a[property] > b[property]) ? 1 : 0; return result * sortOrder; }; return sortfunc; } function dynamicSortMultiple() { /* * save the arguments object as it will be overwritten * note that arguments object is an array-like object * consisting of the names of the properties to sort by */ var props = arguments; return function (obj1, obj2) { var i = 0, result = 0, numberOfProperties = props.length; /* try getting a different result from 0 (equal) * as long as we have extra properties to compare */ while(result === 0 && i < numberOfProperties) { result = dynamicSort(props[i])(obj1, obj2); i++; } return result; } } function objectToArray(myObj) { var arr = []; for (var i in myObj) { if (myObj.hasOwnProperty(i)) { arr.push(myObj[i]); } } return arr; } /* Title: "Tip Menu Plus" bot Author: badbadbubba Version: 1.0.0c (01/14/2016) - Changed to double dash separator 1.0.1 Use data structure for separator graphic 1.0.2 Added new heart and smiley separator 1.0.3 (09/07/16) Improved error checking and reporting for missing double dash and missing menu items 1.0.4 (09/08/16) Added text character separators */ var HEART = '\u2665'; // ♥ BDIAMOND = '\u2666'; // ♦ BSTAR = '\u2605'; // ★ var tip_amt = 0; var separator_char = "| "; var msg; var MAXITEMS=10; var tipmenuprice = []; var tipmenuitem= []; var MAXSEP = 9; separators = [ {label:'Hearts',shortcut:':heart2'}, {label:'Glitter',shortcut:':pixelglitter'}, {label:'Flowers',shortcut:':tinyflower2'}, {label:'Bow',shortcut:':bluebow'}, {label:'Hearts2',shortcut:':pixelheart'}, {label:'Smiley',shortcut:':smile'}, {label:'Text Heart',shortcut:HEART}, {label:'Text Diamond',shortcut:BDIAMOND}, {label:'Text Star',shortcut:BSTAR}, ] cb.settings_choices = [ {name: 'sepchar', type: 'choice', choice1: 'Vertical Bar', choice2: 'Hearts', choice3:'Glitter',choice4:'Flowers',choice5:'Bow',choice6:'Hearts2',choice7:'Smiley',choice8:'Text Heart', choice9:'Text Diamond', choice10:'Text Star', defaultValue: 'Vertical Bar', label: "Separator character"}, {name:'item1', type:'str', label:'Item 1 (eg 10--flash tits)',}, {name:'item2', type:'str', required: false, label:'Item 2',}, {name:'item3', type:'str', required: false, label:'Item 3',}, {name:'item4', type:'str', required: false, label:'Item 4',}, {name:'item5', type:'str', required: false, label:'Item 5',}, {name:'item6', type:'str', required: false, label:'Item 6',}, {name:'item7', type:'str', required: false, label:'Item 7',}, {name:'item8', type:'str', required: false, label:'Item 8',}, {name:'item9', type:'str', required: false, label:'Item 9',}, {name:'item10', type:'str', required: false, label:'Item 10',}, {name:'noticecolor', type:'str', label:'Notice color (html code default red #FF0000)', defaultValue: '#FF0000'}, {name: 'chat_ad', type:'int', minValue: 1, maxValue: 999, defaultValue: 1, label: 'Delay in minutes between notice being displayed (minimum 1)'} ]; cb.onTip(function (tip) { tip_amt=parseInt(tip['amount']); for (var i = 1; i <= MAXITEMS; i++) { if (tip_amt == tipmenuprice[i]) { cb.sendNotice(tip['from_user'] + ' tipped for ' + tipmenuitem[i],'','',cb.settings['noticecolor'],'bold'); } } }); function chatAd() { if (msg!='Tip Menu: ') { cb.sendNotice(msg,'','',cb.settings['noticecolor'],'bold'); } cb.setTimeout(chatAd, (cb.settings.chat_ad * 60000)); } cb.setTimeout(chatAd, (cb.settings.chat_ad * 60000)); function init() { for (i=0;i<=MAXSEP-1;i++) { if (cb.settings['sepchar'] == separators[i].label) { separator_char = separators[i].shortcut + ' '; } } msg = 'Tip Menu: '; for (i=1;i<=MAXITEMS;i++) { var tmp; tmp=cb.settings['item' + i]; if (tmp) { var arr= tmp.split('--'); if (arr[1]===undefined) { cb.sendNotice('Error-You need two dashes to separate the tip amount and menu item for item no '+ i,'','',cb.settings['noticecolor'],'bold'); } else { var amt=parseInt(arr[0]); if (amt>0) { tipmenuprice[i]=amt; tipmenuitem[i]=arr[1]; if (i>=2) { msg += separator_char; } msg += arr[1] + '(' + amt + ') '; } } } } if (msg!= 'Tip Menu: ') { cb.sendNotice(msg,'','',cb.settings['noticecolor'],'bold'); } else { cb.sendNotice('Error-No menu items found','','',cb.settings['noticecolor'],'bold'); } } init(); var foreground = '#FFFFFF'; var fg_warn = '#FF0000'; var background = '#0629AC'; var txt_never = 'When I end it'; var txt_minutes = 'After x minutes'; var txt_votecount= 'After x votes'; var txt_wincount = 'When one option reaches x votes'; var opt_votes = [0, 0, 0, 0, 0]; var opt_labels = [cb.settings.opt1_label, cb.settings.opt2_label, cb.settings.opt3_label, cb.settings.opt4_label, cb.settings.opt5_label]; var opt_tokens = [cb.settings.opt1_tokens, cb.settings.opt2_tokens, cb.settings.opt3_tokens, cb.settings.opt4_tokens, cb.settings.opt5_tokens]; var mins_remain = cb.settings.poll_count; var votes_remain = cb.settings.poll_count; var poll_running = true; // bot options cb.settings_choices = [ {name: 'poll_title', type: 'str', minLength: 1, maxLength: 255, label: 'Poll Title'}, {name: 'board_interval', type: 'int', minValue: 1, default: 3, label: 'Board Display Interval (mins)'}, {name: 'poll_mode', type: 'choice', label: 'Poll ends...', choice1: txt_never, choice2: txt_minutes, choice3: txt_votecount, choice4: txt_wincount, defaultValue: txt_minutes}, {name: 'poll_count', type: 'int', minValue: 1, default: 15, label: '... Where x is ...'}, {name: 'opt1_label', type: 'str', minLength: 1, maxLength: 255, label: 'Option 1'}, {name: 'opt1_tokens', type: 'int', minValue: 1, default: 10, label: 'Option 1 tokens'}, {name: 'opt2_label', type: 'str', minLength: 1, maxLength: 255, label: 'Option 2'}, {name: 'opt2_tokens', type: 'int', minValue: 1, default: 11, label: 'Option 2 tokens'}, {name: 'opt3_label', type: 'str', minLength: 1, maxLength: 255, label: 'Option 3', required: false}, {name: 'opt3_tokens', type: 'int', minValue: 0, default: 0, label: 'Option 3 tokens', required: false}, {name: 'opt4_label', type: 'str', minLength: 1, maxLength: 255, label: 'Option 4', required: false}, {name: 'opt4_tokens', type: 'int', minValue: 0, default: 0, label: 'Option 4 tokens', required: false}, {name: 'opt5_label', type: 'str', minLength: 1, maxLength: 255, label: 'Option 5', required: false}, {name: 'opt5_tokens', type: 'int', minValue: 0, default: 0, label: 'Option 5 tokens', required: false} ]; function showBoard(user) { // var response1 = "Here's the Token Poll board:\n"; var response1 = '---------- Token Poll board' + ('' == user ? ' (sent to all)' : '') + ': ----------\n'; var response2 = cb.settings.poll_title; if (!poll_running) { return; } for (i=0; i<opt_tokens.length; i++) { if (0 != opt_tokens[i]) { response2 += "\n - " + opt_labels[i] + " ["+ opt_votes[i] + " votes]: " + opt_tokens[i] + " tokens"; } } var response3 = ''; switch (cb.settings.poll_mode) { case txt_minutes: response3 = mins_remain + ' minute' + (mins_remain > 1 ? 's' : '') + ' remaining to vote\n'; break; case txt_votecount: response3 = votes_remain + ' vote' + (votes_remain > 1 ? 's' : '') + ' remaining before poll closes\n'; break; case txt_wincount: response3 = 'First option to ' + cb.settings.poll_count + ' votes wins!\n'; break; } response3 += 'Simply tip the shown token amounts to register your vote. Type !poll at any time to see poll board.'; if (undefined == user) { // we were triggered by a timeout user = ''; cb.setTimeout(showBoard, cb.settings.board_interval*60*1000); } // cb.sendNotice(response1, user); cb.sendNotice(response1 + response2, user, background, foreground, 'bold'); // if (undefined != response3) { cb.sendNotice(response3, user, background, foreground); // } // cb.sendNotice(response4, user); } function sanitizeBoard() { for (i=1; i<opt_tokens.length; i++) { // start at option 2 if (0 != opt_tokens[i] && '' == opt_labels[i]) { // make sure no option labels are left blank cb.sendNotice("Token Poll Warning: Label for option " + (i+1) + " is blank -- removing from poll board!", cb.soom_slug, background, fg_warn, 'bold'); opt_tokens[i] = 0; continue; } for (j=0; j<i; j++) { // check all options before this one if (0 != opt_tokens[i] && opt_tokens[i] == opt_tokens[j]) { // make sure we don't have two options with the same token amounts cb.sendNotice("Token Poll Warning: Token amount for option " + (i+1) + " is not unique -- removing from poll board!", cb.soom_slug, background, fg_warn, 'bold'); opt_tokens[i] = 0; break; } else if (0 != opt_tokens[i] && opt_labels[i] == opt_labels[j]) { // make sure we don't have two options with the same label cb.sendNotice("Token Poll Warning: Label for option " + (i+1) + " is not unique -- removing from poll board!", cb.soom_slug, background, fg_warn, 'bold'); opt_tokens[i] = 0; break; } } } } function showWinner() { var options = []; for (i=0; i<opt_tokens.length; i++) { options[i] = i; } options.sort(function(a, b){return opt_votes[b]-opt_votes[a]}); var win_count = 1; for (i=1; i<opt_tokens.length; i++) { if (opt_votes[options[i]] != opt_votes[options[0]]) { break; } if (0 != opt_tokens[options[i]]) { win_count++; } } var response1 = '---------- Token Poll has ended! ----------\n'; var response2 = 'Winner' + (win_count > 1 ? 's (' + win_count + '-way tie)' : '') + ':'; for (i=0; i<win_count; i++) { if (opt_tokens[options[i]] != 0) { response2 += "\n - " + opt_labels[options[i]] + ": " + opt_votes[options[i]] + " votes"; } } cb.sendNotice(response1 + response2, '', background, foreground, 'bold'); } function checkPollEnd() { var _poll_running = poll_running; switch (cb.settings.poll_mode) { case txt_never: return; case txt_minutes: if (mins_remain < 1) { poll_running = false; } break; case txt_votecount: if (votes_remain < 1) { poll_running = false; } break; case txt_wincount: for (i=0; i<opt_tokens.length; i++) { if (opt_votes[i] >= cb.settings.poll_count) { poll_running = false; } } break; } if (_poll_running && !poll_running) { showWinner(); } } function tickTimer() { mins_remain--; checkPollEnd(); if (mins_remain > 0) { cb.setTimeout(tickTimer, 60*1000); } } cb.onMessage(function (m) { switch (m['m']) { case '!poll': // other users don't need to see this message var is_mod = (cb.room_slug == m['user'] || m['is_mod']); m['X-Spam'] = !is_mod; if (is_mod) { if (poll_running) { showBoard(''); } else { showWinner(); } } else { if (poll_running) { showBoard(m['user']); } else { showWinner(); } } break; case '!endpoll': if (cb.room_slug != m['user']) { break; } poll_running = false; showWinner(); break; } }); cb.onEnter(function (user) { cb.sendNotice("Hello " + user['user'] + ", the Token Poll app is currently active in this room.\nType !poll to see voting options.", user['user'], background, foreground); }); cb.onTip(function (tip) { var amount = parseInt(tip['amount']); if (!poll_running) { return; } for (i=0; i<opt_tokens.length; i++) { if (amount == opt_tokens[i]) { cb.sendNotice(tip['from_user'] + " has voted for " + opt_labels[i], '', background, foreground); opt_votes[i]++; if (txt_votecount == cb.settings.poll_mode) { votes_remain--; } checkPollEnd(); break; } } }); sanitizeBoard(); showBoard(); if (txt_minutes == cb.settings.poll_mode) { cb.setTimeout(tickTimer, 60*1000); }
© Copyright Chaturbate 2011- 2024. All Rights Reserved.