rendered paste body//structure
class channel {
public $name;
public $ci = null;
public $creation_time;
public $topic = null; //array('topic' => '', 'by' => '', 'at' => 0);
public $modes = null;
public $bans = null;
public $excepts = null;
public $invex = null;
public $userlist = array(); // array( 'user' => &$u, 'modes' => new cumodes, 'flags' => 0 );
public $tag = 0; //1-nethack;2-forbidden;4-suspended
function __construct () {
$this->modes = new cmodes($this);
$this->bans =& $this->modes->lb;
$this->excepts =& $this->modes->le;
$this->invex =& $this->modes->ui;
}
function destroy() {
global $i, $channels;
run_callback('destroy_chan',$i,$this);
unset($channels[strtolower($this->name)]);
}
}
class cumodes {
//public $q = false, $a = false, $o = false, $h = false, $v = false;
protected $channel, $user;
public function __construct(channel &$channel, user &$user) {
//if ($channel instanceof channel)
$this->channel =& $channel;
$this->user =& $user;
}
public function __set ( $name, $value ) {
if (!isset($this->$name)) {
return error_log("error setting mode $name for cumode");
}
$mm = "l".$name;
if ($value)
$this->channel->modes->$mm[$this->user->lnick()] =& $this->user;
else
unset($this->channel->modes->$mm[$this->user->lnick()]);
}
public function __get ( $name ) {
if (!isset($this->$name)) {
return error_log("error setting mode $name for cumode");
}
$mm = "l".$name;
return array_key_exists($this->user->lnick(), $this->channel->modes->$mm);
}
public function __isset ( $name ) {
return in_array($name,array('q','a','o','h','v'));
}
}
class cmodes {
private $parent = null;
public $lb = array(), $le = array(), $ui = array();
public $lq = array(), $la = array(), $lo = array(), $lh = array(), $lv = array();
public $lc = false, $lf = false, $li = false, $lj = false, $lk = false, $ll = false, $lm = false,
$ln = false, $lp = false, $lr = false, $ls = false, $lt = false, $lz = false, $ua = false,
$uc = false, $ug = false, $um = false, $uk = false, $ul = false, $un = false, $uo = false,
$uq = false, $ur = false, $us = false, $ut = false, $uv = false, $lu = false;
function __construct(&$parent) {
$this->parent =& $parent;
}
function cmodetype ($mode) {
if (in_array($mode,array('c','i','m','n','p','r','s','t','z','A','C','G','M','K','N','O','Q','R','S','T','V','u'))) return CM_BOO;
if (in_array($mode,array('l'))) return CM_INT;
if (in_array($mode,array('k','L'))) return CM_STR;
if (in_array($mode,array('j'))) return CM_ARR;
if (in_array($mode,array('f'))) return CM_FLD;
if (in_array($mode,array('q','a','o','h','v'))) return CM_USR;
if (in_array($mode,array('b','e','I'))) return CM_WLD;
return 0;
}
function apply($modes, $realworld = true, &$cleanmodes = '', &$cleanpars = array()) {
//apply ( str $modes e.g. +nt-f+Q, bool $realworld is sandbox or is protocol ... )
global $users;
$modes = firstword($modes, $params);
$params = explode(' ',trim($params));
$plus = true;
for ($i = 0; $i < strlen($modes); ++$i) {
if ($modes{$i} == '+') {
$plus = true;
if ($i and in_array($modes{$i-1},array('+','-')))
$cleanmodes = substr($cleanmodes,0,-1);
$cleanmodes .= '+';
continue;
}
if ($modes{$i} == '-') {
$plus = false;
if ($i and in_array($modes{$i-1},array('+','-')))
$cleanmodes = substr($cleanmodes,0,-1);
$cleanmodes .= '-';
continue;
}
$mm = (abs(strcmp($modes{$i},strtolower($modes{$i}))) ? 'u' : 'l') . strtolower($modes{$i});
$mt = $this->cmodetype($modes{$i});
if (!$mt) {
errlog("{$this->parent->name}->apply","Unknown mode {$modes{$i}}");
if ($realworld) return;
continue;
}
if ($mt == CM_BOO) {
if ($this->$mm != $plus)
$cleanmodes .= $modes{$i};
$this->$mm = $plus;
}
elseif (!$plus and $mt <= CM_FLD) {
if ($this->$mm) {
$cleanmodes .= $modes{$i};
if ($mm == 'lk') { //stupid stupid unreal
$cleanpars[] = $this->$mm;
}
}
$this->$mm = false;
}
else {
if ($this->$mm === false and $mt < CM_FLD) {
$cleanmodes .= $modes{$i};
$cleanpars[] = current($params);
}
switch ($mt) {
case CM_INT:
$this->$mm = (int)current($params);
break;
case CM_STR:
$this->$mm = current($params);
break;
case CM_ARR:
$this->$mm = explode(':',current($params),2);
break;
case CM_FLD:
if (!preg_match('/^\[[0-9]*[cjkmnt](#[CmMiRKNb][0-9]*)?(,[0-9]*[cjkmnt](#[CmMiRKNb][0-9]*)?)*\]:[0-9]+$/',current($params))) {
//if ($realworld) throw new Exception("Bad CM_FLD ".current($params)."; Referenced at {$this->parent->name}->apply");
errlog("{$this->parent->name}->apply","Bad CM_FLD ".current($params));
continue;
}
$this->$mm = current($params);
break;
case CM_USR:
if (!ake(strtolower(current($params)),$users)) {
errlog("{$this->parent->name}->apply","Unknown user ".current($params)." not in \$users");
//if ($realworld) return;
next($params);
continue;
}
if (!ake(strtolower(current($params)),$this->parent->userlist)) {
//if ($realworld) throw new Exception("Unknown user ".current($params)."; Not found in channel userlist; Referenced at {$this->parent->name}->apply");
errlog("{$this->parent->name}->apply","Unknown user ".current($params)." not in channel userlist");
next($params);
continue;
}
if (($plus and !ake(strtolower(current($params)),$this->$mm))
or (!$plus and ake(strtolower(current($params)),$this->$mm))) {
$cleanmodes .= $modes{$i};
$cleanpars[] = current($params);
}
$thismm =& $this->$mm;
if ($plus) {
$thismm[strtolower(current($params))] =& $users[strtolower(current($params))];
}
else {
unset($thismm[strtolower(current($params))]);
}
//$this->parent->userlist[strtolower(current($params))]['modes']->$modes{$i} = $plus;
break;
case CM_WLD:
if ($plus and !ake(strtolower(current($params)),$this->$mm)) {
$cleanmodes .= $modes{$i};
$cleanpars[] = current($params);
$this->{$mm}[strtolower(current($params))] = current($params);
}
elseif (!$plus and ake(strtolower(current($params)),$this->$mm)) {
$cleanmodes .= $modes{$i};
$cleanpars[] = current($params);
unset($this->{$mm}[strtolower(current($params))]);
}
break;
}
if ($mt != CM_BOO and $mt != CM_USR and $this->$mm) {
$cleanmodes .= $modes{$i};
$cleanpars[] = current($params);
}
if ($mt and $mt != CM_BOO)
next($params);
}
}
$cleanmodes = rtrim($cleanmodes,'+-');
}
}
//------------------------------------------------------------------------------
// on nick change
} else {
$newnick = firstword($par,$ts);
global $users;
if (!ake(strtolower($source),$users))
return "didn't find user $source; nick change to $newnick failed";
last_corruptor_check($users[strtolower($source)],$this);
$u =& $users[strtolower($source)];
run_callback('newnick',$this,$u,$newnick);
$u->nick = $newnick;
$u->signon = $ts;
$users[$u->lnick()] =& $u;
unset($users[strtolower($source)]);
$servusers =& $u->server->users;
$servusers[$u->lnick()] =& $u;
unset($servusers[strtolower($source)]);
foreach($u->channels as &$chan) {
$chan->userlist[$u->lnick()] =& $chan->userlist[strtolower($source)];
/*array('user' => &$u,
'modes' => $chan->userlist[strtolower($source)]['modes'],
'flags' => $chan->userlist[strtolower($source)]['flags']);*/
//$chan->userlist[strtolower($source)]['modes'] = new cumodes();
unset($chan->userlist[strtolower($source)]);
if (ake(strtolower($source),$chan->userlist)) return "failed to clean up at $chan->name for $source >> $u->nick";
foreach (array('lq','la','lo','lh','lv') as $mm) {
if (!ake(strtolower($source),$chan->modes->$mm)) continue;
$chan->modes->$mm[$u->lnick()] =& $u;
unset($chan->modes->$mm[strtolower($source)]);
}
}
}