/**
* @param \ClassLoader $autoloader
* @param \ThreadedLogger $logger
* @param string $filePath
* @param string $dataPath
* @param string $pluginPath
*/
public function __construct(\ClassLoader $autoloader, \ThreadedLogger $logger, $filePath, $dataPath, $pluginPath)
{
self::$instance = $this;
self::$sleeper = new \Threaded();
$this->autoloader = $autoloader;
$this->logger = $logger;
$this->filePath = $filePath;
try {
if (!file_exists($dataPath . "worlds/")) {
mkdir($dataPath . "worlds/", 0777);
}
if (!file_exists($dataPath . "players/")) {
mkdir($dataPath . "players/", 0777);
}
if (!file_exists($pluginPath)) {
mkdir($pluginPath, 0777);
}
if (!file_exists($dataPath . "crashdumps/")) {
mkdir($dataPath . "crashdumps/", 0777);
}
$this->dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
$this->pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
$this->console = new CommandReader();
$version = new VersionString($this->getPocketMineVersion());
$this->version = $version;
$this->aboutstring = "\n\n\t\t §5PocketMine-iTX §3Genisys §fis a fork of PocketMine-MP.\n\t\t Powered by §5iTX Technologies LLC.\n\t\t §fVersion: §6" . $this->getPocketMineVersion() . "\n\t\t §fClient Version: §d0.13.1 alpha\n\t\t §fYou could get the lastest code on https://github.com/iTXTech/Genisys\n\t\t §fDonate link: http://pl.zxda.net/plugins/203.html\n\t\t §f如果你在免费使用本核心,希望你可以进入上面的链接捐赠给我们,这会成为我们前进的动力。\n\t\t\n";
$this->about();
$this->logger->info("Loading pocketmine.yml...");
if (!file_exists($this->dataPath . "pocketmine.yml")) {
$content = file_get_contents($this->filePath . "src/pocketmine/resources/pocketmine.yml");
if ($version->isDev()) {
$content = str_replace("preferred-channel: stable", "preferred-channel: beta", $content);
}
@file_put_contents($this->dataPath . "pocketmine.yml", $content);
}
$this->config = new Config($this->dataPath . "pocketmine.yml", Config::YAML, []);
$this->logger->info("Loading genisys.yml...");
$lang = $this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE);
if (file_exists($this->filePath . "src/pocketmine/resources/genisys_{$lang}.yml")) {
$content = file_get_contents($file = $this->filePath . "src/pocketmine/resources/genisys_{$lang}.yml");
} else {
$content = file_get_contents($file = $this->filePath . "src/pocketmine/resources/genisys_eng.yml");
}
if (!file_exists($this->dataPath . "genisys.yml")) {
@file_put_contents($this->dataPath . "genisys.yml", $content);
}
$internelConfig = new Config($file, Config::YAML, []);
$this->advancedConfig = new Config($this->dataPath . "genisys.yml", Config::YAML, []);
$cfgVer = $this->getAdvancedProperty("config.version", 0, $internelConfig);
$advVer = $this->getAdvancedProperty("config.version", 0);
$this->loadAdvancedConfig();
if ($this->expWriteAhead > 0) {
$this->generateExpCache($this->expWriteAhead);
}
$this->logger->info("Loading server properties...");
$this->properties = new Config($this->dataPath . "server.properties", Config::PROPERTIES, ["motd" => "Minecraft: PE Server", "server-port" => 19132, "white-list" => false, "announce-player-achievements" => true, "spawn-protection" => 16, "max-players" => 20, "allow-flight" => false, "spawn-animals" => true, "spawn-mobs" => true, "gamemode" => 0, "force-gamemode" => false, "hardcore" => false, "pvp" => true, "difficulty" => 1, "generator-settings" => "", "level-name" => "world", "level-seed" => "", "level-type" => "DEFAULT", "enable-query" => true, "enable-rcon" => false, "rcon.password" => substr(base64_encode(@Utils::getRandomBytes(20, false)), 3, 10), "auto-save" => true]);
$this->forceLanguage = $this->getProperty("settings.force-language", false);
$this->baseLang = new BaseLang($this->getProperty("settings.language", BaseLang::FALLBACK_LANGUAGE));
$this->logger->info($this->getLanguage()->translateString("language.selected", [$this->getLanguage()->getName(), $this->getLanguage()->getLang()]));
$this->memoryManager = new MemoryManager($this);
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.start", [TextFormat::AQUA . $this->getVersion()]));
if (($poolSize = $this->getProperty("settings.async-workers", "auto")) === "auto") {
$poolSize = ServerScheduler::$WORKERS;
$processors = Utils::getCoreCount() - 2;
if ($processors > 0) {
$poolSize = max(1, $processors);
}
}
ServerScheduler::$WORKERS = $poolSize;
if ($this->getProperty("network.batch-threshold", 256) >= 0) {
Network::$BATCH_THRESHOLD = (int) $this->getProperty("network.batch-threshold", 256);
} else {
Network::$BATCH_THRESHOLD = -1;
}
$this->networkCompressionLevel = $this->getProperty("network.compression-level", 7);
$this->networkCompressionAsync = $this->getProperty("network.async-compression", true);
$this->autoTickRate = (bool) $this->getProperty("level-settings.auto-tick-rate", true);
$this->autoTickRateLimit = (int) $this->getProperty("level-settings.auto-tick-rate-limit", 20);
$this->alwaysTickPlayers = (int) $this->getProperty("level-settings.always-tick-players", false);
$this->baseTickRate = (int) $this->getProperty("level-settings.base-tick-rate", 1);
$this->scheduler = new ServerScheduler();
if ($this->getConfigBoolean("enable-rcon", false) === true) {
$this->rcon = new RCON($this, $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->entityMetadata = new EntityMetadataStore();
$this->playerMetadata = new PlayerMetadataStore();
$this->levelMetadata = new LevelMetadataStore();
$this->operators = new Config($this->dataPath . "ops.txt", Config::ENUM);
$this->whitelist = new Config($this->dataPath . "white-list.txt", Config::ENUM);
if (file_exists($this->dataPath . "banned.txt") and !file_exists($this->dataPath . "banned-players.txt")) {
@rename($this->dataPath . "banned.txt", $this->dataPath . "banned-players.txt");
}
@touch($this->dataPath . "banned-players.txt");
$this->banByName = new BanList($this->dataPath . "banned-players.txt");
$this->banByName->load();
@touch($this->dataPath . "banned-ips.txt");
$this->banByIP = new BanList($this->dataPath . "banned-ips.txt");
$this->banByIP->load();
@touch($this->dataPath . "banned-cids.txt");
$this->banByCID = new BanList($this->dataPath . "banned-cids.txt");
$this->banByCID->load();
$this->maxPlayers = $this->getConfigInt("max-players", 20);
$this->setAutoSave($this->getConfigBoolean("auto-save", true));
if ($this->getConfigBoolean("hardcore", false) === true and $this->getDifficulty() < 3) {
$this->setConfigInt("difficulty", 3);
}
define("pocketmine\\DEBUG", (int) $this->getProperty("debug.level", 1));
if ($this->logger instanceof MainLogger) {
$this->logger->setLogDebug(\pocketmine\DEBUG > 1);
}
if (\pocketmine\DEBUG >= 0) {
@cli_set_process_title($this->getName() . " " . $this->getPocketMineVersion());
}
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.networkStart", [$this->getIp() === "" ? "*" : $this->getIp(), $this->getPort()]));
define("BOOTUP_RANDOM", @Utils::getRandomBytes(16));
$this->serverID = Utils::getMachineUniqueId($this->getIp() . $this->getPort());
$this->getLogger()->debug("Server unique id: " . $this->getServerUniqueId());
$this->getLogger()->debug("Machine unique id: " . Utils::getMachineUniqueId());
$this->network = new Network($this);
$this->network->setName($this->getMotd());
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.info", [$this->getName(), $this->getPocketMineVersion(), $this->getCodename(), $this->getApiVersion()]));
$this->logger->info($this->getLanguage()->translateString("pocketmine.server.license", [$this->getName()]));
Timings::init();
$this->consoleSender = new ConsoleCommandSender();
$this->commandMap = new SimpleCommandMap($this);
$this->registerEntities();
$this->registerTiles();
InventoryType::init(min(32, $this->inventoryNum));
//Bigger than 32 with cause problems
Block::init();
Item::init();
Biome::init();
Effect::init();
Enchantment::init();
Attribute::init();
/** TODO: @deprecated */
//TextWrapper::init();
$this->craftingManager = new CraftingManager($this->readRecipesFromJson);
$this->pluginManager = new PluginManager($this, $this->commandMap);
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
$this->pluginManager->setUseTimings($this->getProperty("settings.enable-profiling", false));
$this->profilingTickRate = (double) $this->getProperty("settings.profile-report-trigger", 20);
$this->pluginManager->registerInterface(PharPluginLoader::class);
$this->pluginManager->registerInterface(FolderPluginLoader::class);
$this->pluginManager->registerInterface(ScriptPluginLoader::class);
//set_exception_handler([$this, "exceptionHandler"]);
register_shutdown_function([$this, "crashDump"]);
$this->queryRegenerateTask = new QueryRegenerateEvent($this, 5);
$this->network->registerInterface(new RakLibInterface($this));
$this->pluginManager->loadPlugins($this->pluginPath);
//$this->updater = new AutoUpdater($this, $this->getProperty("auto-updater.host", "www.pocketmine.net"));
$this->enablePlugins(PluginLoadOrder::STARTUP);
LevelProviderManager::addProvider($this, Anvil::class);
LevelProviderManager::addProvider($this, McRegion::class);
if (extension_loaded("leveldb")) {
$this->logger->debug($this->getLanguage()->translateString("pocketmine.debug.enable"));
LevelProviderManager::addProvider($this, LevelDB::class);
}
Generator::addGenerator(Flat::class, "flat");
Generator::addGenerator(Normal::class, "normal");
Generator::addGenerator(Normal::class, "default");
Generator::addGenerator(Nether::class, "hell");
Generator::addGenerator(Nether::class, "nether");
foreach ((array) $this->getProperty("worlds", []) as $name => $worldSetting) {
if ($this->loadLevel($name) === false) {
$seed = $this->getProperty("worlds.{$name}.seed", time());
$options = explode(":", $this->getProperty("worlds.{$name}.generator", Generator::getGenerator("default")));
$generator = Generator::getGenerator(array_shift($options));
if (count($options) > 0) {
$options = ["preset" => implode(":", $options)];
} else {
$options = [];
}
$this->generateLevel($name, $seed, $generator, $options);
}
}
if ($this->getDefaultLevel() === null) {
$default = $this->getConfigString("level-name", "world");
if (trim($default) == "") {
$this->getLogger()->warning("level-name cannot be null, using default");
$default = "world";
$this->setConfigString("level-name", "world");
}
if ($this->loadLevel($default) === false) {
$seed = $this->getConfigInt("level-seed", time());
$this->generateLevel($default, $seed === 0 ? time() : $seed);
}
$this->setDefaultLevel($this->getLevelByName($default));
}
$this->properties->save(true);
if (!$this->getDefaultLevel() instanceof Level) {
$this->getLogger()->emergency($this->getLanguage()->translateString("pocketmine.level.defaultError"));
$this->forceShutdown();
return;
}
if ($this->netherEnabled) {
if (!$this->loadLevel($this->netherName)) {
//$this->logger->info("正在生成地狱 ".$this->netherName);
$this->generateLevel($this->netherName, time(), Generator::getGenerator("nether"));
}
$this->netherLevel = $this->getLevelByName($this->netherName);
}
if ($this->getProperty("ticks-per.autosave", 6000) > 0) {
$this->autoSaveTicks = (int) $this->getProperty("ticks-per.autosave", 6000);
}
$this->enablePlugins(PluginLoadOrder::POSTWORLD);
if ($this->aiEnabled) {
$this->aiHolder = new AIHolder($this);
}
if ($this->dserverConfig["enable"] and $this->getAdvancedProperty("dserver.server-list", "") != "") {
$this->scheduler->scheduleRepeatingTask(new CallbackTask([$this, "updateDServerInfo"]), $this->dserverConfig["timer"]);
}
if ($cfgVer != $advVer) {
$this->logger->notice("Your genisys.yml needs update");
$this->logger->notice("Current Version: {$advVer} Latest Version: {$cfgVer}");
}
$this->generateRecipeList();
$this->start();
} catch (\Throwable $e) {
$this->exceptionHandler($e);
}
}