|
@@ -13,7 +13,8 @@ var handlers = {
|
|
|
newUser: null,
|
|
|
parseUmodes: null,
|
|
|
getChannel: null,
|
|
|
- quitUser: null
|
|
|
+ quitUser: null,
|
|
|
+ removeServer: null
|
|
|
};
|
|
|
|
|
|
var settings = {
|
|
@@ -26,20 +27,88 @@ var settings = {
|
|
|
maxUsers: null
|
|
|
};
|
|
|
|
|
|
-var prefixes = {
|
|
|
- '~': 'q',
|
|
|
- '&': 'a',
|
|
|
- '@': 'o',
|
|
|
- '%': 'h',
|
|
|
- '+': 'v'
|
|
|
+var connection = {
|
|
|
+ 'protoctl': {},
|
|
|
+ 'prefixes': {},
|
|
|
+ 'chmodes': [], // 0 - list modes, 1 - argument modes, 2 - argument modes (add only), 3 - standard modes
|
|
|
+ 'umodes': {}
|
|
|
};
|
|
|
|
|
|
+var chmodeMap = {
|
|
|
+ 'k': { 'name': 'KEY', 'user': true, 'services': true },
|
|
|
+ 'L': { 'name': 'CHANNELLINK', 'user': true, 'services': true },
|
|
|
+ 'f': { 'name': 'FLOODPROT', 'user': true, 'services': true },
|
|
|
+ 'l': { 'name': 'LIMIT', 'user': true, 'services': true },
|
|
|
+ 'H': { 'name': 'HISTORY', 'user': true, 'services': true },
|
|
|
+ 'p': { 'name': 'PRIVATE', 'user': true, 'services': true },
|
|
|
+ 's': { 'name': 'SECRET', 'user': true, 'services': true },
|
|
|
+ 'm': { 'name': 'MODERATED', 'user': true, 'services': true },
|
|
|
+ 'n': { 'name': 'NOEXTERNAL', 'user': true, 'services': true },
|
|
|
+ 't': { 'name': 'TOPIC', 'user': true, 'services': true },
|
|
|
+ 'i': { 'name': 'INVITE', 'user': true, 'services': true },
|
|
|
+ 'r': { 'name': 'REGISTERED', 'user': false, 'services': true },
|
|
|
+ 'z': { 'name': 'SECUREONLY', 'user': true, 'services': true },
|
|
|
+ 'M': { 'name': 'NONREGMODERATED', 'user': true, 'services': true },
|
|
|
+ 'Q': { 'name': 'NOKICK', 'user': true, 'services': true },
|
|
|
+ 'N': { 'name': 'NONICK', 'user': true, 'services': true },
|
|
|
+ 'R': { 'name': 'NONREGINVITE', 'user': true, 'services': true },
|
|
|
+ 'T': { 'name': 'NOCTCPS', 'user': true, 'services': true },
|
|
|
+ 'O': { 'name': 'OPERS', 'user': false, 'services': true },
|
|
|
+ 'V': { 'name': 'NOINVITE', 'user': true, 'services': true },
|
|
|
+ 'K': { 'name': 'NOKNOCK', 'user': true, 'services': true },
|
|
|
+ 'D': { 'name': 'OLDDELAYJOIN', 'user': false, 'services': false },
|
|
|
+ 'd': { 'name': 'DELAYJOIN', 'user': true, 'services': true },
|
|
|
+ 'G': { 'name': 'CENSOR', 'user': true, 'services': true },
|
|
|
+ 'P': { 'name': 'PERMANENT', 'user': false, 'services': true },
|
|
|
+ 'Z': { 'name': 'SECURE', 'user': false, 'services': false },
|
|
|
+ 'S': { 'name': 'COLORFILTER', 'user': true, 'services': true },
|
|
|
+ 'C': { 'name': 'NOCTCP', 'user': true, 'services': true },
|
|
|
+ 'c': { 'name': 'NOCOLOR', 'user': true, 'services': true }
|
|
|
+};
|
|
|
+
|
|
|
+function parseChannelModes(modes, args){
|
|
|
+ var plus = true;
|
|
|
+ var argIndex = 0;
|
|
|
+ var output = {};
|
|
|
+ for(var i=0; i<modes.length; i++){
|
|
|
+ var c = modes.charAt(i);
|
|
|
+ if(c in chmodeMap){
|
|
|
+ var name = chmodeMap[c].name;
|
|
|
+ } else {
|
|
|
+ var name = c;
|
|
|
+ }
|
|
|
+ if(c == '+'){
|
|
|
+ plus = true;
|
|
|
+ } else if(c == '-'){
|
|
|
+ plus = false;
|
|
|
+ } else if(connection.chmodes[0].indexOf(c) >= 0){
|
|
|
+ throw 'Unexpected list mode';
|
|
|
+ } else if(connection.chmodes[1].indexOf(c) >= 0){
|
|
|
+ if(plus){
|
|
|
+ output[name] = args[argIndex++];
|
|
|
+ } else {
|
|
|
+ output[name] = false;
|
|
|
+ argIndex++;
|
|
|
+ }
|
|
|
+ } else if(connection.chmodes[2].indexOf(c) >= 0){
|
|
|
+ if(plus){
|
|
|
+ output[name] = args[argIndex++];
|
|
|
+ } else {
|
|
|
+ output[name] = false;
|
|
|
+ }
|
|
|
+ } else { // treat unknown chars as type 3
|
|
|
+ output[name] = plus;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return output;
|
|
|
+}
|
|
|
+
|
|
|
function parseModePrefix(text){
|
|
|
var modes = [];
|
|
|
for(var i=0; i<text.length; i++){
|
|
|
var c = text.charAt(i);
|
|
|
- if(c in prefixes){
|
|
|
- modes[prefixes[c]] = true;
|
|
|
+ if(c in connection.prefixes){
|
|
|
+ modes[connection.prefixes[c]] = true;
|
|
|
} else break;
|
|
|
}
|
|
|
var uid = text.substring(i);
|
|
@@ -53,7 +122,7 @@ function parseModePrefix(text){
|
|
|
|
|
|
function connected(){
|
|
|
ircSend(null, settings.ID, 'PASS', [settings.password]);
|
|
|
- ircSend(null, settings.ID, 'PROTOCTL', ['NICKv2', 'VHP', 'UMODE2', 'NICKIP', 'SJOIN', 'SJOIN2', 'SJ3', 'NOQUIT', 'TKLEXT', 'MLOCK', 'SID']);
|
|
|
+ ircSend(null, settings.ID, 'PROTOCTL', ['NICKv2', 'VHP', 'UMODE2', 'NICKIP', 'SJOIN', 'SJOIN2', 'SJ3', 'NOQUIT', 'TKLEXT', 'MLOCK', 'SID', 'MTAGS']);
|
|
|
ircSend(null, settings.ID, 'PROTOCTL', ['EAUTH=' + settings.name + ',,,' + settings.version]);
|
|
|
ircSend(null, settings.ID, 'PROTOCTL', ['SID=' + settings.ID]);
|
|
|
ircSend(null, settings.ID, 'SERVER', [settings.name, '1', settings.description]);
|
|
@@ -101,8 +170,31 @@ function ircSend(tags, from, cmd, args){
|
|
|
|
|
|
var cmdBinds = {
|
|
|
'PROTOCTL': function(msg){
|
|
|
- //TODO parse
|
|
|
- console.log(msg);
|
|
|
+ for(var i=0; i<msg.args.length; i++){
|
|
|
+ var arg = msg.args[i];
|
|
|
+ if(arg.indexOf('=') >= 0){
|
|
|
+ var arg = arg.split('=');
|
|
|
+ connection.protoctl[arg[0]] = arg[1];
|
|
|
+ switch(arg[0]){
|
|
|
+ case 'PREFIX':
|
|
|
+ var data = arg[1].substring(1).split(')');
|
|
|
+ var modes = data[0].split('');
|
|
|
+ var chars = data[1].split('');
|
|
|
+ for(var i=0; i<modes.length; i++){
|
|
|
+ connection.prefixes[chars[i]] = modes[i];
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case 'CHANMODES':
|
|
|
+ connection.chmodes = arg[1].split(',');
|
|
|
+ break;
|
|
|
+ case 'USERMODES':
|
|
|
+ connection.umodes = arg[1];
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ connection.protoctl[arg] = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
},
|
|
|
|
|
|
'SERVER': function(msg){
|
|
@@ -144,7 +236,7 @@ var cmdBinds = {
|
|
|
},
|
|
|
|
|
|
'SID': function(msg){
|
|
|
- handlers.newServer(msg.args[0], msg.args[2], msg.args[3], msg.args[1], msg.sender);
|
|
|
+ handlers.newServer(msg.args[0], msg.args[2], msg.args[3], msg.args[1], msg.sender.server);
|
|
|
},
|
|
|
|
|
|
'UID': function(msg){
|
|
@@ -162,7 +254,6 @@ var cmdBinds = {
|
|
|
var realname = msg.args[11];
|
|
|
if(ip != '*'){
|
|
|
var ipBinary = Buffer.from(ip, 'base64');
|
|
|
- console.log(ipBinary);
|
|
|
if(ipBinary.byteLength == 4){ // IPv4
|
|
|
ip = ipBinary[0].toString(10) + '.' + ipBinary[1].toString(10) + '.' + ipBinary[2].toString(10) + '.' + ipBinary[3].toString(10);
|
|
|
} else if(ipBinary.byteLength == 16){ // IPv6
|
|
@@ -196,7 +287,7 @@ var cmdBinds = {
|
|
|
for(var i=3; i<msg.args.length - 1; i++){
|
|
|
modeArgs.push(msg.args[i]);
|
|
|
}
|
|
|
- channel.addModes(msg.args[2], modeArgs);
|
|
|
+ channel.addModes(parseChannelModes(msg.args[2], modeArgs));
|
|
|
var members = msg.text.split(' ');
|
|
|
for(var i=0; i<members.length; i++){
|
|
|
var member = members[i];
|
|
@@ -215,30 +306,40 @@ var cmdBinds = {
|
|
|
channel.setStatusModes(udata.user, udata.modes);
|
|
|
}
|
|
|
}
|
|
|
- console.log(channel);
|
|
|
+ },
|
|
|
+
|
|
|
+ 'SENDUMODE': function(msg){ // ignore
|
|
|
+ },
|
|
|
+
|
|
|
+ 'PASS': function(msg){ // ignore
|
|
|
},
|
|
|
|
|
|
'SWHOIS': function(msg){
|
|
|
+ console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
|
|
|
'MODE': function(msg){
|
|
|
+ console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
|
|
|
'TKL': function(msg){
|
|
|
+// console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
|
|
|
'METADATA': function(msg){
|
|
|
+ console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
|
|
|
'NETINFO': function(msg){
|
|
|
- ircSend(null, null, [settings.maxUsers, Math.floor(new Date() / 1000), msg.args[2], msg.args[3], "0", "0", "0", msg.args[7]]);
|
|
|
+ ircSend(null, null, 'NETINFO', [settings.maxUsers.toString(10), Math.floor(new Date() / 1000).toString(10), msg.args[2], msg.args[3], "0", "0", "0", msg.args[7]]);
|
|
|
},
|
|
|
|
|
|
'SASL': function(msg){
|
|
|
+ console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
|
|
@@ -278,23 +379,72 @@ var cmdBinds = {
|
|
|
},
|
|
|
|
|
|
'SETHOST': function(msg){
|
|
|
+ console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
|
|
|
'SETIDENT': function(msg){
|
|
|
+ console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
|
|
|
'NICK': function(msg){
|
|
|
- //TODO
|
|
|
+ msg.sender.user.changeNick(msg.args[0]);
|
|
|
},
|
|
|
|
|
|
'SDESC': function(msg){
|
|
|
+ console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
|
|
|
'TOPIC': function(msg){
|
|
|
+ console.log(msg);
|
|
|
+ //TODO
|
|
|
+ },
|
|
|
+/*
|
|
|
+messagedata {
|
|
|
+ text: '0',
|
|
|
+ args: [ '183.89.186.94', '0' ],
|
|
|
+ tags: [],
|
|
|
+ command: 'REPUTATION',
|
|
|
+ sender: {
|
|
|
+ nick: 'test1.pirc.pl',
|
|
|
+ ident: '',
|
|
|
+ host: '',
|
|
|
+ server: server {
|
|
|
+ name: 'test1.pirc.pl',
|
|
|
+ sid: '093',
|
|
|
+ description: 'serwer testowy!',
|
|
|
+ distance: '3',
|
|
|
+ uplink: [Object],
|
|
|
+ introduce: [Function]
|
|
|
+ },
|
|
|
+ user: false
|
|
|
+ },
|
|
|
+ time: 2020-03-14T10:48:06.207Z,
|
|
|
+ reply: [Function],
|
|
|
+ originalString: ':093 REPUTATION 183.89.186.94 0'
|
|
|
+}
|
|
|
+*/
|
|
|
+ 'REPUTATION': function(msg){
|
|
|
+ //TODO
|
|
|
+ },
|
|
|
+
|
|
|
+ 'UMODE2': function(msg){
|
|
|
+ console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
+
|
|
|
+ 'KILL': function(msg){
|
|
|
+ var user = handlers.findUser(msg.args[0]);
|
|
|
+ if(!user) return;
|
|
|
+ handlers.quitUser(user);
|
|
|
+ },
|
|
|
+
|
|
|
+ 'SQUIT': function(msg){
|
|
|
+ var server = handlers.findServer(msg.args[0]);
|
|
|
+ if(!server) return;
|
|
|
+ handlers.removeServer(server);
|
|
|
+ }
|
|
|
};
|
|
|
|