add config holder.

This commit is contained in:
alexcrea 2024-02-29 16:34:52 +01:00 committed by alexcrea
parent 3afe786b38
commit 643487e1a9
9 changed files with 271 additions and 69 deletions

View file

@ -0,0 +1,239 @@
package xyz.alexcrea.cuanvil.config;
import com.google.common.io.Files;
import io.delilaheve.CustomAnvil;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import xyz.alexcrea.cuanvil.group.EnchantConflictManager;
import xyz.alexcrea.cuanvil.group.ItemGroupManager;
import java.io.File;
import java.io.IOException;
public abstract class ConfigHolder {
// Available configuration:
public static DefaultConfigHolder DEFAULT_CONFIG;
public static ItemGroupConfigHolder ITEM_GROUP_HOLDER;
public static ConflictConfigHolder CONFLICT_HOLDER;
public static UnitRepairHolder UNIT_REPAIR_HOLDER;
public static boolean loadConfig(){
DEFAULT_CONFIG = new DefaultConfigHolder();
ITEM_GROUP_HOLDER = new ItemGroupConfigHolder();
CONFLICT_HOLDER = new ConflictConfigHolder();
UNIT_REPAIR_HOLDER = new UnitRepairHolder();
return reloadAllFromDisk(true);
}
public static boolean reloadAllFromDisk(boolean hardfail){
boolean sucess = DEFAULT_CONFIG.reloadFromDisk(hardfail);
if(!sucess) return false;
sucess = ITEM_GROUP_HOLDER.reloadFromDisk(hardfail);
if(!sucess) return false;
sucess = CONFLICT_HOLDER.reloadFromDisk(hardfail);
if(!sucess) return false;
sucess = UNIT_REPAIR_HOLDER.reloadFromDisk(hardfail);
return sucess;
}
// usefull part of the file
private static final File BACKUP_FOLDER = new File(CustomAnvil.instance.getDataFolder(), "backup");
protected FileConfiguration configuration;
protected ConfigHolder(){
}
public abstract boolean reloadFromDisk(boolean hardFail);
public abstract void reload();
public FileConfiguration getConfig(){
return configuration;
}
// Config name and files
protected abstract String getConfigFileName();
protected String getConfigFileExtension(){
return ".yml";
}
protected File getConfigFile(){
return new File(CustomAnvil.instance.getDataFolder(), getConfigFileName()+getConfigFileExtension());
}
protected File getFirstBackup(){
return new File(BACKUP_FOLDER, getConfigFileName()+"-first"+getConfigFileExtension());
}
protected File getLastBackup(){
return new File(BACKUP_FOLDER, getConfigFileName()+"-latest"+getConfigFileExtension());
}
// Save logic
public boolean saveToDisk(boolean doBackup){
if(!doBackup){
if(!saveBackup()){
CustomAnvil.instance.getLogger().severe("Could not save backup. see above.");
return false;
}
}
File base = getConfigFile();
// if file exist and can't be deleted the file, then we gave up.
if(base.exists() && !base.delete()) {
CustomAnvil.instance.getLogger().severe("Could not save config: can't delete existing file.");
return false;
}
FileConfiguration config = getConfig();
try {
config.save(base);
} catch (IOException e) {
e.printStackTrace();
CustomAnvil.instance.getLogger().severe("Could not save config...");
return false;
}
return true;
}
public boolean saveBackup(){
File base = getConfigFile();
if(!base.exists()) return true; // We did back up everything we had to (nothing in this case)
boolean sufficientSuccess = false;
BACKUP_FOLDER.mkdirs();
// save first backup if do not exist
File firstBackup = getFirstBackup();
if(!firstBackup.exists()){
try {
Files.copy(base, firstBackup);
sufficientSuccess = true;
} catch (IOException e) {
e.printStackTrace();
}
}
// save last backup
File lastBackup = getLastBackup();
// if file exist and can't be deleted the file, then we gave up.
if(lastBackup.exists() && !lastBackup.delete()){
return sufficientSuccess;
}
try {
Files.move(base, lastBackup);
sufficientSuccess = true;
} catch (IOException e) {
e.printStackTrace();
}
return sufficientSuccess;
}
public static class DefaultConfigHolder extends ConfigHolder{
@Override
protected String getConfigFileName() {
return "config";
}
@Override
public boolean reloadFromDisk(boolean hardFail) {
CustomAnvil.instance.reloadConfig();
this.configuration = CustomAnvil.instance.getConfig();
return true;
}
@Override
public void reload() {}// Nothing to do
}
// Abstract class for non default config
public abstract static class ResourceConfigHolder extends ConfigHolder{
String resourceName;
private ResourceConfigHolder(String resourceName){
this.resourceName = resourceName;
}
@Override
protected String getConfigFileName() {
return resourceName;
}
@Override
public boolean reloadFromDisk(boolean hardFail) {
YamlConfiguration configuration = CustomAnvil.instance.reloadResource(
getConfigFileName()+getConfigFileExtension(), hardFail);
if(configuration == null) return false;
this.configuration = configuration;
reload();
return true;
}
}
// Class for itemGroupsManager config
public static class ItemGroupConfigHolder extends ResourceConfigHolder{
private final static String FILE_NAME = "item_groups";
ItemGroupManager itemGroupsManager;
private ItemGroupConfigHolder() {
super(FILE_NAME);
}
public ItemGroupManager getItemGroupsManager() {
return itemGroupsManager;
}
@Override
public void reload() {
// not the most efficient way for in game reload TODO optimise
this.itemGroupsManager = new ItemGroupManager();
this.itemGroupsManager.prepareGroups(this.configuration);
if(CONFLICT_HOLDER.getConfig() != null){
CONFLICT_HOLDER.reload();
}
}
}
// Class for enchant conflict config
public static class ConflictConfigHolder extends ResourceConfigHolder{
private final static String FILE_NAME = "enchant_conflict";
EnchantConflictManager conflictManager;
private ConflictConfigHolder() {
super(FILE_NAME);
}
public EnchantConflictManager getConflictManager() {
return conflictManager;
}
// We assume this is called after item group manager reload;,
@Override
public void reload() {
// not the most efficient way for in game reload TODO optimise
this.conflictManager = new EnchantConflictManager();
this.conflictManager.prepareConflicts(this.configuration, ITEM_GROUP_HOLDER.getItemGroupsManager());
}
}
// Class for unit repair config
public static class UnitRepairHolder extends ResourceConfigHolder{
private final static String ITEM_GROUP_FILE_NAME = "unit_repair_item";
private UnitRepairHolder() {
super(ITEM_GROUP_FILE_NAME);
}
@Override
public void reload() {} // Do nothing
}
}

