Better requirement system.

This commit is contained in:
alexcrea 2024-06-15 23:05:01 +02:00
parent 9e53755c0c
commit c2223080f3
No known key found for this signature in database
GPG key ID: 43FD265DB0DBF91F
9 changed files with 278 additions and 9 deletions

View file

@ -1,37 +1,41 @@
package xyz.alexcrea.cuanvil.update; package xyz.alexcrea.cuanvil.update;
import io.delilaheve.CustomAnvil;
import io.delilaheve.util.ConfigOptions;
import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.config.ConfigHolderEnum; import xyz.alexcrea.cuanvil.config.ConfigHolderEnum;
import xyz.alexcrea.cuanvil.update.requirement.UpdateRequirement;
import java.util.ArrayList;
import java.util.List; import java.util.List;
public class AtomicUpdate{ public class AtomicUpdate{
private static final String UPDATE_TYPE = "type"; private static final String UPDATE_TYPE = "type";
private static final String CONFIG_TYPE_PATH = "config_type"; private static final String CONFIG_TYPE_PATH = "config_type";
private static final String PATH_PATH = "path"; 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 static final String VALUE_PATH = "value";
private final @NotNull AtomicUpdateType type; private final @NotNull AtomicUpdateType type;
private final @NotNull ConfigHolderEnum configType; private final @NotNull ConfigHolderEnum configType;
private final @NotNull String path; private final @NotNull String path;
private final @Nullable String expected; // Ignored on list private final @NotNull List<UpdateRequirement> requirements;
private final @Nullable String value; // Ignored on unset. not null if not unset private final @Nullable String value; // Ignored on unset. not null if not unset
public AtomicUpdate( public AtomicUpdate(
@NotNull AtomicUpdateType type, @NotNull AtomicUpdateType type,
@NotNull ConfigHolderEnum configType, @NotNull ConfigHolderEnum configType,
@NotNull String path, @NotNull String path,
@Nullable String expected, // Ignored on list @NotNull List<UpdateRequirement> requirements,
@Nullable String value) { @Nullable String value) {
this.type = type; this.type = type;
this.configType = configType; this.configType = configType;
this.path = path; this.path = path;
this.expected = expected; this.requirements = requirements;
this.value = value; this.value = value;
} }
@ -39,7 +43,7 @@ public class AtomicUpdate{
String typeString = section.getString(UPDATE_TYPE); String typeString = section.getString(UPDATE_TYPE);
String configTypeString = section.getString(CONFIG_TYPE_PATH); String configTypeString = section.getString(CONFIG_TYPE_PATH);
String path = section.getString(PATH_PATH); String path = section.getString(PATH_PATH);
String expected = section.getString(EXPECTED_PATH); List<String> expected = section.getStringList(REQUIREMENT_PATH);
String value = section.getString(VALUE_PATH); String value = section.getString(VALUE_PATH);
if((configTypeString == null) || if((configTypeString == null) ||
@ -62,8 +66,32 @@ public class AtomicUpdate{
configType = ConfigHolderEnum.valueOf(configTypeString.toUpperCase()); configType = ConfigHolderEnum.valueOf(configTypeString.toUpperCase());
} catch (Exception e) { return null; } } catch (Exception e) { return null; }
List<UpdateRequirement> 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 // 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); return val1.equalsIgnoreCase(val2);
} }
public boolean isExpected(boolean ignoreIfOperationIsDone){ public boolean isExpected(@Deprecated boolean ignoreIfOperationIsDone){
if(!isRequirementValidated()){
return false;
}
String value; String value;
List<String> values; List<String> values;
switch (this.type){ switch (this.type){
case SET: case SET:
value = this.configType.getConfigHolder().getConfig().getString(this.path); 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: case UNSET:
value = this.configType.getConfigHolder().getConfig().getString(this.path); value = this.configType.getConfigHolder().getConfig().getString(this.path);
return (isStringEqual(value, this.expected)) || (ignoreIfOperationIsDone && (value == null)); return ignoreIfOperationIsDone && (value == null);
case LIST_ADD: case LIST_ADD:
values = this.configType.getConfigHolder().getConfig().getStringList(this.path); values = this.configType.getConfigHolder().getConfig().getStringList(this.path);
return ignoreIfOperationIsDone || !values.contains(this.value); return ignoreIfOperationIsDone || !values.contains(this.value);

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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<String> 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);
}
}

View file

@ -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<String> 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);
}
}

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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;
}
}
}

View file

@ -3,10 +3,14 @@ addNewItems:
addPiglinHead: addPiglinHead:
type: add_list type: add_list
config_type: item_group config_type: item_group
requirement:
- "wearable.items is_list"
path: wearable.items path: wearable.items
value: piglin_head value: piglin_head
addBrush: addBrush:
type: list_add type: list_add
config_type: item_group config_type: item_group
requirement:
- "can_unbreak.items is_list"
path: can_unbreak.items path: can_unbreak.items
value: brush value: brush