// // Copyright (c) 2012 Rodolphe Breard // // Permission to use, copy, modify, and/or distribute this software for any // purpose with or without fee is hereby granted, provided that the above // copyright notice and this permission notice appear in all copies. // // THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES // WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF // MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR // ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES // WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN // ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF // OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // var NsClient = function() { this.host = 'ns-server.epita.fr'; this.port = 4242; this.default_status = 'actif'; this.status_disconnected = 'disconnected'; this.actions_enabled = ['ping', 'msg', 'status', 'login_out', 'who']; this.action = {}; this.action.ping = function(client, str) { if (str.substr(0, 5) !== 'ping ') { return false; } client.socket.write(str, function(inf) {}); return true; }; this.action.msg = (function(elem) { return function(client, str) { var mo = {}, mch = /user_cmd (\d+):user:.*?:(.*?)@(.*?):.*?:(.*?):(.*?) \| msg ([^ ]*)/.exec(str); if (mch === null) { return false; } mo.socket = mch[1]; mo.login = mch[2]; mo.host = mch[3]; mo.location = elem.msgDecode(mch[4]); mo.group = mch[5]; mo.message = elem.msgDecode(mch[6]); $cs.ui.addContentToTab(mo.login, mo); // TODO: FIX ME! return true; }; })(this); this.action.status = (function(elem) { return function(client, str) { var mch = /user_cmd (\d+):user:.*?:(.*?)@(.*?):.*?:(.*?):(.*?) \| state ([^ ]*):(\d+)/.exec(str); if (mch === null) { return false; } $cs.contacts.changeContactStatus(mch[2], elem.msgDecode(mch[6])); // TODO: FIX ME! return true; }; })(this); this.action.login_out = function(client, str) { var status = 'offline', mch = /user_cmd (\d+):user:.*?:(.*?)@(.*?):.*?:(.*?):(.*?) \| (login|logout)/.exec(str); if (mch === null) { return false; } if (mch[6] === 'login') { status = 'actif'; } $cs.contacts.changeContactStatus(mch[2], status); // TODO: FIX ME! return true; }; this.action.who = (function(elem) { return function(client, str) { var mch = /user_cmd (\d+):user:.*?:(.*?)@(.*?):.*?:(.*?):(.*?) \| who (\d+) (.*?) (.*?) (\d+) (\d+) (\d+) (\d+) (.*?) (.*?) (.*?) (.*?):(.*) (.*)/.exec(str); if (mch === null) { return false; } $cs.contacts.changeContactStatus(mch[7], elem.msgDecode(mch[16])); // TODO: FIX ME! return true; }; })(this); }; NsClient.prototype.connect = function(client, callback) { var login, pwd_socks; if (!client.is_connected) { login = $cs.opts.get('login'); pwd_socks = $cs.opts.get('pwd_socks'); if (login !== null && pwd_socks !== null) { client.socket.read(function(data) { var auth = ''; data = data.split(' '); auth = 'ext_user_log '; auth += login + ' '; auth += hex_md5(data[2] + '-' + data[3] + '/' + data[4] + pwd_socks) + ' '; auth += 'chromesoul chromesoul\n'; client.socket.write('auth_ag ext_user none none\n', function(inf) { client.socket.read(function(data) { client.socket.write(auth, function(inf) { client.socket.read(function(data) { if (data === 'rep 002 -- cmd end') { client.is_connected = true; console.info('connected to the netsoul server'); } else { console.error('authentication failure'); } callback(); }); }); }); }); }); } else { callback(); } } else { callback(); } }; NsClient.prototype.disconnect = function(client) { var msg = 'user_cmd msg_user exit\n'; client.socket.write(msg, function() { client.socket.disconnect(); }); }; NsClient.prototype.changeStatus = function(client) { if (client.is_connected) { status_msg = 'user_cmd state '; status_msg += this.msgEncode(client.status) + ':'; status_msg += Math.round(new Date().getTime() / 1000) + '\n'; client.socket.write(status_msg, function(inf) { $cs.ui.onUserStatusChange(client.status); }); } else { $cs.ui.onUserStatusChange(client.status); } }; NsClient.prototype.recv = function(client, data) { for (var i = this.actions_enabled.length - 1; i >= 0; --i) { if (this.action[this.actions_enabled[i]](client, data)) { break; } } }; NsClient.prototype.speak = function(client, to, msg) { msg = 'user_cmd msg_user ' + to + ' msg ' + this.msgEncode(msg) + '\n'; client.socket.write(msg, function(inf) {}); }; NsClient.prototype.addContact = function(client, lst) { var msg = 'user_cmd watch_log_user {' + lst.join(',') + '}\n'; client.socket.write(msg, function(inf) { var msg = 'user_cmd who {' + lst.join(',') + '}\n'; client.socket.write(msg, function(inf) {}); }); }; NsClient.prototype.rmContact = function(client, name) { // TODO }; NsClient.prototype.replacePairs = function(str, pairs) { for (var i in pairs) { if (pairs.hasOwnProperty(i)) { str = str.replace(pairs[i], i); } } return str; } NsClient.prototype.msgDecode = function(msg) { return this.replacePairs(unescape(msg), { '@': /%40/g, '*': /%2A/g, '/': /%2F/g, '+': /%2B/g }); }; NsClient.prototype.msgEncode = function(msg) { return this.replacePairs(escape(msg), { '%40': /@/g, '%2A': /\*/g, '%2F': /\//g, '%2B': /\+/g, }); };