Merge branch '3.7'

This commit is contained in:
Dylan K. Taylor 2019-03-29 15:16:27 +00:00
commit f638845ef6
7 changed files with 131 additions and 50 deletions

View File

@ -1195,7 +1195,6 @@ class Server{
EntityFactory::init();
TileFactory::init();
BlockFactory::init();
BlockFactory::registerStaticRuntimeIdMappings();
Enchantment::init();
ItemFactory::init();
Item::initCreativeItems();

View File

@ -39,6 +39,7 @@ use pocketmine\math\RayTraceResult;
use pocketmine\math\Vector3;
use pocketmine\metadata\Metadatable;
use pocketmine\metadata\MetadataValue;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\Player;
use pocketmine\plugin\Plugin;
use pocketmine\tile\TileFactory;
@ -124,7 +125,7 @@ class Block extends Position implements BlockLegacyIds, Metadatable{
* @return int
*/
public function getRuntimeId() : int{
return BlockFactory::toStaticRuntimeId($this->getId(), $this->getMeta());
return RuntimeBlockMapping::toStaticRuntimeId($this->getId(), $this->getMeta());
}
/**

View File

@ -32,13 +32,11 @@ use pocketmine\item\Item;
use pocketmine\item\ItemFactory;
use pocketmine\item\ItemIds;
use pocketmine\level\Position;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\tile\Comparator;
use function array_fill;
use function array_filter;
use function file_get_contents;
use function get_class;
use function json_decode;
use function max;
use function min;
/**
@ -55,15 +53,6 @@ class BlockFactory{
/** @var \SplFixedArray|float[] */
public static $blastResistance = null;
/** @var int[] */
public static $staticRuntimeIdMap = [];
/** @var int[] */
public static $legacyIdMap = [];
/** @var int */
private static $lastRuntimeId = 0;
/**
* Initializes the block factory. By default this is called only once on server start, however you may wish to use
* this if you need to reset the block factory back to its original defaults for whatever reason.
@ -680,21 +669,9 @@ class BlockFactory{
return $b !== null and !($b instanceof UnknownBlock);
}
public static function registerStaticRuntimeIdMappings() : void{
/** @var mixed[] $runtimeIdMap */
$runtimeIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true);
$legacyIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "legacy_id_map.json"), true);
foreach($runtimeIdMap as $k => $obj){
//this has to use the json offset to make sure the mapping is consistent with what we send over network, even though we aren't using all the entries
if(!isset($legacyIdMap[$obj["name"]])){
continue;
}
self::registerMapping($k, $legacyIdMap[$obj["name"]], $obj["data"]);
}
}
/**
* @internal
* @deprecated
*
* @param int $id
* @param int $meta
@ -702,15 +679,11 @@ class BlockFactory{
* @return int
*/
public static function toStaticRuntimeId(int $id, int $meta = 0) : int{
/*
* try id+meta first
* if not found, try id+0 (strip meta)
* if still not found, return update! block
*/
return self::$staticRuntimeIdMap[($id << 4) | $meta] ?? self::$staticRuntimeIdMap[$id << 4] ?? self::$staticRuntimeIdMap[BlockLegacyIds::INFO_UPDATE << 4];
return RuntimeBlockMapping::toStaticRuntimeId($id, $meta);
}
/**
* @deprecated
* @internal
*
* @param int $runtimeId
@ -718,14 +691,7 @@ class BlockFactory{
* @return int[] [id, meta]
*/
public static function fromStaticRuntimeId(int $runtimeId) : array{
$v = self::$legacyIdMap[$runtimeId];
return [$v >> 4, $v & 0xf];
}
private static function registerMapping(int $staticRuntimeId, int $legacyId, int $legacyMeta) : void{
self::$staticRuntimeIdMap[($legacyId << 4) | $legacyMeta] = $staticRuntimeId;
self::$legacyIdMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta;
self::$lastRuntimeId = max(self::$lastRuntimeId, $staticRuntimeId);
return RuntimeBlockMapping::fromStaticRuntimeId($runtimeId);
}
/**

View File

@ -79,6 +79,7 @@ use pocketmine\network\mcpe\protocol\ClientboundPacket;
use pocketmine\network\mcpe\protocol\LevelEventPacket;
use pocketmine\network\mcpe\protocol\SetDifficultyPacket;
use pocketmine\network\mcpe\protocol\SetTimePacket;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
use pocketmine\Player;
use pocketmine\plugin\Plugin;
@ -939,7 +940,7 @@ class Level implements ChunkManager, Metadatable{
$pk->blockRuntimeId = $b->getRuntimeId();
}else{
$fullBlock = $this->getFullBlock($b->x, $b->y, $b->z);
$pk->blockRuntimeId = BlockFactory::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf);
$pk->blockRuntimeId = RuntimeBlockMapping::toStaticRuntimeId($fullBlock >> 4, $fullBlock & 0xf);
}
$packets[] = $pk;

View File

@ -33,6 +33,7 @@ use pocketmine\entity\EntityFactory;
use pocketmine\level\Level;
use pocketmine\nbt\tag\CompoundTag;
use pocketmine\network\mcpe\NetworkBinaryStream;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use pocketmine\Player;
use pocketmine\tile\Spawnable;
use pocketmine\tile\Tile;
@ -749,10 +750,6 @@ class Chunk{
$subChunkCount = $this->getSubChunkSendCount();
$stream->putByte($subChunkCount);
if(empty(BlockFactory::$staticRuntimeIdMap)){
BlockFactory::registerStaticRuntimeIdMappings();
}
for($y = 0; $y < $subChunkCount; ++$y){
$layers = $this->subChunks[$y]->getBlockLayers();
$stream->putByte(8); //version
@ -765,7 +762,7 @@ class Chunk{
$palette = $blocks->getPalette();
$stream->putVarInt(count($palette)); //yes, this is intentionally zigzag
foreach($palette as $p){
$stream->putVarInt(BlockFactory::toStaticRuntimeId($p >> 4, $p & 0xf));
$stream->putVarInt(RuntimeBlockMapping::toStaticRuntimeId($p >> 4, $p & 0xf));
}
}
}

View File

@ -30,9 +30,8 @@ use pocketmine\math\Vector3;
use pocketmine\network\mcpe\handler\SessionHandler;
use pocketmine\network\mcpe\NetworkBinaryStream;
use pocketmine\network\mcpe\protocol\types\PlayerPermissions;
use pocketmine\network\mcpe\protocol\types\RuntimeBlockMapping;
use function count;
use function file_get_contents;
use function json_decode;
class StartGamePacket extends DataPacket implements ClientboundPacket{
public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET;
@ -251,7 +250,7 @@ class StartGamePacket extends DataPacket implements ClientboundPacket{
if(self::$runtimeIdTable === null){
//this is a really nasty hack, but it'll do for now
$stream = new NetworkBinaryStream();
$data = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true);
$data = RuntimeBlockMapping::getBedrockKnownStates();
$stream->putUnsignedVarInt(count($data));
foreach($data as $v){
$stream->putString($v["name"]);

View File

@ -0,0 +1,118 @@
<?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/
*
*
*/
declare(strict_types=1);
namespace pocketmine\network\mcpe\protocol\types;
use pocketmine\block\BlockLegacyIds;
use function file_get_contents;
use function getmypid;
use function json_decode;
use function mt_rand;
use function mt_srand;
use function shuffle;
/**
* @internal
*/
final class RuntimeBlockMapping{
/** @var int[] */
private static $legacyToRuntimeMap = [];
/** @var int[] */
private static $runtimeToLegacyMap = [];
/** @var mixed[] */
private static $bedrockKnownStates;
private function __construct(){
//NOOP
}
public static function init() : void{
$legacyIdMap = json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "legacy_id_map.json"), true);
self::$bedrockKnownStates = self::randomizeTable(json_decode(file_get_contents(\pocketmine\RESOURCE_PATH . "runtimeid_table.json"), true));
foreach(self::$bedrockKnownStates as $k => $obj){
//this has to use the json offset to make sure the mapping is consistent with what we send over network, even though we aren't using all the entries
if(!isset($legacyIdMap[$obj["name"]])){
continue;
}
self::registerMapping($k, $legacyIdMap[$obj["name"]], $obj["data"]);
}
}
/**
* Randomizes the order of the runtimeID table to prevent plugins relying on them.
* Plugins shouldn't use this stuff anyway, but plugin devs have an irritating habit of ignoring what they
* aren't supposed to do, so we have to deliberately break it to make them stop.
*
* @param array $table
*
* @return array
*/
private static function randomizeTable(array $table) : array{
$postSeed = mt_rand(); //save a seed to set afterwards, to avoid poor quality randoms
mt_srand(getmypid() ?: 0); //Use a seed which is the same on all threads. This isn't a secure seed, but we don't care.
shuffle($table);
mt_srand($postSeed); //restore a good quality seed that isn't dependent on PID
return $table;
}
/**
* @param int $id
* @param int $meta
*
* @return int
*/
public static function toStaticRuntimeId(int $id, int $meta = 0) : int{
/*
* try id+meta first
* if not found, try id+0 (strip meta)
* if still not found, return update! block
*/
return self::$legacyToRuntimeMap[($id << 4) | $meta] ?? self::$legacyToRuntimeMap[$id << 4] ?? self::$legacyToRuntimeMap[BlockLegacyIds::INFO_UPDATE << 4];
}
/**
* @param int $runtimeId
*
* @return int[] [id, meta]
*/
public static function fromStaticRuntimeId(int $runtimeId) : array{
$v = self::$runtimeToLegacyMap[$runtimeId];
return [$v >> 4, $v & 0xf];
}
private static function registerMapping(int $staticRuntimeId, int $legacyId, int $legacyMeta) : void{
self::$legacyToRuntimeMap[($legacyId << 4) | $legacyMeta] = $staticRuntimeId;
self::$runtimeToLegacyMap[$staticRuntimeId] = ($legacyId << 4) | $legacyMeta;
}
/**
* @return array
*/
public static function getBedrockKnownStates() : array{
return self::$bedrockKnownStates;
}
}
RuntimeBlockMapping::init();