diff --git a/src/pocketmine/BanAPI.php b/src/pocketmine/BanAPI.php deleted file mode 100644 index 05db4f2d3..000000000 --- a/src/pocketmine/BanAPI.php +++ /dev/null @@ -1,411 +0,0 @@ -server = Server::getInstance(); - } - - public function init(){ - $this->whitelist = new Config(\pocketmine\DATA . "white-list.txt", Config::ENUM); //Open whitelist list file - $this->bannedIPs = new Config(\pocketmine\DATA . "banned-ips.txt", Config::ENUM); //Open Banned IPs list file - $this->banned = new Config(\pocketmine\DATA . "banned.txt", Config::ENUM); //Open Banned Usernames list file - $this->ops = new Config(\pocketmine\DATA . "ops.txt", Config::ENUM); //Open list of OPs - $this->server->api->console->register("banip", " [IP|player]", array($this, "commandHandler")); - $this->server->api->console->register("ban", " [username]", array($this, "commandHandler")); - $this->server->api->console->register("kick", " [reason ...]", array($this, "commandHandler")); - $this->server->api->console->register("whitelist", " [username]", array($this, "commandHandler")); - $this->server->api->console->register("op", "", array($this, "commandHandler")); - $this->server->api->console->register("deop", "", array($this, "commandHandler")); - $this->server->api->console->register("sudo", " ", array($this, "commandHandler")); - $this->server->api->console->alias("ban-ip", "banip add"); - $this->server->api->console->alias("banlist", "ban list"); - $this->server->api->console->alias("pardon", "ban remove"); - $this->server->api->console->alias("pardon-ip", "banip remove"); - $this->server->addHandler("console.command", array($this, "permissionsCheck"), 1); //Event handler when commands are issued. Used to check permissions of commands that go through the server. - $this->server->addHandler("player.block.break", array($this, "permissionsCheck"), 1); //Event handler for blocks - $this->server->addHandler("player.block.place", array($this, "permissionsCheck"), 1); //Event handler for blocks - $this->server->addHandler("player.flying", array($this, "permissionsCheck"), 1); //Flying Event - } - - /** - * @param string $cmd Command to Whitelist - */ - public function cmdWhitelist($cmd){ //Whitelists a CMD so everyone can issue it - Even non OPs. - $this->cmdWhitelist[strtolower(trim($cmd))] = true; - } - - /** - * @param string $username - * - * @return boolean - */ - public function isOp($username){ //Is a player op? - $username = strtolower($username); - if($this->server->api->dhandle("op.check", $username) === true){ - return true; - }elseif($this->ops->exists($username)){ - return true; - } - - return false; - } - - /** - * @param mixed $data - * @param string $event - * - * @return boolean - */ - public function permissionsCheck($data, $event){ - switch($event){ - case "player.flying": //OPs can fly around the server. - if($this->isOp($data->getName())){ - return true; - } - break; - case "player.block.break": - case "player.block.place": //Spawn protection detection. Allows OPs to place/break blocks in the spawn area. - if(!$this->isOp($data["player"]->getName())){ - $t = new Vector2($data["target"]->x, $data["target"]->z); - $s = new Vector2(Level::getDefault()->getSpawn()->x, Level::getDefault()->getSpawn()->z); - if($t->distance($s) <= $this->server->api->getProperty("spawn-protection") and $this->server->api->dhandle($event . ".spawn", $data) !== true){ - return false; - } - } - - return; - case "console.command": //Checks if a command is allowed with the current user permissions. - if(isset($this->cmdWhitelist[$data["cmd"]])){ - return; - } - - if($data["issuer"] instanceof Player){ - if($this->server->api->handle("console.check", $data) === true or $this->isOp($data["issuer"]->getName())){ - return; - } - }elseif($data["issuer"] === "console" or $data["issuer"] === "rcon"){ - return; - } - - return false; - } - } - - /** - * @param string $cmd - * @param array $params - * @param string $issuer - * @param string $alias - * - * @return string - */ - public function commandHandler($cmd, $params, $issuer, $alias){ - $output = ""; - switch($cmd){ - case "sudo": - $target = strtolower(array_shift($params)); - $player = Player::get($target); - if(!($player instanceof Player)){ - $output .= "Player not connected.\n"; - break; - } - $this->server->api->console->run(implode(" ", $params), $player); - $output .= "Command ran as " . $player->getName() . ".\n"; - break; - case "op": - $user = strtolower($params[0]); - if($user == null){ - $output .= "Usage: /op \n"; - break; - } - $player = Player::get($user); - if(!($player instanceof Player)){ - $this->ops->set($user); - $this->ops->save(); - $output .= $user . " is now op\n"; - break; - } - $this->ops->set(strtolower($player->getName())); - $this->ops->save(); - $output .= $player->getName() . " is now op\n"; - $player->sendMessage("You are now op."); - break; - case "deop": - $user = strtolower($params[0]); - $player = Player::get($user); - if(!($player instanceof Player)){ - $this->ops->remove($user); - $this->ops->save(); - $output .= $user . " is no longer op\n"; - break; - } - $this->ops->remove(strtolower($player->getName())); - $this->ops->save(); - $output .= $player->getName() . " is no longer op\n"; - $player->sendMessage("You are no longer op."); - break; - case "kick": - if(!isset($params[0])){ - $output .= "Usage: /kick [reason ...]\n"; - }else{ - $name = strtolower(array_shift($params)); - $player = Player::get($name); - if($player === false){ - $output .= "Player \"" . $name . "\" does not exist\n"; - }else{ - $reason = implode(" ", $params); - $reason = $reason == "" ? "No reason" : $reason; - - $this->server->schedule(60, array($player, "close"), "You have been kicked: " . $reason); //Forces a kick - $player->blocked = true; - if($issuer instanceof Player){ - Player::broadcastMessage($player->getName() . " has been kicked by " . $issuer->getName() . ": $reason\n"); - }else{ - Player::broadcastMessage($player->getName() . " has been kicked: $reason\n"); - } - } - } - break; - case "whitelist": - $p = strtolower(array_shift($params)); - switch($p){ - case "remove": - $user = strtolower($params[0]); - $this->whitelist->remove($user); - $this->whitelist->save(); - $output .= "Player \"$user\" removed from white-list\n"; - break; - case "add": - $user = strtolower($params[0]); - $this->whitelist->set($user); - $this->whitelist->save(); - $output .= "Player \"$user\" added to white-list\n"; - break; - case "reload": - $this->whitelist = new Config(\pocketmine\DATA . "white-list.txt", Config::ENUM); - break; - case "list": - $output .= "White-list: " . implode(", ", $this->whitelist->getAll(true)) . "\n"; - break; - case "on": - case "true": - case "1": - $output .= "White-list turned on\n"; - $this->server->api->setProperty("white-list", true); - break; - case "off": - case "false": - case "0": - $output .= "White-list turned off\n"; - $this->server->api->setProperty("white-list", false); - break; - default: - $output .= "Usage: /whitelist [username]\n"; - break; - } - break; - case "banip": - $p = strtolower(array_shift($params)); - switch($p){ - case "pardon": - case "remove": - $ip = strtolower($params[0]); - $this->bannedIPs->remove($ip); - $this->bannedIPs->save(); - $output .= "IP \"$ip\" removed from ban list\n"; - break; - case "add": - case "ban": - $ip = strtolower($params[0]); - $player = Player::get($ip); - if($player instanceof Player){ - $ip = $player->getIP(); - $player->kick("You are banned"); - } - $this->bannedIPs->set($ip); - $this->bannedIPs->save(); - $output .= "IP \"$ip\" added to ban list\n"; - break; - case "reload": - $this->bannedIPs = new Config(\pocketmine\DATA . "banned-ips.txt", Config::ENUM); - break; - case "list": - $output .= "IP ban list: " . implode(", ", $this->bannedIPs->getAll(true)) . "\n"; - break; - default: - $output .= "Usage: /banip [IP|player]\n"; - break; - } - break; - case "ban": - $p = strtolower(array_shift($params)); - switch($p){ - case "pardon": - case "remove": - $user = strtolower($params[0]); - $this->banned->remove($user); - $this->banned->save(); - $output .= "Player \"$user\" removed from ban list\n"; - break; - case "add": - case "ban": - $user = strtolower($params[0]); - $this->banned->set($user); - $this->banned->save(); - $player = Player::get($user); - if($player !== false){ - $player->kick("You are banned"); - } - if($issuer instanceof Player){ - Player::broadcastMessage($user . " has been banned by " . $issuer->getName() . "\n"); - }else{ - Player::broadcastMessage($user . " has been banned\n"); - } - $this->kick($user, "Banned"); - $output .= "Player \"$user\" added to ban list\n"; - break; - case "reload": - $this->banned = new Config(\pocketmine\DATA . "banned.txt", Config::ENUM); - break; - case "list": - $output .= "Ban list: " . implode(", ", $this->banned->getAll(true)) . "\n"; - break; - default: - $output .= "Usage: /ban [username]\n"; - break; - } - break; - } - - return $output; - } - - /** - * @param string $username - */ - public function ban($username){ - $this->commandHandler("ban", array("add", $username), "console", ""); - } - - /** - * @param string $username - */ - public function pardon($username){ - $this->commandHandler("ban", array("pardon", $username), "console", ""); - } - - /** - * @param string $ip - */ - public function banIP($ip){ - $this->commandHandler("banip", array("add", $ip), "console", ""); - } - - /** - * @param string $ip - */ - public function pardonIP($ip){ - $this->commandHandler("banip", array("pardon", $ip), "console", ""); - } - - /** - * @param string $username - * @param string $reason - */ - public function kick($username, $reason = "No Reason"){ - $this->commandHandler("kick", array($username, $reason), "console", ""); - } - - public function reload(){ - $this->commandHandler("ban", array("reload"), "console", ""); - $this->commandHandler("banip", array("reload"), "console", ""); - $this->commandHandler("whitelist", array("reload"), "console", ""); - } - - /** - * @param string $ip - * - * @return boolean - */ - public function isIPBanned($ip){ - if($this->server->api->dhandle("api.ban.ip.check", $ip) === false){ - return true; - }elseif($this->bannedIPs->exists($ip, true)){ - return true; - }else{ - return false; - } - } - - /** - * @param string $username - * - * @return boolean - */ - public function isBanned($username){ - $username = strtolower($username); - if($this->server->api->dhandle("api.ban.check", $username) === false){ - return true; - }elseif($this->banned->exists($username, true)){ - return true; - }else{ - return false; - } - } - - /** - * @param string $username - * - * @return boolean - */ - public function inWhitelist($username){ - $username = strtolower($username); - if($this->isOp($username)){ - return true; - }elseif($this->server->api->dhandle("api.ban.whitelist.check", $username) === false){ - return true; - }elseif($this->whitelist->exists($username, true)){ - return true; - } - - return false; - } -} diff --git a/src/pocketmine/Player.php b/src/pocketmine/Player.php index a87fbdd85..a6de899f7 100644 --- a/src/pocketmine/Player.php +++ b/src/pocketmine/Player.php @@ -1282,17 +1282,14 @@ class Player extends Human implements CommandSender, IPlayer{ $this->server->getPluginManager()->callEvent($ev = new event\player\PlayerPreLoginEvent($this, "Plugin reason")); if($ev->isCancelled()){ $this->close($ev->getKickMessage(), "Plugin reason"); - return; } if(!$this->server->isWhitelisted(strtolower($this->getName()))){ $this->close($this->username . " has left the game", "Server is white-listed"); - return; }elseif($this->server->getNameBans()->isBanned(strtolower($this->getName())) or $this->server->getIPBans()->isBanned($this->getAddress())){ $this->close($this->username . " has left the game", "You are banned"); - return; } @@ -1303,15 +1300,11 @@ class Player extends Human implements CommandSender, IPlayer{ $this->server->getPluginManager()->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this); } - //TODO - /*$u = $this->server->matchPlayer($this->username); - if(count($u) > 0){ - foreach($u as $p){ - if($p !== $this){ - $p->close($p->getDisplayName() . " has left the game", "logged in from another location"); - } + foreach($this->server->getOnlinePlayers() as $p){ + if($p !== $this and strtolower($p->getName()) === strtolower($this->getName())){ + $p->close($p->getName() . " has left the game", "logged in from another location"); } - }*/ + } $nbt = $this->server->getOfflinePlayerData($this->username); if(!isset($nbt->NameTag)){ @@ -2279,6 +2272,9 @@ class Player extends Human implements CommandSender, IPlayer{ if($this->loggedIn === true){ parent::close(); $this->save(); + if($this->namedtag instanceof Compound){ + $this->server->saveOfflinePlayerData($this->username, $this->namedtag); + } } } @@ -2296,9 +2292,7 @@ class Player extends Human implements CommandSender, IPlayer{ $this->receiveQueue = array(); $this->resendQueue = array(); $this->ackQueue = array(); - if($this->username != "" and ($this->namedtag instanceof Compound)){ - $this->server->saveOfflinePlayerData($this->username, $this->namedtag); - } + if(isset($ev) and $this->username != "" and $this->spawned !== false and $ev->getQuitMessage() != ""){ $this->server->broadcastMessage($ev->getQuitMessage()); } diff --git a/src/pocketmine/command/SimpleCommandMap.php b/src/pocketmine/command/SimpleCommandMap.php index eb644291c..63654596d 100644 --- a/src/pocketmine/command/SimpleCommandMap.php +++ b/src/pocketmine/command/SimpleCommandMap.php @@ -41,6 +41,7 @@ use pocketmine\command\defaults\StopCommand; use pocketmine\command\defaults\TellCommand; use pocketmine\command\defaults\VanillaCommand; use pocketmine\command\defaults\VersionCommand; +use pocketmine\command\defaults\WhitelistCommand; use pocketmine\Server; class SimpleCommandMap implements CommandMap{ @@ -78,6 +79,7 @@ class SimpleCommandMap implements CommandMap{ $this->register("pocketmine", new KickCommand("kick")); $this->register("pocketmine", new OpCommand("op")); $this->register("pocketmine", new DeopCommand("deop")); + $this->register("pocketmine", new WhitelistCommand("whitelist")); } diff --git a/src/pocketmine/command/defaults/WhitelistCommand.php b/src/pocketmine/command/defaults/WhitelistCommand.php new file mode 100644 index 000000000..98361cd66 --- /dev/null +++ b/src/pocketmine/command/defaults/WhitelistCommand.php @@ -0,0 +1,98 @@ +\n/whitelist (on|off|list|reload)" + ); + $this->setPermission("pocketmine.command.whitelist.reload;pocketmine.command.whitelist.enable;pocketmine.command.whitelist.disable;pocketmine.command.whitelist.list;pocketmine.command.whitelist.add;pocketmine.command.whitelist.remove"); + } + + public function execute(CommandSender $sender, $currentAlias, array $args){ + if(!$this->testPermission($sender)){ + return true; + } + + if(count($args) === 1){ + if($this->badPerm($sender, strtolower($args[0]))){ + return true; + } + switch(strtolower($args[0])){ + case "reload": + Server::getInstance()->reloadWhitelist(); + Command::broadcastCommandMessage($sender, "Reloaded white-list from file"); + return true; + case "on": + Server::getInstance()->setConfigBool("white-list", true); + Command::broadcastCommandMessage($sender, "Turned on white-listing"); + return true; + case "off": + Server::getInstance()->setConfigBool("white-list", false); + Command::broadcastCommandMessage($sender, "Turned off white-listing"); + return true; + case "list": + $result = ""; + foreach(Server::getInstance()->getWhitelisted() as $player){ + $result .= $player . ", "; + } + $sender->sendMessage("White-listed players: " . substr($result, 0, -2)); + return true; + } + }elseif(count($args) === 2){ + if($this->badPerm($sender, strtolower($args[0]))){ + return true; + } + switch(strtolower($args[0])){ + case "add": + Server::getInstance()->getOfflinePlayer($args[1])->setWhitelisted(true); + Command::broadcastCommandMessage($sender, "Added ". $args[1] . " to white-list"); + return true; + case "remove": + Server::getInstance()->getOfflinePlayer($args[1])->setWhitelisted(false); + Command::broadcastCommandMessage($sender, "Removed ". $args[1] . " from white-list"); + return true; + } + } + + $sender->sendMessage(TextFormat::RED . "Usage:\n" . $this->usageMessage); + return true; + } + + private function badPerm(CommandSender $sender, $perm){ + if(!$sender->hasPermission("pocketmine.command.whitelist.$perm")){ + $sender->sendMessage(TextFormat::RED . "You do not have permission to perform this action."); + return true; + } + return false; + } +} \ No newline at end of file diff --git a/src/pocketmine/level/Level.php b/src/pocketmine/level/Level.php index b955a2297..43c5c526b 100644 --- a/src/pocketmine/level/Level.php +++ b/src/pocketmine/level/Level.php @@ -32,6 +32,7 @@ use pocketmine\event\block\BlockPlaceEvent; use pocketmine\event\player\PlayerInteractEvent; use pocketmine\item\Item; use pocketmine\level\generator\Generator; +use pocketmine\math\Vector2; use pocketmine\math\Vector3 as Vector3; use pocketmine\nbt\NBT; use pocketmine\nbt\tag\Compound; @@ -382,7 +383,7 @@ class Level{ * @return bool */ public function isLoaded(){ - return $this->level instanceof LevelFormat; + return isset($this->level) and $this->level instanceof LevelFormat; } /** @@ -594,11 +595,19 @@ class Level{ } //TODO: Adventure mode checks + if($player instanceof Player){ $ev = new BlockBreakEvent($player, $target, $item, ($player->getGamemode() & 0x01) === 1 ? true : false); if($item instanceof Item and !$target->isBreakable($item) and $ev->getInstaBreak() === false){ $ev->setCancelled(); } + if(!$player->isOp() and ($distance = $this->server->getConfigInt("spawn-protection", 16)) > -1){ + $t = new Vector2($target->x, $target->z); + $s = new Vector2($this->getSpawn()->x, $this->getSpawn()->z); + if($t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this + $ev->setCancelled(); + } + } $this->server->getPluginManager()->callEvent($ev); if($ev->isCancelled()){ return false; @@ -622,7 +631,7 @@ class Level{ * Uses a item on a position and face, placing it or activating the block * * @param Vector3 $vector - * @param Item &$item + * @param Item $item * @param int $face * @param float $fx default 0.0 * @param float $fy default 0.0 @@ -644,7 +653,15 @@ class Level{ } if($player instanceof Player){ - $this->server->getPluginManager()->callEvent($ev = new PlayerInteractEvent($player, $item, $target, $face)); + $ev = new PlayerInteractEvent($player, $item, $target, $face); + if(!$player->isOp() and ($distance = $this->server->getConfigInt("spawn-protection", 16)) > -1){ + $t = new Vector2($target->x, $target->z); + $s = new Vector2($this->getSpawn()->x, $this->getSpawn()->z); + if($t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this + $ev->setCancelled(); + } + } + $this->server->getPluginManager()->callEvent($ev); if(!$ev->isCancelled()){ $target->onUpdate(self::BLOCK_UPDATE_TOUCH); } @@ -682,7 +699,15 @@ class Level{ if($player instanceof Player){ - $this->server->getPluginManager()->callEvent($ev = new BlockPlaceEvent($player, $hand, $block, $target, $item)); + $ev = new BlockPlaceEvent($player, $hand, $block, $target, $item); + if(!$player->isOp() and ($distance = $this->server->getConfigInt("spawn-protection", 16)) > -1){ + $t = new Vector2($target->x, $target->z); + $s = new Vector2($this->getSpawn()->x, $this->getSpawn()->z); + if($t->distance($s) <= $distance){ //set it to cancelled so plugins can bypass this + $ev->setCancelled(); + } + } + $this->server->getPluginManager()->callEvent($ev); if($ev->isCancelled()){ return false; }