From c2223080f36886503f91b208a8ad5c4ab23aa443 Mon Sep 17 00:00:00 2001 From: alexcrea <42614139+alexcrea@users.noreply.github.com> Date: Sat, 15 Jun 2024 23:05:01 +0200 Subject: [PATCH] Better requirement system. --- .../alexcrea/cuanvil/update/AtomicUpdate.java | 50 +++++++++++++++---- .../update/requirement/ExistRequirement.java | 22 ++++++++ .../update/requirement/IsListRequirement.java | 25 ++++++++++ .../requirement/ListContainRequirement.java | 36 +++++++++++++ .../ListDontContainRequirement.java | 36 +++++++++++++ .../update/requirement/NullRequirement.java | 22 ++++++++ .../requirement/StringEqualRequirement.java | 49 ++++++++++++++++++ .../update/requirement/UpdateRequirement.java | 43 ++++++++++++++++ .../resources/version/1.20/versionUpgrade.yml | 4 ++ 9 files changed, 278 insertions(+), 9 deletions(-) create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/requirement/ExistRequirement.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/requirement/IsListRequirement.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/requirement/ListContainRequirement.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/requirement/ListDontContainRequirement.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/requirement/NullRequirement.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/requirement/StringEqualRequirement.java create mode 100644 src/main/java/xyz/alexcrea/cuanvil/update/requirement/UpdateRequirement.java diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/AtomicUpdate.java b/src/main/java/xyz/alexcrea/cuanvil/update/AtomicUpdate.java index 09c9dc4..5019ceb 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/update/AtomicUpdate.java +++ b/src/main/java/xyz/alexcrea/cuanvil/update/AtomicUpdate.java @@ -1,37 +1,41 @@ package xyz.alexcrea.cuanvil.update; +import io.delilaheve.CustomAnvil; +import io.delilaheve.util.ConfigOptions; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolderEnum; +import xyz.alexcrea.cuanvil.update.requirement.UpdateRequirement; +import java.util.ArrayList; import java.util.List; public class AtomicUpdate{ private static final String UPDATE_TYPE = "type"; private static final String CONFIG_TYPE_PATH = "config_type"; private static final String PATH_PATH = "path"; - private static final String EXPECTED_PATH = "expected"; + private static final String REQUIREMENT_PATH = "requirement"; private static final String VALUE_PATH = "value"; private final @NotNull AtomicUpdateType type; private final @NotNull ConfigHolderEnum configType; private final @NotNull String path; - private final @Nullable String expected; // Ignored on list + private final @NotNull List requirements; private final @Nullable String value; // Ignored on unset. not null if not unset public AtomicUpdate( @NotNull AtomicUpdateType type, @NotNull ConfigHolderEnum configType, @NotNull String path, - @Nullable String expected, // Ignored on list + @NotNull List requirements, @Nullable String value) { this.type = type; this.configType = configType; this.path = path; - this.expected = expected; + this.requirements = requirements; this.value = value; } @@ -39,7 +43,7 @@ public class AtomicUpdate{ String typeString = section.getString(UPDATE_TYPE); String configTypeString = section.getString(CONFIG_TYPE_PATH); String path = section.getString(PATH_PATH); - String expected = section.getString(EXPECTED_PATH); + List expected = section.getStringList(REQUIREMENT_PATH); String value = section.getString(VALUE_PATH); if((configTypeString == null) || @@ -62,8 +66,32 @@ public class AtomicUpdate{ configType = ConfigHolderEnum.valueOf(configTypeString.toUpperCase()); } catch (Exception e) { return null; } + List requirements = new ArrayList<>(); + for (String expectedPart : expected) { + UpdateRequirement requirement = UpdateRequirement.fromString(expectedPart); + if(requirement == null){ + if (!ConfigOptions.INSTANCE.getDebugLog()) { + CustomAnvil.instance.getLogger().warning("This message should not be displayed on Production. " + + "If it do display please check for update or create a new issue."); + CustomAnvil.instance.getLogger().warning("Here are the information of what happened: Atomic Update failed to parse requirement"); + } + CustomAnvil.instance.getLogger().warning("Unsuccessfully parsed requirement: " + expectedPart); - return new AtomicUpdate(type, configType, path, expected, value); + }else{ + requirements.add(requirement); + } + } + + return new AtomicUpdate(type, configType, path, requirements, value); + } + + public boolean isRequirementValidated(){ + for (UpdateRequirement requirement : requirements) { + if(!requirement.isRequirementFulfilled(this.configType.getConfigHolder())){ + return false; + } + } + return true; } // Is string equal can take null, it also checks if the content is equal but ignore case @@ -74,16 +102,20 @@ public class AtomicUpdate{ return val1.equalsIgnoreCase(val2); } - public boolean isExpected(boolean ignoreIfOperationIsDone){ + public boolean isExpected(@Deprecated boolean ignoreIfOperationIsDone){ + if(!isRequirementValidated()){ + return false; + } + String value; List values; switch (this.type){ case SET: value = this.configType.getConfigHolder().getConfig().getString(this.path); - return (isStringEqual(value, this.expected)) || (ignoreIfOperationIsDone && isStringEqual(value, this.value)); + return ignoreIfOperationIsDone && isStringEqual(value, this.value); case UNSET: value = this.configType.getConfigHolder().getConfig().getString(this.path); - return (isStringEqual(value, this.expected)) || (ignoreIfOperationIsDone && (value == null)); + return ignoreIfOperationIsDone && (value == null); case LIST_ADD: values = this.configType.getConfigHolder().getConfig().getStringList(this.path); return ignoreIfOperationIsDone || !values.contains(this.value); diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ExistRequirement.java b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ExistRequirement.java new file mode 100644 index 0000000..c282d07 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ExistRequirement.java @@ -0,0 +1,22 @@ +package xyz.alexcrea.cuanvil.update.requirement; + +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.config.ConfigHolder; + +public class ExistRequirement implements UpdateRequirement{ + + private final @NotNull String path; + protected ExistRequirement(@NotNull String path){ + this.path = path; + } + + @Override + public boolean isRequirementFulfilled(@NotNull ConfigHolder holder) { + return holder.getConfig().get(this.path) != null; + } + + public static ExistRequirement createNew(@NotNull String path) { + return new ExistRequirement(path); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/requirement/IsListRequirement.java b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/IsListRequirement.java new file mode 100644 index 0000000..0533483 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/IsListRequirement.java @@ -0,0 +1,25 @@ +package xyz.alexcrea.cuanvil.update.requirement; + +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.config.ConfigHolder; + +import java.util.List; + +public class IsListRequirement implements UpdateRequirement{ + + private final @NotNull String path; + protected IsListRequirement(@NotNull String path){ + this.path = path; + } + + @Override + public boolean isRequirementFulfilled(@NotNull ConfigHolder holder) { + List list = holder.getConfig().getList(this.path); + return list != null; + } + + public static IsListRequirement createNew(@NotNull String path) { + return new IsListRequirement(path); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ListContainRequirement.java b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ListContainRequirement.java new file mode 100644 index 0000000..eb8f678 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ListContainRequirement.java @@ -0,0 +1,36 @@ +package xyz.alexcrea.cuanvil.update.requirement; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; + +import java.util.List; + +public class ListContainRequirement implements UpdateRequirement{ + + private final @NotNull String path; + private final @NotNull String[] values; + protected ListContainRequirement(@NotNull String path, @NotNull String[] values){ + this.path = path; + this.values = values; + } + + @Override + public boolean isRequirementFulfilled(@NotNull ConfigHolder holder) { + List list = holder.getConfig().getStringList(this.path); + for (String value : this.values) { + if(!list.contains(value)){ + return false; + } + } + + return true; + } + + @Nullable + public static ListContainRequirement createNew(@NotNull String path, @NotNull String[] args) { + if(args.length == 0) return null; + return new ListContainRequirement(path, args); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ListDontContainRequirement.java b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ListDontContainRequirement.java new file mode 100644 index 0000000..983c26f --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/ListDontContainRequirement.java @@ -0,0 +1,36 @@ +package xyz.alexcrea.cuanvil.update.requirement; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; + +import java.util.List; + +public class ListDontContainRequirement implements UpdateRequirement{ + + private final @NotNull String path; + private final @NotNull String[] values; + protected ListDontContainRequirement(@NotNull String path, @NotNull String... values){ + this.path = path; + this.values = values; + } + + @Override + public boolean isRequirementFulfilled(@NotNull ConfigHolder holder) { + List list = holder.getConfig().getStringList(this.path); + for (String value : this.values) { + if(list.contains(value)){ + return false; + } + } + + return true; + } + + @Nullable + public static ListDontContainRequirement createNew(@NotNull String path, @NotNull String... args) { + if(args.length == 0) return null; + return new ListDontContainRequirement(path, args); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/requirement/NullRequirement.java b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/NullRequirement.java new file mode 100644 index 0000000..da23a35 --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/NullRequirement.java @@ -0,0 +1,22 @@ +package xyz.alexcrea.cuanvil.update.requirement; + +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.config.ConfigHolder; + +public class NullRequirement implements UpdateRequirement{ + + private final @NotNull String path; + protected NullRequirement(@NotNull String path){ + this.path = path; + } + + @Override + public boolean isRequirementFulfilled(@NotNull ConfigHolder holder) { + return holder.getConfig().get(this.path) == null; + } + + public static NullRequirement createNew(@NotNull String path) { + return new NullRequirement(path); + } + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/requirement/StringEqualRequirement.java b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/StringEqualRequirement.java new file mode 100644 index 0000000..da344dd --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/StringEqualRequirement.java @@ -0,0 +1,49 @@ +package xyz.alexcrea.cuanvil.update.requirement; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.config.ConfigHolder; + +public class StringEqualRequirement implements UpdateRequirement { + + private final @NotNull String path; + private final @NotNull String equalTo; + private final boolean ignoreCase; + protected StringEqualRequirement( + @NotNull String path, + @NotNull String equalTo, + boolean ignoreCase){ + this.path = path; + this.equalTo = equalTo; + this.ignoreCase = ignoreCase; + } + + @Override + public boolean isRequirementFulfilled(@NotNull ConfigHolder holder) { + String value = holder.getConfig().getString(this.path); + if(this.ignoreCase){ + return equalTo.equalsIgnoreCase(value); + }else{ + return equalTo.equals(value); + } + } + + + @Nullable + public static StringEqualRequirement createNew( + @NotNull String path, + @NotNull String[] args, + boolean ignoreCase) { + if(args.length == 0) return null; + + StringBuilder value = new StringBuilder(); + value.append(args[0]); + for (int i = 1; i < args.length; i++) { + value.append(" ").append(args[i]); + } + + return new StringEqualRequirement(path, value.toString(), ignoreCase); + } + + +} diff --git a/src/main/java/xyz/alexcrea/cuanvil/update/requirement/UpdateRequirement.java b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/UpdateRequirement.java new file mode 100644 index 0000000..28a54fa --- /dev/null +++ b/src/main/java/xyz/alexcrea/cuanvil/update/requirement/UpdateRequirement.java @@ -0,0 +1,43 @@ +package xyz.alexcrea.cuanvil.update.requirement; + +import io.delilaheve.CustomAnvil; +import org.jetbrains.annotations.NotNull; +import xyz.alexcrea.cuanvil.config.ConfigHolder; + +public interface UpdateRequirement { + + boolean isRequirementFulfilled(@NotNull ConfigHolder holder); + + static UpdateRequirement fromString(String value){ + // Format [path requirementType arguments] + String[] args = value.split(" "); + if(args.length < 2) return null; + String path = args[0]; + String type = args[1]; + + String[] newArgs = new String[args.length-2]; + System.arraycopy(args, 2, newArgs, 0, args.length - 2); + + switch (type.toLowerCase()){ + case "exist": + return ExistRequirement.createNew(path); + case "is_list": + return IsListRequirement.createNew(path); + case "list_contain": + return ListContainRequirement.createNew(path, newArgs); + case "list_dont_contain": + return ListDontContainRequirement.createNew(path, newArgs); + case "null": + return NullRequirement.createNew(path); + case "equal": + return StringEqualRequirement.createNew(path, newArgs, true); + case "equal_case": + return StringEqualRequirement.createNew(path, newArgs, false); + + default: + CustomAnvil.Companion.log("Can't find requirement type \"" + type + "\""); + return null; + } + + } +} diff --git a/src/main/resources/version/1.20/versionUpgrade.yml b/src/main/resources/version/1.20/versionUpgrade.yml index ffe2f78..0f41dba 100644 --- a/src/main/resources/version/1.20/versionUpgrade.yml +++ b/src/main/resources/version/1.20/versionUpgrade.yml @@ -3,10 +3,14 @@ addNewItems: addPiglinHead: type: add_list config_type: item_group + requirement: + - "wearable.items is_list" path: wearable.items value: piglin_head addBrush: type: list_add config_type: item_group + requirement: + - "can_unbreak.items is_list" path: can_unbreak.items value: brush