mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-11 08:19:45 +00:00
Merge branch 'dktapps-drew-1.13' into stable
This commit is contained in:
commit
d155de35ed
@ -1 +1 @@
|
||||
Subproject commit 185d7419914005530298bd5e069449bdf4c0be56
|
||||
Subproject commit 83085714483a0cf3a13b4fa780bd14b153c5c36b
|
@ -28,6 +28,7 @@ namespace pocketmine\network\mcpe\protocol;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\protocol\types\CommandData;
|
||||
use pocketmine\network\mcpe\protocol\types\CommandEnum;
|
||||
use pocketmine\network\mcpe\protocol\types\CommandEnumConstraint;
|
||||
use pocketmine\network\mcpe\protocol\types\CommandParameter;
|
||||
use pocketmine\utils\BinaryDataException;
|
||||
use function count;
|
||||
@ -74,6 +75,10 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
*/
|
||||
public const ARG_FLAG_ENUM = 0x200000;
|
||||
|
||||
public const HARDCODED_ENUM_NAMES = [
|
||||
"CommandName" => true
|
||||
];
|
||||
|
||||
/**
|
||||
* This is used for /xp <level: int>L. It can only be applied to integer parameters.
|
||||
*/
|
||||
@ -85,6 +90,13 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
*/
|
||||
public $commandData = [];
|
||||
|
||||
/**
|
||||
* @var CommandEnum[]
|
||||
* List of enums which aren't directly referenced by any vanilla command.
|
||||
* This is used for the `CommandName` enum, which is a magic enum used by the `command` argument type.
|
||||
*/
|
||||
public $hardcodedEnums = [];
|
||||
|
||||
/**
|
||||
* @var CommandEnum[]
|
||||
* List of dynamic command enums, also referred to as "soft" enums. These can by dynamically updated mid-game
|
||||
@ -92,6 +104,12 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
*/
|
||||
public $softEnums = [];
|
||||
|
||||
/**
|
||||
* @var CommandEnumConstraint[]
|
||||
* List of constraints for enum members. Used to constrain gamerules that can bechanged in nocheats mode and more.
|
||||
*/
|
||||
public $enumConstraints = [];
|
||||
|
||||
protected function decodePayload(){
|
||||
/** @var string[] $enumValues */
|
||||
$enumValues = [];
|
||||
@ -108,7 +126,10 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
/** @var CommandEnum[] $enums */
|
||||
$enums = [];
|
||||
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
|
||||
$enums[] = $this->getEnum($enumValues);
|
||||
$enums[] = $enum = $this->getEnum($enumValues);
|
||||
if(isset(self::HARDCODED_ENUM_NAMES[$enum->enumName])){
|
||||
$this->hardcodedEnums[] = $enum;
|
||||
}
|
||||
}
|
||||
|
||||
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
|
||||
@ -118,6 +139,10 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
|
||||
$this->softEnums[] = $this->getSoftEnum();
|
||||
}
|
||||
|
||||
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
|
||||
$this->enumConstraints[] = $this->getEnumConstraint($enums, $enumValues);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -210,6 +235,50 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandEnum[] $enums
|
||||
* @param string[] $enumValues
|
||||
*
|
||||
* @return CommandEnumConstraint
|
||||
*/
|
||||
protected function getEnumConstraint(array $enums, array $enumValues) : CommandEnumConstraint{
|
||||
//wtf, what was wrong with an offset inside the enum? :(
|
||||
$valueIndex = $this->getLInt();
|
||||
if(!isset($enumValues[$valueIndex])){
|
||||
throw new \UnexpectedValueException("Enum constraint refers to unknown enum value index $valueIndex");
|
||||
}
|
||||
$enumIndex = $this->getLInt();
|
||||
if(!isset($enums[$enumIndex])){
|
||||
throw new \UnexpectedValueException("Enum constraint refers to unknown enum index $enumIndex");
|
||||
}
|
||||
$enum = $enums[$enumIndex];
|
||||
$valueOffset = array_search($enumValues[$valueIndex], $enum->enumValues, true);
|
||||
if($valueOffset === false){
|
||||
throw new \UnexpectedValueException("Value \"" . $enumValues[$valueIndex] . "\" does not belong to enum \"$enum->enumName\"");
|
||||
}
|
||||
|
||||
$constraintIds = [];
|
||||
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
|
||||
$constraintIds[] = $this->getByte();
|
||||
}
|
||||
|
||||
return new CommandEnumConstraint($enum, $valueOffset, $constraintIds);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandEnumConstraint $value
|
||||
* @param int[] $enumIndexes string enum name -> int index
|
||||
* @param int[] $enumValueIndexes string value -> int index
|
||||
*/
|
||||
protected function putEnumConstraint(CommandEnumConstraint $constraint, array $enumIndexes, array $enumValueIndexes) : void{
|
||||
$this->putLInt($enumValueIndexes[$constraint->getAffectedValue()]);
|
||||
$this->putLInt($enumIndexes[$constraint->getEnum()->enumName]);
|
||||
$this->putUnsignedVarInt(count($constraint->getConstraints()));
|
||||
foreach($constraint->getConstraints() as $v){
|
||||
$this->putByte($v);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CommandEnum[] $enums
|
||||
* @param string[] $postfixes
|
||||
@ -349,15 +418,21 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
$enumIndexes = [];
|
||||
/** @var CommandEnum[] $enums */
|
||||
$enums = [];
|
||||
|
||||
$addEnumFn = static function(CommandEnum $enum) use (&$enums, &$enumIndexes, &$enumValueIndexes){
|
||||
if(!isset($enumIndexes[$enum->enumName])){
|
||||
$enums[$enumIndexes[$enum->enumName] = count($enumIndexes)] = $enum;
|
||||
}
|
||||
foreach($enum->enumValues as $str){
|
||||
$enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes);
|
||||
}
|
||||
};
|
||||
foreach($this->hardcodedEnums as $enum){
|
||||
$addEnumFn($enum);
|
||||
}
|
||||
foreach($this->commandData as $commandData){
|
||||
if($commandData->aliases !== null){
|
||||
if(!isset($enumIndexes[$commandData->aliases->enumName])){
|
||||
$enums[$enumIndexes[$commandData->aliases->enumName] = count($enumIndexes)] = $commandData->aliases;
|
||||
}
|
||||
|
||||
foreach($commandData->aliases->enumValues as $str){
|
||||
$enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); //latest index
|
||||
}
|
||||
$addEnumFn($commandData->aliases);
|
||||
}
|
||||
|
||||
foreach($commandData->overloads as $overload){
|
||||
@ -367,12 +442,7 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
*/
|
||||
foreach($overload as $parameter){
|
||||
if($parameter->enum !== null){
|
||||
if(!isset($enumIndexes[$parameter->enum->enumName])){
|
||||
$enums[$enumIndexes[$parameter->enum->enumName] = count($enumIndexes)] = $parameter->enum;
|
||||
}
|
||||
foreach($parameter->enum->enumValues as $str){
|
||||
$enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes);
|
||||
}
|
||||
$addEnumFn($parameter->enum);
|
||||
}
|
||||
|
||||
if($parameter->postfix !== null){
|
||||
@ -407,7 +477,10 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
$this->putSoftEnum($enum);
|
||||
}
|
||||
|
||||
$this->putUnsignedVarInt(0); //TODO
|
||||
$this->putUnsignedVarInt(count($this->enumConstraints));
|
||||
foreach($this->enumConstraints as $constraint){
|
||||
$this->putEnumConstraint($constraint, $enumIndexes, $enumValueIndexes);
|
||||
}
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
|
@ -33,6 +33,8 @@ use pocketmine\item\Item;
|
||||
use pocketmine\item\ItemFactory;
|
||||
use pocketmine\network\mcpe\NetworkBinaryStream;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\network\mcpe\protocol\types\PotionContainerChangeRecipe;
|
||||
use pocketmine\network\mcpe\protocol\types\PotionTypeRecipe;
|
||||
#ifndef COMPILE
|
||||
use pocketmine\utils\Binary;
|
||||
#endif
|
||||
@ -53,6 +55,10 @@ class CraftingDataPacket extends DataPacket{
|
||||
|
||||
/** @var object[] */
|
||||
public $entries = [];
|
||||
/** @var PotionTypeRecipe[] */
|
||||
public $potionTypeRecipes = [];
|
||||
/** @var PotionContainerChangeRecipe[] */
|
||||
public $potionContainerRecipes = [];
|
||||
/** @var bool */
|
||||
public $cleanRecipes = false;
|
||||
|
||||
@ -140,6 +146,18 @@ class CraftingDataPacket extends DataPacket{
|
||||
}
|
||||
$this->decodedEntries[] = $entry;
|
||||
}
|
||||
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
|
||||
$input = $this->getVarInt();
|
||||
$ingredient = $this->getVarInt();
|
||||
$output = $this->getVarInt();
|
||||
$this->potionTypeRecipes[] = new PotionTypeRecipe($input, $ingredient, $output);
|
||||
}
|
||||
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
|
||||
$input = $this->getVarInt();
|
||||
$ingredient = $this->getVarInt();
|
||||
$output = $this->getVarInt();
|
||||
$this->potionContainerRecipes[] = new PotionContainerChangeRecipe($input, $ingredient, $output);
|
||||
}
|
||||
$this->cleanRecipes = $this->getBool();
|
||||
}
|
||||
|
||||
@ -240,6 +258,18 @@ class CraftingDataPacket extends DataPacket{
|
||||
|
||||
$writer->reset();
|
||||
}
|
||||
$this->putUnsignedVarInt(count($this->potionTypeRecipes));
|
||||
foreach($this->potionTypeRecipes as $recipe){
|
||||
$this->putVarInt($recipe->getInputPotionType());
|
||||
$this->putVarInt($recipe->getIngredientItemId());
|
||||
$this->putVarInt($recipe->getOutputPotionType());
|
||||
}
|
||||
$this->putUnsignedVarInt(count($this->potionContainerRecipes));
|
||||
foreach($this->potionContainerRecipes as $recipe){
|
||||
$this->putVarInt($recipe->getInputItemId());
|
||||
$this->putVarInt($recipe->getIngredientItemId());
|
||||
$this->putVarInt($recipe->getOutputItemId());
|
||||
}
|
||||
|
||||
$this->putBool($this->cleanRecipes);
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ class MoveActorDeltaPacket extends DataPacket{
|
||||
|
||||
protected function decodePayload(){
|
||||
$this->entityRuntimeId = $this->getEntityRuntimeId();
|
||||
$this->flags = $this->getByte();
|
||||
$this->flags = $this->getLShort();
|
||||
$this->xDiff = $this->maybeReadCoord(self::FLAG_HAS_X);
|
||||
$this->yDiff = $this->maybeReadCoord(self::FLAG_HAS_Y);
|
||||
$this->zDiff = $this->maybeReadCoord(self::FLAG_HAS_Z);
|
||||
@ -93,7 +93,7 @@ class MoveActorDeltaPacket extends DataPacket{
|
||||
|
||||
protected function encodePayload(){
|
||||
$this->putEntityRuntimeId($this->entityRuntimeId);
|
||||
$this->putByte($this->flags);
|
||||
$this->putLShort($this->flags);
|
||||
$this->maybeWriteCoord(self::FLAG_HAS_X, $this->xDiff);
|
||||
$this->maybeWriteCoord(self::FLAG_HAS_Y, $this->yDiff);
|
||||
$this->maybeWriteCoord(self::FLAG_HAS_Z, $this->zDiff);
|
||||
|
@ -0,0 +1,67 @@
|
||||
<?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;
|
||||
|
||||
class CommandEnumConstraint{
|
||||
/** @var CommandEnum */
|
||||
private $enum;
|
||||
/** @var int */
|
||||
private $valueOffset;
|
||||
/** @var int[] */
|
||||
private $constraints; //TODO: find constants
|
||||
|
||||
/**
|
||||
* @param CommandEnum $enum
|
||||
* @param int $valueOffset
|
||||
* @param int[] $constraints
|
||||
*/
|
||||
public function __construct(CommandEnum $enum, int $valueOffset, array $constraints){
|
||||
(static function(int ...$_){})(...$constraints);
|
||||
if(!isset($enum->enumValues[$valueOffset])){
|
||||
throw new \InvalidArgumentException("Invalid enum value offset $valueOffset");
|
||||
}
|
||||
$this->enum = $enum;
|
||||
$this->valueOffset = $valueOffset;
|
||||
$this->constraints = $constraints;
|
||||
}
|
||||
|
||||
public function getEnum() : CommandEnum{
|
||||
return $this->enum;
|
||||
}
|
||||
|
||||
public function getValueOffset() : int{
|
||||
return $this->valueOffset;
|
||||
}
|
||||
|
||||
public function getAffectedValue() : string{
|
||||
return $this->enum->enumValues[$this->valueOffset];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int[]
|
||||
*/
|
||||
public function getConstraints() : array{
|
||||
return $this->constraints;
|
||||
}
|
||||
}
|
@ -24,6 +24,9 @@ declare(strict_types=1);
|
||||
namespace pocketmine\network\mcpe\protocol\types;
|
||||
|
||||
class CommandParameter{
|
||||
public const FLAG_FORCE_COLLAPSE_ENUM = 0x1;
|
||||
public const FLAG_HAS_ENUM_CONSTRAINT = 0x2;
|
||||
|
||||
/** @var string */
|
||||
public $paramName;
|
||||
/** @var int */
|
||||
|
@ -0,0 +1,51 @@
|
||||
<?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;
|
||||
|
||||
class PotionContainerChangeRecipe{
|
||||
/** @var int */
|
||||
private $inputItemId;
|
||||
/** @var int */
|
||||
private $ingredientItemId;
|
||||
/** @var int */
|
||||
private $outputItemId;
|
||||
|
||||
public function __construct(int $inputItemId, int $ingredientItemId, int $outputItemId){
|
||||
$this->inputItemId = $inputItemId;
|
||||
$this->ingredientItemId = $ingredientItemId;
|
||||
$this->outputItemId = $outputItemId;
|
||||
}
|
||||
|
||||
public function getInputItemId() : int{
|
||||
return $this->inputItemId;
|
||||
}
|
||||
|
||||
public function getIngredientItemId() : int{
|
||||
return $this->ingredientItemId;
|
||||
}
|
||||
|
||||
public function getOutputItemId() : int{
|
||||
return $this->outputItemId;
|
||||
}
|
||||
}
|
@ -0,0 +1,51 @@
|
||||
<?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;
|
||||
|
||||
class PotionTypeRecipe{
|
||||
/** @var int */
|
||||
private $inputPotionType;
|
||||
/** @var int */
|
||||
private $ingredientItemId;
|
||||
/** @var int */
|
||||
private $outputPotionType;
|
||||
|
||||
public function __construct(int $inputPotionType, int $ingredientItemId, int $outputPotionType){
|
||||
$this->inputPotionType = $inputPotionType;
|
||||
$this->ingredientItemId = $ingredientItemId;
|
||||
$this->outputPotionType = $outputPotionType;
|
||||
}
|
||||
|
||||
public function getInputPotionType() : int{
|
||||
return $this->inputPotionType;
|
||||
}
|
||||
|
||||
public function getIngredientItemId() : int{
|
||||
return $this->ingredientItemId;
|
||||
}
|
||||
|
||||
public function getOutputPotionType() : int{
|
||||
return $this->outputPotionType;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user