|
@@ -1,8 +1,46 @@
|
|
|
-module.exports.connected = connected;
|
|
|
-module.exports.processMessage = processMessage;
|
|
|
-module.exports.processSender = processSender;
|
|
|
-module.exports.setHandlers = setHandlers;
|
|
|
-module.exports.setSettings = setSettings;
|
|
|
+var protocol = {
|
|
|
+ connected: function(){
|
|
|
+ ircSend(null, settings.ID, 'PASS', [settings.password]);
|
|
|
+ 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]);
|
|
|
+ },
|
|
|
+ processMessage: function(msg){
|
|
|
+ if(!msg) return;
|
|
|
+ if(msg.command in cmdBinds){
|
|
|
+ cmdBinds[msg.command](msg);
|
|
|
+ } else {
|
|
|
+ console.log('Unhandled cmd: '+msg.command);
|
|
|
+ console.log(msg);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ processSender: function(sender){
|
|
|
+ if(sender.nick){
|
|
|
+ if(server = handlers.findServer(sender.nick)){
|
|
|
+ sender.nick = server.name;
|
|
|
+ sender.server = server;
|
|
|
+ } else if(user = handlers.findUser(sender.nick)){
|
|
|
+ sender.nick = user.name
|
|
|
+ sender.ident = user.ident;
|
|
|
+ sender.host = user.host;
|
|
|
+ sender.user = user;
|
|
|
+ } else {
|
|
|
+ handlers.killUser(sender.nick);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return sender;
|
|
|
+ },
|
|
|
+ setHandlers: function(newHandlers){
|
|
|
+ handlers = newHandlers;
|
|
|
+ },
|
|
|
+ setSettings: function(newSettings){
|
|
|
+ settings = newSettings;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+module.exports = protocol;
|
|
|
|
|
|
var handlers = {
|
|
|
sendHandler: null,
|
|
@@ -13,6 +51,7 @@ var handlers = {
|
|
|
newUser: null,
|
|
|
parseUmodes: null,
|
|
|
getChannel: null,
|
|
|
+ findChannel: null,
|
|
|
quitUser: null,
|
|
|
removeServer: null
|
|
|
};
|
|
@@ -30,11 +69,20 @@ var settings = {
|
|
|
var connection = {
|
|
|
'protoctl': {},
|
|
|
'prefixes': {},
|
|
|
+ 'statusmodes': [],
|
|
|
'chmodes': [], // 0 - list modes, 1 - argument modes, 2 - argument modes (add only), 3 - standard modes
|
|
|
'umodes': {}
|
|
|
};
|
|
|
|
|
|
var chmodeMap = {
|
|
|
+ 'b': { 'name': 'BAN', 'user': true, 'services': true },
|
|
|
+ 'e': { 'name': 'EXCEPT', 'user': true, 'services': true },
|
|
|
+ 'I': { 'name': 'INVEX', 'user': true, 'services': true },
|
|
|
+ 'v': { 'name': 'VOICE', 'user': true, 'services': true },
|
|
|
+ 'h': { 'name': 'HALFOP', 'user': true, 'services': true },
|
|
|
+ 'o': { 'name': 'OP', 'user': true, 'services': true },
|
|
|
+ 'a': { 'name': 'PROTECT', 'user': true, 'services': true },
|
|
|
+ 'q': { 'name': 'OWNER', 'user': true, 'services': true },
|
|
|
'k': { 'name': 'KEY', 'user': true, 'services': true },
|
|
|
'L': { 'name': 'CHANNELLINK', 'user': true, 'services': true },
|
|
|
'f': { 'name': 'FLOODPROT', 'user': true, 'services': true },
|
|
@@ -70,6 +118,8 @@ function parseChannelModes(modes, args){
|
|
|
var plus = true;
|
|
|
var argIndex = 0;
|
|
|
var output = {};
|
|
|
+ output['status'] = [];
|
|
|
+ output['list'] = [];
|
|
|
for(var i=0; i<modes.length; i++){
|
|
|
var c = modes.charAt(i);
|
|
|
if(c in chmodeMap){
|
|
@@ -82,7 +132,7 @@ function parseChannelModes(modes, args){
|
|
|
} else if(c == '-'){
|
|
|
plus = false;
|
|
|
} else if(connection.chmodes[0].indexOf(c) >= 0){
|
|
|
- throw 'Unexpected list mode';
|
|
|
+ output['list'].push({ 'name': name, 'value': args[argIndex++], 'status': plus });
|
|
|
} else if(connection.chmodes[1].indexOf(c) >= 0){
|
|
|
if(plus){
|
|
|
output[name] = args[argIndex++];
|
|
@@ -96,72 +146,62 @@ function parseChannelModes(modes, args){
|
|
|
} else {
|
|
|
output[name] = false;
|
|
|
}
|
|
|
+ } else if(connection.statusmodes.indexOf(c) >= 0){
|
|
|
+ var user = handlers.findUser(args[argIndex++]);
|
|
|
+ if(user){
|
|
|
+ console.log('Setting status mode for '+user.name);
|
|
|
+ output['status'].push({ 'name': name, 'user': user, 'status': plus });
|
|
|
+ } else {
|
|
|
+ throw 'User not found';
|
|
|
+ }
|
|
|
} else { // treat unknown chars as type 3
|
|
|
+ if(connection.chmodes[3].indexOf(c) < 0){
|
|
|
+ console.log('Unknown mode '+name);
|
|
|
+ }
|
|
|
output[name] = plus;
|
|
|
}
|
|
|
}
|
|
|
+ console.log(output);
|
|
|
return output;
|
|
|
}
|
|
|
|
|
|
function parseModePrefix(text){
|
|
|
- var modes = [];
|
|
|
- for(var i=0; i<text.length; i++){
|
|
|
- var c = text.charAt(i);
|
|
|
- if(c in connection.prefixes){
|
|
|
- modes[connection.prefixes[c]] = true;
|
|
|
- } else break;
|
|
|
- }
|
|
|
- var uid = text.substring(i);
|
|
|
- var user = handlers.findUser(uid);
|
|
|
- if(!user){
|
|
|
- handlers.killUser(uid);
|
|
|
- return null;
|
|
|
- }
|
|
|
- return { 'user': user, 'modes': modes };
|
|
|
-}
|
|
|
-
|
|
|
-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', '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]);
|
|
|
-}
|
|
|
-
|
|
|
-function processSender(sender){
|
|
|
- if(sender.nick){
|
|
|
- if(server = handlers.findServer(sender.nick)){
|
|
|
- sender.nick = server.name;
|
|
|
- sender.server = server;
|
|
|
- } else if(user = handlers.findUser(sender.nick)){
|
|
|
- sender.nick = user.name
|
|
|
- sender.ident = user.ident;
|
|
|
- sender.host = user.host;
|
|
|
- sender.user = user;
|
|
|
- } else {
|
|
|
- handlers.killUser(sender.nick);
|
|
|
- return false;
|
|
|
+ var modes = {'status': [], 'list': [] };
|
|
|
+ var isUser = false;
|
|
|
+ var c = text.charAt(0);
|
|
|
+ if(c == '&'){ // +b
|
|
|
+ modes.list.push({ 'name': 'BAN', 'value': text.substring(1), 'status': true });
|
|
|
+ } else if(c == '"'){ // +e
|
|
|
+ modes.list.push({ 'name': 'EXCEPT', 'value': text.substring(1), 'status': true });
|
|
|
+ } else if(c == '\''){ // +I
|
|
|
+ modes.list.push({ 'name': 'INVEX', 'value': text.substring(1), 'status': true });
|
|
|
+ } else {
|
|
|
+ isUser = true;
|
|
|
+ for(var i=0; i<text.length; i++){
|
|
|
+ c = text.charAt(i);
|
|
|
+ if(c in connection.prefixes){
|
|
|
+ modes.status.push({ 'name': chmodeMap[connection.prefixes[c]].name, 'user': false /* setting it later */, 'status': true });
|
|
|
+ // can be more than 1
|
|
|
+ } else {
|
|
|
+ break;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- return sender;
|
|
|
-}
|
|
|
|
|
|
-function processMessage(msg){
|
|
|
- if(!msg) return;
|
|
|
- if(msg.command in cmdBinds){
|
|
|
- cmdBinds[msg.command](msg);
|
|
|
- } else {
|
|
|
- console.log('Unhandled cmd: '+msg.command);
|
|
|
- console.log(msg);
|
|
|
+ var user = null;
|
|
|
+ if(isUser){
|
|
|
+ var uid = text.substring(i);
|
|
|
+ user = handlers.findUser(uid);
|
|
|
+ if(!user){
|
|
|
+ handlers.killUser(uid);
|
|
|
+ modes.status = [];
|
|
|
+ }
|
|
|
+ for(var i=0; i<modes.status.length; i++){
|
|
|
+ modes.status[i].user = user;
|
|
|
+ }
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
-function setHandlers(newHandlers){
|
|
|
- handlers = newHandlers;
|
|
|
-}
|
|
|
-
|
|
|
-function setSettings(newSettings){
|
|
|
- settings = newSettings;
|
|
|
+ return { 'modes': modes, 'user': user };
|
|
|
}
|
|
|
|
|
|
function ircSend(tags, from, cmd, args){
|
|
@@ -182,6 +222,7 @@ var cmdBinds = {
|
|
|
var chars = data[1].split('');
|
|
|
for(var i=0; i<modes.length; i++){
|
|
|
connection.prefixes[chars[i]] = modes[i];
|
|
|
+ connection.statusmodes.push(modes[i]);
|
|
|
}
|
|
|
break;
|
|
|
case 'CHANMODES':
|
|
@@ -229,6 +270,7 @@ var cmdBinds = {
|
|
|
},
|
|
|
|
|
|
'EOS': function(msg){ // ?
|
|
|
+ console.log(connection);
|
|
|
},
|
|
|
|
|
|
'SINFO': function(msg){
|
|
@@ -283,28 +325,23 @@ var cmdBinds = {
|
|
|
'SJOIN': function(msg){
|
|
|
var channel = handlers.getChannel(msg.args[1]);
|
|
|
channel.setTS(msg.args[0]);
|
|
|
- var modeArgs = [];
|
|
|
- for(var i=3; i<msg.args.length - 1; i++){
|
|
|
- modeArgs.push(msg.args[i]);
|
|
|
+ if(msg.args.length > 3){
|
|
|
+ var modeArgs = [];
|
|
|
+ for(var i=3; i<msg.args.length - 1; i++){
|
|
|
+ modeArgs.push(msg.args[i]);
|
|
|
+ }
|
|
|
+ channel.changeModes(parseChannelModes(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];
|
|
|
var c = member.charAt(0);
|
|
|
- if(c == '&'){ // +b
|
|
|
- channel.addBan(member.substring(1));
|
|
|
- } else if(c == '"'){ // +e
|
|
|
- channel.addExcept(member.substring(1));
|
|
|
- } else if(c == '\''){ // +I
|
|
|
- channel.addInvex(member.substring(1));
|
|
|
- } else {
|
|
|
- var udata = parseModePrefix(member);
|
|
|
- if(!udata) return;
|
|
|
+ var udata = parseModePrefix(member);
|
|
|
+ if(udata.user){
|
|
|
console.log(udata.user.name + ' joined ' + msg.args[1]);
|
|
|
channel.joinUser(udata.user);
|
|
|
- channel.setStatusModes(udata.user, udata.modes);
|
|
|
}
|
|
|
+ channel.changeModes(udata.modes);
|
|
|
}
|
|
|
},
|
|
|
|
|
@@ -318,8 +355,43 @@ var cmdBinds = {
|
|
|
console.log(msg);
|
|
|
//TODO
|
|
|
},
|
|
|
-
|
|
|
+/*messagedata {
|
|
|
+ text: '1584206946',
|
|
|
+ args: [ '#qwer', '+nt', '1584206946' ],
|
|
|
+ tags: [
|
|
|
+ time: '2020-03-14T17:29:07.017Z',
|
|
|
+ msgid: '0AnsVOjKaaFGxoaANiChIo-Uqo0dqr9WjGPgUEgGzdr3w'
|
|
|
+ ],
|
|
|
+ command: 'MODE',
|
|
|
+ sender: {
|
|
|
+ nick: 'test3.pirc.pl',
|
|
|
+ ident: '',
|
|
|
+ host: '',
|
|
|
+ server: server {
|
|
|
+ name: 'test3.pirc.pl',
|
|
|
+ sid: '143',
|
|
|
+ description: 'serwer testowy!',
|
|
|
+ distance: '1',
|
|
|
+ uplink: [server],
|
|
|
+ introduce: [Function]
|
|
|
+ },
|
|
|
+ user: false
|
|
|
+ },
|
|
|
+ time: 2020-03-14T17:29:07.021Z,
|
|
|
+ reply: [Function],
|
|
|
+ originalString: '@time=2020-03-14T17:29:07.017Z;msgid=0AnsVOjKaaFGxoaANiChIo-Uqo0dqr9WjGPgUEgGzdr3w :143 MODE #qwer +nt 1584206946'
|
|
|
+}
|
|
|
+*/
|
|
|
'MODE': function(msg){
|
|
|
+ var channel = handlers.findChannel(msg.args[0]);
|
|
|
+ if(channel){
|
|
|
+ var modeArgs = [];
|
|
|
+ for(var i=2; i<msg.args.length; i++){
|
|
|
+ modeArgs.push(msg.args[i]);
|
|
|
+ }
|
|
|
+ var chmodes = parseChannelModes(msg.args[1], modeArgs);
|
|
|
+ channel.changeModes(chmodes);
|
|
|
+ }
|
|
|
console.log(msg);
|
|
|
//TODO
|
|
|
},
|