diff --git a/.github/workflows/javadocs.yml b/.github/workflows/javadocs.yml index 6a655229..2e4f2b18 100644 --- a/.github/workflows/javadocs.yml +++ b/.github/workflows/javadocs.yml @@ -10,7 +10,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Set up JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/publish_to_nexus.yml b/.github/workflows/publish_to_nexus.yml index 5908ec77..2a7292d9 100755 --- a/.github/workflows/publish_to_nexus.yml +++ b/.github/workflows/publish_to_nexus.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.0 - name: Set up JDK 17 uses: actions/setup-java@v3 with: diff --git a/.github/workflows/verify.yml b/.github/workflows/verify.yml index bc1ed5e8..6f46e7f2 100755 --- a/.github/workflows/verify.yml +++ b/.github/workflows/verify.yml @@ -3,14 +3,14 @@ name: Verify state on: push: pull_request: - types: [opened, ready_for_review, review_requested, edited] + types: [ opened, ready_for_review, review_requested, edited ] jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3.3.0 + - uses: actions/checkout@v3.5.0 - name: Set up JDK 17 uses: actions/setup-java@v3 with: diff --git a/build.gradle.kts b/build.gradle.kts index 7b6404be..147cedc1 100755 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,108 +1,124 @@ +import com.diffplug.gradle.spotless.SpotlessPlugin +import de.chojo.PublishData + plugins { - id("com.github.johnrengelman.shadow") version "8.1.0" java `maven-publish` `java-library` - id("de.chojo.publishdata") version "1.2.3" - id("com.diffplug.spotless") version "6.16.0" + id("de.chojo.publishdata") version "1.2.4" + id("com.diffplug.spotless") version "6.18.0" } -group = "de.eldoria" +group = "de.eldoria.util" var mainPackage = "eldoutilities" val shadebase = group as String? + "." + mainPackage + "." -version = "1.14.4" +version = "2.0.1" description = "Utility Library for spigot plugins used by the eldoria team." -javaToolchains { - java { - sourceCompatibility = JavaVersion.VERSION_17 +allprojects { + apply { + plugin() + plugin() + plugin() + plugin() + plugin() } - testing{ + repositories { + mavenCentral() + maven("https://eldonexus.de/repository/maven-public") + maven("https://eldonexus.de/repository/maven-proxies") + maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") + maven("https://repo.papermc.io/repository/maven-public/") } -} - -repositories { - mavenCentral() - maven("https://eldonexus.de/repository/maven-proxies") - maven("https://hub.spigotmc.org/nexus/content/repositories/snapshots") - maven("https://repo.papermc.io/repository/maven-public/") -} - -dependencies { - implementation("org.bstats", "bstats-bukkit", "3.0.1") - compileOnly("org.spigotmc", "spigot-api", "1.16.5-R0.1-SNAPSHOT") - compileOnly("org.jetbrains", "annotations", "24.0.1") - - testImplementation("org.jetbrains", "annotations", "24.0.1") - testImplementation("org.spigotmc", "spigot-api", "1.16.5-R0.1-SNAPSHOT") - testImplementation("org.junit.jupiter", "junit-jupiter-api", "5.9.2") - testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", "5.9.2") - testImplementation("org.mockito", "mockito-core", "5.2.0") - testImplementation("com.github.seeseemelk", "MockBukkit-v1.19", "2.145.0") -} - -java { - withSourcesJar() - withJavadocJar() -} + dependencies { + compileOnly("org.spigotmc", "spigot-api", "1.16.5-R0.1-SNAPSHOT") + compileOnly("org.jetbrains", "annotations", "24.0.1") -publishData { - useEldoNexusRepos() - publishTask("shadowJar") - publishTask("sourcesJar") - publishTask("javadocJar") -} + testImplementation("org.jetbrains", "annotations", "24.0.1") + testImplementation("org.spigotmc", "spigot-api", "1.16.5-R0.1-SNAPSHOT") + testImplementation("org.junit.jupiter", "junit-jupiter-api", "5.9.2") + testRuntimeOnly("org.junit.jupiter", "junit-jupiter-engine", "5.9.2") + testImplementation("org.mockito", "mockito-core", "5.2.0") + testImplementation("com.github.seeseemelk", "MockBukkit-v1.19", "2.145.0") + } - spotless { - java { - licenseHeaderFile(rootProject.file("HEADER.txt")) - target("**/*.java") + java { + withSourcesJar() + withJavadocJar() + toolchain { + languageVersion.set(JavaLanguageVersion.of(17)) } } -publishing { - publications.create("maven") { - publishData.configurePublication(this); + publishData{ + useEldoNexusRepos() + publishComponent("java") } - repositories { - maven { - authentication { - credentials(PasswordCredentials::class) { - username = System.getenv("NEXUS_USERNAME") - password = System.getenv("NEXUS_PASSWORD") + publishing { + publications.create("maven") { + publishData.configurePublication(this); + } + + repositories { + maven { + authentication { + credentials(PasswordCredentials::class) { + username = System.getenv("NEXUS_USERNAME") + password = System.getenv("NEXUS_PASSWORD") + } } - } - name = "EldoNexus" - setUrl(publishData.getRepository()) + name = "EldoNexus" + setUrl(publishData.getRepository()) + } } } -} -tasks { - compileJava { - options.encoding = "UTF-8" + spotless { + java { + licenseHeaderFile(rootProject.file("HEADER.txt")) + target("**/*.java") + } } - javadoc { - options.encoding = "UTF-8" - } + tasks { + compileJava { + options.encoding = "UTF-8" + } - compileTestJava { - options.encoding = "UTF-8" - } + javadoc { + options.encoding = "UTF-8" + } - test { - useJUnitPlatform() - testLogging { - events("passed", "skipped", "failed") + compileTestJava { + options.encoding = "UTF-8" + } + + test { + useJUnitPlatform() + testLogging { + events("passed", "skipped", "failed") + } } } - shadowJar { - relocate("org.bstats", shadebase + "bstats") - mergeServiceFiles() - archiveClassifier.set("") - } +} + +dependencies{ + api(project(":commands")) + api(project(":configuration")) + api(project(":core")) + api(project(":crossversion")) + api(project(":debugging")) + api(project(":entities")) + api(project(":inventory")) + api(project(":items")) + api(project(":legacy-serialization")) + api(project(":localization")) + api(project(":messaging")) + api(project(":metrics")) + api(project(":plugin")) + api(project(":threading")) + api(project(":updater")) } diff --git a/commands/build.gradle.kts b/commands/build.gradle.kts new file mode 100644 index 00000000..148620de --- /dev/null +++ b/commands/build.gradle.kts @@ -0,0 +1,6 @@ +dependencies { + api(project(":core")) + api(project(":messaging")) + api(project(":debugging")) + api(project(":localization")) +} diff --git a/src/main/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtil.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/Completion.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtil.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/Completion.java index 4e245b82..412f374d 100644 --- a/src/main/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtil.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/Completion.java @@ -4,11 +4,10 @@ * Copyright (C) EldoriaRPG Team and Contributor */ -package de.eldoria.eldoutilities.simplecommands; +package de.eldoria.eldoutilities.commands; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; -import de.eldoria.eldoutilities.C; import de.eldoria.eldoutilities.commands.command.util.CommandAssertions; import de.eldoria.eldoutilities.commands.exceptions.CommandException; import de.eldoria.eldoutilities.utils.ArrayUtil; @@ -43,20 +42,16 @@ * @since 1.0.0 */ @SuppressWarnings("unused") -public final class TabCompleteUtil { +public final class Completion { + public static final long OFFLINE_PLAYER_CACHE_SIZE = 1000L; private static final Set PLAYER_NAMES = new HashSet<>(); private static final Set ONLINE_NAMES = new HashSet<>(); - public static final long OFFLINE_PLAYER_CACHE_SIZE = 1000L; - private static Instant lastPlayerRefresh = Instant.now(); private static final Set SMART_MATS; private static final Map> SMART_SHORT_MATS; private static final Map> SMART_PART_MATS; private static final Pattern SHORT_NAME = Pattern.compile("(?:(?:^|_)(.))"); private static final Cache> SMART_MAT_RESULTS = CacheBuilder.newBuilder().expireAfterAccess(5, TimeUnit.MINUTES).build(); - - private TabCompleteUtil() { - throw new UnsupportedOperationException("This is a utility class."); - } + private static Instant lastPlayerRefresh = Instant.now(); static { SMART_MATS = new LinkedHashSet<>(); @@ -74,6 +69,10 @@ private TabCompleteUtil() { } } + private Completion() { + throw new UnsupportedOperationException("This is a utility class."); + } + private static String getShortName(Material mat) { var matcher = SHORT_NAME.matcher(mat.name()); var builder = new StringBuilder(); @@ -204,7 +203,7 @@ public static List completeBoolean(String value) { * @return list of strings */ public static List completeWorlds(String value) { - return completeWorlds(value, C.SPACE_REPLACE); + return completeWorlds(value, ":"); } /** diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommand.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommand.java similarity index 90% rename from src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommand.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommand.java index e137ca0a..93be71bd 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommand.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommand.java @@ -6,17 +6,16 @@ package de.eldoria.eldoutilities.commands.command; +import de.eldoria.eldoutilities.commands.Completion; import de.eldoria.eldoutilities.commands.command.util.Arguments; import de.eldoria.eldoutilities.commands.command.util.CommandAssertions; import de.eldoria.eldoutilities.commands.exceptions.CommandException; import de.eldoria.eldoutilities.commands.executor.IConsoleTabExecutor; import de.eldoria.eldoutilities.commands.executor.IPlayerTabExecutor; import de.eldoria.eldoutilities.commands.executor.ITabExecutor; -import de.eldoria.eldoutilities.localization.DummyLocalizer; import de.eldoria.eldoutilities.localization.ILocalizer; -import de.eldoria.eldoutilities.localization.Replacement; import de.eldoria.eldoutilities.messages.MessageSender; -import de.eldoria.eldoutilities.simplecommands.TabCompleteUtil; +import de.eldoria.eldoutilities.messages.Replacement; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; @@ -107,7 +106,7 @@ public void commandRoute(CommandSender sender, String label, Arguments args) thr } if (!access) { var permissions = String.join(", ", meta().permissions()); - return Collections.singletonList(localizer().localize("error.permission", + return Collections.singletonList(messageSender.translatePlain("error.permission", Replacement.create("PERMISSION", permissions))); } } @@ -127,12 +126,12 @@ public void commandRoute(CommandSender sender, String label, Arguments args) thr // Provide routes if (args.size() == 1) { - return TabCompleteUtil.complete(args.asString(0), meta.registeredCommands()); + return Completion.complete(args.asString(0), meta.registeredCommands()); } var command = getCommand(args.asString(0)); if (command.isEmpty()) { - return Collections.singletonList(localizer().getMessage("error.invalidCommand")); + return Collections.singletonList(localizer().localize("error.invalidCommand")); } // forward return command.get().tabCompleteRoute(sender, args.asString(0), args.subArguments()); @@ -153,7 +152,7 @@ private Optional getCommand(String command) { * @return localizer instance */ protected final ILocalizer localizer() { - if (localizer == null || localizer instanceof DummyLocalizer) { + if (localizer == null || localizer instanceof ILocalizer.DummyLocalizer) { localizer = ILocalizer.getPluginLocalizer(plugin); } return localizer; @@ -165,7 +164,7 @@ protected final ILocalizer localizer() { * @return message sender instance */ protected final MessageSender messageSender() { - if (messageSender == null || messageSender.isDefault()) { + if (messageSender == null || messageSender.isAnonymous()) { messageSender = MessageSender.getPluginMessageSender(plugin); } return messageSender; @@ -197,8 +196,8 @@ protected final void meta(CommandMeta meta) { } public void handleCommandError(CommandSender sender, Throwable e) { - if (e instanceof CommandException) { - messageSender().sendLocalizedError(sender, e.getMessage(), ((CommandException) e).replacements()); + if (e instanceof CommandException cmd) { + messageSender().sendError(sender, e.getMessage(), cmd.replacements()); plugin().getLogger().log(Level.CONFIG, "Command exception occured.", e); return; } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommandAdapter.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommandAdapter.java similarity index 89% rename from src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommandAdapter.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommandAdapter.java index 8da5c705..7e02892e 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommandAdapter.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/AdvancedCommandAdapter.java @@ -8,9 +8,6 @@ import de.eldoria.eldoutilities.commands.command.util.Arguments; import de.eldoria.eldoutilities.commands.exceptions.CommandException; -import de.eldoria.eldoutilities.localization.DummyLocalizer; -import de.eldoria.eldoutilities.localization.ILocalizer; -import de.eldoria.eldoutilities.messages.MessageSender; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -28,15 +25,15 @@ public class AdvancedCommandAdapter extends AdvancedCommand implements TabExecutor { private final AdvancedCommand advancedCommand; - public static AdvancedCommandAdapter wrap(Plugin plugin, AdvancedCommand advancedCommand) { - return new AdvancedCommandAdapter(plugin, advancedCommand); - } - private AdvancedCommandAdapter(Plugin plugin, AdvancedCommand advancedCommand) { super(plugin); this.advancedCommand = advancedCommand; } + public static AdvancedCommandAdapter wrap(Plugin plugin, AdvancedCommand advancedCommand) { + return new AdvancedCommandAdapter(plugin, advancedCommand); + } + @Override public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { try { @@ -60,7 +57,7 @@ public List onTabComplete(@NotNull CommandSender sender, @NotNull Comman try { strings = advancedCommand.tabCompleteRoute(sender, label, arguments); } catch (CommandException e) { - strings = Collections.singletonList(localizer().localize(e.getMessage(), e.replacements())); + strings = Collections.singletonList(messageSender().translatePlain(e.getMessage(), e.replacements())); plugin().getLogger().log(Level.CONFIG, "Command exception occured.", e); } return strings; diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/CommandMeta.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/CommandMeta.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/commands/command/CommandMeta.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/CommandMeta.java index 5f79ea8c..6d320a75 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/CommandMeta.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/CommandMeta.java @@ -48,6 +48,10 @@ public CommandMeta(String name, String[] aliases, Set permissions, Set @@ -139,10 +143,6 @@ public boolean isCommand(String value) { return false; } - public static CommandMetaBuilder builder(String name) { - return new CommandMetaBuilder(name); - } - /** * Creates a meta for a internal subcommand. This is for small commands only and has several caveats. *

diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/CommandRoute.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/CommandRoute.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/commands/command/CommandRoute.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/CommandRoute.java diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/util/Argument.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/Argument.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/commands/command/util/Argument.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/Argument.java index 6b5b7b16..f5838197 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/util/Argument.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/Argument.java @@ -15,8 +15,6 @@ protected Argument(String name) { this.name = name; } - public abstract String formatted(); - public static Argument unlocalizedInput(String name, boolean required) { return new InputArgument(name, required); } @@ -29,6 +27,8 @@ public static Argument subCommand(String name) { return new SubCommand(name); } + public abstract String formatted(); + public String name() { return name; } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/util/Arguments.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/Arguments.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/commands/command/util/Arguments.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/Arguments.java diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandAssertions.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandAssertions.java similarity index 88% rename from src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandAssertions.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandAssertions.java index c092f9a2..c4d87106 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandAssertions.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandAssertions.java @@ -9,9 +9,12 @@ import de.eldoria.eldoutilities.commands.command.AdvancedCommand; import de.eldoria.eldoutilities.commands.command.CommandMeta; import de.eldoria.eldoutilities.commands.exceptions.CommandException; -import de.eldoria.eldoutilities.localization.Replacement; +import de.eldoria.eldoutilities.messages.Replacement; import de.eldoria.eldoutilities.utils.EnumUtil; import de.eldoria.eldoutilities.utils.Parser; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.entity.Player; @@ -34,7 +37,7 @@ private CommandAssertions() { public static void unexpectedRouteEnd(CommandMeta meta, Arguments arguments) throws CommandException { if (arguments.isEmpty() && meta.defaultCommand() == null) { var subcommands = meta.subCommands().values().stream().map(c -> "/" + c.meta().createCommandCall()).collect(Collectors.joining("\n")); - throw CommandException.message("error.endOfRoute", Replacement.create("COMMANDS", subcommands).addFormatting('6')); + throw CommandException.message("error.endOfRoute", Replacement.create("COMMANDS", subcommands)); } } @@ -42,7 +45,7 @@ public static void unexpectedRouteEnd(CommandMeta meta, Arguments arguments) thr public static void unexpectedRouteEnd(CommandMeta meta, Optional command) throws CommandException { if (command.isEmpty()) { var subcommands = meta.subCommands().values().stream().map(c -> "/" + c.meta().createCommandCall()).collect(Collectors.joining("\n")); - throw CommandException.message("error.endOfRoute", Replacement.create("COMMANDS", subcommands).addFormatting('6')); + throw CommandException.message("error.endOfRoute", Replacement.create("COMMANDS", subcommands)); } } @@ -55,7 +58,7 @@ public static void unexpectedRouteEnd(CommandMeta meta, Optional= min, "error.invalidRange", - Replacement.create("MIN", min).addFormatting('6'), - Replacement.create("MAX", max).addFormatting('6')); + Replacement.create("MIN", min), + Replacement.create("MAX", max)); } /** - * Checks if a value value is in a invalid Range. + * Checks if a value is in a invalid Range. * * @param value current value * @param min min value @@ -189,8 +192,8 @@ public static void range(double value, double min, double max) throws CommandExc */ public static void range(int value, int min, int max) throws CommandException { isTrue(value <= max && value >= min, "error.invalidRange", - Replacement.create("MIN", min).addFormatting('6'), - Replacement.create("MAX", max).addFormatting('6')); + Replacement.create("MIN", min), + Replacement.create("MAX", max)); } /** @@ -201,40 +204,40 @@ public static void range(int value, int min, int max) throws CommandException { */ public static void min(int value, int min) throws CommandException { isTrue(value >= min, "error.tooLow", - Replacement.create("MIN", min).addFormatting('6')); + Replacement.create("MIN", min)); } /** - * Checks if a value value is larger. + * Checks if a value is larger. * * @param value current value * @param min min value */ public static void min(double value, double min) throws CommandException { isTrue(value >= min, "error.tooLow", - Replacement.create("MIN", min).addFormatting('6')); + Replacement.create("MIN", min)); } /** - * Checks if a value value is smaller. + * Checks if a value is smaller. * * @param value current value * @param max max value (inclusive) */ public static void max(int value, int max) throws CommandException { isTrue(value <= max, "error.tooLarge", - Replacement.create("MAX", max).addFormatting('6')); + Replacement.create("MAX", max)); } /** - * Checks if a value value is smaller. + * Checks if a value is smaller. * * @param value current value * @param max max value (inclusive) */ public static void max(double value, double max) throws CommandException { isTrue(value <= max, "error.tooLarge", - Replacement.create("MAX", max).addFormatting('6')); + Replacement.create("MAX", max)); } /** @@ -247,7 +250,7 @@ public static void max(double value, double max) throws CommandException { */ public static > void enumValue(String value, Class clazz) throws CommandException { isTrue(EnumUtil.parse(value, clazz).isPresent(), "error.invalidEnumValue", Replacement.create("VALUES", - Replacement.create("VALUES", EnumUtil.enumValues(clazz)).addFormatting('6'))); + Replacement.create("VALUES", EnumUtil.enumValues(clazz)))); } public static void invalidNumber() throws CommandException { @@ -294,7 +297,7 @@ public static void missingArgument(Collection args, int index) throws Command * @param replacements replacements * @throws CommandException when eval is true */ - public static void isFalse(boolean eval, String message, Replacement... replacements) throws CommandException { + public static void isFalse(boolean eval, String message, TagResolver replacements) throws CommandException { isTrue(!eval, message, replacements); } @@ -306,9 +309,9 @@ public static void isFalse(boolean eval, String message, Replacement... replacem * @param replacements replacements * @throws CommandException when eval is false */ - public static void isTrue(boolean eval, String message, Replacement... replacements) throws CommandException { + public static void isTrue(boolean eval, String message, TagResolver... replacements) throws CommandException { if (eval) return; - throw CommandException.message(message, replacements); + throw CommandException.message(message, TagResolver.resolver(replacements)); } public static void evalAssertSilent(boolean eval) throws CommandException { diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandMetaBuilder.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandMetaBuilder.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandMetaBuilder.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandMetaBuilder.java index c7608855..d049a139 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandMetaBuilder.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/CommandMetaBuilder.java @@ -89,9 +89,10 @@ public CommandMetaBuilder withSubCommand(AdvancedCommand advancedCommand) { /** * Sets the command as hidden. It will not be suggested in tab completion. + * * @return this instance */ - public CommandMetaBuilder hidden(){ + public CommandMetaBuilder hidden() { hidden = true; return this; } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/util/Input.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/Input.java similarity index 82% rename from src/main/java/de/eldoria/eldoutilities/commands/command/util/Input.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/Input.java index 56691121..b2278424 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/util/Input.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/Input.java @@ -7,9 +7,11 @@ package de.eldoria.eldoutilities.commands.command.util; import de.eldoria.eldoutilities.commands.exceptions.CommandException; -import de.eldoria.eldoutilities.localization.Replacement; +import de.eldoria.eldoutilities.messages.Replacement; import de.eldoria.eldoutilities.utils.EnumUtil; import de.eldoria.eldoutilities.utils.Parser; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; import org.bukkit.Material; import org.bukkit.OfflinePlayer; import org.bukkit.World; @@ -21,12 +23,12 @@ public class Input { private final Plugin plugin; private final String arg; - private Input(Plugin plugin, String arg) { + private Input(Plugin plugin, String arg) { this.plugin = plugin; this.arg = arg; } - public static Input of(Plugin plugin, String arg){ + public static Input of(Plugin plugin, String arg) { return new Input(plugin, arg); } @@ -43,7 +45,7 @@ public static Input of(Plugin plugin, String arg){ * Get the argument as integer * * @return index as integer - * @throws CommandException when the argument is not an integer + * @throws CommandException when the argument is not an integer */ public int asInt() throws CommandException, IndexOutOfBoundsException { return Parser.parseInt(asString()) @@ -52,7 +54,7 @@ public int asInt() throws CommandException, IndexOutOfBoundsException { /** * @return index as long - * @throws CommandException when the argument is not a long + * @throws CommandException when the argument is not a long */ public long asLong() throws CommandException, IndexOutOfBoundsException { return Parser.parseLong(asString()) @@ -61,7 +63,7 @@ public long asLong() throws CommandException, IndexOutOfBoundsException { /** * @return index as double - * @throws CommandException when the argument is not a double + * @throws CommandException when the argument is not a double */ public double asDouble() throws CommandException, IndexOutOfBoundsException { return Parser.parseDouble(asString()) @@ -72,7 +74,7 @@ public double asDouble() throws CommandException, IndexOutOfBoundsException { * Get the argument as a boolean * * @return index as boolean - * @throws CommandException when the argument is not a boolean + * @throws CommandException when the argument is not a boolean */ public boolean asBoolean() throws CommandException, IndexOutOfBoundsException { return asBoolean("true", "false"); @@ -84,7 +86,7 @@ public boolean asBoolean() throws CommandException, IndexOutOfBoundsException { * @param aTrue value of true * @param aFalse value of false * @return index as boolean - * @throws CommandException when the argument is not a boolean + * @throws CommandException when the argument is not a boolean */ public boolean asBoolean(String aTrue, String aFalse) throws CommandException, IndexOutOfBoundsException { return Parser.parseBoolean(asString(), aTrue, aFalse) @@ -98,7 +100,7 @@ public boolean asBoolean(String aTrue, String aFalse) throws CommandException, I * This will send a custom message without listing all possible values. * * @return index as material - * @throws CommandException when the argument is not a material + * @throws CommandException when the argument is not a material */ @NotNull public Material asMaterial() throws CommandException, IndexOutOfBoundsException { @@ -112,7 +114,7 @@ public Material asMaterial() throws CommandException, IndexOutOfBoundsException * * @param stripStrings if true underscores will be removed before checking * @return index as material - * @throws CommandException when the argument is not a material + * @throws CommandException when the argument is not a material */ @NotNull public Material asMaterial(boolean stripStrings) throws CommandException, IndexOutOfBoundsException { @@ -126,7 +128,7 @@ public Material asMaterial(boolean stripStrings) throws CommandException, IndexO * @param clazz enum clazz to parse * @param type of enum * @return index as enum value - * @throws CommandException When the string could not be parsed to an enum + * @throws CommandException When the string could not be parsed to an enum */ @NotNull public > T asEnum(Class clazz) throws CommandException, IndexOutOfBoundsException { @@ -140,20 +142,20 @@ public > T asEnum(Class clazz) throws CommandException, Ind * @param stripStrings if true underscores will be removed before checking * @param type of enum * @return index as enum value - * @throws CommandException When the string could not be parsed to an enum + * @throws CommandException When the string could not be parsed to an enum */ @NotNull public > T asEnum(Class clazz, boolean stripStrings) throws CommandException, IndexOutOfBoundsException { return EnumUtil.parse(asString(), clazz, stripStrings) .orElseThrow(() -> CommandException.message("error.invalidEnumValue", - Replacement.create("VALUES", EnumUtil.enumValues(clazz)).addFormatting('6'))); + Replacement.create("VALUES", EnumUtil.enumValues(clazz)))); } /** * Get the argument as a player * * @return index as player - * @throws CommandException when no player with this name is online + * @throws CommandException when no player with this name is online */ @NotNull public Player asPlayer() throws CommandException, IndexOutOfBoundsException { @@ -166,7 +168,7 @@ public Player asPlayer() throws CommandException, IndexOutOfBoundsException { * Get the argument as a offline player * * @return index as offline player - * @throws CommandException when no player with this name was on this server previously + * @throws CommandException when no player with this name was on this server previously */ @NotNull public OfflinePlayer asOfflinePlayer() throws CommandException, IndexOutOfBoundsException { @@ -181,7 +183,7 @@ public OfflinePlayer asOfflinePlayer() throws CommandException, IndexOutOfBounds * Get the argument as a world * * @return index as world - * @throws CommandException When the string is not the name of a world + * @throws CommandException When the string is not the name of a world */ @NotNull public World asWorld() throws CommandException, IndexOutOfBoundsException { diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/util/InputArgument.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/InputArgument.java similarity index 79% rename from src/main/java/de/eldoria/eldoutilities/commands/command/util/InputArgument.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/InputArgument.java index a58fcd60..068c89fc 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/util/InputArgument.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/InputArgument.java @@ -6,7 +6,7 @@ package de.eldoria.eldoutilities.commands.command.util; -public class InputArgument extends Argument{ +public class InputArgument extends Argument { private final boolean required; public InputArgument(String name, boolean required) { @@ -16,7 +16,7 @@ public InputArgument(String name, boolean required) { @Override public String formatted() { - return String.format(required? "<%s>" : "[%s]", name()); + return String.format(required ? "<%s>" : "[%s]", name()); } public boolean isRequired() { diff --git a/src/main/java/de/eldoria/eldoutilities/commands/command/util/SubCommand.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/SubCommand.java similarity index 90% rename from src/main/java/de/eldoria/eldoutilities/commands/command/util/SubCommand.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/SubCommand.java index 5a7b0a85..426aefb7 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/command/util/SubCommand.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/command/util/SubCommand.java @@ -6,7 +6,7 @@ package de.eldoria.eldoutilities.commands.command.util; -public class SubCommand extends Argument{ +public class SubCommand extends Argument { protected SubCommand(String name) { super(name); } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultAbout.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultAbout.java similarity index 68% rename from src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultAbout.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultAbout.java index 7774a173..55a48958 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultAbout.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultAbout.java @@ -9,14 +9,12 @@ import de.eldoria.eldoutilities.commands.command.AdvancedCommand; import de.eldoria.eldoutilities.commands.command.CommandMeta; import de.eldoria.eldoutilities.commands.command.util.Arguments; -import de.eldoria.eldoutilities.commands.exceptions.CommandException; -import de.eldoria.eldoutilities.commands.executor.IConsoleTabExecutor; -import de.eldoria.eldoutilities.commands.executor.IPlayerTabExecutor; import de.eldoria.eldoutilities.commands.executor.ITabExecutor; -import de.eldoria.eldoutilities.localization.Replacement; +import de.eldoria.eldoutilities.messages.Replacement; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.format.TextDecoration; import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; @@ -24,7 +22,7 @@ public class DefaultAbout extends AdvancedCommand implements ITabExecutor { private final String discord; public DefaultAbout(Plugin plugin) { - this(plugin, "rfRuUge"); + this(plugin, "https://discord.eldoria.de"); } public DefaultAbout(Plugin plugin, String discord) { @@ -35,11 +33,11 @@ public DefaultAbout(Plugin plugin, String discord) { @Override public void onCommand(@NotNull CommandSender sender, @NotNull String alias, @NotNull Arguments args) { var descr = plugin().getDescription(); - messageSender().sendLocalizedMessage(sender, "about", - Replacement.create("PLUGIN_NAME", descr.getName(), 'b'), - Replacement.create("AUTHORS", String.join(", ", descr.getAuthors()), 'b'), - Replacement.create("VERSION", descr.getVersion(), 'b'), - Replacement.create("WEBSITE", descr.getWebsite(), 'b'), - Replacement.create("DISCORD", "https://discord.gg/" + discord, 'b')); + messageSender().sendMessage(sender, "about", + Replacement.create("PLUGIN_NAME", descr.getName()), + Replacement.create("AUTHORS", String.join(", ", descr.getAuthors())), + Replacement.create("VERSION", descr.getVersion()), + Replacement.create("WEBSITE", descr.getWebsite()), + Replacement.create("DISCORD", discord)); } } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultDebug.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultDebug.java similarity index 82% rename from src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultDebug.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultDebug.java index 7b206a57..a0d824c4 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultDebug.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/DefaultDebug.java @@ -9,15 +9,10 @@ import de.eldoria.eldoutilities.commands.command.AdvancedCommand; import de.eldoria.eldoutilities.commands.command.CommandMeta; import de.eldoria.eldoutilities.commands.command.util.Arguments; -import de.eldoria.eldoutilities.commands.exceptions.CommandException; -import de.eldoria.eldoutilities.commands.executor.IConsoleTabExecutor; -import de.eldoria.eldoutilities.commands.executor.IPlayerTabExecutor; import de.eldoria.eldoutilities.commands.executor.ITabExecutor; import de.eldoria.eldoutilities.debug.DebugSettings; import de.eldoria.eldoutilities.debug.DebugUtil; import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.entity.Player; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; diff --git a/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/FailsaveCommand.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/FailsaveCommand.java similarity index 69% rename from src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/FailsaveCommand.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/FailsaveCommand.java index 49906845..3e0d8ffc 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/FailsaveCommand.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/defaultcommands/FailsaveCommand.java @@ -19,13 +19,13 @@ public FailsaveCommand(Plugin plugin, String permission) { @Override public void onCommand(@NotNull CommandSender sender, @NotNull String alias, @NotNull Arguments args) { if (args.isEmpty()) { - sender.sendMessage("§cThe plugin failed to load correctly. Please use /" + alias + "§c debug to create a debug paste and send it to the developer."); + messageSender().sendError(sender, "The plugin failed to load correctly. Please use /" + alias + " debug to create a debug paste and send it to the developer."); return; } if ("debug".equalsIgnoreCase(args.get(0).asString())) { super.onCommand(sender, alias, args); return; } - sender.sendMessage("§cThe plugin failed to load correctly. Please use §a/" + alias + "§c debug to create a debug paste and send it to the developer."); + messageSender().sendMessage(sender, "The plugin failed to load correctly. Please use /" + alias + " debug to create a debug paste and send it to the developer."); } } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/exceptions/CommandException.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/exceptions/CommandException.java similarity index 54% rename from src/main/java/de/eldoria/eldoutilities/commands/exceptions/CommandException.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/exceptions/CommandException.java index 5acb8552..b6084095 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/exceptions/CommandException.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/exceptions/CommandException.java @@ -7,13 +7,13 @@ package de.eldoria.eldoutilities.commands.exceptions; import de.eldoria.eldoutilities.localization.ILocalizer; -import de.eldoria.eldoutilities.localization.Replacement; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; public class CommandException extends RuntimeException { - private Replacement[] replacements; + private TagResolver replacements; private boolean silent; - private CommandException(String message, Replacement... replacements) { + private CommandException(String message, TagResolver replacements) { super(message); this.replacements = replacements; } @@ -23,19 +23,27 @@ private CommandException(boolean silent) { this.silent = silent; } - public static CommandException message(String message, Replacement... replacements) { + public static CommandException message(String message, TagResolver replacements) { return new CommandException(message, replacements); } + public static CommandException message(String message, TagResolver... replacements) { + return new CommandException(message, TagResolver.resolver(replacements)); + } + + public static CommandException message(String message) { + return new CommandException(message, TagResolver.empty()); + } + public static CommandException silent() { return new CommandException(true); } public String localized(ILocalizer localizer) { - return localizer.localize(getMessage(), replacements); + return localizer.localize(getMessage()); } - public Replacement[] replacements() { + public TagResolver replacements() { return replacements; } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/executor/IConsoleTabExecutor.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/executor/IConsoleTabExecutor.java similarity index 97% rename from src/main/java/de/eldoria/eldoutilities/commands/executor/IConsoleTabExecutor.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/executor/IConsoleTabExecutor.java index 07a2bdfc..28a9fd8e 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/executor/IConsoleTabExecutor.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/executor/IConsoleTabExecutor.java @@ -19,7 +19,7 @@ public interface IConsoleTabExecutor { void onCommand(@NotNull ConsoleCommandSender console, @NotNull String alias, @NotNull Arguments args) throws CommandException; @Nullable - default List onTabComplete(@NotNull ConsoleCommandSender console, @NotNull String alias, @NotNull Arguments args) throws CommandException{ + default List onTabComplete(@NotNull ConsoleCommandSender console, @NotNull String alias, @NotNull Arguments args) throws CommandException { return Collections.emptyList(); } } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/executor/IPlayerTabExecutor.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/executor/IPlayerTabExecutor.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/commands/executor/IPlayerTabExecutor.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/executor/IPlayerTabExecutor.java index 723250b2..2b1c886f 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/executor/IPlayerTabExecutor.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/executor/IPlayerTabExecutor.java @@ -19,7 +19,7 @@ public interface IPlayerTabExecutor { void onCommand(@NotNull Player player, @NotNull String alias, @NotNull Arguments args) throws CommandException; @Nullable - default List onTabComplete(@NotNull Player player, @NotNull String alias, @NotNull Arguments args) throws CommandException{ + default List onTabComplete(@NotNull Player player, @NotNull String alias, @NotNull Arguments args) throws CommandException { return Collections.emptyList(); } } diff --git a/src/main/java/de/eldoria/eldoutilities/commands/executor/ITabExecutor.java b/commands/src/main/java/de/eldoria/eldoutilities/commands/executor/ITabExecutor.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/commands/executor/ITabExecutor.java rename to commands/src/main/java/de/eldoria/eldoutilities/commands/executor/ITabExecutor.java index eaac70bd..3114f620 100644 --- a/src/main/java/de/eldoria/eldoutilities/commands/executor/ITabExecutor.java +++ b/commands/src/main/java/de/eldoria/eldoutilities/commands/executor/ITabExecutor.java @@ -19,7 +19,7 @@ public interface ITabExecutor { void onCommand(@NotNull CommandSender sender, @NotNull String alias, @NotNull Arguments args) throws CommandException; @Nullable - default List onTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull Arguments args) throws CommandException{ + default List onTabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull Arguments args) throws CommandException { return Collections.emptyList(); } } diff --git a/src/main/java/de/eldoria/eldoutilities/utils/FlagContainer.java b/commands/src/main/java/de/eldoria/eldoutilities/utils/FlagContainer.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/FlagContainer.java rename to commands/src/main/java/de/eldoria/eldoutilities/utils/FlagContainer.java diff --git a/src/test/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtilTest.java b/commands/src/test/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtilTest.java similarity index 64% rename from src/test/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtilTest.java rename to commands/src/test/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtilTest.java index 102c8ba2..6d316345 100644 --- a/src/test/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtilTest.java +++ b/commands/src/test/java/de/eldoria/eldoutilities/simplecommands/TabCompleteUtilTest.java @@ -6,24 +6,23 @@ package de.eldoria.eldoutilities.simplecommands; +import de.eldoria.eldoutilities.commands.Completion; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.util.List; -import static org.junit.jupiter.api.Assertions.*; - class TabCompleteUtilTest { @Test void completeMaterial() { - List result = TabCompleteUtil.completeMaterial("gp", true); + List result = Completion.completeMaterial("gp", true); Assertions.assertTrue(result.contains("glass_pane")); - result = TabCompleteUtil.completeMaterial("pane", true); + result = Completion.completeMaterial("pane", true); Assertions.assertTrue(result.contains("glass_pane")); - result = TabCompleteUtil.completeMaterial("pa", true); + result = Completion.completeMaterial("pa", true); Assertions.assertTrue(result.contains("glass_pane")); - result = TabCompleteUtil.completeMaterial("glass_p", true); + result = Completion.completeMaterial("glass_p", true); Assertions.assertTrue(result.contains("glass_pane")); } } diff --git a/configuration/build.gradle.kts b/configuration/build.gradle.kts new file mode 100644 index 00000000..cd5a9b2d --- /dev/null +++ b/configuration/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + id("java") +} + +group = "de.eldoria.eldoutilities" +version = "1.14.4" + +repositories { + mavenCentral() +} + +dependencies { + testImplementation("org.junit.jupiter:junit-jupiter-api:5.8.1") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.8.1") +} + +tasks.getByName("test") { + useJUnitPlatform() +} \ No newline at end of file diff --git a/src/main/java/de/eldoria/eldoutilities/configuration/ConfigFileWrapper.java b/configuration/src/main/java/de/eldoria/eldoutilities/configuration/ConfigFileWrapper.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/configuration/ConfigFileWrapper.java rename to configuration/src/main/java/de/eldoria/eldoutilities/configuration/ConfigFileWrapper.java index eadeb1c8..bffeb074 100644 --- a/src/main/java/de/eldoria/eldoutilities/configuration/ConfigFileWrapper.java +++ b/configuration/src/main/java/de/eldoria/eldoutilities/configuration/ConfigFileWrapper.java @@ -130,6 +130,13 @@ public static ConfigFileWrapper forFileWithDefaults(Plugin plugin, Path filePath return new ConfigFileWrapper(plugin, filePath, defaultConfig); } + private static Path resolvePath(Plugin plugin, String filePath) { + if (plugin == null) { + return Bukkit.getUpdateFolderFile().toPath().getParent().resolve(filePath); + } + return plugin.getDataFolder().toPath().resolve(filePath); + } + /** * Get the file configuration. *

@@ -193,11 +200,4 @@ private void log(Level level, String message, Throwable e) { } } - private static Path resolvePath(Plugin plugin, String filePath) { - if (plugin == null) { - return Bukkit.getUpdateFolderFile().toPath().getParent().resolve(filePath); - } - return plugin.getDataFolder().toPath().resolve(filePath); - } - } diff --git a/src/main/java/de/eldoria/eldoutilities/configuration/Configuration.java b/configuration/src/main/java/de/eldoria/eldoutilities/configuration/Configuration.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/configuration/Configuration.java rename to configuration/src/main/java/de/eldoria/eldoutilities/configuration/Configuration.java diff --git a/src/main/java/de/eldoria/eldoutilities/configuration/EldoConfig.java b/configuration/src/main/java/de/eldoria/eldoutilities/configuration/EldoConfig.java similarity index 75% rename from src/main/java/de/eldoria/eldoutilities/configuration/EldoConfig.java rename to configuration/src/main/java/de/eldoria/eldoutilities/configuration/EldoConfig.java index b4007652..d59fefa6 100644 --- a/src/main/java/de/eldoria/eldoutilities/configuration/EldoConfig.java +++ b/configuration/src/main/java/de/eldoria/eldoutilities/configuration/EldoConfig.java @@ -6,16 +6,11 @@ package de.eldoria.eldoutilities.configuration; -import de.eldoria.eldoutilities.core.EldoUtilities; -import de.eldoria.eldoutilities.serialization.wrapper.MapEntry; -import de.eldoria.eldoutilities.utils.ObjUtil; -import de.eldoria.eldoutilities.utils.Parser; import org.bukkit.Bukkit; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.InvalidConfigurationException; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; -import org.bukkit.configuration.serialization.ConfigurationSerialization; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.Nullable; @@ -34,7 +29,6 @@ import java.util.function.Consumer; import java.util.logging.Level; import java.util.regex.Pattern; -import java.util.stream.Collectors; /** * A wrapper class for {@link FileConfiguration}. @@ -56,14 +50,10 @@ public EldoConfig(Plugin plugin) { pluginData = plugin.getDataFolder().toPath(); config = plugin.getConfig(); plugin.saveDefaultConfig(); - // TODO: This is just here for backwards compatibility reasons after a stupid choice - ConfigurationSerialization.registerClass(MapEntry.class, "eldoUtilitiesMapEntry"); if (isMainConfig()) { init(); } reload(); - // TODO: This is just here for backwards compatibility reasons after a stupid choice - ConfigurationSerialization.unregisterClass("eldoUtilitiesMapEntry"); save(); } @@ -73,83 +63,58 @@ public EldoConfig(Plugin plugin) { * @return true if plugin is in debug state. */ public static Level getLogLevel(Plugin plugin) { - Level level = ObjUtil.nonNull(EldoUtilities.getInstanceOwner(plugin.getClass()), instance -> { - // we probably want to load the config before the plugin is enabled. - // Since we use the configuration serializable we cant load the config directly if the plugin is not enabled. - String debug; - if (!instance.isEnabled()) { - var dataFolder = instance.getDataFolder(); - String config; - try { - config = Files.readAllLines(Paths.get(dataFolder.getAbsolutePath(), "config.yml")).stream().collect(Collectors.joining("\n")); - } catch (FileNotFoundException e) { - return Level.INFO; - } catch (IOException e) { - // We dont know if our logger already exists... - Bukkit.getLogger().log(Level.INFO, "[EldoUtilities] Could not load config file. Using default log level."); - return Level.INFO; - } - var compile = Pattern.compile("^debug:.?([a-zA-Z].*?)$", Pattern.MULTILINE); - var matcher = compile.matcher(config); - if (matcher.find()) { - debug = matcher.group(1); - } else { - debug = "INFO"; - } - } else { - debug = instance.getConfig().getString("debug", "INFO"); - instance.saveConfig(); + // we probably want to load the config before the plugin is enabled. + // Since we use the configuration serializable we cant load the config directly if the plugin is not enabled. + String debug; + if (!plugin.isEnabled()) { + var dataFolder = plugin.getDataFolder(); + String config; + try { + config = String.join("\n", Files.readAllLines(Paths.get(dataFolder.getAbsolutePath(), "config.yml"))); + } catch (FileNotFoundException e) { + return Level.INFO; + } catch (IOException e) { + // We dont know if our logger already exists... + Bukkit.getLogger().log(Level.INFO, "[EldoUtilities] Could not load config file. Using default log level."); + return Level.INFO; } - var aBoolean = Parser.parseBoolean(debug); - if (aBoolean.isPresent()) { - debug = aBoolean.get() ? "DEBUG" : "INFO"; - if (instance.isEnabled()) { - instance.getConfig().set("debug", debug); - instance.saveConfig(); - } + var compile = Pattern.compile("^debug:.?([a-zA-Z].*?)$", Pattern.MULTILINE); + var matcher = compile.matcher(config); + if (matcher.find()) { + debug = matcher.group(1); + } else { + debug = "INFO"; } - - return parseLevel(debug); - }); - if (level == null) { - parseLevel("INFO"); - Bukkit.getLogger().log(Level.INFO, "[EldoUtilities] No instance owner set for " + plugin.getClass()); + } else { + debug = plugin.getConfig().getString("debug", "INFO"); } - return level; + + return parseLevel(debug); } private static Level parseLevel(String level) { - if ("OFF".equalsIgnoreCase(level)) { - return Level.OFF; - } - if ("SEVERE".equalsIgnoreCase(level)) { - return Level.SEVERE; - } - if ("WARNING".equalsIgnoreCase(level)) { - return Level.WARNING; - } - if ("INFO".equalsIgnoreCase(level)) { - return Level.INFO; - } - if ("DEBUG".equalsIgnoreCase(level)) { - return Level.CONFIG; - } - if ("CONFIG".equalsIgnoreCase(level)) { - return Level.CONFIG; - } - if ("FINE".equalsIgnoreCase(level)) { - return Level.FINE; - } - if ("FINER".equalsIgnoreCase(level)) { - return Level.FINER; - } - if ("FINEST".equalsIgnoreCase(level)) { - return Level.FINEST; - } - if ("ALL".equalsIgnoreCase(level)) { - return Level.ALL; - } - return Level.INFO; + return switch (level.toUpperCase()) { + case "OFF" -> Level.OFF; + case "SEVERE" -> Level.SEVERE; + case "WARNING" -> Level.WARNING; + case "DEBUG", "TRUE" -> Level.CONFIG; + case "FINE" -> Level.FINE; + case "FINER" -> Level.FINER; + case "FINEST" -> Level.FINEST; + case "ALL" -> Level.ALL; + default -> Level.INFO; + }; + } + + /** + * Get the main config. + *

+ * Also refered as the config.yml + * + * @return file configuration for the main config. + */ + public static EldoConfig getMainConfig(Plugin plugin) { + return INSTANCE_CONFIG.get(plugin); } /** @@ -176,10 +141,8 @@ protected void saveConfigs() { */ public final void reload() { // TODO: This is just here for backwards compatibility reasons after a stupid choice - ConfigurationSerialization.registerClass(MapEntry.class, "eldoUtilitiesMapEntry"); readConfigs(); reloadConfigs(); - ConfigurationSerialization.unregisterClass("eldoUtilitiesMapEntry"); } /** @@ -323,9 +286,7 @@ private FileConfiguration loadConfigWrapped(Path configPath, @Nullable Consumer< var config = new YamlConfiguration(); config.load(configFile); - ObjUtil.nonNull(defaultCreator, d -> { - d.accept(config); - }); + if (defaultCreator != null) defaultCreator.accept(config); try { config.save(configFile); @@ -340,7 +301,7 @@ private FileConfiguration loadConfigWrapped(Path configPath, @Nullable Consumer< return configs.compute(configPath.toString(), (k, v) -> load); } - if(configs.containsKey(configPath.toString())){ + if (configs.containsKey(configPath.toString())) { return configs.get(configPath.toString()); } var load = load(configFile); @@ -378,17 +339,6 @@ public final Plugin getPlugin() { return plugin; } - /** - * Get the main config. - *

- * Also refered as the config.yml - * - * @return file configuration for the main config. - */ - public static EldoConfig getMainConfig(Plugin plugin) { - return INSTANCE_CONFIG.get(plugin); - } - /** * Get the underlying file configuration. * diff --git a/src/main/java/de/eldoria/eldoutilities/configuration/ExternalConfigException.java b/configuration/src/main/java/de/eldoria/eldoutilities/configuration/ExternalConfigException.java similarity index 84% rename from src/main/java/de/eldoria/eldoutilities/configuration/ExternalConfigException.java rename to configuration/src/main/java/de/eldoria/eldoutilities/configuration/ExternalConfigException.java index aa705c26..08442678 100644 --- a/src/main/java/de/eldoria/eldoutilities/configuration/ExternalConfigException.java +++ b/configuration/src/main/java/de/eldoria/eldoutilities/configuration/ExternalConfigException.java @@ -12,6 +12,6 @@ public class ExternalConfigException extends RuntimeException { public ExternalConfigException() { super("You tried to load a configuration file from an external configuration. This is forbidden. " + - "Please use only the main config instance to load other config files."); + "Please use only the main config instance to load other config files."); } } diff --git a/src/main/java/de/eldoria/eldoutilities/configuration/SimpleConfigWrapper.java b/configuration/src/main/java/de/eldoria/eldoutilities/configuration/SimpleConfigWrapper.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/configuration/SimpleConfigWrapper.java rename to configuration/src/main/java/de/eldoria/eldoutilities/configuration/SimpleConfigWrapper.java diff --git a/core/build.gradle.kts b/core/build.gradle.kts new file mode 100644 index 00000000..e69de29b diff --git a/core/src/main/java/de/eldoria/EldoUtilities.java b/core/src/main/java/de/eldoria/EldoUtilities.java new file mode 100644 index 00000000..d983f6ce --- /dev/null +++ b/core/src/main/java/de/eldoria/EldoUtilities.java @@ -0,0 +1,78 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria; + +import org.bukkit.Bukkit; +import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.plugin.Plugin; + +import java.nio.file.Paths; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.logging.Logger; + +/** + * Core class of EldoUtilitites. + *

+ * If you want to use anything from here you need to call {@link EldoUtilities#preWarm(Plugin)} onLoad and {@link EldoUtilities#ignite(Plugin)} onEnable. + * If your plugins extend {@code EldoPlugin} this will be done automatically. + */ +public final class EldoUtilities { + private static Plugin mainOwner; + private static Map, Plugin> instanceOwners = new LinkedHashMap<>(); + private static YamlConfiguration configuration; + + private EldoUtilities() { + } + + public static Logger logger() { + return Bukkit.getLogger(); + } + + public static void preWarm(Plugin eldoPlugin) { + instanceOwners.put(eldoPlugin.getClass(), eldoPlugin); + } + + public static void ignite(Plugin plugin) { + var path = plugin.getDataFolder().toPath().toAbsolutePath().getParent().resolve(Paths.get("EldoUtilities", "config.yml")); + configuration = YamlConfiguration.loadConfiguration(path.toFile()); + } + + public static void shutdown() { + } + + public static YamlConfiguration getConfiguration() { + if (configuration == null) { + var config = Bukkit.getUpdateFolderFile().toPath().toAbsolutePath().getParent().resolve(Paths.get("EldoUtilities", "config.yml")); + configuration = YamlConfiguration.loadConfiguration(config.toFile()); + } + return configuration; + } + + public static Plugin getInstanceOwner(Class plugin) { + return instanceOwners.get(plugin); + } + + public static void forceInstanceOwner(Plugin plugin) { + if (mainOwner != null) { + throw new IllegalStateException("A instance owner is already set"); + } + mainOwner = plugin; + } + + public static Plugin getInstanceOwner() { + if (mainOwner != null) { + return mainOwner; + } + + for (var entry : instanceOwners.entrySet()) { + return entry.getValue(); + } + + throw new IllegalStateException("No instance owner is set but requested"); + } +} diff --git a/src/main/java/de/eldoria/eldoutilities/consumer/QuadConsumer.java b/core/src/main/java/de/eldoria/eldoutilities/consumer/QuadConsumer.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/consumer/QuadConsumer.java rename to core/src/main/java/de/eldoria/eldoutilities/consumer/QuadConsumer.java diff --git a/src/main/java/de/eldoria/eldoutilities/consumer/ThrowingConsumer.java b/core/src/main/java/de/eldoria/eldoutilities/consumer/ThrowingConsumer.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/consumer/ThrowingConsumer.java rename to core/src/main/java/de/eldoria/eldoutilities/consumer/ThrowingConsumer.java diff --git a/src/main/java/de/eldoria/eldoutilities/consumer/TriConsumer.java b/core/src/main/java/de/eldoria/eldoutilities/consumer/TriConsumer.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/consumer/TriConsumer.java rename to core/src/main/java/de/eldoria/eldoutilities/consumer/TriConsumer.java diff --git a/src/main/java/de/eldoria/eldoutilities/container/Pair.java b/core/src/main/java/de/eldoria/eldoutilities/container/Pair.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/container/Pair.java rename to core/src/main/java/de/eldoria/eldoutilities/container/Pair.java diff --git a/src/main/java/de/eldoria/eldoutilities/container/Triple.java b/core/src/main/java/de/eldoria/eldoutilities/container/Triple.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/container/Triple.java rename to core/src/main/java/de/eldoria/eldoutilities/container/Triple.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/DefaultProperties.java b/core/src/main/java/de/eldoria/eldoutilities/debug/DefaultProperties.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/DefaultProperties.java rename to core/src/main/java/de/eldoria/eldoutilities/debug/DefaultProperties.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/UserData.java b/core/src/main/java/de/eldoria/eldoutilities/debug/UserData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/UserData.java rename to core/src/main/java/de/eldoria/eldoutilities/debug/UserData.java index 3d8c8ecb..001ea996 100644 --- a/src/main/java/de/eldoria/eldoutilities/debug/UserData.java +++ b/core/src/main/java/de/eldoria/eldoutilities/debug/UserData.java @@ -25,10 +25,10 @@ public final class UserData { public final String type; - private final Map buildProperties; public final String user = "%%__USER__%%"; public final String resource = "%%__RESOURCE__%%"; public final String nonce = "%%__NONCE__%%"; + private final Map buildProperties; private UserData(Map buildProperties) { this.buildProperties = buildProperties; diff --git a/src/main/java/de/eldoria/eldoutilities/functions/QuadFunction.java b/core/src/main/java/de/eldoria/eldoutilities/functions/QuadFunction.java similarity index 99% rename from src/main/java/de/eldoria/eldoutilities/functions/QuadFunction.java rename to core/src/main/java/de/eldoria/eldoutilities/functions/QuadFunction.java index 2fd9fc15..6fb84b4f 100644 --- a/src/main/java/de/eldoria/eldoutilities/functions/QuadFunction.java +++ b/core/src/main/java/de/eldoria/eldoutilities/functions/QuadFunction.java @@ -52,4 +52,4 @@ default QuadFunction andThen(Function after.apply(apply(t1, t2, t3, t4)); } -} \ No newline at end of file +} diff --git a/src/main/java/de/eldoria/eldoutilities/functions/ThrowingFunction.java b/core/src/main/java/de/eldoria/eldoutilities/functions/ThrowingFunction.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/functions/ThrowingFunction.java rename to core/src/main/java/de/eldoria/eldoutilities/functions/ThrowingFunction.java diff --git a/src/main/java/de/eldoria/eldoutilities/functions/TriFunction.java b/core/src/main/java/de/eldoria/eldoutilities/functions/TriFunction.java similarity index 99% rename from src/main/java/de/eldoria/eldoutilities/functions/TriFunction.java rename to core/src/main/java/de/eldoria/eldoutilities/functions/TriFunction.java index b57df288..5329c572 100644 --- a/src/main/java/de/eldoria/eldoutilities/functions/TriFunction.java +++ b/core/src/main/java/de/eldoria/eldoutilities/functions/TriFunction.java @@ -51,4 +51,4 @@ default TriFunction andThen(Function return (T1 t1, T2 t2, T3 t3) -> after.apply(apply(t1, t2, t3)); } -} \ No newline at end of file +} diff --git a/core/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java b/core/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java new file mode 100644 index 00000000..d5cff723 --- /dev/null +++ b/core/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java @@ -0,0 +1,128 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.localization; + +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.Nullable; + +import java.util.HashMap; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * Basic Interface for localizer implementations. + *

+ * Also allows access to localizer instances per plugin. + * + * @since 1.0.0 + */ +public interface ILocalizer { + Map, ILocalizer> LOCALIZER = new HashMap<>(); + ILocalizer DEFAULT = new DummyLocalizer(); + Pattern LOCALIZATION_CODE = Pattern.compile("([a-zA-Z0-9_\\-]+?)\\.([a-zA-Z0-9_.\\-]+?)"); + + static ILocalizer getPluginLocalizer(Plugin plugin) { + if (plugin == null) return DEFAULT; + return getPluginLocalizer(plugin.getClass()); + } + + static ILocalizer getPluginLocalizer(Class plugin) { + if (plugin == null) return DEFAULT; + return LOCALIZER.getOrDefault(plugin, DEFAULT); + } + + static String escape(String propertyKey) { + return String.format("", propertyKey); + } + + static boolean isLocaleCode(String message) { + return LOCALIZATION_CODE.matcher(message).matches(); + } + + /** + * Sets the locale of the localizer instance. + * + * @param language language to set. + */ + void setLocale(String language); + + /** + * Get a message. + * + * @param key message key + * @return message with replaced replacements if present. + */ + String getMessage(String key); + + /** + * Returns all available locales. + * + * @return array of registered locales. + */ + String[] getIncludedLocales(); + + /** + * Add requested locale codes in runtime. + *

+ * This has to be done before calling {@link #setLocale(String)} + *

+ * Every key has one default value which will be added to the file if the key is not present. + * + * @param runtimeLocaleCodes map with locales codes to add. + */ + void addLocaleCodes(Map runtimeLocaleCodes); + + @Nullable + String getValue(String key); + + /** + * Translates a String with Placeholders. Can handle multiple messages with replacements. Add replacements in the + * right order. + * + * @param message Message to translate + * @return Replaced Messages + * @since 1.2.3 + */ + String localize(String message); + + void registerChild(ILocalizer localizer); + + public class DummyLocalizer implements ILocalizer { + @Override + public void setLocale(String language) { + } + + @Override + public String getMessage(String key) { + return key; + } + + @Override + public String[] getIncludedLocales() { + return new String[0]; + } + + @Override + public void addLocaleCodes(Map runtimeLocaleCodes) { + } + + @Override + public @Nullable String getValue(String key) { + return null; + } + + @Override + public String localize(String message) { + return message; + } + + @Override + public void registerChild(ILocalizer localizer) { + + } + } +} diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/util/PluginSerializationName.java b/core/src/main/java/de/eldoria/eldoutilities/serialization/util/PluginSerializationName.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/serialization/util/PluginSerializationName.java rename to core/src/main/java/de/eldoria/eldoutilities/serialization/util/PluginSerializationName.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/ArgumentUtils.java b/core/src/main/java/de/eldoria/eldoutilities/utils/ArgumentUtils.java similarity index 97% rename from src/main/java/de/eldoria/eldoutilities/utils/ArgumentUtils.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/ArgumentUtils.java index c68e79ba..2c1bf3a2 100644 --- a/src/main/java/de/eldoria/eldoutilities/utils/ArgumentUtils.java +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/ArgumentUtils.java @@ -6,7 +6,6 @@ package de.eldoria.eldoutilities.utils; -import de.eldoria.eldoutilities.C; import org.bukkit.Bukkit; import org.bukkit.World; import org.bukkit.command.CommandSender; @@ -25,6 +24,8 @@ * @since 1.0.0 */ public final class ArgumentUtils { + private static final String SPACE_REPLACE = ":"; + private ArgumentUtils() { throw new UnsupportedOperationException("This is a utility class!"); } @@ -158,7 +159,7 @@ public static String getRangeAsString(String[] strings, int from) { } public static String unescapeWorldName(String world) { - return unescapeWorldName(world, C.SPACE_REPLACE); + return unescapeWorldName(world, SPACE_REPLACE); } public static String unescapeWorldName(String world, String replace) { @@ -166,7 +167,7 @@ public static String unescapeWorldName(String world, String replace) { } public static String escapeWorldName(String world) { - return escapeWorldName(world, C.SPACE_REPLACE); + return escapeWorldName(world, SPACE_REPLACE); } public static String escapeWorldName(String world, String replace) { @@ -174,7 +175,7 @@ public static String escapeWorldName(String world, String replace) { } public static String escapeWorldName(World world) { - return escapeWorldName(world, C.SPACE_REPLACE); + return escapeWorldName(world, SPACE_REPLACE); } public static String escapeWorldName(World world, String replace) { @@ -196,7 +197,6 @@ public static String[] parseQuotedArgs(String args, boolean strip) { * Parse arguments and keep quotes together * * @param args args to parse - * * @return parsed args */ public static String[] parseQuotedArgs(String[] args) { @@ -234,18 +234,17 @@ public static String[] parseQuotedArgs(String[] args) { * * @param strings array of strings. * @param from start index (included). Use negative counts to count from the last index. - * * @return array sequence as string */ public static String getMessage(String[] strings, int from) { return getMessage(strings, from, 0); } + /** * Get a message from string array from 'from' to array.length(). * * @param strings array of strings. * @param from start index (included). Use negative counts to count from the last index. - * * @return array sequence as string */ public static String getMessage(List strings, int from) { @@ -258,7 +257,6 @@ public static String getMessage(List strings, int from) { * @param strings array of strings. * @param from start index (included). Use negative counts to count from the last index. * @param to end index (excluded). Use negative counts to count from the last index. - * * @return array sequence as string */ public static String getMessage(String[] strings, int from, int to) { @@ -271,7 +269,6 @@ public static String getMessage(String[] strings, int from, int to) { * @param strings array of strings. * @param from start index (included). Use negative counts to count from the last index. * @param to end index (excluded). Use negative counts to count from the last index. - * * @return array sequence as string */ public static String getMessage(List strings, int from, int to) { @@ -284,7 +281,6 @@ public static String getMessage(List strings, int from, int to) { * @param objects arguments * @param from start index included * @param Type of objects - * * @return sublist */ public static List getRangeAsList(T[] objects, int from) { @@ -298,7 +294,6 @@ public static List getRangeAsList(T[] objects, int from) { * @param from start index (included). Use negative counts to count from the last index. * @param to end index (excluded). Use negative counts to count from the last index. * @param Type of objects - * * @return sublist. */ public static List getRangeAsList(T[] objects, int from, int to) { @@ -311,7 +306,6 @@ public static List getRangeAsList(T[] objects, int from, int to) { * @param objects list of objects. * @param from start index (included). Use negative counts to count from the last index. * @param Type of objects - * * @return sublist. */ public static List getRangeAsList(List objects, int from) { @@ -325,7 +319,6 @@ public static List getRangeAsList(List objects, int from) { * @param from start index (included). Use negative counts to count from the last index. * @param to end index (excluded). Use negative counts to count from the last index. * @param Type of objects - * * @return sublist. */ public static List getRangeAsList(List objects, int from, int to) { diff --git a/src/main/java/de/eldoria/eldoutilities/utils/ArrayUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/ArrayUtil.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/ArrayUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/ArrayUtil.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/AttributeUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/AttributeUtil.java similarity index 79% rename from src/main/java/de/eldoria/eldoutilities/utils/AttributeUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/AttributeUtil.java index 2b6dd4c0..2fca6422 100644 --- a/src/main/java/de/eldoria/eldoutilities/utils/AttributeUtil.java +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/AttributeUtil.java @@ -6,7 +6,7 @@ package de.eldoria.eldoutilities.utils; -import de.eldoria.eldoutilities.core.EldoUtilities; +import org.bukkit.Bukkit; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeInstance; import org.bukkit.entity.LivingEntity; @@ -48,8 +48,8 @@ public static void setAttributeValue(AttributeInstance attribute, double target) public static void setAttributeValue(@NotNull LivingEntity entity, @NotNull Attribute attribute, @NotNull double target) { var a = entity.getAttribute(attribute); if (a == null) { - EldoUtilities.logger().log(Level.WARNING, "[EldoUtilities] Attempted to set attribute " - + attribute + " for " + entity.getType() + ", but Attribute is not present on this type.", + Bukkit.getLogger().log(Level.WARNING, "[EldoUtilities] Attempted to set attribute " + + attribute + " for " + entity.getType() + ", but Attribute is not present on this type.", new IllegalArgumentException("A not present attribute was requested to change")); return; } @@ -70,16 +70,16 @@ public static void syncAttributeValue(LivingEntity source, LivingEntity target, var targetAttribute = target.getAttribute(attribute); if (sourceAttribute == null) { - EldoUtilities.logger().log(Level.WARNING, "Attempted to sync attribute " - + attribute + " between source " + source.getType() + " and target " + target.getType() - + ", but Attribute is not present on source", + Bukkit.getLogger().log(Level.WARNING, "Attempted to sync attribute " + + attribute + " between source " + source.getType() + " and target " + target.getType() + + ", but Attribute is not present on source", new IllegalArgumentException("A not present attribute was requested to change")); return; } if (targetAttribute == null) { - EldoUtilities.logger().log(Level.WARNING, "Attempted to sync attribute " - + attribute + " between source " + source.getType() + " and target " + target.getType() - + ", but Attribute is not present on target", + Bukkit.getLogger().log(Level.WARNING, "Attempted to sync attribute " + + attribute + " between source " + source.getType() + " and target " + target.getType() + + ", but Attribute is not present on target", new IllegalArgumentException("A not present attribute was requested to change")); return; } diff --git a/src/main/java/de/eldoria/eldoutilities/utils/Consumers.java b/core/src/main/java/de/eldoria/eldoutilities/utils/Consumers.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/Consumers.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/Consumers.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/DataContainerUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/DataContainerUtil.java similarity index 99% rename from src/main/java/de/eldoria/eldoutilities/utils/DataContainerUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/DataContainerUtil.java index 3fa178fe..ed6ba9b1 100644 --- a/src/main/java/de/eldoria/eldoutilities/utils/DataContainerUtil.java +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/DataContainerUtil.java @@ -8,7 +8,6 @@ import org.bukkit.NamespacedKey; import org.bukkit.inventory.ItemStack; -import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.persistence.PersistentDataHolder; import org.bukkit.persistence.PersistentDataType; diff --git a/src/main/java/de/eldoria/eldoutilities/utils/Durations.java b/core/src/main/java/de/eldoria/eldoutilities/utils/Durations.java similarity index 91% rename from src/main/java/de/eldoria/eldoutilities/utils/Durations.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/Durations.java index 16482deb..ded784be 100644 --- a/src/main/java/de/eldoria/eldoutilities/utils/Durations.java +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/Durations.java @@ -7,11 +7,9 @@ package de.eldoria.eldoutilities.utils; import java.time.Duration; -import java.time.Instant; -import java.time.temporal.ChronoUnit; public class Durations { - public static String simpleDurationFormat(Duration duration){ + public static String simpleDurationFormat(Duration duration) { if (duration.toDays() > 0) { if (duration.toDays() == 1) { return "1 day"; diff --git a/src/main/java/de/eldoria/eldoutilities/utils/EMath.java b/core/src/main/java/de/eldoria/eldoutilities/utils/EMath.java similarity index 99% rename from src/main/java/de/eldoria/eldoutilities/utils/EMath.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/EMath.java index a3e76994..161112b5 100644 --- a/src/main/java/de/eldoria/eldoutilities/utils/EMath.java +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/EMath.java @@ -216,7 +216,7 @@ public static double parabolaValue(double xVector, double yVector, double xPoint *

* Returns always a value between half of the height and 0; * - * @param x The Point x between the start end end point. + * @param x The Point x between the start and end point. * @return Returns a value between 0 and 1. */ public static double smoothCurveValue(double x) { diff --git a/src/main/java/de/eldoria/eldoutilities/utils/ERandom.java b/core/src/main/java/de/eldoria/eldoutilities/utils/ERandom.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/ERandom.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/ERandom.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/EnumUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/EnumUtil.java similarity index 91% rename from src/main/java/de/eldoria/eldoutilities/utils/EnumUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/EnumUtil.java index 04715999..8d56145f 100644 --- a/src/main/java/de/eldoria/eldoutilities/utils/EnumUtil.java +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/EnumUtil.java @@ -23,7 +23,7 @@ private EnumUtil() { /** * Searches for a enum value by string with a case insensitive search. * - * @param value enum as string value + * @param value enum as string value * @param values enum values. * @param type of enum. * @return enum value or null if no mathing value was found. @@ -35,7 +35,7 @@ public static > Optional parse(String value, Class value /** * Searches for a enum value by string with a case insensitive search. * - * @param value enum as string value + * @param value enum as string value * @param values enum values. * @param stripStrings if true underscores will be removed before checking * @param defaultValue Default value which will be returned when enum could not be parsed @@ -49,7 +49,7 @@ public static > T parse(String value, Class values, boolean /** * Searches for a enum value by string with a case insensitive search. * - * @param value enum as string value + * @param value enum as string value * @param values enum values. * @param defaultValue Default value which will be returned when enum could not be parsed * @param type of enum. @@ -62,7 +62,7 @@ public static > T parse(String value, Class values, T defau /** * Searches for a enum value by string with a case insensitive search. * - * @param mat enum as string value + * @param mat enum as string value * @param values enum values. * @param stripStrings if true underscores will be removed before checking * @param type of enum. @@ -81,8 +81,8 @@ public static > String enumValues(Class clazz) { return enumValues(clazz, ", "); } - public static > String enumValues(Class clazz, String delimiter){ - return Arrays.stream(clazz.getEnumConstants()) + public static > String enumValues(Class clazz, String delimiter) { + return Arrays.stream(clazz.getEnumConstants()) .map(e -> e.name().toLowerCase()) .collect(Collectors.joining(delimiter)); } diff --git a/src/main/java/de/eldoria/eldoutilities/utils/Futures.java b/core/src/main/java/de/eldoria/eldoutilities/utils/Futures.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/Futures.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/Futures.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/ObjUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/ObjUtil.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/ObjUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/ObjUtil.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/Parser.java b/core/src/main/java/de/eldoria/eldoutilities/utils/Parser.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/utils/Parser.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/Parser.java index 2ee5c1de..784f2058 100644 --- a/src/main/java/de/eldoria/eldoutilities/utils/Parser.java +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/Parser.java @@ -7,9 +7,7 @@ package de.eldoria.eldoutilities.utils; import java.util.Optional; -import java.util.OptionalDouble; import java.util.OptionalInt; -import java.util.OptionalLong; /** * This class contains methods to parse strings to primitve types and other things. diff --git a/src/main/java/de/eldoria/eldoutilities/permissions/PermUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/Permissions.java similarity index 92% rename from src/main/java/de/eldoria/eldoutilities/permissions/PermUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/Permissions.java index 8aabd964..aff855a5 100644 --- a/src/main/java/de/eldoria/eldoutilities/permissions/PermUtil.java +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/Permissions.java @@ -4,24 +4,19 @@ * Copyright (C) EldoriaRPG Team and Contributor */ -package de.eldoria.eldoutilities.permissions; +package de.eldoria.eldoutilities.utils; -import de.eldoria.eldoutilities.utils.Parser; import org.bukkit.entity.Player; -import org.bukkit.permissions.PermissionAttachmentInfo; import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.HashSet; import java.util.Objects; -import java.util.Optional; -import java.util.OptionalDouble; -import java.util.OptionalInt; import java.util.Set; import java.util.function.Function; -public final class PermUtil { - private PermUtil() { +public final class Permissions { + private Permissions() { } /** diff --git a/src/main/java/de/eldoria/eldoutilities/utils/Plugins.java b/core/src/main/java/de/eldoria/eldoutilities/utils/Plugins.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/Plugins.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/Plugins.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/ReflectionUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/ReflectionUtil.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/ReflectionUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/ReflectionUtil.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/TextFormatting.java b/core/src/main/java/de/eldoria/eldoutilities/utils/TextFormatting.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/TextFormatting.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/TextFormatting.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/TextUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/TextUtil.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/TextUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/TextUtil.java diff --git a/src/main/java/de/eldoria/eldoutilities/utils/VectorUtil.java b/core/src/main/java/de/eldoria/eldoutilities/utils/VectorUtil.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/utils/VectorUtil.java rename to core/src/main/java/de/eldoria/eldoutilities/utils/VectorUtil.java diff --git a/core/src/main/java/de/eldoria/eldoutilities/utils/Version.java b/core/src/main/java/de/eldoria/eldoutilities/utils/Version.java new file mode 100644 index 00000000..f303733c --- /dev/null +++ b/core/src/main/java/de/eldoria/eldoutilities/utils/Version.java @@ -0,0 +1,134 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.utils; + +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public record Version(String version, List nums) implements Comparable { + public static final int MAJOR = 0; + public static final int MINOR = 1; + public static final int PATCH = 2; + private static final Pattern NUMBER = Pattern.compile("([0-9]+)"); + + public static Version parse(String version) { + List nums = new ArrayList<>(); + + Matcher matcher = NUMBER.matcher(version); + while (matcher.find()) { + nums.add(Integer.parseInt(matcher.group(1))); + } + + return new Version(version, nums); + } + + public static Version of(Integer... nums) { + return of(Arrays.stream(nums).toList()); + } + + public static Version of(List nums) { + return new Version(nums.stream().map(String::valueOf).collect(Collectors.joining(".")), nums); + } + + @Override + public List nums() { + return Collections.unmodifiableList(nums); + } + + public boolean isOlder(Version version) { + return compareTo(version) < 0; + } + + public boolean isOlderOrEqual(Version version) { + return compareTo(version) <= 0; + } + + public boolean isNewer(Version version) { + return compareTo(version) > 0; + } + + public boolean isNewerOrEqual(Version version) { + return compareTo(version) >= 0; + } + + public boolean isEqual(Version version) { + return compareTo(version) == 0; + } + + public boolean isBetweenInclusive(Version lower, Version upper) { + return isNewer(lower) && isOlder(upper); + } + + /** + * Compares the version to a lower and upper version + * + * @param lower lower version (inclusive) + * @param upper upper version (exclusive) + * @return true if the version is between + */ + public boolean isBetween(Version lower, Version upper) { + return isNewerOrEqual(lower) && isOlder(upper); + } + + public Comparator comparator() { + return Comparator.comparing(Version::parse); + } + + public Version trim(int num) { + return Version.of(nums.subList(0, Math.min(nums.size(), num)).toArray(Integer[]::new)); + } + + public Version set(int index, int value) { + var newNums = new ArrayList<>(nums); + if (newNums.size() < index) { + newNums.set(index, value); + } else { + newNums.add(value); + } + return Version.of(newNums); + } + + public Version increase(int index, int value) { + var newNums = new ArrayList<>(nums); + newNums.set(index, newNums.get(index) + value); + return Version.of(newNums); + } + + public Version decrease(int index, int value) { + var newNums = new ArrayList<>(nums); + newNums.set(index, Math.max(newNums.get(index) - value, 0)); + return Version.of(newNums); + } + + @Override + public String toString() { + return version; + } + + public int size() { + return nums.size(); + } + + @Override + public int compareTo(@NotNull Version version) { + int numbers = Math.max(version.nums().size(), nums().size()); + for (int i = 0; i < numbers; i++) { + int compare = Integer.compare(nums().size() > i ? nums().get(i) : 0, + version.nums().size() > i ? version.nums().get(i) : 0); + if (compare != 0) return compare; + } + return 0; + } +} diff --git a/src/test/java/de/eldoria/eldoutilities/utils/ConsumersTest.java b/core/src/test/java/de/eldoria/eldoutilities/utils/ConsumersTest.java similarity index 100% rename from src/test/java/de/eldoria/eldoutilities/utils/ConsumersTest.java rename to core/src/test/java/de/eldoria/eldoutilities/utils/ConsumersTest.java diff --git a/core/src/test/java/de/eldoria/eldoutilities/utils/EMathTest.java b/core/src/test/java/de/eldoria/eldoutilities/utils/EMathTest.java new file mode 100644 index 00000000..0b466ee3 --- /dev/null +++ b/core/src/test/java/de/eldoria/eldoutilities/utils/EMathTest.java @@ -0,0 +1,77 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.utils; + +import de.eldoria.eldoutilities.container.Pair; +import org.junit.jupiter.api.Test; + +import static de.eldoria.eldoutilities.utils.EMath.clamp; +import static de.eldoria.eldoutilities.utils.EMath.parabolaValue; +import static de.eldoria.eldoutilities.utils.EMath.smoothCurveValue; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +public class EMathTest { + @Test + public void clampTest() { + assertEquals(100, clamp(0, 100, 101)); + assertEquals(0, clamp(0, 100, -1)); + assertEquals(50, clamp(0, 100, 50)); + } + + @Test + public void parabolaValueTest() { + // up + double rightUp = parabolaValue(0, 0, 1, 1, 1); + double leftUp = parabolaValue(0, 0, 1, 1, -1); + assertEquals(rightUp, leftUp); + assertEquals(1, leftUp); + assertNotEquals(2, parabolaValue(0, 0, 1, 1, 2)); + //down + double rightDown = parabolaValue(0, 0, -1, -1, 1); + double leftDown = parabolaValue(0, 0, -1, -1, -1); + assertEquals(rightDown, leftDown); + assertEquals(-1, leftDown); + assertNotEquals(-2, parabolaValue(0, 0, 1, 1, 2)); + } + + @Test + public void smoothCurveValueTest() { + // Simple tests + assertEquals(0, smoothCurveValue(0)); + assertEquals(1, smoothCurveValue(1)); + assertEquals(0.5, smoothCurveValue(0.5)); + assertNotEquals(0.25, smoothCurveValue(0.25)); + assertNotEquals(0.75, smoothCurveValue(0.75)); + + // Complex tests + Pair neg = Pair.of(-1d, -1d); + Pair pos = Pair.of(1d, 1d); + // Descending curve + assertEquals(0, smoothCurveValue(neg, pos, 0)); + assertTrue(smoothCurveValue(neg, pos, -0.5) < -0.5); + assertTrue(smoothCurveValue(neg, pos, 0.5) > 0.5); + + // Ascending curve + neg = Pair.of(1d, -1d); + pos = Pair.of(-1d, 1d); + assertEquals(0, smoothCurveValue(pos, neg, 0)); + assertTrue(smoothCurveValue(pos, neg, -0.5) > 0.6); + assertTrue(smoothCurveValue(pos, neg, 0.5) < -0.6); + } + + @Test + public void diffTest() { + assertEquals(2, EMath.diff(-1, 1)); + assertEquals(1, EMath.diff(0, 1)); + assertEquals(0, EMath.diff(0, 0)); + assertEquals(3, EMath.diff(-4, -1)); + assertEquals(3, EMath.diff(4, 1)); + assertEquals(150, EMath.diff(-50, 100)); + } +} diff --git a/core/src/test/java/de/eldoria/eldoutilities/utils/ObjUtilTest.java b/core/src/test/java/de/eldoria/eldoutilities/utils/ObjUtilTest.java new file mode 100644 index 00000000..5d6b03bf --- /dev/null +++ b/core/src/test/java/de/eldoria/eldoutilities/utils/ObjUtilTest.java @@ -0,0 +1,46 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.utils; + +import org.bukkit.Material; +import org.bukkit.event.player.PlayerInteractEvent; +import org.bukkit.inventory.ItemStack; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +class ObjUtilTest { + + @Test + void nonNull() { + } + + @Test + void testNonNull() { + } + + @Test + void testNonNull1() { + } + + @Test + void testNonNull2() { + } + + @Test + void nonNullOrElse() { + PlayerInteractEvent event = mock(PlayerInteractEvent.class); + when(event.getItem()).thenReturn(new ItemStack(Material.AIR)); + Assertions.assertTrue(ObjUtil.nonNullOrElse(event.getItem(), itemStack -> itemStack.getType() == Material.AIR, false)); + + event = mock(PlayerInteractEvent.class); + when(event.getItem()).thenReturn(null); + Assertions.assertFalse(ObjUtil.nonNullOrElse(event.getItem(), itemStack -> itemStack.getType() == Material.AIR, false)); + } +} diff --git a/crossversion/build.gradle.kts b/crossversion/build.gradle.kts new file mode 100644 index 00000000..533b2ad5 --- /dev/null +++ b/crossversion/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + api(project(":core")) +} diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/ExclusiveVersionRange.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/ExclusiveVersionRange.java new file mode 100644 index 00000000..cdd02cf3 --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/ExclusiveVersionRange.java @@ -0,0 +1,16 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion; + +import de.eldoria.eldoutilities.utils.Version; + +public record ExclusiveVersionRange(Version lower, Version upper) implements VersionRange { + @Override + public boolean isBetween(Version version) { + return version.isBetween(lower, upper); + } +} diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/InclusiveVersionRange.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/InclusiveVersionRange.java new file mode 100644 index 00000000..5bb879c4 --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/InclusiveVersionRange.java @@ -0,0 +1,15 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion; + +import de.eldoria.eldoutilities.utils.Version; + +public record InclusiveVersionRange(Version lower, Version upper) implements VersionRange { + public boolean isBetween(Version version) { + return version.isBetweenInclusive(lower, upper); + } +} diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/ServerVersion.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/ServerVersion.java new file mode 100644 index 00000000..d4af9db0 --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/ServerVersion.java @@ -0,0 +1,50 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion; + +import de.eldoria.eldoutilities.utils.Version; +import org.bukkit.Bukkit; + +/** + * Enum to determine and work with multiple versions. + * + * @since 1.0.0 + */ +public final class ServerVersion { + public static final Version MC_UNKOWN = Version.of(0, 0, 0); + + /** + * Contains the current version of the server. + */ + public static final Version CURRENT_VERSION; + + static { + CURRENT_VERSION = Bukkit.getServer() != null ? getVersion() : MC_UNKOWN; + } + + /** + * Get the version of the server. + * + * @return version of server + */ + public static Version getVersion() { + return Version.parse(Bukkit.getServer().getBukkitVersion()); + } + + /** + * This method will check if the current version is between the oldest and newest version. Will abort enable of + * plugin when called on enable. + * + * @param oldest oldest version (inclusive) + * @param newest newest version (inclusive) + * @throws UnsupportedVersionException when the server version is not between the oldest and newest version. + */ + public static void forceVersion(Version oldest, Version newest) { + if (CURRENT_VERSION.isBetween(oldest, newest)) return; + throw new UnsupportedVersionException(); + } +} diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/UnsupportedVersionException.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/UnsupportedVersionException.java similarity index 81% rename from src/main/java/de/eldoria/eldoutilities/crossversion/UnsupportedVersionException.java rename to crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/UnsupportedVersionException.java index 242a43b0..6b4e2065 100644 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/UnsupportedVersionException.java +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/UnsupportedVersionException.java @@ -11,6 +11,6 @@ */ public class UnsupportedVersionException extends RuntimeException { public UnsupportedVersionException() { - super("Version " + ServerVersion.CURRENT_VERSION.name() + " is not supported."); + super("Version " + ServerVersion.CURRENT_VERSION + " is not supported."); } } diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/VersionRange.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/VersionRange.java new file mode 100644 index 00000000..5eac3728 --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/VersionRange.java @@ -0,0 +1,17 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion; + +import de.eldoria.eldoutilities.utils.Version; + +public interface VersionRange { + boolean isBetween(Version version); + + Version lower(); + + Version upper(); +} diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/BiFunctionBuilder.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/BiFunctionBuilder.java new file mode 100644 index 00000000..63bf466b --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/BiFunctionBuilder.java @@ -0,0 +1,37 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion.builder; + +import de.eldoria.eldoutilities.crossversion.VersionRange; +import de.eldoria.eldoutilities.crossversion.function.BiVersionFunction; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.BiFunction; + +/** + * A builder for a {@link BiVersionFunction} with version sensitive context. + * + * @param first Input Type + * @param second Input Type + * @param result Type + */ +public class BiFunctionBuilder extends VersionFunctionBuilder, BiFunction> { + private final Map> functions = new HashMap<>(); + + protected BiFunctionBuilder() { + } + + /** + * Build the version function. + * + * @return version functions with applied functions for versions. + */ + public BiVersionFunction build() { + return new BiVersionFunction<>(functions); + } +} diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/FunctionBuilder.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/FunctionBuilder.java new file mode 100644 index 00000000..f04cac4b --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/FunctionBuilder.java @@ -0,0 +1,36 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion.builder; + +import de.eldoria.eldoutilities.crossversion.VersionRange; +import de.eldoria.eldoutilities.crossversion.function.VersionFunction; + +import java.util.HashMap; +import java.util.Map; +import java.util.function.Function; + +/** + * A builder for a {@link VersionFunction} with version sensitive context. + * + * @param first Input Type + * @param result Type + */ +public class FunctionBuilder extends VersionFunctionBuilder, Function> { + private final Map> functions = new HashMap<>(); + + protected FunctionBuilder() { + } + + /** + * Build the version function. + * + * @return version functions with applied functions for versions. + */ + public VersionFunction build() { + return new VersionFunction<>(functions); + } +} diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/QuadFunctionBuilder.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/QuadFunctionBuilder.java new file mode 100644 index 00000000..b26fe9fb --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/QuadFunctionBuilder.java @@ -0,0 +1,39 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion.builder; + +import de.eldoria.eldoutilities.crossversion.VersionRange; +import de.eldoria.eldoutilities.crossversion.function.QuadVersionFunction; +import de.eldoria.eldoutilities.functions.QuadFunction; + +import java.util.HashMap; +import java.util.Map; + +/** + * A builder for a {@link QuadVersionFunction} with version sensitive context. + * + * @param first Input Type + * @param second Input Type + * @param third Input Type + * @param fourth Input Type + * @param result Type + */ +public class QuadFunctionBuilder extends VersionFunctionBuilder, QuadFunction> { + private final Map> functions = new HashMap<>(); + + protected QuadFunctionBuilder() { + } + + /** + * Build the version function. + * + * @return version functions with applied functions for versions. + */ + public QuadVersionFunction build() { + return new QuadVersionFunction<>(functions); + } +} diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/TriFunctionBuilder.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/TriFunctionBuilder.java new file mode 100644 index 00000000..b42573e9 --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/TriFunctionBuilder.java @@ -0,0 +1,30 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion.builder; + +import de.eldoria.eldoutilities.crossversion.VersionRange; +import de.eldoria.eldoutilities.crossversion.function.TriVersionFunction; +import de.eldoria.eldoutilities.functions.TriFunction; + +import java.util.HashMap; +import java.util.Map; + +public class TriFunctionBuilder extends VersionFunctionBuilder, TriFunction> { + private final Map> functions = new HashMap<>(); + + protected TriFunctionBuilder() { + } + + /** + * Build the version function. + * + * @return version functions with applied functions for versions. + */ + public TriVersionFunction build() { + return new TriVersionFunction<>(functions); + } +} diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/VersionFunctionBuilder.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/VersionFunctionBuilder.java similarity index 61% rename from src/main/java/de/eldoria/eldoutilities/crossversion/builder/VersionFunctionBuilder.java rename to crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/VersionFunctionBuilder.java index 0745b887..1a9ac6a9 100644 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/VersionFunctionBuilder.java +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/builder/VersionFunctionBuilder.java @@ -6,10 +6,19 @@ package de.eldoria.eldoutilities.crossversion.builder; +import de.eldoria.eldoutilities.crossversion.ExclusiveVersionRange; +import de.eldoria.eldoutilities.crossversion.VersionRange; +import de.eldoria.eldoutilities.utils.Version; + +import java.util.HashMap; +import java.util.Map; + /** * Interface to create different function builders. */ -public interface VersionFunctionBuilder { +public abstract class VersionFunctionBuilder { + protected final Map functions = new HashMap<>(); + /** * Get a function builder. * @@ -74,4 +83,36 @@ static QuadFunctionBuilder quadFunctionBuilder( Class a, Class b, Class c, Class d, Class r) { return new QuadFunctionBuilder<>(); } + + /** + * Add a version function which should be used on one or more versions. + * + * @param function function to execute + * @param version versions which should use this function + * @return builder instance with function applied for versions + */ + public VersionFunctionBuilder addVersionFunction(V function, VersionRange version) { + functions.put(version, function); + return this; + } + + /** + * Add a version functions for all versions between two versions. + * + * @param oldest oldest version (inclusive) + * @param newest newest version (exclusive) + * @param function function to execute + * @return builder instance with function applied for versions + */ + public VersionFunctionBuilder addVersionFunctionBetween(Version oldest, Version newest, V function) { + addVersionFunction(function, new ExclusiveVersionRange(oldest, newest)); + return this; + } + + /** + * Build the version function. + * + * @return version functions with applied functions for versions. + */ + public abstract T build(); } diff --git a/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/BaseVersionFunction.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/BaseVersionFunction.java new file mode 100644 index 00000000..c0096618 --- /dev/null +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/BaseVersionFunction.java @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.crossversion.function; + +import de.eldoria.eldoutilities.crossversion.ServerVersion; +import de.eldoria.eldoutilities.crossversion.UnsupportedVersionException; +import de.eldoria.eldoutilities.crossversion.VersionRange; + +import java.util.Map; + +public class BaseVersionFunction { + private final Map functions; + + public BaseVersionFunction(Map functions) { + this.functions = functions; + } + + protected V get() { + var first = functions.entrySet().stream() + .filter(func -> func.getKey().isBetween(ServerVersion.CURRENT_VERSION)) + .map(Map.Entry::getValue) + .findFirst(); + if (first.isEmpty()) { + throw new UnsupportedVersionException(); + } + return first.get(); + } +} diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/function/BiVersionFunction.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/BiVersionFunction.java similarity index 62% rename from src/main/java/de/eldoria/eldoutilities/crossversion/function/BiVersionFunction.java rename to crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/BiVersionFunction.java index f1256d89..a9a9022a 100644 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/function/BiVersionFunction.java +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/BiVersionFunction.java @@ -6,8 +6,8 @@ package de.eldoria.eldoutilities.crossversion.function; -import de.eldoria.eldoutilities.crossversion.ServerVersion; import de.eldoria.eldoutilities.crossversion.UnsupportedVersionException; +import de.eldoria.eldoutilities.crossversion.VersionRange; import java.util.Map; import java.util.function.BiFunction; @@ -19,11 +19,10 @@ * @param second Input Type * @param result Type */ -public class BiVersionFunction { - private final Map> functions; +public class BiVersionFunction extends BaseVersionFunction> { - public BiVersionFunction(Map> functions) { - this.functions = functions; + public BiVersionFunction(Map> functions) { + super(functions); } /** @@ -35,10 +34,6 @@ public BiVersionFunction(Map> functions) { * @throws UnsupportedVersionException when no function is defined for the server version. */ public R apply(A a, B b) { - var function = functions.get(ServerVersion.CURRENT_VERSION); - if (function == null) { - throw new UnsupportedVersionException(); - } - return function.apply(a, b); + return get().apply(a, b); } } diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/function/QuadVersionFunction.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/QuadVersionFunction.java similarity index 65% rename from src/main/java/de/eldoria/eldoutilities/crossversion/function/QuadVersionFunction.java rename to crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/QuadVersionFunction.java index a113acc4..927f5bd2 100644 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/function/QuadVersionFunction.java +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/QuadVersionFunction.java @@ -6,8 +6,8 @@ package de.eldoria.eldoutilities.crossversion.function; -import de.eldoria.eldoutilities.crossversion.ServerVersion; import de.eldoria.eldoutilities.crossversion.UnsupportedVersionException; +import de.eldoria.eldoutilities.crossversion.VersionRange; import de.eldoria.eldoutilities.functions.QuadFunction; import java.util.Map; @@ -21,11 +21,9 @@ * @param fourth Input Type * @param result Type */ -public class QuadVersionFunction { - private final Map> functions; - - public QuadVersionFunction(Map> functions) { - this.functions = functions; +public class QuadVersionFunction extends BaseVersionFunction> { + public QuadVersionFunction(Map> functions) { + super(functions); } /** @@ -39,10 +37,6 @@ public QuadVersionFunction(Map> funct * @throws UnsupportedVersionException when no function is defined for the server version. */ public R apply(A a, B b, C c, D d) { - var function = functions.get(ServerVersion.CURRENT_VERSION); - if (function == null) { - throw new UnsupportedVersionException(); - } - return function.apply(a, b, c, d); + return get().apply(a, b, c, d); } } diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/function/TriVersionFunction.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/TriVersionFunction.java similarity index 64% rename from src/main/java/de/eldoria/eldoutilities/crossversion/function/TriVersionFunction.java rename to crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/TriVersionFunction.java index 417ca2a6..3da3e272 100644 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/function/TriVersionFunction.java +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/TriVersionFunction.java @@ -6,8 +6,8 @@ package de.eldoria.eldoutilities.crossversion.function; -import de.eldoria.eldoutilities.crossversion.ServerVersion; import de.eldoria.eldoutilities.crossversion.UnsupportedVersionException; +import de.eldoria.eldoutilities.crossversion.VersionRange; import de.eldoria.eldoutilities.functions.TriFunction; import java.util.Map; @@ -20,11 +20,10 @@ * @param third Input Type * @param result Type */ -public class TriVersionFunction { - private final Map> functions; +public class TriVersionFunction extends BaseVersionFunction> { - public TriVersionFunction(Map> functions) { - this.functions = functions; + public TriVersionFunction(Map> functions) { + super(functions); } /** @@ -37,10 +36,6 @@ public TriVersionFunction(Map> functions) * @throws UnsupportedVersionException when no function is defined for the server version. */ public R apply(A a, B b, C c) { - var function = functions.get(ServerVersion.CURRENT_VERSION); - if (function == null) { - throw new UnsupportedVersionException(); - } - return function.apply(a, b, c); + return get().apply(a, b, c); } } diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/function/VersionFunction.java b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/VersionFunction.java similarity index 60% rename from src/main/java/de/eldoria/eldoutilities/crossversion/function/VersionFunction.java rename to crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/VersionFunction.java index 16d6493e..1a467b2e 100644 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/function/VersionFunction.java +++ b/crossversion/src/main/java/de/eldoria/eldoutilities/crossversion/function/VersionFunction.java @@ -6,8 +6,8 @@ package de.eldoria.eldoutilities.crossversion.function; -import de.eldoria.eldoutilities.crossversion.ServerVersion; import de.eldoria.eldoutilities.crossversion.UnsupportedVersionException; +import de.eldoria.eldoutilities.crossversion.VersionRange; import java.util.Map; import java.util.function.Function; @@ -18,11 +18,10 @@ * @param input Type * @param result Type */ -public class VersionFunction { - private final Map> functions; +public class VersionFunction extends BaseVersionFunction> { - public VersionFunction(Map> functions) { - this.functions = functions; + public VersionFunction(Map> functions) { + super(functions); } /** @@ -33,10 +32,6 @@ public VersionFunction(Map> functions) { * @throws UnsupportedVersionException when no function is defined for the server version. */ public R apply(A a) { - var function = functions.get(ServerVersion.CURRENT_VERSION); - if (function == null) { - throw new UnsupportedVersionException(); - } - return function.apply(a); + return get().apply(a); } } diff --git a/debugging/build.gradle.kts b/debugging/build.gradle.kts new file mode 100644 index 00000000..533b2ad5 --- /dev/null +++ b/debugging/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + api(project(":core")) +} diff --git a/src/main/java/de/eldoria/eldoutilities/debug/DebugDataProvider.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugDataProvider.java similarity index 93% rename from src/main/java/de/eldoria/eldoutilities/debug/DebugDataProvider.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugDataProvider.java index 85810683..639424f6 100644 --- a/src/main/java/de/eldoria/eldoutilities/debug/DebugDataProvider.java +++ b/debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugDataProvider.java @@ -7,7 +7,6 @@ package de.eldoria.eldoutilities.debug; import de.eldoria.eldoutilities.debug.data.EntryData; -import de.eldoria.eldoutilities.plugin.EldoPlugin; import org.jetbrains.annotations.NotNull; import java.util.Collections; @@ -22,7 +21,7 @@ *

* Your plugin instance is the entry point for debugging. If you want to use this interface your plugin class has to implement it. *

- * Instance of {@link EldoPlugin} are already a {@link DebugDataProvider}. Just override the method. + * Instance of {@code EldoPlugin} are already a {@link DebugDataProvider}. Just override the method. * * @since 1.3.4 */ diff --git a/src/main/java/de/eldoria/eldoutilities/debug/DebugPayload.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugPayload.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/DebugPayload.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugPayload.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/DebugSettings.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugSettings.java similarity index 92% rename from src/main/java/de/eldoria/eldoutilities/debug/DebugSettings.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugSettings.java index 909b9253..fcc0cbc6 100644 --- a/src/main/java/de/eldoria/eldoutilities/debug/DebugSettings.java +++ b/debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugSettings.java @@ -7,8 +7,6 @@ package de.eldoria.eldoutilities.debug; -import de.eldoria.eldoutilities.updater.butlerupdater.ButlerUpdateData; - import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -21,7 +19,7 @@ public final class DebugSettings { add(new Filter(Pattern.compile("(?i)(user:).*?$", Pattern.MULTILINE), "$1 *****")); }}; - public static final DebugSettings DEFAULT = new DebugSettings(ButlerUpdateData.HOST, DEFAULT_FILTER); + public static final DebugSettings DEFAULT = new DebugSettings("https://plugins.eldoria.de", DEFAULT_FILTER); private final String host; private final List filters = new ArrayList<>(); @@ -52,7 +50,7 @@ public String applyFilter(String text) { public static class Builder { private final List filters = new ArrayList<>(); - private String host = ButlerUpdateData.HOST; + private String host = "https://plugins.eldoria.de"; public Builder forHost(String host) { this.host = host; diff --git a/src/main/java/de/eldoria/eldoutilities/debug/DebugUtil.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugUtil.java similarity index 67% rename from src/main/java/de/eldoria/eldoutilities/debug/DebugUtil.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugUtil.java index 519ac0b9..982f9522 100644 --- a/src/main/java/de/eldoria/eldoutilities/debug/DebugUtil.java +++ b/debugging/src/main/java/de/eldoria/eldoutilities/debug/DebugUtil.java @@ -8,14 +8,10 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import de.eldoria.eldoutilities.core.EldoUtilities; +import de.eldoria.EldoUtilities; import de.eldoria.eldoutilities.debug.data.DebugPayloadData; import de.eldoria.eldoutilities.debug.data.DebugResponse; import de.eldoria.eldoutilities.debug.data.EntryData; -import de.eldoria.eldoutilities.messages.MessageChannel; -import de.eldoria.eldoutilities.messages.MessageSender; -import de.eldoria.eldoutilities.messages.MessageType; -import de.eldoria.eldoutilities.plugin.EldoPlugin; import org.bukkit.Bukkit; import org.bukkit.command.CommandSender; import org.bukkit.plugin.Plugin; @@ -58,46 +54,47 @@ private DebugUtil() { */ public static void dispatchDebug(CommandSender sender, Plugin plugin, DebugSettings settings) { var config = EldoUtilities.getConfiguration(); - var messageSender = MessageSender.getPluginMessageSender(plugin); - if (!config.get().getBoolean("debugConsens", false)) { - var message = "By using this command you agree that we will send data belonging to you to §lour server§r.\n" - + "We will only send data when someone executes this command.\n" - + "The data will be handled confidential from our side and will be only available by a hashed key.\n" - + "Unless you share this key no one can access it. §cEveryone who receives this key will have access to your data.§r\n" - + "You can delete your data at every time with the deletion key. §cIf you lose or didnt save your key we can not help you.§r\n" - + "Your data will be deleted after §l§c14 days§r.\n" - + "This data includes but is §l§cnot§r limited to:\n" - + " - Installed Plugins and their meta data\n" - + " - Latest log\n" - + " - Server Informations like Worldnames and Playercount\n" - + " - The configuration file or files of the debugged plugin\n" - + " - Additional Data provided by our own plugins.\n" - + "We will filter sensitive data like IPs before sending.\n" - + "However we §l§ccan not§r and §l§cwill not§r gurantee that we can remove all data which is considered confidential by you.\n" - + "§2If you agree please execute this command once again.\n" - + "§2This is a one time opt in.\n" - + "You can opt out again in the EldoUtilities config file."; - messageSender.send(MessageChannel.CHAT, () -> "§6", sender, message); - config.write(c -> c.set("debugConsens", true)); + if (!config.getBoolean("debugConsens", false)) { + var message = """ + By using this command you agree that we will send data belonging to you to §lour server§r.\n" + We will only send data when someone executes this command. + The data will be handled confidential from our side and will be only available by a hashed key. + Unless you share this key no one can access it. §cEveryone who receives this key will have access to your data.§r + You can delete your data at every time with the deletion key. §cIf you lose or didnt save your key we can not help you.§r + Your data will be deleted after §l§c14 days§r. + This data includes but is §l§cnot§r limited to: + - Installed Plugins and their meta data + - Latest log + - Server Informations like Worldnames and Playercount + - The configuration file or files of the debugged plugin + - Additional Data provided by our own plugins. + We will filter sensitive data like IPs before sending. + However we §l§ccan not§r and §l§cwill not§r gurantee that we can remove all data which is considered confidential by you. + §2If you agree please execute this command once again. + §2This is a one time opt in. + You can opt out again in the EldoUtilities config file""".stripIndent(); + sender.sendMessage(message); + config.set("debugConsens", true); return; } Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> { var debugResponse = sendDebug(plugin, DebugPayload.create(plugin, settings), settings); if (debugResponse.isPresent()) { - messageSender.send(MessageChannel.CHAT, MessageType.NORMAL, sender, - "Your data is available here:\n" - + "§6" + settings.getHost() + "/debug/v1/read/" + debugResponse.get().getHash() - + "§r\nYou can delete it via this link:\n" - + "§c" + settings.getHost() + "/debug/v1/delete/" + debugResponse.get().getDeletionHash()); + var message = """ + Your data is available here: + §6%s/debug/v1/read/%s§r + You can delete it via this link: + §c%s/debug/v1/delete/%s""".formatted(settings.getHost(), debugResponse.get().getHash(), settings.getHost(), debugResponse.get().getDeletionHash()); + sender.sendMessage(message); } else { - messageSender.send(MessageChannel.CHAT, MessageType.ERROR, sender, "Could not send data. Please try again later"); + sender.sendMessage("Could not send data. Please try again later"); } }); } /** - * Extracts additional Plugin meta data from a {@link EldoPlugin}. + * Extracts additional Plugin meta data from a {@code EldoPlugin}. *

* If the plugin is not a eldo plugin it will return an empty array. * diff --git a/src/main/java/de/eldoria/eldoutilities/debug/Filter.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/Filter.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/Filter.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/Filter.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/data/DebugPayloadData.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/data/DebugPayloadData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/data/DebugPayloadData.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/data/DebugPayloadData.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/data/DebugResponse.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/data/DebugResponse.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/data/DebugResponse.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/data/DebugResponse.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/data/EntryData.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/data/EntryData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/data/EntryData.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/data/EntryData.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/data/LogData.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/data/LogData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/data/LogData.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/data/LogData.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/data/PluginMetaData.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/data/PluginMetaData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/data/PluginMetaData.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/data/PluginMetaData.java diff --git a/src/main/java/de/eldoria/eldoutilities/debug/data/ServerMetaData.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/data/ServerMetaData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/debug/data/ServerMetaData.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/data/ServerMetaData.java diff --git a/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/ConfigDump.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/ConfigDump.java new file mode 100644 index 00000000..de904386 --- /dev/null +++ b/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/ConfigDump.java @@ -0,0 +1,48 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.debug.payload; + +import de.eldoria.eldoutilities.debug.DebugSettings; +import de.eldoria.eldoutilities.debug.data.EntryData; +import org.bukkit.plugin.Plugin; + +import java.util.LinkedList; +import java.util.List; +import java.util.logging.Level; + +public class ConfigDump extends EntryData { + + public ConfigDump(String path, String content) { + super(path, content); + } + + /** + * Creates a new config dump. This dump will include external configs as well if the plugin is a {@code EldoCommand}. + * + * @param plugin plugin to dump the configs + * @param settings settings for debug dispatching + * @return configs as an array. + */ + public static EntryData[] create(Plugin plugin, DebugSettings settings) { + var root = plugin.getDataFolder().toPath().toAbsolutePath().getParent().getParent(); + + var mainConfig = plugin.getConfig(); + + List dumps = new LinkedList<>(); + if (mainConfig != null) { + try { + dumps.add(new ConfigDump("config.yml", mainConfig.saveToString())); + } catch (Exception e) { + plugin.getLogger().log(Level.CONFIG, "something went wrong while saving the config. Skipping", e); + } + } + + dumps.forEach(e -> e.applyFilter(settings)); + + return dumps.toArray(new ConfigDump[0]); + } +} diff --git a/src/main/java/de/eldoria/eldoutilities/debug/payload/LogMeta.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/LogMeta.java similarity index 99% rename from src/main/java/de/eldoria/eldoutilities/debug/payload/LogMeta.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/LogMeta.java index 269689c4..47a2c985 100644 --- a/src/main/java/de/eldoria/eldoutilities/debug/payload/LogMeta.java +++ b/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/LogMeta.java @@ -11,13 +11,11 @@ import org.bukkit.plugin.Plugin; import java.io.BufferedReader; -import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Collection; @@ -29,7 +27,6 @@ import java.util.Scanner; import java.util.Set; import java.util.logging.Level; -import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; diff --git a/src/main/java/de/eldoria/eldoutilities/debug/payload/PluginMeta.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/PluginMeta.java similarity index 97% rename from src/main/java/de/eldoria/eldoutilities/debug/payload/PluginMeta.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/PluginMeta.java index 6535d5d0..e3023338 100644 --- a/src/main/java/de/eldoria/eldoutilities/debug/payload/PluginMeta.java +++ b/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/PluginMeta.java @@ -8,7 +8,6 @@ import de.eldoria.eldoutilities.debug.data.PluginMetaData; import org.bukkit.plugin.Plugin; -import org.bukkit.plugin.PluginDescriptionFile; public final class PluginMeta extends PluginMetaData { diff --git a/src/main/java/de/eldoria/eldoutilities/debug/payload/ServerMeta.java b/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/ServerMeta.java similarity index 97% rename from src/main/java/de/eldoria/eldoutilities/debug/payload/ServerMeta.java rename to debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/ServerMeta.java index d9494593..fbb66745 100644 --- a/src/main/java/de/eldoria/eldoutilities/debug/payload/ServerMeta.java +++ b/debugging/src/main/java/de/eldoria/eldoutilities/debug/payload/ServerMeta.java @@ -9,7 +9,6 @@ import de.eldoria.eldoutilities.debug.data.PluginMetaData; import de.eldoria.eldoutilities.debug.data.ServerMetaData; import org.bukkit.Bukkit; -import org.bukkit.Server; import org.bukkit.World; import java.util.Arrays; diff --git a/entities/build.gradle.kts b/entities/build.gradle.kts new file mode 100644 index 00000000..655b18bb --- /dev/null +++ b/entities/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies{ + api(project(":core")) +} diff --git a/src/main/java/de/eldoria/eldoutilities/builder/EntityBuilder.java b/entities/src/main/java/de/eldoria/eldoutilities/entities/EntityBuilder.java similarity index 99% rename from src/main/java/de/eldoria/eldoutilities/builder/EntityBuilder.java rename to entities/src/main/java/de/eldoria/eldoutilities/entities/EntityBuilder.java index 1bf8cb29..7b8f59dc 100644 --- a/src/main/java/de/eldoria/eldoutilities/builder/EntityBuilder.java +++ b/entities/src/main/java/de/eldoria/eldoutilities/entities/EntityBuilder.java @@ -4,7 +4,7 @@ * Copyright (C) EldoriaRPG Team and Contributor */ -package de.eldoria.eldoutilities.builder; +package de.eldoria.eldoutilities.entities; import de.eldoria.eldoutilities.utils.AttributeUtil; import de.eldoria.eldoutilities.utils.EMath; diff --git a/src/main/java/de/eldoria/eldoutilities/entityutils/ProjectileSender.java b/entities/src/main/java/de/eldoria/eldoutilities/entities/projectiles/ProjectileSender.java similarity index 97% rename from src/main/java/de/eldoria/eldoutilities/entityutils/ProjectileSender.java rename to entities/src/main/java/de/eldoria/eldoutilities/entities/projectiles/ProjectileSender.java index 83957283..f9d6fd54 100644 --- a/src/main/java/de/eldoria/eldoutilities/entityutils/ProjectileSender.java +++ b/entities/src/main/java/de/eldoria/eldoutilities/entities/projectiles/ProjectileSender.java @@ -4,7 +4,7 @@ * Copyright (C) EldoriaRPG Team and Contributor */ -package de.eldoria.eldoutilities.entityutils; +package de.eldoria.eldoutilities.entities.projectiles; import org.bukkit.Material; import org.bukkit.block.Block; diff --git a/src/main/java/de/eldoria/eldoutilities/entityutils/ProjectileUtil.java b/entities/src/main/java/de/eldoria/eldoutilities/entities/projectiles/ProjectileUtil.java similarity index 92% rename from src/main/java/de/eldoria/eldoutilities/entityutils/ProjectileUtil.java rename to entities/src/main/java/de/eldoria/eldoutilities/entities/projectiles/ProjectileUtil.java index 3e2afdf8..1fa87bf6 100644 --- a/src/main/java/de/eldoria/eldoutilities/entityutils/ProjectileUtil.java +++ b/entities/src/main/java/de/eldoria/eldoutilities/entities/projectiles/ProjectileUtil.java @@ -4,13 +4,11 @@ * Copyright (C) EldoriaRPG Team and Contributor */ -package de.eldoria.eldoutilities.entityutils; +package de.eldoria.eldoutilities.entities.projectiles; -import org.bukkit.block.Block; import org.bukkit.entity.Entity; import org.bukkit.entity.Projectile; import org.bukkit.projectiles.BlockProjectileSource; -import org.bukkit.projectiles.ProjectileSource; /** * Util to dtermine the sender of a projectile. diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index bdc9a83b..17a8ddce 100755 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/inventory/build.gradle.kts b/inventory/build.gradle.kts new file mode 100644 index 00000000..b14069c4 --- /dev/null +++ b/inventory/build.gradle.kts @@ -0,0 +1,4 @@ +dependencies{ + api(project(":core")) + api(project(":items")) +} diff --git a/src/main/java/de/eldoria/eldoutilities/inventory/ActionConsumer.java b/inventory/src/main/java/de/eldoria/eldoutilities/inventory/ActionConsumer.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/inventory/ActionConsumer.java rename to inventory/src/main/java/de/eldoria/eldoutilities/inventory/ActionConsumer.java diff --git a/src/main/java/de/eldoria/eldoutilities/inventory/ActionItem.java b/inventory/src/main/java/de/eldoria/eldoutilities/inventory/ActionItem.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/inventory/ActionItem.java rename to inventory/src/main/java/de/eldoria/eldoutilities/inventory/ActionItem.java diff --git a/src/main/java/de/eldoria/eldoutilities/inventory/InventoryActionHandler.java b/inventory/src/main/java/de/eldoria/eldoutilities/inventory/InventoryActionHandler.java similarity index 94% rename from src/main/java/de/eldoria/eldoutilities/inventory/InventoryActionHandler.java rename to inventory/src/main/java/de/eldoria/eldoutilities/inventory/InventoryActionHandler.java index a7d29c5c..f5e877b6 100644 --- a/src/main/java/de/eldoria/eldoutilities/inventory/InventoryActionHandler.java +++ b/inventory/src/main/java/de/eldoria/eldoutilities/inventory/InventoryActionHandler.java @@ -6,7 +6,6 @@ package de.eldoria.eldoutilities.inventory; -import de.eldoria.eldoutilities.plugin.EldoPlugin; import org.bukkit.Bukkit; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; @@ -50,10 +49,10 @@ public static InventoryActionHandler create(Plugin plugin) { } - public static InventoryActionHandler create(EldoPlugin plugin, Runnable onClose) { + public static InventoryActionHandler create(Plugin plugin, Runnable onClose) { return PLUGIN_HANDLER.computeIfAbsent(plugin.getClass(), k -> { var handler = new InventoryActionHandler(onClose); - plugin.registerListener(handler); + Bukkit.getPluginManager().registerEvents(handler, plugin); return handler; }); diff --git a/src/main/java/de/eldoria/eldoutilities/inventory/InventoryActions.java b/inventory/src/main/java/de/eldoria/eldoutilities/inventory/InventoryActions.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/inventory/InventoryActions.java rename to inventory/src/main/java/de/eldoria/eldoutilities/inventory/InventoryActions.java diff --git a/items/build.gradle.kts b/items/build.gradle.kts new file mode 100644 index 00000000..e69de29b diff --git a/src/main/java/de/eldoria/eldoutilities/builder/ItemStackBuilder.java b/items/src/main/java/de/eldoria/eldoutilities/builder/ItemStackBuilder.java similarity index 97% rename from src/main/java/de/eldoria/eldoutilities/builder/ItemStackBuilder.java rename to items/src/main/java/de/eldoria/eldoutilities/builder/ItemStackBuilder.java index 0722e40a..0fcfb9e0 100644 --- a/src/main/java/de/eldoria/eldoutilities/builder/ItemStackBuilder.java +++ b/items/src/main/java/de/eldoria/eldoutilities/builder/ItemStackBuilder.java @@ -6,7 +6,6 @@ package de.eldoria.eldoutilities.builder; -import de.eldoria.eldoutilities.utils.ObjUtil; import org.bukkit.Material; import org.bukkit.attribute.Attribute; import org.bukkit.attribute.AttributeModifier; @@ -94,7 +93,7 @@ public static ItemStackBuilder of(ItemStack stack, boolean clone) { */ public ItemStackBuilder withMetaValue(Consumer<@NotNull ItemMeta> itemMetaConsumer) { var meta = itemStack.getItemMeta(); - ObjUtil.nonNull(meta, itemMetaConsumer); + if (meta != null) itemMetaConsumer.accept(meta); itemStack.setItemMeta(meta); return this; } @@ -351,11 +350,12 @@ public ItemStackBuilder withNBTData(Consumer<@NotNull PersistentDataContainer> d @SuppressWarnings("unchecked") public ItemStackBuilder withMetaValue(Class clazz, Consumer<@NotNull T> consumer) { var itemMeta = itemStack.getItemMeta(); - ObjUtil.nonNull(itemMeta, m -> { - if (clazz.isAssignableFrom(m.getClass())) { - consumer.accept((T) m); + if (itemMeta != null) { + if (clazz.isAssignableFrom(itemMeta.getClass())) { + consumer.accept((T) itemMeta); } - }); + + } itemStack.setItemMeta(itemMeta); return this; } diff --git a/jackson-configuration/build.gradle.kts b/jackson-configuration/build.gradle.kts new file mode 100644 index 00000000..9b456b72 --- /dev/null +++ b/jackson-configuration/build.gradle.kts @@ -0,0 +1,4 @@ +dependencies { + api("de.eldoria.jacksonbukkit:jackson-bukkit:1.2.0") + api("com.fasterxml.jackson.dataformat:jackson-dataformat-yaml") +} diff --git a/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/ConfigKey.java b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/ConfigKey.java new file mode 100644 index 00000000..5a63391b --- /dev/null +++ b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/ConfigKey.java @@ -0,0 +1,68 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config; + +import org.bukkit.plugin.Plugin; + +import java.nio.file.Path; +import java.util.function.Supplier; + +/** + * A key for a config file. A config key is considered unique based on the underlying path. + *

+ * Two config keys pointing at the same file, but one being absolute and the other not are not considered equal. + * However, this should be avoided since it can cause issues when reloading or saving. + * + * @param name name of file + * @param path path of file with file ending. Path might be relative to {@link Plugin#getDataFolder()} + * @param configClazz class representing the file + * @param initValue the initial value when the file does not yet exist. + * @param type of file class + */ +public record ConfigKey(String name, Path path, Class configClazz, Supplier initValue) { + + /** + * Create a key for the default config aka config.yml. + * + * @param configClazz class representing the config.yml + * @param initValue the initial value when the config does not yet exist. + * @param type of config class + * @return config key for config.yml + */ + public static ConfigKey defaultConfig(Class configClazz, Supplier initValue) { + return new ConfigKey<>("config.yml", Path.of("config.yml"), configClazz, initValue); + } + + /** + * Create a key for the default config aka config.yml. + * + * @param name name of file + * @param path path of file with file ending. Path might be relative to {@link Plugin#getDataFolder()} + * @param configClazz class representing the config.yml + * @param initValue the initial value when the config does not yet exist. + * @param type of config class + * @return config key for config.yml + */ + public static ConfigKey of(String name, Path path, Class configClazz, Supplier initValue) { + return new ConfigKey<>(name, path, configClazz, initValue); + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + ConfigKey configKey = (ConfigKey) o; + + return path.equals(configKey.path); + } + + @Override + public int hashCode() { + return path.hashCode(); + } +} diff --git a/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/ConfigSubscriber.java b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/ConfigSubscriber.java new file mode 100644 index 00000000..90fd37d8 --- /dev/null +++ b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/ConfigSubscriber.java @@ -0,0 +1,20 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config; + +/** + * This interface may be implemented by plugins in config classes. + *

+ * It provides hooks for read and write operations. + */ +public interface ConfigSubscriber { + default void postRead(JacksonConfig config) { + } + + default void preWrite(JacksonConfig config) { + } +} diff --git a/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/JacksonConfig.java b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/JacksonConfig.java new file mode 100644 index 00000000..1f0b6999 --- /dev/null +++ b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/JacksonConfig.java @@ -0,0 +1,437 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config; + +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.MapperFeature; +import com.fasterxml.jackson.databind.Module; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.databind.cfg.MapperBuilder; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator; +import com.fasterxml.jackson.dataformat.yaml.YAMLMapper; +import de.eldoria.eldoutilities.config.exceptions.ConfigurationException; +import de.eldoria.eldoutilities.config.template.PluginBaseConfiguration; +import de.eldoria.jacksonbukkit.JacksonBukkit; +import de.eldoria.jacksonbukkit.JacksonPaper; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.Collections; +import java.util.HashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; + +/** + * Class allowing to manage multiple configuration files. + *

+ * Each file is associated with a {@link ConfigKey}, which provides a name, path and a default value. + * + * @param type of main configuration + */ +@SuppressWarnings("unused") +public class JacksonConfig { + private final Plugin plugin; + private final ConfigKey mainKey; + private final Map, Object> files = new ConcurrentHashMap<>(); + private ObjectMapper mapper; + private ObjectMapper writer; + private ObjectMapper reader; + + /** + * Creates a new Jackson Configuration + * + * @param plugin plugin owning the configuration + * @param mainKey key for the main configuration file former config.yml + */ + public JacksonConfig(@NotNull Plugin plugin, @NotNull ConfigKey mainKey) { + this.plugin = plugin; + this.mainKey = mainKey; + } + + /** + * Plugin associated with this configuration + * + * @return plugin instance + */ + public Plugin plugin() { + return plugin; + } + + /** + * Get the primary configuration. + *

+ * This will be the config.yml in most cases. + *

+ * If the config was not yet created, it will be created. + * + * @return configuration + */ + public T main() { + return secondary(mainKey); + } + + /** + * Get a configuration file. + *

+ * If this file was not yet created, it will be created. + * + * @param key configuration key + * @param type of configuration + * @return configuration file + */ + @SuppressWarnings("unchecked") + public synchronized V secondary(ConfigKey key) { + // This configuration might be called to retrieve the logging level. + // This will cause a recursive call + if (key == PluginBaseConfiguration.KEY) { + if (!exists(key)) { + // We schedule the loading of the plugin + CompletableFuture.delayedExecutor(10, TimeUnit.SECONDS).execute(() -> files.computeIfAbsent(key, k -> createAndLoad(key))); + // Return the default value for now. + return key.initValue().get(); + } + } + return (V) files.computeIfAbsent(key, k -> createAndLoad(key)); + } + + /** + * Get the primary configuration wrapper. + *

+ * This wrapper can be used to save the config using the closable. + * It is also safe to be stored since it does not store the file itself. + *

+ * This will be the config.yml in most cases. + *

+ * If the config was not yet created, it will be created. + * + * @return configuration + */ + public Wrapper mainWrapped() { + return Wrapper.of(mainKey, this); + } + + /** + * Get a configuration file. + *

+ * This wrapper can be used to save the config using the closable. + * It is also safe to be stored since it does not store the file itself. + *

+ * If this file was not yet created, it will be created. + * + * @param key configuration key + * @param type of configuration + * @return configuration file + */ + public Wrapper secondaryWrapped(ConfigKey key) { + return Wrapper.of(key, this); + } + + /** + * Checks whether the config file was created already + * + * @param key key + * @param type + * @return true when exists + */ + public boolean exists(ConfigKey key) { + return resolvePath(key).toFile().exists(); + } + + /** + * Checks whether the config file was already loaded + * + * @param key key + * @param type + * @return true when loaded + */ + public boolean loaded(ConfigKey key) { + return files.containsKey(key); + } + + /** + * Replace the configuration currently associated with this key with a new configuration. + * + * @param key configuration key + * @param newValue new value of key + * @param type of key + */ + public void replace(ConfigKey key, V newValue) { + files.put(key, newValue); + } + + /** + * Saves all files loaded via this instance. + */ + public void save() { + for (var configKey : files.keySet()) { + save(configKey); + } + } + + /** + * Saves the file associated with the config key + * + * @param key configuration key + */ + public void save(ConfigKey key) { + write(resolvePath(key), files.get(key)); + } + + /** + * Relaods all files loaded via this instance including the main configuration. + */ + public void reload() { + // We will modify the collection. Therefore, we need to copy first. + for (var key : new HashSet<>(files.keySet())) { + reload(key); + } + } + + /** + * Reloads a single file associated with the config key + * + * @param key configuration key + */ + public void reload(ConfigKey key) { + files.put(key, createAndLoad(key)); + } + + /** + * Get the object mapper used to read files + * + * @return object mapper instance + */ + public final ObjectMapper reader() { + if (reader == null) { + reader = registerAdditionalModules(createReadMapper()); + } + return reader; + } + + /** + * Get the mapper used to write objects + * + * @return object mapper instance + */ + public final ObjectMapper writer() { + if (writer == null) { + writer = registerAdditionalModules(createWriteMapper()); + } + return writer; + } + + /** + * Get the object mapper used to read and write objects + * + * @return object mapper instance + */ + public final ObjectMapper mapper() { + if (mapper == null) { + mapper = registerAdditionalModules(createMapper()); + } + return mapper; + } + + private ObjectMapper registerAdditionalModules(ObjectMapper mapper) { + for (Module module : additionalModules()) { + mapper.registerModule(module); + } + return mapper; + } + + /** + * Create a mapper for reading files. + * + * @return mapper instance + */ + protected ObjectMapper createReadMapper() { + return mapper(); + } + + /** + * Create a mapper for writing files. + * + * @return mapper instance + */ + protected ObjectMapper createWriteMapper() { + return mapper(); + } + + /** + * Load a file defined in the configuration key. + *

+ * Will fail if the file is not present. + *

+ * Use {@link #createAndLoad(ConfigKey)} if you want the file to be created. + * + * @param key configuration key + * @param type of file + * @return instance of file + */ + protected final V load(ConfigKey key) { + if (!exists(key)) return null; + try { + return read(resolvePath(key), key.configClazz()); + } catch (ConfigurationException e) { + plugin.getLogger().log(Level.SEVERE, "Could not load configuration file.", e); + backup(key); + plugin.getLogger().log(Level.WARNING, "Recreating default config"); + write(resolvePath(key), key.initValue().get()); + } + return key.initValue().get(); + } + + /** + * Load a file defined in the configuration key. + *

+ * If this file was not yet created, it will be created. + * + * @param key configuration key + * @param type of file + * @return instance of file + */ + protected final V createAndLoad(ConfigKey key) { + var path = resolvePath(key); + if (!exists(key)) { + plugin.getLogger().info("Configuration file: " + path + " does not exist. Creating."); + write(path, key.initValue().get()); + } + return load(key); + } + + /** + * Create a general mapper for read and write. + *

+ * You can define different wrapper for read and write operations by overwriting {@link #createReadMapper()} and {@link #createWriteMapper()} + * + * @return mapper instance + */ + protected ObjectMapper createMapper() { + return configureDefault(YAMLMapper.builder()); + } + + public ObjectMapper configureDefault(MapperBuilder builder) { + builder.addModule(getPlatformModule()) + // This is very important when using polymorphism and library loader feature. + .typeFactory(TypeFactory.defaultInstance().withClassLoader(plugin.getClass().getClassLoader())) + .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false) + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) + .enable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS); + if (builder instanceof YAMLMapper.Builder yaml) { + yaml.disable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID) + .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER); + } + return builder.build() + .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY) + .setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE); + } + + /** + * Get the module for the current platform. + * + * @return module + */ + public final Module getPlatformModule() { + if (plugin.getServer().getName().toLowerCase(Locale.ROOT).contains("spigot")) { + return getBukkitModule(); + } + return getPaperModule(); + } + + /** + * Allows to register additional modules to the mapper. + * + * @return list of modules. + */ + protected List additionalModules() { + return Collections.emptyList(); + } + + /** + * Create the module used for paper server. + *

+ * This should be a {@link JacksonPaper} module. + * + * @return paper module + */ + protected JacksonPaper getPaperModule() { + return JacksonPaper.builder() + .colorAsHex() + .build(); + } + + /** + * Create the module used for spigot/bukkit server. + *

+ * This should be a {@link JacksonBukkit} module. + * + * @return spigot/bukkit module + */ + protected JacksonBukkit getBukkitModule() { + return JacksonBukkit.builder() + .colorAsHex() + .build(); + } + + private void backup(ConfigKey key) { + var target = resolvePath(key); + var backupName = "backup_" + DateTimeFormatter.ofPattern("yyyy-MM-dd_hh-mm") + .format(LocalDateTime.now()) + "_" + target.getFileName(); + plugin.getLogger().log(Level.WARNING, "Backing up " + target + " to " + backupName); + try { + Files.move(target, target.getParent().resolve(backupName)); + plugin.getLogger().log(Level.SEVERE, "Backup done."); + } catch (IOException e) { + plugin.getLogger().log(Level.SEVERE, "Could not create backup."); + } + } + + private void write(Path path, Object object) { + try { + if (object instanceof ConfigSubscriber sub) { + sub.preWrite(this); + } + Files.createDirectories(path.getParent()); + // We do this to avoid wiping a file on serialization error. + Files.writeString(path, writer().writeValueAsString(object)); + } catch (IOException e) { + plugin.getLogger().log(Level.SEVERE, "Could not write configuration file to " + path, e); + throw new ConfigurationException("Could not write configuration file to " + path, e); + } + } + + private V read(Path path, Class clazz) { + try { + V v = reader().readValue(path.toFile(), clazz); + if (v instanceof ConfigSubscriber sub) { + sub.postRead(this); + } + return v; + } catch (IOException e) { + plugin.getLogger().log(Level.SEVERE, "Could not read configuration file from " + path, e); + throw new ConfigurationException("Could not read configuration file from " + path, e); + } + } + + private Path resolvePath(ConfigKey key) { + return key.path().isAbsolute() ? key.path() : plugin.getDataFolder().toPath().resolve(key.path()); + } +} diff --git a/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/Wrapper.java b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/Wrapper.java new file mode 100644 index 00000000..553a8f6e --- /dev/null +++ b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/Wrapper.java @@ -0,0 +1,46 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config; + +import java.io.Closeable; + +/** + * Class allowing to access a configuration file. + *

+ * The file itself will be accessed via the underlying configuration, making it stable for reloads. + *

+ * Using this class inside an auto closable will save the file afterward. + * + * @param type of config + */ +public class Wrapper implements Closeable { + private final ConfigKey key; + private final JacksonConfig config; + + public Wrapper(ConfigKey key, JacksonConfig config) { + this.key = key; + this.config = config; + } + + public static Wrapper of(ConfigKey key, JacksonConfig config) { + return new Wrapper<>(key, config); + } + + /** + * Get the wrapped config file. + * + * @return config file + */ + public T config() { + return config.secondary(key); + } + + @Override + public void close() { + config.save(key); + } +} diff --git a/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/exceptions/ConfigurationException.java b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/exceptions/ConfigurationException.java new file mode 100644 index 00000000..809889c0 --- /dev/null +++ b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/exceptions/ConfigurationException.java @@ -0,0 +1,13 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config.exceptions; + +public class ConfigurationException extends RuntimeException { + public ConfigurationException(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/parsing/deserializer/LevelDeserializer.java b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/parsing/deserializer/LevelDeserializer.java new file mode 100644 index 00000000..255841a7 --- /dev/null +++ b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/parsing/deserializer/LevelDeserializer.java @@ -0,0 +1,35 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config.parsing.deserializer; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; +import java.util.logging.Level; + +public class LevelDeserializer extends JsonDeserializer { + private static Level parseLevel(String level) { + return switch (level.toUpperCase()) { + case "OFF" -> Level.OFF; + case "SEVERE" -> Level.SEVERE; + case "WARNING" -> Level.WARNING; + case "DEBUG", "TRUE" -> Level.CONFIG; + case "FINE" -> Level.FINE; + case "FINER" -> Level.FINER; + case "FINEST" -> Level.FINEST; + case "ALL" -> Level.ALL; + default -> Level.INFO; + }; + } + + @Override + public Level deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { + return parseLevel(p.getText()); + } +} diff --git a/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/parsing/serializer/LevelSerializer.java b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/parsing/serializer/LevelSerializer.java new file mode 100644 index 00000000..0b6cb8a3 --- /dev/null +++ b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/parsing/serializer/LevelSerializer.java @@ -0,0 +1,21 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config.parsing.serializer; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.logging.Level; + +public class LevelSerializer extends JsonSerializer { + @Override + public void serialize(Level value, JsonGenerator gen, SerializerProvider serializers) throws IOException { + gen.writeString(value.getName()); + } +} diff --git a/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/template/PluginBaseConfiguration.java b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/template/PluginBaseConfiguration.java new file mode 100644 index 00000000..18a0d942 --- /dev/null +++ b/jackson-configuration/src/main/java/de/eldoria/eldoutilities/config/template/PluginBaseConfiguration.java @@ -0,0 +1,71 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config.template; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import de.eldoria.eldoutilities.config.ConfigKey; +import de.eldoria.eldoutilities.config.parsing.deserializer.LevelDeserializer; +import de.eldoria.eldoutilities.config.parsing.serializer.LevelSerializer; +import org.bukkit.plugin.Plugin; + +import java.nio.file.Path; +import java.util.logging.Level; + +public final class PluginBaseConfiguration { + public static final ConfigKey KEY = ConfigKey.of( + "Base configuration", + Path.of("base_configuration.yml"), + PluginBaseConfiguration.class, + PluginBaseConfiguration::new); + @JsonProperty + private int version; + @JsonProperty + private String lastInstalledVersion; + @JsonDeserialize(using = LevelDeserializer.class) + @JsonSerialize(using = LevelSerializer.class) + @JsonProperty + private Level logLevel = Level.INFO; + + public PluginBaseConfiguration() { + } + + public PluginBaseConfiguration(int version, String lastInstalledVersion, Level level) { + this.version = version; + this.lastInstalledVersion = lastInstalledVersion; + this.logLevel = level; + } + + public int version() { + return version; + } + + public String lastInstalledVersion() { + return lastInstalledVersion; + } + + public void version(int version) { + this.version = version; + } + + public void lastInstalledVersion(String lastInstalledVersion) { + this.lastInstalledVersion = lastInstalledVersion; + } + + public void lastInstalledVersion(Plugin plugin) { + this.lastInstalledVersion = plugin.getDescription().getVersion(); + } + + public Level logLevel() { + return logLevel; + } + + public void logLevel(Level logLevel) { + this.logLevel = logLevel; + } +} diff --git a/jackson-configuration/src/test/java/de/eldoria/eldoutilities/config/JacksonConfigTest.java b/jackson-configuration/src/test/java/de/eldoria/eldoutilities/config/JacksonConfigTest.java new file mode 100644 index 00000000..148b22ac --- /dev/null +++ b/jackson-configuration/src/test/java/de/eldoria/eldoutilities/config/JacksonConfigTest.java @@ -0,0 +1,89 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.config; + +import org.bukkit.plugin.java.JavaPlugin; + +import java.nio.file.Path; + +class JacksonConfigTest extends JavaPlugin { + + @Override + public void onEnable(){ + // Defining the key for the config.yml + ConfigKey defKey = ConfigKey.defaultConfig(ConfigFile.class, ConfigFile::new); + var config = new JacksonConfig<>(this, defKey); + // Getting the config.yml data + ConfigFile general = config.main(); + + // Defining a second config key for database.yml + ConfigKey databaseConfig = ConfigKey.of("Database Config", Path.of("database.yml"), Database.class, Database::new); + // Loading the file and creating it, if it doesn't exist yet + Database database = config.secondary(databaseConfig); + // Retrieving a wrapped instance which will be updated during config reloads + Wrapper databaseWrapped = config.secondaryWrapped(databaseConfig); + + // Reloading the config with the key + config.reload(databaseConfig); + // Reloading all configuration files + config.reload(); + + // Saving a specific file + config.save(databaseConfig); + // Saving all files + config.save(); + } + +public class ConfigFile { + private Database database = new Database(); + private General general = new General(); + + public Database database() { + return database; + } + + public General general() { + return general; + } +} + +public class Database { + private String host = "localhost"; + private int port = 3306; + private String user = "root"; + private String password = "root"; + + public String host() { + return host; + } + + public int port() { + return port; + } + + public String user() { + return user; + } + + public String password() { + return password; + } +} + +public class General{ + private String language = "en_US"; + private String prefix = "[Plugin]"; + + public String language() { + return language; + } + + public String prefix() { + return prefix; + } +} +} diff --git a/legacy-serialization/build.gradle.kts b/legacy-serialization/build.gradle.kts new file mode 100644 index 00000000..85215dac --- /dev/null +++ b/legacy-serialization/build.gradle.kts @@ -0,0 +1,4 @@ +dependencies { + api(project(":core")) + api(project(":entities")) +} diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/ConfigKey.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/ConfigKey.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/serialization/ConfigKey.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/ConfigKey.java diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/KebabNamingStrategy.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/KebabNamingStrategy.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/serialization/KebabNamingStrategy.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/KebabNamingStrategy.java diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/NamingStrategy.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/NamingStrategy.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/serialization/NamingStrategy.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/NamingStrategy.java diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/SampleImplementation.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SampleImplementation.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/serialization/SampleImplementation.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SampleImplementation.java index c9d4e2a3..98c973ed 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/SampleImplementation.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SampleImplementation.java @@ -13,6 +13,29 @@ import java.util.Map; public class SampleImplementation { + @SerializableAs("NestedClass") + public static class NestedClass implements ConfigurationSerializable { + private String someString = "Amazing"; + private String someOtherString = "Much default"; + + public NestedClass(Map objectMap) { + var map = SerializationUtil.mapOf(objectMap); + someString = map.getValueOrDefault("someInt", someString); + someOtherString = map.getValueOrDefault("someInt", someOtherString); + } + + public NestedClass() { + } + + @Override + public @NotNull Map serialize() { + return SerializationUtil.newBuilder() + .add("someString", someString) + .add("someOtherString", someOtherString) + .build(); + } + } + // We implement the ConfigurationSerializable interface @SerializableAs("SerializableClass") public class SerializableClass implements ConfigurationSerializable { @@ -46,27 +69,4 @@ public SerializableClass(Map objectMap) { .build(); } } - - @SerializableAs("NestedClass") - public static class NestedClass implements ConfigurationSerializable { - private String someString = "Amazing"; - private String someOtherString = "Much default"; - - public NestedClass(Map objectMap) { - var map = SerializationUtil.mapOf(objectMap); - someString = map.getValueOrDefault("someInt", someString); - someOtherString = map.getValueOrDefault("someInt", someOtherString); - } - - public NestedClass() { - } - - @Override - public @NotNull Map serialize() { - return SerializationUtil.newBuilder() - .add("someString", someString) - .add("someOtherString", someOtherString) - .build(); - } - } } diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/SerializationUtil.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SerializationUtil.java similarity index 99% rename from src/main/java/de/eldoria/eldoutilities/serialization/SerializationUtil.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SerializationUtil.java index 31ef0d4e..db3942ee 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/SerializationUtil.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SerializationUtil.java @@ -6,11 +6,10 @@ package de.eldoria.eldoutilities.serialization; -import de.eldoria.eldoutilities.core.EldoUtilities; +import de.eldoria.EldoUtilities; import de.eldoria.eldoutilities.serialization.wrapper.MapEntry; import de.eldoria.eldoutilities.utils.ReflectionUtil; -import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Collection; diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/SimpleSampleImplementation.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SimpleSampleImplementation.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/serialization/SimpleSampleImplementation.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SimpleSampleImplementation.java index 9abecf0f..7759c914 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/SimpleSampleImplementation.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/SimpleSampleImplementation.java @@ -13,6 +13,24 @@ import java.util.Map; public class SimpleSampleImplementation { + @SerializableAs("NestedClass") + public static class NestedClass implements ConfigurationSerializable { + private final String someString = "Amazing"; + private final String someOtherString = "Much default"; + + public NestedClass(Map objectMap) { + SerializationUtil.mapOnObject(objectMap, this); + } + + public NestedClass() { + } + + @Override + public @NotNull Map serialize() { + return SerializationUtil.objectToMap(this); + } + } + // We implement the ConfigurationSerializable interface @SerializableAs("SerializableClass") public class SerializableClass implements ConfigurationSerializable { @@ -41,22 +59,4 @@ public SerializableClass(Map objectMap) { return SerializationUtil.objectToMap(this); } } - - @SerializableAs("NestedClass") - public static class NestedClass implements ConfigurationSerializable { - private final String someString = "Amazing"; - private final String someOtherString = "Much default"; - - public NestedClass(Map objectMap) { - SerializationUtil.mapOnObject(objectMap, this); - } - - public NestedClass() { - } - - @Override - public @NotNull Map serialize() { - return SerializationUtil.objectToMap(this); - } - } } diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/TypeConversion.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/TypeConversion.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/serialization/TypeConversion.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/TypeConversion.java diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/TypeResolvingMap.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/TypeResolvingMap.java similarity index 96% rename from src/main/java/de/eldoria/eldoutilities/serialization/TypeResolvingMap.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/TypeResolvingMap.java index 842b2f1a..fe168bef 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/TypeResolvingMap.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/TypeResolvingMap.java @@ -6,7 +6,6 @@ package de.eldoria.eldoutilities.serialization; -import de.eldoria.eldoutilities.core.EldoUtilities; import de.eldoria.eldoutilities.serialization.wrapper.MapEntry; import de.eldoria.eldoutilities.utils.EnumUtil; import org.jetbrains.annotations.NotNull; @@ -17,7 +16,6 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import java.util.Objects; import java.util.Optional; import java.util.Set; import java.util.UUID; @@ -155,9 +153,7 @@ public T getValueOrDefault(String key, T defaultValue, Function v mapObjects.forEach(e -> { - EldoUtilities.logger().config("Building map entry from: " + e); if (e == null) { - EldoUtilities.logger().config("Map is null"); return; } results.put(keyOrValueToKey.apply(e.getKey(), (V) e.getObject()), (V) e.getObject()); diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/util/ArmorStandWrapper.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/util/ArmorStandWrapper.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/serialization/util/ArmorStandWrapper.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/util/ArmorStandWrapper.java index 9091609a..4b96aaf4 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/util/ArmorStandWrapper.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/util/ArmorStandWrapper.java @@ -6,13 +6,12 @@ package de.eldoria.eldoutilities.serialization.util; -import de.eldoria.eldoutilities.builder.EntityBuilder; +import de.eldoria.eldoutilities.entities.EntityBuilder; import de.eldoria.eldoutilities.serialization.SerializationUtil; import org.bukkit.Location; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EntityType; -import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.ItemStack; import org.bukkit.util.EulerAngle; import org.bukkit.util.Vector; diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/util/MapEntry.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/util/MapEntry.java similarity index 92% rename from src/main/java/de/eldoria/eldoutilities/serialization/util/MapEntry.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/util/MapEntry.java index 8c0e0852..f738c9ba 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/util/MapEntry.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/util/MapEntry.java @@ -35,8 +35,8 @@ public static de.eldoria.eldoutilities.serialization.wrapper.MapEntry deserializ @Override public String toString() { return "MapEntry{" + - "key='" + key + '\'' + - ", object=" + object + - '}'; + "key='" + key + '\'' + + ", object=" + object + + '}'; } } diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ArmorStandWrapper.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ArmorStandWrapper.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ArmorStandWrapper.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ArmorStandWrapper.java index eac07541..d39566a7 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ArmorStandWrapper.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ArmorStandWrapper.java @@ -6,14 +6,13 @@ package de.eldoria.eldoutilities.serialization.wrapper; -import de.eldoria.eldoutilities.builder.EntityBuilder; +import de.eldoria.eldoutilities.entities.EntityBuilder; import de.eldoria.eldoutilities.serialization.SerializationUtil; import de.eldoria.eldoutilities.serialization.util.PluginSerializationName; import org.bukkit.Location; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.entity.ArmorStand; import org.bukkit.entity.EntityType; -import org.bukkit.inventory.EntityEquipment; import org.bukkit.inventory.ItemStack; import org.bukkit.util.EulerAngle; import org.bukkit.util.Vector; diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/MapEntry.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/MapEntry.java similarity index 86% rename from src/main/java/de/eldoria/eldoutilities/serialization/wrapper/MapEntry.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/MapEntry.java index 8e067891..67eb6a1b 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/MapEntry.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/MapEntry.java @@ -6,9 +6,8 @@ package de.eldoria.eldoutilities.serialization.wrapper; -import de.eldoria.eldoutilities.core.EldoUtilities; +import de.eldoria.EldoUtilities; import de.eldoria.eldoutilities.serialization.SerializationUtil; -import de.eldoria.eldoutilities.serialization.TypeResolvingMap; import de.eldoria.eldoutilities.serialization.util.PluginSerializationName; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.jetbrains.annotations.NotNull; @@ -53,8 +52,8 @@ public Object getObject() { @Override public String toString() { return "MapEntry{" + - "key='" + key + '\'' + - ", object=" + object + - '}'; + "key='" + key + '\'' + + ", object=" + object + + '}'; } } diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/SerializeContainer.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/SerializeContainer.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/serialization/wrapper/SerializeContainer.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/SerializeContainer.java index b1c6d312..6526591d 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/SerializeContainer.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/SerializeContainer.java @@ -13,10 +13,10 @@ import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.reflect.TypeToken; -import java.lang.reflect.Type; import org.bukkit.configuration.serialization.ConfigurationSerializable; import org.bukkit.configuration.serialization.ConfigurationSerialization; +import java.lang.reflect.Type; import java.util.Map; public class SerializeContainer { @@ -96,7 +96,8 @@ public String toJson() { private static class SerializeContainerAdapter implements JsonDeserializer { - private static final Type MAP_TYPE = new TypeToken>(){}.getType(); + private static final Type MAP_TYPE = new TypeToken>() { + }.getType(); @Override public SerializeContainer deserialize(JsonElement json, Type typeOfT, diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ShapedRecipeWrapper.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ShapedRecipeWrapper.java similarity index 98% rename from src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ShapedRecipeWrapper.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ShapedRecipeWrapper.java index 68955405..841e06f2 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ShapedRecipeWrapper.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/ShapedRecipeWrapper.java @@ -7,7 +7,6 @@ package de.eldoria.eldoutilities.serialization.wrapper; import de.eldoria.eldoutilities.serialization.SerializationUtil; -import de.eldoria.eldoutilities.serialization.TypeResolvingMap; import org.bukkit.Material; import org.bukkit.NamespacedKey; import org.bukkit.configuration.serialization.ConfigurationSerializable; diff --git a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/YamlContainer.java b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/YamlContainer.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/serialization/wrapper/YamlContainer.java rename to legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/YamlContainer.java index ac04a0e6..2d4423eb 100644 --- a/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/YamlContainer.java +++ b/legacy-serialization/src/main/java/de/eldoria/eldoutilities/serialization/wrapper/YamlContainer.java @@ -29,14 +29,6 @@ public static YamlContainer fromObject(Object object) { return new YamlContainer(config); } - public String toYaml() { - return config.saveToString(); - } - - public T toObject(Class clazz) { - return config.getObject("object", clazz); - } - public static String objectToYaml(Object object) { return fromObject(object).toYaml(); } @@ -44,4 +36,12 @@ public static String objectToYaml(Object object) { public static T yamlToObject(String yaml, Class clazz) throws InvalidConfigurationException { return fromYaml(yaml).toObject(clazz); } + + public String toYaml() { + return config.saveToString(); + } + + public T toObject(Class clazz) { + return config.getObject("object", clazz); + } } diff --git a/src/test/java/de/eldoria/eldoutilities/serialization/SerializationUtilTest.java b/legacy-serialization/src/test/java/de/eldoria/eldoutilities/serialization/SerializationUtilTest.java similarity index 94% rename from src/test/java/de/eldoria/eldoutilities/serialization/SerializationUtilTest.java rename to legacy-serialization/src/test/java/de/eldoria/eldoutilities/serialization/SerializationUtilTest.java index 0357a435..687ad1df 100644 --- a/src/test/java/de/eldoria/eldoutilities/serialization/SerializationUtilTest.java +++ b/legacy-serialization/src/test/java/de/eldoria/eldoutilities/serialization/SerializationUtilTest.java @@ -17,7 +17,7 @@ public class SerializationUtilTest { private final SerializableClass.NestedObject nestedObject = new SerializableClass.NestedObject(2, "test"); private final SerializableClass testClass = new SerializableClass(10, "test", nestedObject); - private final InheritClass inheritClass = new InheritClass(); + private final InheritClass inheritClass = new InheritClass(); @Test public void serializationTest() { @@ -58,14 +58,18 @@ public SerializableClass(int someInt, String someString, NestedObject someNested this.someNestedObject = someNestedObject; } + public SerializableClass(Map map) { + SerializationUtil.mapOnObject(map, this); + } + @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; SerializableClass that = (SerializableClass) o; return someInt == that.someInt && - someString.equals(that.someString) && - someNestedObject.equals(that.someNestedObject); + someString.equals(that.someString) && + someNestedObject.equals(that.someNestedObject); } @Override @@ -73,10 +77,6 @@ public int hashCode() { return Objects.hash(someInt, someString, someNestedObject); } - public SerializableClass(Map map) { - SerializationUtil.mapOnObject(map, this); - } - @Override public @NotNull Map serialize() { return SerializationUtil.objectToMap(this); @@ -106,7 +106,7 @@ public boolean equals(Object o) { if (o == null || getClass() != o.getClass()) return false; NestedObject that = (NestedObject) o; return someInt == that.someInt && - someString.equals(that.someString); + someString.equals(that.someString); } @Override diff --git a/src/test/java/de/eldoria/eldoutilities/serialization/TypeConversionTest.java b/legacy-serialization/src/test/java/de/eldoria/eldoutilities/serialization/TypeConversionTest.java similarity index 100% rename from src/test/java/de/eldoria/eldoutilities/serialization/TypeConversionTest.java rename to legacy-serialization/src/test/java/de/eldoria/eldoutilities/serialization/TypeConversionTest.java diff --git a/localization/build.gradle.kts b/localization/build.gradle.kts new file mode 100644 index 00000000..9b5b15ed --- /dev/null +++ b/localization/build.gradle.kts @@ -0,0 +1,5 @@ +dependencies { + api(project(":core")) + api(project(":messaging")) +} + diff --git a/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java b/localization/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java similarity index 76% rename from src/main/java/de/eldoria/eldoutilities/localization/Localizer.java rename to localization/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java index a0c3a2ec..afcf667c 100644 --- a/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java +++ b/localization/src/main/java/de/eldoria/eldoutilities/localization/Localizer.java @@ -33,6 +33,8 @@ import java.util.logging.Level; import java.util.regex.Pattern; +import static de.eldoria.eldoutilities.localization.ILocalizer.isLocaleCode; + /** * Compact localizer class. *

@@ -48,9 +50,8 @@ * * @since 1.0.0 */ +@SuppressWarnings("unused") public class Localizer implements ILocalizer { - private static final Pattern EMBED_LOCALIZATION_CODE = Pattern.compile("\\$([a-zA-Z0-9_.]+?)\\$"); - private static final Pattern LOCALIZATION_CODE = Pattern.compile("([a-zA-Z0-9_.]+?)"); private final ResourceBundle fallbackBundle; private final Plugin plugin; @@ -59,8 +60,8 @@ public class Localizer implements ILocalizer { private final String[] includedLocales; private final Pattern localePattern = Pattern.compile("_(([a-zA-Z]{2})(_[a-zA-Z]{2})?)\\.properties"); private final Map runtimeLocaleCodes = new HashMap<>(); - private ResourceBundle bundle; List childs = new ArrayList<>(); + private ResourceBundle bundle; private boolean checked; /** @@ -68,11 +69,11 @@ public class Localizer implements ILocalizer { *

* This instance will create locale files, which are provided in the resources directory. *

- * After this it will updates all locale files inside the locales directory. For this the ref keys from the internal + * After this it will update all locale files inside the locales directory. For this the ref keys from the internal * default locale file will be used. *

* After a update check and a update if needed it will load the provided language or the fallback language if the - * provided language does not exists. + * provided language does not exist. * * @param plugin instance of plugin * @param localesPath path of the locales directory @@ -97,18 +98,65 @@ public class Localizer implements ILocalizer { createDefaults(); } + /** + * Create a new localizer instance with default values. + *

+ * The message path and prefix will be "messages" and the fallback language the "en_US" locale. + *

+ * This instance will create locale files, which are provided in the resources directory. + *

+ * After this it will update all locale files inside the locales directory. For this the ref keys from the internal + * default locale file will be used. + *

+ * After a update check and an update if needed it will load the provided language or the fallback language if the + * provided language does not exist. + * + * @param plugin instance of plugin + * @param includedLocales internal provided locales + * @return the created localizer instance + */ + public static ILocalizer create(Plugin plugin, + String... includedLocales) { + return create(plugin, "messages", "messages", Locale.US, includedLocales); + } + + /** + * Create a new localizer instance. + *

+ * This instance will create locale files, which are provided in the resources directory. + *

+ * After this it will update all locale files inside the locales directory. For this the ref keys from the internal + * default locale file will be used. + *

+ * After a update check and an update if needed it will load the provided language or the fallback language if the + * provided language does not exist. + * + * @param plugin instance of plugin + * @param localesPath path of the locales directory + * @param localesPrefix prefix of the locale files + * @param fallbackLocale fallbackLocale + * @param includedLocales internal provided locales + * @return the created localizer instance + */ + public static ILocalizer create(Plugin plugin, String localesPath, + String localesPrefix, Locale fallbackLocale, String... includedLocales) { + ILocalizer localizer = new Localizer(plugin, localesPath, localesPrefix, fallbackLocale, includedLocales); + LOCALIZER.put(plugin.getClass(), localizer); + return localizer; + } + private void createDefaults() { Map locales = new HashMap<>(); - locales.put("error.invalidArguments", "Invalid arguments.\nSyntax: %SYNTAX%"); + locales.put("error.invalidArguments", "Invalid arguments.\nSyntax: "); locales.put("error.invalidCommand", "Invalid Command"); - locales.put("error.endOfRoute", "Please choose a subcommand. Available commands are:\n%COMMANDS%"); - locales.put("error.permission", "You do not have the permissionNode to do this. (%PERMISSION%)"); - locales.put("error.invalidRange", "This value is out of range. Min: %MIN% Max: %MAX%"); - locales.put("error.invalidEnumValue", "Invalid input value. Valid inputs are %VALUES%."); + locales.put("error.endOfRoute", "Please choose a subcommand. Available commands are:\n"); + locales.put("error.permission", "You do not have the permission to do this. ()"); + locales.put("error.invalidRange", "This value is out of range. Min: Max: "); + locales.put("error.invalidEnumValue", "Invalid input value. Valid inputs are ."); locales.put("error.invalidMaterial", "Invalid material."); locales.put("error.invalidNumber", "Invalid number"); - locales.put("error.invalidBoolean", "Invalid value, %TRUE% or %FALSE%"); - locales.put("error.invalidLength", "This input is too long. Max: %MAX% chars."); + locales.put("error.invalidBoolean", "Invalid value, or "); + locales.put("error.invalidLength", "This input is too long. Max: chars."); locales.put("error.notOnline", "Invalid player. This player is not online."); locales.put("error.unkownPlayer", "Invalid player. This player has never played on this server."); locales.put("error.unkownWorld", "Invalid player. This player has never played on this server."); @@ -116,11 +164,11 @@ private void createDefaults() { locales.put("error.onlyPlayer", "This command can only be used by players."); locales.put("error.onlyConsole", "This command can only be used by console."); locales.put("error.invalidSender", "This command can not be executed from here."); - locales.put("error.missingArgument", "Argument %INDEX% is accessed but not present."); + locales.put("error.missingArgument", "Argument is accessed but not present."); locales.put("error.notAsPlayer", "This command can not be executed as player"); - locales.put("error.tooSmall", "The number is too small. Min: %MIN%"); - locales.put("error.tooLarge", "The number is too Large. Max: %MAX%"); - locales.put("about", "%PLUGIN_NAME% by %AUTHORS%\nVersion: %VERSION%\nSpigot: %WEBSITE%\nSupport: %DISCORD%"); + locales.put("error.tooSmall", "The number is too small. Min: "); + locales.put("error.tooLarge", "The number is too Large. Max: "); + locales.put("about", " by \nVersion: \nSpigot: \nSupport: "); locales.put("dialog.accept", "accept"); locales.put("dialog.deny", "deny"); locales.put("dialog.add", "add"); @@ -154,20 +202,19 @@ public void setLocale(String language) { /** * Translates a String with Placeholders. Can handle multiple messages with replacements. * - * @param key Key of message - * @param replacements Replacements + * @param key Key of message * @return Replaced Messages */ @Override - public String getMessage(String key, Replacement... replacements) { + public String getMessage(String key) { var result = getValue(key); - if (result == null) { + if (result == null && LOCALIZATION_CODE.matcher(key).matches()) { plugin.getLogger().warning("Key " + key + " is missing in fallback file."); result = key; } - return invokeReplacements(result, replacements); + return result; } @Override @@ -211,7 +258,7 @@ private String getLocaleFileName(String locale) { } private void createDefaultFiles() { - // Create the property files if they do not exists. + // Create the property files if they do not exist. for (var locale : includedLocales) { var localeFile = getLocaleFile(locale).toFile(); if (localeFile.exists()) { @@ -240,6 +287,10 @@ private boolean isLocaleFile(Path path) { private ResourceBundle getDefaultBundle() throws IOException { try (var input = plugin.getResource(localesPrefix + ".properties")) { + if (input == null) { + plugin.getLogger().severe("Could not load locale file " + localesPrefix + ".properties. Does it exist?"); + return new DummyResourceBundle(); + } //TODO: Lazy getter return new PropertyResourceBundle(input); } @@ -248,6 +299,7 @@ private ResourceBundle getDefaultBundle() throws IOException { private ResourceBundle getBundle(String locale) throws IOException { try (var input = plugin.getResource(getLocaleFileName(locale))) { if (input == null) { + plugin.getLogger().severe("Could not load locale file " + getLocaleFileName(locale) + ".properties. Does it exist?"); return getDefaultBundle(); } return new PropertyResourceBundle(input); @@ -326,14 +378,6 @@ private void createOrUpdateLocaleFiles() { continue; } - ResourceBundle bundle; - try { - bundle = getBundle(path); - } catch (IOException e) { - plugin.getLogger().log(Level.SEVERE, "Could not load bundle " + path, e); - continue; - } - // load the external property file. Map bundleMap; try { @@ -346,17 +390,17 @@ private void createOrUpdateLocaleFiles() { updateKeys.removeAll(bundleMap.keySet()); if (updateKeys.isEmpty()) { - plugin.getLogger().info("§2Locale " + path + " is up to date."); + plugin.getLogger().info("Locale " + path + " is up to date."); continue; } - plugin.getLogger().info("§2Updating " + path + "."); + plugin.getLogger().info("Updating " + path + "."); // check if ref key is in locale for (var currKey : updateKeys) { var value = refBundle.containsKey(currKey) ? refBundle.getString(currKey) : runtimeLocaleCodes.getOrDefault(currKey, ""); // Add the property with the value if it exists in a internal file. bundleMap.put(currKey, value); - plugin.getLogger().info("§2Added: §3" + currKey + "§6=§b" + value.replace("\n", "\\n")); + plugin.getLogger().info("Added: " + currKey + "=" + value.replace("\n", "\\n")); } List lines = new ArrayList<>(); @@ -372,7 +416,7 @@ private void createOrUpdateLocaleFiles() { plugin.getLogger().log(Level.WARNING, "Could not update locale " + path + ".", e); continue; } - plugin.getLogger().info("§2Updated locale " + path + ". Please check your translation."); + plugin.getLogger().info("Updated locale " + path + ". Please check your translation."); } } @@ -380,11 +424,11 @@ private Locale extractLocale(Path filename) { var matcher = localePattern.matcher(filename.toFile().getName()); if (matcher.find()) { var group = matcher.group(1); - var s = group.split("_"); - if (s.length == 1) { - return new Locale(s[0]); + var part = group.split("_"); + if (part.length == 1) { + return new Locale(part[0]); } - return new Locale(s[0], s[1]); + return new Locale(part[0], part[1]); } return null; } @@ -392,49 +436,20 @@ private Locale extractLocale(Path filename) { /** * Translates a String with Placeholders. Can handle multiple messages with replacements. * - * @param message Message to translate - * @param replacements Replacements. + * @param message Message to translate * @return Replaced Messages */ @Override - public String localize(String message, Replacement... replacements) { + public String localize(String message) { if (message == null) { return null; } - // If the matcher doesn't find any key we assume its a simple message. - if (!EMBED_LOCALIZATION_CODE.matcher(message).find()) { - if (LOCALIZATION_CODE.matcher(message).matches()) { - message = getMessage(message, replacements); - } - } - - // find locale codes in message - var matcher = EMBED_LOCALIZATION_CODE.matcher(message); - List keys = new ArrayList<>(); - while (matcher.find()) { - keys.add(matcher.group(1)); + // Check if input is a locale key. + if (isLocaleCode(message)) { + message = getMessage(message); } - var result = message; - for (var match : keys) { - //Replace current locale code with result - result = result.replace("$" + match + "$", getMessage(match, replacements)); - } - - result = invokeReplacements(result, replacements); - - if (EMBED_LOCALIZATION_CODE.matcher(result).find()) { - return localize(result, replacements); - } - - return result; - } - - private String invokeReplacements(String message, Replacement... replacements) { - for (var replacement : replacements) { - message = replacement.invoke(message); - } return message; } @@ -458,7 +473,7 @@ public void registerChild(ILocalizer localizer) { childs.add(localizer); } - private class DummyResourceBundle extends ResourceBundle { + private static class DummyResourceBundle extends ResourceBundle { @Override protected Object handleGetObject(@NotNull String key) { diff --git a/src/main/java/de/eldoria/eldoutilities/localization/MessageComposer.java b/localization/src/main/java/de/eldoria/eldoutilities/localization/MessageComposer.java similarity index 77% rename from src/main/java/de/eldoria/eldoutilities/localization/MessageComposer.java rename to localization/src/main/java/de/eldoria/eldoutilities/localization/MessageComposer.java index bcb447d1..bb008a4e 100644 --- a/src/main/java/de/eldoria/eldoutilities/localization/MessageComposer.java +++ b/localization/src/main/java/de/eldoria/eldoutilities/localization/MessageComposer.java @@ -7,32 +7,36 @@ package de.eldoria.eldoutilities.localization; import de.eldoria.eldoutilities.utils.TextUtil; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.IntStream; /** * Class to compose localized messages. * Handles escaping and concatenation of messages. */ @SuppressWarnings("unused") -public class MessageComposer { +public class MessageComposer implements IMessageComposer { private final StringBuilder stringBuilder = new StringBuilder(); - private final List replacements = new ArrayList<>(); + private final List replacements = new ArrayList<>(); + + private MessageComposer() { + } public static MessageComposer create() { return new MessageComposer(); } - private MessageComposer() { + public static String escape(String text) { + return ILocalizer.escape(text); } - public MessageComposer localeCode(String propertyKey, Replacement... replacements) { - stringBuilder.append(escape(propertyKey)); + public MessageComposer localeCode(String propertyKey, TagResolver... replacements) { + stringBuilder.append(ILocalizer.escape(propertyKey)); this.replacements.addAll(Arrays.asList(replacements)); return this; } @@ -90,8 +94,7 @@ public MessageComposer space() { } public MessageComposer space(int spaces) { - // TODO: waiting for java 11 migration - stringBuilder.append(IntStream.range(0, spaces).mapToObj(i -> " ").collect(Collectors.joining())); + stringBuilder.append(" ".repeat(spaces)); return this; } @@ -101,14 +104,12 @@ public MessageComposer fillLines() { public MessageComposer fillLines(int lines) { var lineCount = TextUtil.countChars(stringBuilder.toString(), '\n') + 1; - // TODO: waiting for java 11 migration prependLines(Math.max(lines - lineCount, 0)); return this; } public MessageComposer prependLines(int lines) { - var newLines = IntStream.range(0, Math.max(lines, 0)).mapToObj(i -> "\n").collect(Collectors.joining()); - stringBuilder.insert(0, newLines); + stringBuilder.insert(0, "\n".repeat(lines)); return this; } @@ -122,15 +123,17 @@ public MessageComposer newLine() { return this; } + @Override public String build() { return stringBuilder.toString(); } - public String buildLocalized(ILocalizer localizer) { - return localizer.localize(stringBuilder.toString(), replacements.toArray(new Replacement[0])); + @Override + public List replacements() { + return Collections.unmodifiableList(replacements); } - public static String escape(String propertyKey) { - return String.format("$%s$", propertyKey); + public String buildLocalized(ILocalizer localizer) { + return localizer.localize(stringBuilder.toString()); } } diff --git a/src/test/java/de/eldoria/eldoutilities/localization/MessageComposerTest.java b/localization/src/test/java/de/eldoria/eldoutilities/localization/MessageComposerTest.java similarity index 99% rename from src/test/java/de/eldoria/eldoutilities/localization/MessageComposerTest.java rename to localization/src/test/java/de/eldoria/eldoutilities/localization/MessageComposerTest.java index c5084d8d..b57b58e3 100644 --- a/src/test/java/de/eldoria/eldoutilities/localization/MessageComposerTest.java +++ b/localization/src/test/java/de/eldoria/eldoutilities/localization/MessageComposerTest.java @@ -25,6 +25,7 @@ public void fillTest() { public void spacesText() { Assertions.assertEquals(5, MessageComposer.create().space(5).build().length()); } + @Test public void prependText() { Assertions.assertEquals(5, TextUtil.countChars(MessageComposer.create().prependLines(5).build(), '\n')); diff --git a/messaging/build.gradle.kts b/messaging/build.gradle.kts new file mode 100644 index 00000000..56681453 --- /dev/null +++ b/messaging/build.gradle.kts @@ -0,0 +1,9 @@ +dependencies { + api("net.kyori", "adventure-platform-bukkit", "4.3.0") + api("net.kyori", "adventure-text-minimessage", "4.13.0") + api("net.kyori", "adventure-text-serializer-plain", "4.13.0") + compileOnly("com.destroystokyo.paper:paper-api:1.16.5-R0.1-SNAPSHOT") + api(project(":core")){ + exclude("org.spigot") + } +} diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/localization/IMessageComposer.java b/messaging/src/main/java/de/eldoria/eldoutilities/localization/IMessageComposer.java new file mode 100644 index 00000000..2f87a66a --- /dev/null +++ b/messaging/src/main/java/de/eldoria/eldoutilities/localization/IMessageComposer.java @@ -0,0 +1,17 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.localization; + +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; + +import java.util.List; + +public interface IMessageComposer { + String build(); + + List replacements(); +} diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java new file mode 100644 index 00000000..996e88db --- /dev/null +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java @@ -0,0 +1,284 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.messages; + +import de.eldoria.eldoutilities.localization.ILocalizer; +import de.eldoria.eldoutilities.localization.IMessageComposer; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer; +import net.kyori.adventure.title.Title; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** + * A message sender to manage message sending. + *

+ * Allows definition of a plugin prefix, Message color, Error color. + *

+ * Allows sending of messages, error messages, titles. + *

+ * Allows sending of automatically localized messages in combination with a created localizer. + * + * @since 1.0.0 + */ +public abstract class MessageSender { + private static final Map, MessageSender> PLUGIN_SENDER = new HashMap<>(); + @Nullable + private final Class ownerPlugin; + private final Plugin plugin; + private MiniMessage miniMessage; + private TagResolver messageTagResolver; + private TagResolver errorTagResolver; + private Component prefix; + + public MessageSender(Plugin plugin, MiniMessage miniMessage, TagResolver messageTagResolver, TagResolver errorTagResolver, Component prefix) { + this.ownerPlugin = plugin.getClass(); + this.plugin = plugin; + this.miniMessage = miniMessage; + this.messageTagResolver = messageTagResolver; + this.errorTagResolver = errorTagResolver; + this.prefix = prefix; + } + + public static void register(MessageSender messageSender) { + if(messageSender.ownerPlugin == null) return; + PLUGIN_SENDER.put(messageSender.ownerPlugin, messageSender); + } + + /** + * Get the message sender created for this plugin. + * + * @param plugin plugin + * @return message sender of plugin or default sender if plugin is null + */ + public static MessageSender getPluginMessageSender(@NotNull Plugin plugin) { + if (plugin == null) throw new IllegalArgumentException("Plugin can not be null"); + return getPluginMessageSender(plugin.getClass()); + } + + public static MessageSenderBuilder builder(Plugin plugin) { + return new MessageSenderBuilder(plugin); + } + + /** + * Get the message sender created for this plugin. + * + * @param plugin plugin + * @return message sender of plugin or default sender if plugin is null + */ + public static MessageSender getPluginMessageSender(@NotNull Class plugin) { + if (!PLUGIN_SENDER.containsKey(plugin)) { + throw new IllegalStateException("No message sender was created for " + plugin.getName()); + } + if (plugin == null) throw new IllegalArgumentException("Plugin can not be null"); + return PLUGIN_SENDER.get(plugin); + } + + private MessageSender update(MiniMessage miniMessage, TagResolver messageTagResolver, TagResolver errorTagResolver, Component prefix) { + this.miniMessage = miniMessage; + this.messageTagResolver = messageTagResolver; + this.errorTagResolver = errorTagResolver; + this.prefix = prefix; + return this; + } + + /** + * Send a message to a sender + *

+ * The message will be localized if a localizer is available and a locale code is detected. + *

+ * The message can be a simple locale code in the format "code" or "code.code....". + *

+ * If multiple code should be used every code musst be surrounded by a {@code $} mark. Example {@code "$code.code$ + * and $code.more.code$}. You can write what you want between locale codes. + * + * @param sender receiver of the message + * @param message message with optional color codes + */ + public void sendMessage(CommandSender sender, String message, TagResolver... placeholder) { + sendMessage(sender, serialize(message, messageTagResolver, placeholder)); + } + + + /** + * Send a message to a sender + *

+ * The message will be localized if a localizer is available and a locale code is detected. + *

+ * The message can be a simple locale code in the format "code" or "code.code....". + *

+ * If multiple code should be used every code musst be surrounded by a {@code $} mark. Example {@code "$code.code$ + * and $code.more.code$}. You can write what you want between locale codes. + * + * @param sender receiver of the message + * @param composer message composer + */ + public void sendMessage(CommandSender sender, IMessageComposer composer) { + sendMessage(sender, serialize(composer.build(), messageTagResolver, + composer.replacements().toArray(new TagResolver[0]))); + } + + /** + * Sends an error to a sender + *

+ * The message will be localized if a localizer is available and a locale code is detected. + *

+ * The message can be a simple locale code in the format "code" or "code.code....". + *

+ * If multiple code should be used every code musst be surrounded by a {@code $} mark. Example {@code "$code.code$ + * and $code.more.code$}. You can write what you want between locale codes. + * + * @param sender receiver of the message + * @param message message with optinal color codes + */ + public void sendError(CommandSender sender, String message, TagResolver... placeholder) { + sendMessage(sender, serialize(message, errorTagResolver, placeholder)); + } + + /** + * Sends an error to a sender + *

+ * The message will be localized if a localizer is available and a locale code is detected. + *

+ * The message can be a simple locale code in the format "code" or "code.code....". + *

+ * If multiple code should be used every code musst be surrounded by a {@code $} mark. Example {@code "$code.code$ + * and $code.more.code$}. You can write what you want between locale codes. + * + * @param sender receiver of the message + * @param composer message composer + */ + public void sendError(CommandSender sender, IMessageComposer composer) { + sendMessage(sender, serialize(composer.build(), errorTagResolver, + composer.replacements().toArray(new TagResolver[0]))); + } + + public abstract void sendMessage(CommandSender sender, Component component); + + public abstract void broadcast(String message); + + /** + * Send a localized title to a player + * + * @param player player to send + * @param title title to send + */ + public void sendTitle(Player player, String title, String subtitle, Title.Times times, TagResolver... placeholder) { + sendTitle(player, Title.title(serialize(title, messageTagResolver, placeholder), serialize(subtitle, messageTagResolver, placeholder), times)); + } + + /** + * Send a title to a player + * + * @param player player to send + * @param title title to send + */ + public abstract void sendTitle(Player player, Title title); + + /** + * Send a localized action bar to a player + * + * @param player player to send + * @param message message to send + */ + public abstract void sendActionBar(Player player, String message, TagResolver... placeholder); + + /** + * Send a localized action bar to a player + * + * @param player player to send + * @param message message to send + */ + public abstract void sendErrorActionBar(Player player, String message, TagResolver... placeholder); + + public abstract void sendBossBar(Player player, BossBar bossBar) ; + + public abstract BossBar sendBossBar(Player player, String message, float progress, BossBar.Color color, BossBar.Overlay overlay, Set flags); + + public abstract void hideBossBar(Player player, BossBar bossBar); + + private ILocalizer loc() { + return ILocalizer.getPluginLocalizer(ownerPlugin); + } + + protected Component serialize(String message, TagResolver resolver, TagResolver... placeholder) { + if (ILocalizer.isLocaleCode(message)) { + message = ILocalizer.escape(message); + } + message = "" + message; + var finalResolver = new TagResolver[]{resolver}; + if (placeholder.length > 0) { + var tags = Arrays.copyOf(placeholder, placeholder.length + 1); + tags[tags.length - 1] = resolver; + finalResolver = tags; + } + return resolveTags(message, finalResolver); + } + + private Component resolveTags(String message, TagResolver... resolver) { + var component = miniMessage.deserialize(message, resolver); + var newMessage = miniMessage.serialize(component); + if (newMessage.equals(message)) { + return component; + } + return resolveTags(newMessage, resolver); + + } + + public Component prefix() { + return prefix; + } + + protected Component applyPrefix(Component component) { + return prefix.appendSpace().append(component); + } + + public String translatePlain(String message, TagResolver... replacements) { + return PlainTextComponentSerializer.plainText().serialize(serialize(message, messageTagResolver, replacements)); + } + + public Component serializeMessage(String message, TagResolver... placeholder) { + return serialize(message, messageTagResolver, placeholder); + } + + public Component serializeError(String message, TagResolver... placeholder) { + return serialize(message, errorTagResolver, placeholder); + } + + public MiniMessage miniMessage() { + return miniMessage; + } + + public boolean isAnonymous() { + return ownerPlugin == null; + } + + protected TagResolver messageTagResolver() { + return messageTagResolver; + } + + protected TagResolver errorTagResolver() { + return errorTagResolver; + } + + protected Plugin plugin() { + return plugin; + } +} diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSenderBuilder.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSenderBuilder.java new file mode 100644 index 00000000..648c1596 --- /dev/null +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/MessageSenderBuilder.java @@ -0,0 +1,158 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.messages; + +import de.eldoria.eldoutilities.localization.ILocalizer; +import de.eldoria.eldoutilities.messages.impl.PaperMessageSender; +import de.eldoria.eldoutilities.messages.impl.SpigotMessageSender; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.NamedTextColor; +import net.kyori.adventure.text.format.TextColor; +import net.kyori.adventure.text.minimessage.Context; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.Tag; +import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.text.minimessage.tag.standard.StandardTags; +import org.bukkit.plugin.Plugin; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.function.Consumer; +import java.util.function.UnaryOperator; + +public class MessageSenderBuilder { + private final MiniMessage.Builder miniMessage = MiniMessage.builder(); + private final TagResolver.Builder messageTagResolver = TagResolver.builder() + .tag("default", Tag.styling(NamedTextColor.GREEN)); + private final TagResolver.Builder errorTagResolver = TagResolver.builder() + .tag("default", Tag.styling(NamedTextColor.RED)); + private final TagResolver.Builder defaultTagResolver = TagResolver.builder(); + + @Nullable + private final Plugin plugin; + private Component prefix = Component.empty(); + private ILocalizer localizer = ILocalizer.DEFAULT; + private UnaryOperator preProcessor = s -> s; + + public MessageSenderBuilder(@Nullable Plugin plugin) { + this.plugin = plugin; + } + + /** + * The localizer used to serialize messages via the {@code } tag + * + * @param localizer localizer instance + * @return builder instance + */ + public MessageSenderBuilder localizer(ILocalizer localizer) { + this.localizer = localizer; + return this; + } + + public MessageSenderBuilder prefix(Component prefix) { + this.prefix = prefix; + defaultTagResolver.tag("prefix", Tag.selfClosingInserting(this.prefix)); + return this; + } + + public MessageSenderBuilder prefix(String prefix) { + return prefix(MiniMessage.miniMessage() + .deserialize(prefix)); + } + + public MessageSenderBuilder messageColor(TextColor color) { + messageTagResolver.tag("default", Tag.styling(color)); + return this; + } + + public MessageSenderBuilder errorColor(TextColor color) { + errorTagResolver.tag("default", Tag.styling(color)); + return this; + } + + public MessageSenderBuilder addTag(Consumer consumer) { + consumer.accept(defaultTagResolver); + return this; + } + + public MessageSenderBuilder addMessageTag(Consumer consumer) { + consumer.accept(messageTagResolver); + return this; + } + + public MessageSenderBuilder addErrorTag(Consumer consumer) { + consumer.accept(errorTagResolver); + return this; + } + + public MiniMessage.@NotNull Builder strict(boolean strict) { + return miniMessage.strict(strict); + } + + public MiniMessage.@NotNull Builder debug(@Nullable Consumer debugOutput) { + return miniMessage.debug(debugOutput); + } + + public MiniMessage.@NotNull Builder postProcessor(@NotNull UnaryOperator postProcessor) { + return miniMessage.postProcessor(postProcessor); + } + + public MessageSenderBuilder preProcessor(@NotNull UnaryOperator preProcessor) { + this.preProcessor = preProcessor; + return this; + } + + /** + * Builds and registers the message sender for the provided plugin + * + * @return registered message sender + */ + public MessageSender register() { + addL18nTag(); + var defaultResolver = defaultTagResolver + .resolver(StandardTags.defaults()) + .build(); + var legacy = false; + try { + Class.forName(BukkitAudiences.class.getName()); + } catch (ClassNotFoundException e) { + legacy = true; + } + MessageSender messageSender; + if (legacy) { + messageSender = new SpigotMessageSender(plugin, + miniMessage.tags(defaultResolver) + .preProcessor(in -> preProcessor.apply(localizer.localize(in))) + .build(), + TagResolver.resolver(defaultResolver, messageTagResolver.build()), + TagResolver.resolver(defaultResolver, errorTagResolver.build()), + prefix); + } else { + messageSender = new SpigotMessageSender(plugin, + miniMessage.tags(defaultResolver) + .preProcessor(in -> preProcessor.apply(localizer.localize(in))) + .build(), + TagResolver.resolver(defaultResolver, messageTagResolver.build()), + TagResolver.resolver(defaultResolver, errorTagResolver.build()), + prefix); + } + MessageSender.register(messageSender); + return messageSender; + } + + private void addL18nTag() { + if (localizer != ILocalizer.DEFAULT) { + defaultTagResolver.tag("l18n", this::localizeTag); + } + } + + private Tag localizeTag(ArgumentQueue args, Context ctx) { + return Tag.selfClosingInserting(ctx.deserialize(localizer.localize(args.popOr("locale tag required").value()))); + } +} diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/Replacement.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/Replacement.java new file mode 100644 index 00000000..fe557ea2 --- /dev/null +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/Replacement.java @@ -0,0 +1,88 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.messages; + +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.format.Style; +import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import org.bukkit.World; +import org.bukkit.entity.Player; + +import java.util.Locale; + +/** + * A replacement represents a text placeholder and its replacement. + */ +public final class Replacement { + private Replacement() { + throw new UnsupportedOperationException("This is a utility class."); + } + + /** + * Creates a new replacement. + * + * @param key key of replacement + * @param value value for replacement + * @return replacement with registered replacement + */ + public static TagResolver create(String key, String value) { + return Placeholder.parsed(sanatizeKey(key), value); + } + + /** + * Creates a new replacement. + * + * @param key key of replacement + * @param value value for replacement + * @return replacement with registered replacement + */ + public static TagResolver create(String key, Object value) { + return Placeholder.parsed(sanatizeKey(key), String.valueOf(value)); + } + + public static TagResolver create(String key, Double value) { + return create(key, String.format("%.2f", value)); + } + + /** + * Creates a new replacement. + * + * @param key key of replacement + * @param anEnum value which provides a string via {@link Enum#name()} + * @return replacement with registered replacement + */ + public static TagResolver create(String key, Enum anEnum) { + return create(key, anEnum.name()); + } + + /** + * Creates a new replacement for a player. + * + * @param key key of replacement + * @param player value which provides the name of the player + * @return replacement with registered replacement + */ + public static TagResolver create(String key, Player player) { + return create(key, player.getName()); + } + + /** + * Creates a new replacement for a player. + * + * @param key key of replacement + * @param world world which provides the name of the world + * @return replacement with registered replacement + */ + public static TagResolver create(String key, World world) { + return create(key, world.getName()); + } + + private static String sanatizeKey(String key){ + return key.toLowerCase(Locale.ROOT).replaceAll(" ", "_"); + } +} diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/PaperMessageSender.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/PaperMessageSender.java new file mode 100644 index 00000000..00bae959 --- /dev/null +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/PaperMessageSender.java @@ -0,0 +1,78 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.messages.impl; + +import de.eldoria.eldoutilities.messages.MessageSender; +import net.kyori.adventure.audience.Audiences; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.title.Title; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.util.Set; + +public final class PaperMessageSender extends MessageSender { + public PaperMessageSender(Plugin plugin, MiniMessage miniMessage, TagResolver messageTagResolver, TagResolver errorTagResolver, Component prefix) { + super(plugin, miniMessage, messageTagResolver, errorTagResolver, prefix); + } + + public void sendMessage(CommandSender sender, Component component) { + sender.sendActionBar(applyPrefix(component)); + } + + public void broadcast(String message) { + plugin().getServer().broadcast(serialize(message, messageTagResolver())); + } + + /** + * Send a title to a player + * + * @param player player to send + * @param title title to send + */ + public void sendTitle(Player player, Title title) { + player.showTitle(title); + } + + /** + * Send a localized action bar to a player + * + * @param player player to send + * @param message message to send + */ + public void sendActionBar(Player player, String message, TagResolver... placeholder) { + player.sendActionBar(serialize(message, messageTagResolver(), placeholder)); + } + + /** + * Send a localized action bar to a player + * + * @param player player to send + * @param message message to send + */ + public void sendErrorActionBar(Player player, String message, TagResolver... placeholder) { + player.sendActionBar(serialize(message, errorTagResolver(), placeholder)); + } + + public void sendBossBar(Player player, BossBar bossBar) { + player.showBossBar(bossBar); + } + + public BossBar sendBossBar(Player player, String message, float progress, BossBar.Color color, BossBar.Overlay overlay, Set flags) { + var bossBar = BossBar.bossBar(serialize(message, messageTagResolver()), progress, color, overlay, flags); + player.showBossBar(bossBar); + return bossBar; + } + + public void hideBossBar(Player player, BossBar bossBar) { + player.hideBossBar(bossBar); + } +} diff --git a/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/SpigotMessageSender.java b/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/SpigotMessageSender.java new file mode 100644 index 00000000..e58a6731 --- /dev/null +++ b/messaging/src/main/java/de/eldoria/eldoutilities/messages/impl/SpigotMessageSender.java @@ -0,0 +1,81 @@ +/* + * SPDX-License-Identifier: AGPL-3.0-only + * + * Copyright (C) EldoriaRPG Team and Contributor + */ + +package de.eldoria.eldoutilities.messages.impl; + +import de.eldoria.eldoutilities.messages.MessageSender; +import net.kyori.adventure.bossbar.BossBar; +import net.kyori.adventure.platform.bukkit.BukkitAudiences; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; +import net.kyori.adventure.title.Title; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; +import org.bukkit.plugin.Plugin; + +import java.util.Set; + +public final class SpigotMessageSender extends MessageSender { + BukkitAudiences audiences; + public SpigotMessageSender(Plugin plugin, MiniMessage miniMessage, TagResolver messageTagResolver, TagResolver errorTagResolver, Component prefix) { + super(plugin, miniMessage, messageTagResolver, errorTagResolver, prefix); + audiences = BukkitAudiences.create(plugin); + } + + public void sendMessage(CommandSender sender, Component component) { + audiences.sender(sender).sendMessage(applyPrefix(component)); + } + + public void broadcast(String message) { + audiences.all().sendMessage(serialize(message, messageTagResolver())); + } + + /** + * Send a title to a player + * + * @param player player to send + * @param title title to send + */ + public void sendTitle(Player player, Title title) { + audiences.player(player).showTitle(title); + } + + /** + * Send a localized action bar to a player + * + * @param player player to send + * @param message message to send + */ + public void sendActionBar(Player player, String message, TagResolver... placeholder) { + audiences.player(player).sendActionBar(serialize(message, messageTagResolver(), placeholder)); + } + + /** + * Send a localized action bar to a player + * + * @param player player to send + * @param message message to send + */ + public void sendErrorActionBar(Player player, String message, TagResolver... placeholder) { + audiences.player(player).sendActionBar(serialize(message, errorTagResolver(), placeholder)); + } + + public void sendBossBar(Player player, BossBar bossBar) { + audiences.player(player).showBossBar(bossBar); + } + + public BossBar sendBossBar(Player player, String message, float progress, BossBar.Color color, BossBar.Overlay overlay, Set flags) { + var bossBar = BossBar.bossBar(serialize(message, messageTagResolver()), progress, color, overlay, flags); + audiences.player(player).showBossBar(bossBar); + return bossBar; + } + + public void hideBossBar(Player player, BossBar bossBar) { + audiences.player(player).hideBossBar(bossBar); + } + +} diff --git a/metrics/build.gradle.kts b/metrics/build.gradle.kts new file mode 100644 index 00000000..ad9510e8 --- /dev/null +++ b/metrics/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies { + api("org.bstats", "bstats-bukkit", "3.0.2") +} diff --git a/src/main/java/de/eldoria/eldoutilities/bstats/EldoMetrics.java b/metrics/src/main/java/de/eldoria/eldoutilities/metrics/EldoMetrics.java similarity index 96% rename from src/main/java/de/eldoria/eldoutilities/bstats/EldoMetrics.java rename to metrics/src/main/java/de/eldoria/eldoutilities/metrics/EldoMetrics.java index 0885a444..8233081b 100644 --- a/src/main/java/de/eldoria/eldoutilities/bstats/EldoMetrics.java +++ b/metrics/src/main/java/de/eldoria/eldoutilities/metrics/EldoMetrics.java @@ -4,7 +4,7 @@ * Copyright (C) EldoriaRPG Team and Contributor */ -package de.eldoria.eldoutilities.bstats; +package de.eldoria.eldoutilities.metrics; import org.bstats.bukkit.Metrics; import org.bukkit.configuration.file.YamlConfiguration; diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts new file mode 100644 index 00000000..0dde0268 --- /dev/null +++ b/plugin/build.gradle.kts @@ -0,0 +1,6 @@ +dependencies { + api(project(":commands")) + api(project(":core")) + api(project(":debugging")) + api(project(":configuration")) +} diff --git a/src/main/java/de/eldoria/eldoutilities/logging/DebugLogger.java b/plugin/src/main/java/de/eldoria/eldoutilities/logging/DebugLogger.java similarity index 90% rename from src/main/java/de/eldoria/eldoutilities/logging/DebugLogger.java rename to plugin/src/main/java/de/eldoria/eldoutilities/logging/DebugLogger.java index 25cb26a8..1025c1b2 100644 --- a/src/main/java/de/eldoria/eldoutilities/logging/DebugLogger.java +++ b/plugin/src/main/java/de/eldoria/eldoutilities/logging/DebugLogger.java @@ -26,10 +26,10 @@ public class DebugLogger extends Logger { private final Logger logger; public DebugLogger(EldoPlugin plugin, Logger logger) { - // we still want to use our debugger. so we dont really care about what we are doing here. + // we still want to use our debugger. so we don't really care about what we are doing here. super(plugin.getName(), null); this.logger = logger; - setLevel(EldoConfig.getLogLevel(plugin)); + setLevel(plugin.getLogLevel()); log(getLevel(), "Debug logger initialized. Log Level: " + getLevel().getName()); } @@ -37,12 +37,12 @@ public DebugLogger(EldoPlugin plugin, Logger logger) { public void log(LogRecord record) { var level = record.getLevel().intValue(); // check if the level is lover than info. - // if thats the case we need to change it. + // if that's the case we need to change it. if (level < 800) { // check if we really want to log this level if (getLevel().intValue() > level) return; // We need to set the level to info to log this shit. Thanks spigot. - // Lets append another color to differ between them. + // Let's append another color to differ between them. // They will all be displayed as info anyway... record.setLevel(Level.INFO); if (level == Level.CONFIG.intValue()) { diff --git a/src/main/java/de/eldoria/eldoutilities/plugin/EldoPlugin.java b/plugin/src/main/java/de/eldoria/eldoutilities/plugin/EldoPlugin.java similarity index 95% rename from src/main/java/de/eldoria/eldoutilities/plugin/EldoPlugin.java rename to plugin/src/main/java/de/eldoria/eldoutilities/plugin/EldoPlugin.java index 5ea185f8..ed455720 100644 --- a/src/main/java/de/eldoria/eldoutilities/plugin/EldoPlugin.java +++ b/plugin/src/main/java/de/eldoria/eldoutilities/plugin/EldoPlugin.java @@ -6,14 +6,15 @@ package de.eldoria.eldoutilities.plugin; +import de.eldoria.EldoUtilities; import de.eldoria.eldoutilities.commands.command.AdvancedCommand; import de.eldoria.eldoutilities.commands.command.AdvancedCommandAdapter; import de.eldoria.eldoutilities.commands.defaultcommands.FailsaveCommand; import de.eldoria.eldoutilities.configuration.EldoConfig; -import de.eldoria.eldoutilities.core.EldoUtilities; import de.eldoria.eldoutilities.debug.DebugDataProvider; import de.eldoria.eldoutilities.debug.data.EntryData; import de.eldoria.eldoutilities.logging.DebugLogger; +import de.eldoria.eldoutilities.serialization.util.PluginSerializationName; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.command.TabExecutor; @@ -40,6 +41,7 @@ import java.time.temporal.ChronoUnit; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.logging.Level; import java.util.logging.Logger; @@ -70,9 +72,17 @@ private static void registerSelf(EldoPlugin eldoPlugin) { if (instance == null) { instance = eldoPlugin; } + for (var clazz : eldoPlugin.getConfigSerialization()) { - ConfigurationSerialization.registerClass(clazz); + if (clazz.isAnnotationPresent(PluginSerializationName.class)) { + var annotation = clazz.getAnnotation(PluginSerializationName.class); + ConfigurationSerialization.registerClass(clazz, + annotation.value().replace("{plugin}", eldoPlugin.getName().toLowerCase(Locale.ROOT))); + } else { + ConfigurationSerialization.registerClass(clazz); + } } + EldoUtilities.preWarm(eldoPlugin); eldoPlugin.failcmd = AdvancedCommandAdapter.wrap(eldoPlugin, new FailsaveCommand(eldoPlugin, eldoPlugin.getDescription().getFullName().toLowerCase())); } @@ -96,9 +106,11 @@ public Logger getLogger() { } protected final void setLoggerLevel() { - getLogger().setLevel(EldoConfig.getLogLevel(this)); + getLogger().setLevel(getLogLevel()); } + public abstract Level getLogLevel(); + /** * Register a tabexecutor for a command. *

diff --git a/readme.md b/readme.md index cbb11328..9a421be9 100755 --- a/readme.md +++ b/readme.md @@ -1,21 +1,25 @@ ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/eldoriarpg/eldo-util/publish_to_nexus.yml?style=for-the-badge&label=Publishing&branch=master) ![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/eldoriarpg/eldo-util/verify.yml?style=for-the-badge&label=Building&branch=master) -![Sonatype Nexus (Releases)](https://img.shields.io/nexus/maven-releases/de.eldoria/eldo-util?label=Release&logo=Release&server=https%3A%2F%2Feldonexus.de&style=for-the-badge) -![Sonatype Nexus (Development)](https://img.shields.io/nexus/maven-dev/de.eldoria/eldo-util?label=DEV&logo=Release&server=https%3A%2F%2Feldonexus.de&style=for-the-badge) -![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/de.eldoria/eldo-util?color=orange&label=Snapshot&server=https%3A%2F%2Feldonexus.de&style=for-the-badge) +![Sonatype Nexus (Releases)](https://img.shields.io/nexus/maven-releases/de.eldoria.util/eldo-util?label=Release&logo=Release&server=https%3A%2F%2Feldonexus.de&style=for-the-badge) +![Sonatype Nexus (Development)](https://img.shields.io/nexus/maven-dev/de.eldoria.util/eldo-util?label=DEV&logo=Release&server=https%3A%2F%2Feldonexus.de&style=for-the-badge) +![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/de.eldoria.util/eldo-util?color=orange&label=Snapshot&server=https%3A%2F%2Feldonexus.de&style=for-the-badge) + # Dependency + Gradle + ``` kotlin repositories { maven("https://eldonexus.de/repository/maven-public") } dependencies { - implementation("de.eldoria", "eldo-util", "version") + implementation("de.eldoria.util", "eldo-util", "version") } ``` Maven + ``` xml EldoNexus @@ -23,7 +27,7 @@ Maven - de.eldoria + de.eldoria.util eldo-util version diff --git a/renovate.json b/renovate.json index 130e3a70..811b821d 100644 --- a/renovate.json +++ b/renovate.json @@ -1,10 +1,4 @@ { - "baseBranches": ["develop"], - "dependencyDashboard": true, - "labels": ["dependencies"], - "extends": ["config:base"], - "ignoreDeps": ["spigot-api"], - "reviewers": ["RainbowDashLabs"], - "prConcurrentLimit": 3, - "prHourlyLimit": 10 + "baseBranches": ["develop"], "dependencyDashboard": true, "labels": ["dependencies"], "extends": ["config:base"], + "ignoreDeps": ["spigot-api"], "reviewers": ["RainbowDashLabs"], "prConcurrentLimit": 3, "prHourlyLimit": 10 } diff --git a/settings.gradle.kts b/settings.gradle.kts index a6ffa729..ecb95322 100755 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,13 +1,29 @@ rootProject.name = "eldo-util" -pluginManagement{ - repositories{ +pluginManagement { + repositories { mavenLocal() gradlePluginPortal() - maven{ + maven { name = "EldoNexus" url = uri("https://eldonexus.de/repository/maven-public/") } } } +include("core") +include("messaging") +include("plugin") +include("debugging") +include("updater") +include("legacy-serialization") +include("commands") +include("localization") +include("threading") +include("entities") +include("inventory") +include("crossversion") +include("configuration") +include("metrics") +include("items") +include("jackson-configuration") diff --git a/src/main/java/de/eldoria/eldoutilities/C.java b/src/main/java/de/eldoria/eldoutilities/C.java deleted file mode 100644 index ee0e5f2e..00000000 --- a/src/main/java/de/eldoria/eldoutilities/C.java +++ /dev/null @@ -1,14 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities; - -public final class C { - public static final String SPACE_REPLACE = ":"; - - private C() { - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/conversation/ConversationRequester.java b/src/main/java/de/eldoria/eldoutilities/conversation/ConversationRequester.java deleted file mode 100644 index 500d2fbb..00000000 --- a/src/main/java/de/eldoria/eldoutilities/conversation/ConversationRequester.java +++ /dev/null @@ -1,123 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.conversation; - -import de.eldoria.eldoutilities.core.EldoUtilities; -import de.eldoria.eldoutilities.messages.MessageType; -import org.bukkit.Bukkit; -import org.bukkit.conversations.Conversation; -import org.bukkit.conversations.ConversationAbandonedEvent; -import org.bukkit.conversations.ConversationAbandonedListener; -import org.bukkit.conversations.ConversationCanceller; -import org.bukkit.conversations.ConversationContext; -import org.bukkit.conversations.Prompt; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; -import java.util.function.Consumer; -import java.util.function.Predicate; - -/** - * Class to handle Conversations. - */ -public class ConversationRequester implements ConversationAbandonedListener, ConversationCanceller { - - private final Plugin plugin; - private final Map sessions = new HashMap<>(); - - private ConversationRequester(Plugin plugin) { - this.plugin = plugin; - } - - public static ConversationRequester start(Plugin plugin) { - return new ConversationRequester(plugin); - } - - private static Prompt getSimplePromt(String text, Predicate validation, Consumer callback) { - return new Prompt() { - @Override - public @NotNull String getPromptText(@NotNull ConversationContext context) { - return text; - } - - @Override - public boolean blocksForInput(@NotNull ConversationContext context) { - return true; - } - - @Override - public @Nullable Prompt acceptInput(@NotNull ConversationContext context, @Nullable String input) { - if (validation.test(input)) { - Bukkit.getScheduler().runTask(context.getPlugin(), () -> callback.accept(input)); - return null; - } - return this; - } - }; - } - - public void requestInput(Player player, String text, Predicate validation, int timeout, Consumer callback) { - Map data = new HashMap<>(); - var sessionId = System.currentTimeMillis(); - data.put("id", sessionId); - sessions.put(player, sessionId); - var conversation = EldoConversation.builder(plugin, player, - getSimplePromt(text, validation, callback)) - .ofType(MessageType.NORMAL) - .withInitalValues(data) - .build(); - player.beginConversation(conversation); - - conversation.addConversationCanceller(this); - conversation.addConversationAbandonedListener(this); - - if (timeout > 0) { - Bukkit.getScheduler().runTaskLater(plugin, () -> { - if (sessions.containsKey(player)) { - if (sessions.get(player) == sessionId) { - conversation.abandon(new ConversationAbandonedEvent(conversation, this)); - } - } - }, timeout); - } - } - - @Override - public void conversationAbandoned(@NotNull ConversationAbandonedEvent abandonedEvent) { - var id = abandonedEvent.getContext().getSessionData("id"); - if (id != null) { - var aLong = sessions.get(abandonedEvent.getContext().getForWhom()); - if (aLong != null && aLong.equals(id)) { - sessions.remove(abandonedEvent.getContext().getForWhom()); - } - } - } - - @Override - public void setConversation(@NotNull Conversation conversation) { - // we are the canceller and will use ourself. Nothing to do here. - } - - @Override - public boolean cancelBasedOnInput(@NotNull ConversationContext context, @NotNull String input) { - if ("cancel".equalsIgnoreCase(input)) { - if (context.getForWhom() instanceof Player) { - return sessions.containsKey(context.getForWhom()); - } - } - return false; - } - - @Override - public ConversationRequester clone() { - return this; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/conversation/EldoConversation.java b/src/main/java/de/eldoria/eldoutilities/conversation/EldoConversation.java deleted file mode 100644 index ce29c8b0..00000000 --- a/src/main/java/de/eldoria/eldoutilities/conversation/EldoConversation.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.conversation; - -import de.eldoria.eldoutilities.localization.ILocalizer; -import de.eldoria.eldoutilities.messages.MessageSender; -import de.eldoria.eldoutilities.messages.MessageType; -import org.bukkit.conversations.Conversable; -import org.bukkit.conversations.Conversation; -import org.bukkit.conversations.ConversationAbandonedEvent; -import org.bukkit.conversations.ConversationCanceller; -import org.bukkit.conversations.Prompt; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; - -/** - * Wrapper for {@link Conversation} - */ -public class EldoConversation extends Conversation { - private final ILocalizer localizer; - private final MessageSender sender; - private final MessageType messageType; - private final String userPrefix; - private final String pluginPrefix; - - public EldoConversation(@Nullable Plugin plugin, @NotNull Conversable forWhom, @Nullable Prompt firstPrompt, - @NotNull Map initialSessionData, String pluginPrefix, String userPrefix, MessageType messageType) { - super(plugin, forWhom, firstPrompt, initialSessionData); - this.messageType = messageType; - localizer = ILocalizer.getPluginLocalizer(plugin); - sender = MessageSender.getPluginMessageSender(plugin); - this.pluginPrefix = pluginPrefix == null ? sender.getPrefix() : pluginPrefix; - this.userPrefix = userPrefix == null ? "" : userPrefix; - } - - public static Builder builder(Plugin plugin, Conversable forWhom, Prompt firstPrompt) { - return new Builder(plugin, forWhom, firstPrompt); - } - - /** - * Adds a {@link ConversationCanceller} to the cancellers collection. - * - * @param canceller The {@link ConversationCanceller} to add. - */ - void addConversationCanceller(@NotNull ConversationCanceller canceller) { - canceller.setConversation(this); - this.cancellers.add(canceller); - } - - /** - * Passes player input into the current prompt. The next prompt (as - * determined by the current prompt) is then displayed to the user. - * - * @param input The user's chat text. - */ - @Override - public void acceptInput(@NotNull String input) { - if (currentPrompt != null) { - - // Echo the user's input - if (localEchoEnabled) { - context.getForWhom().sendRawMessage(userPrefix + input); - } - - // Test for conversation abandonment based on input - for (var canceller : cancellers) { - if (canceller.cancelBasedOnInput(context, input)) { - abandon(new ConversationAbandonedEvent(this, canceller)); - return; - } - } - - // Not abandoned, output the next prompt - currentPrompt = currentPrompt.acceptInput(context, input); - outputNextPrompt(); - } - } - - /** - * Displays the next user prompt and abandons the conversation if the next - * prompt is null. - */ - @Override - public void outputNextPrompt() { - if (currentPrompt == null) { - abandon(new ConversationAbandonedEvent(this)); - } else { - var promptText = currentPrompt.getPromptText(context); - promptText = localizer.localize(promptText); - promptText = messageType.forceColor(promptText); - context.getForWhom().sendRawMessage(pluginPrefix + promptText); - if (!currentPrompt.blocksForInput(context)) { - currentPrompt = currentPrompt.acceptInput(context, null); - outputNextPrompt(); - } - } - } - - /** - * Builder for a {@link EldoConversation} - */ - public static class Builder { - private final Plugin plugin; - private final Conversable forWhom; - private final Prompt firstPrompt; - private Map initialValues = new HashMap<>(); - private String pluginPrefix; - private String userPrefix = ""; - private MessageType type = MessageType.BLANK; - - public Builder(Plugin plugin, Conversable forWhom, Prompt firstPrompt) { - this.plugin = plugin; - this.forWhom = forWhom; - this.firstPrompt = firstPrompt; - } - - public Builder withDefaultPluginPrefix() { - this.pluginPrefix = null; - return this; - } - - public Builder withPluginPrefix(String pluginPrefix) { - this.pluginPrefix = pluginPrefix; - return this; - } - - public Builder withDefaultUserPrefix() { - this.userPrefix = ""; - return this; - } - - public Builder withUserPrefix(String userPrefix) { - this.userPrefix = userPrefix; - return this; - } - - public Builder ofType(MessageType type) { - this.type = type; - return this; - } - - public Builder withInitalValues(Map initalValues) { - this.initialValues = initalValues; - return this; - } - - public Builder addIniitialValue(Object key, Object value) { - this.initialValues.put(key, value); - return this; - } - - public EldoConversation build() { - return new EldoConversation(plugin, forWhom, firstPrompt, initialValues, pluginPrefix, userPrefix, type); - } - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/core/EldoUtilities.java b/src/main/java/de/eldoria/eldoutilities/core/EldoUtilities.java deleted file mode 100644 index 763535fa..00000000 --- a/src/main/java/de/eldoria/eldoutilities/core/EldoUtilities.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.core; - -import de.eldoria.eldoutilities.configuration.ConfigFileWrapper; -import de.eldoria.eldoutilities.conversation.ConversationRequester; -import de.eldoria.eldoutilities.crossversion.ServerVersion; -import de.eldoria.eldoutilities.crossversion.builder.VersionFunctionBuilder; -import de.eldoria.eldoutilities.inventory.InventoryActionHandler; -import de.eldoria.eldoutilities.messages.MessageChannel; -import de.eldoria.eldoutilities.plugin.EldoPlugin; -import de.eldoria.eldoutilities.scheduling.DelayedActions; -import de.eldoria.eldoutilities.serialization.util.PluginSerializationName; -import de.eldoria.eldoutilities.serialization.wrapper.ArmorStandWrapper; -import de.eldoria.eldoutilities.serialization.wrapper.MapEntry; -import de.eldoria.eldoutilities.threading.AsyncSyncingCallbackExecutor; -import org.bukkit.Bukkit; -import org.bukkit.NamespacedKey; -import org.bukkit.boss.KeyedBossBar; -import org.bukkit.configuration.serialization.ConfigurationSerializable; -import org.bukkit.configuration.serialization.ConfigurationSerialization; -import org.bukkit.plugin.Plugin; - -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.Arrays; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Locale; -import java.util.Map; -import java.util.logging.Logger; - -/** - * Core class of EldoUtilitites. - *

- * If you want to use anything from here you need to call {@link EldoUtilities#preWarm(Plugin)} onLoad and {@link EldoUtilities#ignite(Plugin)} onEnable. - * If your plugins extends {@link EldoPlugin} this will be done automatically. - */ -public final class EldoUtilities { - private static Plugin mainOwner; - private static Map, Plugin> instanceOwners = new LinkedHashMap<>(); - private static ConfigFileWrapper configuration; - - private EldoUtilities() { - } - - public static Logger logger() { - return Bukkit.getLogger(); - } - - public static void preWarm(Plugin eldoPlugin) { - instanceOwners.put(eldoPlugin.getClass(), eldoPlugin); - for (var clazz : getConfigSerialization()) { - if (clazz.isAnnotationPresent(PluginSerializationName.class)) { - var annotation = clazz.getAnnotation(PluginSerializationName.class); - ConfigurationSerialization.registerClass(clazz, - annotation.value().replace("{plugin}", eldoPlugin.getName().toLowerCase(Locale.ROOT))); - } else { - ConfigurationSerialization.registerClass(clazz); - } - } - } - - public static void ignite(Plugin plugin) { - VersionFunctionBuilder.functionBuilder(null, null) - .addVersionFunctionBetween(ServerVersion.MC_1_13, ServerVersion.MC_1_17, - a -> { - Bukkit.getScheduler().runTaskLater(plugin, () -> performLateCleanUp(plugin), 5); - return null; - }); - var path = plugin.getDataFolder().toPath().toAbsolutePath().getParent().resolve(Paths.get("EldoUtilities", "config.yml")); - configuration = ConfigFileWrapper.forFile(plugin, path); - } - - private static void performLateCleanUp(Plugin plugin) { - var bossBars = Bukkit.getBossBars(); - while (bossBars.hasNext()) { - var bar = bossBars.next(); - var key = bar.getKey(); - if (!key.getNamespace().equalsIgnoreCase(plugin.getName())) continue; - if (key.getKey().startsWith(MessageChannel.KEY_PREFIX)) { - logger().config("Removed boss bar with key" + key); - bar.removeAll(); - Bukkit.removeBossBar(key); - } - } - } - - public static void shutdown() { - } - - public static List> getConfigSerialization() { - return Arrays.asList(MapEntry.class, ArmorStandWrapper.class, - de.eldoria.eldoutilities.serialization.util.MapEntry.class, - de.eldoria.eldoutilities.serialization.util.ArmorStandWrapper.class); - } - - public static ConfigFileWrapper getConfiguration() { - if (configuration == null) { - var config = Bukkit.getUpdateFolderFile().toPath().toAbsolutePath().getParent().resolve(Paths.get("EldoUtilities", "config.yml")); - configuration = ConfigFileWrapper.forFile(config); - } - return configuration; - } - - public static Plugin getInstanceOwner(Class plugin) { - return instanceOwners.get(plugin); - } - - public static void forceInstanceOwner(Plugin plugin) { - if (mainOwner != null) { - throw new IllegalStateException("A instance owner is already set"); - } - mainOwner = plugin; - } - - public static Plugin getInstanceOwner() { - if (mainOwner != null) { - return mainOwner; - } - - for (var entry : instanceOwners.entrySet()) { - return entry.getValue(); - } - - throw new IllegalStateException("No instance owner is set but requested"); - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/core/commands/EldoDebug.java b/src/main/java/de/eldoria/eldoutilities/core/commands/EldoDebug.java deleted file mode 100644 index eee8ee61..00000000 --- a/src/main/java/de/eldoria/eldoutilities/core/commands/EldoDebug.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.core.commands; - -import de.eldoria.eldoutilities.debug.DebugSettings; -import de.eldoria.eldoutilities.debug.DebugUtil; -import de.eldoria.eldoutilities.messages.MessageChannel; -import de.eldoria.eldoutilities.messages.MessageType; -import de.eldoria.eldoutilities.simplecommands.EldoCommand; -import de.eldoria.eldoutilities.simplecommands.TabCompleteUtil; -import org.bukkit.Bukkit; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -/** - * Default command for plugin debugging. - */ -public class EldoDebug extends EldoCommand { - - private List plugins; - - public EldoDebug(Plugin plugin) { - super(plugin); - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (denyAccess(sender, "de.eldoria.eldoutilitites.debug")) { - return true; - } - - if (argumentsInvalid(sender, args, 1, "")) { - return true; - } - - @NotNull Plugin[] plugins = Bukkit.getPluginManager().getPlugins(); - Plugin plugin = null; - for (var pl : plugins) { - if (pl.getName().equalsIgnoreCase(args[0])) { - plugin = pl; - break; - } - } - - if (plugin == null) { - messageSender().send(MessageChannel.CHAT, MessageType.ERROR, sender, "Invalid plugin"); - return true; - } - - DebugUtil.dispatchDebug(sender, plugin, DebugSettings.DEFAULT); - return true; - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - if (args.length == 1) { - return TabCompleteUtil.complete(args[0], getPlugins()); - } - return Collections.emptyList(); - } - - private List getPlugins() { - if (plugins == null) { - plugins = Arrays.stream(Bukkit.getPluginManager().getPlugins()).map(Plugin::getName).collect(Collectors.toList()); - } - return Collections.unmodifiableList(plugins); - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/ServerVersion.java b/src/main/java/de/eldoria/eldoutilities/crossversion/ServerVersion.java deleted file mode 100644 index d0796abf..00000000 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/ServerVersion.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.crossversion; - -import de.eldoria.eldoutilities.container.Triple; -import org.bukkit.Bukkit; - -import java.util.Arrays; -import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Enum to determine and work with multiple versions. - * - * @since 1.0.0 - */ -public enum ServerVersion { - MC_UNKOWN(Triple.of(0, 0, 0)), - MC_1_0(Triple.of(1, 0, 0)), - MC_1_1(Triple.of(1, 1, 0)), - MC_1_2(Triple.of(1, 2, 0)), - MC_1_3(Triple.of(1, 3, 0)), - MC_1_4(Triple.of(1, 4, 0)), - MC_1_5(Triple.of(1, 5, 0)), - MC_1_6(Triple.of(1, 6, 0)), - MC_1_7(Triple.of(1, 7, 0)), - MC_1_8(Triple.of(1, 8, 0)), - MC_1_9(Triple.of(1, 9, 0)), - MC_1_10(Triple.of(1, 10, 0)), - MC_1_11(Triple.of(1, 11, 0)), - MC_1_12(Triple.of(1, 12, 0)), - MC_1_13(Triple.of(1, 13, 0)), - MC_1_14(Triple.of(1, 14, 0)), - MC_1_15(Triple.of(1, 15, 0)), - MC_1_16(Triple.of(1, 16, 0)), - MC_1_17(Triple.of(1, 17, 0)), - MC_1_18(Triple.of(1, 18, 0)), - MC_1_19(Triple.of(1, 19, 0)), - MC_1_20(Triple.of(1, 20, 0)); - - /** - * Contains the current version of the server. - */ - public static final ServerVersion CURRENT_VERSION; - private static final Pattern VERSION_PATTERN; - - static { - VERSION_PATTERN = Pattern.compile("^([0-9]{1,3})\\.([0-9]{1,3})(?:\\.([0-9]{1,3}))?"); - CURRENT_VERSION = Bukkit.getServer() != null ? getVersion() : MC_UNKOWN; - } - - private final Triple version; - - ServerVersion(Triple version) { - this.version = version; - } - - /** - * Get the version of the server. - * - * @return version of server - */ - public static ServerVersion getVersion() { - var version = extractVersion(); - - if (!version.isPresent()) { - return MC_UNKOWN; - } - - for (var value : values()) { - if (value.version.first.equals(version.get().first)) { - if (value.version.second.equals(version.get().second)) { - return value; - } - } - } - - Bukkit.getLogger().warning("Could not determine server Version."); - - return MC_UNKOWN; - } - - /** - * Extract the version of the server. - * - * @return optional version of server if the version could be determined - */ - public static Optional> extractVersion() { - var matcher = VERSION_PATTERN.matcher(Bukkit.getServer().getBukkitVersion()); - - if (matcher.find()) { - var major = Integer.parseInt(matcher.group(1)); - var minor = Integer.parseInt(matcher.group(2)); - var patch = Integer.parseInt(matcher.group(3) == null ? "0" : matcher.group(3)); - return Optional.of(new Triple<>(major, minor, patch)); - } - return Optional.empty(); - } - - /** - * Check if a version is between two versions - * - * @param oldest oldest allowed version - * @param newest newest allowed version - * @param current current version - * @return true when the version is between oldest and newest version or equal to the oldest or newest. - */ - public static boolean between(ServerVersion oldest, ServerVersion newest, ServerVersion current) { - var currentMajor = current.version.first; - var oldestMajor = oldest.version.first; - var newestMajor = newest.version.first; - var currentMinor = current.version.second; - var oldestMinor = oldest.version.second; - var newestMinor = newest.version.second; - if (currentMajor < oldestMajor || currentMajor > newestMajor) return false; - return currentMinor >= oldestMinor && currentMinor <= newestMinor; - } - - /** - * Get versions between two versions. - * - * @param oldest oldest version (inclusive) - * @param newest newest version (exclusive) - * @return array of versions - */ - public static ServerVersion[] versionsBetween(ServerVersion oldest, ServerVersion newest) { - return Arrays.stream(values()).filter(v -> v.between(oldest, newest)).toArray(ServerVersion[]::new); - } - - /** - * This method will check if the current version is between the oldest and newest version. Will abort enable of - * plugin when called on enable. - * - * @param oldest oldest version (inclusive) - * @param newest newest version (inclusive) - * @throws UnsupportedVersionException when the server version is not between the oldest and newest version. - */ - public static void forceVersion(ServerVersion oldest, ServerVersion newest) { - if (CURRENT_VERSION.between(oldest, newest)) return; - throw new UnsupportedVersionException(); - } - - /** - * Check if this version is between two versions - * - * @param oldest oldest allowed version - * @param newest newest allowed version - * @return true when the version is between oldest and newest version or equal to the oldest or newest. - */ - public boolean between(ServerVersion oldest, ServerVersion newest) { - return between(oldest, newest, this); - } - - /** - * Get the minor version as a string separated by '.'. E.g. 1.15 - * - * @return version as string - */ - public String version() { - return this.version.first + "." + this.version.second; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/BiFunctionBuilder.java b/src/main/java/de/eldoria/eldoutilities/crossversion/builder/BiFunctionBuilder.java deleted file mode 100644 index b4f80b3f..00000000 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/BiFunctionBuilder.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.crossversion.builder; - -import de.eldoria.eldoutilities.crossversion.ServerVersion; -import de.eldoria.eldoutilities.crossversion.function.BiVersionFunction; - -import java.util.EnumMap; -import java.util.Map; -import java.util.function.BiFunction; - -/** - * A builder for a {@link BiVersionFunction} with version sensitive context. - * - * @param first Input Type - * @param second Input Type - * @param result Type - */ -public class BiFunctionBuilder { - private final Map> functions = new EnumMap<>(ServerVersion.class); - - protected BiFunctionBuilder() { - } - - /** - * Add a version function which should be used on one or more versions. - * - * @param function function to execute - * @param version versions which should use this function - * @return builder instance with function applied for versions - */ - public BiFunctionBuilder addVersionFunctionBetween(BiFunction function, ServerVersion... version) { - for (var serverVersion : version) { - functions.put(serverVersion, function); - } - return this; - } - - /** - * Add a version functions for all versions between two versions. - * - * @param oldest oldest version (inclusive) - * @param newest newest version (inclusive) - * @param function function to execute - * @return builder instance with function applied for versions - */ - public BiFunctionBuilder addVersionFunctionBetween(ServerVersion oldest, ServerVersion newest, BiFunction function) { - addVersionFunctionBetween(function, ServerVersion.versionsBetween(oldest, newest)); - return this; - } - - /** - * Build the version function. - * - * @return version functions with applied functions for versions. - */ - public BiVersionFunction build() { - return new BiVersionFunction<>(functions); - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/FunctionBuilder.java b/src/main/java/de/eldoria/eldoutilities/crossversion/builder/FunctionBuilder.java deleted file mode 100644 index 4a1939f1..00000000 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/FunctionBuilder.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.crossversion.builder; - -import de.eldoria.eldoutilities.crossversion.ServerVersion; -import de.eldoria.eldoutilities.crossversion.function.VersionFunction; - -import java.util.EnumMap; -import java.util.Map; -import java.util.function.Function; - -/** - * A builder for a {@link VersionFunction} with version sensitive context. - * - * @param first Input Type - * @param result Type - */ -public class FunctionBuilder { - private final Map> functions = new EnumMap<>(ServerVersion.class); - - protected FunctionBuilder() { - } - - /** - * Add a version function which should be used on one or more versions. - * - * @param function function to execute - * @param version versions which should use this function - * @return builder instance with function applied for versions - */ - public FunctionBuilder addVersionFunction(Function function, ServerVersion... version) { - for (var serverVersion : version) { - functions.put(serverVersion, function); - } - return this; - } - - /** - * Add a version functions for all versions between two versions. - * - * @param oldest oldest version (inclusive) - * @param newest newest version (inclusive) - * @param function function to execute - * @return builder instance with function applied for versions - */ - public FunctionBuilder addVersionFunctionBetween(ServerVersion oldest, ServerVersion newest, Function function) { - addVersionFunction(function, ServerVersion.versionsBetween(oldest, newest)); - return this; - } - - /** - * Build the version function. - * - * @return version functions with applied functions for versions. - */ - public VersionFunction build() { - return new VersionFunction<>(functions); - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/QuadFunctionBuilder.java b/src/main/java/de/eldoria/eldoutilities/crossversion/builder/QuadFunctionBuilder.java deleted file mode 100644 index 160196b2..00000000 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/QuadFunctionBuilder.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.crossversion.builder; - -import de.eldoria.eldoutilities.crossversion.ServerVersion; -import de.eldoria.eldoutilities.crossversion.function.QuadVersionFunction; -import de.eldoria.eldoutilities.functions.QuadFunction; - -import java.util.EnumMap; -import java.util.Map; - -/** - * A builder for a {@link QuadVersionFunction} with version sensitive context. - * - * @param first Input Type - * @param second Input Type - * @param third Input Type - * @param fourth Input Type - * @param result Type - */ -public class QuadFunctionBuilder { - private final Map> functions = new EnumMap<>(ServerVersion.class); - - protected QuadFunctionBuilder() { - } - - /** - * Add a version function which should be used on one or more versions. - * - * @param function function to execute - * @param version versions which should use this function - * @return builder instance with function applied for versions - */ - public QuadFunctionBuilder addVersionFunction(QuadFunction function, ServerVersion... version) { - for (var serverVersion : version) { - functions.put(serverVersion, function); - } - return this; - } - - /** - * Add a version functions for all versions between two versions. - * - * @param oldest oldest version (inclusive) - * @param newest newest version (inclusive) - * @param function function to execute - * @return builder instance with function applied for versions - */ - public QuadFunctionBuilder addVersionFunctionBetween(ServerVersion oldest, ServerVersion newest, QuadFunction function) { - addVersionFunction(function, ServerVersion.versionsBetween(oldest, newest)); - return this; - } - - /** - * Build the version function. - * - * @return version functions with applied functions for versions. - */ - public QuadVersionFunction build() { - return new QuadVersionFunction<>(functions); - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/TriFunctionBuilder.java b/src/main/java/de/eldoria/eldoutilities/crossversion/builder/TriFunctionBuilder.java deleted file mode 100644 index a342f094..00000000 --- a/src/main/java/de/eldoria/eldoutilities/crossversion/builder/TriFunctionBuilder.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.crossversion.builder; - -import de.eldoria.eldoutilities.crossversion.ServerVersion; -import de.eldoria.eldoutilities.crossversion.function.TriVersionFunction; -import de.eldoria.eldoutilities.functions.TriFunction; - -import java.util.EnumMap; -import java.util.Map; - -public class TriFunctionBuilder { - private final Map> functions = new EnumMap<>(ServerVersion.class); - - protected TriFunctionBuilder() { - } - - /** - * Add a version function which should be used on one or more versions. - * - * @param function function to execute - * @param version versions which should use this function - * @return builder instance with function applied for versions - */ - public TriFunctionBuilder addVersionFunction(TriFunction function, ServerVersion... version) { - for (var serverVersion : version) { - functions.put(serverVersion, function); - } - return this; - } - - /** - * Add a version functions for all versions between two versions. - * - * @param oldest oldest version (inclusive) - * @param newest newest version (inclusive) - * @param function function to execute - * @return builder instance with function applied for versions - */ - public TriFunctionBuilder addVersionFunctionBetween(ServerVersion oldest, ServerVersion newest, TriFunction function) { - addVersionFunction(function, ServerVersion.versionsBetween(oldest, newest)); - return this; - } - - /** - * Build the version function. - * - * @return version functions with applied functions for versions. - */ - public TriVersionFunction build() { - return new TriVersionFunction<>(functions); - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/debug/payload/ConfigDump.java b/src/main/java/de/eldoria/eldoutilities/debug/payload/ConfigDump.java deleted file mode 100644 index e1d23c50..00000000 --- a/src/main/java/de/eldoria/eldoutilities/debug/payload/ConfigDump.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.debug.payload; - -import de.eldoria.eldoutilities.configuration.EldoConfig; -import de.eldoria.eldoutilities.debug.DebugSettings; -import de.eldoria.eldoutilities.debug.data.EntryData; -import de.eldoria.eldoutilities.simplecommands.EldoCommand; -import org.bukkit.plugin.Plugin; - -import java.io.File; -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.LinkedHashSet; -import java.util.LinkedList; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; -import java.util.stream.Collectors; - -public class ConfigDump extends EntryData { - - public ConfigDump(String path, String content) { - super(path, content); - } - - /** - * Creates a new config dump. This dump will include external configs as well if the plugin is a {@link EldoCommand}. - * - * @param plugin plugin to dump teh configs - * @param settings settings for debug dispatching - * @return configs as an array. - */ - public static EntryData[] create(Plugin plugin, DebugSettings settings) { - var root = plugin.getDataFolder().toPath().toAbsolutePath().getParent().getParent(); - - var mainConfig = EldoConfig.getMainConfig(plugin); - - Set configs = new LinkedHashSet<>(); - if (mainConfig != null) { - try { - mainConfig.save(); - } catch (Exception e) { - plugin.getLogger().log(Level.CONFIG, "something went wrong while saving the config. Skipping", e); - } - configs.addAll(mainConfig.getConfigs().keySet()); - } else { - configs.add(Paths.get(plugin.getDataFolder().toPath().toString(), "config.yml").toString()); - } - - List dumps = new LinkedList<>(); - for (var config : configs) { - var currentConfig = Paths.get(root.toString(), config).toFile(); - var content = "Could not read"; - if (currentConfig.exists()) { - try { - content = Files.readAllLines(currentConfig.toPath(), StandardCharsets.UTF_8).stream() - .collect(Collectors.joining(System.lineSeparator())); - } catch (IOException e) { - plugin.getLogger().info("Could not read config file " + config); - } - } - dumps.add(new ConfigDump(config, content)); - } - - dumps.forEach(e -> e.applyFilter(settings)); - - return dumps.toArray(new ConfigDump[0]); - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/localization/DummyLocalizer.java b/src/main/java/de/eldoria/eldoutilities/localization/DummyLocalizer.java deleted file mode 100644 index d60b6759..00000000 --- a/src/main/java/de/eldoria/eldoutilities/localization/DummyLocalizer.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.localization; - -import org.jetbrains.annotations.Nullable; - -import java.util.Map; - -/** - * A dummy localizer which serves as a default localizer. - *

- * Does return the locale code. - * - * @since 1.0.0 - */ -public class DummyLocalizer implements ILocalizer { - @Override - public void setLocale(String language) { - - } - - @Override - public String getMessage(String key, Replacement... replacements) { - return key; - } - - @Override - public String[] getIncludedLocales() { - return new String[0]; - } - - @Override - public void addLocaleCodes(Map runtimeLocaleCodes) { - } - - @Override - public @Nullable String getValue(String key) { - return null; - } - - @Override - public String localize(String message, Replacement... replacements) { - return message; - } - - @Override - public void registerChild(ILocalizer localizer) { - - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java b/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java deleted file mode 100644 index 56ffcc66..00000000 --- a/src/main/java/de/eldoria/eldoutilities/localization/ILocalizer.java +++ /dev/null @@ -1,138 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.localization; - -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.PropertyKey; - -import java.util.HashMap; -import java.util.Locale; -import java.util.Map; - -/** - * Basic Interface for localizer implementations. - *

- * Also allows access to localizer instances per plugin. - * - * @since 1.0.0 - */ -public interface ILocalizer { - Map, ILocalizer> LOCALIZER = new HashMap<>(); - ILocalizer DEFAULT = new DummyLocalizer(); - - static ILocalizer getPluginLocalizer(Plugin plugin) { - if (plugin == null) return DEFAULT; - return getPluginLocalizer(plugin.getClass()); - } - - static ILocalizer getPluginLocalizer(Class plugin) { - if (plugin == null) return DEFAULT; - return LOCALIZER.getOrDefault(plugin, DEFAULT); - } - - static String escape(String string) { - return String.format("$%s$", string); - } - - /** - * Create a new localizer instance with default values. - *

- * The message path and prefix will be "messages" and the fallback language the "en_US" locale. - *

- * This instance will create locale files, which are provided in the resources directory. - *

- * After this it will updates all locale files inside the locales directory. For this the ref keys from the internal - * default locale file will be used. - *

- * After a update check and a update if needed it will load the provided language or the fallback language if the - * provided language does not exists. - * - * @param plugin instance of plugin - * @param includedLocales internal provided locales - * @return the created localizer instance - */ - static ILocalizer create(Plugin plugin, - String... includedLocales) { - return create(plugin, "messages", "messages", Locale.US, includedLocales); - } - - /** - * Create a new localizer instance. - *

- * This instance will create locale files, which are provided in the resources directory. - *

- * After this it will updates all locale files inside the locales directory. For this the ref keys from the internal - * default locale file will be used. - *

- * After a update check and a update if needed it will load the provided language or the fallback language if the - * provided language does not exists. - * - * @param plugin instance of plugin - * @param localesPath path of the locales directory - * @param localesPrefix prefix of the locale files - * @param fallbackLocale fallbackLocale - * @param includedLocales internal provided locales - * @return the created localizer instance - */ - static ILocalizer create(Plugin plugin, String localesPath, - String localesPrefix, Locale fallbackLocale, String... includedLocales) { - ILocalizer localizer = new Localizer(plugin, localesPath, localesPrefix, fallbackLocale, includedLocales); - LOCALIZER.put(plugin.getClass(), localizer); - return localizer; - } - - /** - * Sets the locale of the localizer instance. - * - * @param language language to set. - */ - void setLocale(String language); - - /** - * Get a message. - * - * @param key message key - * @param replacements replacements for replacement keys - * @return message with replaced replacements if present. - */ - String getMessage(String key, Replacement... replacements); - - /** - * Returns all available locales. - * - * @return array of registered locales. - */ - String[] getIncludedLocales(); - - /** - * Add requested locale codes in runtime. - *

- * This has to be done before calling {@link #setLocale(String)} - *

- * Every key has one default value which will be added to the file if the key is not present. - * - * @param runtimeLocaleCodes map with locales codes to add. - */ - void addLocaleCodes(Map runtimeLocaleCodes); - - @Nullable - String getValue(String key); - - /** - * Translates a String with Placeholders. Can handle multiple messages with replacements. Add replacements in the - * right order. - * - * @param message Message to translate - * @param replacements Replacements in the right order. - * @return Replaced Messages - * @since 1.2.3 - */ - String localize(String message, Replacement... replacements); - - void registerChild(ILocalizer localizer); -} diff --git a/src/main/java/de/eldoria/eldoutilities/localization/Replacement.java b/src/main/java/de/eldoria/eldoutilities/localization/Replacement.java deleted file mode 100644 index d04aff18..00000000 --- a/src/main/java/de/eldoria/eldoutilities/localization/Replacement.java +++ /dev/null @@ -1,171 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.localization; - -import org.bukkit.World; -import org.bukkit.entity.Player; - -/** - * A replacement represents a text placeholder and its replacement. - */ -public final class Replacement { - private static String format = "%%%s%%"; - - private final String key; - private String value; - private boolean caseSensitive; - - private Replacement(String key, String value) { - this.key = key; - this.value = value; - } - - /** - * Creates a new replacement. - * - * @param key key of replacement - * @param value value for replacement - * @param formats format which should be applied on the replacement. - * @return replacement with registered replacement - */ - public static Replacement create(String key, String value, char... formats) { - var replacement = new Replacement(key, value); - return replacement.addFormatting(formats); - } - - public static Replacement create(String key, Double value, char... formats) { - return create(key, String.format("%.2f", value), formats); - } - - /** - * Creates a new replacement. - * - * @param key key of replacement - * @param value value which provides a string via {@link Object#toString()} - * @param formats format which should be applied on the replacement. - * @return replacement with registered replacement - */ - public static Replacement create(String key, Object value, char... formats) { - return create(key, value.toString(), formats); - } - - /** - * Creates a new replacement. - * - * @param key key of replacement - * @param anEnum value which provides a string via {@link Enum#name()} - * @param formats format which should be applied on the replacement. - * @return replacement with registered replacement - */ - public static Replacement create(String key, Enum anEnum, char... formats) { - return create(key, anEnum.name(), formats); - } - - /** - * Creates a new replacement for a player. - * - * @param key key of replacement - * @param player value which provides the name of the player - * @param formats format which should be applied on the replacement. - * @return replacement with registered replacement - */ - public static Replacement create(String key, Player player, char... formats) { - return create(key, player.getName(), formats); - } - - /** - * Creates a new replacement for a player. - * - * @param key key of replacement - * @param world world which provides the name of the world - * @param formats format which should be applied on the replacement. - * @return replacement with registered replacement - */ - public static Replacement create(String key, World world, char... formats) { - return create(key, world.getName(), formats); - } - - /** - * Add formatting codes to the replacement. A §r will be appended after the replacement. Only provide the formatting - * character. Without § or &. - * - * @param format format which should be applied on the replacement. - * @param afterFormat The formatting codes which should be applied after the §r. - * @return replacement with formatting set - */ - public Replacement addFormatting(char[] format, char... afterFormat) { - if (format.length == 0 && afterFormat.length == 0) return this; - - var builder = new StringBuilder(); - for (var aChar : format) { - builder.append("§").append(aChar); - } - builder.append(value).append("§r"); - for (var aChar : afterFormat) { - builder.append("§").append(aChar); - } - value = builder.toString(); - return this; - } - - /** - * Add formatting codes to the replacement. A §r will be appended after the replacement. Only provide the formatting - * character. Without § or &. - * - * @param format format which should be applied on the replacement. - * @return replacement with formatting set - */ - public Replacement addFormatting(char... format) { - return addFormatting(format, new char[0]); - } - - /** - * Set the replacement to ignore case of placeholder value - * - * @return Replacement with value changed - */ - public Replacement matchCase() { - this.caseSensitive = true; - return this; - } - - - /** - * Invoke the replacement on the string. - * - * @param string string to replace - * @return string with key replaced by value. - */ - public String invoke(String string) { - if (!caseSensitive) { - return string.replaceAll("(?i)" + markedKey(), value.replace("$", "\\$")); - } - return string.replace(key, value); - } - - private String markedKey() { - return String.format(format, key); - } - - @Override - public String toString() { - return "Replacement{" + - "key='" + key + '\'' + - ", value='" + value + '\'' + - ", caseSensitive=" + caseSensitive + - '}'; - } - - /** - * Sets the format used to recognize placeholders. This is the string which will be replaced by the replacement value - * - * @param format format for replacement markers - */ - public static void setFormat(String format) { - Replacement.format = format; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/messages/MessageChannel.java b/src/main/java/de/eldoria/eldoutilities/messages/MessageChannel.java deleted file mode 100644 index 95f71c66..00000000 --- a/src/main/java/de/eldoria/eldoutilities/messages/MessageChannel.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.messages; - -import de.eldoria.eldoutilities.core.EldoUtilities; -import de.eldoria.eldoutilities.messages.channeldata.BossBarData; -import de.eldoria.eldoutilities.messages.channeldata.ChannelData; -import de.eldoria.eldoutilities.messages.channeldata.TitleData; -import net.md_5.bungee.api.ChatMessageType; -import net.md_5.bungee.api.chat.TextComponent; -import org.bukkit.Bukkit; -import org.bukkit.NamespacedKey; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Optional; -import java.util.concurrent.ThreadLocalRandom; - -public interface MessageChannel { - String KEY_PREFIX = "messageChannel"; - - /** - * Default implementation for a chat message - */ - MessageChannel CHAT = new MessageChannel<>() { - @Override - public String name() { - return "CHAT"; - } - - @Override - public void sendMessage(String message, MessageSender sender, CommandSender target, ChannelData data) { - target.sendMessage(message); - } - - @Override - public String addPrefix(String message, String prefix) { - return prefix + message; - } - }; - - /** - * Default implementation for a title message - */ - MessageChannel TITLE = new MessageChannel<>() { - @Override - public String name() { - return "TITLE"; - } - - @Override - public void sendMessage(String message, MessageSender sender, CommandSender target, TitleData data) { - var titleData = data; - if (titleData == null) titleData = TitleData.DEFAULT; - if (target instanceof Player) { - ((Player) target).sendTitle(message, titleData.getOtherLine(), titleData.getFadeIn(), titleData.getStay(), titleData.getFadeOut()); - } else { - sender.send(CHAT, MessageType.NORMAL, target, message); - } - } - }; - - /** - * Default implementation for a subtitle message - */ - MessageChannel SUBTITLE = new MessageChannel<>() { - @Override - public String name() { - return "SUBTITLE"; - } - - @Override - public void sendMessage(String message, MessageSender sender, CommandSender target, TitleData data) { - var titleData = data; - if (titleData == null) titleData = TitleData.DEFAULT; - if (target instanceof Player) { - ((Player) target).sendTitle(titleData.getOtherLine(), message, titleData.getFadeIn(), titleData.getStay(), titleData.getFadeOut()); - } else { - sender.send(CHAT, MessageType.NORMAL, target, message); - } - - } - }; - - /** - * Default implementation for a action bar message - */ - MessageChannel ACTION_BAR = new MessageChannel<>() { - @Override - public String name() { - return "ACTION_BAR"; - } - - @Override - public void sendMessage(String message, MessageSender sender, CommandSender target, ChannelData data) { - if (target instanceof Player) { - ((Player) target).spigot().sendMessage(ChatMessageType.ACTION_BAR, TextComponent.fromLegacyText(message)); - } else { - sender.send(CHAT, MessageType.NORMAL, target, message); - } - } - }; - - MessageChannel BOSS_BAR = new MessageChannel<>() { - @Override - public String name() { - return "BOSS_BAR"; - } - - @Override - public void sendMessage(String message, MessageSender sender, CommandSender target, BossBarData data) { - var bossBarData = data; - if (bossBarData == null) { - bossBarData = BossBarData.DEFAULT; - } - if (target instanceof Player) { - var key = KEY_PREFIX + target.getName() + ThreadLocalRandom.current().nextInt(10000, 99999); - var barKey = new NamespacedKey(EldoUtilities.getInstanceOwner(), key); - var bossBar = bossBarData.create(barKey, message); - bossBar.setProgress(1); - bossBar.addPlayer((Player) target); - Bukkit.getScheduler().runTaskLater(EldoUtilities.getInstanceOwner(), () -> { - bossBar.removeAll(); - Bukkit.removeBossBar(barKey); - }, bossBarData.getDuration()); - } else { - target.sendMessage(message); - } - } - }; - - MessageChannel BROADCAST = new MessageChannel<>() { - @Override - public String name() { - return "BROADCAST"; - } - - @Override - public void sendMessage(String message, MessageSender sender, CommandSender target, ChannelData data) { - Bukkit.broadcastMessage(message); - } - - @Override - public String addPrefix(String message, String prefix) { - return prefix + message; - } - }; - - /** - * Get a default channel by name. - * - * @param name name of channel not case sensitive - * @return channel or {@link #CHAT} if channel is not found or name is null - */ - static @NotNull MessageChannel getChannelByNameOrDefault(@Nullable String name) { - return getChannelByName(name).orElse(CHAT); - } - - /** - * Get a default channel by name. - * - * @param name name of channel not case sensitive - * @return channel or null if name is null or no matching channel is found - */ - static Optional> getChannelByName(@Nullable String name) { - for (var value : values()) { - if (value.name().equalsIgnoreCase(name)) { - return Optional.of(value); - } - } - return Optional.empty(); - } - - /** - * Get the name of the channel - * - * @return name of channel - */ - String name(); - - /** - * Send a message via this channel to a target with the delivered message sender instance. - * - * @param message message to send - * @param sender message sender instance - * @param target target of message - * @param data Additional data for the channel - */ - void sendMessage(String message, MessageSender sender, CommandSender target, T data); - - /** - * Send a message via this channel to a target with the delivered message sender instance. - * - * @param message message to send - * @param sender message sender instance - * @param target target of message - */ - default void sendMessage(String message, MessageSender sender, CommandSender target) { - sendMessage(message, sender, target, null); - } - - default String addPrefix(String message, String prefix) { - return message; - } - - static MessageChannel[] values() { - return new MessageChannel[]{CHAT, TITLE, SUBTITLE, ACTION_BAR, BOSS_BAR, BROADCAST}; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java b/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java deleted file mode 100644 index 3a1e255c..00000000 --- a/src/main/java/de/eldoria/eldoutilities/messages/MessageSender.java +++ /dev/null @@ -1,413 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.messages; - -import de.eldoria.eldoutilities.localization.ILocalizer; -import de.eldoria.eldoutilities.localization.Replacement; -import de.eldoria.eldoutilities.messages.channeldata.ChannelData; -import de.eldoria.eldoutilities.messages.channeldata.TitleData; -import org.bukkit.Bukkit; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.Nullable; - -import java.util.HashMap; -import java.util.Map; - -/** - * A message sender to manage message sending. - *

- * Allows definition of a plugin prefix, Message color, Error color. - *

- * Allows sending of messages, error messages, titles. - *

- * Allows sending of automatically localized messages in combination with a created localizer. - * - * @since 1.0.0 - */ -public final class MessageSender { - private static final MessageSender DEFAULT_SENDER = new MessageSender(null, ""); - private static final Map, MessageSender> PLUGIN_SENDER = new HashMap<>(); - private final Class ownerPlugin; - private String prefix; - - private MessageSender(Class ownerPlugin, String prefix) { - this.ownerPlugin = ownerPlugin; - this.prefix = prefix; - } - - /** - * Creates a new message sender for the plugin - * - * @param plugin plugin to create the message sender for - * @param prefix plugin prefix with color code - * @param messageColor default message color - * @param errorColor default error color - * @return message sender instance or default sender if plugin is null - */ - @Deprecated - public static MessageSender create(Class plugin, String prefix, char messageColor, char errorColor) { - return create(plugin, prefix, new char[]{messageColor}, new char[]{errorColor}); - } - - /** - * Creates a new message sender for the plugin - * - * @param plugin plugin to create the message sender for - * @param prefix plugin prefix with color code - * @param messageColor default message color - * @param errorColor default error color - * @return message sender instance or default sender if plugin is null - */ - @Deprecated - public static MessageSender create(Plugin plugin, String prefix, char messageColor, char errorColor) { - return create(plugin.getClass(), prefix, new char[]{messageColor}, new char[]{errorColor}); - } - - /** - * Creates a new message sender for the plugin - * - * @param plugin plugin to create the message sender for - * @param prefix plugin prefix with color code - * @param messageColor default message color - * @param errorColor default error color - * @return message sender instance or default sender if plugin is null - */ - @Deprecated - public static MessageSender create(Plugin plugin, String prefix, char[] messageColor, char[] errorColor) { - return create(plugin.getClass(), prefix, messageColor, errorColor); - } - - /** - * Creates a new message sender for the plugin - * - * @param plugin plugin to create the message sender for - * @param prefix plugin prefix with color code - * @param messageColor default message color - * @param errorColor default error color - * @return message sender instance or default sender if plugin is null - */ - @Deprecated - public static MessageSender create(Class plugin, String prefix, char[] messageColor, char[] errorColor) { - return create(plugin, prefix); - } - - public static MessageSender create(Plugin plugin, String prefix) { - return create(plugin.getClass(), prefix); - } - - public static MessageSender create(Class plugin, String prefix) { - if (plugin == null) return DEFAULT_SENDER; - - return PLUGIN_SENDER.compute(plugin, - (k, v) -> v == null - ? new MessageSender(plugin, prefix.trim() + " ") - : v.update(prefix)); - } - - /** - * Get the message sender created for this plugin. - * - * @param plugin plugin - * @return message sender of plugin or default sender if plugin is null - */ - public static MessageSender getPluginMessageSender(@Nullable Plugin plugin) { - if (plugin == null) return DEFAULT_SENDER; - return getPluginMessageSender(plugin.getClass()); - } - - /** - * Get the message sender created for this plugin. - * - * @param plugin plugin - * @return message sender of plugin or default sender if plugin is null - */ - public static MessageSender getPluginMessageSender(@Nullable Class plugin) { - return plugin == null ? DEFAULT_SENDER - : PLUGIN_SENDER.getOrDefault(plugin, DEFAULT_SENDER); - } - - public static MessageSender getDefaultSender() { - return DEFAULT_SENDER; - } - - private MessageSender update(String prefix) { - this.prefix = prefix; - return this; - } - - /** - * Send a message to a sender - * - * @param sender receiver of the message - * @param message message with optinal color codes - */ - public void sendMessage(CommandSender sender, String message) { - send(MessageChannel.CHAT, MessageType.NORMAL, sender, message); - } - - /** - * Sends a error to a sender - * - * @param sender receiver of the message - * @param message message with optinal color codes - */ - public void sendError(CommandSender sender, String message) { - send(MessageChannel.CHAT, MessageType.ERROR, sender, message); - } - - /** - * Send a message to a sender - *

- * The message will be localized. - *

- * The message can be a simple locale code in the format "code" or "code.code....". - *

- * If multiple code should be used every code musst be surrounded by a {@code $} mark. Example {@code "$code.code$ - * and $code.more.code$}. You can write what you want between locale codes. - * - * @param sender receiver of the message - * @param message message with optinal color codes - * @param replacements replacements to apply on the message - */ - public void sendLocalizedMessage(CommandSender sender, String message, Replacement... replacements) { - sendLocalized(MessageChannel.CHAT, MessageType.NORMAL, sender, message, replacements); - } - - /** - * Sends a error to a sender - *

- * The message will be localized. - *

- * The message can be a simple locale code in the format "code" or "code.code....". - *

- * If multiple code should be used every code musst be surrounded by a {@code $} mark. Example {@code "$code.code$ - * and $code.more.code$}. You can write what you want between locale codes. - * - * @param sender receiver of the message - * @param message message with optinal color codes - * @param replacements replacements to apply on the message - */ - public void sendLocalizedError(CommandSender sender, String message, Replacement... replacements) { - sendLocalized(MessageChannel.CHAT, MessageType.ERROR, sender, message, replacements); - } - - /** - * @deprecated flagged for removal. Use {@link #send(MessageChannel, MessageType, CommandSender, String, ChannelData)} instead. - */ - @Deprecated - public void sendTitle(Player player, String defaultColor, String title, String subtitle, int fadeIn, int stay, int fadeOut) { - send(MessageChannel.TITLE, () -> defaultColor, player, title, TitleData.forFadeAndTime(fadeIn, stay, fadeOut, subtitle)); - } - - /** - * @deprecated flagged for removal. Use {@link #send(MessageChannel, MessageType, CommandSender, String, ChannelData)} instead. - */ - @Deprecated - public void sendTitle(Player player, String defaultColor, String title, String subtitle) { - send(MessageChannel.TITLE, () -> defaultColor, player, title, TitleData.forOtherLine(subtitle)); - } - - /** - * Send a title to a player - * - * @param player player to send - * @param title title to send - * @param subtitle subtitle to send - * @param fadeIn fade in time of title - * @param stay stay time of title - * @param fadeOut fade out time of title - * @deprecated flagged for removal. Use {@link #send(MessageChannel, MessageType, CommandSender, String, ChannelData)} instead. - */ - @Deprecated - public void sendTitle(Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut) { - send(MessageChannel.TITLE, MessageType.NORMAL, player, title, TitleData.forFadeAndTime(fadeIn, stay, fadeOut, subtitle)); - } - - /** - * Send a title to a player - * - * @param player player to send - * @param title title to send - * @param subtitle subtitle to send - * @deprecated flagged for removal. Use {@link #send(MessageChannel, MessageType, CommandSender, String, ChannelData)} instead. - */ - @Deprecated - public void sendTitle(Player player, String title, String subtitle) { - send(MessageChannel.TITLE, MessageType.NORMAL, player, title, TitleData.forOtherLine(subtitle)); - } - - /** - * Send a localized title to a player - * - * @param player player to send - * @param defaultColor default color of message - * @param title title to send - * @param subtitle subtitle to send - * @param fadeIn fade in time of title - * @param stay stay time of title - * @param fadeOut fade out time of title - * @param replacements replacements for the localized message - * @deprecated flagged for removal. Use {@link #sendLocalized(MessageChannel, MessageType, CommandSender, String, ChannelData, Replacement...)} instead. - */ - @Deprecated - public void sendLocalizedTitle(Player player, String defaultColor, String title, String subtitle, int fadeIn, int stay, int fadeOut, Replacement... replacements) { - sendLocalized(MessageChannel.TITLE, () -> defaultColor, player, title, TitleData.forFadeAndTime(fadeIn, stay, fadeOut, subtitle), replacements); - } - - /** - * Send a localized title to a player - * - * @param player player to send - * @param title title to send - * @param subtitle subtitle to send - * @param fadeIn fade in time of title - * @param stay stay time of title - * @param fadeOut fade out time of title - * @param replacements replacements for the localized message - * @deprecated flagged for removal. Use {@link #sendLocalized(MessageChannel, MessageType, CommandSender, String, ChannelData, Replacement...)} instead. - */ - @Deprecated - public void sendLocalizedTitle(Player player, String title, String subtitle, int fadeIn, int stay, int fadeOut, Replacement... replacements) { - sendLocalized(MessageChannel.TITLE, MessageType.NORMAL, player, title, TitleData.forFadeAndTime(fadeIn, stay, fadeOut, subtitle), replacements); - } - - /** - * Send a localized title to a player - * - * @param player player to send - * @param defaultColor default color of message - * @param title title to send - * @param subtitle subtitle to send - * @param replacements replacements for the localized message - * @deprecated flagged for removal. Use {@link #sendLocalized(MessageChannel, MessageType, CommandSender, String, ChannelData, Replacement...)} instead. - */ - @Deprecated - public void sendLocalizedTitle(Player player, String defaultColor, String title, String subtitle, Replacement... replacements) { - sendLocalized(MessageChannel.TITLE, () -> defaultColor, player, title, TitleData.forOtherLine(subtitle), replacements); - } - - /** - * Send a localized title to a player - * - * @param player player to send - * @param title title to send - * @param subtitle subtitle to send - * @param replacements replacements for the localized message - * @deprecated flagged for removal. Use {@link #sendLocalized(MessageChannel, MessageType, CommandSender, String, ChannelData, Replacement...)} instead. - */ - @Deprecated - public void sendLocalizedTitle(Player player, String title, String subtitle, Replacement... replacements) { - sendLocalized(MessageChannel.TITLE, MessageType.NORMAL, player, title, TitleData.forOtherLine(subtitle), replacements); - } - - /** - * Send a localized action bar to a player - * - * @param player player to send - * @param message message to send - * @param replacements replacements for the localized message - * @deprecated flagged for removal. Use {@link #sendLocalized(MessageChannel, MessageType, CommandSender, String, Replacement...)} instead. - */ - @Deprecated - public void sendLocalizedActionBar(Player player, String message, Replacement... replacements) { - sendLocalized(MessageChannel.ACTION_BAR, MessageType.NORMAL, player, message, replacements); - } - - /** - * Send a message to a player Action bar. - * - * @param player player to send - * @param message message to send - * @deprecated flagged for removal. Use {@link #sendLocalized(MessageChannel, MessageType, CommandSender, String, Replacement...)} instead. - */ - @Deprecated - public void sendActionBar(Player player, String message) { - send(MessageChannel.ACTION_BAR, MessageType.NORMAL, player, message); - } - - private ILocalizer loc() { - return ILocalizer.getPluginLocalizer(ownerPlugin); - } - - /** - * Send a localized message via a channel. - * - * @param channel channel which should be used - * @param type type of message - * @param sender target of message - * @param message message locale codes - * @param replacements replacements for messages in locale codes - * @param type of channel data - * @since 1.2.1 - */ - public void sendLocalized(MessageChannel channel, MessageType type, CommandSender sender, String message, Replacement... replacements) { - sendLocalized(channel, type, sender, message, null, replacements); - } - - /** - * Send a localized message via a channel. - * - * @param channel channel which should be used - * @param type type of message - * @param sender target of message - * @param message message locale codes - * @param replacements replacements for messages in locale codes - * @param data additional data for channel - * @param channel data type - * @since 1.3.0 - */ - public void sendLocalized(MessageChannel channel, MessageType type, CommandSender sender, String message, @Nullable T data, Replacement... replacements) { - if (data != null) { - data.localized(loc(), replacements); - } - send(channel, type, sender, loc().localize(message, replacements), data); - } - - /** - * Sends a message via a channel - * - * @param channel channel which should be used - * @param type type of message - * @param target target of message - * @param message message locale codes - * @param type of channel data - * @since 1.2.1 - */ - public void send(MessageChannel channel, MessageType type, CommandSender target, String message) { - send(channel, type, target, message, null); - } - - /** - * Sends a message via a channel - * - * @param channel channel which should be used - * @param type type of message - * @param target target of message - * @param message message locale codes - * @param data additional data for channel - * @param type of data - * @since 1.3.0 - */ - public void send(MessageChannel channel, MessageType type, CommandSender target, String message, @Nullable T data) { - var coloredMessage = type.forceColor(message); - coloredMessage = channel.addPrefix(coloredMessage, prefix); - if (data != null) { - data.formatText(type, channel, prefix); - } - channel.sendMessage(coloredMessage, this, target == null ? Bukkit.getConsoleSender() : target, data); - } - - public boolean isDefault() { - return ownerPlugin == null; - } - - public String getPrefix() { - return prefix; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/messages/MessageType.java b/src/main/java/de/eldoria/eldoutilities/messages/MessageType.java deleted file mode 100644 index f805f654..00000000 --- a/src/main/java/de/eldoria/eldoutilities/messages/MessageType.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.messages; - -public interface MessageType { - /** - * Default implementation for a normal message type - */ - MessageType NORMAL = () -> "§2"; - /** - * Default implementation for a error message type. - */ - MessageType ERROR = () -> "§c"; - - /** - * Default implementation for a message without default color. - */ - MessageType BLANK = () -> ""; - - /** - * Get the default color of the channel. - *

- * The color code should use the § notation. - * - * @return color code in § notation. - */ - String getDefaultColor(); - - /** - * Tranform a message to force the correct color code where needed. - *

- * By default the §r mark will be replaced by "§r{@link #getDefaultColor()}". - *

- * The default color code will also be appended at the begin of the message - * - * @param message message to send - * @return message with forced color codes. - */ - default String forceColor(String message) { - return "§r" + getDefaultColor() + message.replaceAll("§r", "§r" + getDefaultColor()); - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/messages/channeldata/BossBarData.java b/src/main/java/de/eldoria/eldoutilities/messages/channeldata/BossBarData.java deleted file mode 100644 index ac534d7d..00000000 --- a/src/main/java/de/eldoria/eldoutilities/messages/channeldata/BossBarData.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.messages.channeldata; - -import org.bukkit.Bukkit; -import org.bukkit.NamespacedKey; -import org.bukkit.boss.BarColor; -import org.bukkit.boss.BarFlag; -import org.bukkit.boss.BarStyle; -import org.bukkit.boss.BossBar; - -public final class BossBarData implements ChannelData { - private static final BarStyle DEFAULT_STYLE = BarStyle.SOLID; - private static final BarColor DEFAULT_COLOR = BarColor.WHITE; - private static final int DEFAULT_DURATION = 20 * 10; - /** - * Default BossBar Data - */ - public static final BossBarData DEFAULT = new BossBarData(DEFAULT_COLOR, DEFAULT_STYLE, DEFAULT_DURATION); - - private final BarColor color; - private final BarStyle style; - private final BarFlag[] flags; - private final int duration; - - private BossBarData(BarColor color, BarStyle style, int duration, BarFlag... flags) { - this.color = color; - this.style = style; - this.duration = duration; - this.flags = flags; - } - - /** - * Get a new BossBar Builder - * - * @return return new Builder instance - */ - public static Builder builder() { - return new Builder(); - } - - /** - * Create a bossbar with a message and a key - * - * @param key kay of message - * @param message text of bossbar - * @return BossBar instance - */ - public BossBar create(NamespacedKey key, String message) { - return Bukkit.createBossBar(key, message, color, style, flags); - } - - public int getDuration() { - return duration; - } - - public static final class Builder { - private BarColor color = DEFAULT_COLOR; - private BarStyle style = DEFAULT_STYLE; - private BarFlag[] barFlags = new BarFlag[0]; - private int duration = DEFAULT_DURATION; - - public Builder color(BarColor color) { - this.color = color; - return this; - } - - public Builder style(BarStyle style) { - this.style = style; - return this; - } - - public Builder flags(BarFlag... barFlags) { - this.barFlags = barFlags; - return this; - } - - public Builder ofDuration(int duration) { - this.duration = duration; - return this; - } - - public BossBarData build() { - return new BossBarData(color, style, duration, barFlags); - } - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/messages/channeldata/ChannelData.java b/src/main/java/de/eldoria/eldoutilities/messages/channeldata/ChannelData.java deleted file mode 100644 index 959ddea4..00000000 --- a/src/main/java/de/eldoria/eldoutilities/messages/channeldata/ChannelData.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.messages.channeldata; - -import de.eldoria.eldoutilities.localization.ILocalizer; -import de.eldoria.eldoutilities.localization.Replacement; -import de.eldoria.eldoutilities.messages.MessageChannel; -import de.eldoria.eldoutilities.messages.MessageType; - -public interface ChannelData { - /** - * Localize any externa component beside the message itself. - * - * @param localizer localizer instance - * @param replacements replacements to apply - */ - default void localized(ILocalizer localizer, Replacement... replacements) { - } - - /** - * Format the text to suit the channel requirements - * - * @param type type of message - * @param channel channel - * @param prefix prefix - */ - default void formatText(MessageType type, MessageChannel channel, String prefix) { - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/messages/channeldata/TitleData.java b/src/main/java/de/eldoria/eldoutilities/messages/channeldata/TitleData.java deleted file mode 100644 index a3c09924..00000000 --- a/src/main/java/de/eldoria/eldoutilities/messages/channeldata/TitleData.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.messages.channeldata; - -import de.eldoria.eldoutilities.localization.ILocalizer; -import de.eldoria.eldoutilities.localization.Replacement; -import de.eldoria.eldoutilities.messages.MessageChannel; -import de.eldoria.eldoutilities.messages.MessageType; - -public final class TitleData implements ChannelData { - public static final TitleData DEFAULT = new TitleData(10, 50, 20, ""); - private final int fadeIn; - private final int stay; - private final int fadeOut; - private String otherLine; - - private TitleData(int fadeIn, int stay, int fadeOut, String otherLine) { - this.fadeIn = fadeIn; - this.stay = stay; - this.fadeOut = fadeOut; - this.otherLine = otherLine; - } - - public static TitleData forTime(int fadeIn, int stay, int fadeOut) { - return new TitleData(fadeIn, stay, fadeOut, ""); - } - - public static TitleData forOtherLine(String otherLine) { - return new TitleData(10, 50, 20, otherLine); - } - - public static TitleData forFadeAndTime(int fadeIn, int stay, int fadeOut, String otherLine) { - return new TitleData(fadeIn, stay, fadeOut, otherLine); - } - - @Override - public void localized(ILocalizer localizer, Replacement... replacements) { - otherLine = localizer.localize(otherLine, replacements); - } - - @Override - public void formatText(MessageType type, MessageChannel channel, String prefix) { - type.forceColor(otherLine); - otherLine = channel.addPrefix(otherLine, prefix); - } - - public int getFadeIn() { - return fadeIn; - } - - public int getStay() { - return stay; - } - - public int getFadeOut() { - return fadeOut; - } - - public String getOtherLine() { - return otherLine; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/simplecommands/EldoCommand.java b/src/main/java/de/eldoria/eldoutilities/simplecommands/EldoCommand.java deleted file mode 100644 index b2473206..00000000 --- a/src/main/java/de/eldoria/eldoutilities/simplecommands/EldoCommand.java +++ /dev/null @@ -1,332 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.simplecommands; - -import de.eldoria.eldoutilities.localization.DummyLocalizer; -import de.eldoria.eldoutilities.localization.ILocalizer; -import de.eldoria.eldoutilities.localization.Replacement; -import de.eldoria.eldoutilities.messages.MessageChannel; -import de.eldoria.eldoutilities.messages.MessageSender; -import de.eldoria.eldoutilities.messages.MessageType; -import de.eldoria.eldoutilities.utils.ArrayUtil; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.command.ConsoleCommandSender; -import org.bukkit.command.TabExecutor; -import org.bukkit.entity.Player; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; - -import java.util.Arrays; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.stream.Collectors; - -/** - * Class for command creation. - *

- * Features automatic tab completion and sub commands. - * - * @since 1.1.0 - * @deprecated Use {@link de.eldoria.eldoutilities.commands.command.AdvancedCommand} instead - */ -@Deprecated -public abstract class EldoCommand implements TabExecutor { - private final Map subCommands = new HashMap<>(); - private final Plugin plugin; - private ILocalizer localizer; - private MessageSender messageSender; - private String[] registeredCommands = new String[0]; - private TabExecutor defaultCommand; - - public EldoCommand(Plugin plugin) { - this.plugin = plugin; - } - - - /** - * Checks if the provided arguments are invalid. - * - * @param sender user which executed the command. - * @param messageSender message sender for calling home. - * @param localizer localizer for localization stuff. - * @param args arguments to check - * @param length min amount of arguments. - * @param syntax correct syntax - * @return true if the arguments are invalid - */ - protected static boolean argumentsInvalid(CommandSender sender, MessageSender messageSender, ILocalizer localizer, String[] args, int length, String syntax) { - if (args.length < length) { - messageSender.sendError(sender, localizer.getMessage("error.invalidArguments", - Replacement.create("SYNTAX", localizer.localize(syntax)).addFormatting('6'))); - return true; - } - return false; - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (args.length == 0) { - if (defaultCommand != null) { - return defaultCommand.onCommand(sender, command, label, args); - } - return true; - } - - final var newArgs = args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]; - - return getCommand(args[0]).map(c -> c.onCommand(sender, command, args[0], newArgs)).orElse(false); - } - - @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) { - if (args.length == 1) { - return ArrayUtil.startingWithInArray(args[0], registeredCommands).collect(Collectors.toList()); - } - final var newArgs = args.length > 1 ? Arrays.copyOfRange(args, 1, args.length) : new String[0]; - - if (args.length == 0) return Collections.emptyList(); - - return getCommand(args[0]).map(c -> c.onTabComplete(sender, command, args[0], newArgs)) - .orElse(Collections.singletonList(localizer().getMessage("error.invalidCommand"))); - } - - private Optional getCommand(String command) { - for (var entry : subCommands.entrySet()) { - if (entry.getKey().equalsIgnoreCase(command)) { - return Optional.ofNullable(entry.getValue()); - } - } - return Optional.empty(); - } - - /** - * Registers a command as sub command. - * - * @param command name of the command. - * @param executor executor - */ - public final void registerCommand(String command, TabExecutor executor) { - subCommands.put(command, executor); - registeredCommands = new String[subCommands.size()]; - subCommands.keySet().toArray(registeredCommands); - } - - /** - * Sets the default command of not arguments are present to determine a subcommand. - * - * @param defaultCommand executor for default command - */ - public final void setDefaultCommand(TabExecutor defaultCommand) { - this.defaultCommand = defaultCommand; - } - - /** - * Get a instance of the localizer. - * - * @return localizer instance - */ - protected final ILocalizer localizer() { - if (localizer == null || localizer instanceof DummyLocalizer) { - localizer = ILocalizer.getPluginLocalizer(plugin); - } - return localizer; - } - - /** - * Get a instance of the message sender. - * - * @return message sender instance - */ - protected final MessageSender messageSender() { - if (messageSender == null || messageSender.isDefault()) { - messageSender = MessageSender.getPluginMessageSender(plugin); - } - return messageSender; - } - - /** - * Checks if the provided arguments are invalid. - * - * @param sender user which executed the command. - * @param args arguments to check - * @param length min amount of arguments. - * @param syntax correct syntax - * @return true if the arguments are invalid - */ - protected boolean argumentsInvalid(CommandSender sender, String[] args, int length, String syntax) { - return argumentsInvalid(sender, messageSender(), localizer(), args, length, syntax); - } - - /** - * Returns true if the sender is a player and sends an error message - *

- * Uses the {@code error.notAsPlayer} error code - * - * @param sender sender to check - * @return true if sender is player - */ - protected boolean denyPlayer(CommandSender sender) { - if (isPlayer(sender)) { - messageSender().sendLocalized(MessageChannel.CHAT, MessageType.ERROR, sender, "error.notAsPlayer"); - return true; - } - return false; - } - - /** - * Returns true if the sender is a console and sends an error message. - *

- * Uses the {@code error.notAsConsole} error code - * - * @param sender sender to check - * @return true if sender is console - */ - protected boolean denyConsole(CommandSender sender) { - if (isConsole(sender)) { - messageSender().sendLocalized(MessageChannel.CHAT, MessageType.ERROR, sender, "error.notAsConsole"); - return true; - } - return false; - } - - /** - * Checks if the user has at least one of the provided permissions. This will send a message to the player which - * uses the {@code error.permission} locale key which should provide a placeholder {@code PERMISSION} for an array - * of required permissions, if the user lacks all of the permissions. - * - * @param actor actor which wants to execute this action - * @param permissions one or more permissions to check - * @return true if the user has no of the required permission - */ - protected boolean denyAccess(CommandSender actor, String... permissions) { - return denyAccess(actor, false, permissions); - } - - /** - * Checks if the user has at least one of the provided permissions. This will send a message to the player which - * uses the {@code error.permission} locale key which should provide a placeholder {@code PERMISSION} for an array - * of required permissions, if the user lacks all of the permissions. - * - * @param actor actor which wants to execute this action - * @param silent set to true if no message should be send to the player - * @param permissions one or more permissions to check - * @return true if the user has none of the required permission - */ - protected boolean denyAccess(CommandSender actor, boolean silent, String... permissions) { - if (actor == null) { - return false; - } - - Player player = null; - - if (actor instanceof Player) { - player = (Player) actor; - } - - if (player == null) { - return false; - } - for (var permission : permissions) { - if (player.hasPermission(permission)) { - return false; - } - } - if (!silent) { - messageSender().sendMessage(player, - localizer().getMessage("error.permission", - Replacement.create("PERMISSION", String.join(", ", permissions)).addFormatting('6'))); - } - return true; - } - - /** - * Get the player from a sender if {@link #isPlayer(CommandSender)} returns true. - * - * @param sender sender to cast - * @return player or null if sender is not player - */ - protected Player getPlayerFromSender(CommandSender sender) { - return isPlayer(sender) ? (Player) sender : null; - } - - /** - * Checks if a command sender is the console. - * - * @param sender sender to check - * @return true if the sender is the console - */ - protected boolean isConsole(CommandSender sender) { - return !(sender instanceof Player); - } - - /** - * Checks if a command sender is a player - * - * @param sender sender to check - * @return true if the sender is a player - */ - protected boolean isPlayer(CommandSender sender) { - return (sender instanceof Player); - } - - /** - * Checks if a value value is in a invalid Range. Will send a message based on {@code error.invalidRange} locale key - * which should provide a placeholder for {@code MIN} and {@code MAX} which will be replaced with the corresponding - * values. - * - * @param sender sender of command - * @param value current value - * @param min min value - * @param max max value - * @return true if the range is invalid - */ - protected boolean invalidRange(CommandSender sender, double value, double min, double max) { - if (value > max || value < min) { - messageSender().sendError(sender, localizer().getMessage("error.invalidRange", - Replacement.create("MIN", min).addFormatting('6'), - Replacement.create("MAX", max).addFormatting('6'))); - return true; - } - return false; - } - - /** - * Checks if a enum value is invalid. Will send a message based on {@code error.invalidEnumValue} locale key which - * should provide a placeholder for {@code VALUE} which will be replaced with an array of possible inputs - * - * @param sender sender of command - * @param value value of enum - * @param clazz clazz of enum - * @param type of enum - * @return true if the enum is invalid - */ - protected > boolean invalidEnumValue(CommandSender sender, T value, Class clazz) { - if (value == null) { - messageSender().sendError(sender, localizer().getMessage("error.invalidEnumValue", - Replacement.create("VALUES", - Arrays.stream(clazz.getEnumConstants()) - .map(e -> e.name().toLowerCase()) - .collect(Collectors.joining(" "))) - .addFormatting('6'))); - return true; - } - return false; - } - - protected boolean invalidRange(CommandSender sender, int value, int min, int max) { - return invalidRange(sender, (double) value, min, max); - } - - public Plugin getPlugin() { - return plugin; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/DefaultAbout.java b/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/DefaultAbout.java deleted file mode 100644 index ce798f4d..00000000 --- a/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/DefaultAbout.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.simplecommands.commands; - -import de.eldoria.eldoutilities.localization.Replacement; -import de.eldoria.eldoutilities.simplecommands.EldoCommand; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; - - -/** - * @deprecated Use {@link de.eldoria.eldoutilities.commands.defaultcommands.DefaultAbout} instead. - */ -@Deprecated(forRemoval = true) -public class DefaultAbout extends EldoCommand { - private String discord = "rfRuUge"; - - public DefaultAbout(Plugin plugin) { - super(plugin); - } - - public DefaultAbout(Plugin plugin, String discord) { - super(plugin); - this.discord = discord; - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - var descr = getPlugin().getDescription(); - messageSender().sendLocalizedMessage(sender, "about", - Replacement.create("PLUGIN_NAME", descr.getName(), 'b'), - Replacement.create("AUTHORS", String.join(", ", descr.getAuthors()), 'b'), - Replacement.create("VERSION", descr.getVersion(), 'b'), - Replacement.create("WEBSITE", descr.getWebsite(), 'b'), - Replacement.create("DISCORD", "https://discord.gg/" + discord, 'b')); - return true; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/DefaultDebug.java b/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/DefaultDebug.java deleted file mode 100644 index fd002cbb..00000000 --- a/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/DefaultDebug.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.simplecommands.commands; - -import de.eldoria.eldoutilities.debug.DebugSettings; -import de.eldoria.eldoutilities.debug.DebugUtil; -import de.eldoria.eldoutilities.simplecommands.EldoCommand; -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; - -/** - * @deprecated Use {@link de.eldoria.eldoutilities.commands.defaultcommands.DefaultDebug} instead. - */ -@Deprecated(forRemoval = true) -public class DefaultDebug extends EldoCommand { - - private final String permission; - private final DebugSettings settings; - - public DefaultDebug(Plugin plugin, String permission, DebugSettings settings) { - super(plugin); - this.permission = permission; - this.settings = settings; - } - - public DefaultDebug(Plugin plugin, String permission) { - super(plugin); - this.permission = permission; - settings = DebugSettings.DEFAULT; - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (denyAccess(sender, permission, "de.eldoria.eldoutilitites.debug")) { - return true; - } - - DebugUtil.dispatchDebug(sender, getPlugin(), DebugSettings.DEFAULT); - return true; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/FailsaveCommand.java b/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/FailsaveCommand.java deleted file mode 100644 index c949794e..00000000 --- a/src/main/java/de/eldoria/eldoutilities/simplecommands/commands/FailsaveCommand.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.simplecommands.commands; - -import org.bukkit.command.Command; -import org.bukkit.command.CommandSender; -import org.bukkit.plugin.Plugin; -import org.jetbrains.annotations.NotNull; - -/** - * @deprecated Use {@link de.eldoria.eldoutilities.commands.defaultcommands.FailsaveCommand} instead - */ -@Deprecated(forRemoval = true) -public class FailsaveCommand extends DefaultDebug { - public FailsaveCommand(Plugin plugin, String permission) { - super(plugin, permission); - } - - @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) { - if (args.length == 0) { - sender.sendMessage("§cThe plugin failed to load correctly. Please use /" + label + "§c debug to create a debug paste and send it to the developer."); - return true; - } - if ("debug".equalsIgnoreCase(args[0])) { - super.onCommand(sender, command, label, args); - return true; - } - sender.sendMessage("§cThe plugin failed to load correctly. Please use §a/" + label + "§c debug to create a debug paste and send it to the developer."); - return true; - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/threading/AsyncSyncingCallbackExecutor.java b/src/main/java/de/eldoria/eldoutilities/threading/AsyncSyncingCallbackExecutor.java deleted file mode 100644 index 91340b63..00000000 --- a/src/main/java/de/eldoria/eldoutilities/threading/AsyncSyncingCallbackExecutor.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.threading; - -import de.eldoria.eldoutilities.scheduling.QueuingSelfSchedulingTask; -import de.eldoria.eldoutilities.threading.futures.BukkitFutureResult; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitScheduler; - -import java.util.function.Consumer; -import java.util.function.Supplier; - -/** - * Scheduler Service which allows to execute a async call and handle the retrieved data in the main thread. - * Preserves the main thread from overloading - * - * @deprecated Use {@link BukkitFutureResult} instead. - */ -@Deprecated -public final class AsyncSyncingCallbackExecutor extends QueuingSelfSchedulingTask> { - - private final BukkitScheduler scheduler; - - private AsyncSyncingCallbackExecutor(Plugin plugin) { - super(plugin); - scheduler = Bukkit.getScheduler(); - } - - /** - * Returns a new running executor instance. - * - * @param plugin plugin of executor - * @return running executor instance - */ - public static AsyncSyncingCallbackExecutor create(Plugin plugin) { - return new AsyncSyncingCallbackExecutor(plugin); - } - - @Override - public void execute(Callback object) { - object.invoke(); - } - - /** - * Schedules a new task for execution. - * - * @param asyncProvider Supplier which is executed async and provides data for the consumer - * @param syncAction Consumer which consumes the data in main thread provided by the supplier - * @param type of data - */ - public void schedule(Supplier asyncProvider, Consumer syncAction) { - if (!isActive()) return; - scheduler.runTaskAsynchronously(getPlugin(), () -> schedule(new Callback<>(asyncProvider.get(), syncAction))); - } - - protected static class Callback { - private final T data; - private final Consumer consumer; - - public Callback(T data, Consumer consumer) { - this.data = data; - this.consumer = consumer; - } - - private void invoke() { - consumer.accept(data); - } - } -} diff --git a/src/main/java/de/eldoria/eldoutilities/threading/BukkitAsyncAction.java b/src/main/java/de/eldoria/eldoutilities/threading/BukkitAsyncAction.java deleted file mode 100644 index aa4041cb..00000000 --- a/src/main/java/de/eldoria/eldoutilities/threading/BukkitAsyncAction.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.threading; - -import de.eldoria.eldoutilities.threading.futures.BukkitFutureResult; -import org.bukkit.Bukkit; -import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitScheduler; - -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.function.Consumer; -import java.util.function.Supplier; -import java.util.logging.Level; - -/** - * @param type of action - * @deprecated Use {@link BukkitFutureResult} instead. - */ -@Deprecated -public final class BukkitAsyncAction { - private static final BukkitScheduler SCHEDULER = Bukkit.getScheduler(); - private static ExecutorService executor = Executors.newCachedThreadPool(); - private final Plugin plugin; - private final Supplier supplier; - private final Consumer supplierError; - - private BukkitAsyncAction(Plugin plugin, Supplier supplier, Consumer supplierError) { - this.supplier = supplier; - this.plugin = plugin; - this.supplierError = supplierError; - } - - /** - * This will change the executor. - *

- * All current running tasks will be canceled. - *

- * It is highly recommended to not do this after startup. - * - * @param executor new executor - */ - public static void changeExecutor(ExecutorService executor) { - BukkitAsyncAction.executor.shutdownNow(); - BukkitAsyncAction.executor = executor; - } - - private static Consumer getDefaultLogger(Plugin plugin) { - return e -> plugin.getLogger().log(Level.SEVERE, plugin.getName() + " generated an Exception in an BukkitAsyncAction.", e); - } - - /** - * Create a new bukkit action. - * - *

- * Asynchronous tasks should never access any API in Bukkit. Great care - * should be taken to assure the thread-safety of asynchronous tasks. - *

- * - * @param plugin plugin of action - * @param asyncSupplier asyncSupplier which will request the data asynchronous - * @param type of asyncSupplier - * @return new Bukkit action - */ - public static BukkitAsyncAction supplyAsync(Plugin plugin, Supplier asyncSupplier) { - return new BukkitAsyncAction<>(plugin, asyncSupplier, getDefaultLogger(plugin)); - } - - /** - * Create a new bukkit action. - *

- * Asynchronous tasks should never access any API in Bukkit. Great care - * should be taken to assure the thread-safety of asynchronous tasks. - *

- * - * @param plugin plugin of action - * @param asyncSupplier asyncSupplier which will request the data asynchronous - * @param supplierError error handler for supplier error - * @param type of asyncSupplier - * @return new Bukkit action - */ - public static BukkitAsyncAction supplyAsync(Plugin plugin, Supplier asyncSupplier, Consumer supplierError) { - return new BukkitAsyncAction<>(plugin, asyncSupplier, supplierError); - } - - /** - * Queue the action for async execution - */ - public void queue() { - executeAsync(supplier, e -> { - }); - } - - /** - * Queue the action async - * - * @param consumer synced consumer which accepts the results - * @param consumerError error handler - */ - public void queue(Consumer consumer, Consumer consumerError) { - executeAsync(supplier, consumer, supplierError, consumerError); - } - - /** - * Queue the action async - * - * @param consumer synced consumer which accepts the results - */ - public void queue(Consumer consumer) { - executeAsync(supplier, consumer); - } - - private void executeAsync(Supplier supplier, Consumer consumer) { - executeAsync(supplier, consumer, supplierError, getDefaultLogger(plugin)); - } - - private void executeAsync(Supplier asyncSupplier, Consumer syncedConsumer, - Consumer asyncSupplierError, Consumer syncedConsumerError) { - executor.execute(() -> { - T result; - try { - result = asyncSupplier.get(); - } catch (Throwable e) { - asyncSupplierError.accept(e); - return; - } - SCHEDULER.runTask(plugin, () -> { - try { - syncedConsumer.accept(result); - } catch (Throwable e) { - syncedConsumerError.accept(e); - } - }); - }); - } -} diff --git a/src/test/java/de/eldoria/eldoutilities/ReplacementTest.java b/src/test/java/de/eldoria/eldoutilities/ReplacementTest.java deleted file mode 100644 index 51a4cdb9..00000000 --- a/src/test/java/de/eldoria/eldoutilities/ReplacementTest.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities; - -import de.eldoria.eldoutilities.localization.Replacement; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class ReplacementTest { - Replacement repCaps = Replacement.create("ENTITY", "name"); - Replacement repLower = Replacement.create("entity", "name"); - Replacement replacement2 = Replacement.create("ENTITY", "name", '6'); - - @Test - public void test1() { - Assertions.assertEquals("name", repCaps.invoke("%ENTITY%")); - Assertions.assertEquals("name", repLower.invoke("%ENTITY%")); - Assertions.assertEquals("2.20", Replacement.create("NUM", 2.2000).invoke("%NUM%").replace(",", ".")); - Assertions.assertEquals("2.00", Replacement.create("NUM", 2.0).invoke("%NUM%").replace(",", ".")); - Assertions.assertEquals("2", Replacement.create("NUM", 2).invoke("%NUM%")); - } -} diff --git a/src/test/java/de/eldoria/eldoutilities/localization/ReplacementTest.java b/src/test/java/de/eldoria/eldoutilities/localization/ReplacementTest.java deleted file mode 100644 index e693305c..00000000 --- a/src/test/java/de/eldoria/eldoutilities/localization/ReplacementTest.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.localization; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -public class ReplacementTest { - Replacement repCaps = Replacement.create("ENTITY", "name"); - Replacement repLower = Replacement.create("entity", "name"); - Replacement replacement2 = Replacement.create("ENTITY", "name", '6'); - - @Test - public void test1() { - Assertions.assertEquals("name", repCaps.invoke("%ENTITY%")); - Assertions.assertEquals("name", repLower.invoke("%ENTITY%")); - } -} diff --git a/src/test/java/de/eldoria/eldoutilities/utils/EMathTest.java b/src/test/java/de/eldoria/eldoutilities/utils/EMathTest.java deleted file mode 100644 index 1447b9eb..00000000 --- a/src/test/java/de/eldoria/eldoutilities/utils/EMathTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.utils; - -import de.eldoria.eldoutilities.container.Pair; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import static de.eldoria.eldoutilities.utils.EMath.clamp; -import static de.eldoria.eldoutilities.utils.EMath.parabolaValue; -import static de.eldoria.eldoutilities.utils.EMath.smoothCurveValue; - -public class EMathTest { - @Test - public void clampTest() { - Assertions.assertEquals(100, clamp(0, 100, 101)); - Assertions.assertEquals(0, clamp(0, 100, -1)); - Assertions.assertEquals(50, clamp(0, 100, 50)); - } - - @Test - public void parabolaValueTest() { - // up - double rightUp = parabolaValue(0, 0, 1, 1, 1); - double leftUp = parabolaValue(0, 0, 1, 1, -1); - Assertions.assertEquals(rightUp, leftUp); - Assertions.assertEquals(1, leftUp); - Assertions.assertNotEquals(2, parabolaValue(0, 0, 1, 1, 2)); - //down - double rightDown = parabolaValue(0, 0, -1, -1, 1); - double leftDown = parabolaValue(0, 0, -1, -1, -1); - Assertions.assertEquals(rightDown, leftDown); - Assertions.assertEquals(-1, leftDown); - Assertions.assertNotEquals(-2, parabolaValue(0, 0, 1, 1, 2)); - } - - @Test - public void smoothCurveValueTest() { - // Simple tests - Assertions.assertEquals(0, smoothCurveValue(0)); - Assertions.assertEquals(1, smoothCurveValue(1)); - Assertions.assertEquals(0.5, smoothCurveValue(0.5)); - Assertions.assertNotEquals(0.25, smoothCurveValue(0.25)); - Assertions.assertNotEquals(0.75, smoothCurveValue(0.75)); - - // Complex tests - Pair neg = Pair.of(-1d, -1d); - Pair pos = Pair.of(1d, 1d); - // Descending curve - Assertions.assertEquals(0, smoothCurveValue(neg, pos, 0)); - Assertions.assertTrue(smoothCurveValue(neg, pos, -0.5) < -0.5); - Assertions.assertTrue(smoothCurveValue(neg, pos, 0.5) > 0.5); - - // Ascending curve - neg = Pair.of(1d, -1d); - pos = Pair.of(-1d, 1d); - Assertions.assertEquals(0, smoothCurveValue(pos, neg, 0)); - Assertions.assertTrue(smoothCurveValue(pos, neg, -0.5) > 0.6); - Assertions.assertTrue(smoothCurveValue(pos, neg, 0.5) < -0.6); - } - - @Test - public void diffTest() { - Assertions.assertEquals(2, EMath.diff(-1,1)); - Assertions.assertEquals(1, EMath.diff(0,1)); - Assertions.assertEquals(0, EMath.diff(0,0)); - Assertions.assertEquals(3, EMath.diff(-4,-1)); - Assertions.assertEquals(3, EMath.diff(4,1)); - Assertions.assertEquals(150, EMath.diff(-50,100)); - } -} diff --git a/src/test/java/de/eldoria/eldoutilities/utils/ObjUtilTest.java b/src/test/java/de/eldoria/eldoutilities/utils/ObjUtilTest.java deleted file mode 100644 index 5a5dbc33..00000000 --- a/src/test/java/de/eldoria/eldoutilities/utils/ObjUtilTest.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * SPDX-License-Identifier: AGPL-3.0-only - * - * Copyright (C) EldoriaRPG Team and Contributor - */ - -package de.eldoria.eldoutilities.utils; - -import org.bukkit.Material; -import org.bukkit.event.player.PlayerInteractEvent; -import org.bukkit.inventory.ItemStack; -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.Test; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -class ObjUtilTest { - - @Test - void nonNull() { - } - - @Test - void testNonNull() { - } - - @Test - void testNonNull1() { - } - - @Test - void testNonNull2() { - } - - @Test - void nonNullOrElse() { - PlayerInteractEvent event = mock(PlayerInteractEvent.class); - when(event.getItem()).thenReturn(new ItemStack(Material.AIR)); - Assertions.assertTrue(ObjUtil.nonNullOrElse(event.getItem(), itemStack -> itemStack.getType() == Material.AIR, false)); - - event = mock(PlayerInteractEvent.class); - when(event.getItem()).thenReturn(null); - Assertions.assertFalse(ObjUtil.nonNullOrElse(event.getItem(), itemStack -> itemStack.getType() == Material.AIR, false)); - } -} \ No newline at end of file diff --git a/threading/build.gradle.kts b/threading/build.gradle.kts new file mode 100644 index 00000000..655b18bb --- /dev/null +++ b/threading/build.gradle.kts @@ -0,0 +1,3 @@ +dependencies{ + api(project(":core")) +} diff --git a/src/main/java/de/eldoria/eldoutilities/scheduling/DelayedActions.java b/threading/src/main/java/de/eldoria/eldoutilities/scheduling/DelayedActions.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/scheduling/DelayedActions.java rename to threading/src/main/java/de/eldoria/eldoutilities/scheduling/DelayedActions.java diff --git a/src/main/java/de/eldoria/eldoutilities/scheduling/QueuingSelfSchedulingTask.java b/threading/src/main/java/de/eldoria/eldoutilities/scheduling/QueuingSelfSchedulingTask.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/scheduling/QueuingSelfSchedulingTask.java rename to threading/src/main/java/de/eldoria/eldoutilities/scheduling/QueuingSelfSchedulingTask.java index dff81263..8da063c1 100644 --- a/src/main/java/de/eldoria/eldoutilities/scheduling/QueuingSelfSchedulingTask.java +++ b/threading/src/main/java/de/eldoria/eldoutilities/scheduling/QueuingSelfSchedulingTask.java @@ -17,9 +17,9 @@ public abstract class QueuingSelfSchedulingTask extends ReschedulingTask { protected static final int DEFAULT_MAX_DURATION_TARGET = 50; // assuming 50ms = 1 tick protected static final int DEFAULT_MAX_IDLE_TICKS = 200; private final Queue tasks; - private int idleTicks; private final int maxIdleTicks; private final int maxDurationTarget; + private int idleTicks; public QueuingSelfSchedulingTask(Plugin plugin, int maxIdleTicks, int maxDurationTarget) { super(plugin); diff --git a/src/main/java/de/eldoria/eldoutilities/scheduling/SelfSchedulingWorker.java b/threading/src/main/java/de/eldoria/eldoutilities/scheduling/SelfSchedulingWorker.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/scheduling/SelfSchedulingWorker.java rename to threading/src/main/java/de/eldoria/eldoutilities/scheduling/SelfSchedulingWorker.java diff --git a/src/main/java/de/eldoria/eldoutilities/threading/IteratingTask.java b/threading/src/main/java/de/eldoria/eldoutilities/threading/IteratingTask.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/threading/IteratingTask.java rename to threading/src/main/java/de/eldoria/eldoutilities/threading/IteratingTask.java diff --git a/src/main/java/de/eldoria/eldoutilities/threading/ReschedulingTask.java b/threading/src/main/java/de/eldoria/eldoutilities/threading/ReschedulingTask.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/threading/ReschedulingTask.java rename to threading/src/main/java/de/eldoria/eldoutilities/threading/ReschedulingTask.java diff --git a/src/main/java/de/eldoria/eldoutilities/threading/TaskStatistics.java b/threading/src/main/java/de/eldoria/eldoutilities/threading/TaskStatistics.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/threading/TaskStatistics.java rename to threading/src/main/java/de/eldoria/eldoutilities/threading/TaskStatistics.java diff --git a/src/main/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResult.java b/threading/src/main/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResult.java similarity index 92% rename from src/main/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResult.java rename to threading/src/main/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResult.java index e13eadd0..1f1859b5 100644 --- a/src/main/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResult.java +++ b/threading/src/main/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResult.java @@ -6,7 +6,8 @@ package de.eldoria.eldoutilities.threading.futures; -import de.eldoria.eldoutilities.core.EldoUtilities; +import de.eldoria.EldoUtilities; +import org.bukkit.Bukkit; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -51,7 +52,7 @@ public void whenComplete(@NotNull Plugin plugin, @NotNull Consumer ca @Override public void whenComplete(@NotNull Plugin plugin, @NotNull Consumer callback) { whenComplete(plugin, callback, throwable -> - EldoUtilities.getInstanceOwner().getLogger().log(Level.SEVERE, "Exception in Future Result", throwable)); + Bukkit.getLogger().log(Level.SEVERE, "Exception in Future Result", throwable)); } @Override diff --git a/src/main/java/de/eldoria/eldoutilities/threading/futures/CompletableBukkitFuture.java b/threading/src/main/java/de/eldoria/eldoutilities/threading/futures/CompletableBukkitFuture.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/threading/futures/CompletableBukkitFuture.java rename to threading/src/main/java/de/eldoria/eldoutilities/threading/futures/CompletableBukkitFuture.java diff --git a/src/main/java/de/eldoria/eldoutilities/threading/futures/FutureResult.java b/threading/src/main/java/de/eldoria/eldoutilities/threading/futures/FutureResult.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/threading/futures/FutureResult.java rename to threading/src/main/java/de/eldoria/eldoutilities/threading/futures/FutureResult.java diff --git a/src/test/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResultTest.java b/threading/src/test/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResultTest.java similarity index 100% rename from src/test/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResultTest.java rename to threading/src/test/java/de/eldoria/eldoutilities/threading/futures/BukkitFutureResultTest.java diff --git a/updater/build.gradle.kts b/updater/build.gradle.kts new file mode 100644 index 00000000..2692ab62 --- /dev/null +++ b/updater/build.gradle.kts @@ -0,0 +1,4 @@ +dependencies{ + api(project(":core")) + api(project(":messaging")) +} diff --git a/src/main/java/de/eldoria/eldoutilities/updater/DefaultUpdateResponse.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/DefaultUpdateResponse.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/DefaultUpdateResponse.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/DefaultUpdateResponse.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/UpdateData.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/UpdateData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/UpdateData.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/UpdateData.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/UpdateDataBuilder.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/UpdateDataBuilder.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/UpdateDataBuilder.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/UpdateDataBuilder.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/UpdateResponse.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/UpdateResponse.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/UpdateResponse.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/UpdateResponse.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/Updater.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/Updater.java similarity index 96% rename from src/main/java/de/eldoria/eldoutilities/updater/Updater.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/Updater.java index 80b00644..92e2fde1 100644 --- a/src/main/java/de/eldoria/eldoutilities/updater/Updater.java +++ b/updater/src/main/java/de/eldoria/eldoutilities/updater/Updater.java @@ -15,10 +15,8 @@ import de.eldoria.eldoutilities.updater.notifier.UpdateNotifier; import de.eldoria.eldoutilities.updater.spigotupdater.SpigotUpdateChecker; import de.eldoria.eldoutilities.updater.spigotupdater.SpigotUpdateData; -import org.bukkit.Color; import org.bukkit.event.Listener; import org.bukkit.plugin.Plugin; -import org.bukkit.scheduler.BukkitRunnable; import java.net.http.HttpClient; import java.util.Optional; @@ -31,7 +29,7 @@ * * @param type of Updater */ -public abstract class Updater> extends BukkitRunnable implements Listener { +public abstract class Updater> implements Listener, Runnable { private final Plugin plugin; private final T data; private final HttpClient client = HttpClient.newBuilder().version(HttpClient.Version.HTTP_2).build(); @@ -155,7 +153,7 @@ protected boolean update() { /** * Start the update check thread. *

- * This will check every 6 hours if a update is available. + * This will check every 6 hours if an update is available. */ public void start() { executor.scheduleAtFixedRate(this, 0, 6, TimeUnit.HOURS); diff --git a/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateCheckResponse.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateCheckResponse.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateCheckResponse.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateCheckResponse.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateChecker.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateChecker.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateChecker.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateChecker.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateData.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateData.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateData.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateDataBuilder.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateDataBuilder.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateDataBuilder.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/butlerupdater/ButlerUpdateDataBuilder.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateChecker.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateChecker.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateChecker.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateChecker.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateData.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateData.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateData.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateDataBuilder.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateDataBuilder.java similarity index 80% rename from src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateDataBuilder.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateDataBuilder.java index 0bde4dff..7e555472 100644 --- a/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateDataBuilder.java +++ b/updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateDataBuilder.java @@ -18,10 +18,10 @@ public LynaUpdateDataBuilder(Plugin plugin, int productId) { super(plugin); this.productId = productId; updateMessage = """ - New version of §b{plugin_name}§r available. - New Version: §a{new_version}§r. Published §a{new_time}§r ago! {new_date_time} - Current version: §c{current_version}§r Published §c{current_time}§r ago! {current_date_time} - Download the new version via Discord: §b{website}""".stripIndent(); + New version of {plugin_name} available. + New Version: {new_version}. Published {new_time} ago! {new_date_time} + Current version: {current_version} Published §c{current_time} ago! {current_date_time} + Download the new version via Discord: {website}""".stripIndent(); } public LynaUpdateDataBuilder host(String host) { diff --git a/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateResponse.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateResponse.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateResponse.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/lynaupdater/LynaUpdateResponse.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/notifier/DownloadedNotifier.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/notifier/DownloadedNotifier.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/notifier/DownloadedNotifier.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/notifier/DownloadedNotifier.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/notifier/Notifier.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/notifier/Notifier.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/notifier/Notifier.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/notifier/Notifier.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/notifier/UpdateNotifier.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/notifier/UpdateNotifier.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/notifier/UpdateNotifier.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/notifier/UpdateNotifier.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateChecker.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateChecker.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateChecker.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateChecker.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateData.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateData.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateData.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateData.java diff --git a/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateDataBuilder.java b/updater/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateDataBuilder.java similarity index 100% rename from src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateDataBuilder.java rename to updater/src/main/java/de/eldoria/eldoutilities/updater/spigotupdater/SpigotUpdateDataBuilder.java