Aluf

Chatango Derplib.py [weights.js,utils.js,socket.js,saving.js

Feb 2nd, 2015
509
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 28.48 KB | None | 0 0
  1. ############################
  2. NOT OWNED BY ALUF #######
  3. ############################
  4.  
  5.  
  6. Utils.js
  7. ########
  8.  
  9.  
  10. 'use strict';
  11. var util = require('util'),
  12. crypto = require('crypto'),
  13. fs = require('fs'),
  14. request = require('request');
  15.  
  16. var MM = module.parent;
  17.  
  18. var crypto_algorithm = 'aes-256-cbc';
  19. var crypto_key = '05f4PP1rL4JPff4PljY3G4ytZxRN662f'; // If you want to use encryption, change this
  20. var crypto_iv = 'T9terqJ0NlCk7OwV'; // And this
  21.  
  22. exports.encrypt = function(text){
  23. var cipher = crypto.createCipheriv(crypto_algorithm, crypto_key, crypto_iv);
  24. return cipher.update(text, 'utf8', 'hex') + cipher.final('hex');
  25. }
  26.  
  27. exports.decrypt = function(text){
  28. var decipher = crypto.createDecipheriv(crypto_algorithm, crypto_key, crypto_iv);
  29. return decipher.update(text, 'hex', 'utf8') + decipher.final('utf8');
  30. }
  31.  
  32. exports.walkdir = function(dir, done) {
  33. var results = [];
  34. fs.readdir(dir, function(err, list) {
  35. if (err) return done(err);
  36. var pending = list.length;
  37. if (!pending) return done(null, results);
  38. list.forEach(function(file) {
  39. file = dir + '/' + file;
  40. fs.stat(file, function(err, stat) {
  41. if (stat && stat.isDirectory()) {
  42. exports.walkdir(file, function(err, res) {
  43. results = results.concat(res);
  44. if (!--pending) done(null, results);
  45. });
  46. } else {
  47. results.push(file);
  48. if (!--pending) done(null, results);
  49. }
  50. });
  51. });
  52. });
  53. };
  54.  
  55. exports.urlUnzip = function(url, cb){
  56. var gunzip = require("zlib").createGunzip();
  57. var buffer = [];
  58. request(url).pipe(gunzip);
  59. gunzip.on('data', function(data) {
  60. buffer.push(data.toString())
  61. }).on("end", function() {
  62. cb(buffer.join(''));
  63. }).on("error", function(e) {
  64. console.log(e);
  65. cb(false);
  66. });
  67. }
  68.  
  69. //utilities.format('someone %action another person %method.', {method: 'on the head', action: 'hit'});
  70. exports.format = function(string, args){
  71. if(!string) return false;
  72. var original_string = string;
  73. var sarr = [];
  74. for(var arg in args){
  75. var keyword = '%'+arg;
  76. var location = original_string.indexOf(keyword);
  77. if(location != -1){
  78. sarr.push([location, args[arg]]);
  79. var type = typeof args[arg];
  80. var sign = (type == 'string' ? '%s' : (type == 'number' ? '%d' : '%s'));
  81. string = string.replace(keyword, sign);
  82. }
  83. }
  84. sarr.sort(function(a,b){
  85. return a[0] - b[0];
  86. });
  87. var arr = [];
  88. for(var i=0; i<sarr.length; i++){
  89. arr.push(sarr[i][1]);
  90. }
  91. arr.unshift(string);
  92. return util.format.apply(this, arr);
  93. }
  94.  
  95. exports.randomString = function(length){
  96. if(!length) length = 10;
  97. var text = "";
  98. var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
  99. for( var i=0; i < length; i++ )
  100. text += possible.charAt(Math.floor(Math.random() * possible.length));
  101.  
  102. return text;
  103. }
  104.  
  105. exports.dateToString = function(timestamp, format){
  106. format = (format || 'readable');
  107. var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
  108. var date = new Date(timestamp * 1000);
  109.  
  110. var day = (String(date.getDate()).length == 1 ? '0'+date.getDate() : date.getDate());
  111. var month = months[date.getMonth()];
  112. var month_num = (String(date.getMonth() + 1).length == 1 ? '0'+(date.getMonth() + 1) : (date.getMonth() + 1));
  113. var year = date.getFullYear();
  114. var hour = date.getHours();
  115. var minutes = date.getMinutes();
  116. var seconds = date.getSeconds();
  117.  
  118. switch(format){
  119.  
  120. case 'readable':
  121. return day+' '+month+' '+year;
  122. break;
  123.  
  124. case 'hour_mins_seconds':
  125. return hour+':'+minutes+':'+seconds;
  126. break;
  127.  
  128. case 'DDMMYYYY':
  129. default:
  130. return day +''+ month_num +''+year;
  131. break;
  132. }
  133.  
  134. }
  135.  
  136. exports.secondsToString = function(seconds, depth) {
  137. function numberEnding (number) { //todo: replace with a wiser code
  138. return (number > 1) ? 's' : '';
  139. }
  140.  
  141. var temp = seconds;
  142. var result = [];
  143. depth = depth || 2;
  144.  
  145. var years = Math.floor(temp / 31536000);
  146. if (years) {
  147. result.push(years + ' year' + numberEnding(years));
  148. }
  149. var days = Math.floor((temp %= 31536000) / 86400);
  150. if (days) {
  151. result.push(days + ' day' + numberEnding(days));
  152. }
  153. var hours = Math.floor((temp %= 86400) / 3600);
  154. if (hours) {
  155. result.push(hours + ' hour' + numberEnding(hours));
  156. }
  157. var minutes = Math.floor((temp %= 3600) / 60);
  158. if (minutes) {
  159. result.push(minutes + ' minute' + numberEnding(minutes));
  160. }
  161. var seconds = temp % 60;
  162. if (seconds) {
  163. result.push(seconds + ' second' + numberEnding(seconds));
  164. }
  165. result = result.slice(0,depth);
  166. return result.length == 1 ? result[0] : result.slice(0,result.length-1).join(' ')+' and '+result[result.length-1];
  167. }
  168. /* OLD
  169. exports.secondsToString = function(seconds, depth) {
  170. console.log('seconds to string', seconds);
  171. function numberEnding (number) { //todo: replace with a wiser code
  172. return (number > 1) ? 's' : '';
  173. }
  174.  
  175. var temp = seconds;
  176. var string = '';
  177. depth = (depth || 2);
  178. var current_depth = 0;
  179.  
  180. var years = Math.floor(temp / 31536000);
  181. if (years) {
  182. current_depth++;
  183. string += years + ' year' + numberEnding(years);
  184. if(depth <= current_depth) return string;
  185. }
  186. var days = Math.floor((temp %= 31536000) / 86400);
  187. if (days) {
  188. current_depth++;
  189. var last = (depth <= current_depth);
  190. string += (string?' ':'') + (last?'and ':'') + days + ' day' + numberEnding(days);
  191. if(depth <= current_depth) return string;
  192. }
  193. var hours = Math.floor((temp %= 86400) / 3600);
  194. if (hours) {
  195. current_depth++;
  196. var last = (depth <= current_depth);
  197. string += (string?' ':'') + (last?'and ':'') + hours + ' hour' + numberEnding(hours);
  198. if(depth <= current_depth) return string;
  199. }
  200. var minutes = Math.floor((temp %= 3600) / 60);
  201. if (minutes) {
  202. current_depth++;
  203. var last = (depth <= current_depth);
  204. string += (string?' ':'') + (last?'and ':'') + minutes + ' minute' + numberEnding(minutes);
  205. if(depth <= current_depth) return string;
  206. }
  207. var seconds = temp % 60;
  208. if (seconds) {
  209. string += (string?' and ':'') + seconds + ' second' + numberEnding(seconds);
  210. return string;
  211. }
  212. if(string) return string;
  213. else return 'less then a second'; //'just now' //or other string you like;
  214. }*/
  215.  
  216.  
  217. // Base valiable types prototypes //
  218.  
  219. // Array //
  220.  
  221. exports.array_shuffle = function(o){
  222. for(var j, x, i = o.length; i; j = parseInt(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x);
  223. return o;
  224. };
  225.  
  226. exports.array_random = function(array){
  227. return array[Math.floor(Math.random() * array.length)];
  228. }
  229.  
  230. // Object //
  231. exports.obj_clone = function(array){
  232. var oldState = history.state;
  233. history.replaceState(array);
  234. var clonedObj = history.state;
  235. history.replaceState(oldState);
  236. return clonedObj;
  237.  
  238. }
  239.  
  240. exports.obj_size = function(obj) {
  241. var size = 0, key;
  242. for (key in obj) {
  243. if (obj.hasOwnProperty(key)) size++;
  244. }
  245. return size;
  246. };
  247.  
  248. /* obj_sort required format:
  249. { 'key': 5, 'key2': 10}
  250. output:
  251. [ ['key2', 10], ['key', 5] ]
  252. */
  253. exports.obj_sort = function(obj){
  254. var sort_array = [];
  255. for(var k in obj){
  256. sort_array.push([k, obj[k]]);
  257. }
  258. sort_array.sort(function(a,b){
  259. return b[1] - a[1];
  260. });
  261. return sort_array;
  262. }
  263.  
  264. exports.obj_deepExtend = function(destination, source) {
  265. for (var property in source) {
  266. if (source[property] && source[property].constructor &&
  267. source[property].constructor === Object) {
  268. destination[property] = destination[property] || {};
  269. exports.obj_deepExtend(destination[property], source[property]);
  270. } else {
  271. destination[property] = source[property];
  272. }
  273. }
  274. return destination;
  275. };
  276.  
  277. // Number //
  278. exports.number_random = function(min, max){
  279. return Math.floor(Math.random() * (max - min + 1)) + min;
  280. }
  281.  
  282. exports.number_tofixed = function(num, length){
  283. var len = '1';
  284. for(var i=0; i<length; i++) len += '0';
  285. return parseFloat(Math.round(num * parseInt(len)) / parseInt(len)).toFixed(length);
  286. }
  287.  
  288. // String //
  289. exports.string_lowerUperFirst = function(str){
  290. return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
  291. }
  292.  
  293. exports.string_random = function(length, possible){
  294. length = length || 10;
  295. possible = possible || 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
  296. var text = '';
  297.  
  298. for( var i=0; i < length; i++ )
  299. text += possible.charAt(Math.floor(Math.random() * possible.length));
  300.  
  301. return text;
  302. }
  303.  
  304. // ------------ end --------------- //
  305.  
  306.  
  307. exports.parseUrl = function(url){
  308. var hostname = url.split('/').splice(2,1).join('/');
  309. var path = '/'+url.split('/').splice(3).join('/');
  310. var domain = url.split('/').splice(2,1)[0].split('.').splice(-2).join('.');
  311. //var domain = url.split('/')[0].split('.').slice(-2).join('.');
  312. }
  313.  
  314.  
  315. //arr1: new Array('&nbsp;', '&iexcl;', '&cent;', '&pound;', '&curren;', '&yen;', '&brvbar;', '&sect;', '&uml;', '&copy;', '&ordf;', '&laquo;', '&not;', '&shy;', '&reg;', '&macr;', '&deg;', '&plusmn;', '&sup2;', '&sup3;', '&acute;', '&micro;', '&para;', '&middot;', '&cedil;', '&sup1;', '&ordm;', '&raquo;', '&frac14;', '&frac12;', '&frac34;', '&iquest;', '&Agrave;', '&Aacute;', '&Acirc;', '&Atilde;', '&Auml;', '&Aring;', '&Aelig;', '&Ccedil;', '&Egrave;', '&Eacute;', '&Ecirc;', '&Euml;', '&Igrave;', '&Iacute;', '&Icirc;', '&Iuml;', '&ETH;', '&Ntilde;', '&Ograve;', '&Oacute;', '&Ocirc;', '&Otilde;', '&Ouml;', '&times;', '&Oslash;', '&Ugrave;', '&Uacute;', '&Ucirc;', '&Uuml;', '&Yacute;', '&THORN;', '&szlig;', '&agrave;', '&aacute;', '&acirc;', '&atilde;', '&auml;', '&aring;', '&aelig;', '&ccedil;', '&egrave;', '&eacute;', '&ecirc;', '&euml;', '&igrave;', '&iacute;', '&icirc;', '&iuml;', '&eth;', '&ntilde;', '&ograve;', '&oacute;', '&ocirc;', '&otilde;', '&ouml;', '&divide;', '&Oslash;', '&ugrave;', '&uacute;', '&ucirc;', '&uuml;', '&yacute;', '&thorn;', '&yuml;', '&quot;', '&amp;', '&lt;', '&gt;', '&oelig;', '&oelig;', '&scaron;', '&scaron;', '&yuml;', '&circ;', '&tilde;', '&ensp;', '&emsp;', '&thinsp;', '&zwnj;', '&zwj;', '&lrm;', '&rlm;', '&ndash;', '&mdash;', '&lsquo;', '&rsquo;', '&sbquo;', '&ldquo;', '&rdquo;', '&bdquo;', '&dagger;', '&dagger;', '&permil;', '&lsaquo;', '&rsaquo;', '&euro;', '&fnof;', '&alpha;', '&beta;', '&gamma;', '&delta;', '&epsilon;', '&zeta;', '&eta;', '&theta;', '&iota;', '&kappa;', '&lambda;', '&mu;', '&nu;', '&xi;', '&omicron;', '&pi;', '&rho;', '&sigma;', '&tau;', '&upsilon;', '&phi;', '&chi;', '&psi;', '&omega;', '&alpha;', '&beta;', '&gamma;', '&delta;', '&epsilon;', '&zeta;', '&eta;', '&theta;', '&iota;', '&kappa;', '&lambda;', '&mu;', '&nu;', '&xi;', '&omicron;', '&pi;', '&rho;', '&sigmaf;', '&sigma;', '&tau;', '&upsilon;', '&phi;', '&chi;', '&psi;', '&omega;', '&thetasym;', '&upsih;', '&piv;', '&bull;', '&hellip;', '&prime;', '&prime;', '&oline;', '&frasl;', '&weierp;', '&image;', '&real;', '&trade;', '&alefsym;', '&larr;', '&uarr;', '&rarr;', '&darr;', '&harr;', '&crarr;', '&larr;', '&uarr;', '&rarr;', '&darr;', '&harr;', '&forall;', '&part;', '&exist;', '&empty;', '&nabla;', '&isin;', '&notin;', '&ni;', '&prod;', '&sum;', '&minus;', '&lowast;', '&radic;', '&prop;', '&infin;', '&ang;', '&and;', '&or;', '&cap;', '&cup;', '&int;', '&there4;', '&sim;', '&cong;', '&asymp;', '&ne;', '&equiv;', '&le;', '&ge;', '&sub;', '&sup;', '&nsub;', '&sube;', '&supe;', '&oplus;', '&otimes;', '&perp;', '&sdot;', '&lceil;', '&rceil;', '&lfloor;', '&rfloor;', '&lang;', '&rang;', '&loz;', '&spades;', '&clubs;', '&hearts;', '&diams;'),
  316. //arr2: new Array('&#160;', '&#161;', '&#162;', '&#163;', '&#164;', '&#165;', '&#166;', '&#167;', '&#168;', '&#169;', '&#170;', '&#171;', '&#172;', '&#173;', '&#174;', '&#175;', '&#176;', '&#177;', '&#178;', '&#179;', '&#180;', '&#181;', '&#182;', '&#183;', '&#184;', '&#185;', '&#186;', '&#187;', '&#188;', '&#189;', '&#190;', '&#191;', '&#192;', '&#193;', '&#194;', '&#195;', '&#196;', '&#197;', '&#198;', '&#199;', '&#200;', '&#201;', '&#202;', '&#203;', '&#204;', '&#205;', '&#206;', '&#207;', '&#208;', '&#209;', '&#210;', '&#211;', '&#212;', '&#213;', '&#214;', '&#215;', '&#216;', '&#217;', '&#218;', '&#219;', '&#220;', '&#221;', '&#222;', '&#223;', '&#224;', '&#225;', '&#226;', '&#227;', '&#228;', '&#229;', '&#230;', '&#231;', '&#232;', '&#233;', '&#234;', '&#235;', '&#236;', '&#237;', '&#238;', '&#239;', '&#240;', '&#241;', '&#242;', '&#243;', '&#244;', '&#245;', '&#246;', '&#247;', '&#248;', '&#249;', '&#250;', '&#251;', '&#252;', '&#253;', '&#254;', '&#255;', '&#34;', '&#38;', '&#60;', '&#62;', '&#338;', '&#339;', '&#352;', '&#353;', '&#376;', '&#710;', '&#732;', '&#8194;', '&#8195;', '&#8201;', '&#8204;', '&#8205;', '&#8206;', '&#8207;', '&#8211;', '&#8212;', '&#8216;', '&#8217;', '&#8218;', '&#8220;', '&#8221;', '&#8222;', '&#8224;', '&#8225;', '&#8240;', '&#8249;', '&#8250;', '&#8364;', '&#402;', '&#913;', '&#914;', '&#915;', '&#916;', '&#917;', '&#918;', '&#919;', '&#920;', '&#921;', '&#922;', '&#923;', '&#924;', '&#925;', '&#926;', '&#927;', '&#928;', '&#929;', '&#931;', '&#932;', '&#933;', '&#934;', '&#935;', '&#936;', '&#937;', '&#945;', '&#946;', '&#947;', '&#948;', '&#949;', '&#950;', '&#951;', '&#952;', '&#953;', '&#954;', '&#955;', '&#956;', '&#957;', '&#958;', '&#959;', '&#960;', '&#961;', '&#962;', '&#963;', '&#964;', '&#965;', '&#966;', '&#967;', '&#968;', '&#969;', '&#977;', '&#978;', '&#982;', '&#8226;', '&#8230;', '&#8242;', '&#8243;', '&#8254;', '&#8260;', '&#8472;', '&#8465;', '&#8476;', '&#8482;', '&#8501;', '&#8592;', '&#8593;', '&#8594;', '&#8595;', '&#8596;', '&#8629;', '&#8656;', '&#8657;', '&#8658;', '&#8659;', '&#8660;', '&#8704;', '&#8706;', '&#8707;', '&#8709;', '&#8711;', '&#8712;', '&#8713;', '&#8715;', '&#8719;', '&#8721;', '&#8722;', '&#8727;', '&#8730;', '&#8733;', '&#8734;', '&#8736;', '&#8743;', '&#8744;', '&#8745;', '&#8746;', '&#8747;', '&#8756;', '&#8764;', '&#8773;', '&#8776;', '&#8800;', '&#8801;', '&#8804;', '&#8805;', '&#8834;', '&#8835;', '&#8836;', '&#8838;', '&#8839;', '&#8853;', '&#8855;', '&#8869;', '&#8901;', '&#8968;', '&#8969;', '&#8970;', '&#8971;', '&#9001;', '&#9002;', '&#9674;', '&#9824;', '&#9827;', '&#9829;', '&#9830;'),
  317.  
  318. exports.chmsg_clean = function(string){
  319. var name = /<n(.*?)\/>/g.exec(string);
  320. name = name ? name[1] : false;
  321. var font = /<f(.*?)\/>/g.exec(string);
  322. font = font ? font[1] : false
  323. string = exports.html_decode(exports.html_remove(string));
  324. return {text: string, name: name, font: font};
  325. }
  326.  
  327. exports.html_view = function(str) {
  328. return String(str)
  329. .replace(/</g, '&lt;')
  330. .replace(/>/g, '&gt;');
  331. }
  332.  
  333. exports.html_encode = function(str) {
  334. return String(str)
  335. .replace(/&/g, '&amp;')
  336. .replace(/"/g, '&quot;')
  337. .replace(/'/g, '&#39;')
  338. .replace(/</g, '&lt;')
  339. .replace(/>/g, '&gt;');
  340. }
  341.  
  342. exports.html_decode = function(value){
  343. return String(value)
  344. .replace(/&quot;/g, '"')
  345. .replace(/&#39;/g, "'")
  346. .replace(/&apos;/g, "'")
  347. .replace(/&lt;/g, '<')
  348. .replace(/&gt;/g, '>')
  349. .replace(/&amp;/g, '&');
  350. }
  351.  
  352. exports.html_remove = function(msg){
  353. var li = msg.split('<');
  354. if(li.length == 1){
  355. return li[0];
  356. }else{
  357. var ret = [li[0]];
  358. for(var data in li){
  359. li[data] = li[data].split('>', 2);
  360. if(li[data][1] != '\r\n\u0000')
  361. ret.push(li[data][1]);
  362. }
  363. return ret.join('');
  364. }
  365. }
  366.  
  367. //
  368. // Internal functions
  369. //
  370.  
  371. exports.parseContact = function(state, time){
  372. time = parseInt(time);
  373. var contact = {state: false, time: false};
  374. if(state == 'online' && time == 0){
  375. //ONLINE
  376. return {state: 'online', time: Math.round(new Date/1000)};
  377. }
  378. else if(state == 'online' && time > 0){
  379. //IDLE
  380. return {state: 'idle', time: Math.round(new Date/1000) - (time * 60)};
  381. }
  382. else if(state == 'offline'){
  383. //OFF
  384. return {state: 'offline', time: time};
  385. }
  386. return false;
  387. }
  388.  
  389. exports.genUid = function() {
  390. var min = Math.pow(10, 15);
  391. var max = Math.pow(10, 16);
  392. return Math.floor(Math.random() * (max - min + 1)) + min;
  393. }
  394.  
  395. exports.getAnonId = function(n,ssid) { //n is from message body, ssid is user_id
  396. //example: 5454/16766087 = anon1431
  397. if(!n || !ssid) return false;
  398. var id = '';
  399. for(var i=0; i<4; i++){
  400. var a = parseInt(n.substr(i, 1)) + parseInt(ssid.substr(i+4, 1));
  401. id += String(a>9 ? a-10 : a);
  402. }
  403. return id;
  404. }
  405.  
  406. exports.getAnonName = function(num, ts) {
  407. num = String(num).substr(4, 4);
  408. if(undefined !== ts){
  409. ts = String(ts).split(".")[0];
  410. ts = ts.substr(ts.length - 4);
  411. }else{
  412. ts = ts || 3452;
  413. }
  414. var id = "";
  415. for(var i = 0; i < num.length; i++){
  416. var part1 = Number(num.substr(i, 1));
  417. var part2 = Number(ts.substr(i, 1));
  418. var part3 = String(part1 + part2);
  419. id = id + part3.substr(part3.length - 1);
  420. }
  421. return "_anon" + id;
  422. }
  423.  
  424.  
  425. /*
  426. def aid(self, n, uid):
  427. '''Generate Anon ID number'''
  428. try:
  429. if (int(n) == 0) or (len(n) < 4): n = "3452"
  430. except ValueError: n = "3452"
  431. if n != "3452": n = str(int(n))[-4:]
  432. v1, v5 = 0, ""
  433. for i in range(0, len(n)): v5 += str(int(n[i:][:1])+int(str(uid)[4:][:4][i:][:1]))[len(str(int(n[i:][:1])+int(str(uid)[4:][:4][i:][:1]))) - 1:]
  434. return v5
  435. */
  436.  
  437.  
  438.  
  439. Socket.j
  440. ########
  441.  
  442. 'use strict';
  443. var _ = require('underscore'),
  444. util = require('util'),
  445. events = require('events'),
  446. net = require('net'),
  447. colors = require('colors');
  448.  
  449. // Chatango Socket connection handler, for both Rooms and PM
  450. // Available events: onconnect, data, error, timeout, close, write ( Note: exceptions must be handled! )
  451.  
  452. function Socket(host, port)
  453. {
  454. this._host = host;
  455. this._port = port || 443;
  456. this._socket = new net.Socket();
  457.  
  458. this._pingTask = false;
  459.  
  460. this._connected = false;
  461.  
  462. this._firstCommand = true;
  463. this._writeLock = false;
  464. this._writeBuffer = [];
  465. this._buffer = '';
  466.  
  467. this.connect();
  468. }
  469.  
  470. util.inherits(Socket, events.EventEmitter);
  471.  
  472. Socket.prototype.connect = function()
  473. {
  474. if(this._socket._connecting) return;
  475.  
  476. var self = this;
  477.  
  478. if(this._socket.destroyed){
  479. var reconnecting = true;
  480. console.log('[SOCKET] reconnecting to '+this._host+':'+this._port);
  481. }else{
  482. var reconnecting = false;
  483. console.log('[SOCKET] connecting to '+this._host+':'+this._port);
  484. }
  485.  
  486. this._writeLock = true;
  487.  
  488. if(this._socket._events.connect){
  489. this._socket.connect(this._port, this._host);
  490. }else{
  491. this._socket.connect(this._port, this._host, function() {
  492. self._connected = true;
  493. self._writeLock = false;
  494.  
  495. self._pingTask = setInterval(function() {
  496. if(self._connected) {
  497. self.write(['']);
  498. }
  499. }, 30000);
  500.  
  501. self.emit('onconnect');
  502. });
  503. }
  504.  
  505. if(reconnecting) return;
  506.  
  507. this._socket.on('data', function(data) {
  508.  
  509. var buffer = data.toString('utf8');
  510.  
  511. if(buffer.substr(-1) !== '\x00')
  512. {
  513. self._buffer += buffer;
  514. }
  515. else
  516. {
  517. if(self._buffer != '')
  518. {
  519. buffer = self._buffer + buffer;
  520. self._buffer = '';
  521. }
  522. var messages = buffer.split('\x00');
  523.  
  524. _.each(messages, function(message){
  525.  
  526. message = message.replace(/(\r|\n)/g, '');
  527.  
  528. if(message !== '')
  529. self.emit('data', message);
  530.  
  531. });
  532. }
  533.  
  534. });
  535.  
  536. this._socket.on('error', function(exception) {
  537. self.emit('error', exception);
  538. });
  539.  
  540. this._socket.on('timeout', function(exception) {
  541. self.emit('timeout', exception);
  542. });
  543.  
  544. this._socket.on('close', function() {
  545. self._connected = false;
  546. self._writeBuffer = [];
  547. self._writeLock = false;
  548. self._buffer = '';
  549. self._firstCommand = true;
  550. clearInterval(self._pingTask);
  551. self.emit('close');
  552. });
  553.  
  554. }
  555.  
  556. Socket.prototype.disconnect = function(){
  557. this._socket.destroy();
  558. }
  559.  
  560. Socket.prototype.setWriteLock = function(bool) {
  561. this._writeLock = _.isBoolean(bool) && bool;
  562. }
  563.  
  564. Socket.prototype.write = function(data) {
  565.  
  566. if(this._connected)
  567. {
  568. if(this._firstCommand)
  569. {
  570. var terminator = '\x00';
  571. this._firstCommand = false;
  572. }
  573. else
  574. var terminator = '\r\n\x00';
  575.  
  576. if(this._writeLock)
  577. this._writeBuffer.push(data);
  578. else
  579. {
  580. _.each(this._writeBuffer, function(value){
  581. this.write(value);
  582. }.bind(this));
  583.  
  584. if(data)
  585. this.emit('write', data.join(':'));
  586. this._socket.write(data.join(':') + terminator);
  587. }
  588. }
  589. }
  590.  
  591. exports.Instance = Socket;
  592.  
  593.  
  594. weights.js
  595. ##########
  596.  
  597. // Weights.js by the awesome Lumirayz
  598.  
  599. //
  600. // Requires
  601. //
  602. var _ = require("underscore"),
  603. crypto = require("crypto");
  604.  
  605. //
  606. // External Data
  607. //
  608.  
  609. _chatangoTagserver = {"sw": {"sv10": 110, "sv12": 116, "w12": 75, "sv8": 101, "sv6": 104, "sv4": 110, "sv2": 95}, "ex": {"b55279b3166dd5d30767d68b50c333ab": 21,
  610. "0a249c2a3a3dcb7e40dcfac36bec194f": 21, "3ae9453fa1557dc71316701777c5ee42": 51, "ebcd66fd5b868f249c1952af02a91cb3": 5, "4913527f3dd834ec1bb3e1eb886b6d62": 56,
  611. "7a067398784395c6208091bc6c3f3aac": 22, "ce7b7bc84a4e8184edb432085883ae04": 51,"fe8d11abb9c391d5f2494d48bb89221b": 8, "2d14c18e510a550f0d13eac7685ba496": 8,
  612. "3e772eba0dfbf48d47b4c02d5a3beac9": 56, "eff4fd30f3fa53a4a1cb3442a951ad03": 54, "082baeccd5eabe581cba35bd777b93ef": 56, "e21569f6966d79cfc1b911681182f71f": 34,
  613. "0b18ed3fb935c9607cb01cc537ec854a": 10, "20e46ddc5e273713109edf7623d89e7a": 22, "72432e25656d6b7dab98148fbd411435": 70, "bb02562ba45ca77e62538e6c5db7c8ae": 10,
  614. "d78524504941b97ec555ef43c4fd9d3c": 21, "2db735f3815eec18b4326bed35337441": 56, "63ff05c1d26064b8fe609e40d6693126": 56, "ec580e6cbdc2977e09e01eb6a6c62218": 69,
  615. "246894b6a72e704e8e88afc67e8c7ea9": 20, "028a31683e35c51862adedc316f9d07b": 51, "2b2e3e5ff1550560502ddd282c025996": 27, "e0d3ff2ad4d2bedc7603159cb79501d7": 67,
  616. "726a56c70721704493191f8b93fe94a3": 21}, "sm": [["5", "w12"], ["6", "w12"], ["7","w12"], ["8", "w12"], ["16", "w12"], ["17", "w12"], ["18", "w12"], ["9", "sv2"],
  617. ["11", "sv2"], ["12", "sv2"], ["13", "sv2"], ["14", "sv2"], ["15", "sv2"], ["19", "sv4"], ["23", "sv4"], ["24", "sv4"], ["25", "sv4"], ["26", "sv4"], ["28",
  618. "sv6"], ["29", "sv6"], ["30", "sv6"], ["31", "sv6"], ["32", "sv6"], ["33", "sv6"], ["35", "sv8"], ["36", "sv8"], ["37", "sv8"], ["38", "sv8"], ["39", "sv8"],
  619. ["40", "sv8"], ["41", "sv8"], ["42", "sv8"], ["43", "sv8"], ["44", "sv8"], ["45", "sv8"], ["46", "sv8"], ["47", "sv8"], ["48", "sv8"], ["49", "sv8"], ["50", "sv8"],
  620. ["52", "sv10"], ["53", "sv10"], ["55", "sv10"], ["57", "sv10"], ["58", "sv10"], ["59", "sv10"], ["60", "sv10"], ["61", "sv10"], ["62", "sv10"], ["63", "sv10"],
  621. ["64", "sv10"], ["65", "sv10"], ["66", "sv10"], ["68", "sv2"], ["71", "sv12"],["72", "sv12"], ["73", "sv12"], ["74", "sv12"], ["75", "sv12"], ["76", "sv12"],
  622. ["77", "sv12"], ["78", "sv12"], ["79", "sv12"], ["80", "sv12"], ["81", "sv12"],["82", "sv12"], ["83", "sv12"], ["84", "sv12"]]};
  623.  
  624. //
  625. // Preprocess
  626. //
  627. var weights = _.map(_chatangoTagserver.sm, function(p) {
  628. return [p[0], _chatangoTagserver.sw[p[1]]];
  629. });
  630.  
  631. //
  632. // getServerId, getServerHost
  633. //
  634. function getServerId(room) {
  635. room = room.toLowerCase();
  636. var roomMd5 = crypto.createHash("md5").update(room).digest("hex");
  637. if(_chatangoTagserver.ex.hasOwnProperty(roomMd5)) {
  638. // If the room has a server directly assigned, return that one.
  639. return _chatangoTagserver.ex[roomMd5];
  640. }
  641. else {
  642. // If it doesn't, calculate the server using a weighted choice
  643. // algorithm which uses a few characters from the room name to
  644. // get a number from 0 to 1.
  645. var
  646. _room = room.replace(/[-_]/g, "q"),
  647. firstNumberString = _room.substring(0, 5),
  648. lastNumberString = _room.substring(6, 6 + Math.min(3, _room.length - 5)),
  649. firstNumber = parseInt(firstNumberString, 36),
  650. lastNumber;
  651. if(lastNumberString.length > 0) {
  652. lastNumber = Math.max(1000, parseInt(lastNumberString, 36));
  653. }
  654. else {
  655. lastNumber = 1000;
  656. }
  657. // Use this number to do a weighted choice over all the
  658. // servers.
  659. var
  660. relDiff = (firstNumber % lastNumber) / lastNumber,
  661. maxDiff = _.reduce(weights, function(acc, next) {
  662. return acc + next[1];
  663. }, 0),
  664. accum = 0;
  665. for(var i = 0; i < weights.length; i++) {
  666. var
  667. currentWeight = weights[i][1] / maxDiff,
  668. nextWeight = accum + currentWeight;
  669. if(nextWeight >= relDiff) {
  670. // BOOYAH, got you.
  671. return weights[i][0];
  672. }
  673. accum = nextWeight;
  674. }
  675. // Should not happen.
  676. return null;
  677. }
  678. }
  679.  
  680. function getServerHost(room) {
  681. return "s" + getServerId(room) + ".chatango.com";
  682. }
  683.  
  684. //
  685. // Exports
  686. //
  687. exports.getServerId = getServerId;
  688. exports.getServerHost = getServerHost;
Add Comment
Please, Sign In to add comment