2 /******************************* PHP-P10 v2 *****************************
3 * Copyright (C) 2011-2012 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 "h" => self::MODE_TYPE_B,
75 "v" => self::MODE_TYPE_B
77 private static $modevalues = null;
78 private $modeflags = 0;
79 private $modeparams = array();
82 public function __construct($channel) {
83 if(self::$modevalues == null) {
84 //build modevalues array
86 self::$modevalues = array();
87 foreach(self::$modes as $mode => $type) {
88 self::$modevalues[$mode] = $flag;
92 $this->channel = $channel;
95 public function parseModes($modes) {
96 $args = explode(" ",$modes);
98 for($i = 0; $i < strlen($args[0]); $i++) {
100 if($mode == "+") continue;
101 if($mode == "-") { //we have no - flag on parseModes???
102 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
105 if(!array_key_exists($mode, self::$modevalues)) {
106 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
109 $flag = self::$modevalues[$mode];
110 if(self::$modes[$mode] == self::MODE_TYPE_A) continue; //we shouldn't get such a mode on parseModes
111 $this->modeflags |= $flag;
112 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
113 $this->modeparams[$mode] = $args[$c++];
119 public function setModes($modes, $returndiff = false) {
120 $args = explode(" ",$modes);
127 for($i = 0; $i < strlen($args[0]); $i++) {
128 $mode = $args[0][$i];
137 if(!array_key_exists($mode, self::$modevalues)) {
138 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
141 if($mode == "o" || $mode == "h" || $mode == "v") {
142 if($this->setPrivs($add, $mode, $args[$c++])) {
143 if($returndiff && $add) {
144 $modestradd .= $mode;
145 $paramstradd .= " ".$args[$c-1];
146 } else if($returndiff && !$add) {
147 $modestrdel .= $mode;
148 $paramstrdel .= " ".$args[$c-1];
152 } else if($mode == "b") {
153 if($this->handleBan($add, $mode, $args[$c++])) {
154 if($returndiff && $add) {
155 $modestradd .= $mode;
156 $paramstradd .= " ".$args[$c-1];
157 } else if($returndiff && !$add) {
158 $modestrdel .= $mode;
159 $paramstrdel .= " ".$args[$c-1];
164 $flag = self::$modevalues[$mode];
166 if($returndiff && !($this->modeflags & $flag)) {
167 $modestradd .= $mode;
168 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
169 $paramstradd .= " ".$args[$c];
172 $this->modeflags |= $flag;
173 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
174 $this->modeparams[$mode] = $args[$c++];
177 if($returndiff && ($this->modeflags & $flag)) {
178 $modestrdel .= $mode;
179 if(self::$modes[$mode] == self::MODE_TYPE_C) {
180 $paramstrdel .= " ".$args[$c];
183 $this->modeflags &= ~$flag;
184 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
185 unset($this->modeparams[$mode]);
187 if(self::$modes[$mode] == self::MODE_TYPE_C) $c++;
191 $modediff = ($modestradd == "+" ? "" : $modestradd);
192 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
193 $modediff .= $paramstradd.$paramstrdel;
198 private function handleBan($add, $mode, $mask) {
199 //no ban management right now...
203 private function setPrivs($add, $mode, $user) {
204 $user = P10_User::getUserByNum($user);
206 trigger_error("Tried to set privs on a User that does not exist.", E_USER_ERROR);
209 $privs = $this->channel->getUserPrivs($user);
211 if($mode == "o") $privFlag = P10_Channel::USERPRIV_OPED;
212 if($mode == "h") $privFlag = P10_Channel::USERPRIV_HALFOP;
213 if($mode == "v") $privFlag = P10_Channel::USERPRIV_VOICE;
214 if(!($add xor ($privs & $privFlag)))
216 if($add) $privs |= $privFlag;
217 else $privs &= ~$privFlag;
218 $this->channel->setUserPrivs($user, $privs);
223 public function getModeString() {
226 foreach(self::$modevalues as $mode => $flag) {
227 if(($this->modeflags & $flag)) {
229 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
230 $paramstr .= " ".$this->modeparams[$mode];
234 return $modestr.$paramstr;
237 public function hasMode($mode) {
238 if(!array_key_exists($mode, self::$modevalues)) {
239 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
242 $flag = self::$modevalues[$mode];
243 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
244 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
246 return ($this->modeflags & $flag);
251 class P10_UserModeSet {
252 const MODE_WITHOUT_PARAMETER = 1, MODE_WITH_PARAMETER = 2;
253 private static $modes = array(
254 "o" => self::MODE_WITHOUT_PARAMETER,
255 "O" => self::MODE_WITHOUT_PARAMETER,
256 "i" => self::MODE_WITHOUT_PARAMETER,
257 "w" => self::MODE_WITHOUT_PARAMETER,
258 "s" => self::MODE_WITHOUT_PARAMETER,
259 "d" => self::MODE_WITHOUT_PARAMETER,
260 "k" => self::MODE_WITHOUT_PARAMETER,
261 "g" => self::MODE_WITHOUT_PARAMETER,
262 "r" => self::MODE_WITH_PARAMETER,
263 "f" => self::MODE_WITH_PARAMETER,
264 "n" => self::MODE_WITHOUT_PARAMETER,
265 "I" => self::MODE_WITHOUT_PARAMETER,
266 "X" => self::MODE_WITHOUT_PARAMETER,
267 "S" => self::MODE_WITHOUT_PARAMETER,
268 "H" => self::MODE_WITHOUT_PARAMETER,
269 "c" => self::MODE_WITHOUT_PARAMETER,
270 "W" => self::MODE_WITHOUT_PARAMETER,
271 "t" => self::MODE_WITHOUT_PARAMETER,
272 "D" => self::MODE_WITHOUT_PARAMETER,
273 "x" => self::MODE_WITHOUT_PARAMETER
275 private static $modevalues = null;
276 private $modeflags = 0;
277 private $modeparams = array();
279 public function __construct($modes) {
280 if(self::$modevalues == null) {
281 //build modevalues array
283 self::$modevalues = array();
284 foreach(self::$modes as $mode => $type) {
285 self::$modevalues[$mode] = $flag;
289 $this->parseModes($modes);
292 public function parseModes($modes) {
293 $args = explode(" ",$modes);
295 for($i = 0; $i < strlen($args[0]); $i++) {
296 $mode = $args[0][$i];
297 if($mode == "+") continue;
298 if($mode == "-") { //we have no - flag on parseModes???
299 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
302 if(!array_key_exists($mode, self::$modevalues)) {
303 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
306 $flag = self::$modevalues[$mode];
307 $this->modeflags |= $flag;
308 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
309 $this->modeparams[$mode] = $args[$c++];
314 public function setModes($modes, $returndiff = false) {
315 $args = explode(" ",$modes);
321 for($i = 0; $i < strlen($args[0]); $i++) {
322 $mode = $args[0][$i];
331 if(!array_key_exists($mode, self::$modevalues)) {
332 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
335 $flag = self::$modevalues[$mode];
337 if($returndiff && !($this->modeflags & $flag)) {
338 $modestradd .= $mode;
339 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
340 $paramstradd .= " ".$args[$c];
343 $this->modeflags |= $flag;
344 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
345 $this->modeparams[$mode] = $args[$c++];
348 if($returndiff && ($this->modeflags & $flag)) {
349 $modestrdel .= $mode;
351 $this->modeflags &= ~$flag;
355 $modediff = ($modestradd == "+" ? "" : $modestradd);
356 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
357 $modediff .= $paramstradd;
362 public function getModeString() {
365 foreach(self::$modevalues as $mode => $flag) {
366 if(($this->modeflags & $flag)) {
368 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
369 $paramstr .= " ".$this->modeparams[$mode];
373 return $modestr.$paramstr;
376 public function hasMode($mode) {
377 if(!array_key_exists($mode, self::$modevalues)) {
378 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
381 $flag = self::$modevalues[$mode];
382 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
383 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
385 return ($this->modeflags & $flag);