Not good but should added lock mecanism for config operations

This commit is contained in:
alexcrea 2024-10-12 19:06:19 +02:00
parent c057a9302f
commit 352606870d
No known key found for this signature in database
GPG key ID: 43FD265DB0DBF91F
27 changed files with 226 additions and 108 deletions

View file

@ -44,7 +44,7 @@ public class ConflictAPI {
* @return True if successful.
*/
public static boolean addConflict(@NotNull ConflictBuilder builder, boolean overrideDeleted){
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.get();
// Test if conflict can be added
if(!overrideDeleted && ConfigHolder.CONFLICT_HOLDER.isDeleted(builder.getName())) return false;
@ -86,10 +86,11 @@ public class ConflictAPI {
* @return True if successful.
*/
public static boolean writeConflict(@NotNull ConflictBuilder builder, boolean updatePlanned){
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.acquiredWrite();
String name = builder.getName();
if(name.contains(".")) {
ConfigHolder.CONFLICT_HOLDER.releaseWrite();
CustomAnvil.instance.getLogger().warning("Conflict " + name +" contain \".\" in its name but should not. this conflict is ignored.");
logConflictOrigin(builder);
return false;
@ -107,6 +108,7 @@ public class ConflictAPI {
prepareSaveTask();
if(updatePlanned) prepareUpdateTask();
ConfigHolder.CONFLICT_HOLDER.releaseWrite();
return true;
}

View file

@ -41,19 +41,27 @@ public class CustomAnvilRecipeApi {
* @return True if successful.
*/
public static boolean addRecipe(@NotNull AnvilRecipeBuilder builder, boolean overrideDeleted){
FileConfiguration config = ConfigHolder.CUSTOM_RECIPE_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.CUSTOM_RECIPE_HOLDER.acquiredWrite();
String name = builder.getName();
if(!overrideDeleted && ConfigHolder.CUSTOM_RECIPE_HOLDER.isDeleted(builder.getName())) return false;
if(config.contains(builder.getName())) return false;
if(!overrideDeleted && ConfigHolder.CUSTOM_RECIPE_HOLDER.isDeleted(builder.getName())) {
ConfigHolder.CUSTOM_RECIPE_HOLDER.releaseWrite();
return false;
}
if(config.contains(builder.getName())) {
ConfigHolder.CUSTOM_RECIPE_HOLDER.releaseWrite();
return false;
}
if(builder.getName().contains(".")) {
ConfigHolder.CUSTOM_RECIPE_HOLDER.releaseWrite();
CustomAnvil.instance.getLogger().warning("Custom anvil recipe " + name + " contain \".\" in its name but should not. this recipe is ignored.");
return false;
}
AnvilCustomRecipe recipe = builder.build();
if(recipe == null){
ConfigHolder.CUSTOM_RECIPE_HOLDER.releaseWrite();
CustomAnvil.instance.getLogger().warning("Custom anvil recipe " + name + " could not be parsed.");
if(builder.getLeftItem() == null){
CustomAnvil.instance.getLogger().warning("It look like left item of the recipe is null.");
@ -66,6 +74,7 @@ public class CustomAnvilRecipeApi {
// Add to registry
ConfigHolder.CUSTOM_RECIPE_HOLDER.getRecipeManager().cleanAddNew(recipe);
ConfigHolder.CUSTOM_RECIPE_HOLDER.releaseWrite();
// Save to file
recipe.saveToFile(false, false);

View file

@ -169,12 +169,13 @@ public class EnchantmentApi {
* @return Return false if override is false and a configuration exist. true otherwise.
*/
public static boolean writeDefaultConfig(CAEnchantment enchantment, boolean override){
FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig();
FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.acquiredWrite();
if(!override && config.contains(enchantment.getName())) return false;
writeDefaultConfig(config, enchantment);
prepareSaveTask();
ConfigHolder.DEFAULT_CONFIG.releaseWrite();
return true;
}

View file

@ -114,7 +114,7 @@ public class MaterialGroupApi {
}
private static void writeKnownGroup(@NotNull String groupType, @NotNull AbstractMaterialGroup group){
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.acquiredWrite();
String basePath = group.getName() + ".";
Set<Material> materialSet = group.getNonGroupInheritedMaterials();
@ -128,10 +128,11 @@ public class MaterialGroupApi {
config.set(basePath + ItemGroupManager.GROUP_LIST_PATH, materialGroupSEtToStringList(groupSet));
}
ConfigHolder.ITEM_GROUP_HOLDER.releaseWrite();
}
private static void writeUnknownGroup(@NotNull AbstractMaterialGroup group) {
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.ITEM_GROUP_HOLDER.acquiredWrite();
String basePath = group.getName() + ".";
EnumSet<Material> materials = group.getMaterials();
@ -141,6 +142,7 @@ public class MaterialGroupApi {
config.set(basePath + ItemGroupManager.MATERIAL_LIST_PATH, materialSetToStringList(materials));
}
ConfigHolder.ITEM_GROUP_HOLDER.releaseWrite();
}
public static List<String> materialSetToStringList(@NotNull Set<Material> materials){

View file

@ -62,7 +62,7 @@ public class UnitRepairApi {
* @return true if successful.
*/
public static boolean addUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value, boolean overrideDeleted){
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.get();
String path = unit.name().toLowerCase() + "." + repairable.name().toLowerCase();
if(!overrideDeleted && ConfigHolder.UNIT_REPAIR_HOLDER.isDeleted(path)) return false;
@ -82,7 +82,7 @@ public class UnitRepairApi {
* @return true if successful.
*/
public static boolean setUnitRepair(@NotNull Material unit, @NotNull Material repairable, double value){
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.acquiredWrite();
String repairableName = repairable.name().toLowerCase();
String path = unit.name().toLowerCase() + "." + repairableName;
@ -100,6 +100,7 @@ public class UnitRepairApi {
repairConfigGui.updateValueForGeneric(unit, true);
}
ConfigHolder.UNIT_REPAIR_HOLDER.releaseWrite();
return true;
}
@ -115,7 +116,7 @@ public class UnitRepairApi {
String unitName = unit.name();
String repairableName = repairable.name();
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.acquiredWrite();
config.set(unitName.toLowerCase() + repairableName.toUpperCase(), null);
config.set(unitName.toUpperCase() + repairableName.toLowerCase(), null);
config.set(unitName.toUpperCase() + repairableName.toUpperCase(), null);
@ -138,6 +139,7 @@ public class UnitRepairApi {
} else lastValue = true;
ConfigHolder.UNIT_REPAIR_HOLDER.releaseWrite();
// We only need to "delete" as the lower case to be counted as deleted
ConfigHolder.UNIT_REPAIR_HOLDER.delete(unitName.toLowerCase() + repairableName.toLowerCase());
@ -184,7 +186,7 @@ public class UnitRepairApi {
public static List<Triple<Material, Material, Double>> getUnitRepairs(){
List<Triple<Material, Material, Double>> mutableList = new ArrayList<>();
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.UNIT_REPAIR_HOLDER.get();
for (String unitKey : config.getKeys(false)) {
// Test if config section exist
if(!config.isConfigurationSection(unitKey)) continue;

View file

@ -15,7 +15,7 @@ import java.io.IOException;
import java.util.logging.Level;
@SuppressWarnings("unused")
public abstract class ConfigHolder {
public abstract class ConfigHolder extends LockStoredObject<FileConfiguration> {
// Available configuration:
public static DefaultConfigHolder DEFAULT_CONFIG;
@ -70,18 +70,29 @@ public abstract class ConfigHolder {
// usefull part of the file
private static final File BACKUP_FOLDER = new File(CustomAnvil.instance.getDataFolder(), "backup");
protected FileConfiguration configuration;
protected ConfigHolder() {
super(null);
}
public abstract boolean reloadFromDisk(boolean hardFail);
public abstract void reload();
public final void reload(){
acquiredWrite();
reloadWriteLocked();
releaseWrite();
}
public abstract void reloadWriteLocked();
/**
*
* @deprecated use {@link #get()}
* @return the stored config
*/
@Deprecated
public FileConfiguration getConfig() {
return configuration;
return get();
}
// Config name and files
@ -118,15 +129,19 @@ public abstract class ConfigHolder {
CustomAnvil.instance.getLogger().severe("Could not save config: can't delete existing file.");
return false;
}
FileConfiguration config = getConfig();
long readStamp = this.lock.readLock();
FileConfiguration config = unsafeGet();
try {
config.save(base);
} catch (IOException e) {
e.printStackTrace();
CustomAnvil.instance.getLogger().severe("Could not save config...");
this.lock.unlockRead(readStamp);
return false;
}
this.lock.unlockRead(readStamp);
CustomAnvil.Companion.log(getConfigFileName()+" saved successfully");
return true;
}
@ -173,14 +188,17 @@ public abstract class ConfigHolder {
@Override
public boolean reloadFromDisk(boolean hardFail) {
acquiredWrite();
CustomAnvil.instance.saveDefaultConfig();
CustomAnvil.instance.reloadConfig();
this.configuration = CustomAnvil.instance.getConfig();
setStored(CustomAnvil.instance.getConfig());
releaseWrite();
return true;
}
@Override
public void reload() {
public void reloadWriteLocked() {
}// Nothing to do
}
@ -203,10 +221,14 @@ public abstract class ConfigHolder {
public boolean reloadFromDisk(boolean hardFail) {
YamlConfiguration configuration = CustomAnvil.instance.reloadResource(
getConfigFileName() + getConfigFileExtension(), hardFail);
if (configuration == null) return false;
if (configuration == null) {
return false;
}
this.configuration = configuration;
reload();
acquiredWrite();
setStored(configuration);
reloadWriteLocked();
releaseWrite();
return true;
}
@ -284,7 +306,7 @@ public abstract class ConfigHolder {
// Add to the deleted config
this.deletedListConfig.set(objectPath, true);
this.getConfig().set(objectPath, null);
this.unsafeGet().set(objectPath, null);
// Save the deleted config (may not be the most efficient, but I will handle it later)
if(doSave){
@ -337,12 +359,12 @@ public abstract class ConfigHolder {
}
@Override
public void reload() {
public void reloadWriteLocked() {
// not the most efficient way for in game reload TODO optimise
this.itemGroupsManager = new ItemGroupManager();
this.itemGroupsManager.prepareGroups(this.configuration);
this.itemGroupsManager.prepareGroups(getWhileWrite());
if (CONFLICT_HOLDER.getConfig() != null) {
if (CONFLICT_HOLDER.unsafeGet() != null) {
CONFLICT_HOLDER.reload();
}
}
@ -365,10 +387,10 @@ public abstract class ConfigHolder {
// We assume this is called after item group manager reload;,
@Override
public void reload() {
public void reloadWriteLocked() {
// not the most efficient way for in game reload TODO optimise
this.conflictManager = new EnchantConflictManager();
this.conflictManager.prepareConflicts(this.configuration, ITEM_GROUP_HOLDER.getItemGroupsManager());
this.conflictManager.prepareConflicts(getWhileWrite(), ITEM_GROUP_HOLDER.getItemGroupsManager());
}
}
@ -382,7 +404,7 @@ public abstract class ConfigHolder {
}
@Override
public void reload() {
public void reloadWriteLocked() {
} // Do nothing
}
@ -402,9 +424,9 @@ public abstract class ConfigHolder {
}
@Override
public void reload() {
public void reloadWriteLocked() {
this.recipeManager = new CustomAnvilRecipeManager();
this.recipeManager.prepareRecipes(this.configuration);
this.recipeManager.prepareRecipes(getWhileWrite());
}
}

View file

@ -0,0 +1,62 @@
package xyz.alexcrea.cuanvil.config;
import java.util.concurrent.locks.StampedLock;
/**
* Bad implementation to acquire an object in a thread safe way
* Made for read heavy case
* @param <T> The type of object to store
*/
public class LockStoredObject<T> {
private T stored;
protected final StampedLock lock;
LockStoredObject(T toStore){
this.stored = toStore;
this.lock = new StampedLock();
}
public T get(){
long stamp = this.lock.tryOptimisticRead();
T stored = this.stored;
if (this.lock.validate(stamp))
return stored;
stamp = this.lock.readLock();
try {stored = this.stored;}
finally {this.lock.unlockRead(stamp);}
return stored;
}
private long writeStamp;
public final T acquiredWrite(){
writeStamp = lock.writeLock();
return stored;
}
public final void releaseWrite(){
lock.unlockWrite(this.writeStamp);
}
public void isWriteLocked(){
if(!lock.isWriteLocked()){
throw new IllegalStateException("Lock is not write locked");
}
}
public final void setStored(T toStore){
isWriteLocked();
this.stored = toStore;
}
public T getWhileWrite(){
isWriteLocked();
return stored;
}
public T unsafeGet(){
return stored;
}
}

View file

@ -54,10 +54,11 @@ public class EnchantConflictGui extends MappedGuiListConfigGui<EnchantConflictGr
// save empty conflict in config
String[] emptyStringArray = new String[0];
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.acquiredWrite();
config.set(name + ".enchantments", emptyStringArray);
config.set(name + ".notAffectedGroups", emptyStringArray);
config.set(name + ".maxEnchantmentBeforeConflict", 0);
ConfigHolder.CONFLICT_HOLDER.releaseWrite();
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
ConfigHolder.CONFLICT_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);

View file

@ -87,8 +87,9 @@ public class GroupConfigGui extends MappedGuiListConfigGui<IncludeGroup, GroupCo
ItemGroupManager manager = ConfigHolder.ITEM_GROUP_HOLDER.getItemGroupsManager();
if(manager.getGroupMap().containsKey(name)) return null;
ConfigurationSection config = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
ConfigurationSection config = ConfigHolder.ITEM_GROUP_HOLDER.acquiredWrite();
config.set(name+"."+ItemGroupManager.GROUP_TYPE_PATH, GroupType.INCLUDE.getGroupID());
ConfigHolder.CONFLICT_HOLDER.releaseWrite();
return (IncludeGroup) manager.createGroup(config, name);
}

View file

@ -49,7 +49,7 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
@Override
protected ItemStack createItemForGeneric(Material material) {
ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getConfigurationSection(material.name().toLowerCase());
ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.get().getConfigurationSection(material.name().toLowerCase());
String materialName = CasedStringUtil.snakeToUpperSpacedCase(material.name().toLowerCase());
if(material.isAir()){
@ -77,7 +77,7 @@ public class UnitRepairConfigGui extends MappedGuiListConfigGui<Material, UnitRe
protected Collection<Material> getEveryDisplayableInstanceOfGeneric() {
ArrayList<Material> materials = new ArrayList<>();
for (String matName : ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getKeys(false)) {
for (String matName : ConfigHolder.UNIT_REPAIR_HOLDER.get().getKeys(false)) {
Material mat = Material.getMaterial(matName.toUpperCase());
if(mat != null){
materials.add(mat);

View file

@ -83,7 +83,9 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
String materialName = type.name().toLowerCase();
// Add new material
ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().set(parentMaterial.name().toLowerCase() + "." + materialName,0.25);
ConfigHolder.UNIT_REPAIR_HOLDER.acquiredWrite()
.set(parentMaterial.name().toLowerCase() + "." + materialName,0.25);
ConfigHolder.UNIT_REPAIR_HOLDER.releaseWrite();
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
@ -143,7 +145,8 @@ public class UnitRepairElementListGui extends SettingGuiListConfigGui<String, Do
return keys;
}
ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig().getConfigurationSection(parentMaterial.name().toLowerCase());
ConfigurationSection materialSection = ConfigHolder.UNIT_REPAIR_HOLDER.get()
.getConfigurationSection(parentMaterial.name().toLowerCase());
if(materialSection == null){
return keys;
}

View file

@ -147,7 +147,8 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
@Override
public void updateGuiValues() {
// update value from config to conflict
int minBeforeBlock = ConfigHolder.CONFLICT_HOLDER.getConfig().getInt(this.enchantConflict.toString()+'.'+EnchantConflictManager.ENCH_MAX_PATH, 0);
int minBeforeBlock = ConfigHolder.CONFLICT_HOLDER.get()
.getInt(this.enchantConflict.toString()+'.'+EnchantConflictManager.ENCH_MAX_PATH, 0);
this.enchantConflict.setMinBeforeBlock(minBeforeBlock);
// Parent should call updateLocal with this call
@ -260,7 +261,9 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
for (CAEnchantment enchantment : enchantments) {
enchantKeys[index++] = enchantment.getKey().toString();
}
ConfigHolder.CONFLICT_HOLDER.getConfig().set(enchantConflict + ".enchantments", enchantKeys);
ConfigHolder.CONFLICT_HOLDER.acquiredWrite().set(enchantConflict + ".enchantments", enchantKeys);
ConfigHolder.CONFLICT_HOLDER.releaseWrite();
try {
updateGuiValues();
@ -304,7 +307,9 @@ public class EnchantConflictSubSettingGui extends MappedToListSubSettingGui impl
for (AbstractMaterialGroup group : groups) {
groupsNames[index++] = group.getName();
}
ConfigHolder.CONFLICT_HOLDER.getConfig().set(this.enchantConflict + ".notAffectedGroups", groupsNames);
ConfigHolder.CONFLICT_HOLDER.acquiredWrite().set(this.enchantConflict + ".notAffectedGroups", groupsNames);
ConfigHolder.CONFLICT_HOLDER.releaseWrite();
try {
updateGuiValues();

View file

@ -286,7 +286,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
groupNames[index++] = otherGroup.getName();
}
ConfigHolder.ITEM_GROUP_HOLDER.getConfig().set(group.getName()+"."+ItemGroupManager.GROUP_LIST_PATH, groupNames);
ConfigHolder.ITEM_GROUP_HOLDER.acquiredWrite().set(group.getName()+"."+ItemGroupManager.GROUP_LIST_PATH, groupNames);
ConfigHolder.ITEM_GROUP_HOLDER.releaseWrite();
// Try to update referencing group. kind of expensive operation in some case.
updateDirectReferencingGroups(group);
@ -330,7 +331,8 @@ public class GroupConfigSubSettingGui extends MappedToListSubSettingGui implemen
groupNames[index++] = otherGroup.name().toLowerCase();
}
ConfigHolder.ITEM_GROUP_HOLDER.getConfig().set(this.group.getName()+"."+ItemGroupManager.MATERIAL_LIST_PATH, groupNames);
ConfigHolder.ITEM_GROUP_HOLDER.acquiredWrite().set(this.group.getName()+"."+ItemGroupManager.MATERIAL_LIST_PATH, groupNames);
ConfigHolder.ITEM_GROUP_HOLDER.releaseWrite();
// update referencing groups
updateDirectReferencingGroups(this.group);

View file

@ -148,7 +148,8 @@ public class BoolSettingsGui extends AbstractSettingGui {
@Override
public boolean onSave() {
holder.config.getConfig().set(holder.configPath, now);
holder.config.acquiredWrite().set(holder.configPath, now);
holder.config.releaseWrite();
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
@ -208,7 +209,7 @@ public class BoolSettingsGui extends AbstractSettingGui {
* @return The configured value for the associated setting.
*/
public boolean getConfiguredValue() {
return this.config.getConfig().getBoolean(this.configPath, this.defaultVal);
return this.config.get().getBoolean(this.configPath, this.defaultVal);
}
@Override

View file

@ -319,10 +319,12 @@ public class DoubleSettingGui extends AbstractSettingGui {
if(this.holder.config instanceof ConfigHolder.DeletableResource deletableResource){
deletableResource.delete(this.holder.configPath);
}else{
this.holder.config.getConfig().set(this.holder.configPath, null);
this.holder.config.acquiredWrite().set(this.holder.configPath, null);
holder.config.releaseWrite();
}
}else{
this.holder.config.getConfig().set(this.holder.configPath, now.doubleValue());
this.holder.config.acquiredWrite().set(this.holder.configPath, now.doubleValue());
holder.config.releaseWrite();
}
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
@ -432,7 +434,7 @@ public class DoubleSettingGui extends AbstractSettingGui {
* @return The configured value for the associated setting.
*/
public BigDecimal getConfiguredValue() {
ConfigurationSection section = this.config.getConfig();
ConfigurationSection section = this.config.get();
if(section.isDouble(this.configPath)){
return BigDecimal.valueOf(section.getDouble(this.configPath)).setScale(2, RoundingMode.HALF_UP);
}

View file

@ -7,6 +7,7 @@ import com.github.stefvanschie.inventoryframework.pane.util.Pattern;
import io.delilaheve.CustomAnvil;
import io.delilaheve.util.ConfigOptions;
import org.bukkit.Material;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack;
@ -225,8 +226,10 @@ public class EnchantCostSettingsGui extends IntSettingsGui {
@Override
public boolean onSave() {
holder.config.getConfig().set(holder.configPath + ITEM_PATH, now);
holder.config.getConfig().set(holder.configPath + BOOK_PATH, nowBook);
FileConfiguration config = holder.config.acquiredWrite();
config.set(holder.configPath + ITEM_PATH, now);
config.set(holder.configPath + BOOK_PATH, nowBook);
holder.config.releaseWrite();
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);

View file

@ -118,7 +118,8 @@ public class EnumSettingGui<T extends Enum<T> & EnumSettingGui.ConfigurableEnum>
@Override
public boolean onSave() {
holder.config.getConfig().set(holder.configPath, this.now.configName());
holder.config.acquiredWrite().set(holder.configPath, this.now.configName());
holder.config.releaseWrite();
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);

View file

@ -262,7 +262,8 @@ public class IntSettingsGui extends AbstractSettingGui {
@Override
public boolean onSave() {
holder.config.getConfig().set(holder.configPath, now);
holder.config.acquiredWrite().set(holder.configPath, now);
holder.config.releaseWrite();
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
@ -340,7 +341,7 @@ public class IntSettingsGui extends AbstractSettingGui {
* @return The configured value for the associated setting.
*/
public int getConfiguredValue() {
return this.config.getConfig().getInt(this.configPath, this.defaultVal);
return this.config.get().getInt(this.configPath, this.defaultVal);
}
@Override

View file

@ -146,7 +146,8 @@ public class ItemSettingGui extends AbstractSettingGui {
@Override
public boolean onSave() {
holder.config.getConfig().set(holder.configPath, this.now);
holder.config.acquiredWrite().set(holder.configPath, this.now);
holder.config.releaseWrite();
if (GuiSharedConstant.TEMPORARY_DO_SAVE_TO_DISK_EVERY_CHANGE) {
return holder.config.saveToDisk(GuiSharedConstant.TEMPORARY_DO_BACKUP_EVERY_SAVE);
@ -211,7 +212,7 @@ public class ItemSettingGui extends AbstractSettingGui {
* @return The configured value for the associated setting.
*/
public ItemStack getConfiguredValue() {
return this.config.getConfig().getItemStack(this.configPath, this.defaultVal);
return this.config.get().getItemStack(this.configPath, this.defaultVal);
}
@NotNull

View file

@ -10,7 +10,7 @@ import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
public class PluginSetDefault {
public static void reAddMissingDefault(){
FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig();
FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.acquiredWrite();
int nbSet = 0;
@ -29,6 +29,8 @@ public class PluginSetDefault {
nbSet+= trySetDefault(config, ConfigOptions.WORK_PENALTY_TYPE, WorkPenaltyType.DEFAULT.configName());
nbSet+= trySetDefault(config, ConfigOptions.DEFAULT_LIMIT_PATH, ConfigOptions.DEFAULT_ENCHANT_LIMIT);
ConfigHolder.DEFAULT_CONFIG.releaseWrite();
if(nbSet > 0){
CustomAnvil.instance.getLogger().info("Adding " + nbSet + " absent default config values.");
ConfigHolder.DEFAULT_CONFIG.saveToDisk(true);

View file

@ -14,7 +14,7 @@ public class Update_1_21 {
public static void handleUpdate(){
// Assume if version path is not null then it's 1.21
String oldVersion = ConfigHolder.DEFAULT_CONFIG.getConfig().getString(UpdateUtils.MINECRAFT_VERSION_PATH);
String oldVersion = ConfigHolder.DEFAULT_CONFIG.get().getString(UpdateUtils.MINECRAFT_VERSION_PATH);
if(oldVersion != null){
Version version = Version.fromString(oldVersion);
@ -33,10 +33,10 @@ public class Update_1_21 {
private static void doUpdate() {
CustomAnvil.instance.getLogger().info("Updating config to support 1.21 ...");
FileConfiguration baseConfig = ConfigHolder.DEFAULT_CONFIG.getConfig();
FileConfiguration groupConfig = ConfigHolder.ITEM_GROUP_HOLDER.getConfig();
FileConfiguration conflictConfig = ConfigHolder.CONFLICT_HOLDER.getConfig();
FileConfiguration unitConfig = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
FileConfiguration baseConfig = ConfigHolder.DEFAULT_CONFIG.acquiredWrite();
FileConfiguration groupConfig = ConfigHolder.ITEM_GROUP_HOLDER.acquiredWrite();
FileConfiguration conflictConfig = ConfigHolder.CONFLICT_HOLDER.acquiredWrite();
FileConfiguration unitConfig = ConfigHolder.UNIT_REPAIR_HOLDER.acquiredWrite();
// Add mace to groups
groupConfig.set("mace.type", "include");
@ -84,10 +84,17 @@ public class Update_1_21 {
// Set version string as 1.21
baseConfig.set(UpdateUtils.MINECRAFT_VERSION_PATH, "1.21");
// Save
// Release write and save
ConfigHolder.DEFAULT_CONFIG.releaseWrite();
ConfigHolder.DEFAULT_CONFIG.saveToDisk(true);
ConfigHolder.ITEM_GROUP_HOLDER.releaseWrite();
ConfigHolder.ITEM_GROUP_HOLDER.saveToDisk(true);
ConfigHolder.CONFLICT_HOLDER.releaseWrite();
ConfigHolder.CONFLICT_HOLDER.saveToDisk(true);
ConfigHolder.UNIT_REPAIR_HOLDER.releaseWrite();
ConfigHolder.UNIT_REPAIR_HOLDER.saveToDisk(true);
// imply reload of CONFLICT_HOLDER

View file

@ -14,7 +14,7 @@ public class PUpdate_1_6_2 {
private static final String[] toUpdate = new String[] {"restriction_density", "restriction_breach", "restriction_wind_burst"};
public static void handleUpdate(@Nonnull Set<ConfigHolder> toSave) {
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig();
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.acquiredWrite();
boolean conflictUpdated = false;
for (String restriction : toUpdate) {
@ -34,6 +34,7 @@ public class PUpdate_1_6_2 {
conflictUpdated = true;
}
}
ConfigHolder.CONFLICT_HOLDER.releaseWrite();
if(conflictUpdated){
toSave.add(ConfigHolder.CONFLICT_HOLDER);
@ -43,13 +44,14 @@ public class PUpdate_1_6_2 {
}
// Then we add the unit repair
config = ConfigHolder.UNIT_REPAIR_HOLDER.getConfig();
config = ConfigHolder.UNIT_REPAIR_HOLDER.acquiredWrite();
String unitRepairPath = "breeze_rod.mace";
if(!config.isConfigurationSection(unitRepairPath)){
config.set(unitRepairPath, 0.25);
toSave.add(ConfigHolder.UNIT_REPAIR_HOLDER);
}
ConfigHolder.UNIT_REPAIR_HOLDER.releaseWrite();
}

View file

@ -13,7 +13,7 @@ public class PluginUpdates {
private static final String CONFIG_VERSION_PATH = "configVersion";
public static void handlePluginUpdate(){
String versionString = ConfigHolder.DEFAULT_CONFIG.getConfig().getString(CONFIG_VERSION_PATH);
String versionString = ConfigHolder.DEFAULT_CONFIG.get().getString(CONFIG_VERSION_PATH);
Version current = versionString == null ? new Version(0) : Version.fromString(versionString);
Set<ConfigHolder> toSave = new HashSet<>();
@ -28,7 +28,9 @@ public class PluginUpdates {
private static void finishConfiguration(@Nonnull String newVersion, @Nonnull Set<ConfigHolder> toSave) {
CustomAnvil.instance.getLogger().info("Configuration file updated to " + newVersion);
ConfigHolder.DEFAULT_CONFIG.getConfig().set(CONFIG_VERSION_PATH, newVersion);
ConfigHolder.DEFAULT_CONFIG.acquiredWrite().set(CONFIG_VERSION_PATH, newVersion);
ConfigHolder.DEFAULT_CONFIG.releaseWrite();
toSave.add(ConfigHolder.DEFAULT_CONFIG);
for (ConfigHolder configHolder : toSave) {

View file

@ -125,8 +125,7 @@ object ConfigOptions {
val doCapCost: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST)
.get().getBoolean(CAP_ANVIL_COST, DEFAULT_CAP_ANVIL_COST)
}
/**
@ -135,8 +134,7 @@ object ConfigOptions {
val maxAnvilCost: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST)
.get().getInt(MAX_ANVIL_COST, DEFAULT_MAX_ANVIL_COST)
.takeIf { it in MAX_ANVIL_COST_RANGE }
?: DEFAULT_MAX_ANVIL_COST
}
@ -147,8 +145,7 @@ object ConfigOptions {
val doRemoveCostLimit: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT)
.get().getBoolean(REMOVE_ANVIL_COST_LIMIT, DEFAULT_REMOVE_ANVIL_COST_LIMIT)
}
/**
@ -157,8 +154,7 @@ object ConfigOptions {
val doReplaceTooExpensive: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(REPLACE_TOO_EXPENSIVE, DEFAULT_REPLACE_TOO_EXPENSIVE)
.get().getBoolean(REPLACE_TOO_EXPENSIVE, DEFAULT_REPLACE_TOO_EXPENSIVE)
}
/**
@ -167,8 +163,7 @@ object ConfigOptions {
val itemRepairCost: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(ITEM_REPAIR_COST, DEFAULT_ITEM_REPAIR_COST)
.get().getInt(ITEM_REPAIR_COST, DEFAULT_ITEM_REPAIR_COST)
.takeIf { it in REPAIR_COST_RANGE }
?: DEFAULT_ITEM_REPAIR_COST
}
@ -179,8 +174,7 @@ object ConfigOptions {
val unitRepairCost: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(UNIT_REPAIR_COST, DEFAULT_UNIT_REPAIR_COST)
.get().getInt(UNIT_REPAIR_COST, DEFAULT_UNIT_REPAIR_COST)
.takeIf { it in REPAIR_COST_RANGE }
?: DEFAULT_UNIT_REPAIR_COST
}
@ -191,8 +185,7 @@ object ConfigOptions {
val itemRenameCost: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(ITEM_RENAME_COST, DEFAULT_ITEM_RENAME_COST)
.get().getInt(ITEM_RENAME_COST, DEFAULT_ITEM_RENAME_COST)
.takeIf { it in ITEM_RENAME_COST_RANGE }
?: DEFAULT_ITEM_RENAME_COST
}
@ -203,8 +196,7 @@ object ConfigOptions {
val sacrificeIllegalCost: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(SACRIFICE_ILLEGAL_COST, DEFAULT_SACRIFICE_ILLEGAL_COST)
.get().getInt(SACRIFICE_ILLEGAL_COST, DEFAULT_SACRIFICE_ILLEGAL_COST)
.takeIf { it in SACRIFICE_ILLEGAL_COST_RANGE }
?: DEFAULT_SACRIFICE_ILLEGAL_COST
}
@ -215,8 +207,7 @@ object ConfigOptions {
val allowColorCode: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(ALLOW_COLOR_CODE, DEFAULT_ALLOW_COLOR_CODE)
.get().getBoolean(ALLOW_COLOR_CODE, DEFAULT_ALLOW_COLOR_CODE)
}
/**
@ -225,8 +216,7 @@ object ConfigOptions {
val allowHexadecimalColor: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR)
.get().getBoolean(ALLOW_HEXADECIMAL_COLOR, DEFAULT_ALLOW_HEXADECIMAL_COLOR)
}
/**
@ -240,8 +230,7 @@ object ConfigOptions {
val permissionNeededForColor: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR)
.get().getBoolean(PERMISSION_NEEDED_FOR_COLOR, DEFAULT_PERMISSION_NEEDED_FOR_COLOR)
}
/**
@ -250,8 +239,7 @@ object ConfigOptions {
val useOfColorCost: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST)
.get().getInt(USE_OF_COLOR_COST, DEFAULT_USE_OF_COLOR_COST)
.takeIf { it in USE_OF_COLOR_COST_RANGE }
?: DEFAULT_USE_OF_COLOR_COST
}
@ -263,8 +251,7 @@ object ConfigOptions {
get() {
return WorkPenaltyType.fromString(
ConfigHolder.DEFAULT_CONFIG
.config
.getString(WORK_PENALTY_TYPE));
.get().getString(WORK_PENALTY_TYPE));
}
/**
@ -273,8 +260,7 @@ object ConfigOptions {
private val defaultEnchantLimit: Int
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getInt(DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT)
.get().getInt(DEFAULT_LIMIT_PATH, DEFAULT_ENCHANT_LIMIT)
}
/**
@ -283,8 +269,7 @@ object ConfigOptions {
val debugLog: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(DEBUG_LOGGING, DEFAULT_DEBUG_LOG)
.get().getBoolean(DEBUG_LOGGING, DEFAULT_DEBUG_LOG)
}
/**
@ -293,8 +278,7 @@ object ConfigOptions {
val verboseDebugLog: Boolean
get() {
return ConfigHolder.DEFAULT_CONFIG
.config
.getBoolean(VERBOSE_DEBUG_LOGGING, DEFAULT_VERBOSE_DEBUG_LOG)
.get().getBoolean(VERBOSE_DEBUG_LOGGING, DEFAULT_VERBOSE_DEBUG_LOG)
}
/**

View file

@ -37,7 +37,7 @@ object DependencyManager {
} else BukkitScheduler()
// Packet Manager
val forceProtocolib = ConfigHolder.DEFAULT_CONFIG.config.getBoolean("force_protocolib", false)
val forceProtocolib = ConfigHolder.DEFAULT_CONFIG.get().getBoolean("force_protocolib", false)
packetManager = PacketManagerSelector.selectPacketManager(forceProtocolib)
externGuiTester = GuiTesterSelector.selectGuiTester

View file

@ -62,7 +62,7 @@ class AnvilCustomRecipe(
}
fun getFromConfig(name: String): AnvilCustomRecipe? {
return getFromConfig(name, ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getConfigurationSection(name))
return getFromConfig(name, ConfigHolder.CUSTOM_RECIPE_HOLDER.unsafeGet().getConfigurationSection(name))
}
}
@ -75,7 +75,7 @@ class AnvilCustomRecipe(
}
fun saveToFile(writeFile: Boolean, doBackup: Boolean){
val fileConfig = ConfigHolder.CUSTOM_RECIPE_HOLDER.config
val fileConfig = ConfigHolder.CUSTOM_RECIPE_HOLDER.acquiredWrite()
fileConfig["$name.$EXACT_COUNT_CONFIG"] = exactCount
//fileConfig.set("$name.$EXACT_LEFT_CONFIG", exactLeft)
@ -86,7 +86,7 @@ class AnvilCustomRecipe(
fileConfig["$name.$LEFT_ITEM_CONFIG"] = leftItem
fileConfig["$name.$RIGHT_ITEM_CONFIG"] = rightItem
fileConfig["$name.$RESULT_ITEM_CONFIG"] = resultItem
ConfigHolder.CUSTOM_RECIPE_HOLDER.releaseWrite()
if (writeFile) {
ConfigHolder.CUSTOM_RECIPE_HOLDER.saveToDisk(doBackup)
@ -99,28 +99,28 @@ class AnvilCustomRecipe(
}
fun updateFromFile(){
this.exactCount = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getBoolean(
this.exactCount = ConfigHolder.CUSTOM_RECIPE_HOLDER.get().getBoolean(
"$name.$EXACT_COUNT_CONFIG",
DEFAULT_EXACT_COUNT_CONFIG
)
this.xpCostPerCraft = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getInt(
this.xpCostPerCraft = ConfigHolder.CUSTOM_RECIPE_HOLDER.get().getInt(
"$name.$XP_COST_CONFIG",
DEFAULT_XP_COST_CONFIG
)
// Update items
val leftItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getItemStack(
val leftItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.get().getItemStack(
"$name.$LEFT_ITEM_CONFIG",
DEFAULT_LEFT_ITEM_CONFIG
)
this.rightItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getItemStack(
this.rightItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.get().getItemStack(
"$name.$RIGHT_ITEM_CONFIG",
DEFAULT_RIGHT_ITEM_CONFIG
)
this.resultItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.config.getItemStack(
this.resultItem = ConfigHolder.CUSTOM_RECIPE_HOLDER.get().getItemStack(
"$name.$RESULT_ITEM_CONFIG",
DEFAULT_RESULT_ITEM_CONFIG
)

View file

@ -20,7 +20,7 @@ object UnitRepairUtil {
other: ItemStack?
): Double? {
if (other == null) return null
val config = ConfigHolder.UNIT_REPAIR_HOLDER.config
val config = ConfigHolder.UNIT_REPAIR_HOLDER.get()
// Get configuration section if exist
val otherName = other.type.name.lowercase()
var section = config.getConfigurationSection(otherName)