CustomAnvil/src/main/java/xyz/alexcrea/cuanvil/api/ConflictAPI.java
2024-11-18 07:29:51 +01:00

196 lines
6.9 KiB
Java

package xyz.alexcrea.cuanvil.api;
import io.delilaheve.CustomAnvil;
import org.bukkit.NamespacedKey;
import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.dependency.DependencyManager;
import xyz.alexcrea.cuanvil.group.EnchantConflictGroup;
import xyz.alexcrea.cuanvil.gui.config.global.EnchantConflictGui;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Custom Anvil api for conflict registry.
*/
@SuppressWarnings("unused")
public class ConflictAPI {
private ConflictAPI() {
}
private static Object saveChangeTask = null;
private static Object reloadChangeTask = null;
/**
* Write and add a conflict.
* Will not write the conflict if it already exists.
* Will not be successful if the conflict is empty.
*
* @param builder The conflict builder to be based on
* @return True if successful.
*/
public static boolean addConflict(@NotNull ConflictBuilder builder) {
return addConflict(builder, false);
}
/**
* Write and add a conflict.
* Will not write the conflict if it already exists.
* Will not be successful if the conflict is empty.
*
* @param builder The conflict builder to be based on
* @param overrideDeleted If we should write even if the conflict was previously deleted.
* @return True if successful.
*/
public static boolean addConflict(@NotNull ConflictBuilder builder, boolean overrideDeleted) {
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig();
// Test if conflict can be added
if (!overrideDeleted && ConfigHolder.CONFLICT_HOLDER.isDeleted(builder.getName())) return false;
if (config.contains(builder.getName())) return false;
if (!writeConflict(builder, false)) return false;
EnchantConflictGroup conflict = builder.build();
// Register conflict
ConfigHolder.CONFLICT_HOLDER.getConflictManager().addConflict(conflict);
// Add conflict to gui
EnchantConflictGui conflictGui = EnchantConflictGui.getCurrentInstance();
if (conflictGui != null) conflictGui.updateValueForGeneric(conflict, true);
return true;
}
/**
* Write a conflict to the config file and plan an update of conflicts.
* <p>
* You may want to use {@link #addConflict(ConflictBuilder)} instead as it is more performance in most case as this function will reload every conflict.
*
* @param builder the builder
* @return true if was written successfully.
*/
public static boolean writeConflict(@NotNull ConflictBuilder builder) {
return writeConflict(builder, true);
}
/**
* Write a conflict to the config file.
* <p>
* You should use {@link #addConflict(ConflictBuilder)} or {@link #writeConflict(ConflictBuilder)} instead
*
* @param builder The builder
* @param updatePlanned If we should plan a global update for conflicts
* @return true if was written successfully.
*/
public static boolean writeConflict(@NotNull ConflictBuilder builder, boolean updatePlanned) {
FileConfiguration config = ConfigHolder.CONFLICT_HOLDER.getConfig();
String name = builder.getName();
if (name.contains(".")) {
CustomAnvil.instance.getLogger().warning("Conflict " + name + " contain \".\" in its name but should not. this conflict is ignored.");
logConflictOrigin(builder);
return false;
}
String basePath = name + ".";
List<String> enchantments = extractEnchantments(builder);
List<String> excludedGroups = new ArrayList<>(builder.getExcludedGroupNames());
if (!enchantments.isEmpty()) config.set(basePath + "enchantments", enchantments);
if (!excludedGroups.isEmpty()) config.set(basePath + "notAffectedGroups", excludedGroups);
if (builder.getMaxBeforeConflict() > 0)
config.set(basePath + "maxEnchantmentBeforeConflict", builder.getMaxBeforeConflict());
if (!config.isConfigurationSection(name)) return false;
prepareSaveTask();
if (updatePlanned) prepareUpdateTask();
return true;
}
/**
* Extract every enchantment names from a builder.
*
* @param builder The builder storing the enchantments
* @return Builder's stored enchantment.
*/
@NotNull
private static List<String> extractEnchantments(@NotNull ConflictBuilder builder) {
List<String> result = new ArrayList<>(builder.getEnchantmentNames());
for (NamespacedKey enchantmentKey : builder.getEnchantmentKeys()) {
result.add(enchantmentKey.toString());
}
return result;
}
/**
* Remove a conflict.
*
* @param conflict The conflict to remove
* @return True if successful.
*/
public static boolean removeConflict(@NotNull EnchantConflictGroup conflict) {
// Remove from registry
ConfigHolder.CONFLICT_HOLDER.getConflictManager().removeConflict(conflict);
// Delete and save to file
ConfigHolder.CONFLICT_HOLDER.delete(conflict.getName());
prepareSaveTask();
// Remove from gui
EnchantConflictGui conflictGui = EnchantConflictGui.getCurrentInstance();
if (conflictGui != null) conflictGui.removeGeneric(conflict);
return true;
}
/**
* Prepare a task to save conflict configuration.
*/
private static void prepareSaveTask() {
if (saveChangeTask != null) return;
saveChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, () -> {
ConfigHolder.CONFLICT_HOLDER.saveToDisk(true);
saveChangeTask = null;
});
}
/**
* Prepare a task to reload every conflict.
*/
private static void prepareUpdateTask() {
if (reloadChangeTask != null) return;
reloadChangeTask = DependencyManager.scheduler.scheduleGlobally(CustomAnvil.instance, () -> {
ConfigHolder.CONFLICT_HOLDER.reload();
EnchantConflictGui conflictGui = EnchantConflictGui.getCurrentInstance();
if (conflictGui != null) conflictGui.reloadValues();
reloadChangeTask = null;
});
}
static void logConflictOrigin(@NotNull ConflictBuilder builder) {
CustomAnvil.instance.getLogger().warning("Conflict " + builder.getName() + " came from " + builder.getSourceName() + ".");
}
/**
* Get every registered conflict.
*
* @return An immutable collection of conflict.
*/
@NotNull
public static List<EnchantConflictGroup> getRegisteredConflict() {
List<EnchantConflictGroup> mutableList = ConfigHolder.CONFLICT_HOLDER.getConflictManager().getConflictList();
return Collections.unmodifiableList(mutableList);
}
}