Explorar el Código

Now sending message tags.
Re-introducing own users when killed.

k4be hace 5 años
padre
commit
73ae9413e7
Se han modificado 5 ficheros con 104 adiciones y 27 borrados
  1. 2 0
      channel.js
  2. 56 7
      irc.js
  3. 24 18
      protocol/unrealircd.js
  4. 8 2
      services.js
  5. 14 0
      user.js

+ 2 - 0
channel.js

@@ -58,6 +58,7 @@ var channel = function(){
 		if(this.users.indexOf(user) >= 0) return;
 		this.users.push(user);
 		this.statusModes[user.uid] = {};
+		user.joinChannel(this);
 		this.events.doEvent('channelJoin', this, user);
 	};
 	
@@ -67,6 +68,7 @@ var channel = function(){
 		}
 		for(var i=0; i<this.users.length; i++){
 			if(this.users[i] == user){
+				user.leaveChannel(this);
 				this.users.splice(i, 1);
 				this.events.doEvent('channelLeave', this, user);
 				break;

+ 56 - 7
irc.js

@@ -24,6 +24,24 @@ function addInternalEvents(){
 			irc.uplink.syncChannel(channels[i]);
 		}
 	});
+	events.newTagMessage.unshift(function(inputTags, newTags, msg){
+		if(!newTags){
+			var newTags = {};
+		}
+		if('label' in inputTags) newTags['label'] = inputTags['label']; // labeled-response
+		newTags['time'] = new Date().toISOString(); // server-time
+		newTags['msgid'] = randomID('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz', 22);
+		return [inputTags, newTags, msg];
+	});
+}
+
+function randomID(characters, length){
+	var result = '';
+	var charactersLength = characters.length;
+	for(var i=0; i<length; i++ ) {
+		result += characters.charAt(Math.floor(Math.random() * charactersLength));
+	}
+	return result;
 }
 
 function findServer(s){
@@ -169,8 +187,25 @@ function ircDataReceived(data){
 }
 
 function makeTagsString(tags){
-	return '';
-	//TODO
+	if(!irc.uplink.supportsTags) return '';
+	if(!tags) return '';
+	var tagText = '';
+	for(name in tags){
+		var value = tags[name].replace(/;/g, '\\:').replace(/ /g, '\\s').replace(/\\/g, '\\\\').replace(/\n/g, '\\n').replace(/\r/g, '\\r');
+		if(tagText.length == 0){
+			tagText += '@';
+		} else {
+			tagText += ';';
+		}
+		tagText += name;
+		if(value.length > 0){
+			tagText += '=' + value;
+		}
+	}
+	if(tagText.length > 0){
+		tagText += ' ';
+	}
+	return tagText;
 }
 
 function ircMessage(data){
@@ -184,12 +219,24 @@ function ircConnectionClosed(e){
 	process.exit(1);
 }
 
-function processReplyTags(inputTags, newTags){
-	return newTags;
-	// TODO
+function processReplyTags(inputTags, newTags, msg){
+	newTags = events.doEvent('newTagMessage', inputTags, newTags, msg);
+	return newTags[1];
+}
+
+function newTags(newTags){
+	return events.doEvent('newTagMessage', {}, newTags, null)[1];
 }
 
 function quitUser(user){
+	if(user.uplink == me){ // out bot was killed?
+		console.log('Tried to kill ' + user.name + '!');
+		irc.uplink.introduceUser(user); // re-introduce
+		for(var i=0; i<user.channels.length; i++){
+			irc.uplink.joinChannel(user, user.channels[i]);
+		}
+		return;
+	}
 	console.log('Removing user '+user.name);
 	for(var i=0; i<channels.length; i++){
 		channels[i].removeUser(user);
@@ -244,7 +291,9 @@ var irc = {
 			getChannel: getChannel,
 			quitUser: quitUser,
 			removeServer: removeServer,
-			findChannel: findChannel
+			findChannel: findChannel,
+			randomID: randomID,
+			newTags: newTags
 		});
 		irc.uplink.setSettings({
 			ID: me.sid,
@@ -288,7 +337,7 @@ var irc = {
 		};
 		this.time = new Date();
 		this.reply = function(tags, cmd, args){
-			var outTags = processReplyTags(this.tags, tags);
+			var outTags = processReplyTags(this.tags, tags, this);
 			ircSendData(outTags, this.sender.nick, cmd, args);
 		}
 		this.originalString = '';

+ 24 - 18
protocol/unrealircd.js

@@ -1,10 +1,11 @@
 var protocol = {
+	supportsTags: false,
 	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]);
+		ircSend(handlers.newTags(), settings.ID, 'PASS', [settings.password]);
+		ircSend(handlers.newTags(), settings.ID, 'PROTOCTL', ['NICKv2', 'VHP', 'UMODE2', 'NICKIP', 'SJOIN', 'SJOIN2', 'SJ3', 'NOQUIT', 'TKLEXT', 'MLOCK', 'SID', 'MTAGS']);
+		ircSend(handlers.newTags(), settings.ID, 'PROTOCTL', ['EAUTH=' + settings.name + ',,,' + settings.version]);
+		ircSend(handlers.newTags(), settings.ID, 'PROTOCTL', ['SID=' + settings.ID]);
+		ircSend(handlers.newTags(), settings.ID, 'SERVER', [settings.name, '1', settings.description]);
 	},
 	processMessage: function(msg){
 		if(!msg) return;
@@ -68,7 +69,7 @@ var protocol = {
 		}
 		var realname = user.realname;
 		var args = [nick, distance, TS, ident, host, uid, account, umodes, vhost, cloakedHost, ip, realname];
-		ircSend(null, settings.ID, 'UID', args);
+		ircSend(handlers.newTags(), settings.ID, 'UID', args);
 	},
 	syncChannel: function(channel){
 		var modes = null;
@@ -135,7 +136,7 @@ var protocol = {
 			if(modes) args.push(modes); else args.push('+');
 			if(modeArgs) args.push(modeArgs);
 			args.push(text);
-			ircSend(null, settings.ID, 'SJOIN', args);
+			ircSend(handlers.newTags(), settings.ID, 'SJOIN', args);
 		} while(true);
 	},
 	'makeUid': function(){
@@ -143,24 +144,24 @@ var protocol = {
 	},
 	'changeUmodes': function(user, umodes){
 		if(user.uplink == settings.me){ // services bot
-			ircSend(null, user.uid, 'UMODE2', [makeUmodeString(umodes, true)]);
+			ircSend(handlers.newTags(), user.uid, 'UMODE2', [makeUmodeString(umodes, true)]);
 		} else { // normal user
-			ircSend(null, settings.ID, 'SVS2MODE', [user.uid, makeUmodeString(umodes, false)]);
+			ircSend(handlers.newTags(), settings.ID, 'SVS2MODE', [user.uid, makeUmodeString(umodes, false)]);
 		}
 		user.changeUmodes(umodes);
+	},
+	'joinChannel': function(user, channel){
+		ircSend(handlers.newTags(), settings.ID, 'SJOIN', [Math.floor(new Date() / 1000).toString(10), channel.name, user.uid]);
+		channel.joinUser(user);
 	}
 }
+//>>> @time=2020-03-17T08:14:32.290Z;msgid=uwGzT2VzSTEEGab0demOxX :093 SJOIN 1584303585 #test :0931Y7O8W
 //>>> @time=2020-03-15T12:17:07.355Z;msgid=FhjgUp20YBKQ32TGPM28tS :143 SJOIN 1580651090 #help +nt :0931Y7O8W 093375CFR 123VTY20R
 
 function randomID(){
-	var result = '';
 	var length = 6;
 	var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
-	var charactersLength = characters.length;
-	for(var i=0; i<length; i++ ) {
-		result += characters.charAt(Math.floor(Math.random() * charactersLength));
-	}
-	return result;
+	return handlers.randomID(characters, length);
 }
 
 module.exports = protocol;
@@ -175,7 +176,8 @@ var handlers = {
 	getChannel: null,
 	findChannel: null,
 	quitUser: null,
-	removeServer: null
+	removeServer: null,
+	randomID: null
 };
 
 var settings = {
@@ -423,9 +425,13 @@ var cmdBinds = {
 						break;						
 				}
 			} else {
+				switch(arg){
+					case 'MTAGS': protocol.supportsTags = true; break;
+				}
 				connection.protoctl[arg] = true;
 			}
 		}
+		console.log(protocol);
 	},
 	
 	'SERVER': function(msg){
@@ -437,7 +443,7 @@ var cmdBinds = {
 			throw 'Unknown SERVER message';
 		}
 		events.doEvent('netSynced');
-		ircSend(null, settings.ID, 'EOS');
+		ircSend(handlers.newTags(), settings.ID, 'EOS');
 	},
 	
 	'MD': function(msg){
@@ -589,7 +595,7 @@ var cmdBinds = {
 	},
 	
 	'NETINFO': function(msg){
-		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]]);
+		ircSend(handlers.newTags(), 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){

+ 8 - 2
services.js

@@ -14,6 +14,8 @@ var events = {
 	'channelCreate': [],
 
 	'netSynced': [],
+	
+	'newTagMessage': [],
 
 	'serverDelete': [],
 	'serverCreate': [],
@@ -30,10 +32,14 @@ var events = {
 	'userUmode': [],
 	'userMetadata': [],
 
-	'doEvent': function(event, args){
+	'doEvent': function(event){
+		var args = new Array(arguments.length - 1);
+		for(var i=1; i<arguments.length; i++){
+			args[i-1] = arguments[i];
+		}
 		if(event in events){
 			for(var i=0; i<events[event].length; i++){
-				args = events[event][i](args);
+				args = events[event][i].apply(null, args);
 			}
 		} else {
 			console.log('Called unknown event '+event);

+ 14 - 0
user.js

@@ -16,6 +16,7 @@ var user = function(){
 	this.certfp = null;
 	this.vident = null;
 	this.metadata = {};
+	this.channels = [];
 	
 	this.events = {};
 
@@ -84,6 +85,19 @@ var user = function(){
 		}
 		this.events.doEvent('userMetadata', this, name);
 	}
+	
+	this.joinChannel = function(channel){
+		if(this.channels.indexOf(channel) < 0) this.channels.push(channel);
+	}
+	
+	this.leaveChannel = function(channel){
+		for(var i=0; i<this.channels.length; i++){
+			if(this.channels[i] == channel){
+				this.channels.splice(i, 1);
+				break;
+			}
+		}
+	}
 }
 
 module.exports = user;