Advertisement
Guest User

Untitled

a guest
Aug 8th, 2016
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.95 KB | None | 0 0
  1. var Discord = require("discord.js");
  2. var mysql = require("mysql");
  3. var settings = require("./settings.json");
  4. var io = require('socket.io')(settings.port || 49001);
  5. var pokemon = require("./pokemon.json");
  6. var app = require("express")();
  7. var http = require("http").Server(app);
  8.  
  9. http.listen("8755", function() {
  10. console.log("Listening to port deine mutti");
  11. });
  12.  
  13. app.get("/", function(req, res) {
  14. res.end(JSON.stringify(pokelog));
  15. });
  16.  
  17. // Vars
  18. var debug = settings.debug;
  19. var invite_keys = settings.invite_keys; // Autojoin servers for which we have an invite key
  20. var pokelog = [];
  21.  
  22. // Allowed Discord channels
  23. var allowed_channels = settings.allowed_channels;
  24.  
  25. // Discord
  26. var bot = new Discord.Client({
  27. autoReconnect: true,
  28. disableEveryone: true
  29. });
  30.  
  31. // Start MySQL
  32. var conn = mysql.createConnection({
  33. host: settings.db_host,
  34. user: settings.db_user,
  35. password: settings.db_pass,
  36. database: settings.db_name
  37. });
  38.  
  39. if(debug) {
  40. console.log("Connecting to MySQL...");
  41. }
  42.  
  43. conn.connect(function(err) {
  44. // Stop on error. We need you, MySQL :( SOMEONE THINK OF THE SQL!
  45. if(err) {
  46. console.log('DB Error: ' + err.code);
  47. process.exit();
  48. }
  49.  
  50. // Let's go
  51. if(debug) {
  52. console.log("Connecting to Discord...");
  53. }
  54.  
  55. bot.login(settings.discord_user, settings.discord_pass, function(err, token) {
  56. if(err) {
  57. console.log("Discord error: " + err);
  58. process.exit();
  59. }
  60.  
  61. if(debug) {
  62. console.log("Connected to Discord. Token: " + token + ".");
  63. }
  64. });
  65. });
  66.  
  67. // Register MySQL events
  68. bot.on("message", function(message) {
  69. if(message.content === "ping") {
  70. bot.reply(message, "pong");
  71. }
  72.  
  73. if(allowed_channels.indexOf(message.channel.name) > -1) {
  74. // Clean up the "clean" content
  75. message.cleanContent = message.cleanContent.replace('\r', '').replace('\n', '');
  76.  
  77. // Parse
  78. var coord = parseCoordMessage(message.cleanContent);
  79.  
  80. // Valid coord message? And not yet in our log?
  81. if(coord[0] === true && !containsPoke(coord[1].name, coord[1].lat, coord[1].long)) {
  82. var poke = coord[1];
  83. var log = ' [+] Spotted: ' + poke.name;
  84.  
  85. // Optional IV
  86. if (poke.IV !== null) {
  87. log += '(' + poke.IV + '%)';
  88. }
  89.  
  90. log += ' at ' + poke.lat + ', ' + poke.long;
  91.  
  92. // Save to db
  93. var data = {
  94. name: poke.name,
  95. lat: poke.lat,
  96. lon: poke.long, // "long" is a MySQL reserved keyword :(
  97. IV: poke.IV
  98. };
  99.  
  100. // Emit to clients
  101. io.emit('poke', data);
  102.  
  103. // Add to history (newest at front)
  104. pokelog.unshift(data);
  105.  
  106. // Add remaining data (keep it hidden from sockets)
  107. data.channel = message.channel.name;
  108. data.userId = message.author.id;
  109. data.server = message.server.name;
  110.  
  111. if(pokelog.length > settings.max_poke_history) {
  112. pokelog.pop();
  113. }
  114.  
  115. // Save to DB
  116. conn.query("INSERT INTO spawns SET ?", data, function(err, result) {
  117. // Stop on error.
  118. if(err) {
  119. console.log('DB Error: ' + err.code);
  120. process.exit();
  121. }
  122. });
  123.  
  124. // Log to console
  125. console.log('From ' + message.channel.name + ':');
  126. console.log(log);
  127. }
  128. }
  129. });
  130.  
  131. bot.on("error", function(err) {
  132. console.log(err);
  133. });
  134.  
  135. bot.on("debug", function(e) {
  136. if(debug) {
  137. console.log(e);
  138. }
  139. });
  140.  
  141. bot.on("serverCreated", function(server) {
  142. console.log('[#] Joined: ' + server.name);
  143. });
  144.  
  145. bot.on("ready", function() {
  146. bot.userAgent = {
  147. url: '',
  148. version: '',
  149. full: ''
  150. };
  151.  
  152. if(debug) {
  153. console.log('Are we a bot? ' + bot.user.bot);
  154. console.log('User-Agent: ' + JSON.stringify(bot.userAgent));
  155. console.log('# of servers: ' + bot.servers.length);
  156. }
  157. "use strict";
  158. for(let i = 0; i < invite_keys; i++) {
  159. var key = invite_keys.pop();
  160. bot.joinServer(key, function() {});
  161. }
  162. });
  163.  
  164. // Register socket.io events
  165. io.on('connection', function(socket) {
  166. console.log('+++ Socket connected.');
  167.  
  168. // Say hi
  169. socket.emit('helo', pokelog);
  170. });
  171.  
  172.  
  173. /* Helpers */
  174.  
  175. // Does our pokelog contain this pokémon with exact same name, lat, lon?
  176. function containsPoke(name, lat, lon) {
  177. for(var i = 0; i < pokelog.length; i++) {
  178. var p = pokelog[i];
  179.  
  180. if(p.name === name && p.lat === lat && p.lon === lon) {
  181. return true;
  182. }
  183. }
  184.  
  185. return false;
  186. }
  187.  
  188. // Is this message one containing: a pokémon's name, a valid lat + a valid long (+ an optional IV)?
  189. // Returns [ true/false, pokeObject/null ]
  190. function parseCoordMessage(text) {
  191. // Don't waste time on these people
  192. if(isUserComplaining(text)) {
  193. return [ false, null ];
  194. }
  195.  
  196. // Remove tabs
  197. text = text.replace(/\t/g, '').trim();
  198.  
  199. // Split on spaces to parse each part individually
  200. var pieces = text.split(' ');
  201.  
  202. // Requirements
  203. var containsPokeName = false;
  204. var containsValidLat = false;
  205. var containsValidLong = false;
  206.  
  207. // Pokémon object we'll return
  208. var poke = {
  209. name: '',
  210. IV: null, // optional
  211. lat: '',
  212. long: ''
  213. };
  214.  
  215. // dotheloop.jpeg
  216. for(let i = 0; i < pieces.length; i++) {
  217. var p = pieces[i].trim();
  218. var _p = p.replace(',', ''); // Replace commas at the end/front of lat/long, careful for combined
  219.  
  220. if(!containsPokeName && isPokeName(p)) {
  221. containsPokeName = true;
  222. poke.name = p.trim();
  223. // Capitalize
  224. poke.name = poke.name.charAt(0).toUpperCase() + poke.name.slice(1).toLowerCase();
  225. } else if(!containsValidLat && isValidLatLong(_p)) {
  226. containsValidLat = true;
  227. poke.lat = _p;
  228. } else if(containsValidLat && !containsValidLong && isValidLatLong(_p)) {
  229. containsValidLong = true;
  230. poke.long = _p;
  231. } else if(!containsValidLat && !containsValidLong && isCombinedCoord(p)) { // p, not _p
  232. var coords = p.split(',');
  233.  
  234. containsValidLat = true;
  235. containsValidLong = true;
  236. poke.lat = coords[0];
  237. poke.long = coords[1];
  238. } else {
  239. // Only missing thing is the poke's IV
  240. poke.IV = parsePokeIV(text);
  241.  
  242. // If IV > 100, malformed message.
  243. if(poke.IV !== null && parseInt(poke.IV) > 100) {
  244. return [ false, null ];
  245. }
  246. }
  247. }
  248.  
  249. return [ containsPokeName && containsValidLat && containsValidLong, poke ];
  250. }
  251.  
  252. // Is this another guy confirming or complaining about the previous messages?
  253. // Everyone complaining, posting bot logs, or timestamped copy/pasted are removed.
  254. function isUserComplaining(str) {
  255. str = str.toLowerCase();
  256. return str.indexOf('fake') > -1 || str.indexOf('confirm') > -1 || str.indexOf('got it') > -1 ||
  257. str.indexOf('there is no') > -1 || str.indexOf('[') > -1 || str.indexOf(']') > -1;
  258. }
  259.  
  260. // Turn a string w/ numbers into only the numbers
  261. function removeNonNumbers(str) {
  262. return str.match(/\d+/g).join('');
  263. }
  264.  
  265. // Does this string contain the pokémon's IV?
  266. function parsePokeIV(str) {
  267. // Turn it into a better format
  268. str = str.toLowerCase();
  269.  
  270. // 1% to 100%
  271. var percentage = str.match(/[\d]{1,3}[%]/ig);
  272. // 0 IV to 100 IV (required whitespace in front [avoid 0.999 IV 20], optional space between)
  273. var xiv = str.match(/[ ][\d]{1,3}[ ]?iv/ig);
  274. // IV 0 to IV 100 (optional space)
  275. var ivx = str.match(/iv[ ]?[\d]{1,3}/ig);
  276. // 1% IV to 100% IV (CoordBot uses this, optional space)
  277. var percentageCombo = str.match(/[\d]{1,3}[%][ ]?iv/ig);
  278.  
  279. if (percentage) {
  280. return removeNonNumbers(percentage[0])
  281. } else if (xiv){
  282. return removeNonNumbers(xiv[0]);
  283. } else if (ivx) {
  284. return removeNonNumbers(ivx[0]);
  285. } else if (percentageCombo) {
  286. return removeNonNumbers(percentageCombo[0]);
  287. }
  288.  
  289. return null;
  290. }
  291.  
  292. // Check if a string is a combination of coords without space in-between.
  293. function isCombinedCoord(str) {
  294. return str.match(/^[-]?[\d]+[.][\d]+[,][-]?[\d]+[.][\d]+$/mg) != null
  295. }
  296.  
  297. // Is this a valid lat or long (format 29.335001809974 w/ any precision)
  298. function isValidLatLong(str) {
  299. return str.match(/^[-]?[\d]+[.][\d]+$/m) != null
  300. }
  301.  
  302. // Is this piece of text a Pokémon's valid name?
  303. function isPokeName(str) {
  304. for(let i = 0; i < pokemon.length; i++) {
  305. if(str.toLowerCase().trim() === pokemon[i].toLowerCase().trim()) {
  306. return true;
  307. }
  308. }
  309.  
  310. return false;
  311. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement