improve packet config serializer (#7920)

This commit is contained in:
Jake Potrebic 2022-06-10 01:45:41 -07:00 committed by GitHub
parent dd6a8e9394
commit 8141349df1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 70 additions and 55 deletions

View File

@ -2191,36 +2191,49 @@ index 0000000000000000000000000000000000000000..f2f362883d1825084c277608c791f821
+} +}
diff --git a/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java diff --git a/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..a13691523554a85c3ea3efb70d847904a9d91f0c index 0000000000000000000000000000000000000000..bc065d5cc8975dd189954272116a6bc5bc7f4e28
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java +++ b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java
@@ -0,0 +1,61 @@ @@ -0,0 +1,86 @@
+package io.papermc.paper.configuration.serializer; +package io.papermc.paper.configuration.serializer;
+ +
+import com.google.common.collect.BiMap;
+import com.google.common.collect.ImmutableBiMap;
+import com.mojang.logging.LogUtils;
+import io.leangen.geantyref.TypeToken; +import io.leangen.geantyref.TypeToken;
+import io.papermc.paper.configuration.serializer.collections.MapSerializer;
+import io.papermc.paper.util.ObfHelper; +import io.papermc.paper.util.ObfHelper;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Collectors;
+import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.Packet;
+import org.checkerframework.checker.nullness.qual.Nullable; +import org.checkerframework.checker.nullness.qual.Nullable;
+import org.slf4j.Logger;
+import org.spongepowered.configurate.serialize.ScalarSerializer; +import org.spongepowered.configurate.serialize.ScalarSerializer;
+import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.serialize.SerializationException;
+ +
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+import java.util.function.Predicate;
+
+@SuppressWarnings("Convert2Diamond") +@SuppressWarnings("Convert2Diamond")
+public final class PacketClassSerializer extends ScalarSerializer<Class<? extends Packet<?>>> { +public final class PacketClassSerializer extends ScalarSerializer<Class<? extends Packet<?>>> implements MapSerializer.WriteBack {
+
+ private static final Logger LOGGER = LogUtils.getLogger();
+ private static final TypeToken<Class<? extends Packet<?>>> TYPE = new TypeToken<Class<? extends Packet<?>>>() {}; + private static final TypeToken<Class<? extends Packet<?>>> TYPE = new TypeToken<Class<? extends Packet<?>>>() {};
+ private static final List<String> SUBPACKAGES = List.of("game", "handshake", "login", "status"); + private static final List<String> SUBPACKAGES = List.of("game", "handshake", "login", "status");
+ private static final Map<String, String> MOJANG_TO_OBF = Optional.ofNullable(ObfHelper.INSTANCE.mappingsByMojangName()) + private static final BiMap<String, String> MOJANG_TO_OBF;
+ .map(Map::entrySet) +
+ .map(Collection::stream) + static {
+ .map(stream -> stream.collect(Collectors.toMap(entry -> entry.getValue().mojangName(), entry -> entry.getValue().obfName()))) + final ImmutableBiMap.Builder<String, String> builder = ImmutableBiMap.builder();
+ .orElseGet(Collections::emptyMap); + final @Nullable Map<String, ObfHelper.ClassMapping> classMappingMap = ObfHelper.INSTANCE.mappingsByMojangName();
+ if (classMappingMap != null) {
+ classMappingMap.forEach((mojMap, classMapping) -> {
+ if (mojMap.startsWith("net.minecraft.network.protocol.")) {
+ builder.put(classMapping.mojangName(), classMapping.obfName());
+ }
+ });
+ }
+ MOJANG_TO_OBF = builder.build();
+ }
+ +
+ public PacketClassSerializer() { + public PacketClassSerializer() {
+ super(TYPE); + super(TYPE);
@ -2251,9 +2264,21 @@ index 0000000000000000000000000000000000000000..a13691523554a85c3ea3efb70d847904
+ } + }
+ +
+ @Override + @Override
+ protected Object serialize(final Class<? extends Packet<?>> item, final Predicate<Class<?>> typeSupported) { + protected @Nullable Object serialize(final Class<? extends Packet<?>> packetClass, final Predicate<Class<?>> typeSupported) {
+ //TODO always serialize the mapped class name to not break on switching between mapped/unmapped servers + final String name = packetClass.getName();
+ return item.getSimpleName(); + @Nullable String mojName = ObfHelper.INSTANCE.mappingsByMojangName() == null ? name : MOJANG_TO_OBF.inverse().get(name); // if the mappings are null, running on moj-mapped server
+ if (mojName == null && MOJANG_TO_OBF.containsKey(name)) {
+ mojName = name;
+ }
+ if (mojName != null) {
+ int pos = mojName.lastIndexOf('.');
+ if (pos != -1 && pos != mojName.length() - 1) {
+ return mojName.substring(pos + 1);
+ }
+ }
+
+ LOGGER.error("Could not serialize {} into a mojang-mapped packet class name", packetClass);
+ return null;
+ } + }
+} +}
diff --git a/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java diff --git a/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java
@ -2402,10 +2427,10 @@ index 0000000000000000000000000000000000000000..0b235ebe6e79d7aa420d6b8a52aedb3a
+} +}
diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..f5c0fb018b7f8eff1d6ca1f0425409adac242180 index 0000000000000000000000000000000000000000..f44d4cb05eab25d79a8ac09b9da981633380c4fc
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java +++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java
@@ -0,0 +1,148 @@ @@ -0,0 +1,162 @@
+package io.papermc.paper.configuration.serializer.collections; +package io.papermc.paper.configuration.serializer.collections;
+ +
+import com.mojang.logging.LogUtils; +import com.mojang.logging.LogUtils;
@ -2466,13 +2491,24 @@ index 0000000000000000000000000000000000000000..f5c0fb018b7f8eff1d6ca1f0425409ad
+ } + }
+ +
+ final BasicConfigurationNode keyNode = BasicConfigurationNode.root(node.options()); + final BasicConfigurationNode keyNode = BasicConfigurationNode.root(node.options());
+ final Set<Object> keysToClear = new HashSet<>();
+ for (Map.Entry<Object, ? extends ConfigurationNode> ent : node.childrenMap().entrySet()) { + for (Map.Entry<Object, ? extends ConfigurationNode> ent : node.childrenMap().entrySet()) {
+ final @Nullable Object keyValue = deserialize(key, keySerializer, "key", keyNode.set(ent.getKey()), node.path()); + final @Nullable Object deserializedKey = deserialize(key, keySerializer, "key", keyNode.set(ent.getKey()), node.path());
+ final @Nullable Object valueValue = deserialize(value, valueSerializer, "value", ent.getValue(), ent.getValue().path()); + final @Nullable Object deserializedValue = deserialize(value, valueSerializer, "value", ent.getValue(), ent.getValue().path());
+ if (keyValue == null || valueValue == null) { + if (deserializedKey == null || deserializedValue == null) {
+ continue; + continue;
+ } + }
+ map.put(keyValue, valueValue); + if (keySerializer instanceof WriteBack) {
+ if (serialize(key, keySerializer, deserializedKey, "key", keyNode, node.path()) && !ent.getKey().equals(requireNonNull(keyNode.raw(), "Key must not be null!"))) {
+ keysToClear.add(ent.getKey());
+ }
+ }
+ map.put(deserializedKey, deserializedValue);
+ }
+ if (keySerializer instanceof WriteBack) { // supports cleaning keys which deserialize to the same value
+ for (Object keyToClear : keysToClear) {
+ node.node(keyToClear).raw(null);
+ }
+ } + }
+ } + }
+ return map; + return map;
@ -2553,6 +2589,9 @@ index 0000000000000000000000000000000000000000..f5c0fb018b7f8eff1d6ca1f0425409ad
+ public @Nullable Map<?, ?> emptyValue(Type specificType, ConfigurationOptions options) { + public @Nullable Map<?, ?> emptyValue(Type specificType, ConfigurationOptions options) {
+ return new LinkedHashMap<>(); + return new LinkedHashMap<>();
+ } + }
+
+ public interface WriteBack { // marker interface
+ }
+} +}
diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java
new file mode 100644 new file mode 100644
@ -2745,16 +2784,14 @@ index 0000000000000000000000000000000000000000..0300fb1e09d41465e4a50bfdc987b957
+} +}
diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java b/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java b/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java
new file mode 100644 new file mode 100644
index 0000000000000000000000000000000000000000..3be5cb126e41a533e9453bbd6326cd1c10dd879d index 0000000000000000000000000000000000000000..62e41812b0df4fc548f97273215a92b993ebf1d7
--- /dev/null --- /dev/null
+++ b/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java +++ b/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java
@@ -0,0 +1,248 @@ @@ -0,0 +1,224 @@
+package io.papermc.paper.configuration.transformation.global; +package io.papermc.paper.configuration.transformation.global;
+ +
+import com.mojang.logging.LogUtils; +import com.mojang.logging.LogUtils;
+import io.papermc.paper.configuration.Configuration; +import io.papermc.paper.configuration.Configuration;
+import io.papermc.paper.configuration.serializer.PacketClassSerializer;
+import io.papermc.paper.util.ObfHelper;
+import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.NamedTextColor;
+import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.MiniMessage;
@ -2768,14 +2805,12 @@ index 0000000000000000000000000000000000000000..3be5cb126e41a533e9453bbd6326cd1c
+import org.spongepowered.configurate.transformation.ConfigurationTransformation; +import org.spongepowered.configurate.transformation.ConfigurationTransformation;
+import org.spongepowered.configurate.transformation.TransformAction; +import org.spongepowered.configurate.transformation.TransformAction;
+ +
+import java.util.List;
+import java.util.function.Predicate; +import java.util.function.Predicate;
+ +
+import static org.spongepowered.configurate.NodePath.path; +import static org.spongepowered.configurate.NodePath.path;
+ +
+public final class LegacyPaperConfig { +public final class LegacyPaperConfig {
+ private static final Logger LOGGER = LogUtils.getLogger(); + private static final Logger LOGGER = LogUtils.getLogger();
+ private static final PacketClassSerializer PACKET_CLASS_SERIALIZER = new PacketClassSerializer();
+ +
+ private LegacyPaperConfig() { + private LegacyPaperConfig() {
+ } + }
@ -2872,31 +2907,11 @@ index 0000000000000000000000000000000000000000..3be5cb126e41a533e9453bbd6326cd1c
+ .addAction(path("packet-limiter", "limits", "all"), (path, value) -> new Object[]{"packet-limiter", "all-packets"}) + .addAction(path("packet-limiter", "limits", "all"), (path, value) -> new Object[]{"packet-limiter", "all-packets"})
+ .addAction(path("packet-limiter", "limits"), (path, value) -> new Object[]{"packet-limiter", "overrides"}) + .addAction(path("packet-limiter", "limits"), (path, value) -> new Object[]{"packet-limiter", "overrides"})
+ .addAction(path("packet-limiter", "overrides", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> { + .addAction(path("packet-limiter", "overrides", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> {
+ if (ObfHelper.INSTANCE.mappingsByObfName() != null) { // requires mappings to be present + final @Nullable Object keyValue = value.key();
+ final @Nullable Object key = value.key(); + if (keyValue != null && keyValue.toString().equals("PacketPlayInAutoRecipe")) { // add special cast to handle the default for moj-mapped servers that upgrade the config
+ if (key != null) { + return path.with(path.size() - 1, ServerboundPlaceRecipePacket.class.getSimpleName()).array();
+ String className = key.toString();
+ for (final String state : List.of("game", "handshake", "login", "status")) {
+ final String fullClassName = "net.minecraft.network.protocol." + state + "." + className;
+ final ObfHelper.ClassMapping classMapping = ObfHelper.INSTANCE.mappingsByObfName().get(fullClassName);
+ if (classMapping != null) {
+ final String[] split = classMapping.mojangName().split("\\.");
+ className = split[split.length - 1];
+ break;
+ }
+ }
+
+ return path.with(path.size() - 1, className).array();
+ } else {
+ LOGGER.warn("Could not convert spigot-mapped packet class name {}", value);
+ }
+ } else { + } else {
+ final @Nullable Object keyValue = value.key(); + LOGGER.warn("Could not convert spigot-mapped packet class name {} because no mappings were found in the jar", keyValue);
+ if (keyValue != null && keyValue.toString().equals("PacketPlayInAutoRecipe")) { // add special case to catch the default
+ return path.with(path.size() - 1, ServerboundPlaceRecipePacket.class.getSimpleName()).array();
+ } else {
+ LOGGER.warn("Could not convert spigot-mapped packet class name {} because no mappings were found in the jar", keyValue);
+ }
+ } + }
+ return null; + return null;
+ }).addAction(path("loggers"), TransformAction.rename("logging")); + }).addAction(path("loggers"), TransformAction.rename("logging"));