|
|
|
@ -131,6 +131,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+import io.leangen.geantyref.TypeToken;
|
|
|
|
|
+import io.papermc.paper.configuration.constraint.Constraint;
|
|
|
|
|
+import io.papermc.paper.configuration.constraint.Constraints;
|
|
|
|
|
+import net.minecraft.core.RegistryAccess;
|
|
|
|
|
+import net.minecraft.resources.ResourceLocation;
|
|
|
|
|
+import net.minecraft.server.level.ServerLevel;
|
|
|
|
|
+import org.checkerframework.checker.nullness.qual.Nullable;
|
|
|
|
@ -196,6 +197,10 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+
|
|
|
|
|
+ protected abstract boolean isConfigType(final Type type);
|
|
|
|
|
+
|
|
|
|
|
+ protected abstract int globalConfigVersion();
|
|
|
|
|
+
|
|
|
|
|
+ protected abstract int worldConfigVersion();
|
|
|
|
|
+
|
|
|
|
|
+ protected ObjectMapper.Factory.Builder createGlobalObjectMapperFactoryBuilder() {
|
|
|
|
|
+ return this.createObjectMapper();
|
|
|
|
|
+ }
|
|
|
|
@ -224,7 +229,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ };
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public G initializeGlobalConfiguration() throws ConfigurateException {
|
|
|
|
|
+ public G initializeGlobalConfiguration(final RegistryAccess registryAccess) throws ConfigurateException {
|
|
|
|
|
+ return this.initializeGlobalConfiguration(creator(this.globalConfigClass, true));
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
@ -245,10 +250,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ .path(configFile)
|
|
|
|
|
+ .build();
|
|
|
|
|
+ final ConfigurationNode node;
|
|
|
|
|
+ if (Files.exists(configFile)) {
|
|
|
|
|
+ node = loader.load();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (Files.notExists(configFile)) {
|
|
|
|
|
+ node = CommentedConfigurationNode.root(loader.defaultOptions());
|
|
|
|
|
+ node.node(Configuration.VERSION_FIELD).raw(this.globalConfigVersion());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ node = loader.load();
|
|
|
|
|
+ this.verifyGlobalConfigVersion(node);
|
|
|
|
|
+ }
|
|
|
|
|
+ this.applyGlobalConfigTransformations(node);
|
|
|
|
|
+ final G instance = creator.apply(node);
|
|
|
|
@ -256,18 +263,29 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ return instance;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected void verifyGlobalConfigVersion(final ConfigurationNode globalNode) {
|
|
|
|
|
+ final ConfigurationNode version = globalNode.node(Configuration.VERSION_FIELD);
|
|
|
|
|
+ if (version.virtual()) {
|
|
|
|
|
+ LOGGER.warn("The global config file didn't have a version set, assuming latest");
|
|
|
|
|
+ version.raw(this.globalConfigVersion());
|
|
|
|
|
+ } else if (version.getInt() > this.globalConfigVersion()) {
|
|
|
|
|
+ LOGGER.error("Loading a newer configuration than is supported ({} > {})! You may have to backup & delete your global config file to start the server.", version.getInt(), this.globalConfigVersion());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected void applyGlobalConfigTransformations(final ConfigurationNode node) throws ConfigurateException {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @MustBeInvokedByOverriders
|
|
|
|
|
+ protected ContextMap.Builder createDefaultContextMap() {
|
|
|
|
|
+ protected ContextMap.Builder createDefaultContextMap(final RegistryAccess registryAccess) {
|
|
|
|
|
+ return ContextMap.builder()
|
|
|
|
|
+ .put(WORLD_NAME, WORLD_DEFAULTS)
|
|
|
|
|
+ .put(WORLD_KEY, WORLD_DEFAULTS_KEY);
|
|
|
|
|
+ .put(WORLD_KEY, WORLD_DEFAULTS_KEY)
|
|
|
|
|
+ .put(REGISTRY_ACCESS, registryAccess);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public void initializeWorldDefaultsConfiguration() throws ConfigurateException {
|
|
|
|
|
+ final ContextMap contextMap = this.createDefaultContextMap()
|
|
|
|
|
+ public void initializeWorldDefaultsConfiguration(final RegistryAccess registryAccess) throws ConfigurateException {
|
|
|
|
|
+ final ContextMap contextMap = this.createDefaultContextMap(registryAccess)
|
|
|
|
|
+ .put(FIRST_DEFAULT)
|
|
|
|
|
+ .build();
|
|
|
|
|
+ final Path configFile = this.globalFolder.resolve(this.defaultWorldConfigFileName);
|
|
|
|
@ -275,7 +293,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ final YamlConfigurationLoader loader = result.loader();
|
|
|
|
|
+ final ConfigurationNode node = loader.load();
|
|
|
|
|
+ if (result.isNewFile()) { // add version to new files
|
|
|
|
|
+ node.node(Configuration.VERSION_FIELD).raw(WorldConfiguration.CURRENT_VERSION);
|
|
|
|
|
+ node.node(Configuration.VERSION_FIELD).raw(this.worldConfigVersion());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.verifyWorldConfigVersion(contextMap, node);
|
|
|
|
|
+ }
|
|
|
|
|
+ this.applyWorldConfigTransformations(contextMap, node);
|
|
|
|
|
+ final W instance = node.require(this.worldConfigClass);
|
|
|
|
@ -316,7 +336,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+
|
|
|
|
|
+ protected W createWorldConfig(final ContextMap contextMap, final CheckedFunction<ConfigurationNode, W, SerializationException> creator) throws IOException {
|
|
|
|
|
+ final Path defaultsConfigFile = this.globalFolder.resolve(this.defaultWorldConfigFileName);
|
|
|
|
|
+ final YamlConfigurationLoader defaultsLoader = this.createDefaultWorldLoader(true, this.createDefaultContextMap().build(), defaultsConfigFile).loader();
|
|
|
|
|
+ final YamlConfigurationLoader defaultsLoader = this.createDefaultWorldLoader(true, this.createDefaultContextMap(contextMap.require(REGISTRY_ACCESS)).build(), defaultsConfigFile).loader();
|
|
|
|
|
+ final ConfigurationNode defaultsNode = defaultsLoader.load();
|
|
|
|
|
+
|
|
|
|
|
+ boolean newFile = false;
|
|
|
|
@ -334,7 +354,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ .build();
|
|
|
|
|
+ final ConfigurationNode worldNode = worldLoader.load();
|
|
|
|
|
+ if (newFile) { // set the version field if new file
|
|
|
|
|
+ worldNode.node(Configuration.VERSION_FIELD).set(WorldConfiguration.CURRENT_VERSION);
|
|
|
|
|
+ worldNode.node(Configuration.VERSION_FIELD).set(this.worldConfigVersion());
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.verifyWorldConfigVersion(contextMap, worldNode);
|
|
|
|
|
+ }
|
|
|
|
|
+ this.applyWorldConfigTransformations(contextMap, worldNode);
|
|
|
|
|
+ this.applyDefaultsAwareWorldConfigTransformations(contextMap, worldNode, defaultsNode);
|
|
|
|
@ -343,6 +365,27 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ return creator.apply(worldNode);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected void verifyWorldConfigVersion(final ContextMap contextMap, final ConfigurationNode worldNode) {
|
|
|
|
|
+ final ConfigurationNode version = worldNode.node(Configuration.VERSION_FIELD);
|
|
|
|
|
+ final String worldName = contextMap.require(WORLD_NAME);
|
|
|
|
|
+ if (version.virtual()) {
|
|
|
|
|
+ if (worldName.equals(WORLD_DEFAULTS)) {
|
|
|
|
|
+ LOGGER.warn("The world defaults config file didn't have a version set, assuming latest");
|
|
|
|
|
+ } else {
|
|
|
|
|
+ LOGGER.warn("The world config file for " + worldName + " didn't have a version set, assuming latest");
|
|
|
|
|
+ }
|
|
|
|
|
+ version.raw(this.worldConfigVersion());
|
|
|
|
|
+ } else if (version.getInt() > this.worldConfigVersion()) {
|
|
|
|
|
+ String msg = "Loading a newer configuration than is supported ({} > {})! ";
|
|
|
|
|
+ if (worldName.equals(WORLD_DEFAULTS)) {
|
|
|
|
|
+ msg += "You may have to backup & delete the world defaults config file to start the server.";
|
|
|
|
|
+ } else {
|
|
|
|
|
+ msg += "You may have to backup & delete the " + worldName + " config file to start the server.";
|
|
|
|
|
+ }
|
|
|
|
|
+ LOGGER.error(msg, version.getInt(), this.worldConfigVersion());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected void applyWorldConfigTransformations(final ContextMap contextMap, final ConfigurationNode node) throws ConfigurateException {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
@ -423,6 +466,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ public static final ContextKey<String> WORLD_NAME = new ContextKey<>(String.class, "world name"); // TODO remove when we deprecate level names
|
|
|
|
|
+ public static final ContextKey<ResourceLocation> WORLD_KEY = new ContextKey<>(ResourceLocation.class, "world key");
|
|
|
|
|
+ public static final ContextKey<Void> FIRST_DEFAULT = new ContextKey<>(Void.class, "first default");
|
|
|
|
|
+ public static final ContextKey<RegistryAccess> REGISTRY_ACCESS = new ContextKey<>(RegistryAccess.class, "registry access");
|
|
|
|
|
+
|
|
|
|
|
+ public record ContextKey<T>(TypeToken<T> type, String name) {
|
|
|
|
|
+
|
|
|
|
@ -824,9 +868,9 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+import io.papermc.paper.configuration.type.Duration;
|
|
|
|
|
+import io.papermc.paper.configuration.type.DurationOrDisabled;
|
|
|
|
|
+import io.papermc.paper.configuration.type.EngineMode;
|
|
|
|
|
+import io.papermc.paper.configuration.type.fallback.FallbackValueSerializer;
|
|
|
|
|
+import io.papermc.paper.configuration.type.number.DoubleOr;
|
|
|
|
|
+import io.papermc.paper.configuration.type.number.IntOr;
|
|
|
|
|
+import io.papermc.paper.configuration.type.fallback.FallbackValueSerializer;
|
|
|
|
|
+import it.unimi.dsi.fastutil.objects.Reference2IntMap;
|
|
|
|
|
+import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
|
|
|
|
|
+import it.unimi.dsi.fastutil.objects.Reference2LongMap;
|
|
|
|
@ -840,12 +884,14 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.function.Function;
|
|
|
|
|
+import java.util.function.Supplier;
|
|
|
|
|
+import net.minecraft.core.RegistryAccess;
|
|
|
|
|
+import net.minecraft.core.registries.Registries;
|
|
|
|
|
+import net.minecraft.resources.ResourceLocation;
|
|
|
|
|
+import net.minecraft.server.MinecraftServer;
|
|
|
|
|
+import net.minecraft.server.level.ServerLevel;
|
|
|
|
|
+import net.minecraft.world.entity.EntityType;
|
|
|
|
|
+import net.minecraft.world.item.Item;
|
|
|
|
|
+import net.minecraft.world.level.block.Block;
|
|
|
|
|
+import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
|
|
|
|
+import org.apache.commons.lang3.RandomStringUtils;
|
|
|
|
|
+import org.bukkit.configuration.ConfigurationSection;
|
|
|
|
@ -941,6 +987,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int globalConfigVersion() {
|
|
|
|
|
+ return GlobalConfiguration.CURRENT_VERSION;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected int worldConfigVersion() {
|
|
|
|
|
+ return WorldConfiguration.CURRENT_VERSION;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected YamlConfigurationLoader.Builder createLoaderBuilder() {
|
|
|
|
|
+ return super.createLoaderBuilder()
|
|
|
|
|
+ .defaultOptions(PaperConfigurations::defaultOptions);
|
|
|
|
@ -979,15 +1035,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public GlobalConfiguration initializeGlobalConfiguration() throws ConfigurateException {
|
|
|
|
|
+ GlobalConfiguration configuration = super.initializeGlobalConfiguration();
|
|
|
|
|
+ public GlobalConfiguration initializeGlobalConfiguration(final RegistryAccess registryAccess) throws ConfigurateException {
|
|
|
|
|
+ GlobalConfiguration configuration = super.initializeGlobalConfiguration(registryAccess);
|
|
|
|
|
+ GlobalConfiguration.set(configuration);
|
|
|
|
|
+ return configuration;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected ContextMap.Builder createDefaultContextMap() {
|
|
|
|
|
+ return super.createDefaultContextMap()
|
|
|
|
|
+ protected ContextMap.Builder createDefaultContextMap(final RegistryAccess registryAccess) {
|
|
|
|
|
+ return super.createDefaultContextMap(registryAccess)
|
|
|
|
|
+ .put(SPIGOT_WORLD_CONFIG_CONTEXT_KEY, SPIGOT_WORLD_DEFAULTS);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
@ -1008,6 +1064,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected YamlConfigurationLoader.Builder createWorldConfigLoaderBuilder(final ContextMap contextMap) {
|
|
|
|
|
+ final RegistryAccess access = contextMap.require(REGISTRY_ACCESS);
|
|
|
|
|
+ return super.createWorldConfigLoaderBuilder(contextMap)
|
|
|
|
|
+ .defaultOptions(options -> options
|
|
|
|
|
+ .header(contextMap.require(WORLD_NAME).equals(WORLD_DEFAULTS) ? WORLD_DEFAULTS_HEADER : WORLD_HEADER.apply(contextMap))
|
|
|
|
@ -1025,22 +1082,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ .register(EngineMode.SERIALIZER)
|
|
|
|
|
+ .register(NbtPathSerializer.SERIALIZER)
|
|
|
|
|
+ .register(FallbackValueSerializer.create(contextMap.require(SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get(), MinecraftServer::getServer))
|
|
|
|
|
+ .register(new RegistryValueSerializer<>(new TypeToken<EntityType<?>>() {}, Registries.ENTITY_TYPE, true))
|
|
|
|
|
+ .register(new RegistryValueSerializer<>(Item.class, Registries.ITEM, true))
|
|
|
|
|
+ .register(new RegistryHolderSerializer<>(new TypeToken<ConfiguredFeature<?, ?>>() {}, Registries.CONFIGURED_FEATURE, false))
|
|
|
|
|
+ .register(new RegistryHolderSerializer<>(Item.class, Registries.ITEM, true))
|
|
|
|
|
+ .register(new RegistryValueSerializer<>(new TypeToken<EntityType<?>>() {}, access, Registries.ENTITY_TYPE, true))
|
|
|
|
|
+ .register(new RegistryValueSerializer<>(Item.class, access, Registries.ITEM, true))
|
|
|
|
|
+ .register(new RegistryValueSerializer<>(Block.class, access, Registries.BLOCK, true))
|
|
|
|
|
+ .register(new RegistryHolderSerializer<>(new TypeToken<ConfiguredFeature<?, ?>>() {}, access, Registries.CONFIGURED_FEATURE, false))
|
|
|
|
|
+ )
|
|
|
|
|
+ );
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
|
+ protected void applyWorldConfigTransformations(final ContextMap contextMap, final ConfigurationNode node) throws ConfigurateException {
|
|
|
|
|
+ final ConfigurationNode version = node.node(Configuration.VERSION_FIELD);
|
|
|
|
|
+ final String world = contextMap.require(WORLD_NAME);
|
|
|
|
|
+ if (version.virtual()) {
|
|
|
|
|
+ LOGGER.warn("The world config file for " + world + " didn't have a version set, assuming latest");
|
|
|
|
|
+ version.raw(WorldConfiguration.CURRENT_VERSION);
|
|
|
|
|
+ }
|
|
|
|
|
+ ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder();
|
|
|
|
|
+ for (NodePath path : RemovedConfigurations.REMOVED_WORLD_PATHS) {
|
|
|
|
|
+ builder.addAction(path, TransformAction.remove());
|
|
|
|
@ -1103,7 +1154,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ public void reloadConfigs(MinecraftServer server) {
|
|
|
|
|
+ try {
|
|
|
|
|
+ this.initializeGlobalConfiguration(reloader(this.globalConfigClass, GlobalConfiguration.get()));
|
|
|
|
|
+ this.initializeWorldDefaultsConfiguration();
|
|
|
|
|
+ this.initializeWorldDefaultsConfiguration(server.registryAccess());
|
|
|
|
|
+ for (ServerLevel level : server.getAllLevels()) {
|
|
|
|
|
+ this.createWorldConfig(createWorldContextMap(level), reloader(this.worldConfigClass, level.paperConfig()));
|
|
|
|
|
+ }
|
|
|
|
@ -1113,15 +1164,16 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ private static ContextMap createWorldContextMap(ServerLevel level) {
|
|
|
|
|
+ return createWorldContextMap(level.convertable.levelDirectory.path(), level.serverLevelData.getLevelName(), level.dimension().location(), level.spigotConfig);
|
|
|
|
|
+ return createWorldContextMap(level.convertable.levelDirectory.path(), level.serverLevelData.getLevelName(), level.dimension().location(), level.spigotConfig, level.registryAccess());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public static ContextMap createWorldContextMap(Path dir, String levelName, ResourceLocation worldKey, SpigotWorldConfig spigotConfig) {
|
|
|
|
|
+ public static ContextMap createWorldContextMap(Path dir, String levelName, ResourceLocation worldKey, SpigotWorldConfig spigotConfig, RegistryAccess registryAccess) {
|
|
|
|
|
+ return ContextMap.builder()
|
|
|
|
|
+ .put(WORLD_DIRECTORY, dir)
|
|
|
|
|
+ .put(WORLD_NAME, levelName)
|
|
|
|
|
+ .put(WORLD_KEY, worldKey)
|
|
|
|
|
+ .put(SPIGOT_WORLD_CONFIG_CONTEXT_KEY, Suppliers.ofInstance(spigotConfig))
|
|
|
|
|
+ .put(REGISTRY_ACCESS, registryAccess)
|
|
|
|
|
+ .build();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
@ -1367,6 +1419,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+import it.unimi.dsi.fastutil.objects.Reference2LongMap;
|
|
|
|
|
+import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap;
|
|
|
|
|
+import java.util.Arrays;
|
|
|
|
|
+import java.util.IdentityHashMap;
|
|
|
|
|
+import java.util.List;
|
|
|
|
|
+import java.util.Map;
|
|
|
|
|
+import java.util.function.Function;
|
|
|
|
@ -1384,8 +1437,6 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+import net.minecraft.world.entity.MobCategory;
|
|
|
|
|
+import net.minecraft.world.entity.boss.enderdragon.EnderDragon;
|
|
|
|
|
+import net.minecraft.world.entity.decoration.HangingEntity;
|
|
|
|
|
+import net.minecraft.world.entity.decoration.ItemFrame;
|
|
|
|
|
+import net.minecraft.world.entity.decoration.Painting;
|
|
|
|
|
+import net.minecraft.world.entity.item.ItemEntity;
|
|
|
|
|
+import net.minecraft.world.entity.monster.Vindicator;
|
|
|
|
|
+import net.minecraft.world.entity.monster.Zombie;
|
|
|
|
@ -1393,10 +1444,11 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+import net.minecraft.world.item.Item;
|
|
|
|
|
+import net.minecraft.world.item.Items;
|
|
|
|
|
+import net.minecraft.world.level.NaturalSpawner;
|
|
|
|
|
+import net.minecraft.world.level.block.Block;
|
|
|
|
|
+import net.minecraft.world.level.block.Blocks;
|
|
|
|
|
+import net.minecraft.world.level.levelgen.feature.ConfiguredFeature;
|
|
|
|
|
+import org.slf4j.Logger;
|
|
|
|
|
+import org.spigotmc.SpigotWorldConfig;
|
|
|
|
|
+import org.spigotmc.TrackingRange;
|
|
|
|
|
+import org.spongepowered.configurate.objectmapping.ConfigSerializable;
|
|
|
|
|
+import org.spongepowered.configurate.objectmapping.meta.PostProcess;
|
|
|
|
|
+import org.spongepowered.configurate.objectmapping.meta.Required;
|
|
|
|
@ -1445,10 +1497,34 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ public int updateRadius = 2;
|
|
|
|
|
+ public boolean lavaObscures = false;
|
|
|
|
|
+ public boolean usePermission = false;
|
|
|
|
|
+ public List<String> hiddenBlocks = List.of("copper_ore", "deepslate_copper_ore", "raw_copper_block", "gold_ore", "deepslate_gold_ore", "iron_ore", "deepslate_iron_ore", "raw_iron_block",
|
|
|
|
|
+ "coal_ore", "deepslate_coal_ore", "lapis_ore", "deepslate_lapis_ore", "mossy_cobblestone", "obsidian", "chest", "diamond_ore", "deepslate_diamond_ore",
|
|
|
|
|
+ "redstone_ore", "deepslate_redstone_ore", "clay", "emerald_ore", "deepslate_emerald_ore", "ender_chest"); // TODO update type to List<Block>
|
|
|
|
|
+ public List<String> replacementBlocks = List.of("stone", "oak_planks", "deepslate"); // TODO update type to List<Block>
|
|
|
|
|
+ public List<Block> hiddenBlocks = List.of(
|
|
|
|
|
+ //<editor-fold desc="Anti-Xray Hidden Blocks" defaultstate="collapsed">
|
|
|
|
|
+ Blocks.COPPER_ORE,
|
|
|
|
|
+ Blocks.DEEPSLATE_COPPER_ORE,
|
|
|
|
|
+ Blocks.RAW_COPPER_BLOCK,
|
|
|
|
|
+ Blocks.GOLD_ORE,
|
|
|
|
|
+ Blocks.DEEPSLATE_GOLD_ORE,
|
|
|
|
|
+ Blocks.IRON_ORE,
|
|
|
|
|
+ Blocks.DEEPSLATE_IRON_ORE,
|
|
|
|
|
+ Blocks.RAW_IRON_BLOCK,
|
|
|
|
|
+ Blocks.COAL_ORE,
|
|
|
|
|
+ Blocks.DEEPSLATE_COAL_ORE,
|
|
|
|
|
+ Blocks.LAPIS_ORE,
|
|
|
|
|
+ Blocks.DEEPSLATE_LAPIS_ORE,
|
|
|
|
|
+ Blocks.MOSSY_COBBLESTONE,
|
|
|
|
|
+ Blocks.OBSIDIAN,
|
|
|
|
|
+ Blocks.CHEST,
|
|
|
|
|
+ Blocks.DIAMOND_ORE,
|
|
|
|
|
+ Blocks.DEEPSLATE_DIAMOND_ORE,
|
|
|
|
|
+ Blocks.REDSTONE_ORE,
|
|
|
|
|
+ Blocks.DEEPSLATE_REDSTONE_ORE,
|
|
|
|
|
+ Blocks.CLAY,
|
|
|
|
|
+ Blocks.EMERALD_ORE,
|
|
|
|
|
+ Blocks.DEEPSLATE_EMERALD_ORE,
|
|
|
|
|
+ Blocks.ENDER_CHEST
|
|
|
|
|
+ //</editor-fold>
|
|
|
|
|
+ );
|
|
|
|
|
+ public List<Block> replacementBlocks = List.of(Blocks.STONE, Blocks.OAK_PLANKS, Blocks.DEEPSLATE);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
@ -1579,38 +1655,15 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ public boolean piglinsGuardChests = true;
|
|
|
|
|
+ public double babyZombieMovementModifier = 0.5;
|
|
|
|
|
+ public boolean allowSpiderWorldBorderClimbing = true;
|
|
|
|
|
+ public DoorBreakingDifficulty doorBreakingDifficulty;
|
|
|
|
|
+
|
|
|
|
|
+ public class DoorBreakingDifficulty extends ConfigurationPart { // TODO convert to map at some point
|
|
|
|
|
+ public List<Difficulty> zombie = Arrays.stream(Difficulty.values()).filter(Zombie.DOOR_BREAKING_PREDICATE).toList();
|
|
|
|
|
+ public List<Difficulty> husk = Arrays.stream(Difficulty.values()).filter(Zombie.DOOR_BREAKING_PREDICATE).toList();
|
|
|
|
|
+ @Setting("zombie_villager")
|
|
|
|
|
+ public List<Difficulty> zombieVillager = Arrays.stream(Difficulty.values()).filter(Zombie.DOOR_BREAKING_PREDICATE).toList();
|
|
|
|
|
+ @Setting("zombified_piglin")
|
|
|
|
|
+ public List<Difficulty> zombified_piglin = Arrays.stream(Difficulty.values()).filter(Zombie.DOOR_BREAKING_PREDICATE).toList();
|
|
|
|
|
+ public List<Difficulty> vindicator = Arrays.stream(Difficulty.values()).filter(Vindicator.DOOR_BREAKING_PREDICATE).toList();
|
|
|
|
|
+
|
|
|
|
|
+ // TODO remove when this becomes a proper map
|
|
|
|
|
+ public List<Difficulty> get(EntityType<?> type) {
|
|
|
|
|
+ return this.getOrDefault(type, null);
|
|
|
|
|
+ private static final List<EntityType<?>> ZOMBIE_LIKE = List.of(EntityType.ZOMBIE, EntityType.HUSK, EntityType.ZOMBIE_VILLAGER, EntityType.ZOMBIFIED_PIGLIN);
|
|
|
|
|
+ @MergeMap
|
|
|
|
|
+ public Map<EntityType<?>, List<Difficulty>> doorBreakingDifficulty = Util.make(new IdentityHashMap<>(), map -> {
|
|
|
|
|
+ for (final EntityType<?> type : ZOMBIE_LIKE) {
|
|
|
|
|
+ map.put(type, Arrays.stream(Difficulty.values()).filter(Zombie.DOOR_BREAKING_PREDICATE).toList());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public List<Difficulty> getOrDefault(EntityType<?> type, List<Difficulty> fallback) {
|
|
|
|
|
+ if (type == EntityType.ZOMBIE) {
|
|
|
|
|
+ return this.zombie;
|
|
|
|
|
+ } else if (type == EntityType.HUSK) {
|
|
|
|
|
+ return this.husk;
|
|
|
|
|
+ } else if (type == EntityType.ZOMBIE_VILLAGER) {
|
|
|
|
|
+ return this.zombieVillager;
|
|
|
|
|
+ } else if (type == EntityType.ZOMBIFIED_PIGLIN) {
|
|
|
|
|
+ return this.zombified_piglin;
|
|
|
|
|
+ } else if (type == EntityType.VINDICATOR) {
|
|
|
|
|
+ return this.vindicator;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return fallback;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ map.put(EntityType.VINDICATOR, Arrays.stream(Difficulty.values()).filter(Vindicator.DOOR_BREAKING_PREDICATE).toList());
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ public boolean disableCreeperLingeringEffect = false;
|
|
|
|
|
+ public boolean enderDragonsDeathAlwaysPlacesDragonEgg = false;
|
|
|
|
@ -3019,36 +3072,38 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+package io.papermc.paper.configuration.serializer.registry;
|
|
|
|
|
+
|
|
|
|
|
+import io.leangen.geantyref.TypeToken;
|
|
|
|
|
+import java.lang.reflect.Type;
|
|
|
|
|
+import java.util.function.Predicate;
|
|
|
|
|
+import net.minecraft.core.Registry;
|
|
|
|
|
+import net.minecraft.core.RegistryAccess;
|
|
|
|
|
+import net.minecraft.resources.ResourceKey;
|
|
|
|
|
+import net.minecraft.resources.ResourceLocation;
|
|
|
|
|
+import net.minecraft.server.MinecraftServer;
|
|
|
|
|
+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.function.Predicate;
|
|
|
|
|
+
|
|
|
|
|
+abstract class RegistryEntrySerializer<T, R> extends ScalarSerializer<T> {
|
|
|
|
|
+
|
|
|
|
|
+ private final RegistryAccess registryAccess;
|
|
|
|
|
+ private final ResourceKey<? extends Registry<R>> registryKey;
|
|
|
|
|
+ private final boolean omitMinecraftNamespace;
|
|
|
|
|
+
|
|
|
|
|
+ protected RegistryEntrySerializer(TypeToken<T> type, ResourceKey<? extends Registry<R>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ protected RegistryEntrySerializer(TypeToken<T> type, final RegistryAccess registryAccess, ResourceKey<? extends Registry<R>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ super(type);
|
|
|
|
|
+ this.registryAccess = registryAccess;
|
|
|
|
|
+ this.registryKey = registryKey;
|
|
|
|
|
+ this.omitMinecraftNamespace = omitMinecraftNamespace;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected RegistryEntrySerializer(Class<T> type, ResourceKey<? extends Registry<R>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ protected RegistryEntrySerializer(Class<T> type, final RegistryAccess registryAccess, ResourceKey<? extends Registry<R>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ super(type);
|
|
|
|
|
+ this.registryAccess = registryAccess;
|
|
|
|
|
+ this.registryKey = registryKey;
|
|
|
|
|
+ this.omitMinecraftNamespace = omitMinecraftNamespace;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected final Registry<R> registry() {
|
|
|
|
|
+ return MinecraftServer.getServer().registryAccess().registryOrThrow(this.registryKey); // TODO don't depend on MinecraftServer#getServer
|
|
|
|
|
+ return this.registryAccess.registryOrThrow(this.registryKey);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected abstract T convertFromResourceKey(ResourceKey<R> key) throws SerializationException;
|
|
|
|
@ -3089,22 +3144,22 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+import com.google.common.base.Preconditions;
|
|
|
|
|
+import io.leangen.geantyref.TypeFactory;
|
|
|
|
|
+import io.leangen.geantyref.TypeToken;
|
|
|
|
|
+import java.util.function.Function;
|
|
|
|
|
+import net.minecraft.core.Holder;
|
|
|
|
|
+import net.minecraft.core.Registry;
|
|
|
|
|
+import net.minecraft.core.RegistryAccess;
|
|
|
|
|
+import net.minecraft.resources.ResourceKey;
|
|
|
|
|
+import org.spongepowered.configurate.serialize.SerializationException;
|
|
|
|
|
+
|
|
|
|
|
+import java.util.function.Function;
|
|
|
|
|
+
|
|
|
|
|
+public final class RegistryHolderSerializer<T> extends RegistryEntrySerializer<Holder<T>, T> {
|
|
|
|
|
+
|
|
|
|
|
+ @SuppressWarnings("unchecked")
|
|
|
|
|
+ public RegistryHolderSerializer(TypeToken<T> typeToken, ResourceKey<? extends Registry<T>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ super((TypeToken<Holder<T>>) TypeToken.get(TypeFactory.parameterizedClass(Holder.class, typeToken.getType())), registryKey, omitMinecraftNamespace);
|
|
|
|
|
+ public RegistryHolderSerializer(TypeToken<T> typeToken, final RegistryAccess registryAccess, ResourceKey<? extends Registry<T>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ super((TypeToken<Holder<T>>) TypeToken.get(TypeFactory.parameterizedClass(Holder.class, typeToken.getType())), registryAccess, registryKey, omitMinecraftNamespace);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public RegistryHolderSerializer(Class<T> type, ResourceKey<? extends Registry<T>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ this(TypeToken.get(type), registryKey, omitMinecraftNamespace);
|
|
|
|
|
+ public RegistryHolderSerializer(Class<T> type, final RegistryAccess registryAccess, ResourceKey<? extends Registry<T>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ this(TypeToken.get(type), registryAccess, registryKey, omitMinecraftNamespace);
|
|
|
|
|
+ Preconditions.checkArgument(type.getTypeParameters().length == 0, "%s must have 0 type parameters", type);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
@ -3128,6 +3183,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+
|
|
|
|
|
+import io.leangen.geantyref.TypeToken;
|
|
|
|
|
+import net.minecraft.core.Registry;
|
|
|
|
|
+import net.minecraft.core.RegistryAccess;
|
|
|
|
|
+import net.minecraft.resources.ResourceKey;
|
|
|
|
|
+import org.spongepowered.configurate.serialize.SerializationException;
|
|
|
|
|
+
|
|
|
|
@ -3136,12 +3192,12 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ */
|
|
|
|
|
+public final class RegistryValueSerializer<T> extends RegistryEntrySerializer<T, T> {
|
|
|
|
|
+
|
|
|
|
|
+ public RegistryValueSerializer(TypeToken<T> type, ResourceKey<? extends Registry<T>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ super(type, registryKey, omitMinecraftNamespace);
|
|
|
|
|
+ public RegistryValueSerializer(TypeToken<T> type, final RegistryAccess registryAccess, ResourceKey<? extends Registry<T>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ super(type, registryAccess, registryKey, omitMinecraftNamespace);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ public RegistryValueSerializer(Class<T> type, ResourceKey<? extends Registry<T>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ super(type, registryKey, omitMinecraftNamespace);
|
|
|
|
|
+ public RegistryValueSerializer(Class<T> type, final RegistryAccess registryAccess, ResourceKey<? extends Registry<T>> registryKey, boolean omitMinecraftNamespace) {
|
|
|
|
|
+ super(type, registryAccess, registryKey, omitMinecraftNamespace);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Override
|
|
|
|
@ -3468,9 +3524,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
+ builder.addVersion(VERSION, ConfigurationTransformation.builder().addAction(PATH, INSTANCE).build());
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ @Nullable
|
|
|
|
|
+ @Override
|
|
|
|
|
+ public Object[] visitPath(final NodePath path, final ConfigurationNode value) throws ConfigurateException {
|
|
|
|
|
+ public Object @Nullable [] visitPath(final NodePath path, final ConfigurationNode value) throws ConfigurateException {
|
|
|
|
|
+ DedicatedServer server = ((DedicatedServer) MinecraftServer.getServer());
|
|
|
|
|
+
|
|
|
|
|
+ boolean val = value.getBoolean(server.settings.getProperties().logIPs);
|
|
|
|
@ -4840,8 +4895,8 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
org.spigotmc.SpigotConfig.registerCommands();
|
|
|
|
|
// Spigot end
|
|
|
|
|
+ // Paper start
|
|
|
|
|
+ paperConfigurations.initializeGlobalConfiguration();
|
|
|
|
|
+ paperConfigurations.initializeWorldDefaultsConfiguration();
|
|
|
|
|
+ paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
|
|
|
|
|
+ paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
|
|
|
|
+ // Paper end
|
|
|
|
|
|
|
|
|
|
this.setPvpAllowed(dedicatedserverproperties.pvp);
|
|
|
|
@ -4867,7 +4922,7 @@ index 0000000000000000000000000000000000000000..00000000000000000000000000000000
|
|
|
|
|
|
|
|
|
|
// Objects.requireNonNull(minecraftserver); // CraftBukkit - decompile error
|
|
|
|
|
- super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env);
|
|
|
|
|
+ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig))); // Paper
|
|
|
|
|
+ super(iworlddataserver, resourcekey, minecraftserver.registryAccess(), worlddimension.type(), minecraftserver::getProfiler, false, flag, i, minecraftserver.getMaxChainedNeighborUpdates(), gen, biomeProvider, env, spigotConfig -> minecraftserver.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(convertable_conversionsession.levelDirectory.path(), iworlddataserver.getLevelName(), resourcekey.location(), spigotConfig, minecraftserver.registryAccess()))); // Paper
|
|
|
|
|
this.pvpMode = minecraftserver.isPvpAllowed();
|
|
|
|
|
this.convertable = convertable_conversionsession;
|
|
|
|
|
this.uuid = WorldUUID.getUUID(convertable_conversionsession.levelDirectory.path().toFile());
|
|
|
|
|