2019-08-03 06:51:05 +00:00
/ *
2021-01-01 15:10:36 +00:00
* Copyright ( c ) 2019 - 2021 GeyserMC . http : //geysermc.org
2019-08-03 06:51:05 +00:00
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software .
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
*
* @author GeyserMC
* @link https : //github.com/GeyserMC/Geyser
* /
package org.geysermc.connector.network.translators.java.entity.player ;
2020-05-29 19:11:38 +00:00
import com.github.steveice10.mc.protocol.data.game.entity.player.PositionElement ;
2019-08-10 00:15:06 +00:00
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientTeleportConfirmPacket ;
2019-08-03 06:51:05 +00:00
import com.github.steveice10.mc.protocol.packet.ingame.server.entity.player.ServerPlayerPositionRotationPacket ;
2019-10-09 18:39:38 +00:00
import com.nukkitx.math.vector.Vector3f ;
2019-08-03 06:51:05 +00:00
import com.nukkitx.protocol.bedrock.packet.MovePlayerPacket ;
2020-03-24 04:24:17 +00:00
import com.nukkitx.protocol.bedrock.packet.RespawnPacket ;
2019-08-03 06:51:05 +00:00
import com.nukkitx.protocol.bedrock.packet.SetEntityDataPacket ;
2020-11-20 19:56:39 +00:00
import org.geysermc.connector.entity.player.PlayerEntity ;
2020-04-29 16:06:25 +00:00
import org.geysermc.connector.entity.type.EntityType ;
import org.geysermc.connector.network.session.GeyserSession ;
import org.geysermc.connector.network.session.cache.TeleportCache ;
import org.geysermc.connector.network.translators.PacketTranslator ;
import org.geysermc.connector.network.translators.Translator ;
import org.geysermc.connector.utils.ChunkUtils ;
2020-07-05 23:35:51 +00:00
import org.geysermc.connector.utils.LanguageUtils ;
2019-12-21 17:35:48 +00:00
2020-03-24 04:24:17 +00:00
@Translator ( packet = ServerPlayerPositionRotationPacket . class )
2019-08-03 06:51:05 +00:00
public class JavaPlayerPositionRotationTranslator extends PacketTranslator < ServerPlayerPositionRotationPacket > {
@Override
public void translate ( ServerPlayerPositionRotationPacket packet , GeyserSession session ) {
if ( ! session . isLoggedIn ( ) )
return ;
2021-01-04 00:06:20 +00:00
PlayerEntity entity = session . getPlayerEntity ( ) ;
2019-08-10 00:15:06 +00:00
if ( ! session . isSpawned ( ) ) {
2020-05-26 03:35:26 +00:00
Vector3f pos = Vector3f . from ( packet . getX ( ) , packet . getY ( ) , packet . getZ ( ) ) ;
2020-02-15 23:39:34 +00:00
entity . setPosition ( pos ) ;
entity . setRotation ( Vector3f . from ( packet . getYaw ( ) , packet . getPitch ( ) , packet . getYaw ( ) ) ) ;
2019-12-27 11:29:46 +00:00
RespawnPacket respawnPacket = new RespawnPacket ( ) ;
2020-07-30 20:31:12 +00:00
respawnPacket . setRuntimeEntityId ( 0 ) ; // Bedrock server behavior
2020-07-25 14:38:00 +00:00
respawnPacket . setPosition ( entity . getPosition ( ) ) ;
2020-02-14 23:39:26 +00:00
respawnPacket . setState ( RespawnPacket . State . SERVER_READY ) ;
2020-05-05 15:51:43 +00:00
session . sendUpstreamPacket ( respawnPacket ) ;
2019-12-27 11:29:46 +00:00
2019-08-10 00:15:06 +00:00
SetEntityDataPacket entityDataPacket = new SetEntityDataPacket ( ) ;
entityDataPacket . setRuntimeEntityId ( entity . getGeyserId ( ) ) ;
entityDataPacket . getMetadata ( ) . putAll ( entity . getMetadata ( ) ) ;
2020-05-05 15:51:43 +00:00
session . sendUpstreamPacket ( entityDataPacket ) ;
2019-08-05 20:30:56 +00:00
2019-08-10 00:15:06 +00:00
MovePlayerPacket movePlayerPacket = new MovePlayerPacket ( ) ;
movePlayerPacket . setRuntimeEntityId ( entity . getGeyserId ( ) ) ;
2020-07-25 14:38:00 +00:00
movePlayerPacket . setPosition ( entity . getPosition ( ) ) ;
2019-10-09 18:39:38 +00:00
movePlayerPacket . setRotation ( Vector3f . from ( packet . getPitch ( ) , packet . getYaw ( ) , 0 ) ) ;
2020-07-30 20:31:12 +00:00
movePlayerPacket . setMode ( MovePlayerPacket . Mode . RESPAWN ) ;
2019-08-03 06:51:05 +00:00
2020-05-05 15:51:43 +00:00
session . sendUpstreamPacket ( movePlayerPacket ) ;
2019-08-10 00:15:06 +00:00
session . setSpawned ( true ) ;
2020-02-06 04:23:08 +00:00
ClientTeleportConfirmPacket teleportConfirmPacket = new ClientTeleportConfirmPacket ( packet . getTeleportId ( ) ) ;
2020-05-05 15:51:43 +00:00
session . sendDownstreamPacket ( teleportConfirmPacket ) ;
2020-02-06 04:23:08 +00:00
2020-03-06 01:26:36 +00:00
ChunkUtils . updateChunkPosition ( session , pos . toInt ( ) ) ;
2020-07-05 23:35:51 +00:00
session . getConnector ( ) . getLogger ( ) . info ( LanguageUtils . getLocaleStringLog ( " geyser.entity.player.spawn " , packet . getX ( ) , packet . getY ( ) , packet . getZ ( ) ) ) ;
2019-09-16 01:25:16 +00:00
return ;
2019-08-10 00:15:06 +00:00
}
2019-08-03 06:51:05 +00:00
session . setSpawned ( true ) ;
2020-04-29 16:06:25 +00:00
2020-05-29 19:11:38 +00:00
// Ignore certain move correction packets for smoother movement
// These are never relative
2020-11-20 19:56:39 +00:00
// When chunk caching is enabled this isn't needed as we shouldn't get these
if ( ! session . getConnector ( ) . getConfig ( ) . isCacheChunks ( ) & & packet . getRelative ( ) . isEmpty ( ) ) {
2020-02-26 00:50:09 +00:00
double xDis = Math . abs ( entity . getPosition ( ) . getX ( ) - packet . getX ( ) ) ;
double yDis = entity . getPosition ( ) . getY ( ) - packet . getY ( ) ;
double zDis = Math . abs ( entity . getPosition ( ) . getZ ( ) - packet . getZ ( ) ) ;
2020-05-29 19:11:38 +00:00
if ( ! ( xDis > 1 . 5 | | ( yDis < 1 . 45 | | yDis > ( session . isJumping ( ) ? 4 . 3 : ( session . isSprinting ( ) ? 2 . 5 : 1 . 9 ) ) ) | | zDis > 1 . 5 ) ) {
// Fake confirm the teleport but don't send it to the client
2020-04-29 16:06:25 +00:00
ClientTeleportConfirmPacket teleportConfirmPacket = new ClientTeleportConfirmPacket ( packet . getTeleportId ( ) ) ;
2020-05-05 15:51:43 +00:00
session . sendDownstreamPacket ( teleportConfirmPacket ) ;
2020-05-29 19:11:38 +00:00
return ;
2020-02-16 18:40:54 +00:00
}
}
2020-05-29 19:11:38 +00:00
// If coordinates are relative, then add to the existing coordinate
double newX = packet . getX ( ) +
( packet . getRelative ( ) . contains ( PositionElement . X ) ? entity . getPosition ( ) . getX ( ) : 0 ) ;
double newY = packet . getY ( ) +
( packet . getRelative ( ) . contains ( PositionElement . Y ) ? entity . getPosition ( ) . getY ( ) - EntityType . PLAYER . getOffset ( ) : 0 ) ;
double newZ = packet . getZ ( ) +
( packet . getRelative ( ) . contains ( PositionElement . Z ) ? entity . getPosition ( ) . getZ ( ) : 0 ) ;
2020-11-20 19:56:39 +00:00
float newPitch = packet . getPitch ( ) +
2020-05-29 19:11:38 +00:00
( packet . getRelative ( ) . contains ( PositionElement . PITCH ) ? entity . getBedrockRotation ( ) . getX ( ) : 0 ) ;
2020-11-20 19:56:39 +00:00
float newYaw = packet . getYaw ( ) +
2020-05-29 19:11:38 +00:00
( packet . getRelative ( ) . contains ( PositionElement . YAW ) ? entity . getBedrockRotation ( ) . getY ( ) : 0 ) ;
2020-11-20 19:56:39 +00:00
session . getConnector ( ) . getLogger ( ) . debug ( " Teleport from " + entity . getPosition ( ) . getX ( ) + " " + ( entity . getPosition ( ) . getY ( ) - EntityType . PLAYER . getOffset ( ) ) + " " + entity . getPosition ( ) . getZ ( ) ) ;
2020-05-29 19:11:38 +00:00
2020-11-20 19:56:39 +00:00
session . addTeleport ( new TeleportCache ( newX , newY , newZ , newPitch , newYaw , packet . getTeleportId ( ) ) ) ;
entity . moveAbsolute ( session , Vector3f . from ( newX , newY , newZ ) , newYaw , newPitch , true , true ) ;
session . getConnector ( ) . getLogger ( ) . debug ( " to " + entity . getPosition ( ) . getX ( ) + " " + ( entity . getPosition ( ) . getY ( ) - EntityType . PLAYER . getOffset ( ) ) + " " + entity . getPosition ( ) . getZ ( ) ) ;
2019-08-03 06:51:05 +00:00
}
}