3
0
Mirror von https://github.com/ViaVersion/ViaVersion.git synchronisiert 2024-07-30 19:08:03 +02:00

Fix lightning, track entities sent to the client and use them for mapping MetaIndex instead of previous method. (Allows custom entities and client side packets properly. Echo Pet works!!! + fixes some latency with methods)

Dieser Commit ist enthalten in:
Myles 2016-03-01 23:16:10 +00:00
Ursprung 1445bd37c3
Commit f9da275358
2 geänderte Dateien mit 71 neuen und 32 gelöschten Zeilen

Datei anzeigen

@ -2,13 +2,15 @@ package us.myles.ViaVersion.transformers;
import com.google.gson.Gson;
import com.google.gson.JsonObject;
import com.sun.xml.internal.bind.v2.runtime.reflect.Lister;
import io.netty.buffer.ByteBuf;
import io.netty.channel.Channel;
import org.bukkit.Bukkit;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.spacehq.mc.protocol.data.game.chunk.Column;
import org.spacehq.mc.protocol.util.NetUtil;
import us.myles.ViaVersion.*;
import us.myles.ViaVersion.CancelException;
import us.myles.ViaVersion.ConnectionInfo;
import us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
import us.myles.ViaVersion.metadata.MetaIndex;
@ -23,7 +25,6 @@ import us.myles.ViaVersion.util.ReflectionUtil;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;
import static us.myles.ViaVersion.util.PacketUtil.*;
@ -36,6 +37,7 @@ public class OutgoingTransformer {
private final ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
private boolean cancel = false;
private Map<Integer, UUID> uuidMap = new HashMap<Integer, UUID>();
private Map<Integer, EntityType> clientEntityTypes = new HashMap<Integer, EntityType>();
public OutgoingTransformer(Channel channel, ConnectionInfo info, ViaVersionInitializer init) {
this.channel = channel;
@ -212,13 +214,7 @@ public class OutgoingTransformer {
try {
List dw = ReflectionUtil.get(info.getLastPacket(), "b", List.class);
// get entity via entityID, not preferred but we need it.
Entity entity = ViaVersionPlugin.getEntity(info.getUUID(), id);
if (entity != null) {
transformMetadata(entity, dw, output);
} else {
// Died before we could get to it. rip
throw new CancelException();
}
transformMetadata(id, dw, output);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
@ -226,13 +222,41 @@ public class OutgoingTransformer {
}
return;
}
if (packet == PacketType.PLAY_SPAWN_OBJECT) {
if (packet == PacketType.PLAY_SPAWN_GLOBAL_ENTITY) {
int id = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(id, output);
// only used for lightning
byte type = input.readByte();
clientEntityTypes.put(id, EntityType.LIGHTNING);
output.writeByte(type);
double x = input.readInt();
output.writeDouble(x / 32D);
double y = input.readInt();
output.writeDouble(y / 32D);
double z = input.readInt();
output.writeDouble(z / 32D);
return;
}
if (packet == PacketType.PLAY_DESTROY_ENTITIES) {
int count = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(count, output);
int[] toDestroy = PacketUtil.readVarInts(count, input);
for (int entityID : toDestroy) {
clientEntityTypes.remove(entityID);
PacketUtil.writeVarInt(entityID, output);
}
return;
}
if (packet == PacketType.PLAY_SPAWN_OBJECT) {
int id = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(id, output);
PacketUtil.writeUUID(getUUID(id), output);
byte type = input.readByte();
clientEntityTypes.put(id, EntityUtil.getTypeFromID(type, true));
output.writeByte(type);
double x = input.readInt();
@ -258,8 +282,9 @@ public class OutgoingTransformer {
return;
}
if (packet == PacketType.PLAY_SPAWN_XP_ORB) { // TODO: Verify
if (packet == PacketType.PLAY_SPAWN_XP_ORB) {
int id = PacketUtil.readVarInt(input);
clientEntityTypes.put(id, EntityType.EXPERIENCE_ORB);
PacketUtil.writeVarInt(id, output);
double x = input.readInt();
@ -276,6 +301,7 @@ public class OutgoingTransformer {
}
if (packet == PacketType.PLAY_SPAWN_PAINTING) {
int id = PacketUtil.readVarInt(input);
clientEntityTypes.put(id, EntityType.PAINTING);
PacketUtil.writeVarInt(id, output);
PacketUtil.writeUUID(getUUID(id), output);
@ -308,7 +334,9 @@ public class OutgoingTransformer {
PacketUtil.writeUUID(getUUID(id), output);
short type = input.readUnsignedByte();
clientEntityTypes.put(id, EntityUtil.getTypeFromID(type, false));
output.writeByte(type);
double x = input.readInt();
output.writeDouble(x / 32D);
double y = input.readInt();
@ -330,7 +358,7 @@ public class OutgoingTransformer {
output.writeShort(vZ);
try {
Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "l", ReflectionUtil.nms("DataWatcher"));
transformMetadata(dataWatcher, output);
transformMetadata(id, dataWatcher, output);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
@ -348,10 +376,17 @@ public class OutgoingTransformer {
PacketUtil.writeString(fixJson(line), output);
}
}
if (packet == PacketType.PLAY_JOIN_GAME) {
int id = input.readInt();
clientEntityTypes.put(id, EntityType.PLAYER);
output.writeInt(id);
output.writeBytes(input);
return;
}
if (packet == PacketType.PLAY_SPAWN_PLAYER) {
int id = PacketUtil.readVarInt(input);
PacketUtil.writeVarInt(id, output);
clientEntityTypes.put(id, EntityType.PLAYER);
UUID playerUUID = PacketUtil.readUUID(input);
PacketUtil.writeUUID(playerUUID, output);
@ -368,7 +403,7 @@ public class OutgoingTransformer {
output.writeByte(yaw);
try {
Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "i", ReflectionUtil.nms("DataWatcher"));
transformMetadata(dataWatcher, output);
transformMetadata(id, dataWatcher, output);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
@ -469,30 +504,25 @@ public class OutgoingTransformer {
return line;
}
private void transformMetadata(Object dw, ByteBuf output) {
private void transformMetadata(int entityID, Object dw, ByteBuf output) {
// get entity
try {
Class<?> nmsClass = ReflectionUtil.nms("Entity");
Object nmsEntity = ReflectionUtil.get(dw, "a", nmsClass);
Class<?> craftClass = ReflectionUtil.obc("entity.CraftEntity");
Method bukkitMethod = craftClass.getDeclaredMethod("getEntity", ReflectionUtil.obc("CraftServer"), nmsClass);
Object entity = bukkitMethod.invoke(null, Bukkit.getServer(), nmsEntity);
transformMetadata((Entity) entity, (List) ReflectionUtil.invoke(dw, "b"), output);
} catch (NoSuchFieldException e) {
e.printStackTrace();
transformMetadata(entityID, (List) ReflectionUtil.invoke(dw, "b"), output);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private void transformMetadata(Entity entity, List dw, ByteBuf output) {
private void transformMetadata(int entityID, List dw, ByteBuf output) {
EntityType type = clientEntityTypes.get(entityID);
if (type == null) {
System.out.println("Unable to get entity for ID: " + entityID);
return;
}
if (dw != null) {
short id = -1;
int data = -1;
@ -502,7 +532,7 @@ public class OutgoingTransformer {
Object watchableObj = iterator.next(); //
MetaIndex metaIndex = null;
try {
metaIndex = MetaIndex.getIndex(entity, (int) ReflectionUtil.invoke(watchableObj, "a"));
metaIndex = MetaIndex.getIndex(type, (int) ReflectionUtil.invoke(watchableObj, "a"));
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
@ -592,8 +622,8 @@ public class OutgoingTransformer {
}
} catch (Exception e) {
if (entity != null) {
System.out.println("An error occurred with entity meta data for " + entity.getType());
if (type != null) {
System.out.println("An error occurred with entity meta data for " + type);
System.out.println("Old ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex());
System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType());
}

Datei anzeigen

@ -376,4 +376,13 @@ public class PacketUtil {
public static void writeBlockPosition(ByteBuf buf, long x, long y, long z) {
buf.writeLong(((x & 0x3ffffff) << 38) | ((y & 0xfff) << 26) | (z & 0x3ffffff));
}
public static int[] readVarInts(int amount, ByteBuf input) {
int data[] = new int[amount];
for (int index = 0; index < amount; index++) {
data[index] = PacketUtil.readVarInt(input);
}
return data;
}
}