Channel case-sensitivity issues. Main cause of "Cannot call method 'clientEvent'...
[KiwiIRC.git] / server / irc / channel.js
index 1d47dbdc29e5634a125941f96180a50baf52b270..2226828a0372d1a49b44b3946af723867929330c 100644 (file)
+var util        = require('util'),
+    EventBinder = require('./eventbinder.js'),
+    IrcUser     = require('./user.js');
+
+var IrcChannel = function(irc_connection, name) {
+    this.irc_connection = irc_connection;
+
+    // Lowercase the channel name so we don't run into case-sensitive issues
+    this.name = name.toLowerCase();
+
+    this.members = [];
+    this.ban_list_buffer = [];
+
+    // Listen for events on the IRC connection
+    this.irc_events = {
+        join:           onJoin,
+        part:           onPart,
+        kick:           onKick,
+        quit:           onQuit,
+        privmsg:        onMsg,
+        notice:         onNotice,
+        ctcp_request:   onCtcpRequest,
+        ctcp_response:  onCtcpResponse,
+        topic:          onTopic,
+        userlist:       onNicklist,
+        userlist_end:   onNicklistEnd,
+        banlist:        onBanList,
+        banlist_end:    onBanListEnd,
+        topicsetby:     onTopicSetBy,
+        mode:           onMode,
+        info:           onChannelInfo
+    };
+    EventBinder.bindIrcEvents('channel ' + this.name, this.irc_events, this, irc_connection);
+};
 
-function IrcChannel(irc_connection, name) {
-    var that = this;
 
-       this.irc_connection = irc_connection;
-       this.name = name;
+module.exports = IrcChannel;
 
-       // Helper for binding listeners
-       function bindEvent(event, fn) {
-               irc_connection.on('channel:' + name + ':' + event, function () {
-            fn.apply(that, arguments);
-        });
-       }
 
-       bindEvent('join', this.onJoin);
-       bindEvent('part', this.onPart);
-       bindEvent('kick', this.onKick);
-       bindEvent('quit', this.onQuit);
+IrcChannel.prototype.dispose = function (){
+    EventBinder.unbindIrcEvents('channel ' + this.name, this.irc_events, this.irc_connection);
+    this.irc_connection = undefined;
+};
 
-       bindEvent('privmsg', this.onMsg);
-       bindEvent('notice', this.onNotice);
-       bindEvent('ctcp_request', this.onCtcpRequest);
-    bindEvent('ctcp_response', this.onCtcpResponse);
 
-    bindEvent('topic', this.onTopic)
 
-    bindEvent('nicklist', this.onNicklist);
-    bindEvent('nicklistEnd', this.onNicklistEnd);
-}
+function onJoin(event) {
+    var that = this;
 
+    global.modules.emit('irc channel join', {
+        channel: this,
+        connection: this.irc_connection,
+        irc_event: event
+    })
+    .done(function() {
+        that.irc_connection.clientEvent('join', {
+            channel: that.name,
+            nick: event.nick,
+            ident: event.ident,
+            hostname: event.hostname,
+            time: event.time
+        });
+    });
+}
 
-IrcChannel.prototype.clientEvent = function (event_name, event) {
-       event.server = this.irc_connection.con_num;
-       this.irc_connection.state.sendIrcCommand(event_name, event);
-};
 
+function onPart(event) {
+    var that = this;
 
-IrcChannel.prototype.onJoin = function (event) {
-       this.clientEvent('join', {
-               channel: this.name,
-               nick: event.nick,
-               ident: event.ident,
-               hostname: event.hostname,
-       });
+    global.modules.emit('irc channel part', {
+        channel: this,
+        connection: this.irc_connection,
+        irc_event: event
+    })
+    .done(function() {
+        that.irc_connection.clientEvent('part', {
+            nick: event.nick,
+            ident: event.ident,
+            hostname: event.hostname,
+            channel: that.name,
+            message: event.message,
+            time: event.time
+        });
+    });
+}
 
-       // If we've just joined this channel then requesr=t get a nick list
-    if (event.nick === this.irc_connection.nick) {
-        this.irc_connection.write('NAMES ' + channel);
-    }
-};
 
+function onKick(event) {
+    var that = this;
 
-IrcChannel.prototype.onPart = function (event) {
-    this.clientEvent('part', {
-        nick: event.nick,
-        ident: event.ident,
-        hostname: event.hostname,
-        channel: this.name,
-        message: event.message
+    global.modules.emit('irc channel kick', {
+        channel: this,
+        connection: this.irc_connection,
+        irc_event: event
+    })
+    .done(function() {
+        that.irc_connection.clientEvent('kick', {
+            kicked: event.kicked,  // Nick of the kicked
+            nick: event.nick, // Nick of the kicker
+            ident: event.ident,
+            hostname: event.hostname,
+            channel: that.name,
+            message: event.message,
+            time: event.time
+        });
     });
-};
-
+}
 
-IrcChannel.prototype.onKick = function (event) {
-    this.client.sendIrcCommand('kick', {
-        kicked: event.kicked,  // Nick of the kicked
-        nick: event.nick, // Nick of the kicker
-        ident: event.ident,
-        hostname: event.hostname,
-        channel: this.name,
-        message: event.message
-    });
-};
 
+function onQuit(event) {
+    var that = this;
 
-IrcChannel.prototype.onQuit = function (event) {
-    this.clientEvent('quit', {
-        nick: event.nick,
-        ident: event.ident,
-        hostname: event.hostname,
-        message: event.message
+    global.modules.emit('irc channel quit', {
+        channel: this,
+        connection: this.irc_connection,
+        irc_event: event
+    })
+    .done(function() {
+        that.irc_connection.clientEvent('quit', {
+            nick: event.nick,
+            ident: event.ident,
+            hostname: event.hostname,
+            message: event.message,
+            time: event.time
+        });
     });
-};
+}
 
 
-IrcChannel.prototype.onMsg = function (event) {
-    this.clientEvent('msg', {
-        nick: event.nick,
-        ident: event.ident,
-        hostname: event.hostname,
-        channel: this.name,
-        msg: event.message
+function onMsg(event) {
+    var that = this;
+
+    global.modules.emit('irc message', {
+        channel: this,
+        connection: this.irc_connection,
+        irc_event: event
+    })
+    .done(function() {
+        that.irc_connection.clientEvent('msg', {
+            nick: event.nick,
+            ident: event.ident,
+            hostname: event.hostname,
+            channel: that.name,
+            msg: event.msg,
+            time: event.time
+        });
     });
-};
+}
 
 
-IrcChannel.prototype.onNotice = function (event) {
-    this.clientEvent('msg', {
-        nick: event.nick,
-        ident: event.ident,
-        hostname: event.hostname,
-        channel: this.name,
-        msg: event.trailing
+function onNotice(event) {
+    var that = this;
+
+    global.modules.emit('irc channel notice', {
+        channel: this,
+        connection: this.irc_connection,
+        irc_event: event
+    })
+    .done(function() {
+        that.irc_connection.clientEvent('notice', {
+            from_server: event.from_server,
+            nick: event.nick,
+            ident: event.ident,
+            hostname: event.hostname,
+            target: event.target,
+            msg: event.msg,
+            time: event.time
+        });
     });
-};
+}
 
 
-IrcChannel.prototype.onCtcpRequest = function (event) {
-    this.clientEvent('ctcp_request', {
+function onCtcpRequest(event) {
+    this.irc_connection.clientEvent('ctcp_request', {
         nick: event.nick,
         ident: event.ident,
         hostname: event.hostname,
         target: event.target,
         type: event.type,
-        msg: event.msg
+        msg: event.msg,
+        time: event.time
     });
-};
+}
 
 
-IrcChannel.prototype.onCtcpResponse = function (event) {
-    this.clientEvent('ctcp_response', {
+function onCtcpResponse(event) {
+    this.irc_connection.clientEvent('ctcp_response', {
         nick: event.nick,
         ident: event.ident,
         hostname: event.hostname,
         target: event.target,
         type: event.type,
-        msg: event.msg
+        msg: event.msg,
+        time: event.time
     });
-};
+}
 
 
 // TODO: Split event.users into batches of 50
-IrcChannel.prototype.onNicklist = function (event) {
-    this.clientEvent('userlist', {
+function onNicklist(event) {
+    this.irc_connection.clientEvent('userlist', {
         users: event.users,
         channel: this.name
     });
-};
+    // TODO: uncomment when using an IrcUser per nick
+    //updateUsersList.call(this, event.users);
+}
 
 
-IrcChannel.prototype.onNicklistEnd = function (event) {
-    this.clientEvent('userlist_end', {
+function onNicklistEnd(event) {
+    this.irc_connection.clientEvent('userlist_end', {
         users: event.users,
         channel: this.name
     });
-};
+    // TODO: uncomment when using an IrcUser per nick
+    //updateUsersList.call(this, event.users);
+}
 
+function updateUsersList(users) {
+    var that = this;
+    if (users) {
+        users.forEach(function (user) {
+            if (!that.irc_connection.irc_users[user.nick]) {
+                that.irc_connection.irc_users[user.nick] = new IrcUser(that.irc_connection, user.nick);
+            }
+        });
+    }
+}
 
-IrcChannel.prototype.onTopic = function (event) {
-    this.clientEvent('topic', {
-        nick: event.nick,
+
+function onTopic(event) {
+    var that = this;
+
+    global.modules.emit('irc channel topic', {
+        channel: this,
+        connection: this.irc_connection,
+        irc_event: event
+    })
+    .done(function() {
+        that.irc_connection.clientEvent('topic', {
+            nick: event.nick,
+            channel: that.name,
+            topic: event.topic,
+            time: event.time
+        });
+    });
+}
+
+
+function onChannelInfo(event) {
+    // Channel info event may contain 1 of several types of info,
+    // including creation time, modes. So just pipe the event
+    // right through to the client
+    this.irc_connection.clientEvent('channel_info', event);
+}
+
+
+function onBanList(event) {
+    this.ban_list_buffer.push(event);
+}
+
+function onBanListEnd(event) {
+    this.irc_connection.clientEvent('banlist', {
         channel: this.name,
-        topic: event.topic
+        bans: this.ban_list_buffer
     });
-};
 
-/*
-server:event
-server:*
-channel:#channel:event
-channel:*:event
-user:event
-user:*
-
-Server disconnected:
-       server:disconnect
-       server:*
-
-Joining channel #kiwiirc:
-       channel:#kiwiirc:join
-       channel:*:join
-
-Channel message:
-       channel:#kiwiirc:privmsg
-       channel:*:privmsg
-
-Private message:
-       user:privmsg
-       user:*
-*/
\ No newline at end of file
+    this.ban_list_buffer = [];
+}
+
+function onTopicSetBy(event) {
+    this.irc_connection.clientEvent('topicsetby', {
+        nick: event.nick,
+        channel: event.channel,
+        when: event.when
+    });
+}
+
+function onMode(event) {
+    var that = this;
+
+    global.modules.emit('irc channel mode', {
+        channel: this,
+        connection: this.irc_connection,
+        irc_event: event
+    })
+    .done(function() {
+        that.irc_connection.clientEvent('mode', {
+            target: event.target,
+            nick: event.nick,
+            modes: event.modes,
+            time: event.time
+        });
+    });
+}