Mercurial > hg > udpmsg3
annotate unrealircdlink/unrealircdlink.php @ 1:7f01316130e8
Basic support for private messages in unrealircd proxy
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Fri, 01 Apr 2011 17:02:41 +0200 |
parents | dd81c38b513a |
children |
rev | line source |
---|---|
0 | 1 <?php |
2 /* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. All rights reserved. | |
3 Redistribution and use in source and binary forms, with or without modification, are | |
4 permitted provided that the following conditions are met: | |
5 | |
6 1. Redistributions of source code must retain the above copyright notice, this list of | |
7 conditions and the following disclaimer. | |
8 | |
9 2. Redistributions in binary form must reproduce the above copyright notice, this list | |
10 of conditions and the following disclaimer in the documentation and/or other materials | |
11 provided with the distribution. | |
12 | |
13 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
14 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
15 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR | |
16 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
17 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
18 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
19 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
20 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
21 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
22 | |
23 The views and conclusions contained in the software and documentation are those of the | |
24 authors and should not be interpreted as representing official policies, either expressed | |
25 or implied, of Ivo Smits.*/ | |
26 | |
27 if (defined('APP_LOADED')) return; | |
28 define('APP_LOADED', TRUE); | |
29 if (!defined('CONFIGFILE')) define('CONFIGFILE', './config.php'); | |
30 | |
31 print("UCIS IRC Relay bot (c) 2010 Ivo Smits <Ivo@UCIS.nl>\n"); | |
32 print("More information: http://wiki.qontrol.nl/IRCRelay\n"); | |
33 print("\n"); | |
34 | |
35 class UUser { | |
36 public $iname = NULL; | |
37 public $unet = NULL; | |
38 public $uname = NULL; | |
39 public $channels = array(); | |
40 public $seen = 0; | |
41 public $explicit = FALSE; | |
42 } | |
43 class IUser { | |
44 public $iname = NULL; | |
45 public $channels = array(); | |
46 } | |
47 class Channel { | |
48 public $name = NULL; | |
49 public $iname = NULL; | |
50 public $uname = NULL; | |
51 } | |
52 | |
53 $iusers = array(); | |
54 $uusers = array(); | |
55 $ichannels = array(); | |
56 $uchannels = array(); | |
57 | |
58 $ircd_socket = NULL; | |
59 $ircd_buffer = ''; | |
60 $ircd_name = ''; | |
61 | |
62 $udpmsg_socket = NULL; | |
63 $udpmsg_buffer = ''; | |
64 $udpmsg_config = array(); | |
65 | |
66 $bot_nick = NULL; | |
67 | |
68 srand(); | |
69 | |
70 print("Loading configuration...\n"); | |
71 if (!isset($config)) require constant('CONFIGFILE'); | |
72 | |
73 $ircd_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); | |
74 socket_connect($ircd_socket, $config['ircd']['host'], $config['ircd']['port']); | |
75 $ircd_name = $config['ircd']['name']; | |
76 $bot_nick = $config['ircd']['bot_nick']; | |
77 if (!strlen($bot_nick)) $bot_nick = NULL; | |
78 ircd_send('PROTOCTL'); | |
79 ircd_send('PASS :'.$config['ircd']['password']); | |
80 ircd_send('SERVER '.$ircd_name.' 0 0 :'.$config['ircd']['desc']); | |
81 ircd_send('AO 0 0 0 0 - 0 :Kwaaknet.org'); | |
82 if ($bot_nick) ircd_send('NICK '.$bot_nick.' 0 0 gateway '.$ircd_name.' '.$ircd_name.' 0 :'.$config['ircd']['desc']); | |
83 ircd_send('ES'); | |
84 $udpmsg_socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); | |
85 socket_connect($udpmsg_socket, $config['udpmsg']['host'], $config['udpmsg']['port']); | |
86 foreach ($config['channels'] as $iname => $uname) { | |
87 $ch = new Channel(); | |
88 $ch->iname = $iname; | |
89 $ch->uname = $uname; | |
90 $ch->name = $iname; | |
91 $uchannels[$ch->uname] = $ch; | |
92 $ichannels[strtoupper($ch->iname)] = $ch; | |
93 if ($bot_nick) ircd_send(':'.$bot_nick.' JOIN :'.$ch->iname); | |
94 } | |
95 $iusers[strtoupper($bot_nick)] = new IUser(); | |
96 $iusers[strtoupper($bot_nick)]->iname = $bot_nick; | |
97 | |
98 function reconfigure() { | |
99 global $config; | |
100 include constant('CONFIGFILE'); | |
101 } | |
102 | |
103 $ntime = 0; | |
104 $atime = 0; | |
105 print("Running\n"); | |
106 while (TRUE) { | |
107 $selread = array($udpmsg_socket, $ircd_socket); | |
108 $selwrite = NULL; | |
109 $selerror = array($udpmsg_socket, $ircd_socket); | |
110 socket_select(&$selread, &$selwrite, &$selerror, 60); | |
111 if (in_array($udpmsg_socket, $selerror)) die("UDPMSG: Error: select error.\n"); | |
112 if (in_array($ircd_socket, $selerror)) die("IRCd: Error: select error.\n"); | |
113 if (in_array($udpmsg_socket, $selread) && !udpmsg_read()) die("UDPMSG: Error: closing connection.\n"); | |
114 if (in_array($ircd_socket, $selread) && !ircd_read()) die("IRCd: read error.\n"); | |
115 $ctime = time(); | |
116 if ($ntime < $ctime) { | |
117 foreach ($uusers as $usr) { | |
118 if ($usr->seen > $ctime - $config['udpmsg'][$usr->explicit ? 'timeout_explicit' : 'timeout_implicit']) continue; | |
119 unset($uusers[$usr->uname]); | |
120 unset($iusers[strtoupper($usr->iname)]); | |
121 ircd_send(':'.$usr->iname.' QUIT :Inactivity'); | |
122 } | |
123 $ntime = $ctime + 120; //min($config['udpmsg']['timeout_explicit'], $config['udpmsg']['timeout_implicit']); | |
124 } | |
125 if ($atime < $ctime) { | |
126 foreach ($iusers as $usr) if (is_a($usr, 'IUser')) ircd_userchannels($usr, array('CMD' => 'ALIVE')); | |
127 $atime = $ctime + (isset($config['udpmsg']['send_alive']) ? $config['udpmsg']['send_alive'] : 1800); | |
128 } | |
129 } | |
130 | |
131 function udpmsg_read() { | |
132 global $udpmsg_socket, $udpmsg_buffer; | |
133 $msg = socket_read($udpmsg_socket, 1024); | |
134 if (!strlen($msg)) { | |
135 fprintf(STDERR, "UDPMSG: End of file\n"); | |
136 return FALSE; | |
137 } | |
138 $udpmsg_buffer .= $msg; | |
139 while (strlen($udpmsg_buffer) > 2) { | |
140 $len = ord($udpmsg_buffer[0]) * 256 + ord($udpmsg_buffer[1]); | |
141 if ($len <= 0 || $len > 1024) { | |
142 fprintf(STDERR, "UDPMSG: Error: protocol error\n"); | |
143 return FALSE; | |
144 } | |
145 if (strlen($udpmsg_buffer) < 2 + $len) break; | |
146 $msg = substr($udpmsg_buffer, 2, $len); | |
147 $udpmsg_buffer = substr($udpmsg_buffer, 2 + $len); | |
148 $parts = explode("\0", $msg); | |
149 $ret = array(); | |
150 for ($i = 0; $i < count($parts)-1; $i += 2) $ret[$parts[$i]] = $parts[$i+1]; | |
151 udpmsg_process($ret); | |
152 } | |
153 return TRUE; | |
154 } | |
155 | |
156 function udpmsg_send($arr) { | |
157 global $udpmsg_socket, $config; | |
158 $tmp = array(); | |
159 $arr['DUMMY'] = rand(0, 999999); | |
160 $arr['NET'] = $config['udpmsg']['netname']; | |
161 foreach ($arr as $key => $value) { $tmp[] = $key; $tmp[] = $value; } | |
162 $tmp[] = ''; | |
163 $msg = implode("\0", $tmp); | |
164 $len = strlen($msg); | |
165 if ($len > 1024) { | |
166 fprintf(STDERR, "UDPMSG: Error: message too long!\n"); | |
167 return; | |
168 } | |
169 $lens = chr(floor($len / 256)).chr($len % 256); | |
170 socket_write($udpmsg_socket, $lens.$msg); | |
171 } | |
172 | |
173 function ircd_read() { | |
174 global $ircd_socket, $ircd_buffer; | |
175 $newdata = socket_read($ircd_socket, 1024); | |
176 if ($newdata === FALSE || !strlen($newdata)) return FALSE; | |
177 $ircd_buffer .= $newdata; | |
178 $offset = 0; | |
179 $len = strlen($ircd_buffer); | |
180 while ($offset < $len) { | |
181 $posa = strpos($ircd_buffer, "\n", $offset); | |
182 $posb = strpos($ircd_buffer, "\r", $offset); | |
183 if ($posa !== FALSE && $posb !== FALSE) $pos = min($posa, $posb); | |
184 else if ($posa !== FALSE) $pos = $posa; | |
185 else if ($posb !== FALSE) $pos = $posb; | |
186 else break; | |
187 $line = substr($ircd_buffer, $offset, $pos - $offset); | |
188 if (strlen($line) && !ircd_process($line)) { | |
189 fprintf(STDERR, "IRCd: process error\n"); | |
190 return FALSE; | |
191 } | |
192 $offset = $pos + 1; | |
193 } | |
194 $ircd_buffer = ($offset == $len) ? '' : substr($ircd_buffer, $offset); | |
195 return TRUE; | |
196 } | |
197 | |
198 function ircd_send($line) { | |
199 global $ircd_socket; | |
200 print('IW: '.$line."\n"); | |
201 $line .= "\r\n"; | |
202 socket_send($ircd_socket, $line, strlen($line), 0); | |
203 } | |
204 | |
205 function udpmsg_process($ret) { | |
1
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
206 global $uchannels, $config; |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
207 if (!isset($ret['CHN']) || !isset($ret['CMD']) || !isset($ret['USR']) || !array_key_exists($ret['CHN'], $uchannels)) { |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
208 $ch = NULL; |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
209 } else { |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
210 $ch = $uchannels[$ret['CHN']]; |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
211 } |
0 | 212 $net = isset($ret['NET']) ? $ret['NET'] : NULL; |
213 switch ($ret['CMD']) { | |
214 case 'MSG': | |
1
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
215 if ($ch === NULL || !isset($ret['MSG'])) break; |
0 | 216 $usr = udpmsg_join($ret['USR'], $ch, $net); |
217 ircd_send(':'.$usr->iname.' PRIVMSG '.$ch->iname.' :'.preg_replace('/[\x00\x10-\x13]/', '', $ret['MSG'])); | |
218 break; | |
1
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
219 case 'PMSG': |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
220 if (!isset($ret['DUSR']) || !isset($ret['MSG'])) break; |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
221 if (isset($ret['DNET']) && $ret['DNET'] != $config['udpmsg']['netname']) break; |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
222 $tousr = ircd_getuser($ret['DUSR'], FALSE); |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
223 if ($tousr === NULL) break; |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
224 $usr = udpmsg_getuser($ret['USR'], TRUE, $net, FALSE); |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
225 ircd_send(':'.$usr->iname.' PRIVMSG '.$tousr->iname.' :'.preg_replace('/[\x00\x10-\x13]/', '', $ret['MSG'])); |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
226 break; |
0 | 227 case 'ALIVE': |
228 case 'JOIN': | |
1
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
229 if ($ch === NULL) break; |
0 | 230 udpmsg_join($ret['USR'], $ch, $net, TRUE); |
231 break; | |
232 case 'PART': | |
1
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
233 if ($ch === NULL) break; |
0 | 234 udpmsg_part($ret['USR'], $ch); |
235 break; | |
236 case 'NICK': | |
237 udpmsg_part($ret['USR'], $ch); | |
238 if (!isset($ret['NEWNICK'])) break; | |
239 udpmsg_join($ret['NEWNICK'], $ch, $net, TRUE); | |
240 break; | |
241 } | |
242 } | |
243 | |
244 function udpmsg_join($name, $ch, $net = NULL, $explicit = FALSE) { | |
245 $usr = udpmsg_getuser($name, TRUE, $net, $explicit); | |
246 if (array_key_exists($ch->name, $usr->channels)) return $usr; | |
247 $usr->channels[$ch->name] = $ch; | |
248 ircd_send(':'.$usr->iname.' JOIN :'.$ch->iname); | |
249 return $usr; | |
250 } | |
251 | |
252 function udpmsg_part($name, $ch) { | |
253 global $uusers, $iusers; | |
254 $usr = udpmsg_getuser($name, FALSE); | |
255 if ($usr === NULL || !array_key_exists($ch->name, $usr->channels)) return; | |
256 unset($usr->channels[$ch->name]); | |
257 if (count($usr->channels)) { | |
258 ircd_send(':'.$usr->iname.' PART :'.$ch->iname); | |
259 } else { | |
260 unset($uusers[$usr->uname]); | |
261 unset($iusers[strtoupper($usr->iname)]); | |
262 ircd_send(':'.$usr->iname.' QUIT :No more channels'); | |
263 } | |
264 } | |
265 | |
266 function udpmsg_getuser($nick, $create = FALSE, $net = NULL, $explicit = FALSE) { | |
267 global $uusers, $iusers, $ircd_name; | |
268 if (array_key_exists($nick, $uusers)) { | |
269 $usr = $uusers[$nick]; | |
270 } else { | |
271 if (!$create) return NULL; | |
272 $usr = new UUser(); | |
273 $usr->uname = $nick; | |
274 $usr->unet = $net; | |
275 $usr->explicit = $explicit; | |
276 $usr->iname = udpmsg_getnick($usr, $nick); | |
277 $ident = preg_replace('/[^a-zA-Z0-9\-_]/', '', $usr->uname); | |
278 if (!strlen($ident)) $ident = 'unknown'; | |
279 $net = preg_replace('/[^a-zA-Z0-9\-_]/', '', $net); | |
280 if (!strlen($net)) $net = 'unknown'; | |
281 ircd_send('NICK '.$usr->iname.' 0 0 '.$ident.' '.$net.'.udpmsg3 '.$ircd_name.' 0 :UDPMSG3 user'); | |
282 $uusers[$nick] = $iusers[strtoupper($usr->iname)] = $usr; | |
283 } | |
284 $usr->seen = time(); | |
285 return $usr; | |
286 } | |
287 | |
288 function udpmsg_getnick($usr, $req) { | |
289 global $iusers, $config; | |
290 $nick = preg_replace('/[^a-zA-Z0-9\-_]/', '', $req); | |
291 if (!strlen($nick)) $nick = 'NoNick'; | |
1
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
292 else if (strlen($nick) > 20) $nick = substr($nick, 0, 20); |
0 | 293 switch ($config['ircd']['nick_format']) { |
294 case 'plain': break; | |
295 case 'prefix': $nick = $config['ircd']['nick_prefix'].$nick; break; | |
296 case 'suffix': $nick = $nick.$config['ircd']['nick_suffix']; break; | |
297 } | |
298 if (isset($iusers[strtoupper($nick)])) { | |
299 switch ($config['ircd']['nick_in_use']) { | |
300 case 'prefix': $nick = $config['ircd']['nick_prefix'].$nick; break; | |
301 case 'suffix': $nick = $nick.$config['ircd']['nick_suffix']; break; | |
302 } | |
303 $bnick = $nick; | |
304 while (isset($iusers[strtoupper($nick)])) $nick = $bnick.rand(0, 999); | |
305 } | |
306 return $nick; | |
307 } | |
308 | |
309 function ircd_process($line) { | |
310 global $ichannels, $iusers, $ircd_name, $bot_nick; | |
311 print('IR: '.$line."\n"); | |
312 $partsa = explode(' :', $line, 2); | |
313 $parts = explode(' ', $partsa[0]); | |
314 $sender = ($parts[0][0] == ':') ? substr(array_shift(&$parts), 1) : NULL; | |
315 $command = array_shift(&$parts); | |
316 if (count($partsa) > 1) array_push(&$parts, $partsa[1]); | |
317 $partsa = explode('!', $sender); | |
318 $sendernick = $partsa[0]; | |
319 switch (strtoupper($command)) { | |
320 case 'REHASH': | |
321 if (strtoupper($parts[0]) != strtoupper($ircd_name)) break; | |
322 reconfigure(); | |
323 ircd_send('NOTICE '.$sendernick.' :Reloaded configuration.'); | |
324 break; | |
325 case 'PING': | |
326 ircd_send('PONG'.($sender?' '.$sender:'').' :'.$parts[0]); | |
327 break; | |
328 case 'SVSNICK': | |
329 $sendernick = array_shift($parts); | |
330 case 'NICK': | |
331 if ($sender === NULL) { | |
332 ircd_getuser($parts[0], TRUE); | |
333 } else { | |
334 $usr = ircd_getuser($sendernick, FALSE); | |
335 if ($usr === NULL) break; | |
336 if (is_a($usr, 'IUser')) ircd_userchannels($usr, array('CMD' => 'NICK', 'NEWNICK' => $parts[0])); | |
337 unset($iusers[strtoupper($usr->iname)]); | |
338 $usr->iname = $parts[0]; | |
339 $iusers[strtoupper($usr->iname)] = $usr; | |
340 } | |
341 break; | |
342 case 'PRIVMSG': case 'NOTICE': | |
343 if ($parts[1] == '--print-internals' && $parts[0][0] == '#') { | |
344 ircd_send(':'.$bot_nick.' PRIVMSG '.$parts[0].' :We have '.count($GLOBALS['iusers']).' IRC users of which '.count($GLOBALS['uusers']).' UDPMSG users, and '.count($GLOBALS['ichannels']).' channels.'); | |
345 break; | |
346 } | |
347 $usr = ircd_getuser($sendernick, FALSE); | |
1
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
348 if ($parts[0][0] == '#') { |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
349 $ch = ircd_getchannel($parts[0]); |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
350 if ($ch === NULL || $usr === NULL) break; |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
351 udpmsg_send(array('CMD' => 'MSG', 'CHN' => $ch->uname, 'MSG' => $parts[1], 'USR' => $usr->iname)); |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
352 } else { |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
353 $tousr = ircd_getuser($parts[0], FALSE); |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
354 if ($tousr === NULL || $usr === NULL) break; |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
355 udpmsg_send(array('CMD' => 'PMSG', 'DUSR' => $tousr->uname, 'MSG' => $parts[1], 'USR' => $usr->iname)); |
7f01316130e8
Basic support for private messages in unrealircd proxy
Ivo Smits <Ivo@UCIS.nl>
parents:
0
diff
changeset
|
356 } |
0 | 357 break; |
358 case 'SAJOIN': | |
359 case 'SVSJOIN': | |
360 $sendernick = array_shift($parts); | |
361 case 'JOIN': | |
362 $usr = ircd_getuser($sendernick, FALSE); | |
363 if ($usr === NULL) break; | |
364 $chs = explode(',', $parts[0]); | |
365 foreach ($chs as $chn) { | |
366 $ch = ircd_getchannel($chn); | |
367 if ($ch === NULL) break; | |
368 $usr->channels[$ch->name] = $ch; | |
369 if (is_a($usr, 'IUser')) udpmsg_send(array('CMD' => 'JOIN', 'CHN' => $ch->uname, 'USR' => $usr->iname)); | |
370 } | |
371 break; | |
372 case 'SAPART': | |
373 case 'SVSPART': | |
374 $sendernick = array_shift($parts); | |
375 case 'PART': | |
376 $usr = ircd_getuser($sendernick, FALSE); | |
377 if ($usr === NULL) break; | |
378 $chs = explode(',', $parts[0]); | |
379 foreach ($chs as $chn) ircd_part($usr, $chn); | |
380 break; | |
381 case 'KICK': | |
382 ircd_part(ircd_getuser($parts[1], FALSE), $parts[0]); | |
383 break; | |
384 case 'QUIT': | |
385 ircd_quit($sendernick); | |
386 break; | |
387 case 'KILL': | |
388 case 'SVSKILL': | |
389 ircd_quit($parts[0]); | |
390 break; | |
391 } | |
392 return TRUE; | |
393 } | |
394 | |
395 function ircd_quit($nick) { | |
396 global $iusers, $uusers; | |
397 $usr = ircd_getuser($nick, FALSE); | |
398 if ($usr === NULL) return; | |
399 if (is_a($usr, 'IUser')) ircd_userchannels($usr, array('CMD' => 'PART')); | |
400 if (is_a($usr, 'UUser')) unset($uusers[$usr->uname]); | |
401 unset($iusers[strtoupper($usr->iname)]); | |
402 } | |
403 | |
404 function ircd_getchannel($chn) { | |
405 global $ichannels; | |
406 $chn = strtoupper($chn); | |
407 if (!array_key_exists($chn, $ichannels)) return NULL; | |
408 return $ichannels[$chn]; | |
409 } | |
410 function ircd_getuser($nick, $create = TRUE) { | |
411 global $iusers; | |
412 $snick = strtoupper($nick); | |
413 if (array_key_exists($snick, $iusers)) return $iusers[$snick]; | |
414 if (!$create) return NULL; | |
415 $usr = new IUser(); | |
416 $usr->iname = $nick; | |
417 $iusers[$snick] = $usr; | |
418 return $usr; | |
419 } | |
420 function ircd_part($usr, $chn) { | |
421 $ch = ircd_getchannel($chn); | |
422 if ($ch === NULL || $usr === NULL) return; | |
423 unset($usr->channels[$ch->name]); | |
424 if (is_a($usr, 'IUser')) udpmsg_send(array('CMD' => 'PART', 'CHN' => $ch->uname, 'USR' => $usr->iname)); | |
425 } | |
426 function ircd_userchannels($usr, $msg) { | |
427 $msg['USR'] = $usr->iname; | |
428 foreach ($usr->channels as $ch) { | |
429 $msg['CHN'] = $ch->uname; | |
430 udpmsg_send($msg); | |
431 } | |
432 } |