require_once("P10_ModeSets.class.php");
require_once("EventHandler.interface.php");
+$e=1;
+define("ERR_NICK_IN_USE", $e++);
+define("ERR_INVALID_USER", $e++);
+define("ERR_INVALID_CHANNAME", $e++);
+define("ERR_NOT_CONNECTED", $e++);
+define("ERR_NOT_ON_CHANNEL", $e++);
+
class Uplink {
private $client;
private $settings = array();
private $server;
private $eventHandler = null;
+ private $last_local_numeric = 1;
const FLAG_P10SESSION = 0x0001; //connection is in P10 mode (server is connected)
const FLAG_SECURITY_QUIT = 0x0002; //local connection abort because of security issues
if($cmdPos == 1) $from = $tokens[0];
else $from = null;
$arguments = array_slice($tokens, $cmdPos + 1);
+ if(($this->flags & self::FLAG_P10SESSION) && $this->eventHandler) {
+ $this->eventHandler->event_preparse($from, strtoupper($tokens[$cmdPos]), $arguments);
+ }
switch(strtoupper($tokens[$cmdPos])) {
//pre P10 Session
case "PASS":
case "L":
$this->recv_part($from, $arguments);
break;
+ case "K":
+ $this->recv_kick($from, $arguments);
+ break;
+ case "D":
+ $this->recv_kill($from, $arguments);
+ break;
+ case "P":
+ $this->recv_privmsg($from, $arguments);
+ break;
+ case "O":
+ $this->recv_notice($from, $arguments);
+ break;
//default
default:
//unknown cmd
+ if($this->eventHandler)
+ $this->eventHandler->event_unknown_cmd($from, strtoupper($tokens[$cmdPos]), $arguments);
break;
}
}
return;
}
if($this->eventHandler)
- $this->eventHandler->event_quit($user, $args[1]);
+ $this->eventHandler->event_quit($user, $args[0]);
$user->quit($args[0]);
}
$channel->partUser($user);
}
+ private function recv_kick($from, $args) {
+ $user = P10_User::getUserByNum($from);
+ if($user == null) {
+ trigger_error("An unknown user tries to kick another user on recv_kick.", E_USER_ERROR);
+ return;
+ }
+ $channel = P10_Channel::getChannelByName($args[0]);
+ if($channel == null)
+ $channel = new P10_Channel($args[0]);
+ $target = P10_User::getUserByNum($args[1]);
+ if($target == null) {
+ trigger_error("Someone tries to kick an user that does not exist or was not found on recv_kick.", E_USER_ERROR);
+ return;
+ }
+ if($this->eventHandler)
+ $this->eventHandler->event_kick($user, $target, $channel, $args[1]);
+ $channel->partUser($user);
+ }
+
+ private function recv_kill($from, $args) {
+ $user = P10_User::getUserByNum($args[0]);
+ if($user == null) {
+ trigger_error("Server tries to kill an user that does not exist or was not found on recv_quit.", E_USER_ERROR);
+ return;
+ }
+ if($this->eventHandler)
+ $this->eventHandler->event_quit($user, "Killed (".$args[1].")");
+ $user->quit($args[1]);
+ }
+
+ private function recv_privmsg($from, $args) {
+ $user = P10_User::getUserByNum($from);
+ if($user == null) {
+ trigger_error("Server tries to send a privmsg from an user that does not exist or was not found on recv_privmsg.", E_USER_ERROR);
+ return;
+ }
+ if($this->eventHandler) {
+ if($args[0] == "#") {
+ $channel = P10_Channel::getChannelByName($args[0]);
+ if($channel == null)
+ $channel = new P10_Channel($args[0]);
+ $this->eventHandler->event_chanmessage($user, $channel, $args[1]);
+ } else {
+ $targetUser = P10_User::getUserByNum($args[0]);
+ if($targetUser == null) {
+ trigger_error("Server tries to send a privmsg to an user that does not exist or was not found on recv_privmsg.", E_USER_ERROR);
+ return;
+ }
+ $this->eventHandler->event_privmessage($user, $targetUser, $args[1]);
+ }
+ }
+ }
+
+ private function recv_notice($from, $args) {
+ $user = P10_User::getUserByNum($from);
+ if($user == null) {
+ trigger_error("Server tries to send a notice from an user that does not exist or was not found on recv_notice.", E_USER_ERROR);
+ return;
+ }
+ if($this->eventHandler) {
+ if($args[0] == "#") {
+ $channel = P10_Channel::getChannelByName($args[0]);
+ if($channel == null)
+ $channel = new P10_Channel($args[0]);
+ $this->eventHandler->event_channotice($user, $channel, $args[1]);
+ } else {
+ $targetUser = P10_User::getUserByNum($args[0]);
+ if($targetUser == null) {
+ trigger_error("Server tries to send a notice to an user that does not exist or was not found on recv_notice.", E_USER_ERROR);
+ return;
+ }
+ $this->eventHandler->event_privnotice($user, $targetUser, $args[1]);
+ }
+ }
+ }
+
/********************************************************************************************
* SERVER FUNCTIONS *
********************************************************************************************/
$local_users = true;
$sorted_users[$strPrivs][] = $user;
}
- if(!$local_users) continue;
+ if(!$local_users && !$channel->getModes()->hasMode("z")) continue;
$userStr = "";
foreach($sorted_users['-'] as $user) {
if($userStr != "") $userStr.=",";
$this->send("EB");
}
+ /********************************************************************************************
+ * LOCAL USER FUNCTIONS *
+ ********************************************************************************************/
+
+ public function addUser($nick, $ident, $host, $ip, $modes, $realname) {
+ $user = P10_User::getUserByNick($nick);
+ if($user != null) return ERR_NICK_IN_USE;
+ $numeric = substr($this->server->getNumeric(),0,2).Numerics::intToNum($this->last_local_numeric, 3);
+ while(P10_User::getUserByNum($numeric)) {
+ $this->last_local_numeric++;
+ $numeric = substr($this->server->getNumeric(),0,2).Numerics::intToNum($this->last_local_numeric, 3);
+ }
+ $this->last_local_numeric++;
+ $user = new P10_User($nick, $numeric, $this->server, time(), $ident, $host, $ip, $realname, $modes);
+ if(($this->flags & self::FLAG_CONNECTED)) {
+ $ip = Numerics::numericFromIP($user->getIP());
+ $this->send("N", $nick, $user->getConnectTime(), $ident, $host, $user->getModes()->getModeString(), $ip, $numeric, $realname);
+ }
+ return $user;
+ }
+
+ public function delUser($user, $reason) {
+ if(!is_a($user, "P10_User")) return ERR_INVALID_USER;
+ if($user->getServer() === $this->server) {
+ //local user (QUIT)
+ $user->quit($reason);
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send("Q", $user->getNumeric(), $reason);
+ } else {
+ //remote user (KILL)
+ if(!($this->flags & self::FLAG_CONNECTED))
+ return ERR_NOT_CONNECTED;
+ if($this->eventHandler)
+ $this->eventHandler->event_quit($user, "Killed (".$reason.")");
+ $user->quit("Killed (".$reason.")");
+ $name = ($this->getSetting('his_name') ? $this->getSetting('his_name') : $this->getSetting('name'));
+
+ $this->send("D", $user->getNumeric(), $name, $reason);
+ }
+ }
+
+ public function join($user, $chanName) {
+ if(!is_a($user, "P10_User") || !($user->getServer() === $this->server))
+ return ERR_INVALID_USER;
+ if($chanName[0] != "#")
+ return ERR_INVALID_CHANNAME;
+ $channel = P10_Channel::getChannelByName($chanName);
+ if($channel == null)
+ $channel = new P10_Channel($chanName);
+ $channel->joinUser($user);
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send("J", $user->getNumeric(), $chanName, time(), 0);
+ if($this->eventHandler)
+ $this->eventHandler->event_join($user, $channel, false);
+ }
+
+ public function part($user, $chanName, $reason) {
+ if(!is_a($user, "P10_User") || !($user->getServer() === $this->server))
+ return ERR_INVALID_USER;
+ if(!((is_string($chanName) && $chanName[0] == "#") || is_a($chanName, "P10_Channel")))
+ return ERR_INVALID_CHANNAME;
+ if(is_a($chanName, "P10_Channel"))
+ $channel = $chanName;
+ else
+ $channel = P10_Channel::getChannelByName($chanName);
+ if($channel == null)
+ $channel = new P10_Channel($chanName);
+ if(!$user->isOnChannel($channel))
+ return ERR_NOT_ON_CHANNEL;
+ if($this->eventHandler)
+ $this->eventHandler->event_part($user, $channel, $reason);
+ $channel->partUser($user, $reason);
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send("L", $user->getNumeric(), $chanName, $reason);
+ }
+
+ public function kick($user, $target, $chanName, $reason) {
+ if(!is_a($user, "P10_User") || !($user->getServer() === $this->server))
+ return ERR_INVALID_USER;
+ if(!is_a($target, "P10_User"))
+ return ERR_INVALID_USER;
+ if(!((is_string($chanName) && $chanName[0] == "#") || is_a($chanName, "P10_Channel")))
+ return ERR_INVALID_CHANNAME;
+ if(is_a($chanName, "P10_Channel"))
+ $channel = $chanName;
+ else
+ $channel = P10_Channel::getChannelByName($chanName);
+ if($channel == null)
+ $channel = new P10_Channel($chanName);
+ if(!$target->isOnChannel($channel))
+ return ERR_NOT_ON_CHANNEL;
+ if($this->eventHandler)
+ $this->eventHandler->event_kick($user, $target, $channel, $reason);
+ $channel->partUser($target, $reason);
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send("K", $user->getNumeric(), $chanName, $target->getNumeric(), $reason);
+ }
+
+ public function privmsg($user, $target, $message) {
+ if(!is_a($user, "P10_User") || !($user->getServer() === $this->server))
+ return ERR_INVALID_USER;
+ if(!is_a($target, "P10_User") && !is_a($target, "P10_Channel") && !(is_string($target) && ($target[0] == "#" || P10_User::getUserByNick($target))))
+ return ERR_INVALID_USER;
+ if(is_a($target, "P10_Channel"))
+ $targetStr = $target->getName();
+ else if(is_a($target, "P10_User"))
+ $targetStr = $target->getNumeric();
+ else if($target[0] == "#")
+ $targetStr = $target;
+ else
+ $targetStr = P10_User::getUserByNick($target)->getNumeric();
+
+ if($this->eventHandler) {
+ if($targetStr[0] == "#") {
+ $channel = P10_Channel::getChannelByName($targetStr);
+ if($channel == null)
+ $channel = new P10_Channel($targetStr);
+ $this->eventHandler->event_chanmessage($user, $channel, $message);
+ } else {
+ $targetUser = P10_User::getUserByNum($targetStr);
+ $this->eventHandler->event_privmessage($user, $targetUser, $message);
+ }
+ }
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send("P", $user->getNumeric(), $targetStr, $message);
+ }
+
+ public function notice($user, $target, $message) {
+ if(!is_a($user, "P10_User") || !($user->getServer() === $this->server))
+ return ERR_INVALID_USER;
+ if(!is_a($target, "P10_User") && !is_a($target, "P10_Channel") && !(is_string($target) && ($target[0] == "#" || P10_User::getUserByNick($target))))
+ return ERR_INVALID_USER;
+ if(is_a($target, "P10_Channel"))
+ $targetStr = $target->getName();
+ else if(is_a($target, "P10_User"))
+ $targetStr = $target->getNumeric();
+ else if($target[0] == "#")
+ $targetStr = $target;
+ else
+ $targetStr = P10_User::getUserByNick($target)->getNumeric();
+
+ if($this->eventHandler) {
+ if($targetStr[0] == "#") {
+ $channel = P10_Channel::getChannelByName($targetStr);
+ if($channel == null)
+ $channel = new P10_Channel($targetStr);
+ $this->eventHandler->event_channotice($user, $channel, $message);
+ } else {
+ $targetUser = P10_User::getUserByNum($targetStr);
+ $this->eventHandler->event_privnotice($user, $targetUser, $message);
+ }
+ }
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send("O", $user->getNumeric(), $targetStr, $message);
+ }
+
+ public function mode($user, $target, $modes, $force = false) {
+ if(!is_a($user, "P10_User") || !($user->getServer() === $this->server))
+ return ERR_INVALID_USER;
+ if(!is_a($target, "P10_User") && !is_a($target, "P10_Channel") && !(is_string($target) && ($target[0] == "#" || P10_User::getUserByNick($target))))
+ return ERR_INVALID_USER;
+ if(is_a($target, "P10_Channel"))
+ $targetStr = $target->getName();
+ else if(is_a($target, "P10_User"))
+ $targetStr = $target->getNumeric();
+ else if($target[0] == "#")
+ $targetStr = $target;
+ else
+ $targetStr = P10_User::getUserByNick($target)->getNumeric();
+
+ if($targetStr[0] == "#") {
+ $channel = P10_Channel::getChannelByName($targetStr);
+ if($channel == null)
+ $channel = new P10_Channel($targetStr);
+ $modes = $channel->getModes()->setModes($modes);
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send(($force ? "OM" : "M"), $user->getNumeric(), $targetStr, $modes);
+ if($this->eventHandler)
+ $this->eventHandler->event_chanmode(($force ? $this->server : $user), $channel, $modes);
+ } else {
+ $targetUser = P10_User::getUserByNum($targetStr);
+ if($targetUser->getServer() === $this->server) {
+ //just do it :D
+ $modes = $targetUser->getModes()->setModes($modes);
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send("M", $targetUser->getNumeric(), $targetUser->getNick(), $modes);
+ if($this->eventHandler)
+ $this->eventHandler->event_usermode($targetUser, $modes);
+ } else {
+ //SVSMODE
+ if(($this->flags & self::FLAG_CONNECTED))
+ $this->send("SM", $user->getNumeric(), $targetUser->getNumeric(), $modes);
+ }
+ }
+ }
+
+
+
}
?>
\ No newline at end of file