View file

@ -23,6 +23,7 @@ import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView.Property.REPAIR_COST import org.bukkit.inventory.InventoryView.Property.REPAIR_COST
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Repairable import org.bukkit.inventory.meta.Repairable
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.group.ConflictType
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
import kotlin.math.min import kotlin.math.min
@ -320,7 +321,7 @@ class AnvilEventListener : Listener {
// count enchant as illegal enchant if it conflicts with another enchant or not in result // count enchant as illegal enchant if it conflicts with another enchant or not in result
if((enchantment.key !in resultEnchsKeys)){ if((enchantment.key !in resultEnchsKeys)){
resultEnchsKeys.add(enchantment.key) resultEnchsKeys.add(enchantment.key)
val conflictType = CustomAnvil.conflictManager.isConflicting(resultEnchsKeys,result.type,enchantment.key) val conflictType = ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(resultEnchsKeys,result.type,enchantment.key)
resultEnchsKeys.remove(enchantment.key) resultEnchsKeys.remove(enchantment.key)
if(ConflictType.BIG_CONFLICT == conflictType){ if(ConflictType.BIG_CONFLICT == conflictType){

View file

@ -6,9 +6,8 @@ import org.bukkit.configuration.file.YamlConfiguration
import org.bukkit.plugin.java.JavaPlugin import org.bukkit.plugin.java.JavaPlugin
import xyz.alexcrea.cuanvil.command.ReloadExecutor import xyz.alexcrea.cuanvil.command.ReloadExecutor
import xyz.alexcrea.cuanvil.command.TestExecutor import xyz.alexcrea.cuanvil.command.TestExecutor
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.util.Metrics import xyz.alexcrea.cuanvil.util.Metrics
import xyz.alexcrea.cuanvil.group.EnchantConflictManager
import xyz.alexcrea.cuanvil.group.ItemGroupManager
import xyz.alexcrea.cuanvil.util.MetricsUtil import xyz.alexcrea.cuanvil.util.MetricsUtil
import java.io.File import java.io.File
import java.io.FileReader import java.io.FileReader
@ -37,17 +36,8 @@ class CustomAnvil : JavaPlugin() {
// Test command name // Test command name
const val commandTestName = "test" const val commandTestName = "test"
// Item Grouping Configuration file name
const val itemGroupingConfigFilePath = "item_groups.yml"
// Conflict Configuration file name
const val enchantConflicConfigFilePath = "enchant_conflict.yml"
// Unit Repair Configuration file name
const val unitRepairFilePath = "unit_repair_item.yml"
// Current plugin instance // Current plugin instance
lateinit var instance: CustomAnvil lateinit var instance: CustomAnvil
// Current item grouping configuration instance
lateinit var conflictManager: EnchantConflictManager
// Configuration for unit repair // Configuration for unit repair
lateinit var unitRepairConfig: YamlConfiguration lateinit var unitRepairConfig: YamlConfiguration
@ -76,7 +66,9 @@ class CustomAnvil : JavaPlugin() {
logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus") logger.warning("Please note CustomAnvil is a more recent version of UnsafeEnchantsPlus")
} }
val success = reloadAllConfigs(true) // Load config
val success = ConfigHolder.loadConfig();
if(!success) return if(!success) return
// Load metrics // Load metrics
@ -92,36 +84,8 @@ class CustomAnvil : JavaPlugin() {
) )
} }
fun reloadAllConfigs(hardFailSafe: Boolean): Boolean{ fun reloadResource(resourceName: String,
saveDefaultConfig() hardFailSafe:Boolean = true): YamlConfiguration?{
reloadConfig()
// Load material grouping config
val itemGroupConfig = reloadResource(itemGroupingConfigFilePath, hardFailSafe) ?: return false
// Read material groups from config
val itemGroupsManager = ItemGroupManager()
itemGroupsManager.prepareGroups(itemGroupConfig)
// Load enchantment conflicts config
val conflictConfig = reloadResource(enchantConflicConfigFilePath, hardFailSafe) ?: return false
// Read conflicts from config and material group manager
val conflictManager = EnchantConflictManager()
conflictManager.prepareConflicts(conflictConfig,itemGroupsManager)
// Load unit repair config
val unitRepairConfig = reloadResource(unitRepairFilePath, hardFailSafe) ?: return false
// Set the global variable
CustomAnvil.conflictManager = conflictManager
CustomAnvil.unitRepairConfig = unitRepairConfig
// Test if is default config
MetricsUtil.testIfConfigIsDefault(config, itemGroupConfig, conflictConfig, unitRepairConfig)
return true
}
private fun reloadResource(resourceName: String,
hardFailSafe:Boolean = true): YamlConfiguration?{
// Save default resource // Save default resource
val file = File(dataFolder,resourceName) val file = File(dataFolder,resourceName)
if(!file.exists()){ if(!file.exists()){

View file

@ -3,6 +3,7 @@ package io.delilaheve.util
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import io.delilaheve.util.EnchantmentUtil.enchantmentName import io.delilaheve.util.EnchantmentUtil.enchantmentName
import org.bukkit.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import xyz.alexcrea.cuanvil.config.ConfigHolder
/** /**
* Config option accessors * Config option accessors
@ -71,7 +72,7 @@ object ConfigOptions {
*/ */
private val defaultEnchantLimit: Int private val defaultEnchantLimit: Int
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getInt(DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT) .getInt(DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT)
} }
@ -81,7 +82,7 @@ object ConfigOptions {
*/ */
val limitRepairCost: Boolean val limitRepairCost: Boolean
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getBoolean(LIMIT_REPAIR_COST, DEFAULT_LIMIT_REPAIR) .getBoolean(LIMIT_REPAIR_COST, DEFAULT_LIMIT_REPAIR)
} }
@ -91,7 +92,7 @@ object ConfigOptions {
*/ */
val limitRepairValue: Int val limitRepairValue: Int
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getInt(LIMIT_REPAIR_VALUE, DEFAULT_LIMIT_REPAIR_VALUE) .getInt(LIMIT_REPAIR_VALUE, DEFAULT_LIMIT_REPAIR_VALUE)
.takeIf { it in REPAIR_LIMIT_RANGE } .takeIf { it in REPAIR_LIMIT_RANGE }
@ -103,7 +104,7 @@ object ConfigOptions {
*/ */
val itemRepairCost: Int val itemRepairCost: Int
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getInt(ITEM_REPAIR_COST, DEFAULT_ITEM_REPAIR_COST) .getInt(ITEM_REPAIR_COST, DEFAULT_ITEM_REPAIR_COST)
.takeIf { it in REPAIR_COST_RANGE } .takeIf { it in REPAIR_COST_RANGE }
@ -115,7 +116,7 @@ object ConfigOptions {
*/ */
val unitRepairCost: Int val unitRepairCost: Int
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getInt(UNIT_REPAIR_COST, DEFAULT_UNIT_REPAIR_COST) .getInt(UNIT_REPAIR_COST, DEFAULT_UNIT_REPAIR_COST)
.takeIf { it in REPAIR_COST_RANGE } .takeIf { it in REPAIR_COST_RANGE }
@ -127,7 +128,7 @@ object ConfigOptions {
*/ */
val itemRenameCost: Int val itemRenameCost: Int
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getInt(ITEM_RENAME_COST, DEFAULT_ITEM_RENAME_COST) .getInt(ITEM_RENAME_COST, DEFAULT_ITEM_RENAME_COST)
.takeIf { it in ITEM_RENAME_COST_RANGE } .takeIf { it in ITEM_RENAME_COST_RANGE }
@ -139,7 +140,7 @@ object ConfigOptions {
*/ */
val sacrificeIllegalCost: Int val sacrificeIllegalCost: Int
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getInt(SACRIFICE_ILLEGAL_COST, DEFAULT_SACRIFICE_ILLEGAL_COST) .getInt(SACRIFICE_ILLEGAL_COST, DEFAULT_SACRIFICE_ILLEGAL_COST)
.takeIf { it in SACRIFICE_ILLEGAL_COST_RANGE } .takeIf { it in SACRIFICE_ILLEGAL_COST_RANGE }
@ -150,7 +151,7 @@ object ConfigOptions {
*/ */
val removeRepairLimit: Boolean val removeRepairLimit: Boolean
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getBoolean(REMOVE_REPAIR_LIMIT, DEFAULT_REMOVE_LIMIT) .getBoolean(REMOVE_REPAIR_LIMIT, DEFAULT_REMOVE_LIMIT)
} }
@ -160,7 +161,7 @@ object ConfigOptions {
*/ */
val debugLog: Boolean val debugLog: Boolean
get() { get() {
return CustomAnvil.instance return ConfigHolder.DEFAULT_CONFIG
.config .config
.getBoolean(DEBUG_LOGGING, DEFAULT_DEBUG_LOG) .getBoolean(DEBUG_LOGGING, DEFAULT_DEBUG_LOG)
} }

View file

@ -4,6 +4,7 @@ import io.delilaheve.CustomAnvil
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.group.ConflictType
import kotlin.math.max import kotlin.math.max
import kotlin.math.min import kotlin.math.min
@ -34,7 +35,7 @@ object EnchantmentUtil {
// Add the enchantment if it doesn't have conflicts, or, if player is allowed to bypass enchantment restrictions // Add the enchantment if it doesn't have conflicts, or, if player is allowed to bypass enchantment restrictions
this[enchantment] = level this[enchantment] = level
if(!player.hasPermission(CustomAnvil.bypassFusePermission) && if(!player.hasPermission(CustomAnvil.bypassFusePermission) &&
(CustomAnvil.conflictManager.isConflicting(this.keys,mat,enchantment) != ConflictType.NO_CONFLICT)){ (ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys,mat,enchantment) != ConflictType.NO_CONFLICT)){
this.remove(enchantment) this.remove(enchantment)
} }
@ -42,7 +43,7 @@ object EnchantmentUtil {
// Enchantment already in result list // Enchantment already in result list
else{ else{
// ... and they are conflicting // ... and they are conflicting
if((CustomAnvil.conflictManager.isConflicting(this.keys,mat,enchantment) != ConflictType.NO_CONFLICT) if((ConfigHolder.CONFLICT_HOLDER.conflictManager.isConflicting(this.keys,mat,enchantment) != ConflictType.NO_CONFLICT)
&& !player.hasPermission(CustomAnvil.bypassFusePermission)){ && !player.hasPermission(CustomAnvil.bypassFusePermission)){
return@forEach return@forEach
} }

View file

@ -4,6 +4,7 @@ import io.delilaheve.CustomAnvil
import org.bukkit.command.Command import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import xyz.alexcrea.cuanvil.config.ConfigHolder
class ReloadExecutor : CommandExecutor { class ReloadExecutor : CommandExecutor {
override fun onCommand(sender: CommandSender, cmd: Command, cmdstr: String, args: Array<out String>): Boolean { override fun onCommand(sender: CommandSender, cmd: Command, cmdstr: String, args: Array<out String>): Boolean {
@ -30,7 +31,7 @@ class ReloadExecutor : CommandExecutor {
*/ */
private fun commandBody(hardfail: Boolean): Boolean{ private fun commandBody(hardfail: Boolean): Boolean{
try { try {
return CustomAnvil.instance.reloadAllConfigs(hardfail) return ConfigHolder.reloadAllFromDisk(hardfail);
}catch (e: Exception){ }catch (e: Exception){
e.printStackTrace() e.printStackTrace()
return false return false

View file

@ -4,9 +4,7 @@ import io.delilaheve.CustomAnvil
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.configuration.file.YamlConfiguration
import org.bukkit.enchantments.Enchantment import org.bukkit.enchantments.Enchantment
import kotlin.collections.ArrayList
class EnchantConflictManager { class EnchantConflictManager {
@ -29,7 +27,7 @@ class EnchantConflictManager {
private lateinit var conflictMap: HashMap<Enchantment, ArrayList<EnchantConflictGroup>> private lateinit var conflictMap: HashMap<Enchantment, ArrayList<EnchantConflictGroup>>
// Read and prepare all conflict // Read and prepare all conflict
fun prepareConflicts(config: YamlConfiguration, itemManager: ItemGroupManager){ fun prepareConflicts(config: ConfigurationSection, itemManager: ItemGroupManager){
conflictMap = HashMap() conflictMap = HashMap()
val keys = config.getKeys(false) val keys = config.getKeys(false)
@ -140,7 +138,7 @@ class EnchantConflictManager {
} }
enum class ConflictType(){ enum class ConflictType{
NO_CONFLICT, NO_CONFLICT,
SMALL_CONFLICT, SMALL_CONFLICT,
BIG_CONFLICT BIG_CONFLICT

View file

@ -3,9 +3,7 @@ package xyz.alexcrea.cuanvil.group
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.configuration.file.YamlConfiguration
import java.util.* import java.util.*
import kotlin.collections.HashMap
class ItemGroupManager { class ItemGroupManager {
@ -23,7 +21,7 @@ class ItemGroupManager {
private lateinit var groupMap : HashMap<String, AbstractMaterialGroup> private lateinit var groupMap : HashMap<String, AbstractMaterialGroup>
// Read and create material groups // Read and create material groups
fun prepareGroups(config: YamlConfiguration){ fun prepareGroups(config: ConfigurationSection){
groupMap = HashMap() groupMap = HashMap()
val keys = config.getKeys(false) val keys = config.getKeys(false)
@ -35,7 +33,7 @@ class ItemGroupManager {
} }
// Create group by key // Create group by key
private fun createGroup(config: YamlConfiguration, private fun createGroup(config: ConfigurationSection,
keys: Set<String>, keys: Set<String>,
key: String): AbstractMaterialGroup { key: String): AbstractMaterialGroup {
val groupSection = config.getConfigurationSection(key)!! val groupSection = config.getConfigurationSection(key)!!
@ -60,7 +58,7 @@ class ItemGroupManager {
// Read Group elements // Read Group elements
private fun readGroup(group: AbstractMaterialGroup, private fun readGroup(group: AbstractMaterialGroup,
groupSection: ConfigurationSection, groupSection: ConfigurationSection,
config: YamlConfiguration, config: ConfigurationSection,
keys: Set<String>){ keys: Set<String>){
// Read material to include in this group policy // Read material to include in this group policy
val materialList = groupSection.getStringList(MATERIAL_LIST_PATH) val materialList = groupSection.getStringList(MATERIAL_LIST_PATH)

View file

@ -1,8 +1,8 @@
package xyz.alexcrea.cuanvil.util package xyz.alexcrea.cuanvil.util
import io.delilaheve.CustomAnvil
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.config.ConfigHolder
object UnitRepairUtil { object UnitRepairUtil {
@ -19,15 +19,14 @@ object UnitRepairUtil {
other: ItemStack? other: ItemStack?
): Double? { ): Double? {
if(other == null) return null if(other == null) return null
val config = CustomAnvil.unitRepairConfig val config = ConfigHolder.UNIT_REPAIR_HOLDER.config
// Get configuration section if exist // Get configuration section if exist
val otherName = other.type.name.uppercase() val otherName = other.type.name.uppercase()
var section = config.getConfigurationSection(otherName) var section = config.getConfigurationSection(otherName)
if(section == null){ if(section == null){
section = config.getConfigurationSection(otherName.lowercase()) section = config.getConfigurationSection(otherName.lowercase())
if(section == null) { if(section == null) return null
return null
}
} }
// Get repair amount // Get repair amount
var userDefault = config.getDouble(UNIT_REPAIR_DEFAULT_PATH, DEFAULT_DEFAULT_UNIT_REPAIR) var userDefault = config.getDouble(UNIT_REPAIR_DEFAULT_PATH, DEFAULT_DEFAULT_UNIT_REPAIR)