diff --git a/.github/workflows/buildtools.sh b/.github/workflows/buildtools.sh
index b07819f..b9f1473 100644
--- a/.github/workflows/buildtools.sh
+++ b/.github/workflows/buildtools.sh
@@ -28,4 +28,5 @@ checkVersion () {
checkVersion "1.19" "17"
checkVersion "1.19.3" "17"
checkVersion "1.19.4" "17"
-checkVersion "1.20" "17"
\ No newline at end of file
+checkVersion "1.20.1" "17"
+checkVersion "1.20.2" "17"
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 5145f2b..d0f41fc 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,6 @@
-
+
4.0.0
net.imprex
@@ -13,7 +15,8 @@
GitHub
- https://github.com/Imprex-Development/zero-inventory-problems/issues
+
+ https://github.com/Imprex-Development/zero-inventory-problems/issues
@@ -29,20 +32,51 @@
1.2.7
1.2.4
- 17
- 17
- 17
-
UTF-8
spigot-repo
+ Spigot Repositories
https://hub.spigotmc.org/nexus/content/groups/public/
+
+ minecraft-libraries
+ Minecraft Libraries
+ https://libraries.minecraft.net
+
+
+
+
+ com.mojang
+ brigadier
+ 1.0.18
+ provided
+
+
+ io.netty
+ netty-buffer
+ 4.1.68.Final
+ provided
+
+
+ org.bstats
+ bstats-base
+ 3.0.2
+ provided
+
+
+ com.google.code.gson
+ gson
+ 2.10.1
+ provided
+
+
+
+
@@ -119,9 +153,9 @@
- zip-plugin
zip-api
+ zip-base
zip-nms
- zip-common
+ zip-bukkit
\ No newline at end of file
diff --git a/zip-api/src/main/java/net/imprex/zip/api/ZIPHandler.java b/zip-api/src/main/java/net/imprex/zip/api/ZIPHandler.java
index 7b93da3..16d1c4f 100644
--- a/zip-api/src/main/java/net/imprex/zip/api/ZIPHandler.java
+++ b/zip-api/src/main/java/net/imprex/zip/api/ZIPHandler.java
@@ -1,17 +1,21 @@
package net.imprex.zip.api;
+import java.util.concurrent.CompletableFuture;
+
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
public interface ZIPHandler {
- void save(ZIPBackpack backpack);
+ CompletableFuture save(ZIPBackpack backpack);
+
+ CompletableFuture getBackpack(ZIPUniqueId id);
- ZIPBackpack getBackpack(ZIPUniqueId id);
+ CompletableFuture getBackpack(ItemStack item);
- ZIPBackpack getBackpack(Inventory inventory);
+ ZIPBackpack getLoadedBackpack(Inventory inventory);
- ZIPBackpack getBackpack(ItemStack item);
+ ZIPUniqueId getBackpackId(ItemStack item);
boolean isBackpack(ItemStack item);
}
diff --git a/zip-base/pom.xml b/zip-base/pom.xml
new file mode 100644
index 0000000..28d697f
--- /dev/null
+++ b/zip-base/pom.xml
@@ -0,0 +1,43 @@
+
+ 4.0.0
+
+
+ net.imprex
+ zip
+ ${revision}
+
+
+ zip-base
+ jar
+
+
+
+ net.imprex
+ zip-api
+ ${revision}
+ compile
+
+
+ com.mojang
+ brigadier
+ compile
+
+
+ org.bstats
+ bstats-base
+ compile
+
+
+ io.netty
+ netty-buffer
+ compile
+
+
+ com.google.code.gson
+ gson
+ compile
+
+
+
\ No newline at end of file
diff --git a/zip-base/simple/example.yml b/zip-base/simple/example.yml
new file mode 100644
index 0000000..2a2d9a8
--- /dev/null
+++ b/zip-base/simple/example.yml
@@ -0,0 +1,29 @@
+version: 4
+testBoolean: false # Just some testing
+general:
+ # Change this value to true to enable update notifications.
+ checkForUpdates: true
+ # Change a test value to someting else
+ #
+ # Just added some space
+ #
+ testCountKey xD: 60
+ # Set your username
+ username: INGRIM
+ randomList:
+ - Just
+ - Some
+ - Random
+ - Input
+exampleMap:
+ a:
+ - java
+ - html
+ - csharp
+ b:
+ - lua
+ - python
+ - scss
+ c:
+ - html
+ - css
diff --git a/zip-base/src/main/java/net/imprex/command/ArgumentBuilder.java b/zip-base/src/main/java/net/imprex/command/ArgumentBuilder.java
new file mode 100644
index 0000000..fdcfeea
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/command/ArgumentBuilder.java
@@ -0,0 +1,29 @@
+package net.imprex.command;
+
+import com.mojang.brigadier.arguments.ArgumentType;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import com.mojang.brigadier.builder.RequiredArgumentBuilder;
+import com.mojang.brigadier.context.CommandContext;
+
+public class ArgumentBuilder {
+
+ public static final int RESULT_OK = 1;
+
+ public static LiteralArgumentBuilder literal(String name) {
+ return LiteralArgumentBuilder.literal(name);
+ }
+
+ public static RequiredArgumentBuilder argument(final String name,
+ final ArgumentType type) {
+ return RequiredArgumentBuilder.argument(name, type);
+ }
+
+ public static String getSafeStringArgument(CommandContext> context, String fieldName, String defaultValue) {
+ try {
+ return ArgumentTypes.getString(context, fieldName);
+ } catch (IllegalArgumentException e) {
+ // Ignore missing argument exception and return default value
+ return defaultValue;
+ }
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/command/ArgumentTypes.java b/zip-base/src/main/java/net/imprex/command/ArgumentTypes.java
new file mode 100644
index 0000000..52433b0
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/command/ArgumentTypes.java
@@ -0,0 +1,165 @@
+package net.imprex.command;
+
+import com.mojang.brigadier.arguments.ArgumentType;
+import com.mojang.brigadier.arguments.BoolArgumentType;
+import com.mojang.brigadier.arguments.DoubleArgumentType;
+import com.mojang.brigadier.arguments.FloatArgumentType;
+import com.mojang.brigadier.arguments.IntegerArgumentType;
+import com.mojang.brigadier.arguments.LongArgumentType;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.brigadier.context.CommandContext;
+
+public class ArgumentTypes {
+
+ /**
+ * Converted into tick's
+ *
+ * Examples: "0d", "0s", "0t", "0"
+ */
+ public static ArgumentType> time() {
+ return TimeArgumentType.time();
+ }
+
+ /**
+ * Converted into tick's
+ */
+ public static Long getTime(CommandContext> context, String name) {
+ return TimeArgumentType.getTime(context, name);
+ }
+
+ /**
+ * Examples: "true", "false"
+ */
+ public static BoolArgumentType bool() {
+ return BoolArgumentType.bool();
+ }
+
+ public static boolean getBoolean(CommandContext> context, String name) {
+ return BoolArgumentType.getBool(context, name);
+ }
+
+ /**
+ * Examples: "0", "1.2", ".5", "-1", "-.5", "-1234.56"
+ */
+ public static DoubleArgumentType doubleArg() {
+ return DoubleArgumentType.doubleArg();
+ }
+
+ /**
+ * Examples: "0", "1.2", ".5", "-1", "-.5", "-1234.56"
+ */
+ public static DoubleArgumentType doubleArg(double min) {
+ return DoubleArgumentType.doubleArg(min);
+ }
+
+ /**
+ * Examples: "0", "1.2", ".5", "-1", "-.5", "-1234.56"
+ */
+ public static DoubleArgumentType doubleArg(double min, double max) {
+ return DoubleArgumentType.doubleArg(min, max);
+ }
+
+ public static double getDouble(CommandContext> context, String name) {
+ return DoubleArgumentType.getDouble(context, name);
+ }
+
+ /**
+ * Examples: "0", "1.2", ".5", "-1", "-.5", "-1234.56"
+ */
+ public static FloatArgumentType floatArg() {
+ return FloatArgumentType.floatArg();
+ }
+
+ /**
+ * Examples: "0", "1.2", ".5", "-1", "-.5", "-1234.56"
+ */
+ public static FloatArgumentType floatArg(float min) {
+ return FloatArgumentType.floatArg(min);
+ }
+
+ /**
+ * Examples: "0", "1.2", ".5", "-1", "-.5", "-1234.56"
+ */
+ public static FloatArgumentType floatArg(float min, float max) {
+ return FloatArgumentType.floatArg(min, max);
+ }
+
+ public static float getFloat(CommandContext> context, String name) {
+ return FloatArgumentType.getFloat(context, name);
+ }
+
+ /**
+ * Examples: "0", "123", "-123"
+ */
+ public static IntegerArgumentType integer() {
+ return IntegerArgumentType.integer();
+ }
+
+ /**
+ * Examples: "0", "123", "-123"
+ */
+ public static IntegerArgumentType integer(int min) {
+ return IntegerArgumentType.integer(min);
+ }
+
+ /**
+ * Examples: "0", "123", "-123"
+ */
+ public static IntegerArgumentType integer(int min, int max) {
+ return IntegerArgumentType.integer(min, max);
+ }
+
+ public static int getInteger(CommandContext> context, String name) {
+ return IntegerArgumentType.getInteger(context, name);
+ }
+
+ /**
+ * Examples: "0", "123", "-123"
+ */
+ public static LongArgumentType longArg() {
+ return LongArgumentType.longArg();
+ }
+
+ /**
+ * Examples: "0", "123", "-123"
+ */
+ public static LongArgumentType longArg(long min) {
+ return LongArgumentType.longArg(min);
+ }
+
+ /**
+ * Examples: "0", "123", "-123"
+ */
+ public static LongArgumentType longArg(long min, long max) {
+ return LongArgumentType.longArg(min, max);
+ }
+
+ public static long getLong(CommandContext> context, String name) {
+ return LongArgumentType.getLong(context, name);
+ }
+
+ /**
+ * Examples: "word", "words with spaces", "\"and symbols\""
+ */
+ public static StringArgumentType greedyString() {
+ return StringArgumentType.greedyString();
+ }
+
+ /**
+ * Examples: "\"quoted phrase\"", "word", "\"\""
+ */
+ public static StringArgumentType string() {
+ return StringArgumentType.string();
+ }
+
+ /**
+ * Examples: "word", "words_with_underscores"
+ */
+ public static StringArgumentType word() {
+ return StringArgumentType.word();
+ }
+
+ public static String getString(CommandContext> context, String name) {
+ return StringArgumentType.getString(context, name);
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/command/CommandRegistry.java b/zip-base/src/main/java/net/imprex/command/CommandRegistry.java
new file mode 100644
index 0000000..16370ad
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/command/CommandRegistry.java
@@ -0,0 +1,17 @@
+package net.imprex.command;
+
+import com.mojang.brigadier.CommandDispatcher;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+
+public class CommandRegistry {
+
+ private final CommandDispatcher dispatcher = new CommandDispatcher<>();
+
+ public void register(LiteralArgumentBuilder literal) {
+ this.dispatcher.register(literal);
+ }
+
+ public CommandDispatcher getDispatcher() {
+ return this.dispatcher;
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/command/CommandSender.java b/zip-base/src/main/java/net/imprex/command/CommandSender.java
new file mode 100644
index 0000000..a2db6be
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/command/CommandSender.java
@@ -0,0 +1,8 @@
+package net.imprex.command;
+
+public interface CommandSender {
+
+ void sendMessage(String message, Object... args);
+
+ boolean hasPermission(String permission);
+}
diff --git a/zip-base/src/main/java/net/imprex/command/SuggestionBuilder.java b/zip-base/src/main/java/net/imprex/command/SuggestionBuilder.java
new file mode 100644
index 0000000..1a82e30
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/command/SuggestionBuilder.java
@@ -0,0 +1,83 @@
+package net.imprex.command;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.BiFunction;
+import java.util.function.BiPredicate;
+import java.util.function.Function;
+import java.util.function.Predicate;
+import java.util.function.Supplier;
+import java.util.stream.Stream;
+import java.util.stream.StreamSupport;
+
+import com.mojang.brigadier.context.CommandContext;
+import com.mojang.brigadier.suggestion.SuggestionProvider;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class SuggestionBuilder {
+
+ private final List, Stream>> transformations = new ArrayList<>();
+ private final Supplier> supplier;
+
+ public SuggestionBuilder(Supplier> supplier) {
+ this.supplier = supplier;
+ }
+
+ public SuggestionBuilder filter(Predicate predicate) {
+ this.transformations.add((stream, context) -> stream.filter(predicate));
+ return this;
+ }
+
+ public SuggestionBuilder filter(BiPredicate> predicate) {
+ this.transformations.add((stream, context) -> stream.filter(value -> predicate.test((TOut) value, context)));
+ return this;
+ }
+
+ public SuggestionBuilder map(Function function) {
+ this.transformations.add((stream, context) -> stream.map(function));
+ return (SuggestionBuilder) this;
+ }
+
+ public SuggestionBuilder flatMap(Function function) {
+ this.transformations.add((stream, context) -> stream.flatMap(function));
+ return (SuggestionBuilder) this;
+ }
+
+ public Function, Stream> buildStream(CommandContext context) {
+ return stream -> {
+ for (BiFunction, Stream> transformation : this.transformations) {
+ stream = transformation.apply(stream, context);
+ }
+ return (Stream) stream;
+ };
+ }
+
+ public Function, Stream> buildIterable(CommandContext context) {
+ return (iterable) -> {
+ Stream stream = StreamSupport.stream(iterable.spliterator(), false);
+ for (var transformation : transformations) {
+ stream = transformation.apply(stream, context);
+ }
+ return (Stream) stream;
+ };
+ }
+
+ public SuggestionProvider buildSuggest() {
+ return (context, builder) -> {
+ String input = builder.getRemaining().toLowerCase();
+ this.buildStream(context)
+ .apply(this.supplier.get())
+ .map(Objects::toString)
+ .filter(Objects::nonNull)
+ .filter(name -> {
+ if (input == null || name.toLowerCase().startsWith(input)) {
+ return true;
+ }
+ return false;
+ })
+ .forEach(builder::suggest);
+ return builder.buildFuture();
+ };
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/command/SuggestionProvider.java b/zip-base/src/main/java/net/imprex/command/SuggestionProvider.java
new file mode 100644
index 0000000..2addee9
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/command/SuggestionProvider.java
@@ -0,0 +1,64 @@
+package net.imprex.command;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.concurrent.CompletableFuture;
+import java.util.stream.Stream;
+
+import com.mojang.brigadier.suggestion.Suggestions;
+import com.mojang.brigadier.suggestion.SuggestionsBuilder;
+
+public class SuggestionProvider {
+
+ public static boolean match(String input, String message) {
+ int length = Math.min(input.length(), message.length());
+ for (int i = 0; i < length; i++) {
+ if (message.charAt(i) != input.charAt(i)) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static CompletableFuture suggest(SuggestionsBuilder builder, Iterator values) {
+ String input = builder.getRemaining().toLowerCase();
+ while (values.hasNext()) {
+ String value = values.next().toLowerCase();
+ if (match(input, value)) {
+ builder.suggest(value);
+ }
+ }
+ return builder.buildFuture();
+ }
+
+ public static CompletableFuture suggest(SuggestionsBuilder builder, Collection values) {
+ return suggest(builder, values.stream());
+ }
+
+ public static CompletableFuture suggest(SuggestionsBuilder builder, String[] values) {
+ return suggest(builder, Arrays.stream(values));
+ }
+
+ public static CompletableFuture suggest(SuggestionsBuilder builder, Stream values) {
+ String input = builder.getRemaining().toLowerCase();
+ values.filter(value -> match(input, value.toLowerCase())).forEach(builder::suggest);
+ return builder.buildFuture();
+ }
+
+ public static final CompletableFuture compareSuggest(SuggestionsBuilder builder, String input, String prefix, Stream values) {
+ return compareSuggest(builder, input, prefix, values.toArray(String[]::new));
+ }
+
+ public static final CompletableFuture compareSuggest(SuggestionsBuilder builder, String input, String prefix, String... values) {
+ input = input.toLowerCase();
+
+ for (String value : values) {
+ String name = value.toLowerCase();
+ if (name.startsWith(input) || name.contains(input)) {
+ builder.suggest(prefix + value.toLowerCase());
+ }
+ }
+ return builder.buildFuture();
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleComment.java b/zip-base/src/main/java/net/imprex/config/SimpleComment.java
new file mode 100644
index 0000000..8934eca
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleComment.java
@@ -0,0 +1,18 @@
+package net.imprex.config;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Repeatable(SimpleCommentList.class)
+@Retention(RUNTIME)
+@Target({ FIELD, TYPE })
+public @interface SimpleComment {
+
+ String value();
+ boolean inline() default false;
+}
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleCommentList.java b/zip-base/src/main/java/net/imprex/config/SimpleCommentList.java
new file mode 100644
index 0000000..19697d1
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleCommentList.java
@@ -0,0 +1,14 @@
+package net.imprex.config;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target({ FIELD, TYPE })
+public @interface SimpleCommentList {
+ SimpleComment[] value();
+}
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleConfig.java b/zip-base/src/main/java/net/imprex/config/SimpleConfig.java
new file mode 100644
index 0000000..554a465
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleConfig.java
@@ -0,0 +1,266 @@
+package net.imprex.config;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Constructor;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardOpenOption;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Predicate;
+
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.YamlConfiguration;
+import org.bukkit.plugin.Plugin;
+
+import com.google.common.base.Charsets;
+
+import net.imprex.zip.util.ZipLogger;
+
+public class SimpleConfig {
+
+ public static T getOrDefault(T object, T defaultValue) {
+ return object != null ? object : defaultValue;
+ }
+
+ public static T getOrDefault(T object, T defaultValue, Predicate predicate) {
+ return object != null ? predicate.test(object) ? object : defaultValue : defaultValue;
+ }
+
+ static final String VERSION_FIELD = "version";
+
+ private final Path dataFolder;
+ private final Class extends Config> configClass;
+
+ private final SimpleSectionRoot rootSection;
+
+ private Config instance;
+
+ public SimpleConfig(Plugin plugin, Class extends Config> configClass) {
+ this(plugin.getDataFolder().toPath(), configClass);
+ }
+
+ public SimpleConfig(Path dataFolder, Class extends Config> configClass) {
+ Objects.requireNonNull(dataFolder, "dataFolder can't be null!");
+ Objects.requireNonNull(configClass, "configClass can't be null!");
+
+ this.dataFolder = dataFolder;
+ this.configClass = configClass;
+
+ this.rootSection = configClass.getAnnotation(SimpleSectionRoot.class);
+ Objects.requireNonNull(this.rootSection, configClass.getSimpleName() + " has no SimpleSectionRoot annotation!");
+ }
+
+ private Path getConfigPath() throws IOException {
+ Path folderPath = this.dataFolder.resolve(this.rootSection.directory());
+ Files.createDirectories(folderPath);
+
+ String fileName = this.rootSection.name();
+ if (!fileName.endsWith(this.rootSection.fileSuffix())) {
+ fileName = fileName + this.rootSection.fileSuffix();
+ }
+
+ Path filePath = folderPath.resolve(fileName);
+ return filePath;
+ }
+
+ private void setComments(ConfigurationSection config, SimpleField> field, String fieldName) {
+ List comments = field.getComments(false);
+ List inlineComments = field.getComments(true);
+
+ if (comments.size() != 0) {
+ config.setComments(fieldName, comments);
+ }
+
+ if (inlineComments.size() != 0) {
+ config.setInlineComments(fieldName, inlineComments);
+ }
+ }
+
+ public void serialize() throws Exception {
+ Objects.requireNonNull(this.instance, "config wasn't loaded before!");
+
+ YamlConfiguration config = new YamlConfiguration();
+ config.set(VERSION_FIELD, this.rootSection.version());
+ config.setComments(VERSION_FIELD, SimpleField.getComments(false, this.configClass));
+ config.setInlineComments(VERSION_FIELD, SimpleField.getComments(true, this.configClass));
+ this.serialize(config, this.instance);
+
+ Path configFilePath = this.getConfigPath();
+ if (Files.notExists(configFilePath)) {
+ Files.createFile(configFilePath);
+ }
+
+ try (OutputStream outputStream = Files.newOutputStream(configFilePath, StandardOpenOption.CREATE);
+ OutputStreamWriter outputStreamWriter = new OutputStreamWriter(outputStream, Charsets.UTF_8)) {
+ String configSaved = config.saveToString();
+ outputStreamWriter.write(configSaved);
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ private void serialize(ConfigurationSection config, Object instance) throws Exception {
+ for (SimpleField> field : SimpleField.getFields(instance.getClass())) {
+ SimpleTranslatorKey translatorKey = SimpleTranslatorKey.key(field);
+ if (translatorKey == null) {
+ ZipLogger.info("No SimpleKey annotation found in section " + config.getName() + " (Class: " + this.configClass.getSimpleName() + ")");
+ continue;
+ }
+
+ if (field.isSection()) {
+ String newSectionName = translatorKey.name();
+ // Check if version field will be overwritten in root section
+ if (newSectionName.equalsIgnoreCase(VERSION_FIELD) && config.getRoot().equals(config)) {
+ throw new IllegalArgumentException(String.format("Section name '%s' in '%s' is not allowed to use in root section.",
+ VERSION_FIELD,
+ instance.getClass().getSimpleName()));
+ }
+
+ ConfigurationSection newSection = config.getConfigurationSection(newSectionName);
+ if (newSection == null) {
+ newSection = config.createSection(newSectionName);
+ }
+
+
+ // Create new config section when current value is null
+ Object newSectionInstance = field.getField(instance);
+ if (newSectionInstance == null && field.isChildSection()) {
+ try {
+ Constructor> constructor = field.getType().getConstructor();
+ newSectionInstance = constructor.newInstance();
+ } catch (NoSuchMethodException e) {
+ ZipLogger.error("Unable to create config section for " + newSectionName + " in " + this.configClass.getSimpleName(), e);
+ }
+ }
+
+ if (newSectionInstance != null) {
+ this.serialize(newSection, newSectionInstance);
+ }
+
+ this.setComments(config, field, newSectionName);
+ continue;
+ }
+
+ // Check if version field will be overwritten in root section
+ if (translatorKey.isVersionInRoot(config)) {
+ throw new IllegalArgumentException(String.format("Field name '%s' in '%s' is not allowed to use in root section.",
+ VERSION_FIELD,
+ instance.getClass().getSimpleName()));
+ }
+
+ SimpleTranslator translator = SimpleTranslatorRegistry.getTranslator(field);
+ Require requireAnnotation = field.getRequire(translator);
+
+ Type initialValue = (Type) field.getField(instance);
+ Type defaultValue = (Type) translator.defaultValue(translatorKey, initialValue, requireAnnotation);
+
+ translator.serialize(config, translatorKey, defaultValue, requireAnnotation);
+ this.setComments(config, field, translatorKey.name());
+ }
+ }
+
+ public Config deserialize() throws Exception {
+ return this.deserialize(false);
+ }
+
+ public Config deserialize(boolean storeMissingValue) throws Exception {
+ Path configFilePath = this.getConfigPath();
+
+ if (Files.notExists(configFilePath)) {
+ this.instance = this.deserialize(new YamlConfiguration(), this.configClass);
+ this.serialize();
+ }
+
+ YamlConfiguration config = new YamlConfiguration();
+ try (InputStream inputStream = Files.newInputStream(configFilePath, StandardOpenOption.CREATE);
+ InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charsets.UTF_8)) {
+ config.load(inputStreamReader);
+ }
+
+ int version = config.getInt(VERSION_FIELD, -1);
+ if (version == -1) {
+ throw new IllegalStateException("Unable to detect config version!");
+ } else if (version < this.rootSection.version()) {
+ throw new IllegalStateException("Config version is higher then the currently one! (config: " + version + " current:" + this.rootSection.version() + ")");
+ }
+ // TODO handle migration
+
+ this.instance = this.deserialize(config, this.configClass);
+
+ // TODO storeMissingValue
+ return this.instance;
+ }
+
+ @SuppressWarnings("unchecked")
+ private Type deserialize(ConfigurationSection config, Class extends Type> configClass) throws Exception {
+ Constructor extends Type> constructor = configClass.getConstructor();
+ Objects.requireNonNull(constructor, configClass.getSimpleName() + " no empty constructor was found!");
+
+ Type instance = constructor.newInstance();
+
+ for (SimpleField> field : SimpleField.getFields(configClass)) {
+ SimpleTranslatorKey translatorKey = SimpleTranslatorKey.key(field);
+ if (translatorKey == null) {
+ ZipLogger.info("No SimpleKey annotation found in section " + config.getName() + " (Class: " + this.configClass.getSimpleName() + ")");
+ continue;
+ }
+
+
+ if (field.isSection()) {
+ String newSectionName = translatorKey.name();
+ ConfigurationSection newSection = config.getConfigurationSection(newSectionName);
+ if (newSection == null) {
+ newSection = config.createSection(newSectionName);
+ }
+
+ Object newSectionInstance = this.deserialize(newSection, field.getType());
+ field.setField(instance, newSectionInstance);
+ continue;
+ }
+
+ SimpleTranslator translator = SimpleTranslatorRegistry.getTranslator(field);
+ Require requireAnnotation = field.getRequire(translator);
+
+ Type initialValue = (Type) field.getField(instance);
+ Type defaultValue = translator.defaultValue(translatorKey, initialValue, requireAnnotation);
+ Type value = translator.deserialize(config, translatorKey, defaultValue, requireAnnotation);
+
+ if (value != null) {
+ if (requireAnnotation != null) {
+ Object result = translator.requirement(translatorKey, value, requireAnnotation);
+ if (result != null && !result.equals(value)) {
+ ZipLogger.warn("Unsing default value (" + result + ") for key \"" + translatorKey.name() + "\" in section " + config.getName());
+ }
+ field.setField(instance, result);
+ continue;
+ }
+
+ if (field.getType().isAssignableFrom(value.getClass())) {
+ field.setField(instance, value);
+ continue;
+ }
+ }
+
+ ZipLogger.warn("Unsing default value (" + defaultValue + ") for key \"" + translatorKey.name() + "\" in section " + config.getName());
+ field.setField(instance, defaultValue);
+ }
+
+ return instance;
+ }
+
+ public Config getOrDeserializeConfig() {
+ if (this.instance == null) {
+ try {
+ this.deserialize();
+ } catch (Exception e) {
+ ZipLogger.error("Unable to deserialize config class of " + this.configClass.getSimpleName(), e);
+ }
+ }
+ return this.instance;
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleField.java b/zip-base/src/main/java/net/imprex/config/SimpleField.java
new file mode 100644
index 0000000..416d10a
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleField.java
@@ -0,0 +1,127 @@
+package net.imprex.config;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import net.imprex.zip.util.ZipLogger;
+
+public class SimpleField {
+
+ public static SimpleField>[] getFields(Class> fieldClass) {
+ return Arrays.stream(fieldClass.getDeclaredFields())
+ .filter(field -> field.getAnnotation(SimpleUnused.class) == null)
+ .filter(field -> !Modifier.isStatic(field.getModifiers()))
+ .map(SimpleField::new)
+ .toArray(SimpleField[]::new);
+ }
+
+ static List getComments(boolean inlineComments, AnnotatedElement annotatedElement) {
+ List comments = new ArrayList<>();
+
+ SimpleCommentList commentList = annotatedElement.getAnnotation(SimpleCommentList.class);
+ if (commentList != null) {
+ for (SimpleComment comment : commentList.value()) {
+ if (comment.inline() && inlineComments) {
+ comments.add(comment.value());
+ } else if (!comment.inline() && !inlineComments) {
+ comments.add(comment.value());
+ }
+ }
+ }
+
+ SimpleComment comment = annotatedElement.getAnnotation(SimpleComment.class);
+ if (comment != null) {
+ if (comment.inline() && inlineComments) {
+ comments.add(comment.value());
+ } else if (!comment.inline() && !inlineComments) {
+ comments.add(comment.value());
+ }
+ }
+
+ return comments;
+ }
+
+ private final Field field;
+ private final Class> genericClass;
+
+ public SimpleField(Field field) {
+ this.field = field;
+ this.field.setAccessible(true);
+
+ if (field.getType().getGenericSuperclass() instanceof ParameterizedType parameterizedType) {
+ this.genericClass = (Class>) parameterizedType.getActualTypeArguments()[0];
+ } else {
+ this.genericClass = field.getType();
+ }
+ }
+
+ public void validateValue(Object value) {
+ Class> valueClass = value.getClass();
+ if (!this.genericClass.isAssignableFrom(valueClass)) {
+ throw new IllegalArgumentException(String.format("%s is not type of %s",
+ valueClass.getSimpleName(),
+ this.genericClass.getSimpleName()
+ ));
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ public Type getField(Object instance) {
+ try {
+ return (Type) this.field.get(instance);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ ZipLogger.error("Unable to get field value!", e);
+ return null;
+ }
+ }
+
+ public void setField(Object instance, Object value) {
+ this.validateValue(value);
+
+ try {
+ this.field.set(instance, value);
+ } catch (IllegalArgumentException | IllegalAccessException e) {
+ ZipLogger.error("Unable to set field value!", e);
+ }
+ }
+
+ public List getComments(boolean inlineComments) {
+ return SimpleField.getComments(inlineComments, this.field);
+ }
+
+ public Require getRequire(SimpleTranslator, Require> translator) {
+ Class require = translator.require();
+ if (require != null) {
+ return this.field.getAnnotation(require);
+ }
+ return null;
+ }
+
+ public SimpleKey getKey() {
+ return this.field.getAnnotation(SimpleKey.class);
+ }
+
+ public boolean isSection() {
+ Class> configClass = this.getType();
+ return configClass.getAnnotation(SimpleSection.class) != null
+ || configClass.getAnnotation(SimpleSectionRoot.class) != null;
+ }
+
+ public boolean isChildSection() {
+ return this.getType().getAnnotation(SimpleSection.class) != null;
+ }
+
+ public Class> getType() {
+ return this.field.getType();
+ }
+
+ public String getFieldName() {
+ return this.field.getName();
+ }
+}
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleKey.java b/zip-base/src/main/java/net/imprex/config/SimpleKey.java
new file mode 100644
index 0000000..ffb2cba
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleKey.java
@@ -0,0 +1,13 @@
+package net.imprex.config;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface SimpleKey {
+
+ String value() default "";
+}
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleMigration.java b/zip-base/src/main/java/net/imprex/config/SimpleMigration.java
new file mode 100644
index 0000000..39989d9
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleMigration.java
@@ -0,0 +1,32 @@
+package net.imprex.config;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Repeatable;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Repeatable(SimpleMigrationList.class)
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface SimpleMigration {
+
+ String beforeName();
+
+ int beforeVersion() default -1;
+
+ /**
+ * When value is defined the migration will checkout another section
+ *
+ * @return
+ */
+ Class> beforeSection() default SimpleMigration.class;
+
+ /**
+ * When value is defined the migration will checkout another section
+ *
+ * @return
+ */
+ String beforeSectionName() default "";
+}
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleMigrationList.java b/zip-base/src/main/java/net/imprex/config/SimpleMigrationList.java
new file mode 100644
index 0000000..578e3aa
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleMigrationList.java
@@ -0,0 +1,13 @@
+package net.imprex.config;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface SimpleMigrationList {
+ SimpleMigration[] value();
+}
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleSection.java b/zip-base/src/main/java/net/imprex/config/SimpleSection.java
new file mode 100644
index 0000000..94c8ea8
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleSection.java
@@ -0,0 +1,11 @@
+package net.imprex.config;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface SimpleSection {
+}
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleSectionRoot.java b/zip-base/src/main/java/net/imprex/config/SimpleSectionRoot.java
new file mode 100644
index 0000000..f40eff1
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleSectionRoot.java
@@ -0,0 +1,26 @@
+package net.imprex.config;
+
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target(TYPE)
+public @interface SimpleSectionRoot {
+
+ // Default file name can include file suffix
+ String name();
+
+ // Default configuration directory
+ String directory() default "";
+
+ String fileSuffix() default ".yml";
+
+ // Plugin.jar default configuration location. Will be copied from the jar into the file system when no configuration file exists!
+ String defaultConfigPath() default "";
+
+ // Currently configuration version
+ int version();
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleTranslator.java b/zip-base/src/main/java/net/imprex/config/SimpleTranslator.java
new file mode 100644
index 0000000..1bfcc0d
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleTranslator.java
@@ -0,0 +1,24 @@
+package net.imprex.config;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+public interface SimpleTranslator {
+
+ void serialize(ConfigurationSection config, SimpleTranslatorKey key, Value value, Requirement requirement);
+
+ Value deserialize(ConfigurationSection config, SimpleTranslatorKey key, Value defaultValue, Requirement requirement);
+
+ Value defaultValue(SimpleTranslatorKey key, Value initialValue, Requirement requirement);
+
+ default Value requirement(SimpleTranslatorKey key, Value value, Requirement requirement) {
+ return null;
+ }
+ default Class require() {
+ return null;
+ }
+
+ List> types();
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleTranslatorKey.java b/zip-base/src/main/java/net/imprex/config/SimpleTranslatorKey.java
new file mode 100644
index 0000000..4f8714d
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleTranslatorKey.java
@@ -0,0 +1,22 @@
+package net.imprex.config;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+public interface SimpleTranslatorKey {
+
+ static SimpleTranslatorKey key(SimpleField> field) {
+ SimpleKey key = field.getKey();
+ if (key == null) {
+ return null;
+ }
+
+ String value = key.value().trim();
+ return () -> value.isBlank() ? field.getFieldName() : value;
+ }
+
+ String name();
+
+ default boolean isVersionInRoot(ConfigurationSection config) {
+ return this.name().equalsIgnoreCase(SimpleConfig.VERSION_FIELD) && config.getRoot().equals(config);
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleTranslatorRegistry.java b/zip-base/src/main/java/net/imprex/config/SimpleTranslatorRegistry.java
new file mode 100644
index 0000000..8a469fc
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleTranslatorRegistry.java
@@ -0,0 +1,57 @@
+package net.imprex.config;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import net.imprex.config.translator.BooleanTranslator;
+import net.imprex.config.translator.DoubleTranslator;
+import net.imprex.config.translator.EnumTranslator;
+import net.imprex.config.translator.IntegerTranslator;
+import net.imprex.config.translator.ListTranslator;
+import net.imprex.config.translator.MapTranslator;
+import net.imprex.config.translator.ObjectTranslator;
+import net.imprex.config.translator.StringTranslator;
+
+public class SimpleTranslatorRegistry {
+
+ private static final Map, SimpleTranslator, ?>> TRANSLATOR_LIST = new HashMap<>();
+ private static final ObjectTranslator DEFAULT_TRANSLATOR = new ObjectTranslator();
+
+ static {
+ registerTranslator(new BooleanTranslator());
+ registerTranslator(new IntegerTranslator());
+ registerTranslator(new DoubleTranslator());
+ registerTranslator(new ListTranslator());
+ registerTranslator(new MapTranslator());
+ registerTranslator(new StringTranslator());
+ registerTranslator(new EnumTranslator());
+ }
+
+ public static void registerTranslator(SimpleTranslator, ?> converter) {
+ for (Class> type : converter.types()) {
+ TRANSLATOR_LIST.put(type, converter);
+ }
+ }
+
+ public static SimpleTranslator getTranslator(SimpleField> field) {
+ return getTranslator(field.getType());
+ }
+
+ @SuppressWarnings("unchecked") // TODO find a better way then using unchecked
+ public static SimpleTranslator getTranslator(Class> fieldClass) {
+ SimpleTranslator, ?> converter = TRANSLATOR_LIST.get(fieldClass);
+ if (converter == null) {
+ for (Entry, SimpleTranslator, ?>> entry : TRANSLATOR_LIST.entrySet()) {
+ if (entry.getKey().isAssignableFrom(fieldClass)) {
+ return (SimpleTranslator) entry.getValue();
+ }
+ }
+ } else {
+ return (SimpleTranslator) converter;
+ }
+
+ return (SimpleTranslator) DEFAULT_TRANSLATOR;
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/SimpleUnused.java b/zip-base/src/main/java/net/imprex/config/SimpleUnused.java
new file mode 100644
index 0000000..d7412a4
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/SimpleUnused.java
@@ -0,0 +1,11 @@
+package net.imprex.config;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface SimpleUnused {
+}
diff --git a/zip-base/src/main/java/net/imprex/config/require/SimpleDouble.java b/zip-base/src/main/java/net/imprex/config/require/SimpleDouble.java
new file mode 100644
index 0000000..bfccf94
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/require/SimpleDouble.java
@@ -0,0 +1,17 @@
+package net.imprex.config.require;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface SimpleDouble {
+
+ double defaultValue() default 0;
+
+ double min() default Double.MIN_VALUE;
+ double max() default Double.MAX_VALUE;
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/require/SimpleInteger.java b/zip-base/src/main/java/net/imprex/config/require/SimpleInteger.java
new file mode 100644
index 0000000..f8cce2c
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/require/SimpleInteger.java
@@ -0,0 +1,17 @@
+package net.imprex.config.require;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface SimpleInteger {
+
+ int defaultValue() default 0;
+
+ int min() default Integer.MIN_VALUE;
+ int max() default Integer.MAX_VALUE;
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/require/SimpleList.java b/zip-base/src/main/java/net/imprex/config/require/SimpleList.java
new file mode 100644
index 0000000..2eb798a
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/require/SimpleList.java
@@ -0,0 +1,14 @@
+package net.imprex.config.require;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface SimpleList {
+
+ Class> typeClass();
+}
diff --git a/zip-base/src/main/java/net/imprex/config/require/SimpleString.java b/zip-base/src/main/java/net/imprex/config/require/SimpleString.java
new file mode 100644
index 0000000..fc6cec0
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/require/SimpleString.java
@@ -0,0 +1,16 @@
+package net.imprex.config.require;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+@Retention(RUNTIME)
+@Target(FIELD)
+public @interface SimpleString {
+
+ String defaultValue() default "";
+
+ String regex() default "";
+}
diff --git a/zip-base/src/main/java/net/imprex/config/translator/BooleanTranslator.java b/zip-base/src/main/java/net/imprex/config/translator/BooleanTranslator.java
new file mode 100644
index 0000000..216d79e
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/translator/BooleanTranslator.java
@@ -0,0 +1,32 @@
+package net.imprex.config.translator;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+import net.imprex.config.SimpleTranslator;
+import net.imprex.config.SimpleTranslatorKey;
+
+public class BooleanTranslator implements SimpleTranslator {
+
+ @Override
+ public void serialize(ConfigurationSection config, SimpleTranslatorKey key, Boolean value, Annotation requirement) {
+ config.set(key.name(), value);
+ }
+
+ @Override
+ public Boolean deserialize(ConfigurationSection config, SimpleTranslatorKey key, Boolean defaultValue, Annotation requirement) {
+ return config.getBoolean(key.name(), defaultValue);
+ }
+
+ @Override
+ public Boolean defaultValue(SimpleTranslatorKey key, Boolean initialValue, Annotation requirement) {
+ return initialValue != null ? initialValue : false;
+ }
+
+ @Override
+ public List> types() {
+ return List.of(Boolean.class, boolean.class);
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/translator/DoubleTranslator.java b/zip-base/src/main/java/net/imprex/config/translator/DoubleTranslator.java
new file mode 100644
index 0000000..06bd61e
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/translator/DoubleTranslator.java
@@ -0,0 +1,52 @@
+package net.imprex.config.translator;
+
+import java.util.List;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+import net.imprex.config.SimpleTranslator;
+import net.imprex.config.SimpleTranslatorKey;
+import net.imprex.config.require.SimpleDouble;
+
+public class DoubleTranslator implements SimpleTranslator {
+
+ @Override
+ public void serialize(ConfigurationSection config, SimpleTranslatorKey key, Double value, SimpleDouble requirement) {
+ config.set(key.name(), value);
+ }
+
+ @Override
+ public Double deserialize(ConfigurationSection config, SimpleTranslatorKey key, Double defaultValue, SimpleDouble requirement) {
+ return config.getDouble(key.name(), defaultValue);
+ }
+
+ @Override
+ public Double requirement(SimpleTranslatorKey key, Double value, SimpleDouble requirement) {
+ return this.getOrDefault(requirement, value);
+ }
+
+ @Override
+ public Double defaultValue(SimpleTranslatorKey key, Double initialValue, SimpleDouble requirement) {
+ return requirement != null ? this.getOrDefault(requirement, null) : initialValue;
+ }
+
+ public double getOrDefault(SimpleDouble requirement, Double value) {
+ if (value == null) {
+ value = requirement.defaultValue();
+ }
+
+ double minValue = requirement.min();
+ double maxValue = requirement.max();
+ return value >= minValue ? value <= maxValue ? value : maxValue : minValue;
+ }
+
+ @Override
+ public Class require() {
+ return SimpleDouble.class;
+ }
+
+ @Override
+ public List> types() {
+ return List.of(Double.class, double.class);
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/translator/EnumTranslator.java b/zip-base/src/main/java/net/imprex/config/translator/EnumTranslator.java
new file mode 100644
index 0000000..c57e170
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/translator/EnumTranslator.java
@@ -0,0 +1,44 @@
+package net.imprex.config.translator;
+
+import java.lang.annotation.Annotation;
+import java.util.List;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+import net.imprex.config.SimpleTranslator;
+import net.imprex.config.SimpleTranslatorKey;
+
+@SuppressWarnings("rawtypes")
+public class EnumTranslator implements SimpleTranslator {
+
+ @Override
+ public void serialize(ConfigurationSection config, SimpleTranslatorKey key, Enum value, Annotation requirement) {
+ config.set(key.name(), value.name());
+ }
+
+ @Override
+ public Enum deserialize(ConfigurationSection config, SimpleTranslatorKey key, Enum defaultValue, Annotation requirement) {
+ if (defaultValue == null) {
+ return defaultValue;
+ }
+
+ String enumName = config.getString(key.name());
+ Enum[] values = defaultValue.getClass().getEnumConstants();
+ for (Enum value : values) {
+ if (value.name().equalsIgnoreCase(enumName)) {
+ return value;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public Enum defaultValue(SimpleTranslatorKey key, Enum initialValue, Annotation requirement) {
+ return initialValue != null ? initialValue : null;
+ }
+
+ @Override
+ public List> types() {
+ return List.of(Enum.class);
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/translator/IntegerTranslator.java b/zip-base/src/main/java/net/imprex/config/translator/IntegerTranslator.java
new file mode 100644
index 0000000..cac6e16
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/translator/IntegerTranslator.java
@@ -0,0 +1,52 @@
+package net.imprex.config.translator;
+
+import java.util.List;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+import net.imprex.config.SimpleTranslator;
+import net.imprex.config.SimpleTranslatorKey;
+import net.imprex.config.require.SimpleInteger;
+
+public class IntegerTranslator implements SimpleTranslator {
+
+ @Override
+ public void serialize(ConfigurationSection config, SimpleTranslatorKey key, Integer value, SimpleInteger requirement) {
+ config.set(key.name(), value);
+ }
+
+ @Override
+ public Integer deserialize(ConfigurationSection config, SimpleTranslatorKey key, Integer defaultValue, SimpleInteger requirement) {
+ return config.getInt(key.name(), defaultValue);
+ }
+
+ @Override
+ public Integer requirement(SimpleTranslatorKey key, Integer value, SimpleInteger requirement) {
+ return this.getOrDefault(requirement, value);
+ }
+
+ @Override
+ public Integer defaultValue(SimpleTranslatorKey key, Integer initialValue, SimpleInteger requirement) {
+ return requirement != null ? this.getOrDefault(requirement, null) : initialValue;
+ }
+
+ public int getOrDefault(SimpleInteger requirement, Integer value) {
+ if (value == null) {
+ value = requirement.defaultValue();
+ }
+
+ int minValue = requirement.min();
+ int maxValue = requirement.max();
+ return value >= minValue ? value <= maxValue ? value : maxValue : minValue;
+ }
+
+ @Override
+ public Class require() {
+ return SimpleInteger.class;
+ }
+
+ @Override
+ public List> types() {
+ return List.of(Integer.class, int.class);
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/translator/ListTranslator.java b/zip-base/src/main/java/net/imprex/config/translator/ListTranslator.java
new file mode 100644
index 0000000..6c120d0
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/translator/ListTranslator.java
@@ -0,0 +1,83 @@
+package net.imprex.config.translator;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.bukkit.configuration.ConfigurationSection;
+import org.bukkit.configuration.file.YamlConfiguration;
+
+import net.imprex.config.SimpleTranslator;
+import net.imprex.config.SimpleTranslatorKey;
+import net.imprex.config.SimpleTranslatorRegistry;
+import net.imprex.config.require.SimpleList;
+
+@SuppressWarnings({ "rawtypes", "unchecked" })
+public class ListTranslator implements SimpleTranslator {
+
+ @Override
+ public void serialize(ConfigurationSection config, SimpleTranslatorKey key, List value, SimpleList requirement) {
+ YamlConfiguration configuration = new YamlConfiguration();
+ SimpleTranslator translator = null;
+ List mappedList = new ArrayList<>();
+ for (Object entry : value) {
+ if (entry == null) {
+ continue;
+ }
+
+ configuration.set(key.name(), entry);
+
+ if (translator == null) {
+ translator = SimpleTranslatorRegistry.getTranslator(entry.getClass());
+ }
+ translator.serialize(configuration, key, entry, null);
+ Object parsed = configuration.get(key.name());
+ if (parsed != null) {
+ mappedList.add(parsed.toString());
+ }
+ }
+ config.set(key.name(), mappedList);
+ }
+
+ @Override
+ public List> deserialize(ConfigurationSection config, SimpleTranslatorKey key, List defaultValue, SimpleList requirement) {
+ List list = config.getStringList(key.name());
+ if (list == null || requirement == null) {
+ return defaultValue;
+ }
+
+ SimpleTranslator translator = SimpleTranslatorRegistry.getTranslator(requirement.typeClass());
+ if (translator == null) {
+ return defaultValue;
+ }
+
+ YamlConfiguration configuration = new YamlConfiguration();
+ List mappedList = new ArrayList<>();
+ for (String value : list) {
+ if (value == null) {
+ continue;
+ }
+
+ configuration.set(key.name(), value);
+ Object parsed = translator.deserialize(configuration, key, null, null);
+ if (parsed != null) {
+ mappedList.add(parsed);
+ }
+ }
+ return mappedList;
+ }
+
+ @Override
+ public List> defaultValue(SimpleTranslatorKey key, List initialValue, SimpleList requirement) {
+ return initialValue != null ? initialValue : new ArrayList<>();
+ }
+
+ @Override
+ public Class require() {
+ return SimpleList.class;
+ }
+
+ @Override
+ public List> types() {
+ return List.of(List.class);
+ }
+}
\ No newline at end of file
diff --git a/zip-base/src/main/java/net/imprex/config/translator/MapTranslator.java b/zip-base/src/main/java/net/imprex/config/translator/MapTranslator.java
new file mode 100644
index 0000000..6787aa1
--- /dev/null
+++ b/zip-base/src/main/java/net/imprex/config/translator/MapTranslator.java
@@ -0,0 +1,36 @@
+package net.imprex.config.translator;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.bukkit.configuration.ConfigurationSection;
+
+import net.imprex.config.SimpleTranslator;
+import net.imprex.config.SimpleTranslatorKey;
+
+@SuppressWarnings("rawtypes")
+public class MapTranslator implements SimpleTranslator
\ No newline at end of file
diff --git a/zip-nms/zip-nms-api/src/main/java/net/imprex/zip/nms/api/NmsManager.java b/zip-nms/zip-nms-api/src/main/java/net/imprex/zip/nms/api/NmsManager.java
index 7bcaa4e..8b0485f 100644
--- a/zip-nms/zip-nms-api/src/main/java/net/imprex/zip/nms/api/NmsManager.java
+++ b/zip-nms/zip-nms-api/src/main/java/net/imprex/zip/nms/api/NmsManager.java
@@ -14,5 +14,7 @@ public interface NmsManager {
void setSkullProfile(SkullMeta meta, String texture);
+ void setupBackpackItem(ItemStack item);
+
boolean isAir(Material material);
}
\ No newline at end of file
diff --git a/zip-nms/zip-nms-v1_19_R1/src/main/java/net/imprex/zip/nms/v1_19_R1/ZipNmsManager.java b/zip-nms/zip-nms-v1_19_R1/src/main/java/net/imprex/zip/nms/v1_19_R1/ZipNmsManager.java
index 2e1ebd5..70b5b1f 100644
--- a/zip-nms/zip-nms-v1_19_R1/src/main/java/net/imprex/zip/nms/v1_19_R1/ZipNmsManager.java
+++ b/zip-nms/zip-nms-v1_19_R1/src/main/java/net/imprex/zip/nms/v1_19_R1/ZipNmsManager.java
@@ -15,8 +15,8 @@
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
-import net.imprex.zip.common.ReflectionUtil;
import net.imprex.zip.nms.api.NmsManager;
+import net.imprex.zip.util.ReflectionUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
@@ -85,6 +85,10 @@ public void setSkullProfile(SkullMeta meta, String texture) {
}
}
+ @Override
+ public void setupBackpackItem(ItemStack item) {
+ }
+
@Override
public boolean isAir(Material material) {
return material == null || material == Material.AIR;
diff --git a/zip-nms/zip-nms-v1_19_R2/src/main/java/net/imprex/zip/nms/v1_19_R2/ZipNmsManager.java b/zip-nms/zip-nms-v1_19_R2/src/main/java/net/imprex/zip/nms/v1_19_R2/ZipNmsManager.java
index 4b80fb1..ea3d9c7 100644
--- a/zip-nms/zip-nms-v1_19_R2/src/main/java/net/imprex/zip/nms/v1_19_R2/ZipNmsManager.java
+++ b/zip-nms/zip-nms-v1_19_R2/src/main/java/net/imprex/zip/nms/v1_19_R2/ZipNmsManager.java
@@ -15,8 +15,8 @@
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
-import net.imprex.zip.common.ReflectionUtil;
import net.imprex.zip.nms.api.NmsManager;
+import net.imprex.zip.util.ReflectionUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
@@ -85,6 +85,10 @@ public void setSkullProfile(SkullMeta meta, String texture) {
}
}
+ @Override
+ public void setupBackpackItem(ItemStack item) {
+ }
+
@Override
public boolean isAir(Material material) {
return material == null || material == Material.AIR;
diff --git a/zip-nms/zip-nms-v1_19_R3/src/main/java/net/imprex/zip/nms/v1_19_R3/ZipNmsManager.java b/zip-nms/zip-nms-v1_19_R3/src/main/java/net/imprex/zip/nms/v1_19_R3/ZipNmsManager.java
index 33b2dd1..33dc5bd 100644
--- a/zip-nms/zip-nms-v1_19_R3/src/main/java/net/imprex/zip/nms/v1_19_R3/ZipNmsManager.java
+++ b/zip-nms/zip-nms-v1_19_R3/src/main/java/net/imprex/zip/nms/v1_19_R3/ZipNmsManager.java
@@ -15,8 +15,8 @@
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
-import net.imprex.zip.common.ReflectionUtil;
import net.imprex.zip.nms.api.NmsManager;
+import net.imprex.zip.util.ReflectionUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
@@ -85,6 +85,10 @@ public void setSkullProfile(SkullMeta meta, String texture) {
}
}
+ @Override
+ public void setupBackpackItem(ItemStack item) {
+ }
+
@Override
public boolean isAir(Material material) {
return material == null || material == Material.AIR;
diff --git a/zip-nms/zip-nms-v1_20_R1/src/main/java/net/imprex/zip/nms/v1_20_R1/ZipNmsManager.java b/zip-nms/zip-nms-v1_20_R1/src/main/java/net/imprex/zip/nms/v1_20_R1/ZipNmsManager.java
index ecc1f92..32006e6 100644
--- a/zip-nms/zip-nms-v1_20_R1/src/main/java/net/imprex/zip/nms/v1_20_R1/ZipNmsManager.java
+++ b/zip-nms/zip-nms-v1_20_R1/src/main/java/net/imprex/zip/nms/v1_20_R1/ZipNmsManager.java
@@ -15,8 +15,8 @@
import com.mojang.authlib.GameProfile;
import com.mojang.authlib.properties.Property;
-import net.imprex.zip.common.ReflectionUtil;
import net.imprex.zip.nms.api.NmsManager;
+import net.imprex.zip.util.ReflectionUtil;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.nbt.NbtIo;
@@ -85,6 +85,10 @@ public void setSkullProfile(SkullMeta meta, String texture) {
}
}
+ @Override
+ public void setupBackpackItem(ItemStack item) {
+ }
+
@Override
public boolean isAir(Material material) {
return material == null || material == Material.AIR;
diff --git a/zip-nms/zip-nms-v1_20_R2/pom.xml b/zip-nms/zip-nms-v1_20_R2/pom.xml
new file mode 100644
index 0000000..e8aec54
--- /dev/null
+++ b/zip-nms/zip-nms-v1_20_R2/pom.xml
@@ -0,0 +1,68 @@
+
+ 4.0.0
+
+
+ net.imprex
+ zip-nms
+ ${revision}
+
+
+ zip-nms-v1_20_R2
+ jar
+
+
+
+ net.imprex
+ zip-nms-api
+ ${revision}
+ provided
+
+
+ org.spigotmc
+ spigot
+ 1.20.2-R0.1-SNAPSHOT
+ remapped-mojang
+ provided
+
+
+
+
+
+
+ net.md-5
+ specialsource-maven-plugin
+ ${plugin.specialsource.version}
+
+
+ package
+
+ remap
+
+ remap-obf
+
+ org.spigotmc:minecraft-server:1.20.2-R0.1-SNAPSHOT:txt:maps-mojang
+ true
+ org.spigotmc:spigot:1.20.2-R0.1-SNAPSHOT:jar:remapped-mojang
+ true
+ remapped-obf
+
+
+
+ package
+
+ remap
+
+ remap-spigot
+
+ ${project.build.directory}/${project.artifactId}-${project.version}-remapped-obf.jar
+ org.spigotmc:minecraft-server:1.20.2-R0.1-SNAPSHOT:csrg:maps-spigot
+ org.spigotmc:spigot:1.20.2-R0.1-SNAPSHOT:jar:remapped-obf
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/zip-nms/zip-nms-v1_20_R2/src/main/java/net/imprex/zip/nms/v1_20_R2/ZipNmsManager.java b/zip-nms/zip-nms-v1_20_R2/src/main/java/net/imprex/zip/nms/v1_20_R2/ZipNmsManager.java
new file mode 100644
index 0000000..14eed5e
--- /dev/null
+++ b/zip-nms/zip-nms-v1_20_R2/src/main/java/net/imprex/zip/nms/v1_20_R2/ZipNmsManager.java
@@ -0,0 +1,96 @@
+package net.imprex.zip.nms.v1_20_R2;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.UUID;
+
+import org.bukkit.Material;
+import org.bukkit.craftbukkit.v1_20_R2.inventory.CraftItemStack;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.SkullMeta;
+
+import com.mojang.authlib.GameProfile;
+import com.mojang.authlib.properties.Property;
+
+import net.imprex.zip.nms.api.NmsManager;
+import net.imprex.zip.util.ReflectionUtil;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.nbt.ListTag;
+import net.minecraft.nbt.NbtIo;
+import net.minecraft.nbt.Tag;
+
+public class ZipNmsManager implements NmsManager {
+
+ private static final Class> CRAFTMETASKULL_CLASS = ReflectionUtil.getCraftBukkitClass("inventory.CraftMetaSkull");
+ private static final Method CRAFTMETASKULL_SET_PROFILE = ReflectionUtil.getMethod(CRAFTMETASKULL_CLASS,
+ "setProfile", GameProfile.class);
+
+ public byte[] nbtToBinary(CompoundTag compound) {
+ try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
+ NbtIo.writeCompressed(compound, outputStream);
+ return outputStream.toByteArray();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
+ public CompoundTag binaryToNBT(byte[] binary) {
+ try (ByteArrayInputStream inputStream = new ByteArrayInputStream(binary)) {
+ return NbtIo.readCompressed(inputStream);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return new CompoundTag();
+ }
+
+ @Override
+ public byte[] itemstackToBinary(ItemStack[] items) {
+ CompoundTag inventory = new CompoundTag();
+ ListTag list = new ListTag();
+ for (ItemStack itemStack : items) {
+ net.minecraft.world.item.ItemStack craftItem = CraftItemStack.asNMSCopy(itemStack);
+ list.add(craftItem.save(new CompoundTag()));
+ }
+ inventory.put("i", list);
+ return nbtToBinary(inventory);
+ }
+
+ @Override
+ public List binaryToItemStack(byte[] binary) {
+ CompoundTag nbt = binaryToNBT(binary);
+ List items = new ArrayList<>();
+ if (nbt.contains("i", 9)) {
+ ListTag list = nbt.getList("i", 10);
+ for (Tag base : list) {
+ if (base instanceof CompoundTag) {
+ items.add(CraftItemStack.asBukkitCopy(net.minecraft.world.item.ItemStack.of((CompoundTag) base)));
+ }
+ }
+ }
+ return items;
+ }
+
+ @Override
+ public void setSkullProfile(SkullMeta meta, String texture) {
+ try {
+ GameProfile gameProfile = new GameProfile(UUID.randomUUID(), "");
+ gameProfile.getProperties().put("textures", new Property("textures", texture));
+ CRAFTMETASKULL_SET_PROFILE.invoke(meta, gameProfile);
+ } catch (Exception e) {
+ throw new ClassCastException("Error by setting skull profile");
+ }
+ }
+
+ @Override
+ public void setupBackpackItem(ItemStack item) {
+ }
+
+ @Override
+ public boolean isAir(Material material) {
+ return material == null || material == Material.AIR;
+ }
+}
\ No newline at end of file
diff --git a/zip-plugin/pom.xml b/zip-plugin/pom.xml
deleted file mode 100644
index 24034a3..0000000
--- a/zip-plugin/pom.xml
+++ /dev/null
@@ -1,75 +0,0 @@
-
- 4.0.0
-
-
- net.imprex
- zip
- ${revision}
-
-
- zip-plugin
- jar
-
-
-
- io.netty
- netty-buffer
- ${dependency.netty.version}
- provided
-
-
- org.spigotmc
- spigot-api
- ${dependency.bukkit.version}
- provided
-
-
- org.bstats
- bstats-bukkit
- ${dependency.bstats.version}
- compile
-
-
- net.imprex
- zip-api
- ${revision}
- compile
-
-
- net.imprex
- zip-common
- ${revision}
- provided
-
-
- net.imprex
- zip-nms-api
- ${revision}
- compile
-
-
- net.imprex
- zip-nms-v1_19_R1
- ${revision}
- compile
-
-
- net.imprex
- zip-nms-v1_19_R2
- ${revision}
- compile
-
-
- net.imprex
- zip-nms-v1_19_R3
- ${revision}
- compile
-
-
- net.imprex
- zip-nms-v1_20_R1
- ${revision}
- compile
-
-
-
\ No newline at end of file
diff --git a/zip-plugin/src/main/java/net/imprex/zip/BackpackPlugin.java b/zip-plugin/src/main/java/net/imprex/zip/BackpackPlugin.java
deleted file mode 100644
index 6861ce4..0000000
--- a/zip-plugin/src/main/java/net/imprex/zip/BackpackPlugin.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package net.imprex.zip;
-
-import org.bukkit.Bukkit;
-import org.bukkit.NamespacedKey;
-import org.bukkit.entity.Player;
-import org.bukkit.event.Cancellable;
-import org.bukkit.event.EventHandler;
-import org.bukkit.event.Listener;
-import org.bukkit.event.block.BlockPlaceEvent;
-import org.bukkit.event.player.PlayerInteractEvent;
-import org.bukkit.inventory.ItemStack;
-import org.bukkit.inventory.meta.ItemMeta;
-import org.bukkit.persistence.PersistentDataContainer;
-import org.bukkit.persistence.PersistentDataType;
-import org.bukkit.plugin.ServicePriority;
-import org.bukkit.plugin.java.JavaPlugin;
-
-import net.imprex.zip.api.ZIPService;
-import net.imprex.zip.command.BackpackCommand;
-import net.imprex.zip.config.BackpackConfig;
-import net.imprex.zip.util.ZIPLogger;
-
-public class BackpackPlugin extends JavaPlugin implements Listener, ZIPService {
-
- private NamespacedKey backpackIdentifierKey;
- private NamespacedKey backpackStorageKey;
-
- private BackpackConfig backpackConfig;
- private BackpackRegistry backpackRegistry;
- private BackpackHandler backpackHandler;
-
- private UpdateSystem updateSystem;
-
- @Override
- public void onLoad() {
- this.backpackIdentifierKey = this.createNamespacedKey("backpack.type");
- this.backpackStorageKey = this.createNamespacedKey("backpack.id");
-
- this.backpackConfig = new BackpackConfig(this);
- this.backpackRegistry = new BackpackRegistry(this);
- this.backpackHandler = new BackpackHandler(this);
- }
-
- @Override
- public void onEnable() {
- try {
- NmsInstance.initialize();
-
- this.backpackConfig.deserialize();
-
- this.backpackRegistry.register();
- this.backpackHandler.loadBackpacks();
-
- this.updateSystem = new UpdateSystem(this);
-
- new MetricsSystem(this);
-
- this.getCommand("zeroinventoryproblems").setExecutor(new BackpackCommand(this));
-
- Bukkit.getPluginManager().registerEvents(new BackpackListener(this), this);
- Bukkit.getServicesManager().register(ZIPService.class, this, this, ServicePriority.Normal);
- } catch (Exception e) {
- ZIPLogger.error("An error occured while enabling plugin", e);
-
- Bukkit.getPluginManager().registerEvents(this, this);
- }
- }
-
- @Override
- public void onDisable() {
- Bukkit.getOnlinePlayers().forEach(Player::closeInventory);
-
- if (this.backpackHandler != null) {
- this.backpackHandler.disable();
- }
- if (this.backpackRegistry != null) {
- this.backpackRegistry.unregister();
- }
-
- Bukkit.getServer().getScheduler().cancelTasks(this);
- }
-
- @EventHandler
- public void onBlockPlace(BlockPlaceEvent event) {
- this.handleItemOnError(event, event.getPlayer(), event.getItemInHand());
- }
-
- @EventHandler
- public void onPlayerInteract(PlayerInteractEvent event) {
- this.handleItemOnError(event, event.getPlayer(), event.getItem());
- }
-
- public void handleItemOnError(Cancellable event, Player player, ItemStack item) {
- if (item == null) {
- return;
- }
-
- ItemMeta meta = item.getItemMeta();
- if (meta == null) {
- return;
- }
-
- PersistentDataContainer persistentDataContainer = meta.getPersistentDataContainer();
- if (persistentDataContainer.has(this.backpackIdentifierKey, PersistentDataType.STRING)) {
- event.setCancelled(true);
-
- player.sendMessage("""
- §8[§eZeroInventoryProblems§8] §7Item is §cdisabled §7because of a plugin error§8.
- §8[§eZeroInventoryProblems§8] §7Please contact your server administrator§8.
- """);
- }
- }
-
- public NamespacedKey createNamespacedKey(String key) {
- return new NamespacedKey(this, key);
- }
-
- public UpdateSystem getUpdateSystem() {
- return this.updateSystem;
- }
-
- @Override
- public BackpackHandler getBackpackHandler() {
- return this.backpackHandler;
- }
-
- @Override
- public BackpackRegistry getBackpackRegistry() {
- return this.backpackRegistry;
- }
-
- public BackpackConfig getBackpackConfig() {
- return this.backpackConfig;
- }
-
- public NamespacedKey getBackpackStorageKey() {
- return this.backpackStorageKey;
- }
-
- public NamespacedKey getBackpackIdentifierKey() {
- return this.backpackIdentifierKey;
- }
-}
\ No newline at end of file
diff --git a/zip-plugin/src/main/java/net/imprex/zip/config/BackpackConfig.java b/zip-plugin/src/main/java/net/imprex/zip/config/BackpackConfig.java
deleted file mode 100644
index 4d0bdb0..0000000
--- a/zip-plugin/src/main/java/net/imprex/zip/config/BackpackConfig.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package net.imprex.zip.config;
-
-import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
-import org.bukkit.configuration.ConfigurationSection;
-import org.bukkit.configuration.file.FileConfiguration;
-
-import net.imprex.zip.BackpackPlugin;
-import net.imprex.zip.common.MinecraftVersion;
-
-public class BackpackConfig {
-
- private final BackpackPlugin plugin;
-
- private GeneralConfig generalConfig;
- private MessageConfig messageConfig;
- private BackpackTypeListConfig typeListConfig;
-
- public BackpackConfig(BackpackPlugin plugin) {
- this.plugin = plugin;
- }
-
- public void deserialize() {
- try {
- Path dataFolder = this.plugin.getDataFolder().toPath();
- Path configPath = dataFolder.resolve("config.yml");
-
- if (Files.notExists(configPath)) {
- String configVersion = MinecraftVersion.getMajorVersion() + "." + MinecraftVersion.getMinorVersion();
-
- if (Files.notExists(dataFolder)) {
- Files.createDirectories(dataFolder);
- }
-
- Files.copy(BackpackPlugin.class.getResourceAsStream("/config/config-" + configVersion + ".yml"), configPath);
- }
- } catch (IOException e) {
- throw new RuntimeException("unable to create config", e);
- }
-
- FileConfiguration config = this.plugin.getConfig();
-
- ConfigurationSection generalSection = config.getConfigurationSection("general");
- this.generalConfig = new GeneralConfig(generalSection);
-
- ConfigurationSection backpackTypeListSection = config.getConfigurationSection("type");
- this.typeListConfig = new BackpackTypeListConfig(backpackTypeListSection);
-
- this.messageConfig = new MessageConfig(this.plugin);
- }
-
- public GeneralConfig general() {
- return this.generalConfig;
- }
-
- public MessageConfig message() {
- return this.messageConfig;
- }
-
- public BackpackTypeListConfig typeList() {
- return this.typeListConfig;
- }
-}
\ No newline at end of file
diff --git a/zip-plugin/src/main/java/net/imprex/zip/config/BackpackTypeConfig.java b/zip-plugin/src/main/java/net/imprex/zip/config/BackpackTypeConfig.java
deleted file mode 100644
index 217c0b7..0000000
--- a/zip-plugin/src/main/java/net/imprex/zip/config/BackpackTypeConfig.java
+++ /dev/null
@@ -1,66 +0,0 @@
-package net.imprex.zip.config;
-
-import java.util.List;
-
-import org.bukkit.ChatColor;
-import org.bukkit.configuration.ConfigurationSection;
-
-public class BackpackTypeConfig {
-
- public String uniqueName;
-
- public Integer inventoryRows;
-
- public String displayName;
- public Integer customModelData;
- public String texture;
- public List lore;
-
- public RecipeConfig recipe;
-
- public BackpackTypeConfig(ConfigurationSection config, String key) {
- if (config == null) {
- throw new IllegalArgumentException("Config section for backpack type " + key + " not found");
- }
-
- if (config.contains("uniqueName")) {
- this.uniqueName = config.getString("uniqueName");
- } else {
- throw new IllegalArgumentException("Config value uniqueName was not found in backpack type " + key);
- }
-
- if (config.contains("displayName")) {
- this.displayName = ChatColor.translateAlternateColorCodes('&', config.getString("displayName"));
- } else {
- throw new IllegalArgumentException("Config value displayName was not found in backpack type " + key);
- }
-
- if (config.contains("inventoryRows") && config.isInt("customModelData")) {
- this.inventoryRows = config.getInt("inventoryRows");
- } else {
- throw new IllegalArgumentException("Config value inventoryRows was not found in backpack type " + key);
- }
-
- if (config.contains("customModelData") && config.isInt("customModelData")) {
- this.customModelData = config.getInt("customModelData");
- } else {
- throw new IllegalArgumentException("Config value customModelData was not found in backpack type " + key);
- }
-
- if (config.contains("texture")) {
- this.texture = config.getString("texture");
- } else {
- throw new IllegalArgumentException("Config value texture was not found in backpack type " + key);
- }
-
- if (config.contains("lore") && config.isList("lore")) {
- this.lore = config.getStringList("lore").stream().map(lore -> ChatColor.translateAlternateColorCodes('&', lore)).toList();
- } else {
- throw new IllegalArgumentException("Config value lore was not found in backpack type " + key);
- }
-
- ConfigurationSection recipeSection = config.getConfigurationSection("recipe");
- RecipeConfig recipeConfig = new RecipeConfig(recipeSection, key);
- this.recipe = recipeConfig;
- }
-}
diff --git a/zip-plugin/src/main/java/net/imprex/zip/config/BackpackTypeListConfig.java b/zip-plugin/src/main/java/net/imprex/zip/config/BackpackTypeListConfig.java
deleted file mode 100644
index eb61bde..0000000
--- a/zip-plugin/src/main/java/net/imprex/zip/config/BackpackTypeListConfig.java
+++ /dev/null
@@ -1,27 +0,0 @@
-package net.imprex.zip.config;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.bukkit.configuration.ConfigurationSection;
-
-public class BackpackTypeListConfig {
-
- public List type = new ArrayList<>();
-
- public BackpackTypeListConfig(ConfigurationSection config) {
- if (config == null) {
- throw new IllegalArgumentException("Config section type was not found");
- }
-
- for (String key : config.getKeys(false)) {
- try {
- ConfigurationSection backpackTypeSection = config.getConfigurationSection(key);
- BackpackTypeConfig backpackTypeConfig = new BackpackTypeConfig(backpackTypeSection, key);
- this.type.add(backpackTypeConfig);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
-}
diff --git a/zip-plugin/src/main/java/net/imprex/zip/config/GeneralConfig.java b/zip-plugin/src/main/java/net/imprex/zip/config/GeneralConfig.java
deleted file mode 100644
index 28bb450..0000000
--- a/zip-plugin/src/main/java/net/imprex/zip/config/GeneralConfig.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.imprex.zip.config;
-
-import org.bukkit.configuration.ConfigurationSection;
-
-public class GeneralConfig {
-
- public boolean checkForUpdates;
-
- public boolean verbose;
-
- public String locale;
-
- public int maxLoreCount;
-
- public GeneralConfig(ConfigurationSection config) {
- if (config == null) {
- throw new IllegalArgumentException("Config section general was not found");
- }
-
- if (config.contains("checkForUpdates") && config.isBoolean("checkForUpdates")) {
- this.checkForUpdates = config.getBoolean("checkForUpdates");
- } else {
- throw new IllegalArgumentException("Config section general is missing errorOccured value");
- }
-
- if (config.contains("verbose") && config.isBoolean("verbose")) {
- this.verbose = config.getBoolean("verbose");
- } else {
- throw new IllegalArgumentException("Config section general is missing verbose value");
- }
-
- if (config.contains("locale")) {
- this.locale = config.getString("locale");
- } else {
- throw new IllegalArgumentException("Config section general is missing locale value");
- }
-
- if (config.contains("maxLoreCount") && config.isInt("maxLoreCount")) {
- this.maxLoreCount = config.getInt("maxLoreCount");
- } else {
- this.maxLoreCount = 10;
- }
- }
-}
\ No newline at end of file
diff --git a/zip-plugin/src/main/java/net/imprex/zip/config/MessageConfig.java b/zip-plugin/src/main/java/net/imprex/zip/config/MessageConfig.java
deleted file mode 100644
index aa40f5a..0000000
--- a/zip-plugin/src/main/java/net/imprex/zip/config/MessageConfig.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package net.imprex.zip.config;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.nio.file.FileSystem;
-import java.nio.file.FileSystems;
-import java.nio.file.FileVisitResult;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.SimpleFileVisitor;
-import java.nio.file.attribute.BasicFileAttributes;
-import java.text.MessageFormat;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-
-import org.bukkit.command.CommandSender;
-import org.bukkit.configuration.file.YamlConfiguration;
-
-import net.imprex.zip.BackpackPlugin;
-import net.imprex.zip.util.ZIPLogger;
-import net.md_5.bungee.api.ChatColor;
-
-public class MessageConfig {
-
- private final BackpackPlugin plugin;
-
- private final Map messages = new HashMap<>();
-
- private String locale;
- private Path localeFolder;
- private Path localeFile;
-
- public MessageConfig(BackpackPlugin plugin) {
- this.plugin = plugin;
-
- this.locale = plugin.getBackpackConfig().general().locale;
- this.localeFolder = plugin.getDataFolder().toPath().resolve("lang");
- this.localeFile = this.localeFolder.resolve(this.locale + ".yml");
-
- this.copyLocaleWhenNotExist();
- this.loadLocale(plugin.getBackpackConfig().general().locale);
- }
-
- public void copyLocaleWhenNotExist() {
- try {
- URI resource = BackpackPlugin.class.getResource("").toURI();
-
- try (FileSystem fileSystem = FileSystems.newFileSystem(
- resource,
- Collections.emptyMap())) {
- Files.createDirectories(this.localeFolder);
-
- Path langPath = fileSystem.getPath("/lang");
- Files.walkFileTree(langPath, new SimpleFileVisitor() {
-
- @Override
- public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
- Path filePath = MessageConfig.this.localeFolder.resolve(langPath.relativize(file).toString());
- if (Files.notExists(filePath)) {
- Files.copy(file, MessageConfig.this.localeFolder.resolve(langPath.relativize(file).toString()));
- }
- return FileVisitResult.CONTINUE;
- }
- });
- }
- } catch (IOException | URISyntaxException e) {
- throw new RuntimeException("unable to copy locale configs", e);
- }
- }
-
- public void loadLocale(String locale) {
- if (Files.notExists(this.localeFile)) {
- ZIPLogger.warn("No config path for locale " + this.plugin.getBackpackConfig().general().locale + ".yml found in lang folder");
- return;
- }
-
- YamlConfiguration config = new YamlConfiguration();
- try (BufferedReader reader = Files.newBufferedReader(this.localeFile)) {
- config.load(reader);
- } catch (Exception e) {
- ZIPLogger.error("Unable to read locale config file " + this.locale + ".yml", e);
- }
-
- for (String key : config.getKeys(false)) {
- MessageKey messageKey = MessageKey.findByKey(key);
- if (messageKey != null) {
- this.messages.put(messageKey, ChatColor.translateAlternateColorCodes('&', config.getString(key)));
- } else {
- ZIPLogger.warn(String.format("Unable to find a vaild message key for \"%s\" in language file \"%s\"", key, this.locale));
- }
- }
-
- for (MessageKey messageKey : MessageKey.values()) {
- if (this.messages.containsKey(messageKey)) {
- continue;
- }
-
- ZIPLogger.warn(String.format("Unable to find a message key for \"%s\" in language file \"%s\"", messageKey.getKey(), this.locale));
- }
- }
-
- public String get(MessageKey key, Object... args) {
- return this.getWithoutPrefix(MessageKey.Prefix) + this.getWithoutPrefix(key, args);
- }
-
- public String getWithoutPrefix(MessageKey key, Object... args) {
- String message = this.messages.get(key);
- if (message == null) {
- message = key.getDefaultMessage();
- }
-
- return MessageFormat.format(message, args);
- }
-
- public void send(CommandSender sender, MessageKey key, Object... args) {
- sender.sendMessage(this.get(key, args));
- }
-}
diff --git a/zip-plugin/src/main/java/net/imprex/zip/config/MessageKey.java b/zip-plugin/src/main/java/net/imprex/zip/config/MessageKey.java
deleted file mode 100644
index c9b2c94..0000000
--- a/zip-plugin/src/main/java/net/imprex/zip/config/MessageKey.java
+++ /dev/null
@@ -1,88 +0,0 @@
-package net.imprex.zip.config;
-
-public enum MessageKey {
-
- Prefix("prefix", "§8[§eZIP§8] §7"),
- NotAConsoleCommand("notAConsoleCommand", "This command can not be executed from the console"),
- YouDontHaveTheFollowingPermission("youDontHaveTheFollowingPermission", "You Don't have the following permission §8\"§e{0}§8\""),
- ThisBackpackNoLongerExist("ThisBackpackNoLongerExist", "This backpack no longer exist"),
- ClickHereToSeeTheLatestRelease("clickHereToSeeTheLatestRelease", "Click here to see the latest release"),
- ANewReleaseIsAvailable("ANewReleaseIsAvailable", "A new version is available"),
- ClickHere("clickHere", "§f§l[CLICK HERE]"),
- CommandHelpStart("commandHelpStart", "§8[]§7========== §eZeroInventoryProblems §7==========§8[]"),
- CommandHelpPickup("commandHelpPickup", "§8/§7zip §epickup §8| §7Pickup inaccessible items§8."),
- CommandHelpLink("commandHelpLink", "§8/§7zip §elink §7<§ecancel§7> §8| §7Link multiple backpacks or cancel the request§8."),
- CommandHelpGive("commandHelpGive", "§8/§7zip §egive §7[§etype§7] §7<§eplayer§7> §8| §7Give yourself a backpack§8."),
- CommandHelpType("commandHelpType", "§8/§7zip §etype §8| §7Get a list of all backpacks§8."),
- CommandHelpLore("commandHelpLore", "§8/§7zip §elore §8| §7Write a custom lore§8."),
- CommandHelpEnd("commandHelpEnd", "§8[]§7========== §eZeroInventoryProblems §7==========§8[]"),
- CommandTypeStart("commandTypeStart", "§8[]§7========== §eZeroInventoryProblems Types §7==========§8[]"),
- CommandTypeContent("commandTypeContent", " §8-§e{0}"),
- CommandTypeButtonGive("commandTypeButtonGive", "§7[§eGive§7]"),
- CommandTypeButtonGiveHover("commandTypeButtonGiveHover", "§eClick here to give yourself a §8\"§e{0}§8\" backpack"),
- CommandTypeEnd("commandTypeEnd", "§8[]§7========== §eZeroInventoryProblems Types §7==========§8[]"),
- CommandHelpLoreSyntax("commandHelpLoreSyntax", """
- §8/§7zip §elore add §7<§eMessage§7> §8| §7Add a lore§8.
- §8/§7zip §elore change §7<§eLine§7> §7<§eMessage§7> §8| §7Change a line§8.
- §8/§7zip §elore delete §7<§eLine§7> §8| §7Delete a line§8.
- §8/§7zip §elore list §8| §7List of all lore lines§8.
- """),
- CommandLoreStart("commandLoreStart", "§8[]§7========== §eZeroInventoryProblems Lore §7==========§8[]"),
- CommandLoreContent("commandLoreContent", " §8{0}: §e{1}"),
- CommandLoreButtonEdit("commandLoreButtonEdit", "§7[§eEdit§7]"),
- CommandLoreButtonEditHover("commandLoreButtonEditHover", "§eClick here to edit this line"),
- CommandLoreButtonDelete("commandLoreButtonDelete", "§7[§eDelete§7]"),
- CommandLoreButtonDeleteHover("commandLoreButtonDeleteHover", "§eClick here to delete this line"),
- CommandLoreEnd("commandLoreEnd", "§8[]§7========== §eZeroInventoryProblems Lore §7==========§8[]"),
- NoOnlinePlayerWasFound("noOnlinePlayerWasFound", "No online player with the name §8\"§e{0}§8} §7was found"),
- PleaseEnterABackpackType("pleaseEnterABackpackType", "Please enter a backpack type §8(small/medium/big)"),
- BackpackTypeWasNotFound("backpackTypeWasNotFound", "Backpack type §8\"§e{0}§8\" §7was not found"),
- YouHaveGivenYourselfABackpack("youHaveGivenYourselfABackpack", "You received a §8\"§e{0}§8\" §7backpack"),
- YouHaveGivenTargetPlayerABackpack("youHaveGivenTargetPlayerABackpack", "You given a §8\"§e{0}§8\" §7backpack to §8\"§e{1}§8\""),
- YouNeedToHoldABackpackInYourHand("youNeedToHoldABackpackInYourHand", "You need to hold a backpack in your hand"),
- YourBackpackHasNoUnusableItems("yourBackpackHasNoUnusableItems", "Your backpack has no inaccessible items"),
- YouNeedMoreSpaceInYourInventory("youNeedMoreSpaceInYourInventory", "You need more space in your inventory"),
- TargetPlayerNeedMoreSpaceInYourInventory("targetPlayerNeedMoreSpaceInYourInventory", "§8\"§e{0}§8\" §7needs more space in his/her inventory"),
- YouReceivedAllUnusableItems("youReceivedAllUnusableItems", "You\'ve received all inaccessible items"),
- YouHaveUnusableItemsUsePickup("youHaveUnusableItemsUsePickup", "Your backpack contains inaccessible items§8! §7Use §e/zip pickup"),
- YourBackpackIsNotEmpty("yourBackpackIsNotEmpty", "Your Backpack needs to be empty"),
- YouNeedToHoldBothBackpacksInYouInventory("youNeedToHoldBothBackpacksInYourInventory", "You need to hold both backpacks in your inventory"),
- YouCanNowHoldTheBackpackWhichShouldBeLinked("youCanNowHoldTheBackpackWhichShouldBeLinked", "You can now hold the second backpack that should be linked"),
- ThisShouldNotHappenedPleaseTryToLinkAgain("thisShouldNotHappenedPleaseTryToLinkAgain", "An error occurred, please try to link again"),
- YourBackpackIsNowLinked("yourBackpackIsNowLinked", "Your backpack is now linked"),
- YouNeedToLinkABackpackFirst("youNeedToLinkABackpackFirst", "You need to link a backpack at first"),
- YourBackpackLinkRequestWasCancelled("yourBackpackLinkRequestWasCancelled", "Your backpack link request was cancelled"),
- BothBackpacksNeedToBeTheSameType("bothBackpacksNeedToBeTheSameType", "Both Backpacks need to be the same type"),
- ThisBackpackIsAlreadyLinkedThoThat("thisBackpackIsAlreadyLinkedThoThat", "This backpack is already linked to that backpack"),
- PleaseEnterANumber("pleaseEnterANumber", "Please enter a number"),
- EnterANumberBetweenArgsAndArgs("enterANumberBetweenArgsAndArgs", "Please enter a number between {0} and {1}"),
- LoreLineCreate("loreLineCreate", "The lore line {0} was added"),
- LoreLineChange("loreLineChange", "The lore line {0} was changed"),
- LoreLineDelete("loreLineDelete", "The lore line {0} was deleted"),
- MaxLoreCountReached("maxLoreCountReached", "You have reached the max lore count of {0}");
-
- public static MessageKey findByKey(String key) {
- for (MessageKey messageKey : values()) {
- if (messageKey.key.equalsIgnoreCase(key)) {
- return messageKey;
- }
- }
- return null;
- }
-
- private final String key;
- private final String defaultMessage;
-
- private MessageKey(String key, String defaultMessage) {
- this.key = key;
- this.defaultMessage = defaultMessage;
- }
-
- public String getKey() {
- return this.key;
- }
-
- public String getDefaultMessage() {
- return this.defaultMessage;
- }
-}
\ No newline at end of file
diff --git a/zip-plugin/src/main/java/net/imprex/zip/config/RecipeConfig.java b/zip-plugin/src/main/java/net/imprex/zip/config/RecipeConfig.java
deleted file mode 100644
index 99d4d3c..0000000
--- a/zip-plugin/src/main/java/net/imprex/zip/config/RecipeConfig.java
+++ /dev/null
@@ -1,91 +0,0 @@
-package net.imprex.zip.config;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import org.bukkit.Material;
-import org.bukkit.configuration.ConfigurationSection;
-
-import net.imprex.zip.util.ZIPLogger;
-
-public class RecipeConfig {
-
- public Boolean discover;
- public String group;
- public String patternOne;
- public String patternTwo;
- public String patternThree;
- public Map patternMapping;
-
- public RecipeConfig(ConfigurationSection config, String key) {
- if (config == null) {
- throw new IllegalArgumentException("Config section for backpack recipe in " + key + " not found");
- }
-
- if (config.contains("discover") && config.isBoolean("discover")) {
- this.discover = config.getBoolean("discover");
- } else {
- throw new IllegalArgumentException("Config value discover was not found in backpack type " + key);
- }
-
- if (config.contains("group")) {
- String group = config.getString("group");
- this.group = group != null && !group.equalsIgnoreCase("null")
- ? group
- : null;
- } else {
- throw new IllegalArgumentException("Config value group was not found in backpack type " + key);
- }
-
- if (config.contains("patternOne")) {
- this.patternOne = config.getString("patternOne");
- } else {
- throw new IllegalArgumentException("Config value patternOne was not found in backpack type " + key);
- }
-
- if (config.contains("patternTwo")) {
- this.patternTwo = config.getString("patternTwo");
- } else {
- throw new IllegalArgumentException("Config value patternTwo was not found in backpack type " + key);
- }
-
- if (config.contains("patternThree")) {
- this.patternThree = config.getString("patternThree");
- } else {
- throw new IllegalArgumentException("Config value patternThree was not found in backpack type " + key);
- }
-
-
- ConfigurationSection patternMappingSection = config.getConfigurationSection("patternMapping");
- Map patternMapping = this.loadBackpackRecipeMapping(patternMappingSection, key);
- this.patternMapping = patternMapping;
- }
-
- public Map loadBackpackRecipeMapping(ConfigurationSection config, String key) {
- if (config == null) {
- throw new IllegalArgumentException("Config value patternMapping was not found in backpack type " + key);
- }
-
- Map patternMapping = new HashMap<>();
- for (String mappingKey : config.getKeys(false)) {
- Material material = null;
- try {
- material = Material.valueOf(config.getString(mappingKey));
- } catch (Exception e) {
- ZIPLogger.warn(String.format("Config material value \"%s\" is not valid in backpack recipe type section \"%s\"",
- config.getString(mappingKey),
- key));
- }
-
- if (material == null || mappingKey.length() != 1) {
- throw new IllegalArgumentException(String.format("Config value \"%s\" is not valid in backpack recipe type section \"%s\"",
- mappingKey,
- key));
- }
-
- patternMapping.put(mappingKey, material);
- }
-
- return patternMapping;
- }
-}
diff --git a/zip-plugin/src/main/resources/config/config-1.19.yml b/zip-plugin/src/main/resources/config/config-1.19.yml
deleted file mode 100644
index b4b5562..0000000
--- a/zip-plugin/src/main/resources/config/config-1.19.yml
+++ /dev/null
@@ -1,63 +0,0 @@
-general:
- checkForUpdates: true
- verbose: false
- locale: en_US
-type:
- big:
- uniqueName: 'big'
- displayName: '&7Big &eBackpack'
- inventoryRows: 6
- customModelData: 3
- texture: 'ewogICJ0aW1lc3RhbXAiIDogMTYzMzg2MjQwNTg4NSwKICAicHJvZmlsZUlkIiA6ICI1NjY3NWIyMjMyZjA0ZWUwODkxNzllOWM5MjA2Y2ZlOCIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaGVJbmRyYSIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9kYTMzMTY5YjcyY2Y4OTE4YjgyYzViZDI3Y2JhOWVlNmMwZWI4OTE2NDA0MDQ4MGJiMjdmODUzNGUwZmE1ODA3IiwKICAgICAgIm1ldGFkYXRhIiA6IHsKICAgICAgICAibW9kZWwiIDogInNsaW0iCiAgICAgIH0KICAgIH0KICB9Cn0='
- lore:
- - '&aA Big Backpack'
- recipe:
- discover: true
- group: 'null'
- patternOne: 'LCL'
- patternTwo: 'ECE'
- patternThree: 'DCD'
- patternMapping:
- L: LEATHER
- E: LEAD
- C: CHEST
- D: DIAMOND
- medium:
- uniqueName: 'medium'
- displayName: '&7Medium &eBackpack'
- inventoryRows: 3
- customModelData: 2
- texture: 'ewogICJ0aW1lc3RhbXAiIDogMTY3NDM0NDQ0MzY4NywKICAicHJvZmlsZUlkIiA6ICIxMzdmMjg3MjUwOTE0ZmI4YjA0ZTYwYjg4MWUwZWE2YiIsCiAgInByb2ZpbGVOYW1lIiA6ICJub3JtYWxpc2luZyIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9lZjhlZDY4NWIzYzNjYWI4NDM1ZDBmNmIwZDJkZGI0NmRmYTNhYzk2ZmUyZjlhNmQ3NDhmNzExOTFjMGI1MjJiIgogICAgfQogIH0KfQ=='
- lore:
- - '&aA Medium Backpack'
- recipe:
- discover: true
- group: 'null'
- patternOne: 'LSL'
- patternTwo: 'ECE'
- patternThree: 'ICI'
- patternMapping:
- L: LEATHER
- S: STICK
- E: LEAD
- C: CHEST
- I: IRON_INGOT
- small:
- uniqueName: 'small'
- displayName: '&7Small &eBackpack'
- inventoryRows: 1
- customModelData: 1
- texture: 'ewogICJ0aW1lc3RhbXAiIDogMTYxMzM4Nzk2NDUxNSwKICAicHJvZmlsZUlkIiA6ICJkZTU3MWExMDJjYjg0ODgwOGZlN2M5ZjQ0OTZlY2RhZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJNSEZfTWluZXNraW4iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGFlMTg3MTQ1ZWU3MzJlN2MwMDkwNWE5YzE2ZWQxZTQzYmE4OGQ1NjI0YTZmNGFmODI5ZjEwNDUzZmNjOTE2NSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9'
- lore:
- - '&aA Small Backpack'
- recipe:
- discover: true
- group: 'null'
- patternOne: 'LSL'
- patternTwo: 'ECE'
- patternThree: 'LLL'
- patternMapping:
- L: LEATHER
- S: STICK
- E: LEAD
- C: CHEST
\ No newline at end of file
diff --git a/zip-plugin/src/main/resources/config/config-1.20.yml b/zip-plugin/src/main/resources/config/config-1.20.yml
deleted file mode 100644
index b4b5562..0000000
--- a/zip-plugin/src/main/resources/config/config-1.20.yml
+++ /dev/null
@@ -1,63 +0,0 @@
-general:
- checkForUpdates: true
- verbose: false
- locale: en_US
-type:
- big:
- uniqueName: 'big'
- displayName: '&7Big &eBackpack'
- inventoryRows: 6
- customModelData: 3
- texture: 'ewogICJ0aW1lc3RhbXAiIDogMTYzMzg2MjQwNTg4NSwKICAicHJvZmlsZUlkIiA6ICI1NjY3NWIyMjMyZjA0ZWUwODkxNzllOWM5MjA2Y2ZlOCIsCiAgInByb2ZpbGVOYW1lIiA6ICJUaGVJbmRyYSIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9kYTMzMTY5YjcyY2Y4OTE4YjgyYzViZDI3Y2JhOWVlNmMwZWI4OTE2NDA0MDQ4MGJiMjdmODUzNGUwZmE1ODA3IiwKICAgICAgIm1ldGFkYXRhIiA6IHsKICAgICAgICAibW9kZWwiIDogInNsaW0iCiAgICAgIH0KICAgIH0KICB9Cn0='
- lore:
- - '&aA Big Backpack'
- recipe:
- discover: true
- group: 'null'
- patternOne: 'LCL'
- patternTwo: 'ECE'
- patternThree: 'DCD'
- patternMapping:
- L: LEATHER
- E: LEAD
- C: CHEST
- D: DIAMOND
- medium:
- uniqueName: 'medium'
- displayName: '&7Medium &eBackpack'
- inventoryRows: 3
- customModelData: 2
- texture: 'ewogICJ0aW1lc3RhbXAiIDogMTY3NDM0NDQ0MzY4NywKICAicHJvZmlsZUlkIiA6ICIxMzdmMjg3MjUwOTE0ZmI4YjA0ZTYwYjg4MWUwZWE2YiIsCiAgInByb2ZpbGVOYW1lIiA6ICJub3JtYWxpc2luZyIsCiAgInNpZ25hdHVyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgInVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS9lZjhlZDY4NWIzYzNjYWI4NDM1ZDBmNmIwZDJkZGI0NmRmYTNhYzk2ZmUyZjlhNmQ3NDhmNzExOTFjMGI1MjJiIgogICAgfQogIH0KfQ=='
- lore:
- - '&aA Medium Backpack'
- recipe:
- discover: true
- group: 'null'
- patternOne: 'LSL'
- patternTwo: 'ECE'
- patternThree: 'ICI'
- patternMapping:
- L: LEATHER
- S: STICK
- E: LEAD
- C: CHEST
- I: IRON_INGOT
- small:
- uniqueName: 'small'
- displayName: '&7Small &eBackpack'
- inventoryRows: 1
- customModelData: 1
- texture: 'ewogICJ0aW1lc3RhbXAiIDogMTYxMzM4Nzk2NDUxNSwKICAicHJvZmlsZUlkIiA6ICJkZTU3MWExMDJjYjg0ODgwOGZlN2M5ZjQ0OTZlY2RhZCIsCiAgInByb2ZpbGVOYW1lIiA6ICJNSEZfTWluZXNraW4iLAogICJzaWduYXR1cmVSZXF1aXJlZCIgOiB0cnVlLAogICJ0ZXh0dXJlcyIgOiB7CiAgICAiU0tJTiIgOiB7CiAgICAgICJ1cmwiIDogImh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOGFlMTg3MTQ1ZWU3MzJlN2MwMDkwNWE5YzE2ZWQxZTQzYmE4OGQ1NjI0YTZmNGFmODI5ZjEwNDUzZmNjOTE2NSIsCiAgICAgICJtZXRhZGF0YSIgOiB7CiAgICAgICAgIm1vZGVsIiA6ICJzbGltIgogICAgICB9CiAgICB9CiAgfQp9'
- lore:
- - '&aA Small Backpack'
- recipe:
- discover: true
- group: 'null'
- patternOne: 'LSL'
- patternTwo: 'ECE'
- patternThree: 'LLL'
- patternMapping:
- L: LEATHER
- S: STICK
- E: LEAD
- C: CHEST
\ No newline at end of file
diff --git a/zip-plugin/src/main/resources/lang/en_US.yml b/zip-plugin/src/main/resources/lang/en_US.yml
deleted file mode 100644
index 46c27e3..0000000
--- a/zip-plugin/src/main/resources/lang/en_US.yml
+++ /dev/null
@@ -1,53 +0,0 @@
-prefix: "&8[&eZIP&8] &7"
-notAConsoleCommand: "This command can not be executed from the console"
-youDontHaveTheFollowingPermission: "You Don''t have the following permission &8\"&e{0}&8\""
-ThisBackpackNoLongerExist: "This backpack no longer exist"
-clickHereToSeeTheLatestRelease: "Click here to see the latest release"
-ANewReleaseIsAvailable: "A new version is available"
-clickHere: "&f&l[CLICK HERE]"
-commandHelpStart: "&8[]&7========== &eZeroInventoryProblems &7==========&8[]"
-commandHelpPickup: "&8/&7zip &epickup &8| &7Pickup inaccessible items&8."
-commandHelpLink: "&8/&7zip &elink &7<&ecancel&7> &8| &7Link multiple backpacks or cancel the request&8."
-commandHelpGive: "&8/&7zip &egive &7[&etype&7] &7<&eplayer&7> &8| &7Give yourself a backpack&8."
-commandHelpType: "&8/&7zip &etype &8| &7Get a list of all backpacks&8."
-commandHelpLore: "&8/&7zip &elore &8| &7Write a custom lore&8."
-commandHelpEnd: "&8[]&7========== &eZeroInventoryProblems &7==========&8[]"
-commandTypeStart: "&8[]&7========== &eZeroInventoryProblems Types &7==========&8[]"
-commandTypeContent: " &8-&e{0}"
-commandTypeButtonGive: "&7[&eGive&7]"
-commandTypeButtonGiveHover: "&eClick here to give yourself a &8\"&e{0}&8\" &ebackpack"
-commandTypeEnd: "&8[]&7========== &eZeroInventoryProblems Types &7==========&8[]"
-commandHelpLoreSyntax: "&8/&7zip &elore add &7<&eMessage&7> &8| &7Add a lore&8.\n&8/&7zip &elore change &7<&eLine&7> &7<&eMessage&7> &8| &7Change a line&8.\n&8/&7zip &elore delete &7<&eLine&7> &8| &7Delete a line&8.\n&8/&7zip &elore list &8| &7List of all lore lines&8."
-commandLoreStart: "&8[]&7========== &eZeroInventoryProblems Lore &7==========&8[]"
-commandLoreContent: " &8{0}: &e{1}"
-commandLoreButtonEdit: "&7[&eEdit&7]"
-commandLoreButtonEditHover: "&eClick here to edit this line"
-commandLoreButtonDelete: "&7[&eDelete&7]"
-commandLoreButtonDeleteHover: "&eClick here to delete this line"
-commandLoreEnd: "&8[]&7========== &eZeroInventoryProblems Lore &7==========&8[]"
-noOnlinePlayerWasFound: "No online player with the name &8\"&e{0}&8} &7was found"
-pleaseEnterABackpackType: "Please enter a backpack type &8(small/medium/big)"
-backpackTypeWasNotFound: "Backpack type &8\"&e{0}&8\" &7was not found"
-youHaveGivenYourselfABackpack: "You received a &8\"&e{0}&8\" &7backpack"
-youHaveGivenTargetPlayerABackpack: "You given a &8\"&e{0}&8\" &7backpack to &8\"&e{1}&8\""
-youNeedToHoldABackpackInYourHand: "You need to hold a backpack in your hand"
-yourBackpackHasNoUnusableItems: "Your backpack has no inaccessible items"
-youNeedMoreSpaceInYourInventory: "You need more space in your inventory"
-targetPlayerNeedMoreSpaceInYourInventory: "&8\"&e{0}&8\" &7needs more space in his/her inventory"
-youReceivedAllUnusableItems: "You''ve received all inaccessible items"
-youHaveUnusableItemsUsePickup: "Your backpack contains inaccessible items&8! &7Use &e/zip pickup"
-yourBackpackIsNotEmpty: "Your Backpack needs to be empty"
-youNeedToHoldBothBackpacksInYourInventory: "You need to hold both backpacks in your inventory"
-youCanNowHoldTheBackpackWhichShouldBeLinked: "You can now hold the second backpack that should be linked"
-thisShouldNotHappenedPleaseTryToLinkAgain: "An error occurred, please try to link again"
-yourBackpackIsNowLinked: "Your backpack is now linked"
-youNeedToLinkABackpackFirst: "You need to link a backpack at first"
-yourBackpackLinkRequestWasCancelled: "Your backpack link request was cancelled"
-bothBackpacksNeedToBeTheSameType: "Both Backpacks need to be the same type"
-thisBackpackIsAlreadyLinkedThoThat: "This backpack is already linked to that backpack"
-pleaseEnterANumber: "Please enter a number"
-enterANumberBetweenArgsAndArgs: "Please enter a number between {0} and {1}"
-loreLineCreate: "The lore line {0} was added"
-loreLineChange: "The lore line {0} was changed"
-loreLineDelete: "The lore line {0} was deleted"
-maxLoreCountReached: "You have reached the max lore count of {0}"
\ No newline at end of file