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); }
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; }
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; }
/** * @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); } }