Remount players in their vehicle if they're not supposed to leave

This commit is contained in:
Camotoy 2022-12-22 13:19:46 -05:00
parent bd73f199d5
commit c48cb2a4a8
No known key found for this signature in database
GPG key ID: 7EEFB66FE798081F
4 changed files with 34 additions and 4 deletions

View file

@ -44,8 +44,6 @@ import lombok.Setter;
import net.kyori.adventure.text.Component;
import org.geysermc.geyser.entity.EntityDefinition;
import org.geysermc.geyser.entity.GeyserDirtyMetadata;
import org.geysermc.geyser.entity.type.player.SessionPlayerEntity;
import org.geysermc.geyser.network.GameProtocol;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.EntityUtils;

View file

@ -62,7 +62,6 @@ import com.github.steveice10.packetlib.event.session.*;
import com.github.steveice10.packetlib.packet.Packet;
import com.github.steveice10.packetlib.tcp.TcpClientSession;
import com.github.steveice10.packetlib.tcp.TcpSession;
import com.nukkitx.math.GenericMath;
import com.nukkitx.math.vector.*;
import com.nukkitx.nbt.NbtMap;
import com.nukkitx.protocol.bedrock.BedrockPacket;
@ -135,7 +134,6 @@ import org.geysermc.geyser.translator.text.MessageTranslator;
import org.geysermc.geyser.util.ChunkUtils;
import org.geysermc.geyser.util.DimensionUtils;
import org.geysermc.geyser.util.LoginEncryptionUtils;
import org.geysermc.geyser.util.MathUtils;
import java.net.ConnectException;
import java.net.InetSocketAddress;
@ -539,6 +537,12 @@ public class GeyserSession implements GeyserConnection, GeyserCommandSource {
@Setter
private ScheduledFuture<?> lookBackScheduledFuture = null;
/**
* Used to return players back to their vehicles if the server doesn't want them unmounting.
*/
@Setter
private ScheduledFuture<?> mountVehicleScheduledFuture = null;
private MinecraftProtocol protocol;
public GeyserSession(GeyserImpl geyser, BedrockServerSession bedrockServerSession, EventLoop eventLoop) {

View file

@ -32,15 +32,19 @@ import com.github.steveice10.mc.protocol.data.game.entity.type.EntityType;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundInteractPacket;
import com.github.steveice10.mc.protocol.packet.ingame.serverbound.player.ServerboundPlayerCommandPacket;
import com.nukkitx.protocol.bedrock.data.entity.EntityData;
import com.nukkitx.protocol.bedrock.data.entity.EntityLinkData;
import com.nukkitx.protocol.bedrock.data.inventory.ContainerType;
import com.nukkitx.protocol.bedrock.packet.ContainerOpenPacket;
import com.nukkitx.protocol.bedrock.packet.InteractPacket;
import com.nukkitx.protocol.bedrock.packet.SetEntityLinkPacket;
import org.geysermc.geyser.entity.type.Entity;
import org.geysermc.geyser.entity.type.living.animal.horse.AbstractHorseEntity;
import org.geysermc.geyser.session.GeyserSession;
import org.geysermc.geyser.translator.protocol.PacketTranslator;
import org.geysermc.geyser.translator.protocol.Translator;
import java.util.concurrent.TimeUnit;
@Translator(packet = InteractPacket.class)
public class BedrockInteractTranslator extends PacketTranslator<InteractPacket> {
@ -73,6 +77,23 @@ public class BedrockInteractTranslator extends PacketTranslator<InteractPacket>
case LEAVE_VEHICLE:
ServerboundPlayerCommandPacket sneakPacket = new ServerboundPlayerCommandPacket(entity.getEntityId(), PlayerState.START_SNEAKING);
session.sendDownstreamPacket(sneakPacket);
Entity currentVehicle = session.getPlayerEntity().getVehicle();
session.setMountVehicleScheduledFuture(session.scheduleInEventLoop(() -> {
if (session.getPlayerEntity().getVehicle() == null) {
return;
}
long vehicleBedrockId = currentVehicle.getGeyserId();
if (session.getPlayerEntity().getVehicle().getGeyserId() == vehicleBedrockId) {
// The Bedrock client, as of 1.19.51, dismounts on its end. The server may not agree with this.
// If the server doesn't agree with our dismount (sends a packet saying we dismounted),
// then remount the player.
SetEntityLinkPacket linkPacket = new SetEntityLinkPacket();
linkPacket.setEntityLink(new EntityLinkData(vehicleBedrockId, session.getPlayerEntity().getGeyserId(), EntityLinkData.Type.PASSENGER, true, false));
session.sendUpstreamPacket(linkPacket);
}
}, 1, TimeUnit.SECONDS));
break;
case MOUSEOVER:
// Handle the buttons for mobile - "Mount", etc; and the suggestions for console - "ZL: Mount", etc

View file

@ -114,6 +114,13 @@ public class JavaPlayerPositionTranslator extends PacketTranslator<ClientboundPl
EntityUtils.updateRiderRotationLock(entity, null, false);
EntityUtils.updateMountOffset(entity, null, false, false, entity.getPassengers().size() > 1);
entity.updateBedrockMetadata();
if (session.getMountVehicleScheduledFuture() != null) {
// Cancel this task as it is now unnecessary.
// Note that this isn't present in JavaSetPassengersTranslator as that code is not called for players
// as of Java 1.19.3, but the scheduled future checks for the vehicle being null anyway.
session.getMountVehicleScheduledFuture().cancel(false);
}
}
// If coordinates are relative, then add to the existing coordinate