Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix length issues when sending long messages #142

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 7 additions & 6 deletions docs/API.rst
Expand Up @@ -32,7 +32,7 @@ Client
sasl: false,
stripColors: false,
channelPrefixes: "&#",
messageSplit: 512
messageLength: 512
}

`secure` (SSL connection) can be a true value or an object (the kind of object
Expand All @@ -51,14 +51,15 @@ Client
Set `sasl` to true to enable SASL support. You'll also want to set `nick`,
`userName`, and `password` for authentication.

`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
bold, 0x1f underline, 0x16 reverse, 0x0f reset) from the entire
message before parsing it and passing it along.

`messageSplit` will split up large messages sent with the `say` method
into multiple messages of length fewer than `messageSplit` characters.

Setting `autoConnect` to false prevents the Client from connecting on
instantiation. You will need to call `connect()` on the client instance::

Expand Down Expand Up @@ -356,7 +357,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`
Expand All @@ -368,7 +369,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`
Expand Down
4 changes: 4 additions & 0 deletions lib/codes.js
Expand Up @@ -335,6 +335,10 @@ module.exports = { // {{{
"name" : "rpl_nousers",
"type" : "reply"
},
"396" : {
"name" : "rpl_hosthidden",
"type" : "reply"
},
"401" : {
"name" : "err_nosuchnick",
"type" : "error"
Expand Down
45 changes: 35 additions & 10 deletions lib/irc.js
Expand Up @@ -51,9 +51,13 @@ function Client(server, nick, opt) {
sasl: false,
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)
Expand Down Expand Up @@ -100,6 +104,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 "rpl_myinfo":
Expand Down Expand Up @@ -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]);
Expand All @@ -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;
Expand Down Expand Up @@ -784,33 +794,45 @@ Client.prototype.part = function(channel, message, callback) { // {{{
}

if (message) {
this.send('PART', channel, message);
this.send('PART', channel, message);
} else {
this.send('PART', channel);
this.send('PART', channel);
}
} // }}}
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]) {
if (line[1]) {
util.log("\033[01;31mWARNING: Action over multiple lines, only first line used.\033[0m");
}
var r = new RegExp(".{1," + messageSplit + "}");
line = r.exec(line[0])[0];
self.msg(target, '\1ACTION ' + line + '\1');
}
}
} // }}}
Client.prototype.notice = function(target, text) { // {{{
Expand Down Expand Up @@ -845,6 +867,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, message) {
text = text.slice(1)
text = text.slice(0, text.indexOf('\1'))
Expand Down