diff --git a/src/main/java/de/nexuslobby/NexusLobby.java b/src/main/java/de/nexuslobby/NexusLobby.java index fcf92d0..e2c6f3c 100644 --- a/src/main/java/de/nexuslobby/NexusLobby.java +++ b/src/main/java/de/nexuslobby/NexusLobby.java @@ -204,18 +204,55 @@ public class NexusLobby extends JavaPlugin implements Listener { private void checkUpdates() { new UpdateChecker(this).getVersion(version -> { - if (!this.getDescription().getVersion().equalsIgnoreCase(version)) { + String currentVersion = this.getDescription().getVersion(); + if (isRemoteVersionNewer(currentVersion, version)) { this.updateAvailable = true; this.latestVersion = version; getLogger().warning("===================================================="); - getLogger().warning("Update gefunden! v" + getDescription().getVersion() + " -> v" + version); + getLogger().warning("Update gefunden! v" + currentVersion + " -> v" + version); getLogger().warning("===================================================="); } else { - getLogger().info("NexusLobby ist aktuell (v" + version + ")."); + this.updateAvailable = false; + this.latestVersion = ""; + getLogger().info("NexusLobby ist aktuell/neu genug (lokal v" + currentVersion + ", remote v" + version + ")."); } }); } + private boolean isRemoteVersionNewer(String localVersion, String remoteVersion) { + int[] local = extractVersionNumbers(localVersion); + int[] remote = extractVersionNumbers(remoteVersion); + + int max = Math.max(local.length, remote.length); + for (int i = 0; i < max; i++) { + int l = i < local.length ? local[i] : 0; + int r = i < remote.length ? remote[i] : 0; + if (r > l) return true; + if (r < l) return false; + } + return false; + } + + private int[] extractVersionNumbers(String version) { + if (version == null || version.isBlank()) return new int[0]; + + java.util.regex.Matcher matcher = java.util.regex.Pattern.compile("\\\\d+").matcher(version); + java.util.List parts = new java.util.ArrayList<>(); + while (matcher.find()) { + try { + parts.add(Integer.parseInt(matcher.group())); + } catch (NumberFormatException ignored) { + parts.add(0); + } + } + + int[] result = new int[parts.size()]; + for (int i = 0; i < parts.size(); i++) { + result[i] = parts.get(i); + } + return result; + } + private void registerModules() { moduleManager.registerModule(new ProtectionModule()); moduleManager.registerModule(new ScoreboardModule()); diff --git a/src/main/java/de/nexuslobby/modules/armorstandtools/ASTListener.java b/src/main/java/de/nexuslobby/modules/armorstandtools/ASTListener.java index a8bf018..cb41831 100644 --- a/src/main/java/de/nexuslobby/modules/armorstandtools/ASTListener.java +++ b/src/main/java/de/nexuslobby/modules/armorstandtools/ASTListener.java @@ -6,11 +6,15 @@ import de.nexuslobby.NexusLobby; import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.entity.ArmorStand; +import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.entity.Projectile; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.entity.EntityDamageByEntityEvent; import org.bukkit.event.inventory.InventoryClickEvent; +import org.bukkit.event.player.PlayerArmorStandManipulateEvent; import org.bukkit.event.player.PlayerInteractAtEntityEvent; import org.bukkit.inventory.EquipmentSlot; import org.bukkit.inventory.ItemStack; @@ -20,6 +24,41 @@ import java.util.UUID; public class ASTListener implements Listener { + private boolean hasArmorStandBypass(Player player) { + return player.isOp() || player.hasPermission("nexuslobby.armorstand.editbypass"); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onArmorStandManipulate(PlayerArmorStandManipulateEvent event) { + Player player = event.getPlayer(); + if (hasArmorStandBypass(player)) { + return; + } + + // Verhindert, dass Spieler Rüstung/Items aus ArmorStands nehmen oder austauschen. + event.setCancelled(true); + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onArmorStandDamage(EntityDamageByEntityEvent event) { + if (!(event.getEntity() instanceof ArmorStand)) return; + + Player player = null; + Entity damager = event.getDamager(); + if (damager instanceof Player p) { + player = p; + } else if (damager instanceof Projectile projectile && projectile.getShooter() instanceof Player p) { + player = p; + } + + if (player != null && hasArmorStandBypass(player)) { + return; + } + + // Verhindert Abbauen/Beschädigen ohne Bypass, damit keine Equipment-Drops entnommen werden können. + event.setCancelled(true); + } + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) public void onInteract(PlayerInteractAtEntityEvent event) { if (event.getHand() != EquipmentSlot.HAND) return; diff --git a/src/main/java/de/nexuslobby/modules/gadgets/GadgetModule.java b/src/main/java/de/nexuslobby/modules/gadgets/GadgetModule.java index 2ed5b69..924fcad 100644 --- a/src/main/java/de/nexuslobby/modules/gadgets/GadgetModule.java +++ b/src/main/java/de/nexuslobby/modules/gadgets/GadgetModule.java @@ -137,7 +137,11 @@ public class GadgetModule implements Module, Listener { // Wenn der Schütze selbst geschützt ist (Parkour oder Admin-Schutz) → kampfbezogene Gadgets sperren if (GadgetShield.isProtected(player)) { if (name.equals("§b§lFreeze-Ray") || name.equals("§c§lMeteorit")) { - player.sendMessage("§8[§6Parkour§8] §cGadgets können während des Parkours nicht benutzt werden."); + if (GadgetShield.isAdminShielded(player)) { + player.sendMessage("§8[§6Nexus§8] §cDein Gadget-Schutz ist aktiv. Deaktiviere ihn mit §e/nexus gadgetshield§c."); + } else { + player.sendMessage("§8[§6Parkour§8] §cGadgets können während des Parkours nicht benutzt werden."); + } event.setCancelled(true); return; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index c4f840f..3274c35 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -482,6 +482,5 @@ ball: # # Benötigst du Hilfe oder Support? # - Webseite: https://m-viper.de -# - Dokumentation: https://git.viper.ipv64.net/M_Viper/NexusLobby/wiki -# - Discord: https://discord.com/invite/FdRs4BRd8D -# - GitHub: https://git.viper.ipv64.net/M_Viper/NexusLobby \ No newline at end of file +# - Dokumentation: https://viper-network.de/wiki/NexusLobby/ +# - Discord: https://discord.com/invite/FdRs4BRd8D \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 6943e0d..50b9d3e 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,6 +1,6 @@ name: NexusLobby main: de.nexuslobby.NexusLobby -version: "1.1.5" +version: "1.6" api-version: "1.21" author: M_Viper description: Modular Lobby Plugin with an invisible Particle-Parkour system.