mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-21 16:24:05 +00:00
RuntimeDataDescriber: Support dynamically describing arbitrary enums (#6039)
Previously, we were using codegen to support describing a fixed set of enums. Instead, we implement an enum() function, allowing any native PHP enum to be described. All enums used in runtime data have been migrated to native PHP 8.1 enums in minor-next to facilitate this. This implementation: - is faster (in extreme cases by 40x, such as with PotionType) - requires way less code - does not require a build step - is way more flexible This fixes #5877, increasing the range of stuff that plugins are now able to do. EnumTrait enums are not supported, as it's easier and cleaner to just support native enums. Most core EnumTrait enums have been migrated to native enums by now to facilitate this.
This commit is contained in:
parent
6887fcd590
commit
7dcd2592d4
3
.github/workflows/main.yml
vendored
3
.github/workflows/main.yml
vendored
@ -152,9 +152,6 @@ jobs:
|
||||
- name: Regenerate KnownTranslation APIs
|
||||
run: php build/generate-known-translation-apis.php
|
||||
|
||||
- name: Regenerate RuntimeEnum(De)serializer
|
||||
run: php build/generate-runtime-enum-serializers.php
|
||||
|
||||
- name: Regenerate BedrockData available files constants
|
||||
run: php build/generate-bedrockdata-path-consts.php
|
||||
|
||||
|
@ -1,265 +0,0 @@
|
||||
<?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\build\generate_runtime_enum_serializers;
|
||||
|
||||
use pocketmine\block\utils\BellAttachmentType;
|
||||
use pocketmine\block\utils\CopperOxidation;
|
||||
use pocketmine\block\utils\CoralType;
|
||||
use pocketmine\block\utils\DirtType;
|
||||
use pocketmine\block\utils\DripleafState;
|
||||
use pocketmine\block\utils\DyeColor;
|
||||
use pocketmine\block\utils\FroglightType;
|
||||
use pocketmine\block\utils\LeverFacing;
|
||||
use pocketmine\block\utils\MobHeadType;
|
||||
use pocketmine\block\utils\MushroomBlockType;
|
||||
use pocketmine\block\utils\SlabType;
|
||||
use pocketmine\item\MedicineType;
|
||||
use pocketmine\item\PotionType;
|
||||
use pocketmine\item\SuspiciousStewType;
|
||||
use function array_key_first;
|
||||
use function array_map;
|
||||
use function ceil;
|
||||
use function count;
|
||||
use function dirname;
|
||||
use function file_put_contents;
|
||||
use function implode;
|
||||
use function ksort;
|
||||
use function lcfirst;
|
||||
use function log;
|
||||
use function ob_get_clean;
|
||||
use function ob_start;
|
||||
use function usort;
|
||||
use const SORT_STRING;
|
||||
|
||||
require dirname(__DIR__) . '/vendor/autoload.php';
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildWriterFunc(string $virtualTypeName, string $nativeTypeName, array $memberNames, string $functionName) : array{
|
||||
$bits = getBitsRequired($memberNames);
|
||||
$lines = [];
|
||||
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$this->writeInt($bits, match(\$value){";
|
||||
|
||||
foreach($memberNames as $key => $memberName){
|
||||
$lines[] = "\t\t$memberName => $key,";
|
||||
}
|
||||
$lines[] = "\t\tdefault => throw new \pocketmine\utils\AssumptionFailedError(\"All $virtualTypeName cases should be covered\")";
|
||||
$lines[] = "\t});";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildReaderFunc(string $virtualTypeName, string $nativeTypeName, array $memberNames, string $functionName) : array{
|
||||
$bits = getBitsRequired($memberNames);
|
||||
$lines = [];
|
||||
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$value = match(\$this->readInt($bits)){";
|
||||
|
||||
foreach($memberNames as $key => $memberName){
|
||||
$lines[] = "\t\t$key => $memberName,";
|
||||
}
|
||||
$lines[] = "\t\tdefault => throw new InvalidSerializedRuntimeDataException(\"Invalid serialized value for $virtualTypeName\")";
|
||||
$lines[] = "\t};";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
function buildInterfaceFunc(string $nativeTypeName, string $functionName) : string{
|
||||
return "public function $functionName(\\$nativeTypeName &\$value) : void;";
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[] $memberNames
|
||||
* @phpstan-param list<string> $memberNames
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function buildSizeCalculationFunc(string $nativeTypeName, string $functionName, array $memberNames) : array{
|
||||
$lines = [];
|
||||
$lines[] = "public function $functionName(\\$nativeTypeName &\$value) : void{";
|
||||
$lines[] = "\t\$this->addBits(" . getBitsRequired($memberNames) . ");";
|
||||
$lines[] = "}";
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed[] $members
|
||||
*/
|
||||
function getBitsRequired(array $members) : int{
|
||||
return (int) ceil(log(count($members), 2));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \UnitEnum[] $members
|
||||
* @phpstan-param list<\UnitEnum> $members
|
||||
*
|
||||
* @return string[]
|
||||
* @phpstan-return list<string>
|
||||
*/
|
||||
function stringifyEnumMembers(array $members, string $enumClass) : array{
|
||||
usort($members, fn(\UnitEnum $a, \UnitEnum $b) => $a->name <=> $b->name);
|
||||
return array_map(fn(\UnitEnum $case) => "\\$enumClass::$case->name", $members);
|
||||
}
|
||||
|
||||
$enumsUsed = [
|
||||
BellAttachmentType::cases(),
|
||||
CopperOxidation::cases(),
|
||||
CoralType::cases(),
|
||||
DirtType::cases(),
|
||||
DripleafState::cases(),
|
||||
DyeColor::cases(),
|
||||
FroglightType::cases(),
|
||||
LeverFacing::cases(),
|
||||
MedicineType::cases(),
|
||||
MushroomBlockType::cases(),
|
||||
MobHeadType::cases(),
|
||||
SlabType::cases(),
|
||||
SuspiciousStewType::cases(),
|
||||
PotionType::cases()
|
||||
];
|
||||
|
||||
$readerFuncs = [
|
||||
"" => [
|
||||
"abstract protected function readInt(int \$bits) : int;"
|
||||
]
|
||||
];
|
||||
$writerFuncs = [
|
||||
"" => [
|
||||
"abstract protected function writeInt(int \$bits, int \$value) : void;"
|
||||
]
|
||||
];
|
||||
$interfaceFuncs = [];
|
||||
$sizeCalculationFuncs = [
|
||||
"" => [
|
||||
"abstract protected function addBits(int \$bits) : void;"
|
||||
]
|
||||
];
|
||||
|
||||
foreach($enumsUsed as $enumMembers){
|
||||
if(count($enumMembers) === 0){
|
||||
throw new \InvalidArgumentException("Enum members cannot be empty");
|
||||
}
|
||||
$reflect = new \ReflectionClass($enumMembers[array_key_first($enumMembers)]);
|
||||
$virtualTypeName = $reflect->getShortName();
|
||||
$nativeTypeName = $reflect->getName();
|
||||
$functionName = lcfirst($virtualTypeName);
|
||||
|
||||
$stringifiedMembers = stringifyEnumMembers($enumMembers, $nativeTypeName);
|
||||
$writerFuncs[$functionName] = buildWriterFunc(
|
||||
$virtualTypeName,
|
||||
$nativeTypeName,
|
||||
$stringifiedMembers,
|
||||
$functionName
|
||||
);
|
||||
$readerFuncs[$functionName] = buildReaderFunc(
|
||||
$virtualTypeName,
|
||||
$nativeTypeName,
|
||||
$stringifiedMembers,
|
||||
$functionName
|
||||
);
|
||||
$interfaceFuncs[$functionName] = [buildInterfaceFunc(
|
||||
$nativeTypeName,
|
||||
$functionName
|
||||
)];
|
||||
$sizeCalculationFuncs[$functionName] = buildSizeCalculationFunc(
|
||||
$nativeTypeName,
|
||||
$functionName,
|
||||
$stringifiedMembers
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string[][] $functions
|
||||
* @phpstan-param array<string, list<string>> $functions
|
||||
*/
|
||||
function printFunctions(array $functions, string $className, string $classType) : void{
|
||||
ksort($functions, SORT_STRING);
|
||||
|
||||
ob_start();
|
||||
|
||||
echo <<<'HEADER'
|
||||
<?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\data\runtime;
|
||||
|
||||
/**
|
||||
* This class is auto-generated. Do not edit it manually.
|
||||
* @see build/generate-runtime-enum-serializers.php
|
||||
*/
|
||||
|
||||
HEADER;
|
||||
|
||||
echo "$classType $className{\n\n";
|
||||
echo implode("\n\n", array_map(fn(array $functionLines) => "\t" . implode("\n\t", $functionLines), $functions));
|
||||
echo "\n\n}\n";
|
||||
|
||||
file_put_contents(dirname(__DIR__) . '/src/data/runtime/' . $className . '.php', ob_get_clean());
|
||||
}
|
||||
|
||||
printFunctions($writerFuncs, "RuntimeEnumSerializerTrait", "trait");
|
||||
printFunctions($readerFuncs, "RuntimeEnumDeserializerTrait", "trait");
|
||||
printFunctions($interfaceFuncs, "RuntimeEnumDescriber", "interface");
|
||||
printFunctions($sizeCalculationFuncs, "RuntimeEnumSizeCalculatorTrait", "trait");
|
||||
|
||||
echo "Done. Don't forget to run CS fixup after generating code.\n";
|
@ -44,7 +44,7 @@ final class Bell extends Transparent{
|
||||
private BellAttachmentType $attachmentType = BellAttachmentType::FLOOR;
|
||||
|
||||
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
$w->bellAttachmentType($this->attachmentType);
|
||||
$w->enum($this->attachmentType);
|
||||
$w->horizontalFacing($this->facing);
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ class BigDripleafHead extends BaseBigDripleaf{
|
||||
|
||||
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
parent::describeBlockOnlyState($w);
|
||||
$w->dripleafState($this->leafState);
|
||||
$w->enum($this->leafState);
|
||||
}
|
||||
|
||||
protected function isHead() : bool{
|
||||
|
@ -41,7 +41,7 @@ class Dirt extends Opaque{
|
||||
protected DirtType $dirtType = DirtType::NORMAL;
|
||||
|
||||
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
|
||||
$w->dirtType($this->dirtType);
|
||||
$w->enum($this->dirtType);
|
||||
}
|
||||
|
||||
public function getDirtType() : DirtType{ return $this->dirtType; }
|
||||
|
@ -31,7 +31,7 @@ final class Froglight extends SimplePillar{
|
||||
private FroglightType $froglightType = FroglightType::OCHRE;
|
||||
|
||||
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
|
||||
$w->froglightType($this->froglightType);
|
||||
$w->enum($this->froglightType);
|
||||
}
|
||||
|
||||
public function getFroglightType() : FroglightType{ return $this->froglightType; }
|
||||
|
@ -40,7 +40,7 @@ class Lever extends Flowable{
|
||||
protected bool $activated = false;
|
||||
|
||||
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
$w->leverFacing($this->facing);
|
||||
$w->enum($this->facing);
|
||||
$w->bool($this->activated);
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ class MobHead extends Flowable{
|
||||
protected int $rotation = self::MIN_ROTATION; //TODO: split this into floor skull and wall skull handling
|
||||
|
||||
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
|
||||
$w->mobHeadType($this->mobHeadType);
|
||||
$w->enum($this->mobHeadType);
|
||||
}
|
||||
|
||||
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
|
@ -34,7 +34,7 @@ class RedMushroomBlock extends Opaque{
|
||||
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
|
||||
//these blocks always drop as all-cap, but may exist in other forms in the inventory (particularly creative),
|
||||
//so this information needs to be kept in the type info
|
||||
$w->mushroomBlockType($this->mushroomBlockType);
|
||||
$w->enum($this->mushroomBlockType);
|
||||
}
|
||||
|
||||
public function getMushroomBlockType() : MushroomBlockType{ return $this->mushroomBlockType; }
|
||||
|
@ -41,7 +41,7 @@ class Slab extends Transparent{
|
||||
}
|
||||
|
||||
protected function describeBlockOnlyState(RuntimeDataDescriber $w) : void{
|
||||
$w->slabType($this->slabType);
|
||||
$w->enum($this->slabType);
|
||||
}
|
||||
|
||||
public function isTransparent() : bool{
|
||||
|
@ -32,7 +32,7 @@ trait ColoredTrait{
|
||||
|
||||
/** @see Block::describeBlockItemState() */
|
||||
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
|
||||
$w->dyeColor($this->color);
|
||||
$w->enum($this->color);
|
||||
}
|
||||
|
||||
public function getColor() : DyeColor{ return $this->color; }
|
||||
|
@ -38,7 +38,7 @@ trait CopperTrait{
|
||||
private bool $waxed = false;
|
||||
|
||||
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
|
||||
$w->copperOxidation($this->oxidation);
|
||||
$w->enum($this->oxidation);
|
||||
$w->bool($this->waxed);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ trait CoralTypeTrait{
|
||||
|
||||
/** @see Block::describeBlockItemState() */
|
||||
public function describeBlockItemState(RuntimeDataDescriber $w) : void{
|
||||
$w->coralType($this->coralType);
|
||||
$w->enum($this->coralType);
|
||||
$w->bool($this->dead);
|
||||
}
|
||||
|
||||
|
@ -24,67 +24,71 @@ declare(strict_types=1);
|
||||
namespace pocketmine\data\runtime;
|
||||
|
||||
/**
|
||||
* This class is auto-generated. Do not edit it manually.
|
||||
* @see build/generate-runtime-enum-serializers.php
|
||||
* Provides backwards-compatible shims for the old codegen'd enum describer methods.
|
||||
* This is kept for plugin backwards compatibility, but these functions should not be used in new code.
|
||||
* @deprecated
|
||||
*/
|
||||
trait RuntimeEnumSizeCalculatorTrait{
|
||||
trait LegacyRuntimeEnumDescriberTrait{
|
||||
|
||||
abstract protected function addBits(int $bits) : void;
|
||||
/**
|
||||
* @phpstan-template T of \UnitEnum
|
||||
* @phpstan-param T $case
|
||||
*/
|
||||
abstract protected function enum(\UnitEnum &$case) : void;
|
||||
|
||||
public function bellAttachmentType(\pocketmine\block\utils\BellAttachmentType &$value) : void{
|
||||
$this->addBits(2);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function copperOxidation(\pocketmine\block\utils\CopperOxidation &$value) : void{
|
||||
$this->addBits(2);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function coralType(\pocketmine\block\utils\CoralType &$value) : void{
|
||||
$this->addBits(3);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function dirtType(\pocketmine\block\utils\DirtType &$value) : void{
|
||||
$this->addBits(2);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function dripleafState(\pocketmine\block\utils\DripleafState &$value) : void{
|
||||
$this->addBits(2);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function dyeColor(\pocketmine\block\utils\DyeColor &$value) : void{
|
||||
$this->addBits(4);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function froglightType(\pocketmine\block\utils\FroglightType &$value) : void{
|
||||
$this->addBits(2);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function leverFacing(\pocketmine\block\utils\LeverFacing &$value) : void{
|
||||
$this->addBits(3);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function medicineType(\pocketmine\item\MedicineType &$value) : void{
|
||||
$this->addBits(2);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function mobHeadType(\pocketmine\block\utils\MobHeadType &$value) : void{
|
||||
$this->addBits(3);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function mushroomBlockType(\pocketmine\block\utils\MushroomBlockType &$value) : void{
|
||||
$this->addBits(4);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function potionType(\pocketmine\item\PotionType &$value) : void{
|
||||
$this->addBits(6);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function slabType(\pocketmine\block\utils\SlabType &$value) : void{
|
||||
$this->addBits(2);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
public function suspiciousStewType(\pocketmine\item\SuspiciousStewType &$value) : void{
|
||||
$this->addBits(4);
|
||||
$this->enum($value);
|
||||
}
|
||||
|
||||
}
|
@ -77,4 +77,10 @@ interface RuntimeDataDescriber extends RuntimeEnumDescriber{
|
||||
public function railShape(int &$railShape) : void;
|
||||
|
||||
public function straightOnlyRailShape(int &$railShape) : void;
|
||||
|
||||
/**
|
||||
* @phpstan-template T of \UnitEnum
|
||||
* @phpstan-param T $case
|
||||
*/
|
||||
public function enum(\UnitEnum &$case) : void;
|
||||
}
|
||||
|
@ -29,11 +29,12 @@ use pocketmine\block\utils\WallConnectionType;
|
||||
use pocketmine\math\Axis;
|
||||
use pocketmine\math\Facing;
|
||||
use pocketmine\utils\AssumptionFailedError;
|
||||
use function get_class;
|
||||
use function intdiv;
|
||||
use function spl_object_id;
|
||||
|
||||
final class RuntimeDataReader implements RuntimeDataDescriber{
|
||||
use RuntimeEnumDeserializerTrait;
|
||||
use LegacyRuntimeEnumDescriberTrait;
|
||||
|
||||
private int $offset = 0;
|
||||
|
||||
@ -210,5 +211,16 @@ final class RuntimeDataReader implements RuntimeDataDescriber{
|
||||
$railShape = $result;
|
||||
}
|
||||
|
||||
public function enum(\UnitEnum &$case) : void{
|
||||
$metadata = RuntimeEnumMetadata::from($case);
|
||||
$raw = $this->readInt($metadata->bits);
|
||||
$result = $metadata->intToEnum($raw);
|
||||
if($result === null){
|
||||
throw new InvalidSerializedRuntimeDataException("Invalid serialized value $raw for " . get_class($case));
|
||||
}
|
||||
|
||||
$case = $result;
|
||||
}
|
||||
|
||||
public function getOffset() : int{ return $this->offset; }
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ use pocketmine\math\Facing;
|
||||
use function count;
|
||||
|
||||
final class RuntimeDataSizeCalculator implements RuntimeDataDescriber{
|
||||
use RuntimeEnumSizeCalculatorTrait;
|
||||
use LegacyRuntimeEnumDescriberTrait;
|
||||
|
||||
private int $bits = 0;
|
||||
|
||||
@ -95,4 +95,9 @@ final class RuntimeDataSizeCalculator implements RuntimeDataDescriber{
|
||||
public function straightOnlyRailShape(int &$railShape) : void{
|
||||
$this->addBits(3);
|
||||
}
|
||||
|
||||
public function enum(\UnitEnum &$case) : void{
|
||||
$metadata = RuntimeEnumMetadata::from($case);
|
||||
$this->addBits($metadata->bits);
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ use function array_flip;
|
||||
use function spl_object_id;
|
||||
|
||||
final class RuntimeDataWriter implements RuntimeDataDescriber{
|
||||
use RuntimeEnumSerializerTrait;
|
||||
use LegacyRuntimeEnumDescriberTrait;
|
||||
|
||||
private int $value = 0;
|
||||
private int $offset = 0;
|
||||
@ -174,6 +174,11 @@ final class RuntimeDataWriter implements RuntimeDataDescriber{
|
||||
$this->int(3, $railShape);
|
||||
}
|
||||
|
||||
public function enum(\UnitEnum &$case) : void{
|
||||
$metadata = RuntimeEnumMetadata::from($case);
|
||||
$this->writeInt($metadata->bits, $metadata->enumToInt($case));
|
||||
}
|
||||
|
||||
public function getValue() : int{ return $this->value; }
|
||||
|
||||
public function getOffset() : int{ return $this->offset; }
|
||||
|
@ -24,8 +24,9 @@ declare(strict_types=1);
|
||||
namespace pocketmine\data\runtime;
|
||||
|
||||
/**
|
||||
* This class is auto-generated. Do not edit it manually.
|
||||
* @see build/generate-runtime-enum-serializers.php
|
||||
* Provides backwards-compatible shims for the old codegen'd enum describer methods.
|
||||
* This is kept for plugin backwards compatibility, but these functions should not be used in new code.
|
||||
* @deprecated
|
||||
*/
|
||||
interface RuntimeEnumDescriber{
|
||||
|
||||
|
@ -1,243 +0,0 @@
|
||||
<?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\data\runtime;
|
||||
|
||||
/**
|
||||
* This class is auto-generated. Do not edit it manually.
|
||||
* @see build/generate-runtime-enum-serializers.php
|
||||
*/
|
||||
trait RuntimeEnumDeserializerTrait{
|
||||
|
||||
abstract protected function readInt(int $bits) : int;
|
||||
|
||||
public function bellAttachmentType(\pocketmine\block\utils\BellAttachmentType &$value) : void{
|
||||
$value = match($this->readInt(2)){
|
||||
0 => \pocketmine\block\utils\BellAttachmentType::CEILING,
|
||||
1 => \pocketmine\block\utils\BellAttachmentType::FLOOR,
|
||||
2 => \pocketmine\block\utils\BellAttachmentType::ONE_WALL,
|
||||
3 => \pocketmine\block\utils\BellAttachmentType::TWO_WALLS,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for BellAttachmentType")
|
||||
};
|
||||
}
|
||||
|
||||
public function copperOxidation(\pocketmine\block\utils\CopperOxidation &$value) : void{
|
||||
$value = match($this->readInt(2)){
|
||||
0 => \pocketmine\block\utils\CopperOxidation::EXPOSED,
|
||||
1 => \pocketmine\block\utils\CopperOxidation::NONE,
|
||||
2 => \pocketmine\block\utils\CopperOxidation::OXIDIZED,
|
||||
3 => \pocketmine\block\utils\CopperOxidation::WEATHERED,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for CopperOxidation")
|
||||
};
|
||||
}
|
||||
|
||||
public function coralType(\pocketmine\block\utils\CoralType &$value) : void{
|
||||
$value = match($this->readInt(3)){
|
||||
0 => \pocketmine\block\utils\CoralType::BRAIN,
|
||||
1 => \pocketmine\block\utils\CoralType::BUBBLE,
|
||||
2 => \pocketmine\block\utils\CoralType::FIRE,
|
||||
3 => \pocketmine\block\utils\CoralType::HORN,
|
||||
4 => \pocketmine\block\utils\CoralType::TUBE,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for CoralType")
|
||||
};
|
||||
}
|
||||
|
||||
public function dirtType(\pocketmine\block\utils\DirtType &$value) : void{
|
||||
$value = match($this->readInt(2)){
|
||||
0 => \pocketmine\block\utils\DirtType::COARSE,
|
||||
1 => \pocketmine\block\utils\DirtType::NORMAL,
|
||||
2 => \pocketmine\block\utils\DirtType::ROOTED,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for DirtType")
|
||||
};
|
||||
}
|
||||
|
||||
public function dripleafState(\pocketmine\block\utils\DripleafState &$value) : void{
|
||||
$value = match($this->readInt(2)){
|
||||
0 => \pocketmine\block\utils\DripleafState::FULL_TILT,
|
||||
1 => \pocketmine\block\utils\DripleafState::PARTIAL_TILT,
|
||||
2 => \pocketmine\block\utils\DripleafState::STABLE,
|
||||
3 => \pocketmine\block\utils\DripleafState::UNSTABLE,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for DripleafState")
|
||||
};
|
||||
}
|
||||
|
||||
public function dyeColor(\pocketmine\block\utils\DyeColor &$value) : void{
|
||||
$value = match($this->readInt(4)){
|
||||
0 => \pocketmine\block\utils\DyeColor::BLACK,
|
||||
1 => \pocketmine\block\utils\DyeColor::BLUE,
|
||||
2 => \pocketmine\block\utils\DyeColor::BROWN,
|
||||
3 => \pocketmine\block\utils\DyeColor::CYAN,
|
||||
4 => \pocketmine\block\utils\DyeColor::GRAY,
|
||||
5 => \pocketmine\block\utils\DyeColor::GREEN,
|
||||
6 => \pocketmine\block\utils\DyeColor::LIGHT_BLUE,
|
||||
7 => \pocketmine\block\utils\DyeColor::LIGHT_GRAY,
|
||||
8 => \pocketmine\block\utils\DyeColor::LIME,
|
||||
9 => \pocketmine\block\utils\DyeColor::MAGENTA,
|
||||
10 => \pocketmine\block\utils\DyeColor::ORANGE,
|
||||
11 => \pocketmine\block\utils\DyeColor::PINK,
|
||||
12 => \pocketmine\block\utils\DyeColor::PURPLE,
|
||||
13 => \pocketmine\block\utils\DyeColor::RED,
|
||||
14 => \pocketmine\block\utils\DyeColor::WHITE,
|
||||
15 => \pocketmine\block\utils\DyeColor::YELLOW,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for DyeColor")
|
||||
};
|
||||
}
|
||||
|
||||
public function froglightType(\pocketmine\block\utils\FroglightType &$value) : void{
|
||||
$value = match($this->readInt(2)){
|
||||
0 => \pocketmine\block\utils\FroglightType::OCHRE,
|
||||
1 => \pocketmine\block\utils\FroglightType::PEARLESCENT,
|
||||
2 => \pocketmine\block\utils\FroglightType::VERDANT,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for FroglightType")
|
||||
};
|
||||
}
|
||||
|
||||
public function leverFacing(\pocketmine\block\utils\LeverFacing &$value) : void{
|
||||
$value = match($this->readInt(3)){
|
||||
0 => \pocketmine\block\utils\LeverFacing::DOWN_AXIS_X,
|
||||
1 => \pocketmine\block\utils\LeverFacing::DOWN_AXIS_Z,
|
||||
2 => \pocketmine\block\utils\LeverFacing::EAST,
|
||||
3 => \pocketmine\block\utils\LeverFacing::NORTH,
|
||||
4 => \pocketmine\block\utils\LeverFacing::SOUTH,
|
||||
5 => \pocketmine\block\utils\LeverFacing::UP_AXIS_X,
|
||||
6 => \pocketmine\block\utils\LeverFacing::UP_AXIS_Z,
|
||||
7 => \pocketmine\block\utils\LeverFacing::WEST,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for LeverFacing")
|
||||
};
|
||||
}
|
||||
|
||||
public function medicineType(\pocketmine\item\MedicineType &$value) : void{
|
||||
$value = match($this->readInt(2)){
|
||||
0 => \pocketmine\item\MedicineType::ANTIDOTE,
|
||||
1 => \pocketmine\item\MedicineType::ELIXIR,
|
||||
2 => \pocketmine\item\MedicineType::EYE_DROPS,
|
||||
3 => \pocketmine\item\MedicineType::TONIC,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for MedicineType")
|
||||
};
|
||||
}
|
||||
|
||||
public function mobHeadType(\pocketmine\block\utils\MobHeadType &$value) : void{
|
||||
$value = match($this->readInt(3)){
|
||||
0 => \pocketmine\block\utils\MobHeadType::CREEPER,
|
||||
1 => \pocketmine\block\utils\MobHeadType::DRAGON,
|
||||
2 => \pocketmine\block\utils\MobHeadType::PIGLIN,
|
||||
3 => \pocketmine\block\utils\MobHeadType::PLAYER,
|
||||
4 => \pocketmine\block\utils\MobHeadType::SKELETON,
|
||||
5 => \pocketmine\block\utils\MobHeadType::WITHER_SKELETON,
|
||||
6 => \pocketmine\block\utils\MobHeadType::ZOMBIE,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for MobHeadType")
|
||||
};
|
||||
}
|
||||
|
||||
public function mushroomBlockType(\pocketmine\block\utils\MushroomBlockType &$value) : void{
|
||||
$value = match($this->readInt(4)){
|
||||
0 => \pocketmine\block\utils\MushroomBlockType::ALL_CAP,
|
||||
1 => \pocketmine\block\utils\MushroomBlockType::CAP_EAST,
|
||||
2 => \pocketmine\block\utils\MushroomBlockType::CAP_MIDDLE,
|
||||
3 => \pocketmine\block\utils\MushroomBlockType::CAP_NORTH,
|
||||
4 => \pocketmine\block\utils\MushroomBlockType::CAP_NORTHEAST,
|
||||
5 => \pocketmine\block\utils\MushroomBlockType::CAP_NORTHWEST,
|
||||
6 => \pocketmine\block\utils\MushroomBlockType::CAP_SOUTH,
|
||||
7 => \pocketmine\block\utils\MushroomBlockType::CAP_SOUTHEAST,
|
||||
8 => \pocketmine\block\utils\MushroomBlockType::CAP_SOUTHWEST,
|
||||
9 => \pocketmine\block\utils\MushroomBlockType::CAP_WEST,
|
||||
10 => \pocketmine\block\utils\MushroomBlockType::PORES,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for MushroomBlockType")
|
||||
};
|
||||
}
|
||||
|
||||
public function potionType(\pocketmine\item\PotionType &$value) : void{
|
||||
$value = match($this->readInt(6)){
|
||||
0 => \pocketmine\item\PotionType::AWKWARD,
|
||||
1 => \pocketmine\item\PotionType::FIRE_RESISTANCE,
|
||||
2 => \pocketmine\item\PotionType::HARMING,
|
||||
3 => \pocketmine\item\PotionType::HEALING,
|
||||
4 => \pocketmine\item\PotionType::INVISIBILITY,
|
||||
5 => \pocketmine\item\PotionType::LEAPING,
|
||||
6 => \pocketmine\item\PotionType::LONG_FIRE_RESISTANCE,
|
||||
7 => \pocketmine\item\PotionType::LONG_INVISIBILITY,
|
||||
8 => \pocketmine\item\PotionType::LONG_LEAPING,
|
||||
9 => \pocketmine\item\PotionType::LONG_MUNDANE,
|
||||
10 => \pocketmine\item\PotionType::LONG_NIGHT_VISION,
|
||||
11 => \pocketmine\item\PotionType::LONG_POISON,
|
||||
12 => \pocketmine\item\PotionType::LONG_REGENERATION,
|
||||
13 => \pocketmine\item\PotionType::LONG_SLOWNESS,
|
||||
14 => \pocketmine\item\PotionType::LONG_SLOW_FALLING,
|
||||
15 => \pocketmine\item\PotionType::LONG_STRENGTH,
|
||||
16 => \pocketmine\item\PotionType::LONG_SWIFTNESS,
|
||||
17 => \pocketmine\item\PotionType::LONG_TURTLE_MASTER,
|
||||
18 => \pocketmine\item\PotionType::LONG_WATER_BREATHING,
|
||||
19 => \pocketmine\item\PotionType::LONG_WEAKNESS,
|
||||
20 => \pocketmine\item\PotionType::MUNDANE,
|
||||
21 => \pocketmine\item\PotionType::NIGHT_VISION,
|
||||
22 => \pocketmine\item\PotionType::POISON,
|
||||
23 => \pocketmine\item\PotionType::REGENERATION,
|
||||
24 => \pocketmine\item\PotionType::SLOWNESS,
|
||||
25 => \pocketmine\item\PotionType::SLOW_FALLING,
|
||||
26 => \pocketmine\item\PotionType::STRENGTH,
|
||||
27 => \pocketmine\item\PotionType::STRONG_HARMING,
|
||||
28 => \pocketmine\item\PotionType::STRONG_HEALING,
|
||||
29 => \pocketmine\item\PotionType::STRONG_LEAPING,
|
||||
30 => \pocketmine\item\PotionType::STRONG_POISON,
|
||||
31 => \pocketmine\item\PotionType::STRONG_REGENERATION,
|
||||
32 => \pocketmine\item\PotionType::STRONG_SLOWNESS,
|
||||
33 => \pocketmine\item\PotionType::STRONG_STRENGTH,
|
||||
34 => \pocketmine\item\PotionType::STRONG_SWIFTNESS,
|
||||
35 => \pocketmine\item\PotionType::STRONG_TURTLE_MASTER,
|
||||
36 => \pocketmine\item\PotionType::SWIFTNESS,
|
||||
37 => \pocketmine\item\PotionType::THICK,
|
||||
38 => \pocketmine\item\PotionType::TURTLE_MASTER,
|
||||
39 => \pocketmine\item\PotionType::WATER,
|
||||
40 => \pocketmine\item\PotionType::WATER_BREATHING,
|
||||
41 => \pocketmine\item\PotionType::WEAKNESS,
|
||||
42 => \pocketmine\item\PotionType::WITHER,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for PotionType")
|
||||
};
|
||||
}
|
||||
|
||||
public function slabType(\pocketmine\block\utils\SlabType &$value) : void{
|
||||
$value = match($this->readInt(2)){
|
||||
0 => \pocketmine\block\utils\SlabType::BOTTOM,
|
||||
1 => \pocketmine\block\utils\SlabType::DOUBLE,
|
||||
2 => \pocketmine\block\utils\SlabType::TOP,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for SlabType")
|
||||
};
|
||||
}
|
||||
|
||||
public function suspiciousStewType(\pocketmine\item\SuspiciousStewType &$value) : void{
|
||||
$value = match($this->readInt(4)){
|
||||
0 => \pocketmine\item\SuspiciousStewType::ALLIUM,
|
||||
1 => \pocketmine\item\SuspiciousStewType::AZURE_BLUET,
|
||||
2 => \pocketmine\item\SuspiciousStewType::BLUE_ORCHID,
|
||||
3 => \pocketmine\item\SuspiciousStewType::CORNFLOWER,
|
||||
4 => \pocketmine\item\SuspiciousStewType::DANDELION,
|
||||
5 => \pocketmine\item\SuspiciousStewType::LILY_OF_THE_VALLEY,
|
||||
6 => \pocketmine\item\SuspiciousStewType::OXEYE_DAISY,
|
||||
7 => \pocketmine\item\SuspiciousStewType::POPPY,
|
||||
8 => \pocketmine\item\SuspiciousStewType::TULIP,
|
||||
9 => \pocketmine\item\SuspiciousStewType::WITHER_ROSE,
|
||||
default => throw new InvalidSerializedRuntimeDataException("Invalid serialized value for SuspiciousStewType")
|
||||
};
|
||||
}
|
||||
|
||||
}
|
114
src/data/runtime/RuntimeEnumMetadata.php
Normal file
114
src/data/runtime/RuntimeEnumMetadata.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?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\data\runtime;
|
||||
|
||||
use function array_values;
|
||||
use function ceil;
|
||||
use function count;
|
||||
use function log;
|
||||
use function spl_object_id;
|
||||
use function usort;
|
||||
|
||||
/**
|
||||
* A big hack to allow lazily associating enum cases with packed bit values for RuntimeDataDescriber :)
|
||||
*
|
||||
* @internal
|
||||
* @phpstan-template T of \UnitEnum
|
||||
*/
|
||||
final class RuntimeEnumMetadata{
|
||||
public readonly int $bits;
|
||||
|
||||
/**
|
||||
* @var object[]
|
||||
* @phpstan-var list<T>
|
||||
*/
|
||||
private readonly array $intToEnum;
|
||||
/**
|
||||
* @var int[]
|
||||
* @phpstan-var array<int, int>
|
||||
*/
|
||||
private readonly array $enumToInt;
|
||||
|
||||
/**
|
||||
* @param \UnitEnum[] $members
|
||||
* @phpstan-param list<T> $members
|
||||
*/
|
||||
public function __construct(
|
||||
array $members
|
||||
){
|
||||
usort($members, fn(\UnitEnum $a, \UnitEnum $b) => $a->name <=> $b->name); //sort by name to ensure consistent ordering (and thus consistent bit assignments)
|
||||
|
||||
$this->bits = (int) ceil(log(count($members), 2));
|
||||
$this->intToEnum = array_values($members);
|
||||
|
||||
$reversed = [];
|
||||
foreach($this->intToEnum as $int => $enum){
|
||||
$reversed[spl_object_id($enum)] = $int;
|
||||
}
|
||||
|
||||
$this->enumToInt = $reversed;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-return T|null
|
||||
*/
|
||||
public function intToEnum(int $value) : ?object{
|
||||
return $this->intToEnum[$value] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @phpstan-param T $enum
|
||||
*/
|
||||
public function enumToInt(object $enum) : int{
|
||||
return $this->enumToInt[spl_object_id($enum)];
|
||||
}
|
||||
|
||||
/**
|
||||
* @var self[]
|
||||
* @phpstan-var array<class-string, object>
|
||||
*/
|
||||
private static array $cache = [];
|
||||
|
||||
/**
|
||||
* @phpstan-template TEnum of \UnitEnum
|
||||
* @phpstan-param TEnum $case
|
||||
*
|
||||
* @phpstan-return self<TEnum>
|
||||
*/
|
||||
public static function from(\UnitEnum $case) : self{
|
||||
$class = $case::class;
|
||||
/** @phpstan-var self<TEnum>|null $metadata */
|
||||
$metadata = self::$cache[$class] ?? null;
|
||||
if($metadata === null){
|
||||
/**
|
||||
* PHPStan can't infer this correctly :( https://github.com/phpstan/phpstan/issues/7162
|
||||
* @phpstan-var list<TEnum> $cases
|
||||
*/
|
||||
$cases = $case::cases();
|
||||
self::$cache[$class] = $metadata = new self($cases);
|
||||
}
|
||||
|
||||
return $metadata;
|
||||
}
|
||||
}
|
@ -1,243 +0,0 @@
|
||||
<?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\data\runtime;
|
||||
|
||||
/**
|
||||
* This class is auto-generated. Do not edit it manually.
|
||||
* @see build/generate-runtime-enum-serializers.php
|
||||
*/
|
||||
trait RuntimeEnumSerializerTrait{
|
||||
|
||||
abstract protected function writeInt(int $bits, int $value) : void;
|
||||
|
||||
public function bellAttachmentType(\pocketmine\block\utils\BellAttachmentType &$value) : void{
|
||||
$this->writeInt(2, match($value){
|
||||
\pocketmine\block\utils\BellAttachmentType::CEILING => 0,
|
||||
\pocketmine\block\utils\BellAttachmentType::FLOOR => 1,
|
||||
\pocketmine\block\utils\BellAttachmentType::ONE_WALL => 2,
|
||||
\pocketmine\block\utils\BellAttachmentType::TWO_WALLS => 3,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All BellAttachmentType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function copperOxidation(\pocketmine\block\utils\CopperOxidation &$value) : void{
|
||||
$this->writeInt(2, match($value){
|
||||
\pocketmine\block\utils\CopperOxidation::EXPOSED => 0,
|
||||
\pocketmine\block\utils\CopperOxidation::NONE => 1,
|
||||
\pocketmine\block\utils\CopperOxidation::OXIDIZED => 2,
|
||||
\pocketmine\block\utils\CopperOxidation::WEATHERED => 3,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All CopperOxidation cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function coralType(\pocketmine\block\utils\CoralType &$value) : void{
|
||||
$this->writeInt(3, match($value){
|
||||
\pocketmine\block\utils\CoralType::BRAIN => 0,
|
||||
\pocketmine\block\utils\CoralType::BUBBLE => 1,
|
||||
\pocketmine\block\utils\CoralType::FIRE => 2,
|
||||
\pocketmine\block\utils\CoralType::HORN => 3,
|
||||
\pocketmine\block\utils\CoralType::TUBE => 4,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All CoralType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function dirtType(\pocketmine\block\utils\DirtType &$value) : void{
|
||||
$this->writeInt(2, match($value){
|
||||
\pocketmine\block\utils\DirtType::COARSE => 0,
|
||||
\pocketmine\block\utils\DirtType::NORMAL => 1,
|
||||
\pocketmine\block\utils\DirtType::ROOTED => 2,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All DirtType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function dripleafState(\pocketmine\block\utils\DripleafState &$value) : void{
|
||||
$this->writeInt(2, match($value){
|
||||
\pocketmine\block\utils\DripleafState::FULL_TILT => 0,
|
||||
\pocketmine\block\utils\DripleafState::PARTIAL_TILT => 1,
|
||||
\pocketmine\block\utils\DripleafState::STABLE => 2,
|
||||
\pocketmine\block\utils\DripleafState::UNSTABLE => 3,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All DripleafState cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function dyeColor(\pocketmine\block\utils\DyeColor &$value) : void{
|
||||
$this->writeInt(4, match($value){
|
||||
\pocketmine\block\utils\DyeColor::BLACK => 0,
|
||||
\pocketmine\block\utils\DyeColor::BLUE => 1,
|
||||
\pocketmine\block\utils\DyeColor::BROWN => 2,
|
||||
\pocketmine\block\utils\DyeColor::CYAN => 3,
|
||||
\pocketmine\block\utils\DyeColor::GRAY => 4,
|
||||
\pocketmine\block\utils\DyeColor::GREEN => 5,
|
||||
\pocketmine\block\utils\DyeColor::LIGHT_BLUE => 6,
|
||||
\pocketmine\block\utils\DyeColor::LIGHT_GRAY => 7,
|
||||
\pocketmine\block\utils\DyeColor::LIME => 8,
|
||||
\pocketmine\block\utils\DyeColor::MAGENTA => 9,
|
||||
\pocketmine\block\utils\DyeColor::ORANGE => 10,
|
||||
\pocketmine\block\utils\DyeColor::PINK => 11,
|
||||
\pocketmine\block\utils\DyeColor::PURPLE => 12,
|
||||
\pocketmine\block\utils\DyeColor::RED => 13,
|
||||
\pocketmine\block\utils\DyeColor::WHITE => 14,
|
||||
\pocketmine\block\utils\DyeColor::YELLOW => 15,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All DyeColor cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function froglightType(\pocketmine\block\utils\FroglightType &$value) : void{
|
||||
$this->writeInt(2, match($value){
|
||||
\pocketmine\block\utils\FroglightType::OCHRE => 0,
|
||||
\pocketmine\block\utils\FroglightType::PEARLESCENT => 1,
|
||||
\pocketmine\block\utils\FroglightType::VERDANT => 2,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All FroglightType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function leverFacing(\pocketmine\block\utils\LeverFacing &$value) : void{
|
||||
$this->writeInt(3, match($value){
|
||||
\pocketmine\block\utils\LeverFacing::DOWN_AXIS_X => 0,
|
||||
\pocketmine\block\utils\LeverFacing::DOWN_AXIS_Z => 1,
|
||||
\pocketmine\block\utils\LeverFacing::EAST => 2,
|
||||
\pocketmine\block\utils\LeverFacing::NORTH => 3,
|
||||
\pocketmine\block\utils\LeverFacing::SOUTH => 4,
|
||||
\pocketmine\block\utils\LeverFacing::UP_AXIS_X => 5,
|
||||
\pocketmine\block\utils\LeverFacing::UP_AXIS_Z => 6,
|
||||
\pocketmine\block\utils\LeverFacing::WEST => 7,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All LeverFacing cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function medicineType(\pocketmine\item\MedicineType &$value) : void{
|
||||
$this->writeInt(2, match($value){
|
||||
\pocketmine\item\MedicineType::ANTIDOTE => 0,
|
||||
\pocketmine\item\MedicineType::ELIXIR => 1,
|
||||
\pocketmine\item\MedicineType::EYE_DROPS => 2,
|
||||
\pocketmine\item\MedicineType::TONIC => 3,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All MedicineType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function mobHeadType(\pocketmine\block\utils\MobHeadType &$value) : void{
|
||||
$this->writeInt(3, match($value){
|
||||
\pocketmine\block\utils\MobHeadType::CREEPER => 0,
|
||||
\pocketmine\block\utils\MobHeadType::DRAGON => 1,
|
||||
\pocketmine\block\utils\MobHeadType::PIGLIN => 2,
|
||||
\pocketmine\block\utils\MobHeadType::PLAYER => 3,
|
||||
\pocketmine\block\utils\MobHeadType::SKELETON => 4,
|
||||
\pocketmine\block\utils\MobHeadType::WITHER_SKELETON => 5,
|
||||
\pocketmine\block\utils\MobHeadType::ZOMBIE => 6,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All MobHeadType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function mushroomBlockType(\pocketmine\block\utils\MushroomBlockType &$value) : void{
|
||||
$this->writeInt(4, match($value){
|
||||
\pocketmine\block\utils\MushroomBlockType::ALL_CAP => 0,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_EAST => 1,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_MIDDLE => 2,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_NORTH => 3,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_NORTHEAST => 4,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_NORTHWEST => 5,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_SOUTH => 6,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_SOUTHEAST => 7,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_SOUTHWEST => 8,
|
||||
\pocketmine\block\utils\MushroomBlockType::CAP_WEST => 9,
|
||||
\pocketmine\block\utils\MushroomBlockType::PORES => 10,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All MushroomBlockType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function potionType(\pocketmine\item\PotionType &$value) : void{
|
||||
$this->writeInt(6, match($value){
|
||||
\pocketmine\item\PotionType::AWKWARD => 0,
|
||||
\pocketmine\item\PotionType::FIRE_RESISTANCE => 1,
|
||||
\pocketmine\item\PotionType::HARMING => 2,
|
||||
\pocketmine\item\PotionType::HEALING => 3,
|
||||
\pocketmine\item\PotionType::INVISIBILITY => 4,
|
||||
\pocketmine\item\PotionType::LEAPING => 5,
|
||||
\pocketmine\item\PotionType::LONG_FIRE_RESISTANCE => 6,
|
||||
\pocketmine\item\PotionType::LONG_INVISIBILITY => 7,
|
||||
\pocketmine\item\PotionType::LONG_LEAPING => 8,
|
||||
\pocketmine\item\PotionType::LONG_MUNDANE => 9,
|
||||
\pocketmine\item\PotionType::LONG_NIGHT_VISION => 10,
|
||||
\pocketmine\item\PotionType::LONG_POISON => 11,
|
||||
\pocketmine\item\PotionType::LONG_REGENERATION => 12,
|
||||
\pocketmine\item\PotionType::LONG_SLOWNESS => 13,
|
||||
\pocketmine\item\PotionType::LONG_SLOW_FALLING => 14,
|
||||
\pocketmine\item\PotionType::LONG_STRENGTH => 15,
|
||||
\pocketmine\item\PotionType::LONG_SWIFTNESS => 16,
|
||||
\pocketmine\item\PotionType::LONG_TURTLE_MASTER => 17,
|
||||
\pocketmine\item\PotionType::LONG_WATER_BREATHING => 18,
|
||||
\pocketmine\item\PotionType::LONG_WEAKNESS => 19,
|
||||
\pocketmine\item\PotionType::MUNDANE => 20,
|
||||
\pocketmine\item\PotionType::NIGHT_VISION => 21,
|
||||
\pocketmine\item\PotionType::POISON => 22,
|
||||
\pocketmine\item\PotionType::REGENERATION => 23,
|
||||
\pocketmine\item\PotionType::SLOWNESS => 24,
|
||||
\pocketmine\item\PotionType::SLOW_FALLING => 25,
|
||||
\pocketmine\item\PotionType::STRENGTH => 26,
|
||||
\pocketmine\item\PotionType::STRONG_HARMING => 27,
|
||||
\pocketmine\item\PotionType::STRONG_HEALING => 28,
|
||||
\pocketmine\item\PotionType::STRONG_LEAPING => 29,
|
||||
\pocketmine\item\PotionType::STRONG_POISON => 30,
|
||||
\pocketmine\item\PotionType::STRONG_REGENERATION => 31,
|
||||
\pocketmine\item\PotionType::STRONG_SLOWNESS => 32,
|
||||
\pocketmine\item\PotionType::STRONG_STRENGTH => 33,
|
||||
\pocketmine\item\PotionType::STRONG_SWIFTNESS => 34,
|
||||
\pocketmine\item\PotionType::STRONG_TURTLE_MASTER => 35,
|
||||
\pocketmine\item\PotionType::SWIFTNESS => 36,
|
||||
\pocketmine\item\PotionType::THICK => 37,
|
||||
\pocketmine\item\PotionType::TURTLE_MASTER => 38,
|
||||
\pocketmine\item\PotionType::WATER => 39,
|
||||
\pocketmine\item\PotionType::WATER_BREATHING => 40,
|
||||
\pocketmine\item\PotionType::WEAKNESS => 41,
|
||||
\pocketmine\item\PotionType::WITHER => 42,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All PotionType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function slabType(\pocketmine\block\utils\SlabType &$value) : void{
|
||||
$this->writeInt(2, match($value){
|
||||
\pocketmine\block\utils\SlabType::BOTTOM => 0,
|
||||
\pocketmine\block\utils\SlabType::DOUBLE => 1,
|
||||
\pocketmine\block\utils\SlabType::TOP => 2,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All SlabType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
public function suspiciousStewType(\pocketmine\item\SuspiciousStewType &$value) : void{
|
||||
$this->writeInt(4, match($value){
|
||||
\pocketmine\item\SuspiciousStewType::ALLIUM => 0,
|
||||
\pocketmine\item\SuspiciousStewType::AZURE_BLUET => 1,
|
||||
\pocketmine\item\SuspiciousStewType::BLUE_ORCHID => 2,
|
||||
\pocketmine\item\SuspiciousStewType::CORNFLOWER => 3,
|
||||
\pocketmine\item\SuspiciousStewType::DANDELION => 4,
|
||||
\pocketmine\item\SuspiciousStewType::LILY_OF_THE_VALLEY => 5,
|
||||
\pocketmine\item\SuspiciousStewType::OXEYE_DAISY => 6,
|
||||
\pocketmine\item\SuspiciousStewType::POPPY => 7,
|
||||
\pocketmine\item\SuspiciousStewType::TULIP => 8,
|
||||
\pocketmine\item\SuspiciousStewType::WITHER_ROSE => 9,
|
||||
default => throw new \pocketmine\utils\AssumptionFailedError("All SuspiciousStewType cases should be covered")
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -58,7 +58,7 @@ class Banner extends ItemBlockWallOrFloor{
|
||||
}
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->dyeColor($this->color);
|
||||
$w->enum($this->color);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,7 +30,7 @@ class Dye extends Item{
|
||||
private DyeColor $color = DyeColor::BLACK;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->dyeColor($this->color);
|
||||
$w->enum($this->color);
|
||||
}
|
||||
|
||||
public function getColor() : DyeColor{
|
||||
|
@ -32,7 +32,7 @@ class Medicine extends Item implements ConsumableItem{
|
||||
private MedicineType $medicineType = MedicineType::EYE_DROPS;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->medicineType($this->medicineType);
|
||||
$w->enum($this->medicineType);
|
||||
}
|
||||
|
||||
public function getType() : MedicineType{ return $this->medicineType; }
|
||||
|
@ -32,7 +32,7 @@ class Potion extends Item implements ConsumableItem{
|
||||
private PotionType $potionType = PotionType::WATER;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->potionType($this->potionType);
|
||||
$w->enum($this->potionType);
|
||||
}
|
||||
|
||||
public function getType() : PotionType{ return $this->potionType; }
|
||||
|
@ -34,7 +34,7 @@ class SplashPotion extends ProjectileItem{
|
||||
private PotionType $potionType = PotionType::WATER;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->potionType($this->potionType);
|
||||
$w->enum($this->potionType);
|
||||
}
|
||||
|
||||
public function getType() : PotionType{ return $this->potionType; }
|
||||
|
@ -30,7 +30,7 @@ class SuspiciousStew extends Food{
|
||||
private SuspiciousStewType $suspiciousStewType = SuspiciousStewType::POPPY;
|
||||
|
||||
protected function describeState(RuntimeDataDescriber $w) : void{
|
||||
$w->suspiciousStewType($this->suspiciousStewType);
|
||||
$w->enum($this->suspiciousStewType);
|
||||
}
|
||||
|
||||
public function getType() : SuspiciousStewType{ return $this->suspiciousStewType; }
|
||||
|
Loading…
x
Reference in New Issue
Block a user