mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 08:17:34 +00:00
Merge branch '3.7'
This commit is contained in:
commit
f638845ef6
@ -1195,7 +1195,6 @@ class Server{
|
||||
EntityFactory::init();
|
||||
TileFactory::init();
|
||||
BlockFactory::init();
|
||||
BlockFactory::registerStaticRuntimeIdMappings();
|
||||
Enchantment::init();
|
||||
ItemFactory::init();
|
||||
Item::initCreativeItems();
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"]);
|
||||
|
@ -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();
|
Loading…
x
Reference in New Issue
Block a user