diff --git a/README.md b/README.md index f0b1704f..7861698c 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,15 @@ # [![HuskSync Banner](images/banner-graphic.png)](https://github.com/WiIIiam278/HuskSync) -![Github Actions](https://github.com/WiIIiam278/HuskSync/workflows/Java%20CI/badge.svg) -[![Discord](https://img.shields.io/discord/818135932103557162?color=7289da&logo=discord)](https://discord.gg/tVYhJfyDWG) +[![GitHub CI](https://img.shields.io/github/workflow/status/WiIIiam278/HuskSync/Java%20CI?logo=github)](https://github.com/WiIIiam278/HuskSync/actions/workflows/java_ci.yml) +[![JitPack API](https://img.shields.io/jitpack/version/net.william278/HuskSync?color=%2300fb9a&label=api&logo=gradle)](https://jitpack.io/#net.william278/HuskSync) +[![Support Discord](https://img.shields.io/discord/818135932103557162.svg?label=&logo=discord&logoColor=fff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/tVYhJfyDWG) -[Documentation, Guides & API](https://william278.net/docs/husksync/Home) · [Resource Page](https://www.spigotmc.org/resources/husksync.97144/) · [Bug Reports](https://github.com/WiIIiam278/HuskSync/issues) +[Documentation, Guides & API](https://william278.net/docs/husksync) · [Resource Page](https://www.spigotmc.org/resources/husksync.97144/) · [Bug Reports](https://github.com/WiIIiam278/HuskSync/issues) **HuskSync** is a modern, cross-server player data synchronisation system that enables the comprehensive synchronisation of your user's data across multiple proxied servers. It does this by making use of Redis and MySQL to optimally cache data while players change servers. ## Features +![Data snapshot viewer](images/data-snapshot-viewer.png) + - Synchronise inventories, ender chests, advancements, statistics, experience points, health, max health, hunger, saturation, potion effects, persistent data container tags, game mode, location and more across multiple proxied servers. - Create and manage "snapshot" backups of user data and roll back users to previous states on-the-fly. (`/userdata`) - Preview, list, delete, restore & pin user data snapshots in-game with an intuitive menu. @@ -23,7 +26,7 @@ 1. Place the plugin jar file in the `/plugins/` directory of each Spigot server. You do not need to install HuskSync as a proxy plugin. 2. Start, then stop every server to let HuskSync generate the config file. 3. Navigate to the HuskSync config file on each server (`~/plugins/HuskSync/config.yml`) and fill in both the MySQL and Redis database credentials. -4. Start every server again and synchronistaion will begin. +4. Start every server again and synchronization will begin. ## Building To build HuskSync, simply run the following in the root of the repository: @@ -52,7 +55,7 @@ This plugin uses bStats to provide me with metrics about its usage: You can turn metric collection off by navigating to `~/plugins/bStats/config.yml` and editing the config to disable plugin metrics. ## Links -- [Documentation, Guides & API](https://william278.net/docs/husksync/Home) +- [Documentation, Guides & API](https://william278.net/docs/husksync) - [Resource Page](https://www.spigotmc.org/resources/husksync.97144/) - [Bug Reports](https://github.com/WiIIiam278/HuskSync/issues) - [Discord Support](https://discord.gg/tVYhJfyDWG) (Proof of purchase required) diff --git a/build.gradle b/build.gradle index 275edfa9..d6a0883b 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ plugins { } group 'net.william278' -version "$ext.plugin_version+${versionMetadata()}" +version "$ext.plugin_version-${versionMetadata()}" ext { set 'version', version.toString() @@ -102,5 +102,5 @@ def versionMetadata() { if (grgit == null) { return System.getenv("GITHUB_RUN_NUMBER") ? 'build.' + System.getenv("GITHUB_RUN_NUMBER") : 'unknown' } - return 'rev.' + grgit.head().abbreviatedId + (grgit.status().clean ? '' : '-indev') + return grgit.head().abbreviatedId + (grgit.status().clean ? '' : '-indev') } \ No newline at end of file diff --git a/bukkit/build.gradle b/bukkit/build.gradle index 0942897a..5af21039 100644 --- a/bukkit/build.gradle +++ b/bukkit/build.gradle @@ -10,6 +10,7 @@ dependencies { compileOnly 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT' compileOnly 'dev.dejvokep:boosted-yaml:1.3' compileOnly 'com.zaxxer:HikariCP:5.0.1' + compileOnly 'net.william278:DesertWell:1.0' testImplementation 'org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT' } @@ -26,6 +27,7 @@ shadowJar { relocate 'org.intellij', 'net.william278.husksync.libraries' relocate 'com.zaxxer', 'net.william278.husksync.libraries' relocate 'dev.dejvokep', 'net.william278.husksync.libraries' + relocate 'net.william278.desertwell', 'net.william278.huskhomes.libraries.desertwell' relocate 'me.lucko.commodore', 'net.william278.husksync.libraries.commodore' relocate 'net.byteflux.libby', 'net.william278.husksync.libraries.libby' diff --git a/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java b/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java index 0d62b01b..5f566f5d 100644 --- a/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java +++ b/bukkit/src/main/java/net/william278/husksync/BukkitHuskSync.java @@ -6,6 +6,7 @@ import dev.dejvokep.boostedyaml.settings.dumper.DumperSettings; import dev.dejvokep.boostedyaml.settings.general.GeneralSettings; import dev.dejvokep.boostedyaml.settings.loader.LoaderSettings; import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings; +import net.william278.desertwell.Version; import net.william278.husksync.command.BukkitCommand; import net.william278.husksync.command.BukkitCommandType; import net.william278.husksync.command.Permission; @@ -28,7 +29,10 @@ import net.william278.husksync.migrator.MpdbMigrator; import net.william278.husksync.player.BukkitPlayer; import net.william278.husksync.player.OnlineUser; import net.william278.husksync.redis.RedisManager; -import net.william278.husksync.util.*; +import net.william278.husksync.util.BukkitLogger; +import net.william278.husksync.util.BukkitResourceReader; +import net.william278.husksync.util.Logger; +import net.william278.husksync.util.ResourceReader; import org.bstats.bukkit.Metrics; import org.bukkit.Bukkit; import org.bukkit.command.PluginCommand; @@ -127,7 +131,7 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync { getLoggingAdapter().log(Level.INFO, "Successfully established a connection to the database"); } else { throw new HuskSyncInitializationException("Failed to establish a connection to the database. " + - "Please check the supplied database credentials in the config file"); + "Please check the supplied database credentials in the config file"); } // Prepare redis connection @@ -138,7 +142,7 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync { getLoggingAdapter().log(Level.INFO, "Successfully established a connection to the Redis server"); } else { throw new HuskSyncInitializationException("Failed to establish a connection to the Redis server. " + - "Please check the supplied Redis credentials in the config file"); + "Please check the supplied Redis credentials in the config file"); } // Register events @@ -181,7 +185,10 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync { // Check for updates if (settings.getBooleanValue(Settings.ConfigOption.CHECK_FOR_UPDATES)) { getLoggingAdapter().log(Level.INFO, "Checking for updates..."); - CompletableFuture.runAsync(() -> new UpdateChecker(getPluginVersion(), getLoggingAdapter()).logToConsole()); + getLatestVersionIfOutdated().thenAccept(newestVersion -> + newestVersion.ifPresent(newVersion -> getLoggingAdapter().log(Level.WARNING, + "An update is available for HuskSync, v" + newVersion + + " (Currently running v" + getPluginVersion() + ")"))); } } catch (HuskSyncInitializationException exception) { getLoggingAdapter().log(Level.SEVERE, """ @@ -286,14 +293,16 @@ public class BukkitHuskSync extends JavaPlugin implements HuskSync { return resourceReader; } + @NotNull @Override - public @NotNull Version getPluginVersion() { - return Version.pluginVersion(getDescription().getVersion()); + public Version getPluginVersion() { + return Version.fromString(getDescription().getVersion(), "-"); } + @NotNull @Override - public @NotNull Version getMinecraftVersion() { - return Version.minecraftVersion(Bukkit.getBukkitVersion()); + public Version getMinecraftVersion() { + return Version.fromMinecraftVersionString(Bukkit.getBukkitVersion()); } @Override diff --git a/bukkit/src/main/java/net/william278/husksync/player/BukkitPlayer.java b/bukkit/src/main/java/net/william278/husksync/player/BukkitPlayer.java index d835d07f..e1503c60 100644 --- a/bukkit/src/main/java/net/william278/husksync/player/BukkitPlayer.java +++ b/bukkit/src/main/java/net/william278/husksync/player/BukkitPlayer.java @@ -6,7 +6,7 @@ import net.md_5.bungee.api.chat.BaseComponent; import net.william278.husksync.BukkitHuskSync; import net.william278.husksync.data.*; import net.william278.husksync.editor.ItemEditorMenu; -import net.william278.husksync.util.Version; +import net.william278.desertwell.Version; import org.bukkit.*; import org.bukkit.advancement.Advancement; import org.bukkit.advancement.AdvancementProgress; @@ -554,7 +554,7 @@ public class BukkitPlayer extends OnlineUser { @NotNull @Override public Version getMinecraftVersion() { - return Version.minecraftVersion(Bukkit.getBukkitVersion()); + return Version.fromMinecraftVersionString(Bukkit.getBukkitVersion()); } @Override diff --git a/common/build.gradle b/common/build.gradle index 9b94a48c..951a3f09 100644 --- a/common/build.gradle +++ b/common/build.gradle @@ -3,6 +3,7 @@ dependencies { implementation 'de.themoep:minedown:1.7.1-SNAPSHOT' implementation 'com.google.code.gson:gson:2.9.0' implementation 'dev.dejvokep:boosted-yaml:1.3' + implementation 'net.william278:DesertWell:1.0' implementation ('com.zaxxer:HikariCP:5.0.1') { exclude module: 'slf4j-api' } @@ -26,4 +27,5 @@ shadowJar { relocate 'org.intellij', 'net.william278.husksync.libraries' relocate 'com.zaxxer', 'net.william278.husksync.libraries' relocate 'dev.dejvokep', 'net.william278.husksync.libraries' + relocate 'net.william278.desertwell', 'net.william278.husksync.libraries.desertwell' } \ No newline at end of file diff --git a/common/src/main/java/net/william278/husksync/HuskSync.java b/common/src/main/java/net/william278/husksync/HuskSync.java index 7c20ddea..a3511160 100644 --- a/common/src/main/java/net/william278/husksync/HuskSync.java +++ b/common/src/main/java/net/william278/husksync/HuskSync.java @@ -1,5 +1,6 @@ package net.william278.husksync; +import net.william278.desertwell.UpdateChecker; import net.william278.husksync.config.Locales; import net.william278.husksync.config.Settings; import net.william278.husksync.data.DataAdapter; @@ -11,7 +12,7 @@ import net.william278.husksync.player.OnlineUser; import net.william278.husksync.redis.RedisManager; import net.william278.husksync.util.Logger; import net.william278.husksync.util.ResourceReader; -import net.william278.husksync.util.Version; +import net.william278.desertwell.Version; import org.jetbrains.annotations.NotNull; import java.util.List; @@ -25,6 +26,8 @@ import java.util.concurrent.CompletableFuture; */ public interface HuskSync { + int SPIGOT_RESOURCE_ID = 97144; + /** * Returns a set of online players. * @@ -131,6 +134,22 @@ public interface HuskSync { @NotNull Version getPluginVersion(); + /** + * Returns a future returning the latest plugin {@link Version} if the plugin is out-of-date + * + * @return a {@link CompletableFuture} returning the latest {@link Version} if the current one is out-of-date + */ + default CompletableFuture> getLatestVersionIfOutdated() { + final UpdateChecker updateChecker = UpdateChecker.create(getPluginVersion(), SPIGOT_RESOURCE_ID); + return updateChecker.isUpToDate().thenApply(upToDate -> { + if (upToDate) { + return Optional.empty(); + } else { + return Optional.of(updateChecker.getLatestVersion().join()); + } + }); + } + /** * Returns the Minecraft version implementation * diff --git a/common/src/main/java/net/william278/husksync/command/CommandBase.java b/common/src/main/java/net/william278/husksync/command/CommandBase.java index c13038ae..e7aac53c 100644 --- a/common/src/main/java/net/william278/husksync/command/CommandBase.java +++ b/common/src/main/java/net/william278/husksync/command/CommandBase.java @@ -52,7 +52,7 @@ public abstract class CommandBase { */ public String getDescription() { return plugin.getLocales().getRawLocale(command + "_command_description") - .orElse("A HuskHomes command"); + .orElse("A HuskSync command"); } } diff --git a/common/src/main/java/net/william278/husksync/command/HuskSyncCommand.java b/common/src/main/java/net/william278/husksync/command/HuskSyncCommand.java index 02bfd1f5..f6a5fe89 100644 --- a/common/src/main/java/net/william278/husksync/command/HuskSyncCommand.java +++ b/common/src/main/java/net/william278/husksync/command/HuskSyncCommand.java @@ -1,11 +1,10 @@ package net.william278.husksync.command; import de.themoep.minedown.MineDown; +import net.william278.desertwell.AboutMenu; import net.william278.husksync.HuskSync; -import net.william278.husksync.config.Locales; import net.william278.husksync.migrator.Migrator; import net.william278.husksync.player.OnlineUser; -import net.william278.husksync.util.UpdateChecker; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -17,16 +16,41 @@ import java.util.stream.Collectors; public class HuskSyncCommand extends CommandBase implements TabCompletable, ConsoleExecutable { - private final String[] COMMAND_ARGUMENTS = {"update", "about", "reload", "migrate"}; + private final String[] SUB_COMMANDS = {"update", "about", "reload", "migrate"}; + private final AboutMenu aboutMenu; public HuskSyncCommand(@NotNull HuskSync implementor) { super("husksync", Permission.COMMAND_HUSKSYNC, implementor); + this.aboutMenu = AboutMenu.create("HuskSync") + .withDescription("A modern, cross-server player data synchronization system") + .withVersion(implementor.getPluginVersion()) + .addAttribution("Author", + AboutMenu.Credit.of("William278").withDescription("Click to visit website").withUrl("https://william278.net")) + .addAttribution("Contributors", + AboutMenu.Credit.of("HarvelsX").withDescription("Code"), + AboutMenu.Credit.of("HookWoods").withDescription("Code")) + .addAttribution("Translators", + AboutMenu.Credit.of("Namiu").withDescription("Japanese (ja-jp)"), + AboutMenu.Credit.of("anchelthe").withDescription("Spanish (es-es)"), + AboutMenu.Credit.of("Melonzio").withDescription("Spanish (es-es)"), + AboutMenu.Credit.of("Ceddix").withDescription("German (de-de)"), + AboutMenu.Credit.of("Pukejoy_1").withDescription("Bulgarian (bg-bg)"), + AboutMenu.Credit.of("mateusneresrb").withDescription("Brazilian Portuguese (pt-br)"), + AboutMenu.Credit.of("小蔡").withDescription("Traditional Chinese (zh-tw)"), + AboutMenu.Credit.of("Ghost-chu").withDescription("Simplified Chinese (zh-cn)"), + AboutMenu.Credit.of("DJelly4K").withDescription("Simplified Chinese (zh-cn)"), + AboutMenu.Credit.of("Thourgard").withDescription("Ukrainian (uk-ua)"), + AboutMenu.Credit.of("xF3d3").withDescription("Italian (it-it)")) + .addButtons( + AboutMenu.Link.of("https://william278.net/docs/husksync").withText("Documentation").withIcon("⛏"), + AboutMenu.Link.of("https://github.com/WiIIiam278/HuskSync/issues").withText("Issues").withIcon("❌").withColor("#ff9f0f"), + AboutMenu.Link.of("https://discord.gg/tVYhJfyDWG").withText("Discord").withIcon("⭐").withColor("#6773f5")); } @Override public void onExecute(@NotNull OnlineUser player, @NotNull String[] args) { if (args.length < 1) { - displayPluginInformation(player); + sendAboutMenu(player); return; } switch (args[0].toLowerCase()) { @@ -35,18 +59,16 @@ public class HuskSyncCommand extends CommandBase implements TabCompletable, Cons plugin.getLocales().getLocale("error_no_permission").ifPresent(player::sendMessage); return; } - final UpdateChecker updateChecker = new UpdateChecker(plugin.getPluginVersion(), plugin.getLoggingAdapter()); - updateChecker.fetchLatestVersion().thenAccept(latestVersion -> { - if (updateChecker.isUpdateAvailable(latestVersion)) { - player.sendMessage(new MineDown("[HuskSync](#00fb9a bold) [| A new update is available:](#00fb9a) [HuskSync " + latestVersion + "](#00fb9a bold)" + - "[•](white) [Currently running:](#00fb9a) [Version " + updateChecker.getCurrentVersion() + "](gray)" + - "[•](white) [Download links:](#00fb9a) [[⏩ Spigot]](gray open_url=https://www.spigotmc.org/resources/husksync.97144/updates) [•](#262626) [[⏩ Polymart]](gray open_url=https://polymart.org/resource/husksync.1634/updates) [•](#262626) [[⏩ Songoda]](gray open_url=https://songoda.com/marketplace/product/husksync-a-modern-cross-server-player-data-synchronization-system.758)")); - } else { - player.sendMessage(new MineDown("[HuskSync](#00fb9a bold) [| HuskSync is up-to-date, running version " + updateChecker.getCurrentVersion() + "](#00fb9a)")); - } - }); + plugin.getLatestVersionIfOutdated().thenAccept(newestVersion -> + newestVersion.ifPresentOrElse( + newVersion -> player.sendMessage( + new MineDown("[HuskSync](#00fb9a bold) [| A new version of HuskSync is available!" + + " (v" + newVersion + " (Running: v" + plugin.getPluginVersion() + ")](#00fb9a)")), + () -> player.sendMessage( + new MineDown("[HuskSync](#00fb9a bold) [| HuskSync is up-to-date." + + " (Running: v" + plugin.getPluginVersion() + ")](#00fb9a)")))); } - case "info", "about" -> displayPluginInformation(player); + case "about", "info" -> sendAboutMenu(player); case "reload" -> { if (!player.hasPermission(Permission.COMMAND_HUSKSYNC_RELOAD.node)) { plugin.getLocales().getLocale("error_no_permission").ifPresent(player::sendMessage); @@ -70,11 +92,14 @@ public class HuskSyncCommand extends CommandBase implements TabCompletable, Cons return; } switch (args[0].toLowerCase()) { - case "update", "version" -> - new UpdateChecker(plugin.getPluginVersion(), plugin.getLoggingAdapter()).logToConsole(); - case "info", "about" -> - plugin.getLoggingAdapter().log(Level.INFO, new MineDown(plugin.getLocales().stripMineDown( - Locales.PLUGIN_INFORMATION.replace("%version%", plugin.getPluginVersion().toString())))); + case "update", "version" -> plugin.getLatestVersionIfOutdated().thenAccept(newestVersion -> + newestVersion.ifPresentOrElse(newVersion -> plugin.getLoggingAdapter().log(Level.WARNING, + "An update is available for HuskSync, v" + newVersion + + " (Running v" + plugin.getPluginVersion() + ")"), + () -> plugin.getLoggingAdapter().log(Level.INFO, + "HuskSync is up to date" + + " (Running v" + plugin.getPluginVersion() + ")"))); + case "about", "info" -> aboutMenu.toString().lines().forEach(plugin.getLoggingAdapter()::info); case "reload" -> { plugin.reload(); plugin.getLoggingAdapter().log(Level.INFO, "Reloaded config & message files."); @@ -108,7 +133,7 @@ public class HuskSyncCommand extends CommandBase implements TabCompletable, Cons }, () -> { plugin.getLoggingAdapter().log(Level.INFO, "Please specify a valid migrator.\n" + - "If a migrator is not available, please verify that you meet the prerequisites to use it."); + "If a migrator is not available, please verify that you meet the prerequisites to use it."); logMigratorsList(); }); } @@ -120,26 +145,26 @@ public class HuskSyncCommand extends CommandBase implements TabCompletable, Cons private void logMigratorsList() { plugin.getLoggingAdapter().log(Level.INFO, "List of available migrators:\nMigrator ID / Migrator Name:\n" + - plugin.getAvailableMigrators().stream() - .map(migrator -> migrator.getIdentifier() + " - " + migrator.getName()) - .collect(Collectors.joining("\n"))); + plugin.getAvailableMigrators().stream() + .map(migrator -> migrator.getIdentifier() + " - " + migrator.getName()) + .collect(Collectors.joining("\n"))); } @Override public List onTabComplete(@NotNull String[] args) { if (args.length <= 1) { - return Arrays.stream(COMMAND_ARGUMENTS) + return Arrays.stream(SUB_COMMANDS) .filter(argument -> argument.startsWith(args.length >= 1 ? args[0] : "")) .sorted().collect(Collectors.toList()); } return Collections.emptyList(); } - private void displayPluginInformation(@NotNull OnlineUser player) { - if (!player.hasPermission(Permission.COMMAND_HUSKSYNC_INFO.node)) { + private void sendAboutMenu(@NotNull OnlineUser player) { + if (!player.hasPermission(Permission.COMMAND_HUSKSYNC_ABOUT.node)) { plugin.getLocales().getLocale("error_no_permission").ifPresent(player::sendMessage); return; } - player.sendMessage(new MineDown(Locales.PLUGIN_INFORMATION.replace("%version%", plugin.getPluginVersion().toString()))); + player.sendMessage(aboutMenu.toMineDown()); } } diff --git a/common/src/main/java/net/william278/husksync/command/Permission.java b/common/src/main/java/net/william278/husksync/command/Permission.java index 4e7dba78..344b3666 100644 --- a/common/src/main/java/net/william278/husksync/command/Permission.java +++ b/common/src/main/java/net/william278/husksync/command/Permission.java @@ -18,7 +18,7 @@ public enum Permission { /** * Lets the user view plugin info {@code /husksync info} */ - COMMAND_HUSKSYNC_INFO("husksync.command.husksync.info", DefaultAccess.EVERYONE), + COMMAND_HUSKSYNC_ABOUT("husksync.command.husksync.info", DefaultAccess.EVERYONE), /** * Lets the user reload the plugin {@code /husksync reload} */ diff --git a/common/src/main/java/net/william278/husksync/config/Locales.java b/common/src/main/java/net/william278/husksync/config/Locales.java index e2f281e8..cf5c3deb 100644 --- a/common/src/main/java/net/william278/husksync/config/Locales.java +++ b/common/src/main/java/net/william278/husksync/config/Locales.java @@ -6,7 +6,6 @@ import org.jetbrains.annotations.NotNull; import java.util.HashMap; import java.util.Optional; -import java.util.regex.Matcher; import java.util.regex.Pattern; /** @@ -14,16 +13,6 @@ import java.util.regex.Pattern; */ public class Locales { - public static final String PLUGIN_INFORMATION = """ - [HuskSync](#00fb9a bold) [| Version %version%](#00fb9a) - [A modern, cross-server player data synchronization system](gray) - [• Author:](white) [William278](gray show_text=&7Click to visit website open_url=https://william278.net) - [• Contributors:](white) [HarvelsX](gray show_text=&7Code), [HookWoods](gray show_text=&7Code) - [• Translators:](white) [Namiu](gray show_text=&7\\(うにたろう\\) - Japanese, ja-jp), [anchelthe](gray show_text=&7Spanish, es-es), [Melonzio](gray show_text=&7Spanish, es-es), [Ceddix](gray show_text=&7German, de-de), [Pukejoy_1](gray show_text=&7Bulgarian, bg-bg), [mateusneresrb](gray show_text=&7Brazilian Portuguese, pt-br], [小蔡](gray show_text=&7Traditional Chinese, zh-tw), [Ghost-chu](gray show_text=&7Simplified Chinese, zh-cn), [DJelly4K](gray show_text=&7Simplified Chinese, zh-cn), [Thourgard](gray show_text=&7Ukrainian, uk-ua), [xF3d3](gray show_text=&7Italian, it-it) - [• Documentation:](white) [[Link]](#00fb9a show_text=&7Click to open link open_url=https://william278.net/docs/husksync/Home/) - [• Bug reporting:](white) [[Link]](#00fb9a show_text=&7Click to open link open_url=https://github.com/WiIIiam278/HuskSync/issues) - [• Discord support:](white) [[Link]](#00fb9a show_text=&7Click to join open_url=https://discord.gg/tVYhJfyDWG)"""; - @NotNull private final HashMap rawLocales; @@ -106,34 +95,4 @@ public class Locales { return new Locales(localesConfig); } - /** - * Strips a string of basic MineDown formatting, used for displaying plugin info to console - * - * @param string The string to strip - * @return The MineDown-stripped string - */ - public String stripMineDown(@NotNull String string) { - final String[] in = string.split("\n"); - final StringBuilder out = new StringBuilder(); - String regex = "[^\\[\\]() ]*\\[([^()]+)]\\([^()]+open_url=(\\S+).*\\)"; - - for (int i = 0; i < in.length; i++) { - Pattern pattern = Pattern.compile(regex); - Matcher m = pattern.matcher(in[i]); - - if (m.find()) { - out.append(in[i].replace(m.group(0), "")); - out.append(m.group(2)); - } else { - out.append(in[i]); - } - - if (i + 1 != in.length) { - out.append("\n"); - } - } - - return out.toString(); - } - } diff --git a/common/src/main/java/net/william278/husksync/player/OnlineUser.java b/common/src/main/java/net/william278/husksync/player/OnlineUser.java index d3e08903..a28a35d8 100644 --- a/common/src/main/java/net/william278/husksync/player/OnlineUser.java +++ b/common/src/main/java/net/william278/husksync/player/OnlineUser.java @@ -7,7 +7,7 @@ import net.william278.husksync.editor.ItemEditorMenu; import net.william278.husksync.event.EventCannon; import net.william278.husksync.event.PreSyncEvent; import net.william278.husksync.util.Logger; -import net.william278.husksync.util.Version; +import net.william278.desertwell.Version; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -176,7 +176,7 @@ public abstract class OnlineUser extends User { @NotNull Version serverMinecraftVersion) { return CompletableFuture.supplyAsync(() -> { // Prevent synchronising user data from newer versions of Minecraft - if (Version.minecraftVersion(data.getMinecraftVersion()).compareTo(serverMinecraftVersion) > 0) { + if (Version.fromMinecraftVersionString(data.getMinecraftVersion()).compareTo(serverMinecraftVersion) > 0) { logger.log(Level.SEVERE, "Cannot set data for " + username + " because the Minecraft version of their user data (" + data.getMinecraftVersion() + ") is newer than the server's Minecraft version (" + serverMinecraftVersion + ")."); diff --git a/common/src/main/java/net/william278/husksync/util/UpdateChecker.java b/common/src/main/java/net/william278/husksync/util/UpdateChecker.java deleted file mode 100644 index 4d9f48ad..00000000 --- a/common/src/main/java/net/william278/husksync/util/UpdateChecker.java +++ /dev/null @@ -1,57 +0,0 @@ -package net.william278.husksync.util; - -import org.jetbrains.annotations.NotNull; - -import java.io.BufferedReader; -import java.io.InputStreamReader; -import java.net.URL; -import java.net.URLConnection; -import java.util.concurrent.CompletableFuture; -import java.util.logging.Level; - -public class UpdateChecker { - - private final static int SPIGOT_PROJECT_ID = 97144; - private final Logger logger; - private final Version currentVersion; - - public UpdateChecker(@NotNull Version currentVersion, @NotNull Logger logger) { - this.currentVersion = currentVersion; - this.logger = logger; - } - - public CompletableFuture fetchLatestVersion() { - return CompletableFuture.supplyAsync(() -> { - try { - final URL url = new URL("https://api.spigotmc.org/legacy/update.php?resource=" + SPIGOT_PROJECT_ID); - URLConnection urlConnection = url.openConnection(); - return Version.pluginVersion(new BufferedReader(new InputStreamReader(urlConnection.getInputStream())).readLine()); - } catch (Exception e) { - logger.log(Level.WARNING, "Failed to fetch the latest plugin version", e); - } - return new Version(); - }); - } - - public boolean isUpdateAvailable(@NotNull Version latestVersion) { - return latestVersion.compareTo(currentVersion) > 0; - } - - public Version getCurrentVersion() { - return currentVersion; - } - - public CompletableFuture isUpToDate() { - return fetchLatestVersion().thenApply(this::isUpdateAvailable); - } - - public void logToConsole() { - fetchLatestVersion().thenAccept(latestVersion -> { - if (isUpdateAvailable(latestVersion)) { - logger.log(Level.WARNING, "A new version of HuskSync is available: v" + latestVersion); - } else { - logger.log(Level.INFO, "HuskSync is up-to-date! (Running: v" + getCurrentVersion().toString() + ")"); - } - }); - } -} \ No newline at end of file diff --git a/common/src/main/java/net/william278/husksync/util/Version.java b/common/src/main/java/net/william278/husksync/util/Version.java deleted file mode 100644 index d93cc8e8..00000000 --- a/common/src/main/java/net/william278/husksync/util/Version.java +++ /dev/null @@ -1,71 +0,0 @@ -package net.william278.husksync.util; - -import org.jetbrains.annotations.NotNull; - -import java.util.Arrays; -import java.util.StringJoiner; -import java.util.regex.Pattern; - -public class Version implements Comparable { - private final static String VERSION_SEPARATOR = "."; - private final static String MINECRAFT_META_SEPARATOR = "-"; - private final static String PLUGIN_META_SEPARATOR = "+"; - - private int[] versions = new int[]{}; - @NotNull - private String metadata = ""; - @NotNull - private String metaSeparator = ""; - - protected Version() { - } - - private Version(@NotNull String version, @NotNull String metaSeparator) { - this.parse(version, metaSeparator); - this.metaSeparator = metaSeparator; - } - - @NotNull - public static Version pluginVersion(@NotNull String versionString) { - return new Version(versionString, PLUGIN_META_SEPARATOR); - } - - @NotNull - public static Version minecraftVersion(@NotNull String versionString) { - return new Version(versionString, MINECRAFT_META_SEPARATOR); - } - - private void parse(@NotNull String version, @NotNull String metaSeparator) { - int metaIndex = version.indexOf(metaSeparator); - if (metaIndex > 0) { - this.metadata = version.substring(metaIndex + 1); - version = version.substring(0, metaIndex); - } - String[] versions = version.split(Pattern.quote(VERSION_SEPARATOR)); - this.versions = Arrays.stream(versions).mapToInt(Integer::parseInt).toArray(); - } - - @Override - public int compareTo(@NotNull Version other) { - int length = Math.max(this.versions.length, other.versions.length); - for (int i = 0; i < length; i++) { - int a = i < this.versions.length ? this.versions[i] : 0; - int b = i < other.versions.length ? other.versions[i] : 0; - - if (a < b) return -1; - if (a > b) return 1; - } - - return 0; - } - - @Override - public String toString() { - final StringJoiner joiner = new StringJoiner(VERSION_SEPARATOR); - for (int version : this.versions) { - joiner.add(String.valueOf(version)); - } - return joiner + ((!this.metadata.isEmpty()) ? (this.metaSeparator + this.metadata) : ""); - } - -} diff --git a/common/src/test/java/net/william278/husksync/player/DummyPlayer.java b/common/src/test/java/net/william278/husksync/player/DummyPlayer.java index c8cb46c3..06bfdd69 100644 --- a/common/src/test/java/net/william278/husksync/player/DummyPlayer.java +++ b/common/src/test/java/net/william278/husksync/player/DummyPlayer.java @@ -3,7 +3,7 @@ package net.william278.husksync.player; import de.themoep.minedown.MineDown; import net.william278.husksync.data.*; import net.william278.husksync.editor.ItemEditorMenu; -import net.william278.husksync.util.Version; +import net.william278.desertwell.Version; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -132,7 +132,7 @@ public class DummyPlayer extends OnlineUser { @NotNull @Override public Version getMinecraftVersion() { - return Version.minecraftVersion("1.19-beta123456"); + return Version.fromMinecraftVersionString("1.19-beta123456"); } @Override diff --git a/gradle.properties b/gradle.properties index 1928bb97..d2bffd12 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,7 +3,7 @@ org.gradle.jvmargs='-Dfile.encoding=UTF-8' org.gradle.daemon=true javaVersion=16 -plugin_version=2.0.2 +plugin_version=2.1 plugin_archive=husksync jedis_version=4.2.3