Advertisement
Guest User

Untitled

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