2 /******************************* PHP-P10 v2 *****************************
3 * Copyright (C) 2011 Philipp Kreil (pk910) *
5 * This program is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 3 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
18 ************************************************************************
20 * Uplink/P10_ModeSets.class.php
22 * classes to parse and store channel or user modes
26 class P10_ChannelModeSet {
27 const MODE_TYPE_A = 1, MODE_TYPE_B = 2, MODE_TYPE_C = 3, MODE_TYPE_D = 4;
28 /** http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
29 * Section 3.3 CHANMODES
31 * Type A: Modes that add or remove an address to or from a list.
32 * These modes always take a parameter when sent by the server to a
33 * client; when sent by a client, they may be specified without a
34 * parameter, which requests the server to display the current
35 * contents of the corresponding list on the channel to the client.
37 * Type B: Modes that change a setting on the channel. These modes
38 * always take a parameter.
40 * Type C: Modes that change a setting on the channel. These modes
41 * take a parameter only when set; the parameter is absent when the
42 * mode is removed both in the client's and server's MODE command.
44 * Type D: Modes that change a setting on the channel. These modes
45 * never take a parameter.
47 private static $modes = array(
48 "b" => self::MODE_TYPE_A,
49 "k" => self::MODE_TYPE_B,
50 "a" => self::MODE_TYPE_C,
51 "l" => self::MODE_TYPE_C,
52 "f" => self::MODE_TYPE_C,
53 "F" => self::MODE_TYPE_C,
54 "c" => self::MODE_TYPE_D,
55 "C" => self::MODE_TYPE_D,
56 "i" => self::MODE_TYPE_D,
57 "m" => self::MODE_TYPE_D,
58 "M" => self::MODE_TYPE_D,
59 "n" => self::MODE_TYPE_D,
60 "N" => self::MODE_TYPE_D,
61 "p" => self::MODE_TYPE_D,
62 "r" => self::MODE_TYPE_D,
63 "s" => self::MODE_TYPE_D,
64 "t" => self::MODE_TYPE_D,
65 "u" => self::MODE_TYPE_D,
66 "D" => self::MODE_TYPE_D,
67 "d" => self::MODE_TYPE_D,
68 "R" => self::MODE_TYPE_D,
69 "z" => self::MODE_TYPE_D,
70 "S" => self::MODE_TYPE_D,
73 "o" => self::MODE_TYPE_B,
74 "v" => self::MODE_TYPE_B
76 private static $modevalues = null;
77 private $modeflags = 0;
78 private $modeparams = array();
81 public function __construct($channel) {
82 if(self::$modevalues == null) {
83 //build modevalues array
85 self::$modevalues = array();
86 foreach(self::$modes as $mode => $type) {
87 self::$modevalues[$mode] = $flag;
91 $this->channel = $channel;
94 public function parseModes($modes) {
95 $args = explode(" ",$modes);
97 for($i = 0; $i < strlen($args[0]); $i++) {
99 if($mode == "+") continue;
100 if($mode == "-") { //we have no - flag on parseModes???
101 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
104 if(!array_key_exists($mode, self::$modevalues)) {
105 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
108 $flag = self::$modevalues[$mode];
109 if(self::$modes[$mode] == self::MODE_TYPE_A) continue; //we shouldn't get such a mode on parseModes
110 $this->modeflags |= $flag;
111 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
112 $this->modeparams[$mode] = $args[$c++];
118 public function setModes($modes, $returndiff = false) {
119 $args = explode(" ",$modes);
126 for($i = 0; $i < strlen($args[0]); $i++) {
127 $mode = $args[0][$i];
136 if(!array_key_exists($mode, self::$modevalues)) {
137 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
140 if($mode == "o" || $mode == "v") {
141 if($this->setPrivs($add, $mode, $args[$c++])) {
142 if($returndiff && $add) {
143 $modestradd .= $mode;
144 $paramstradd .= " ".$args[$c-1];
145 } else if($returndiff && !$add) {
146 $modestrdel .= $mode;
147 $paramstrdel .= " ".$args[$c-1];
151 } else if($mode == "b") {
152 if($this->handleBan($add, $mode, $args[$c++])) {
153 if($returndiff && $add) {
154 $modestradd .= $mode;
155 $paramstradd .= " ".$args[$c-1];
156 } else if($returndiff && !$add) {
157 $modestrdel .= $mode;
158 $paramstrdel .= " ".$args[$c-1];
163 $flag = self::$modevalues[$mode];
165 if($returndiff && !($this->modeflags & $flag)) {
166 $modestradd .= $mode;
167 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
168 $paramstradd .= " ".$args[$c];
171 $this->modeflags |= $flag;
172 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
173 $this->modeparams[$mode] = $args[$c++];
176 if($returndiff && ($this->modeflags & $flag)) {
177 $modestrdel .= $mode;
178 if(self::$modes[$mode] == self::MODE_TYPE_C) {
179 $paramstrdel .= " ".$args[$c];
182 $this->modeflags &= ~$flag;
183 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
184 unset($this->modeparams[$mode]);
186 if(self::$modes[$mode] == self::MODE_TYPE_C) $c++;
190 $modediff = ($modestradd == "+" ? "" : $modestradd);
191 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
192 $modediff .= $paramstradd.$paramstrdel;
197 private function handleBan($add, $mode, $mask) {
198 //no ban management right now...
202 private function setPrivs($add, $mode, $user) {
203 $user = P10_User::getUserByNum($user);
205 trigger_error("Tried to set privs on a User that does not exist.", E_USER_ERROR);
208 $privs = $this->channel->getUserPrivs($user);
210 if($mode == "o") $privFlag = P10_Channel::USERPRIV_OPED;
211 if($mode == "v") $privFlag = P10_Channel::USERPRIV_VOICE;
212 if(!($add xor ($privs & $privFlag)))
214 if($add) $privs |= $privFlag;
215 else $privs &= ~$privFlag;
216 $this->channel->setUserPrivs($user, $privs);
221 public function getModeString() {
224 foreach(self::$modevalues as $mode => $flag) {
225 if(($this->modeflags & $flag)) {
227 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
228 $paramstr .= " ".$this->modeparams[$mode];
232 return $modestr.$paramstr;
235 public function hasMode($mode) {
236 if(!array_key_exists($mode, self::$modevalues)) {
237 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
240 $flag = self::$modevalues[$mode];
241 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
242 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
244 return ($this->modeflags & $flag);
249 class P10_UserModeSet {
250 const MODE_WITHOUT_PARAMETER = 1, MODE_WITH_PARAMETER = 2;
251 private static $modes = array(
252 "o" => self::MODE_WITHOUT_PARAMETER,
253 "O" => self::MODE_WITHOUT_PARAMETER,
254 "i" => self::MODE_WITHOUT_PARAMETER,
255 "w" => self::MODE_WITHOUT_PARAMETER,
256 "s" => self::MODE_WITHOUT_PARAMETER,
257 "d" => self::MODE_WITHOUT_PARAMETER,
258 "k" => self::MODE_WITHOUT_PARAMETER,
259 "g" => self::MODE_WITHOUT_PARAMETER,
260 "r" => self::MODE_WITH_PARAMETER,
261 "f" => self::MODE_WITH_PARAMETER,
262 "n" => self::MODE_WITHOUT_PARAMETER,
263 "I" => self::MODE_WITHOUT_PARAMETER,
264 "X" => self::MODE_WITHOUT_PARAMETER,
265 "S" => self::MODE_WITHOUT_PARAMETER,
266 "H" => self::MODE_WITHOUT_PARAMETER,
267 "c" => self::MODE_WITHOUT_PARAMETER,
268 "W" => self::MODE_WITHOUT_PARAMETER,
269 "t" => self::MODE_WITHOUT_PARAMETER,
270 "D" => self::MODE_WITHOUT_PARAMETER,
271 "x" => self::MODE_WITHOUT_PARAMETER
273 private static $modevalues = null;
274 private $modeflags = 0;
275 private $modeparams = array();
277 public function __construct($modes) {
278 if(self::$modevalues == null) {
279 //build modevalues array
281 self::$modevalues = array();
282 foreach(self::$modes as $mode => $type) {
283 self::$modevalues[$mode] = $flag;
287 $this->parseModes($modes);
290 public function parseModes($modes) {
291 $args = explode(" ",$modes);
293 for($i = 0; $i < strlen($args[0]); $i++) {
294 $mode = $args[0][$i];
295 if($mode == "+") continue;
296 if($mode == "-") { //we have no - flag on parseModes???
297 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
300 if(!array_key_exists($mode, self::$modevalues)) {
301 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
304 $flag = self::$modevalues[$mode];
305 $this->modeflags |= $flag;
306 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
307 $this->modeparams[$mode] = $args[$c++];
312 public function setModes($modes, $returndiff = false) {
313 $args = explode(" ",$modes);
319 for($i = 0; $i < strlen($args[0]); $i++) {
320 $mode = $args[0][$i];
329 if(!array_key_exists($mode, self::$modevalues)) {
330 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
333 $flag = self::$modevalues[$mode];
335 if($returndiff && !($this->modeflags & $flag)) {
336 $modestradd .= $mode;
337 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
338 $paramstradd .= " ".$args[$c];
341 $this->modeflags |= $flag;
342 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
343 $this->modeparams[$mode] = $args[$c++];
346 if($returndiff && ($this->modeflags & $flag)) {
347 $modestrdel .= $mode;
349 $this->modeflags &= ~$flag;
353 $modediff = ($modestradd == "+" ? "" : $modestradd);
354 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
355 $modediff .= $paramstradd;
360 public function getModeString() {
363 foreach(self::$modevalues as $mode => $flag) {
364 if(($this->modeflags & $flag)) {
366 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
367 $paramstr .= " ".$this->modeparams[$mode];
371 return $modestr.$paramstr;
374 public function hasMode($mode) {
375 if(!array_key_exists($mode, self::$modevalues)) {
376 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
379 $flag = self::$modevalues[$mode];
380 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
381 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
383 return ($this->modeflags & $flag);