9ae2df031ff0cc3e251013eda573e3f14f7804a2
[KiwiIRC.git] / server / irc / state.js
1 var util = require('util'),
2 events = require('events'),
3 _ = require('lodash'),
4 winston = require('winston'),
5 IrcConnection = require('./connection.js').IrcConnection;
6
7 var State = function (client, save_state) {
8 var that = this;
9
10 events.EventEmitter.call(this);
11 this.client = client;
12 this.save_state = save_state || false;
13
14 this.irc_connections = [];
15 this.next_connection = 0;
16
17 this.client.on('dispose', function () {
18 if (!that.save_state) {
19 _.each(that.irc_connections, function (irc_connection, i, cons) {
20 if (irc_connection) {
21 irc_connection.end('QUIT :' + (global.config.quit_message || ''));
22 global.servers.removeConnection(irc_connection);
23 cons[i] = null;
24 }
25 });
26
27 that.dispose();
28 }
29 });
30 };
31
32 util.inherits(State, events.EventEmitter);
33
34 module.exports = State;
35
36 State.prototype.connect = function (hostname, port, ssl, nick, user, options, callback) {
37 var that = this;
38 var con, con_num;
39
40 // Check the per-server limit on the number of connections
41 if ((global.config.max_server_conns > 0) &&
42 (!global.config.restrict_server) &&
43 (!(global.config.webirc_pass && global.config.webirc_pass[hostname])) &&
44 (!(global.config.ip_as_username && _.contains(global.config.ip_as_username, hostname))) &&
45 (global.servers.numOnHost(hostname) >= global.config.max_server_conns))
46 {
47 return callback('Too many connections to host', {host: hostname, limit: global.config.max_server_conns});
48 }
49
50 con_num = this.next_connection++;
51 con = new IrcConnection(
52 hostname,
53 port,
54 ssl,
55 nick,
56 user,
57 options,
58 this,
59 con_num);
60
61 this.irc_connections[con_num] = con;
62
63 con.on('connected', function IrcConnectionConnection() {
64 global.servers.addConnection(this);
65 return callback(null, con_num);
66 });
67
68 con.on('error', function IrcConnectionError(err) {
69 winston.warn('irc_connection error (%s):', hostname, err);
70 return callback(err.message);
71 });
72
73 con.on('reconnecting', function IrcConnectionReconnecting() {
74 that.sendIrcCommand('disconnect', {connection_id: con.con_num, reason: 'IRC server reconnecting'});
75 });
76
77 con.on('close', function IrcConnectionClose() {
78 // TODO: Can we get a better reason for the disconnection? Was it planned?
79 that.sendIrcCommand('disconnect', {connection_id: con.con_num, reason: 'disconnected'});
80
81 that.irc_connections[con_num] = null;
82 global.servers.removeConnection(this);
83 });
84
85 // Call any modules before making the connection
86 global.modules.emit('irc connecting', {state: this, connection: con})
87 .done(function () {
88 con.connect();
89 });
90 };
91
92 State.prototype.sendIrcCommand = function () {
93 this.client.sendIrcCommand.apply(this.client, arguments);
94 };
95
96 State.prototype.sendKiwiCommand = function () {
97 this.client.sendKiwicommand.apply(this.client, arguments);
98 };
99
100 State.prototype.dispose = function () {
101 this.emit('dispose');
102 this.removeAllListeners();
103 };