Permalink
Browse files

Fix length issues when sending long messages

Fixes missing message parts when sending long PRIVMSG lines (incl.
ACTIONs). Also, maintains 'userhost' string through nick and host mask
changes.
  • Loading branch information...
1 parent d3d9ba7 commit fa15d400df9fdf51085f98bce0ce8eeac4a3af3e @qsheets committed Jan 24, 2013
Showing with 39 additions and 12 deletions.
  1. +6 −5 docs/API.rst
  2. +4 −0 lib/codes.js
  3. +29 −7 lib/irc.js
View
@@ -31,7 +31,7 @@ Client
floodProtectionDelay: 1000,
stripColors: false,
channelPrefixes: "&#",
- messageSplit: 512
+ messageLength: 512
}
`secure` (SSL connection) can be a true value or an object (the kind of object
@@ -47,8 +47,9 @@ Client
`floodProtectionDelay` sets the amount of time that the client will wait
between sending subsequent messages when `floodProtection` is enabled.
- `messageSplit` will split up large messages sent with the `say` method
- into multiple messages of length fewer than `messageSplit` characters.
+ `messageLength` sets the character length at which messages sent with `msg` will
+ be split into multiple messages. This value should not be changed unless the
+ server explicitly indicates another value.
`stripColors` removes mirc colors (0x03 followed by one or two ascii
numbers for foreground,background) and ircII "effect" codes (0x02
@@ -348,7 +349,7 @@ Events
.. js:data:: '+mode'
- `function (channel, by, mode, argument, message) { }`
+ `function (channel, by, mode, argument, message) { }`
Emitted when a mode is added to a user or channel. `channel` is the channel
which the mode is being set on/in. `by` is the user setting the mode. `mode`
@@ -360,7 +361,7 @@ Events
.. js:data:: '-mode'
- `function (channel, by, mode, argument, message) { }`
+ `function (channel, by, mode, argument, message) { }`
Emitted when a mode is removed from a user or channel. `channel` is the channel
which the mode is being set on/in. `by` is the user setting the mode. `mode`
View
@@ -315,6 +315,10 @@ module.exports = { // {{{
"name" : "rpl_nousers",
"type" : "reply"
},
+ "396" : {
+ "name" : "rpl_hosthidden",
+ "type" : "reply"
+ },
"401" : {
"name" : "err_nosuchnick",
"type" : "error"
View
@@ -50,9 +50,13 @@ function Client(server, nick, opt) {
floodProtectionDelay: 1000,
stripColors: false,
channelPrefixes: "&#",
- messageSplit: 512
+ messageLength: 512
};
+ // All lines end with CR-LF (2 chars) plus 2 chars for
+ // server provided padding to be safe.
+ self.opt.messageLength -= 4;
+
// Features supported by the server
// (initial values are RFC 1459 defaults. Zeros signify
// no default or unlimited value)
@@ -99,6 +103,7 @@ function Client(server, nick, opt) {
// (normally this is because you chose something too long and
// the server has shortened it
self.nick = message.args[0];
+ self.whois(self.nick, self._setUserhost);
self.emit('registered', message);
break;
case "002":
@@ -263,9 +268,11 @@ function Client(server, nick, opt) {
});
break;
case "NICK":
- if ( message.nick == self.nick )
+ if ( message.nick == self.nick ) {
// the user just changed their own nick
self.nick = message.args[0];
+ self.userhost = self.nick+'!'+self.userhost.split('!')[1];
+ }
if ( self.opt.debug )
util.log("NICK: " + message.nick + " changes nick to " + message.args[0]);
@@ -285,6 +292,9 @@ function Client(server, nick, opt) {
// old nick, new nick, channels
self.emit('nick', message.nick, message.args[0], channels, message);
break;
+ case "rpl_hosthidden":
+ self.userhost = self.userhost.split('@')[0]+'@'+message.args[1];
+ break;
case "rpl_motdstart":
self.motd = message.args[1] + "\n";
break;
@@ -759,25 +769,34 @@ Client.prototype.part = function(channel, callback) { // {{{
Client.prototype.say = function(target, text) { // {{{
var self = this;
if (typeof text !== 'undefined') {
+ var messageSplit = self.opt.messageLength - (12 + target.length + self.userhost.length);
text.toString().split(/\r?\n/).filter(function(line) {
return line.length > 0;
}).forEach(function(line) {
- var r = new RegExp(".{1," + self.opt.messageSplit + "}", "g");
+ var r = new RegExp(".{1," + messageSplit + "}", "g");
while ((messagePart = r.exec(line)) != null) {
self.send('PRIVMSG', target, messagePart[0]);
self.emit('selfMessage', target, messagePart[0]);
}
});
}
} // }}}
-Client.prototype.action = function(channel, text) { // {{{
+Client.prototype.action = function(target, text) { // {{{
var self = this;
if (typeof text !== 'undefined') {
- text.toString().split(/\r?\n/).filter(function(line) {
+ var messageSplit = self.opt.messageLength - (21 + target.length + self.userhost.length);
+ var line = text.toString().split(/\r?\n/).filter(function(line) {
return line.length > 0;
- }).forEach(function(line) {
- self.say(channel, '\u0001ACTION ' + line + '\u0001');
});
+
+ // It would be odd to continue an action over multiple lines as
+ // only the first would appear as an actual action. So that is
+ // all we are sending.
+ if (line[0]) {
+ var r = new RegExp(".{1," + messageSplit + "}");
+ line = r.exec(line[0])[0];
+ self.msg(target, '\1ACTION ' + line + '\1');
+ }
}
} // }}}
Client.prototype.notice = function(target, text) { // {{{
@@ -812,6 +831,9 @@ Client.prototype._clearWhoisData = function(nick) { // {{{
delete this._whoisData[nick];
return data;
} // }}}
+Client.prototype._setUserhost = function(info) { // {{{
+ this.userhost = info.nick+'!'+info.user+'@'+info.host;
+} // }}}
Client.prototype._handleCTCP = function(from, to, text, type) {
text = text.slice(1)
text = text.slice(0, text.indexOf('\1'))

0 comments on commit fa15d40

Please sign in to comment.