From d9f73f6e35bc2b03a9174621015c3070841f282b Mon Sep 17 00:00:00 2001 From: M_Viper Date: Tue, 5 Aug 2025 21:20:14 +0000 Subject: [PATCH] Dateien nach "src/main/java/dev/viper/telegramchat" hochladen --- .../telegramchat/AccountLinkManager.java | 161 ++++++++ .../dev/viper/telegramchat/ChatListener.java | 30 ++ .../viper/telegramchat/ChatModeManager.java | 40 ++ .../dev/viper/telegramchat/LinkCommand.java | 57 +++ .../telegramchat/MinecraftChatCommand.java | 25 ++ .../telegramchat/PlayerEventListener.java | 40 ++ .../dev/viper/telegramchat/TBCommand.java | 83 ++++ .../telegramchat/TelegramBotHandler.java | 355 ++++++++++++++++++ .../telegramchat/TelegramChatBridge.java | 123 ++++++ .../viper/telegramchat/TelegramCommand.java | 65 ++++ 10 files changed, 979 insertions(+) create mode 100644 src/main/java/dev/viper/telegramchat/AccountLinkManager.java create mode 100644 src/main/java/dev/viper/telegramchat/ChatListener.java create mode 100644 src/main/java/dev/viper/telegramchat/ChatModeManager.java create mode 100644 src/main/java/dev/viper/telegramchat/LinkCommand.java create mode 100644 src/main/java/dev/viper/telegramchat/MinecraftChatCommand.java create mode 100644 src/main/java/dev/viper/telegramchat/PlayerEventListener.java create mode 100644 src/main/java/dev/viper/telegramchat/TBCommand.java create mode 100644 src/main/java/dev/viper/telegramchat/TelegramBotHandler.java create mode 100644 src/main/java/dev/viper/telegramchat/TelegramChatBridge.java create mode 100644 src/main/java/dev/viper/telegramchat/TelegramCommand.java diff --git a/src/main/java/dev/viper/telegramchat/AccountLinkManager.java b/src/main/java/dev/viper/telegramchat/AccountLinkManager.java new file mode 100644 index 0000000..8e1060d --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/AccountLinkManager.java @@ -0,0 +1,161 @@ +package dev.viper.telegramchat; + +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +public class AccountLinkManager { + + private final TelegramChatBridge plugin; + private final Map linkedAccounts; // Minecraft UUID -> Telegram UserID + private final Map verificationCodes; // Minecraft UUID -> VerificationEntry + private final Map cooldowns; // Für Verifizierungscooldown + private final File dataFile; + private final YamlConfiguration dataConfig; + + private static class VerificationEntry { + private final String code; + private final long expiryTime; + + public VerificationEntry(String code, long expiryTime) { + this.code = code; + this.expiryTime = expiryTime; + } + + public String getCode() { + return code; + } + + public boolean isExpired() { + return System.currentTimeMillis() > expiryTime; + } + } + + public AccountLinkManager(TelegramChatBridge plugin) { + this.plugin = plugin; + this.linkedAccounts = new HashMap<>(); + this.verificationCodes = new HashMap<>(); + this.cooldowns = new HashMap<>(); + this.dataFile = new File(plugin.getDataFolder(), "data.yml"); + this.dataConfig = YamlConfiguration.loadConfiguration(dataFile); + loadLinkedAccounts(); + } + + private void loadLinkedAccounts() { + if (!dataFile.exists()) { + try { + dataFile.createNewFile(); + } catch (IOException e) { + plugin.getLogger().severe("Fehler beim Erstellen von data.yml: " + e.getMessage()); + } + } + for (String key : dataConfig.getKeys(false)) { + linkedAccounts.put(UUID.fromString(key), dataConfig.getString(key)); + } + plugin.getLogger().info("Geladene Verknüpfungen: " + linkedAccounts.size()); + } + + private void saveLinkedAccounts() { + for (Map.Entry entry : linkedAccounts.entrySet()) { + dataConfig.set(entry.getKey().toString(), entry.getValue()); + } + try { + dataConfig.save(dataFile); + } catch (IOException e) { + plugin.getLogger().severe("Fehler beim Speichern von data.yml: " + e.getMessage()); + } + } + + public boolean isLinked(UUID uuid) { + return linkedAccounts.containsKey(uuid); + } + + public void linkAccount(UUID uuid, String telegramUserId) { + linkedAccounts.put(uuid, telegramUserId); + saveLinkedAccounts(); + plugin.getLogger().info("Verknüpfung gespeichert: UUID=" + uuid + ", TelegramID=" + telegramUserId); + } + + public String getLinkedTelegramId(UUID uuid) { + return linkedAccounts.get(uuid); + } + + public UUID findUUIDByTelegramId(String telegramId) { + for (Map.Entry entry : linkedAccounts.entrySet()) { + if (entry.getValue().equals(telegramId)) { + return entry.getKey(); + } + } + return null; + } + + public boolean isOnCooldown(UUID uuid) { + if (!cooldowns.containsKey(uuid)) return false; + long lastTime = cooldowns.get(uuid); + return System.currentTimeMillis() - lastTime < 60000; // 60 Sek. Cooldown + } + + public void setCooldown(UUID uuid) { + cooldowns.put(uuid, System.currentTimeMillis()); + } + + public String generateVerificationCode(UUID uuid) { + String code = Integer.toString((int)(Math.random() * 900000) + 100000); // 6-stellige Zahl + long expiryTime = System.currentTimeMillis() + 5 * 60 * 1000; // 5 Minuten Gültigkeit + verificationCodes.put(uuid, new VerificationEntry(code, expiryTime)); + plugin.getLogger().info("Verifizierungscode generiert: " + code + " für Spieler: " + uuid); + return code; + } + + public String getVerificationCode(UUID uuid) { + VerificationEntry entry = verificationCodes.get(uuid); + if (entry == null || entry.isExpired()) { + verificationCodes.remove(uuid); + return null; + } + return entry.getCode(); + } + + public void removeVerificationCode(UUID uuid) { + verificationCodes.remove(uuid); + } + + public boolean verifyCode(UUID uuid, String code) { + VerificationEntry entry = verificationCodes.get(uuid); + if (entry == null) { + plugin.getLogger().info("Kein Verifizierungscode für UUID: " + uuid); + return false; + } + if (entry.isExpired()) { + verificationCodes.remove(uuid); + plugin.getLogger().info("Verifizierungscode abgelaufen für UUID: " + uuid); + return false; + } + if (!entry.getCode().equals(code)) { + plugin.getLogger().info("Ungültiger Verifizierungscode: " + code + " für UUID: " + uuid); + return false; + } + verificationCodes.remove(uuid); + return true; + } + + public UUID findUUIDByCode(String code) { + for (Map.Entry entry : verificationCodes.entrySet()) { + VerificationEntry verificationEntry = entry.getValue(); + if (verificationEntry.getCode().equals(code)) { + if (verificationEntry.isExpired()) { + verificationCodes.remove(entry.getKey()); + plugin.getLogger().info("Verifizierungscode abgelaufen: " + code + " für UUID: " + entry.getKey()); + return null; + } + return entry.getKey(); + } + } + plugin.getLogger().info("Kein UUID für Verifizierungscode gefunden: " + code); + return null; + } +} \ No newline at end of file diff --git a/src/main/java/dev/viper/telegramchat/ChatListener.java b/src/main/java/dev/viper/telegramchat/ChatListener.java new file mode 100644 index 0000000..325ad08 --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/ChatListener.java @@ -0,0 +1,30 @@ +package dev.viper.telegramchat; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerChatEvent; + +public class ChatListener implements Listener { + private final TelegramChatBridge plugin; + + public ChatListener(TelegramChatBridge plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onChat(AsyncPlayerChatEvent event) { + var player = event.getPlayer(); + var mode = plugin.getChatModeManager().getMode(player.getUniqueId()); + + String username = player.getName(); + String message = event.getMessage(); + + if (mode == ChatModeManager.ChatMode.TELEGRAM) { + // Nachricht an Telegram senden und im Minecraft-Chat unterdrücken + plugin.getBotHandler().sendMessageToTelegram(username, message); + event.setCancelled(true); + } + + // Im Minecraft-Modus passiert nichts weiter – Nachricht wird normal angezeigt + } +} diff --git a/src/main/java/dev/viper/telegramchat/ChatModeManager.java b/src/main/java/dev/viper/telegramchat/ChatModeManager.java new file mode 100644 index 0000000..2922f3f --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/ChatModeManager.java @@ -0,0 +1,40 @@ +package dev.viper.telegramchat; + +import java.util.HashMap; +import java.util.UUID; + +public class ChatModeManager { + + public enum ChatMode { + TELEGRAM, + MINECRAFT + } + + private final HashMap playerModes = new HashMap<>(); + + /** + * Setzt den Chat-Modus für einen Spieler. + * @param playerId Die UUID des Spielers. + * @param mode Der zu setzende Chat-Modus. + */ + public void setMode(UUID playerId, ChatMode mode) { + playerModes.put(playerId, mode); + } + + /** + * Gibt den aktuellen Chat-Modus eines Spielers zurück. + * Standardmäßig ist es MINECRAFT, falls kein Modus gesetzt wurde. + * @param playerId Die UUID des Spielers. + * @return Der Chat-Modus des Spielers. + */ + public ChatMode getMode(UUID playerId) { + return playerModes.getOrDefault(playerId, ChatMode.MINECRAFT); + } + + /** + * Entfernt alle gespeicherten Chat-Modi (z.B. beim Reload). + */ + public void clearAllModes() { + playerModes.clear(); + } +} diff --git a/src/main/java/dev/viper/telegramchat/LinkCommand.java b/src/main/java/dev/viper/telegramchat/LinkCommand.java new file mode 100644 index 0000000..8acb7e0 --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/LinkCommand.java @@ -0,0 +1,57 @@ +package dev.viper.telegramchat.commands; + +import dev.viper.telegramchat.AccountLinkManager; +import dev.viper.telegramchat.TelegramChatBridge; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import java.util.UUID; + +public class LinkCommand implements CommandExecutor { + + private final TelegramChatBridge plugin; + private final AccountLinkManager linkManager; + + public LinkCommand(TelegramChatBridge plugin) { + this.plugin = plugin; + this.linkManager = plugin.getAccountLinkManager(); + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (!(sender instanceof Player)) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + plugin.getConfig().getString("messages.link.only-players", "Diesen Befehl kannst du nur als Spieler verwenden."))); + return true; + } + + Player player = (Player) sender; + UUID uuid = player.getUniqueId(); + + if (linkManager.isLinked(uuid)) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', + plugin.getConfig().getString("messages.link.already-linked", "Dein Account ist bereits mit Telegram verknüpft."))); + return true; + } + + if (linkManager.isOnCooldown(uuid)) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', + plugin.getConfig().getString("messages.link.cooldown", "Bitte warte einen Moment, bevor du einen neuen Code anforderst."))); + return true; + } + + String code = linkManager.generateVerificationCode(uuid); + linkManager.setCooldown(uuid); + + String codeMessage = plugin.getConfig().getString("messages.link.code", "Dein Verifizierungscode lautet: {code}").replace("{code}", code); + String instructionsMessage = plugin.getConfig().getString("messages.link.instructions", "Sende in Telegram: /verify {code}").replace("{code}", code); + + player.sendMessage(ChatColor.translateAlternateColorCodes('&', codeMessage)); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', instructionsMessage)); + + return true; + } +} \ No newline at end of file diff --git a/src/main/java/dev/viper/telegramchat/MinecraftChatCommand.java b/src/main/java/dev/viper/telegramchat/MinecraftChatCommand.java new file mode 100644 index 0000000..8168f28 --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/MinecraftChatCommand.java @@ -0,0 +1,25 @@ +package dev.viper.telegramchat; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class MinecraftChatCommand implements CommandExecutor { + private final ChatModeManager chatModeManager; + + public MinecraftChatCommand(ChatModeManager manager) { + this.chatModeManager = manager; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player player)) return false; + + chatModeManager.setMode(player.getUniqueId(), ChatModeManager.ChatMode.MINECRAFT); + String msg = TelegramChatBridge.getInstance().getConfig().getString("messages.mode-set-minecraft"); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', msg)); + return true; + } +} diff --git a/src/main/java/dev/viper/telegramchat/PlayerEventListener.java b/src/main/java/dev/viper/telegramchat/PlayerEventListener.java new file mode 100644 index 0000000..885d75e --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/PlayerEventListener.java @@ -0,0 +1,40 @@ +package dev.viper.telegramchat; + +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.PlayerJoinEvent; +import org.bukkit.event.player.PlayerQuitEvent; +import org.bukkit.event.entity.PlayerDeathEvent; + +public class PlayerEventListener implements Listener { + + private final TelegramChatBridge plugin; + + public PlayerEventListener(TelegramChatBridge plugin) { + this.plugin = plugin; + } + + @EventHandler + public void onPlayerJoin(PlayerJoinEvent event) { + if (!plugin.getConfig().getBoolean("messages.joinAndLeaveEvent", true)) return; + + String message = event.getPlayer().getName() + " ist dem Server beigetreten."; + plugin.getBotHandler().sendMessageToTelegram("Server", message); + } + + @EventHandler + public void onPlayerQuit(PlayerQuitEvent event) { + if (!plugin.getConfig().getBoolean("messages.joinAndLeaveEvent", true)) return; + + String message = event.getPlayer().getName() + " hat den Server verlassen."; + plugin.getBotHandler().sendMessageToTelegram("Server", message); + } + + @EventHandler + public void onPlayerDeath(PlayerDeathEvent event) { + if (!plugin.getConfig().getBoolean("messages.deathEvent", true)) return; + + String message = event.getDeathMessage(); + plugin.getBotHandler().sendMessageToTelegram("Server", message); + } +} diff --git a/src/main/java/dev/viper/telegramchat/TBCommand.java b/src/main/java/dev/viper/telegramchat/TBCommand.java new file mode 100644 index 0000000..645a5bb --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/TBCommand.java @@ -0,0 +1,83 @@ +package dev.viper.telegramchat.commands; + +import dev.viper.telegramchat.TelegramChatBridge; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; + +public class TBCommand implements CommandExecutor { + + private final TelegramChatBridge plugin; + + public TBCommand(TelegramChatBridge plugin) { + this.plugin = plugin; + } + + @Override + public boolean onCommand(CommandSender sender, Command command, String label, String[] args) { + if (args.length == 0) { + sendHelpMessage(sender); + return true; + } + + String subCommand = args[0].toLowerCase(); + + switch (subCommand) { + case "reload": + if (!sender.hasPermission("telegramchat.admin")) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + plugin.getConfig().getString("messages.no-permission", "&cDu hast keine Berechtigung für diesen Befehl."))); + return true; + } + + plugin.reloadConfig(); + plugin.getBotHandler().stop(); + plugin.getBotHandler().start(); + + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + plugin.getConfig().getString("messages.reload-success", "&aKonfiguration und Bot wurden erfolgreich neu geladen."))); + plugin.getLogger().info("Konfiguration und Telegram-Bot neu geladen von " + sender.getName()); + return true; + + case "info": + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&6TelegramChatBridge\n" + + "&7Version: &f1.0\n" + + "&7Ersteller: &fM_Viper")); + return true; + + case "help": + sendHelpMessage(sender); + return true; + + default: + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', + plugin.getConfig().getString("messages.unknown-command", "&cUnbekannter Befehl: {command}") + .replace("{command}", subCommand))); + return true; + } + } + + private void sendHelpMessage(CommandSender sender) { + String helpMessage = ChatColor.translateAlternateColorCodes('&', + plugin.getConfig().getString("messages.help", + "&6TelegramChatBridge Hilfe\n" + + "&7Minecraft-Befehle:\n" + + "&f/tg &7- Wechselt in den Telegram-Chatmodus\n" + + "&f/chat &7- Wechselt in den Minecraft-Chatmodus\n" + + "&f/link &7- Verknüpft deinen Minecraft-Account mit Telegram\n" + + "&f/tb reload &7- Lädt die Konfiguration und den Bot neu (nur Admins)\n" + + "&f/tb info &7- Zeigt Plugin-Informationen an\n" + + "&f/tb help &7- Zeigt diese Hilfe an\n" + + "&7Telegram-Befehle:\n" + + "&f/verify &7- Verknüpft deinen Telegram-Account mit Minecraft\n" + + "&f/online &7- Zeigt die Liste der online Spieler\n" + + "&f/time &7- Zeigt die Serverzeit an\n" + + "&f/say &7- Sendet eine Nachricht an den Minecraft-Chat\n" + + "&f/r &7- Sendet eine private Nachricht\n" + + "&f/mem &7- Zeigt den Server-Speicher (nur Admins)\n" + + "&f/status &7- Zeigt die Serverlaufzeit an")); + sender.sendMessage(helpMessage); + } +} diff --git a/src/main/java/dev/viper/telegramchat/TelegramBotHandler.java b/src/main/java/dev/viper/telegramchat/TelegramBotHandler.java new file mode 100644 index 0000000..6cfdbfa --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/TelegramBotHandler.java @@ -0,0 +1,355 @@ +package dev.viper.telegramchat; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.OfflinePlayer; +import org.bukkit.entity.Player; +import org.telegram.telegrambots.bots.TelegramLongPollingBot; +import org.telegram.telegrambots.meta.TelegramBotsApi; +import org.telegram.telegrambots.meta.api.methods.send.SendMessage; +import org.telegram.telegrambots.meta.api.objects.Message; +import org.telegram.telegrambots.meta.api.objects.Update; +import org.telegram.telegrambots.updatesreceivers.DefaultBotSession; + +import java.lang.management.ManagementFactory; +import java.text.SimpleDateFormat; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +public class TelegramBotHandler extends TelegramLongPollingBot { + private final TelegramChatBridge plugin; + private final String botToken; + private final List chatIds = new ArrayList<>(); + private final Map cooldowns = new HashMap<>(); + private final Map mutedPlayers = new ConcurrentHashMap<>(); + private final Map mutedTelegramUsers = new ConcurrentHashMap<>(); + private boolean botRegistered = false; + private boolean running = false; + + public TelegramBotHandler(TelegramChatBridge plugin) { + this.plugin = plugin; + this.botToken = plugin.getConfig().getString("telegram.bot-token"); + + List chats = plugin.getConfig().getList("telegram.chats"); + if (chats != null) { + for (Object obj : chats) { + if (obj instanceof Map map) { + Object idObj = map.get("id"); + if (idObj != null) { + String idStr = idObj.toString().trim(); + if (!idStr.isEmpty() && !idStr.startsWith("#")) { + chatIds.add(idStr); + } + } + } + } + } + + if (chatIds.isEmpty()) { + String singleChatId = plugin.getConfig().getString("telegram.chat-id"); + if (singleChatId != null && !singleChatId.isEmpty()) { + chatIds.add(singleChatId.trim()); + } + } + } + + public void start() { + if (botRegistered) { + plugin.getLogger().warning("Telegram-Bot wurde bereits gestartet!"); + return; + } + try { + TelegramBotsApi api = new TelegramBotsApi(DefaultBotSession.class); + api.registerBot(this); + botRegistered = true; + running = true; + plugin.getLogger().info("Telegram-Bot erfolgreich gestartet."); + plugin.getLogger().info("Überwachte Chat-IDs: " + String.join(", ", chatIds)); + } catch (Exception e) { + plugin.getLogger().severe("Fehler beim Starten des Telegram-Bots: " + e.getMessage()); + } + } + + public void stop() { + running = false; + plugin.getLogger().info("Telegram-Bot wurde gestoppt."); + } + + @Override + public String getBotUsername() { + return "TelegramChatBridgeBot"; + } + + @Override + public String getBotToken() { + return botToken; + } + + @Override + public void onUpdateReceived(Update update) { + if (!running || !update.hasMessage()) return; + + Message msg = update.getMessage(); + if (!msg.hasText()) return; + if (!chatIds.contains(msg.getChatId().toString())) return; + + String telegramId = String.valueOf(msg.getFrom().getId()); + String text = msg.getText().trim(); + + if (text.startsWith("/")) { + handleTelegramCommand(telegramId, text, msg); + return; + } + + // Check Telegram mute + if (mutedTelegramUsers.containsKey(telegramId)) { + if (System.currentTimeMillis() > mutedTelegramUsers.get(telegramId)) { + mutedTelegramUsers.remove(telegramId); + } else { + return; // muted + } + } + + UUID uuid = plugin.getAccountLinkManager().findUUIDByTelegramId(telegramId); + String from = uuid != null && Bukkit.getOfflinePlayer(uuid).getName() != null + ? Bukkit.getOfflinePlayer(uuid).getName() + : msg.getFrom().getFirstName(); + + String formatted = plugin.getTelegramToMinecraftFormat() + .replace("{username}", from) + .replace("{message}", text); + + String colored = ChatColor.translateAlternateColorCodes('&', formatted); + + if (uuid == null || !mutedPlayers.containsKey(uuid) || System.currentTimeMillis() > mutedPlayers.get(uuid)) { + Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(colored)); + } + } + + private void handleTelegramCommand(String telegramId, String text, Message msg) { + String[] split = text.split(" ", 2); + String cmd = split[0].toLowerCase(); + String args = split.length > 1 ? split[1] : ""; + + UUID uuid = plugin.getAccountLinkManager().findUUIDByTelegramId(telegramId); + String from = uuid != null && Bukkit.getOfflinePlayer(uuid).getName() != null + ? Bukkit.getOfflinePlayer(uuid).getName() + : msg.getFrom().getFirstName(); + + switch (cmd) { + case "/verify": + if (args.isEmpty()) { + sendTelegramMessage(getConfigMessage("messages.telegram.verify.usage")); + return; + } + UUID mcUUID = plugin.getAccountLinkManager().findUUIDByCode(args); + if (mcUUID != null && plugin.getAccountLinkManager().verifyCode(mcUUID, args)) { + plugin.getAccountLinkManager().linkAccount(mcUUID, telegramId); + Player player = Bukkit.getPlayer(mcUUID); + if (player != null) { + player.sendMessage(ChatColor.translateAlternateColorCodes('&', + getConfigMessage("messages.telegram.verify.player-success"))); + } + sendTelegramMessage(getConfigMessage("messages.telegram.verify.success")); + plugin.getAccountLinkManager().removeVerificationCode(mcUUID); + } else { + sendTelegramMessage(getConfigMessage("messages.telegram.verify.invalid-code")); + } + break; + + case "/online": + case "/time": + case "/say": + case "/r": + case "/mem": + case "/status": + if (uuid == null) { + sendTelegramMessage(getConfigMessage("messages.telegram.command.no-verification")); + return; + } + handleOtherCommands(cmd, args, from, msg, uuid); + break; + + case "/mute": + if (!isAdmin(msg)) { + sendTelegramMessage(getConfigMessage("messages.telegram.command.no-permission")); + return; + } + if (args.isEmpty()) { + sendTelegramMessage("Verwendung: /mute "); + return; + } + String[] muteArgs = args.split(" "); + if (muteArgs.length < 2) { + sendTelegramMessage("Verwendung: /mute "); + return; + } + try { + long seconds = Long.parseLong(muteArgs[1]); + long until = System.currentTimeMillis() + seconds * 1000; + + // Try Minecraft name + Player p = Bukkit.getPlayerExact(muteArgs[0]); + if (p != null) { + mutedPlayers.put(p.getUniqueId(), until); + sendTelegramMessage("Spieler " + p.getName() + " für " + seconds + " Sekunden gemutet."); + return; + } + + // Try Telegram ID + mutedTelegramUsers.put(muteArgs[0], until); + sendTelegramMessage("Telegram-Nutzer " + muteArgs[0] + " für " + seconds + " Sekunden gemutet."); + } catch (NumberFormatException e) { + sendTelegramMessage("Ungültige Zeitangabe."); + } + break; + + case "/unmute": + if (!isAdmin(msg)) { + sendTelegramMessage(getConfigMessage("messages.telegram.command.no-permission")); + return; + } + if (args.isEmpty()) { + sendTelegramMessage("Verwendung: /unmute "); + return; + } + + Player player = Bukkit.getPlayerExact(args); + if (player != null && mutedPlayers.remove(player.getUniqueId()) != null) { + sendTelegramMessage("Spieler " + player.getName() + " entmutet."); + } else if (mutedTelegramUsers.remove(args) != null) { + sendTelegramMessage("Telegram-Nutzer " + args + " entmutet."); + } else { + sendTelegramMessage("Kein stummgeschalteter Nutzer gefunden."); + } + break; + + default: + sendTelegramMessage(getConfigMessage("messages.telegram.command.unknown") + .replace("{command}", cmd)); + break; + } + } + + private void handleOtherCommands(String cmd, String args, String from, Message msg, UUID uuid) { + switch (cmd) { + case "/online": + List players = Bukkit.getOnlinePlayers().stream().map(Player::getName).collect(Collectors.toList()); + String msgText = players.isEmpty() + ? getConfigMessage("messages.telegram.command.online-empty") + : getConfigMessage("messages.telegram.command.online-list").replace("{list}", String.join(", ", players)); + sendTelegramMessage(msgText); + break; + + case "/time": + String time = new SimpleDateFormat("HH:mm:ss dd.MM.yyyy").format(new Date()); + sendTelegramMessage(getConfigMessage("messages.telegram.command.server-time").replace("{time}", time)); + break; + + case "/say": + if (!args.isEmpty() && !isMuted(uuid)) { + String broadcast = ChatColor.translateAlternateColorCodes('&', + "&7[&3TG &7] &f" + from + ": &r" + args); + Bukkit.getOnlinePlayers().forEach(p -> p.sendMessage(broadcast)); + } + break; + + case "/r": + String[] parts = args.split(" ", 2); + if (parts.length == 2) { + String target = parts[0].replace("@", ""); + Player targetPlayer = Bukkit.getPlayerExact(target); + if (targetPlayer != null && targetPlayer.isOnline()) { + targetPlayer.sendMessage(ChatColor.translateAlternateColorCodes('&', + "&7[&3TG &7-> &2PM&7] &f" + from + ": &r" + parts[1])); + sendTelegramMessage(getConfigMessage("messages.telegram.command.reply.success").replace("{player}", target)); + } else { + sendTelegramMessage(getConfigMessage("messages.telegram.command.reply.not-online").replace("{player}", target)); + } + } else { + sendTelegramMessage(getConfigMessage("messages.telegram.command.reply.usage")); + } + break; + + case "/mem": + if (!isAdmin(msg)) { + sendTelegramMessage(getConfigMessage("messages.telegram.command.no-permission")); + return; + } + long free = Runtime.getRuntime().freeMemory() / 1024 / 1024; + long total = Runtime.getRuntime().totalMemory() / 1024 / 1024; + String memMessage = getConfigMessage("messages.telegram.command.memory") + .replace("{free}", Long.toString(free)) + .replace("{total}", Long.toString(total)); + sendTelegramMessage(memMessage); + break; + + case "/status": + long uptime = ManagementFactory.getRuntimeMXBean().getUptime(); + long seconds = uptime / 1000 % 60; + long minutes = uptime / (1000 * 60) % 60; + long hours = uptime / (1000 * 60 * 60); + String statusMessage = getConfigMessage("messages.telegram.command.status") + .replace("{hours}", String.format("%02d", hours)) + .replace("{minutes}", String.format("%02d", minutes)) + .replace("{seconds}", String.format("%02d", seconds)); + sendTelegramMessage(statusMessage); + break; + } + } + + private boolean isMuted(UUID uuid) { + if (uuid == null) return true; + Long end = mutedPlayers.get(uuid); + if (end == null) return false; + if (System.currentTimeMillis() > end) { + mutedPlayers.remove(uuid); + return false; + } + return true; + } + + private boolean isAdmin(Message msg) { + List adminIds = plugin.getConfig().getLongList("telegram.admin-ids"); + if (adminIds.contains(msg.getFrom().getId())) return true; + + String telegramId = String.valueOf(msg.getFrom().getId()); + UUID uuid = plugin.getAccountLinkManager().findUUIDByTelegramId(telegramId); + if (uuid != null) { + OfflinePlayer player = Bukkit.getOfflinePlayer(uuid); + return player.isOp(); + } + return false; + } + + public void sendMessageToTelegram(String username, String message) { + String formatted = plugin.getMinecraftToTelegramFormat() + .replace("{username}", username) + .replace("{message}", message); + String telegramMessage = formatted.replaceAll("&[0-9a-fk-or]", ""); + try { + for (String id : chatIds) { + execute(new SendMessage(id, telegramMessage)); + } + } catch (Exception e) { + plugin.getLogger().warning("Fehler beim Senden an Telegram: " + e.getMessage()); + } + } + + private void sendTelegramMessage(String text) { + String cleanText = text.replaceAll("&[0-9a-fk-or]", ""); + try { + for (String id : chatIds) { + execute(new SendMessage(id, cleanText)); + } + } catch (Exception e) { + plugin.getLogger().warning("Fehler beim Telegram-Senden: " + e.getMessage()); + } + } + + private String getConfigMessage(String path) { + String msg = plugin.getConfig().getString(path); + return msg != null ? msg : "Fehlende Nachricht: " + path; + } +} diff --git a/src/main/java/dev/viper/telegramchat/TelegramChatBridge.java b/src/main/java/dev/viper/telegramchat/TelegramChatBridge.java new file mode 100644 index 0000000..81ae963 --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/TelegramChatBridge.java @@ -0,0 +1,123 @@ +package dev.viper.telegramchat; + +import dev.viper.telegramchat.commands.LinkCommand; +import dev.viper.telegramchat.commands.TBCommand; +import org.bukkit.plugin.java.JavaPlugin; + +public class TelegramChatBridge extends JavaPlugin { + + private static TelegramChatBridge instance; + private TelegramBotHandler botHandler; + private ChatModeManager chatModeManager; + private AccountLinkManager accountLinkManager; + + @Override + public void onEnable() { + instance = this; + saveDefaultConfig(); + + chatModeManager = new ChatModeManager(); + accountLinkManager = new AccountLinkManager(this); + + botHandler = new TelegramBotHandler(this); + try { + botHandler.start(); + } catch (Exception e) { + getLogger().severe("Fehler beim Starten des Telegram Bots: " + e.getMessage()); + e.printStackTrace(); + } + + getServer().getPluginManager().registerEvents(new ChatListener(this), this); + getServer().getPluginManager().registerEvents(new PlayerEventListener(this), this); + + getCommand("tg").setExecutor(new TelegramCommand(this, chatModeManager)); + getCommand("chat").setExecutor(new MinecraftChatCommand(chatModeManager)); + getCommand("link").setExecutor(new LinkCommand(this)); + getCommand("tb").setExecutor(new TBCommand(this)); + + getLogger().info("TelegramChatBridge aktiviert!"); + } + + @Override + public void onDisable() { + if (botHandler != null) { + try { + botHandler.stop(); + } catch (Exception e) { + getLogger().warning("Fehler beim Stoppen des Telegram Bots: " + e.getMessage()); + } + } + } + + public static TelegramChatBridge getInstance() { + return instance; + } + + public TelegramBotHandler getBotHandler() { + return botHandler; + } + + public ChatModeManager getChatModeManager() { + return chatModeManager; + } + + public AccountLinkManager getAccountLinkManager() { + return accountLinkManager; + } + + public String getBotToken() { + return getConfig().getString("telegram.bot-token"); + } + + public String getChatId() { + return getConfig().getString("telegram.chat-id"); + } + + public boolean isSendToTelegramEnabled() { + return getConfig().getBoolean("telegram.send-to-telegram", true); + } + + public boolean isSendToChatEnabled() { + return getConfig().getBoolean("telegram.send-to-chat", true); + } + + public boolean isJoinAndLeaveEnabled() { + return getConfig().getBoolean("telegram.join-and-leave-event", true); + } + + public boolean isDeathEventEnabled() { + return getConfig().getBoolean("telegram.death-event", true); + } + + public boolean isAdvancementEventEnabled() { + return getConfig().getBoolean("telegram.advancement-event", true); + } + + public boolean isSleepEventEnabled() { + return getConfig().getBoolean("telegram.sleep-event", false); + } + + public boolean isServerStartStopEnabled() { + return getConfig().getBoolean("telegram.server-start-stop", false); + } + + public String getTelegramToMinecraftFormat() { + return getConfig().getString("messages.telegram-to-minecraft", "&7[&3TG &r-> &2MC&7] &f{username}: &r{message}"); + } + + public String getMinecraftToTelegramFormat() { + return getConfig().getString("messages.minecraft-to-telegram", "[MC -> TG] {username}: {message}"); + } + + public String getTelegramEchoFormat() { + return getConfig().getString("messages.telegram-echo", "&7[&2MC &r-> &3TG&7] &f{username}: &r{message}"); + } + + public String getModeSetTelegramMessage() { + return getConfig().getString("messages.mode-set-telegram", "&aDu bist jetzt im Telegram-Chatmodus."); + } + + public String getModeSetMinecraftMessage() { + return getConfig().getString("messages.mode-set-minecraft", "&aDu bist jetzt im Minecraft-Chatmodus."); + } +} \ No newline at end of file diff --git a/src/main/java/dev/viper/telegramchat/TelegramCommand.java b/src/main/java/dev/viper/telegramchat/TelegramCommand.java new file mode 100644 index 0000000..c1ff5a8 --- /dev/null +++ b/src/main/java/dev/viper/telegramchat/TelegramCommand.java @@ -0,0 +1,65 @@ +package dev.viper.telegramchat; + +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandExecutor; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +public class TelegramCommand implements CommandExecutor { + private final TelegramChatBridge plugin; + private final ChatModeManager chatModeManager; + + public TelegramCommand(TelegramChatBridge plugin, ChatModeManager manager) { + this.plugin = plugin; + this.chatModeManager = manager; + } + + @Override + public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) { + if (!(sender instanceof Player player)) { + sender.sendMessage(ChatColor.RED + "Dieser Befehl kann nur von einem Spieler ausgeführt werden."); + return true; + } + + if (args.length == 0) { + // Wechsel in Telegram-Chatmodus + chatModeManager.setMode(player.getUniqueId(), ChatModeManager.ChatMode.TELEGRAM); + String msg = plugin.getConfig().getString("messages.mode-set-telegram", "Du bist jetzt im Telegram-Chatmodus."); + player.sendMessage(ChatColor.translateAlternateColorCodes('&', msg)); + return true; + } + + String sub = args[0].toLowerCase(); + + if (sub.equals("info")) { + player.sendMessage(ChatColor.DARK_GRAY + "=== TelegramChatBridge Info ==="); + player.sendMessage(ChatColor.GRAY + "Version: " + ChatColor.WHITE + plugin.getDescription().getVersion()); + player.sendMessage(ChatColor.GRAY + "Ersteller: " + ChatColor.WHITE + "M_Viper"); + + String chatId = plugin.getChatId(); + String chatType = "Unbekannt"; + if (chatId != null) { + if (chatId.startsWith("-")) { + chatType = "Gruppenchat"; + } else { + chatType = "Privat Chat"; + } + } + player.sendMessage(ChatColor.GRAY + "Chat-Typ: " + ChatColor.WHITE + chatType); + + return true; + } + + if (sub.equals("help")) { + player.sendMessage(ChatColor.GREEN + "=== TelegramChatBridge Befehle ==="); + player.sendMessage(ChatColor.YELLOW + "/tg" + ChatColor.WHITE + " - Wechsel in Telegram-Chatmodus"); + player.sendMessage(ChatColor.YELLOW + "/tg info" + ChatColor.WHITE + " - Plugin-Informationen anzeigen"); + player.sendMessage(ChatColor.YELLOW + "/tg help" + ChatColor.WHITE + " - Diese Hilfe anzeigen"); + return true; + } + + player.sendMessage(ChatColor.RED + "Unbekannter Unterbefehl. Nutze /tg help"); + return true; + } +}