diff --git a/core/src/main/java/nl/matsv/viabackwards/ViaBackwardsConfig.java b/core/src/main/java/nl/matsv/viabackwards/ViaBackwardsConfig.java index 0c66484b..eab0ab41 100644 --- a/core/src/main/java/nl/matsv/viabackwards/ViaBackwardsConfig.java +++ b/core/src/main/java/nl/matsv/viabackwards/ViaBackwardsConfig.java @@ -12,6 +12,7 @@ public class ViaBackwardsConfig extends Config implements nl.matsv.viabackwards. private boolean addCustomEnchantsToLore; private boolean addTeamColorToPrefix; + private boolean fix1_13FacePlayer; public ViaBackwardsConfig(File configFile) { super(configFile); @@ -26,6 +27,7 @@ public class ViaBackwardsConfig extends Config implements nl.matsv.viabackwards. private void loadFields() { addCustomEnchantsToLore = getBoolean("add-custom-enchants-into-lore", true); addTeamColorToPrefix = getBoolean("add-teamcolor-to-prefix", true); + fix1_13FacePlayer = getBoolean("fix-1_13-face-player", true); } @Override @@ -38,6 +40,11 @@ public class ViaBackwardsConfig extends Config implements nl.matsv.viabackwards. return addTeamColorToPrefix; } + @Override + public boolean isFix1_13FacePlayer() { + return fix1_13FacePlayer; + } + @Override public URL getDefaultConfigURL() { return getClass().getClassLoader().getResource("assets/viabackwards/config.yml"); diff --git a/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsConfig.java b/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsConfig.java index 01ccafbb..39ea5f8b 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsConfig.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/ViaBackwardsConfig.java @@ -15,4 +15,11 @@ public interface ViaBackwardsConfig { * @return true if enabled */ boolean addTeamColorTo1_13Prefix(); + + /** + * Converts the new 1.13 face player packets to look packets. + * + * @return true if enabled + */ + boolean isFix1_13FacePlayer(); } diff --git a/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityPositionHandler.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityPositionHandler.java new file mode 100644 index 00000000..c2b75e22 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityPositionHandler.java @@ -0,0 +1,98 @@ +package nl.matsv.viabackwards.api.entities.storage; + +import nl.matsv.viabackwards.ViaBackwards; +import nl.matsv.viabackwards.api.rewriters.EntityRewriter; +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.Via; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.type.Type; + +import java.util.Optional; +import java.util.function.Supplier; + +public class EntityPositionHandler { + + public static final double RELATIVE_MOVE_FACTOR = 32 * 128; + private final EntityRewriter entityRewriter; + private final Class storageClass; + private final Supplier storageSupplier; + private boolean warnedForMissingEntity; + + public EntityPositionHandler(EntityRewriter entityRewriter, + Class storageClass, Supplier storageSupplier) { + this.entityRewriter = entityRewriter; + this.storageClass = storageClass; + this.storageSupplier = storageSupplier; + } + + public void cacheEntityPosition(PacketWrapper wrapper, boolean create, boolean relative) throws Exception { + cacheEntityPosition(wrapper, + wrapper.get(Type.DOUBLE, 0), wrapper.get(Type.DOUBLE, 1), wrapper.get(Type.DOUBLE, 2), create, relative); + } + + public void cacheEntityPosition(PacketWrapper wrapper, double x, double y, double z, boolean create, boolean relative) throws Exception { + int entityId = wrapper.get(Type.VAR_INT, 0); + Optional optStoredEntity = entityRewriter.getEntityTracker(wrapper.user()).getEntity(entityId); + if (!optStoredEntity.isPresent()) { + if (!Via.getConfig().isSuppressMetadataErrors()) { + ViaBackwards.getPlatform().getLogger().warning("Stored entity with id " + entityId + " missing at position: " + x + " - " + y + " - " + z + " in " + storageClass.getSimpleName()); + if (!warnedForMissingEntity) { + warnedForMissingEntity = true; + ViaBackwards.getPlatform().getLogger().warning("This is very likely caused by a plugin sending a teleport packet for an entity outside of the player's range."); + ViaBackwards.getPlatform().getLogger().warning("You can disable this warning in the ViaVersion config under \"suppress-metadata-errors\""); + } + } + return; + } + + EntityTracker.StoredEntity storedEntity = optStoredEntity.get(); + EntityPositionStorage positionStorage = create ? storageSupplier.get() : storedEntity.get(storageClass); + if (positionStorage == null) { + ViaBackwards.getPlatform().getLogger().warning("Stored entity with id " + entityId + " missing " + storageClass.getSimpleName()); + return; + } + + positionStorage.setCoordinates(x, y, z, relative); + storedEntity.put(positionStorage); + } + + public EntityPositionStorage getStorage(UserConnection user, int entityId) { + Optional optEntity = user.get(EntityTracker.class).get(entityRewriter.getProtocol()).getEntity(entityId); + EntityPositionStorage storedEntity; + if (!optEntity.isPresent() || (storedEntity = optEntity.get().get(EntityPositionStorage.class)) == null) { + ViaBackwards.getPlatform().getLogger().warning("Untracked entity with id " + entityId + " in " + storageClass.getSimpleName()); + return null; + } + return storedEntity; + } + + public static void writeFacingAngles(PacketWrapper wrapper, double x, double y, double z, double targetX, double targetY, double targetZ) { + double dX = targetX - x; + double dY = targetY - y; + double dZ = targetZ - z; + double r = Math.sqrt(dX * dX + dY * dY + dZ * dZ); + double yaw = -Math.atan2(dX, dZ) / Math.PI * 180; + if (yaw < 0) { + yaw = 360 + yaw; + } + double pitch = -Math.asin(dY / r) / Math.PI * 180; + + wrapper.write(Type.BYTE, (byte) (yaw * 256f / 360f)); + wrapper.write(Type.BYTE, (byte) (pitch * 256f / 360f)); + } + + public static void writeFacingDegrees(PacketWrapper wrapper, double x, double y, double z, double targetX, double targetY, double targetZ) { + double dX = targetX - x; + double dY = targetY - y; + double dZ = targetZ - z; + double r = Math.sqrt(dX * dX + dY * dY + dZ * dZ); + double yaw = -Math.atan2(dX, dZ) / Math.PI * 180; + if (yaw < 0) { + yaw = 360 + yaw; + } + double pitch = -Math.asin(dY / r) / Math.PI * 180; + + wrapper.write(Type.FLOAT, (float) yaw); + wrapper.write(Type.FLOAT, (float) pitch); + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/EntityPositionStorage.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityPositionStorage.java similarity index 72% rename from core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/EntityPositionStorage.java rename to core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityPositionStorage.java index ed89f881..aa298354 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/data/EntityPositionStorage.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityPositionStorage.java @@ -1,9 +1,6 @@ -package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data; - -import nl.matsv.viabackwards.api.entities.storage.EntityStorage; - -public class EntityPositionStorage extends EntityStorage { +package nl.matsv.viabackwards.api.entities.storage; +public abstract class EntityPositionStorage implements EntityStorage { private double x; private double y; private double z; diff --git a/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityStorage.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityStorage.java index 17d7a034..1481ffa0 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityStorage.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/EntityStorage.java @@ -10,5 +10,5 @@ package nl.matsv.viabackwards.api.entities.storage; -public class EntityStorage { +public interface EntityStorage { } diff --git a/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/object/PlayerPositionStorage.java b/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/object/PlayerPositionStorage.java new file mode 100644 index 00000000..6dc62917 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/api/entities/storage/object/PlayerPositionStorage.java @@ -0,0 +1,44 @@ +package nl.matsv.viabackwards.api.entities.storage.object; + +import us.myles.ViaVersion.api.PacketWrapper; +import us.myles.ViaVersion.api.data.StoredObject; +import us.myles.ViaVersion.api.data.UserConnection; +import us.myles.ViaVersion.api.type.Type; + +public abstract class PlayerPositionStorage extends StoredObject { + private double x; + private double y; + private double z; + + protected PlayerPositionStorage(UserConnection user) { + super(user); + } + + public double getX() { + return x; + } + + public double getY() { + return y; + } + + public double getZ() { + return z; + } + + public void setCoordinates(PacketWrapper wrapper, boolean relative) throws Exception { + setCoordinates(wrapper.get(Type.DOUBLE, 0), wrapper.get(Type.DOUBLE, 1), wrapper.get(Type.DOUBLE, 2), relative); + } + + public void setCoordinates(double x, double y, double z, boolean relative) { + if (relative) { + this.x += x; + this.y += y; + this.z += z; + } else { + this.x = x; + this.y = y; + this.z = z; + } + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/api/rewriters/EntityRewriter.java b/core/src/main/java/nl/matsv/viabackwards/api/rewriters/EntityRewriter.java index 35147fc5..4128d51b 100644 --- a/core/src/main/java/nl/matsv/viabackwards/api/rewriters/EntityRewriter.java +++ b/core/src/main/java/nl/matsv/viabackwards/api/rewriters/EntityRewriter.java @@ -377,7 +377,7 @@ public abstract class EntityRewriter extends Rewrit }; } - protected EntityTracker.ProtocolEntityTracker getEntityTracker(UserConnection user) { + public EntityTracker.ProtocolEntityTracker getEntityTracker(UserConnection user) { return user.get(EntityTracker.class).get(getProtocol()); } diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/storage/ChestedHorseStorage.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/storage/ChestedHorseStorage.java index 74820d86..db8ce482 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/storage/ChestedHorseStorage.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_10to1_11/storage/ChestedHorseStorage.java @@ -18,7 +18,7 @@ import nl.matsv.viabackwards.api.entities.storage.EntityStorage; @Getter @Setter @ToString -public class ChestedHorseStorage extends EntityStorage { +public class ChestedHorseStorage implements EntityStorage { private boolean chested = false; private int liamaStrength = 0; diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11_1to1_12/data/ParrotStorage.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11_1to1_12/data/ParrotStorage.java index 0e1c1432..c9f882a3 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11_1to1_12/data/ParrotStorage.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_11_1to1_12/data/ParrotStorage.java @@ -14,7 +14,7 @@ import lombok.Data; import nl.matsv.viabackwards.api.entities.storage.EntityStorage; @Data -public class ParrotStorage extends EntityStorage { +public class ParrotStorage implements EntityStorage { private boolean tamed = true; private boolean sitting = true; } diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/Protocol1_12_2To1_13.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/Protocol1_12_2To1_13.java index acba53b6..84054c56 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/Protocol1_12_2To1_13.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/Protocol1_12_2To1_13.java @@ -11,6 +11,7 @@ package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13; import lombok.Getter; +import nl.matsv.viabackwards.ViaBackwards; import nl.matsv.viabackwards.api.BackwardsProtocol; import nl.matsv.viabackwards.api.entities.storage.EntityTracker; import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.BackwardsMappings; @@ -21,11 +22,11 @@ import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets.PlayerPacket1 import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets.SoundPackets1_13; import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.providers.BackwardsBlockEntityProvider; import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.BackwardsBlockStorage; +import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.PlayerPositionStorage1_13; import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.TabCompleteStorage; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.data.UserConnection; import us.myles.ViaVersion.api.platform.providers.ViaProviders; -import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion.protocols.protocol1_9_3to1_9_1_2.storage.ClientWorld; @@ -49,7 +50,6 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol { // Thanks to https://wiki.vg/index.php?title=Pre-release_protocol&oldid=14150 - out(State.PLAY, 0x07, 0x07, cancel()); // Statistics TODO MODIFIED out(State.PLAY, 0x0E, 0x0F); // Chat Message (clientbound) out(State.PLAY, 0x11, -1, cancel()); // Declare Commands TODO NEW @@ -65,15 +65,12 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol { out(State.PLAY, 0x20, 0x1E); // Change Game State out(State.PLAY, 0x21, 0x1F); // Keep Alive (clientbound) out(State.PLAY, 0x27, 0x25); // Entity - out(State.PLAY, 0x28, 0x26); // Entity Relative Move - out(State.PLAY, 0x29, 0x27); // Entity Look And Relative Move out(State.PLAY, 0x2A, 0x28); // Entity Look out(State.PLAY, 0x2B, 0x29); // Vehicle Move (clientbound) out(State.PLAY, 0x2C, 0x2A); // Open Sign Editor out(State.PLAY, 0x2D, 0x2B, cancel()); // Craft Recipe Response TODO MODIFIED out(State.PLAY, 0x2E, 0x2C); // Player Abilities (clientbound) out(State.PLAY, 0x2F, 0x2D); // Combat Event - out(State.PLAY, 0x31, -1, cancel()); // Face Player TODO NEW out(State.PLAY, 0x32, 0x2F); // Player Position And Look (clientbound) out(State.PLAY, 0x33, 0x30); // Use Bed out(State.PLAY, 0x34, 0x31, cancel()); // Unlock Recipes TODO MODIFIED @@ -96,7 +93,6 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol { out(State.PLAY, 0x4B, 0x48); // Title out(State.PLAY, 0x4E, 0x4A); // Player List Header And Footer out(State.PLAY, 0x4F, 0x4B); // Collect Item - out(State.PLAY, 0x50, 0x4C); // Entity Teleport out(State.PLAY, 0x51, 0x4D, cancel()); // Advancements out(State.PLAY, 0x52, 0x4E); // Entity Properties out(State.PLAY, 0x53, 0x4F); // Entity Effect @@ -109,10 +105,7 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol { in(State.PLAY, 0x0D, 0x0A); // Use Entity in(State.PLAY, 0x0E, 0x0B); // Keep Alive (serverbound) in(State.PLAY, 0x0F, 0x0C); // Player - in(State.PLAY, 0x10, 0x0D); // Player Position - in(State.PLAY, 0x11, 0x0E); // Player Position And Look (serverbound) in(State.PLAY, 0x12, 0x0F); // Player Look - in(State.PLAY, 0x13, 0x10); // Vehicle Move (serverbound) in(State.PLAY, 0x14, 0x11); // Steer Boat in(State.PLAY, 0x16, 0x12, cancel()); // Craft Recipe Request TODO MODIFIED in(State.PLAY, 0x17, 0x13); // Player Abilities (serverbound) @@ -130,7 +123,6 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol { in(State.PLAY, 0x28, 0x1E); // Spectate in(State.PLAY, 0x29, 0x1F); // Player Block Placement in(State.PLAY, 0x2A, 0x20); // Use Item - } @Override @@ -152,6 +144,10 @@ public class Protocol1_12_2To1_13 extends BackwardsProtocol { // Register Block Storage if (!user.has(TabCompleteStorage.class)) user.put(new TabCompleteStorage(user)); + + if (ViaBackwards.getConfig().isFix1_13FacePlayer() && !user.has(PlayerPositionStorage1_13.class)) { + user.put(new PlayerPositionStorage1_13(user)); + } } @Override diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/EntityPackets1_13.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/EntityPackets1_13.java index a06d1b16..6b2c754a 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/EntityPackets1_13.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/EntityPackets1_13.java @@ -1,12 +1,14 @@ package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.packets; import nl.matsv.viabackwards.ViaBackwards; +import nl.matsv.viabackwards.api.entities.storage.EntityPositionHandler; import nl.matsv.viabackwards.api.exceptions.RemovedValueException; import nl.matsv.viabackwards.api.rewriters.EntityRewriter; import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.Protocol1_12_2To1_13; import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.EntityTypeMapping; import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.PaintingMapping; import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.data.ParticleMapping; +import nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage.PlayerPositionStorage1_13; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.entities.Entity1_13Types; import us.myles.ViaVersion.api.entities.EntityType; @@ -28,6 +30,52 @@ public class EntityPackets1_13 extends EntityRewriter { @Override protected void registerPackets(Protocol1_12_2To1_13 protocol) { + // Entity teleport + protocol.registerOutgoing(State.PLAY, 0x50, 0x4C, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); + map(Type.DOUBLE); + map(Type.DOUBLE); + map(Type.DOUBLE); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + if (!ViaBackwards.getConfig().isFix1_13FacePlayer()) return; + PlayerPositionStorage1_13 playerStorage = wrapper.user().get(PlayerPositionStorage1_13.class); + if (playerStorage.getEntityId() == wrapper.get(Type.VAR_INT, 0)) { + playerStorage.setCoordinates(wrapper, false); + } + } + }); + } + }); + + // Entity relative move + Entity look and relative move + PacketRemapper relativeMoveHandler = new PacketRemapper() { + @Override + public void registerMap() { + map(Type.VAR_INT); + map(Type.SHORT); + map(Type.SHORT); + map(Type.SHORT); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + if (!ViaBackwards.getConfig().isFix1_13FacePlayer()) return; + PlayerPositionStorage1_13 playerStorage = wrapper.user().get(PlayerPositionStorage1_13.class); + if (playerStorage.getEntityId() == wrapper.get(Type.VAR_INT, 0)) { + double x = wrapper.get(Type.SHORT, 0) / EntityPositionHandler.RELATIVE_MOVE_FACTOR; + double y = wrapper.get(Type.SHORT, 1) / EntityPositionHandler.RELATIVE_MOVE_FACTOR; + double z = wrapper.get(Type.SHORT, 2) / EntityPositionHandler.RELATIVE_MOVE_FACTOR; + playerStorage.setCoordinates(x, y, z, true); + } + } + }); + } + }; + protocol.registerOutgoing(State.PLAY, 0x28, 0x26, relativeMoveHandler); + protocol.registerOutgoing(State.PLAY, 0x29, 0x27, relativeMoveHandler); //Spawn Object protocol.out(State.PLAY, 0x00, 0x00, new PacketRemapper() { @@ -139,6 +187,16 @@ public class EntityPackets1_13 extends EntityRewriter { map(Types1_13.METADATA_LIST, Types1_12.METADATA_LIST); handler(getTrackerAndMetaHandler(Types1_12.METADATA_LIST, Entity1_13Types.EntityType.PLAYER)); + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + if (!ViaBackwards.getConfig().isFix1_13FacePlayer()) return; + PlayerPositionStorage1_13 positionStorage = wrapper.user().get(PlayerPositionStorage1_13.class); + if (positionStorage.getEntityId() == wrapper.get(Type.VAR_INT, 0)) { + positionStorage.setCoordinates(wrapper, false); + } + } + }); } }); @@ -171,6 +229,10 @@ public class EntityPackets1_13 extends EntityRewriter { handler(getTrackerHandler(Entity1_13Types.EntityType.PLAYER, Type.INT)); handler(getDimensionHandler(1)); + handler(wrapper -> { + if (!ViaBackwards.getConfig().isFix1_13FacePlayer()) return; + wrapper.user().get(PlayerPositionStorage1_13.class).setEntityId(wrapper.get(Type.INT, 0)); + }); } }); @@ -189,6 +251,66 @@ public class EntityPackets1_13 extends EntityRewriter { // Entity Metadata packet registerMetadataRewriter(0x3F, 0x3C, Types1_13.METADATA_LIST, Types1_12.METADATA_LIST); + + // Face Player (new packet) + protocol.out(State.PLAY, 0x31, -1, new PacketRemapper() { + @Override + public void registerMap() { + handler(new PacketHandler() { + @Override + public void handle(PacketWrapper wrapper) throws Exception { + wrapper.cancel(); + + if (!ViaBackwards.getConfig().isFix1_13FacePlayer()) return; + + // We will just accept a possible, very minor mismatch between server and client position, + // and will take the server's one in both cases, else we would have to cache all entities' positions. + final int anchor = wrapper.read(Type.VAR_INT); // feet/eyes enum + final double x = wrapper.read(Type.DOUBLE); + final double y = wrapper.read(Type.DOUBLE); + final double z = wrapper.read(Type.DOUBLE); + + PlayerPositionStorage1_13 positionStorage = wrapper.user().get(PlayerPositionStorage1_13.class); + + PacketWrapper pPacket = wrapper.create(0x12); + EntityPositionHandler.writeFacingDegrees(pPacket, positionStorage.getX(), + anchor == 1 ? positionStorage.getY() + 1.62 : positionStorage.getY(), + positionStorage.getZ(), x, y, z); + pPacket.write(Type.BOOLEAN, false); + pPacket.sendToServer(Protocol1_12_2To1_13.class); + + PacketWrapper lookPacket = wrapper.create(0x28); + + lookPacket.write(Type.VAR_INT, positionStorage.getEntityId()); + //TODO properly cache and calculate head position + EntityPositionHandler.writeFacingAngles(lookPacket, positionStorage.getX(), + anchor == 1 ? positionStorage.getY() + 1.62 : positionStorage.getY(), + positionStorage.getZ(), x, y, z); + lookPacket.write(Type.BOOLEAN, false); + lookPacket.send(Protocol1_12_2To1_13.class); + } + }); + } + }); + + if (ViaBackwards.getConfig().isFix1_13FacePlayer()) { + PacketRemapper movementRemapper = new PacketRemapper() { + @Override + public void registerMap() { + map(Type.DOUBLE); + map(Type.DOUBLE); + map(Type.DOUBLE); + handler(wrapper -> wrapper.user().get(PlayerPositionStorage1_13.class).setCoordinates(wrapper, false)); + } + }; + protocol.in(State.PLAY, 0x10, 0x0D, movementRemapper); // Player Position + protocol.in(State.PLAY, 0x11, 0x0E, movementRemapper); // Player Position And Look (serverbound) + protocol.in(State.PLAY, 0x13, 0x10, movementRemapper); // Vehicle Move (serverbound) + } else { + protocol.in(State.PLAY, 0x10, 0x0D); // Player Position + protocol.in(State.PLAY, 0x11, 0x0E); // Player Position And Look (serverbound) + protocol.in(State.PLAY, 0x13, 0x10); // Vehicle Move (serverbound) + } } @Override diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/PlayerPacket1_13.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/PlayerPacket1_13.java index 9526cf65..9a35b64e 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/PlayerPacket1_13.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/packets/PlayerPacket1_13.java @@ -49,7 +49,6 @@ public class PlayerPacket1_13 extends Rewriter { } }); - //Plugin Message protocol.out(State.PLAY, 0x19, 0x18, new PacketRemapper() { @Override @@ -140,8 +139,6 @@ public class PlayerPacket1_13 extends Rewriter { wrapper.write(Type.VAR_INT, i); } }); - - } }); @@ -272,7 +269,7 @@ public class PlayerPacket1_13 extends Rewriter { } }); - // Tab-Complete (clientbound) TODO MODIFIED + // Tab-Complete (clientbound) protocol.out(State.PLAY, 0x10, 0x0E, new PacketRemapper() { @Override public void registerMap() { diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/storage/PlayerPositionStorage1_13.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/storage/PlayerPositionStorage1_13.java new file mode 100644 index 00000000..2f4dd753 --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_12_2to1_13/storage/PlayerPositionStorage1_13.java @@ -0,0 +1,21 @@ +package nl.matsv.viabackwards.protocol.protocol1_12_2to1_13.storage; + +import nl.matsv.viabackwards.api.entities.storage.object.PlayerPositionStorage; +import us.myles.ViaVersion.api.data.UserConnection; + +public class PlayerPositionStorage1_13 extends PlayerPositionStorage { + + private int entityId; + + public PlayerPositionStorage1_13(UserConnection user) { + super(user); + } + + public int getEntityId() { + return entityId; + } + + public void setEntityId(int entityId) { + this.entityId = entityId; + } +} diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/EntityPackets1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/EntityPackets1_14.java index 046cae10..e3ca87e1 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/EntityPackets1_14.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/EntityPackets1_14.java @@ -3,15 +3,14 @@ package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.packets; import nl.matsv.viabackwards.ViaBackwards; import nl.matsv.viabackwards.api.entities.meta.MetaHandler; import nl.matsv.viabackwards.api.entities.storage.EntityData; -import nl.matsv.viabackwards.api.entities.storage.EntityTracker; +import nl.matsv.viabackwards.api.entities.storage.EntityPositionHandler; import nl.matsv.viabackwards.api.exceptions.RemovedValueException; import nl.matsv.viabackwards.api.rewriters.EntityRewriter; import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14; -import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data.EntityPositionStorage; import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data.EntityTypeMapping; import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.storage.ChunkLightStorage; +import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.storage.EntityPositionStorage1_14; import us.myles.ViaVersion.api.PacketWrapper; -import us.myles.ViaVersion.api.Via; import us.myles.ViaVersion.api.entities.Entity1_13Types; import us.myles.ViaVersion.api.entities.Entity1_14Types; import us.myles.ViaVersion.api.entities.EntityType; @@ -34,8 +33,7 @@ import java.util.Optional; public class EntityPackets1_14 extends EntityRewriter { - private static final double RELATIVE_MOVE_FACTOR = 32 * 128; - private boolean warnedForMissingEntity; + private EntityPositionHandler positionHandler; @Override protected void addTrackedEntity(PacketWrapper wrapper, int entityId, EntityType type) throws Exception { @@ -44,14 +42,16 @@ public class EntityPackets1_14 extends EntityRewriter { // Cache the position for every newly tracked entity if (type == Entity1_14Types.EntityType.PAINTING) { final Position position = wrapper.get(Type.POSITION, 0); - cacheEntityPosition(wrapper, position.getX(), position.getY(), position.getZ(), true, false); + positionHandler.cacheEntityPosition(wrapper, position.getX(), position.getY(), position.getZ(), true, false); } else if (wrapper.getId() != 0x25) { // ignore join game - cacheEntityPosition(wrapper, true, false); + positionHandler.cacheEntityPosition(wrapper, true, false); } } @Override protected void registerPackets(Protocol1_13_2To1_14 protocol) { + positionHandler = new EntityPositionHandler(this, EntityPositionStorage1_14.class, EntityPositionStorage1_14::new); + // Entity teleport protocol.registerOutgoing(State.PLAY, 0x56, 0x50, new PacketRemapper() { @Override @@ -60,7 +60,7 @@ public class EntityPackets1_14 extends EntityRewriter { map(Type.DOUBLE); map(Type.DOUBLE); map(Type.DOUBLE); - handler(wrapper -> cacheEntityPosition(wrapper, false, false)); + handler(wrapper -> positionHandler.cacheEntityPosition(wrapper, false, false)); } }); @@ -75,10 +75,10 @@ public class EntityPackets1_14 extends EntityRewriter { handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) throws Exception { - double x = wrapper.get(Type.SHORT, 0) / RELATIVE_MOVE_FACTOR; - double y = wrapper.get(Type.SHORT, 1) / RELATIVE_MOVE_FACTOR; - double z = wrapper.get(Type.SHORT, 2) / RELATIVE_MOVE_FACTOR; - cacheEntityPosition(wrapper, x, y, z, false, true); + double x = wrapper.get(Type.SHORT, 0) / EntityPositionHandler.RELATIVE_MOVE_FACTOR; + double y = wrapper.get(Type.SHORT, 1) / EntityPositionHandler.RELATIVE_MOVE_FACTOR; + double z = wrapper.get(Type.SHORT, 2) / EntityPositionHandler.RELATIVE_MOVE_FACTOR; + positionHandler.cacheEntityPosition(wrapper, x, y, z, false, true); } }); } @@ -271,7 +271,7 @@ public class EntityPackets1_14 extends EntityRewriter { map(Types1_14.METADATA_LIST, Types1_13_2.METADATA_LIST); // 7 - Metadata handler(getTrackerAndMetaHandler(Types1_13_2.METADATA_LIST, Entity1_14Types.EntityType.PLAYER)); - handler(wrapper -> cacheEntityPosition(wrapper, true, false)); + handler(wrapper -> positionHandler.cacheEntityPosition(wrapper, true, false)); } }); @@ -508,37 +508,6 @@ public class EntityPackets1_14 extends EntityRewriter { }); } - private void cacheEntityPosition(PacketWrapper wrapper, boolean create, boolean relative) throws Exception { - cacheEntityPosition(wrapper, - wrapper.get(Type.DOUBLE, 0), wrapper.get(Type.DOUBLE, 1), wrapper.get(Type.DOUBLE, 2), create, relative); - } - - private void cacheEntityPosition(PacketWrapper wrapper, double x, double y, double z, boolean create, boolean relative) throws Exception { - int entityId = wrapper.get(Type.VAR_INT, 0); - Optional optStoredEntity = getEntityTracker(wrapper.user()).getEntity(entityId); - if (!optStoredEntity.isPresent()) { - if (!Via.getConfig().isSuppressMetadataErrors()) { - ViaBackwards.getPlatform().getLogger().warning("Stored entity with id " + entityId + " missing at position: " + x + " - " + y + " - " + z); - if (!warnedForMissingEntity) { - warnedForMissingEntity = true; - ViaBackwards.getPlatform().getLogger().warning("This is very likely caused by a plugin sending a teleport packet for an entity outside of the player's range."); - ViaBackwards.getPlatform().getLogger().warning("You can disable this warning in the ViaVersion config under \"suppress-metadata-errors\""); - } - } - return; - } - - EntityTracker.StoredEntity storedEntity = optStoredEntity.get(); - EntityPositionStorage positionStorage = create ? new EntityPositionStorage() : storedEntity.get(EntityPositionStorage.class); - if (positionStorage == null) { - ViaBackwards.getPlatform().getLogger().warning("Stored entity with id " + entityId + " missing entitypositionstorage!"); - return; - } - - positionStorage.setCoordinates(x, y, z, relative); - storedEntity.put(positionStorage); - } - public int villagerDataToProfession(VillagerData data) { switch (data.getProfession()) { case 1: // Armorer diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/SoundPackets1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/SoundPackets1_14.java index 355b0395..bd9709aa 100644 --- a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/SoundPackets1_14.java +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/packets/SoundPackets1_14.java @@ -5,7 +5,7 @@ import nl.matsv.viabackwards.api.entities.storage.EntityTracker; import nl.matsv.viabackwards.api.rewriters.Rewriter; import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.Protocol1_13_2To1_14; import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data.BackwardsMappings; -import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.data.EntityPositionStorage; +import nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.storage.EntityPositionStorage1_14; import us.myles.ViaVersion.api.PacketWrapper; import us.myles.ViaVersion.api.remapper.PacketHandler; import us.myles.ViaVersion.api.remapper.PacketRemapper; @@ -53,8 +53,8 @@ public class SoundPackets1_14 extends Rewriter { int entityId = wrapper.read(Type.VAR_INT); Optional optEntity = wrapper.user().get(EntityTracker.class).get(protocol).getEntity(entityId); - EntityPositionStorage storedEntity; - if (!optEntity.isPresent() || (storedEntity = optEntity.get().get(EntityPositionStorage.class)) == null) { + EntityPositionStorage1_14 storedEntity; + if (!optEntity.isPresent() || (storedEntity = optEntity.get().get(EntityPositionStorage1_14.class)) == null) { ViaBackwards.getPlatform().getLogger().warning("Untracked entity with id " + entityId); return; } diff --git a/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/storage/EntityPositionStorage1_14.java b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/storage/EntityPositionStorage1_14.java new file mode 100644 index 00000000..1b50b1cd --- /dev/null +++ b/core/src/main/java/nl/matsv/viabackwards/protocol/protocol1_13_2to1_14/storage/EntityPositionStorage1_14.java @@ -0,0 +1,6 @@ +package nl.matsv.viabackwards.protocol.protocol1_13_2to1_14.storage; + +import nl.matsv.viabackwards.api.entities.storage.EntityPositionStorage; + +public class EntityPositionStorage1_14 extends EntityPositionStorage { +} diff --git a/core/src/main/resources/assets/viabackwards/config.yml b/core/src/main/resources/assets/viabackwards/config.yml index f27096c3..a6a03eb6 100644 --- a/core/src/main/resources/assets/viabackwards/config.yml +++ b/core/src/main/resources/assets/viabackwards/config.yml @@ -5,4 +5,8 @@ add-custom-enchants-into-lore: true # # Adds the color of a scoreboard team after its prefix for 1.12 clients on 1.13+ servers. -add-teamcolor-to-prefix: true \ No newline at end of file +add-teamcolor-to-prefix: true +# +# Converts the 1.13 face look-at packet for 1.12- players. +# Might produce a bit of overhead and caching, so you may turn this off if unused (usually only sent by the vanilla teleport). +fix-1_13-face-player: true \ No newline at end of file