diff --git a/src/main/java/de/mviper/elevator/Elevator.java b/src/main/java/de/mviper/elevator/Elevator.java index dac32de..1749849 100644 --- a/src/main/java/de/mviper/elevator/Elevator.java +++ b/src/main/java/de/mviper/elevator/Elevator.java @@ -1,39 +1,91 @@ package de.mviper.elevator; +import net.md_5.bungee.api.chat.ClickEvent; +import net.md_5.bungee.api.chat.HoverEvent; +import net.md_5.bungee.api.chat.TextComponent; +import net.md_5.bungee.api.chat.hover.content.Text; import org.bukkit.Material; import org.bukkit.NamespacedKey; +import org.bukkit.configuration.ConfigurationSection; import org.bukkit.enchantments.Enchantment; +import org.bukkit.entity.Player; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ShapedRecipe; import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.plugin.java.JavaPlugin; import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; -public class Elevator extends JavaPlugin { +public class Elevator extends JavaPlugin implements Listener { private static Elevator instance; private DatabaseManager databaseManager; private HologramManager hologramManager; + private String latestVersionFound; + private final String releaseUrl = "https://git.viper.ipv64.net/M_Viper/Elevator/releases"; @Override public void onEnable() { instance = this; saveDefaultConfig(); + this.databaseManager = new DatabaseManager(); this.hologramManager = new HologramManager(); hologramManager.purgeAllHolograms(); + // Events & Commands registrieren getServer().getPluginManager().registerEvents(new ElevatorListener(), this); + getServer().getPluginManager().registerEvents(this, this); getCommand("elevator").setExecutor(new ElevatorCommand()); + + // Rezept laden registerElevatorRecipe(); + + // Update Check starten + checkForUpdates(); + } + + private void checkForUpdates() { + new UpdateChecker(this).getLatestVersion(version -> { + this.latestVersionFound = version; + String currentVersion = this.getDescription().getVersion(); + + if (!currentVersion.equalsIgnoreCase(version)) { + getLogger().info("===================================================="); + getLogger().info("NEUES UPDATE VERFÜGBAR: " + version); + getLogger().info("Download: " + releaseUrl); + getLogger().info("===================================================="); + } + }); + } + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + Player player = event.getPlayer(); + if (player.hasPermission("elevator.admin") || player.isOp()) { + if (latestVersionFound != null && !this.getDescription().getVersion().equalsIgnoreCase(latestVersionFound)) { + + player.sendMessage(" "); + player.sendMessage("§b§l[Elevator] §eEine neue Version (§b" + latestVersionFound + "§e) ist verfügbar!"); + + TextComponent message = new TextComponent("§eDownload: "); + TextComponent link = new TextComponent("§6§l[KLICK HIER FÜR UPDATE]"); + link.setClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, releaseUrl)); + link.setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new Text("§7Öffnet die Release-Seite"))); + + message.addExtra(link); + player.spigot().sendMessage(message); + player.sendMessage(" "); + } + } } - /** - * Registriert das Elevator-Modul Rezept basierend auf der Config-Einstellung. - * Unterstützte Rezept-Typen: "standard", "expensive" - */ private void registerElevatorRecipe() { - // Erstelle das Elevator-Modul Item + // Das Resultat-Item (Aufzug-Modul) ItemStack item = new ItemStack(Material.DAYLIGHT_DETECTOR); ItemMeta meta = item.getItemMeta(); if (meta != null) { @@ -48,56 +100,71 @@ public class Elevator extends JavaPlugin { item.setItemMeta(meta); } - // Lese Rezept-Typ aus der Config (Standard: "standard") - String recipeType = getConfig().getString("recipe.type", "standard").toLowerCase(); - - // Erstelle das ShapedRecipe - ShapedRecipe recipe = new ShapedRecipe(new NamespacedKey(this, "elevator_module"), item); - - // Wähle das Rezept basierend auf dem Config-Wert - switch (recipeType) { - case "expensive": - // Teures Rezept: - // D E D D = DIAMOND - // E I E E = ENDER_PEARL - // D E D I = IRON_BLOCK - recipe.shape("DED", "EIE", "DED"); - recipe.setIngredient('D', Material.DIAMOND); - recipe.setIngredient('E', Material.ENDER_PEARL); - recipe.setIngredient('I', Material.IRON_BLOCK); - getLogger().info("§aElevator-Rezept aktiviert: §eExpensive (Diamanten + Enderperlen)"); - break; - - case "standard": - default: - // Standard-Rezept: - // S . S S = DAYLIGHT_DETECTOR - // . I . I = IRON_BLOCK - // S . S - recipe.shape("S.S", ".I.", "S.S"); - recipe.setIngredient('S', Material.DAYLIGHT_DETECTOR); - recipe.setIngredient('I', Material.IRON_BLOCK); - getLogger().info("§aElevator-Rezept aktiviert: §eStandard (Daylight Detector + Iron Block)"); - break; + NamespacedKey key = new NamespacedKey(this, "elevator_module"); + ShapedRecipe recipe = new ShapedRecipe(key, item); + + // Shape laden und bereinigen (verhindert den "Length 5" Fehler) + List shapeLines = getConfig().getStringList("recipe.shape"); + if (shapeLines.size() != 3) { + getLogger().severe("Rezept konnte nicht geladen werden: 'shape' benötigt genau 3 Zeilen!"); + return; } - - // Rezept zum Server hinzufügen + + String[] cleanedRows = new String[3]; + for (int i = 0; i < 3; i++) { + // Entferne alle Leerzeichen für die interne Verarbeitung + String line = shapeLines.get(i).replace(" ", ""); + + // Mit Leerzeichen auffüllen, falls die Zeile kürzer als 3 ist + while (line.length() < 3) { + line += " "; + } + // Kürzen, falls sie länger als 3 ist + if (line.length() > 3) { + line = line.substring(0, 3); + } + cleanedRows[i] = line; + } + + recipe.shape(cleanedRows[0], cleanedRows[1], cleanedRows[2]); + + // Zutaten zuweisen + ConfigurationSection section = getConfig().getConfigurationSection("recipe.ingredients"); + if (section == null) { + getLogger().severe("Keine 'recipe.ingredients' in der Config gefunden!"); + return; + } + + for (String row : cleanedRows) { + for (char c : row.toCharArray()) { + if (c == ' ') continue; + + String matName = section.getString(String.valueOf(c)); + if (matName != null) { + Material mat = Material.matchMaterial(matName.toUpperCase()); + if (mat != null) { + recipe.setIngredient(c, mat); + } else { + getLogger().warning("Ungültiges Material '" + matName + "' für Symbol '" + c + "'!"); + return; + } + } else { + getLogger().warning("Symbol '" + c + "' im Shape hat keine Zuweisung in ingredients!"); + return; + } + } + } + try { + getServer().removeRecipe(key); getServer().addRecipe(recipe); + getLogger().info("Elevator: Crafting-Rezept erfolgreich registriert."); } catch (Exception e) { - getLogger().warning("§cKonnte Elevator-Rezept nicht registrieren: " + e.getMessage()); + getLogger().log(Level.WARNING, "Fehler beim Rezept-Setup: {0}", e.getMessage()); } } - public static Elevator getInstance() { - return instance; - } - - public DatabaseManager getDatabaseManager() { - return databaseManager; - } - - public HologramManager getHologramManager() { - return hologramManager; - } + public static Elevator getInstance() { return instance; } + public DatabaseManager getDatabaseManager() { return databaseManager; } + public HologramManager getHologramManager() { return hologramManager; } } \ No newline at end of file diff --git a/src/main/java/de/mviper/elevator/UpdateChecker.java b/src/main/java/de/mviper/elevator/UpdateChecker.java new file mode 100644 index 0000000..9d1bf6c --- /dev/null +++ b/src/main/java/de/mviper/elevator/UpdateChecker.java @@ -0,0 +1,43 @@ +package de.mviper.elevator; + +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import org.bukkit.Bukkit; + +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.util.function.Consumer; + +public class UpdateChecker { + + private final Elevator plugin; + private final String versionUrl = "https://git.viper.ipv64.net/api/v1/repos/M_Viper/Elevator/releases/latest"; + + public UpdateChecker(Elevator plugin) { + this.plugin = plugin; + } + + public void getLatestVersion(Consumer consumer) { + Bukkit.getScheduler().runTaskAsynchronously(this.plugin, () -> { + try { + HttpURLConnection connection = (HttpURLConnection) new URL(versionUrl).openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(5000); + connection.setReadTimeout(5000); + + if (connection.getResponseCode() == 200) { + InputStreamReader reader = new InputStreamReader(connection.getInputStream()); + JsonObject jsonResponse = JsonParser.parseReader(reader).getAsJsonObject(); + // Holt den Tag-Namen (z.B. v1.1) aus der Gitea API + if (jsonResponse.has("tag_name")) { + String latestVersion = jsonResponse.get("tag_name").getAsString(); + consumer.accept(latestVersion); + } + } + } catch (Exception e) { + plugin.getLogger().warning("Update-Check fehlgeschlagen: " + e.getMessage()); + } + }); + } +} \ No newline at end of file diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 019fb80..20f43f5 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -1,4 +1,8 @@ -# Elevator Config by mviper +# ============================================================= +# Elevator Config by M_Viper +# ============================================================= + +# Datenbank-Einstellungen (SQLite wird standardmäßig genutzt, falls false) mysql: enable: false host: "localhost" @@ -7,51 +11,64 @@ mysql: user: "root" password: "" +# Allgemeine Aufzug-Logik settings: - max-distance: 64 - hologram-duration: 45 - cooldown: 500 - + max-distance: 64 # Maximale Reichweite zwischen zwei Modulen + hologram-duration: 45 # Wie lange das Hologramm (in Ticks) sichtbar bleibt + cooldown: 500 # Wartezeit zwischen Teleports (in Millisekunden) + +# Optische Effekte & Hologramme visuals: enable-particles: true particle-type: "FIREWORKS_SPARK" - # Nutze HIER nur das & Zeichen für Farben! + + # Texte & Farben (Nutze '&' für Farbcodes) hologram-text: "&8&l» &b&lEtage %floor% &8&l«" + actionbar-text: "&fTransport: &b&lEtage %floor%" + + # Darstellung des Hologramms hologram-height-offset: 2.2 hologram-scale: 1.5 - actionbar-text: "&fTransport: &b&lEtage %floor%" + + # Hintergrund-Box (RGBA Werte) hologram-background-color: alpha: 120 red: 0 green: 0 blue: 0 +# Akustisches Feedback sounds: enable: true type: "BLOCK_NOTE_BLOCK_CHIME" volume: 1.0 pitch: 1.5 +# Nachrichten-System messages: prefix: "&8[&bElevator&8] " registered: "&aModul erfolgreich registriert!" no-target: "&cKeine weitere Etage gefunden." -# ============================================ -# REZEPT-AUSWAHL -# ============================================ -# Hier kannst du zwischen verschiedenen Crafting-Rezepten wählen. -# Mögliche Werte: "standard", "expensive" -# -Standard-Rezept: - S.S S = DAYLIGHT_DETECTOR - .I. I = IRON_BLOCK - S.S -# -Teures Rezept (Expensive): - DED D = DIAMOND - EIE E = ENDER_PEARL - DED I = IRON_BLOCK - +# ============================================================= +# REZEPT-EINSTELLUNGEN +# ============================================================= +# Crafting-Gitter Übersicht: +# [ 1 | 2 | 3 ] -> Zeile 1 +# [ 4 | 5 | 6 ] -> Zeile 2 +# [ 7 | 8 | 9 ] -> Zeile 3 +# ============================================================= recipe: - type: "standard" \ No newline at end of file + # Das 3x3 Layout (Maximal 3 Zeichen pro Zeile!) + # Nutze einen Punkt (.) für ein leeres Feld. + shape: + - "ABA" # Slot 1 2 3 + - "BCB" # Slot 4 5 6 + - "ABA" # Slot 7 8 9 + + # Material-Zuweisung + # Liste aller Materialien: https://hub.spigotmc.org/javadocs/spigot/org/bukkit/Material.html + ingredients: + A: "IRON_INGOT" + B: "ENDER_PEARL" + C: "DAYLIGHT_DETECTOR" \ No newline at end of file diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index de00672..e22b661 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -1,5 +1,5 @@ name: Elevator -version: 1.1 +version: 1.2 main: de.mviper.elevator.Elevator api-version: 1.20 author: mviper