mirror of
https://github.com/PaperMC/Velocity.git
synced 2026-02-20 16:07:43 +01:00
More work on the Chat Registries
leaving some debug in as I'm still working on this, TODO: some registries are now 1:1 with what is sended, however, there is some restructing here as the code doesn't reflect some caveats of how this information is populated, i.e. fields which where said to not be nullable are actually in fact nullable, AND, this matters, at least if we wanna ensure that what we send is what we got Needs some moving stuff around to factor the above in, overlay section needs dealing with currently breaks chatting, chances are the registry repopulation is bork somewhere
This commit is contained in:
@@ -2,11 +2,11 @@ import com.github.jengelman.gradle.plugins.shadow.transformers.Log4j2PluginsCach
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id 'java'
|
id 'java'
|
||||||
id 'checkstyle'
|
//id 'checkstyle' // This is bork
|
||||||
}
|
}
|
||||||
|
|
||||||
apply plugin: 'org.cadixdev.licenser'
|
apply plugin: 'org.cadixdev.licenser'
|
||||||
apply from: '../gradle/checkstyle.gradle'
|
//apply from: '../gradle/checkstyle.gradle' // This is bork
|
||||||
apply plugin: 'com.github.johnrengelman.shadow'
|
apply plugin: 'com.github.johnrengelman.shadow'
|
||||||
|
|
||||||
license {
|
license {
|
||||||
|
|||||||
@@ -34,13 +34,17 @@ import com.google.common.base.Preconditions;
|
|||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.kyori.adventure.nbt.BinaryTag;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import net.kyori.adventure.nbt.BinaryTagTypes;
|
||||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||||
import net.kyori.adventure.nbt.ListBinaryTag;
|
import net.kyori.adventure.nbt.ListBinaryTag;
|
||||||
|
import net.kyori.adventure.nbt.StringBinaryTag;
|
||||||
import net.kyori.adventure.text.format.NamedTextColor;
|
import net.kyori.adventure.text.format.NamedTextColor;
|
||||||
|
import net.kyori.adventure.text.format.TextColor;
|
||||||
import net.kyori.adventure.text.format.TextDecoration;
|
import net.kyori.adventure.text.format.TextDecoration;
|
||||||
import net.kyori.adventure.text.format.TextFormat;
|
import net.kyori.adventure.text.format.TextFormat;
|
||||||
import net.kyori.adventure.translation.Translatable;
|
import org.checkerframework.checker.nullness.qual.Nullable;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
// TODO Implement
|
// TODO Implement
|
||||||
@@ -49,7 +53,12 @@ public class ChatData {
|
|||||||
private static final ListBinaryTag EMPTY_LIST_TAG = ListBinaryTag.empty();
|
private static final ListBinaryTag EMPTY_LIST_TAG = ListBinaryTag.empty();
|
||||||
private final String identifier;
|
private final String identifier;
|
||||||
private final int id;
|
private final int id;
|
||||||
|
@Nullable
|
||||||
private final Decoration chatDecoration;
|
private final Decoration chatDecoration;
|
||||||
|
@Nullable
|
||||||
|
private final Priority narrationPriority;
|
||||||
|
// TODO: move to own thing?
|
||||||
|
@Nullable
|
||||||
private final Decoration narrationDecoration;
|
private final Decoration narrationDecoration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -60,10 +69,11 @@ public class ChatData {
|
|||||||
* @param chatDecoration chat decoration
|
* @param chatDecoration chat decoration
|
||||||
* @param narrationDecoration narration decoration
|
* @param narrationDecoration narration decoration
|
||||||
*/
|
*/
|
||||||
public ChatData(int id, String identifier, Decoration chatDecoration, Decoration narrationDecoration) {
|
public ChatData(int id, String identifier, @Nullable Decoration chatDecoration, @Nullable Priority narrationPriority, @Nullable Decoration narrationDecoration) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.identifier = identifier;
|
this.identifier = identifier;
|
||||||
this.chatDecoration = chatDecoration;
|
this.chatDecoration = chatDecoration;
|
||||||
|
this.narrationPriority = narrationPriority;
|
||||||
this.narrationDecoration = narrationDecoration;
|
this.narrationDecoration = narrationDecoration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,31 +89,37 @@ public class ChatData {
|
|||||||
final Integer id = binaryTag.getInt("id");
|
final Integer id = binaryTag.getInt("id");
|
||||||
|
|
||||||
CompoundBinaryTag element = binaryTag.getCompound("element");
|
CompoundBinaryTag element = binaryTag.getCompound("element");
|
||||||
ChatData decodedChatData = decodeElementCompound(element);
|
ChatData decodedChatData = decodeElementCompound(element, version);
|
||||||
return decodedChatData.annotateWith(id, registryIdentifier);
|
return decodedChatData.annotateWith(id, registryIdentifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private ChatData annotateWith(Integer id, String registryIdentifier) {
|
private ChatData annotateWith(Integer id, String registryIdentifier) {
|
||||||
return new ChatData(id, registryIdentifier, this.chatDecoration, this.narrationDecoration);
|
return new ChatData(id, registryIdentifier, this.chatDecoration, this.narrationPriority, this.narrationDecoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ChatData decodeElementCompound(CompoundBinaryTag element) {
|
private static ChatData decodeElementCompound(CompoundBinaryTag element, ProtocolVersion version) {
|
||||||
Decoration chatDecoration = null;
|
Decoration chatDecoration = null;
|
||||||
Decoration narrationDecoration = null;
|
Decoration narrationDecoration = null;
|
||||||
|
Priority narrationPriority = null;
|
||||||
|
|
||||||
final CompoundBinaryTag chatCompound = element.getCompound("chat");
|
final CompoundBinaryTag chatCompound = element.getCompound("chat");
|
||||||
final CompoundBinaryTag chatDecorationCompound = chatCompound.getCompound("decoration");
|
final CompoundBinaryTag chatDecorationCompound = (CompoundBinaryTag) chatCompound.get("decoration");
|
||||||
if (chatDecorationCompound != CompoundBinaryTag.empty()) {
|
if (chatDecorationCompound != null) {
|
||||||
chatDecoration = Decoration.decodeRegistryEntry(chatDecorationCompound);
|
chatDecoration = Decoration.decodeRegistryEntry(chatDecorationCompound);
|
||||||
}
|
}
|
||||||
|
|
||||||
final CompoundBinaryTag narrationCompound = element.getCompound("narration");
|
final CompoundBinaryTag narrationCompound = element.getCompound("narration");
|
||||||
final CompoundBinaryTag narrationDecorationCompound = narrationCompound.getCompound("decoration");
|
final String priorityString = narrationCompound.getString("priority");
|
||||||
if (narrationDecorationCompound != CompoundBinaryTag.empty()) {
|
if (!priorityString.isEmpty()) {
|
||||||
narrationDecoration = Decoration.decodeRegistryEntry(narrationCompound);
|
narrationPriority = Priority.valueOf(priorityString.toUpperCase(Locale.ROOT));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ChatData(-1, "invalid", chatDecoration, narrationDecoration);
|
final CompoundBinaryTag narrationDecorationCompound = (CompoundBinaryTag) narrationCompound.get("decoration");
|
||||||
|
if (narrationDecorationCompound != null) {
|
||||||
|
narrationDecoration = Decoration.decodeRegistryEntry(narrationDecorationCompound);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ChatData(-1, "invalid", chatDecoration, narrationPriority, narrationDecoration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getIdentifier() {
|
public String getIdentifier() {
|
||||||
@@ -116,18 +132,46 @@ public class ChatData {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Encodes the chat data for the network.
|
* Encodes the chat data for the network.
|
||||||
|
*
|
||||||
* @param version The protocol version to encode this chat data for
|
* @param version The protocol version to encode this chat data for
|
||||||
* @return The encoded data structure
|
* @return The encoded data structure
|
||||||
*/
|
*/
|
||||||
public CompoundBinaryTag encodeAsCompoundTag(ProtocolVersion version) {
|
public CompoundBinaryTag encodeAsCompoundTag(ProtocolVersion version) {
|
||||||
return null;
|
final CompoundBinaryTag.Builder compound = CompoundBinaryTag.builder();
|
||||||
|
compound.putString("name", identifier);
|
||||||
|
compound.putInt("id", id);
|
||||||
|
|
||||||
|
final CompoundBinaryTag.Builder elementCompound = CompoundBinaryTag.builder();
|
||||||
|
|
||||||
|
CompoundBinaryTag.@NotNull Builder chatCompound = CompoundBinaryTag.builder();
|
||||||
|
if (chatDecoration != null) {
|
||||||
|
chatCompound.put("decoration", chatDecoration.encodeRegistryEntry(version));
|
||||||
|
elementCompound.put("chat", chatCompound.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
final CompoundBinaryTag.Builder narrationCompoundBuilder = CompoundBinaryTag.builder();
|
||||||
|
if (narrationPriority != null) {
|
||||||
|
narrationCompoundBuilder.putString("priority", narrationPriority.name().toLowerCase(Locale.ROOT));
|
||||||
|
}
|
||||||
|
if (narrationDecoration != null) {
|
||||||
|
narrationCompoundBuilder.put("decoration", narrationDecoration.encodeRegistryEntry(version));
|
||||||
|
}
|
||||||
|
final CompoundBinaryTag narrationCompound = narrationCompoundBuilder.build();
|
||||||
|
if (!narrationCompound.equals(CompoundBinaryTag.empty())) {
|
||||||
|
elementCompound.put("narration", narrationCompound);
|
||||||
|
}
|
||||||
|
|
||||||
|
compound.put("element", elementCompound.build());
|
||||||
|
|
||||||
|
return compound.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class Decoration implements Translatable {
|
public static class Decoration {
|
||||||
|
|
||||||
private final List<String> parameters;
|
private final List<String> parameters;
|
||||||
private final List<TextFormat> style;
|
private final List<TextFormat> style;
|
||||||
|
@Nullable
|
||||||
private final String translationKey;
|
private final String translationKey;
|
||||||
|
|
||||||
public List<String> getParameters() {
|
public List<String> getParameters() {
|
||||||
@@ -138,26 +182,26 @@ public class ChatData {
|
|||||||
return style;
|
return style;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public @Nullable String translationKey() {
|
||||||
public @NotNull String translationKey() {
|
|
||||||
return translationKey;
|
return translationKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Decoration with the associated data.
|
* Creates a Decoration with the associated data.
|
||||||
|
*
|
||||||
* @param parameters chat params
|
* @param parameters chat params
|
||||||
* @param style chat style
|
* @param style chat style
|
||||||
* @param translationKey translation key
|
* @param translationKey translation key
|
||||||
*/
|
*/
|
||||||
public Decoration(List<String> parameters, List<TextFormat> style, String translationKey) {
|
public Decoration(List<String> parameters, List<TextFormat> style, @Nullable String translationKey) {
|
||||||
this.parameters = Preconditions.checkNotNull(parameters);
|
this.parameters = Preconditions.checkNotNull(parameters);
|
||||||
this.style = Preconditions.checkNotNull(style);
|
this.style = Preconditions.checkNotNull(style);
|
||||||
this.translationKey = Preconditions.checkNotNull(translationKey);
|
this.translationKey = translationKey;
|
||||||
Preconditions.checkArgument(translationKey.length() > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes a decoration entry.
|
* Decodes a decoration entry.
|
||||||
|
*
|
||||||
* @param toDecode Compound Tag to decode
|
* @param toDecode Compound Tag to decode
|
||||||
* @return the parsed Decoration entry.
|
* @return the parsed Decoration entry.
|
||||||
*/
|
*/
|
||||||
@@ -165,7 +209,7 @@ public class ChatData {
|
|||||||
ImmutableList.Builder<String> parameters = ImmutableList.builder();
|
ImmutableList.Builder<String> parameters = ImmutableList.builder();
|
||||||
ListBinaryTag paramList = toDecode.getList("parameters", EMPTY_LIST_TAG);
|
ListBinaryTag paramList = toDecode.getList("parameters", EMPTY_LIST_TAG);
|
||||||
if (paramList != EMPTY_LIST_TAG) {
|
if (paramList != EMPTY_LIST_TAG) {
|
||||||
paramList.forEach(binaryTag -> parameters.add(binaryTag.toString()));
|
paramList.forEach(binaryTag -> parameters.add(((StringBinaryTag) binaryTag).value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
ImmutableList.Builder<TextFormat> style = ImmutableList.builder();
|
ImmutableList.Builder<TextFormat> style = ImmutableList.builder();
|
||||||
@@ -188,10 +232,39 @@ public class ChatData {
|
|||||||
|
|
||||||
String translationKey = toDecode.getString("translation_key");
|
String translationKey = toDecode.getString("translation_key");
|
||||||
|
|
||||||
return new Decoration(parameters.build(), style.build(), translationKey);
|
return new Decoration(parameters.build(), style.build(), translationKey.isEmpty() ? null : translationKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void encodeRegistryEntry(CompoundBinaryTag compoundBinaryTag) {}
|
public CompoundBinaryTag encodeRegistryEntry(ProtocolVersion version) {
|
||||||
|
|
||||||
|
CompoundBinaryTag.Builder compoundBinaryTag = CompoundBinaryTag.builder();
|
||||||
|
|
||||||
|
if (translationKey != null) {
|
||||||
|
compoundBinaryTag.put("translation_key", StringBinaryTag.of(translationKey));
|
||||||
|
}
|
||||||
|
|
||||||
|
final CompoundBinaryTag.Builder styleBuilder = CompoundBinaryTag.builder();
|
||||||
|
style.forEach(styleEntry -> {
|
||||||
|
if (styleEntry instanceof TextColor color) {
|
||||||
|
styleBuilder.putString("color", color.toString());
|
||||||
|
} else if (styleEntry instanceof TextDecoration decoration) {
|
||||||
|
styleBuilder.putByte(decoration.name().toLowerCase(Locale.ROOT), (byte) 1); // This won't be here if not applied
|
||||||
|
}
|
||||||
|
});
|
||||||
|
compoundBinaryTag.put("style", styleBuilder.build());
|
||||||
|
|
||||||
|
if (parameters.size() == 0) {
|
||||||
|
compoundBinaryTag.put("parameters", EMPTY_LIST_TAG);
|
||||||
|
} else {
|
||||||
|
final ListBinaryTag.Builder<StringBinaryTag> parametersBuilder = ListBinaryTag.builder(BinaryTagTypes.STRING);
|
||||||
|
parameters.forEach(param -> parametersBuilder.add(StringBinaryTag.of(param)));
|
||||||
|
compoundBinaryTag.put("parameters", parametersBuilder.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return compoundBinaryTag.build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21,10 +21,12 @@ import com.google.common.collect.ImmutableList;
|
|||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
import com.velocitypowered.api.network.ProtocolVersion;
|
import com.velocitypowered.api.network.ProtocolVersion;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import net.kyori.adventure.nbt.BinaryTag;
|
import net.kyori.adventure.nbt.BinaryTag;
|
||||||
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
import net.kyori.adventure.nbt.CompoundBinaryTag;
|
||||||
import net.kyori.adventure.nbt.ListBinaryTag;
|
import net.kyori.adventure.nbt.ListBinaryTag;
|
||||||
|
import net.kyori.adventure.nbt.TagStringIO;
|
||||||
|
|
||||||
|
|
||||||
public final class ChatRegistry {
|
public final class ChatRegistry {
|
||||||
@@ -44,9 +46,31 @@ public final class ChatRegistry {
|
|||||||
*/
|
*/
|
||||||
public static ImmutableList<ChatData> fromGameData(ListBinaryTag compound, ProtocolVersion version) {
|
public static ImmutableList<ChatData> fromGameData(ListBinaryTag compound, ProtocolVersion version) {
|
||||||
final ImmutableList.Builder<ChatData> builder = ImmutableList.builder();
|
final ImmutableList.Builder<ChatData> builder = ImmutableList.builder();
|
||||||
|
try {
|
||||||
|
System.out.println(TagStringIO.builder().indent(2).build().asString(CompoundBinaryTag.empty().put("tag", compound)));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
for (BinaryTag binaryTag : compound) {
|
for (BinaryTag binaryTag : compound) {
|
||||||
if (binaryTag instanceof CompoundBinaryTag) {
|
if (binaryTag instanceof CompoundBinaryTag) {
|
||||||
builder.add(ChatData.decodeRegistryEntry((CompoundBinaryTag) binaryTag, version));
|
final ChatData chatData = ChatData.decodeRegistryEntry((CompoundBinaryTag) binaryTag, version);
|
||||||
|
builder.add(chatData);
|
||||||
|
System.out.println(chatData.encodeAsCompoundTag(version).equals(binaryTag));
|
||||||
|
System.out.println("========");
|
||||||
|
System.out.println("========");
|
||||||
|
try {
|
||||||
|
System.out.println(TagStringIO.builder().indent(2).build().asString((CompoundBinaryTag) binaryTag));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
System.out.println("========");
|
||||||
|
try {
|
||||||
|
System.out.println(TagStringIO.builder().indent(2).build().asString(chatData.encodeAsCompoundTag(version)));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
System.out.println("========");
|
||||||
|
System.out.println("========");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder.build();
|
||||||
|
|||||||
@@ -397,7 +397,7 @@ public class JoinGame implements MinecraftPacket {
|
|||||||
CompoundBinaryTag.Builder chatRegistryEntry = CompoundBinaryTag.builder();
|
CompoundBinaryTag.Builder chatRegistryEntry = CompoundBinaryTag.builder();
|
||||||
chatRegistryEntry.putString("type", "minecraft:chat_type");
|
chatRegistryEntry.putString("type", "minecraft:chat_type");
|
||||||
chatRegistryEntry.put("value", encodedChatRegistry);
|
chatRegistryEntry.put("value", encodedChatRegistry);
|
||||||
registryContainer.put("minecraft:chat_type", encodedChatRegistry);
|
registryContainer.put("minecraft:chat_type", chatRegistryEntry.build());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
registryContainer.put("dimension", encodedDimensionRegistry);
|
registryContainer.put("dimension", encodedDimensionRegistry);
|
||||||
|
|||||||
Reference in New Issue
Block a user