2 /********************************* PHP-P10 ******************************
3 * P10 uplink class by pk910 (c)2011 pk910 *
4 ************************************************************************
7 * PHP-P10 is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
17 * You should have received a copy of the GNU General Public License *
18 * along with PHP-P10; if not, write to the Free Software Foundation, *
19 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
21 ************************************************************************
23 * Uplink/P10_ModeSets.class.php
25 * classes to parse and store channel or user modes
29 class P10_ChannelModeSet {
30 const MODE_TYPE_A = 1, MODE_TYPE_B = 2, MODE_TYPE_C = 3, MODE_TYPE_D = 4;
31 /** http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt
32 * Section 3.3 CHANMODES
34 * Type A: Modes that add or remove an address to or from a list.
35 * These modes always take a parameter when sent by the server to a
36 * client; when sent by a client, they may be specified without a
37 * parameter, which requests the server to display the current
38 * contents of the corresponding list on the channel to the client.
40 * Type B: Modes that change a setting on the channel. These modes
41 * always take a parameter.
43 * Type C: Modes that change a setting on the channel. These modes
44 * take a parameter only when set; the parameter is absent when the
45 * mode is removed both in the client's and server's MODE command.
47 * Type D: Modes that change a setting on the channel. These modes
48 * never take a parameter.
50 private static $modes = array(
51 "b" => self::MODE_TYPE_A,
52 "k" => self::MODE_TYPE_B,
53 "a" => self::MODE_TYPE_C,
54 "l" => self::MODE_TYPE_C,
55 "f" => self::MODE_TYPE_C,
56 "F" => self::MODE_TYPE_C,
57 "c" => self::MODE_TYPE_D,
58 "C" => self::MODE_TYPE_D,
59 "i" => self::MODE_TYPE_D,
60 "m" => self::MODE_TYPE_D,
61 "M" => self::MODE_TYPE_D,
62 "n" => self::MODE_TYPE_D,
63 "N" => self::MODE_TYPE_D,
64 "p" => self::MODE_TYPE_D,
65 "r" => self::MODE_TYPE_D,
66 "s" => self::MODE_TYPE_D,
67 "t" => self::MODE_TYPE_D,
68 "u" => self::MODE_TYPE_D,
69 "D" => self::MODE_TYPE_D,
70 "d" => self::MODE_TYPE_D,
71 "R" => self::MODE_TYPE_D,
72 "z" => self::MODE_TYPE_D,
75 "o" => self::MODE_TYPE_B,
76 "v" => self::MODE_TYPE_B
78 private static $modevalues = null;
79 private $modeflags = 0;
80 private $modeparams = array();
83 public function __construct($channel) {
84 if(self::$modevalues == null) {
85 //build modevalues array
87 self::$modevalues = array();
88 foreach(self::$modes as $mode => $type) {
89 self::$modevalues[$mode] = $flag;
93 $this->channel = $channel;
96 public function parseModes($modes) {
97 $args = explode(" ",$modes);
99 for($i = 0; $i < strlen($args[0]); $i++) {
100 $mode = $args[0][$i];
101 if($mode == "+") continue;
102 if($mode == "-") { //we have no - flag on parseModes???
103 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
106 if(!array_key_exists($mode, self::$modevalues)) {
107 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
110 $flag = self::$modevalues[$mode];
111 if(self::$modes[$mode] == self::MODE_TYPE_A) continue; //we shouldn't get such a mode on parseModes
112 $this->modeflags |= $flag;
113 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
114 $this->modeparams[$mode] = $args[$c++];
120 public function setModes($modes, $returndiff = false) {
121 $args = explode(" ",$modes);
128 for($i = 0; $i < strlen($args[0]); $i++) {
129 $mode = $args[0][$i];
138 if(!array_key_exists($mode, self::$modevalues)) {
139 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
142 if($mode == "o" || $mode == "v") {
143 if($this->setPrivs($add, $mode, $args[$c++])) {
144 if($returndiff && $add) {
145 $modestradd .= $mode;
146 $paramstradd .= " ".$args[$c-1];
147 } else if($returndiff && !$add) {
148 $modestrdel .= $mode;
149 $paramstrdel .= " ".$args[$c-1];
154 $flag = self::$modevalues[$mode];
156 if($returndiff && !($this->modeflags & $flag)) {
157 $modestradd .= $mode;
158 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
159 $paramstradd .= " ".$args[$c];
162 $this->modeflags |= $flag;
163 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
164 $this->modeparams[$mode] = $args[$c++];
167 if($returndiff && ($this->modeflags & $flag)) {
168 $modestrdel .= $mode;
169 if(self::$modes[$mode] == self::MODE_TYPE_C) {
170 $paramstrdel .= " ".$args[$c];
173 $this->modeflags &= ~$flag;
174 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
175 unset($this->modeparams[$mode]);
177 if(self::$modes[$mode] == self::MODE_TYPE_C) $c++;
181 $modediff = ($modestradd == "+" ? "" : $modestradd);
182 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
183 $modediff .= $paramstradd.$paramstrdel;
188 private function setPrivs($add, $mode, $user) {
189 $user = P10_User::getUserByNum($user);
191 trigger_error("Tried to set privs on a User that does not exist.", E_USER_ERROR);
194 $privs = $this->channel->getUserPrivs($user);
196 if($mode == "o") $privFlag = P10_Channel::USERPRIV_OPED;
197 if($mode == "v") $privFlag = P10_Channel::USERPRIV_VOICE;
198 if(!($add xor ($privs & $privFlag)))
200 if($add) $privs |= $privFlag;
201 else $privs &= ~$privFlag;
202 $this->channel->setUserPrivs($user, $privs);
207 public function getModeString() {
210 foreach(self::$modevalues as $mode => $flag) {
211 if(($this->modeflags & $flag)) {
213 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
214 $paramstr .= " ".$this->modeparams[$mode];
218 return $modestr.$paramstr;
221 public function hasMode($mode) {
222 if(!array_key_exists($mode, self::$modevalues)) {
223 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
226 $flag = self::$modevalues[$mode];
227 if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) {
228 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
230 return ($this->modeflags & $flag);
235 class P10_UserModeSet {
236 const MODE_WITHOUT_PARAMETER = 1, MODE_WITH_PARAMETER = 2;
237 private static $modes = array(
238 "o" => self::MODE_WITHOUT_PARAMETER,
239 "O" => self::MODE_WITHOUT_PARAMETER,
240 "i" => self::MODE_WITHOUT_PARAMETER,
241 "w" => self::MODE_WITHOUT_PARAMETER,
242 "s" => self::MODE_WITHOUT_PARAMETER,
243 "d" => self::MODE_WITHOUT_PARAMETER,
244 "k" => self::MODE_WITHOUT_PARAMETER,
245 "g" => self::MODE_WITHOUT_PARAMETER,
246 "r" => self::MODE_WITH_PARAMETER,
247 "f" => self::MODE_WITH_PARAMETER,
248 "n" => self::MODE_WITHOUT_PARAMETER,
249 "I" => self::MODE_WITHOUT_PARAMETER,
250 "X" => self::MODE_WITHOUT_PARAMETER,
251 "S" => self::MODE_WITHOUT_PARAMETER,
252 "H" => self::MODE_WITHOUT_PARAMETER,
253 "c" => self::MODE_WITHOUT_PARAMETER,
254 "W" => self::MODE_WITHOUT_PARAMETER,
255 "t" => self::MODE_WITHOUT_PARAMETER,
256 "D" => self::MODE_WITHOUT_PARAMETER,
257 "x" => self::MODE_WITHOUT_PARAMETER
259 private static $modevalues = null;
260 private $modeflags = 0;
261 private $modeparams = array();
263 public function __construct($modes) {
264 if(self::$modevalues == null) {
265 //build modevalues array
267 self::$modevalues = array();
268 foreach(self::$modes as $mode => $type) {
269 self::$modevalues[$mode] = $flag;
273 $this->parseModes($modes);
276 public function parseModes($modes) {
277 $args = explode(" ",$modes);
279 for($i = 0; $i < strlen($args[0]); $i++) {
280 $mode = $args[0][$i];
281 if($mode == "+") continue;
282 if($mode == "-") { //we have no - flag on parseModes???
283 trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING);
286 if(!array_key_exists($mode, self::$modevalues)) {
287 trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING);
290 $flag = self::$modevalues[$mode];
291 $this->modeflags |= $flag;
292 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
293 $this->modeparams[$mode] = $args[$c++];
298 public function setModes($modes, $returndiff = false) {
299 $args = explode(" ",$modes);
305 for($i = 0; $i < strlen($args[0]); $i++) {
306 $mode = $args[0][$i];
315 if(!array_key_exists($mode, self::$modevalues)) {
316 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
319 $flag = self::$modevalues[$mode];
321 if($returndiff && !($this->modeflags & $flag)) {
322 $modestradd .= $mode;
323 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
324 $paramstradd .= " ".$args[$c];
327 $this->modeflags |= $flag;
328 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
329 $this->modeparams[$mode] = $args[$c++];
332 if($returndiff && ($this->modeflags & $flag)) {
333 $modestrdel .= $mode;
335 $this->modeflags &= ~$flag;
339 $modediff = ($modestradd == "+" ? "" : $modestradd);
340 $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
341 $modediff .= $paramstradd;
346 public function getModeString() {
349 foreach(self::$modevalues as $mode => $flag) {
350 if(($this->modeflags & $flag)) {
352 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
353 $paramstr .= " ".$this->modeparams[$mode];
357 return $modestr.$paramstr;
360 public function hasMode($mode) {
361 if(!array_key_exists($mode, self::$modevalues)) {
362 trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING);
365 $flag = self::$modevalues[$mode];
366 if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) {
367 return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false);
369 return ($this->modeflags & $flag);