Added /reload command (does not reload source code)

This commit is contained in:
Shoghi Cervantes 2014-04-03 15:49:00 +02:00
parent ee6dc989ce
commit 80f9093875
12 changed files with 210 additions and 70 deletions

View File

@ -1185,6 +1185,10 @@ class Server{
"auto-save" => true, "auto-save" => true,
)); ));
if($this->getConfigBoolean("enable-rcon", false) === true){
$this->rcon = new RCON($this->getConfigString("rcon.password", ""), $this->getConfigInt("rcon.port", $this->getPort()), ($ip = $this->getIp()) != "" ? $ip : "0.0.0.0", $this->getConfigInt("rcon.threads", 1), $this->getConfigInt("rcon.clients-per-thread", 50));
}
$this->maxPlayers = $this->getConfigInt("max-players", 20); $this->maxPlayers = $this->getConfigInt("max-players", 20);
if(($memory = str_replace("B", "", strtoupper($this->getConfigString("memory-limit", "128M")))) !== false){ if(($memory = str_replace("B", "", strtoupper($this->getConfigString("memory-limit", "128M")))) !== false){
@ -1215,7 +1219,7 @@ class Server{
console("[INFO] Starting Minecraft PE server on " . ($this->getIp() === "" ? "*" : $this->getIp()) . ":" . $this->getPort()); console("[INFO] Starting Minecraft PE server on " . ($this->getIp() === "" ? "*" : $this->getIp()) . ":" . $this->getPort());
define("BOOTUP_RANDOM", Utils::getRandomBytes(16)); define("BOOTUP_RANDOM", Utils::getRandomBytes(16));
$this->serverID = Utils::readLong(substr(Utils::getUniqueID(true, $this->getIp() . $this->getPort()), 8)); $this->serverID = Utils::readLong(substr(Utils::getUniqueID(true, $this->getIp() . $this->getPort()), 0, 8));
$this->interface = new ThreadedHandler("255.255.255.255", $this->getPort(), $this->getIp() === "" ? "0.0.0.0" : $this->getIp()); $this->interface = new ThreadedHandler("255.255.255.255", $this->getPort(), $this->getIp() === "" ? "0.0.0.0" : $this->getIp());
console("[INFO] This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET . " \"" . $this->getCodename() . "\" (API " . $this->getApiVersion() . ")", true, true, 0); console("[INFO] This server is running PocketMine-MP version " . ($version->isDev() ? TextFormat::YELLOW : "") . $this->getPocketMineVersion() . TextFormat::RESET . " \"" . $this->getCodename() . "\" (API " . $this->getApiVersion() . ")", true, true, 0);
@ -1398,6 +1402,48 @@ class Server{
return false; return false;
} }
public function reload(){
console("[INFO] Saving levels...");
foreach($this->levels as $level){
$level->save();
}
$this->pluginManager->disablePlugins();
$this->pluginManager->clearPlugins();
$this->commandMap->clearCommands();
console("[INFO] Reloading properties...");
$this->properties->reload();
$this->maxPlayers = $this->getConfigInt("max-players", 20);
if(($memory = str_replace("B", "", strtoupper($this->getConfigString("memory-limit", "128M")))) !== false){
$value = array("M" => 1, "G" => 1024);
$real = ((int) substr($memory, 0, -1)) * $value[substr($memory, -1)];
if($real < 128){
console("[WARNING] PocketMine-MP may not work right with less than 128MB of RAM", true, true, 0);
}
@ini_set("memory_limit", $memory);
}else{
$this->setConfigString("memory-limit", "128M");
}
if($this->getConfigBoolean("hardcore", false) === true and $this->getDifficulty() < 3){
$this->setConfigInt("difficulty", 3);
}
$this->banByIP->load();
$this->banByName->load();
$this->reloadWhitelist();
$this->operators->reload();
$this->pluginManager->registerInterface("pocketmine\\plugin\\PharPluginLoader");
$this->pluginManager->loadPlugins($this->pluginPath);
$this->enablePlugins(PluginLoadOrder::STARTUP);
$this->enablePlugins(PluginLoadOrder::POSTWORLD);
}
/** /**
* Shutdowns the server correctly * Shutdowns the server correctly
*/ */
@ -1405,50 +1451,8 @@ class Server{
$this->isRunning = false; $this->isRunning = false;
} }
/** public function forceShutdown(){
* Starts the PocketMine-MP server and starts processing ticks and packets $this->shutdown();
*/
public function start(){
if($this->getConfigBoolean("enable-rcon", false) === true){
$this->rcon = new RCON($this->getConfigString("rcon.password", ""), $this->getConfigInt("rcon.port", $this->getPort()), ($ip = $this->getIp()) != "" ? $ip : "0.0.0.0", $this->getConfigInt("rcon.threads", 1), $this->getConfigInt("rcon.clients-per-thread", 50));
}
if($this->getConfigBoolean("enable-query", true) === true){
$this->queryHandler = new QueryHandler();
}
if($this->getConfigBoolean("send-usage", true) !== false){
$this->scheduler->scheduleDelayedRepeatingTask(new CallbackTask(array($this, "sendUsage")), 6000, 6000);
$this->sendUsage();
}
if($this->getConfigBoolean("upnp-forwarding", false) == true){
console("[INFO] [UPnP] Trying to port forward...");
UPnP::PortForward($this->getPort());
}
$this->tickCounter = 0;
//register_shutdown_function(array($this, "dumpError"));
register_shutdown_function(array($this, "shutdown"));
if(function_exists("pcntl_signal")){
pcntl_signal(SIGTERM, array($this, "shutdown"));
pcntl_signal(SIGINT, array($this, "shutdown"));
pcntl_signal(SIGHUP, array($this, "shutdown"));
}
console("[INFO] Default game type: " . self::getGamemodeString($this->getGamemode())); //TODO: string name
console('[INFO] Done (' . round(microtime(true) - \pocketmine\START_TIME, 3) . 's)! For help, type "help" or "?"');
if(Utils::getOS() === "win"){ //Workaround less usleep() waste
$this->tickProcessorWindows();
}else{
$this->tickProcessor();
}
if($this->rcon instanceof RCON){ if($this->rcon instanceof RCON){
$this->rcon->stop(); $this->rcon->stop();
} }
@ -1476,7 +1480,48 @@ class Server{
$this->tickScheduler->kill(); $this->tickScheduler->kill();
$this->console->kill(); $this->console->kill();
}
/**
* Starts the PocketMine-MP server and starts processing ticks and packets
*/
public function start(){
if($this->getConfigBoolean("enable-query", true) === true){
$this->queryHandler = new QueryHandler();
}
if($this->getConfigBoolean("send-usage", true) !== false){
$this->scheduler->scheduleDelayedRepeatingTask(new CallbackTask(array($this, "sendUsage")), 6000, 6000);
$this->sendUsage();
}
if($this->getConfigBoolean("upnp-forwarding", false) == true){
console("[INFO] [UPnP] Trying to port forward...");
UPnP::PortForward($this->getPort());
}
$this->tickCounter = 0;
//register_shutdown_function(array($this, "dumpError"));
register_shutdown_function(array($this, "forceShutdown"));
if(function_exists("pcntl_signal")){
pcntl_signal(SIGTERM, array($this, "shutdown"));
pcntl_signal(SIGINT, array($this, "shutdown"));
pcntl_signal(SIGHUP, array($this, "shutdown"));
}
console("[INFO] Default game type: " . self::getGamemodeString($this->getGamemode())); //TODO: string name
console('[INFO] Done (' . round(microtime(true) - \pocketmine\START_TIME, 3) . 's)! For help, type "help" or "?"');
if(Utils::getOS() === "win"){ //Workaround less usleep() waste
$this->tickProcessorWindows();
}else{
$this->tickProcessor();
}
$this->forceShutdown();
} }
private function tickProcessorWindows(){ private function tickProcessorWindows(){

View File

@ -38,6 +38,7 @@ use pocketmine\command\defaults\OpCommand;
use pocketmine\command\defaults\PardonCommand; use pocketmine\command\defaults\PardonCommand;
use pocketmine\command\defaults\PardonIpCommand; use pocketmine\command\defaults\PardonIpCommand;
use pocketmine\command\defaults\PluginsCommand; use pocketmine\command\defaults\PluginsCommand;
use pocketmine\command\defaults\ReloadCommand;
use pocketmine\command\defaults\SaveCommand; use pocketmine\command\defaults\SaveCommand;
use pocketmine\command\defaults\SaveOffCommand; use pocketmine\command\defaults\SaveOffCommand;
use pocketmine\command\defaults\SaveOnCommand; use pocketmine\command\defaults\SaveOnCommand;
@ -97,6 +98,7 @@ class SimpleCommandMap implements CommandMap{
$this->register("pocketmine", new KillCommand("kill")); $this->register("pocketmine", new KillCommand("kill"));
$this->register("pocketmine", new SpawnpointCommand("spawnpoint")); $this->register("pocketmine", new SpawnpointCommand("spawnpoint"));
$this->register("pocketmine", new TeleportCommand("tp")); $this->register("pocketmine", new TeleportCommand("tp"));
$this->register("pocketmine", new ReloadCommand("reload"));
if($this->server->getConfigBoolean("debug.commands", false) === true){ if($this->server->getConfigBoolean("debug.commands", false) === true){
$this->register("pocketmine", new StatusCommand("status")); $this->register("pocketmine", new StatusCommand("status"));

View File

@ -0,0 +1,53 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\command\defaults;
use pocketmine\command\Command;
use pocketmine\command\CommandSender;
use pocketmine\event\HandlerList;
use pocketmine\Server;
use pocketmine\utils\TextFormat;
class ReloadCommand extends VanillaCommand{
public function __construct($name){
parent::__construct(
$name,
"Reloads the server configuration and plugins",
"/reload"
);
$this->setPermission("pocketmine.command.reload");
}
public function execute(CommandSender $sender, $currentAlias, array $args){
if(!$this->testPermission($sender)){
return true;
}
Command::broadcastCommandMessage($sender, TextFormat::YELLOW . "Reloading server...");
Server::getInstance()->reload();
Command::broadcastCommandMessage($sender, TextFormat::GOLD . "Reload complete.");
return true;
}
}

View File

@ -39,6 +39,7 @@ class ThreadedHandler extends \Thread{
protected $server; protected $server;
protected $port; protected $port;
protected $serverip; protected $serverip;
public $path;
function __construct($server, $port = 19132, $serverip = "0.0.0.0"){ function __construct($server, $port = 19132, $serverip = "0.0.0.0"){
$this->server = $server; $this->server = $server;
@ -56,8 +57,8 @@ class ThreadedHandler extends \Thread{
new Packet(0); new Packet(0);
new QueryPacket(); new QueryPacket();
new RakNetPacket(0); new RakNetPacket(0);
$this->path = \pocketmine\PATH;
$this->start(PTHREADS_INHERIT_ALL); $this->start(PTHREADS_INHERIT_ALL & ~PTHREADS_INHERIT_CLASSES);
} }
public function close(){ public function close(){
@ -105,9 +106,10 @@ class ThreadedHandler extends \Thread{
} }
public function run(){ public function run(){
require($this->path . "src/spl/SplClassLoader.php");
$autoloader = new \SplClassLoader(); $autoloader = new \SplClassLoader();
$autoloader->add("pocketmine", array( $autoloader->add("pocketmine", array(
\pocketmine\PATH . "src" $this->path . "src"
)); ));
$autoloader->register(true); $autoloader->register(true);

View File

@ -31,6 +31,7 @@ class RCONInstance extends \Thread{
private $password; private $password;
private $maxClients; private $maxClients;
public function __construct($socket, $password, $maxClients = 50){ public function __construct($socket, $password, $maxClients = 50){
$this->stop = false; $this->stop = false;
$this->cmd = ""; $this->cmd = "";
@ -43,6 +44,7 @@ class RCONInstance extends \Thread{
$this->{"status" . $n} = 0; $this->{"status" . $n} = 0;
$this->{"timeout" . $n} = 0; $this->{"timeout" . $n} = 0;
} }
$this->start(); $this->start();
} }
@ -80,6 +82,7 @@ class RCONInstance extends \Thread{
} }
public function run(){ public function run(){
while($this->stop !== true){ while($this->stop !== true){
usleep(2000); usleep(2000);
$r = array($socket = $this->socket); $r = array($socket = $this->socket);

View File

@ -29,7 +29,7 @@ use pocketmine\command\PluginIdentifiableCommand;
use pocketmine\Server; use pocketmine\Server;
use pocketmine\utils\Config; use pocketmine\utils\Config;
abstract class PluginBase implements Plugin, CommandExecutor{ abstract class PluginBase implements Plugin{
/** @var PluginLoader */ /** @var PluginLoader */
private $loader; private $loader;
@ -116,22 +116,18 @@ abstract class PluginBase implements Plugin, CommandExecutor{
} }
} }
/**
* @return bool
*/
public final function isInitialized(){ public final function isInitialized(){
return $this->initialized; return $this->initialized;
} }
/** /**
* @param CommandSender $sender * @param string $name
* @param Command $command
* @param string $label
* @param string[] $args
* *
* @return bool * @return PluginIdentifiableCommand
*/ */
public function onCommand(CommandSender $sender, Command $command, $label, array $args){
return false;
}
public function getCommand($name){ public function getCommand($name){
$command = $this->getServer()->getPluginCommand($name); $command = $this->getServer()->getPluginCommand($name);
if($command === null or $command->getPlugin() !== $this){ if($command === null or $command->getPlugin() !== $this){

View File

@ -172,6 +172,7 @@ class PluginManager{
* @return Plugin[] * @return Plugin[]
*/ */
public function loadPlugins($directory, $newLoaders = null){ public function loadPlugins($directory, $newLoaders = null){
if(is_dir($directory)){ if(is_dir($directory)){
$plugins = array(); $plugins = array();
$loadedPlugins = array(); $loadedPlugins = array();

View File

@ -33,12 +33,12 @@ abstract class AsyncTask extends \Threaded{
private $result; private $result;
public function run(){ public function run(){
$this->synchronized(function(){ $this->lock();
$this->result = null; $this->result = null;
$this->onRun(\Thread::getCurrentThread()); $this->onRun();
$this->finished = true; $this->finished = true;
$this->complete = $this->result === null ? true : false; $this->complete = $this->result === null ? true : false;
}); $this->unlock();
} }
/** /**
@ -82,10 +82,8 @@ abstract class AsyncTask extends \Threaded{
/** /**
* Actions to execute when run * Actions to execute when run
* *
* @param \Thread $thread
*
* @return void * @return void
*/ */
public abstract function onRun(\Thread $thread); public abstract function onRun();
} }

View File

@ -0,0 +1,40 @@
<?php
/*
*
* ____ _ _ __ __ _ __ __ ____
* | _ \ ___ ___| | _____| |_| \/ (_)_ __ ___ | \/ | _ \
* | |_) / _ \ / __| |/ / _ \ __| |\/| | | '_ \ / _ \_____| |\/| | |_) |
* | __/ (_) | (__| < __/ |_| | | | | | | | __/_____| | | | __/
* |_| \___/ \___|_|\_\___|\__|_| |_|_|_| |_|\___| |_| |_|_|
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* @author PocketMine Team
* @link http://www.pocketmine.net/
*
*
*/
namespace pocketmine\scheduler;
class AsyncWorker extends \Worker{
public $path;
public function start($options = PTHREADS_INHERIT_CLASSES){
$this->path = \pocketmine\PATH;
return parent::start($options & ~PTHREADS_INHERIT_CLASSES);
}
public function run(){
require($this->path . "src/spl/SplClassLoader.php");
$autoloader = new \SplClassLoader();
$autoloader->add("pocketmine", array(
$this->path . "src"
));
$autoloader->register(true);
}
}

View File

@ -33,7 +33,7 @@ class SendUsageTask extends AsyncTask{
$this->data = serialize($data); $this->data = serialize($data);
} }
public function onRun(\Thread $thread){ public function onRun(){
Utils::postURL($this->endpoint, unserialize($this->data)); Utils::postURL($this->endpoint, unserialize($this->data));
} }

View File

@ -52,7 +52,7 @@ class ServerScheduler{
public function __construct(){ public function __construct(){
$this->queue = new ReversePriorityQueue(); $this->queue = new ReversePriorityQueue();
$this->asyncPool = new \Pool(self::$WORKERS, "Worker"); $this->asyncPool = new \Pool(self::$WORKERS, "pocketmine\\scheduler\\AsyncWorker");
} }
/** /**

View File

@ -1,6 +1,6 @@
<?php <?php
require_once("SplAutoloader.php"); require("SplAutoloader.php");
/** /**
* SplClassLoader implementation that implements the technical interoperability * SplClassLoader implementation that implements the technical interoperability