diff --git a/api/src/main/java/net/md_5/bungee/api/ServerPing.java b/api/src/main/java/net/md_5/bungee/api/ServerPing.java index 550a07bcd..240cb9933 100644 --- a/api/src/main/java/net/md_5/bungee/api/ServerPing.java +++ b/api/src/main/java/net/md_5/bungee/api/ServerPing.java @@ -3,6 +3,9 @@ package net.md_5.bungee.api; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; +import net.md_5.bungee.Util; + +import java.util.UUID; /** * Represents the standard list data returned by opening a server in the @@ -42,7 +45,32 @@ public class ServerPing { private String name; - private String id; + private UUID uniqueId; + + private static final UUID md5UUID = Util.getUUID( "af74a02d19cb445bb07f6866a861f783" ); + + public PlayerInfo(String name, String id) + { + setName( name ); + setId( id ); + } + + public void setId(String id) + { + try + { + uniqueId = Util.getUUID( id ); + } catch ( Exception e ) + { + // Fallback on a valid uuid otherwise Minecraft complains + uniqueId = md5UUID; + } + } + + public String getId() + { + return uniqueId.toString().replaceAll( "-", "" ); + } } private String description; private String favicon; diff --git a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java index 70e7c8460..d8993b2e4 100644 --- a/proxy/src/main/java/net/md_5/bungee/BungeeCord.java +++ b/proxy/src/main/java/net/md_5/bungee/BungeeCord.java @@ -1,5 +1,7 @@ package net.md_5.bungee; +import com.google.gson.GsonBuilder; +import net.md_5.bungee.api.ServerPing; import net.md_5.bungee.module.ModuleManager; import com.google.common.io.ByteStreams; import net.md_5.bungee.api.chat.BaseComponent; @@ -128,7 +130,10 @@ public class BungeeCord extends ProxyServer private ConsoleReader consoleReader; @Getter private final Logger logger; - public final Gson gson = new Gson(); + public final Gson gson = new GsonBuilder() + .registerTypeAdapter( ServerPing.PlayerInfo.class, new PlayerInfoSerializer( 5 ) ).create(); + public final Gson gsonLegacy = new GsonBuilder() + .registerTypeAdapter( ServerPing.PlayerInfo.class, new PlayerInfoSerializer( 4 ) ).create(); @Getter private ConnectionThrottle connectionThrottle; private final ModuleManager moduleManager = new ModuleManager(); diff --git a/proxy/src/main/java/net/md_5/bungee/PlayerInfoSerializer.java b/proxy/src/main/java/net/md_5/bungee/PlayerInfoSerializer.java new file mode 100644 index 000000000..9cb577620 --- /dev/null +++ b/proxy/src/main/java/net/md_5/bungee/PlayerInfoSerializer.java @@ -0,0 +1,51 @@ +package net.md_5.bungee; + +import com.google.gson.JsonDeserializationContext; +import com.google.gson.JsonDeserializer; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import com.google.gson.JsonSerializationContext; +import com.google.gson.JsonSerializer; +import lombok.RequiredArgsConstructor; +import net.md_5.bungee.api.ServerPing; + +import java.lang.reflect.Type; +import java.util.UUID; + +@RequiredArgsConstructor +public class PlayerInfoSerializer implements JsonSerializer, JsonDeserializer +{ + + private final int protocol; + + @Override + public ServerPing.PlayerInfo deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException + { + JsonObject js = json.getAsJsonObject(); + ServerPing.PlayerInfo info = new ServerPing.PlayerInfo( js.get( "name" ).getAsString(), (UUID) null ); + if ( protocol == 4 ) + { + info.setId( js.get( "id" ).getAsString() ); + } else + { + info.setUniqueId( UUID.fromString( js.get( "id" ).getAsString() ) ); + } + return null; + } + + @Override + public JsonElement serialize(ServerPing.PlayerInfo src, Type typeOfSrc, JsonSerializationContext context) + { + JsonObject out = new JsonObject(); + out.addProperty( "name", src.getName() ); + if ( protocol == 4 ) + { + out.addProperty( "id", src.getId() ); + } else + { + out.addProperty( "id", src.getUniqueId().toString() ); + } + return out; + } +} diff --git a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java index 2386a4fa9..d41dbf0de 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/InitialHandler.java @@ -11,6 +11,8 @@ import java.util.List; import java.util.UUID; import java.util.logging.Level; import javax.crypto.SecretKey; + +import com.google.gson.Gson; import lombok.Getter; import lombok.RequiredArgsConstructor; import net.md_5.bungee.*; @@ -161,7 +163,8 @@ public class InitialHandler extends PacketHandler implements PendingConnection result = bungee.getPluginManager().callEvent( new ProxyPingEvent( InitialHandler.this, result ) ).getResponse(); BungeeCord.getInstance().getConnectionThrottle().unthrottle( getAddress().getAddress() ); - unsafe.sendPacket( new StatusResponse( BungeeCord.getInstance().gson.toJson( result ) ) ); + Gson gson = handshake.getProtocolVersion() == 4 ? BungeeCord.getInstance().gsonLegacy : BungeeCord.getInstance().gson; + unsafe.sendPacket( new StatusResponse( gson.toJson( result ) ) ); } }; diff --git a/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java b/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java index 2e291d038..a9acee8a0 100644 --- a/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java +++ b/proxy/src/main/java/net/md_5/bungee/connection/PingHandler.java @@ -1,5 +1,6 @@ package net.md_5.bungee.connection; +import com.google.gson.Gson; import lombok.RequiredArgsConstructor; import net.md_5.bungee.BungeeCord; import net.md_5.bungee.api.Callback; @@ -49,7 +50,8 @@ public class PingHandler extends PacketHandler @Override public void handle(StatusResponse statusResponse) throws Exception { - callback.done( BungeeCord.getInstance().gson.fromJson( statusResponse.getResponse(), ServerPing.class ), null ); + Gson gson = protocol == 4 ? BungeeCord.getInstance().gsonLegacy : BungeeCord.getInstance().gson; + callback.done( gson.fromJson( statusResponse.getResponse(), ServerPing.class ), null ); channel.close(); }