13
0
geforkt von Mirrors/Velocity

Allow serializing legacy hover events

Should fix #349
Dieser Commit ist enthalten in:
Andrew Steinborn 2020-08-06 20:51:44 -04:00
Ursprung cab6919a46
Commit 46e34ddb7f
3 geänderte Dateien mit 116 neuen und 6 gelöschten Zeilen

Datei anzeigen

@ -32,6 +32,7 @@ import com.velocitypowered.proxy.console.VelocityConsole;
import com.velocitypowered.proxy.network.ConnectionManager;
import com.velocitypowered.proxy.plugin.VelocityEventManager;
import com.velocitypowered.proxy.plugin.VelocityPluginManager;
import com.velocitypowered.proxy.protocol.ProtocolUtils;
import com.velocitypowered.proxy.protocol.packet.Chat;
import com.velocitypowered.proxy.protocol.util.FaviconSerializer;
import com.velocitypowered.proxy.protocol.util.GameProfileSerializer;
@ -91,13 +92,14 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())
.registerTypeHierarchyAdapter(GameProfile.class, new GameProfileSerializer())
.create();
private static final Gson PRE_1_16_PING_SERIALIZER = GsonComponentSerializer
.colorDownsamplingGson()
private static final Gson PRE_1_16_PING_SERIALIZER = ProtocolUtils
.getJsonChatSerializer(ProtocolVersion.MINECRAFT_1_15_2)
.serializer()
.newBuilder()
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())
.create();
private static final Gson POST_1_16_PING_SERIALIZER = GsonComponentSerializer.gson()
private static final Gson POST_1_16_PING_SERIALIZER = ProtocolUtils
.getJsonChatSerializer(ProtocolVersion.MINECRAFT_1_16)
.serializer()
.newBuilder()
.registerTypeHierarchyAdapter(Favicon.class, new FaviconSerializer())

Datei anzeigen

@ -3,10 +3,10 @@ package com.velocitypowered.proxy.protocol;
import static com.google.common.base.Preconditions.checkArgument;
import static com.velocitypowered.proxy.protocol.util.NettyPreconditions.checkFrame;
import com.google.common.base.Preconditions;
import com.velocitypowered.api.network.ProtocolVersion;
import com.velocitypowered.api.util.GameProfile;
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
import com.velocitypowered.proxy.protocol.util.VelocityLegacyHoverEventSerializer;
import com.velocitypowered.proxy.util.except.QuietDecoderException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
@ -28,6 +28,18 @@ import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
public enum ProtocolUtils {
;
private static final GsonComponentSerializer PRE_1_16_SERIALIZER =
GsonComponentSerializer.builder()
.downsampleColors()
.emitLegacyHoverEvent()
.legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE)
.build();
private static final GsonComponentSerializer MODERN_SERIALIZER =
GsonComponentSerializer.builder()
.legacyHoverEventSerializer(VelocityLegacyHoverEventSerializer.INSTANCE)
.build();
private static final int DEFAULT_MAX_STRING_SIZE = 65536; // 64KiB
private static final QuietDecoderException BAD_VARINT_CACHED =
new QuietDecoderException("Bad varint decoded");
@ -468,9 +480,9 @@ public enum ProtocolUtils {
*/
public static GsonComponentSerializer getJsonChatSerializer(ProtocolVersion version) {
if (version.compareTo(ProtocolVersion.MINECRAFT_1_16) >= 0) {
return GsonComponentSerializer.gson();
return MODERN_SERIALIZER;
}
return GsonComponentSerializer.colorDownsamplingGson();
return PRE_1_16_SERIALIZER;
}
public enum Direction {

Datei anzeigen

@ -0,0 +1,96 @@
package com.velocitypowered.proxy.protocol.util;
import java.io.IOException;
import java.util.UUID;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.nbt.CompoundBinaryTag;
import net.kyori.adventure.nbt.TagStringIO;
import net.kyori.adventure.nbt.api.BinaryTagHolder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.event.HoverEvent;
import net.kyori.adventure.text.event.HoverEvent.ShowEntity;
import net.kyori.adventure.text.event.HoverEvent.ShowItem;
import net.kyori.adventure.text.serializer.gson.LegacyHoverEventSerializer;
import net.kyori.adventure.text.serializer.plain.PlainComponentSerializer;
import net.kyori.adventure.util.Codec.Decoder;
import net.kyori.adventure.util.Codec.Encoder;
import org.checkerframework.checker.nullness.qual.NonNull;
/**
* An implementation of {@link LegacyHoverEventSerializer} that implements the interface in the
* most literal, albeit "incompatible" way possible.
*/
public class VelocityLegacyHoverEventSerializer implements LegacyHoverEventSerializer {
public static final LegacyHoverEventSerializer INSTANCE =
new VelocityLegacyHoverEventSerializer();
private VelocityLegacyHoverEventSerializer() {
}
private static Key legacyIdToFakeKey(byte id) {
return Key.of("velocity", "legacy_hover/id_" + id);
}
@Override
public HoverEvent.@NonNull ShowItem deserializeShowItem(@NonNull Component input)
throws IOException {
String snbt = PlainComponentSerializer.plain().serialize(input);
CompoundBinaryTag item = TagStringIO.get().asCompound(snbt);
Key key;
String idIfString = item.getString("id", "");
if (idIfString.isEmpty()) {
key = legacyIdToFakeKey(item.getByte("id"));
} else {
key = Key.of(idIfString);
}
byte count = item.getByte("Count", (byte) 1);
return new ShowItem(key, count, BinaryTagHolder.of(snbt));
}
@Override
public HoverEvent.@NonNull ShowEntity deserializeShowEntity(@NonNull Component input,
Decoder<Component, String, ? extends RuntimeException> componentDecoder) throws IOException {
String snbt = PlainComponentSerializer.plain().serialize(input);
CompoundBinaryTag item = TagStringIO.get().asCompound(snbt);
return new ShowEntity(Key.of(item.getString("type")),
UUID.fromString(item.getString("id")),
componentDecoder.decode(item.getString("name")));
}
@Override
public @NonNull Component serializeShowItem(HoverEvent.@NonNull ShowItem input)
throws IOException {
final CompoundBinaryTag.Builder builder = CompoundBinaryTag.builder()
.putByte("Count", (byte) input.count());
String keyAsString = input.item().asString();
if (keyAsString.startsWith("velocity:legacy_hover/id_")) {
builder.putByte("id", Byte.parseByte(keyAsString
.substring("velocity:legacy_hover/id_".length())));
} else {
builder.putString("id", keyAsString);
}
if (input.nbt() != null) {
builder.put("tag", TagStringIO.get().asCompound(input.nbt().string()));
}
return TextComponent.of(TagStringIO.get().asString(builder.build()));
}
@Override
public @NonNull Component serializeShowEntity(HoverEvent.@NonNull ShowEntity input,
Encoder<Component, String, ? extends RuntimeException> componentEncoder) throws IOException {
CompoundBinaryTag.Builder tag = CompoundBinaryTag.builder()
.putString("id", input.id().toString())
.putString("type", input.type().asString());
if (input.name() != null) {
tag.putString("name", componentEncoder.encode(input.name()));
}
return TextComponent.of(TagStringIO.get().asString(tag.build()));
}
}