Merge remote-tracking branch 'upstream/development' into development
[KiwiIRC.git] / server / irc / server.js
1 var util = require('util'),
2 EventBinder = require('./eventbinder.js'),
3 _ = require('lodash'),
4 Stats = require('../stats.js');
5
6 var IrcServer = function (irc_connection) {
7 this.irc_connection = irc_connection;
8
9 this.list_buffer = [];
10 this.motd_buffer = '';
11
12 // Date when registeration with the IRCd had completed
13 this.registered = false;
14
15 this.irc_events = {
16 connect: onConnect,
17 options: onOptions,
18 list_start: onListStart,
19 list_channel: onListChannel,
20 list_end: onListEnd,
21 motd_start: onMotdStart,
22 motd: onMotd,
23 motd_end: onMotdEnd,
24 error: onError,
25 password_mismatch: onPasswordMismatch,
26 channel_redirect: onChannelRedirect,
27 no_such_nick: onNoSuchNick,
28 cannot_send_to_channel: onCannotSendToChan,
29 too_many_channels: onTooManyChannels,
30 user_not_in_channel: onUserNotInChannel,
31 not_on_channel: onNotOnChannel,
32 channel_is_full: onChannelIsFull,
33 invite_only_channel: onInviteOnlyChannel,
34 user_on_channel: onUserAlreadyInChannel,
35 banned_from_channel: onBannedFromChannel,
36 bad_channel_key: onBadChannelKey,
37 chanop_privs_needed: onChanopPrivsNeeded,
38 nickname_in_use: onNicknameInUse,
39 erroneus_nickname: onErroneusNickname,
40 unknown_command: onUnknownCommand
41 };
42 EventBinder.bindIrcEvents('server *', this.irc_events, this, this.irc_connection);
43
44 };
45
46
47 module.exports = IrcServer;
48
49
50 IrcServer.prototype.dispose = function (){
51 EventBinder.unbindIrcEvents('server *', this.irc_events, this.irc_connection);
52 this.irc_connection = undefined;
53 };
54
55
56 IrcServer.prototype.reset = function() {
57 this.registered = false;
58 this.list_buffer = [];
59 this.motd_buffer = '';
60 };
61
62
63
64 function onConnect(event) {
65 Stats.incr('irc.connection.registered');
66 this.registered = new Date();
67
68 this.irc_connection.clientEvent('connect', {
69 nick: event.nick
70 });
71 }
72
73 function onOptions(event) {
74 this.irc_connection.clientEvent('options', {
75 options: event.options,
76 cap: event.cap
77 });
78 }
79
80 function onListStart(event) {
81 this.irc_connection.clientEvent('list_start', {});
82 this.list_buffer = [];
83 this.busy_listing = true;
84 }
85
86 function onListChannel(event) {
87 var buf;
88 if (!this.busy_listing) {
89 onListStart.call(this);
90 }
91 this.list_buffer.push({
92 channel: event.channel,
93 num_users: event.num_users,
94 topic: event.topic
95 });
96
97 if (this.list_buffer.length > 200) {
98 buf = _.sortBy(this.list_buffer, function (channel) {
99 // sortBy sorts in ascending order, we want to sort by descending, hence using 0 - num_users.
100 return 0 - channel.num_users;
101 });
102 this.irc_connection.clientEvent('list_channel', {
103 chans: buf
104 });
105 this.list_buffer = [];
106 }
107 }
108
109 function onListEnd(event) {
110 var buf;
111
112 buf = _.sortBy(this.list_buffer, function (channel) {
113 // sortBy sorts in ascending order, we want to sort by descending, hence using 0 - num_users.
114 return 0 - channel.num_users;
115 });
116 this.irc_connection.clientEvent('list_channel', {
117 chans: buf
118 });
119 this.list_buffer = [];
120 this.busy_listing = false;
121
122 this.irc_connection.clientEvent('list_end', {});
123 }
124
125 function onMotdStart(event) {
126 this.motd_buffer = '';
127 }
128
129 function onMotd(event) {
130 this.motd_buffer += event.motd;
131 }
132
133 function onMotdEnd(event) {
134 this.irc_connection.clientEvent('motd', {
135 msg: this.motd_buffer
136 });
137 }
138
139 function onError(event) {
140 this.irc_connection.clientEvent('irc_error', {
141 error: 'error',
142 reason: event.reason
143 });
144 }
145
146 function onPasswordMismatch(event) {
147 this.irc_connection.clientEvent('irc_error', {
148 error: 'password_mismatch'
149 });
150 }
151
152 function onChannelRedirect(event) {
153 this.irc_connection.clientEvent('channel_redirect', {
154 from: event.from,
155 to: event.to
156 });
157 }
158
159 function onNoSuchNick(event) {
160 this.irc_connection.clientEvent('irc_error', {
161 error: 'no_such_nick',
162 nick: event.nick,
163 reason: event.reason
164 });
165 }
166
167 function onCannotSendToChan(event) {
168 this.irc_connection.clientEvent('irc_error', {
169 error: 'cannot_send_to_channel',
170 channel: event.channel,
171 reason: event.reason
172 });
173 }
174
175 function onTooManyChannels(event) {
176 this.irc_connection.clientEvent('irc_error', {
177 error: 'too_many_channels',
178 channel: event.channel,
179 reason: event.reason
180 });
181 }
182
183 function onUserNotInChannel(event) {
184 this.irc_connection.clientEvent('irc_error', {
185 error: 'user_not_in_channel',
186 nick: event.nick,
187 channel: event.channel,
188 reason: event.reason
189 });
190 }
191
192 function onNotOnChannel(event) {
193 this.irc_connection.clientEvent('irc_error', {
194 error: 'not_on_channel',
195 channel: event.channel,
196 reason: event.reason
197 });
198 }
199
200 function onChannelIsFull(event) {
201 this.irc_connection.clientEvent('irc_error', {
202 error: 'channel_is_full',
203 channel: event.channel,
204 reason: event.reason
205 });
206 }
207
208 function onInviteOnlyChannel(event) {
209 this.irc_connection.clientEvent('irc_error', {
210 error: 'invite_only_channel',
211 channel: event.channel,
212 reason: event.reason
213 });
214 }
215
216 function onUserAlreadyInChannel(event) {
217 this.irc_connection.clientEvent('irc_error', {
218 error: 'user_on_channel',
219 channel: event.channel,
220 nick: event.nick
221 });
222 }
223
224 function onBannedFromChannel(event) {
225 this.irc_connection.clientEvent('irc_error', {
226 error: 'banned_from_channel',
227 channel: event.channel,
228 reason: event.reason
229 });
230 }
231
232 function onBadChannelKey(event) {
233 this.irc_connection.clientEvent('irc_error', {
234 error: 'bad_channel_key',
235 channel: event.channel,
236 reason: event.reason
237 });
238 }
239
240 function onChanopPrivsNeeded(event) {
241 this.irc_connection.clientEvent('irc_error', {
242 error: 'chanop_privs_needed',
243 channel: event.channel,
244 reason: event.reason
245 });
246 }
247
248 function onNicknameInUse(event) {
249 this.irc_connection.clientEvent('irc_error', {
250 error: 'nickname_in_use',
251 nick: event.nick,
252 reason: event.reason
253 });
254 }
255
256 function onErroneusNickname(event) {
257 this.irc_connection.clientEvent('irc_error', {
258 error: 'erroneus_nickname',
259 nick: event.nick,
260 reason: event.reason
261 });
262 }
263
264 function onUnknownCommand(event) {
265 this.irc_connection.clientEvent('unknown_command', {
266 error: 'unknown_command',
267 command: event.command,
268 params: event.params
269 });
270 }