mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-07-22 19:06:35 +00:00
Merge network current changes - checkpointing
This is stable enough for everyone to be using it in production, and we're about 200 commits up from the previous tag. This branch contains hundreds of bug fixes, regardless of other changes which are not yet finished.
This commit is contained in:
commit
c6229b1e52
1
.gitignore
vendored
1
.gitignore
vendored
@ -9,6 +9,7 @@ timings/*
|
||||
server.properties
|
||||
/pocketmine.yml
|
||||
memoryDump_*/*
|
||||
resource_packs/
|
||||
|
||||
# Common IDEs
|
||||
.idea/
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
namespace pocketmine;
|
||||
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\plugin\PluginBase;
|
||||
use pocketmine\plugin\PluginLoadOrder;
|
||||
use pocketmine\utils\Utils;
|
||||
@ -226,7 +226,7 @@ class CrashDump{
|
||||
$this->data["general"] = [];
|
||||
$this->data["general"]["version"] = $version->get(false);
|
||||
$this->data["general"]["build"] = $version->getBuild();
|
||||
$this->data["general"]["protocol"] = Info::CURRENT_PROTOCOL;
|
||||
$this->data["general"]["protocol"] = ProtocolInfo::CURRENT_PROTOCOL;
|
||||
$this->data["general"]["api"] = \pocketmine\API_VERSION;
|
||||
$this->data["general"]["git"] = \pocketmine\GIT_COMMIT;
|
||||
$this->data["general"]["raklib"] = RakLib::VERSION;
|
||||
@ -235,7 +235,7 @@ class CrashDump{
|
||||
$this->data["general"]["zend"] = zend_version();
|
||||
$this->data["general"]["php_os"] = PHP_OS;
|
||||
$this->data["general"]["os"] = Utils::getOS();
|
||||
$this->addLine("PocketMine-MP version: " . $version->get(false) . " #" . $version->getBuild() . " [Protocol " . Info::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
||||
$this->addLine("PocketMine-MP version: " . $version->get(false) . " #" . $version->getBuild() . " [Protocol " . ProtocolInfo::CURRENT_PROTOCOL . "; API " . API_VERSION . "]");
|
||||
$this->addLine("Git commit: " . GIT_COMMIT);
|
||||
$this->addLine("uname -a: " . php_uname("a"));
|
||||
$this->addLine("PHP Version: " . phpversion());
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -74,7 +74,7 @@ namespace pocketmine {
|
||||
use raklib\RakLib;
|
||||
|
||||
const VERSION = "1.6.2dev";
|
||||
const API_VERSION = "3.0.0-ALPHA4";
|
||||
const API_VERSION = "3.0.0-ALPHA5";
|
||||
const CODENAME = "Unleashed";
|
||||
|
||||
/*
|
||||
@ -397,11 +397,6 @@ namespace pocketmine {
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("sockets")){
|
||||
$logger->critical("Unable to find the Socket extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
$pthreads_version = phpversion("pthreads");
|
||||
if(substr_count($pthreads_version, ".") < 2){
|
||||
$pthreads_version = "0.$pthreads_version";
|
||||
@ -430,19 +425,21 @@ namespace pocketmine {
|
||||
");
|
||||
}
|
||||
|
||||
if(!extension_loaded("curl")){
|
||||
$logger->critical("Unable to find the cURL extension.");
|
||||
++$errors;
|
||||
}
|
||||
$extensions = [
|
||||
"curl" => "cURL",
|
||||
"json" => "JSON",
|
||||
"mbstring" => "Multibyte String",
|
||||
"yaml" => "YAML",
|
||||
"sockets" => "Sockets",
|
||||
"zip" => "Zip",
|
||||
"zlib" => "Zlib"
|
||||
];
|
||||
|
||||
if(!extension_loaded("yaml")){
|
||||
$logger->critical("Unable to find the YAML extension.");
|
||||
++$errors;
|
||||
}
|
||||
|
||||
if(!extension_loaded("zlib")){
|
||||
$logger->critical("Unable to find the Zlib extension.");
|
||||
++$errors;
|
||||
foreach($extensions as $ext => $name){
|
||||
if(!extension_loaded($ext)){
|
||||
$logger->critical("Unable to find the $name ($ext) extension.");
|
||||
++$errors;
|
||||
}
|
||||
}
|
||||
|
||||
if($errors > 0){
|
||||
@ -452,6 +449,10 @@ namespace pocketmine {
|
||||
exit(1); //Exit with error
|
||||
}
|
||||
|
||||
if(PHP_INT_SIZE < 8){
|
||||
$logger->warning("Running PocketMine-MP with 32-bit systems/PHP is deprecated. Support for 32-bit may be dropped in the future.");
|
||||
}
|
||||
|
||||
$gitHash = str_repeat("00", 20);
|
||||
if(file_exists(\pocketmine\PATH . ".git/HEAD")){ //Found Git information!
|
||||
$ref = trim(file_get_contents(\pocketmine\PATH . ".git/HEAD"));
|
||||
|
@ -48,8 +48,8 @@ use pocketmine\inventory\Recipe;
|
||||
use pocketmine\item\enchantment\Enchantment;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\lang\BaseLang;
|
||||
use pocketmine\level\format\io\LevelProviderManager;
|
||||
use pocketmine\level\format\io\leveldb\LevelDB;
|
||||
use pocketmine\level\format\io\LevelProviderManager;
|
||||
use pocketmine\level\format\io\region\Anvil;
|
||||
use pocketmine\level\format\io\region\McRegion;
|
||||
use pocketmine\level\format\io\region\PMAnvil;
|
||||
@ -74,13 +74,13 @@ use pocketmine\nbt\tag\LongTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\CompressBatchedTask;
|
||||
use pocketmine\network\mcpe\protocol\BatchPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
||||
use pocketmine\network\mcpe\RakLibInterface;
|
||||
use pocketmine\network\Network;
|
||||
use pocketmine\network\protocol\BatchPacket;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\protocol\Info as ProtocolInfo;
|
||||
use pocketmine\network\protocol\PlayerListPacket;
|
||||
use pocketmine\network\query\QueryHandler;
|
||||
use pocketmine\network\RakLibInterface;
|
||||
use pocketmine\network\rcon\RCON;
|
||||
use pocketmine\network\upnp\UPnP;
|
||||
use pocketmine\permission\BanList;
|
||||
@ -90,6 +90,7 @@ use pocketmine\plugin\Plugin;
|
||||
use pocketmine\plugin\PluginLoadOrder;
|
||||
use pocketmine\plugin\PluginManager;
|
||||
use pocketmine\plugin\ScriptPluginLoader;
|
||||
use pocketmine\resourcepacks\ResourcePackManager;
|
||||
use pocketmine\scheduler\FileWriteTask;
|
||||
use pocketmine\scheduler\SendUsageTask;
|
||||
use pocketmine\scheduler\ServerScheduler;
|
||||
@ -179,6 +180,9 @@ class Server{
|
||||
/** @var CraftingManager */
|
||||
private $craftingManager;
|
||||
|
||||
/** @var ResourcePackManager */
|
||||
private $resourceManager;
|
||||
|
||||
/** @var ConsoleCommandSender */
|
||||
private $consoleSender;
|
||||
|
||||
@ -597,6 +601,13 @@ class Server{
|
||||
return $this->craftingManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ResourcePackManager
|
||||
*/
|
||||
public function getResourceManager() : ResourcePackManager{
|
||||
return $this->resourceManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ServerScheduler
|
||||
*/
|
||||
@ -690,7 +701,7 @@ class Server{
|
||||
*
|
||||
* @return CompoundTag
|
||||
*/
|
||||
public function getOfflinePlayerData($name){
|
||||
public function getOfflinePlayerData($name) : CompoundTag{
|
||||
$name = strtolower($name);
|
||||
$path = $this->getDataPath() . "players/";
|
||||
if($this->shouldSavePlayerData()){
|
||||
@ -809,7 +820,7 @@ class Server{
|
||||
public function getPlayerExact($name){
|
||||
$name = strtolower($name);
|
||||
foreach($this->getOnlinePlayers() as $player){
|
||||
if(strtolower($player->getName()) === $name){
|
||||
if($player->getLowerCaseName() === $name){
|
||||
return $player;
|
||||
}
|
||||
}
|
||||
@ -826,7 +837,7 @@ class Server{
|
||||
$partialName = strtolower($partialName);
|
||||
$matchedPlayers = [];
|
||||
foreach($this->getOnlinePlayers() as $player){
|
||||
if(strtolower($player->getName()) === $partialName){
|
||||
if($player->getLowerCaseName() === $partialName){
|
||||
$matchedPlayers = [$player];
|
||||
break;
|
||||
}elseif(stripos($player->getName(), $partialName) !== false){
|
||||
@ -1540,6 +1551,8 @@ class Server{
|
||||
Attribute::init();
|
||||
$this->craftingManager = new CraftingManager();
|
||||
|
||||
$this->resourceManager = new ResourcePackManager($this, $this->getDataPath() . "resource_packs" . DIRECTORY_SEPARATOR);
|
||||
|
||||
$this->pluginManager = new PluginManager($this, $this->commandMap);
|
||||
$this->pluginManager->subscribeToPermission(Server::BROADCAST_CHANNEL_ADMINISTRATIVE, $this->consoleSender);
|
||||
$this->pluginManager->setUseTimings($this->getProperty("settings.enable-profiling", false));
|
||||
@ -2196,7 +2209,7 @@ class Server{
|
||||
foreach($this->players as $p){
|
||||
if(!$p->loggedIn and ($tickTime - $p->creationTime) >= 10){
|
||||
$p->close("", "Login timeout");
|
||||
}elseif($this->alwaysTickPlayers){
|
||||
}elseif($this->alwaysTickPlayers and $p->joined){
|
||||
$p->onUpdate($currentTick);
|
||||
}
|
||||
}
|
||||
@ -2241,7 +2254,7 @@ class Server{
|
||||
if($this->getAutoSave()){
|
||||
Timings::$worldSaveTimer->startTiming();
|
||||
foreach($this->players as $index => $player){
|
||||
if($player->isOnline()){
|
||||
if($player->joined){
|
||||
$player->save(true);
|
||||
}elseif(!$player->isConnected()){
|
||||
$this->removePlayer($player);
|
||||
|
@ -29,4 +29,8 @@ class Furnace extends BurningFurnace{
|
||||
public function getName(){
|
||||
return "Furnace";
|
||||
}
|
||||
|
||||
public function getLightLevel(){
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -24,7 +24,7 @@ namespace pocketmine\command\defaults;
|
||||
use pocketmine\command\Command;
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\network\protocol\SetDifficultyPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetDifficultyPacket;
|
||||
use pocketmine\Server;
|
||||
|
||||
class DifficultyCommand extends VanillaCommand{
|
||||
|
@ -23,7 +23,6 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\entity\Effect;
|
||||
use pocketmine\entity\InstantEffect;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
@ -80,12 +79,9 @@ class EffectCommand extends VanillaCommand{
|
||||
$amplification = 0;
|
||||
|
||||
if(count($args) >= 3){
|
||||
$duration = (int) $args[2];
|
||||
if(!($effect instanceof InstantEffect)){
|
||||
$duration *= 20;
|
||||
}
|
||||
}elseif($effect instanceof InstantEffect){
|
||||
$duration = 1;
|
||||
$duration = ((int) $args[2]) * 20; //ticks
|
||||
}else{
|
||||
$duration = $effect->getDefaultDuration();
|
||||
}
|
||||
|
||||
if(count($args) >= 4){
|
||||
|
@ -23,7 +23,7 @@ namespace pocketmine\command\defaults;
|
||||
|
||||
use pocketmine\command\CommandSender;
|
||||
use pocketmine\event\TranslationContainer;
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use pocketmine\utils\TextFormat;
|
||||
|
||||
@ -51,7 +51,7 @@ class VersionCommand extends VanillaCommand{
|
||||
$sender->getServer()->getCodename(),
|
||||
$sender->getServer()->getApiVersion(),
|
||||
$sender->getServer()->getVersion(),
|
||||
Info::CURRENT_PROTOCOL
|
||||
ProtocolInfo::CURRENT_PROTOCOL
|
||||
]));
|
||||
}else{
|
||||
$pluginName = implode(" ", $args);
|
||||
|
@ -24,7 +24,7 @@ namespace pocketmine\entity;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\particle\CriticalParticle;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Arrow extends Projectile{
|
||||
|
@ -165,6 +165,10 @@ class Attribute{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function resetToDefault(){
|
||||
$this->setValue($this->getDefaultValue());
|
||||
}
|
||||
|
||||
public function getValue(){
|
||||
return $this->currentValue;
|
||||
}
|
||||
|
@ -38,6 +38,9 @@ class AttributeMap implements \ArrayAccess{
|
||||
return $this->attributes[$id] ?? null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Attribute[]
|
||||
*/
|
||||
public function getAll(): array{
|
||||
return $this->attributes;
|
||||
}
|
||||
|
@ -26,22 +26,20 @@ use pocketmine\event\entity\EntityEffectAddEvent;
|
||||
use pocketmine\event\entity\EntityEffectRemoveEvent;
|
||||
use pocketmine\event\entity\EntityRegainHealthEvent;
|
||||
use pocketmine\event\player\PlayerExhaustEvent;
|
||||
use pocketmine\network\protocol\MobEffectPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEffectPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\Config;
|
||||
|
||||
class Effect{
|
||||
const SPEED = 1;
|
||||
const SLOWNESS = 2;
|
||||
const HASTE = 3;
|
||||
const SWIFTNESS = 3;
|
||||
const FATIGUE = 4;
|
||||
const MINING_FATIGUE = 4;
|
||||
const FATIGUE = 4, MINING_FATIGUE = 4;
|
||||
const STRENGTH = 5;
|
||||
// TODO: const HEALING = 6;
|
||||
// TODO: const HARMING = 7;
|
||||
const INSTANT_HEALTH = 6, HEALING = 6;
|
||||
const INSTANT_DAMAGE = 7, HARMING = 7;
|
||||
const JUMP = 8;
|
||||
const NAUSEA = 9;
|
||||
const CONFUSION = 9;
|
||||
const NAUSEA = 9, CONFUSION = 9;
|
||||
const REGENERATION = 10;
|
||||
const DAMAGE_RESISTANCE = 11;
|
||||
const FIRE_RESISTANCE = 12;
|
||||
@ -54,44 +52,43 @@ class Effect{
|
||||
const POISON = 19;
|
||||
const WITHER = 20;
|
||||
const HEALTH_BOOST = 21;
|
||||
const ABSORPTION = 22; // TODO implement
|
||||
const ABSORPTION = 22;
|
||||
const SATURATION = 23;
|
||||
const LEVITATION = 24; //TODO
|
||||
|
||||
/** @var Effect[] */
|
||||
protected static $effects;
|
||||
protected static $effects = [];
|
||||
|
||||
public static function init(){
|
||||
self::$effects = new \SplFixedArray(256);
|
||||
$config = new Config(\pocketmine\PATH . "src/pocketmine/resources/effects.json", Config::JSON, []);
|
||||
|
||||
self::$effects[Effect::SPEED] = new Effect(Effect::SPEED, "%potion.moveSpeed", 124, 175, 198);
|
||||
self::$effects[Effect::SLOWNESS] = new Effect(Effect::SLOWNESS, "%potion.moveSlowdown", 90, 108, 129, true);
|
||||
self::$effects[Effect::SWIFTNESS] = new Effect(Effect::SWIFTNESS, "%potion.digSpeed", 217, 192, 67);
|
||||
self::$effects[Effect::FATIGUE] = new Effect(Effect::FATIGUE, "%potion.digSlowDown", 74, 66, 23, true);
|
||||
self::$effects[Effect::STRENGTH] = new Effect(Effect::STRENGTH, "%potion.damageBoost", 147, 36, 35);
|
||||
//self::$effects[Effect::HEALING] = new InstantEffect(Effect::HEALING, "%potion.heal", 248, 36, 35);
|
||||
//self::$effects[Effect::HARMING] = new InstantEffect(Effect::HARMING, "%potion.harm", 67, 10, 9, true);
|
||||
self::$effects[Effect::JUMP] = new Effect(Effect::JUMP, "%potion.jump", 34, 255, 76);
|
||||
self::$effects[Effect::NAUSEA] = new Effect(Effect::NAUSEA, "%potion.confusion", 85, 29, 74, true);
|
||||
self::$effects[Effect::REGENERATION] = new Effect(Effect::REGENERATION, "%potion.regeneration", 205, 92, 171);
|
||||
self::$effects[Effect::DAMAGE_RESISTANCE] = new Effect(Effect::DAMAGE_RESISTANCE, "%potion.resistance", 153, 69, 58);
|
||||
self::$effects[Effect::FIRE_RESISTANCE] = new Effect(Effect::FIRE_RESISTANCE, "%potion.fireResistance", 228, 154, 58);
|
||||
self::$effects[Effect::WATER_BREATHING] = new Effect(Effect::WATER_BREATHING, "%potion.waterBreathing", 46, 82, 153);
|
||||
self::$effects[Effect::INVISIBILITY] = new Effect(Effect::INVISIBILITY, "%potion.invisibility", 127, 131, 146);
|
||||
self::$effects[Effect::BLINDNESS] = new Effect(Effect::BLINDNESS, "%potion.blindness", 191, 192, 192);
|
||||
self::$effects[Effect::NIGHT_VISION] = new Effect(Effect::NIGHT_VISION, "%potion.nightVision", 0, 0, 139);
|
||||
self::$effects[Effect::HUNGER] = new Effect(Effect::HUNGER, "%potion.hunger", 46, 139, 87);
|
||||
self::$effects[Effect::WEAKNESS] = new Effect(Effect::WEAKNESS, "%potion.weakness", 72, 77, 72, true);
|
||||
self::$effects[Effect::POISON] = new Effect(Effect::POISON, "%potion.poison", 78, 147, 49, true);
|
||||
self::$effects[Effect::WITHER] = new Effect(Effect::WITHER, "%potion.wither", 53, 42, 39, true);
|
||||
self::$effects[Effect::HEALTH_BOOST] = new Effect(Effect::HEALTH_BOOST, "%potion.healthBoost", 248, 125, 35);
|
||||
self::$effects[Effect::ABSORPTION] = new Effect(Effect::ABSORPTION, "%potion.absorption", 36, 107, 251);
|
||||
self::$effects[Effect::SATURATION] = new Effect(Effect::SATURATION, "%potion.saturation", 255, 0, 255);
|
||||
foreach($config->getAll() as $name => $data){
|
||||
$color = hexdec($data["color"]);
|
||||
$r = ($color >> 16) & 0xff;
|
||||
$g = ($color >> 8) & 0xff;
|
||||
$b = $color & 0xff;
|
||||
self::registerEffect($name, new Effect(
|
||||
$data["id"],
|
||||
"%" . $data["name"],
|
||||
$r,
|
||||
$g,
|
||||
$b,
|
||||
$data["isBad"] ?? false,
|
||||
$data["default_duration"] ?? 300 * 20,
|
||||
$data["has_bubbles"] ?? true
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
public static function registerEffect(string $internalName, Effect $effect){
|
||||
self::$effects[$effect->getId()] = $effect;
|
||||
self::$effects[$internalName] = $effect;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return $this
|
||||
* @return Effect|null
|
||||
*/
|
||||
public static function getEffect($id){
|
||||
if(isset(self::$effects[$id])){
|
||||
@ -100,9 +97,14 @@ class Effect{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
*
|
||||
* @return Effect|null
|
||||
*/
|
||||
public static function getEffectByName($name){
|
||||
if(defined(Effect::class . "::" . strtoupper($name))){
|
||||
return self::getEffect(constant(Effect::class . "::" . strtoupper($name)));
|
||||
if(isset(self::$effects[$name])){
|
||||
return clone self::$effects[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@ -124,40 +126,106 @@ class Effect{
|
||||
|
||||
protected $bad;
|
||||
|
||||
public function __construct($id, $name, $r, $g, $b, $isBad = false){
|
||||
protected $defaultDuration = 300 * 20;
|
||||
|
||||
protected $hasBubbles = true;
|
||||
|
||||
/**
|
||||
* @param int $id Effect ID as per Minecraft PE
|
||||
* @param string $name Translation key used for effect name
|
||||
* @param int $r 0-255, red balance of potion particle colour
|
||||
* @param int $g 0-255, green balance of potion particle colour
|
||||
* @param int $b 0-255, blue balance of potion particle colour
|
||||
* @param bool $isBad Whether the effect is harmful
|
||||
* @param int $defaultDuration Duration in ticks the effect will last for by default if applied without a duration.
|
||||
* @param bool $hasBubbles Whether the effect has potion bubbles. Some do not (e.g. Instant Damage has its own particles instead of bubbles)
|
||||
*/
|
||||
public function __construct($id, $name, $r, $g, $b, $isBad = false, int $defaultDuration = 300 * 20, bool $hasBubbles = true){
|
||||
$this->id = $id;
|
||||
$this->name = $name;
|
||||
$this->bad = (bool) $isBad;
|
||||
$this->setColor($r, $g, $b);
|
||||
$this->defaultDuration = $defaultDuration;
|
||||
$this->duration = $defaultDuration;
|
||||
$this->hasBubbles = $hasBubbles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translation key used to translate this effect's name.
|
||||
* @return string
|
||||
*/
|
||||
public function getName(){
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the effect ID as per Minecraft PE
|
||||
* @return int
|
||||
*/
|
||||
public function getId(){
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the duration in ticks of the effect.
|
||||
* @param $ticks
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setDuration($ticks){
|
||||
$this->duration = $ticks;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration remaining of the effect in ticks.
|
||||
* @return int
|
||||
*/
|
||||
public function getDuration(){
|
||||
return $this->duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default duration this effect will apply for if a duration is not specified.
|
||||
* @return int
|
||||
*/
|
||||
public function getDefaultDuration() : int{
|
||||
return $this->defaultDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this effect will give the subject potion bubbles.
|
||||
* @return bool
|
||||
*/
|
||||
public function hasBubbles() : bool{
|
||||
return $this->hasBubbles;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this effect will produce some visible effect, such as bubbles or particles.
|
||||
* NOTE: Do not confuse this with {@link Effect#hasBubbles}. For example, Instant Damage does not have bubbles, but still produces visible effects (particles).
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isVisible(){
|
||||
return $this->show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the visibility of the effect.
|
||||
* @param bool $bool
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setVisible($bool){
|
||||
$this->show = (bool) $bool;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the amplifier of this effect.
|
||||
* TODO: fix mess of amplifier used instead of level for effect calculation.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getAmplifier(){
|
||||
@ -174,19 +242,40 @@ class Effect{
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the effect is ambient.
|
||||
* @return bool
|
||||
*/
|
||||
public function isAmbient(){
|
||||
return $this->ambient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the ambiency of this effect.
|
||||
* @param bool $ambient
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAmbient($ambient = true){
|
||||
$this->ambient = (bool) $ambient;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this effect is harmful.
|
||||
* TODO: implement inverse effect results for undead mobs
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isBad(){
|
||||
return $this->bad;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the effect will do something on the current tick.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canTick(){
|
||||
switch($this->id){
|
||||
case Effect::POISON:
|
||||
@ -212,10 +301,19 @@ class Effect{
|
||||
return ($this->duration % $interval) === 0;
|
||||
}
|
||||
return true;
|
||||
case Effect::INSTANT_DAMAGE:
|
||||
case Effect::INSTANT_HEALTH:
|
||||
//If forced to last longer than 1 tick, these apply every tick.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies effect results to an entity.
|
||||
*
|
||||
* @param Entity $entity
|
||||
*/
|
||||
public function applyEffect(Entity $entity){
|
||||
switch($this->id){
|
||||
case Effect::POISON:
|
||||
@ -241,17 +339,48 @@ class Effect{
|
||||
if($entity instanceof Human){
|
||||
$entity->exhaust(0.5 * $this->amplifier, PlayerExhaustEvent::CAUSE_POTION);
|
||||
}
|
||||
break;
|
||||
case Effect::INSTANT_HEALTH:
|
||||
//TODO: add particles (witch spell)
|
||||
if($entity->getHealth() < $entity->getMaxHealth()){
|
||||
$amount = 2 * (2 ** (($this->amplifier + 1) % 32));
|
||||
$entity->heal($amount, new EntityRegainHealthEvent($entity, $amount, EntityRegainHealthEvent::CAUSE_MAGIC));
|
||||
}
|
||||
break;
|
||||
case Effect::INSTANT_DAMAGE:
|
||||
//TODO: add particles (witch spell)
|
||||
$amount = 2 * (2 ** (($this->amplifier + 1) % 32));
|
||||
$entity->attack($amount, new EntityDamageEvent($entity, EntityDamageEvent::CAUSE_MAGIC, $amount));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an RGB color array of this effect's color.
|
||||
* @return array
|
||||
*/
|
||||
public function getColor(){
|
||||
return [$this->color >> 16, ($this->color >> 8) & 0xff, $this->color & 0xff];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the color of this effect.
|
||||
*
|
||||
* @param int $r
|
||||
* @param int $g
|
||||
* @param int $b
|
||||
*/
|
||||
public function setColor($r, $g, $b){
|
||||
$this->color = (($r & 0xff) << 16) + (($g & 0xff) << 8) + ($b & 0xff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this effect to the Entity, performing effect overriding as specified.
|
||||
*
|
||||
* @param Entity $entity
|
||||
* @param bool $modify
|
||||
* @param Effect|null $oldEffect
|
||||
*/
|
||||
public function add(Entity $entity, $modify = false, Effect $oldEffect = null){
|
||||
$entity->getLevel()->getServer()->getPluginManager()->callEvent($ev = new EntityEffectAddEvent($entity, $this, $modify, $oldEffect));
|
||||
if($ev->isCancelled()){
|
||||
@ -273,30 +402,58 @@ class Effect{
|
||||
$entity->dataPacket($pk);
|
||||
}
|
||||
|
||||
if($this->id === Effect::INVISIBILITY){
|
||||
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, true);
|
||||
$entity->setNameTagVisible(false);
|
||||
}elseif($this->id === Effect::SPEED){
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
if($ev->willModify() and $oldEffect !== null){
|
||||
$speed = $attr->getValue() / (1 + 0.2 * $oldEffect->getAmplifier());
|
||||
}else{
|
||||
$speed = $attr->getValue();
|
||||
}
|
||||
$speed *= (1 + 0.2 * $this->amplifier);
|
||||
$attr->setValue($speed);
|
||||
}elseif($this->id === Effect::SLOWNESS){
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
if($ev->willModify() and $oldEffect !== null){
|
||||
$speed = $attr->getValue() / (1 - 0.15 * $oldEffect->getAmplifier());
|
||||
}else{
|
||||
$speed = $attr->getValue();
|
||||
}
|
||||
$speed *= (1 - 0.15 * $this->amplifier);
|
||||
$attr->setValue($speed, true);
|
||||
switch($this->id){
|
||||
case Effect::INVISIBILITY:
|
||||
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, true);
|
||||
$entity->setNameTagVisible(false);
|
||||
break;
|
||||
case Effect::SPEED:
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
if($ev->willModify() and $oldEffect !== null){
|
||||
$speed = $attr->getValue() / (1 + 0.2 * $oldEffect->getAmplifier());
|
||||
}else{
|
||||
$speed = $attr->getValue();
|
||||
}
|
||||
$speed *= (1 + 0.2 * $this->amplifier);
|
||||
$attr->setValue($speed);
|
||||
break;
|
||||
case Effect::SLOWNESS:
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
if($ev->willModify() and $oldEffect !== null){
|
||||
$speed = $attr->getValue() / (1 - 0.15 * $oldEffect->getAmplifier());
|
||||
}else{
|
||||
$speed = $attr->getValue();
|
||||
}
|
||||
$speed *= (1 - 0.15 * $this->amplifier);
|
||||
$attr->setValue($speed, true);
|
||||
break;
|
||||
|
||||
case Effect::HEALTH_BOOST:
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::HEALTH);
|
||||
if($ev->willModify() and $oldEffect !== null){
|
||||
$max = $attr->getMaxValue() - (4 * ($oldEffect->getAmplifier() + 1));
|
||||
}else{
|
||||
$max = $attr->getMaxValue();
|
||||
}
|
||||
|
||||
$max += (4 * ($this->amplifier + 1));
|
||||
$attr->setMaxValue($max);
|
||||
break;
|
||||
case Effect::ABSORPTION:
|
||||
$new = (4 * ($this->amplifier + 1));
|
||||
if($new > $entity->getAbsorption()){
|
||||
$entity->setAbsorption($new);
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the effect from the entity, resetting any changed values back to their original defaults.
|
||||
*
|
||||
* @param Entity $entity
|
||||
*/
|
||||
public function remove(Entity $entity){
|
||||
$entity->getLevel()->getServer()->getPluginManager()->callEvent($ev = new EntityEffectRemoveEvent($entity, $this));
|
||||
if($ev->isCancelled()){
|
||||
@ -311,15 +468,26 @@ class Effect{
|
||||
$entity->dataPacket($pk);
|
||||
}
|
||||
|
||||
if($this->id === Effect::INVISIBILITY){
|
||||
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, false);
|
||||
$entity->setNameTagVisible(true);
|
||||
}elseif($this->id === Effect::SPEED){
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
$attr->setValue($attr->getValue() / (1 + 0.2 * $this->amplifier));
|
||||
}elseif($this->id === Effect::SLOWNESS){
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
$attr->setValue($attr->getValue() / (1 - 0.15 * $this->amplifier));
|
||||
switch($this->id){
|
||||
case Effect::INVISIBILITY:
|
||||
$entity->setDataFlag(Entity::DATA_FLAGS, Entity::DATA_FLAG_INVISIBLE, false);
|
||||
$entity->setNameTagVisible(true);
|
||||
break;
|
||||
case Effect::SPEED:
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
$attr->setValue($attr->getValue() / (1 + 0.2 * $this->amplifier));
|
||||
break;
|
||||
case Effect::SLOWNESS:
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::MOVEMENT_SPEED);
|
||||
$attr->setValue($attr->getValue() / (1 - 0.15 * $this->amplifier));
|
||||
break;
|
||||
case Effect::HEALTH_BOOST:
|
||||
$attr = $entity->getAttributeMap()->getAttribute(Attribute::HEALTH);
|
||||
$attr->setMaxValue($attr->getMaxValue() - (4 * ($this->amplifier + 1)));
|
||||
break;
|
||||
case Effect::ABSORPTION:
|
||||
$entity->setAbsorption(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,9 +52,9 @@ use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\protocol\MobEffectPacket;
|
||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\protocol\SetEntityDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEffectPacket;
|
||||
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetEntityDataPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use pocketmine\Server;
|
||||
@ -339,6 +339,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
$this->invulnerable = $this->namedtag["Invulnerable"] > 0 ? true : false;
|
||||
|
||||
$this->attributeMap = new AttributeMap();
|
||||
$this->addAttributes();
|
||||
|
||||
$this->chunk->addEntity($this);
|
||||
$this->level->addEntity($this);
|
||||
@ -501,10 +502,6 @@ abstract class Entity extends Location implements Metadatable{
|
||||
$this->effects[$effect->getId()] = $effect;
|
||||
|
||||
$this->recalculateEffectColor();
|
||||
|
||||
if($effect->getId() === Effect::HEALTH_BOOST){
|
||||
$this->setHealth($this->getHealth() + 4 * ($effect->getAmplifier() + 1));
|
||||
}
|
||||
}
|
||||
|
||||
protected function recalculateEffectColor(){
|
||||
@ -513,7 +510,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
$count = 0;
|
||||
$ambient = true;
|
||||
foreach($this->effects as $effect){
|
||||
if($effect->isVisible()){
|
||||
if($effect->isVisible() and $effect->hasBubbles()){
|
||||
$c = $effect->getColor();
|
||||
$color[0] += $c[0] * ($effect->getAmplifier() + 1);
|
||||
$color[1] += $c[1] * ($effect->getAmplifier() + 1);
|
||||
@ -530,7 +527,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
$g = ($color[1] / $count) & 0xff;
|
||||
$b = ($color[2] / $count) & 0xff;
|
||||
|
||||
$this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, ($r << 16) + ($g << 8) + $b);
|
||||
$this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, 0xff000000 | ($r << 16) | ($g << 8) | $b);
|
||||
$this->setDataProperty(Entity::DATA_POTION_AMBIENT, Entity::DATA_TYPE_BYTE, $ambient ? 1 : 0);
|
||||
}else{
|
||||
$this->setDataProperty(Entity::DATA_POTION_COLOR, Entity::DATA_TYPE_INT, 0);
|
||||
@ -646,8 +643,6 @@ abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
$this->scheduleUpdate();
|
||||
|
||||
$this->addAttributes();
|
||||
|
||||
if(isset($this->namedtag->ActiveEffects)){
|
||||
foreach($this->namedtag->ActiveEffects->getValue() as $e){
|
||||
$amplifier = $e["Amplifier"] & 0xff; //0-255 only
|
||||
@ -724,6 +719,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
/**
|
||||
* @param Player $player
|
||||
* @param bool $send
|
||||
*/
|
||||
public function despawnFrom(Player $player, bool $send = true){
|
||||
if(isset($this->hasSpawned[$player->getLoaderId()])){
|
||||
@ -758,7 +754,21 @@ abstract class Entity extends Location implements Metadatable{
|
||||
|
||||
$this->setLastDamageCause($source);
|
||||
|
||||
$this->setHealth($this->getHealth() - $source->getFinalDamage());
|
||||
$damage = $source->getFinalDamage();
|
||||
|
||||
$absorption = $this->getAbsorption();
|
||||
if($absorption > 0){
|
||||
if($absorption > $damage){
|
||||
//Use absorption health before normal health.
|
||||
$this->setAbsorption($absorption - $damage);
|
||||
$damage = 0;
|
||||
}else{
|
||||
$this->setAbsorption(0);
|
||||
$damage -= $absorption;
|
||||
}
|
||||
}
|
||||
|
||||
$this->setHealth($this->getHealth() - $damage);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -808,6 +818,14 @@ abstract class Entity extends Location implements Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
public function getAbsorption() : int{
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function setAbsorption(int $absorption){
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @param EntityDamageEvent $type
|
||||
*/
|
||||
@ -830,7 +848,7 @@ abstract class Entity extends Location implements Metadatable{
|
||||
* @return int
|
||||
*/
|
||||
public function getMaxHealth(){
|
||||
return $this->maxHealth + ($this->hasEffect(Effect::HEALTH_BOOST) ? 4 * ($this->getEffect(Effect::HEALTH_BOOST)->getAmplifier() + 1) : 0);
|
||||
return $this->maxHealth;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1659,7 +1677,10 @@ abstract class Entity extends Location implements Metadatable{
|
||||
if(!$this->closed){
|
||||
$this->server->getPluginManager()->callEvent(new EntityDespawnEvent($this));
|
||||
$this->closed = true;
|
||||
|
||||
$this->despawnFromAll();
|
||||
$this->hasSpawned = [];
|
||||
|
||||
if($this->chunk !== null){
|
||||
$this->chunk->removeEntity($this);
|
||||
$this->chunk = null;
|
||||
|
@ -29,7 +29,7 @@ use pocketmine\item\Item as ItemItem;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class FallingSand extends Entity{
|
||||
|
@ -27,6 +27,7 @@ use pocketmine\event\player\PlayerExhaustEvent;
|
||||
use pocketmine\inventory\InventoryHolder;
|
||||
use pocketmine\inventory\PlayerInventory;
|
||||
use pocketmine\item\Item as ItemItem;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
@ -35,8 +36,7 @@ use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\utils\UUID;
|
||||
|
||||
@ -62,13 +62,21 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
public $eyeHeight = 1.62;
|
||||
|
||||
protected $skinId;
|
||||
protected $skin;
|
||||
protected $skin = null;
|
||||
|
||||
protected $foodTickTimer = 0;
|
||||
|
||||
protected $totalXp = 0;
|
||||
protected $xpSeed;
|
||||
|
||||
public function __construct(Level $level, CompoundTag $nbt){
|
||||
if($this->skin === null and (!isset($nbt->Skin) or !isset($nbt->Skin->Data) or !Player::isValidSkin($nbt->Skin->Data->getValue()))){
|
||||
throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set");
|
||||
}
|
||||
|
||||
parent::__construct($level, $nbt);
|
||||
}
|
||||
|
||||
public function getSkinData(){
|
||||
return $this->skin;
|
||||
}
|
||||
@ -96,10 +104,23 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
* @param string $skinId
|
||||
*/
|
||||
public function setSkin($str, $skinId){
|
||||
if(!Player::isValidSkin($str)){
|
||||
throw new \InvalidStateException("Specified skin is not valid, must be 8KiB or 16KiB");
|
||||
}
|
||||
|
||||
$this->skin = $str;
|
||||
$this->skinId = $skinId;
|
||||
}
|
||||
|
||||
public function jump(){
|
||||
parent::jump();
|
||||
if($this->isSprinting()){
|
||||
$this->exhaust(0.8, PlayerExhaustEvent::CAUSE_SPRINT_JUMPING);
|
||||
}else{
|
||||
$this->exhaust(0.2, PlayerExhaustEvent::CAUSE_JUMPING);
|
||||
}
|
||||
}
|
||||
|
||||
public function getFood() : float{
|
||||
return $this->attributeMap->getAttribute(Attribute::HUNGER)->getValue();
|
||||
}
|
||||
@ -353,42 +374,50 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
public function entityBaseTick($tickDiff = 1){
|
||||
$hasUpdate = parent::entityBaseTick($tickDiff);
|
||||
|
||||
$this->doFoodTick($tickDiff);
|
||||
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
public function doFoodTick(int $tickDiff = 1){
|
||||
if($this->isAlive()){
|
||||
$food = $this->getFood();
|
||||
$health = $this->getHealth();
|
||||
if($food >= 18){
|
||||
$this->foodTickTimer++;
|
||||
if($this->foodTickTimer >= 80 and $health < $this->getMaxHealth()){
|
||||
$this->heal(1, new EntityRegainHealthEvent($this, 1, EntityRegainHealthEvent::CAUSE_SATURATION));
|
||||
$this->exhaust(3.0, PlayerExhaustEvent::CAUSE_HEALTH_REGEN);
|
||||
$this->foodTickTimer = 0;
|
||||
$difficulty = $this->server->getDifficulty();
|
||||
|
||||
$this->foodTickTimer += $tickDiff;
|
||||
if($this->foodTickTimer >= 80){
|
||||
$this->foodTickTimer = 0;
|
||||
}
|
||||
|
||||
if($difficulty === 0 and $this->foodTickTimer % 10 === 0){ //Peaceful
|
||||
if($food < 20){
|
||||
$this->addFood(1.0);
|
||||
}
|
||||
}elseif($food === 0){
|
||||
$this->foodTickTimer++;
|
||||
if($this->foodTickTimer >= 80){
|
||||
$diff = $this->server->getDifficulty();
|
||||
$can = false;
|
||||
if($diff === 1){
|
||||
$can = $health > 10;
|
||||
}elseif($diff === 2){
|
||||
$can = $health > 1;
|
||||
}elseif($diff === 3){
|
||||
$can = true;
|
||||
if($this->foodTickTimer % 20 === 0 and $health < $this->getMaxHealth()){
|
||||
$this->heal(1, new EntityRegainHealthEvent($this, 1, EntityRegainHealthEvent::CAUSE_SATURATION));
|
||||
}
|
||||
}
|
||||
|
||||
if($this->foodTickTimer === 0){
|
||||
if($food >= 18){
|
||||
if($health < $this->getMaxHealth()){
|
||||
$this->heal(1, new EntityRegainHealthEvent($this, 1, EntityRegainHealthEvent::CAUSE_SATURATION));
|
||||
$this->exhaust(3.0, PlayerExhaustEvent::CAUSE_HEALTH_REGEN);
|
||||
}
|
||||
if($can){
|
||||
}elseif($food <= 0){
|
||||
if(($difficulty === 1 and $health > 10) or ($difficulty === 2 and $health > 1) or $difficulty === 3){
|
||||
$this->attack(1, new EntityDamageEvent($this, EntityDamageEvent::CAUSE_STARVATION, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if($food <= 6){
|
||||
if($this->isSprinting()){
|
||||
$this->setSprinting(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $hasUpdate;
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
@ -471,7 +500,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
if($player !== $this and !isset($this->hasSpawned[$player->getLoaderId()])){
|
||||
$this->hasSpawned[$player->getLoaderId()] = $player;
|
||||
|
||||
if(strlen($this->skin) < 64 * 32 * 4){
|
||||
if(!Player::isValidSkin($this->skin)){
|
||||
throw new \InvalidStateException((new \ReflectionClass($this))->getShortName() . " must have a valid skin set");
|
||||
}
|
||||
|
||||
@ -505,7 +534,7 @@ class Human extends Creature implements ProjectileSource, InventoryHolder{
|
||||
|
||||
public function close(){
|
||||
if(!$this->closed){
|
||||
if(!($this instanceof Player) or $this->loggedIn){
|
||||
if($this->inventory !== null){
|
||||
foreach($this->inventory->getViewers() as $viewer){
|
||||
$viewer->removeWindow($this->inventory);
|
||||
}
|
||||
|
@ -1,26 +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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\entity;
|
||||
|
||||
class InstantEffect extends Effect{
|
||||
|
||||
}
|
@ -28,7 +28,7 @@ use pocketmine\item\Item as ItemItem;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\protocol\AddItemEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddItemEntityPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Item extends Entity{
|
||||
|
@ -31,7 +31,7 @@ use pocketmine\event\Timings;
|
||||
use pocketmine\item\Item as ItemItem;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\network\protocol\EntityEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
||||
use pocketmine\utils\BlockIterator;
|
||||
|
||||
abstract class Living extends Entity implements Damageable{
|
||||
@ -43,6 +43,8 @@ abstract class Living extends Entity implements Damageable{
|
||||
|
||||
protected $invisible = false;
|
||||
|
||||
protected $jumpVelocity = 0.42;
|
||||
|
||||
protected function initEntity(){
|
||||
parent::initEntity();
|
||||
|
||||
@ -68,7 +70,7 @@ abstract class Living extends Entity implements Damageable{
|
||||
public function setHealth($amount){
|
||||
$wasAlive = $this->isAlive();
|
||||
parent::setHealth($amount);
|
||||
$this->attributeMap->getAttribute(Attribute::HEALTH)->setValue($this->getHealth());
|
||||
$this->attributeMap->getAttribute(Attribute::HEALTH)->setValue($this->getHealth(), true);
|
||||
if($this->isAlive() and !$wasAlive){
|
||||
$pk = new EntityEventPacket();
|
||||
$pk->eid = $this->getId();
|
||||
@ -77,10 +79,22 @@ abstract class Living extends Entity implements Damageable{
|
||||
}
|
||||
}
|
||||
|
||||
public function getMaxHealth(){
|
||||
return $this->attributeMap->getAttribute(Attribute::HEALTH)->getMaxValue();
|
||||
}
|
||||
|
||||
public function setMaxHealth($amount){
|
||||
$this->attributeMap->getAttribute(Attribute::HEALTH)->setMaxValue($amount);
|
||||
}
|
||||
|
||||
public function getAbsorption() : int{
|
||||
return (int) $this->attributeMap->getAttribute(Attribute::ABSORPTION)->getValue();
|
||||
}
|
||||
|
||||
public function setAbsorption(int $absorption){
|
||||
$this->attributeMap->getAttribute(Attribute::ABSORPTION)->setValue($absorption);
|
||||
}
|
||||
|
||||
public function saveNBT(){
|
||||
parent::saveNBT();
|
||||
$this->namedtag->Health = new ShortTag("Health", $this->getHealth());
|
||||
@ -103,6 +117,23 @@ abstract class Living extends Entity implements Damageable{
|
||||
$this->attackTime = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the initial upwards velocity of a jumping entity in blocks/tick, including additional velocity due to effects.
|
||||
* @return float
|
||||
*/
|
||||
public function getJumpVelocity() : float{
|
||||
return $this->jumpVelocity + ($this->hasEffect(Effect::JUMP) ? (($this->getEffect(Effect::JUMP)->getAmplifier() + 1) / 10) : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the entity jumps from the ground. This method adds upwards velocity to the entity.
|
||||
*/
|
||||
public function jump(){
|
||||
if($this->onGround){
|
||||
$this->motionY = $this->getJumpVelocity(); //Y motion should already be 0 if we're jumping from the ground.
|
||||
}
|
||||
}
|
||||
|
||||
public function attack($damage, EntityDamageEvent $source){
|
||||
if($this->attackTime > 0 or $this->noDamageTicks > 0){
|
||||
$lastCause = $this->getLastDamageCause();
|
||||
@ -171,6 +202,10 @@ abstract class Living extends Entity implements Damageable{
|
||||
return;
|
||||
}
|
||||
parent::kill();
|
||||
$this->callDeathEvent();
|
||||
}
|
||||
|
||||
protected function callDeathEvent(){
|
||||
$this->server->getPluginManager()->callEvent($ev = new EntityDeathEvent($this, $this->getDrops()));
|
||||
foreach($ev->getDrops() as $item){
|
||||
$this->getLevel()->dropItem($this, $item);
|
||||
|
@ -25,7 +25,7 @@ use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\event\entity\ExplosionPrimeEvent;
|
||||
use pocketmine\level\Explosion;
|
||||
use pocketmine\nbt\tag\ByteTag;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class PrimedTNT extends Entity implements Explosive{
|
||||
|
@ -23,7 +23,7 @@ namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Snowball extends Projectile{
|
||||
|
@ -25,8 +25,8 @@ use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
use pocketmine\event\entity\EntityDamageEvent;
|
||||
use pocketmine\item\Item as ItemItem;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\protocol\EntityEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Squid extends WaterAnimal implements Ageable{
|
||||
@ -43,8 +43,8 @@ class Squid extends WaterAnimal implements Ageable{
|
||||
private $switchDirectionTicker = 0;
|
||||
|
||||
public function initEntity(){
|
||||
$this->setMaxHealth(10);
|
||||
parent::initEntity();
|
||||
$this->setMaxHealth(5);
|
||||
}
|
||||
|
||||
public function getName(){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\nbt\tag\IntTag;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Villager extends Creature implements NPC, Ageable{
|
||||
|
@ -23,7 +23,7 @@ namespace pocketmine\entity;
|
||||
|
||||
use pocketmine\event\entity\EntityDamageByEntityEvent;
|
||||
use pocketmine\item\Item as ItemItem;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class Zombie extends Monster{
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\event;
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\plugin\PluginManager;
|
||||
use pocketmine\scheduler\PluginTask;
|
||||
|
@ -34,19 +34,21 @@ class PlayerExhaustEvent extends PlayerEvent implements Cancellable{
|
||||
const CAUSE_HEALTH_REGEN = 4;
|
||||
const CAUSE_POTION = 5;
|
||||
const CAUSE_WALKING = 6;
|
||||
const CAUSE_SNEAKING = 7;
|
||||
const CAUSE_SPRINTING = 7;
|
||||
const CAUSE_SWIMMING = 8;
|
||||
const CAUSE_JUMPING = 10;
|
||||
const CAUSE_JUMPING = 9;
|
||||
const CAUSE_SPRINT_JUMPING = 10;
|
||||
const CAUSE_CUSTOM = 11;
|
||||
|
||||
const CAUSE_FLAG_SPRINT = 0x10000;
|
||||
|
||||
/** @var float */
|
||||
private $amount;
|
||||
/** @var int */
|
||||
private $cause;
|
||||
|
||||
public function __construct(Human $human, float $amount, int $cause){
|
||||
$this->player = $human;
|
||||
$this->amount = $amount;
|
||||
$this->cause = $cause;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -63,4 +65,12 @@ class PlayerExhaustEvent extends PlayerEvent implements Cancellable{
|
||||
public function setAmount(float $amount){
|
||||
$this->amount = $amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an int cause of the exhaustion - one of the constants at the top of this class.
|
||||
* @return int
|
||||
*/
|
||||
public function getCause() : int{
|
||||
return $this->cause;
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\event\server;
|
||||
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class DataPacketReceiveEvent extends ServerEvent implements Cancellable{
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\event\server;
|
||||
|
||||
use pocketmine\event\Cancellable;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
class DataPacketSendEvent extends ServerEvent implements Cancellable{
|
||||
|
@ -25,8 +25,8 @@ use pocketmine\entity\Entity;
|
||||
use pocketmine\event\entity\EntityInventoryChangeEvent;
|
||||
use pocketmine\event\inventory\InventoryOpenEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\protocol\ContainerSetSlotPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetSlotPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\network\protocol\BlockEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\BlockEventPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Chest;
|
||||
|
||||
|
@ -22,8 +22,8 @@
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\ContainerClosePacket;
|
||||
use pocketmine\network\protocol\ContainerOpenPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
abstract class ContainerInventory extends BaseInventory{
|
||||
|
@ -23,7 +23,7 @@ namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\event\Timings;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\protocol\CraftingDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\CraftingDataPacket;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\Config;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
@ -23,7 +23,7 @@ namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\network\protocol\BlockEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\BlockEventPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\tile\Chest;
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
namespace pocketmine\inventory;
|
||||
|
||||
use pocketmine\network\protocol\types\InventoryNetworkIds;
|
||||
use pocketmine\network\mcpe\protocol\types\WindowTypes;
|
||||
|
||||
/**
|
||||
* Saves all the information regarding default inventory sizes and types
|
||||
@ -63,15 +63,15 @@ class InventoryType{
|
||||
//TODO: move network stuff out of here
|
||||
//TODO: move inventory data to json
|
||||
static::$default = [
|
||||
static::CHEST => new InventoryType(27, "Chest", InventoryNetworkIds::CONTAINER),
|
||||
static::DOUBLE_CHEST => new InventoryType(27 + 27, "Double Chest", InventoryNetworkIds::CONTAINER),
|
||||
static::PLAYER => new InventoryType(36 + 4, "Player", InventoryNetworkIds::INVENTORY), //36 CONTAINER, 4 ARMOR
|
||||
static::CRAFTING => new InventoryType(5, "Crafting", InventoryNetworkIds::INVENTORY), //yes, the use of INVENTORY is intended! 4 CRAFTING slots, 1 RESULT
|
||||
static::WORKBENCH => new InventoryType(10, "Crafting", InventoryNetworkIds::WORKBENCH), //9 CRAFTING slots, 1 RESULT
|
||||
static::FURNACE => new InventoryType(3, "Furnace", InventoryNetworkIds::FURNACE), //2 INPUT, 1 OUTPUT
|
||||
static::ENCHANT_TABLE => new InventoryType(2, "Enchant", InventoryNetworkIds::ENCHANTMENT), //1 INPUT/OUTPUT, 1 LAPIS
|
||||
static::BREWING_STAND => new InventoryType(4, "Brewing", InventoryNetworkIds::BREWING_STAND), //1 INPUT, 3 POTION
|
||||
static::ANVIL => new InventoryType(3, "Anvil", InventoryNetworkIds::ANVIL) //2 INPUT, 1 OUTP
|
||||
static::CHEST => new InventoryType(27, "Chest", WindowTypes::CONTAINER),
|
||||
static::DOUBLE_CHEST => new InventoryType(27 + 27, "Double Chest", WindowTypes::CONTAINER),
|
||||
static::PLAYER => new InventoryType(36 + 4, "Player", WindowTypes::INVENTORY), //36 CONTAINER, 4 ARMOR
|
||||
static::CRAFTING => new InventoryType(5, "Crafting", WindowTypes::INVENTORY), //yes, the use of INVENTORY is intended! 4 CRAFTING slots, 1 RESULT
|
||||
static::WORKBENCH => new InventoryType(10, "Crafting", WindowTypes::WORKBENCH), //9 CRAFTING slots, 1 RESULT
|
||||
static::FURNACE => new InventoryType(3, "Furnace", WindowTypes::FURNACE), //2 INPUT, 1 OUTPUT
|
||||
static::ENCHANT_TABLE => new InventoryType(2, "Enchant", WindowTypes::ENCHANTMENT), //1 INPUT/OUTPUT, 1 LAPIS
|
||||
static::BREWING_STAND => new InventoryType(4, "Brewing", WindowTypes::BREWING_STAND), //1 INPUT, 3 POTION
|
||||
static::ANVIL => new InventoryType(3, "Anvil", WindowTypes::ANVIL) //2 INPUT, 1 OUTP
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -26,10 +26,10 @@ use pocketmine\event\entity\EntityArmorChangeEvent;
|
||||
use pocketmine\event\entity\EntityInventoryChangeEvent;
|
||||
use pocketmine\event\player\PlayerItemHeldEvent;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\protocol\ContainerSetSlotPacket;
|
||||
use pocketmine\network\protocol\MobArmorEquipmentPacket;
|
||||
use pocketmine\network\protocol\MobEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetSlotPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace pocketmine\item;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Human;
|
||||
use pocketmine\event\entity\EntityEatItemEvent;
|
||||
use pocketmine\network\protocol\EntityEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
abstract class Food extends Item implements FoodSource{
|
||||
|
@ -670,6 +670,35 @@ class Item implements ItemIds, \JsonSerializable{
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLore() : array{
|
||||
$tag = $this->getNamedTagEntry("display");
|
||||
if($tag instanceof CompoundTag and isset($tag->Lore) and $tag->Lore instanceof ListTag){
|
||||
$lines = [];
|
||||
foreach($tag->Lore->getValue() as $line){
|
||||
$lines[] = $line->getValue();
|
||||
}
|
||||
|
||||
return $lines;
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
public function setLore(array $lines){
|
||||
$tag = $this->getNamedTag() ?? new CompoundTag("", []);
|
||||
if(!isset($tag->display)){
|
||||
$tag->display = new CompoundTag("display", []);
|
||||
}
|
||||
$tag->display->Lore = new ListTag("Lore");
|
||||
$tag->display->Lore->setTagType(NBT::TAG_String);
|
||||
$count = 0;
|
||||
foreach($lines as $line){
|
||||
$tag->display->Lore[$count++] = new StringTag("", $line);
|
||||
}
|
||||
|
||||
$this->setNamedTag($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $name
|
||||
* @return Tag|null
|
||||
|
@ -38,7 +38,7 @@ use pocketmine\nbt\tag\CompoundTag;
|
||||
use pocketmine\nbt\tag\DoubleTag;
|
||||
use pocketmine\nbt\tag\FloatTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\network\protocol\ExplodePacket;
|
||||
use pocketmine\network\mcpe\protocol\ExplodePacket;
|
||||
use pocketmine\utils\Random;
|
||||
|
||||
class Explosion{
|
||||
|
@ -90,14 +90,14 @@ use pocketmine\nbt\tag\FloatTag;
|
||||
use pocketmine\nbt\tag\ListTag;
|
||||
use pocketmine\nbt\tag\ShortTag;
|
||||
use pocketmine\nbt\tag\StringTag;
|
||||
use pocketmine\network\protocol\BatchPacket;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\protocol\FullChunkDataPacket;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\protocol\MoveEntityPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\network\protocol\SetTimePacket;
|
||||
use pocketmine\network\protocol\UpdateBlockPacket;
|
||||
use pocketmine\network\mcpe\protocol\BatchPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\MoveEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetTimePacket;
|
||||
use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\plugin\Plugin;
|
||||
use pocketmine\Server;
|
||||
@ -134,9 +134,6 @@ class Level implements ChunkManager, Metadatable{
|
||||
/** @var Tile[] */
|
||||
private $tiles = [];
|
||||
|
||||
private $motionToSend = [];
|
||||
private $moveToSend = [];
|
||||
|
||||
/** @var Player[] */
|
||||
private $players = [];
|
||||
|
||||
@ -425,7 +422,9 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
|
||||
public function close(){
|
||||
assert(!$this->closed, "Tried to close a level which is already closed");
|
||||
if($this->closed){
|
||||
throw new \InvalidStateException("Tried to close a level which is already closed");
|
||||
}
|
||||
|
||||
if($this->getAutoSave()){
|
||||
$this->save();
|
||||
@ -652,6 +651,9 @@ class Level implements ChunkManager, Metadatable{
|
||||
*
|
||||
*/
|
||||
public function doTick(int $currentTick){
|
||||
if($this->closed){
|
||||
throw new \InvalidStateException("Attempted to tick a Level which has been closed");
|
||||
}
|
||||
|
||||
$this->timings->doTick->startTiming();
|
||||
|
||||
@ -742,35 +744,6 @@ class Level implements ChunkManager, Metadatable{
|
||||
$this->checkSleep();
|
||||
}
|
||||
|
||||
foreach($this->moveToSend as $index => $entry){
|
||||
Level::getXZ($index, $chunkX, $chunkZ);
|
||||
foreach($entry as $e){
|
||||
$pk = new MoveEntityPacket();
|
||||
$pk->eid = $e[0];
|
||||
$pk->x = $e[1];
|
||||
$pk->y = $e[2];
|
||||
$pk->z = $e[3];
|
||||
$pk->yaw = $e[4];
|
||||
$pk->headYaw = $e[5];
|
||||
$pk->pitch = $e[6];
|
||||
$this->addChunkPacket($chunkX, $chunkZ, $pk);
|
||||
}
|
||||
}
|
||||
$this->moveToSend = [];
|
||||
|
||||
foreach($this->motionToSend as $index => $entry){
|
||||
Level::getXZ($index, $chunkX, $chunkZ);
|
||||
foreach($entry as $entity){
|
||||
$pk = new SetEntityMotionPacket();
|
||||
$pk->eid = $entity[0];
|
||||
$pk->motionX = $entity[1];
|
||||
$pk->motionY = $entity[2];
|
||||
$pk->motionZ = $entity[3];
|
||||
$this->addChunkPacket($chunkX, $chunkZ, $pk);
|
||||
}
|
||||
}
|
||||
$this->motionToSend = [];
|
||||
|
||||
foreach($this->chunkPackets as $index => $entries){
|
||||
Level::getXZ($index, $chunkX, $chunkZ);
|
||||
$chunkPlayers = $this->getChunkPlayers($chunkX, $chunkZ);
|
||||
@ -1597,6 +1570,25 @@ class Level implements ChunkManager, Metadatable{
|
||||
$ev->setCancelled();
|
||||
}
|
||||
}
|
||||
|
||||
if($player->isAdventure(true) and !$ev->isCancelled()){
|
||||
$tag = $item->getNamedTagEntry("CanDestroy");
|
||||
$canBreak = false;
|
||||
if($tag instanceof ListTag){
|
||||
foreach($tag as $v){
|
||||
if($v instanceof StringTag){
|
||||
$entry = Item::fromString($v->getValue());
|
||||
if($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()){
|
||||
$canBreak = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ev->setCancelled(!$canBreak);
|
||||
}
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
if($ev->isCancelled()){
|
||||
return false;
|
||||
@ -1608,8 +1600,8 @@ class Level implements ChunkManager, Metadatable{
|
||||
$breakTime = 3;
|
||||
}
|
||||
|
||||
if($player->hasEffect(Effect::SWIFTNESS)){
|
||||
$breakTime *= 1 - (0.2 * ($player->getEffect(Effect::SWIFTNESS)->getAmplifier() + 1));
|
||||
if($player->hasEffect(Effect::HASTE)){
|
||||
$breakTime *= 1 - (0.2 * ($player->getEffect(Effect::HASTE)->getAmplifier() + 1));
|
||||
}
|
||||
|
||||
if($player->hasEffect(Effect::MINING_FATIGUE)){
|
||||
@ -1642,24 +1634,6 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
$tag = $item->getNamedTagEntry("CanDestroy");
|
||||
if($tag instanceof ListTag){
|
||||
$canBreak = false;
|
||||
foreach($tag as $v){
|
||||
if($v instanceof StringTag){
|
||||
$entry = Item::fromString($v->getValue());
|
||||
if($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()){
|
||||
$canBreak = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$canBreak){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if($createParticles){
|
||||
$this->addParticle(new DestroyBlockParticle($target->add(0.5, 0.5, 0.5), $target));
|
||||
}
|
||||
@ -1734,6 +1708,25 @@ class Level implements ChunkManager, Metadatable{
|
||||
$ev->setCancelled();
|
||||
}
|
||||
}
|
||||
|
||||
if($player->isAdventure(true) and !$ev->isCancelled()){
|
||||
$canPlace = false;
|
||||
$tag = $item->getNamedTagEntry("CanPlaceOn");
|
||||
if($tag instanceof ListTag){
|
||||
foreach($tag as $v){
|
||||
if($v instanceof StringTag){
|
||||
$entry = Item::fromString($v->getValue());
|
||||
if($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()){
|
||||
$canPlace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ev->setCancelled(!$canPlace);
|
||||
}
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev);
|
||||
if(!$ev->isCancelled()){
|
||||
$target->onUpdate(self::BLOCK_UPDATE_TOUCH);
|
||||
@ -1796,24 +1789,6 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
}
|
||||
|
||||
$tag = $item->getNamedTagEntry("CanPlaceOn");
|
||||
if($tag instanceof ListTag){
|
||||
$canPlace = false;
|
||||
foreach($tag as $v){
|
||||
if($v instanceof StringTag){
|
||||
$entry = Item::fromString($v->getValue());
|
||||
if($entry->getId() > 0 and $entry->getBlock() !== null and $entry->getBlock()->getId() === $target->getId()){
|
||||
$canPlace = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!$canPlace){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($player !== null){
|
||||
$ev = new BlockPlaceEvent($player, $hand, $block, $target, $item);
|
||||
@ -2255,18 +2230,20 @@ class Level implements ChunkManager, Metadatable{
|
||||
$oldEntities = $oldChunk !== null ? $oldChunk->getEntities() : [];
|
||||
$oldTiles = $oldChunk !== null ? $oldChunk->getTiles() : [];
|
||||
|
||||
$this->provider->setChunk($chunkX, $chunkZ, $chunk);
|
||||
$this->chunks[$index] = $chunk;
|
||||
|
||||
foreach($oldEntities as $entity){
|
||||
$chunk->addEntity($entity);
|
||||
$oldChunk->removeEntity($entity);
|
||||
$entity->chunk = $chunk;
|
||||
}
|
||||
|
||||
foreach($oldTiles as $tile){
|
||||
$chunk->addTile($tile);
|
||||
$oldChunk->removeTile($tile);
|
||||
$tile->chunk = $chunk;
|
||||
}
|
||||
|
||||
$this->provider->setChunk($chunkX, $chunkZ, $chunk);
|
||||
$this->chunks[$index] = $chunk;
|
||||
}
|
||||
|
||||
unset($this->chunkCache[$index]);
|
||||
@ -2909,16 +2886,23 @@ class Level implements ChunkManager, Metadatable{
|
||||
}
|
||||
|
||||
public function addEntityMotion(int $chunkX, int $chunkZ, int $entityId, float $x, float $y, float $z){
|
||||
if(!isset($this->motionToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){
|
||||
$this->motionToSend[$index] = [];
|
||||
}
|
||||
$this->motionToSend[$index][$entityId] = [$entityId, $x, $y, $z];
|
||||
$pk = new SetEntityMotionPacket();
|
||||
$pk->eid = $entityId;
|
||||
$pk->motionX = $x;
|
||||
$pk->motionY = $y;
|
||||
$pk->motionZ = $z;
|
||||
$this->addChunkPacket($chunkX, $chunkZ, $pk);
|
||||
}
|
||||
|
||||
public function addEntityMovement(int $chunkX, int $chunkZ, int $entityId, float $x, float $y, float $z, float $yaw, float $pitch, $headYaw = null){
|
||||
if(!isset($this->moveToSend[$index = Level::chunkHash($chunkX, $chunkZ)])){
|
||||
$this->moveToSend[$index] = [];
|
||||
}
|
||||
$this->moveToSend[$index][$entityId] = [$entityId, $x, $y, $z, $yaw, $headYaw === null ? $yaw : $headYaw, $pitch];
|
||||
$pk = new MoveEntityPacket();
|
||||
$pk->eid = $entityId;
|
||||
$pk->x = $x;
|
||||
$pk->y = $y;
|
||||
$pk->z = $z;
|
||||
$pk->yaw = $yaw;
|
||||
$pk->pitch = $pitch;
|
||||
$pk->headYaw = $headYaw ?? $yaw;
|
||||
$this->addChunkPacket($chunkX, $chunkZ, $pk);
|
||||
}
|
||||
}
|
||||
|
@ -568,6 +568,9 @@ class Chunk{
|
||||
* @param Entity $entity
|
||||
*/
|
||||
public function addEntity(Entity $entity){
|
||||
if($entity->closed){
|
||||
throw new \InvalidArgumentException("Attempted to add a garbage closed Entity to a chunk");
|
||||
}
|
||||
$this->entities[$entity->getId()] = $entity;
|
||||
if(!($entity instanceof Player) and $this->isInit){
|
||||
$this->hasChanged = true;
|
||||
@ -588,6 +591,9 @@ class Chunk{
|
||||
* @param Tile $tile
|
||||
*/
|
||||
public function addTile(Tile $tile){
|
||||
if($tile->closed){
|
||||
throw new \InvalidArgumentException("Attempted to add a garbage closed Tile to a chunk");
|
||||
}
|
||||
$this->tiles[$tile->getId()] = $tile;
|
||||
if(isset($this->tileList[$index = (($tile->x & 0x0f) << 12) | (($tile->z & 0x0f) << 8) | ($tile->y & 0xff)]) and $this->tileList[$index] !== $tile){
|
||||
$this->tileList[$index]->close();
|
||||
@ -691,9 +697,16 @@ class Chunk{
|
||||
continue; //Fixes entities allocated in wrong chunks.
|
||||
}
|
||||
|
||||
if(($entity = Entity::createEntity($nbt["id"], $level, $nbt)) instanceof Entity){
|
||||
$entity->spawnToAll();
|
||||
}else{
|
||||
try{
|
||||
$entity = Entity::createEntity($nbt["id"], $level, $nbt);
|
||||
if($entity instanceof Entity){
|
||||
$entity->spawnToAll();
|
||||
}else{
|
||||
$changed = true;
|
||||
continue;
|
||||
}
|
||||
}catch(\Throwable $t){
|
||||
$level->getServer()->getLogger()->logException($t);
|
||||
$changed = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -22,18 +22,18 @@
|
||||
namespace pocketmine\level\format\io\leveldb;
|
||||
|
||||
use pocketmine\level\format\Chunk;
|
||||
use pocketmine\level\format\SubChunk;
|
||||
use pocketmine\level\format\io\BaseLevelProvider;
|
||||
use pocketmine\level\format\io\ChunkUtils;
|
||||
use pocketmine\level\generator\Generator;
|
||||
use pocketmine\level\format\SubChunk;
|
||||
use pocketmine\level\generator\Flat;
|
||||
use pocketmine\level\generator\Generator;
|
||||
use pocketmine\level\Level;
|
||||
use pocketmine\level\LevelException;
|
||||
use pocketmine\nbt\NBT;
|
||||
use pocketmine\nbt\tag\{
|
||||
ByteTag, CompoundTag, FloatTag, IntTag, LongTag, StringTag
|
||||
};
|
||||
use pocketmine\network\protocol\Info as ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\utils\Binary;
|
||||
use pocketmine\utils\MainLogger;
|
||||
|
||||
|
@ -23,7 +23,7 @@ namespace pocketmine\level\particle;
|
||||
|
||||
use pocketmine\block\Block;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class DestroyBlockParticle extends Particle{
|
||||
|
||||
|
@ -24,8 +24,8 @@ namespace pocketmine\level\particle;
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\entity\Item as ItemEntity;
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
|
||||
|
||||
class FloatingTextParticle extends Particle{
|
||||
//TODO: HACK!
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\particle;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class GenericParticle extends Particle{
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\particle;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class MobSpawnParticle extends Particle{
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\particle;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
|
||||
abstract class Particle extends Vector3{
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class AnvilBreakSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class AnvilFallSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class AnvilUseSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class BlazeShootSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class ClickSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class DoorBumpSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class DoorCrashSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class DoorSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class EndermanTeleportSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class FizzSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class GenericSound extends Sound{
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class GhastShootSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class GhastSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class LaunchSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
|
@ -22,10 +22,10 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
|
||||
class PopSound extends GenericSound{
|
||||
public function __construct(Vector3 $pos, $pitch = 0){
|
||||
parent::__construct($pos, LevelEventPacket::EVENT_SOUND_CLICK_FAIL, $pitch);
|
||||
parent::__construct($pos, LevelEventPacket::EVENT_SOUND_POP, $pitch);
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
namespace pocketmine\level\sound;
|
||||
|
||||
use pocketmine\math\Vector3;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
|
||||
abstract class Sound extends Vector3{
|
||||
|
||||
|
@ -24,79 +24,91 @@
|
||||
*/
|
||||
namespace pocketmine\network;
|
||||
|
||||
use pocketmine\network\protocol\AddEntityPacket;
|
||||
use pocketmine\network\protocol\AddHangingEntityPacket;
|
||||
use pocketmine\network\protocol\AddItemEntityPacket;
|
||||
use pocketmine\network\protocol\AddItemPacket;
|
||||
use pocketmine\network\protocol\AddPaintingPacket;
|
||||
use pocketmine\network\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\protocol\AdventureSettingsPacket;
|
||||
use pocketmine\network\protocol\AnimatePacket;
|
||||
use pocketmine\network\protocol\AvailableCommandsPacket;
|
||||
use pocketmine\network\protocol\BatchPacket;
|
||||
use pocketmine\network\protocol\BlockEntityDataPacket;
|
||||
use pocketmine\network\protocol\BlockEventPacket;
|
||||
use pocketmine\network\protocol\ChangeDimensionPacket;
|
||||
use pocketmine\network\protocol\ChunkRadiusUpdatedPacket;
|
||||
use pocketmine\network\protocol\CommandStepPacket;
|
||||
use pocketmine\network\protocol\ContainerClosePacket;
|
||||
use pocketmine\network\protocol\ContainerOpenPacket;
|
||||
use pocketmine\network\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\protocol\ContainerSetDataPacket;
|
||||
use pocketmine\network\protocol\ContainerSetSlotPacket;
|
||||
use pocketmine\network\protocol\CraftingDataPacket;
|
||||
use pocketmine\network\protocol\CraftingEventPacket;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\protocol\DisconnectPacket;
|
||||
use pocketmine\network\protocol\DropItemPacket;
|
||||
use pocketmine\network\protocol\EntityEventPacket;
|
||||
use pocketmine\network\protocol\ExplodePacket;
|
||||
use pocketmine\network\protocol\FullChunkDataPacket;
|
||||
use pocketmine\network\protocol\HurtArmorPacket;
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\network\protocol\Info as ProtocolInfo;
|
||||
use pocketmine\network\protocol\InteractPacket;
|
||||
use pocketmine\network\protocol\InventoryActionPacket;
|
||||
use pocketmine\network\protocol\ItemFrameDropItemPacket;
|
||||
use pocketmine\network\protocol\LevelEventPacket;
|
||||
use pocketmine\network\protocol\LevelSoundEventPacket;
|
||||
use pocketmine\network\protocol\LoginPacket;
|
||||
use pocketmine\network\protocol\MobArmorEquipmentPacket;
|
||||
use pocketmine\network\protocol\MobEquipmentPacket;
|
||||
use pocketmine\network\protocol\MoveEntityPacket;
|
||||
use pocketmine\network\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\protocol\PlayerActionPacket;
|
||||
use pocketmine\network\protocol\PlayerFallPacket;
|
||||
use pocketmine\network\protocol\PlayerInputPacket;
|
||||
use pocketmine\network\protocol\PlayerListPacket;
|
||||
use pocketmine\network\protocol\PlayStatusPacket;
|
||||
use pocketmine\network\protocol\RemoveBlockPacket;
|
||||
use pocketmine\network\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\protocol\ReplaceItemInSlotPacket;
|
||||
use pocketmine\network\protocol\RequestChunkRadiusPacket;
|
||||
use pocketmine\network\protocol\ResourcePackClientResponsePacket;
|
||||
use pocketmine\network\protocol\ResourcePacksInfoPacket;
|
||||
use pocketmine\network\protocol\RespawnPacket;
|
||||
use pocketmine\network\protocol\SetCommandsEnabledPacket;
|
||||
use pocketmine\network\protocol\SetDifficultyPacket;
|
||||
use pocketmine\network\protocol\SetEntityDataPacket;
|
||||
use pocketmine\network\protocol\SetEntityLinkPacket;
|
||||
use pocketmine\network\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\network\protocol\SetHealthPacket;
|
||||
use pocketmine\network\protocol\SetPlayerGameTypePacket;
|
||||
use pocketmine\network\protocol\SetSpawnPositionPacket;
|
||||
use pocketmine\network\protocol\SetTimePacket;
|
||||
use pocketmine\network\protocol\SpawnExperienceOrbPacket;
|
||||
use pocketmine\network\protocol\StartGamePacket;
|
||||
use pocketmine\network\protocol\TakeItemEntityPacket;
|
||||
use pocketmine\network\protocol\TextPacket;
|
||||
use pocketmine\network\protocol\TransferPacket;
|
||||
use pocketmine\network\protocol\UpdateBlockPacket;
|
||||
use pocketmine\network\protocol\UpdateTradePacket;
|
||||
use pocketmine\network\protocol\UseItemPacket;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddHangingEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddItemEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddItemPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddPaintingPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
|
||||
use pocketmine\network\mcpe\protocol\AnimatePacket;
|
||||
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
|
||||
use pocketmine\network\mcpe\protocol\BatchPacket;
|
||||
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\BlockEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\ChangeDimensionPacket;
|
||||
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket;
|
||||
use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
|
||||
use pocketmine\network\mcpe\protocol\CommandStepPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetSlotPacket;
|
||||
use pocketmine\network\mcpe\protocol\CraftingDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\CraftingEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\DisconnectPacket;
|
||||
use pocketmine\network\mcpe\protocol\DropItemPacket;
|
||||
use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\ExplodePacket;
|
||||
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\HurtArmorPacket;
|
||||
use pocketmine\network\mcpe\protocol\InteractPacket;
|
||||
use pocketmine\network\mcpe\protocol\InventoryActionPacket;
|
||||
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LoginPacket;
|
||||
use pocketmine\network\mcpe\protocol\MapInfoRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\MoveEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerActionPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerFallPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\mcpe\protocol\RemoveBlockPacket;
|
||||
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\ReplaceItemInSlotPacket;
|
||||
use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket;
|
||||
use pocketmine\network\mcpe\protocol\RespawnPacket;
|
||||
use pocketmine\network\mcpe\protocol\RiderJumpPacket;
|
||||
use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetDifficultyPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetEntityDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetEntityLinkPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetHealthPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetTimePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetTitlePacket;
|
||||
use pocketmine\network\mcpe\protocol\ShowCreditsPacket;
|
||||
use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket;
|
||||
use pocketmine\network\mcpe\protocol\StartGamePacket;
|
||||
use pocketmine\network\mcpe\protocol\StopSoundPacket;
|
||||
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\TextPacket;
|
||||
use pocketmine\network\mcpe\protocol\TransferPacket;
|
||||
use pocketmine\network\mcpe\protocol\UnknownPacket;
|
||||
use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
|
||||
use pocketmine\network\mcpe\protocol\UpdateTradePacket;
|
||||
use pocketmine\network\mcpe\protocol\UseItemPacket;
|
||||
use pocketmine\Server;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
|
||||
class Network{
|
||||
|
||||
@ -223,46 +235,6 @@ class Network{
|
||||
return $this->server;
|
||||
}
|
||||
|
||||
public function processBatch(BatchPacket $packet, Player $p){
|
||||
try{
|
||||
if(strlen($packet->payload) === 0){
|
||||
//prevent zlib_decode errors for incorrectly-decoded packets
|
||||
throw new \InvalidArgumentException("BatchPacket payload is empty or packet decode error");
|
||||
}
|
||||
|
||||
$str = zlib_decode($packet->payload, 1024 * 1024 * 64); //Max 64MB
|
||||
$len = strlen($str);
|
||||
|
||||
if($len === 0){
|
||||
throw new \InvalidStateException("Decoded BatchPacket payload is empty");
|
||||
}
|
||||
|
||||
$stream = new BinaryStream($str);
|
||||
|
||||
while($stream->offset < $len){
|
||||
$buf = $stream->getString();
|
||||
|
||||
if(($pk = $this->getPacket(ord($buf{0}))) !== null){
|
||||
if($pk::NETWORK_ID === Info::BATCH_PACKET){
|
||||
throw new \InvalidStateException("Invalid BatchPacket inside BatchPacket");
|
||||
}
|
||||
|
||||
$pk->setBuffer($buf, 1);
|
||||
|
||||
$pk->decode();
|
||||
assert($pk->feof(), "Still " . strlen(substr($pk->buffer, $pk->offset)) . " bytes unread in " . get_class($pk));
|
||||
$p->handleDataPacket($pk);
|
||||
}
|
||||
}
|
||||
}catch(\Throwable $e){
|
||||
if(\pocketmine\DEBUG > 1){
|
||||
$logger = $this->server->getLogger();
|
||||
$logger->debug("BatchPacket " . " 0x" . bin2hex($packet->payload));
|
||||
$logger->logException($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $id
|
||||
*
|
||||
@ -274,7 +246,7 @@ class Network{
|
||||
if($class !== null){
|
||||
return clone $class;
|
||||
}
|
||||
return null;
|
||||
return new UnknownPacket();
|
||||
}
|
||||
|
||||
|
||||
@ -316,8 +288,12 @@ class Network{
|
||||
$this->registerPacket(ProtocolInfo::BATCH_PACKET, BatchPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BLOCK_ENTITY_DATA_PACKET, BlockEntityDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BLOCK_EVENT_PACKET, BlockEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::BLOCK_PICK_REQUEST_PACKET, BlockPickRequestPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CHANGE_DIMENSION_PACKET, ChangeDimensionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET, ChunkRadiusUpdatedPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CLIENTBOUND_MAP_ITEM_DATA_PACKET, ClientboundMapItemDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET, ClientToServerHandshakePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET, CommandBlockUpdatePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::COMMAND_STEP_PACKET, CommandStepPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_CLOSE_PACKET, ContainerClosePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::CONTAINER_OPEN_PACKET, ContainerOpenPacket::class);
|
||||
@ -338,6 +314,7 @@ class Network{
|
||||
$this->registerPacket(ProtocolInfo::LEVEL_EVENT_PACKET, LevelEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::LEVEL_SOUND_EVENT_PACKET, LevelSoundEventPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::LOGIN_PACKET, LoginPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MAP_INFO_REQUEST_PACKET, MapInfoRequestPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOB_ARMOR_EQUIPMENT_PACKET, MobArmorEquipmentPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOB_EQUIPMENT_PACKET, MobEquipmentPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::MOVE_ENTITY_PACKET, MoveEntityPacket::class);
|
||||
@ -346,14 +323,20 @@ class Network{
|
||||
$this->registerPacket(ProtocolInfo::PLAYER_FALL_PACKET, PlayerFallPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAYER_INPUT_PACKET, PlayerInputPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAYER_LIST_PACKET, PlayerListPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAY_SOUND_PACKET, PlaySoundPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::PLAY_STATUS_PACKET, PlayStatusPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REMOVE_BLOCK_PACKET, RemoveBlockPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REMOVE_ENTITY_PACKET, RemoveEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REPLACE_ITEM_IN_SLOT_PACKET, ReplaceItemInSlotPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::REQUEST_CHUNK_RADIUS_PACKET, RequestChunkRadiusPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESOURCE_PACK_CHUNK_DATA_PACKET, ResourcePackChunkDataPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESOURCE_PACK_CHUNK_REQUEST_PACKET, ResourcePackChunkRequestPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESOURCE_PACK_CLIENT_RESPONSE_PACKET, ResourcePackClientResponsePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESOURCE_PACK_DATA_INFO_PACKET, ResourcePackDataInfoPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESOURCE_PACKS_INFO_PACKET, ResourcePacksInfoPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RESPAWN_PACKET, RespawnPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::RIDER_JUMP_PACKET, RiderJumpPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SERVER_TO_CLIENT_HANDSHAKE_PACKET, ServerToClientHandshakePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_COMMANDS_ENABLED_PACKET, SetCommandsEnabledPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_DIFFICULTY_PACKET, SetDifficultyPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_ENTITY_DATA_PACKET, SetEntityDataPacket::class);
|
||||
@ -363,8 +346,11 @@ class Network{
|
||||
$this->registerPacket(ProtocolInfo::SET_PLAYER_GAME_TYPE_PACKET, SetPlayerGameTypePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_SPAWN_POSITION_PACKET, SetSpawnPositionPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_TIME_PACKET, SetTimePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SET_TITLE_PACKET, SetTitlePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SHOW_CREDITS_PACKET, ShowCreditsPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::SPAWN_EXPERIENCE_ORB_PACKET, SpawnExperienceOrbPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::START_GAME_PACKET, StartGamePacket::class);
|
||||
$this->registerPacket(ProtocolInfo::STOP_SOUND_PACKET, StopSoundPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::TAKE_ITEM_ENTITY_PACKET, TakeItemEntityPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::TEXT_PACKET, TextPacket::class);
|
||||
$this->registerPacket(ProtocolInfo::TRANSFER_PACKET, TransferPacket::class);
|
||||
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
namespace pocketmine\network;
|
||||
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\Player;
|
||||
|
||||
/**
|
||||
|
@ -19,7 +19,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network;
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
use raklib\protocol\EncapsulatedPacket;
|
||||
|
297
src/pocketmine/network/mcpe/NetworkSession.php
Normal file
297
src/pocketmine/network/mcpe/NetworkSession.php
Normal file
@ -0,0 +1,297 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\protocol\AddEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddHangingEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddItemEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddItemPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddPaintingPacket;
|
||||
use pocketmine\network\mcpe\protocol\AddPlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\AdventureSettingsPacket;
|
||||
use pocketmine\network\mcpe\protocol\AnimatePacket;
|
||||
use pocketmine\network\mcpe\protocol\AvailableCommandsPacket;
|
||||
use pocketmine\network\mcpe\protocol\BlockEntityDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\BlockEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\BlockPickRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\ChangeDimensionPacket;
|
||||
use pocketmine\network\mcpe\protocol\ChunkRadiusUpdatedPacket;
|
||||
use pocketmine\network\mcpe\protocol\ClientboundMapItemDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ClientToServerHandshakePacket;
|
||||
use pocketmine\network\mcpe\protocol\CommandBlockUpdatePacket;
|
||||
use pocketmine\network\mcpe\protocol\CommandStepPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerClosePacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerOpenPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetContentPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ContainerSetSlotPacket;
|
||||
use pocketmine\network\mcpe\protocol\CraftingDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\CraftingEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\DisconnectPacket;
|
||||
use pocketmine\network\mcpe\protocol\DropItemPacket;
|
||||
use pocketmine\network\mcpe\protocol\EntityEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\ExplodePacket;
|
||||
use pocketmine\network\mcpe\protocol\FullChunkDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\HurtArmorPacket;
|
||||
use pocketmine\network\mcpe\protocol\InteractPacket;
|
||||
use pocketmine\network\mcpe\protocol\InventoryActionPacket;
|
||||
use pocketmine\network\mcpe\protocol\ItemFrameDropItemPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LevelSoundEventPacket;
|
||||
use pocketmine\network\mcpe\protocol\LoginPacket;
|
||||
use pocketmine\network\mcpe\protocol\MapInfoRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobArmorEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEffectPacket;
|
||||
use pocketmine\network\mcpe\protocol\MobEquipmentPacket;
|
||||
use pocketmine\network\mcpe\protocol\MoveEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\MovePlayerPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerActionPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerFallPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerInputPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayerListPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlaySoundPacket;
|
||||
use pocketmine\network\mcpe\protocol\PlayStatusPacket;
|
||||
use pocketmine\network\mcpe\protocol\RemoveBlockPacket;
|
||||
use pocketmine\network\mcpe\protocol\RemoveEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\ReplaceItemInSlotPacket;
|
||||
use pocketmine\network\mcpe\protocol\RequestChunkRadiusPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackChunkDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackChunkRequestPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackClientResponsePacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackDataInfoPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePacksInfoPacket;
|
||||
use pocketmine\network\mcpe\protocol\ResourcePackStackPacket;
|
||||
use pocketmine\network\mcpe\protocol\RespawnPacket;
|
||||
use pocketmine\network\mcpe\protocol\RiderJumpPacket;
|
||||
use pocketmine\network\mcpe\protocol\ServerToClientHandshakePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetCommandsEnabledPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetDifficultyPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetEntityDataPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetEntityLinkPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetEntityMotionPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetHealthPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetPlayerGameTypePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetSpawnPositionPacket;
|
||||
use pocketmine\network\mcpe\protocol\SetTimePacket;
|
||||
use pocketmine\network\mcpe\protocol\SetTitlePacket;
|
||||
use pocketmine\network\mcpe\protocol\ShowCreditsPacket;
|
||||
use pocketmine\network\mcpe\protocol\SpawnExperienceOrbPacket;
|
||||
use pocketmine\network\mcpe\protocol\StartGamePacket;
|
||||
use pocketmine\network\mcpe\protocol\StopSoundPacket;
|
||||
use pocketmine\network\mcpe\protocol\TakeItemEntityPacket;
|
||||
use pocketmine\network\mcpe\protocol\TextPacket;
|
||||
use pocketmine\network\mcpe\protocol\TransferPacket;
|
||||
use pocketmine\network\mcpe\protocol\UnknownPacket;
|
||||
use pocketmine\network\mcpe\protocol\UpdateAttributesPacket;
|
||||
use pocketmine\network\mcpe\protocol\UpdateBlockPacket;
|
||||
use pocketmine\network\mcpe\protocol\UpdateTradePacket;
|
||||
use pocketmine\network\mcpe\protocol\UseItemPacket;
|
||||
use pocketmine\Server;
|
||||
|
||||
interface NetworkSession{
|
||||
|
||||
/**
|
||||
* @return Server
|
||||
*/
|
||||
public function getServer();
|
||||
|
||||
public function handleDataPacket(DataPacket $pk);
|
||||
|
||||
public function handleLogin(LoginPacket $packet) : bool;
|
||||
|
||||
public function handlePlayStatus(PlayStatusPacket $packet) : bool;
|
||||
|
||||
public function handleServerToClientHandshake(ServerToClientHandshakePacket $packet) : bool;
|
||||
|
||||
public function handleClientToServerHandshake(ClientToServerHandshakePacket $packet) : bool;
|
||||
|
||||
public function handleDisconnect(DisconnectPacket $packet) : bool;
|
||||
|
||||
public function handleResourcePacksInfo(ResourcePacksInfoPacket $packet) : bool;
|
||||
|
||||
public function handleResourcePackStack(ResourcePackStackPacket $packet) : bool;
|
||||
|
||||
public function handleResourcePackClientResponse(ResourcePackClientResponsePacket $packet) : bool;
|
||||
|
||||
public function handleText(TextPacket $packet) : bool;
|
||||
|
||||
public function handleSetTime(SetTimePacket $packet) : bool;
|
||||
|
||||
public function handleStartGame(StartGamePacket $packet) : bool;
|
||||
|
||||
public function handleAddPlayer(AddPlayerPacket $packet) : bool;
|
||||
|
||||
public function handleAddEntity(AddEntityPacket $packet) : bool;
|
||||
|
||||
public function handleRemoveEntity(RemoveEntityPacket $packet) : bool;
|
||||
|
||||
public function handleAddItemEntity(AddItemEntityPacket $packet) : bool;
|
||||
|
||||
public function handleAddHangingEntity(AddHangingEntityPacket $packet) : bool;
|
||||
|
||||
public function handleTakeItemEntity(TakeItemEntityPacket $packet) : bool;
|
||||
|
||||
public function handleMoveEntity(MoveEntityPacket $packet) : bool;
|
||||
|
||||
public function handleMovePlayer(MovePlayerPacket $packet) : bool;
|
||||
|
||||
public function handleRiderJump(RiderJumpPacket $packet) : bool;
|
||||
|
||||
public function handleRemoveBlock(RemoveBlockPacket $packet) : bool;
|
||||
|
||||
public function handleUpdateBlock(UpdateBlockPacket $packet) : bool;
|
||||
|
||||
public function handleAddPainting(AddPaintingPacket $packet) : bool;
|
||||
|
||||
public function handleExplode(ExplodePacket $packet) : bool;
|
||||
|
||||
public function handleLevelSoundEvent(LevelSoundEventPacket $packet) : bool;
|
||||
|
||||
public function handleLevelEvent(LevelEventPacket $packet) : bool;
|
||||
|
||||
public function handleBlockEvent(BlockEventPacket $packet) : bool;
|
||||
|
||||
public function handleEntityEvent(EntityEventPacket $packet) : bool;
|
||||
|
||||
public function handleMobEffect(MobEffectPacket $packet) : bool;
|
||||
|
||||
public function handleUpdateAttributes(UpdateAttributesPacket $packet) : bool;
|
||||
|
||||
public function handleMobEquipment(MobEquipmentPacket $packet) : bool;
|
||||
|
||||
public function handleMobArmorEquipment(MobArmorEquipmentPacket $packet) : bool;
|
||||
|
||||
public function handleInteract(InteractPacket $packet) : bool;
|
||||
|
||||
public function handleBlockPickRequest(BlockPickRequestPacket $packet) : bool;
|
||||
|
||||
public function handleUseItem(UseItemPacket $packet) : bool;
|
||||
|
||||
public function handlePlayerAction(PlayerActionPacket $packet) : bool;
|
||||
|
||||
public function handlePlayerFall(PlayerFallPacket $packet) : bool;
|
||||
|
||||
public function handleHurtArmor(HurtArmorPacket $packet) : bool;
|
||||
|
||||
public function handleSetEntityData(SetEntityDataPacket $packet) : bool;
|
||||
|
||||
public function handleSetEntityMotion(SetEntityMotionPacket $packet) : bool;
|
||||
|
||||
public function handleSetEntityLink(SetEntityLinkPacket $packet) : bool;
|
||||
|
||||
public function handleSetHealth(SetHealthPacket $packet) : bool;
|
||||
|
||||
public function handleSetSpawnPosition(SetSpawnPositionPacket $packet) : bool;
|
||||
|
||||
public function handleAnimate(AnimatePacket $packet) : bool;
|
||||
|
||||
public function handleRespawn(RespawnPacket $packet) : bool;
|
||||
|
||||
public function handleDropItem(DropItemPacket $packet) : bool;
|
||||
|
||||
public function handleInventoryAction(InventoryActionPacket $packet) : bool;
|
||||
|
||||
public function handleContainerOpen(ContainerOpenPacket $packet) : bool;
|
||||
|
||||
public function handleContainerClose(ContainerClosePacket $packet) : bool;
|
||||
|
||||
public function handleContainerSetSlot(ContainerSetSlotPacket $packet) : bool;
|
||||
|
||||
public function handleContainerSetData(ContainerSetDataPacket $packet) : bool;
|
||||
|
||||
public function handleContainerSetContent(ContainerSetContentPacket $packet) : bool;
|
||||
|
||||
public function handleCraftingData(CraftingDataPacket $packet) : bool;
|
||||
|
||||
public function handleCraftingEvent(CraftingEventPacket $packet) : bool;
|
||||
|
||||
public function handleAdventureSettings(AdventureSettingsPacket $packet) : bool;
|
||||
|
||||
public function handleBlockEntityData(BlockEntityDataPacket $packet) : bool;
|
||||
|
||||
public function handlePlayerInput(PlayerInputPacket $packet) : bool;
|
||||
|
||||
public function handleFullChunkData(FullChunkDataPacket $packet) : bool;
|
||||
|
||||
public function handleSetCommandsEnabled(SetCommandsEnabledPacket $packet) : bool;
|
||||
|
||||
public function handleSetDifficulty(SetDifficultyPacket $packet) : bool;
|
||||
|
||||
public function handleChangeDimension(ChangeDimensionPacket $packet) : bool;
|
||||
|
||||
public function handleSetPlayerGameType(SetPlayerGameTypePacket $packet) : bool;
|
||||
|
||||
public function handlePlayerList(PlayerListPacket $packet) : bool;
|
||||
|
||||
//public function handleTelemetryEvent(EventPacket $packet) : bool; //TODO
|
||||
|
||||
public function handleSpawnExperienceOrb(SpawnExperienceOrbPacket $packet) : bool;
|
||||
|
||||
public function handleClientboundMapItemData(ClientboundMapItemDataPacket $packet) : bool;
|
||||
|
||||
public function handleMapInfoRequest(MapInfoRequestPacket $packet) : bool; //TODO
|
||||
|
||||
public function handleRequestChunkRadius(RequestChunkRadiusPacket $packet) : bool;
|
||||
|
||||
public function handleChunkRadiusUpdated(ChunkRadiusUpdatedPacket $packet) : bool;
|
||||
|
||||
public function handleItemFrameDropItem(ItemFrameDropItemPacket $packet) : bool;
|
||||
|
||||
public function handleReplaceItemInSlot(ReplaceItemInSlotPacket $packet) : bool;
|
||||
|
||||
//public function handleGameRulesChanged(GameRulesChangedPacket $packet) : bool; //TODO
|
||||
|
||||
//public function handleCamera(CameraPacket $packet) : bool; //edu only :(
|
||||
|
||||
public function handleAddItem(AddItemPacket $packet) : bool;
|
||||
|
||||
//public function handleBossEvent(BossEventPacket $packet) : bool;
|
||||
|
||||
public function handleShowCredits(ShowCreditsPacket $packet) : bool;
|
||||
|
||||
public function handleAvailableCommands(AvailableCommandsPacket $packet) : bool;
|
||||
|
||||
public function handleCommandStep(CommandStepPacket $packet) : bool;
|
||||
|
||||
public function handleCommandBlockUpdate(CommandBlockUpdatePacket $packet) : bool;
|
||||
|
||||
public function handleUpdateTrade(UpdateTradePacket $packet) : bool;
|
||||
|
||||
public function handleResourcePackDataInfo(ResourcePackDataInfoPacket $packet) : bool;
|
||||
|
||||
public function handleResourcePackChunkData(ResourcePackChunkDataPacket $packet) : bool;
|
||||
|
||||
public function handleResourcePackChunkRequest(ResourcePackChunkRequestPacket $packet) : bool;
|
||||
|
||||
public function handleTransfer(TransferPacket $packet) : bool;
|
||||
|
||||
public function handlePlaySound(PlaySoundPacket $packet) : bool;
|
||||
|
||||
public function handleStopSound(StopSoundPacket $packet) : bool;
|
||||
|
||||
public function handleSetTitle(SetTitlePacket $packet) : bool;
|
||||
|
||||
public function handleUnknown(UnknownPacket $packet) : bool;
|
||||
}
|
@ -19,12 +19,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network;
|
||||
namespace pocketmine\network\mcpe;
|
||||
|
||||
use pocketmine\event\player\PlayerCreationEvent;
|
||||
use pocketmine\network\protocol\DataPacket;
|
||||
use pocketmine\network\protocol\Info;
|
||||
use pocketmine\network\protocol\Info as ProtocolInfo;
|
||||
use pocketmine\network\AdvancedSourceInterface;
|
||||
use pocketmine\network\mcpe\protocol\DataPacket;
|
||||
use pocketmine\network\mcpe\protocol\ProtocolInfo;
|
||||
use pocketmine\network\Network;
|
||||
use pocketmine\Player;
|
||||
use pocketmine\Server;
|
||||
use raklib\protocol\EncapsulatedPacket;
|
||||
@ -131,11 +132,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{
|
||||
try{
|
||||
if($packet->buffer !== ""){
|
||||
$pk = $this->getPacket($packet->buffer);
|
||||
if($pk !== null){
|
||||
$pk->decode();
|
||||
assert($pk->feof(), "Still " . strlen(substr($pk->buffer, $pk->offset)) . " bytes unread!");
|
||||
$this->players[$identifier]->handleDataPacket($pk);
|
||||
}
|
||||
$this->players[$identifier]->handleDataPacket($pk);
|
||||
}
|
||||
}catch(\Throwable $e){
|
||||
if(\pocketmine\DEBUG > 1 and isset($pk)){
|
||||
@ -172,8 +169,8 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{
|
||||
|
||||
$this->interface->sendOption("name",
|
||||
"MCPE;" . rtrim(addcslashes($name, ";"), '\\') . ";" .
|
||||
Info::CURRENT_PROTOCOL . ";" .
|
||||
Info::MINECRAFT_VERSION_NETWORK . ";" .
|
||||
ProtocolInfo::CURRENT_PROTOCOL . ";" .
|
||||
ProtocolInfo::MINECRAFT_VERSION_NETWORK . ";" .
|
||||
$info->getPlayerCount() . ";" .
|
||||
$info->getMaxPlayerCount()
|
||||
);
|
||||
@ -208,7 +205,7 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{
|
||||
$pk = $packet->__encapsulatedPacket;
|
||||
}
|
||||
|
||||
if(!$immediate and !$needACK and $packet::NETWORK_ID !== ProtocolInfo::BATCH_PACKET
|
||||
if(!$immediate and !$needACK and $packet->canBeBatched()
|
||||
and Network::$BATCH_THRESHOLD >= 0
|
||||
and strlen($packet->buffer) >= Network::$BATCH_THRESHOLD){
|
||||
$this->server->batchPackets([$player], [$packet], true);
|
||||
@ -218,8 +215,8 @@ class RakLibInterface implements ServerInstance, AdvancedSourceInterface{
|
||||
if($pk === null){
|
||||
$pk = new EncapsulatedPacket();
|
||||
$pk->buffer = chr(0xfe) . $packet->buffer; // #blameshoghi
|
||||
$packet->reliability = PacketReliability::RELIABLE_ORDERED;
|
||||
$packet->orderChannel = 0;
|
||||
$pk->reliability = PacketReliability::RELIABLE_ORDERED;
|
||||
$pk->orderChannel = 0;
|
||||
|
||||
if($needACK === true){
|
||||
$pk->identifierACK = $this->identifiersACK[$identifier]++;
|
@ -19,14 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\entity\Attribute;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AddEntityPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADD_ENTITY_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ADD_ENTITY_PACKET;
|
||||
|
||||
public $eid;
|
||||
public $type;
|
||||
@ -49,8 +50,8 @@ class AddEntityPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putEntityId($this->eid); //EntityUniqueID - TODO: verify this
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putEntityUniqueId($this->eid);
|
||||
$this->putEntityRuntimeId($this->eid);
|
||||
$this->putUnsignedVarInt($this->type);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVector3f($this->speedX, $this->speedY, $this->speedZ);
|
||||
@ -66,10 +67,14 @@ class AddEntityPacket extends DataPacket{
|
||||
$this->putEntityMetadata($this->metadata);
|
||||
$this->putUnsignedVarInt(count($this->links));
|
||||
foreach($this->links as $link){
|
||||
$this->putEntityId($link[0]);
|
||||
$this->putEntityId($link[1]);
|
||||
$this->putEntityUniqueId($link[0]);
|
||||
$this->putEntityUniqueId($link[1]);
|
||||
$this->putByte($link[2]);
|
||||
}
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAddEntity($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,12 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AddHangingEntityPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADD_HANGING_ENTITY_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ADD_HANGING_ENTITY_PACKET;
|
||||
|
||||
public $entityUniqueId;
|
||||
public $entityRuntimeId;
|
||||
@ -39,10 +41,14 @@ class AddHangingEntityPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putEntityId($this->entityUniqueId);
|
||||
$this->putEntityId($this->entityRuntimeId);
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putEntityUniqueId($this->entityUniqueId);
|
||||
$this->putEntityRuntimeId($this->entityRuntimeId);
|
||||
$this->putBlockPosition($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->unknown);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAddHangingEntity($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AddItemEntityPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADD_ITEM_ENTITY_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ADD_ITEM_ENTITY_PACKET;
|
||||
|
||||
public $eid;
|
||||
public $item;
|
||||
@ -42,11 +44,15 @@ class AddItemEntityPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putEntityId($this->eid); //EntityUniqueID
|
||||
$this->putEntityId($this->eid); //EntityRuntimeID
|
||||
$this->putEntityUniqueId($this->eid);
|
||||
$this->putEntityRuntimeId($this->eid);
|
||||
$this->putSlot($this->item);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVector3f($this->speedX, $this->speedY, $this->speedZ);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAddItemEntity($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AddItemPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADD_ITEM_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ADD_ITEM_PACKET;
|
||||
|
||||
public $item;
|
||||
|
||||
@ -38,4 +40,8 @@ class AddItemPacket extends DataPacket{
|
||||
$this->putSlot($this->item);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAddItem($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AddPaintingPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADD_PAINTING_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ADD_PAINTING_PACKET;
|
||||
|
||||
public $eid;
|
||||
public $x;
|
||||
@ -40,11 +42,15 @@ class AddPaintingPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putEntityId($this->eid); //EntityUniqueID
|
||||
$this->putEntityId($this->eid); //EntityRuntimeID
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putEntityUniqueId($this->eid);
|
||||
$this->putEntityRuntimeId($this->eid);
|
||||
$this->putBlockPosition($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->direction);
|
||||
$this->putString($this->title);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAddPainting($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,12 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AddPlayerPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADD_PLAYER_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ADD_PLAYER_PACKET;
|
||||
|
||||
public $uuid;
|
||||
public $username;
|
||||
@ -49,8 +51,8 @@ class AddPlayerPacket extends DataPacket{
|
||||
$this->reset();
|
||||
$this->putUUID($this->uuid);
|
||||
$this->putString($this->username);
|
||||
$this->putEntityId($this->eid); //EntityUniqueID
|
||||
$this->putEntityId($this->eid); //EntityRuntimeID
|
||||
$this->putEntityUniqueId($this->eid);
|
||||
$this->putEntityRuntimeId($this->eid);
|
||||
$this->putVector3f($this->x, $this->y, $this->z);
|
||||
$this->putVector3f($this->speedX, $this->speedY, $this->speedZ);
|
||||
$this->putLFloat($this->pitch);
|
||||
@ -60,4 +62,8 @@ class AddPlayerPacket extends DataPacket{
|
||||
$this->putEntityMetadata($this->metadata);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAddPlayer($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AdventureSettingsPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ADVENTURE_SETTINGS_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ADVENTURE_SETTINGS_PACKET;
|
||||
|
||||
const PERMISSION_NORMAL = 0;
|
||||
const PERMISSION_OPERATOR = 1;
|
||||
@ -95,4 +97,8 @@ class AdventureSettingsPacket extends DataPacket{
|
||||
$this->putUnsignedVarInt($this->userPermission);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAdventureSettings($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,26 +19,32 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AnimatePacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ANIMATE_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ANIMATE_PACKET;
|
||||
|
||||
public $action;
|
||||
public $eid;
|
||||
|
||||
public function decode(){
|
||||
$this->action = $this->getVarInt();
|
||||
$this->eid = $this->getEntityId();
|
||||
$this->eid = $this->getEntityRuntimeId();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putVarInt($this->action);
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putEntityRuntimeId($this->eid);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAnimate($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,12 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class AvailableCommandsPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::AVAILABLE_COMMANDS_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::AVAILABLE_COMMANDS_PACKET;
|
||||
|
||||
public $commands; //JSON-encoded command data
|
||||
public $unknown;
|
||||
@ -39,4 +41,8 @@ class AvailableCommandsPacket extends DataPacket{
|
||||
$this->putString($this->unknown);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleAvailableCommands($this);
|
||||
}
|
||||
|
||||
}
|
80
src/pocketmine/network/mcpe/protocol/BatchPacket.php
Normal file
80
src/pocketmine/network/mcpe/protocol/BatchPacket.php
Normal file
@ -0,0 +1,80 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class BatchPacket extends DataPacket{
|
||||
const NETWORK_ID = ProtocolInfo::BATCH_PACKET;
|
||||
|
||||
public $payload;
|
||||
|
||||
public function canBeBatched() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
public function canBeSentBeforeLogin() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
$this->payload = $this->getString();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putString($this->payload);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
if(strlen($this->payload) < 2){
|
||||
throw new \InvalidStateException("Not enough bytes in payload, expected zlib header");
|
||||
}
|
||||
|
||||
$str = zlib_decode($this->payload, 1024 * 1024 * 64); //Max 64MB
|
||||
$len = strlen($str);
|
||||
|
||||
if($len === 0){
|
||||
throw new \InvalidStateException("Decoded BatchPacket payload is empty");
|
||||
}
|
||||
|
||||
$this->setBuffer($str, 0);
|
||||
|
||||
$network = $session->getServer()->getNetwork();
|
||||
while(!$this->feof()){
|
||||
$buf = $this->getString();
|
||||
$pk = $network->getPacket(ord($buf{0}));
|
||||
if(!$pk->canBeBatched()){
|
||||
throw new \InvalidArgumentException("Received invalid " . get_class($pk) . " inside BatchPacket");
|
||||
}
|
||||
|
||||
$pk->setBuffer($buf, 1);
|
||||
$session->handleDataPacket($pk);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class BlockEntityDataPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::BLOCK_ENTITY_DATA_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::BLOCK_ENTITY_DATA_PACKET;
|
||||
|
||||
public $x;
|
||||
public $y;
|
||||
@ -33,14 +35,18 @@ class BlockEntityDataPacket extends DataPacket{
|
||||
public $namedtag;
|
||||
|
||||
public function decode(){
|
||||
$this->getBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->getBlockPosition($this->x, $this->y, $this->z);
|
||||
$this->namedtag = $this->get(true);
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putBlockPosition($this->x, $this->y, $this->z);
|
||||
$this->put($this->namedtag);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleBlockEntityData($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class BlockEventPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::BLOCK_EVENT_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::BLOCK_EVENT_PACKET;
|
||||
|
||||
public $x;
|
||||
public $y;
|
||||
@ -39,9 +41,13 @@ class BlockEventPacket extends DataPacket{
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putBlockPosition($this->x, $this->y, $this->z);
|
||||
$this->putVarInt($this->case1);
|
||||
$this->putVarInt($this->case2);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleBlockEvent($this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class BlockPickRequestPacket extends DataPacket{
|
||||
const NETWORK_ID = ProtocolInfo::BLOCK_PICK_REQUEST_PACKET;
|
||||
|
||||
public $tileX;
|
||||
public $tileY;
|
||||
public $tileZ;
|
||||
public $hotbarSlot;
|
||||
|
||||
public function decode(){
|
||||
$this->getSignedBlockPosition($this->tileX, $this->tileY, $this->tileZ);
|
||||
$this->hotbarSlot = $this->getByte();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putSignedBlockPosition($this->tileX, $this->tileY, $this->tileZ);
|
||||
$this->putByte($this->hotbarSlot);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleBlockPickRequest($this);
|
||||
}
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ChangeDimensionPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CHANGE_DIMENSION_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CHANGE_DIMENSION_PACKET;
|
||||
|
||||
const DIMENSION_OVERWORLD = 0;
|
||||
const DIMENSION_NETHER = 1;
|
||||
@ -47,4 +49,8 @@ class ChangeDimensionPacket extends DataPacket{
|
||||
$this->putBool($this->unknown);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleChangeDimension($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ChunkRadiusUpdatedPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CHUNK_RADIUS_UPDATED_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CHUNK_RADIUS_UPDATED_PACKET;
|
||||
|
||||
public $radius;
|
||||
|
||||
@ -37,4 +39,8 @@ class ChunkRadiusUpdatedPacket extends DataPacket{
|
||||
$this->putVarInt($this->radius);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleChunkRadiusUpdated($this);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ClientToServerHandshakePacket extends DataPacket{
|
||||
const NETWORK_ID = ProtocolInfo::CLIENT_TO_SERVER_HANDSHAKE_PACKET;
|
||||
|
||||
public function canBeSentBeforeLogin() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
//No payload
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
//No payload
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleClientToServerHandshake($this);
|
||||
}
|
||||
}
|
@ -0,0 +1,149 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\utils\Color;
|
||||
|
||||
class ClientboundMapItemDataPacket extends DataPacket{
|
||||
const NETWORK_ID = ProtocolInfo::CLIENTBOUND_MAP_ITEM_DATA_PACKET;
|
||||
|
||||
const BITFLAG_TEXTURE_UPDATE = 0x02;
|
||||
const BITFLAG_DECORATION_UPDATE = 0x04;
|
||||
|
||||
public $mapId;
|
||||
public $type;
|
||||
|
||||
public $eids = [];
|
||||
public $scale;
|
||||
public $decorations = [];
|
||||
|
||||
public $width;
|
||||
public $height;
|
||||
public $xOffset = 0;
|
||||
public $yOffset = 0;
|
||||
/** @var Color[][] */
|
||||
public $colors = [];
|
||||
|
||||
public function decode(){
|
||||
$this->mapId = $this->getVarInt();
|
||||
$this->type = $this->getUnsignedVarInt();
|
||||
|
||||
if(($this->type & 0x08) !== 0){
|
||||
$count = $this->getUnsignedVarInt();
|
||||
for($i = 0; $i < $count; ++$i){
|
||||
$this->eids[] = $this->getVarInt(); //entity unique ID, signed var-int
|
||||
}
|
||||
}
|
||||
|
||||
if(($this->type & (self::BITFLAG_DECORATION_UPDATE | self::BITFLAG_TEXTURE_UPDATE)) !== 0){ //Decoration bitflag or colour bitflag
|
||||
$this->scale = $this->getByte();
|
||||
}
|
||||
|
||||
if(($this->type & self::BITFLAG_DECORATION_UPDATE) !== 0){
|
||||
$count = $this->getUnsignedVarInt();
|
||||
for($i = 0; $i < $count; ++$i){
|
||||
$weird = $this->getVarInt();
|
||||
$this->decorations[$i]["rot"] = $weird & 0x0f;
|
||||
$this->decorations[$i]["img"] = $weird >> 4;
|
||||
|
||||
$this->decorations[$i]["xOffset"] = $this->getByte();
|
||||
$this->decorations[$i]["yOffset"] = $this->getByte();
|
||||
$this->decorations[$i]["label"] = $this->getString();
|
||||
|
||||
$this->decorations[$i]["color"] = Color::fromARGB($this->getLInt()); //already BE, don't need to reverse it again
|
||||
}
|
||||
}
|
||||
|
||||
if(($this->type & self::BITFLAG_TEXTURE_UPDATE) !== 0){
|
||||
$this->width = $this->getVarInt();
|
||||
$this->height = $this->getVarInt();
|
||||
$this->xOffset = $this->getVarInt();
|
||||
$this->yOffset = $this->getVarInt();
|
||||
for($y = 0; $y < $this->height; ++$y){
|
||||
for($x = 0; $x < $this->width; ++$x){
|
||||
$this->colors[$y][$x] = Color::fromABGR($this->getUnsignedVarInt());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putVarInt($this->mapId); //entity unique ID, signed var-int
|
||||
|
||||
$type = 0;
|
||||
if(($eidsCount = count($this->eids)) > 0){
|
||||
$type |= 0x08;
|
||||
}
|
||||
if(($decorationCount = count($this->decorations)) > 0){
|
||||
$type |= self::BITFLAG_DECORATION_UPDATE;
|
||||
}
|
||||
if(count($this->colors) > 0){
|
||||
$type |= self::BITFLAG_TEXTURE_UPDATE;
|
||||
}
|
||||
|
||||
$this->putUnsignedVarInt($type);
|
||||
|
||||
if(($type & 0x08) !== 0){ //TODO: find out what these are for
|
||||
$this->putUnsignedVarInt($eidsCount);
|
||||
foreach($this->eids as $eid){
|
||||
$this->putVarInt($eid);
|
||||
}
|
||||
}
|
||||
|
||||
if(($type & (self::BITFLAG_TEXTURE_UPDATE | self::BITFLAG_DECORATION_UPDATE)) !== 0){
|
||||
$this->putByte($this->scale);
|
||||
}
|
||||
|
||||
if(($type & self::BITFLAG_DECORATION_UPDATE) !== 0){
|
||||
$this->putUnsignedVarInt($decorationCount);
|
||||
foreach($this->decorations as $decoration){
|
||||
$this->putVarInt(($decoration["rot"] & 0x0f) | ($decoration["img"] << 4));
|
||||
$this->putByte($decoration["xOffset"]);
|
||||
$this->putByte($decoration["yOffset"]);
|
||||
$this->putString($decoration["label"]);
|
||||
$this->putLInt($decoration["color"]->toARGB());
|
||||
}
|
||||
}
|
||||
|
||||
if(($type & self::BITFLAG_TEXTURE_UPDATE) !== 0){
|
||||
$this->putVarInt($this->width);
|
||||
$this->putVarInt($this->height);
|
||||
$this->putVarInt($this->xOffset);
|
||||
$this->putVarInt($this->yOffset);
|
||||
for($y = 0; $y < $this->height; ++$y){
|
||||
for($x = 0; $x < $this->width; ++$x){
|
||||
$this->putUnsignedVarInt($this->colors[$y][$x]->toABGR());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleClientboundMapItemData($this);
|
||||
}
|
||||
}
|
@ -0,0 +1,93 @@
|
||||
<?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/
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class CommandBlockUpdatePacket extends DataPacket{
|
||||
const NETWORK_ID = ProtocolInfo::COMMAND_BLOCK_UPDATE_PACKET;
|
||||
|
||||
public $isBlock;
|
||||
|
||||
public $x;
|
||||
public $y;
|
||||
public $z;
|
||||
public $commandBlockMode;
|
||||
public $isRedstoneMode;
|
||||
public $isConditional;
|
||||
|
||||
public $minecartEid;
|
||||
|
||||
public $command;
|
||||
public $lastOutput;
|
||||
public $name;
|
||||
|
||||
public $shouldTrackOutput;
|
||||
|
||||
public function decode(){
|
||||
$this->isBlock = $this->getBool();
|
||||
|
||||
if($this->isBlock){
|
||||
$this->getBlockPosition($this->x, $this->y, $this->z);
|
||||
$this->commandBlockMode = $this->getUnsignedVarInt();
|
||||
$this->isRedstoneMode = $this->getBool();
|
||||
$this->isConditional = $this->getBool();
|
||||
}else{
|
||||
//Minecart with command block
|
||||
$this->minecartEid = $this->getEntityRuntimeId();
|
||||
}
|
||||
|
||||
$this->command = $this->getString();
|
||||
$this->lastOutput = $this->getString();
|
||||
$this->name = $this->getString();
|
||||
|
||||
$this->shouldTrackOutput = $this->getBool();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putBool($this->isBlock);
|
||||
|
||||
if($this->isBlock){
|
||||
$this->putBlockPosition($this->x, $this->y, $this->z);
|
||||
$this->putUnsignedVarInt($this->commandBlockMode);
|
||||
$this->putBool($this->isRedstoneMode);
|
||||
$this->putBool($this->isConditional);
|
||||
}else{
|
||||
$this->putEntityRuntimeId($this->minecartEid);
|
||||
}
|
||||
|
||||
$this->putString($this->command);
|
||||
$this->putString($this->lastOutput);
|
||||
$this->putString($this->name);
|
||||
|
||||
$this->putBool($this->shouldTrackOutput);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleCommandBlockUpdate($this);
|
||||
}
|
||||
}
|
@ -19,24 +19,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
class CommandStepPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::COMMAND_STEP_PACKET;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
/**
|
||||
* unknown (string)
|
||||
* unknown (string)
|
||||
* unknown (uvarint)
|
||||
* unknown (uvarint)
|
||||
* unknown (bool)
|
||||
* unknown (uvarint64)
|
||||
* unknown (string)
|
||||
* unknown (string)
|
||||
* https://gist.github.com/dktapps/8285b93af4ca38e0104bfeb9a6c87afd
|
||||
*/
|
||||
class CommandStepPacket extends DataPacket{
|
||||
const NETWORK_ID = ProtocolInfo::COMMAND_STEP_PACKET;
|
||||
|
||||
public $command;
|
||||
public $overload;
|
||||
@ -44,7 +34,7 @@ class CommandStepPacket extends DataPacket{
|
||||
public $uvarint2;
|
||||
public $bool;
|
||||
public $uvarint64;
|
||||
public $args; //JSON formatted command arguments
|
||||
public $args;
|
||||
public $string4;
|
||||
|
||||
public function decode(){
|
||||
@ -53,16 +43,19 @@ class CommandStepPacket extends DataPacket{
|
||||
$this->uvarint1 = $this->getUnsignedVarInt();
|
||||
$this->uvarint2 = $this->getUnsignedVarInt();
|
||||
$this->bool = (bool) $this->getByte();
|
||||
$this->uvarint64 = $this->getUnsignedVarInt(); //TODO: varint64
|
||||
$this->uvarint64 = $this->getUnsignedVarLong();
|
||||
$this->args = json_decode($this->getString());
|
||||
$this->string4 = $this->getString();
|
||||
while(!$this->feof()){
|
||||
$this->getByte(); //prevent assertion errors. TODO: find out why there are always 3 extra bytes at the end of this packet.
|
||||
}
|
||||
|
||||
$this->get(true); //TODO: read command origin data
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleCommandStep($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ContainerClosePacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CONTAINER_CLOSE_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CONTAINER_CLOSE_PACKET;
|
||||
|
||||
public $windowid;
|
||||
|
||||
@ -38,4 +40,7 @@ class ContainerClosePacket extends DataPacket{
|
||||
$this->putByte($this->windowid);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleContainerClose($this);
|
||||
}
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ContainerOpenPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CONTAINER_OPEN_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CONTAINER_OPEN_PACKET;
|
||||
|
||||
public $windowid;
|
||||
public $type;
|
||||
@ -44,8 +46,12 @@ class ContainerOpenPacket extends DataPacket{
|
||||
$this->putByte($this->windowid);
|
||||
$this->putByte($this->type);
|
||||
$this->putVarInt($this->slots);
|
||||
$this->putBlockCoords($this->x, $this->y, $this->z);
|
||||
$this->putEntityId($this->entityId);
|
||||
$this->putBlockPosition($this->x, $this->y, $this->z);
|
||||
$this->putEntityUniqueId($this->entityId);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleContainerOpen($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ContainerSetContentPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CONTAINER_SET_CONTENT_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CONTAINER_SET_CONTENT_PACKET;
|
||||
|
||||
const SPECIAL_INVENTORY = 0;
|
||||
const SPECIAL_ARMOR = 0x78;
|
||||
@ -73,4 +75,8 @@ class ContainerSetContentPacket extends DataPacket{
|
||||
}
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleContainerSetContent($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ContainerSetDataPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CONTAINER_SET_DATA_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CONTAINER_SET_DATA_PACKET;
|
||||
|
||||
public $windowid;
|
||||
public $property;
|
||||
@ -42,4 +44,8 @@ class ContainerSetDataPacket extends DataPacket{
|
||||
$this->putVarInt($this->value);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleContainerSetData($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,14 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ContainerSetSlotPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CONTAINER_SET_SLOT_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CONTAINER_SET_SLOT_PACKET;
|
||||
|
||||
public $windowid;
|
||||
public $slot;
|
||||
@ -52,4 +53,8 @@ class ContainerSetSlotPacket extends DataPacket{
|
||||
$this->putByte($this->selectSlot);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleContainerSetSlot($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,20 +19,20 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\inventory\FurnaceRecipe;
|
||||
use pocketmine\inventory\MultiRecipe;
|
||||
use pocketmine\inventory\ShapedRecipe;
|
||||
use pocketmine\inventory\ShapelessRecipe;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
|
||||
class CraftingDataPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CRAFTING_DATA_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CRAFTING_DATA_PACKET;
|
||||
|
||||
const ENTRY_SHAPELESS = 0;
|
||||
const ENTRY_SHAPED = 1;
|
||||
@ -198,4 +198,8 @@ class CraftingDataPacket extends DataPacket{
|
||||
$this->putBool($this->cleanRecipes);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleCraftingData($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,14 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class CraftingEventPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::CRAFTING_EVENT_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::CRAFTING_EVENT_PACKET;
|
||||
|
||||
public $windowId;
|
||||
public $type;
|
||||
@ -62,4 +63,8 @@ class CraftingEventPacket extends DataPacket{
|
||||
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleCraftingEvent($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,12 +19,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
use pocketmine\entity\Entity;
|
||||
use pocketmine\item\Item;
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
use pocketmine\utils\BinaryStream;
|
||||
use pocketmine\utils\Utils;
|
||||
|
||||
@ -39,10 +40,20 @@ abstract class DataPacket extends BinaryStream{
|
||||
return $this::NETWORK_ID;
|
||||
}
|
||||
|
||||
public function canBeBatched() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function canBeSentBeforeLogin() : bool{
|
||||
return false;
|
||||
}
|
||||
|
||||
abstract public function encode();
|
||||
|
||||
abstract public function decode();
|
||||
|
||||
abstract public function handle(NetworkSession $session) : bool;
|
||||
|
||||
public function reset(){
|
||||
$this->buffer = chr($this::NETWORK_ID);
|
||||
$this->offset = 0;
|
||||
@ -109,17 +120,15 @@ abstract class DataPacket extends BinaryStream{
|
||||
$value[2] = $item->getDamage();
|
||||
break;
|
||||
case Entity::DATA_TYPE_POS:
|
||||
$value = [];
|
||||
$value[0] = $this->getVarInt(); //x
|
||||
$value[1] = $this->getVarInt(); //y (SIGNED)
|
||||
$value[2] = $this->getVarInt(); //z
|
||||
$value = [0, 0, 0];
|
||||
$this->getSignedBlockPosition(...$value);
|
||||
break;
|
||||
case Entity::DATA_TYPE_LONG:
|
||||
$value = $this->getVarInt(); //TODO: varint64 proper support
|
||||
$value = $this->getVarLong();
|
||||
break;
|
||||
case Entity::DATA_TYPE_VECTOR3F:
|
||||
$value = [0.0, 0.0, 0.0];
|
||||
$this->getVector3f($value[0], $value[1], $value[2]);
|
||||
$this->getVector3f(...$value);
|
||||
break;
|
||||
default:
|
||||
$value = [];
|
||||
@ -166,17 +175,119 @@ abstract class DataPacket extends BinaryStream{
|
||||
break;
|
||||
case Entity::DATA_TYPE_POS:
|
||||
//TODO: change this implementation (use objects)
|
||||
$this->putVarInt($d[1][0]); //x
|
||||
$this->putVarInt($d[1][1]); //y (SIGNED)
|
||||
$this->putVarInt($d[1][2]); //z
|
||||
$this->putSignedBlockPosition(...$d[1]);
|
||||
break;
|
||||
case Entity::DATA_TYPE_LONG:
|
||||
$this->putVarInt($d[1]); //TODO: varint64 support
|
||||
$this->putVarLong($d[1]);
|
||||
break;
|
||||
case Entity::DATA_TYPE_VECTOR3F:
|
||||
//TODO: change this implementation (use objects)
|
||||
$this->putVector3f($d[1][0], $d[1][1], $d[1][2]); //x, y, z
|
||||
$this->putVector3f(...$d[1]); //x, y, z
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and returns an EntityUniqueID
|
||||
* @return int|string
|
||||
*/
|
||||
public function getEntityUniqueId(){
|
||||
return $this->getVarLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an EntityUniqueID
|
||||
* @param int|string $eid
|
||||
*/
|
||||
public function putEntityUniqueId($eid){
|
||||
$this->putVarLong($eid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads and returns an EntityRuntimeID
|
||||
* @return int|string
|
||||
*/
|
||||
public function getEntityRuntimeId(){
|
||||
return $this->getUnsignedVarLong();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes an EntityUniqueID
|
||||
* @param int|string $eid
|
||||
*/
|
||||
public function putEntityRuntimeId($eid){
|
||||
$this->putUnsignedVarLong($eid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads an block position with unsigned Y coordinate.
|
||||
* @param int $x
|
||||
* @param int $y 0-255
|
||||
* @param int $z
|
||||
*/
|
||||
public function getBlockPosition(&$x, &$y, &$z){
|
||||
$x = $this->getVarInt();
|
||||
$y = $this->getUnsignedVarInt();
|
||||
$z = $this->getVarInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a block position with unsigned Y coordinate.
|
||||
* @param int &$x
|
||||
* @param int &$y
|
||||
* @param int &$z
|
||||
*/
|
||||
public function putBlockPosition($x, $y, $z){
|
||||
$this->putVarInt($x);
|
||||
$this->putUnsignedVarInt($y);
|
||||
$this->putVarInt($z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a block position with a signed Y coordinate.
|
||||
* @param int &$x
|
||||
* @param int &$y
|
||||
* @param int &$z
|
||||
*/
|
||||
public function getSignedBlockPosition(&$x, &$y, &$z){
|
||||
$x = $this->getVarInt();
|
||||
$y = $this->getVarInt();
|
||||
$z = $this->getVarInt();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a block position with a signed Y coordinate.
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
* @param int $z
|
||||
*/
|
||||
public function putSignedBlockPosition($x, $y, $z){
|
||||
$this->putVarInt($x);
|
||||
$this->putVarInt($y);
|
||||
$this->putVarInt($z);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a floating-point vector3 rounded to 4dp.
|
||||
* @param float $x
|
||||
* @param float $y
|
||||
* @param float $z
|
||||
*/
|
||||
public function getVector3f(&$x, &$y, &$z){
|
||||
$x = $this->getLFloat(4);
|
||||
$y = $this->getLFloat(4);
|
||||
$z = $this->getLFloat(4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a floating-point vector3
|
||||
* @param float $x
|
||||
* @param float $y
|
||||
* @param float $z
|
||||
*/
|
||||
public function putVector3f($x, $y, $z){
|
||||
$this->putLFloat($x);
|
||||
$this->putLFloat($y);
|
||||
$this->putLFloat($z);
|
||||
}
|
||||
}
|
@ -19,17 +19,23 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class DisconnectPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::DISCONNECT_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::DISCONNECT_PACKET;
|
||||
|
||||
public $hideDisconnectionScreen = false;
|
||||
public $message;
|
||||
|
||||
public function canBeSentBeforeLogin() : bool{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function decode(){
|
||||
$this->hideDisconnectionScreen = $this->getBool();
|
||||
$this->message = $this->getString();
|
||||
@ -41,4 +47,8 @@ class DisconnectPacket extends DataPacket{
|
||||
$this->putString($this->message);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleDisconnect($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class DropItemPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::DROP_ITEM_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::DROP_ITEM_PACKET;
|
||||
|
||||
public $type;
|
||||
public $item;
|
||||
@ -39,4 +41,8 @@ class DropItemPacket extends DataPacket{
|
||||
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleDropItem($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class EntityEventPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::ENTITY_EVENT_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::ENTITY_EVENT_PACKET;
|
||||
|
||||
const HURT_ANIMATION = 2;
|
||||
const DEATH_ANIMATION = 3;
|
||||
@ -41,25 +43,30 @@ class EntityEventPacket extends DataPacket{
|
||||
const FISH_HOOK_TEASE = 14;
|
||||
const SQUID_INK_CLOUD = 15;
|
||||
const AMBIENT_SOUND = 16;
|
||||
const RESPAWN = 17;
|
||||
|
||||
//TODO add new events
|
||||
const RESPAWN = 18;
|
||||
|
||||
//TODO: add more events
|
||||
|
||||
public $eid;
|
||||
public $event;
|
||||
public $unknown;
|
||||
|
||||
public function decode(){
|
||||
$this->eid = $this->getEntityId();
|
||||
$this->eid = $this->getEntityRuntimeId();
|
||||
$this->event = $this->getByte();
|
||||
$this->unknown = $this->getVarInt();
|
||||
}
|
||||
|
||||
public function encode(){
|
||||
$this->reset();
|
||||
$this->putEntityId($this->eid);
|
||||
$this->putEntityRuntimeId($this->eid);
|
||||
$this->putByte($this->event);
|
||||
$this->putVarInt($this->unknown);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleEntityEvent($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class ExplodePacket extends DataPacket{
|
||||
const NETWORK_ID = Info::EXPLODE_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::EXPLODE_PACKET;
|
||||
|
||||
public $x;
|
||||
public $y;
|
||||
@ -49,9 +51,13 @@ class ExplodePacket extends DataPacket{
|
||||
$this->putUnsignedVarInt(count($this->records));
|
||||
if(count($this->records) > 0){
|
||||
foreach($this->records as $record){
|
||||
$this->putBlockCoords($record->x, $record->y, $record->z);
|
||||
$this->putBlockPosition($record->x, $record->y, $record->z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleExplode($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class FullChunkDataPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::FULL_CHUNK_DATA_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::FULL_CHUNK_DATA_PACKET;
|
||||
|
||||
public $chunkX;
|
||||
public $chunkZ;
|
||||
@ -42,4 +44,8 @@ class FullChunkDataPacket extends DataPacket{
|
||||
$this->putString($this->data);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleFullChunkData($this);
|
||||
}
|
||||
|
||||
}
|
@ -19,13 +19,15 @@
|
||||
*
|
||||
*/
|
||||
|
||||
namespace pocketmine\network\protocol;
|
||||
namespace pocketmine\network\mcpe\protocol;
|
||||
|
||||
#include <rules/DataPacket.h>
|
||||
|
||||
|
||||
use pocketmine\network\mcpe\NetworkSession;
|
||||
|
||||
class HurtArmorPacket extends DataPacket{
|
||||
const NETWORK_ID = Info::HURT_ARMOR_PACKET;
|
||||
const NETWORK_ID = ProtocolInfo::HURT_ARMOR_PACKET;
|
||||
|
||||
public $health;
|
||||
|
||||
@ -38,4 +40,8 @@ class HurtArmorPacket extends DataPacket{
|
||||
$this->putVarInt($this->health);
|
||||
}
|
||||
|
||||
public function handle(NetworkSession $session) : bool{
|
||||
return $session->handleHurtArmor($this);
|
||||
}
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user