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,
72 "o" => self::MODE_TYPE_B,
73 "v" => self::MODE_TYPE_B
75 private static $modevalues = null;
76 private $modeflags = 0;
77 private $modeparams = array();
80 public function __construct($channel) {
81 if(self::$modevalues == null) {
82 //build modevalues array
84 self::$modevalues = array();
85 foreach(self::$modes as $mode => $type) {
86 self::$modevalues[$mode] = $flag;
90 $this->channel = $channel;
93 public function parseModes($modes) {
94 $args = explode(" ",$modes);
96 for($i = 0; $i < strlen($args[0]); $i++) {
98 if($mode == "+") continue;
99 if($mode == "-") { //we have no - flag on parseModes???
100 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
103 if(!array_key_exists($mode, self::$modevalues)) {
104 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
107 $flag = self::$modevalues[$mode];
108 if(self::$modes[$mode] == self::MODE_TYPE_A) continue; //we shouldn't get such a mode on parseModes
109 $this->modeflags |= $flag;
110 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
111 $this->modeparams[$mode] = $args[$c++];
117 public function setModes($modes, $returndiff = false) {
118 $args = explode(" ",$modes);
125 for($i = 0; $i < strlen($args[0]); $i++) {
126 $mode = $args[0][$i];
135 if(!array_key_exists($mode, self::$modevalues)) {
136 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
139 if($mode == "o" || $mode == "v") {
140 if($this->setPrivs($add, $mode, $args[$c++])) {
141 if($returndiff && $add) {
142 $modestradd .= $mode;
143 $paramstradd .= " ".$args[$c-1];
144 } else if($returndiff && !$add) {
145 $modestrdel .= $mode;
146 $paramstrdel .= " ".$args[$c-1];
150 } else if($mode == "b") {
151 if($this->handleBan($add, $mode, $args[$c++])) {
152 if($returndiff && $add) {
153 $modestradd .= $mode;
154 $paramstradd .= " ".$args[$c-1];
155 } else if($returndiff && !$add) {
156 $modestrdel .= $mode;
157 $paramstrdel .= " ".$args[$c-1];
162 $flag = self::$modevalues[$mode];
164 if($returndiff && !($this->modeflags & $flag)) {
165 $modestradd .= $mode;
166 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
167 $paramstradd .= " ".$args[$c];
170 $this->modeflags |= $flag;
171 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
172 $this->modeparams[$mode] = $args[$c++];
175 if($returndiff && ($this->modeflags & $flag)) {
176 $modestrdel .= $mode;
177 if(self::$modes[$mode] == self::MODE_TYPE_C) {
178 $paramstrdel .= " ".$args[$c];
181 $this->modeflags &= ~$flag;
182 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
183 unset($this->modeparams[$mode]);
185 if(self::$modes[$mode] == self::MODE_TYPE_C) $c++;
189 $modediff = ($modestradd == "+" ? "" : $modestradd);
190 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
191 $modediff .= $paramstradd.$paramstrdel;
196 private function handleBan($add, $mode, $mask) {
197 //no ban management right now...
201 private function setPrivs($add, $mode, $user) {
202 $user = P10_User::getUserByNum($user);
204 trigger_error("Tried to set privs on a User that does not exist.", E_USER_ERROR);
207 $privs = $this->channel->getUserPrivs($user);
209 if($mode == "o") $privFlag = P10_Channel::USERPRIV_OPED;
210 if($mode == "v") $privFlag = P10_Channel::USERPRIV_VOICE;
211 if(!($add xor ($privs & $privFlag)))
213 if($add) $privs |= $privFlag;
214 else $privs &= ~$privFlag;
215 $this->channel->setUserPrivs($user, $privs);
220 public function getModeString() {
223 foreach(self::$modevalues as $mode => $flag) {
224 if(($this->modeflags & $flag)) {
226 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
227 $paramstr .= " ".$this->modeparams[$mode];
231 return $modestr.$paramstr;
234 public function hasMode($mode) {
235 if(!array_key_exists($mode, self::$modevalues)) {
236 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
239 $flag = self::$modevalues[$mode];
240 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
241 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
243 return ($this->modeflags & $flag);
248 class P10_UserModeSet {
249 const MODE_WITHOUT_PARAMETER = 1, MODE_WITH_PARAMETER = 2;
250 private static $modes = array(
251 "o" => self::MODE_WITHOUT_PARAMETER,
252 "O" => self::MODE_WITHOUT_PARAMETER,
253 "i" => self::MODE_WITHOUT_PARAMETER,
254 "w" => self::MODE_WITHOUT_PARAMETER,
255 "s" => self::MODE_WITHOUT_PARAMETER,
256 "d" => self::MODE_WITHOUT_PARAMETER,
257 "k" => self::MODE_WITHOUT_PARAMETER,
258 "g" => self::MODE_WITHOUT_PARAMETER,
259 "r" => self::MODE_WITH_PARAMETER,
260 "f" => self::MODE_WITH_PARAMETER,
261 "n" => self::MODE_WITHOUT_PARAMETER,
262 "I" => self::MODE_WITHOUT_PARAMETER,
263 "X" => self::MODE_WITHOUT_PARAMETER,
264 "S" => self::MODE_WITHOUT_PARAMETER,
265 "H" => self::MODE_WITHOUT_PARAMETER,
266 "c" => self::MODE_WITHOUT_PARAMETER,
267 "W" => self::MODE_WITHOUT_PARAMETER,
268 "t" => self::MODE_WITHOUT_PARAMETER,
269 "D" => self::MODE_WITHOUT_PARAMETER,
270 "x" => self::MODE_WITHOUT_PARAMETER
272 private static $modevalues = null;
273 private $modeflags = 0;
274 private $modeparams = array();
276 public function __construct($modes) {
277 if(self::$modevalues == null) {
278 //build modevalues array
280 self::$modevalues = array();
281 foreach(self::$modes as $mode => $type) {
282 self::$modevalues[$mode] = $flag;
286 $this->parseModes($modes);
289 public function parseModes($modes) {
290 $args = explode(" ",$modes);
292 for($i = 0; $i < strlen($args[0]); $i++) {
293 $mode = $args[0][$i];
294 if($mode == "+") continue;
295 if($mode == "-") { //we have no - flag on parseModes???
296 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
299 if(!array_key_exists($mode, self::$modevalues)) {
300 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
303 $flag = self::$modevalues[$mode];
304 $this->modeflags |= $flag;
305 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
306 $this->modeparams[$mode] = $args[$c++];
311 public function setModes($modes, $returndiff = false) {
312 $args = explode(" ",$modes);
318 for($i = 0; $i < strlen($args[0]); $i++) {
319 $mode = $args[0][$i];
328 if(!array_key_exists($mode, self::$modevalues)) {
329 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
332 $flag = self::$modevalues[$mode];
334 if($returndiff && !($this->modeflags & $flag)) {
335 $modestradd .= $mode;
336 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
337 $paramstradd .= " ".$args[$c];
340 $this->modeflags |= $flag;
341 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
342 $this->modeparams[$mode] = $args[$c++];
345 if($returndiff && ($this->modeflags & $flag)) {
346 $modestrdel .= $mode;
348 $this->modeflags &= ~$flag;
352 $modediff = ($modestradd == "+" ? "" : $modestradd);
353 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
354 $modediff .= $paramstradd;
359 public function getModeString() {
362 foreach(self::$modevalues as $mode => $flag) {
363 if(($this->modeflags & $flag)) {
365 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
366 $paramstr .= " ".$this->modeparams[$mode];
370 return $modestr.$paramstr;
373 public function hasMode($mode) {
374 if(!array_key_exists($mode, self::$modevalues)) {
375 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
378 $flag = self::$modevalues[$mode];
379 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
380 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
382 return ($this->modeflags & $flag);