示例#1
0
 public function setCustomColor(Color $color)
 {
     if ($hasTag = $this->hasCompoundTag()) {
         $tag = $this->getNamedTag();
     } else {
         $tag = new CompoundTag("", []);
     }
     $tag->customColor = new IntTag("customColor", $color->getColorCode());
     $this->setCompoundTag($tag);
 }
示例#2
0
 public function onActivate(Item $item, Player $player = null)
 {
     //@author iTX. rewrite @Dog194
     $tile = $this->getLevel()->getTile($this);
     if (!$tile instanceof TileCauldron) {
         return false;
     }
     switch ($item->getId()) {
         case Item::BUCKET:
             if ($item->getDamage() === 0) {
                 //empty bucket
                 if (!$this->isFull() or $tile->isCustomColor() or $tile->hasPotion()) {
                     break;
                 }
                 $bucket = clone $item;
                 $bucket->setDamage(8);
                 //water bucket
                 Server::getInstance()->getPluginManager()->callEvent($ev = new PlayerBucketFillEvent($player, $this, 0, $item, $bucket));
                 if (!$ev->isCancelled()) {
                     if ($player->isSurvival()) {
                         $player->getInventory()->setItemInHand($ev->getItem());
                     }
                     $this->meta = 0;
                     //empty
                     $this->getLevel()->setBlock($this, $this, true);
                     $tile->clearCustomColor();
                     $this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
                 }
             } elseif ($item->getDamage() === 8) {
                 //water bucket
                 if ($this->isFull() and !$tile->isCustomColor() and !$tile->hasPotion()) {
                     break;
                 }
                 $bucket = clone $item;
                 $bucket->setDamage(0);
                 //empty bucket
                 Server::getInstance()->getPluginManager()->callEvent($ev = new PlayerBucketEmptyEvent($player, $this, 0, $item, $bucket));
                 if (!$ev->isCancelled()) {
                     if ($player->isSurvival()) {
                         $player->getInventory()->setItemInHand($ev->getItem());
                     }
                     if ($tile->hasPotion()) {
                         //if has potion
                         $this->meta = 0;
                         //empty
                         $tile->setPotionId(0xffff);
                         //reset potion
                         $tile->setSplashPotion(false);
                         $tile->clearCustomColor();
                         $this->getLevel()->setBlock($this, $this, true);
                         $this->getLevel()->addSound(new ExplodeSound($this->add(0.5, 0, 0.5)));
                     } else {
                         $this->meta = 6;
                         //fill
                         $tile->clearCustomColor();
                         $this->getLevel()->setBlock($this, $this, true);
                         $this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
                     }
                     $this->update();
                 }
             }
             break;
         case Item::DYE:
             if ($tile->hasPotion()) {
                 break;
             }
             $color = Color::getDyeColor($item->getDamage());
             if ($tile->isCustomColor()) {
                 $color = Color::averageColor($color, $tile->getCustomColor());
             }
             if ($player->isSurvival()) {
                 $item->setCount($item->getCount() - 1);
                 /*if($item->getCount() <= 0){
                 			$player->getInventory()->setItemInHand(Item::get(Item::AIR));
                 		}*/
             }
             $tile->setCustomColor($color);
             $this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
             $this->update();
             break;
         case Item::LEATHER_CAP:
         case Item::LEATHER_TUNIC:
         case Item::LEATHER_PANTS:
         case Item::LEATHER_BOOTS:
             if ($this->isEmpty()) {
                 break;
             }
             if ($tile->isCustomColor()) {
                 --$this->meta;
                 $this->getLevel()->setBlock($this, $this, true);
                 $newItem = clone $item;
                 /** @var Armor $newItem */
                 $newItem->setCustomColor($tile->getCustomColor());
                 $player->getInventory()->setItemInHand($newItem);
                 $this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
                 if ($this->isEmpty()) {
                     $tile->clearCustomColor();
                 }
             } else {
                 --$this->meta;
                 $this->getLevel()->setBlock($this, $this, true);
                 $newItem = clone $item;
                 /** @var Armor $newItem */
                 $newItem->clearCustomColor();
                 $player->getInventory()->setItemInHand($newItem);
                 $this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
             }
             break;
         case Item::POTION:
         case Item::SPLASH_POTION:
             if (!$this->isEmpty() and ($tile->getPotionId() !== $item->getDamage() and $item->getDamage() !== Potion::WATER_BOTTLE or $item->getId() === Item::POTION and $tile->getSplashPotion() or $item->getId() === Item::SPLASH_POTION and !$tile->getSplashPotion() and $item->getDamage() !== 0 or $item->getDamage() === Potion::WATER_BOTTLE and $tile->hasPotion())) {
                 //long...
                 $this->meta = 0x0;
                 $this->getLevel()->setBlock($this, $this, true);
                 $tile->setPotionId(0xffff);
                 //reset
                 $tile->setSplashPotion(false);
                 $tile->clearCustomColor();
                 if ($player->isSurvival()) {
                     $player->getInventory()->setItemInHand(Item::get(Item::GLASS_BOTTLE));
                 }
                 $this->getLevel()->addSound(new ExplodeSound($this->add(0.5, 0, 0.5)));
             } elseif ($item->getDamage() === Potion::WATER_BOTTLE) {
                 //水瓶 喷溅型水瓶
                 $this->meta += 2;
                 if ($this->meta > 0x6) {
                     $this->meta = 0x6;
                 }
                 $this->getLevel()->setBlock($this, $this, true);
                 if ($player->isSurvival()) {
                     $player->getInventory()->setItemInHand(Item::get(Item::GLASS_BOTTLE));
                 }
                 $tile->setPotionId(0xffff);
                 $tile->setSplashPotion(false);
                 $tile->clearCustomColor();
                 $this->getLevel()->addSound(new SplashSound($this->add(0.5, 1, 0.5)));
             } elseif (!$this->isFull()) {
                 $this->meta += 2;
                 if ($this->meta > 0x6) {
                     $this->meta = 0x6;
                 }
                 $tile->setPotionId($item->getDamage());
                 $tile->setSplashPotion($item->getId() === Item::SPLASH_POTION);
                 $tile->clearCustomColor();
                 $this->getLevel()->setBlock($this, $this, true);
                 if ($player->isSurvival()) {
                     $player->getInventory()->setItemInHand(Item::get(Item::GLASS_BOTTLE));
                 }
                 $color = Potion::getColor($item->getDamage());
                 $this->getLevel()->addSound(new SpellSound($this->add(0.5, 1, 0.5), $color[0], $color[1], $color[2]));
             }
             break;
         case Item::GLASS_BOTTLE:
             $player->getServer()->getPluginManager()->callEvent($ev = new PlayerGlassBottleEvent($player, $this, $item));
             if ($ev->isCancelled()) {
                 return false;
             }
             if ($this->meta < 2) {
                 break;
             }
             if ($tile->hasPotion()) {
                 $this->meta -= 2;
                 if ($tile->getSplashPotion() === true) {
                     $result = Item::get(Item::SPLASH_POTION, $tile->getPotionId());
                 } else {
                     $result = Item::get(Item::POTION, $tile->getPotionId());
                 }
                 if ($this->isEmpty()) {
                     $tile->setPotionId(0xffff);
                     //reset
                     $tile->setSplashPotion(false);
                     $tile->clearCustomColor();
                 }
                 $this->getLevel()->setBlock($this, $this, true);
                 $this->addItem($item, $player, $result);
                 $color = Potion::getColor($result->getDamage());
                 $this->getLevel()->addSound(new SpellSound($this->add(0.5, 1, 0.5), $color[0], $color[1], $color[2]));
             } else {
                 $this->meta -= 2;
                 $this->getLevel()->setBlock($this, $this, true);
                 if ($player->isSurvival()) {
                     $result = Item::get(Item::POTION, Potion::WATER_BOTTLE);
                     $this->addItem($item, $player, $result);
                 }
                 $this->getLevel()->addSound(new GraySplashSound($this->add(0.5, 1, 0.5)));
             }
             break;
     }
     return true;
 }
