From 56d5f8eec635aafaeaba626d24c3a057efe59413 Mon Sep 17 00:00:00 2001 From: Myles Date: Thu, 17 Mar 2016 21:24:25 +0000 Subject: [PATCH] Add protocol registry. Fix some issues with PacketWrapper Add 1.9.1 port Add ProtocolVersion detection on boot Add more type converters Implement Pipeline properly --- .../us/myles/ViaVersion/ViaVersionPlugin.java | 65 +++++++++++++++- .../myles/ViaVersion2/api/PacketWrapper.java | 15 +++- .../ViaVersion2/api/protocol/Protocol.java | 8 +- .../api/protocol/ProtocolPipeline.java | 10 ++- .../api/protocol/ProtocolRegistry.java | 76 +++++++++++++++++++ .../api/protocol/ProtocolVersion.java | 12 +++ .../api/protocol/base/BaseProtocol.java | 45 ++++++++--- .../Protocol1_9_1TO1_9.java | 33 ++++++++ .../protocol1_9to1_8/Protocol1_9TO1_8.java | 1 - .../api/type/types/BooleanType.java | 12 ++- .../ViaVersion2/api/type/types/ByteType.java | 4 +- .../api/type/types/DoubleType.java | 14 +++- .../ViaVersion2/api/type/types/FloatType.java | 15 +++- .../ViaVersion2/api/type/types/IntType.java | 14 +++- .../ViaVersion2/api/type/types/LongType.java | 15 +++- .../ViaVersion2/api/type/types/ShortType.java | 14 +++- .../api/type/types/UnsignedByteType.java | 14 +++- .../api/type/types/UnsignedShortType.java | 14 +++- .../api/type/types/VarIntType.java | 15 +++- .../us/myles/ViaVersion2/api/util/Pair.java | 2 + 20 files changed, 370 insertions(+), 28 deletions(-) create mode 100644 src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolRegistry.java create mode 100644 src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolVersion.java create mode 100644 src/main/java/us/myles/ViaVersion2/api/protocol1_9_1to1_9/Protocol1_9_1TO1_9.java diff --git a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index 3dbe21463..09c51cd6d 100644 --- a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -28,6 +28,7 @@ import us.myles.ViaVersion.util.Configuration; import us.myles.ViaVersion.util.ListWrapper; import us.myles.ViaVersion.util.ReflectionUtil; import us.myles.ViaVersion2.api.data.UserConnection; +import us.myles.ViaVersion2.api.protocol.ProtocolRegistry; import us.myles.ViaVersion2.api.protocol.base.ProtocolInfo; import java.io.File; @@ -75,7 +76,22 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { return; } - getLogger().info("ViaVersion " + getDescription().getVersion() + " is now enabled, injecting. (Allows 1.8 to be accessed via 1.9)"); + // Gather version :) + Bukkit.getScheduler().scheduleSyncDelayedTask(this, new Runnable() { + @Override + public void run() { + gatherProtocolVersion(); + // Check if there are any pipes to this version + if (ProtocolRegistry.SERVER_PROTOCOL != -1) { + getLogger().info("ViaVersion detected protocol version: " + ProtocolRegistry.SERVER_PROTOCOL); + if (!ProtocolRegistry.isWorkingPipe()) { + getLogger().warning("ViaVersion will not function on the current protocol."); + } + } + } + }); + + getLogger().info("ViaVersion " + getDescription().getVersion() + " is now enabled, injecting."); injectPacketHandler(); if (getConfig().getBoolean("simulate-pt", true)) new ViaIdleThread(portedPlayers).runTaskTimerAsynchronously(this, 1L, 1L); // Updates player's idle status @@ -97,6 +113,53 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { getCommand("viaversion").setExecutor(new ViaVersionCommand(this)); } + public void gatherProtocolVersion() { + try { + Class serverClazz = ReflectionUtil.nms("MinecraftServer"); + Object server = ReflectionUtil.invokeStatic(serverClazz, "getServer"); + Class pingClazz = ReflectionUtil.nms("ServerPing"); + Object ping = null; + // Search for ping method + for (Field f : serverClazz.getDeclaredFields()) { + if (f.getType() != null) { + if (f.getType().getSimpleName().equals("ServerPing")) { + f.setAccessible(true); + ping = f.get(server); + } + } + } + if (ping != null) { + Object serverData = null; + for (Field f : pingClazz.getDeclaredFields()) { + if (f.getType() != null) { + if (f.getType().getSimpleName().endsWith("ServerData")) { + f.setAccessible(true); + serverData = f.get(ping); + } + } + } + if (serverData != null) { + int protocolVersion = -1; + for (Field f : serverData.getClass().getDeclaredFields()) { + if (f.getType() != null) { + if (f.getType() == int.class) { + f.setAccessible(true); + protocolVersion = (int) f.get(serverData); + } + } + } + if (protocolVersion != -1) { + ProtocolRegistry.SERVER_PROTOCOL = protocolVersion; + return; + } + } + } + } catch (Exception e) { + e.printStackTrace(); + // We couldn't work it out... We'll just use ping and hope for the best... + } + } + public void generateConfig() { File file = new File(getDataFolder(), "config.yml"); if (file.exists()) { diff --git a/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java b/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java index eaf7fce8f..8573dd5d9 100644 --- a/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java +++ b/src/main/java/us/myles/ViaVersion2/api/PacketWrapper.java @@ -60,6 +60,7 @@ public class PacketWrapper { } public T read(Type type) throws Exception { + if(type == Type.NOTHING) return null; if (readableObjects.isEmpty()) { Preconditions.checkNotNull(inputBuffer, "This packet does not have an input buffer."); // We could in the future log input read values, but honestly for things like bulk maps, mem waste D: @@ -69,7 +70,11 @@ public class PacketWrapper { if (read.getKey().equals(type)) { return (T) read.getValue(); } else { - throw new IOException("Unable to read type " + type.getTypeName() + ", found " + type.getTypeName()); + if (type == Type.NOTHING) { + return read(type); // retry + } else { + throw new IOException("Unable to read type " + type.getTypeName() + ", found " + read.getKey().getTypeName()); + } } } } @@ -89,9 +94,13 @@ public class PacketWrapper { if (id != -1) { Type.VAR_INT.write(buffer, id); } + if (readableObjects.size() > 0) { + packetValues.addAll(readableObjects); + } + int index = 0; for (Pair packetValue : packetValues) { - try { + try { Object value = packetValue.getValue(); if (value != null) { if (!packetValue.getKey().getOutputClass().isAssignableFrom(value.getClass())) { @@ -116,6 +125,7 @@ public class PacketWrapper { public void clearInputBuffer() { if (inputBuffer != null) inputBuffer.clear(); + readableObjects.clear(); // :( } private void writeRemaining(ByteBuf output) { @@ -154,5 +164,6 @@ public class PacketWrapper { public void resetReader() { this.readableObjects.addAll(packetValues); + this.packetValues.clear(); } } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java b/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java index b05f2b805..dd0b5cd68 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/Protocol.java @@ -7,7 +7,6 @@ import us.myles.ViaVersion.packets.Direction; import us.myles.ViaVersion.packets.State; import us.myles.ViaVersion2.api.PacketWrapper; import us.myles.ViaVersion2.api.data.UserConnection; -import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; import us.myles.ViaVersion2.api.remapper.PacketRemapper; import us.myles.ViaVersion2.api.util.Pair; @@ -59,11 +58,16 @@ public abstract class Protocol { // remap if (protocolPacket.getRemapper() != null) { protocolPacket.getRemapper().remap(packetWrapper); - if(packetWrapper.isCancelled()) + if (packetWrapper.isCancelled()) throw new CancelException(); } } + @Override + public String toString() { + return "Protocol:" + getClass().getSimpleName(); + } + @AllArgsConstructor @Getter class ProtocolPacket { diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java index d6c6d24a9..80af7de4f 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolPipeline.java @@ -8,7 +8,9 @@ import us.myles.ViaVersion2.api.protocol.base.BaseProtocol; import us.myles.ViaVersion2.api.protocol.base.ProtocolInfo; import java.util.ArrayList; +import java.util.Collections; import java.util.LinkedList; +import java.util.List; public class ProtocolPipeline extends Protocol { LinkedList protocolList; @@ -54,7 +56,13 @@ public class ProtocolPipeline extends Protocol { @Override public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception { // System.out.println("--> Packet ID incoming: " + packetWrapper.getId() + " - " + state); - for (Protocol protocol : new ArrayList<>(protocolList)) { // Copy to prevent from removal. + List protocols = new ArrayList<>(protocolList); + // Other way if outgoing + if (direction == Direction.OUTGOING) + Collections.reverse(protocols); + + for (Protocol protocol : protocols) { // Copy to prevent from removal. + System.out.println("Calling " + protocol.getClass().getSimpleName() + " " + direction); protocol.transform(direction, state, packetWrapper); // Reset the reader for the packetWrapper (So it can be recycled across packets) packetWrapper.resetReader(); diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolRegistry.java b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolRegistry.java new file mode 100644 index 000000000..4af67c409 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolRegistry.java @@ -0,0 +1,76 @@ +package us.myles.ViaVersion2.api.protocol; + +import us.myles.ViaVersion2.api.protocol1_9_1to1_9.Protocol1_9_1TO1_9; +import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion2.api.util.Pair; + +import java.util.*; + +public class ProtocolRegistry { + // Input Version -> Output Version & Protocol (Allows fast lookup) + private static Map> registryMap = new HashMap<>(); + + public static int SERVER_PROTOCOL = -1; + + static { + // Register built in protocols + registerProtocol(new Protocol1_9TO1_8(), Arrays.asList(ProtocolVersion.V1_9), ProtocolVersion.V1_8); + registerProtocol(new Protocol1_9_1TO1_9(), Arrays.asList(ProtocolVersion.V1_9_1_PRE2), ProtocolVersion.V1_9); + } + + public static void registerProtocol(Protocol protocol, List supported, Integer output) { + for (Integer version : supported) { + if (!registryMap.containsKey(version)) { + registryMap.put(version, new HashMap()); + } + + registryMap.get(version).put(output, protocol); + } + } + + public static boolean isWorkingPipe() { + for (Map maps : registryMap.values()) { + if (maps.containsKey(SERVER_PROTOCOL)) return true; + } + return false; // No destination for protocol + } + + private static List> getProtocolPath(List> current, int clientVersion, int serverVersion) { + if (current.size() > 50) return null; // Fail safe, protocol too complicated. + + // First check if there is any protocols for this + if (!registryMap.containsKey(clientVersion)) { + return null; // Not supported + } + // Next check there isn't an obvious path + Map inputMap = registryMap.get(clientVersion); + if (inputMap.containsKey(serverVersion)) { + current.add(new Pair<>(serverVersion, inputMap.get(serverVersion))); + return current; // Easy solution + } + // There might be a more advanced solution... So we'll see if any of the others can get us there + for (Map.Entry entry : inputMap.entrySet()) { + // Ensure it wasn't caught by the other loop + if (!entry.getKey().equals(serverVersion)) { + Pair pair = new Pair<>(entry.getKey(), entry.getValue()); + // Ensure no recursion + if (!current.contains(pair)) { + // Create a copy + List> newCurrent = new ArrayList<>(current); + newCurrent.add(pair); + // Calculate the rest of the protocol using the current + newCurrent = getProtocolPath(newCurrent, entry.getKey(), serverVersion); + if (newCurrent != null) { + return newCurrent; + } + } + } + } + + return null; + } + + public static List> getProtocolPath(int clientVersion, int serverVersion) { + return getProtocolPath(new ArrayList>(), clientVersion, serverVersion); + } +} diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolVersion.java b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolVersion.java new file mode 100644 index 000000000..c800db6c1 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/ProtocolVersion.java @@ -0,0 +1,12 @@ +package us.myles.ViaVersion2.api.protocol; + +public class ProtocolVersion { + /* Defined protocol constants */ + public static int V1_7_1 = 4; + public static int V1_7_6 = 5; + + public static int V1_8 = 47; + + public static int V1_9 = 107; + public static int V1_9_1_PRE2 = 108; +} diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol/base/BaseProtocol.java b/src/main/java/us/myles/ViaVersion2/api/protocol/base/BaseProtocol.java index ae1b50e9a..e43e9b2cf 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol/base/BaseProtocol.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol/base/BaseProtocol.java @@ -6,15 +6,17 @@ import org.json.simple.parser.ParseException; import us.myles.ViaVersion.ViaVersionPlugin; import us.myles.ViaVersion.api.ViaVersion; import us.myles.ViaVersion.packets.State; -import us.myles.ViaVersion.util.PacketUtil; import us.myles.ViaVersion2.api.PacketWrapper; import us.myles.ViaVersion2.api.data.UserConnection; import us.myles.ViaVersion2.api.protocol.Protocol; -import us.myles.ViaVersion2.api.protocol1_9to1_8.Protocol1_9TO1_8; +import us.myles.ViaVersion2.api.protocol.ProtocolPipeline; +import us.myles.ViaVersion2.api.protocol.ProtocolRegistry; import us.myles.ViaVersion2.api.remapper.PacketHandler; import us.myles.ViaVersion2.api.remapper.PacketRemapper; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.util.Pair; +import java.util.List; import java.util.UUID; public class BaseProtocol extends Protocol { @@ -29,14 +31,25 @@ public class BaseProtocol extends Protocol { handler(new PacketHandler() { @Override public void handle(PacketWrapper wrapper) { - // TODO: Actually make this show compatible versions ProtocolInfo info = wrapper.user().get(ProtocolInfo.class); String originalStatus = wrapper.get(Type.STRING, 0); try { JSONObject json = (JSONObject) new JSONParser().parse(originalStatus); JSONObject version = (JSONObject) json.get("version"); - version.put("protocol", info.getProtocolVersion()); + System.out.println("Calculating " + info.getProtocolVersion()); + // TODO: Make it so the detection doesn't base off just ping :) + if (ProtocolRegistry.SERVER_PROTOCOL == -1) { + Long original = (Long) version.get("protocol"); + ProtocolRegistry.SERVER_PROTOCOL = original.intValue(); + } + List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), ProtocolRegistry.SERVER_PROTOCOL); + if (protocols != null) { + version.put("protocol", info.getProtocolVersion()); + } else { + // not compatible :(, *plays very sad violin* + wrapper.user().setActive(false); + } wrapper.set(Type.STRING, 0, json.toJSONString()); // Update value } catch (ParseException e) { e.printStackTrace(); @@ -88,15 +101,27 @@ public class BaseProtocol extends Protocol { @Override public void handle(PacketWrapper wrapper) { int protVer = wrapper.get(Type.VAR_INT, 0); + int state = wrapper.get(Type.VAR_INT, 1); + ProtocolInfo info = wrapper.user().get(ProtocolInfo.class); info.setProtocolVersion(protVer); - // TODO: Choose the right pipe - // We'll just cheat lol - wrapper.user().get(ProtocolInfo.class).getPipeline().add(new Protocol1_9TO1_8()); - System.out.println("I should decide on a protocol for " + protVer); - wrapper.set(Type.VAR_INT, 0, 47); // TODO remove hard code + // Choose the pipe + List> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), ProtocolRegistry.SERVER_PROTOCOL); + ProtocolPipeline pipeline = wrapper.user().get(ProtocolInfo.class).getPipeline(); + if (protocols != null) { + for (Pair prot : protocols) { + pipeline.add(prot.getValue()); + System.out.println("adding pipe"); + } + wrapper.set(Type.VAR_INT, 0, ProtocolRegistry.SERVER_PROTOCOL); + } else { + if (state == 2) { + // not compatible :(, *plays very sad violin* + wrapper.user().setActive(false); + } + } + // Change state - int state = wrapper.get(Type.VAR_INT, 1); if (state == 1) { info.setState(State.STATUS); } diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9_1to1_9/Protocol1_9_1TO1_9.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9_1to1_9/Protocol1_9_1TO1_9.java new file mode 100644 index 000000000..7452435f4 --- /dev/null +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9_1to1_9/Protocol1_9_1TO1_9.java @@ -0,0 +1,33 @@ +package us.myles.ViaVersion2.api.protocol1_9_1to1_9; + +import us.myles.ViaVersion.packets.State; +import us.myles.ViaVersion2.api.data.UserConnection; +import us.myles.ViaVersion2.api.protocol.Protocol; +import us.myles.ViaVersion2.api.remapper.PacketRemapper; +import us.myles.ViaVersion2.api.type.Type; + +public class Protocol1_9_1TO1_9 extends Protocol{ + @Override + protected void registerPackets() { + // Currently supports 1.9.1 PRE 2 + // Join Game Packet + registerOutgoing(State.PLAY, 0x23, 0x23, new PacketRemapper() { + @Override + public void registerMap() { + map(Type.INT); // 0 - Player ID + map(Type.UNSIGNED_BYTE); // 1 - Player Gamemode + // 1.9.1 PRE 2 Changed this + map(Type.BYTE, Type.INT); // 2 - Player Dimension + map(Type.UNSIGNED_BYTE); // 3 - World Difficulty + map(Type.UNSIGNED_BYTE); // 4 - Max Players (Tab) + map(Type.STRING); // 5 - Level Type + map(Type.BOOLEAN); // 6 - Reduced Debug info + } + }); + } + + @Override + public void init(UserConnection userConnection) { + + } +} diff --git a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java index 4e536918c..f67de10fb 100644 --- a/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java +++ b/src/main/java/us/myles/ViaVersion2/api/protocol1_9to1_8/Protocol1_9TO1_8.java @@ -56,7 +56,6 @@ public class Protocol1_9TO1_8 extends Protocol { @Override protected void registerPackets() { - System.out.println("Registering packets for 1.9 to 1.8"); SpawnPackets.register(this); InventoryPackets.register(this); EntityPackets.register(this); diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/BooleanType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/BooleanType.java index db5d98071..17723fb01 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/BooleanType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/BooleanType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class BooleanType extends Type { +public class BooleanType extends Type implements TypeConverter{ public BooleanType() { super(Boolean.class); } @@ -17,4 +18,13 @@ public class BooleanType extends Type { public void write(ByteBuf buffer, Boolean object) { buffer.writeBoolean(object); } + + + @Override + public Boolean from(Object o) { + if (o instanceof Number) { + return ((Number) o).intValue() == 1; + } + return (Boolean) o; + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java index 29670a0d3..1d6971e9e 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/ByteType.java @@ -19,14 +19,14 @@ public class ByteType extends Type implements TypeConverter { buffer.writeByte(object); } + @Override public Byte from(Object o) { if (o instanceof Number) { return ((Number) o).byteValue(); } if(o instanceof Boolean){ - if(o == true) return 1; - if(o == false) return 0; + return ((Boolean)o) == true ? (byte) 1 : 0; } return (Byte) o; } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/DoubleType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/DoubleType.java index 688099d5a..e1f05baff 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/DoubleType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/DoubleType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class DoubleType extends Type { +public class DoubleType extends Type implements TypeConverter{ public DoubleType() { super(Double.class); } @@ -17,4 +18,15 @@ public class DoubleType extends Type { public void write(ByteBuf buffer, Double object) { buffer.writeDouble(object); } + + @Override + public Double from(Object o) { + if (o instanceof Number) { + return ((Number) o).doubleValue(); + } + if(o instanceof Boolean){ + return ((Boolean)o) == true ? 1D : 0D; + } + return (Double) o; + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/FloatType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/FloatType.java index 90051445d..b1319ab96 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/FloatType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/FloatType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class FloatType extends Type { +public class FloatType extends Type implements TypeConverter{ public FloatType() { super(Float.class); } @@ -17,4 +18,16 @@ public class FloatType extends Type { public void write(ByteBuf buffer, Float object) { buffer.writeFloat(object); } + + + @Override + public Float from(Object o) { + if (o instanceof Number) { + return ((Number) o).floatValue(); + } + if(o instanceof Boolean){ + return ((Boolean)o) == true ? 1F : 0; + } + return (Float) o; + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/IntType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/IntType.java index 4ff966c4e..73a91326c 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/IntType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/IntType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class IntType extends Type { +public class IntType extends Type implements TypeConverter{ public IntType() { super(Integer.class); } @@ -17,4 +18,15 @@ public class IntType extends Type { public void write(ByteBuf buffer, Integer object) { buffer.writeInt(object); } + + @Override + public Integer from(Object o) { + if (o instanceof Number) { + return ((Number) o).intValue(); + } + if(o instanceof Boolean){ + return ((Boolean)o) == true ? 1 : 0; + } + return (Integer) o; + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/LongType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/LongType.java index 5475dcb16..f0129a140 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/LongType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/LongType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class LongType extends Type { +public class LongType extends Type implements TypeConverter { public LongType() { super(Long.class); } @@ -17,4 +18,16 @@ public class LongType extends Type { public void write(ByteBuf buffer, Long object) { buffer.writeLong(object); } + + + @Override + public Long from(Object o) { + if (o instanceof Number) { + return ((Number) o).longValue(); + } + if(o instanceof Boolean){ + return ((Boolean)o) == true ? 1L : 0; + } + return (Long) o; + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/ShortType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/ShortType.java index d48f19994..e50704c4c 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/ShortType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/ShortType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class ShortType extends Type { +public class ShortType extends Type implements TypeConverter { public ShortType() { super(Short.class); } @@ -17,4 +18,15 @@ public class ShortType extends Type { public void write(ByteBuf buffer, Short object) { buffer.writeShort(object); } + + @Override + public Short from(Object o) { + if (o instanceof Number) { + return ((Number) o).shortValue(); + } + if(o instanceof Boolean){ + return ((Boolean)o) == true ? (short) 1 : 0; + } + return (short) o; + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/UnsignedByteType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/UnsignedByteType.java index 4217536be..a5e8ff02b 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/UnsignedByteType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/UnsignedByteType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class UnsignedByteType extends Type { +public class UnsignedByteType extends Type implements TypeConverter { public UnsignedByteType() { super(Short.class); } @@ -17,4 +18,15 @@ public class UnsignedByteType extends Type { public void write(ByteBuf buffer, Short object) { buffer.writeByte(object); } + + @Override + public Short from(Object o) { + if (o instanceof Number) { + return ((Number) o).shortValue(); + } + if(o instanceof Boolean){ + return ((Boolean)o) == true ? (short) 1 : 0; + } + return (short) o; + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/UnsignedShortType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/UnsignedShortType.java index 9fcbfe2cb..659e28ef2 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/UnsignedShortType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/UnsignedShortType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class UnsignedShortType extends Type { +public class UnsignedShortType extends Type implements TypeConverter { public UnsignedShortType() { super(Integer.class); } @@ -17,4 +18,15 @@ public class UnsignedShortType extends Type { public void write(ByteBuf buffer, Integer object) { buffer.writeShort(object); } + + @Override + public Integer from(Object o) { + if (o instanceof Number) { + return ((Number) o).intValue(); + } + if(o instanceof Boolean){ + return ((Boolean)o) == true ? 1 : 0; + } + return (Integer) o; + } } diff --git a/src/main/java/us/myles/ViaVersion2/api/type/types/VarIntType.java b/src/main/java/us/myles/ViaVersion2/api/type/types/VarIntType.java index 8aa2b3609..cc05e1f78 100644 --- a/src/main/java/us/myles/ViaVersion2/api/type/types/VarIntType.java +++ b/src/main/java/us/myles/ViaVersion2/api/type/types/VarIntType.java @@ -2,8 +2,9 @@ package us.myles.ViaVersion2.api.type.types; import io.netty.buffer.ByteBuf; import us.myles.ViaVersion2.api.type.Type; +import us.myles.ViaVersion2.api.type.TypeConverter; -public class VarIntType extends Type{ +public class VarIntType extends Type implements TypeConverter { public VarIntType() { super("VarInt", Integer.class); @@ -49,4 +50,16 @@ public class VarIntType extends Type{ return out; } + + + @Override + public Integer from(Object o) { + if (o instanceof Number) { + return ((Number) o).intValue(); + } + if (o instanceof Boolean) { + return ((Boolean) o) == true ? 1 : 0; + } + return (Integer) o; + } } \ No newline at end of file diff --git a/src/main/java/us/myles/ViaVersion2/api/util/Pair.java b/src/main/java/us/myles/ViaVersion2/api/util/Pair.java index 163ff4f5f..c57280547 100644 --- a/src/main/java/us/myles/ViaVersion2/api/util/Pair.java +++ b/src/main/java/us/myles/ViaVersion2/api/util/Pair.java @@ -3,10 +3,12 @@ package us.myles.ViaVersion2.api.util; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; +import lombok.ToString; @Getter @Setter @EqualsAndHashCode +@ToString public class Pair { private X key; private Y value;