diff options
author | Jake Potrebic <[email protected]> | 2024-11-23 13:27:37 -0800 |
---|---|---|
committer | GitHub <[email protected]> | 2024-11-23 13:27:37 -0800 |
commit | eef40b78c278df085b3c852be21e68a59680def4 (patch) | |
tree | 015ad6a88c25b69fb9267a65b239e729a3e634a8 | |
parent | aee6f7abe161976fb6cb0558aeda5aef49845787 (diff) | |
download | Paper-eef40b78c278df085b3c852be21e68a59680def4.tar.gz Paper-eef40b78c278df085b3c852be21e68a59680def4.zip |
Configurable Entity Despawn Time (#11454)
* Configurable Entity Despawn Time
Co-authored-by: Kevin Raneri <[email protected]>
* Rebase
* Rebase
* rebase
* throw exceptions for this map
---------
Co-authored-by: Kevin Raneri <[email protected]>
4 files changed, 388 insertions, 199 deletions
diff --git a/patches/server/0005-Paper-config-files.patch b/patches/server/0005-Paper-config-files.patch index 8115fc2d48..d5545fac61 100644 --- a/patches/server/0005-Paper-config-files.patch +++ b/patches/server/0005-Paper-config-files.patch @@ -121,10 +121,10 @@ index 0000000000000000000000000000000000000000..042478cf7ce150f1f1bc5cddd7fa40f8 +} diff --git a/src/main/java/io/papermc/paper/configuration/Configurations.java b/src/main/java/io/papermc/paper/configuration/Configurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd8066b857ca3 +index 0000000000000000000000000000000000000000..007e01d329a31acf7f4ed4c6dc4de7ad54ccad04 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/Configurations.java -@@ -0,0 +1,360 @@ +@@ -0,0 +1,358 @@ +package io.papermc.paper.configuration; + +import com.google.common.base.Preconditions; @@ -132,34 +132,32 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +import io.leangen.geantyref.TypeToken; +import io.papermc.paper.configuration.constraint.Constraint; +import io.papermc.paper.configuration.constraint.Constraints; ++import java.io.IOException; ++import java.lang.reflect.Type; ++import java.nio.file.AccessDeniedException; ++import java.nio.file.Files; ++import java.nio.file.Path; ++import java.util.HashMap; ++import java.util.Map; ++import java.util.NoSuchElementException; ++import java.util.Objects; ++import java.util.function.UnaryOperator; +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.world.level.GameRules; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.jetbrains.annotations.MustBeInvokedByOverriders; ++import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.ConfigurationOptions; -+import org.spongepowered.configurate.NodePath; +import org.spongepowered.configurate.objectmapping.ObjectMapper; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.util.CheckedFunction; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; + -+import java.io.IOException; -+import java.lang.reflect.Type; -+import java.nio.file.AccessDeniedException; -+import java.nio.file.Files; -+import java.nio.file.Path; -+import java.util.HashMap; -+import java.util.Map; -+import java.util.NoSuchElementException; -+import java.util.Objects; -+import java.util.function.UnaryOperator; -+ +public abstract class Configurations<G, W> { + + private static final Logger LOGGER = LogUtils.getClassLogger(); @@ -487,7 +485,7 @@ index 0000000000000000000000000000000000000000..d9502ba028a96f9cc846f9ed428bd806 +} diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..f0d470d7770e119f734b9e72021c806d0ea8ecbd +index 0000000000000000000000000000000000000000..0ea9eba1367858dfa5284524a8dd2f79daf6fc69 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -0,0 +1,330 @@ @@ -501,7 +499,7 @@ index 0000000000000000000000000000000000000000..f0d470d7770e119f734b9e72021c806d +import net.kyori.adventure.text.format.NamedTextColor; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.spongepowered.configurate.objectmapping.ConfigSerializable; +import org.spongepowered.configurate.objectmapping.meta.Comment; @@ -823,21 +821,20 @@ index 0000000000000000000000000000000000000000..f0d470d7770e119f734b9e72021c806d +} diff --git a/src/main/java/io/papermc/paper/configuration/NestedSetting.java b/src/main/java/io/papermc/paper/configuration/NestedSetting.java new file mode 100644 -index 0000000000000000000000000000000000000000..69add4a7f1147015806bc9b63a8340d1893356c1 +index 0000000000000000000000000000000000000000..b8c42cc2624f325dc8725ebab68bbff0addb3855 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/NestedSetting.java -@@ -0,0 +1,32 @@ +@@ -0,0 +1,31 @@ +package io.papermc.paper.configuration; + -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.objectmapping.meta.NodeResolver; -+ +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.objectmapping.meta.NodeResolver; + +@Documented +@Retention(RetentionPolicy.RUNTIME) @@ -861,10 +858,10 @@ index 0000000000000000000000000000000000000000..69add4a7f1147015806bc9b63a8340d1 +} diff --git a/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java new file mode 100644 -index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef5701383f6f258 +index 0000000000000000000000000000000000000000..c5644d8d64f12073e39bc6ed79c8714f4560ff89 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/PaperConfigurations.java -@@ -0,0 +1,467 @@ +@@ -0,0 +1,470 @@ +package io.papermc.paper.configuration; + +import com.google.common.base.Suppliers; @@ -903,6 +900,8 @@ index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef57013 +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2LongMap; +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Type; @@ -925,8 +924,8 @@ index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef57013 +import org.apache.commons.lang3.RandomStringUtils; +import org.bukkit.configuration.ConfigurationSection; +import org.bukkit.configuration.file.YamlConfiguration; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.jetbrains.annotations.VisibleForTesting; ++import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.spigotmc.SpigotConfig; +import org.spigotmc.SpigotWorldConfig; @@ -1108,6 +1107,7 @@ index 0000000000000000000000000000000000000000..1029b6de6f36b08bf634b4056ef57013 + .serializers(serializers -> serializers + .register(new TypeToken<Reference2IntMap<?>>() {}, new FastutilMapSerializer.SomethingToPrimitive<Reference2IntMap<?>>(Reference2IntOpenHashMap::new, Integer.TYPE)) + .register(new TypeToken<Reference2LongMap<?>>() {}, new FastutilMapSerializer.SomethingToPrimitive<Reference2LongMap<?>>(Reference2LongOpenHashMap::new, Long.TYPE)) ++ .register(new TypeToken<Reference2ObjectMap<?, ?>>() {}, new FastutilMapSerializer.SomethingToSomething<Reference2ObjectMap<?, ?>>(Reference2ObjectOpenHashMap::new)) + .register(new TypeToken<Table<?, ?, ?>>() {}, new TableSerializer()) + .register(DespawnRange.class, DespawnRange.SERIALIZER) + .register(StringRepresentableSerializer::isValidFor, new StringRepresentableSerializer()) @@ -1423,10 +1423,10 @@ index 0000000000000000000000000000000000000000..279b24c689b9979884b65df7eb1f0590 +} diff --git a/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java new file mode 100644 -index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7d0fd0d36 +index 0000000000000000000000000000000000000000..b1c917d65076a3805e5b78cb946753f0c101e214 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/WorldConfiguration.java -@@ -0,0 +1,581 @@ +@@ -0,0 +1,590 @@ +package io.papermc.paper.configuration; + +import com.google.common.collect.HashBasedTable; @@ -1436,6 +1436,7 @@ index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7 +import io.papermc.paper.configuration.legacy.RequiresSpigotInitialization; +import io.papermc.paper.configuration.mapping.MergeMap; +import io.papermc.paper.configuration.serializer.NbtPathSerializer; ++import io.papermc.paper.configuration.serializer.collections.MapSerializer; +import io.papermc.paper.configuration.transformation.world.FeatureSeedsGeneration; +import io.papermc.paper.configuration.type.BooleanOrDefault; +import io.papermc.paper.configuration.type.DespawnRange; @@ -1451,6 +1452,8 @@ index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7 +import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; +import it.unimi.dsi.fastutil.objects.Reference2LongMap; +import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; ++import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import java.util.Arrays; +import java.util.IdentityHashMap; +import java.util.List; @@ -1628,6 +1631,12 @@ index 0000000000000000000000000000000000000000..dad3fcc689ec806f985122a7cbd501a7 + } + } + ++ @MapSerializer.ThrowExceptions ++ public Reference2ObjectMap<EntityType<?>, IntOr.Disabled> despawnTime = Util.make(new Reference2ObjectOpenHashMap<>(), map -> { ++ map.put(EntityType.SNOWBALL, IntOr.Disabled.DISABLED); ++ map.put(EntityType.LLAMA_SPIT, IntOr.Disabled.DISABLED); ++ }); ++ + @PostProcess + public void precomputeDespawnDistances() throws SerializationException { + for (Map.Entry<MobCategory, DespawnRangePair> entry : this.despawnRanges.entrySet()) { @@ -2046,7 +2055,7 @@ index 0000000000000000000000000000000000000000..514be9a11e2ca368ea72dd2bac1b84bf +} diff --git a/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java b/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java new file mode 100644 -index 0000000000000000000000000000000000000000..2d8c91007d5ebc051623bb308cf973bdad3f3273 +index 0000000000000000000000000000000000000000..9cab83a5b47b29d394bdf6e5c5f8e2c9952d9156 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/constraint/Constraints.java @@ -0,0 +1,43 @@ @@ -2058,7 +2067,7 @@ index 0000000000000000000000000000000000000000..2d8c91007d5ebc051623bb308cf973bd +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.reflect.Type; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.objectmapping.meta.Constraint; +import org.spongepowered.configurate.serialize.SerializationException; + @@ -2095,13 +2104,13 @@ index 0000000000000000000000000000000000000000..2d8c91007d5ebc051623bb308cf973bd +} diff --git a/src/main/java/io/papermc/paper/configuration/legacy/MaxEntityCollisionsInitializer.java b/src/main/java/io/papermc/paper/configuration/legacy/MaxEntityCollisionsInitializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..62b43280f59163f7910f79cc901b50d05cdd024e +index 0000000000000000000000000000000000000000..ddef1ed3ff6fef52a70ee8bbf0b7607f6588ae6d --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/legacy/MaxEntityCollisionsInitializer.java @@ -0,0 +1,29 @@ +package io.papermc.paper.configuration.legacy; + -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spigotmc.SpigotWorldConfig; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.objectmapping.meta.NodeResolver; @@ -2130,18 +2139,14 @@ index 0000000000000000000000000000000000000000..62b43280f59163f7910f79cc901b50d0 +} diff --git a/src/main/java/io/papermc/paper/configuration/legacy/RequiresSpigotInitialization.java b/src/main/java/io/papermc/paper/configuration/legacy/RequiresSpigotInitialization.java new file mode 100644 -index 0000000000000000000000000000000000000000..611bdbcef3d52e09179aa8b1677ab1e198c70b02 +index 0000000000000000000000000000000000000000..81c64a2ffad4bcd69f0012f04567a7d15f2d6dd5 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/legacy/RequiresSpigotInitialization.java -@@ -0,0 +1,51 @@ +@@ -0,0 +1,48 @@ +package io.papermc.paper.configuration.legacy; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.Table; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spigotmc.SpigotWorldConfig; -+import org.spongepowered.configurate.objectmapping.meta.NodeResolver; -+ +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; @@ -2149,8 +2154,9 @@ index 0000000000000000000000000000000000000000..611bdbcef3d52e09179aa8b1677ab1e1 +import java.lang.annotation.Target; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Constructor; -+import java.util.Map; -+import java.util.concurrent.ConcurrentHashMap; ++import org.jspecify.annotations.Nullable; ++import org.spigotmc.SpigotWorldConfig; ++import org.spongepowered.configurate.objectmapping.meta.NodeResolver; + +@Documented +@Retention(RetentionPolicy.RUNTIME) @@ -2220,21 +2226,19 @@ index 0000000000000000000000000000000000000000..fe5cc1c097f8d8c135e6ead6f458426b +} diff --git a/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java new file mode 100644 -index 0000000000000000000000000000000000000000..8f23276796037d048eb114952891a01a40971b3e +index 0000000000000000000000000000000000000000..05339a176083af667c16f77d76dc1878dafce3f0 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassFieldDiscoverer.java -@@ -0,0 +1,54 @@ +@@ -0,0 +1,52 @@ +package io.papermc.paper.configuration.mapping; + +import io.papermc.paper.configuration.ConfigurationPart; -+import io.papermc.paper.configuration.Configurations; -+import io.papermc.paper.configuration.PaperConfigurations; +import io.papermc.paper.configuration.WorldConfiguration; +import java.lang.reflect.AnnotatedType; +import java.lang.reflect.Field; +import java.util.Collections; +import java.util.Map; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.objectmapping.FieldDiscoverer; +import org.spongepowered.configurate.serialize.SerializationException; + @@ -2280,10 +2284,10 @@ index 0000000000000000000000000000000000000000..8f23276796037d048eb114952891a01a +} diff --git a/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceFactory.java b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceFactory.java new file mode 100644 -index 0000000000000000000000000000000000000000..cec678ae24a7d99a46fa672be907f4c28fe4da96 +index 0000000000000000000000000000000000000000..25e3152c3307175da734a1cad7f7a4166e233021 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceFactory.java -@@ -0,0 +1,65 @@ +@@ -0,0 +1,64 @@ +package io.papermc.paper.configuration.mapping; + +import java.lang.reflect.AnnotatedType; @@ -2291,7 +2295,6 @@ index 0000000000000000000000000000000000000000..cec678ae24a7d99a46fa672be907f4c2 +import java.util.Iterator; +import java.util.Map; +import java.util.Objects; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.objectmapping.FieldDiscoverer; +import org.spongepowered.configurate.serialize.SerializationException; + @@ -2323,7 +2326,7 @@ index 0000000000000000000000000000000000000000..cec678ae24a7d99a46fa672be907f4c2 + Map.Entry<Field, Object> entry = iter.next(); + if (entry.getKey().isAnnotationPresent(MergeMap.class) && Map.class.isAssignableFrom(entry.getKey().getType()) && intermediate.get(entry.getKey()) instanceof Map<?, ?> map) { + iter.remove(); -+ @Nullable Map<Object, Object> existingMap = (Map<Object, Object>) entry.getKey().get(instance); ++ Map<Object, Object> existingMap = (Map<Object, Object>) entry.getKey().get(instance); + if (existingMap != null) { + existingMap.putAll(map); + } else { @@ -2351,7 +2354,7 @@ index 0000000000000000000000000000000000000000..cec678ae24a7d99a46fa672be907f4c2 +} diff --git a/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceSupplier.java b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceSupplier.java new file mode 100644 -index 0000000000000000000000000000000000000000..8d8bc050441c02cf65dfcb6400978363d6b8ef10 +index 0000000000000000000000000000000000000000..3778c47f563fd0011659234fc8394e3d59325782 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/mapping/InnerClassInstanceSupplier.java @@ -0,0 +1,72 @@ @@ -2364,7 +2367,7 @@ index 0000000000000000000000000000000000000000..8d8bc050441c02cf65dfcb6400978363 +import java.util.HashMap; +import java.util.Map; +import java.util.function.Supplier; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.util.CheckedFunction; +import org.spongepowered.configurate.util.CheckedSupplier; @@ -2400,7 +2403,7 @@ index 0000000000000000000000000000000000000000..8d8bc050441c02cf65dfcb6400978363 + final Constructor<?> constructor; + final CheckedSupplier<Object, ReflectiveOperationException> instanceSupplier; + if (type.getEnclosingClass() != null && !Modifier.isStatic(type.getModifiers())) { -+ final @Nullable Object instance = this.instanceMap.get(type.getEnclosingClass()); ++ final Object instance = this.instanceMap.get(type.getEnclosingClass()); + if (instance == null) { + throw new SerializationException("Cannot create a new instance of an inner class " + type.getName() + " without an instance of its enclosing class " + type.getEnclosingClass().getName()); + } @@ -2453,18 +2456,26 @@ index 0000000000000000000000000000000000000000..471b161ac51900672434c6608595bb73 +@Retention(RetentionPolicy.RUNTIME) +public @interface MergeMap { +} +diff --git a/src/main/java/io/papermc/paper/configuration/mapping/package-info.java b/src/main/java/io/papermc/paper/configuration/mapping/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..454e6ec7ebf9c54a38d6ba3a73e7c197c67c2c00 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/mapping/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.mapping; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/package-info.java b/src/main/java/io/papermc/paper/configuration/package-info.java new file mode 100644 -index 0000000000000000000000000000000000000000..4e3bcd7c478096384fcc643d48771ab94318deb3 +index 0000000000000000000000000000000000000000..11bf7bb357305cf90c201444be08dc71c14b7505 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/package-info.java -@@ -0,0 +1,5 @@ -+@DefaultQualifier(NonNull.class) +@@ -0,0 +1,4 @@ ++@NullMarked +package io.papermc.paper.configuration; + -+import org.checkerframework.checker.nullness.qual.NonNull; -+import org.checkerframework.framework.qual.DefaultQualifier; -\ No newline at end of file ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/ComponentSerializer.java new file mode 100644 index 0000000000000000000000000000000000000000..9c339ef178ebc3b0251095f320e4a7a3656d3521 @@ -2538,24 +2549,23 @@ index 0000000000000000000000000000000000000000..27c0679d376bb31ab52131dfea74b3b5 +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/EnumValueSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/EnumValueSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..8535c748a5e355362e77e6c5103e11c4c318a138 +index 0000000000000000000000000000000000000000..d24d1480e3ee7e5004c2dcbe826823aa427f787a --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/EnumValueSerializer.java -@@ -0,0 +1,50 @@ +@@ -0,0 +1,49 @@ +package io.papermc.paper.configuration.serializer; + +import com.mojang.logging.LogUtils; +import io.leangen.geantyref.TypeToken; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.slf4j.Logger; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+import org.spongepowered.configurate.util.EnumLookup; -+ +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; +import java.util.function.Predicate; ++import org.jspecify.annotations.Nullable; ++import org.slf4j.Logger; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; ++import org.spongepowered.configurate.util.EnumLookup; + +import static io.leangen.geantyref.GenericTypeReflector.erase; + @@ -2575,14 +2585,14 @@ index 0000000000000000000000000000000000000000..8535c748a5e355362e77e6c5103e11c4 + public @Nullable Enum<?> deserialize(final Type type, final Object obj) throws SerializationException { + final String enumConstant = obj.toString(); + final Class<? extends Enum> typeClass = erase(type).asSubclass(Enum.class); -+ @Nullable Enum<?> ret = EnumLookup.lookupEnum(typeClass, enumConstant); ++ Enum<?> ret = EnumLookup.lookupEnum(typeClass, enumConstant); + if (ret == null) { + ret = EnumLookup.lookupEnum(typeClass, enumConstant.replace("-", "_")); + } + if (ret == null) { + boolean longer = typeClass.getEnumConstants().length > 10; + List<String> options = Arrays.stream(typeClass.getEnumConstants()).limit(10L).map(Enum::name).toList(); -+ LOGGER.error("Invalid enum constant provided, expected one of [" + String.join(", " ,options) + (longer ? ", ..." : "") + "], but got " + enumConstant); ++ LOGGER.error("Invalid enum constant provided, expected one of [{}{}], but got {}", String.join(", ", options), longer ? ", ..." : "", enumConstant); + } + return ret; + } @@ -2652,10 +2662,10 @@ index 0000000000000000000000000000000000000000..b44b2dc28f619594e302417848e95c00 +} 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 -index 0000000000000000000000000000000000000000..893ad5e7c2d32ccd64962d95d146bbd317c28ab8 +index 0000000000000000000000000000000000000000..b61935052154e76b1b8cb49868c96c52f34a41d1 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java -@@ -0,0 +1,86 @@ +@@ -0,0 +1,85 @@ +package io.papermc.paper.configuration.serializer; + +import com.google.common.collect.BiMap; @@ -2664,16 +2674,15 @@ index 0000000000000000000000000000000000000000..893ad5e7c2d32ccd64962d95d146bbd3 +import io.leangen.geantyref.TypeToken; +import io.papermc.paper.configuration.serializer.collections.MapSerializer; +import io.papermc.paper.util.ObfHelper; -+import net.minecraft.network.protocol.Packet; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.slf4j.Logger; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; ++import net.minecraft.network.protocol.Packet; ++import org.jspecify.annotations.Nullable; ++import org.slf4j.Logger; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +@SuppressWarnings("Convert2Diamond") +public final class PacketClassSerializer extends ScalarSerializer<Class<? extends Packet<?>>> implements MapSerializer.WriteBack { @@ -2703,14 +2712,14 @@ index 0000000000000000000000000000000000000000..893ad5e7c2d32ccd64962d95d146bbd3 + @SuppressWarnings("unchecked") + @Override + public Class<? extends Packet<?>> deserialize(final Type type, final Object obj) throws SerializationException { -+ @Nullable Class<?> packetClass = null; ++ Class<?> packetClass = null; + for (final String subpackage : SUBPACKAGES) { + final String fullClassName = "net.minecraft.network.protocol." + subpackage + "." + obj; + try { + packetClass = Class.forName(fullClassName); + break; + } catch (final ClassNotFoundException ex) { -+ final @Nullable String spigotClassName = MOJANG_TO_OBF.get(fullClassName); ++ final String spigotClassName = MOJANG_TO_OBF.get(fullClassName); + if (spigotClassName != null) { + try { + packetClass = Class.forName(spigotClassName); @@ -2744,23 +2753,22 @@ index 0000000000000000000000000000000000000000..893ad5e7c2d32ccd64962d95d146bbd3 +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..7fc0905fc6b8f5df762b4cea573f935dc00b8bc1 +index 0000000000000000000000000000000000000000..629012cb8ea8d8d81f99033794226bef19ee6c80 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/StringRepresentableSerializer.java -@@ -0,0 +1,52 @@ +@@ -0,0 +1,51 @@ +package io.papermc.paper.configuration.serializer; + -+import net.minecraft.util.StringRepresentable; -+import net.minecraft.world.entity.MobCategory; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; +import java.util.function.Predicate; ++import net.minecraft.util.StringRepresentable; ++import net.minecraft.world.entity.MobCategory; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +public final class StringRepresentableSerializer extends ScalarSerializer<StringRepresentable> { + private static final Map<Type, Function<String, StringRepresentable>> TYPES = Collections.synchronizedMap(Map.ofEntries( @@ -2802,52 +2810,61 @@ index 0000000000000000000000000000000000000000..7fc0905fc6b8f5df762b4cea573f935d +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/FastutilMapSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/FastutilMapSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..4af710e144b70933d750c22edfe484c18e4a3540 +index 0000000000000000000000000000000000000000..68ed5ad7b6f28a9fdda35e25c12a13a2619e1449 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/FastutilMapSerializer.java -@@ -0,0 +1,69 @@ +@@ -0,0 +1,91 @@ +package io.papermc.paper.configuration.serializer.collections; + +import io.leangen.geantyref.GenericTypeReflector; +import io.leangen.geantyref.TypeFactory; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.ConfigurationNode; -+import org.spongepowered.configurate.serialize.SerializationException; -+import org.spongepowered.configurate.serialize.TypeSerializer; -+ ++import java.lang.annotation.Annotation; ++import java.lang.reflect.AnnotatedParameterizedType; ++import java.lang.reflect.AnnotatedType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collections; +import java.util.Map; +import java.util.function.Function; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.ConfigurationNode; ++import org.spongepowered.configurate.serialize.SerializationException; ++import org.spongepowered.configurate.serialize.TypeSerializer; + +@SuppressWarnings("rawtypes") -+public abstract class FastutilMapSerializer<M extends Map<?, ?>> implements TypeSerializer<M> { -+ private final Function<Map, ? extends M> factory; ++public abstract class FastutilMapSerializer<M extends Map<?, ?>> implements TypeSerializer.Annotated<M> { + -+ protected FastutilMapSerializer(final Function<Map, ? extends M> factory) { ++ private final Function<? super Map, ? extends M> factory; ++ ++ protected FastutilMapSerializer(final Function<? super Map, ? extends M> factory) { + this.factory = factory; + } + + @Override -+ public M deserialize(final Type type, final ConfigurationNode node) throws SerializationException { -+ @Nullable final Map map = (Map) node.get(this.createBaseMapType((ParameterizedType) type)); ++ public M deserialize(final AnnotatedType annotatedType, final ConfigurationNode node) throws SerializationException { ++ final Map map = (Map) node.get(this.createAnnotatedMapType((AnnotatedParameterizedType) annotatedType)); + return this.factory.apply(map == null ? Collections.emptyMap() : map); + } + + @Override -+ public void serialize(final Type type, @Nullable final M obj, final ConfigurationNode node) throws SerializationException { ++ public void serialize(final AnnotatedType annotatedType, final @Nullable M obj, final ConfigurationNode node) throws SerializationException { + if (obj == null || obj.isEmpty()) { + node.raw(null); + } else { -+ final Type baseMapType = this.createBaseMapType((ParameterizedType) type); ++ final AnnotatedType baseMapType = this.createAnnotatedMapType((AnnotatedParameterizedType) annotatedType); + node.set(baseMapType, obj); + } + } + ++ private AnnotatedType createAnnotatedMapType(final AnnotatedParameterizedType type) { ++ final Type baseType = this.createBaseMapType((ParameterizedType) type.getType()); ++ return GenericTypeReflector.annotate(baseType, type.getAnnotations()); ++ } ++ + protected abstract Type createBaseMapType(final ParameterizedType type); + + public static final class SomethingToPrimitive<M extends Map<?, ?>> extends FastutilMapSerializer<M> { ++ + private final Type primitiveType; + + public SomethingToPrimitive(final Function<Map, ? extends M> factory, final Type primitiveType) { @@ -2862,6 +2879,7 @@ index 0000000000000000000000000000000000000000..4af710e144b70933d750c22edfe484c1 + } + + public static final class PrimitiveToSomething<M extends Map<?, ?>> extends FastutilMapSerializer<M> { ++ + private final Type primitiveType; + + public PrimitiveToSomething(final Function<Map, ? extends M> factory, final Type primitiveType) { @@ -2874,26 +2892,32 @@ index 0000000000000000000000000000000000000000..4af710e144b70933d750c22edfe484c1 + return TypeFactory.parameterizedClass(Map.class, GenericTypeReflector.box(this.primitiveType), type.getActualTypeArguments()[0]); + } + } ++ ++ public static final class SomethingToSomething<M extends Map<?, ?>> extends FastutilMapSerializer<M> { ++ ++ public SomethingToSomething(final Function<? super Map, ? extends M> factory) { ++ super(factory); ++ } ++ ++ @Override ++ protected Type createBaseMapType(final ParameterizedType type) { ++ return TypeFactory.parameterizedClass(Map.class, type.getActualTypeArguments()[0], type.getActualTypeArguments()[1]); ++ } ++ } +} 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 -index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4231e6f98 +index 0000000000000000000000000000000000000000..6bb8304b9d98bf2ba53274a3808e607e08f0787f --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/MapSerializer.java -@@ -0,0 +1,162 @@ +@@ -0,0 +1,182 @@ +package io.papermc.paper.configuration.serializer.collections; + +import com.mojang.logging.LogUtils; +import io.leangen.geantyref.TypeToken; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.slf4j.Logger; -+import org.spongepowered.configurate.BasicConfigurationNode; -+import org.spongepowered.configurate.ConfigurationNode; -+import org.spongepowered.configurate.ConfigurationOptions; -+import org.spongepowered.configurate.NodePath; -+import org.spongepowered.configurate.serialize.SerializationException; -+import org.spongepowered.configurate.serialize.TypeSerializer; -+ ++import java.lang.annotation.Retention; ++import java.lang.annotation.RetentionPolicy; ++import java.lang.reflect.AnnotatedType; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.util.Collections; @@ -2901,27 +2925,45 @@ index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4 +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; ++import org.jspecify.annotations.Nullable; ++import org.slf4j.Logger; ++import org.spongepowered.configurate.BasicConfigurationNode; ++import org.spongepowered.configurate.ConfigurationNode; ++import org.spongepowered.configurate.ConfigurationOptions; ++import org.spongepowered.configurate.NodePath; ++import org.spongepowered.configurate.serialize.SerializationException; ++import org.spongepowered.configurate.serialize.TypeSerializer; ++import org.spongepowered.configurate.serialize.TypeSerializerCollection; + +import static java.util.Objects.requireNonNull; + +/** + * Map serializer that does not throw errors on individual entry serialization failures. + */ -+public class MapSerializer implements TypeSerializer<Map<?, ?>> { ++public class MapSerializer implements TypeSerializer.Annotated<Map<?, ?>> { + + public static final TypeToken<Map<?, ?>> TYPE = new TypeToken<Map<?, ?>>() {}; + + private static final Logger LOGGER = LogUtils.getClassLogger(); + + private final boolean clearInvalids; ++ private final TypeSerializer<Map<?, ?>> fallback; + + public MapSerializer(boolean clearInvalids) { + this.clearInvalids = clearInvalids; ++ this.fallback = requireNonNull(TypeSerializerCollection.defaults().get(TYPE), "Could not find default Map<?, ?> serializer"); + } + ++ @Retention(RetentionPolicy.RUNTIME) ++ public @interface ThrowExceptions {} ++ + @Override -+ public Map<?, ?> deserialize(Type type, ConfigurationNode node) throws SerializationException { ++ public Map<?, ?> deserialize(AnnotatedType annotatedType, ConfigurationNode node) throws SerializationException { ++ if (annotatedType.isAnnotationPresent(ThrowExceptions.class)) { ++ return this.fallback.deserialize(annotatedType, node); ++ } + final Map<Object, Object> map = new LinkedHashMap<>(); ++ final Type type = annotatedType.getType(); + if (node.isMap()) { + if (!(type instanceof ParameterizedType parameterizedType)) { + throw new SerializationException(type, "Raw types are not supported for collections"); @@ -2975,7 +3017,12 @@ index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4 + } + + @Override -+ public void serialize(Type type, @Nullable Map<?, ?> obj, ConfigurationNode node) throws SerializationException { ++ public void serialize(AnnotatedType annotatedType, @Nullable Map<?, ?> obj, ConfigurationNode node) throws SerializationException { ++ if (annotatedType.isAnnotationPresent(ThrowExceptions.class)) { ++ this.fallback.serialize(annotatedType, obj, node); ++ return; ++ } ++ final Type type = annotatedType.getType(); + if (!(type instanceof ParameterizedType parameterizedType)) { + throw new SerializationException(type, "Raw types are not supported for collections"); + } @@ -3036,7 +3083,10 @@ index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4 + } + + @Override -+ public @Nullable Map<?, ?> emptyValue(Type specificType, ConfigurationOptions options) { ++ public @Nullable Map<?, ?> emptyValue(AnnotatedType specificType, ConfigurationOptions options) { ++ if (specificType.isAnnotationPresent(ThrowExceptions.class)) { ++ return this.fallback.emptyValue(specificType, options); ++ } + return new LinkedHashMap<>(); + } + @@ -3045,28 +3095,27 @@ index 0000000000000000000000000000000000000000..e7e997796ec47c742cc1f98e61db75a4 +} diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/TableSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/TableSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6de7ecd007 +index 0000000000000000000000000000000000000000..c02b2aa2565645d64c2709310d2aba9e32fd536d --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/TableSerializer.java -@@ -0,0 +1,89 @@ +@@ -0,0 +1,88 @@ +package io.papermc.paper.configuration.serializer.collections; + +import com.google.common.collect.HashBasedTable; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.Table; +import io.leangen.geantyref.TypeFactory; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import java.lang.reflect.ParameterizedType; ++import java.lang.reflect.Type; ++import java.util.Map; ++import java.util.Objects; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.BasicConfigurationNode; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.ConfigurationOptions; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.serialize.TypeSerializer; + -+import java.lang.reflect.ParameterizedType; -+import java.lang.reflect.Type; -+import java.util.Map; -+import java.util.Objects; -+ +public class TableSerializer implements TypeSerializer<Table<?, ?, ?>> { + private static final int ROW_TYPE_ARGUMENT_INDEX = 0; + private static final int COLUMN_TYPE_ARGUMENT_INDEX = 1; @@ -3087,13 +3136,13 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d + final Type columnType = type.getActualTypeArguments()[COLUMN_TYPE_ARGUMENT_INDEX]; + final Type valueType = type.getActualTypeArguments()[VALUE_TYPE_ARGUMENT_INDEX]; + -+ final @Nullable TypeSerializer<R> rowKeySerializer = (TypeSerializer<R>) node.options().serializers().get(rowType); ++ final TypeSerializer<R> rowKeySerializer = (TypeSerializer<R>) node.options().serializers().get(rowType); + if (rowKeySerializer == null) { + throw new SerializationException("Could not find serializer for table row type " + rowType); + } + + final Type mapType = TypeFactory.parameterizedClass(Map.class, columnType, valueType); -+ final @Nullable TypeSerializer<Map<C, V>> columnValueSerializer = (TypeSerializer<Map<C, V>>) node.options().serializers().get(mapType); ++ final TypeSerializer<Map<C, V>> columnValueSerializer = (TypeSerializer<Map<C, V>>) node.options().serializers().get(mapType); + if (columnValueSerializer == null) { + throw new SerializationException("Could not find serializer for table column-value map " + type); + } @@ -3108,7 +3157,7 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d + } + + @Override -+ public void serialize(final Type type, @Nullable final Table<?, ?, ?> table, final ConfigurationNode node) throws SerializationException { ++ public void serialize(final Type type, final @Nullable Table<?, ?, ?> table, final ConfigurationNode node) throws SerializationException { + if (table != null) { + this.serialize0(table, (ParameterizedType) type, node); + } @@ -3120,7 +3169,7 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d + final Type columnType = type.getActualTypeArguments()[COLUMN_TYPE_ARGUMENT_INDEX]; + final Type valueType = type.getActualTypeArguments()[VALUE_TYPE_ARGUMENT_INDEX]; + -+ final @Nullable TypeSerializer rowKeySerializer = node.options().serializers().get(rowType); ++ final TypeSerializer rowKeySerializer = node.options().serializers().get(rowType); + if (rowKeySerializer == null) { + throw new SerializationException("Could not find a serializer for table row type " + rowType); + } @@ -3138,12 +3187,32 @@ index 0000000000000000000000000000000000000000..36ca88b677e1b55b41c52750948d5b6d + return ImmutableTable.of(); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..78899dc1357626f993119efabf29c52396e15b2b +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/serializer/collections/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.serializer.collections; ++ ++import org.jspecify.annotations.NullMarked; +diff --git a/src/main/java/io/papermc/paper/configuration/serializer/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..757de4562e038a2d62f276e18e86ecab7c7332bf +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/serializer/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.serializer; ++ ++import org.jspecify.annotations.NullMarked; 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 -index 0000000000000000000000000000000000000000..cb0de1a639578320fd38177a915bfa5d1e9a73bd +index 0000000000000000000000000000000000000000..6b600a133f0689a70d1619c684c5e3c0f313b42d --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/RegistryEntrySerializer.java -@@ -0,0 +1,64 @@ +@@ -0,0 +1,63 @@ +package io.papermc.paper.configuration.serializer.registry; + +import io.leangen.geantyref.TypeToken; @@ -3153,7 +3222,6 @@ index 0000000000000000000000000000000000000000..cb0de1a639578320fd38177a915bfa5d +import net.minecraft.core.RegistryAccess; +import net.minecraft.resources.ResourceKey; +import net.minecraft.resources.ResourceLocation; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.serialize.ScalarSerializer; +import org.spongepowered.configurate.serialize.SerializationException; + @@ -3201,7 +3269,7 @@ index 0000000000000000000000000000000000000000..cb0de1a639578320fd38177a915bfa5d + } + + private ResourceKey<R> deserializeKey(final Object input) throws SerializationException { -+ final @Nullable ResourceLocation key = ResourceLocation.tryParse(input.toString()); ++ final ResourceLocation key = ResourceLocation.tryParse(input.toString()); + if (key == null) { + throw new SerializationException("Could not create a key from " + input); + } @@ -3289,6 +3357,16 @@ index 0000000000000000000000000000000000000000..6831b7b72c5e1f79eff36019ca2ff565 + return this.registry().getResourceKey(value).orElseThrow(); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java b/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5185a314b555dffb6dea355dc9e2b005e5808843 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/serializer/registry/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.serializer.registry; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/transformation/Transformations.java b/src/main/java/io/papermc/paper/configuration/transformation/Transformations.java new file mode 100644 index 0000000000000000000000000000000000000000..96e8d03bd4a4d43633a94bb251054610ac07315a @@ -3338,14 +3416,15 @@ index 0000000000000000000000000000000000000000..96e8d03bd4a4d43633a94bb251054610 +} 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 -index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799733d66d9 +index 0000000000000000000000000000000000000000..7b984ec88a72a5e2581cb717d1f228b01cffbcda --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/global/LegacyPaperConfig.java -@@ -0,0 +1,223 @@ +@@ -0,0 +1,221 @@ +package io.papermc.paper.configuration.transformation.global; + +import com.mojang.logging.LogUtils; +import io.papermc.paper.configuration.Configuration; ++import java.util.function.Predicate; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.minimessage.MiniMessage; @@ -3353,14 +3432,11 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 +import net.minecraft.network.protocol.game.ServerboundPlaceRecipePacket; +import org.bukkit.ChatColor; +import org.bukkit.configuration.file.YamlConfiguration; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.slf4j.Logger; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.transformation.ConfigurationTransformation; +import org.spongepowered.configurate.transformation.TransformAction; + -+import java.util.function.Predicate; -+ +import static org.spongepowered.configurate.NodePath.path; + +public final class LegacyPaperConfig { @@ -3425,7 +3501,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + .addAction(path("allow-perm-block-break-exploits"), (path, value) -> new Object[]{"settings", "unsupported-settings", "allow-permanent-block-break-exploits"}) + .addAction(path("settings", "unsupported-settings", "allow-tnt-duplication"), TransformAction.rename("allow-piston-duplication")) + .addAction(path("settings", "save-player-data"), (path, value) -> { -+ final @Nullable Object val = value.raw(); ++ final Object val = value.raw(); + if (val instanceof Boolean bool) { + spigotConfiguration.set("players.disable-saving", !bool); + } @@ -3433,7 +3509,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + return null; + }) + .addAction(path("settings", "log-named-entity-deaths"), (path, value) -> { -+ final @Nullable Object val = value.raw(); ++ final Object val = value.raw(); + if (val instanceof Boolean bool && !bool) { + spigotConfiguration.set("settings.log-named-deaths", false); + } @@ -3461,7 +3537,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + .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", "overrides", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> { -+ final @Nullable Object keyValue = value.key(); ++ final Object keyValue = value.key(); + if (keyValue != null && keyValue.toString().equals("PacketPlayInAutoRecipe")) { // add special cast to handle the default for moj-mapped servers that upgrade the config + return path.with(path.size() - 1, ServerboundPlaceRecipePacket.class.getSimpleName()).array(); + } @@ -3520,7 +3596,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + } + private static void miniMessageWithTranslatable(final ConfigurationTransformation.Builder builder, final Predicate<String> englishCheck, final Component component, final String... strPath) { + builder.addAction(path((Object[]) strPath), (path, value) -> { -+ final @Nullable Object val = value.raw(); ++ final Object val = value.raw(); + if (val != null) { + final String strVal = val.toString(); + if (!englishCheck.test(strVal)) { @@ -3535,7 +3611,7 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + + private static void miniMessage(final ConfigurationTransformation.Builder builder, final String... strPath) { + builder.addAction(path((Object[]) strPath), (path, value) -> { -+ final @Nullable Object val = value.raw(); ++ final Object val = value.raw(); + if (val != null) { + value.set(miniMessage(val.toString())); + } @@ -3565,9 +3641,19 @@ index 0000000000000000000000000000000000000000..ef0e834c164b0ccc1a61b349348e6799 + }); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..241101a25821d3e506308ef9d7edb36aecd76232 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/global/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation.global; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/V29_LogIPs.java b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/V29_LogIPs.java new file mode 100644 -index 0000000000000000000000000000000000000000..66073f7a6a96405348cc4044ad1e6922158b13ba +index 0000000000000000000000000000000000000000..bf5de965d26a59f7b4ba5ade3cdab35c37f42be2 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/V29_LogIPs.java @@ -0,0 +1,44 @@ @@ -3576,7 +3662,7 @@ index 0000000000000000000000000000000000000000..66073f7a6a96405348cc4044ad1e6922 +import java.util.Properties; +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.dedicated.DedicatedServer; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.NodePath; @@ -3615,9 +3701,29 @@ index 0000000000000000000000000000000000000000..66073f7a6a96405348cc4044ad1e6922 + } + +} +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d9f90a01e88fb402b796a354bb3419193566b4b5 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/global/versioned/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation.global.versioned; ++ ++import org.jspecify.annotations.NullMarked; +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7a1220c80c3eb4d365dd317958bdca0a6c8321aa +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java b/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java new file mode 100644 -index 0000000000000000000000000000000000000000..cb1f5f65c098470dc8553b015d0f0f29f28ed956 +index 0000000000000000000000000000000000000000..d670865dc9bf75ccc5309222e8af7fc10325c5fb --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/FeatureSeedsGeneration.java @@ -0,0 +1,71 @@ @@ -3633,7 +3739,7 @@ index 0000000000000000000000000000000000000000..cb1f5f65c098470dc8553b015d0f0f29 +import net.minecraft.resources.ResourceLocation; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.level.levelgen.feature.ConfiguredFeature; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.slf4j.Logger; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; @@ -3694,14 +3800,19 @@ index 0000000000000000000000000000000000000000..cb1f5f65c098470dc8553b015d0f0f29 +} diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java b/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java new file mode 100644 -index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71524a54d2 +index 0000000000000000000000000000000000000000..7af8f613ac63f04f01e373ec80747336f744baa4 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/LegacyPaperWorldConfig.java -@@ -0,0 +1,322 @@ +@@ -0,0 +1,320 @@ +package io.papermc.paper.configuration.transformation.world; + +import io.papermc.paper.configuration.Configuration; +import io.papermc.paper.configuration.WorldConfiguration; ++import java.util.HashMap; ++import java.util.List; ++import java.util.Locale; ++import java.util.Map; ++import java.util.Optional; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.BuiltInRegistries; +import net.minecraft.core.registries.Registries; @@ -3710,16 +3821,9 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 +import net.minecraft.world.entity.MobCategory; +import net.minecraft.world.item.Item; +import org.bukkit.Material; -+import org.checkerframework.checker.nullness.qual.Nullable; +import org.spongepowered.configurate.transformation.ConfigurationTransformation; +import org.spongepowered.configurate.transformation.TransformAction; + -+import java.util.HashMap; -+import java.util.List; -+import java.util.Locale; -+import java.util.Map; -+import java.util.Optional; -+ +import static io.papermc.paper.configuration.transformation.Transformations.moveFromRoot; +import static io.papermc.paper.configuration.transformation.Transformations.moveFromRootAndRename; +import static org.spongepowered.configurate.NodePath.path; @@ -3758,14 +3862,14 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + }).build()) + .addVersion(19, ConfigurationTransformation.builder() + .addAction(path("anti-xray", "hidden-blocks"), (path, value) -> { -+ @Nullable final List<String> hiddenBlocks = value.getList(String.class); ++ final List<String> hiddenBlocks = value.getList(String.class); + if (hiddenBlocks != null) { + hiddenBlocks.remove("lit_redstone_ore"); + } + return null; + }) + .addAction(path("anti-xray", "replacement-blocks"), (path, value) -> { -+ @Nullable final List<String> replacementBlocks = value.getList(String.class); ++ final List<String> replacementBlocks = value.getList(String.class); + if (replacementBlocks != null) { + final int index = replacementBlocks.indexOf("planks"); + if (index != -1) { @@ -3838,9 +3942,9 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + value.childrenMap().forEach((key, node) -> { + String itemName = key.toString(); + final Optional<Holder.Reference<Item>> itemHolder = BuiltInRegistries.ITEM.get(ResourceKey.create(Registries.ITEM, ResourceLocation.parse(itemName.toLowerCase(Locale.ROOT)))); -+ final @Nullable String item; ++ final String item; + if (itemHolder.isEmpty()) { -+ final @Nullable Material bukkitMat = Material.matchMaterial(itemName); ++ final Material bukkitMat = Material.matchMaterial(itemName); + item = bukkitMat != null ? bukkitMat.getKey().getKey() : null; + } else { + item = itemHolder.get().unwrapKey().orElseThrow().location().getPath(); @@ -3976,7 +4080,7 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + + builder.addAction(path("feature-seeds", ConfigurationTransformation.WILDCARD_OBJECT), (path, value) -> { + final String key = path.array()[path.size() - 1].toString(); -+ if (!key.equals("generate-random-seeds-for-all")) { ++ if (!"generate-random-seeds-for-all".equals(key)) { + return new Object[]{"feature-seeds", "features", key}; + } + return null; @@ -3994,7 +4098,7 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + }); + + builder.addAction(path("redstone-implementation"), (path, value) -> { -+ if (value.require(String.class).equalsIgnoreCase("alternate-current")) { ++ if ("alternate-current".equalsIgnoreCase(value.require(String.class))) { + value.set("alternate_current"); + } + return new Object[]{"misc", "redstone-implementation"}; @@ -4020,16 +4124,26 @@ index 0000000000000000000000000000000000000000..77e530830dc8ebc861b2e70f787f9b71 + moveFromRootAndRename(builder, path("game-mechanics", oldKey), newKey, parents); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0db4d187f780a0cf90c9c2936d1f33415d004137 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/world/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation.world; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V29_ZeroWorldHeight.java b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V29_ZeroWorldHeight.java new file mode 100644 -index 0000000000000000000000000000000000000000..6e481d509d091e65a4909d79014ac94ea63c8455 +index 0000000000000000000000000000000000000000..a1e8ce5407f2c5f188b2ce2d768512d3d42ad64b --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V29_ZeroWorldHeight.java @@ -0,0 +1,49 @@ +package io.papermc.paper.configuration.transformation.world.versioned; + +import io.papermc.paper.configuration.type.number.IntOr; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.ConfigurateException; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.NodePath; @@ -4108,7 +4222,7 @@ index 0000000000000000000000000000000000000000..d08b65234192d5b639cead675114f64b +} diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V31_SpawnLoadedRangeToGameRule.java b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V31_SpawnLoadedRangeToGameRule.java new file mode 100644 -index 0000000000000000000000000000000000000000..d872b1948df52759fed9c3d892aed6abfdfc8068 +index 0000000000000000000000000000000000000000..cb05980256f20df7b3c30e33eaa2c3185f2a38f8 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/V31_SpawnLoadedRangeToGameRule.java @@ -0,0 +1,55 @@ @@ -4116,7 +4230,7 @@ index 0000000000000000000000000000000000000000..d872b1948df52759fed9c3d892aed6ab + +import io.papermc.paper.configuration.Configurations; +import net.minecraft.world.level.GameRules; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.NodePath; +import org.spongepowered.configurate.transformation.ConfigurationTransformation; @@ -4167,22 +4281,31 @@ index 0000000000000000000000000000000000000000..d872b1948df52759fed9c3d892aed6ab + } + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..087aa63ae612aaabf4c161c56c78d47ef5b591d3 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/transformation/world/versioned/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.transformation.world.versioned; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/type/BooleanOrDefault.java b/src/main/java/io/papermc/paper/configuration/type/BooleanOrDefault.java new file mode 100644 -index 0000000000000000000000000000000000000000..a3eaa47cfcfc4fd2a607f9b375230fada35620d3 +index 0000000000000000000000000000000000000000..1e73f51b7f6d06a1e86b150b001f90dd179b8ec8 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/type/BooleanOrDefault.java -@@ -0,0 +1,53 @@ +@@ -0,0 +1,52 @@ +package io.papermc.paper.configuration.type; + -+import org.apache.commons.lang3.BooleanUtils; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.Locale; +import java.util.function.Predicate; ++import org.apache.commons.lang3.BooleanUtils; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +public record BooleanOrDefault(@Nullable Boolean value) { + private static final String DEFAULT_VALUE = "default"; @@ -4217,7 +4340,7 @@ index 0000000000000000000000000000000000000000..a3eaa47cfcfc4fd2a607f9b375230fad + + @Override + protected Object serialize(BooleanOrDefault item, Predicate<Class<?>> typeSupported) { -+ final @Nullable Boolean value = item.value; ++ final Boolean value = item.value; + if (value != null) { + return value.toString(); + } else { @@ -4228,7 +4351,7 @@ index 0000000000000000000000000000000000000000..a3eaa47cfcfc4fd2a607f9b375230fad +} diff --git a/src/main/java/io/papermc/paper/configuration/type/DespawnRange.java b/src/main/java/io/papermc/paper/configuration/type/DespawnRange.java new file mode 100644 -index 0000000000000000000000000000000000000000..8a792a000e924b3ddc572edc788598811e9ef71c +index 0000000000000000000000000000000000000000..7779edcbbce36d7da177a92807dac73fbe24c9fa --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/type/DespawnRange.java @@ -0,0 +1,109 @@ @@ -4236,7 +4359,7 @@ index 0000000000000000000000000000000000000000..8a792a000e924b3ddc572edc78859881 + +import io.papermc.paper.configuration.type.number.IntOr; +import java.lang.reflect.Type; -+import org.checkerframework.checker.nullness.qual.Nullable; ++import org.jspecify.annotations.Nullable; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.serialize.SerializationException; +import org.spongepowered.configurate.serialize.TypeSerializer; @@ -4343,26 +4466,25 @@ index 0000000000000000000000000000000000000000..8a792a000e924b3ddc572edc78859881 +} diff --git a/src/main/java/io/papermc/paper/configuration/type/Duration.java b/src/main/java/io/papermc/paper/configuration/type/Duration.java new file mode 100644 -index 0000000000000000000000000000000000000000..422ccb0b332b3e94be228b9b94f379467d6461a5 +index 0000000000000000000000000000000000000000..ad1c77388da868b61d99dd8d7ab272bf6f7142a9 --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/type/Duration.java -@@ -0,0 +1,97 @@ +@@ -0,0 +1,96 @@ +package io.papermc.paper.configuration.type; + -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.Objects; +import java.util.function.Predicate; +import java.util.regex.Pattern; ++import org.jspecify.annotations.Nullable; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +public final class Duration { + + private static final Pattern SPACE = Pattern.compile(" "); + private static final Pattern NOT_NUMERIC = Pattern.compile("[^-\\d.]"); -+ public static final Serializer SERIALIZER = new Serializer(); ++ public static final ScalarSerializer<Duration> SERIALIZER = new Serializer(); + + private final long seconds; + private final String value; @@ -4746,23 +4868,21 @@ index 0000000000000000000000000000000000000000..a3a1d398d783c37914fb6d646e11361a +} diff --git a/src/main/java/io/papermc/paper/configuration/type/fallback/FallbackValueSerializer.java b/src/main/java/io/papermc/paper/configuration/type/fallback/FallbackValueSerializer.java new file mode 100644 -index 0000000000000000000000000000000000000000..8d0fcd038e12c70a3a5aaf2669452589d9055255 +index 0000000000000000000000000000000000000000..8def3c63b146905df287779cbe2502ff89ecd4bd --- /dev/null +++ b/src/main/java/io/papermc/paper/configuration/type/fallback/FallbackValueSerializer.java -@@ -0,0 +1,55 @@ +@@ -0,0 +1,53 @@ +package io.papermc.paper.configuration.type.fallback; + -+import net.minecraft.server.MinecraftServer; -+import org.checkerframework.checker.nullness.qual.Nullable; -+import org.spigotmc.SpigotWorldConfig; -+import org.spongepowered.configurate.serialize.ScalarSerializer; -+import org.spongepowered.configurate.serialize.SerializationException; -+ +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Map; +import java.util.function.Predicate; +import java.util.function.Supplier; ++import net.minecraft.server.MinecraftServer; ++import org.spigotmc.SpigotWorldConfig; ++import org.spongepowered.configurate.serialize.ScalarSerializer; ++import org.spongepowered.configurate.serialize.SerializationException; + +import static io.leangen.geantyref.GenericTypeReflector.erase; + @@ -4789,7 +4909,7 @@ index 0000000000000000000000000000000000000000..8d0fcd038e12c70a3a5aaf2669452589 + + @Override + public FallbackValue deserialize(Type type, Object obj) throws SerializationException { -+ final @Nullable FallbackCreator<?> creator = REGISTRY.get(erase(type)); ++ final FallbackCreator<?> creator = REGISTRY.get(erase(type)); + if (creator == null) { + throw new SerializationException(type + " does not have a FallbackCreator registered"); + } @@ -4821,6 +4941,16 @@ index 0000000000000000000000000000000000000000..70cc7b45e7355f6c8476a74a070f1266 + return value < 0 ? OptionalInt.empty() : OptionalInt.of(value); + } +} +diff --git a/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java b/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7daf9e0ec8f35b68373d4f025ec2366ab110e22e +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/type/fallback/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.type.fallback; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/io/papermc/paper/configuration/type/number/BelowZeroToEmpty.java b/src/main/java/io/papermc/paper/configuration/type/number/BelowZeroToEmpty.java new file mode 100644 index 0000000000000000000000000000000000000000..31068170086aeac51a2adb952b19672e875ba528 @@ -5073,6 +5203,26 @@ index 0000000000000000000000000000000000000000..614aba60bb07946a144650fd3aedb316 + + protected abstract boolean belowZero(O value); +} +diff --git a/src/main/java/io/papermc/paper/configuration/type/number/package-info.java b/src/main/java/io/papermc/paper/configuration/type/number/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a1e8c3a3922aea672bc75c810496718ea3acfe0a +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/type/number/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.type.number; ++ ++import org.jspecify.annotations.NullMarked; +diff --git a/src/main/java/io/papermc/paper/configuration/type/package-info.java b/src/main/java/io/papermc/paper/configuration/type/package-info.java +new file mode 100644 +index 0000000000000000000000000000000000000000..af8bcae3fb6aeb75350d0783599582d0d0cd3912 +--- /dev/null ++++ b/src/main/java/io/papermc/paper/configuration/type/package-info.java +@@ -0,0 +1,4 @@ ++@NullMarked ++package io.papermc.paper.configuration.type; ++ ++import org.jspecify.annotations.NullMarked; diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java index fc5c42e77a76b0ca946b13435144584b9c4bfafa..9bd6056bba6ba48bada7e9cd5883b0a171b0bbc4 100644 --- a/src/main/java/net/minecraft/server/Main.java @@ -5226,7 +5376,7 @@ index 9cf0c141fefe67893828e300cba4f8a8545ba25f..c8e49c1904c80c4ede40ca5c26efad9b this.world = new CraftWorld((ServerLevel) this, gen, biomeProvider, env); diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java -index 60805f6a2badca9b9cdfa54a9273ceba6311b16c..6c8a69b7c1b45549b2c388a8df2258184c587309 100644 +index 46b067fdfbbdeb3c0005b37d24ae248ec2d6bb90..d5451cb1976ca3675dd19b07bd8a2d363f82db86 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -967,6 +967,7 @@ public final class CraftServer implements Server { @@ -5238,7 +5388,7 @@ index 60805f6a2badca9b9cdfa54a9273ceba6311b16c..6c8a69b7c1b45549b2c388a8df225818 world.serverLevelData.setDifficulty(config.difficulty); world.setSpawnSettings(config.spawnMonsters); diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java -index 17e10c4373b4281cc74b748c4a1e173e36eb9196..755b1d77418ecae0dc9ec5197275d0cd914e7bee 100644 +index 5e75839c0620f94e5b58942c984938e564d3b936..3ee69736494467aa6a1450baf868e73c94733e5b 100644 --- a/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/src/main/java/org/bukkit/craftbukkit/Main.java @@ -142,6 +142,19 @@ public class Main { diff --git a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch index 047ec2d29f..d04608c8b2 100644 --- a/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch +++ b/patches/server/0022-Remap-reflection-calls-in-plugins-using-internals.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Remap reflection calls in plugins using internals Co-authored-by: Jason Penilla <[email protected]> diff --git a/build.gradle.kts b/build.gradle.kts -index 24f3d0c96fe9d70b1a7cf528e09ebfc4366577ed..7aee6d9849f0a9c64db0368d2faa03c0633a72a4 100644 +index 8678e5bd59a7e085cb1b4e38f29e06ce36d2c1de..8d05216e246bfaec5945cdd55d08b6a388a769e8 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -62,6 +62,12 @@ dependencies { @@ -23,7 +23,7 @@ index 24f3d0c96fe9d70b1a7cf528e09ebfc4366577ed..7aee6d9849f0a9c64db0368d2faa03c0 paperweight { diff --git a/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java -index 893ad5e7c2d32ccd64962d95d146bbd317c28ab8..3d73ea0e63c97b2b08e719b7be7af3894fb2d4e8 100644 +index b61935052154e76b1b8cb49868c96c52f34a41d1..a2fe12513b93ded71517955ef3e52c925f56f7d1 100644 --- a/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java +++ b/src/main/java/io/papermc/paper/configuration/serializer/PacketClassSerializer.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableBiMap; @@ -32,9 +32,9 @@ index 893ad5e7c2d32ccd64962d95d146bbd317c28ab8..3d73ea0e63c97b2b08e719b7be7af389 import io.papermc.paper.configuration.serializer.collections.MapSerializer; +import io.papermc.paper.util.MappingEnvironment; import io.papermc.paper.util.ObfHelper; - import net.minecraft.network.protocol.Packet; - import org.checkerframework.checker.nullness.qual.Nullable; -@@ -69,7 +70,7 @@ public final class PacketClassSerializer extends ScalarSerializer<Class<? extend + import java.lang.reflect.Type; + import java.util.List; +@@ -68,7 +69,7 @@ public final class PacketClassSerializer extends ScalarSerializer<Class<? extend @Override protected @Nullable Object serialize(final Class<? extends Packet<?>> packetClass, final Predicate<Class<?>> typeSupported) { final String name = packetClass.getName(); diff --git a/patches/server/0928-Add-onboarding-message-for-initial-server-start.patch b/patches/server/0928-Add-onboarding-message-for-initial-server-start.patch index 64a7380197..b9d8134356 100644 --- a/patches/server/0928-Add-onboarding-message-for-initial-server-start.patch +++ b/patches/server/0928-Add-onboarding-message-for-initial-server-start.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Add onboarding message for initial server start diff --git a/src/main/java/io/papermc/paper/configuration/Configurations.java b/src/main/java/io/papermc/paper/configuration/Configurations.java -index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e28585773 100644 +index 007e01d329a31acf7f4ed4c6dc4de7ad54ccad04..8cf720f08514e8e4f62f4ad196f1277bd761c6b2 100644 --- a/src/main/java/io/papermc/paper/configuration/Configurations.java +++ b/src/main/java/io/papermc/paper/configuration/Configurations.java -@@ -129,6 +129,7 @@ public abstract class Configurations<G, W> { +@@ -127,6 +127,7 @@ public abstract class Configurations<G, W> { if (Files.notExists(configFile)) { node = CommentedConfigurationNode.root(loader.defaultOptions()); node.node(Configuration.VERSION_FIELD).raw(this.globalConfigVersion()); @@ -17,7 +17,7 @@ index d9502ba028a96f9cc846f9ed428bd8066b857ca3..87e5f614ba988547a827486740db217e node = loader.load(); this.verifyGlobalConfigVersion(node); diff --git a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java -index 56798215644d8bca1695856b3a941e8089f49e48..46c37c8db8ecf3cc808fcf59f6bee5fe6ca49b75 100644 +index e0cef37664b64f5db95943c5c118424436163e06..5e9c471ab20b0391e7e41351c65d96745fc8ce4a 100644 --- a/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java +++ b/src/main/java/io/papermc/paper/configuration/GlobalConfiguration.java @@ -25,6 +25,7 @@ public class GlobalConfiguration extends ConfigurationPart { diff --git a/patches/server/1070-Configurable-Entity-Despawn-Time.patch b/patches/server/1070-Configurable-Entity-Despawn-Time.patch new file mode 100644 index 0000000000..9f3d4aa488 --- /dev/null +++ b/patches/server/1070-Configurable-Entity-Despawn-Time.patch @@ -0,0 +1,39 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Kevin Raneri <[email protected]> +Date: Mon, 30 Sep 2024 09:50:55 -0700 +Subject: [PATCH] Configurable Entity Despawn Time + + +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index 8be1b051543cda2b2e9e3d337834757e53f442de..ed5b00620527c1776722d25b1b45f1544802a341 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -432,6 +432,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + private UUID originWorld; + public boolean freezeLocked = false; // Paper - Freeze Tick Lock API + public boolean fixedPose = false; // Paper - Expand Pose API ++ private final int despawnTime; // Paper - entity despawn time limit + + public void setOrigin(@javax.annotation.Nonnull Location location) { + this.origin = location.toVector(); +@@ -614,6 +615,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + + public Entity(EntityType<?> type, Level world) { + this.id = Entity.ENTITY_COUNTER.incrementAndGet(); ++ this.despawnTime = type == EntityType.PLAYER ? -1 : world.paperConfig().entities.spawning.despawnTime.getOrDefault(type, io.papermc.paper.configuration.type.number.IntOr.Disabled.DISABLED).or(-1); // Paper - entity despawn time limit + this.passengers = ImmutableList.of(); + this.deltaMovement = Vec3.ZERO; + this.bb = Entity.INITIAL_AABB; +@@ -912,6 +914,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + } + + public void tick() { ++ // Paper start - entity despawn time limit ++ if (this.despawnTime >= 0 && this.tickCount >= this.despawnTime) { ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); ++ return; ++ } ++ // Paper end - entity despawn time limit + this.baseTick(); + } + |