X-Git-Url: http://git.pk910.de/?p=PHP-P10.git;a=blobdiff_plain;f=Uplink%2FP10_ModeSets.class.php;h=9eb36eab7a60b14b1aa6d5bed5ca06c6b0baad7d;hp=52eed7d5eb75b9e59e7a06668a740a2a94b24667;hb=0f30e96ae37491aee19e72b89cc54a6798d1f254;hpb=e8b8beead9e81f42f9c125d82ab6b21b60718f67 diff --git a/Uplink/P10_ModeSets.class.php b/Uplink/P10_ModeSets.class.php index 52eed7d..9eb36ea 100644 --- a/Uplink/P10_ModeSets.class.php +++ b/Uplink/P10_ModeSets.class.php @@ -1,22 +1,19 @@ . * * * ************************************************************************ * @@ -27,17 +24,346 @@ */ class P10_ChannelModeSet { - + const MODE_TYPE_A = 1, MODE_TYPE_B = 2, MODE_TYPE_C = 3, MODE_TYPE_D = 4; + /** http://www.irc.org/tech_docs/draft-brocklesby-irc-isupport-03.txt + * Section 3.3 CHANMODES + * + * Type A: Modes that add or remove an address to or from a list. + * These modes always take a parameter when sent by the server to a + * client; when sent by a client, they may be specified without a + * parameter, which requests the server to display the current + * contents of the corresponding list on the channel to the client. + * + * Type B: Modes that change a setting on the channel. These modes + * always take a parameter. + * + * Type C: Modes that change a setting on the channel. These modes + * take a parameter only when set; the parameter is absent when the + * mode is removed both in the client's and server's MODE command. + * + * Type D: Modes that change a setting on the channel. These modes + * never take a parameter. + **/ + private static $modes = array( + "b" => self::MODE_TYPE_A, + "k" => self::MODE_TYPE_B, + "a" => self::MODE_TYPE_C, + "l" => self::MODE_TYPE_C, + "f" => self::MODE_TYPE_C, + "F" => self::MODE_TYPE_C, + "c" => self::MODE_TYPE_D, + "C" => self::MODE_TYPE_D, + "i" => self::MODE_TYPE_D, + "m" => self::MODE_TYPE_D, + "M" => self::MODE_TYPE_D, + "n" => self::MODE_TYPE_D, + "N" => self::MODE_TYPE_D, + "p" => self::MODE_TYPE_D, + "r" => self::MODE_TYPE_D, + "s" => self::MODE_TYPE_D, + "t" => self::MODE_TYPE_D, + "u" => self::MODE_TYPE_D, + "D" => self::MODE_TYPE_D, + "d" => self::MODE_TYPE_D, + "R" => self::MODE_TYPE_D, + "z" => self::MODE_TYPE_D, + + //special behavior + "o" => self::MODE_TYPE_B, + "v" => self::MODE_TYPE_B + ); + private static $modevalues = null; + private $modeflags = 0; + private $modeparams = array(); + private $channel; + + public function __construct($channel) { + if(self::$modevalues == null) { + //build modevalues array + $flag = 1; + self::$modevalues = array(); + foreach(self::$modes as $mode => $type) { + self::$modevalues[$mode] = $flag; + $flag <<= 1; + } + } + $this->channel = $channel; + } + + public function parseModes($modes) { + $args = explode(" ",$modes); + $c = 1; + for($i = 0; $i < strlen($args[0]); $i++) { + $mode = $args[0][$i]; + if($mode == "+") continue; + if($mode == "-") { //we have no - flag on parseModes??? + trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING); + break; + } + if(!array_key_exists($mode, self::$modevalues)) { + trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING); + continue; + } + $flag = self::$modevalues[$mode]; + if(self::$modes[$mode] == self::MODE_TYPE_A) continue; //we shouldn't get such a mode on parseModes + $this->modeflags |= $flag; + if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) { + $this->modeparams[$mode] = $args[$c++]; + } + } + return $c-1; + } + + public function setModes($modes, $returndiff = false) { + $args = explode(" ",$modes); + $c = 1; + $add = true; + $modestradd = "+"; + $paramstradd = ""; + $modestrdel = "-"; + $paramstrdel = ""; + for($i = 0; $i < strlen($args[0]); $i++) { + $mode = $args[0][$i]; + if($mode == "+") { + $add = true; + continue; + } + if($mode == "-") { + $add = false; + continue; + } + if(!array_key_exists($mode, self::$modevalues)) { + trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING); + continue; + } + if($mode == "o" || $mode == "v") { + if($this->setPrivs($add, $mode, $args[$c++])) { + if($returndiff && $add) { + $modestradd .= $mode; + $paramstradd .= " ".$args[$c-1]; + } else if($returndiff && !$add) { + $modestrdel .= $mode; + $paramstrdel .= " ".$args[$c-1]; + } + } + continue; + } + $flag = self::$modevalues[$mode]; + if($add) { + if($returndiff && !($this->modeflags & $flag)) { + $modestradd .= $mode; + if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) { + $paramstradd .= " ".$args[$c]; + } + } + $this->modeflags |= $flag; + if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) { + $this->modeparams[$mode] = $args[$c++]; + } + } else { + if($returndiff && ($this->modeflags & $flag)) { + $modestrdel .= $mode; + if(self::$modes[$mode] == self::MODE_TYPE_C) { + $paramstrdel .= " ".$args[$c]; + } + } + $this->modeflags &= ~$flag; + if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) { + unset($this->modeparams[$mode]); + } + if(self::$modes[$mode] == self::MODE_TYPE_C) $c++; + } + } + if($returndiff) { + $modediff = ($modestradd == "+" ? "" : $modestradd); + $modediff .= ($modestrdel == "-" ? "" : $modestrdel); + $modediff .= $paramstradd.$paramstrdel; + return $modediff; + } + } + + private function setPrivs($add, $mode, $user) { + $user = P10_User::getUserByNum($user); + if($user == null) { + trigger_error("Tried to set privs on a User that does not exist.", E_USER_ERROR); + return; + } + $privs = $this->channel->getUserPrivs($user); + $privFlag = 0; + if($mode == "o") $privFlag = P10_Channel::USERPRIV_OPED; + if($mode == "v") $privFlag = P10_Channel::USERPRIV_VOICE; + if(!($add xor ($privs & $privFlag))) + return false; + if($add) $privs |= $privFlag; + else $privs &= ~$privFlag; + $this->channel->setUserPrivs($user, $privs); + return true; + + } + + public function getModeString() { + $modestr = "+"; + $paramstr = ""; + foreach(self::$modevalues as $mode => $flag) { + if(($this->modeflags & $flag)) { + $modestr .= $mode; + if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) { + $paramstr .= " ".$this->modeparams[$mode]; + } + } + } + return $modestr.$paramstr; + } + + public function hasMode($mode) { + if(!array_key_exists($mode, self::$modevalues)) { + trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING); + continue; + } + $flag = self::$modevalues[$mode]; + if(self::$modes[$mode] == self::MODE_TYPE_B || self::$modes[$mode] == self::MODE_TYPE_C) { + return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false); + } else + return ($this->modeflags & $flag); + } + } class P10_UserModeSet { + const MODE_WITHOUT_PARAMETER = 1, MODE_WITH_PARAMETER = 2; + private static $modes = array( + "o" => self::MODE_WITHOUT_PARAMETER, + "O" => self::MODE_WITHOUT_PARAMETER, + "i" => self::MODE_WITHOUT_PARAMETER, + "w" => self::MODE_WITHOUT_PARAMETER, + "s" => self::MODE_WITHOUT_PARAMETER, + "d" => self::MODE_WITHOUT_PARAMETER, + "k" => self::MODE_WITHOUT_PARAMETER, + "g" => self::MODE_WITHOUT_PARAMETER, + "r" => self::MODE_WITH_PARAMETER, + "f" => self::MODE_WITH_PARAMETER, + "n" => self::MODE_WITHOUT_PARAMETER, + "I" => self::MODE_WITHOUT_PARAMETER, + "X" => self::MODE_WITHOUT_PARAMETER, + "S" => self::MODE_WITHOUT_PARAMETER, + "H" => self::MODE_WITHOUT_PARAMETER, + "c" => self::MODE_WITHOUT_PARAMETER, + "W" => self::MODE_WITHOUT_PARAMETER, + "t" => self::MODE_WITHOUT_PARAMETER, + "D" => self::MODE_WITHOUT_PARAMETER, + "x" => self::MODE_WITHOUT_PARAMETER + ); + private static $modevalues = null; + private $modeflags = 0; + private $modeparams = array(); - public __construct($modes) { + public function __construct($modes) { + if(self::$modevalues == null) { + //build modevalues array + $flag = 1; + self::$modevalues = array(); + foreach(self::$modes as $mode => $type) { + self::$modevalues[$mode] = $flag; + $flag <<= 1; + } + } + $this->parseModes($modes); + } + public function parseModes($modes) { + $args = explode(" ",$modes); + $c = 1; + for($i = 0; $i < strlen($args[0]); $i++) { + $mode = $args[0][$i]; + if($mode == "+") continue; + if($mode == "-") { //we have no - flag on parseModes??? + trigger_error("unexpected MODE_DEL (-) on parseModes (".$modes.").", E_USER_WARNING); + break; + } + if(!array_key_exists($mode, self::$modevalues)) { + trigger_error("unknown mode (".$mode.") on parseModes (".$modes.").", E_USER_WARNING); + continue; + } + $flag = self::$modevalues[$mode]; + $this->modeflags |= $flag; + if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) { + $this->modeparams[$mode] = $args[$c++]; + } + } } - public getModeString() { + public function setModes($modes, $returndiff = false) { + $args = explode(" ",$modes); + $c = 1; + $add = true; + $modestradd = "+"; + $paramstradd = ""; + $modestrdel = "-"; + for($i = 0; $i < strlen($args[0]); $i++) { + $mode = $args[0][$i]; + if($mode == "+") { + $add = true; + continue; + } + if($mode == "-") { + $add = false; + continue; + } + if(!array_key_exists($mode, self::$modevalues)) { + trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING); + continue; + } + $flag = self::$modevalues[$mode]; + if($add) { + if($returndiff && !($this->modeflags & $flag)) { + $modestradd .= $mode; + if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) { + $paramstradd .= " ".$args[$c]; + } + } + $this->modeflags |= $flag; + if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) { + $this->modeparams[$mode] = $args[$c++]; + } + } else { + if($returndiff && ($this->modeflags & $flag)) { + $modestrdel .= $mode; + } + $this->modeflags &= ~$flag; + } + } + if($returndiff) { + $modediff = ($modestradd == "+" ? "" : $modestradd); + $modediff .= ($modestrdel == "-" ? "" : $modestrdel); + $modediff .= $paramstradd; + return $modediff; + } + } + + public function getModeString() { + $modestr = "+"; + $paramstr = ""; + foreach(self::$modevalues as $mode => $flag) { + if(($this->modeflags & $flag)) { + $modestr .= $mode; + if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) { + $paramstr .= " ".$this->modeparams[$mode]; + } + } + } + return $modestr.$paramstr; + } + public function hasMode($mode) { + if(!array_key_exists($mode, self::$modevalues)) { + trigger_error("unknown mode (".$mode.") on setModes (".$modes.").", E_USER_WARNING); + continue; + } + $flag = self::$modevalues[$mode]; + if(self::$modes[$mode] == self::MODE_WITH_PARAMETER) { + return (($this->modeflags & $flag) ? $this->modeparams[$mode] : false); + } else + return ($this->modeflags & $flag); } }