forked from GeyserMC/Geyser
		
	Fix boat movement on land (#1668)
* Fix boat movement on land 1.16.100 appears to now take advantage of two newer entity metadata properties, IS_BUOYANT and BUOYANCY_DATA. Without the former, moving on land will not work properly. With the former and without the latter, moving in water no longer works. * Use offset kind of
This commit is contained in:
		
							parent
							
								
									aed1eef6e1
								
							
						
					
					
						commit
						988fd66a85
					
				
					 5 changed files with 47 additions and 15 deletions
				
			
		| 
						 | 
				
			
			@ -35,6 +35,16 @@ import java.util.concurrent.TimeUnit;
 | 
			
		|||
 | 
			
		||||
public class BoatEntity extends Entity {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Required when IS_BUOYANT is sent in order for boats to work in the water. <br>
 | 
			
		||||
     *
 | 
			
		||||
     * Taken from BDS 1.16.200, with the modification of <code>simulate_waves</code> since Java doesn't bob the boat up and down
 | 
			
		||||
     * like Bedrock.
 | 
			
		||||
     */
 | 
			
		||||
    private static final String BUOYANCY_DATA = "{\"apply_gravity\":true,\"base_buoyancy\":1.0,\"big_wave_probability\":0.02999999932944775," +
 | 
			
		||||
            "\"big_wave_speed\":10.0,\"drag_down_on_buoyancy_removed\":0.0,\"liquid_blocks\":[\"minecraft:water\"," +
 | 
			
		||||
            "\"minecraft:flowing_water\"],\"simulate_waves\":false}}";
 | 
			
		||||
 | 
			
		||||
    private boolean isPaddlingLeft;
 | 
			
		||||
    private float paddleTimeLeft;
 | 
			
		||||
    private boolean isPaddlingRight;
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +55,10 @@ public class BoatEntity extends Entity {
 | 
			
		|||
 | 
			
		||||
    public BoatEntity(long entityId, long geyserId, EntityType entityType, Vector3f position, Vector3f motion, Vector3f rotation) {
 | 
			
		||||
        super(entityId, geyserId, entityType, position.add(0d, entityType.getOffset(), 0d), motion, rotation.add(90, 0, 90));
 | 
			
		||||
 | 
			
		||||
        // Required to be able to move on land 1.16.200+ or apply gravity not in the water 1.16.100+
 | 
			
		||||
        metadata.put(EntityData.IS_BUOYANT, (byte) 1);
 | 
			
		||||
        metadata.put(EntityData.BUOYANCY_DATA, BUOYANCY_DATA);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -219,6 +219,17 @@ public class GeyserSession implements CommandSender {
 | 
			
		|||
    @Setter
 | 
			
		||||
    private long lastHitTime;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Saves if the client is steering left on a boat.
 | 
			
		||||
     */
 | 
			
		||||
    @Setter
 | 
			
		||||
    private boolean steeringLeft;
 | 
			
		||||
    /**
 | 
			
		||||
     * Saves if the client is steering right on a boat.
 | 
			
		||||
     */
 | 
			
		||||
    @Setter
 | 
			
		||||
    private boolean steeringRight;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Store the last time the player interacted. Used to fix a right-click spam bug.
 | 
			
		||||
     * See https://github.com/GeyserMC/Geyser/issues/503 for context.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,23 +25,19 @@
 | 
			
		|||
 | 
			
		||||
package org.geysermc.connector.network.translators.bedrock;
 | 
			
		||||
 | 
			
		||||
import org.geysermc.connector.network.session.GeyserSession;
 | 
			
		||||
import org.geysermc.connector.network.translators.PacketTranslator;
 | 
			
		||||
import org.geysermc.connector.network.translators.Translator;
 | 
			
		||||
 | 
			
		||||
import com.github.steveice10.mc.protocol.data.game.entity.player.Hand;
 | 
			
		||||
import com.github.steveice10.mc.protocol.packet.ingame.client.player.ClientPlayerSwingArmPacket;
 | 
			
		||||
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientSteerBoatPacket;
 | 
			
		||||
import com.nukkitx.protocol.bedrock.packet.AnimatePacket;
 | 
			
		||||
import org.geysermc.connector.network.session.GeyserSession;
 | 
			
		||||
import org.geysermc.connector.network.translators.PacketTranslator;
 | 
			
		||||
import org.geysermc.connector.network.translators.Translator;
 | 
			
		||||
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
 | 
			
		||||
@Translator(packet = AnimatePacket.class)
 | 
			
		||||
public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
 | 
			
		||||
 | 
			
		||||
    private boolean isSteeringLeft;
 | 
			
		||||
    private boolean isSteeringRight;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void translate(AnimatePacket packet, GeyserSession session) {
 | 
			
		||||
        // Stop the player sending animations before they have fully spawned into the server
 | 
			
		||||
| 
						 | 
				
			
			@ -61,13 +57,13 @@ public class BedrockAnimateTranslator extends PacketTranslator<AnimatePacket> {
 | 
			
		|||
            // These two might need to be flipped, but my recommendation is getting moving working first
 | 
			
		||||
            case ROW_LEFT:
 | 
			
		||||
                // Packet value is a float of how long one has been rowing, so we convert that into a boolean
 | 
			
		||||
                isSteeringLeft = packet.getRowingTime() > 0.0;
 | 
			
		||||
                ClientSteerBoatPacket steerLeftPacket = new ClientSteerBoatPacket(isSteeringRight, isSteeringLeft);
 | 
			
		||||
                session.setSteeringLeft(packet.getRowingTime() > 0.0);
 | 
			
		||||
                ClientSteerBoatPacket steerLeftPacket = new ClientSteerBoatPacket(session.isSteeringLeft(), session.isSteeringRight());
 | 
			
		||||
                session.sendDownstreamPacket(steerLeftPacket);
 | 
			
		||||
                break;
 | 
			
		||||
            case ROW_RIGHT:
 | 
			
		||||
                isSteeringRight = packet.getRowingTime() > 0.0;
 | 
			
		||||
                ClientSteerBoatPacket steerRightPacket = new ClientSteerBoatPacket(isSteeringRight, isSteeringLeft);
 | 
			
		||||
                session.setSteeringRight(packet.getRowingTime() > 0.0);
 | 
			
		||||
                ClientSteerBoatPacket steerRightPacket = new ClientSteerBoatPacket(session.isSteeringLeft(), session.isSteeringRight());
 | 
			
		||||
                session.sendDownstreamPacket(steerRightPacket);
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -27,6 +27,8 @@ package org.geysermc.connector.network.translators.bedrock;
 | 
			
		|||
 | 
			
		||||
import com.github.steveice10.mc.protocol.packet.ingame.client.world.ClientVehicleMovePacket;
 | 
			
		||||
import com.nukkitx.protocol.bedrock.packet.MoveEntityAbsolutePacket;
 | 
			
		||||
import org.geysermc.connector.entity.BoatEntity;
 | 
			
		||||
import org.geysermc.connector.entity.type.EntityType;
 | 
			
		||||
import org.geysermc.connector.network.session.GeyserSession;
 | 
			
		||||
import org.geysermc.connector.network.translators.PacketTranslator;
 | 
			
		||||
import org.geysermc.connector.network.translators.Translator;
 | 
			
		||||
| 
						 | 
				
			
			@ -39,8 +41,14 @@ public class BedrockMoveEntityAbsoluteTranslator extends PacketTranslator<MoveEn
 | 
			
		|||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void translate(MoveEntityAbsolutePacket packet, GeyserSession session) {
 | 
			
		||||
        float y = packet.getPosition().getY();
 | 
			
		||||
        if (session.getRidingVehicleEntity() instanceof BoatEntity) {
 | 
			
		||||
            // Remove some Y position to prevents boats from looking like they're floating in water
 | 
			
		||||
            // Not by the full boat offset because 1.16.100 complains and that's probably not good for the future
 | 
			
		||||
            y -= (EntityType.BOAT.getOffset() - 0.5f);
 | 
			
		||||
        }
 | 
			
		||||
        ClientVehicleMovePacket clientVehicleMovePacket = new ClientVehicleMovePacket(
 | 
			
		||||
                packet.getPosition().getX(), packet.getPosition().getY(), packet.getPosition().getZ(),
 | 
			
		||||
                packet.getPosition().getX(), y, packet.getPosition().getZ(),
 | 
			
		||||
                packet.getRotation().getY() - 90, packet.getRotation().getX()
 | 
			
		||||
        );
 | 
			
		||||
        session.sendDownstreamPacket(clientVehicleMovePacket);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -86,9 +86,9 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator<ServerEn
 | 
			
		|||
                passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 90f);
 | 
			
		||||
                passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, !passengers.isEmpty() ? -90f : 0f);
 | 
			
		||||
            } else {
 | 
			
		||||
                passenger.getMetadata().remove(EntityData.RIDER_ROTATION_LOCKED);
 | 
			
		||||
                passenger.getMetadata().remove(EntityData.RIDER_MAX_ROTATION);
 | 
			
		||||
                passenger.getMetadata().remove(EntityData.RIDER_MIN_ROTATION);
 | 
			
		||||
                passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0);
 | 
			
		||||
                passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f);
 | 
			
		||||
                passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 0f);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            passenger.updateBedrockMetadata(session);
 | 
			
		||||
| 
						 | 
				
			
			@ -110,6 +110,9 @@ public class JavaEntitySetPassengersTranslator extends PacketTranslator<ServerEn
 | 
			
		|||
                linkPacket.setEntityLink(new EntityLinkData(entity.getGeyserId(), passenger.getGeyserId(), EntityLinkData.Type.REMOVE, false));
 | 
			
		||||
                session.sendUpstreamPacket(linkPacket);
 | 
			
		||||
                passengers.remove(passenger.getEntityId());
 | 
			
		||||
                passenger.getMetadata().put(EntityData.RIDER_ROTATION_LOCKED, (byte) 0);
 | 
			
		||||
                passenger.getMetadata().put(EntityData.RIDER_MAX_ROTATION, 0f);
 | 
			
		||||
                passenger.getMetadata().put(EntityData.RIDER_MIN_ROTATION, 0f);
 | 
			
		||||
 | 
			
		||||
                this.updateOffset(passenger, entity, session, false, false, (packet.getPassengerIds().length > 1));
 | 
			
		||||
            } else {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue