Skip to content

Commit

Permalink
Improve smooth teleport
Browse files Browse the repository at this point in the history
Revert much of the reflection
  • Loading branch information
TylerS1066 committed Sep 26, 2023
1 parent 6f528f0 commit 1abd580
Showing 1 changed file with 18 additions and 61 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@

import net.countercraft.movecraft.SmoothTeleport;
import net.countercraft.movecraft.util.ReflectUtils;
import net.minecraft.network.protocol.game.ClientboundPlayerPositionPacket;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.server.network.ServerGamePacketListenerImpl;
import net.minecraft.world.entity.RelativeMovement;
import net.minecraft.world.phys.Vec3;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;

/**
Expand All @@ -18,82 +20,37 @@
* Used for 1.20.2
*/
public class ISmoothTeleport extends SmoothTeleport {
private final Set<Object> teleportFlags;

private final Method positionMethod;
private final Method sendMethod;

private final Constructor<?> vec3Constructor;
private final Constructor<?> packetConstructor;

private final Field connectionField;
private final Field teleportPosField;
private final Field teleportAwaitField;
private final Field awaitingTeleportTimeField;
private final Field tickCountField;
private final Field yawField;
private final Field pitchField;

private static @NotNull Class<?> getNmClass(String name) throws ClassNotFoundException {
return Class.forName("net.minecraft." + name);
}

private void sendPacket(Object packet, Player p) {
try {
Object handle = ReflectUtils.getHandle(p);
Object pConnection = connectionField.get(handle);
sendMethod.invoke(pConnection, packet);
}
catch (Exception e) {
e.printStackTrace();
}
}

public ISmoothTeleport() throws NoSuchFieldException, NoSuchMethodException, ClassNotFoundException {
Class<?> packetClass = getNmClass("network.protocol.Packet");
Class<?> positionPacketClass = getNmClass("network.protocol.game.PacketPlayOutPosition"); // ClientboundPlayerPositionPacket
Class<?> entityClass = getNmClass("world.entity.Entity");
Class<?> playerClass = getNmClass("server.level.EntityPlayer"); // ServerPlayer
Class<?> connectionClass = getNmClass("server.network.PlayerConnection"); // ServerGamePacketListenerImpl
Class<?> vectorClass = getNmClass("world.phys.Vec3D"); // Vec3

Object[] flags = getNmClass("world.entity.RelativeMovement").getEnumConstants();
teleportFlags = Set.of(flags[4], flags[3]); // X_ROT, Y_ROT

positionMethod = entityClass.getDeclaredMethod("a", Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE); // absMoveTo
sendMethod = connectionClass.getMethod("a", packetClass); // send TODO!

vec3Constructor = vectorClass.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE);
packetConstructor = positionPacketClass.getConstructor(Double.TYPE, Double.TYPE, Double.TYPE, Float.TYPE, Float.TYPE, Set.class, Integer.TYPE);

connectionField = ReflectUtils.getField(playerClass, "c"); // connection
teleportPosField = ReflectUtils.getField(connectionClass, "B"); // awaitingPositionFromClient
teleportAwaitField = ReflectUtils.getField(connectionClass, "C"); // awaitingTeleport
awaitingTeleportTimeField = ReflectUtils.getField(connectionClass, "D"); // awaitingTeleportTime
tickCountField = ReflectUtils.getField(connectionClass, "k"); // tickCount
yawField = ReflectUtils.getField(entityClass, "aH"); // xRot
pitchField = ReflectUtils.getField(entityClass, "aG"); // yRot
public ISmoothTeleport() throws NoSuchFieldException, ClassNotFoundException {
teleportPosField = ReflectUtils.getField(ServerGamePacketListenerImpl.class, "B"); // awaitingPositionFromClient
teleportAwaitField = ReflectUtils.getField(ServerGamePacketListenerImpl.class, "C"); // awaitingTeleport
awaitingTeleportTimeField = ReflectUtils.getField(ServerGamePacketListenerImpl.class, "D"); // awaitingTeleportTime
tickCountField = ReflectUtils.getField(ServerGamePacketListenerImpl.class, "k"); // tickCount
}

public void teleport(Player player, @NotNull Location location, float yawChange, float pitchChange) {
double x = location.getX();
double y = location.getY();
double z = location.getZ();
Object handle = ReflectUtils.getHandle(player);
ServerPlayer handle = (ServerPlayer) ReflectUtils.getHandle(player);

try {
positionMethod.invoke(handle, x, y, z, yawField.get(handle), pitchField.get(handle));
Object connection = connectionField.get(handle);
teleportPosField.set(connection, vec3Constructor.newInstance(x, y, z));
handle.absMoveTo(x, y, z, handle.getXRot(), handle.getYRot());
ServerGamePacketListenerImpl connection = handle.connection;
teleportPosField.set(connection, new Vec3(x, y, z));
int teleportAwait = teleportAwaitField.getInt(connection) + 1;
if (teleportAwait == Integer.MAX_VALUE)
teleportAwait = 0;
teleportAwaitField.setInt(connection, teleportAwait);
awaitingTeleportTimeField.set(connection, tickCountField.get(connection));

Object packet = packetConstructor.newInstance(x, y, z, yawChange, pitchChange, teleportFlags, teleportAwait);
sendPacket(packet, player);
}
catch (IllegalAccessException | InvocationTargetException | InstantiationException e) {
ClientboundPlayerPositionPacket packet = new ClientboundPlayerPositionPacket(x, y, z, yawChange, pitchChange, Set.of(RelativeMovement.X_ROT, RelativeMovement.Y_ROT), teleportAwait);
connection.send(packet);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
Expand Down

0 comments on commit 1abd580

Please sign in to comment.