mirror of
https://github.com/pmmp/PocketMine-MP.git
synced 2025-09-06 09:56:06 +00:00
Merge branch 'stable' into next-minor
This commit is contained in:
@ -145,6 +145,11 @@ class InGamePacketHandler extends PacketHandler{
|
||||
/** @var UseItemTransactionData|null */
|
||||
protected $lastRightClickData = null;
|
||||
|
||||
protected ?Vector3 $lastPlayerAuthInputPosition = null;
|
||||
protected ?float $lastPlayerAuthInputYaw = null;
|
||||
protected ?float $lastPlayerAuthInputPitch = null;
|
||||
protected ?int $lastPlayerAuthInputFlags = null;
|
||||
|
||||
/** @var bool */
|
||||
public $forceMoveSync = false;
|
||||
|
||||
@ -168,9 +173,10 @@ class InGamePacketHandler extends PacketHandler{
|
||||
return true;
|
||||
}
|
||||
|
||||
private function resolveOnOffInputFlags(PlayerAuthInputPacket $packet, int $startFlag, int $stopFlag) : ?bool{
|
||||
$enabled = $packet->hasFlag($startFlag);
|
||||
if($enabled !== $packet->hasFlag($stopFlag)){
|
||||
private function resolveOnOffInputFlags(int $inputFlags, int $startFlag, int $stopFlag) : ?bool{
|
||||
$enabled = ($inputFlags & (1 << $startFlag)) !== 0;
|
||||
$disabled = ($inputFlags & (1 << $stopFlag)) !== 0;
|
||||
if($enabled !== $disabled){
|
||||
return $enabled;
|
||||
}
|
||||
//neither flag was set, or both were set
|
||||
@ -179,51 +185,68 @@ class InGamePacketHandler extends PacketHandler{
|
||||
|
||||
public function handlePlayerAuthInput(PlayerAuthInputPacket $packet) : bool{
|
||||
$rawPos = $packet->getPosition();
|
||||
foreach([$rawPos->x, $rawPos->y, $rawPos->z, $packet->getYaw(), $packet->getHeadYaw(), $packet->getPitch()] as $float){
|
||||
$rawYaw = $packet->getYaw();
|
||||
$rawPitch = $packet->getPitch();
|
||||
foreach([$rawPos->x, $rawPos->y, $rawPos->z, $rawYaw, $packet->getHeadYaw(), $rawPitch] as $float){
|
||||
if(is_infinite($float) || is_nan($float)){
|
||||
$this->session->getLogger()->debug("Invalid movement received, contains NAN/INF components");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$yaw = fmod($packet->getYaw(), 360);
|
||||
$pitch = fmod($packet->getPitch(), 360);
|
||||
if($yaw < 0){
|
||||
$yaw += 360;
|
||||
if($rawYaw !== $this->lastPlayerAuthInputYaw || $rawPitch !== $this->lastPlayerAuthInputPitch){
|
||||
$this->lastPlayerAuthInputYaw = $rawYaw;
|
||||
$this->lastPlayerAuthInputPitch = $rawPitch;
|
||||
|
||||
$yaw = fmod($rawYaw, 360);
|
||||
$pitch = fmod($rawPitch, 360);
|
||||
if($yaw < 0){
|
||||
$yaw += 360;
|
||||
}
|
||||
|
||||
$this->player->setRotation($yaw, $pitch);
|
||||
}
|
||||
|
||||
$this->player->setRotation($yaw, $pitch);
|
||||
|
||||
$curPos = $this->player->getLocation();
|
||||
$hasMoved = $this->lastPlayerAuthInputPosition === null || !$this->lastPlayerAuthInputPosition->equals($rawPos);
|
||||
$newPos = $rawPos->round(4)->subtract(0, 1.62, 0);
|
||||
|
||||
if($this->forceMoveSync && $newPos->distanceSquared($curPos) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks
|
||||
$this->session->getLogger()->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $curPos);
|
||||
//Still getting movements from before teleport, ignore them
|
||||
return false;
|
||||
if($this->forceMoveSync && $hasMoved){
|
||||
$curPos = $this->player->getLocation();
|
||||
|
||||
if($newPos->distanceSquared($curPos) > 1){ //Tolerate up to 1 block to avoid problems with client-sided physics when spawning in blocks
|
||||
$this->session->getLogger()->debug("Got outdated pre-teleport movement, received " . $newPos . ", expected " . $curPos);
|
||||
//Still getting movements from before teleport, ignore them
|
||||
return false;
|
||||
}
|
||||
|
||||
// Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock
|
||||
$this->forceMoveSync = false;
|
||||
}
|
||||
|
||||
// Once we get a movement within a reasonable distance, treat it as a teleport ACK and remove position lock
|
||||
$this->forceMoveSync = false;
|
||||
$inputFlags = $packet->getInputFlags();
|
||||
if($inputFlags !== $this->lastPlayerAuthInputFlags){
|
||||
$this->lastPlayerAuthInputFlags = $inputFlags;
|
||||
|
||||
$sneaking = $this->resolveOnOffInputFlags($packet, PlayerAuthInputFlags::START_SNEAKING, PlayerAuthInputFlags::STOP_SNEAKING);
|
||||
$sprinting = $this->resolveOnOffInputFlags($packet, PlayerAuthInputFlags::START_SPRINTING, PlayerAuthInputFlags::STOP_SPRINTING);
|
||||
$swimming = $this->resolveOnOffInputFlags($packet, PlayerAuthInputFlags::START_SWIMMING, PlayerAuthInputFlags::STOP_SWIMMING);
|
||||
$gliding = $this->resolveOnOffInputFlags($packet, PlayerAuthInputFlags::START_GLIDING, PlayerAuthInputFlags::STOP_GLIDING);
|
||||
$mismatch =
|
||||
($sneaking !== null && !$this->player->toggleSneak($sneaking)) |
|
||||
($sprinting !== null && !$this->player->toggleSprint($sprinting)) |
|
||||
($swimming !== null && !$this->player->toggleSwim($swimming)) |
|
||||
($gliding !== null && !$this->player->toggleGlide($gliding));
|
||||
if((bool) $mismatch){
|
||||
$this->player->sendData([$this->player]);
|
||||
$sneaking = $this->resolveOnOffInputFlags($inputFlags, PlayerAuthInputFlags::START_SNEAKING, PlayerAuthInputFlags::STOP_SNEAKING);
|
||||
$sprinting = $this->resolveOnOffInputFlags($inputFlags, PlayerAuthInputFlags::START_SPRINTING, PlayerAuthInputFlags::STOP_SPRINTING);
|
||||
$swimming = $this->resolveOnOffInputFlags($inputFlags, PlayerAuthInputFlags::START_SWIMMING, PlayerAuthInputFlags::STOP_SWIMMING);
|
||||
$gliding = $this->resolveOnOffInputFlags($inputFlags, PlayerAuthInputFlags::START_GLIDING, PlayerAuthInputFlags::STOP_GLIDING);
|
||||
$mismatch =
|
||||
($sneaking !== null && !$this->player->toggleSneak($sneaking)) |
|
||||
($sprinting !== null && !$this->player->toggleSprint($sprinting)) |
|
||||
($swimming !== null && !$this->player->toggleSwim($swimming)) |
|
||||
($gliding !== null && !$this->player->toggleGlide($gliding));
|
||||
if((bool) $mismatch){
|
||||
$this->player->sendData([$this->player]);
|
||||
}
|
||||
|
||||
if($packet->hasFlag(PlayerAuthInputFlags::START_JUMPING)){
|
||||
$this->player->jump();
|
||||
}
|
||||
}
|
||||
|
||||
if($packet->hasFlag(PlayerAuthInputFlags::START_JUMPING)){
|
||||
$this->player->jump();
|
||||
}
|
||||
|
||||
if(!$this->forceMoveSync){
|
||||
if(!$this->forceMoveSync && $hasMoved){
|
||||
$this->lastPlayerAuthInputPosition = $rawPos;
|
||||
//TODO: this packet has WAYYYYY more useful information that we're not using
|
||||
$this->player->handleMovement($newPos);
|
||||
}
|
||||
|
Reference in New Issue
Block a user