mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-05-15 18:29:46 +00:00
Clean up some internal commands protocol handling
This commit is contained in:
parent
4364d2a942
commit
8afea36919
@ -668,30 +668,28 @@ class NetworkSession{
|
||||
continue;
|
||||
}
|
||||
|
||||
$data = new CommandData();
|
||||
//TODO: commands containing uppercase letters in the name crash 1.9.0 client
|
||||
$data->commandName = strtolower($command->getName());
|
||||
$data->commandDescription = $this->server->getLanguage()->translateString($command->getDescription());
|
||||
$data->flags = 0;
|
||||
$data->permission = 0;
|
||||
|
||||
$parameter = new CommandParameter();
|
||||
$parameter->paramName = "args";
|
||||
$parameter->paramType = AvailableCommandsPacket::ARG_FLAG_VALID | AvailableCommandsPacket::ARG_TYPE_RAWTEXT;
|
||||
$parameter->isOptional = true;
|
||||
$data->overloads[0][0] = $parameter;
|
||||
|
||||
$lname = strtolower($command->getName());
|
||||
$aliases = $command->getAliases();
|
||||
$aliasObj = null;
|
||||
if(!empty($aliases)){
|
||||
if(!in_array($data->commandName, $aliases, true)){
|
||||
if(!in_array($lname, $aliases, true)){
|
||||
//work around a client bug which makes the original name not show when aliases are used
|
||||
$aliases[] = $data->commandName;
|
||||
$aliases[] = $lname;
|
||||
}
|
||||
$data->aliases = new CommandEnum();
|
||||
$data->aliases->enumName = ucfirst($command->getName()) . "Aliases";
|
||||
$data->aliases->enumValues = $aliases;
|
||||
$aliasObj = new CommandEnum(ucfirst($command->getName()) . "Aliases", $aliases);
|
||||
}
|
||||
|
||||
$data = new CommandData(
|
||||
$lname, //TODO: commands containing uppercase letters in the name crash 1.9.0 client
|
||||
$this->server->getLanguage()->translateString($command->getDescription()),
|
||||
0,
|
||||
0,
|
||||
$aliasObj,
|
||||
[
|
||||
[CommandParameter::standard("args", AvailableCommandsPacket::ARG_TYPE_RAWTEXT, true)]
|
||||
]
|
||||
);
|
||||
|
||||
$pk->commandData[$command->getName()] = $data;
|
||||
}
|
||||
|
||||
|
@ -129,8 +129,8 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
* @throws BinaryDataException
|
||||
*/
|
||||
protected function getEnum(array $enumValueList) : CommandEnum{
|
||||
$retval = new CommandEnum();
|
||||
$retval->enumName = $this->getString();
|
||||
$enumName = $this->getString();
|
||||
$enumValues = [];
|
||||
|
||||
$listSize = count($enumValueList);
|
||||
|
||||
@ -140,10 +140,10 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
throw new BadPacketException("Invalid enum value index $index");
|
||||
}
|
||||
//Get the enum value from the initial pile of mess
|
||||
$retval->enumValues[] = $enumValueList[$index];
|
||||
$enumValues[] = $enumValueList[$index];
|
||||
}
|
||||
|
||||
return $retval;
|
||||
return new CommandEnum($enumName, $enumValues);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -151,15 +151,15 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
* @throws BinaryDataException
|
||||
*/
|
||||
protected function getSoftEnum() : CommandEnum{
|
||||
$retval = new CommandEnum();
|
||||
$retval->enumName = $this->getString();
|
||||
$enumName = $this->getString();
|
||||
$enumValues = [];
|
||||
|
||||
for($i = 0, $count = $this->getUnsignedVarInt(); $i < $count; ++$i){
|
||||
//Get the enum value from the initial pile of mess
|
||||
$retval->enumValues[] = $this->getString();
|
||||
$enumValues[] = $this->getString();
|
||||
}
|
||||
|
||||
return $retval;
|
||||
return new CommandEnum($enumName, $enumValues);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -167,11 +167,12 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
* @param string[] $enumValueMap
|
||||
*/
|
||||
protected function putEnum(CommandEnum $enum, array $enumValueMap) : void{
|
||||
$this->putString($enum->enumName);
|
||||
$this->putString($enum->getName());
|
||||
|
||||
$this->putUnsignedVarInt(count($enum->enumValues));
|
||||
$values = $enum->getValues();
|
||||
$this->putUnsignedVarInt(count($values));
|
||||
$listSize = count($enumValueMap);
|
||||
foreach($enum->enumValues as $value){
|
||||
foreach($values as $value){
|
||||
$index = $enumValueMap[$value] ?? -1;
|
||||
if($index === -1){
|
||||
throw new \InvalidStateException("Enum value '$value' not found");
|
||||
@ -181,10 +182,11 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
}
|
||||
|
||||
protected function putSoftEnum(CommandEnum $enum) : void{
|
||||
$this->putString($enum->enumName);
|
||||
$this->putString($enum->getName());
|
||||
|
||||
$this->putUnsignedVarInt(count($enum->enumValues));
|
||||
foreach($enum->enumValues as $value){
|
||||
$values = $enum->getValues();
|
||||
$this->putUnsignedVarInt(count($values));
|
||||
foreach($values as $value){
|
||||
$this->putString($value);
|
||||
}
|
||||
}
|
||||
@ -224,12 +226,12 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
* @throws BinaryDataException
|
||||
*/
|
||||
protected function getCommandData(array $enums, array $postfixes) : CommandData{
|
||||
$retval = new CommandData();
|
||||
$retval->commandName = $this->getString();
|
||||
$retval->commandDescription = $this->getString();
|
||||
$retval->flags = $this->getByte();
|
||||
$retval->permission = $this->getByte();
|
||||
$retval->aliases = $enums[$this->getLInt()] ?? null;
|
||||
$name = $this->getString();
|
||||
$description = $this->getString();
|
||||
$flags = $this->getByte();
|
||||
$permission = $this->getByte();
|
||||
$aliases = $enums[$this->getLInt()] ?? null;
|
||||
$overloads = [];
|
||||
|
||||
for($overloadIndex = 0, $overloadCount = $this->getUnsignedVarInt(); $overloadIndex < $overloadCount; ++$overloadIndex){
|
||||
for($paramIndex = 0, $paramCount = $this->getUnsignedVarInt(); $paramIndex < $paramCount; ++$paramIndex){
|
||||
@ -243,23 +245,23 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
$index = ($parameter->paramType & 0xffff);
|
||||
$parameter->enum = $enums[$index] ?? null;
|
||||
if($parameter->enum === null){
|
||||
throw new BadPacketException("deserializing $retval->commandName parameter $parameter->paramName: expected enum at $index, but got none");
|
||||
throw new BadPacketException("deserializing $name parameter $parameter->paramName: expected enum at $index, but got none");
|
||||
}
|
||||
}elseif($parameter->paramType & self::ARG_FLAG_POSTFIX){
|
||||
$index = ($parameter->paramType & 0xffff);
|
||||
$parameter->postfix = $postfixes[$index] ?? null;
|
||||
if($parameter->postfix === null){
|
||||
throw new BadPacketException("deserializing $retval->commandName parameter $parameter->paramName: expected postfix at $index, but got none");
|
||||
throw new BadPacketException("deserializing $name parameter $parameter->paramName: expected postfix at $index, but got none");
|
||||
}
|
||||
}elseif(($parameter->paramType & self::ARG_FLAG_VALID) === 0){
|
||||
throw new BadPacketException("deserializing $retval->commandName parameter $parameter->paramName: Invalid parameter type 0x" . dechex($parameter->paramType));
|
||||
throw new BadPacketException("deserializing $name parameter $parameter->paramName: Invalid parameter type 0x" . dechex($parameter->paramType));
|
||||
}
|
||||
|
||||
$retval->overloads[$overloadIndex][$paramIndex] = $parameter;
|
||||
$overloads[$overloadIndex][$paramIndex] = $parameter;
|
||||
}
|
||||
}
|
||||
|
||||
return $retval;
|
||||
return new CommandData($name, $description, $flags, $permission, $aliases, $overloads);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -268,13 +270,13 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
* @param int[] $postfixIndexes
|
||||
*/
|
||||
protected function putCommandData(CommandData $data, array $enumIndexes, array $postfixIndexes) : void{
|
||||
$this->putString($data->commandName);
|
||||
$this->putString($data->commandDescription);
|
||||
$this->putString($data->name);
|
||||
$this->putString($data->description);
|
||||
$this->putByte($data->flags);
|
||||
$this->putByte($data->permission);
|
||||
|
||||
if($data->aliases !== null){
|
||||
$this->putLInt($enumIndexes[$data->aliases->enumName] ?? -1);
|
||||
$this->putLInt($enumIndexes[$data->aliases->getName()] ?? -1);
|
||||
}else{
|
||||
$this->putLInt(-1);
|
||||
}
|
||||
@ -287,7 +289,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
$this->putString($parameter->paramName);
|
||||
|
||||
if($parameter->enum !== null){
|
||||
$type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($enumIndexes[$parameter->enum->enumName] ?? -1);
|
||||
$type = self::ARG_FLAG_ENUM | self::ARG_FLAG_VALID | ($enumIndexes[$parameter->enum->getName()] ?? -1);
|
||||
}elseif($parameter->postfix !== null){
|
||||
$key = $postfixIndexes[$parameter->postfix] ?? -1;
|
||||
if($key === -1){
|
||||
@ -353,15 +355,18 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
$enumIndexes = [];
|
||||
/** @var CommandEnum[] $enums */
|
||||
$enums = [];
|
||||
|
||||
$addEnumFn = static function(CommandEnum $enum) use(&$enums, &$enumIndexes, &$enumValueIndexes){
|
||||
if(!isset($enumIndexes[$enum->getName()])){
|
||||
$enums[$enumIndexes[$enum->getName()] = count($enumIndexes)] = $enum;
|
||||
}
|
||||
foreach($enum->getValues() as $str){
|
||||
$enumValueIndexes[$str] = $enumValueIndexes[$str] ?? count($enumValueIndexes); //latest index
|
||||
}
|
||||
};
|
||||
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){
|
||||
@ -371,12 +376,7 @@ class AvailableCommandsPacket extends DataPacket implements ClientboundPacket{
|
||||
*/
|
||||
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){
|
||||
|
@ -25,9 +25,9 @@ namespace pocketmine\network\mcpe\protocol\types;
|
||||
|
||||
class CommandData{
|
||||
/** @var string */
|
||||
public $commandName;
|
||||
public $name;
|
||||
/** @var string */
|
||||
public $commandDescription;
|
||||
public $description;
|
||||
/** @var int */
|
||||
public $flags;
|
||||
/** @var int */
|
||||
@ -37,4 +37,67 @@ class CommandData{
|
||||
/** @var CommandParameter[][] */
|
||||
public $overloads = [];
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @param string $description
|
||||
* @param int $flags
|
||||
* @param int $permission
|
||||
* @param CommandEnum|null $aliases
|
||||
* @param CommandParameter[][] $overloads
|
||||
*/
|
||||
public function __construct(string $name, string $description, int $flags, int $permission, ?CommandEnum $aliases, array $overloads){
|
||||
(function(array ...$overloads){
|
||||
foreach($overloads as $overload){
|
||||
(function(CommandParameter ...$parameters){})(...$overload);
|
||||
}
|
||||
})(...$overloads);
|
||||
$this->name = $name;
|
||||
$this->description = $description;
|
||||
$this->flags = $flags;
|
||||
$this->permission = $permission;
|
||||
$this->aliases = $aliases;
|
||||
$this->overloads = $overloads;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() : string{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription() : string{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getFlags() : int{
|
||||
return $this->flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getPermission() : int{
|
||||
return $this->permission;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CommandEnum|null
|
||||
*/
|
||||
public function getAliases() : ?CommandEnum{
|
||||
return $this->aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CommandParameter[][]
|
||||
*/
|
||||
public function getOverloads() : array{
|
||||
return $this->overloads;
|
||||
}
|
||||
}
|
||||
|
@ -25,8 +25,30 @@ namespace pocketmine\network\mcpe\protocol\types;
|
||||
|
||||
class CommandEnum{
|
||||
/** @var string */
|
||||
public $enumName;
|
||||
private $enumName;
|
||||
/** @var string[] */
|
||||
public $enumValues = [];
|
||||
private $enumValues = [];
|
||||
|
||||
/**
|
||||
* @param string $enumName
|
||||
* @param string[] $enumValues
|
||||
*/
|
||||
public function __construct(string $enumName, array $enumValues){
|
||||
$this->enumName = $enumName;
|
||||
$this->enumValues = $enumValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName() : string{
|
||||
return $this->enumName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string[]
|
||||
*/
|
||||
public function getValues() : array{
|
||||
return $this->enumValues;
|
||||
}
|
||||
}
|
||||
|
@ -23,6 +23,8 @@ declare(strict_types=1);
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol\types;
|
||||
|
||||
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
|
||||
|
||||
class CommandParameter{
|
||||
/** @var string */
|
||||
public $paramName;
|
||||
@ -36,4 +38,29 @@ class CommandParameter{
|
||||
public $enum;
|
||||
/** @var string|null */
|
||||
public $postfix;
|
||||
|
||||
private static function baseline(string $name, int $type, bool $optional) : self{
|
||||
$result = new self;
|
||||
$result->paramName = $name;
|
||||
$result->paramType = $type;
|
||||
$result->isOptional = $optional;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function standard(string $name, int $type, bool $optional = false) : self{
|
||||
return self::baseline($name, AvailableCommandsPacket::ARG_FLAG_VALID | $type, $optional);
|
||||
}
|
||||
|
||||
public static function postfixed(string $name, string $postfix, bool $optional = false) : self{
|
||||
$result = self::baseline($name, AvailableCommandsPacket::ARG_FLAG_POSTFIX, $optional);
|
||||
$result->postfix = $postfix;
|
||||
return $result;
|
||||
}
|
||||
|
||||
public static function enum(string $name, CommandEnum $enum, int $flags, bool $optional = false) : self{
|
||||
$result = self::baseline($name, AvailableCommandsPacket::ARG_FLAG_ENUM | AvailableCommandsPacket::ARG_FLAG_VALID, $optional);
|
||||
$result->enum = $enum;
|
||||
$result->byte1 = $flags;
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user