PocketMine-MP 5.35.1 git-e32e836dad793a3a3c8ddd8927c00e112b1e576a
Loading...
Searching...
No Matches
AbilitiesLayer.php
1<?php
2
3/*
4 * This file is part of BedrockProtocol.
5 * Copyright (C) 2014-2022 PocketMine Team <https://github.com/pmmp/BedrockProtocol>
6 *
7 * BedrockProtocol is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 */
12
13declare(strict_types=1);
14
15namespace pocketmine\network\mcpe\protocol\types;
16
17use pmmp\encoding\ByteBufferReader;
18use pmmp\encoding\ByteBufferWriter;
19use pmmp\encoding\LE;
21
22final class AbilitiesLayer{
23
24 public const LAYER_CACHE = 0;
25 public const LAYER_BASE = 1;
26 public const LAYER_SPECTATOR = 2;
27 public const LAYER_COMMANDS = 3;
28 public const LAYER_EDITOR = 4;
29 public const LAYER_LOADING_SCREEN = 5;
30
31 public const ABILITY_BUILD = 0;
32 public const ABILITY_MINE = 1;
33 public const ABILITY_DOORS_AND_SWITCHES = 2; //disabling this also disables dropping items (???)
34 public const ABILITY_OPEN_CONTAINERS = 3;
35 public const ABILITY_ATTACK_PLAYERS = 4;
36 public const ABILITY_ATTACK_MOBS = 5;
37 public const ABILITY_OPERATOR = 6;
38 public const ABILITY_TELEPORT = 7;
39 public const ABILITY_INVULNERABLE = 8;
40 public const ABILITY_FLYING = 9;
41 public const ABILITY_ALLOW_FLIGHT = 10;
42 public const ABILITY_INFINITE_RESOURCES = 11; //in vanilla they call this "instabuild", which is a bad name
43 public const ABILITY_LIGHTNING = 12; //???
44 private const ABILITY_FLY_SPEED = 13;
45 private const ABILITY_WALK_SPEED = 14;
46 public const ABILITY_MUTED = 15;
47 public const ABILITY_WORLD_BUILDER = 16;
48 public const ABILITY_NO_CLIP = 17;
49 public const ABILITY_PRIVILEGED_BUILDER = 18;
50 public const ABILITY_VERTICAL_FLY_SPEED = 19;
51
52 public const NUMBER_OF_ABILITIES = 20;
53
58 public function __construct(
59 private int $layerId,
60 private array $boolAbilities,
61 private ?float $flySpeed,
62 private ?float $verticalFlySpeed,
63 private ?float $walkSpeed
64 ){}
65
66 public function getLayerId() : int{ return $this->layerId; }
67
73 public function getBoolAbilities() : array{ return $this->boolAbilities; }
74
75 public function getFlySpeed() : ?float{ return $this->flySpeed; }
76
77 public function getVerticalFlySpeed() : ?float{ return $this->verticalFlySpeed; }
78
79 public function getWalkSpeed() : ?float{ return $this->walkSpeed; }
80
81 public static function decode(ByteBufferReader $in) : self{
82 $layerId = LE::readUnsignedShort($in);
83 $setAbilities = LE::readUnsignedInt($in);
84 $setAbilityValues = LE::readUnsignedInt($in);
85 $flySpeed = LE::readFloat($in);
86 $verticalFlySpeed = LE::readFloat($in);
87 $walkSpeed = LE::readFloat($in);
88
89 $boolAbilities = [];
90 for($i = 0; $i < self::NUMBER_OF_ABILITIES; $i++){
91 if($i === self::ABILITY_FLY_SPEED || $i === self::ABILITY_WALK_SPEED){
92 continue;
93 }
94 if(($setAbilities & (1 << $i)) !== 0){
95 $boolAbilities[$i] = ($setAbilityValues & (1 << $i)) !== 0;
96 }
97 }
98 if(($setAbilities & (1 << self::ABILITY_FLY_SPEED)) === 0){
99 if($flySpeed !== 0.0){
100 throw new PacketDecodeException("Fly speed should be zero if the layer does not set it");
101 }
102 $flySpeed = null;
103 }
104 if(($setAbilities & (1 << self::ABILITY_VERTICAL_FLY_SPEED)) === 0){
105 if($verticalFlySpeed !== 0.0){
106 throw new PacketDecodeException("Vertical fly speed should be zero if the layer does not set it");
107 }
108 $verticalFlySpeed = null;
109 }
110 if(($setAbilities & (1 << self::ABILITY_WALK_SPEED)) === 0){
111 if($walkSpeed !== 0.0){
112 throw new PacketDecodeException("Walk speed should be zero if the layer does not set it");
113 }
114 $walkSpeed = null;
115 }
116
117 return new self($layerId, $boolAbilities, $flySpeed, $verticalFlySpeed, $walkSpeed);
118 }
119
120 public function encode(ByteBufferWriter $out) : void{
121 LE::writeUnsignedShort($out, $this->layerId);
122
123 $setAbilities = 0;
124 $setAbilityValues = 0;
125 foreach($this->boolAbilities as $ability => $value){
126 $setAbilities |= (1 << $ability);
127 $setAbilityValues |= ($value ? 1 << $ability : 0);
128 }
129 if($this->flySpeed !== null){
130 $setAbilities |= (1 << self::ABILITY_FLY_SPEED);
131 }
132 if($this->verticalFlySpeed !== null){
133 $setAbilities |= (1 << self::ABILITY_VERTICAL_FLY_SPEED);
134 }
135 if($this->walkSpeed !== null){
136 $setAbilities |= (1 << self::ABILITY_WALK_SPEED);
137 }
138
139 LE::writeUnsignedInt($out, $setAbilities);
140 LE::writeUnsignedInt($out, $setAbilityValues);
141 LE::writeFloat($out, $this->flySpeed ?? 0);
142 LE::writeFloat($out, $this->verticalFlySpeed ?? 0);
143 LE::writeFloat($out, $this->walkSpeed ?? 0);
144 }
145}
__construct(private int $layerId, private array $boolAbilities, private ?float $flySpeed, private ?float $verticalFlySpeed, private ?float $walkSpeed)