StartGamePacket: allow specifying a custom runtimeID table

this is not the intended goal, but it's a happy side effect of making it easier to extract structured information from the client.
This commit is contained in:
Dylan K. Taylor 2019-04-24 18:40:29 +01:00
parent 15ae323bcb
commit fc76d04dcb

View File

@ -37,7 +37,7 @@ class StartGamePacket extends DataPacket{
public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET; public const NETWORK_ID = ProtocolInfo::START_GAME_PACKET;
/** @var string|null */ /** @var string|null */
private static $runtimeIdTable; private static $runtimeIdTableCache;
/** @var int */ /** @var int */
public $entityUniqueId; public $entityUniqueId;
@ -138,6 +138,9 @@ class StartGamePacket extends DataPacket{
/** @var string */ /** @var string */
public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort public $multiplayerCorrelationId = ""; //TODO: this should be filled with a UUID of some sort
/** @var array|null each entry must have a "name" (string) and "data" (int16) element */
public $runtimeIdTable = null;
protected function decodePayload(){ protected function decodePayload(){
$this->entityUniqueId = $this->getEntityUniqueId(); $this->entityUniqueId = $this->getEntityUniqueId();
$this->entityRuntimeId = $this->getEntityRuntimeId(); $this->entityRuntimeId = $this->getEntityRuntimeId();
@ -189,10 +192,14 @@ class StartGamePacket extends DataPacket{
$this->enchantmentSeed = $this->getVarInt(); $this->enchantmentSeed = $this->getVarInt();
$count = $this->getUnsignedVarInt(); $count = $this->getUnsignedVarInt();
$table = [];
for($i = 0; $i < $count; ++$i){ for($i = 0; $i < $count; ++$i){
$this->getString(); $id = $this->getString();
$this->getLShort(); $data = $this->getLShort();
$table[$i] = ["name" => $id, "data" => $data];
} }
$this->runtimeIdTable = $table;
$this->multiplayerCorrelationId = $this->getString(); $this->multiplayerCorrelationId = $this->getString();
} }
@ -247,22 +254,29 @@ class StartGamePacket extends DataPacket{
$this->putVarInt($this->enchantmentSeed); $this->putVarInt($this->enchantmentSeed);
if(self::$runtimeIdTable === null){ if($this->runtimeIdTable === null){
//this is a really nasty hack, but it'll do for now if(self::$runtimeIdTableCache === null){
$stream = new NetworkBinaryStream(); //this is a really nasty hack, but it'll do for now
$data = RuntimeBlockMapping::getBedrockKnownStates(); self::$runtimeIdTableCache = self::serializeBlockTable(RuntimeBlockMapping::getBedrockKnownStates());
$stream->putUnsignedVarInt(count($data));
foreach($data as $v){
$stream->putString($v["name"]);
$stream->putLShort($v["data"]);
} }
self::$runtimeIdTable = $stream->buffer; $this->put(self::$runtimeIdTableCache);
}else{
$this->put(self::serializeBlockTable($this->runtimeIdTable));
} }
$this->put(self::$runtimeIdTable);
$this->putString($this->multiplayerCorrelationId); $this->putString($this->multiplayerCorrelationId);
} }
private static function serializeBlockTable(array $table) : string{
$stream = new NetworkBinaryStream();
$stream->putUnsignedVarInt(count($table));
foreach($table as $v){
$stream->putString($v["name"]);
$stream->putLShort($v["data"]);
}
return $stream->getBuffer();
}
public function handle(NetworkSession $session) : bool{ public function handle(NetworkSession $session) : bool{
return $session->handleStartGame($this); return $session->handleStartGame($this);
} }