mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-04-22 00:33:59 +00:00
Player: patch exploits relating to quitting on death (#2017)
* Revert "Revert bad duct-tape fix that broke lots of other things" This reverts commit 4a4900e5e7ea1fd7b897b025b4b666fd2050f80a. Player: Perform respawn actions when joining while dead This fixes exploits related to #1567 by calling respawn logic on join when the player has zero health. This is a shitty fix and doesn't solve the actual issues described in #1567, but it's a simple solution for the exploits related to it.
This commit is contained in:
parent
9abfd54cc1
commit
f66928c345
@ -991,7 +991,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
}
|
||||
|
||||
if($this->getHealth() <= 0){
|
||||
$this->sendRespawnPacket($this->getSpawn());
|
||||
$this->respawn();
|
||||
}
|
||||
}
|
||||
|
||||
@ -2626,50 +2626,7 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
break;
|
||||
}
|
||||
|
||||
if($this->server->isHardcore()){
|
||||
$this->setBanned(true);
|
||||
break;
|
||||
}
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $this->getSpawn()));
|
||||
|
||||
$realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getLevel());
|
||||
|
||||
if($realSpawn->distanceSquared($this->getSpawn()->add(0.5, 0, 0.5)) > 0.01){
|
||||
$this->teleport($realSpawn); //If the destination was modified by plugins
|
||||
}else{
|
||||
$this->setPosition($realSpawn); //The client will move to the position of its own accord once chunks are sent
|
||||
$this->nextChunkOrderRun = 0;
|
||||
$this->isTeleporting = true;
|
||||
$this->newPosition = null;
|
||||
}
|
||||
|
||||
$this->resetLastMovements();
|
||||
$this->resetFallDistance();
|
||||
|
||||
$this->setSprinting(false);
|
||||
$this->setSneaking(false);
|
||||
|
||||
$this->extinguish();
|
||||
$this->setAirSupplyTicks($this->getMaxAirSupplyTicks());
|
||||
$this->deadTicks = 0;
|
||||
$this->noDamageTicks = 60;
|
||||
|
||||
$this->removeAllEffects();
|
||||
$this->setHealth($this->getMaxHealth());
|
||||
|
||||
foreach($this->attributeMap->getAll() as $attr){
|
||||
$attr->resetToDefault();
|
||||
}
|
||||
|
||||
$this->sendData($this);
|
||||
|
||||
$this->sendSettings();
|
||||
$this->inventory->sendContents($this);
|
||||
$this->armorInventory->sendContents($this);
|
||||
|
||||
$this->spawnToAll();
|
||||
$this->scheduleUpdate();
|
||||
$this->respawn();
|
||||
break;
|
||||
case PlayerActionPacket::ACTION_JUMP:
|
||||
$this->jump();
|
||||
@ -3395,6 +3352,15 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
$this->namedtag->setInt("SpawnX", (int) $this->spawnPosition->x);
|
||||
$this->namedtag->setInt("SpawnY", (int) $this->spawnPosition->y);
|
||||
$this->namedtag->setInt("SpawnZ", (int) $this->spawnPosition->z);
|
||||
|
||||
if(!$this->isAlive()){
|
||||
//hack for respawn after quit
|
||||
$this->namedtag->setTag(new ListTag("Pos", [
|
||||
new DoubleTag("", $this->spawnPosition->x),
|
||||
new DoubleTag("", $this->spawnPosition->y),
|
||||
new DoubleTag("", $this->spawnPosition->z)
|
||||
]));
|
||||
}
|
||||
}
|
||||
|
||||
$achievements = new CompoundTag("Achievements");
|
||||
@ -3567,6 +3533,45 @@ class Player extends Human implements CommandSender, ChunkLoader, IPlayer{
|
||||
return false; //never flag players for despawn
|
||||
}
|
||||
|
||||
protected function respawn() : void{
|
||||
if($this->server->isHardcore()){
|
||||
$this->setBanned(true);
|
||||
return;
|
||||
}
|
||||
|
||||
$this->server->getPluginManager()->callEvent($ev = new PlayerRespawnEvent($this, $this->getSpawn()));
|
||||
|
||||
$realSpawn = Position::fromObject($ev->getRespawnPosition()->add(0.5, 0, 0.5), $ev->getRespawnPosition()->getLevel());
|
||||
$this->teleport($realSpawn);
|
||||
|
||||
$this->resetLastMovements();
|
||||
$this->resetFallDistance();
|
||||
|
||||
$this->setSprinting(false);
|
||||
$this->setSneaking(false);
|
||||
|
||||
$this->extinguish();
|
||||
$this->setAirSupplyTicks($this->getMaxAirSupplyTicks());
|
||||
$this->deadTicks = 0;
|
||||
$this->noDamageTicks = 60;
|
||||
|
||||
$this->removeAllEffects();
|
||||
$this->setHealth($this->getMaxHealth());
|
||||
|
||||
foreach($this->attributeMap->getAll() as $attr){
|
||||
$attr->resetToDefault();
|
||||
}
|
||||
|
||||
$this->sendData($this);
|
||||
|
||||
$this->sendSettings();
|
||||
$this->inventory->sendContents($this);
|
||||
$this->armorInventory->sendContents($this);
|
||||
|
||||
$this->spawnToAll();
|
||||
$this->scheduleUpdate();
|
||||
}
|
||||
|
||||
protected function applyPostDamageEffects(EntityDamageEvent $source) : void{
|
||||
parent::applyPostDamageEffects($source);
|
||||
|
||||
|
@ -929,6 +929,7 @@ abstract class Entity extends Location implements Metadatable, EntityIds{
|
||||
|
||||
if($amount <= 0){
|
||||
if($this->isAlive()){
|
||||
$this->health = 0;
|
||||
$this->kill();
|
||||
}
|
||||
}elseif($amount <= $this->getMaxHealth() or $amount < $this->health){
|
||||
|
Loading…
x
Reference in New Issue
Block a user