code refactoring
This commit is contained in:
parent
e78c5f919e
commit
5ee9143b71
12 changed files with 445 additions and 246 deletions
22
background.js
Normal file
22
background.js
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
//
|
||||||
|
|
||||||
|
chrome.app.runtime.onLaunched.addListener(function() {
|
||||||
|
chrome.app.window.create('chromesoul.html', {
|
||||||
|
'width': 800,
|
||||||
|
'height': 500
|
||||||
|
});
|
||||||
|
});
|
|
@ -18,7 +18,6 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="main-ctn">
|
<div id="main-ctn">
|
||||||
<p id="pre-conf-pannel">You haven't configured chromesoul yet, you should go to the configuration pannel.</p>
|
|
||||||
<div id="config-pannel">
|
<div id="config-pannel">
|
||||||
<input type="text" placeholder="Login" id="login" class="opt" value=""><br>
|
<input type="text" placeholder="Login" id="login" class="opt" value=""><br>
|
||||||
<input type="password" placeholder="Password (SOCKS)" id="pwd_socks" class="opt" value=""><br>
|
<input type="password" placeholder="Password (SOCKS)" id="pwd_socks" class="opt" value=""><br>
|
||||||
|
@ -33,13 +32,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript" src="third-party/md5-min.js"></script>
|
<script type="text/javascript" src="third-party/md5-min.js"></script>
|
||||||
<script type="text/javascript" src="third-party/ab-str.js"></script>
|
<script type="text/javascript" src="lib/txt_socket.js"></script>
|
||||||
|
<script type="text/javascript" src="lib/client.js"></script>
|
||||||
<script type="text/javascript" src="lib/ns_client.js"></script>
|
<script type="text/javascript" src="lib/ns_client.js"></script>
|
||||||
<script type="text/javascript" src="lib/avatars.js"></script>
|
<script type="text/javascript" src="lib/avatars.js"></script>
|
||||||
<script type="text/javascript" src="lib/options.js"></script>
|
<script type="text/javascript" src="lib/options.js"></script>
|
||||||
<script type="text/javascript" src="lib/tab.nsui.js"></script>
|
<script type="text/javascript" src="lib/tab.nsui.js"></script>
|
||||||
<script type="text/javascript" src="lib/contacts.nsui.js"></script>
|
<script type="text/javascript" src="lib/contacts.nsui.js"></script>
|
||||||
<script type="text/javascript" src="lib/nsui.js"></script>
|
<script type="text/javascript" src="lib/nsui.js"></script>
|
||||||
<script type="text/javascript" src="start.js"></script>
|
<script type="text/javascript" src="chromesoul.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,22 +1,21 @@
|
||||||
//
|
var chromesoul = (function() {
|
||||||
// Copyright (c) 2012 Rodolphe Breard
|
var chromesoul = {
|
||||||
//
|
"opts": new OptionsManager(),
|
||||||
// Permission to use, copy, modify, and/or distribute this software for any
|
"ui": new Nsui(),
|
||||||
// purpose with or without fee is hereby granted, provided that the above
|
"contacts": new ContactList(),
|
||||||
// copyright notice and this permission notice appear in all copies.
|
"client": new Client(),
|
||||||
//
|
"avatars": new AvatarManager()
|
||||||
// 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.
|
|
||||||
//
|
|
||||||
|
|
||||||
chrome.app.runtime.onLaunched.addListener(function() {
|
return (window.chromesoul = window.$cs = chromesoul);
|
||||||
chrome.app.window.create('chromesoul.html', {
|
})();
|
||||||
'width': 400,
|
|
||||||
'height': 500
|
$cs.opts.init();
|
||||||
});
|
$cs.ui.init();
|
||||||
|
$cs.client.init(new NsClient(), $cs.ui);
|
||||||
|
$cs.contacts.init();
|
||||||
|
|
||||||
|
$cs.ui.setReconnect(function() {
|
||||||
|
$cs.client.disconnect();
|
||||||
|
$cs.client.connect();
|
||||||
});
|
});
|
||||||
|
|
124
lib/client.js
Normal file
124
lib/client.js
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2013 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 Client = function() {
|
||||||
|
this.socket = null;
|
||||||
|
this.is_connected = false;
|
||||||
|
this.client = null;
|
||||||
|
this.ui = null;
|
||||||
|
this.status = null;
|
||||||
|
this.contacts = [];
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.createSocket = function() {
|
||||||
|
if (this.socket === null) {
|
||||||
|
this.socket = new TxtSocket();
|
||||||
|
this.socket.onError = (function(elem) {
|
||||||
|
return function() {
|
||||||
|
elem.is_connected = false;
|
||||||
|
elem.connect();
|
||||||
|
};
|
||||||
|
})(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.connect = function() {
|
||||||
|
if (!this.is_connected) {
|
||||||
|
this.createSocket();
|
||||||
|
this.socket.connect(this.client.host, this.client.port, (function(elem) {
|
||||||
|
return function() {
|
||||||
|
elem.client.connect(elem, function() {
|
||||||
|
if (elem.is_connected) {
|
||||||
|
elem.daemonize();
|
||||||
|
elem.changeStatus();
|
||||||
|
} else {
|
||||||
|
elem.disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
})(this));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Client.prototype.disconnect = function() {
|
||||||
|
if (this.is_connected) {
|
||||||
|
this.is_connected = false;
|
||||||
|
this.client.disconnect(this);
|
||||||
|
this.socket.disconnect();
|
||||||
|
this.socket = null;
|
||||||
|
}
|
||||||
|
this.changeStatus(this.client.status_disconnected);
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.reconnect = function() {
|
||||||
|
this.disconnect();
|
||||||
|
this.connect();
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.daemonize = function() {
|
||||||
|
this.socket.read((function(elem) {
|
||||||
|
return function(data) {
|
||||||
|
elem.client.recv(elem, data);
|
||||||
|
elem.daemonize();
|
||||||
|
};
|
||||||
|
})(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.changeStatus = function(status) {
|
||||||
|
if (typeof status === 'undefined') {
|
||||||
|
status = this.client.default_status;
|
||||||
|
}
|
||||||
|
if (status !== this.status) {
|
||||||
|
this.status = status;
|
||||||
|
this.updateStatus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.updateStatus = function() {
|
||||||
|
if (this.status !== null) {
|
||||||
|
this.client.changeStatus(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.addContact = function(name) {
|
||||||
|
if (this.is_connected) {
|
||||||
|
this.client.addContact(this, name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.rmContact = function(name) {
|
||||||
|
if (this.is_connected) {
|
||||||
|
this.client.rmContact(this, name);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.speak = function(to, msg) {
|
||||||
|
if (this.is_connected) {
|
||||||
|
this.client.speak(this, to, msg);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Client.prototype.init = function(client, ui) {
|
||||||
|
this.client = client;
|
||||||
|
this.ui = ui;
|
||||||
|
|
||||||
|
this.connect();
|
||||||
|
setInterval((function(elem) {
|
||||||
|
return function() {
|
||||||
|
elem.connect();
|
||||||
|
};
|
||||||
|
})(this), 10000);
|
||||||
|
};
|
|
@ -76,6 +76,7 @@ ContactList.prototype.addContact = function(name) {
|
||||||
this.save();
|
this.save();
|
||||||
this.insertContact(infos);
|
this.insertContact(infos);
|
||||||
}
|
}
|
||||||
|
$cs.client.addContact(name);
|
||||||
};
|
};
|
||||||
|
|
||||||
ContactList.prototype.rmContact = function(name) {
|
ContactList.prototype.rmContact = function(name) {
|
||||||
|
@ -86,6 +87,10 @@ ContactList.prototype.rmContact = function(name) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ContactList.prototype.changeContactStatus = function(name, status) {
|
||||||
|
console.log(name + ' changed his status to ' + status);
|
||||||
|
};
|
||||||
|
|
||||||
ContactList.prototype.save = function() {
|
ContactList.prototype.save = function() {
|
||||||
var i, data = {"contact_list": []};
|
var i, data = {"contact_list": []};
|
||||||
|
|
||||||
|
|
344
lib/ns_client.js
344
lib/ns_client.js
|
@ -15,46 +15,180 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
var NsClient = function() {
|
var NsClient = function() {
|
||||||
this.state = "actif";
|
this.host = 'ns-server.epita.fr';
|
||||||
this.allowed_statuses = ["actif", "away", "idle", "lock"];
|
this.port = 4242;
|
||||||
this.is_connected = false;
|
this.default_status = 'actif';
|
||||||
this.socket = null;
|
this.status_disconnected = 'disconnected';
|
||||||
this.actions = {};
|
this.actions_enabled = ['ping', 'msg', 'status', 'login_out', 'who'];
|
||||||
|
|
||||||
this.actions.ping = {};
|
this.action = {};
|
||||||
this.actions.ping.is = function(msg) {
|
this.action.ping = function(client, str) {
|
||||||
return msg.substr(0, 5) === "ping ";
|
if (str.substr(0, 5) !== 'ping ') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.socket.write(str, function(inf) {});
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
this.actions.ping.act = (function(elem) {
|
|
||||||
return function(msg) {
|
this.action.msg = (function(elem) {
|
||||||
chrome.socket.write(elem.socket, str2ab(msg), function(w_inf) {});
|
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);
|
||||||
|
|
||||||
this.actions.msg = {};
|
this.action.status = (function(elem) {
|
||||||
this.actions.msg.exp = /user_cmd (\d+):user:.*?:(.*?)@(.*?):.*?:(.*?):(.*?) \| msg ([^ ]*)/;
|
return function(client, str) {
|
||||||
this.actions.msg.is = (function(exp) {
|
var mch = /user_cmd (\d+):user:.*?:(.*?)@(.*?):.*?:(.*?):(.*?) \| state ([^ ]*):(\d+)/.exec(str);
|
||||||
return function(msg) {
|
|
||||||
return exp.exec(msg) !== null;
|
|
||||||
};
|
|
||||||
})(this.actions.msg.exp);
|
|
||||||
this.actions.msg.act = (function(elem) {
|
|
||||||
return function(msg) {
|
|
||||||
var mo = {};
|
|
||||||
|
|
||||||
mch = elem.actions.msg.exp.exec(msg);
|
if (mch === null) {
|
||||||
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);
|
$cs.contacts.changeContactStatus(mch[2], this.msgDecode(mch[6])); // TODO: FIX ME!
|
||||||
}
|
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
})(this);
|
})(this);
|
||||||
|
|
||||||
|
this.action.login_out = function(client, str) {
|
||||||
|
var status = null, 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], this.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) {
|
||||||
|
console.log('Debug: ' + data); // TODO: REMOVE ME!
|
||||||
|
for (var i = this.actions_enabled.length - 1; i >= 0; --i) {
|
||||||
|
if (this.action[this.actions_enabled[i]](client, data)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
NsClient.prototype.addContact = function(client, name) {
|
||||||
|
// TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
NsClient.prototype.rmContact = function(client, name) {
|
||||||
|
// TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
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, name) {
|
||||||
|
var msg = 'user_cmd watch_log_user {' + name + '}\n';
|
||||||
|
|
||||||
|
client.socket.write(msg, function(inf) {
|
||||||
|
var msg = 'user_cmd who {' + name + '}\n';
|
||||||
|
console.log('stalking ' + name + ': ' + msg);
|
||||||
|
client.socket.write(msg, function(inf) {});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
NsClient.prototype.rmContact = function(client, name) {
|
||||||
};
|
};
|
||||||
|
|
||||||
NsClient.prototype.replacePairs = function(str, pairs) {
|
NsClient.prototype.replacePairs = function(str, pairs) {
|
||||||
|
@ -68,150 +202,18 @@ NsClient.prototype.replacePairs = function(str, pairs) {
|
||||||
|
|
||||||
NsClient.prototype.msgDecode = function(msg) {
|
NsClient.prototype.msgDecode = function(msg) {
|
||||||
return this.replacePairs(unescape(msg), {
|
return this.replacePairs(unescape(msg), {
|
||||||
"@": /%40/g,
|
'@': /%40/g,
|
||||||
"*": /%2A/g,
|
'*': /%2A/g,
|
||||||
"/": /%2F/g,
|
'/': /%2F/g,
|
||||||
"+": /%2B/g
|
'+': /%2B/g
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
NsClient.prototype.msgEncode = function(msg) {
|
NsClient.prototype.msgEncode = function(msg) {
|
||||||
return this.replacePairs(escape(msg), {
|
return this.replacePairs(escape(msg), {
|
||||||
"%40": /@/g,
|
'%40': /@/g,
|
||||||
"%2A": /\*/g,
|
'%2A': /\*/g,
|
||||||
"%2F": /\//g,
|
'%2F': /\//g,
|
||||||
"%2B": /\+/g,
|
'%2B': /\+/g,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
NsClient.prototype.connect = function() {
|
|
||||||
var login, pwd_socks;
|
|
||||||
|
|
||||||
if (!this.is_connected) {
|
|
||||||
login = $cs.opts.get('login');
|
|
||||||
pwd_socks = $cs.opts.get('pwd_socks');
|
|
||||||
if (login !== null && pwd_socks !== null) {
|
|
||||||
chrome.socket.create('tcp', {}, (function(elem) {
|
|
||||||
return function(sock_inf) {
|
|
||||||
elem.socket = sock_inf.socketId;
|
|
||||||
chrome.socket.connect(elem.socket, "ns-server.epita.fr", 4242, function(res) {
|
|
||||||
chrome.socket.read(elem.socket, null, function(rd_inf) {
|
|
||||||
if (rd_inf.resultCode > 0) {
|
|
||||||
var data = ab2str(rd_inf.data).split(' '),
|
|
||||||
auth = "ext_user_log ";
|
|
||||||
auth += login + " ";
|
|
||||||
auth += hex_md5(data[2] + "-" + data[3] + "/" + data[4] + pwd_socks) + " ";
|
|
||||||
auth += "chromesoul chromesoul\n";
|
|
||||||
chrome.socket.write(elem.socket, str2ab("auth_ag ext_user none none\n"), function(w_inf) {
|
|
||||||
chrome.socket.read(elem.socket, null, function(rd_inf) {
|
|
||||||
if (rd_inf.resultCode > 0) {
|
|
||||||
chrome.socket.write(elem.socket, str2ab(auth), function(w_inf) {
|
|
||||||
chrome.socket.read(elem.socket, null, function(rd_inf) {
|
|
||||||
if (rd_inf.resultCode > 0) {
|
|
||||||
elem.is_connected = true;
|
|
||||||
console.info("connected to the netsoul server");
|
|
||||||
elem.updateStatus();
|
|
||||||
elem.daemonize();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
})(this));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NsClient.prototype.disconnect = function() {
|
|
||||||
if (this.is_connected) {
|
|
||||||
chrome.socket.disconnect(this.socket);
|
|
||||||
this.is_connected = false;
|
|
||||||
console.info("disconnected");
|
|
||||||
this.updateStatus();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NsClient.prototype.daemonize = function() {
|
|
||||||
if (this.is_connected) {
|
|
||||||
chrome.socket.read(this.socket, (function(elem) {
|
|
||||||
return function(rd_inf) {
|
|
||||||
if (rd_inf.resultCode > 0) {
|
|
||||||
var at, data = ab2str(rd_inf.data);
|
|
||||||
|
|
||||||
for (at in elem.actions) {
|
|
||||||
if (elem.actions[at].is(data)) {
|
|
||||||
elem.actions[at].act(data);
|
|
||||||
break ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elem.daemonize();
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* A read error is the only way to know if the remote peer has disconnected.
|
|
||||||
* See <http://developer.chrome.com/apps/socket.html> for more informations.
|
|
||||||
*/
|
|
||||||
elem.disconnect();
|
|
||||||
console.info('connection lost, reconnecting...');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
})(this));
|
|
||||||
} else {
|
|
||||||
console.error("unable to daemonize: not connected");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NsClient.prototype.sendMessage = function(to, message) {
|
|
||||||
var msg = "user_cmd msg_user " + to + " msg " + this.msgEncode(message) + "\n";
|
|
||||||
|
|
||||||
chrome.socket.write(this.socket, str2ab(msg), function(w_inf) {});
|
|
||||||
};
|
|
||||||
|
|
||||||
NsClient.prototype.updateStatus = function() {
|
|
||||||
var status = "disconnected", status_msg = "";
|
|
||||||
|
|
||||||
if (this.is_connected) {
|
|
||||||
status_msg = "user_cmd state ";
|
|
||||||
status = this.state;
|
|
||||||
status_msg += this.state + ":";
|
|
||||||
status_msg += Math.round(new Date().getTime() / 1000) + "\n";
|
|
||||||
chrome.socket.write(this.socket, str2ab(status_msg), function(w_inf) {});
|
|
||||||
}
|
|
||||||
$cs.ui.onUserStatusChange(status);
|
|
||||||
};
|
|
||||||
|
|
||||||
NsClient.prototype.changeStatus = function(new_status) {
|
|
||||||
if (this.is_connected) {
|
|
||||||
if (this.allowed_statuses.indexOf(new_status) !== -1) {
|
|
||||||
this.status = new_status;
|
|
||||||
} else {
|
|
||||||
console.warn("invalid status: " + new_status);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.warn("not connected");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
NsClient.prototype.init = function() {
|
|
||||||
var status_update = function(elem) {
|
|
||||||
return function() {
|
|
||||||
elem.updateStatus();
|
|
||||||
};
|
|
||||||
},
|
|
||||||
connect = function(elem) {
|
|
||||||
return function() {
|
|
||||||
if (!elem.is_connected) {
|
|
||||||
elem.connect();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
status_update(this).apply();
|
|
||||||
setTimeout(connect(this), 500);
|
|
||||||
setInterval(connect(this), 10000);
|
|
||||||
setInterval(status_update(this), 600000);
|
|
||||||
};
|
|
||||||
|
|
12
lib/nsui.js
12
lib/nsui.js
|
@ -20,7 +20,10 @@ var Nsui = function() {
|
||||||
};
|
};
|
||||||
|
|
||||||
Nsui.prototype.setReconnect = function(func) {
|
Nsui.prototype.setReconnect = function(func) {
|
||||||
document.getElementById("user-status").addEventListener("click", func, false);
|
document.getElementById("user-status").addEventListener("click", function() {
|
||||||
|
func();
|
||||||
|
$cs.contacts.restore();
|
||||||
|
}, false);
|
||||||
};
|
};
|
||||||
|
|
||||||
Nsui.prototype.onUserStatusChange = function(new_status) {
|
Nsui.prototype.onUserStatusChange = function(new_status) {
|
||||||
|
@ -179,7 +182,7 @@ Nsui.prototype.sanitizeText = function(str) {
|
||||||
};
|
};
|
||||||
|
|
||||||
Nsui.prototype.showContent = function(part_id) {
|
Nsui.prototype.showContent = function(part_id) {
|
||||||
var i, ctn_lst = ["config-pannel", "chat-pannel", "pre-conf-pannel"];
|
var i, ctn_lst = ["config-pannel", "chat-pannel"];
|
||||||
|
|
||||||
for (i = ctn_lst.length - 1; i>= 0; --i) {
|
for (i = ctn_lst.length - 1; i>= 0; --i) {
|
||||||
if (ctn_lst[i] === part_id) {
|
if (ctn_lst[i] === part_id) {
|
||||||
|
@ -229,9 +232,4 @@ Nsui.prototype.init = function() {
|
||||||
})(this);
|
})(this);
|
||||||
|
|
||||||
this.showContent("chat-pannel");
|
this.showContent("chat-pannel");
|
||||||
setTimeout(function() {
|
|
||||||
if ($cs.opts.get("login") === null || $cs.opts.get("pwd_socks") === null) {
|
|
||||||
$cs.ui.showContent("pre-conf-pannel");
|
|
||||||
}
|
|
||||||
}, 600);
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -73,7 +73,7 @@ Tab.prototype.initBodyElement = function() {
|
||||||
this.value = "";
|
this.value = "";
|
||||||
|
|
||||||
if (typeof $cs.client !== "undefined" && $cs.opts.get("enable_msg")) {
|
if (typeof $cs.client !== "undefined" && $cs.opts.get("enable_msg")) {
|
||||||
$cs.client.sendMessage(elem.name, msg);
|
$cs.client.speak(elem.name, msg);
|
||||||
$cs.ui.addContentToTab(elem.name, {"message": msg});
|
$cs.ui.addContentToTab(elem.name, {"message": msg});
|
||||||
} else {
|
} else {
|
||||||
console.error("chromesoul client not found");
|
console.error("chromesoul client not found");
|
||||||
|
|
91
lib/txt_socket.js
Normal file
91
lib/txt_socket.js
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
0000263103
|
||||||
|
0//
|
||||||
|
// Copyright (c) 2013 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 TxtSocket = function() {
|
||||||
|
this.socket_id = null;
|
||||||
|
this.buffer = '';
|
||||||
|
this.onError = function(infos) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
TxtSocket.prototype.connect = function(host, port, callback) {
|
||||||
|
chrome.socket.create('tcp', {}, (function(elem) {
|
||||||
|
return function(inf) {
|
||||||
|
elem.socket_id = inf.socketId;
|
||||||
|
chrome.socket.connect(elem.socket_id, host, port, callback);
|
||||||
|
};
|
||||||
|
})(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
TxtSocket.prototype.disconnect = function() {
|
||||||
|
if (this.socket_id !== null) {
|
||||||
|
chrome.socket.disconnect(this.socket_id);
|
||||||
|
chrome.socket.destroy(this.socket_id);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TxtSocket.prototype.read = function(callback) {
|
||||||
|
var tmp = '', offset = this.buffer.indexOf("\n");
|
||||||
|
|
||||||
|
if (offset === -1) {
|
||||||
|
chrome.socket.read(this.socket_id, (function(elem) {
|
||||||
|
return function(rd_inf) {
|
||||||
|
if (rd_inf.resultCode > 0) {
|
||||||
|
elem.buffer += elem.ab2str(rd_inf.data);
|
||||||
|
elem.read(callback);
|
||||||
|
} else {
|
||||||
|
elem.throwError({code: rd_inf.resultCode});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(this));
|
||||||
|
} else {
|
||||||
|
tmp = this.buffer.substr(0, offset);
|
||||||
|
this.buffer = this.buffer.substr(offset + 1);
|
||||||
|
callback(tmp);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TxtSocket.prototype.write = function(str, callback) {
|
||||||
|
chrome.socket.write(this.socket_id, this.str2ab(str), (function(elem) {
|
||||||
|
return function(w_inf) {
|
||||||
|
if (w_inf.bytesWritten >= 0) {
|
||||||
|
callback(w_inf);
|
||||||
|
} else {
|
||||||
|
elem.throwError({code: w_inf.bytesWritten});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
})(this));
|
||||||
|
};
|
||||||
|
|
||||||
|
TxtSocket.prototype.throwError = function(infos) {
|
||||||
|
console.error('socket error ' + infos.code + ', shutting it down');
|
||||||
|
this.disconnect();
|
||||||
|
this.onError(infos);
|
||||||
|
};
|
||||||
|
|
||||||
|
TxtSocket.prototype.ab2str = function(buff) {
|
||||||
|
return String.fromCharCode.apply(null, new Uint8Array(buff));
|
||||||
|
};
|
||||||
|
|
||||||
|
TxtSocket.prototype.str2ab = function(str) {
|
||||||
|
var i = 0, buff = new ArrayBuffer(str.length), buff_v = new Uint8Array(buff);
|
||||||
|
|
||||||
|
for (i = str.length - 1; i >= 0; --i) {
|
||||||
|
buff_v[i] = str.charCodeAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return buff;
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "Chromesoul",
|
"name": "Chromesoul",
|
||||||
"version": "0.4.9",
|
"version": "0.5.0",
|
||||||
"minimum_chrome_version": "25",
|
"minimum_chrome_version": "25",
|
||||||
"manifest_version": 2,
|
"manifest_version": 2,
|
||||||
"offline_enabled": false,
|
"offline_enabled": false,
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
},
|
},
|
||||||
"app": {
|
"app": {
|
||||||
"background": {
|
"background": {
|
||||||
"scripts": ["chromesoul.js"]
|
"scripts": ["background.js"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"permissions": [
|
"permissions": [
|
||||||
|
|
21
start.js
21
start.js
|
@ -1,21 +0,0 @@
|
||||||
var chromesoul = (function() {
|
|
||||||
var chromesoul = {
|
|
||||||
"opts": new OptionsManager(),
|
|
||||||
"ui": new Nsui(),
|
|
||||||
"contacts": new ContactList(),
|
|
||||||
"client": new NsClient(),
|
|
||||||
"avatars": new AvatarManager()
|
|
||||||
};
|
|
||||||
|
|
||||||
return (window.chromesoul = window.$cs = chromesoul);
|
|
||||||
})();
|
|
||||||
|
|
||||||
$cs.opts.init();
|
|
||||||
$cs.ui.init();
|
|
||||||
$cs.client.init();
|
|
||||||
$cs.contacts.init();
|
|
||||||
|
|
||||||
$cs.ui.setReconnect(function() {
|
|
||||||
$cs.client.disconnect();
|
|
||||||
$cs.client.connect();
|
|
||||||
});
|
|
21
third-party/ab-str.js
vendored
21
third-party/ab-str.js
vendored
|
@ -1,21 +0,0 @@
|
||||||
//
|
|
||||||
// Renato Mangini
|
|
||||||
// http://updates.html5rocks.com/2012/06/How-to-convert-ArrayBuffer-to-and-from-String
|
|
||||||
// http://stackoverflow.com/questions/6965107/converting-between-strings-and-arraybuffers
|
|
||||||
//
|
|
||||||
// Edited by Rodolphe Breard
|
|
||||||
// - Using Uint8Array instead of Uint16Array
|
|
||||||
//
|
|
||||||
|
|
||||||
function ab2str(buf) {
|
|
||||||
return String.fromCharCode.apply(null, new Uint8Array(buf));
|
|
||||||
}
|
|
||||||
|
|
||||||
function str2ab(str) {
|
|
||||||
var buf = new ArrayBuffer(str.length);
|
|
||||||
var bufView = new Uint8Array(buf);
|
|
||||||
for (var i=0, strLen=str.length; i<strLen; i++) {
|
|
||||||
bufView[i] = str.charCodeAt(i);
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
}
|
|
Reference in a new issue