Add multiple add/remove for list.

Also add 1.21 update.
This commit is contained in:
alexcrea 2024-06-16 00:42:27 +02:00
parent c2223080f3
commit cbb3bb5a54
No known key found for this signature in database
GPG key ID: 43FD265DB0DBF91F
12 changed files with 270 additions and 60 deletions

View file

@ -7,68 +7,66 @@ 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.update.requirement.UpdateRequirement; import xyz.alexcrea.cuanvil.update.requirement.UpdateRequirement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
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 PATH_PATH = "path"; private static final String PATH_PATH = "path";
private static final String REQUIREMENT_PATH = "requirement"; private static final String REQUIREMENT_PATH = "requirement";
private static final String VALUE_PATH = "value"; private static final String VALUE_PATH = "value";
private static final String MULTIPLES_VALUES_SEPARATOR = ",";
private final @NotNull UpdatePart parent;
private final @NotNull AtomicUpdateType type; private final @NotNull AtomicUpdateType type;
private final @NotNull ConfigHolderEnum configType;
private final @NotNull String path; private final @NotNull String path;
private final @NotNull List<UpdateRequirement> requirements; 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 UpdatePart parent,
@NotNull AtomicUpdateType type, @NotNull AtomicUpdateType type,
@NotNull ConfigHolderEnum configType,
@NotNull String path, @NotNull String path,
@NotNull List<UpdateRequirement> requirements, @NotNull List<UpdateRequirement> requirements,
@Nullable String value) { @Nullable String value) {
this.parent = parent;
this.type = type; this.type = type;
this.configType = configType;
this.path = path; this.path = path;
this.requirements = requirements; this.requirements = requirements;
this.value = value; this.value = value;
} }
public static @Nullable AtomicUpdate fromConfig(@NotNull ConfigurationSection section){ public static @Nullable AtomicUpdate fromConfig(
@NotNull UpdatePart parent,
@NotNull ConfigurationSection section){
String typeString = section.getString(UPDATE_TYPE); String typeString = section.getString(UPDATE_TYPE);
String configTypeString = section.getString(CONFIG_TYPE_PATH); String path = parent.absoluteRestrictionPath(section.getString(PATH_PATH));
String path = section.getString(PATH_PATH);
List<String> expected = section.getStringList(REQUIREMENT_PATH); List<String> expected = section.getStringList(REQUIREMENT_PATH);
String value = section.getString(VALUE_PATH); String value = section.getString(VALUE_PATH);
if((configTypeString == null) || if((path == null)){
(typeString == null) ||
(path == null)){
return null; return null;
} }
AtomicUpdateType type; AtomicUpdateType type;
if(typeString == null){
type = parent.getDefaultType();
}else{
try { try {
type = AtomicUpdateType.valueOf(typeString.toUpperCase()); type = AtomicUpdateType.valueOf(typeString.toUpperCase());
} catch (Exception e) { return null; } } catch (Exception e) { return null; }
}
if(type != AtomicUpdateType.UNSET && value == null){ if(type != AtomicUpdateType.UNSET && value == null){
return null; return null;
} }
ConfigHolderEnum configType;
try {
configType = ConfigHolderEnum.valueOf(configTypeString.toUpperCase());
} catch (Exception e) { return null; }
List<UpdateRequirement> requirements = new ArrayList<>(); List<UpdateRequirement> requirements = new ArrayList<>();
for (String expectedPart : expected) { for (String expectedPart : expected) {
UpdateRequirement requirement = UpdateRequirement.fromString(expectedPart); UpdateRequirement requirement = UpdateRequirement.fromString(expectedPart, parent);
if(requirement == null){ if(requirement == null){
if (!ConfigOptions.INSTANCE.getDebugLog()) { if (!ConfigOptions.INSTANCE.getDebugLog()) {
CustomAnvil.instance.getLogger().warning("This message should not be displayed on Production. " + CustomAnvil.instance.getLogger().warning("This message should not be displayed on Production. " +
@ -82,12 +80,12 @@ public class AtomicUpdate{
} }
} }
return new AtomicUpdate(type, configType, path, requirements, value); return new AtomicUpdate(parent, type, path, requirements, value);
} }
public boolean isRequirementValidated(){ public boolean isRequirementValidated(){
for (UpdateRequirement requirement : requirements) { for (UpdateRequirement requirement : requirements) {
if(!requirement.isRequirementFulfilled(this.configType.getConfigHolder())){ if(!requirement.isRequirementFulfilled(getConfigHolder())){
return false; return false;
} }
} }
@ -103,26 +101,43 @@ public class AtomicUpdate{
} }
public boolean isExpected(@Deprecated boolean ignoreIfOperationIsDone){ public boolean isExpected(@Deprecated boolean ignoreIfOperationIsDone){
if(!isRequirementValidated()){ if(!isRequirementValidated()) return false;
return false; if(ignoreIfOperationIsDone) return true;
}
String value; String value;
List<String> values; List<String> list;
String[] values;
switch (this.type){ switch (this.type){
case SET: case SET:
value = this.configType.getConfigHolder().getConfig().getString(this.path); value = getConfigHolder().getConfig().getString(this.path);
return ignoreIfOperationIsDone && isStringEqual(value, this.value); return !isStringEqual(value, this.value);
case UNSET: case UNSET:
value = this.configType.getConfigHolder().getConfig().getString(this.path); return getConfigHolder().getConfig().contains(this.path);
return ignoreIfOperationIsDone && (value == null);
case LIST_ADD: case LIST_ADD:
values = this.configType.getConfigHolder().getConfig().getStringList(this.path); list = getConfigHolder().getConfig().getStringList(this.path);
return ignoreIfOperationIsDone || !values.contains(this.value); return !list.contains(this.value);
case LIST_ADD_MULTIPLES:
list = getConfigHolder().getConfig().getStringList(this.path);
assert this.value != null;
values = this.value.split(MULTIPLES_VALUES_SEPARATOR);
for (String value2 : values) {
if(list.contains(value2)) return false;
}
return true;
case LIST_REMOVE: case LIST_REMOVE:
values = this.configType.getConfigHolder().getConfig().getStringList(this.path); list = getConfigHolder().getConfig().getStringList(this.path);
return ignoreIfOperationIsDone || values.contains(this.value); return list.contains(this.value);
case LIST_REMOVE_MULTIPLES:
list = getConfigHolder().getConfig().getStringList(this.path);
assert this.value != null;
values = this.value.split(MULTIPLES_VALUES_SEPARATOR);
for (String value2 : values) {
if(!list.contains(value2)) return false;
}
return true;
} }
return false; return false;
@ -133,8 +148,7 @@ public class AtomicUpdate{
return false; return false;
} }
ConfigHolder configHolder = this.configType.getConfigHolder(); FileConfiguration config = getConfigHolder().getConfig();
FileConfiguration config = configHolder.getConfig();
List<String> values; List<String> values;
switch (this.type){ switch (this.type){
@ -144,19 +158,37 @@ public class AtomicUpdate{
case UNSET: case UNSET:
config.set(this.path, null); config.set(this.path, null);
break; break;
case LIST_ADD: case LIST_ADD:
values = config.getStringList(this.path); values = config.getStringList(this.path);
values.add(this.value); values.add(this.value);
config.set(this.path, this.value); config.set(this.path, this.value);
break; break;
case LIST_ADD_MULTIPLES:
values = config.getStringList(this.path);
assert this.value != null;
values.addAll(Arrays.asList(this.value.split(MULTIPLES_VALUES_SEPARATOR)));
config.set(this.path, this.value);
break;
case LIST_REMOVE: case LIST_REMOVE:
values = config.getStringList(this.path); values = config.getStringList(this.path);
values.remove(this.value); values.remove(this.value);
config.set(this.path, this.value); config.set(this.path, this.value);
break; break;
case LIST_REMOVE_MULTIPLES:
values = config.getStringList(this.path);
assert this.value != null;
values.removeAll(Arrays.asList(this.value.split(MULTIPLES_VALUES_SEPARATOR)));
config.set(this.path, this.value);
break;
} }
return true; return true;
} }
public ConfigHolder getConfigHolder(){
return this.parent.getUsedConfig().getConfigHolder();
}
} }

View file

@ -5,6 +5,8 @@ public enum AtomicUpdateType {
SET, SET,
UNSET, UNSET,
LIST_ADD, LIST_ADD,
LIST_REMOVE LIST_ADD_MULTIPLES,
LIST_REMOVE,
LIST_REMOVE_MULTIPLES,
} }

View file

@ -1,6 +1,5 @@
package xyz.alexcrea.cuanvil.update; package xyz.alexcrea.cuanvil.update;
import jdk.incubator.vector.VectorShape;
import kotlin.Pair; import kotlin.Pair;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
@ -13,10 +12,12 @@ import java.io.InputStream;
import java.util.*; import java.util.*;
public class UpdateManager { public class UpdateManager {
private final static Version MAX_KNOW_MINECRAFT_VERSION = new Version(1, 20, 6); private final static Version MAX_KNOW_MINECRAFT_VERSION = new Version(1, 21, 0);
public final static String MINECRAFT_VERSION_PATH = "lowMinecraftVersion";
public final static String PLUGIN_VERSION_PATH = "configVersion";
private final static String UPDATE_FOLDER = "version"; private final static String UPDATE_FOLDER = "version";
private final static String VERSION_LIST_RESSOUCE = UPDATE_FOLDER+"/versionList.txt"; private final static String VERSION_LIST_RESSOUCE = UPDATE_FOLDER+"/minecraftVersions.txt";
private List<Version> minecraftVersionList; private List<Version> minecraftVersionList;
private Version minecraftVersion; private Version minecraftVersion;
@ -58,15 +59,15 @@ public class UpdateManager {
// Should work //TODO test for paper and spigot // Should work //TODO test for paper and spigot
String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0]; String versionString = Bukkit.getServer().getBukkitVersion().split("-")[0];
System.out.println(versionString + " ; " + Bukkit.getServer().getBukkitVersion()); //TESTING System.out.println(versionString + " ; " + Bukkit.getServer().getBukkitVersion()); //TESTING (for paper & spigot)
this.minecraftVersion = Version.versionOf(versionString); this.minecraftVersion = Version.versionOf(versionString);
if(this.minecraftVersion == null) return; if(this.minecraftVersion == null) return;
this.usedMinecraftVersion = firstValidVersion(this.minecraftVersion); this.usedMinecraftVersion = firstValidVersion(this.minecraftVersion);
FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig(); FileConfiguration config = ConfigHolder.DEFAULT_CONFIG.getConfig();
String lastUsedMinecraftVersionString = config.getString("lowestMinecraftVersion"); String lastUsedMinecraftVersionString = config.getString(MINECRAFT_VERSION_PATH);
String configVersionString = config.getString("configVersion"); String configVersionString = config.getString(PLUGIN_VERSION_PATH);
this.lastUsedMinecraftVersion = Version.versionOf(lastUsedMinecraftVersionString); this.lastUsedMinecraftVersion = Version.versionOf(lastUsedMinecraftVersionString);
this.configVersion = Version.versionOf(configVersionString); this.configVersion = Version.versionOf(configVersionString);
@ -78,7 +79,7 @@ public class UpdateManager {
} }
public Version firstValidVersion(Version toFind){ public Version firstValidVersion(Version toFind){
for (Version version : this.minecraftVersionList) { // Assume sorted for (Version version : this.minecraftVersionList) { // Assume sorted by readMinecraftVersionList
if(version.compareTo(toFind) >= 0) return version; if(version.compareTo(toFind) >= 0) return version;
} }
return null; return null;

View file

@ -0,0 +1,63 @@
package xyz.alexcrea.cuanvil.update;
import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolderEnum;
import java.util.ArrayList;
import java.util.List;
public class UpdatePart {
private static final String DEFAULT_TYPE_PATH = "default_type";
private static final String CONFIG_TYPE_PATH = "config_file";
private static final String BASE_PATH = "base_path";
private static final String RESTRICTION_BASE_PATH = "restriction_base_path";
private final @NotNull String name;
private final @NotNull String message;
private final @NotNull AtomicUpdateType defaultType;
private final @NotNull ConfigHolderEnum usedConfig;
private final @NotNull String configRelativePath;
private final @NotNull String restrictionRelativePath;
private final @NotNull List<AtomicUpdate> updates;
private UpdatePart(
@NotNull String name,
@NotNull String message,
@NotNull AtomicUpdateType defaultType,
@NotNull ConfigHolderEnum usedConfig,
@NotNull String configRelativePath,
@NotNull String restrictionRelativePath
){
this.name = name;
this.message = message;
this.defaultType = defaultType;
this.usedConfig = usedConfig;
if(configRelativePath.isEmpty()) this.configRelativePath = "";
else this.configRelativePath = configRelativePath+".";
if(restrictionRelativePath.isEmpty()) this.restrictionRelativePath = "";
else this.restrictionRelativePath = restrictionRelativePath+".";
this.updates = new ArrayList<>();
}
@NotNull
public ConfigHolderEnum getUsedConfig() {
return this.usedConfig;
}
@NotNull
public AtomicUpdateType getDefaultType() {
return defaultType;
}
public String absoluteConfigPath(String path){
return this.configRelativePath + path;
}
public String absoluteRestrictionPath(String path){
return this.restrictionRelativePath + path;
}
}

View file

@ -1,7 +0,0 @@
package xyz.alexcrea.cuanvil.update;
public class UpdateResource {
}

View file

@ -3,16 +3,17 @@ package xyz.alexcrea.cuanvil.update.requirement;
import io.delilaheve.CustomAnvil; import io.delilaheve.CustomAnvil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.update.UpdatePart;
public interface UpdateRequirement { public interface UpdateRequirement {
boolean isRequirementFulfilled(@NotNull ConfigHolder holder); boolean isRequirementFulfilled(@NotNull ConfigHolder holder);
static UpdateRequirement fromString(String value){ static UpdateRequirement fromString(String value, UpdatePart parent){
// Format [path requirementType arguments] // Format: path requirementType [arguments]
String[] args = value.split(" "); String[] args = value.split(" ");
if(args.length < 2) return null; if(args.length < 2) return null;
String path = args[0]; String path = parent.absoluteRestrictionPath(args[0]);
String type = args[1]; String type = args[1];
String[] newArgs = new String[args.length-2]; String[] newArgs = new String[args.length-2];

View file

@ -1,15 +1,14 @@
addNewItems: addNewItems:
message: "Add 1.20 items" message: "Add 1.20 items"
config_file: item_group
addPiglinHead: addPiglinHead:
type: add_list type: list_add
config_type: item_group
requirement: requirement:
- "wearable.items is_list" - "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
requirement: requirement:
- "can_unbreak.items is_list" - "can_unbreak.items is_list"
path: can_unbreak.items path: can_unbreak.items

View file

@ -0,0 +1,119 @@
add_mace_group:
message: "Add mace group"
config_file: item_group
default_type: set
base_path: "mace"
set_mace_type:
path: type
value: include
add_mace:
type: list_add
path: items
value: mace
add_density:
message: "Add density enchantment conflict"
config_file: conflict
default_type: list_add
base_path: "restriction_density"
set_enchant_list:
path: enchantments
value: density
set_mace_allowed:
path: notAffectedGroups
value: mace
add_breach:
message: "Add breach enchantment conflict"
config_file: conflict
default_type: list_add
base_path: "restriction_breach"
set_enchant_list:
path: enchantments
value: breach
set_mace_allowed:
path: notAffectedGroups
value: mace
add_wind_burst:
message: "Add wind burst enchantment conflict"
config_file: conflict
default_type: list_add
base_path: "restriction_wind_burst"
set_enchant_list:
path: enchantments
value: wind_burst
set_mace_allowed:
path: notAffectedGroups
value: mace
add_other_enchants_for_mace:
message: "Add mace to other allowed enchants"
config_file: conflict
default_type: list_add
add_mace_to_fire_aspect:
restrictions: ["restriction_fire_aspect.notAffectedGroups is_list"]
path: restriction_fire_aspect.notAffectedGroups
value: mace
add_mace_to_smite:
restrictions: ["restriction_smite.notAffectedGroups is_list"]
path: restriction_smite.notAffectedGroups
value: mace
add_mace_to_bane_of_arthropods:
restrictions: ["restriction_bane_of_arthropods.notAffectedGroups is_list"]
path: restriction_bane_of_arthropods.notAffectedGroups
value: mace
add_mace_conflict:
message: "Add mace enchantment conflict with breach, density, smite and bane of arthropods."
config_file: conflict
default_type: set
base_path: "mace_enchant_conflict"
add_enchants:
type: list_add_multiples
path: enchantments
value: "density,breach,smite,bane_of_arthropods"
set_max_enchant_before_conflict:
path: maxEnchantmentBeforeConflict
value: 1
add_level_limits:
message: "Add level limit for density, breach and wind burst"
config_file: default
default_type: set
base_path: "enchant_limits"
set_density_level_limit:
path: density
value: 5
set_breach_level_limit:
path: breach
value: 4
set_wind_burst_level_limit:
path: wind_burst
value: 3
add_enchant_values:
message: "Add enchant values for density, breach and wind burst."
config_file: default
default_type: set
base_path: "mace_enchant_conflict"
set_density_item_value:
path: density.item
value: 1
set_breach_item_value:
path: breach.item
value: 4
set_wind_burst_item_value:
path: wind_burst.item
value: 4
set_density_book_value:
path: density.book
value: 1
set_breach_book_value:
path: breach.book
value: 2
set_wind_burst_book_value:
path: wind_burst.book
value: 2