Alpha commit. Time to tidy up..
[KiwiIRC.git] / class_ircconnection.php
1 <?php
2
3 class IRCConnection extends IRC {
4
5 var $scrollback = array();
6 var $server_options = array();
7
8 function ProcessMessage($message){
9 global $config;
10 global $buffer;
11 global $send_debug;
12
13 //debug("Message: ".print_r($message, 1));
14 deb(print_r($message, 1));
15
16 if(strlen($message['trailing']) && ord($message['trailing'][0]) == 1){
17 $message['trailing'] = trim($message['trailing'], chr(1));
18 if(strtoupper(substr($message['trailing'], 1, 6)) == 'ACTION'){
19 $message['command'] = 'ACTION';
20 } else {
21 $message['command'] = 'CTCP';
22 }
23 }
24
25 switch(strtoupper($message['command'])){
26 case '001':
27 $buffer[] = json_encode(array(
28 'event'=>'connect',
29 'connected'=>true,
30 'host'=>$args['server']
31 ));
32 break;
33
34 case '005':
35 $opts = explode(' ', $message['params']);
36 $to_client = array();
37 foreach($opts as $pair){
38 $opt = explode('=', $pair, 2);
39 $name = strtoupper($opt[0]);
40 $val = isset($opt[1]) ? $opt[1] : true;
41 $this->server_options[$name] = $val;
42
43 if(in_array($name, array('NETWORK', 'PREFIX', 'CHANTYPES'))){
44 // Put the user prefixes (~&@ etc etc) into a more usable format
45 if($name == 'PREFIX'){
46 $matches = null;
47 preg_match('/\(([^)]*)\)(.*)/', $val, $matches);
48
49 $val = array();
50 if(count($matches) == 3){
51 for($i=0; $i<strlen($matches[1]); $i++){
52 $val[$matches[2][$i]] = $matches[1][$i];
53 }
54 }
55 }
56 $to_client[$name] = $val;
57 }
58 }
59
60 $data = array(
61 'event' => 'options',
62 'server' => '',
63 'options' => $to_client
64 );
65 $buffer[] = json_encode($data);
66 break;
67
68 case RPL_WHOISUSER:
69 case RPL_WHOISSERVER:
70 case RPL_WHOISOPERATOR:
71 case RPL_WHOISIDLE:
72 case RPL_ENDOFWHOIS:
73 case RPL_WHOISCHANNELS:
74 case RPL_WHOISMODES:
75 $tmp = explode(' ', $message['params']);
76 $tmp = $tmp[1];
77 $data = array(
78 'event' => 'whois',
79 'server' => '',
80 'nick' => $tmp,
81 'msg' => $message['trailing']
82 );
83 $buffer[] = json_encode($data);
84 break;
85
86 case RPL_MOTD:
87 $data = array(
88 'event' => 'motd',
89 'server' => '',
90 'msg' => $message['trailing']
91 );
92 $buffer[] = json_encode($data);
93 break;
94
95 case "353":
96 // NAMES command reply
97 list($nick,,$chan) = explode(" ", $message['params']);
98 $nicks = explode(" ", $message['trailing']);
99
100 $data = array(
101 'event' => 'userlist',
102 'server' => '',
103 'users' => array(),
104 'channel' => $chan
105 );
106
107 $prefixes = array('~', '&', '@','%','+');
108 $nicklist = array();
109 $i = 0;
110 foreach($nicks as $nick){
111 if(in_array($nick{0}, $prefixes)){
112 $prefix = $nick{0};
113 $nick = substr($nick,1);
114 } else {
115 $prefix = '';
116 }
117 $nicklist[$nick] = $prefix;
118
119 if($i==50){
120 $tmp = $data;
121 $tmp['users'] = $nicklist;
122 $buffer[] = json_encode($tmp);
123 unset($tmp);
124 $nicklist = array();
125 }
126
127 $i++;
128 }
129
130 if(count($nicklist)){
131 $tmp = $data;
132 $tmp['users'] = $nicklist;
133 $buffer[] = json_encode($tmp);
134 }
135 //deb(print_r($data, 1));
136 break;
137
138 case '366':
139 list(,$chan) = explode(' ', $message['params']);
140 $data = array(
141 'event' => 'userlist_end',
142 'server' => '',
143 'channel' => $chan
144 );
145 $buffer[] = json_encode($data);
146 break;
147
148 case ERR_LINKCHANNEL:
149 list($nick, $source_chan, $dest_chan) = explode(' ', $message['params']);
150 $data = array(
151 'event' => 'channel_redirect',
152 'from' => $source_chan,
153 'to' => $dest_chan
154 );
155 $buffer[] = json_encode($data);
156 break;
157
158 case ERR_NOSUCHNICK:
159 //TODO: shit
160 break;
161
162 case "JOIN":
163 $data = array(
164 'event' => 'join',
165 'nick' => $message['nick'],
166 'ident' => $message['ident'],
167 'hostname' => $message['hostname'],
168 'channel' => $message['trailing'],
169 );
170 $buffer[] = json_encode($data);
171
172 deb("JOIN: {$message['nick']} / {$this->nick}");
173 if($message['nick'] == $this->nick){
174 $this->stream->Write("NAMES {$message['trailing']}\r\n");
175 }
176
177 break;
178
179 case "PART":
180 $data = array(
181 'event' => 'part',
182 'nick' => $message['nick'],
183 'ident' => $message['ident'],
184 'hostname' => $message['hostname'],
185 'channel' => trim($message['params']),
186 'message' => $message['trailing'],
187 );
188 $buffer[] = json_encode($data);
189 break;
190
191 case "KICK":
192 $tmp = explode(' ', $message['params']);
193
194 $data = array(
195 'event' => 'kick',
196 'kicked' => $tmp[1],
197 'nick' => $message['nick'],
198 'ident' => $message['ident'],
199 'hostname' => $message['hostname'],
200 'channel' => trim($tmp[0]),
201 'message' => $message['trailing'],
202 );
203 $buffer[] = json_encode($data);
204 break;
205
206 case "QUIT":
207 $data = array(
208 'event' => 'quit',
209 'nick' => $message['nick'],
210 'ident' => $message['ident'],
211 'hostname' => $message['hostname'],
212 'message' => $message['trailing'],
213 );
214 $buffer[] = json_encode($data);
215 break;
216
217 case "NOTICE":
218 $data = array(
219 'event' => 'notice',
220 'nick' => $message['nick'],
221 'ident' => $message['ident'],
222 'hostname' => $message['hostname'],
223 'msg' => $message['trailing'],
224 );
225 $buffer[] = json_encode($data);
226 break;
227
228 case "NICK":
229 $data = array(
230 'event' => 'nick',
231 'nick' => $message['nick'],
232 'ident' => $message['ident'],
233 'hostname' => $message['hostname'],
234 'newnick' => $message['trailing'],
235 );
236 $buffer[] = json_encode($data);
237 break;
238
239 case 'TOPIC':
240 $data = array(
241 'event' => 'topic',
242 'nick' => $message['nick'],
243 'channel' => $message['params'],
244 'topic' => $message['trailing']
245 );
246 $buffer[] = json_encode($data);
247 break;
248
249 case '332':
250 $tmp = explode(' ', $message['params']);
251 $data = array(
252 'event' => 'topic',
253 'nick' => '',
254 'channel' => $tmp[1],
255 'topic' => $message['trailing']
256 );
257 $buffer[] = json_encode($data);
258 break;
259
260 case 'ACTION':
261 $data = array(
262 'event' => 'action',
263 'nick' => $message['nick'],
264 'msg' => trim(substr($message['trailing'], 8), chr(1)),
265 'channel' => $message['params'],
266 'time' => time()
267 );
268 $buffer[] = json_encode($data);
269 break;
270
271 case 'CTCP':
272 $data = array(
273 'event' => 'ctcp',
274 'nick' => $message['nick'],
275 'msg' => trim(substr($message['trailing'], 8), chr(1)),
276 'channel' => $message['params'],
277 'time' => time()
278 );
279 $buffer[] = json_encode($data);
280 break;
281
282 case 'MODE':
283 $opts = explode(' ', $message['params']);
284 if(count($opts) == 1){
285 $effected_nick = $opts[0];
286 $mode = $message['trailing'];
287 } elseif(count($opts) == 2){
288 $channel = $opts[0];
289 $mode = $opts[1];
290 } else {
291 $channel = $opts[0];
292 $mode = $opts[1];
293 $effected_nick = $opts[2];
294 }
295
296 $data = array(
297 'event' => 'mode',
298 'nick' => $message['nick'],
299 'mode' => $mode
300 );
301
302 if(isset($effected_nick)) $data['effected_nick'] = $effected_nick;
303 if(isset($channel)) $data['channel'] = $channel;
304 $buffer[] = json_encode($data);
305
306 break;
307 }
308
309 if($send_debug){
310 $ret = str_replace('\n', ' ', print_r($message, 1));
311 $data = array(
312 'event' => 'debug',
313 'msg' => $ret,
314 'time' => time()
315 );
316 $buffer[] = json_encode($data);
317 }
318
319 parent::ProcessMessage($message);
320 }
321
322
323
324
325 function ProcessPrivMsg($message){
326 global $buffer;
327 global $timeout;
328 global $config;
329
330 $msg = $message['trailing'];
331 $cmd = strtok($msg, ' ');
332 //debug(print_r($message));
333 //deb(print_r($message, 1));
334 $data = array(
335 'event' => 'msg',
336 'nick' => $message['nick'],
337 'msg' => $message['trailing'],
338 'channel' => $message['params'],
339 'time' => time()
340 );
341
342 // Save it into the scrollback
343 if($config['scrollback_size']){
344 deb('Size: '.count($this->scrollback));
345 if(count($this->scrollback) >= $config['scrollback_size']){
346
347 for($i=1; $i<count($this->scrollback); $i++){
348 $this->scrollback[$i-1] = $this->scrollback[$i];
349 }
350 /*
351 for($j=$i; $j<count($this->scrollback); $j++){
352 unset($this->scrollback[$i]);
353 }
354 //unset($this->scrollback[$i]);
355 */
356 $pos = count($this->scrollback)-1;
357 deb('Popped');
358 } else {
359 $pos = count($this->scrollback);
360 }
361
362 $this->scrollback[$pos] = $data;
363 }
364
365 $buffer[] = json_encode($data);
366 parent::ProcessPrivMsg($message);
367
368 return;
369 }
370
371
372 private function isChannel($name){
373 return ($name[0] == "#");
374 }
375
376
377 private function formatMsgToHtml($inp){
378 $tmp = $inp;
379
380 // Bold
381 if(strpos($tmp, chr(2))){
382 $next = '<b>';
383 while(strpos($tmp, chr(2)) !== false){
384 $pos = strpos($tmp, chr(2));
385 $tmp = str_replace($tmp, chr(2), $next);
386 $next = ($next=='<b>') ? '</b>' : '<b>';
387 }
388 if($next == '</b>') $tmp = $tmp . '</b>';
389 }
390
391 return $tmp;
392 }
393
394 }