示例#3
0
 public function getCustomColor()
 {
     //
     if ($this->isCustomColor()) {
         $color = $this->namedtag["CustomColor"];
         $green = $color >> 8 & 0xff;
         $red = $color >> 16 & 0xff;
         $blue = $color & 0xff;
         return Color::getRGB($red, $green, $blue);
     }
     return null;
 }
示例#4
0
 /**
  * @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 . "crashdumps/")) {
             mkdir($dataPath . "crashdumps/", 0777);
         }
         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);
         }
         $this->dataPath = realpath($dataPath) . DIRECTORY_SEPARATOR;
         $this->pluginPath = realpath($pluginPath) . DIRECTORY_SEPARATOR;
         $this->console = new CommandReader($logger);
         $version = new VersionString($this->getPocketMineVersion());
         $reloadpreConfig = false;
         $this->logger->info("Loading pocketmine.yml...");
         if (!file_exists($this->dataPath . "pocketmine.yml")) {
             //$content = $this->translateConfig(file_get_contents($this->filePath . "src/pocketmine/resources/pocketmine.yml"),"eng");
             $content = \file_get_contents($this->filePath . "src/pocketmine/resources/pocketmine.yml");
             @\file_put_contents($this->dataPath . "pocketmine.yml", $content);
         } else {
             $this->config = new Config($this->dataPath . "pocketmine.yml", Config::YAML, []);
             $internal_config = yaml_parse(file_get_contents($this->filePath . "src/pocketmine/resources/pocketmine.yml"));
             if ($this->getProperty("version", 0) < $internal_config['version']) {
                 $this->logger->warning("Outdated pocketmine.yml");
                 if ($this->getProperty("settings.config-update", true)) {
                     $this->logger->info("Updating pocketmine.yml...");
                     if (!$this->getProperty("temp-file", false)) {
                         rename($this->dataPath . "pocketmine.yml", $this->dataPath . "pocketmine.yml." . time() . ".bak");
                     }
                     //$content = $this->translateConfig(file_get_contents($this->filePath . "src/pocketmine/resources/pocketmine.yml"),$this->getProperty("settings.language", "eng"));
                     $content = \file_get_contents($this->filePath . "src/pocketmine/resources/pocketmine.yml");
                     @\file_put_contents($this->dataPath . "pocketmine.yml", $content);
                 } else {
                     $this->logger->info("Ignore outdated pocketmine.yml");
                 }
             }
             unset($inernal_config);
         }
         $this->config = new Config($this->dataPath . "pocketmine.yml", Config::YAML, []);
         $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(random_bytes(20)), 3, 10), "auto-save" => true, "online-mode" => false]);
         if (!extension_loaded("openssl") && $this->getConfigBoolean("online-mode", false)) {
             $this->logger->warning("The OpenSSL extension is not loaded, and this is required for XBOX authentication to work. If you want to use Xbox Live auth, please use PHP binarys with OpenSSL, or recompile PHP with the OpenSSL extension.");
             //TODO:TRANSLATE
             $this->setConfigBool("online-mode", false);
         }
         if (extension_loaded("xdebug")) {
             if (!$this->getProperty("debug.allow-xdebug", false)) {
                 $this->logger->critical("Please do not use a PHP installation with the xDebug extension loaded for a Production server. If you do want to use it however, set debug.allow-xdebug to true.");
                 //TODO:TRANSLATE
                 return;
             } else {
                 $this->logger->warning("xDebug is enabled, this decreases Performance. Use this for development purposes only.");
                 //TODO:TRANSLATE
             }
         }
         if (!$this->getProperty("I/O.log-to-file", true)) {
             $this->logger->disable();
             $this->logger->info("MainLogger will not write to server.log");
             //TODO:TRANSLATE
         } else {
             $this->logger->enable();
             $this->logger->info("MainLogger will write to server.log");
             //TODO:TRANSLATE
         }
         $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();
         $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));
         ini_set('assert.exception', 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", random_bytes(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->getPocketMineBuild()]));
         $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();
         Block::init();
         Item::init();
         Biome::init();
         Effect::init();
         Enchantment::init();
         Attribute::init();
         EnchantmentLevelTable::init();
         Color::init();
         $this->craftingManager = new CraftingManager();
         $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(ScriptPluginLoader::class);
         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", "jenkins.clearskyteam.org"));
         $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 = getopt("", ["level-seed::"])["level-seed"] ?? $this->properties->get("level-seed", time());
                 if (!is_numeric($seed) or bccomp($seed, "9223372036854775807") > 0) {
                     $seed = Utils::javaStringHash($seed);
                 } elseif (PHP_INT_SIZE === 8) {
                     $seed = (int) $seed;
                 }
                 $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->getProperty("ticks-per.autosave", 6000) > 0) {
             $this->autoSaveTicks = (int) $this->getProperty("ticks-per.autosave", 6000);
         }
         $this->enablePlugins(PluginLoadOrder::POSTWORLD);
         $this->start();
     } catch (\Throwable $e) {
         $this->exceptionHandler($e);
     }
 }