diff --git a/README.md b/README.md index 8e23616..03d5964 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![Static Badge](https://img.shields.io/badge/MC-1.18-green) ![Static Badge](https://img.shields.io/badge/MC-1.19-green) ![Static Badge](https://img.shields.io/badge/MC-1.20-green) -![Static Badge](https://img.shields.io/badge/MC-1.21-green) +![Static Badge](https://img.shields.io/badge/MC-1.21.x-green) ![Modrinth Downloads](https://img.shields.io/modrinth/dt/km0yAITg?logo=Modrinth&style=flat-square) @@ -42,6 +42,10 @@ This is a Minecraft plugin for Spigot/Paper servers that allows players to set t - The Plugin got Placeholders: - `%tubsstatusplugin_status_playername%` (playname should be changed out for the real Playername, Duuuh.) - `%tubsstatusplugin_status%` +- The Plugin Supports `LuckPerms v5.4` + - The Plugin supports LuckPerms prefix and suffix. + - `%LP_prefix&%` + - `%LP_suffix%` - Groupmode - turn on Group Mode in the Config and preconfigure set Groups for Players - A Player will not be able to set a fully custom status but he can use one of the preconfigured Groups. diff --git a/pom.xml b/pom.xml index a722e2d..fd5a6da 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ de.tubyoub StatusPlugin - 1.4.1 + 1.5 jar Tub's Status Plugin @@ -95,6 +95,12 @@ 2.11.5 provided + + net.luckperms + api + 5.4 + provided + dev.dejvokep boosted-yaml diff --git a/src/main/java/de/tubyoub/statusplugin/Listener/PlayerJoinListener.java b/src/main/java/de/tubyoub/statusplugin/Listener/PlayerJoinListener.java index 5f26889..899d5fa 100644 --- a/src/main/java/de/tubyoub/statusplugin/Listener/PlayerJoinListener.java +++ b/src/main/java/de/tubyoub/statusplugin/Listener/PlayerJoinListener.java @@ -2,6 +2,11 @@ import de.tubyoub.statusplugin.Managers.StatusManager; import de.tubyoub.statusplugin.StatusPlugin; +import de.tubyoub.utils.VersionChecker; +import de.tubyoub.utils.VersionChecker.UpdateUrgency; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.TextComponent; +import org.bukkit.ChatColor; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.Listener; @@ -14,18 +19,23 @@ public class PlayerJoinListener implements Listener { private final StatusManager statusManager; private final StatusPlugin plugin; + private final VersionChecker.VersionInfo versionInfo; + /** * Constructor for the PlayerJoinListener class. + * * @param statusManager The StatusManager instance used to manage player statuses. */ public PlayerJoinListener(StatusPlugin plugin, StatusManager statusManager) { this.statusManager = statusManager; this.plugin = plugin; + this.versionInfo = plugin.getVersionInfo(); } /** * Event handler for player join events. * When a player joins, their display name is updated based on their status. + * * @param event The PlayerJoinEvent to be handled. */ @EventHandler @@ -34,5 +44,23 @@ public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); statusManager.updateDisplayName(player); } + Player player = event.getPlayer(); + // Check if the player has admin privileges + if (player.hasPermission("StatusPlugin.admin") && plugin.getConfigManager().isCheckUpdate()) { + // Alert if a critical update is available + if (this.versionInfo.isNewVersionAvailable && this.versionInfo.urgency == UpdateUrgency.CRITICAL || this.versionInfo.urgency == UpdateUrgency.HIGH) { + player.sendMessage(plugin.getPluginPrefix() + ChatColor.RED + "A critical update for BT Grave is available!"); + player.sendMessage(plugin.getPluginPrefix() + ChatColor.RED + "Please update to version: " + this.versionInfo.latestVersion); + player.sendMessage(plugin.getPluginPrefix() + ChatColor.RED + "Backup your config"); + // only works this way and idk why + TextComponent modrinthLink = new TextComponent(ChatColor.GREEN + "" + ChatColor.UNDERLINE + "Modrinth"); + modrinthLink.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, "https://modrinth.com/plugin/bt-graves/version/" + this.versionInfo.latestVersion)); + modrinthLink.setUnderlined(true); + TextComponent message = new TextComponent(plugin.getPluginPrefix() + ChatColor.RED + "Download the new version now from "); + message.addExtra(modrinthLink); + + player.spigot().sendMessage(message); + } + } } } \ No newline at end of file diff --git a/src/main/java/de/tubyoub/statusplugin/Managers/ConfigManager.java b/src/main/java/de/tubyoub/statusplugin/Managers/ConfigManager.java index 336a891..dd3b241 100644 --- a/src/main/java/de/tubyoub/statusplugin/Managers/ConfigManager.java +++ b/src/main/java/de/tubyoub/statusplugin/Managers/ConfigManager.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.MergeRule; import dev.dejvokep.boostedyaml.settings.updater.UpdaterSettings; import java.io.File; @@ -17,6 +18,7 @@ public class ConfigManager { private YamlDocument config; private int maxStatusLength; + private boolean checkUpdate; private boolean chatFormatter; private boolean tablistFormatter; private boolean groupMode; @@ -37,9 +39,15 @@ public void loadConfig() { LoaderSettings.builder().setAutoUpdate(true).build(), DumperSettings.DEFAULT, UpdaterSettings.builder().setVersioning(new BasicVersioning("fileversion")) - .setOptionSorting(UpdaterSettings.OptionSorting.SORT_BY_DEFAULTS).build()); + .setOptionSorting(UpdaterSettings.OptionSorting.SORT_BY_DEFAULTS) + .setMergeRule(MergeRule.MAPPINGS, true) + .setMergeRule(MergeRule.MAPPING_AT_SECTION, true) + .setMergeRule(MergeRule.SECTION_AT_MAPPING, true) + .setKeepAll(true) + .build()); maxStatusLength = config.getInt("maxStatusLength", 15); + checkUpdate = config.getBoolean("checkUpdate", true); chatFormatter = config.getBoolean("chatFormatter", true); tablistFormatter = config.getBoolean("changeTablistNames", true); groupMode = config.getBoolean("groupMode", false); @@ -108,6 +116,10 @@ public void resetMaxStatusLength() { saveConfig(); } + public boolean isCheckUpdate() { + return checkUpdate; + } + public boolean isGroupMode() { return groupMode; } diff --git a/src/main/java/de/tubyoub/statusplugin/Managers/StatusManager.java b/src/main/java/de/tubyoub/statusplugin/Managers/StatusManager.java index f37632b..a9ff61b 100644 --- a/src/main/java/de/tubyoub/statusplugin/Managers/StatusManager.java +++ b/src/main/java/de/tubyoub/statusplugin/Managers/StatusManager.java @@ -13,6 +13,7 @@ import java.io.IOException; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -119,8 +120,12 @@ public String getStatus(Player player) { public void updateDisplayName(Player player) { String status = getStatus(player); - if (status != null) { + if (status != "") { String translatedStatus = translateColorsAndFormatting(status, player); + if (plugin.isLuckPermsPresent() && player.hasPermission("StatusPlugin.placeholders")) { + translatedStatus.replace("%LP_prefix%", Objects.requireNonNull(plugin.getLuckPerms().getPlayerAdapter(Player.class).getUser(player).getCachedData().getMetaData().getPrefix())); + translatedStatus.replace("%LP_suffix%", Objects.requireNonNull(plugin.getLuckPerms().getPlayerAdapter(Player.class).getUser(player).getCachedData().getMetaData().getSuffix())); + } if (placeholderAPIPresent && player.hasPermission("StatusPlugin.placeholders")) { translatedStatus = PlaceholderAPI.setPlaceholders(player, translatedStatus); } diff --git a/src/main/java/de/tubyoub/statusplugin/StatusPlugin.java b/src/main/java/de/tubyoub/statusplugin/StatusPlugin.java index 78ae5a4..d3fa71f 100644 --- a/src/main/java/de/tubyoub/statusplugin/StatusPlugin.java +++ b/src/main/java/de/tubyoub/statusplugin/StatusPlugin.java @@ -10,27 +10,31 @@ import de.tubyoub.statusplugin.commands.tabCompleter.StatusTabCompleter; import de.tubyoub.utils.VersionChecker; import de.tubyoub.statusplugin.metrics.Metrics; +import net.luckperms.api.LuckPerms; import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.plugin.java.JavaPlugin; -import java.util.ArrayList; - /** * Main class for the StatusPlugin. * This class extends JavaPlugin and represents the main entry point for the plugin. */ public class StatusPlugin extends JavaPlugin { - private final String version = "1.4.1"; + private final String version = "1.5"; + private final String project = "km0yAITg"; + private int pluginId = 20463; private StatusManager statusManager; private VersionChecker versionChecker; private boolean placeholderAPIPresent = false; private ConfigManager configManager; private StatusPlaceholderExpansion placeholderExpansion; private boolean newVersion; - private int pluginId = 20463; + private VersionChecker.VersionInfo versionInfo; + private LuckPerms luckPerms; + private boolean luckPermsPresent = false; + /** * This method is called when the plugin is enabled. @@ -50,9 +54,44 @@ public void onEnable() { configManager.loadConfig(); // Initialize the StatusManager and VersionChecker - this.statusManager = new StatusManager(this); - this.versionChecker = new VersionChecker(); - newVersion = VersionChecker.isNewVersionAvailable(version); + if (configManager.isCheckUpdate()) { + versionInfo = VersionChecker.isNewVersionAvailable(version, project); + if (versionInfo.isNewVersionAvailable) { + switch (versionInfo.urgency) { + case CRITICAL: + this.getLogger().warning("--- Important Update --- "); + this.getLogger().warning("There is a new critical update for Tubs Status Plugin available"); + this.getLogger().warning("please update NOW"); + this.getLogger().warning("https://modrinth.com/plugin/tubs-status-plugin/version/" + versionInfo.latestVersion); + this.getLogger().warning("backup your config"); + this.getLogger().warning("---"); + break; + case HIGH: + this.getLogger().warning("--- Important Update --- "); + this.getLogger().warning("There is a new critical update for Tubs Status Plugin available"); + this.getLogger().warning("please update NOW"); + this.getLogger().warning("https://modrinth.com/plugin/tubs-status-plugin/version/" + versionInfo.latestVersion); + this.getLogger().warning("backup your config"); + this.getLogger().warning("---"); + break; + case NORMAL: + this.getLogger().warning("There is a new update for Tubs Status Plugin available"); + this.getLogger().warning("https://modrinth.com/plugin/tubs-status-plugin/version/" + versionInfo.latestVersion); + this.getLogger().warning("backup your config"); + break; + case LOW: + // beta update urgency currently not needed + break; + case NONE: + // alpha update urgency currently not needed + break; + } + } else { + this.getLogger().info(" You are running the latest version of Tubs Status Plugin"); + } + } else { + this.getLogger().info("You have automatic checks for new updates disabled. Enable them in the config to stay up to date"); + } // Register the PlayerJoinListener and ChatListener getServer().getPluginManager().registerEvents(new PlayerJoinListener(this ,this.statusManager), this); @@ -80,6 +119,14 @@ public void onEnable() { getLogger().warning("Could not find PlaceholderAPI! Tub's StatusPlugin will run without it.."); } + if (Bukkit.getPluginManager().getPlugin("LuckPerms") != null) { + this.luckPerms = getServer().getServicesManager().load(LuckPerms.class); + luckPermsPresent = true; + getLogger().info("Tub's StatusPlugin will now hook into LuckPerms"); + } else { + getLogger().warning("Could not find LuckPerms! Tub's StatusPlugin will run without it.."); + } + // Schedule a task to update the display name of online players every 30 seconds if (configManager.isTablistFormatter()) { Bukkit.getScheduler().runTaskTimer(this, () -> { @@ -134,6 +181,15 @@ public StatusManager getStatusManager(){ public boolean isPlaceholderAPIPresent() { return placeholderAPIPresent; } + public VersionChecker.VersionInfo getVersionInfo() { + return versionInfo; + } + public LuckPerms getLuckPerms() { + return luckPerms; + } + public boolean isLuckPermsPresent() { + return luckPermsPresent; + } /** * This method is called when the plugin is disabled. * It saves the statuses. diff --git a/src/main/java/de/tubyoub/utils/VersionChecker.java b/src/main/java/de/tubyoub/utils/VersionChecker.java index 75b10df..71f001b 100644 --- a/src/main/java/de/tubyoub/utils/VersionChecker.java +++ b/src/main/java/de/tubyoub/utils/VersionChecker.java @@ -17,21 +17,20 @@ * Class responsible for checking if a new version of the plugin is available. */ public class VersionChecker { - private static final String project = "km0yAITg"; + public VersionChecker(){} /** * Checks if a new version of the plugin is available. * @param version The current version of the plugin. * @return A boolean indicating whether a new version is available. */ - public static boolean isNewVersionAvailable(String version) { + public static VersionInfo isNewVersionAvailable(String version, String project) { try { URL url = new URL("https://api.modrinth.com/v2/project/" + project + "/version"); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("GET"); - - connection.setRequestProperty("User-Agent", "TubYoub/StatusPlugin/"+ version +" (github@tubyoub.de)"); + connection.setRequestProperty("User-Agent", "BTPluginz/TubsStatusPlugin/"+ version + " (github@tubyoub.de)"); int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { @@ -40,21 +39,62 @@ public static boolean isNewVersionAvailable(String version) { List> versions = parseJsonArray(jsonResponse); if (!versions.isEmpty()) { - String latestVersion = (String) versions.get(0).get("version_number"); + Map latestVersion = versions.get(0); + String latestVersionNumber = (String) latestVersion.get("version_number"); + String changelog = (String) latestVersion.get("changelog"); + String versionType = (String) latestVersion.get("version_type"); - String currentVersion = version; - return !latestVersion.equals(currentVersion); - } else { - return false; + if (!latestVersionNumber.equals(version)) { + UpdateUrgency urgency = determineUrgency(changelog, versionType); + return new VersionInfo(true, latestVersionNumber, changelog, urgency); + } else { + return new VersionInfo(false, version, null, UpdateUrgency.NONE); + } } } - } else { - return false; } } catch (IOException e) { e.printStackTrace(); - return false; } + return new VersionInfo(false, version, null, UpdateUrgency.NONE); + } + + private static UpdateUrgency determineUrgency(String changelog, String versionType) { + if (versionType.equals("release")) { + if (changelog.toLowerCase().contains("security") || changelog.toLowerCase().contains("critical")) { + return UpdateUrgency.CRITICAL; + } else if (changelog.toLowerCase().contains("important") || changelog.toLowerCase().contains("major")) { + return UpdateUrgency.HIGH; + } else { + return UpdateUrgency.NORMAL; + } + } else if (versionType.equals("beta")) { + return UpdateUrgency.LOW; + } else { + return UpdateUrgency.NONE; + } + } + + public static class VersionInfo { + public final boolean isNewVersionAvailable; + public final String latestVersion; + public final String changelog; + public final UpdateUrgency urgency; + + public VersionInfo(boolean isNewVersionAvailable, String latestVersion, String changelog, UpdateUrgency urgency) { + this.isNewVersionAvailable = isNewVersionAvailable; + this.latestVersion = latestVersion; + this.changelog = changelog; + this.urgency = urgency; + } + } + + public enum UpdateUrgency { + CRITICAL, + HIGH, + NORMAL, + LOW, + NONE } /** diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c7ab57c..22f2e46 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -5,6 +5,9 @@ # Don't change this value, it's changed by the plugin if needed fileversion: 4 +# Check for updates on startup +# default: true +checkUpdate: true # maximum Character length a Status should be allowed to have. # default: 15 maxStatusLength: 15 diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 0389394..044245c 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -3,7 +3,7 @@ version: '${project.version}' main: de.tubyoub.statusplugin.StatusPlugin api-version: 1.13 author: TubYoub -softdepend: [PlaceholderAPI] +softdepend: [PlaceholderAPI, LuckPerms] commands: status: description: Set a player's status, get info, get help, reload the plugin, set/reset max length