Advertisement
sparkychild

Untitled

Apr 28th, 2015
292
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. var sys = require('sys');
  2. var https = require('https');
  3. var url = require('url');
  4.  
  5. const ACTION_COOLDOWN = 3 * 1000;
  6. const FLOOD_MESSAGE_NUM = 5;
  7. const FLOOD_PER_MSG_MIN = 500; // this is the minimum time between messages for legitimate spam. It's used to determine what "flooding" is caused by lag
  8. const FLOOD_MESSAGE_TIME = 6 * 1000;
  9. const MIN_CAPS_LENGTH = 8;
  10. const MIN_CAPS_PROPORTION = 0.8;
  11.  
  12. settings = {};
  13. try {
  14.     settings = JSON.parse(fs.readFileSync('settings.json'));
  15.     if (!Object.keys(settings).length && settings !== {}) settings = {};
  16. } catch (e) {} // file doesn't exist [yet]
  17.  
  18. messages = {};
  19. try {
  20.     messages = JSON.parse(fs.readFileSync('messages.json'));
  21.     if (!Object.keys(messages).length && messages !== {}) messages = {};
  22. } catch (e) {} // file doesn't exist [yet]
  23.  
  24. quotes = {};
  25. try {
  26.     quotes = JSON.parse(fs.readFileSync('quotes.json'));
  27.     if (!Object.keys(quotes).length && quotes !== {}) quotes = {};
  28. } catch (e) {} // file doesn't exist [yet]
  29.  
  30. exports.parse = {
  31.     actionUrl: url.parse('https://play.pokemonshowdown.com/~~' + config.serverid + '/action.php'),
  32.     room: 'lobby',
  33.     'settings': settings,
  34.     'messages': messages,
  35.     'quotes': quotes,
  36.     chatData: {},
  37.     ranks: {},
  38.     msgQueue: [],
  39.  
  40.     data: function(data, connection) {
  41.         if (data.substr(0, 1) === 'a') {
  42.             data = JSON.parse(data.substr(1));
  43.             if (data instanceof Array) {
  44.                 for (var i = 0, len = data.length; i < len; i++) {
  45.                     this.splitMessage(data[i], connection);
  46.                 }
  47.             } else {
  48.                 this.splitMessage(data, connection);
  49.             }
  50.         }
  51.     },
  52.     splitMessage: function(message, connection) {
  53.         if (!message) return;
  54.  
  55.         var room = 'lobby';
  56.         if (message.indexOf('\n') < 0) return this.message(message, connection, room);
  57.  
  58.         var spl = message.split('\n');
  59.  
  60.         if (spl[0].charAt(0) === '>') {
  61.             if (spl[1].substr(1, 4) === 'init') return ok('joined ' + spl[2].substr(7));
  62.             if (spl[1].substr(1, 10) === 'tournament') return;
  63.             room = spl.shift().substr(1);
  64.         }
  65.  
  66.         for (var i = 0, len = spl.length; i < len; i++) {
  67.             this.message(spl[i], connection, room);
  68.         }
  69.     },
  70.     message: function(message, connection, room) {
  71.         var spl = message.split('|');
  72.         if (!spl[1]) {
  73.             if (/was promoted to Room (Driver|Moderator|Owner)/i.test(spl[0])) this.say(connection, room, 'Congratulations on the promotion ' + spl[0].substr(0, spl[0].indexOf("was") - 1) + '! ^-^');
  74.             if (/was promoted to Room Voice/i.test(spl[0])) this.say(connection, room, 'Welcome to THA, ' + spl[0].substr(0, spl[0].indexOf("was") - 1) + '! :3');
  75.             if (/was muted by (Flowerbless~|DanceBoTTT|BriyellaBot)/i.test(spl[0])) {
  76.                 this.say(connection, room, 'Sorry, bot moderation is being worked on... here ya go! ^-^');
  77.                 this.say(connection, room, '/unmute ' + spl[0].substr(0, spl[0].indexOf("was") - 1));
  78.             }
  79.             spl = spl[0].split('>');
  80.             if (spl[1]) this.room = spl[1];
  81.             return;
  82.         }
  83.  
  84.         switch (spl[1]) {
  85.             case 'challstr':
  86.                 info('received challstr, logging in...');
  87.                 var id = spl[2];
  88.                 var str = spl[3];
  89.  
  90.                 var requestOptions = {
  91.                     hostname: this.actionUrl.hostname,
  92.                     port: this.actionUrl.port,
  93.                     path: this.actionUrl.pathname,
  94.                     agent: false
  95.                 };
  96.  
  97.                 if (!config.pass) {
  98.                     requestOptions.method = 'GET';
  99.                     requestOptions.path += '?act=getassertion&userid=' + toId(config.nick) + '&challengekeyid=' + id + '&challenge=' + str;
  100.                 } else {
  101.                     requestOptions.method = 'POST';
  102.                     var data = 'act=login&name=' + config.nick + '&pass=' + config.pass + '&challengekeyid=' + id + '&challenge=' + str;
  103.                     requestOptions.headers = {
  104.                         'Content-Type': 'application/x-www-form-urlencoded',
  105.                         'Content-Length': data.length
  106.                     };
  107.                 }
  108.  
  109.                 var req = https.request(requestOptions, function(res) {
  110.                     res.setEncoding('utf8');
  111.                     var data = '';
  112.                     res.on('data', function(chunk) {
  113.                         data += chunk;
  114.                     });
  115.                     res.on('end', function() {
  116.                         if (data === ';') {
  117.                             error('failed to log in; nick is registered - invalid or no password given');
  118.                             process.exit(-1);
  119.                         }
  120.                         if (data.length < 50) {
  121.                             error('failed to log in: ' + data);
  122.                             process.exit(-1);
  123.                         }
  124.  
  125.                         if (data.indexOf('heavy load') !== -1) {
  126.                             error('the login server is under heavy load; trying again in one minute');
  127.                             setTimeout(function() {
  128.                                 this.message(message);
  129.                             }.bind(this), 60 * 1000);
  130.                             return;
  131.                         }
  132.  
  133.                         if (data.substr(0, 16) === '<!DOCTYPE html>') {
  134.                             error('Connection error 522; trying agian in one minute');
  135.                             setTimeout(function() {
  136.                                 this.message(message);
  137.                             }.bind(this), 60 * 1000);
  138.                             return;
  139.                         }
  140.  
  141.                         try {
  142.                             data = JSON.parse(data.substr(1));
  143.                             if (data.actionsuccess) {
  144.                                 data = data.assertion;
  145.                             } else {
  146.                                 error('could not log in; action was not successful: ' + JSON.stringify(data));
  147.                                 process.exit(-1);
  148.                             }
  149.                         } catch (e) {}
  150.                         send(connection, '|/trn ' + config.nick + ',0,' + data);
  151.                     }.bind(this));
  152.                 }.bind(this));
  153.  
  154.                 req.on('error', function(err) {
  155.                     error('login error: ' + sys.inspect(err));
  156.                 });
  157.  
  158.                 if (data) req.write(data);
  159.                 req.end();
  160.                 break;
  161.             case 'updateuser':
  162.                 if (spl[2] !== config.nick) return;
  163.  
  164.                 if (spl[3] !== '1') {
  165.                     error('failed to log in, still guest');
  166.                     process.exit(-1);
  167.                 }
  168.  
  169.                 ok('logged in as ' + spl[2] + '^-^');
  170.  
  171.                 this.msgQueue.push('|/blockchallenges');
  172.                 for (var i = 0, len = config.rooms.length; i < len; i++) {
  173.                     var room = toId(config.rooms[i]);
  174.                     if (room === 'lobby' && config.serverid === 'showdown') continue;
  175.                     this.msgQueue.push('|/join ' + room);
  176.                 }
  177.                 for (var i = 0, len = config.privaterooms.length; i < len; i++) {
  178.                     var room = toId(config.privaterooms[i]);
  179.                     if (room === 'lobby' && config.serverid === 'showdown') continue;
  180.                     this.msgQueue.push('|/join ' + room);
  181.                 }
  182.                 this.msgDequeue = setInterval(function() {
  183.                     var msg = this.msgQueue.shift();
  184.                     if (msg) return send(connection, msg);
  185.                     clearInterval(this.msgDequeue);
  186.                     this.msgDequeue = null;
  187.                 }.bind(this), 750);
  188.                 setInterval(this.cleanChatData.bind(this), 30 * 60 * 1000);
  189.                 break;
  190.             case 'c':
  191.                 var by = spl[2];
  192.                 spl = spl.splice(3).join('|');
  193.                 this.processChatData(toId(by), room, connection, spl);
  194.                 this.chatMessage(spl, by, room, connection);
  195.                 if (toId(by) === toId(config.nick) && ' +%@#~'.indexOf(by.charAt(0)) > -1) this.ranks[room] = by.charAt(0);
  196.                 break;
  197.             case 'c:':
  198.                 var by = spl[3];
  199.                 spl = spl.splice(4).join('|');
  200.                 this.processChatData(toId(by), room, connection, spl);
  201.                 this.chatMessage(spl, by, room, connection);
  202.                 if (toId(by) === toId(config.nick) && ' +%@#~'.indexOf(by.charAt(0)) > -1) this.ranks[room] = by.charAt(0);
  203.                 break;
  204.             case 'pm':
  205.                 var by = spl[2];
  206.                 spl = spl.splice(4).join('|');
  207.                 if (toId(by) === toId(config.nick) && ' +%@#~'.indexOf(by.charAt(0)) > -1) this.ranks[room] = by.charAt(0);
  208.                 this.chatMessage(spl, by, ',' + by, connection);
  209.                 break;
  210.             case 'N':
  211.                 var by = spl[2];
  212.                 this.updateSeen(spl[3], spl[1], toId(by));
  213.                 if (toId(by) !== toId(config.nick) || ' +%@&#~'.indexOf(by.charAt(0)) === -1) return;
  214.                 this.ranks[toId(this.room === '' ? 'lobby' : this.room)] = by.charAt(0);
  215.                 this.room = '';
  216.                 break;
  217.             case 'J':
  218.             case 'j':
  219.                 var by = spl[2];
  220.                 this.updateSeen(by, spl[1], (this.room === '' ? 'lobby' : this.room));
  221.                 if (toId(by) === toId(config.nick) && ' +%@&#~'.indexOf(by.charAt(0)) > -1) this.ranks[room] = by.charAt(0);
  222.                 if (['goddessbriyella', 'themansavage', 'omegaxis14'].indexOf(toId(by)) > -1) {
  223.                     this.say(connection, room, '/w ' + toId(by) + ', **#warn** __is a new command that has been made for Moderators and Room Owners. To use the command, **PM Slowbro Bot** with this syntax:__ #warn **[user]**, **[warn reason]**');
  224.                     this.say(connection, room, '/w ' + toId(by) + ', __This command is not to be abused and is for purely moderation purposes, thanks!^-^ ~Alpha-Kun__');
  225.                 }
  226.                 /*  if (toId(by) == 'goddessbriyella') this.say(connection, room, 'Haaii Briyella!^-^ I missed you ;~;');
  227.                 if (toId(by) == 'themansavage') this.say(connection, room, 'Hey Butch :3');
  228.                 if (toId(by) == 'omegaxis14') this.say(connection, room, '**om**e**g**a o3o hai :3');
  229.                 if (toId(by) == 'starbloom') this.say(connection, room, 'Haaii Kat^-^ How are you? :3');
  230.                 */
  231.                 break;
  232.             case 'l':
  233.             case 'L':
  234.                 var by = spl[2];
  235.                 this.updateSeen(by, spl[1], (this.room === '' ? 'lobby' : this.room));
  236.                 this.room = '';
  237.                 break;
  238.             case 'raw':
  239.                 if (/[3-9] ?days/i.test(spl[2])) this.say(connection, room, 'zarel pls ;-;');
  240.                 break;
  241.             case 'tournament':
  242.                 if (/end\|\{"results":\[\[/i.test(spl[2])) this.say(connection, room, 'Good job ' + spl[2].substr(spl[2].indexOf("results") + 12, spl[2].indexOf("\"\],\[")) + ' on winning the tournament!^~^');
  243.                 break;
  244.         }
  245.     },
  246.     chatMessage: function(message, by, room, connection) {
  247.         var now = Date.now();
  248.         var cmdrMessage = '["' + room + '|' + by + '|' + message + '"]';
  249.         message = message.trim();
  250.         // auto accept invitations to rooms
  251.         if (room.charAt(0) === ',' && message.substr(0, 8) === '/invite ' && this.hasRank(by, '%@&~') && !(config.serverid === 'showdown' && toId(message.substr(8)) === 'lobby')) {
  252.             this.say(connection, '', '/join ' + message.substr(8));
  253.         }
  254.         if (message.substr(0, config.commandcharacter.length) !== config.commandcharacter || toId(by) === toId(config.nick)) return;
  255.  
  256.         message = message.substr(config.commandcharacter.length);
  257.         var index = message.indexOf(' ');
  258.         var arg = '';
  259.         if (index > -1) {
  260.             var cmd = message.substr(0, index);
  261.             arg = message.substr(index + 1).trim();
  262.         } else {
  263.             var cmd = message;
  264.         }
  265.  
  266.         if (Commands[cmd]) {
  267.             var failsafe = 0;
  268.             while (typeof Commands[cmd] !== "function" && failsafe++ < 10) {
  269.                 cmd = Commands[cmd];
  270.             }
  271.             if (typeof Commands[cmd] === "function") {
  272.                 cmdr(cmdrMessage);
  273.                 Commands[cmd].call(this, arg, by, room, connection);
  274.             } else {
  275.                 error("invalid command type for " + cmd + ": " + (typeof Commands[cmd]));
  276.             }
  277.         }
  278.         /*      if (config.allowmute && this.hasRank(this.ranks[room] || ' ', '%@&#~') && config.whitelist.indexOf(user) === -1) {
  279.                     var useDefault = !(this.settings['modding'] && this.settings['modding'][room]);
  280.                 // moderation for abusing bot commands
  281.                 for (cmd in Commands)
  282.                     var isAbusing = (this.chatData.commandFlooding[room][cmd].times.length >= 6 && (time - this.chatData.commandFlooding[room][cmd].times[this.chatData.commandFlooding[room][cmd].times.length - 10]) < 30 * 1000
  283.                         && (time - this.chatData.commandFlooding[room][cmd].times[this.chatData.commandFlooding[room][cmd].times.length - 6]) > (6 * 30 * 1000));
  284.                     if ((useDefault || this.settings['modding'][room]['flooding'] !== 0) && isAbusing) this.say(connection, room, '/wall Please stop abusing bot commands, they have all been set to # until things settle down again.');
  285.                 } */
  286.     },
  287.     say: function(connection, room, text) {
  288.         if (room.charAt(0) !== ',') {
  289.             var str = (room !== 'lobby' ? room : '') + '|' + text;
  290.             send(connection, str);
  291.         } else {
  292.             room = room.substr(1);
  293.             var str = '|/pm ' + room + ', ' + text;
  294.             send(connection, str);
  295.         }
  296.     },
  297.     shorten: function(link) {
  298.         var BitlyAPI = require("node-bitlyapi");
  299.         var Bitly = new BitlyAPI({
  300.             client_id: "Something",
  301.             client_secret: "Something"
  302.         });
  303.         var self = this;
  304.         Bitly.setAccessToken("c8a15558cbf4a555391b974849d7684e211fb707");
  305.         Bitly.shortenLink(link, function(err, results) {
  306.             var resObject = eval("(" + results + ")");
  307.             console.log('url: ' + resObject.data.url);
  308.             bitLink += resObject.data.url;
  309.             console.log('bitLink: ' + bitLink);
  310.         });
  311.     },
  312.     hasRank: function(user, rank) {
  313.         var hasRank = (rank.split('').indexOf(user.charAt(0)) !== -1) || (config.excepts.indexOf(toId(user)) !== -1);
  314.         return hasRank;
  315.     },
  316.     canUse: function(cmd, room, user) {
  317.         var canUse = false;
  318.         var ranks = ' +%@&#~';
  319.         if (!this.settings[cmd] || !this.settings[cmd][room]) {
  320.             canUse = this.hasRank(user, ranks.substr(ranks.indexOf((cmd === 'autoban' || cmd === 'banword') ? '#' : config.defaultrank)));
  321.         } else if (this.settings[cmd][room] === true) {
  322.             canUse = true;
  323.         } else if (ranks.indexOf(this.settings[cmd][room]) > -1) {
  324.             canUse = this.hasRank(user, ranks.substr(ranks.indexOf(this.settings[cmd][room])));
  325.         }
  326.         return canUse;
  327.     },
  328.     sendMail: function(user, room) {
  329.         if (!this.messages || !this.messages[user]) return false;
  330.         if (this.messages[user]) {
  331.             console.log(user + ' has mail.');
  332.             return true;
  333.         }
  334.     },
  335.     processChatData: function(user, room, connection, msg, by) {
  336.         var botName = msg.toLowerCase().indexOf(toId(config.nick));
  337.  
  338.         if (toId(user.substr(1)) === toId(config.nick)) {
  339.             this.ranks[room] = user.charAt(0);
  340.             return;
  341.         }
  342.         var by = user;
  343.         user = toId(user);
  344.         var user = toId(by);
  345.  
  346.         if (!user || room.charAt(0) === ',') return;
  347.         room = toId(room);
  348.         msg = msg.trim().replace(/[ \u0000\u200B-\u200F]+/g, ' '); // removes extra spaces and null characters so messages that should trigger stretching do so
  349.  
  350.         this.updateSeen(user, 'c', room);
  351.         var now = Date.now();
  352.         if (!this.chatData[user]) this.chatData[user] = {
  353.             zeroTol: 0,
  354.             lastSeen: '',
  355.             seenAt: now
  356.         };
  357.  
  358.         var userData = this.chatData[user];
  359.         if (!this.chatData[user][room]) this.chatData[user][room] = {
  360.             times: [],
  361.             points: 0,
  362.             lastAction: 0
  363.         };
  364.  
  365.         var roomData = userData[room];
  366.         roomData.times.push(now);
  367.         this.chatData[user][room].times.push(now);
  368.  
  369.         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  370.         /////// Regex /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  371.         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  372.  
  373.         //Greetings & Farewells
  374.         if (/(good)? ?(night|nite) (everyone|guys|friends|all)/i.test(msg) && toId(config.nick) !== toId(by)) this.say(connection, room, 'Goodnight ' + by + '^-^');
  375.         if (/i(\'?m| am).*go.*to (bed|sleep)/i.test(msg) && toId(config.nick) !== toId(by)) this.say(connection, room, 'Goodnight ' + by + '^-^');
  376.     if (/i(\'?m| am).*go.*to (eat)/i.test(msg) && toId(config.nick) !== toId(by)) this.say(connection, room, 'omnomnom Have a nice meal ' + by + '^-^');
  377.         if (/(hey|hi|hello|ha+?i+) (everyone|guys|friends|all)/i.test(msg) && toId(config.nick) !== toId(by)) this.say(connection, room, 'Haaii ' + by + '^-^');
  378.         if (/(bye|g2g|gtg|ba+?i+) (everyone|guys|friends|all)/i.test(msg) && toId(config.nick) !== toId(by)) this.say(connection, room, 'Baaii ' + by + '~');
  379.         if (/g2g/i.test(msg) && toId(config.nick) !== toId(by)) this.say(connection, room, 'Baaii ' + by + '~');
  380.         if (/how(\'re)? (r|are|is) (u|you|chu)?/i.test(msg)) this.say(connection, room, 'I am good, how about you ' + by + '? :o');
  381.  
  382.  
  383.         //Miscellaneous
  384.         if (/(why are there )?so many bots( in here)?\??/i.test(msg)) this.say(connection, room, 'Sorry if I\'m intruding, I\'ll try and be as quiet as possible! >~<');
  385.         if (/(mashiro|mashy|goddess ?mashiro)/i.test(msg) && isAfk == true) this.say(connection, room, '/w ' + by + ', Mashiro-chan is AFK right now, leave a PM or check back in a bit, thanks^-^');
  386.         if (/(why are there )?so many goddess(es)?( in here)?\??/i.test(msg)) this.say(connection, room, 'Mashiro is just a Briyella wannabe o3o');
  387.         if (/(9[0-9]|100)% compatible/i.test(msg)) {
  388.             var rand = ~~(2 * Math.random()) + 1;
  389.             if (rand == 1) this.say(connection, room, '__it was meant to be :O__');
  390.             if (rand == 2) this.say(connection, room, '/me plays wedding music');
  391.         }
  392.         if (/(1| )[0-9]% compatible/i.test(msg)) this.say(connection, room, '__rip ;-;__');
  393.         if (/I(\'?m| am) back/i.test(msg)) this.say(connection, room, 'Hi back, I am Slowbro Bot o3o');
  394.         if (/I(\'?m| am) tired/i.test(msg)) this.say(connection, room, 'Hi tired, I am Slowbro Bot o3o');
  395.         if (/I(\'?m| am) hungry/i.test(msg)) this.say(connection, room, 'Hi hungry, I am Slowbro Bot o3o');
  396.         if (/(cut|kick|punch(es)?|hit|hurt|slap|stab)s? (goddess)? ?mash(y|iro)/i.test(msg)) this.say(connection, room, 'D-don\'t hurt my creator..!! >~<');
  397.         if (/\brip\b/i.test(msg) && toId(by) !== toId('mashibot')) {
  398.             var rand = ~~(13 * Math.random()) + 1;
  399.             if (rand == 1) this.say(connection, room, '__rip in pepperoni ;-;__');
  400.             if (rand == 2) this.say(connection, room, '__rip in pieces ;-;__');
  401.             if (rand == 3) this.say(connection, room, '__rip in pepsi ;-;__');
  402.             if (rand == 4) this.say(connection, room, '__rip in PixelMoniac ;-;__');
  403.             if (rand == 5) this.say(connection, room, '__rip in pizza ;-;__');
  404.             if (rand == 6) this.say(connection, room, '__rip in pringles ;-;__');
  405.             if (rand == 7) this.say(connection, room, '__rip in pretzels ;-;__');
  406.             if (rand == 8) this.say(connection, room, '__rip in pistachios ;-;__');
  407.             if (rand == 9) this.say(connection, room, '__rip in pasta ;-;__');
  408.             if (rand == 10) this.say(connection, room, '__rip in peaches ;-;__');
  409.             if (rand == 11) this.say(connection, room, '__rip in pumpkins ;-;__');
  410.             if (rand == 12) this.say(connection, room, '__rip in papayas ;-;__');
  411.             if (rand == 13) this.say(connection, room, '__rip in potatoes ;-;__');
  412.         }
  413.         if (/\bej\b/i.test(msg) && toId(by) !== toId('mashibot')) {
  414.             var rand = ~~(13 * Math.random()) + 1;
  415.             if (rand == 1) this.say(connection, room, '__andy saks__');
  416.             if (rand == 2) this.say(connection, room, '__pindakaas__');
  417.             if (rand == 3) this.say(connection, room, '__IK WIL KOEKJES__');
  418.             if (rand == 4) this.say(connection, room, '__slooowbrooo__');
  419.             if (rand == 5) this.say(connection, room, '__plalalalala__');
  420.             if (rand == 6) this.say(connection, room, '__lolololol__');
  421.             if (rand == 7) this.say(connection, room, '__keukenrol__');
  422.             if (rand == 8) this.say(connection, room, '__banaan__');
  423.             if (rand == 9) this.say(connection, room, '__ontbijtkoek__');
  424.             if (rand == 10) this.say(connection, room, '__I like turltes__');
  425.         }
  426.         //      if (/(rekt|burn)/i.test(msg)) this.say(connection, room, '!data Rawst Berry');
  427.  
  428.         //Favorite Pokemon
  429.         if (/what(\'s| is)? (goddess ?)?mash(i|y|iro)?(chan|bot)?\'?s? fav(e|ou?rite)? poke(mon)?\??/i.test(msg)) this.say(connection, room, '!data Ninetales');
  430.         if (/what(\'s| is)? (goddess ?)?bri(yella)?\'?s? fav(e|ou?rite)? poke(mon)?\??/i.test(msg)) this.say(connection, room, '!data Vespiquen');
  431.         if (/what(\'s| is)? omega-?(xis14)?\'?s? fav(e|ou?rite)? poke(mon)?\??/i.test(msg)) this.say(connection, room, '!data Mew');
  432.         if (/what(\'s| is)? (the|butch) ?mansavage\'?s? fav(e|ou?rite)? poke(mon)?\??/i.test(msg) || /what(\'s| is)? butch\'?s? fav(ou?rite)? poke(mon)?\??/i.test(msg)) this.say(connection, room, '!data Rhyperior');
  433.  
  434.         //League Names
  435.         if (/(does)? ?(some|any)(one|1|body) play (league( of legends)?|lol)/i.test(msg)) this.say(connection, room, 'Add Mashiro-chan on League if you want to play: LeInfiniti');
  436.         if (/what(\'s| is)? jess(ilina| league)?\'?s? (league( of legends)?|lol)( name)?/i.test(msg)) this.say(connection, room, 'Jess\'s League name is: namegohere');
  437.  
  438.         //osu! room
  439.         if (/(pronounce|say) osu/i.test(msg)) {
  440.             if (room !== 'osu') return false;
  441.             this.say(connection, room, 'osu! is pronounced like \"os\", not \"osu\". This is because when a \'u\' follows an \'s\' in Japanese, the \'u\' is silent.');
  442.         }
  443.         if (/what(\'s| is)? osu/i.test(msg)) {
  444.             if (room !== 'osu') return false;
  445.             this.say(connection, room, 'osu! is a Japanese rhythm game where the player hits notes in time with the beat of the music. There are 5 different game modes, the most popular being standard osu! and osu! mania.');
  446.         }
  447.  
  448.         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  449.         /////// /me Regex /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  450.         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  451.  
  452. if (msg.toLowerCase().indexOf(toId(config.nick)) > -1 && toId(by) !== toId(config.nick)) {
  453.             if (/^\/me/i.test(msg)) {
  454.                 if (/(pet|stroke)s?/i.test(msg)) {
  455.                     this.say(connection, room, '/me purrs~');
  456.                 }
  457.                 if (/licks?/i.test(msg)) {
  458.                   this.say(connection, room, '/me squirms ;~;');
  459.                 }
  460.                 if (/(kiss(es)?|kissu)/i.test(msg)) {
  461.                     this.say(connection, room, '/me blushes deeply');
  462.                     this.say(connection, room, 'o////o');
  463.                 }
  464.                 if (/(eat|nom|nibble)s?/i.test(msg)) {
  465.                     this.say(connection, room, 'nuuu dun eat me ;~;');
  466.                     this.say(connection, room, '/me hides');
  467.                 }
  468.                 if (/(hit|stab|punch|kick|hurt)s?/i.test(msg)) {
  469.                     this.say(connection, room, '/me cries in pain ;-;');
  470.                 }
  471.                 if (/(hug|glomp|squeeze)s?/i.test(msg)) {
  472.                     this.say(connection, room, '/me squee~ :3');
  473.                 }
  474.                 if (/(cuddle|snuggle)s?/i.test(msg)) {
  475.                     this.say(connection, room, '/me cuddles ' + by + ' back warmly<3');
  476.                 }
  477.                 if (/pokes?/i.test(msg)) {
  478.                     this.say(connection, room, 'oww!! >~<');
  479.                 }
  480.                 if (/(gives? food|a cookie)/i.test(msg)) {
  481.                     this.say(connection, room, '/me noms :3');
  482.                 }
  483.                 if (/(tickle)s?/i.test(msg)) {
  484.                     this.say(connection, room, '/me giggles and squirms');
  485.                     this.say(connection, room, 'Staaahhhpp!! ;~;');
  486.                 }
  487.             }
  488.         }
  489.  
  490.         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  491.         /////// Moderation Detection //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  492.         ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////    
  493.  
  494.         /*          // this deals with punishing rulebreakers, but note that the bot can't think, so it might make mistakes
  495.                 if (config.allowmute && this.hasRank(this.ranks[room] || ' ', '%@&#~') && config.whitelist.indexOf(user) === -1) {
  496.                     var useDefault = !(this.settings['modding'] && this.settings['modding'][room]);
  497.                     var pointVal = 0;
  498.                     var muteMessage = '';
  499.                     var warnMessage = '';
  500.                    
  501.                     // moderation for flooding (more than x lines in y seconds)
  502.                     var times = roomData.times;
  503.             var timesLen = times.length;
  504.             var isFlooding = (timesLen >= FLOOD_MESSAGE_NUM && (now - times[timesLen - FLOOD_MESSAGE_NUM]) < FLOOD_MESSAGE_TIME &&
  505.                 (now - times[timesLen - FLOOD_MESSAGE_NUM]) > (FLOOD_PER_MSG_MIN * FLOOD_MESSAGE_NUM));
  506.             if ((useDefault || !('flooding' in modSettings)) && isFlooding) {
  507.                 if (pointVal < 2) {
  508.                     pointVal = 2;
  509.                     muteMessage = ', Please stop flooding the chat! ;~;';
  510.                         }
  511.                     } */
  512.  
  513.         // moderation for caps (over x% of the letters in a line of y characters are capital)
  514.         /*  var capsMatch = msg.replace(/[^A-Za-z]/g, '').match(/[A-Z]/g);
  515.             if ((useDefault || !('caps' in modSettings)) && capsMatch && toId(msg).length > MIN_CAPS_LENGTH && (capsMatch.length >= ~~(toId(msg).length * MIN_CAPS_PROPORTION))) {
  516.                 if (pointVal < 1) {
  517.                     pointVal = 1;
  518.                     muteMessage = ', Don\'t be so loud wtf ;-;';
  519.                 }
  520.             }
  521.             // moderation for stretching (over x consecutive characters in the message are the same)
  522.             var stretchMatch = /(.)\1{7,}/gi.test(msg) || /(..+)\1{4,}/gi.test(msg); // matches the same character (or group of characters) 8 (or 5) or more times in a row
  523.             if ((useDefault || !('stretching' in modSettings)) && stretchMatch) {
  524.                 if (pointVal < 1) {
  525.                     pointVal = 1;
  526.                     muteMessage = ', This isn\'t yoga, no streching please ._.';
  527.                 }
  528.             }
  529.  
  530.             if (pointVal > 0 && !(now - this.chatData[user][room].lastAction < ACTION_COOLDOWN)) {
  531.                 var cmd = 'mute';
  532.                 // defaults to the next punishment in config.punishVals instead of repeating the same action (so a second warn-worthy
  533.                 // offence would result in a mute instead of a warn, and the third an hourmute, etc)
  534.                 if (this.chatData[user][room].points >= pointVal && pointVal < 4) {
  535.                     this.chatData[user][room].points++;
  536.                     cmd = config.punishvals[this.chatData[user][room].points] || cmd;
  537.                 } else { // if the action hasn't been done before (is worth more points) it will be the one picked
  538.                     cmd = config.punishvals[pointVal] || cmd;
  539.                     this.chatData[user][room].points = pointVal; // next action will be one level higher than this one (in most cases)
  540.                 }
  541.                 if (config.privaterooms.indexOf(room) >= 0 && cmd === 'warn') cmd = 'mute'; // can't warn in private rooms
  542.                 // if the bot has % and not @, it will default to hourmuting as its highest level of punishment instead of roombanning
  543.                 if (this.chatData[user][room].points >= 4 && !this.hasRank(this.ranks[room] || ' ', '@&#~')) cmd = 'hourmute';
  544.                 if (this.chatData[user].zeroTol > 4) { // if zero tolerance users break a rule they get an instant roomban or hourmute
  545.                     muteMessage = ', Automated response: zero tolerance user';
  546.                     cmd = this.hasRank(this.ranks[room] || ' ', '@&#~') ? 'roomban' : 'hourmute';
  547.                 }
  548.                 if (this.chatData[user][room].points >= 2) this.chatData[user].zeroTol++; // getting muted or higher increases your zero tolerance level (warns do not)
  549.                 this.chatData[user][room].lastAction = now;
  550.                 if (this.chatData[user][room].points <= 2) this.say(connection, room, user + ', ' + warnMessage);
  551.                 if (this.chatData[user][room].points >= 3) this.say(connection, room, '/' + cmd + ' ' + user + muteMessage);
  552.             }
  553.          } */
  554.     },
  555.     cleanChatData: function() {
  556.  
  557.         var chatData = this.chatData;
  558.         for (var user in chatData) {
  559.             for (var room in chatData[user]) {
  560.                 var roomData = chatData[user][room];
  561.                 if (!Object.isObject(roomData)) continue;
  562.  
  563.                 if (!roomData.times || !roomData.times.length) {
  564.                     delete chatData[user][room];
  565.                     continue;
  566.                 }
  567.                 var newTimes = [];
  568.                 var now = Date.now();
  569.                 var times = roomData.times;
  570.                 for (var i = 0, len = times.length; i < len; i++) {
  571.                     if (now - times[i] < 5 * 1000) newTimes.push(times[i]);
  572.                 }
  573.                 newTimes.sort(function(a, b) {
  574.                     return a - b;
  575.                 });
  576.                 roomData.times = newTimes;
  577.                 if (roomData.points > 0 && roomData.points < 4) roomData.points--;
  578.             }
  579.         }
  580.     },
  581.     updateSeen: function(user, type, detail) {
  582.         if (type !== 'n' && config.rooms.indexOf(detail) === -1 || config.privaterooms.indexOf(toId(detail)) > -1) return;
  583.         var now = Date.now();
  584.         if (!this.chatData[user]) this.chatData[user] = {
  585.             zeroTol: 0,
  586.             lastSeen: '',
  587.             seenAt: now
  588.         };
  589.         if (!detail) return;
  590.         var userData = this.chatData[user];
  591.         var msg = '';
  592.         switch (type) {
  593.             case 'j':
  594.             case 'J':
  595.                 msg += 'joining ';
  596.                 break;
  597.             case 'l':
  598.             case 'L':
  599.                 msg += 'leaving ';
  600.                 break;
  601.             case 'c':
  602.             case 'c:':
  603.                 msg += 'chatting in ';
  604.                 break;
  605.             case 'N':
  606.                 msg += 'changing nick to ';
  607.                 if (detail.charAt(0) !== ' ') detail = detail.substr(1);
  608.                 break;
  609.         }
  610.         msg += detail.trim() + '.';
  611.         userData.lastSeen = msg;
  612.         userData.seenAt = now;
  613.     },
  614.     getTimeAgo: function(time) {
  615.         time = ~~((Date.now() - time) / 1000);
  616.  
  617.         var seconds = time % 60;
  618.         var times = [];
  619.         if (seconds) times.push(seconds + (seconds === 1 ? ' second' : ' seconds'));
  620.         if (time >= 60) {
  621.             time = ~~((time - seconds) / 60);
  622.             var minutes = time % 60;
  623.             if (minutes) times.unshift(minutes + (minutes === 1 ? ' minute' : ' minutes'));
  624.             if (time >= 60) {
  625.                 time = ~~((time - minutes) / 60);
  626.                 hours = time % 24;
  627.                 if (hours) times.unshift(hours + (hours === 1 ? ' hour' : ' hours'));
  628.                 if (time >= 24) {
  629.                     days = ~~((time - hours) / 24);
  630.                     if (days) times.unshift(days + (days === 1 ? ' day' : ' days'));
  631.                 }
  632.             }
  633.         }
  634.         if (!times.length) return '0 seconds';
  635.         return times.join(', ');
  636.     },
  637.     writeSettings: (function() {
  638.         var writing = false;
  639.         var writePending = false; // whether or not a new write is pending
  640.         var finishWriting = function() {
  641.             writing = false;
  642.             if (writePending) {
  643.                 writePending = false;
  644.                 this.writeSettings();
  645.             }
  646.         };
  647.         return function() {
  648.             if (writing) {
  649.                 writePending = true;
  650.                 return;
  651.             }
  652.             writing = true;
  653.             var data = JSON.stringify(this.settings);
  654.             fs.writeFile('settings.json.0', data, function() {
  655.                 // rename is atomic on POSIX, but will throw an error on Windows
  656.                 fs.rename('settings.json.0', 'settings.json', function(err) {
  657.                     if (err) {
  658.                         // This should only happen on Windows.
  659.                         fs.writeFile('settings.json', data, finishWriting);
  660.                         return;
  661.                     }
  662.                     finishWriting();
  663.                 });
  664.             });
  665.         };
  666.     })(),
  667.     writeMessages: (function() {
  668.         var writing = false;
  669.         var writePending = false; // whether or not a new write is pending
  670.         var finishWriting = function() {
  671.             writing = false;
  672.             if (writePending) {
  673.                 writePending = false;
  674.                 this.writeMessages();
  675.             }
  676.         };
  677.         return function() {
  678.             if (writing) {
  679.                 writePending = true;
  680.                 return;
  681.  
  682.             }
  683.             writing = true;
  684.             var data = JSON.stringify(this.messages);
  685.             fs.writeFile('messages.json.0', data, function() {
  686.                 // rename is atomic on POSIX, but will throw an error on Windows
  687.                 fs.rename('messages.json.0', 'messages.json', function(err) {
  688.                     if (err) {
  689.                         // This should only happen on Windows.
  690.                         fs.writeFile('messages.json', data, finishWriting);
  691.                         return;
  692.                     }
  693.                     finishWriting();
  694.                 });
  695.             });
  696.         };
  697.     })(),
  698.     writeQuotes: (function() {
  699.         var writing = false;
  700.         var writePending = false; // whether or not a new write is pending
  701.         var finishWriting = function() {
  702.             writing = false;
  703.             if (writePending) {
  704.                 writePending = false;
  705.                 this.writeQuotes();
  706.             }
  707.         };
  708.         return function() {
  709.             if (writing) {
  710.                 writePending = true;
  711.                 return;
  712.  
  713.             }
  714.             writing = true;
  715.             var data = JSON.stringify(this.quotes);
  716.             fs.writeFile('quotes.json.0', data, function() {
  717.                 // rename is atomic on POSIX, but will throw an error on Windows
  718.                 fs.rename('quotes.json.0', 'quotes.json', function(err) {
  719.                     if (err) {
  720.                         // This should only happen on Windows.
  721.                         fs.writeFile('quotes.json', data, finishWriting);
  722.                         return;
  723.                     }
  724.                     finishWriting();
  725.                 });
  726.             });
  727.         };
  728.     })(),
  729.     uncacheTree: function(root) {
  730.         var uncache = [require.resolve(root)];
  731.         do {
  732.             var newuncache = [];
  733.             for (var i = 0; i < uncache.length; ++i) {
  734.                 if (require.cache[uncache[i]]) {
  735.                     newuncache.push.apply(newuncache,
  736.                         require.cache[uncache[i]].children.map(function(module) {
  737.                             return module.filename;
  738.                         })
  739.                     );
  740.                     delete require.cache[uncache[i]];
  741.                 }
  742.             }
  743.             uncache = newuncache;
  744.         } while (uncache.length > 0);
  745.     },
  746.     getDocMeta: function(id, callback) {
  747.         https.get('https://www.googleapis.com/drive/v2/files/' + id + '?key=' + config.googleapikey, function(res) {
  748.             var data = '';
  749.             res.on('data', function(part) {
  750.                 data += part;
  751.             });
  752.             res.on('end', function(end) {
  753.                 var json = JSON.parse(data);
  754.                 if (json) {
  755.                     callback(null, json);
  756.                 } else {
  757.                     callback('Invalid response', data);
  758.                 }
  759.             });
  760.         });
  761.     },
  762.     getDocCsv: function(meta, callback) {
  763.         https.get('https://docs.google.com/spreadsheet/pub?key=' + meta.id + '&output=csv', function(res) {
  764.             var data = '';
  765.             res.on('data', function(part) {
  766.                 data += part;
  767.             });
  768.             res.on('end', function(end) {
  769.                 callback(data);
  770.             });
  771.         });
  772.     }
  773. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement