Advertisement
Guest User

Untitled

a guest
Jan 13th, 2016
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 11.72 KB | None | 0 0
  1.  
  2.  
  3. var fs = require('fs');
  4. var path = require('path');
  5. var https = require('https');
  6. var parseString = require('xml2js').parseString;
  7. var platform = process.platform;
  8.  
  9. var jid = "watchlist.bot@eneticum.de";
  10. var password = "logbotpw";
  11. var room = "lobby@conference.eneticum.de";
  12. var resource = "/Watchlist Bot";
  13.  
  14. var Client = require("node-xmpp-client");
  15.  
  16. var client = new Client({
  17. jid: jid,
  18. password: password
  19. });
  20.  
  21. client.on('online', function() {
  22. console.log("online");
  23. client.send(new Client.Stanza("presence", { from: jid, to: room + resource }));
  24. init();
  25. });
  26.  
  27. process.on('SIGINT', function(code) {
  28. console.log('leaving the room')
  29. var stanza = new Client.Stanza('presence', { from: jid, to: room, type: 'unavailable' })
  30. client.send(stanza)
  31.  
  32. setTimeout(function() {
  33. process.exit()
  34. }, 1000);
  35. });
  36.  
  37. var reading = false;
  38. var watcher;
  39. var files = [];
  40. var curFile = "";
  41.  
  42. var characters = [];
  43.  
  44. var logpath;
  45. function init () {
  46. logpath = process.argv[2];
  47. startDirWatcher(logpath);
  48. }
  49.  
  50. function startDirWatcher (fp) {
  51. if(watcher) watcher.close();
  52. if(!fp || fp == "") return;
  53. watcher = fs.watch(fp, function (event, filename) {
  54. if(curFile != filename) console.log(filename);
  55.  
  56. if(curFile != filename) files[fp + path.sep + filename] = { row: 0, off: 0 };
  57.  
  58. curFile = filename;
  59. parseFile(fp + path.sep + filename, filename);
  60. });
  61. }
  62.  
  63. function parseFile (f, fn) {
  64. var cnk = "";
  65. var off = 0;
  66. if(reading) return;
  67. reading = true;
  68. fs.createReadStream(f, { start: files[f].off }).on("data", function (chunk) { off += chunk.length; cnk += chunk.toString("utf8"); }).on("end", function () {
  69. files[f].off += off;
  70. reading = false;
  71. var data = cnk.split("\n");
  72. for(var i = 0; i < data.length; i++) {
  73. if(data[i].indexOf("OnContactLoggedOn") >= 0 || data[i].indexOf("OnContactLoggedOff") >= 0) {
  74. var type = data[i].indexOf("OnContactLoggedOn") >= 0 ? "logon" : "logoff";
  75.  
  76. var m = data[i].match(/<MarshalStream '(.+?)'>|<MarshalStream "(.+?)">/);
  77. if(m && m.length > 1) {
  78. STORAGE = [];
  79. eval('var n = "' + m[m[1] ? 1 : 2].replace(/"/g, "\\\"") + ' ";');
  80. dat = n.replace(/\\x/g, "").hexEncode();
  81. ind = 2 + (4 * 2);
  82. var tmpo = processSnip();
  83. var di = tmpo[1][1][0];
  84. getCharacterSheet(di, function (data) {
  85. console.log(data.characterName + " " + type);
  86. sendNotification(data.characterID, data.characterName, type);
  87. characters[data.characterID] = { state: type, data: data, id: data.characterID, name: data.characterName };
  88. });
  89. }
  90. }
  91. }
  92. });
  93. }
  94.  
  95. function sendNotification (id, name, state) {
  96. client.send(new Client.Stanza("message", { to: room, type: "groupchat" })
  97. .c("body")
  98. .t(("@name @state (@url)")
  99. .replace(new RegExp("@name", "g"), name)
  100. .replace(new RegExp("@state", "g"), "just logged " + state.substr(3))
  101. .replace(new RegExp("@url","g"), "https://zkillboard.com/character/" + id + "/" )
  102. )
  103. .up()
  104. .up()
  105. .c("html", { xmlns: 'http://jabber.org/protocol/xhtml-im' })
  106. .c("body", { xmlns: 'http://www.w3.org/1999/xhtml' })
  107. .c("a", { href: "https://zkillboard.com/character/" + id + "/" })
  108. .t(name)
  109. .up()
  110. .up()
  111. .t(" just logged " + state.substr(3))
  112. );
  113.  
  114.  
  115.  
  116. //var stanza = "<message type='groupchat' to='lobby@conference.eneticum.de'><body>@name @state (@url)</body><html xmlns='http://jabber.org/protocol/xhtml-im'><body xmlns='http://www.w3.org/1999/xhtml'><a href='@url'>@name</a> @state</body></html></message>";
  117. //client.methodCall("send_stanza_c2s", [{ user: "admin", server: "eneticum.de", password: "hase2001", admin: true }, { user: "admin", host: "eneticum.de", resource: "LogBot", stanza: stanza.replace(new RegExp("@name", "g"), data.characterName).replace(new RegExp("@state", "g"), "just logged " + type.substr(3)).replace(new RegExp("@url","g"), "https://zkillboard.com/character/" + di + "/" ) }], function (err, val) { console.log(err, val); });
  118. }
  119.  
  120. // stuff
  121.  
  122. var PROTOCOL_ID = 0x7e;
  123. var TYPE = {
  124. NONE: 0x01, // 1: None
  125. GLOBAL: 0x02, // 2: usually a type, function or class object, but just the name,
  126. // so it has to exist for this to decode properly.
  127. INT64: 0x03, // 3: 8 byte signed int
  128. INT32: 0x04, // 4: 4 byte signed int
  129. INT16: 0x05, // 5: 2 byte signed int
  130. INT8: 0x06, // 6: 1 byte signed int
  131. MINUSONE: 0x07, // 7: the value of -1
  132. ZERO: 0x08, // 8: the value of 0
  133. ONE: 0x09, // 9: the value of 1
  134. FLOAT: 0x0a, // 10: 8 byte float
  135. FLOAT0: 0x0b, // 11: the value of 0.0
  136. //COMPLEX: 0x0c, // 12: (not used, complex number)
  137. STRINGL: 0x0d, // 13: string, longer than 255 characters using normal count*
  138. STRING0: 0x0e, // 14: string, empty
  139. STRING1: 0x0f, // 15: string, 1 character
  140. STRING: 0x10, // 16: string, next byte is 0x00 - 0xff being the count.
  141. STRINGR: 0x11, // 17: string, reference to line in strings.txt (stringTable)
  142. UNICODE: 0x12, // 18: unicode string, next byte is count*
  143. BUFFER: 0x13, // 19: buffer object... hmmm
  144. TUPLE: 0x14, // 20: tuple, next byte is count*
  145. LIST: 0x15, // 21: list, next byte is count*
  146. DICT: 0x16, // 22: dict, next byte is count*
  147. INSTANCE: 0x17, // 23: class instance, name of the class follows (as string, probably)
  148. BLUE: 0x18, // 24: blue object.
  149. CALLBACK: 0x19, // 25: callback
  150. //PICKLE: 0x1a, // 26: (not used, old pickle method)
  151. REF: 0x1b, // 27: shared object reference
  152. CHECKSUM: 0x1c, // 28: checksum of rest of stream
  153. COMPRESS: 0x1d, // 29: (not used)
  154. //UNUSED: 0x1e, // 30: (not used)
  155. TRUE: 0x1f, // 31: True
  156. FALSE: 0x20, // 32: False
  157. PICKLER: 0x21, // 33: standard pickle of undetermined size
  158. REDUCE: 0x22, // 34: reduce protocol
  159. NEWOBJ: 0x23, // 35: new style class object
  160. TUPLE0: 0x24, // 36: tuple, empty
  161. TUPLE1: 0x25, // 37: tuple, single element
  162. LIST0: 0x26, // 38: list, empty
  163. LIST1: 0x27, // 39: list, single element
  164. UNICODE0: 0x28, // 40: unicode string, empty
  165. UNICODE1: 0x29, // 41: unicode string, 1 character,
  166. DBROW: 0x2a, // 42: database row (quite hard, custom data format)
  167. STREAM: 0x2b, // 43: embedded marshal stream
  168. TUPLE2: 0x2c, // 44: tuple, 2 elements
  169. MARK: 0x2d, // 45: marker (for the NEWOBJ/REDUCE iterators that follow them)
  170. UTF8: 0x2e, // 46: UTF8 unicode string, buffer size count follows*,
  171. LONG: 0x2f, // 47: big int, byte count follows.,
  172. };
  173. var SHARED_FLAG = 0x40;
  174.  
  175. String.prototype.hexEncode = function () {
  176. var hex, i;
  177.  
  178. var result = "";
  179. for (i=0; i<this.length; i++) {
  180. hex = this.charCodeAt(i).toString(16);
  181. result += ("0"+hex).slice(-2);
  182. }
  183.  
  184. return result
  185. }
  186.  
  187. function processSnip () {
  188.  
  189. var type = parseInt(getBytes(1), 16);
  190. var shared = (type & SHARED_FLAG) == SHARED_FLAG;
  191. type &= ~SHARED_FLAG;
  192.  
  193. var result;
  194.  
  195. switch(type) {
  196. case TYPE.TUPLE2:
  197. result = [processSnip(), processSnip()];
  198. break;
  199.  
  200. case TYPE.FLOAT0:
  201. case TYPE.ZERO:
  202. result = 0;
  203. break;
  204.  
  205. case TYPE.ONE:
  206. result = 1;
  207. break;
  208.  
  209. case TYPE.MINUSONE:
  210. result = -1;
  211. break;
  212.  
  213. case TYPE.LIST:
  214. case TYPE.TUPLE:
  215. result = Array.apply(null, Array(parseInt(getBytes(1), 16))).map(function () { return processSnip(); });
  216. break;
  217.  
  218. case TYPE.INT32:
  219. result = parseInt(lTobEnd(getBytes(4)), 16);
  220. break;
  221.  
  222. case TYPE.STRINGR:
  223. result = stringTable[parseInt(getBytes(1), 16)];
  224. break;
  225.  
  226. case TYPE.LONG:
  227. result = new bigInt(lTobEnd(getBytes(parseInt(getBytes(1), 16))), 16).toString();
  228. break;
  229.  
  230. case TYPE.INT16:
  231. result = parseInt(lTobEnd(getBytes(2)), 16);
  232. break;
  233.  
  234. case TYPE.STRING:
  235. case TYPE.STRINGL:
  236. case TYPE.BUFFER:
  237. result = hexToString(getBytes(parseInt(getBytes(1), 16)));
  238. break;
  239.  
  240. case TYPE.FLOAT:
  241. var ua = new Uint8Array(8);
  242. ua.set(getBytes(8).match(/.{1,2}/g).map(function (m) { return "0x" + m; }));
  243. result = new DataView(ua.buffer).getFloat64(0, true);
  244. break;
  245.  
  246. case TYPE.TRUE:
  247. result = true;
  248. break;
  249.  
  250. case TYPE.FALSE:
  251. result = false;
  252. break;
  253.  
  254. case TYPE.NONE:
  255. result = null;
  256. break;
  257.  
  258. case TYPE.STRING0:
  259. case TYPE.UNICODE0:
  260. result = "";
  261. break;
  262.  
  263. case TYPE.DICT:
  264. var length = parseInt(getBytes(1), 16);
  265. var data = {};
  266. for(var i = 0; i < length; i++) {
  267. var tmp = processSnip();
  268. var tmpind = processSnip();
  269. if(typeof tmpind != "string" && typeof tmp == "string")
  270. data[tmp] = tmpind;
  271. else
  272. data[tmpind] = tmp;
  273. }
  274. result = data;
  275. break;
  276.  
  277. case TYPE.UTF8:
  278. result = hexToString(getBytes(parseInt(getBytes(1), 16)));
  279. break;
  280.  
  281. case TYPE.INT8:
  282. result = parseInt(lTobEnd(getBytes(1)), 16);
  283. break;
  284.  
  285. case TYPE.REF:
  286. result = STORAGE[parseInt(getBytes(1), 16) - 1];
  287. break;
  288.  
  289. case TYPE.LIST0:
  290. case TYPE.TUPLE0:
  291. result = [];
  292. break;
  293.  
  294. case TYPE.INSTANCE:
  295. result = { "(instanceName)": processSnip(), "(instanceData)": processSnip() };
  296. break;
  297.  
  298. case TYPE.DBROW:
  299. result = processDBROW();
  300. break;
  301.  
  302. case TYPE.GLOBAL:
  303. result = { "(global)": hexToString(getBytes(parseInt(getBytes(1), 16))) };
  304. break;
  305.  
  306. case TYPE.CALLBACK:
  307. result = { "(callback)": processSnip() };
  308. break;
  309.  
  310. case TYPE.REDUCE:
  311. var results = [];
  312. var tmpres;
  313. while((tmpres = processSnip()) && tmpres != "(mark)") {
  314. results.push(tmpres);
  315. }
  316. processSnip(); // remove 2nd mark
  317. result = { "(reduce)": results };
  318. break;
  319.  
  320. case TYPE.NEWOBJ:
  321. result = { "(newobj)": processSnip() };
  322. break;
  323.  
  324. case TYPE.MARK:
  325. result = "(mark)";
  326. break;
  327.  
  328. case TYPE.TUPLE1:
  329. case TYPE.LIST1:
  330. result = [processSnip()];
  331. break;
  332.  
  333. case TYPE.INT64:
  334. result = new bigInt(lTobEnd(getBytes(8)), 16).toString();
  335. break;
  336.  
  337. case TYPE.STRING1:
  338. result = hexToString(getBytes(1));
  339. break;
  340.  
  341. case TYPE.STREAM:
  342. var tmpind = ind;
  343. var length = parseInt(getBytes(1), 16);
  344. ind += 2 + (2 * 4);
  345. var res = { "(marshal)": [] };
  346. while(ind < (tmpind + (length * 2))) res["(marshal)"].push(processSnip());
  347. result = res;
  348. break;
  349.  
  350. case 0x00:
  351. break;
  352.  
  353. default:
  354. if(settings.logging) console.log("TYPE " + type + " OFF " + ind);
  355. }
  356.  
  357. if(shared) {
  358. STORAGE.push(result);
  359. }
  360. return result;
  361. }
  362.  
  363. function getBytes(cnt) {
  364. var res = dat.substr(ind, 2 * cnt);
  365. ind += 2 * cnt;
  366. return res;
  367. }
  368.  
  369. function lTobEnd (hex) {
  370. return !hex.match(/.{1,2}/g) ? hex : hex.match(/.{1,2}/g).reverse().join("");
  371. }
  372.  
  373. function getCharacterSheet (id, cb) {
  374. var req = https.request(
  375. {
  376. host: "api.eveonline.com",
  377. path: "/EVE/CharacterAffiliation.xml.aspx",
  378. method: "POST",
  379. headers: {
  380. 'Content-Type': 'application/x-www-form-urlencoded',
  381. 'user-agent': 'EVETOOL by rschuh, charinfo.eve@eneticum.de'
  382. }
  383. }, function (res) {
  384. var resData = "";
  385. res.on("data", function (chunk) {
  386. resData += chunk;
  387. });
  388. res.on("end", function () {
  389. parseString(resData, function (err, result) {
  390. if(err) {
  391. console.log(err);
  392. console.log(resData);
  393. } else {
  394. if(result.eveapi) {
  395. if(result.eveapi.error) {
  396. console.log(result.eveapi.error);
  397. } else {
  398. if(cb) cb(result.eveapi.result[0].rowset[0].row[0].$);
  399. }
  400. }
  401. }
  402. });
  403. });
  404. }).on('error', function(e) {
  405. console.error(e);
  406. });
  407. req.write("ids=" + id);
  408. req.end();
  409. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement