9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-22 16:29:23 +00:00

update configuration to version 4

This commit is contained in:
NONPLAYT
2025-01-12 17:07:25 +03:00
parent 864c30b001
commit 1b38b9d986
22 changed files with 810 additions and 431 deletions

View File

@@ -1,66 +0,0 @@
package space.bxteam.divinemc.commands;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.level.ServerLevel;
import space.bxteam.divinemc.configuration.DivineConfig;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class DivineCommand extends Command {
public DivineCommand(String name) {
super(name);
this.description = "DivineMC related commands";
this.usageMessage = "/divinemc [reload | version]";
this.setPermission("bukkit.command.divinemc");
}
@Override
public List<String> tabComplete(CommandSender sender, String alias, String[] args, Location location) throws IllegalArgumentException {
if (args.length == 1) {
return Stream.of("reload", "version")
.filter(arg -> arg.startsWith(args[0].toLowerCase()))
.collect(Collectors.toList());
}
return Collections.emptyList();
}
@Override
public boolean execute(CommandSender sender, String commandLabel, String[] args) {
if (!testPermission(sender)) return true;
if (args.length != 1) {
sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage);
return false;
}
if (args[0].equalsIgnoreCase("reload")) {
Command.broadcastCommandMessage(sender, ChatColor.RED + "Please note that this command is not supported and may cause issues.");
Command.broadcastCommandMessage(sender, ChatColor.RED + "If you encounter any issues please use the /stop command to restart your server.");
MinecraftServer console = MinecraftServer.getServer();
DivineConfig.init((File) console.options.valueOf("divinemc-settings"));
for (ServerLevel level : console.getAllLevels()) {
level.divinemcConfig.init();
level.resetBreedingCooldowns();
}
console.server.reloadCount++;
Command.broadcastCommandMessage(sender, ChatColor.GREEN + "DivineMC config reload complete.");
} else if (args[0].equalsIgnoreCase("version")) {
Command verCmd = org.bukkit.Bukkit.getServer().getCommandMap().getCommand("version");
if (verCmd != null) {
return verCmd.execute(sender, commandLabel, new String[0]);
}
}
return true;
}
}

View File

@@ -1,157 +0,0 @@
package space.bxteam.divinemc.configuration;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableMap;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockBehaviour;
import space.bxteam.divinemc.commands.*;
import net.minecraft.server.MinecraftServer;
import net.minecraft.world.level.block.Blocks;
import org.bukkit.Bukkit;
import org.bukkit.command.Command;
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
@SuppressWarnings("unused")
public class DivineConfig {
private static final String HEADER = "This is the main configuration file for DivineMC.\n"
+ "If you need help with the configuration or have any questions related to DivineMC,\n"
+ "join us in our Discord server.\n"
+ "\n"
+ "Discord: https://discord.gg/p7cxhw7E2M \n"
+ "Docs: https://docs.bx-team.space/divinemc \n"
+ "New builds: https://github.com/DivineMC/DivineMC/releases/latest";
private static File CONFIG_FILE;
public static YamlConfiguration config;
private static Map<String, Command> commands;
public static int version;
static boolean verbose;
public static void init(File configFile) {
CONFIG_FILE = configFile;
config = new YamlConfiguration();
try {
config.load(CONFIG_FILE);
} catch (IOException ignore) {
} catch (InvalidConfigurationException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Could not load divinemc.yml, please correct your syntax errors", ex);
throw Throwables.propagate(ex);
}
config.options().header(HEADER);
config.options().copyDefaults(true);
verbose = getBoolean("verbose", false);
commands = new HashMap<>();
commands.put("divinemc", new DivineCommand("divinemc"));
version = getInt("config-version", 3);
set("config-version", 3);
readConfig(DivineConfig.class, null);
Block.BLOCK_STATE_REGISTRY.forEach(BlockBehaviour.BlockStateBase::initCache);
}
protected static void log(String s) {
if (verbose) {
log(Level.INFO, s);
}
}
protected static void log(Level level, String s) {
Bukkit.getLogger().log(level, s);
}
public static void registerCommands() {
for (Map.Entry<String, Command> entry : commands.entrySet()) {
MinecraftServer.getServer().server.getCommandMap().register(entry.getKey(), "DivineMC", entry.getValue());
}
}
static void readConfig(Class<?> clazz, Object instance) {
for (Method method : clazz.getDeclaredMethods()) {
if (Modifier.isPrivate(method.getModifiers())) {
if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
try {
method.setAccessible(true);
method.invoke(instance);
} catch (InvocationTargetException ex) {
throw Throwables.propagate(ex.getCause());
} catch (Exception ex) {
Bukkit.getLogger().log(Level.SEVERE, "Error invoking " + method, ex);
}
}
}
}
try {
config.save(CONFIG_FILE);
} catch (IOException ex) {
Bukkit.getLogger().log(Level.SEVERE, "Could not save " + CONFIG_FILE, ex);
}
}
private static void set(String path, Object val) {
config.addDefault(path, val);
config.set(path, val);
}
private static String getString(String path, String def) {
config.addDefault(path, def);
return config.getString(path, config.getString(path));
}
private static boolean getBoolean(String path, boolean def) {
config.addDefault(path, def);
return config.getBoolean(path, config.getBoolean(path));
}
private static double getDouble(String path, double def) {
config.addDefault(path, def);
return config.getDouble(path, config.getDouble(path));
}
private static int getInt(String path, int def) {
config.addDefault(path, def);
return config.getInt(path, config.getInt(path));
}
private static <T> List getList(String path, T def) {
config.addDefault(path, def);
return config.getList(path, config.getList(path));
}
static Map<String, Object> getMap(String path, Map<String, Object> def) {
if (def != null && config.getConfigurationSection(path) == null) {
config.addDefault(path, def);
return def;
}
return toMap(config.getConfigurationSection(path));
}
private static Map<String, Object> toMap(ConfigurationSection section) {
ImmutableMap.Builder<String, Object> builder = ImmutableMap.builder();
if (section != null) {
for (String key : section.getKeys(false)) {
Object obj = section.get(key);
if (obj != null) {
builder.put(key, obj instanceof ConfigurationSection val ? toMap(val) : obj);
}
}
}
return builder.build();
}
}

View File

@@ -0,0 +1,286 @@
package space.bxteam.divinemc.configuration;
import com.google.common.collect.Table;
import com.mojang.logging.LogUtils;
import io.leangen.geantyref.TypeToken;
import io.papermc.paper.configuration.Configuration;
import io.papermc.paper.configuration.ConfigurationPart;
import io.papermc.paper.configuration.Configurations;
import io.papermc.paper.configuration.NestedSetting;
import io.papermc.paper.configuration.PaperConfigurations;
import io.papermc.paper.configuration.legacy.RequiresSpigotInitialization;
import io.papermc.paper.configuration.mapping.InnerClassFieldDiscoverer;
import io.papermc.paper.configuration.serializer.ComponentSerializer;
import io.papermc.paper.configuration.serializer.EnumValueSerializer;
import io.papermc.paper.configuration.serializer.PacketClassSerializer;
import io.papermc.paper.configuration.serializer.StringRepresentableSerializer;
import io.papermc.paper.configuration.serializer.collections.FastutilMapSerializer;
import io.papermc.paper.configuration.serializer.collections.MapSerializer;
import io.papermc.paper.configuration.serializer.collections.TableSerializer;
import io.papermc.paper.configuration.serializer.registry.RegistryHolderSerializer;
import io.papermc.paper.configuration.serializer.registry.RegistryValueSerializer;
import io.papermc.paper.configuration.transformation.Transformations;
import io.papermc.paper.configuration.type.BooleanOrDefault;
import io.papermc.paper.configuration.type.Duration;
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 it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import it.unimi.dsi.fastutil.objects.Reference2LongMap;
import it.unimi.dsi.fastutil.objects.Reference2LongOpenHashMap;
import net.minecraft.core.RegistryAccess;
import net.minecraft.core.registries.Registries;
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.levelgen.feature.ConfiguredFeature;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
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.transformation.ConfigurationTransformation;
import org.spongepowered.configurate.transformation.TransformAction;
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import static io.leangen.geantyref.GenericTypeReflector.erase;
@SuppressWarnings("Convert2Diamond")
public class DivineConfigurations extends Configurations<DivineGlobalConfiguration, DivineWorldConfiguration> {
private static final Logger LOGGER = LogUtils.getLogger();
static final String GLOBAL_CONFIG_FILE_NAME = "divinemc-global.yml";
static final String WORLD_DEFAULTS_CONFIG_FILE_NAME = "divinemc-world-defaults.yml";
static final String WORLD_CONFIG_FILE_NAME = "divinemc-world.yml";
public static final String CONFIG_DIR = "config";
private static final String GLOBAL_HEADER = String.format("""
This is the global configuration file for DivineMC.
If you need help with the configuration or have any questions related to DivineMC,
join us in our Discord, or check our Documentation website.
The world configuration options are inside
their respective world folder. The files are named %s
Documentation: https://docs.bx-team.space/documentation/divinemc/about
Discord: https://discord.gg/p7cxhw7E2M""", WORLD_CONFIG_FILE_NAME);
private static final String WORLD_DEFAULTS_HEADER = """
This is the world defaults configuration file for DivineMC.
If you need help with the configuration or have any questions related to DivineMC,
join us in our Discord, or check our Documentation website.
Configuration options here apply to all worlds, unless you specify overrides inside
the world-specific config file inside each world folder.
Documentation: https://docs.bx-team.space/documentation/divinemc/about
Discord: https://discord.gg/p7cxhw7E2M""";
private static final Function<ContextMap, String> WORLD_HEADER = map -> String.format("""
This is a world configuration file for DivineMC.
This file may start empty but can be filled with settings to override ones in the %s/%s
World: %s (%s)""",
CONFIG_DIR,
WORLD_DEFAULTS_CONFIG_FILE_NAME,
map.require(WORLD_NAME),
map.require(WORLD_KEY)
);
public DivineConfigurations(final Path globalFolder) {
super(globalFolder, DivineGlobalConfiguration.class, DivineWorldConfiguration.class, GLOBAL_CONFIG_FILE_NAME, WORLD_DEFAULTS_CONFIG_FILE_NAME, WORLD_CONFIG_FILE_NAME);
}
@Override
protected YamlConfigurationLoader.Builder createLoaderBuilder() {
return super.createLoaderBuilder()
.defaultOptions(DivineConfigurations::defaultOptions);
}
private static ConfigurationOptions defaultOptions(ConfigurationOptions options) {
return options.serializers(builder -> builder
.register(MapSerializer.TYPE, new MapSerializer(false))
.register(new EnumValueSerializer())
.register(new ComponentSerializer())
);
}
@Override
protected ObjectMapper.Factory.Builder createGlobalObjectMapperFactoryBuilder() {
return defaultGlobalFactoryBuilder(super.createGlobalObjectMapperFactoryBuilder());
}
private static ObjectMapper.Factory.Builder defaultGlobalFactoryBuilder(ObjectMapper.Factory.Builder builder) {
return builder.addDiscoverer(InnerClassFieldDiscoverer.globalConfig());
}
@Override
protected YamlConfigurationLoader.Builder createGlobalLoaderBuilder() {
return super.createGlobalLoaderBuilder()
.defaultOptions(DivineConfigurations::defaultGlobalOptions);
}
private static ConfigurationOptions defaultGlobalOptions(ConfigurationOptions options) {
return options
.header(GLOBAL_HEADER)
.serializers(builder -> builder.register(new PacketClassSerializer()));
}
@Override
public DivineGlobalConfiguration initializeGlobalConfiguration(final RegistryAccess registryAccess) throws ConfigurateException {
DivineGlobalConfiguration configuration = super.initializeGlobalConfiguration(registryAccess);
DivineGlobalConfiguration.set(configuration);
return configuration;
}
@Override
protected ContextMap.Builder createDefaultContextMap(final RegistryAccess registryAccess) {
return super.createDefaultContextMap(registryAccess)
.put(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY, PaperConfigurations.SPIGOT_WORLD_DEFAULTS);
}
@Override
protected ObjectMapper.Factory.Builder createWorldObjectMapperFactoryBuilder(final ContextMap contextMap) {
return super.createWorldObjectMapperFactoryBuilder(contextMap)
.addNodeResolver(new RequiresSpigotInitialization.Factory(contextMap.require(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get()))
.addNodeResolver(new NestedSetting.Factory())
.addDiscoverer(InnerClassFieldDiscoverer.divineWorldConfig(contextMap));
}
@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))
.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<Table<?, ?, ?>>() {}, new TableSerializer())
.register(new StringRepresentableSerializer())
.register(IntOr.Default.SERIALIZER)
.register(IntOr.Disabled.SERIALIZER)
.register(DoubleOr.Default.SERIALIZER)
.register(BooleanOrDefault.SERIALIZER)
.register(Duration.SERIALIZER)
.register(EngineMode.SERIALIZER)
.register(FallbackValueSerializer.create(contextMap.require(PaperConfigurations.SPIGOT_WORLD_CONFIG_CONTEXT_KEY).get(), MinecraftServer::getServer))
.register(new RegistryValueSerializer<>(new TypeToken<EntityType<?>>() {}, access, Registries.ENTITY_TYPE, true))
.register(new RegistryValueSerializer<>(Item.class, access, Registries.ITEM, true))
.register(new RegistryHolderSerializer<>(new TypeToken<ConfiguredFeature<?, ?>>() {}, access, Registries.CONFIGURED_FEATURE, false))
.register(new RegistryHolderSerializer<>(Item.class, access, Registries.ITEM, true))
)
);
}
@Override
protected void applyWorldConfigTransformations(final ContextMap contextMap, final ConfigurationNode node, final @Nullable ConfigurationNode defaultsNode) throws ConfigurateException {
final ConfigurationNode version = node.node(Configuration.VERSION_FIELD);
final String world = contextMap.require(WORLD_NAME);
if (version.virtual()) {
LOGGER.warn("The DivineMC world config file for " + world + " didn't have a version set, assuming latest");
version.raw(DivineWorldConfiguration.CURRENT_VERSION);
}
if (DivineRemovedConfiguration.REMOVED_WORLD_PATHS.length > 0) {
ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder();
for (NodePath path : DivineRemovedConfiguration.REMOVED_WORLD_PATHS) {
builder.addAction(path, TransformAction.remove());
}
builder.build().apply(node);
}
// ADD FUTURE TRANSFORMS HERE
}
@Override
protected void applyGlobalConfigTransformations(ConfigurationNode node) throws ConfigurateException {
if (DivineRemovedConfiguration.REMOVED_GLOBAL_PATHS.length > 0) {
ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder();
for (NodePath path : DivineRemovedConfiguration.REMOVED_GLOBAL_PATHS) {
builder.addAction(path, TransformAction.remove());
}
builder.build().apply(node);
}
// ADD FUTURE TRANSFORMS HERE
}
private static final List<Transformations.DefaultsAware> DEFAULT_AWARE_TRANSFORMATIONS = Collections.emptyList();
@Override
protected void applyDefaultsAwareWorldConfigTransformations(final ContextMap contextMap, final ConfigurationNode worldNode, final ConfigurationNode defaultsNode) throws ConfigurateException {
final ConfigurationTransformation.Builder builder = ConfigurationTransformation.builder();
// ADD FUTURE TRANSFORMS HERE (these transforms run after the defaults have been merged into the node)
DEFAULT_AWARE_TRANSFORMATIONS.forEach(transform -> transform.apply(builder, contextMap, defaultsNode));
ConfigurationTransformation transformation;
try {
transformation = builder.build(); // build throws IAE if no actions were provided (bad zml)
} catch (IllegalArgumentException ignored) {
return;
}
transformation.apply(worldNode);
}
@Override
public DivineWorldConfiguration createWorldConfig(final ContextMap contextMap) {
final String levelName = contextMap.require(WORLD_NAME);
try {
return super.createWorldConfig(contextMap);
} catch (IOException exception) {
throw new RuntimeException("Could not create DivineMC world config for " + levelName, exception);
}
}
@Override
protected boolean isConfigType(final Type type) {
return ConfigurationPart.class.isAssignableFrom(erase(type));
}
public void reloadConfigs(MinecraftServer server) {
try {
this.initializeGlobalConfiguration(reloader(this.globalConfigClass, DivineGlobalConfiguration.get()));
this.initializeWorldDefaultsConfiguration(server.registryAccess());
for (ServerLevel level : server.getAllLevels()) {
this.createWorldConfig(PaperConfigurations.createWorldContextMap(level), reloader(this.worldConfigClass, level.divineConfig()));
}
} catch (Exception ex) {
throw new RuntimeException("Could not reload DivineMC configuration files", ex);
}
}
public static DivineConfigurations setup(final Path configDir) throws Exception {
try {
PaperConfigurations.createDirectoriesSymlinkAware(configDir);
return new DivineConfigurations(configDir);
} catch (final IOException ex) {
throw new RuntimeException("Could not setup DivineConfigurations", ex);
}
}
@Override
protected int globalConfigVersion() {
return DivineGlobalConfiguration.CURRENT_VERSION;
}
@Override
protected int worldConfigVersion() {
return getWorldConfigurationCurrentVersion();
}
@Override
public int getWorldConfigurationCurrentVersion() {
return DivineWorldConfiguration.CURRENT_VERSION;
}
}

View File

@@ -0,0 +1,23 @@
package space.bxteam.divinemc.configuration;
import io.papermc.paper.configuration.Configuration;
import io.papermc.paper.configuration.ConfigurationPart;
import org.spongepowered.configurate.objectmapping.meta.Setting;
@SuppressWarnings({"CanBeFinal", "FieldCanBeLocal", "FieldMayBeFinal", "NotNullFieldNotInitialized", "InnerClassMayBeStatic"})
public class DivineGlobalConfiguration extends ConfigurationPart {
static final int CURRENT_VERSION = 4;
private static DivineGlobalConfiguration instance;
public static DivineGlobalConfiguration get() {
return instance;
}
static void set(DivineGlobalConfiguration instance) {
DivineGlobalConfiguration.instance = instance;
}
@Setting(Configuration.VERSION_FIELD)
public int version = CURRENT_VERSION;
}

View File

@@ -0,0 +1,9 @@
package space.bxteam.divinemc.configuration;
import org.spongepowered.configurate.NodePath;
interface DivineRemovedConfiguration {
NodePath[] REMOVED_WORLD_PATHS = {};
NodePath[] REMOVED_GLOBAL_PATHS = {};
}

View File

@@ -1,84 +0,0 @@
package space.bxteam.divinemc.configuration;
import org.apache.commons.lang.BooleanUtils;
import org.bukkit.World;
import org.bukkit.configuration.ConfigurationSection;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
import static space.bxteam.divinemc.configuration.DivineConfig.log;
@SuppressWarnings("unused")
public class DivineWorldConfig {
private final String worldName;
private final World.Environment environment;
public DivineWorldConfig(String worldName, World.Environment environment) {
this.worldName = worldName;
this.environment = environment;
init();
}
public void init() {
log("-------- World Settings For [" + worldName + "] --------");
DivineConfig.readConfig(DivineWorldConfig.class, this);
}
private void set(String path, Object val) {
DivineConfig.config.addDefault("world-settings.default." + path, val);
DivineConfig.config.set("world-settings.default." + path, val);
if (DivineConfig.config.get("world-settings." + worldName + "." + path) != null) {
DivineConfig.config.addDefault("world-settings." + worldName + "." + path, val);
DivineConfig.config.set("world-settings." + worldName + "." + path, val);
}
}
private ConfigurationSection getConfigurationSection(String path) {
ConfigurationSection section = DivineConfig.config.getConfigurationSection("world-settings." + worldName + "." + path);
return section != null ? section : DivineConfig.config.getConfigurationSection("world-settings.default." + path);
}
private String getString(String path, String def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getString("world-settings." + worldName + "." + path, DivineConfig.config.getString("world-settings.default." + path));
}
private boolean getBoolean(String path, boolean def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getBoolean("world-settings." + worldName + "." + path, DivineConfig.config.getBoolean("world-settings.default." + path));
}
private boolean getBoolean(String path, Predicate<Boolean> predicate) {
String val = getString(path, "default").toLowerCase();
Boolean bool = BooleanUtils.toBooleanObject(val, "true", "false", "default");
return predicate.test(bool);
}
private double getDouble(String path, double def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getDouble("world-settings." + worldName + "." + path, DivineConfig.config.getDouble("world-settings.default." + path));
}
private int getInt(String path, int def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getInt("world-settings." + worldName + "." + path, DivineConfig.config.getInt("world-settings.default." + path));
}
private <T> List<?> getList(String path, T def) {
DivineConfig.config.addDefault("world-settings.default." + path, def);
return DivineConfig.config.getList("world-settings." + worldName + "." + path, DivineConfig.config.getList("world-settings.default." + path));
}
private Map<String, Object> getMap(String path, Map<String, Object> def) {
final Map<String, Object> fallback = DivineConfig.getMap("world-settings.default." + path, def);
final Map<String, Object> value = DivineConfig.getMap("world-settings." + worldName + "." + path, null);
return value.isEmpty() ? fallback : value;
}
public boolean saveFireworks = false;
private void saveFireworks() {
saveFireworks = getBoolean("gameplay-mechanics.should-save-fireworks", saveFireworks);
}
}

View File

@@ -0,0 +1,31 @@
package space.bxteam.divinemc.configuration;
import com.mojang.logging.LogUtils;
import io.papermc.paper.configuration.Configuration;
import io.papermc.paper.configuration.ConfigurationPart;
import io.papermc.paper.configuration.PaperConfigurations;
import net.minecraft.resources.ResourceLocation;
import org.slf4j.Logger;
import org.spigotmc.SpigotWorldConfig;
import org.spongepowered.configurate.objectmapping.meta.Setting;
@SuppressWarnings({"FieldCanBeLocal", "FieldMayBeFinal", "NotNullFieldNotInitialized", "InnerClassMayBeStatic"})
public class DivineWorldConfiguration extends ConfigurationPart {
private static final Logger LOGGER = LogUtils.getLogger();
public static final int CURRENT_VERSION = 4;
private transient final SpigotWorldConfig spigotConfig;
private transient final ResourceLocation worldKey;
public DivineWorldConfiguration(SpigotWorldConfig spigotConfig, ResourceLocation worldKey) {
this.spigotConfig = spigotConfig;
this.worldKey = worldKey;
}
public boolean isDefault() {
return this.worldKey.equals(PaperConfigurations.WORLD_DEFAULTS_KEY);
}
@Setting(Configuration.VERSION_FIELD)
public int version = CURRENT_VERSION;
}