Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-11-03 14:50:30 +01: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:
Ursprung
1445bd37c3
Commit
f9da275358
@ -2,13 +2,15 @@ package us.myles.ViaVersion.transformers;
|
|||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
|
import com.sun.xml.internal.bind.v2.runtime.reflect.Lister;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.channel.Channel;
|
import io.netty.channel.Channel;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Entity;
|
|
||||||
import org.spacehq.mc.protocol.data.game.chunk.Column;
|
import org.spacehq.mc.protocol.data.game.chunk.Column;
|
||||||
import org.spacehq.mc.protocol.util.NetUtil;
|
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.api.ViaVersion;
|
||||||
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
|
import us.myles.ViaVersion.handlers.ViaVersionInitializer;
|
||||||
import us.myles.ViaVersion.metadata.MetaIndex;
|
import us.myles.ViaVersion.metadata.MetaIndex;
|
||||||
@ -23,7 +25,6 @@ import us.myles.ViaVersion.util.ReflectionUtil;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static us.myles.ViaVersion.util.PacketUtil.*;
|
import static us.myles.ViaVersion.util.PacketUtil.*;
|
||||||
@ -36,6 +37,7 @@ public class OutgoingTransformer {
|
|||||||
private final ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
|
private final ViaVersionPlugin plugin = (ViaVersionPlugin) ViaVersion.getInstance();
|
||||||
private boolean cancel = false;
|
private boolean cancel = false;
|
||||||
private Map<Integer, UUID> uuidMap = new HashMap<Integer, UUID>();
|
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) {
|
public OutgoingTransformer(Channel channel, ConnectionInfo info, ViaVersionInitializer init) {
|
||||||
this.channel = channel;
|
this.channel = channel;
|
||||||
@ -212,13 +214,7 @@ public class OutgoingTransformer {
|
|||||||
try {
|
try {
|
||||||
List dw = ReflectionUtil.get(info.getLastPacket(), "b", List.class);
|
List dw = ReflectionUtil.get(info.getLastPacket(), "b", List.class);
|
||||||
// get entity via entityID, not preferred but we need it.
|
// get entity via entityID, not preferred but we need it.
|
||||||
Entity entity = ViaVersionPlugin.getEntity(info.getUUID(), id);
|
transformMetadata(id, dw, output);
|
||||||
if (entity != null) {
|
|
||||||
transformMetadata(entity, dw, output);
|
|
||||||
} else {
|
|
||||||
// Died before we could get to it. rip
|
|
||||||
throw new CancelException();
|
|
||||||
}
|
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
@ -226,13 +222,41 @@ public class OutgoingTransformer {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (packet == PacketType.PLAY_SPAWN_OBJECT) {
|
if (packet == PacketType.PLAY_SPAWN_GLOBAL_ENTITY) {
|
||||||
int id = PacketUtil.readVarInt(input);
|
int id = PacketUtil.readVarInt(input);
|
||||||
PacketUtil.writeVarInt(id, output);
|
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);
|
PacketUtil.writeUUID(getUUID(id), output);
|
||||||
|
|
||||||
byte type = input.readByte();
|
byte type = input.readByte();
|
||||||
|
clientEntityTypes.put(id, EntityUtil.getTypeFromID(type, true));
|
||||||
output.writeByte(type);
|
output.writeByte(type);
|
||||||
|
|
||||||
double x = input.readInt();
|
double x = input.readInt();
|
||||||
@ -258,8 +282,9 @@ public class OutgoingTransformer {
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (packet == PacketType.PLAY_SPAWN_XP_ORB) { // TODO: Verify
|
if (packet == PacketType.PLAY_SPAWN_XP_ORB) {
|
||||||
int id = PacketUtil.readVarInt(input);
|
int id = PacketUtil.readVarInt(input);
|
||||||
|
clientEntityTypes.put(id, EntityType.EXPERIENCE_ORB);
|
||||||
PacketUtil.writeVarInt(id, output);
|
PacketUtil.writeVarInt(id, output);
|
||||||
|
|
||||||
double x = input.readInt();
|
double x = input.readInt();
|
||||||
@ -276,6 +301,7 @@ public class OutgoingTransformer {
|
|||||||
}
|
}
|
||||||
if (packet == PacketType.PLAY_SPAWN_PAINTING) {
|
if (packet == PacketType.PLAY_SPAWN_PAINTING) {
|
||||||
int id = PacketUtil.readVarInt(input);
|
int id = PacketUtil.readVarInt(input);
|
||||||
|
clientEntityTypes.put(id, EntityType.PAINTING);
|
||||||
PacketUtil.writeVarInt(id, output);
|
PacketUtil.writeVarInt(id, output);
|
||||||
|
|
||||||
PacketUtil.writeUUID(getUUID(id), output);
|
PacketUtil.writeUUID(getUUID(id), output);
|
||||||
@ -308,7 +334,9 @@ public class OutgoingTransformer {
|
|||||||
|
|
||||||
PacketUtil.writeUUID(getUUID(id), output);
|
PacketUtil.writeUUID(getUUID(id), output);
|
||||||
short type = input.readUnsignedByte();
|
short type = input.readUnsignedByte();
|
||||||
|
clientEntityTypes.put(id, EntityUtil.getTypeFromID(type, false));
|
||||||
output.writeByte(type);
|
output.writeByte(type);
|
||||||
|
|
||||||
double x = input.readInt();
|
double x = input.readInt();
|
||||||
output.writeDouble(x / 32D);
|
output.writeDouble(x / 32D);
|
||||||
double y = input.readInt();
|
double y = input.readInt();
|
||||||
@ -330,7 +358,7 @@ public class OutgoingTransformer {
|
|||||||
output.writeShort(vZ);
|
output.writeShort(vZ);
|
||||||
try {
|
try {
|
||||||
Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "l", ReflectionUtil.nms("DataWatcher"));
|
Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "l", ReflectionUtil.nms("DataWatcher"));
|
||||||
transformMetadata(dataWatcher, output);
|
transformMetadata(id, dataWatcher, output);
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
@ -348,10 +376,17 @@ public class OutgoingTransformer {
|
|||||||
PacketUtil.writeString(fixJson(line), output);
|
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) {
|
if (packet == PacketType.PLAY_SPAWN_PLAYER) {
|
||||||
int id = PacketUtil.readVarInt(input);
|
int id = PacketUtil.readVarInt(input);
|
||||||
PacketUtil.writeVarInt(id, output);
|
PacketUtil.writeVarInt(id, output);
|
||||||
|
clientEntityTypes.put(id, EntityType.PLAYER);
|
||||||
UUID playerUUID = PacketUtil.readUUID(input);
|
UUID playerUUID = PacketUtil.readUUID(input);
|
||||||
PacketUtil.writeUUID(playerUUID, output);
|
PacketUtil.writeUUID(playerUUID, output);
|
||||||
|
|
||||||
@ -368,7 +403,7 @@ public class OutgoingTransformer {
|
|||||||
output.writeByte(yaw);
|
output.writeByte(yaw);
|
||||||
try {
|
try {
|
||||||
Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "i", ReflectionUtil.nms("DataWatcher"));
|
Object dataWatcher = ReflectionUtil.get(info.getLastPacket(), "i", ReflectionUtil.nms("DataWatcher"));
|
||||||
transformMetadata(dataWatcher, output);
|
transformMetadata(id, dataWatcher, output);
|
||||||
} catch (NoSuchFieldException e) {
|
} catch (NoSuchFieldException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
@ -469,30 +504,25 @@ public class OutgoingTransformer {
|
|||||||
return line;
|
return line;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transformMetadata(Object dw, ByteBuf output) {
|
private void transformMetadata(int entityID, Object dw, ByteBuf output) {
|
||||||
// get entity
|
// get entity
|
||||||
try {
|
try {
|
||||||
Class<?> nmsClass = ReflectionUtil.nms("Entity");
|
transformMetadata(entityID, (List) ReflectionUtil.invoke(dw, "b"), output);
|
||||||
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();
|
|
||||||
} catch (IllegalAccessException e) {
|
} catch (IllegalAccessException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
e.printStackTrace();
|
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) {
|
if (dw != null) {
|
||||||
short id = -1;
|
short id = -1;
|
||||||
int data = -1;
|
int data = -1;
|
||||||
@ -502,7 +532,7 @@ public class OutgoingTransformer {
|
|||||||
Object watchableObj = iterator.next(); //
|
Object watchableObj = iterator.next(); //
|
||||||
MetaIndex metaIndex = null;
|
MetaIndex metaIndex = null;
|
||||||
try {
|
try {
|
||||||
metaIndex = MetaIndex.getIndex(entity, (int) ReflectionUtil.invoke(watchableObj, "a"));
|
metaIndex = MetaIndex.getIndex(type, (int) ReflectionUtil.invoke(watchableObj, "a"));
|
||||||
} catch (NoSuchMethodException e) {
|
} catch (NoSuchMethodException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
} catch (InvocationTargetException e) {
|
} catch (InvocationTargetException e) {
|
||||||
@ -592,8 +622,8 @@ public class OutgoingTransformer {
|
|||||||
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
if (entity != null) {
|
if (type != null) {
|
||||||
System.out.println("An error occurred with entity meta data for " + entity.getType());
|
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 ID: " + metaIndex.getIndex() + " New ID: " + metaIndex.getNewIndex());
|
||||||
System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType());
|
System.out.println("Old Type: " + metaIndex.getOldType() + " New Type: " + metaIndex.getNewType());
|
||||||
}
|
}
|
||||||
|
@ -376,4 +376,13 @@ public class PacketUtil {
|
|||||||
public static void writeBlockPosition(ByteBuf buf, long x, long y, long z) {
|
public static void writeBlockPosition(ByteBuf buf, long x, long y, long z) {
|
||||||
buf.writeLong(((x & 0x3ffffff) << 38) | ((y & 0xfff) << 26) | (z & 0x3ffffff));
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren