mode handler
authorpk910 <philipp@zoelle1.de>
Tue, 26 Jul 2011 08:17:34 +0000 (10:17 +0200)
committerpk910 <philipp@zoelle1.de>
Tue, 26 Jul 2011 08:17:34 +0000 (10:17 +0200)
Uplink/P10_ModeSets.class.php

index 52eed7d5eb75b9e59e7a06668a740a2a94b24667..7f58c7dd05edcb277eec8c17c5258e5a3c1fda27 100644 (file)
  */
 
 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
+       );
+       private static $modevalues = null;
+       private $modeflags = 0;
+       private $modeparams = array();
+       
+       public __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 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::$modevalues[$mode] == self::MODE_TYPE_A) continue; //we shouldn't get such a mode on parseModes
+                       $this->modeflags |= $flag;
+                       if(self::$modevalues[$mode] == self::MODE_TYPE_B || self::$modevalues[$mode] == self::MODE_TYPE_C) {
+                               $this->modeparams[$mode] = $args[$c++];
+                       }
+               }
+       }
+       
+       public 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;
+                       }
+                       $flag = self::$modevalues[$mode];
+                       if($add) {
+                               if($returndiff && !($this->modeflags & $flag)) {
+                                       $modestradd .= $mode;
+                                       if(self::$modevalues[$mode] == self::MODE_TYPE_B || self::$modevalues[$mode] == self::MODE_TYPE_C) {
+                                               $paramstradd .= " ".$args[$c];
+                                       }
+                               }
+                               $this->modeflags |= $flag;
+                               if(self::$modevalues[$mode] == self::MODE_TYPE_B || self::$modevalues[$mode] == self::MODE_TYPE_C) {
+                                       $this->modeparams[$mode] = $args[$c++];
+                               }
+                       } else {
+                               if($returndiff && ($this->modeflags & $flag)) {
+                                       $modestrdel .= $mode;
+                                       if(self::$modevalues[$mode] == self::MODE_TYPE_C) {
+                                               $paramstrdel .= " ".$args[$c];
+                                       }
+                               }
+                               $this->modeflags &= ~$flag;
+                               if(self::$modevalues[$mode] == self::MODE_TYPE_B || self::$modevalues[$mode] == self::MODE_TYPE_C) {
+                                       unset($this->modeparams[$mode]);
+                               }
+                               if(self::$modevalues[$mode] == self::MODE_TYPE_C) $c++;
+                       }
+               }
+               if($returndiff) {
+                       $modediff = ($modestradd == "+" ? "" : $modestradd);
+                       $modediff .= ($modestrdel == "-" ? "" : $modestrdel);
+                       $modediff .= $paramstradd.$paramstrdel;
+                       return $modediff;
+               }
+       }
+       
+       public getModeString() {
+               $modestr = "+";
+               $paramstr = "";
+               foreach(self::$modevalues as $mode => $flag) {
+                       if(($this->modeflags & $flag)) {
+                               $modestr .= $mode;
+                               if(self::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
+                                       $paramstr .= " ".$this->modeparams[$mode];
+                               }
+                       }
+               }
+               return $modestr.$paramstr;
+       }
+       
 }
 
 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_WITH_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) {
+               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 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::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
+                               $this->modeparams[$mode] = $args[$c++];
+                       }
+               }
        }
        
-       public getModeString() {
+       public 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::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
+                                               $paramstradd .= " ".$args[$c];
+                                       }
+                               }
+                               $this->modeflags |= $flag;
+                               if(self::$modevalues[$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 getModeString() {
+               $modestr = "+";
+               $paramstr = "";
+               foreach(self::$modevalues as $mode => $flag) {
+                       if(($this->modeflags & $flag)) {
+                               $modestr .= $mode;
+                               if(self::$modevalues[$mode] == self::MODE_WITH_PARAMETER) {
+                                       $paramstr .= " ".$this->modeparams[$mode];
+                               }
+                       }
+               }
+               return $modestr.$paramstr;
        }
        
 }