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];
151 $flag = self::$modevalues[$mode];
153 if($returndiff && !($this->modeflags & $flag)) {
154 $modestradd .= $mode;
155 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
156 $paramstradd .= " ".$args[$c];
159 $this->modeflags |= $flag;
160 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
161 $this->modeparams[$mode] = $args[$c++];
164 if($returndiff && ($this->modeflags & $flag)) {
165 $modestrdel .= $mode;
166 if(self::$modes[$mode] == self::MODE_TYPE_C) {
167 $paramstrdel .= " ".$args[$c];
170 $this->modeflags &= ~$flag;
171 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
172 unset($this->modeparams[$mode]);
174 if(self::$modes[$mode] == self::MODE_TYPE_C) $c++;
178 $modediff = ($modestradd == "+" ? "" : $modestradd);
179 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
180 $modediff .= $paramstradd.$paramstrdel;
185 private function setPrivs($add, $mode, $user) {
186 $user = P10_User::getUserByNum($user);
188 trigger_error("Tried to set privs on a User that does not exist.", E_USER_ERROR);
191 $privs = $this->channel->getUserPrivs($user);
193 if($mode == "o") $privFlag = P10_Channel::USERPRIV_OPED;
194 if($mode == "v") $privFlag = P10_Channel::USERPRIV_VOICE;
195 if(!($add xor ($privs & $privFlag)))
197 if($add) $privs |= $privFlag;
198 else $privs &= ~$privFlag;
199 $this->channel->setUserPrivs($user, $privs);
204 public function getModeString() {
207 foreach(self::$modevalues as $mode => $flag) {
208 if(($this->modeflags & $flag)) {
210 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
211 $paramstr .= " ".$this->modeparams[$mode];
215 return $modestr.$paramstr;
218 public function hasMode($mode) {
219 if(!array_key_exists($mode, self::$modevalues)) {
220 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
223 $flag = self::$modevalues[$mode];
224 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
225 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
227 return ($this->modeflags & $flag);
232 class P10_UserModeSet {
233 const MODE_WITHOUT_PARAMETER = 1, MODE_WITH_PARAMETER = 2;
234 private static $modes = array(
235 "o" => self::MODE_WITHOUT_PARAMETER,
236 "O" => self::MODE_WITHOUT_PARAMETER,
237 "i" => self::MODE_WITHOUT_PARAMETER,
238 "w" => self::MODE_WITHOUT_PARAMETER,
239 "s" => self::MODE_WITHOUT_PARAMETER,
240 "d" => self::MODE_WITHOUT_PARAMETER,
241 "k" => self::MODE_WITHOUT_PARAMETER,
242 "g" => self::MODE_WITHOUT_PARAMETER,
243 "r" => self::MODE_WITH_PARAMETER,
244 "f" => self::MODE_WITH_PARAMETER,
245 "n" => self::MODE_WITHOUT_PARAMETER,
246 "I" => self::MODE_WITHOUT_PARAMETER,
247 "X" => self::MODE_WITHOUT_PARAMETER,
248 "S" => self::MODE_WITHOUT_PARAMETER,
249 "H" => self::MODE_WITHOUT_PARAMETER,
250 "c" => self::MODE_WITHOUT_PARAMETER,
251 "W" => self::MODE_WITHOUT_PARAMETER,
252 "t" => self::MODE_WITHOUT_PARAMETER,
253 "D" => self::MODE_WITHOUT_PARAMETER,
254 "x" => self::MODE_WITHOUT_PARAMETER
256 private static $modevalues = null;
257 private $modeflags = 0;
258 private $modeparams = array();
260 public function __construct($modes) {
261 if(self::$modevalues == null) {
262 //build modevalues array
264 self::$modevalues = array();
265 foreach(self::$modes as $mode => $type) {
266 self::$modevalues[$mode] = $flag;
270 $this->parseModes($modes);
273 public function parseModes($modes) {
274 $args = explode(" ",$modes);
276 for($i = 0; $i < strlen($args[0]); $i++) {
277 $mode = $args[0][$i];
278 if($mode == "+") continue;
279 if($mode == "-") { //we have no - flag on parseModes???
280 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
283 if(!array_key_exists($mode, self::$modevalues)) {
284 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
287 $flag = self::$modevalues[$mode];
288 $this->modeflags |= $flag;
289 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
290 $this->modeparams[$mode] = $args[$c++];
295 public function setModes($modes, $returndiff = false) {
296 $args = explode(" ",$modes);
302 for($i = 0; $i < strlen($args[0]); $i++) {
303 $mode = $args[0][$i];
312 if(!array_key_exists($mode, self::$modevalues)) {
313 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
316 $flag = self::$modevalues[$mode];
318 if($returndiff && !($this->modeflags & $flag)) {
319 $modestradd .= $mode;
320 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
321 $paramstradd .= " ".$args[$c];
324 $this->modeflags |= $flag;
325 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
326 $this->modeparams[$mode] = $args[$c++];
329 if($returndiff && ($this->modeflags & $flag)) {
330 $modestrdel .= $mode;
332 $this->modeflags &= ~$flag;
336 $modediff = ($modestradd == "+" ? "" : $modestradd);
337 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
338 $modediff .= $paramstradd;
343 public function getModeString() {
346 foreach(self::$modevalues as $mode => $flag) {
347 if(($this->modeflags & $flag)) {
349 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
350 $paramstr .= " ".$this->modeparams[$mode];
354 return $modestr.$paramstr;
357 public function hasMode($mode) {
358 if(!array_key_exists($mode, self::$modevalues)) {
359 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
362 $flag = self::$modevalues[$mode];
363 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
364 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
366 return ($this->modeflags & $flag);