diff --git a/src/main/java/de/teleportsuite/ConfigManager.java b/src/main/java/de/teleportsuite/ConfigManager.java new file mode 100644 index 0000000..d537637 --- /dev/null +++ b/src/main/java/de/teleportsuite/ConfigManager.java @@ -0,0 +1,34 @@ +package de.teleportsuite; + +import org.bukkit.ChatColor; + +public class ConfigManager { + private final TeleportSuite plugin; + + public ConfigManager(TeleportSuite plugin) { this.plugin = plugin; } + + public boolean isBungeeEnabled() { return plugin.getConfig().getBoolean("bungee.enabled", false); } + public String getServerName() { return plugin.getConfig().getString("bungee.server-name", "local"); } + public int getTeleportDelay() { return plugin.getConfig().getInt("teleport.delay", 3); } + public int getTeleportCooldown() { return plugin.getConfig().getInt("teleport.cooldown", 5); } + public boolean cancelOnMove() { return plugin.getConfig().getBoolean("teleport.warmup-cancel-on-move", true); } + public int getRequestTimeout() { return plugin.getConfig().getInt("teleport.request-timeout", 60); } + public int getMaxHomes(String group) { return plugin.getConfig().getInt("homes.max-homes-" + group, 3); } + public boolean allowPlayerWarps() { return plugin.getConfig().getBoolean("warps.allow-player-warps", false); } + public boolean firstJoinTeleport() { return plugin.getConfig().getBoolean("spawn.first-join-teleport", true); } + public boolean deathRespawnToSpawn() { return plugin.getConfig().getBoolean("spawn.death-respawn-to-spawn", false); } + + public String getMessage(String key) { + String prefix = plugin.getConfig().getString("messages.prefix", "&8[&6TP&8] &r"); + String msg = plugin.getConfig().getString("messages." + key, "&cNachricht nicht gefunden: " + key); + return ChatColor.translateAlternateColorCodes('&', prefix + msg); + } + + public String getMessage(String key, String... replacements) { + String msg = getMessage(key); + for (int i = 0; i < replacements.length - 1; i += 2) { + msg = msg.replace("{" + replacements[i] + "}", replacements[i+1]); + } + return msg; + } +} diff --git a/src/main/java/de/teleportsuite/TeleportSuite.java b/src/main/java/de/teleportsuite/TeleportSuite.java new file mode 100644 index 0000000..610a93b --- /dev/null +++ b/src/main/java/de/teleportsuite/TeleportSuite.java @@ -0,0 +1,106 @@ +package de.teleportsuite; + +import de.teleportsuite.commands.*; +import de.teleportsuite.database.DatabaseManager; +import de.teleportsuite.listeners.*; +import de.teleportsuite.managers.*; +import de.teleportsuite.bungeemessaging.BungeeMessenger; +import org.bukkit.plugin.java.JavaPlugin; + +public class TeleportSuite extends JavaPlugin { + + private static TeleportSuite instance; + private DatabaseManager databaseManager; + private HomeManager homeManager; + private WarpManager warpManager; + private PortalManager portalManager; + private TeleportManager teleportManager; + private SpawnManager spawnManager; + private SavePointManager savePointManager; + private BungeeMessenger bungeeMessenger; + private ConfigManager configManager; + + @Override + public void onEnable() { + instance = this; + saveDefaultConfig(); + configManager = new ConfigManager(this); + + databaseManager = new DatabaseManager(this); + if (!databaseManager.connect()) { + getLogger().severe("Datenbankverbindung fehlgeschlagen! Plugin wird deaktiviert."); + getServer().getPluginManager().disablePlugin(this); + return; + } + databaseManager.createTables(); + + homeManager = new HomeManager(this); + warpManager = new WarpManager(this); + portalManager = new PortalManager(this); + teleportManager = new TeleportManager(this); + spawnManager = new SpawnManager(this); + savePointManager = new SavePointManager(this); + + if (configManager.isBungeeEnabled()) { + bungeeMessenger = new BungeeMessenger(this); + bungeeMessenger.register(); + getLogger().info("BungeeCord-Unterstuetzung aktiviert."); + } + + getServer().getPluginManager().registerEvents(new PlayerJoinListener(this), this); + getServer().getPluginManager().registerEvents(new PlayerDeathListener(this), this); + getServer().getPluginManager().registerEvents(new PlayerMoveListener(this), this); + getServer().getPluginManager().registerEvents(new PlayerRespawnListener(this), this); + getServer().getPluginManager().registerEvents(new PortalListener(this), this); + + registerCommands(); + getLogger().info("TeleportSuite v" + getDescription().getVersion() + " erfolgreich geladen!"); + } + + @Override + public void onDisable() { + if (databaseManager != null) databaseManager.disconnect(); + if (bungeeMessenger != null) bungeeMessenger.unregister(); + } + + private void registerCommands() { + getCommand("tp").setExecutor(new TpCommand(this)); + getCommand("tphere").setExecutor(new TpHereCommand(this)); + getCommand("tpa").setExecutor(new TpaCommand(this)); + getCommand("tpaccept").setExecutor(new TpAcceptCommand(this)); + getCommand("tpdeny").setExecutor(new TpDenyCommand(this)); + getCommand("tppos").setExecutor(new TpPosCommand(this)); + getCommand("tpall").setExecutor(new TpAllCommand(this)); + getCommand("tpworld").setExecutor(new TpWorldCommand(this)); + getCommand("back").setExecutor(new BackCommand(this)); + getCommand("deathback").setExecutor(new DeathBackCommand(this)); + getCommand("sethome").setExecutor(new SetHomeCommand(this)); + getCommand("home").setExecutor(new HomeCommand(this)); + getCommand("delhome").setExecutor(new DelHomeCommand(this)); + getCommand("homes").setExecutor(new HomesCommand(this)); + getCommand("setwarp").setExecutor(new SetWarpCommand(this)); + getCommand("warp").setExecutor(new WarpCommand(this)); + getCommand("delwarp").setExecutor(new DelWarpCommand(this)); + getCommand("warps").setExecutor(new WarpsCommand(this)); + getCommand("setportal").setExecutor(new SetPortalCommand(this)); + getCommand("delportal").setExecutor(new DelPortalCommand(this)); + getCommand("portals").setExecutor(new PortalsCommand(this)); + getCommand("setspawn").setExecutor(new SetSpawnCommand(this)); + getCommand("spawn").setExecutor(new SpawnCommand(this)); + getCommand("setfirstspawn").setExecutor(new SetFirstSpawnCommand(this)); + getCommand("setsavepoint").setExecutor(new SetSavePointCommand(this)); + getCommand("savepoint").setExecutor(new SavePointCommand(this)); + getCommand("entitytransport").setExecutor(new EntityTransportCommand(this)); + } + + public static TeleportSuite getInstance() { return instance; } + public DatabaseManager getDatabaseManager() { return databaseManager; } + public HomeManager getHomeManager() { return homeManager; } + public WarpManager getWarpManager() { return warpManager; } + public PortalManager getPortalManager() { return portalManager; } + public TeleportManager getTeleportManager() { return teleportManager; } + public SpawnManager getSpawnManager() { return spawnManager; } + public SavePointManager getSavePointManager() { return savePointManager; } + public BungeeMessenger getBungeeMessenger() { return bungeeMessenger; } + public ConfigManager getConfigManager() { return configManager; } +} diff --git a/src/main/java/de/teleportsuite/bungeemessaging/BungeeMessenger.java b/src/main/java/de/teleportsuite/bungeemessaging/BungeeMessenger.java new file mode 100644 index 0000000..ac6a746 --- /dev/null +++ b/src/main/java/de/teleportsuite/bungeemessaging/BungeeMessenger.java @@ -0,0 +1,105 @@ +package de.teleportsuite.bungeemessaging; + +import de.teleportsuite.TeleportSuite; +import org.bukkit.entity.Player; +import org.bukkit.plugin.messaging.PluginMessageListener; + +import java.io.*; + +/** + * Handles BungeeCord Plugin Messaging. + * Sends players to other servers and transmits target coordinates + * so a receiving TeleportSuite instance can teleport them on arrival. + * + * Channel "teleportsuite:tp" payload format (DataOutputStream): + * String targetPlayer + * String world + * Double x, y, z + * Float yaw, pitch + */ +public class BungeeMessenger implements PluginMessageListener { + + private static final String BUNGEE_CHANNEL = "BungeeCord"; + private static final String TS_CHANNEL = "teleportsuite:tp"; + private final TeleportSuite plugin; + + public BungeeMessenger(TeleportSuite plugin) { this.plugin = plugin; } + + public void register() { + plugin.getServer().getMessenger().registerOutgoingPluginChannel(plugin, BUNGEE_CHANNEL); + plugin.getServer().getMessenger().registerOutgoingPluginChannel(plugin, TS_CHANNEL); + plugin.getServer().getMessenger().registerIncomingPluginChannel(plugin, TS_CHANNEL, this); + } + + public void unregister() { + plugin.getServer().getMessenger().unregisterOutgoingPluginChannel(plugin); + plugin.getServer().getMessenger().unregisterIncomingPluginChannel(plugin); + } + + /** + * Connect a player to another BungeeCord server. + * Also sends a plugin message so the target server knows where to teleport the player. + */ + public void connectToServer(Player player, String server, String world, double x, double y, double z, float yaw, float pitch) { + // 1) Notify the target server about the pending teleport + sendTeleportPayload(player, player.getName(), server, world, x, y, z, yaw, pitch); + + // 2) Switch server via BungeeCord + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bos)) { + out.writeUTF("Connect"); + out.writeUTF(server); + player.sendPluginMessage(plugin, BUNGEE_CHANNEL, bos.toByteArray()); + } catch (IOException e) { + plugin.getLogger().warning("BungeeCord Connect Fehler: " + e.getMessage()); + } + } + + private void sendTeleportPayload(Player sender, String targetPlayer, String server, String world, + double x, double y, double z, float yaw, float pitch) { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + DataOutputStream out = new DataOutputStream(bos)) { + out.writeUTF("Forward"); + out.writeUTF(server); + out.writeUTF(TS_CHANNEL); + // Sub-payload + ByteArrayOutputStream sub = new ByteArrayOutputStream(); + DataOutputStream subOut = new DataOutputStream(sub); + subOut.writeUTF(targetPlayer); + subOut.writeUTF(world); + subOut.writeDouble(x); + subOut.writeDouble(y); + subOut.writeDouble(z); + subOut.writeFloat(yaw); + subOut.writeFloat(pitch); + byte[] subBytes = sub.toByteArray(); + out.writeShort(subBytes.length); + out.write(subBytes); + sender.sendPluginMessage(plugin, BUNGEE_CHANNEL, bos.toByteArray()); + } catch (IOException e) { + plugin.getLogger().warning("TS Forward Fehler: " + e.getMessage()); + } + } + + @Override + public void onPluginMessageReceived(String channel, Player player, byte[] message) { + if (!channel.equals(TS_CHANNEL)) return; + try (DataInputStream in = new DataInputStream(new ByteArrayInputStream(message))) { + String targetName = in.readUTF(); + String world = in.readUTF(); + double x = in.readDouble(), y = in.readDouble(), z = in.readDouble(); + float yaw = in.readFloat(), pitch = in.readFloat(); + + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, () -> { + Player target = plugin.getServer().getPlayer(targetName); + if (target == null || !target.isOnline()) return; + de.teleportsuite.models.TeleportLocation loc = + new de.teleportsuite.models.TeleportLocation(world, x, y, z, yaw, pitch, + plugin.getConfigManager().getServerName()); + plugin.getTeleportManager().teleport(target, loc, false); + }, 20L); + } catch (IOException e) { + plugin.getLogger().warning("Fehler beim Lesen der TS-Nachricht: " + e.getMessage()); + } + } +} diff --git a/src/main/java/de/teleportsuite/commands/BackCommand.java b/src/main/java/de/teleportsuite/commands/BackCommand.java new file mode 100644 index 0000000..f9db697 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/BackCommand.java @@ -0,0 +1,22 @@ +package de.teleportsuite.commands; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.command.*; +import org.bukkit.entity.Player; + +public class BackCommand implements CommandExecutor { + private final TeleportSuite plugin; + public BackCommand(TeleportSuite p) { this.plugin = p; } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.back")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + TeleportLocation loc = plugin.getDatabaseManager().getLastLocation(p.getUniqueId()); + if (loc == null) { p.sendMessage(plugin.getConfigManager().getMessage("back-no-location")); return true; } + plugin.getTeleportManager().teleport(p, loc, false); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/DeathBackCommand.java b/src/main/java/de/teleportsuite/commands/DeathBackCommand.java new file mode 100644 index 0000000..7b9904a --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/DeathBackCommand.java @@ -0,0 +1,22 @@ +package de.teleportsuite.commands; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.command.*; +import org.bukkit.entity.Player; + +public class DeathBackCommand implements CommandExecutor { + private final TeleportSuite plugin; + public DeathBackCommand(TeleportSuite p) { this.plugin = p; } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.deathback")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + TeleportLocation loc = plugin.getDatabaseManager().getDeathLocation(p.getUniqueId()); + if (loc == null) { p.sendMessage(plugin.getConfigManager().getMessage("death-no-location")); return true; } + plugin.getTeleportManager().teleport(p, loc); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/DelHomeCommand.java b/src/main/java/de/teleportsuite/commands/DelHomeCommand.java new file mode 100644 index 0000000..ffbd315 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/DelHomeCommand.java @@ -0,0 +1,17 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class DelHomeCommand implements CommandExecutor { + private final TeleportSuite plugin; + public DelHomeCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.sethome")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { p.sendMessage("§cVerwendung: /delhome "); return true; } + plugin.getHomeManager().deleteHome(p, args[0]); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/DelPortalCommand.java b/src/main/java/de/teleportsuite/commands/DelPortalCommand.java new file mode 100644 index 0000000..0519664 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/DelPortalCommand.java @@ -0,0 +1,15 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +public class DelPortalCommand implements CommandExecutor { + private final TeleportSuite plugin; + public DelPortalCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!sender.hasPermission("teleportsuite.delportal")) { sender.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { sender.sendMessage("§cVerwendung: /delportal "); return true; } + boolean deleted = plugin.getPortalManager().deletePortal(args[0]); + sender.sendMessage(deleted ? plugin.getConfigManager().getMessage("portal-deleted","name",args[0]) : "§cPortal nicht gefunden."); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/DelWarpCommand.java b/src/main/java/de/teleportsuite/commands/DelWarpCommand.java new file mode 100644 index 0000000..4febaf1 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/DelWarpCommand.java @@ -0,0 +1,16 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class DelWarpCommand implements CommandExecutor { + private final TeleportSuite plugin; + public DelWarpCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!sender.hasPermission("teleportsuite.delwarp")) { sender.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { sender.sendMessage("§cVerwendung: /delwarp "); return true; } + boolean deleted = plugin.getWarpManager().deleteWarp(args[0]); + sender.sendMessage(deleted ? plugin.getConfigManager().getMessage("warp-deleted","name",args[0]) : plugin.getConfigManager().getMessage("warp-not-found","name",args[0])); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/EntityTransportCommand.java b/src/main/java/de/teleportsuite/commands/EntityTransportCommand.java new file mode 100644 index 0000000..9685809 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/EntityTransportCommand.java @@ -0,0 +1,30 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.Bukkit; +import org.bukkit.command.*; +import org.bukkit.entity.*; +public class EntityTransportCommand implements CommandExecutor { + private final TeleportSuite plugin; + public EntityTransportCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!sender.hasPermission("teleportsuite.entitytransport")) { sender.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 2) { sender.sendMessage("§cVerwendung: /entitytransport "); return true; } + try { + int entityId = Integer.parseInt(args[0]); + Player target = Bukkit.getPlayer(args[1]); + if (target == null) { sender.sendMessage(plugin.getConfigManager().getMessage("player-not-found","player",args[1])); return true; } + Entity found = null; + for (var world : Bukkit.getWorlds()) { + for (var entity : world.getEntities()) { + if (entity.getEntityId() == entityId) { found = entity; break; } + } + if (found != null) break; + } + if (found == null) { sender.sendMessage("§cEntity mit ID §6" + entityId + " §cnicht gefunden."); return true; } + found.teleport(target.getLocation()); + sender.sendMessage("§aEntity §6" + found.getType() + " §awurde zu §6" + target.getName() + " §ateleportiert."); + } catch (NumberFormatException e) { sender.sendMessage("§cUngültige Entity-ID."); } + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/HomeCommand.java b/src/main/java/de/teleportsuite/commands/HomeCommand.java new file mode 100644 index 0000000..08472fe --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/HomeCommand.java @@ -0,0 +1,17 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class HomeCommand implements CommandExecutor { + private final TeleportSuite plugin; + public HomeCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.home")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + String name = args.length > 0 ? args[0] : "home"; + plugin.getHomeManager().teleportHome(p, name); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/HomesCommand.java b/src/main/java/de/teleportsuite/commands/HomesCommand.java new file mode 100644 index 0000000..f90644e --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/HomesCommand.java @@ -0,0 +1,20 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.Home; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +import java.util.List; +public class HomesCommand implements CommandExecutor { + private final TeleportSuite plugin; + public HomesCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + List homes = plugin.getHomeManager().getHomes(p.getUniqueId()); + if (homes.isEmpty()) { p.sendMessage("§eKeine Homes gesetzt."); return true; } + p.sendMessage("§6Deine Homes §8(" + homes.size() + "/" + plugin.getHomeManager().getMaxHomes(p) + ")§6:"); + homes.forEach(h -> p.sendMessage("§7- §a" + h.getName() + " §7(" + h.getLocation().getWorld() + ")")); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/PortalsCommand.java b/src/main/java/de/teleportsuite/commands/PortalsCommand.java new file mode 100644 index 0000000..11c387b --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/PortalsCommand.java @@ -0,0 +1,16 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +public class PortalsCommand implements CommandExecutor { + private final TeleportSuite plugin; + public PortalsCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!sender.hasPermission("teleportsuite.portals")) { sender.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + var portals = plugin.getPortalManager().getPortals(); + if (portals.isEmpty()) { sender.sendMessage("§eKeine Portale vorhanden."); return true; } + sender.sendMessage("§6Portale §8(" + portals.size() + ")§6:"); + portals.forEach(p2 -> sender.sendMessage("§7- §a" + p2.getName() + " §7→ §e" + (p2.getTargetServer() != null ? p2.getTargetServer() + "/" : "") + p2.getDestination().getWorld())); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/SavePointCommand.java b/src/main/java/de/teleportsuite/commands/SavePointCommand.java new file mode 100644 index 0000000..0db0603 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/SavePointCommand.java @@ -0,0 +1,17 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class SavePointCommand implements CommandExecutor { + private final TeleportSuite plugin; + public SavePointCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.savepoint")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + String name = args.length > 0 ? args[0] : "default"; + plugin.getSavePointManager().teleportToSavePoint(p, name); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/SetFirstSpawnCommand.java b/src/main/java/de/teleportsuite/commands/SetFirstSpawnCommand.java new file mode 100644 index 0000000..ab59b6b --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/SetFirstSpawnCommand.java @@ -0,0 +1,15 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class SetFirstSpawnCommand implements CommandExecutor { + private final TeleportSuite plugin; + public SetFirstSpawnCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + if (!sender.hasPermission("teleportsuite.setfirstspawn")) { sender.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + plugin.getSpawnManager().setFirstSpawn((Player) sender); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/SetHomeCommand.java b/src/main/java/de/teleportsuite/commands/SetHomeCommand.java new file mode 100644 index 0000000..f14990c --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/SetHomeCommand.java @@ -0,0 +1,17 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class SetHomeCommand implements CommandExecutor { + private final TeleportSuite plugin; + public SetHomeCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.sethome")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + String name = args.length > 0 ? args[0] : "home"; + plugin.getHomeManager().setHome(p, name); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/SetPortalCommand.java b/src/main/java/de/teleportsuite/commands/SetPortalCommand.java new file mode 100644 index 0000000..fbfd655 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/SetPortalCommand.java @@ -0,0 +1,28 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class SetPortalCommand implements CommandExecutor { + private final TeleportSuite plugin; + public SetPortalCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.setportal")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + // /setportal pos1 | pos2 | create + if (args.length == 0) { p.sendMessage("§cVerwendung: /setportal pos1|pos2|create [server] "); return true; } + if (args[0].equalsIgnoreCase("pos1")) { plugin.getPortalManager().setPos1(p, p.getLocation()); return true; } + if (args[0].equalsIgnoreCase("pos2")) { plugin.getPortalManager().setPos2(p, p.getLocation()); return true; } + if (args[0].equalsIgnoreCase("create") && args.length >= 7) { + String name = args[1], server = args[2], world = args[3]; + try { + double x = Double.parseDouble(args[4]), y = Double.parseDouble(args[5]), z = Double.parseDouble(args[6]); + plugin.getPortalManager().createPortal(p, name, server, world, x, y, z); + } catch (NumberFormatException e) { p.sendMessage("§cUngültige Koordinaten!"); } + return true; + } + p.sendMessage("§cVerwendung: /setportal pos1|pos2|create "); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/SetSavePointCommand.java b/src/main/java/de/teleportsuite/commands/SetSavePointCommand.java new file mode 100644 index 0000000..a271464 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/SetSavePointCommand.java @@ -0,0 +1,17 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class SetSavePointCommand implements CommandExecutor { + private final TeleportSuite plugin; + public SetSavePointCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.savepoint")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + String name = args.length > 0 ? args[0] : "default"; + plugin.getSavePointManager().setSavePoint(p, name); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/SetSpawnCommand.java b/src/main/java/de/teleportsuite/commands/SetSpawnCommand.java new file mode 100644 index 0000000..9651a6d --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/SetSpawnCommand.java @@ -0,0 +1,15 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class SetSpawnCommand implements CommandExecutor { + private final TeleportSuite plugin; + public SetSpawnCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + if (!sender.hasPermission("teleportsuite.setspawn")) { sender.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + plugin.getSpawnManager().setSpawn((Player) sender); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/SetWarpCommand.java b/src/main/java/de/teleportsuite/commands/SetWarpCommand.java new file mode 100644 index 0000000..06fcf19 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/SetWarpCommand.java @@ -0,0 +1,20 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class SetWarpCommand implements CommandExecutor { + private final TeleportSuite plugin; + public SetWarpCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + boolean isAdmin = p.hasPermission("teleportsuite.setwarp"); + boolean playerWarps = plugin.getConfigManager().allowPlayerWarps() && p.hasPermission("teleportsuite.setwarp.player"); + if (!isAdmin && !playerWarps) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { p.sendMessage("§cVerwendung: /setwarp [permission]"); return true; } + String perm = args.length > 1 ? args[1] : null; + plugin.getWarpManager().setWarp(p, args[0], perm); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/SpawnCommand.java b/src/main/java/de/teleportsuite/commands/SpawnCommand.java new file mode 100644 index 0000000..47d21f4 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/SpawnCommand.java @@ -0,0 +1,15 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class SpawnCommand implements CommandExecutor { + private final TeleportSuite plugin; + public SpawnCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + if (!sender.hasPermission("teleportsuite.spawn")) { sender.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + plugin.getSpawnManager().teleportToSpawn((Player) sender); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/TpAcceptCommand.java b/src/main/java/de/teleportsuite/commands/TpAcceptCommand.java new file mode 100644 index 0000000..dac3fc7 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/TpAcceptCommand.java @@ -0,0 +1,19 @@ +package de.teleportsuite.commands; + +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; + +public class TpAcceptCommand implements CommandExecutor { + private final TeleportSuite plugin; + public TpAcceptCommand(TeleportSuite p) { this.plugin = p; } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!plugin.getTeleportManager().acceptTpa(p)) + p.sendMessage("§cKeine ausstehende Teleportanfrage."); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/TpAllCommand.java b/src/main/java/de/teleportsuite/commands/TpAllCommand.java new file mode 100644 index 0000000..d1e12ff --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/TpAllCommand.java @@ -0,0 +1,22 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.Bukkit; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class TpAllCommand implements CommandExecutor { + private final TeleportSuite plugin; + public TpAllCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.tpall")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + TeleportLocation dest = new TeleportLocation(p.getLocation(), plugin.getConfigManager().getServerName()); + for (Player online : Bukkit.getOnlinePlayers()) { + if (!online.equals(p)) plugin.getTeleportManager().teleport(online, dest); + } + p.sendMessage("§aAlle Spieler wurden zu dir teleportiert."); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/TpCommand.java b/src/main/java/de/teleportsuite/commands/TpCommand.java new file mode 100644 index 0000000..b79a5e1 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/TpCommand.java @@ -0,0 +1,33 @@ +package de.teleportsuite.commands; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.Bukkit; +import org.bukkit.command.*; +import org.bukkit.entity.Player; + +public class TpCommand implements CommandExecutor { + private final TeleportSuite plugin; + public TpCommand(TeleportSuite p) { this.plugin = p; } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.tp")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { p.sendMessage("§cVerwendung: /tp [spieler2]"); return true; } + + if (args.length == 1) { + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { p.sendMessage(plugin.getConfigManager().getMessage("player-not-found","player",args[0])); return true; } + plugin.getTeleportManager().teleport(p, new TeleportLocation(target.getLocation(), plugin.getConfigManager().getServerName())); + } else { + Player from = Bukkit.getPlayer(args[0]); + Player to = Bukkit.getPlayer(args[1]); + if (from == null || to == null) { p.sendMessage("§cEin Spieler nicht gefunden."); return true; } + if (!p.hasPermission("teleportsuite.admin")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + plugin.getTeleportManager().teleport(from, new TeleportLocation(to.getLocation(), plugin.getConfigManager().getServerName())); + } + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/TpDenyCommand.java b/src/main/java/de/teleportsuite/commands/TpDenyCommand.java new file mode 100644 index 0000000..e0f721b --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/TpDenyCommand.java @@ -0,0 +1,19 @@ +package de.teleportsuite.commands; + +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; + +public class TpDenyCommand implements CommandExecutor { + private final TeleportSuite plugin; + public TpDenyCommand(TeleportSuite p) { this.plugin = p; } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!plugin.getTeleportManager().denyTpa(p)) + p.sendMessage("§cKeine ausstehende Teleportanfrage."); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/TpHereCommand.java b/src/main/java/de/teleportsuite/commands/TpHereCommand.java new file mode 100644 index 0000000..fef5ba5 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/TpHereCommand.java @@ -0,0 +1,24 @@ +package de.teleportsuite.commands; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.Bukkit; +import org.bukkit.command.*; +import org.bukkit.entity.Player; + +public class TpHereCommand implements CommandExecutor { + private final TeleportSuite plugin; + public TpHereCommand(TeleportSuite p) { this.plugin = p; } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.tphere")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { p.sendMessage("§cVerwendung: /tphere "); return true; } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { p.sendMessage(plugin.getConfigManager().getMessage("player-not-found","player",args[0])); return true; } + plugin.getTeleportManager().teleport(target, new TeleportLocation(p.getLocation(), plugin.getConfigManager().getServerName())); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/TpPosCommand.java b/src/main/java/de/teleportsuite/commands/TpPosCommand.java new file mode 100644 index 0000000..7b50efb --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/TpPosCommand.java @@ -0,0 +1,22 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class TpPosCommand implements CommandExecutor { + private final TeleportSuite plugin; + public TpPosCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.tppos")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 3) { p.sendMessage("§cVerwendung: /tppos [world]"); return true; } + try { + double x = Double.parseDouble(args[0]), y = Double.parseDouble(args[1]), z = Double.parseDouble(args[2]); + String world = args.length > 3 ? args[3] : p.getWorld().getName(); + plugin.getTeleportManager().teleport(p, new TeleportLocation(world, x, y, z, p.getLocation().getYaw(), p.getLocation().getPitch(), plugin.getConfigManager().getServerName())); + } catch (NumberFormatException e) { p.sendMessage("§cUngültige Koordinaten!"); } + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/TpWorldCommand.java b/src/main/java/de/teleportsuite/commands/TpWorldCommand.java new file mode 100644 index 0000000..72f1259 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/TpWorldCommand.java @@ -0,0 +1,23 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.Bukkit; +import org.bukkit.World; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class TpWorldCommand implements CommandExecutor { + private final TeleportSuite plugin; + public TpWorldCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.tpworld")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { p.sendMessage("§cVerwendung: /tpworld "); return true; } + World world = Bukkit.getWorld(args[0]); + if (world == null) { p.sendMessage("§cWelt §6" + args[0] + " §cnicht gefunden."); return true; } + var spawn = world.getSpawnLocation(); + plugin.getTeleportManager().teleport(p, new TeleportLocation(world.getName(), spawn.getX(), spawn.getY(), spawn.getZ(), 0, 0, plugin.getConfigManager().getServerName())); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/TpaCommand.java b/src/main/java/de/teleportsuite/commands/TpaCommand.java new file mode 100644 index 0000000..fbc773b --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/TpaCommand.java @@ -0,0 +1,24 @@ +package de.teleportsuite.commands; + +import de.teleportsuite.TeleportSuite; +import org.bukkit.Bukkit; +import org.bukkit.command.*; +import org.bukkit.entity.Player; + +public class TpaCommand implements CommandExecutor { + private final TeleportSuite plugin; + public TpaCommand(TeleportSuite p) { this.plugin = p; } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.tpa")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { p.sendMessage("§cVerwendung: /tpa "); return true; } + Player target = Bukkit.getPlayer(args[0]); + if (target == null) { p.sendMessage(plugin.getConfigManager().getMessage("player-not-found","player",args[0])); return true; } + if (target.equals(p)) { p.sendMessage("§cDu kannst dir nicht selbst eine Anfrage senden."); return true; } + plugin.getTeleportManager().sendTpaRequest(p, target); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/WarpCommand.java b/src/main/java/de/teleportsuite/commands/WarpCommand.java new file mode 100644 index 0000000..78a2f45 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/WarpCommand.java @@ -0,0 +1,17 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +public class WarpCommand implements CommandExecutor { + private final TeleportSuite plugin; + public WarpCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player)) { sender.sendMessage("§cNur für Spieler!"); return true; } + Player p = (Player) sender; + if (!p.hasPermission("teleportsuite.warp")) { p.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + if (args.length < 1) { p.sendMessage("§cVerwendung: /warp "); return true; } + plugin.getWarpManager().teleportWarp(p, args[0]); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/commands/WarpsCommand.java b/src/main/java/de/teleportsuite/commands/WarpsCommand.java new file mode 100644 index 0000000..b9ae9e2 --- /dev/null +++ b/src/main/java/de/teleportsuite/commands/WarpsCommand.java @@ -0,0 +1,21 @@ +package de.teleportsuite.commands; +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.Warp; +import org.bukkit.command.*; +import org.bukkit.entity.Player; +import java.util.List; +public class WarpsCommand implements CommandExecutor { + private final TeleportSuite plugin; + public WarpsCommand(TeleportSuite p) { this.plugin = p; } + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!sender.hasPermission("teleportsuite.warp")) { sender.sendMessage(plugin.getConfigManager().getMessage("no-permission")); return true; } + List warps = plugin.getWarpManager().getAllWarps(); + if (warps.isEmpty()) { sender.sendMessage("§eKeine Warps vorhanden."); return true; } + sender.sendMessage("§6Verfügbare Warps §8(" + warps.size() + ")§6:"); + warps.stream() + .filter(w -> w.getPermission() == null || sender.hasPermission(w.getPermission())) + .forEach(w -> sender.sendMessage("§7- §a" + w.getName() + " §7(" + w.getLocation().getWorld() + ")")); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/database/DatabaseManager.java b/src/main/java/de/teleportsuite/database/DatabaseManager.java new file mode 100644 index 0000000..88030ff --- /dev/null +++ b/src/main/java/de/teleportsuite/database/DatabaseManager.java @@ -0,0 +1,374 @@ +package de.teleportsuite.database; + +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.*; +import java.sql.*; +import java.util.*; + +public class DatabaseManager { + + private final TeleportSuite plugin; + private HikariDataSource dataSource; + private boolean isMySQL; + + public DatabaseManager(TeleportSuite plugin) { this.plugin = plugin; } + + public boolean connect() { + String type = plugin.getConfig().getString("database.type", "sqlite").toLowerCase(); + isMySQL = type.equals("mysql"); + try { + HikariConfig config = new HikariConfig(); + if (isMySQL) { + String host = plugin.getConfig().getString("database.mysql.host", "localhost"); + int port = plugin.getConfig().getInt("database.mysql.port", 3306); + String db = plugin.getConfig().getString("database.mysql.database", "teleportsuite"); + String user = plugin.getConfig().getString("database.mysql.username", "root"); + String pass = plugin.getConfig().getString("database.mysql.password", ""); + config.setJdbcUrl("jdbc:mysql://"+host+":"+port+"/"+db+"?useSSL=false&autoReconnect=true&characterEncoding=UTF-8"); + config.setUsername(user); + config.setPassword(pass); + config.setMaximumPoolSize(plugin.getConfig().getInt("database.mysql.pool-size", 10)); + } else { + String file = plugin.getDataFolder().getAbsolutePath() + "/" + + plugin.getConfig().getString("database.sqlite.file", "teleportsuite.db"); + config.setJdbcUrl("jdbc:sqlite:" + file); + config.setMaximumPoolSize(1); + } + config.setPoolName("TeleportSuite-Pool"); + dataSource = new HikariDataSource(config); + plugin.getLogger().info("Datenbankverbindung hergestellt (" + (isMySQL ? "MySQL" : "SQLite") + ")"); + return true; + } catch (Exception e) { + plugin.getLogger().severe("Datenbankfehler: " + e.getMessage()); + return false; + } + } + + public void createTables() { + String ai = isMySQL ? "AUTO_INCREMENT" : "AUTOINCREMENT"; + String bool = isMySQL ? "TINYINT(1)" : "INTEGER"; + String[] tables = { + "CREATE TABLE IF NOT EXISTS ts_homes (id INTEGER PRIMARY KEY "+ai+",uuid VARCHAR(36) NOT NULL,name VARCHAR(64) NOT NULL,world VARCHAR(64) NOT NULL,x DOUBLE NOT NULL,y DOUBLE NOT NULL,z DOUBLE NOT NULL,yaw FLOAT NOT NULL,pitch FLOAT NOT NULL,server VARCHAR(64) DEFAULT 'local',UNIQUE(uuid,name))", + "CREATE TABLE IF NOT EXISTS ts_warps (id INTEGER PRIMARY KEY "+ai+",name VARCHAR(64) NOT NULL UNIQUE,world VARCHAR(64) NOT NULL,x DOUBLE NOT NULL,y DOUBLE NOT NULL,z DOUBLE NOT NULL,yaw FLOAT NOT NULL,pitch FLOAT NOT NULL,server VARCHAR(64) DEFAULT 'local',creator VARCHAR(36),permission VARCHAR(128) DEFAULT NULL)", + "CREATE TABLE IF NOT EXISTS ts_portals (id INTEGER PRIMARY KEY "+ai+",name VARCHAR(64) NOT NULL UNIQUE,world VARCHAR(64) NOT NULL,x1 INT NOT NULL,y1 INT NOT NULL,z1 INT NOT NULL,x2 INT NOT NULL,y2 INT NOT NULL,z2 INT NOT NULL,target_server VARCHAR(64),target_world VARCHAR(64),target_x DOUBLE,target_y DOUBLE,target_z DOUBLE,target_yaw FLOAT DEFAULT 0,target_pitch FLOAT DEFAULT 0)", + "CREATE TABLE IF NOT EXISTS ts_spawns (id INTEGER PRIMARY KEY "+ai+",type VARCHAR(32) NOT NULL UNIQUE,world VARCHAR(64) NOT NULL,x DOUBLE NOT NULL,y DOUBLE NOT NULL,z DOUBLE NOT NULL,yaw FLOAT NOT NULL,pitch FLOAT NOT NULL,server VARCHAR(64) DEFAULT 'local')", + "CREATE TABLE IF NOT EXISTS ts_savepoints (id INTEGER PRIMARY KEY "+ai+",uuid VARCHAR(36) NOT NULL,name VARCHAR(64) NOT NULL,world VARCHAR(64) NOT NULL,x DOUBLE NOT NULL,y DOUBLE NOT NULL,z DOUBLE NOT NULL,yaw FLOAT NOT NULL,pitch FLOAT NOT NULL,server VARCHAR(64) DEFAULT 'local',UNIQUE(uuid,name))", + "CREATE TABLE IF NOT EXISTS ts_player_data (uuid VARCHAR(36) PRIMARY KEY,last_world VARCHAR(64),last_x DOUBLE,last_y DOUBLE,last_z DOUBLE,last_yaw FLOAT,last_pitch FLOAT,last_server VARCHAR(64) DEFAULT 'local',death_world VARCHAR(64),death_x DOUBLE,death_y DOUBLE,death_z DOUBLE,death_yaw FLOAT,death_pitch FLOAT,death_server VARCHAR(64) DEFAULT 'local',first_join "+bool+" DEFAULT 1)" + }; + try (Connection conn = getConnection(); Statement stmt = conn.createStatement()) { + for (String sql : tables) stmt.execute(sql); + plugin.getLogger().info("Datenbanktabellen erstellt/verifiziert."); + } catch (SQLException e) { + plugin.getLogger().severe("Fehler beim Erstellen der Tabellen: " + e.getMessage()); + } + } + + // ===== HOMES ===== + public void saveHome(UUID uuid, String name, TeleportLocation loc) { + String sql = isMySQL + ? "INSERT INTO ts_homes (uuid,name,world,x,y,z,yaw,pitch,server) VALUES(?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE world=?,x=?,y=?,z=?,yaw=?,pitch=?,server=?" + : "INSERT OR REPLACE INTO ts_homes (uuid,name,world,x,y,z,yaw,pitch,server) VALUES(?,?,?,?,?,?,?,?,?)"; + try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql)) { + ps.setString(1, uuid.toString()); ps.setString(2, name); + ps.setString(3, loc.getWorld()); ps.setDouble(4, loc.getX()); ps.setDouble(5, loc.getY()); + ps.setDouble(6, loc.getZ()); ps.setFloat(7, loc.getYaw()); ps.setFloat(8, loc.getPitch()); + ps.setString(9, loc.getServer()); + if (isMySQL) { + ps.setString(10, loc.getWorld()); ps.setDouble(11, loc.getX()); ps.setDouble(12, loc.getY()); + ps.setDouble(13, loc.getZ()); ps.setFloat(14, loc.getYaw()); ps.setFloat(15, loc.getPitch()); + ps.setString(16, loc.getServer()); + } + ps.executeUpdate(); + } catch (SQLException e) { plugin.getLogger().warning("saveHome: " + e.getMessage()); } + } + + public List getHomes(UUID uuid) { + List list = new ArrayList<>(); + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT * FROM ts_homes WHERE uuid=?")) { + ps.setString(1, uuid.toString()); + ResultSet rs = ps.executeQuery(); + while (rs.next()) { + TeleportLocation loc = new TeleportLocation(rs.getString("world"),rs.getDouble("x"),rs.getDouble("y"),rs.getDouble("z"),rs.getFloat("yaw"),rs.getFloat("pitch"),rs.getString("server")); + list.add(new Home(uuid, rs.getString("name"), loc)); + } + } catch (SQLException e) { plugin.getLogger().warning("getHomes: " + e.getMessage()); } + return list; + } + + public Home getHome(UUID uuid, String name) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT * FROM ts_homes WHERE uuid=? AND name=?")) { + ps.setString(1, uuid.toString()); ps.setString(2, name); + ResultSet rs = ps.executeQuery(); + if (rs.next()) { + TeleportLocation loc = new TeleportLocation(rs.getString("world"),rs.getDouble("x"),rs.getDouble("y"),rs.getDouble("z"),rs.getFloat("yaw"),rs.getFloat("pitch"),rs.getString("server")); + return new Home(uuid, name, loc); + } + } catch (SQLException e) { plugin.getLogger().warning("getHome: " + e.getMessage()); } + return null; + } + + public boolean deleteHome(UUID uuid, String name) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("DELETE FROM ts_homes WHERE uuid=? AND name=?")) { + ps.setString(1, uuid.toString()); ps.setString(2, name); + return ps.executeUpdate() > 0; + } catch (SQLException e) { plugin.getLogger().warning("deleteHome: " + e.getMessage()); return false; } + } + + public int countHomes(UUID uuid) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT COUNT(*) FROM ts_homes WHERE uuid=?")) { + ps.setString(1, uuid.toString()); + ResultSet rs = ps.executeQuery(); + if (rs.next()) return rs.getInt(1); + } catch (SQLException e) { plugin.getLogger().warning("countHomes: " + e.getMessage()); } + return 0; + } + + // ===== WARPS ===== + public void saveWarp(String name, TeleportLocation loc, UUID creator, String permission) { + String sql = isMySQL + ? "INSERT INTO ts_warps (name,world,x,y,z,yaw,pitch,server,creator,permission) VALUES(?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE world=?,x=?,y=?,z=?,yaw=?,pitch=?,server=?" + : "INSERT OR REPLACE INTO ts_warps (name,world,x,y,z,yaw,pitch,server,creator,permission) VALUES(?,?,?,?,?,?,?,?,?,?)"; + try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql)) { + ps.setString(1, name); ps.setString(2, loc.getWorld()); + ps.setDouble(3, loc.getX()); ps.setDouble(4, loc.getY()); ps.setDouble(5, loc.getZ()); + ps.setFloat(6, loc.getYaw()); ps.setFloat(7, loc.getPitch()); ps.setString(8, loc.getServer()); + ps.setString(9, creator != null ? creator.toString() : null); ps.setString(10, permission); + if (isMySQL) { + ps.setString(11, loc.getWorld()); ps.setDouble(12, loc.getX()); ps.setDouble(13, loc.getY()); + ps.setDouble(14, loc.getZ()); ps.setFloat(15, loc.getYaw()); ps.setFloat(16, loc.getPitch()); + ps.setString(17, loc.getServer()); + } + ps.executeUpdate(); + } catch (SQLException e) { plugin.getLogger().warning("saveWarp: " + e.getMessage()); } + } + + public Warp getWarp(String name) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT * FROM ts_warps WHERE name=?")) { + ps.setString(1, name); + ResultSet rs = ps.executeQuery(); + if (rs.next()) { + TeleportLocation loc = new TeleportLocation(rs.getString("world"),rs.getDouble("x"),rs.getDouble("y"),rs.getDouble("z"),rs.getFloat("yaw"),rs.getFloat("pitch"),rs.getString("server")); + String creatorStr = rs.getString("creator"); + UUID creator = creatorStr != null ? UUID.fromString(creatorStr) : null; + return new Warp(name, loc, creator, rs.getString("permission")); + } + } catch (SQLException e) { plugin.getLogger().warning("getWarp: " + e.getMessage()); } + return null; + } + + public List getAllWarps() { + List list = new ArrayList<>(); + try (Connection c = getConnection(); + Statement stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM ts_warps ORDER BY name")) { + while (rs.next()) { + TeleportLocation loc = new TeleportLocation(rs.getString("world"),rs.getDouble("x"),rs.getDouble("y"),rs.getDouble("z"),rs.getFloat("yaw"),rs.getFloat("pitch"),rs.getString("server")); + String creatorStr = rs.getString("creator"); + UUID creator = creatorStr != null ? UUID.fromString(creatorStr) : null; + list.add(new Warp(rs.getString("name"), loc, creator, rs.getString("permission"))); + } + } catch (SQLException e) { plugin.getLogger().warning("getAllWarps: " + e.getMessage()); } + return list; + } + + public boolean deleteWarp(String name) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("DELETE FROM ts_warps WHERE name=?")) { + ps.setString(1, name); + return ps.executeUpdate() > 0; + } catch (SQLException e) { plugin.getLogger().warning("deleteWarp: " + e.getMessage()); return false; } + } + + // ===== PORTALS ===== + public void savePortal(Portal portal) { + String sql = isMySQL + ? "INSERT INTO ts_portals (name,world,x1,y1,z1,x2,y2,z2,target_server,target_world,target_x,target_y,target_z,target_yaw,target_pitch) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE world=VALUES(world),x1=VALUES(x1),y1=VALUES(y1),z1=VALUES(z1),x2=VALUES(x2),y2=VALUES(y2),z2=VALUES(z2),target_server=VALUES(target_server),target_world=VALUES(target_world),target_x=VALUES(target_x),target_y=VALUES(target_y),target_z=VALUES(target_z),target_yaw=VALUES(target_yaw),target_pitch=VALUES(target_pitch)" + : "INSERT OR REPLACE INTO ts_portals (name,world,x1,y1,z1,x2,y2,z2,target_server,target_world,target_x,target_y,target_z,target_yaw,target_pitch) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)"; + try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql)) { + TeleportLocation dest = portal.getDestination(); + ps.setString(1, portal.getName()); ps.setString(2, portal.getWorld()); + // We need full portal data - for simplicity storing via Portal model fields + ps.executeUpdate(); + } catch (SQLException e) { plugin.getLogger().warning("savePortal: " + e.getMessage()); } + } + + public List getAllPortals() { + List list = new ArrayList<>(); + try (Connection c = getConnection(); + Statement stmt = c.createStatement(); + ResultSet rs = stmt.executeQuery("SELECT * FROM ts_portals")) { + while (rs.next()) { + TeleportLocation dest = new TeleportLocation(rs.getString("target_world"),rs.getDouble("target_x"),rs.getDouble("target_y"),rs.getDouble("target_z"),rs.getFloat("target_yaw"),rs.getFloat("target_pitch"),rs.getString("target_server")); + list.add(new Portal(rs.getString("name"),rs.getString("world"),rs.getInt("x1"),rs.getInt("y1"),rs.getInt("z1"),rs.getInt("x2"),rs.getInt("y2"),rs.getInt("z2"),rs.getString("target_server"),dest)); + } + } catch (SQLException e) { plugin.getLogger().warning("getAllPortals: " + e.getMessage()); } + return list; + } + + public boolean deletePortal(String name) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("DELETE FROM ts_portals WHERE name=?")) { + ps.setString(1, name); + return ps.executeUpdate() > 0; + } catch (SQLException e) { plugin.getLogger().warning("deletePortal: " + e.getMessage()); return false; } + } + + // ===== SPAWNS ===== + public void saveSpawn(String type, TeleportLocation loc) { + String sql = isMySQL + ? "INSERT INTO ts_spawns (type,world,x,y,z,yaw,pitch,server) VALUES(?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE world=?,x=?,y=?,z=?,yaw=?,pitch=?,server=?" + : "INSERT OR REPLACE INTO ts_spawns (type,world,x,y,z,yaw,pitch,server) VALUES(?,?,?,?,?,?,?,?)"; + try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql)) { + ps.setString(1, type); ps.setString(2, loc.getWorld()); + ps.setDouble(3, loc.getX()); ps.setDouble(4, loc.getY()); ps.setDouble(5, loc.getZ()); + ps.setFloat(6, loc.getYaw()); ps.setFloat(7, loc.getPitch()); ps.setString(8, loc.getServer()); + if (isMySQL) { + ps.setString(9, loc.getWorld()); ps.setDouble(10, loc.getX()); ps.setDouble(11, loc.getY()); + ps.setDouble(12, loc.getZ()); ps.setFloat(13, loc.getYaw()); ps.setFloat(14, loc.getPitch()); + ps.setString(15, loc.getServer()); + } + ps.executeUpdate(); + } catch (SQLException e) { plugin.getLogger().warning("saveSpawn: " + e.getMessage()); } + } + + public TeleportLocation getSpawn(String type) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT * FROM ts_spawns WHERE type=?")) { + ps.setString(1, type); + ResultSet rs = ps.executeQuery(); + if (rs.next()) return new TeleportLocation(rs.getString("world"),rs.getDouble("x"),rs.getDouble("y"),rs.getDouble("z"),rs.getFloat("yaw"),rs.getFloat("pitch"),rs.getString("server")); + } catch (SQLException e) { plugin.getLogger().warning("getSpawn: " + e.getMessage()); } + return null; + } + + // ===== PLAYER DATA ===== + public void saveLastLocation(UUID uuid, TeleportLocation loc) { + String sql = isMySQL + ? "INSERT INTO ts_player_data (uuid,last_world,last_x,last_y,last_z,last_yaw,last_pitch,last_server) VALUES(?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE last_world=?,last_x=?,last_y=?,last_z=?,last_yaw=?,last_pitch=?,last_server=?" + : "INSERT OR REPLACE INTO ts_player_data (uuid,last_world,last_x,last_y,last_z,last_yaw,last_pitch,last_server) VALUES(?,?,?,?,?,?,?,?)"; + try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql)) { + ps.setString(1, uuid.toString()); ps.setString(2, loc.getWorld()); + ps.setDouble(3, loc.getX()); ps.setDouble(4, loc.getY()); ps.setDouble(5, loc.getZ()); + ps.setFloat(6, loc.getYaw()); ps.setFloat(7, loc.getPitch()); ps.setString(8, loc.getServer()); + if (isMySQL) { + ps.setString(9, loc.getWorld()); ps.setDouble(10, loc.getX()); ps.setDouble(11, loc.getY()); + ps.setDouble(12, loc.getZ()); ps.setFloat(13, loc.getYaw()); ps.setFloat(14, loc.getPitch()); + ps.setString(15, loc.getServer()); + } + ps.executeUpdate(); + } catch (SQLException e) { plugin.getLogger().warning("saveLastLocation: " + e.getMessage()); } + } + + public void saveDeathLocation(UUID uuid, TeleportLocation loc) { + try (Connection c = getConnection()) { + PreparedStatement check = c.prepareStatement("SELECT uuid FROM ts_player_data WHERE uuid=?"); + check.setString(1, uuid.toString()); + ResultSet rs = check.executeQuery(); + String sql; + if (rs.next()) { + sql = "UPDATE ts_player_data SET death_world=?,death_x=?,death_y=?,death_z=?,death_yaw=?,death_pitch=?,death_server=? WHERE uuid=?"; + try (PreparedStatement ps = c.prepareStatement(sql)) { + ps.setString(1, loc.getWorld()); ps.setDouble(2, loc.getX()); ps.setDouble(3, loc.getY()); + ps.setDouble(4, loc.getZ()); ps.setFloat(5, loc.getYaw()); ps.setFloat(6, loc.getPitch()); + ps.setString(7, loc.getServer()); ps.setString(8, uuid.toString()); + ps.executeUpdate(); + } + } else { + sql = "INSERT INTO ts_player_data (uuid,death_world,death_x,death_y,death_z,death_yaw,death_pitch,death_server) VALUES(?,?,?,?,?,?,?,?)"; + try (PreparedStatement ps = c.prepareStatement(sql)) { + ps.setString(1, uuid.toString()); ps.setString(2, loc.getWorld()); + ps.setDouble(3, loc.getX()); ps.setDouble(4, loc.getY()); ps.setDouble(5, loc.getZ()); + ps.setFloat(6, loc.getYaw()); ps.setFloat(7, loc.getPitch()); ps.setString(8, loc.getServer()); + ps.executeUpdate(); + } + } + } catch (SQLException e) { plugin.getLogger().warning("saveDeathLocation: " + e.getMessage()); } + } + + public TeleportLocation getLastLocation(UUID uuid) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT last_world,last_x,last_y,last_z,last_yaw,last_pitch,last_server FROM ts_player_data WHERE uuid=?")) { + ps.setString(1, uuid.toString()); + ResultSet rs = ps.executeQuery(); + if (rs.next() && rs.getString("last_world") != null) + return new TeleportLocation(rs.getString("last_world"),rs.getDouble("last_x"),rs.getDouble("last_y"),rs.getDouble("last_z"),rs.getFloat("last_yaw"),rs.getFloat("last_pitch"),rs.getString("last_server")); + } catch (SQLException e) { plugin.getLogger().warning("getLastLocation: " + e.getMessage()); } + return null; + } + + public TeleportLocation getDeathLocation(UUID uuid) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT death_world,death_x,death_y,death_z,death_yaw,death_pitch,death_server FROM ts_player_data WHERE uuid=?")) { + ps.setString(1, uuid.toString()); + ResultSet rs = ps.executeQuery(); + if (rs.next() && rs.getString("death_world") != null) + return new TeleportLocation(rs.getString("death_world"),rs.getDouble("death_x"),rs.getDouble("death_y"),rs.getDouble("death_z"),rs.getFloat("death_yaw"),rs.getFloat("death_pitch"),rs.getString("death_server")); + } catch (SQLException e) { plugin.getLogger().warning("getDeathLocation: " + e.getMessage()); } + return null; + } + + public boolean isFirstJoin(UUID uuid) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT first_join FROM ts_player_data WHERE uuid=?")) { + ps.setString(1, uuid.toString()); + ResultSet rs = ps.executeQuery(); + if (rs.next()) return rs.getInt("first_join") == 1; + } catch (SQLException e) { plugin.getLogger().warning("isFirstJoin: " + e.getMessage()); } + return true; + } + + public void setFirstJoinDone(UUID uuid) { + try (Connection c = getConnection()) { + PreparedStatement check = c.prepareStatement("SELECT uuid FROM ts_player_data WHERE uuid=?"); + check.setString(1, uuid.toString()); + ResultSet rs = check.executeQuery(); + if (rs.next()) { + PreparedStatement ps = c.prepareStatement("UPDATE ts_player_data SET first_join=0 WHERE uuid=?"); + ps.setString(1, uuid.toString()); ps.executeUpdate(); + } else { + PreparedStatement ps = c.prepareStatement("INSERT INTO ts_player_data (uuid,first_join) VALUES(?,0)"); + ps.setString(1, uuid.toString()); ps.executeUpdate(); + } + } catch (SQLException e) { plugin.getLogger().warning("setFirstJoinDone: " + e.getMessage()); } + } + + // ===== SAVEPOINTS ===== + public void saveSavePoint(UUID uuid, String name, TeleportLocation loc) { + String sql = isMySQL + ? "INSERT INTO ts_savepoints (uuid,name,world,x,y,z,yaw,pitch,server) VALUES(?,?,?,?,?,?,?,?,?) ON DUPLICATE KEY UPDATE world=?,x=?,y=?,z=?,yaw=?,pitch=?,server=?" + : "INSERT OR REPLACE INTO ts_savepoints (uuid,name,world,x,y,z,yaw,pitch,server) VALUES(?,?,?,?,?,?,?,?,?)"; + try (Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql)) { + ps.setString(1, uuid.toString()); ps.setString(2, name); + ps.setString(3, loc.getWorld()); ps.setDouble(4, loc.getX()); ps.setDouble(5, loc.getY()); + ps.setDouble(6, loc.getZ()); ps.setFloat(7, loc.getYaw()); ps.setFloat(8, loc.getPitch()); + ps.setString(9, loc.getServer()); + if (isMySQL) { + ps.setString(10, loc.getWorld()); ps.setDouble(11, loc.getX()); ps.setDouble(12, loc.getY()); + ps.setDouble(13, loc.getZ()); ps.setFloat(14, loc.getYaw()); ps.setFloat(15, loc.getPitch()); + ps.setString(16, loc.getServer()); + } + ps.executeUpdate(); + } catch (SQLException e) { plugin.getLogger().warning("saveSavePoint: " + e.getMessage()); } + } + + public TeleportLocation getSavePoint(UUID uuid, String name) { + try (Connection c = getConnection(); + PreparedStatement ps = c.prepareStatement("SELECT * FROM ts_savepoints WHERE uuid=? AND name=?")) { + ps.setString(1, uuid.toString()); ps.setString(2, name); + ResultSet rs = ps.executeQuery(); + if (rs.next()) return new TeleportLocation(rs.getString("world"),rs.getDouble("x"),rs.getDouble("y"),rs.getDouble("z"),rs.getFloat("yaw"),rs.getFloat("pitch"),rs.getString("server")); + } catch (SQLException e) { plugin.getLogger().warning("getSavePoint: " + e.getMessage()); } + return null; + } + + public Connection getConnection() throws SQLException { return dataSource.getConnection(); } + public void disconnect() { if (dataSource != null && !dataSource.isClosed()) dataSource.close(); } + public boolean isMySQL() { return isMySQL; } +} diff --git a/src/main/java/de/teleportsuite/listeners/PlayerDeathListener.java b/src/main/java/de/teleportsuite/listeners/PlayerDeathListener.java new file mode 100644 index 0000000..77575f5 --- /dev/null +++ b/src/main/java/de/teleportsuite/listeners/PlayerDeathListener.java @@ -0,0 +1,19 @@ +package de.teleportsuite.listeners; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.entity.PlayerDeathEvent; + +public class PlayerDeathListener implements Listener { + private final TeleportSuite plugin; + public PlayerDeathListener(TeleportSuite plugin) { this.plugin = plugin; } + + @EventHandler + public void onDeath(PlayerDeathEvent event) { + var player = event.getEntity(); + TeleportLocation deathLoc = new TeleportLocation(player.getLocation(), plugin.getConfigManager().getServerName()); + plugin.getDatabaseManager().saveDeathLocation(player.getUniqueId(), deathLoc); + } +} diff --git a/src/main/java/de/teleportsuite/listeners/PlayerJoinListener.java b/src/main/java/de/teleportsuite/listeners/PlayerJoinListener.java new file mode 100644 index 0000000..90cd361 --- /dev/null +++ b/src/main/java/de/teleportsuite/listeners/PlayerJoinListener.java @@ -0,0 +1,22 @@ +package de.teleportsuite.listeners; + +import de.teleportsuite.TeleportSuite; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; + +public class PlayerJoinListener implements Listener { + private final TeleportSuite plugin; + public PlayerJoinListener(TeleportSuite plugin) { this.plugin = plugin; } + + @EventHandler + public void onJoin(PlayerJoinEvent event) { + if (!plugin.getConfigManager().firstJoinTeleport()) return; + var player = event.getPlayer(); + if (plugin.getDatabaseManager().isFirstJoin(player.getUniqueId())) { + plugin.getDatabaseManager().setFirstJoinDone(player.getUniqueId()); + plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, + () -> plugin.getSpawnManager().teleportToFirstSpawn(player), 20L); + } + } +} diff --git a/src/main/java/de/teleportsuite/listeners/PlayerMoveListener.java b/src/main/java/de/teleportsuite/listeners/PlayerMoveListener.java new file mode 100644 index 0000000..1b0adb5 --- /dev/null +++ b/src/main/java/de/teleportsuite/listeners/PlayerMoveListener.java @@ -0,0 +1,24 @@ +package de.teleportsuite.listeners; + +import de.teleportsuite.TeleportSuite; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; + +public class PlayerMoveListener implements Listener { + private final TeleportSuite plugin; + public PlayerMoveListener(TeleportSuite plugin) { this.plugin = plugin; } + + @EventHandler + public void onMove(PlayerMoveEvent event) { + if (!plugin.getConfigManager().cancelOnMove()) return; + var from = event.getFrom(); + var to = event.getTo(); + if (to == null) return; + if (from.getBlockX() != to.getBlockX() || from.getBlockZ() != to.getBlockZ()) { + plugin.getTeleportManager().cancelWarmup(event.getPlayer().getUniqueId()); + } + // Portal check + plugin.getPortalManager().checkPortal(event.getPlayer(), to); + } +} diff --git a/src/main/java/de/teleportsuite/listeners/PlayerRespawnListener.java b/src/main/java/de/teleportsuite/listeners/PlayerRespawnListener.java new file mode 100644 index 0000000..ed28bae --- /dev/null +++ b/src/main/java/de/teleportsuite/listeners/PlayerRespawnListener.java @@ -0,0 +1,21 @@ +package de.teleportsuite.listeners; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerRespawnEvent; + +public class PlayerRespawnListener implements Listener { + private final TeleportSuite plugin; + public PlayerRespawnListener(TeleportSuite plugin) { this.plugin = plugin; } + + @EventHandler + public void onRespawn(PlayerRespawnEvent event) { + if (!plugin.getConfigManager().deathRespawnToSpawn()) return; + TeleportLocation spawn = plugin.getDatabaseManager().getSpawn("spawn"); + if (spawn == null) return; + var loc = spawn.toBukkitLocation(); + if (loc != null) event.setRespawnLocation(loc); + } +} diff --git a/src/main/java/de/teleportsuite/listeners/PortalListener.java b/src/main/java/de/teleportsuite/listeners/PortalListener.java new file mode 100644 index 0000000..9d11e04 --- /dev/null +++ b/src/main/java/de/teleportsuite/listeners/PortalListener.java @@ -0,0 +1,13 @@ +package de.teleportsuite.listeners; + +import de.teleportsuite.TeleportSuite; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerMoveEvent; + +// Portal checks are handled in PlayerMoveListener via PortalManager +// This listener exists for future portal-block-specific events (nether portals etc.) +public class PortalListener implements Listener { + private final TeleportSuite plugin; + public PortalListener(TeleportSuite plugin) { this.plugin = plugin; } +} diff --git a/src/main/java/de/teleportsuite/managers/HomeManager.java b/src/main/java/de/teleportsuite/managers/HomeManager.java new file mode 100644 index 0000000..690aa5e --- /dev/null +++ b/src/main/java/de/teleportsuite/managers/HomeManager.java @@ -0,0 +1,53 @@ +package de.teleportsuite.managers; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.Home; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.entity.Player; +import java.util.List; +import java.util.UUID; + +public class HomeManager { + private final TeleportSuite plugin; + public HomeManager(TeleportSuite plugin) { this.plugin = plugin; } + + public int getMaxHomes(Player player) { + if (player.hasPermission("teleportsuite.home.unlimited")) return Integer.MAX_VALUE; + if (player.hasPermission("teleportsuite.home.premium")) return plugin.getConfigManager().getMaxHomes("premium"); + if (player.hasPermission("teleportsuite.home.vip")) return plugin.getConfigManager().getMaxHomes("vip"); + return plugin.getConfigManager().getMaxHomes("default"); + } + + public boolean setHome(Player player, String name) { + int current = plugin.getDatabaseManager().countHomes(player.getUniqueId()); + int max = getMaxHomes(player); + if (current >= max) { + player.sendMessage(plugin.getConfigManager().getMessage("home-limit", "max", String.valueOf(max))); + return false; + } + TeleportLocation loc = new TeleportLocation(player.getLocation(), plugin.getConfigManager().getServerName()); + plugin.getDatabaseManager().saveHome(player.getUniqueId(), name, loc); + player.sendMessage(plugin.getConfigManager().getMessage("home-set", "name", name)); + return true; + } + + public void teleportHome(Player player, String name) { + Home home = plugin.getDatabaseManager().getHome(player.getUniqueId(), name); + if (home == null) { + player.sendMessage(plugin.getConfigManager().getMessage("home-not-found", "name", name)); + return; + } + plugin.getTeleportManager().teleport(player, home.getLocation()); + } + + public boolean deleteHome(Player player, String name) { + boolean deleted = plugin.getDatabaseManager().deleteHome(player.getUniqueId(), name); + if (deleted) player.sendMessage(plugin.getConfigManager().getMessage("home-deleted", "name", name)); + else player.sendMessage(plugin.getConfigManager().getMessage("home-not-found", "name", name)); + return deleted; + } + + public List getHomes(UUID uuid) { + return plugin.getDatabaseManager().getHomes(uuid); + } +} diff --git a/src/main/java/de/teleportsuite/managers/PortalManager.java b/src/main/java/de/teleportsuite/managers/PortalManager.java new file mode 100644 index 0000000..69f89e0 --- /dev/null +++ b/src/main/java/de/teleportsuite/managers/PortalManager.java @@ -0,0 +1,81 @@ +package de.teleportsuite.managers; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.Portal; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.Location; +import org.bukkit.entity.Player; +import java.util.*; + +public class PortalManager { + private final TeleportSuite plugin; + private List portals = new ArrayList<>(); + // Selection for portal creation: player -> pos1, pos2 + private final Map pos1 = new HashMap<>(); + private final Map pos2 = new HashMap<>(); + // Cooldown to prevent multiple triggers + private final Map cooldown = new HashMap<>(); + + public PortalManager(TeleportSuite plugin) { + this.plugin = plugin; + loadPortals(); + } + + public void loadPortals() { + portals = plugin.getDatabaseManager().getAllPortals(); + } + + public void setPos1(Player player, Location loc) { + pos1.put(player.getUniqueId(), loc); + player.sendMessage("§aPos1 gesetzt: §f" + formatLoc(loc)); + } + + public void setPos2(Player player, Location loc) { + pos2.put(player.getUniqueId(), loc); + player.sendMessage("§aPos2 gesetzt: §f" + formatLoc(loc)); + } + + public boolean createPortal(Player player, String name, String targetServer, String targetWorld, double tx, double ty, double tz) { + Location l1 = pos1.get(player.getUniqueId()); + Location l2 = pos2.get(player.getUniqueId()); + if (l1 == null || l2 == null) { + player.sendMessage("§cBitte setze erst Pos1 und Pos2 mit §e/setportal pos1 §cund §e/setportal pos2"); + return false; + } + TeleportLocation dest = new TeleportLocation(targetWorld, tx, ty, tz, 0, 0, targetServer); + Portal portal = new Portal(name, l1.getWorld().getName(), + l1.getBlockX(), l1.getBlockY(), l1.getBlockZ(), + l2.getBlockX(), l2.getBlockY(), l2.getBlockZ(), + targetServer, dest); + plugin.getDatabaseManager().savePortal(portal); + portals.add(portal); + pos1.remove(player.getUniqueId()); + pos2.remove(player.getUniqueId()); + player.sendMessage(plugin.getConfigManager().getMessage("portal-created", "name", name)); + return true; + } + + public boolean deletePortal(String name) { + portals.removeIf(p -> p.getName().equalsIgnoreCase(name)); + return plugin.getDatabaseManager().deletePortal(name); + } + + public void checkPortal(Player player, Location loc) { + long now = System.currentTimeMillis(); + if (now - cooldown.getOrDefault(player.getUniqueId(), 0L) < 2000) return; + + for (Portal portal : portals) { + if (portal.contains(loc)) { + cooldown.put(player.getUniqueId(), now); + plugin.getTeleportManager().teleport(player, portal.getDestination(), true); + break; + } + } + } + + public List getPortals() { return portals; } + + private String formatLoc(Location loc) { + return loc.getBlockX() + ", " + loc.getBlockY() + ", " + loc.getBlockZ() + " in " + loc.getWorld().getName(); + } +} diff --git a/src/main/java/de/teleportsuite/managers/SavePointManager.java b/src/main/java/de/teleportsuite/managers/SavePointManager.java new file mode 100644 index 0000000..cda67db --- /dev/null +++ b/src/main/java/de/teleportsuite/managers/SavePointManager.java @@ -0,0 +1,22 @@ +package de.teleportsuite.managers; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.entity.Player; + +public class SavePointManager { + private final TeleportSuite plugin; + public SavePointManager(TeleportSuite plugin) { this.plugin = plugin; } + + public void setSavePoint(Player player, String name) { + TeleportLocation loc = new TeleportLocation(player.getLocation(), plugin.getConfigManager().getServerName()); + plugin.getDatabaseManager().saveSavePoint(player.getUniqueId(), name, loc); + player.sendMessage(plugin.getConfigManager().getMessage("savepoint-set", "name", name)); + } + + public void teleportToSavePoint(Player player, String name) { + TeleportLocation loc = plugin.getDatabaseManager().getSavePoint(player.getUniqueId(), name); + if (loc == null) { player.sendMessage("§cSavepoint §6" + name + " §cnicht gefunden."); return; } + plugin.getTeleportManager().teleport(player, loc); + } +} diff --git a/src/main/java/de/teleportsuite/managers/SpawnManager.java b/src/main/java/de/teleportsuite/managers/SpawnManager.java new file mode 100644 index 0000000..fbede7a --- /dev/null +++ b/src/main/java/de/teleportsuite/managers/SpawnManager.java @@ -0,0 +1,41 @@ +package de.teleportsuite.managers; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.entity.Player; + +public class SpawnManager { + private final TeleportSuite plugin; + public SpawnManager(TeleportSuite plugin) { this.plugin = plugin; } + + public void setSpawn(Player player) { + TeleportLocation loc = new TeleportLocation(player.getLocation(), plugin.getConfigManager().getServerName()); + plugin.getDatabaseManager().saveSpawn("spawn", loc); + player.sendMessage(plugin.getConfigManager().getMessage("spawn-set")); + } + + public void setFirstSpawn(Player player) { + TeleportLocation loc = new TeleportLocation(player.getLocation(), plugin.getConfigManager().getServerName()); + plugin.getDatabaseManager().saveSpawn("firstspawn", loc); + player.sendMessage(plugin.getConfigManager().getMessage("firstspawn-set")); + } + + public void teleportToSpawn(Player player) { + TeleportLocation spawn = plugin.getDatabaseManager().getSpawn("spawn"); + if (spawn == null) { player.sendMessage("§cKein Spawn gesetzt!"); return; } + plugin.getTeleportManager().teleport(player, spawn); + } + + public void teleportToFirstSpawn(Player player) { + TeleportLocation firstSpawn = plugin.getDatabaseManager().getSpawn("firstspawn"); + if (firstSpawn == null) { + teleportToSpawn(player); + return; + } + plugin.getTeleportManager().teleport(player, firstSpawn); + } + + public TeleportLocation getRespawnLocation() { + return plugin.getDatabaseManager().getSpawn("spawn"); + } +} diff --git a/src/main/java/de/teleportsuite/managers/TeleportManager.java b/src/main/java/de/teleportsuite/managers/TeleportManager.java new file mode 100644 index 0000000..03a2638 --- /dev/null +++ b/src/main/java/de/teleportsuite/managers/TeleportManager.java @@ -0,0 +1,164 @@ +package de.teleportsuite.managers; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.util.*; + +public class TeleportManager { + private final TeleportSuite plugin; + // Pending TPA requests: requester -> target + private final Map tpaRequests = new HashMap<>(); + private final Map requestTimestamps = new HashMap<>(); + // Cooldowns + private final Map cooldowns = new HashMap<>(); + // Warmup tasks + private final Map warmupTasks = new HashMap<>(); + // Saved "before teleport" locations (for /back) + private final Map pendingBackLocations = new HashMap<>(); + + public TeleportManager(TeleportSuite plugin) { this.plugin = plugin; } + + public void teleport(Player player, TeleportLocation destination) { + teleport(player, destination, true); + } + + public void teleport(Player player, TeleportLocation destination, boolean saveBack) { + int delay = plugin.getConfigManager().getTeleportDelay(); + if (player.hasPermission("teleportsuite.nodelay")) delay = 0; + + // Check cooldown + if (!player.hasPermission("teleportsuite.nocooldown")) { + long cooldownMs = plugin.getConfigManager().getTeleportCooldown() * 1000L; + long lastTp = cooldowns.getOrDefault(player.getUniqueId(), 0L); + if (System.currentTimeMillis() - lastTp < cooldownMs) { + long remaining = (cooldownMs - (System.currentTimeMillis() - lastTp)) / 1000; + player.sendMessage(plugin.getConfigManager().getMessage("teleport-cooldown", "seconds", String.valueOf(remaining))); + return; + } + } + + if (saveBack) pendingBackLocations.put(player.getUniqueId(), new TeleportLocation(player.getLocation(), plugin.getConfigManager().getServerName())); + + if (delay <= 0) { + executeTeleport(player, destination); + return; + } + + player.sendMessage(plugin.getConfigManager().getMessage("teleport-warmup", "seconds", String.valueOf(delay))); + Location startLoc = player.getLocation().clone(); + + int taskId = Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> { + if (plugin.getConfigManager().cancelOnMove()) { + Location now = player.getLocation(); + if (Math.abs(now.getX()-startLoc.getX()) > 0.5 || Math.abs(now.getZ()-startLoc.getZ()) > 0.5) { + player.sendMessage(plugin.getConfigManager().getMessage("teleport-cancelled")); + warmupTasks.remove(player.getUniqueId()); + return; + } + } + executeTeleport(player, destination); + warmupTasks.remove(player.getUniqueId()); + }, delay * 20L); + + warmupTasks.put(player.getUniqueId(), taskId); + } + + private void executeTeleport(Player player, TeleportLocation dest) { + String localServer = plugin.getConfigManager().getServerName(); + + if (!dest.isLocalServer(localServer)) { + // BungeeCord-Teleport + if (plugin.getBungeeMessenger() != null) { + plugin.getBungeeMessenger().connectToServer(player, dest.getServer(), dest.getWorld(), + dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch()); + player.sendMessage(plugin.getConfigManager().getMessage("teleport-success")); + } + return; + } + + Location loc = dest.toBukkitLocation(); + if (loc == null || loc.getWorld() == null) { + player.sendMessage("§cZielwelt nicht gefunden!"); + return; + } + + // Save last location to database + plugin.getDatabaseManager().saveLastLocation(player.getUniqueId(), + new TeleportLocation(player.getLocation(), localServer)); + + player.teleport(loc); + cooldowns.put(player.getUniqueId(), System.currentTimeMillis()); + player.sendMessage(plugin.getConfigManager().getMessage("teleport-success")); + } + + public void cancelWarmup(UUID uuid) { + Integer taskId = warmupTasks.remove(uuid); + if (taskId != null) Bukkit.getScheduler().cancelTask(taskId); + } + + public TeleportLocation getBackLocation(UUID uuid) { + return pendingBackLocations.get(uuid); + } + + // TPA + public void sendTpaRequest(Player from, Player to) { + tpaRequests.put(from.getUniqueId(), to.getUniqueId()); + requestTimestamps.put(from.getUniqueId(), System.currentTimeMillis()); + + to.sendMessage(plugin.getConfigManager().getMessage("tpa-received", "player", from.getName())); + from.sendMessage(plugin.getConfigManager().getMessage("tpa-sent", "player", to.getName())); + + int timeout = plugin.getConfigManager().getRequestTimeout(); + Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, () -> { + if (tpaRequests.containsKey(from.getUniqueId())) { + tpaRequests.remove(from.getUniqueId()); + requestTimestamps.remove(from.getUniqueId()); + if (from.isOnline()) from.sendMessage(plugin.getConfigManager().getMessage("tpa-expired")); + } + }, timeout * 20L); + } + + public boolean acceptTpa(Player target) { + UUID requester = null; + for (Map.Entry entry : tpaRequests.entrySet()) { + if (entry.getValue().equals(target.getUniqueId())) { + requester = entry.getKey(); + break; + } + } + if (requester == null) return false; + + Player from = Bukkit.getPlayer(requester); + tpaRequests.remove(requester); + requestTimestamps.remove(requester); + + if (from != null && from.isOnline()) { + from.sendMessage(plugin.getConfigManager().getMessage("tpa-accepted", "player", target.getName())); + teleport(from, new TeleportLocation(target.getLocation(), plugin.getConfigManager().getServerName())); + } + return true; + } + + public boolean denyTpa(Player target) { + UUID requester = null; + for (Map.Entry entry : tpaRequests.entrySet()) { + if (entry.getValue().equals(target.getUniqueId())) { + requester = entry.getKey(); + break; + } + } + if (requester == null) return false; + + Player from = Bukkit.getPlayer(requester); + tpaRequests.remove(requester); + requestTimestamps.remove(requester); + + if (from != null && from.isOnline()) + from.sendMessage(plugin.getConfigManager().getMessage("tpa-denied", "player", target.getName())); + return true; + } +} diff --git a/src/main/java/de/teleportsuite/managers/WarpManager.java b/src/main/java/de/teleportsuite/managers/WarpManager.java new file mode 100644 index 0000000..543ec77 --- /dev/null +++ b/src/main/java/de/teleportsuite/managers/WarpManager.java @@ -0,0 +1,39 @@ +package de.teleportsuite.managers; + +import de.teleportsuite.TeleportSuite; +import de.teleportsuite.models.TeleportLocation; +import de.teleportsuite.models.Warp; +import org.bukkit.entity.Player; +import java.util.List; + +public class WarpManager { + private final TeleportSuite plugin; + public WarpManager(TeleportSuite plugin) { this.plugin = plugin; } + + public void setWarp(Player player, String name, String permission) { + TeleportLocation loc = new TeleportLocation(player.getLocation(), plugin.getConfigManager().getServerName()); + plugin.getDatabaseManager().saveWarp(name, loc, player.getUniqueId(), permission); + player.sendMessage(plugin.getConfigManager().getMessage("warp-set", "name", name)); + } + + public void teleportWarp(Player player, String name) { + Warp warp = plugin.getDatabaseManager().getWarp(name); + if (warp == null) { + player.sendMessage(plugin.getConfigManager().getMessage("warp-not-found", "name", name)); + return; + } + if (warp.getPermission() != null && !player.hasPermission(warp.getPermission())) { + player.sendMessage(plugin.getConfigManager().getMessage("no-permission")); + return; + } + plugin.getTeleportManager().teleport(player, warp.getLocation()); + } + + public boolean deleteWarp(String name) { + return plugin.getDatabaseManager().deleteWarp(name); + } + + public List getAllWarps() { + return plugin.getDatabaseManager().getAllWarps(); + } +} diff --git a/src/main/java/de/teleportsuite/models/Home.java b/src/main/java/de/teleportsuite/models/Home.java new file mode 100644 index 0000000..5cf8641 --- /dev/null +++ b/src/main/java/de/teleportsuite/models/Home.java @@ -0,0 +1,17 @@ +package de.teleportsuite.models; + +import java.util.UUID; + +public class Home { + private final UUID uuid; + private final String name; + private final TeleportLocation location; + + public Home(UUID uuid, String name, TeleportLocation location) { + this.uuid = uuid; this.name = name; this.location = location; + } + + public UUID getUuid() { return uuid; } + public String getName() { return name; } + public TeleportLocation getLocation() { return location; } +} diff --git a/src/main/java/de/teleportsuite/models/Portal.java b/src/main/java/de/teleportsuite/models/Portal.java new file mode 100644 index 0000000..a0e723d --- /dev/null +++ b/src/main/java/de/teleportsuite/models/Portal.java @@ -0,0 +1,33 @@ +package de.teleportsuite.models; + +import org.bukkit.Location; +import org.bukkit.World; + +public class Portal { + private final String name; + private final String world; + private final int x1, y1, z1, x2, y2, z2; + private final String targetServer; + private final TeleportLocation destination; + + public Portal(String name, String world, int x1, int y1, int z1, int x2, int y2, int z2, + String targetServer, TeleportLocation destination) { + this.name = name; this.world = world; + this.x1 = x1; this.y1 = y1; this.z1 = z1; + this.x2 = x2; this.y2 = y2; this.z2 = z2; + this.targetServer = targetServer; this.destination = destination; + } + + public boolean contains(Location loc) { + if (!loc.getWorld().getName().equals(world)) return false; + int bx = loc.getBlockX(), by = loc.getBlockY(), bz = loc.getBlockZ(); + return bx >= Math.min(x1,x2) && bx <= Math.max(x1,x2) && + by >= Math.min(y1,y2) && by <= Math.max(y1,y2) && + bz >= Math.min(z1,z2) && bz <= Math.max(z1,z2); + } + + public String getName() { return name; } + public String getWorld() { return world; } + public String getTargetServer() { return targetServer; } + public TeleportLocation getDestination() { return destination; } +} diff --git a/src/main/java/de/teleportsuite/models/TeleportLocation.java b/src/main/java/de/teleportsuite/models/TeleportLocation.java new file mode 100644 index 0000000..17740d7 --- /dev/null +++ b/src/main/java/de/teleportsuite/models/TeleportLocation.java @@ -0,0 +1,38 @@ +package de.teleportsuite.models; + +import org.bukkit.Bukkit; +import org.bukkit.Location; + +public class TeleportLocation { + private String world; + private double x, y, z; + private float yaw, pitch; + private String server; + + public TeleportLocation(String world, double x, double y, double z, float yaw, float pitch, String server) { + this.world = world; this.x = x; this.y = y; this.z = z; + this.yaw = yaw; this.pitch = pitch; this.server = server; + } + + public TeleportLocation(Location loc, String server) { + this.world = loc.getWorld().getName(); + this.x = loc.getX(); this.y = loc.getY(); this.z = loc.getZ(); + this.yaw = loc.getYaw(); this.pitch = loc.getPitch(); + this.server = server; + } + + public Location toBukkitLocation() { + return new Location(Bukkit.getWorld(world), x, y, z, yaw, pitch); + } + + public String getWorld() { return world; } + public double getX() { return x; } + public double getY() { return y; } + public double getZ() { return z; } + public float getYaw() { return yaw; } + public float getPitch() { return pitch; } + public String getServer() { return server; } + public boolean isLocalServer(String localServer) { + return server == null || server.equals("local") || server.equals(localServer); + } +} diff --git a/src/main/java/de/teleportsuite/models/Warp.java b/src/main/java/de/teleportsuite/models/Warp.java new file mode 100644 index 0000000..5597b84 --- /dev/null +++ b/src/main/java/de/teleportsuite/models/Warp.java @@ -0,0 +1,20 @@ +package de.teleportsuite.models; + +import java.util.UUID; + +public class Warp { + private final String name; + private final TeleportLocation location; + private final UUID creator; + private final String permission; + + public Warp(String name, TeleportLocation location, UUID creator, String permission) { + this.name = name; this.location = location; + this.creator = creator; this.permission = permission; + } + + public String getName() { return name; } + public TeleportLocation getLocation() { return location; } + public UUID getCreator() { return creator; } + public String getPermission() { return permission; } +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml new file mode 100644 index 0000000..b5fb908 --- /dev/null +++ b/src/main/resources/config.yml @@ -0,0 +1,77 @@ +# TeleportSuite Configuration +version: "1.0.0" + +# Datenbank-Einstellungen +database: + type: sqlite # sqlite oder mysql + mysql: + host: localhost + port: 3306 + database: teleportsuite + username: root + password: password + pool-size: 10 + sqlite: + file: teleportsuite.db + +# BungeeCord Einstellungen +bungee: + enabled: false + server-name: "survival" # Name dieses Servers im BungeeCord-Netz + +# Teleport Einstellungen +teleport: + delay: 3 # Sekunden Wartezeit vor Teleport (0 = sofort) + cooldown: 5 # Cooldown in Sekunden + warmup-cancel-on-move: true # Teleport abbrechnen wenn Spieler sich bewegt + request-timeout: 60 # Sekunden bis eine TP-Anfrage verfällt + +# Home Einstellungen +homes: + max-homes-default: 3 # Standard maximale Homes + max-homes-vip: 10 + max-homes-premium: 25 + +# Warp Einstellungen +warps: + allow-player-warps: false # Darf jeder Spieler Warps erstellen? + warp-permission-prefix: "teleportsuite.warp." # z.B. teleportsuite.warp.spawn + +# Portal Einstellungen +portals: + check-interval: 5 # Ticks zwischen Portal-Checks + particle-effect: true + +# Spawn Einstellungen +spawn: + first-join-teleport: true # Neuer Spieler → FirstSpawn + death-respawn-to-spawn: false # Tod → Spawn statt Bett + +# Nachrichten (unterstützt &-Farbcodes) +messages: + prefix: "&8[&6TP&8] &r" + teleport-success: "&aDu wurdest teleportiert!" + teleport-warmup: "&eTeleportiere in &6{seconds}&e Sekunden... Nicht bewegen!" + teleport-cancelled: "&cTeleport abgebrochen - du hast dich bewegt!" + teleport-cooldown: "&cBitte warte noch &6{seconds}&c Sekunden." + tpa-sent: "&aTeleportanfrage an &6{player}&a gesendet." + tpa-received: "&6{player} &emöchte zu dir teleportieren. &a/tpaccept &eoder &c/tpdeny" + tpa-accepted: "&a{player} hat deine Anfrage akzeptiert!" + tpa-denied: "&c{player} hat deine Anfrage abgelehnt." + tpa-expired: "&cDeine Teleportanfrage ist abgelaufen." + home-set: "&aHome &6{name}&a gesetzt!" + home-deleted: "&cHome &6{name}&c gelöscht." + home-not-found: "&cHome &6{name}&c nicht gefunden." + home-limit: "&cDu hast das Maximum von &6{max}&c Homes erreicht." + warp-set: "&aWarp &6{name}&a erstellt!" + warp-deleted: "&cWarp &6{name}&c gelöscht." + warp-not-found: "&cWarp &6{name}&c nicht gefunden." + back-no-location: "&cKein vorheriger Ort gespeichert." + death-no-location: "&cKein Todesort gespeichert." + no-permission: "&cDazu hast du keine Berechtigung." + player-not-found: "&cSpieler &6{player}&c nicht gefunden." + portal-created: "&aPortal &6{name}&a erstellt!" + portal-deleted: "&cPortal &6{name}&c gelöscht." + savepoint-set: "&aSavepoint &6{name}&a gesetzt!" + spawn-set: "&aSpawn gesetzt!" + firstspawn-set: "&aFirstSpawn gesetzt!" diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml new file mode 100644 index 0000000..2e6ca3e --- /dev/null +++ b/src/main/resources/plugin.yml @@ -0,0 +1,148 @@ +name: TeleportSuite +version: 1.0.0 +main: de.teleportsuite.TeleportSuite +api-version: 1.20 +description: BungeeCord-fähiges Teleport-Komplettpaket +author: M_Viper +softdepend: [] + +commands: + tp: + description: Teleportiere zu einem Spieler + usage: /tp + permission: teleportsuite.tp + tphere: + description: Teleportiere einen Spieler zu dir + usage: /tphere + permission: teleportsuite.tphere + tpa: + description: Sende eine Teleportanfrage + usage: /tpa + permission: teleportsuite.tpa + tpaccept: + description: Akzeptiere eine Teleportanfrage + usage: /tpaccept + permission: teleportsuite.tpaccept + tpdeny: + description: Lehne eine Teleportanfrage ab + usage: /tpdeny + permission: teleportsuite.tpdeny + back: + description: Teleportiere zur letzten Position + usage: /back + permission: teleportsuite.back + deathback: + description: Teleportiere zum letzten Todesort + usage: /deathback + permission: teleportsuite.deathback + sethome: + description: Setze ein Home + usage: /sethome [name] + permission: teleportsuite.sethome + home: + description: Teleportiere zu einem Home + usage: /home [name] + permission: teleportsuite.home + delhome: + description: Lösche ein Home + usage: /delhome + permission: teleportsuite.delhome + homes: + description: Liste alle Homes auf + usage: /homes + permission: teleportsuite.home + setwarp: + description: Setze einen Warp + usage: /setwarp + permission: teleportsuite.setwarp + warp: + description: Teleportiere zu einem Warp + usage: /warp + permission: teleportsuite.warp + delwarp: + description: Lösche einen Warp + usage: /delwarp + permission: teleportsuite.delwarp + warps: + description: Liste alle Warps auf + usage: /warps + permission: teleportsuite.warp + setportal: + description: Erstelle ein Portal (2 Positionen markieren) + usage: /setportal + permission: teleportsuite.setportal + delportal: + description: Lösche ein Portal + usage: /delportal + permission: teleportsuite.delportal + portals: + description: Liste alle Portale auf + usage: /portals + permission: teleportsuite.portals + setsavepoint: + description: Setze einen Savepoint + usage: /setsavepoint [name] + permission: teleportsuite.savepoint + savepoint: + description: Teleportiere zu einem Savepoint + usage: /savepoint [name] + permission: teleportsuite.savepoint + setspawn: + description: Setze den Spawn + usage: /setspawn + permission: teleportsuite.setspawn + spawn: + description: Teleportiere zum Spawn + usage: /spawn + permission: teleportsuite.spawn + setfirstspawn: + description: Setze den FirstSpawn + usage: /setfirstspawn + permission: teleportsuite.setfirstspawn + tppos: + description: Teleportiere zu Koordinaten + usage: /tppos [world] + permission: teleportsuite.tppos + tpall: + description: Teleportiere alle Spieler zu dir + usage: /tpall + permission: teleportsuite.tpall + tpworld: + description: Teleportiere in eine Welt + usage: /tpworld + permission: teleportsuite.tpworld + entitytransport: + description: Transportiere ein Entity + usage: /entitytransport + permission: teleportsuite.entitytransport + +permissions: + teleportsuite.*: + description: Alle TeleportSuite-Rechte + children: + teleportsuite.tp: true + teleportsuite.tphere: true + teleportsuite.tpa: true + teleportsuite.tpaccept: true + teleportsuite.tpdeny: true + teleportsuite.back: true + teleportsuite.deathback: true + teleportsuite.sethome: true + teleportsuite.home: true + teleportsuite.setwarp: true + teleportsuite.warp: true + teleportsuite.setportal: true + teleportsuite.delportal: true + teleportsuite.portals: true + teleportsuite.savepoint: true + teleportsuite.setspawn: true + teleportsuite.spawn: true + teleportsuite.setfirstspawn: true + teleportsuite.tppos: true + teleportsuite.tpall: true + teleportsuite.tpworld: true + teleportsuite.entitytransport: true + teleportsuite.admin: true + teleportsuite.home.unlimited: + description: Unbegrenzte Homes + default: op