diff --git a/.gradle/8.8/executionHistory/executionHistory.bin b/.gradle/8.8/executionHistory/executionHistory.bin index 98058b6..115517d 100644 Binary files a/.gradle/8.8/executionHistory/executionHistory.bin and b/.gradle/8.8/executionHistory/executionHistory.bin differ diff --git a/.gradle/8.8/executionHistory/executionHistory.lock b/.gradle/8.8/executionHistory/executionHistory.lock index 9a696ad..269f36e 100644 Binary files a/.gradle/8.8/executionHistory/executionHistory.lock and b/.gradle/8.8/executionHistory/executionHistory.lock differ diff --git a/.gradle/8.8/fileHashes/fileHashes.bin b/.gradle/8.8/fileHashes/fileHashes.bin index 5ab0aa5..a063853 100644 Binary files a/.gradle/8.8/fileHashes/fileHashes.bin and b/.gradle/8.8/fileHashes/fileHashes.bin differ diff --git a/.gradle/8.8/fileHashes/fileHashes.lock b/.gradle/8.8/fileHashes/fileHashes.lock index 2732f42..9c366dc 100644 Binary files a/.gradle/8.8/fileHashes/fileHashes.lock and b/.gradle/8.8/fileHashes/fileHashes.lock differ diff --git a/.gradle/8.8/fileHashes/resourceHashesCache.bin b/.gradle/8.8/fileHashes/resourceHashesCache.bin index baf3a03..a0c134a 100644 Binary files a/.gradle/8.8/fileHashes/resourceHashesCache.bin and b/.gradle/8.8/fileHashes/resourceHashesCache.bin differ diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index 1678000..b81338f 100644 Binary files a/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ diff --git a/.gradle/buildOutputCleanup/outputFiles.bin b/.gradle/buildOutputCleanup/outputFiles.bin index 08bbe90..055d6f5 100644 Binary files a/.gradle/buildOutputCleanup/outputFiles.bin and b/.gradle/buildOutputCleanup/outputFiles.bin differ diff --git a/.gradle/file-system.probe b/.gradle/file-system.probe index eb4f76e..d4fe1fd 100644 Binary files a/.gradle/file-system.probe and b/.gradle/file-system.probe differ diff --git a/.idea/inspectionProfiles/Project_Default.xml b/.idea/inspectionProfiles/Project_Default.xml new file mode 100644 index 0000000..3908719 --- /dev/null +++ b/.idea/inspectionProfiles/Project_Default.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 526e09f..26a7d9b 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -2,7 +2,7 @@ - + \ No newline at end of file diff --git a/.idea/modules/me.freezy.plugins.papermc.BlazeSMP.main.iml b/.idea/modules/me.freezy.plugins.papermc.BlazeSMP.main.iml new file mode 100644 index 0000000..bbeeb3e --- /dev/null +++ b/.idea/modules/me.freezy.plugins.papermc.BlazeSMP.main.iml @@ -0,0 +1,14 @@ + + + + + + + PAPER + ADVENTURE + + 1 + + + + \ No newline at end of file diff --git a/src/main/java/me/freezy/plugins/papermc/blazesmp/command/ClanCommand.java b/src/main/java/me/freezy/plugins/papermc/blazesmp/command/ClanCommand.java index da9480f..bcde620 100644 --- a/src/main/java/me/freezy/plugins/papermc/blazesmp/command/ClanCommand.java +++ b/src/main/java/me/freezy/plugins/papermc/blazesmp/command/ClanCommand.java @@ -6,6 +6,7 @@ import me.freezy.plugins.papermc.blazesmp.module.Clan; import me.freezy.plugins.papermc.blazesmp.module.manager.Clans; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; +import org.bukkit.OfflinePlayer; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; @@ -13,14 +14,12 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.*; -import java.util.LinkedList; import java.util.stream.Collectors; import java.util.stream.Stream; import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage; public class ClanCommand extends SimpleCommand { - private final BlazeSMP plugin; private final Clans clans; // Mapping: Clan -> Liste der Join-Anfragen (Spieler, die einer bestehenden Clan beitreten möchten) @@ -30,420 +29,941 @@ public class ClanCommand extends SimpleCommand { public ClanCommand() { super("clan"); - plugin = BlazeSMP.getInstance(); + BlazeSMP plugin = BlazeSMP.getInstance(); clans = plugin.getClans(); } @Override - public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args) { + public boolean onCommand(@NotNull CommandSender sender, + @NotNull Command cmd, + @NotNull String label, + @NotNull String[] args) { if (!(sender instanceof Player player)) { - sender.sendMessage(miniMessage().deserialize("You must be a player to execute this command!")); + sender.sendMessage(miniMessage().deserialize("You must be a player to execute this command!")); return true; } UUID playerUUID = player.getUniqueId(); + // Keine Subcommands -> zeige Hilfe if (args.length == 0) { - // Anzeige der Hilfemeldung – abhängig von der Rolle des Spielers - if (clans.isLeader(playerUUID)) { - Component l1 = miniMessage().deserialize("=== Clan Commands ===\n"); - Component l2 = miniMessage().deserialize(" - /clan info\n"); - Component l3 = miniMessage().deserialize(" - /clan invite\n"); - Component l4 = miniMessage().deserialize(" - /clan kick\n"); - Component l5 = miniMessage().deserialize(" - /clan transfer\n"); - Component l6 = miniMessage().deserialize(" - /clan promote\n"); - Component l7 = miniMessage().deserialize(" - /clan demote\n"); - Component l8 = miniMessage().deserialize(" - /clan disband\n"); - Component l9 = miniMessage().deserialize(" - /clan leave\n"); - Component l10 = miniMessage().deserialize(" - /clan accept\n"); - Component l11 = miniMessage().deserialize(" - /clan deny\n"); - Component l12 = miniMessage().deserialize(" - /clan modify\n"); - Component l13 = miniMessage().deserialize("====================="); - player.sendMessage(l1.append(l2).append(l3).append(l4).append(l5) - .append(l6).append(l7).append(l8).append(l9).append(l10).append(l11).append(l12).append(l13)); - } else if (clans.isVice(playerUUID)) { - Component l1 = miniMessage().deserialize("=== Clan Commands ===\n"); - Component l2 = miniMessage().deserialize(" - /clan info\n"); - Component l3 = miniMessage().deserialize(" - /clan invite\n"); - Component l4 = miniMessage().deserialize(" - /clan kick\n"); - Component l5 = miniMessage().deserialize(" - /clan demote\n"); - Component l6 = miniMessage().deserialize(" - /clan leave\n"); - Component l7 = miniMessage().deserialize(" - /clan accept\n"); - Component l8 = miniMessage().deserialize(" - /clan deny\n"); - Component l9 = miniMessage().deserialize("====================="); - player.sendMessage(l1.append(l2).append(l3).append(l4).append(l5) - .append(l6).append(l7).append(l8).append(l9)); - } else if (clans.isMember(playerUUID)) { - Component l1 = miniMessage().deserialize("=== Clan Commands ===\n"); - Component l2 = miniMessage().deserialize(" - /clan info\n"); - Component l3 = miniMessage().deserialize(" - /clan leave\n"); - Component l4 = miniMessage().deserialize("====================="); - player.sendMessage(l1.append(l2).append(l3).append(l4)); - } else { - Component l1 = miniMessage().deserialize("=== Clan Commands ===\n"); - Component l2 = miniMessage().deserialize(" - /clan create\n"); - Component l3 = miniMessage().deserialize(" - /clan join\n"); - Component l4 = miniMessage().deserialize(" - /clan accept\n"); - Component l5 = miniMessage().deserialize(" - /clan deny\n"); - Component l6 = miniMessage().deserialize("====================="); - player.sendMessage(l1.append(l2).append(l3).append(l4).append(l5).append(l6)); - } + sendHelpMessage(player, playerUUID); return true; } // Verarbeitung der Unterbefehle String subCommand = args[0].toLowerCase(); switch (subCommand) { + + // ========== CREATE ========== case "create" -> { if (clans.isInClan(playerUUID)) { - player.sendMessage(miniMessage().deserialize("You are already in a clan!")); + player.sendMessage(miniMessage().deserialize("You are already in a clan!")); return true; } if (args.length < 3) { - player.sendMessage(miniMessage().deserialize("Usage: /clan create ")); + player.sendMessage(miniMessage().deserialize("Usage: /clan create ")); return true; } String clanName = args[1]; String clanTag = args[2]; Component tagComponent = miniMessage().deserialize(clanTag); + Clan newClan = new Clan(clanName, tagComponent, playerUUID); + // Clan hinzufügen und speichern clans.addClan(newClan); newClan.save(); - player.sendMessage(miniMessage().deserialize("Clan created successfully!")); + + player.sendMessage(miniMessage().deserialize("Clan created successfully!")); return true; } + + // ========== JOIN ========== case "join" -> { if (clans.isInClan(playerUUID)) { - player.sendMessage(miniMessage().deserialize("You are already in a clan!")); + player.sendMessage(miniMessage().deserialize("You are already in a clan!")); return true; } if (args.length < 2) { - player.sendMessage(miniMessage().deserialize("Usage: /clan join ")); + player.sendMessage(miniMessage().deserialize("Usage: /clan join ")); return true; } String targetClanName = args[1]; Clan targetClan = clans.getClanByName(targetClanName); if (targetClan == null) { - player.sendMessage(miniMessage().deserialize("Clan not found!")); + player.sendMessage(miniMessage().deserialize("Clan not found!")); return true; } - // Füge eine Join-Anfrage hinzu + clanJoins.computeIfAbsent(targetClan, k -> new LinkedList<>()); LinkedList joinRequests = clanJoins.get(targetClan); + if (joinRequests.contains(playerUUID)) { - player.sendMessage(miniMessage().deserialize("You have already requested to join this clan.")); + player.sendMessage(miniMessage().deserialize("You have already requested to join this clan.")); return true; } joinRequests.add(playerUUID); - player.sendMessage(miniMessage().deserialize("Join request sent to clan " + targetClan.getName() + "!")); - // Benachrichtige den Clan-Leader (sofern online) mit klickbaren Nachrichten + player.sendMessage(miniMessage().deserialize( + String.format("Join request sent to clan %s!", targetClan.getName()))); + + // Benachrichtige den Clan-Leader (sofern online) Player leader = Bukkit.getPlayer(targetClan.getLeaderUUID()); if (leader != null && leader.isOnline()) { String acceptCommand = "/clan accept " + player.getName(); String denyCommand = "/clan deny " + player.getName(); Component notifyMsg = miniMessage().deserialize( - "New join request from " + player.getName() + ".\n" + - "[Accept] " + - "[Deny]" + String.format("New join request from %s.\n", player.getName()) + + String.format("[Accept] ", acceptCommand) + + String.format("[Deny]", denyCommand) ); leader.sendMessage(notifyMsg); } return true; } + + // ========== INVITE ========== case "invite" -> { if (!clans.isLeader(playerUUID) && !clans.isVice(playerUUID)) { - player.sendMessage(miniMessage().deserialize("You are not authorized to invite players to a clan!")); + player.sendMessage(miniMessage().deserialize("You are not authorized to invite players to a clan!")); return true; } if (args.length < 2) { - player.sendMessage(miniMessage().deserialize("Usage: /clan invite ")); + player.sendMessage(miniMessage().deserialize("Usage: /clan invite ")); return true; } String inviteeName = args[1]; Player invitee = Bukkit.getPlayer(inviteeName); if (invitee == null || !invitee.isOnline()) { - player.sendMessage(miniMessage().deserialize("Player " + inviteeName + " is not online!")); + player.sendMessage(miniMessage().deserialize(String.format("Player %s is not online!", inviteeName))); return true; } if (clans.isInClan(invitee.getUniqueId())) { - player.sendMessage(miniMessage().deserialize("" + inviteeName + " is already in a clan!")); + player.sendMessage(miniMessage().deserialize(String.format("%s is already in a clan!", inviteeName))); return true; } Clan inviterClan = clans.getClanByMember(playerUUID); if (inviterClan == null) { - player.sendMessage(miniMessage().deserialize("Error: Your clan could not be found.")); + player.sendMessage(miniMessage().deserialize("Error: Your clan could not be found.")); return true; } clanInvites.computeIfAbsent(inviterClan, k -> new LinkedList<>()); LinkedList inviteList = clanInvites.get(inviterClan); + if (inviteList.contains(invitee.getUniqueId())) { - player.sendMessage(miniMessage().deserialize("Player " + inviteeName + " has already been invited!")); + player.sendMessage(miniMessage().deserialize(String.format("Player %s has already been invited!", inviteeName))); return true; } inviteList.add(invitee.getUniqueId()); - player.sendMessage(miniMessage().deserialize("Invite sent to " + inviteeName + ".")); - // Benachrichtige den eingeladenen Spieler mit klickbaren Nachrichten + player.sendMessage(miniMessage().deserialize(String.format("Invite sent to %s.", inviteeName))); + + // Benachrichtige den Eingeladenen String acceptCmd = "/clan accept " + inviterClan.getName(); String denyCmd = "/clan deny " + inviterClan.getName(); Component inviteNotify = miniMessage().deserialize( - "Invite from clan " + inviterClan.getName() + ".\n" + - "[Accept] " + - "[Deny]" + String.format("Invite from clan %s.\n", inviterClan.getName()) + + String.format("[Accept] ", acceptCmd) + + String.format("[Deny]", denyCmd) ); invitee.sendMessage(inviteNotify); return true; } + + // ========== ACCEPT ========== case "accept" -> { - // Unterscheidung: Ist der Spieler noch in keinem Clan? -> Einladung annehmen. + // 1) Spieler ist noch in keinem Clan -> Einladung annehmen if (!clans.isInClan(playerUUID)) { if (args.length < 2) { - player.sendMessage(miniMessage().deserialize("Usage: /clan accept ")); + player.sendMessage(miniMessage().deserialize("Usage: /clan accept ")); return true; } String clanNameForInvite = args[1]; Clan invitedClan = null; - for (var entry : clanInvites.entrySet()) { - if (entry.getValue().contains(playerUUID) && - entry.getKey().getName().equalsIgnoreCase(clanNameForInvite)) { + for (Map.Entry> entry : clanInvites.entrySet()) { + if (entry.getValue().contains(playerUUID) + && entry.getKey().getName().equalsIgnoreCase(clanNameForInvite)) { invitedClan = entry.getKey(); break; } } if (invitedClan == null) { - player.sendMessage(miniMessage().deserialize("No invite found from clan " + clanNameForInvite + ".")); + player.sendMessage(miniMessage().deserialize(String.format("No invite found from clan %s.", clanNameForInvite))); return true; } invitedClan.getMembers().add(playerUUID); clanInvites.get(invitedClan).remove(playerUUID); - player.sendMessage(miniMessage().deserialize("You have joined the clan " + invitedClan.getName() + "!")); + + player.sendMessage(miniMessage().deserialize( + String.format("You have joined the clan %s!", invitedClan.getName()))); + Player leader = Bukkit.getPlayer(invitedClan.getLeaderUUID()); if (leader != null && leader.isOnline()) { - leader.sendMessage(miniMessage().deserialize("" + player.getName() + " has accepted the clan invite.")); + leader.sendMessage(miniMessage().deserialize( + String.format("%s has accepted the clan invite.", player.getName()))); } invitedClan.save(); } else { - // Akzeptiere eine Beitrittsanfrage – nur für Leader oder Vice + // 2) Spieler ist bereits in einem Clan -> Beitrittsanfrage annehmen (Leader/Vice) if (!clans.isLeader(playerUUID) && !clans.isVice(playerUUID)) { - player.sendMessage(miniMessage().deserialize("You are not authorized to accept join requests.")); + player.sendMessage(miniMessage().deserialize("You are not authorized to accept join requests.")); return true; } if (args.length < 2) { - player.sendMessage(miniMessage().deserialize("Usage: /clan accept ")); + player.sendMessage(miniMessage().deserialize("Usage: /clan accept ")); return true; } String joinRequesterName = args[1]; Clan currentClan = clans.getClanByMember(playerUUID); if (currentClan == null) { - player.sendMessage(miniMessage().deserialize("Error: Your clan could not be found.")); + player.sendMessage(miniMessage().deserialize("Error: Your clan could not be found.")); return true; } LinkedList joinReqs = clanJoins.get(currentClan); if (joinReqs == null || joinReqs.isEmpty()) { - player.sendMessage(miniMessage().deserialize("No join requests available.")); + player.sendMessage(miniMessage().deserialize("No join requests available.")); return true; } - UUID requesterUUID = null; - for (UUID uuid : joinReqs) { - Player p = Bukkit.getPlayer(uuid); - if (p != null && p.getName().equalsIgnoreCase(joinRequesterName)) { - requesterUUID = uuid; - break; - } - } + UUID requesterUUID = getUuidByName(joinReqs, joinRequesterName); if (requesterUUID == null) { - player.sendMessage(miniMessage().deserialize("No join request found from " + joinRequesterName + ".")); + player.sendMessage(miniMessage().deserialize(String.format("No join request found from %s.", joinRequesterName))); return true; } currentClan.getMembers().add(requesterUUID); joinReqs.remove(requesterUUID); - player.sendMessage(miniMessage().deserialize("You have accepted " + joinRequesterName + "'s join request.")); + + player.sendMessage(miniMessage().deserialize( + String.format("You have accepted %s's join request.", joinRequesterName))); + Player requester = Bukkit.getPlayer(requesterUUID); if (requester != null && requester.isOnline()) { - requester.sendMessage(miniMessage().deserialize("Your join request for clan " + currentClan.getName() + " has been accepted.")); + requester.sendMessage(miniMessage().deserialize( + String.format("Your join request for clan %s has been accepted.", currentClan.getName()))); } currentClan.save(); } return true; } + + // ========== DENY ========== case "deny" -> { + // 1) Spieler ist noch in keinem Clan -> Einladung ablehnen if (!clans.isInClan(playerUUID)) { if (args.length < 2) { - player.sendMessage(miniMessage().deserialize("Usage: /clan deny ")); + player.sendMessage(miniMessage().deserialize("Usage: /clan deny ")); return true; } String clanNameForInvite = args[1]; Clan invitedClan = null; - for (var entry : clanInvites.entrySet()) { - if (entry.getValue().contains(playerUUID) && - entry.getKey().getName().equalsIgnoreCase(clanNameForInvite)) { + for (Map.Entry> entry : clanInvites.entrySet()) { + if (entry.getValue().contains(playerUUID) + && entry.getKey().getName().equalsIgnoreCase(clanNameForInvite)) { invitedClan = entry.getKey(); break; } } if (invitedClan == null) { - player.sendMessage(miniMessage().deserialize("No invite found from clan " + clanNameForInvite + ".")); + player.sendMessage(miniMessage().deserialize(String.format("No invite found from clan %s.", clanNameForInvite))); return true; } clanInvites.get(invitedClan).remove(playerUUID); - player.sendMessage(miniMessage().deserialize("You have declined the clan invite from " + invitedClan.getName() + ".")); + player.sendMessage(miniMessage().deserialize( + String.format("You have declined the clan invite from %s.", invitedClan.getName()))); + Player leader = Bukkit.getPlayer(invitedClan.getLeaderUUID()); if (leader != null && leader.isOnline()) { - leader.sendMessage(miniMessage().deserialize("" + player.getName() + " has declined the clan invite.")); + leader.sendMessage(miniMessage().deserialize( + String.format("%s has declined the clan invite.", player.getName()))); } } else { + // 2) Spieler ist in einem Clan -> Beitrittsanfrage ablehnen (Leader/Vice) if (!clans.isLeader(playerUUID) && !clans.isVice(playerUUID)) { - player.sendMessage(miniMessage().deserialize("You are not authorized to deny join requests.")); + player.sendMessage(miniMessage().deserialize("You are not authorized to deny join requests.")); return true; } if (args.length < 2) { - player.sendMessage(miniMessage().deserialize("Usage: /clan deny ")); + player.sendMessage(miniMessage().deserialize("Usage: /clan deny ")); return true; } String joinRequesterName = args[1]; Clan currentClan = clans.getClanByMember(playerUUID); if (currentClan == null) { - player.sendMessage(miniMessage().deserialize("Error: Your clan could not be found.")); + player.sendMessage(miniMessage().deserialize("Error: Your clan could not be found.")); return true; } LinkedList joinReqs = clanJoins.get(currentClan); if (joinReqs == null || joinReqs.isEmpty()) { - player.sendMessage(miniMessage().deserialize("No join requests available.")); + player.sendMessage(miniMessage().deserialize("No join requests available.")); return true; } - UUID requesterUUID = null; - for (UUID uuid : joinReqs) { - Player p = Bukkit.getPlayer(uuid); - if (p != null && p.getName().equalsIgnoreCase(joinRequesterName)) { - requesterUUID = uuid; - break; - } - } + UUID requesterUUID = getUuidByName(joinReqs, joinRequesterName); if (requesterUUID == null) { - player.sendMessage(miniMessage().deserialize("No join request found from " + joinRequesterName + ".")); + player.sendMessage(miniMessage().deserialize(String.format("No join request found from %s.", joinRequesterName))); return true; } joinReqs.remove(requesterUUID); - player.sendMessage(miniMessage().deserialize("You have denied " + joinRequesterName + "'s join request.")); + + player.sendMessage(miniMessage().deserialize( + String.format("You have denied %s's join request.", joinRequesterName))); + Player requester = Bukkit.getPlayer(requesterUUID); if (requester != null && requester.isOnline()) { - requester.sendMessage(miniMessage().deserialize("Your join request for clan " + currentClan.getName() + " has been denied.")); + requester.sendMessage(miniMessage().deserialize( + String.format("Your join request for clan %s has been denied.", currentClan.getName()))); } } return true; } + + // ========== LIST ========== + case "list" -> { + // Zeige eine Liste aller existierenden Clans an + sendClanList(player); + return true; + } + + // ========== INFO ========== + case "info" -> { + if (!clans.isInClan(playerUUID)) { + player.sendMessage(miniMessage().deserialize("You are not in a clan!")); + return true; + } + Clan clan = clans.getClanByMember(playerUUID); + if (clan == null) { + player.sendMessage(miniMessage().deserialize("Could not find your clan.")); + return true; + } + + // Sammle die Daten + UUID leaderUUID = clan.getLeaderUUID(); + UUID viceUUID = clan.getViceUUID(); + List members = clan.getMembers(); + + OfflinePlayer leaderOffline = Bukkit.getOfflinePlayer(leaderUUID); + String leaderName = leaderOffline.getName() != null ? leaderOffline.getName() : leaderUUID.toString(); + + String viceName = ""; + if (viceUUID != null) { + OfflinePlayer viceOffline = Bukkit.getOfflinePlayer(viceUUID); + viceName = (viceOffline.getName() != null) ? viceOffline.getName() : viceUUID.toString(); + } + + // Wir bauen den Info-Text in mehreren Component-Teilen auf + Component infoComponent = Component.empty(); + + // Header + Component l1 = miniMessage().deserialize("=== Clan info ===\n"); + // ID + Component l2 = miniMessage().deserialize(String.format( + " - ID: %s\n", + clan.getUuid() + )); + // Name + Component l3 = miniMessage().deserialize(String.format( + " - Name: %s\n", + clan.getName() + )); + // Leader + Component l4 = miniMessage().deserialize(String.format( + " - Leader: %s\n", + leaderName + )); + // Vice + Component l5 = miniMessage().deserialize(String.format( + " - Vice Leader: %s\n", + viceName + )); + // Member Count + Component l6 = miniMessage().deserialize(String.format( + " - Members: %d\n", + members.size() + )); + // Tag + Component l8 = miniMessage().deserialize(String.format( + " - Tag: %s\n", + miniMessage().serialize(clan.getTag()) + )); + // Member-Liste + Component l7 = miniMessage().deserialize("Members List:\n"); + + infoComponent = infoComponent + .append(l1).append(l2).append(l3) + .append(l4).append(l5).append(l6) + .append(l8).append(l7); + + // Detaillierte Auflistung der Mitglieder + for (UUID mem : members) { + OfflinePlayer off = Bukkit.getOfflinePlayer(mem); + String name = off.getName() != null ? off.getName() : mem.toString(); + Component memberLine = miniMessage().deserialize(String.format( + " - Member: %s\n", + name + )); + infoComponent = infoComponent.append(memberLine); + } + + // Abschlusslinie + Component endLine = miniMessage().deserialize("====================="); + infoComponent = infoComponent.append(endLine); + + player.sendMessage(infoComponent); + return true; + } + + // ========== KICK ========== + case "kick" -> { + if (!clans.isLeader(playerUUID) && !clans.isVice(playerUUID)) { + player.sendMessage(miniMessage().deserialize("You are not authorized to kick players.")); + return true; + } + if (args.length < 2) { + player.sendMessage(miniMessage().deserialize("Usage: /clan kick ")); + return true; + } + Clan currentClan = clans.getClanByMember(playerUUID); + if (currentClan == null) { + player.sendMessage(miniMessage().deserialize("Could not find your clan.")); + return true; + } + String targetName = args[1]; + OfflinePlayer targetOffline = Bukkit.getOfflinePlayer(targetName); + + if (targetOffline.getName() == null) { + player.sendMessage(miniMessage().deserialize("No such player found.")); + return true; + } + UUID targetUUID = targetOffline.getUniqueId(); + + // Check: Ist der Spieler im Clan? + if (!currentClan.isMember(targetUUID)) { + player.sendMessage(miniMessage().deserialize(String.format("%s is not in your clan!", targetName))); + return true; + } + // Vice kann keinen Leader kicken + if (clans.isVice(playerUUID) && currentClan.isLeader(targetUUID)) { + player.sendMessage(miniMessage().deserialize("You cannot kick the clan leader!")); + return true; + } + + // Vice entfernen, falls der Gekickte Vice war + if (currentClan.isVice(targetUUID)) { + currentClan.setViceUUID(null); + } + currentClan.getMembers().remove(targetUUID); + currentClan.save(); + + player.sendMessage(miniMessage().deserialize(String.format("You kicked %s from the clan.", targetName))); + if (targetOffline.isOnline()) { + Player targetOnline = (Player) targetOffline; + targetOnline.sendMessage(miniMessage().deserialize(String.format("You have been kicked from the clan %s.", currentClan.getName()))); + } + return true; + } + + // ========== TRANSFER ========== + case "transfer" -> { + if (!clans.isLeader(playerUUID)) { + player.sendMessage(miniMessage().deserialize("Only the clan leader can transfer leadership.")); + return true; + } + if (args.length < 2) { + player.sendMessage(miniMessage().deserialize("Usage: /clan transfer ")); + return true; + } + Clan currentClan = clans.getClanByMember(playerUUID); + if (currentClan == null) { + player.sendMessage(miniMessage().deserialize("Could not find your clan.")); + return true; + } + String newLeaderName = args[1]; + OfflinePlayer newLeaderOffline = Bukkit.getOfflinePlayer(newLeaderName); + if (newLeaderOffline.getName() == null) { + player.sendMessage(miniMessage().deserialize("No such player found.")); + return true; + } + UUID newLeaderUUID = newLeaderOffline.getUniqueId(); + + if (!currentClan.isMember(newLeaderUUID)) { + player.sendMessage(miniMessage().deserialize(String.format("%s is not in your clan!", newLeaderName))); + return true; + } + + // Füge den alten Leader zur Members-Liste hinzu (falls nicht enthalten) + if (!currentClan.getMembers().contains(playerUUID)) { + currentClan.getMembers().add(playerUUID); + } + // Setze neuen Leader + currentClan.setLeaderUUID(newLeaderUUID); + // Falls Vice, entfernen + if (currentClan.isVice(newLeaderUUID)) { + currentClan.setViceUUID(null); + } + currentClan.save(); + + player.sendMessage(miniMessage().deserialize(String.format("You transferred leadership to %s.", newLeaderName))); + if (newLeaderOffline.isOnline()) { + ((Player) newLeaderOffline).sendMessage(miniMessage().deserialize( + String.format("You are now the leader of the clan %s.", currentClan.getName()))); + } + return true; + } + + // ========== PROMOTE ========== + case "promote" -> { + if (!clans.isLeader(playerUUID)) { + player.sendMessage(miniMessage().deserialize("Only the clan leader can promote a member.")); + return true; + } + if (args.length < 2) { + player.sendMessage(miniMessage().deserialize("Usage: /clan promote ")); + return true; + } + Clan currentClan = clans.getClanByMember(playerUUID); + if (currentClan == null) { + player.sendMessage(miniMessage().deserialize("Could not find your clan.")); + return true; + } + String promoteName = args[1]; + OfflinePlayer promoteOffline = Bukkit.getOfflinePlayer(promoteName); + + if (promoteOffline.getName() == null) { + player.sendMessage(miniMessage().deserialize("No such player found.")); + return true; + } + UUID promoteUUID = promoteOffline.getUniqueId(); + + if (!currentClan.isMember(promoteUUID)) { + player.sendMessage(miniMessage().deserialize(String.format("%s is not in your clan!", promoteName))); + return true; + } + // Vice setzen + currentClan.setViceUUID(promoteUUID); + currentClan.save(); + + player.sendMessage(miniMessage().deserialize(String.format("You promoted %s to vice leader.", promoteName))); + if (promoteOffline.isOnline()) { + ((Player) promoteOffline).sendMessage(miniMessage().deserialize( + String.format("You have been promoted to vice leader of clan %s.", currentClan.getName()))); + } + return true; + } + + // ========== DEMOTE ========== + case "demote" -> { + if (!clans.isLeader(playerUUID) && !clans.isVice(playerUUID)) { + player.sendMessage(miniMessage().deserialize("You are not authorized to demote anyone.")); + return true; + } + if (args.length < 2) { + player.sendMessage(miniMessage().deserialize("Usage: /clan demote ")); + return true; + } + Clan currentClan = clans.getClanByMember(playerUUID); + if (currentClan == null) { + player.sendMessage(miniMessage().deserialize("Could not find your clan.")); + return true; + } + String demoteName = args[1]; + OfflinePlayer demoteOffline = Bukkit.getOfflinePlayer(demoteName); + + if (demoteOffline.getName() == null) { + player.sendMessage(miniMessage().deserialize("No such player found.")); + return true; + } + UUID demoteUUID = demoteOffline.getUniqueId(); + + // Check, ob der Spieler Vice ist + if (!currentClan.isVice(demoteUUID)) { + player.sendMessage(miniMessage().deserialize(String.format("%s is not the vice leader!", demoteName))); + return true; + } + // Vice kann nur sich selbst demoten (oder Leader kann Vice demoten) + if (!clans.isLeader(playerUUID) && !playerUUID.equals(demoteUUID)) { + player.sendMessage(miniMessage().deserialize("You can only demote yourself!")); + return true; + } + currentClan.setViceUUID(null); + // Sicherstellen, dass der Spieler in der Memberliste bleibt + if (!currentClan.getMembers().contains(demoteUUID)) { + currentClan.getMembers().add(demoteUUID); + } + currentClan.save(); + + player.sendMessage(miniMessage().deserialize(String.format("You demoted %s to a normal member.", demoteName))); + if (demoteOffline.isOnline()) { + ((Player) demoteOffline).sendMessage(miniMessage().deserialize( + String.format("You have been demoted to a normal member of clan %s.", currentClan.getName()))); + } + return true; + } + + // ========== DISBAND ========== + case "disband" -> { + if (!clans.isLeader(playerUUID)) { + player.sendMessage(miniMessage().deserialize("Only the clan leader can disband the clan.")); + return true; + } + Clan currentClan = clans.getClanByMember(playerUUID); + if (currentClan == null) { + player.sendMessage(miniMessage().deserialize("Could not find your clan.")); + return true; + } + + // Benachrichtige alle Mitglieder + for (UUID memberUUID : currentClan.getMembers()) { + Player memberOnline = Bukkit.getPlayer(memberUUID); + if (memberOnline != null && memberOnline.isOnline()) { + memberOnline.sendMessage(miniMessage().deserialize( + String.format("Your clan %s has been disbanded by the leader.", currentClan.getName()))); + } + } + // Clan entfernen + clans.removeClan(currentClan); + player.sendMessage(miniMessage().deserialize("You have disbanded your clan.")); + return true; + } + + // ========== LEAVE ========== + case "leave" -> { + if (!clans.isInClan(playerUUID)) { + player.sendMessage(miniMessage().deserialize("You are not in a clan!")); + return true; + } + Clan currentClan = clans.getClanByMember(playerUUID); + if (currentClan == null) { + player.sendMessage(miniMessage().deserialize("Could not find your clan.")); + return true; + } + + // Leader kann nicht einfach gehen, ohne disband oder transfer + if (currentClan.isLeader(playerUUID)) { + if (!currentClan.getMembers().isEmpty()) { + player.sendMessage(miniMessage().deserialize("You must transfer leadership or disband the clan before leaving.")); + } else { + // Keine weiteren Mitglieder -> disband + clans.removeClan(currentClan); + player.sendMessage(miniMessage().deserialize( + "You have disbanded your clan (no other members) and left.")); + } + return true; + } + // Vice -> Vice-Position freigeben + if (currentClan.isVice(playerUUID)) { + currentClan.setViceUUID(null); + } + currentClan.getMembers().remove(playerUUID); + currentClan.save(); + + player.sendMessage(miniMessage().deserialize( + String.format("You have left the clan %s.", currentClan.getName()))); + return true; + } + + // ========== MODIFY (Name/Tag) ========== + case "modify" -> { + if (!clans.isLeader(playerUUID)) { + player.sendMessage(miniMessage().deserialize("Only the clan leader can modify clan settings.")); + return true; + } + if (args.length < 3) { + player.sendMessage(miniMessage().deserialize("Usage: /clan modify ")); + return true; + } + String whatToModify = args[1].toLowerCase(); + String newValue = args[2]; + + Clan currentClan = clans.getClanByMember(playerUUID); + if (currentClan == null) { + player.sendMessage(miniMessage().deserialize("Could not find your clan.")); + return true; + } + + switch (whatToModify) { + case "name" -> { + currentClan.setName(newValue); + currentClan.save(); + player.sendMessage(miniMessage().deserialize(String.format("Clan name changed to %s.", newValue))); + } + case "tag" -> { + Component newTag = miniMessage().deserialize(newValue); + currentClan.setTag(newTag); + currentClan.save(); + player.sendMessage(miniMessage().deserialize(String.format("Clan tag changed to %s.", newValue))); + } + default -> { + player.sendMessage(miniMessage().deserialize("You can only modify 'name' or 'tag'.")); + } + } + return true; + } + + // ========== Fallback für Unbekanntes ========== default -> { - player.sendMessage(miniMessage().deserialize("Unknown subcommand. Use /clan for help.")); + player.sendMessage(miniMessage().deserialize("Unknown subcommand. Use /clan for help.")); return true; } } } + /** + * Zeigt eine Liste aller Clans auf dem Server an. + */ + private void sendClanList(Player player) { + // Hier nehmen wir an, dass 'clans.getClans()' alle existierenden Clans liefert. + Collection allClans = clans.getClans(); + if (allClans.isEmpty()) { + player.sendMessage(miniMessage().deserialize("No clans found!")); + return; + } + + Component clanListComponent = Component.empty(); + clanListComponent = clanListComponent.append( + miniMessage().deserialize("=== List of clans ===\n")); + + for (Clan clan : allClans) { + Component clanComponent = miniMessage().deserialize( + String.format(" - %s\n", clan.getName())); + clanListComponent = clanListComponent.append(clanComponent); + } + clanListComponent = clanListComponent.append( + miniMessage().deserialize("=====================")); + + player.sendMessage(clanListComponent); + } + + /** + * Hilfsfunktion: Zeigt eine übersichtliche Hilfe basierend auf der Rolle (Leader, Vice, Member, Kein-Mitglied). + */ + private void sendHelpMessage(Player player, UUID playerUUID) { + if (clans.isLeader(playerUUID)) { + Component l1 = miniMessage().deserialize("=== Clan Commands ===\n"); + Component l2 = miniMessage().deserialize(" - /clan info\n"); + Component l3 = miniMessage().deserialize(" - /clan invite\n"); + Component l4 = miniMessage().deserialize(" - /clan kick\n"); + Component l5 = miniMessage().deserialize(" - /clan transfer\n"); + Component l6 = miniMessage().deserialize(" - /clan promote\n"); + Component l7 = miniMessage().deserialize(" - /clan demote\n"); + Component l8 = miniMessage().deserialize(" - /clan disband\n"); + Component l9 = miniMessage().deserialize(" - /clan leave\n"); + Component l10 = miniMessage().deserialize(" - /clan accept\n"); + Component l11 = miniMessage().deserialize(" - /clan deny\n"); + Component l12 = miniMessage().deserialize(" - /clan modify\n"); + Component l13 = miniMessage().deserialize(" - /clan list\n"); + Component l14 = miniMessage().deserialize("====================="); + + player.sendMessage(l1.append(l2).append(l3).append(l4).append(l5) + .append(l6).append(l7).append(l8).append(l9).append(l10).append(l11).append(l12).append(l13).append(l14)); + } else if (clans.isVice(playerUUID)) { + Component l1 = miniMessage().deserialize("=== Clan Commands ===\n"); + Component l2 = miniMessage().deserialize(" - /clan info\n"); + Component l3 = miniMessage().deserialize(" - /clan invite\n"); + Component l4 = miniMessage().deserialize(" - /clan kick\n"); + Component l5 = miniMessage().deserialize(" - /clan demote\n"); + Component l6 = miniMessage().deserialize(" - /clan leave\n"); + Component l7 = miniMessage().deserialize(" - /clan accept\n"); + Component l8 = miniMessage().deserialize(" - /clan deny\n"); + Component l9 = miniMessage().deserialize(" - /clan list\n"); + Component l10 = miniMessage().deserialize("====================="); + + player.sendMessage(l1.append(l2).append(l3).append(l4).append(l5) + .append(l6).append(l7).append(l8).append(l9).append(l10)); + } else if (clans.isMember(playerUUID)) { + Component l1 = miniMessage().deserialize("=== Clan Commands ===\n"); + Component l2 = miniMessage().deserialize(" - /clan info\n"); + Component l3 = miniMessage().deserialize(" - /clan leave\n"); + Component l4 = miniMessage().deserialize(" - /clan list\n"); + Component l5 = miniMessage().deserialize("====================="); + + player.sendMessage(l1.append(l2).append(l3).append(l4).append(l5)); + } else { + // Spieler ist in keinem Clan + Component l1 = miniMessage().deserialize("=== Clan Commands ===\n"); + Component l2 = miniMessage().deserialize(" - /clan create\n"); + Component l3 = miniMessage().deserialize(" - /clan join\n"); + Component l4 = miniMessage().deserialize(" - /clan accept\n"); + Component l5 = miniMessage().deserialize(" - /clan deny\n"); + Component l6 = miniMessage().deserialize(" - /clan list\n"); + Component l7 = miniMessage().deserialize("====================="); + + player.sendMessage(l1.append(l2).append(l3).append(l4).append(l5).append(l6).append(l7)); + } + } + @Override - public @Nullable List onTabComplete(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args) { - Player player = (Player) sender; + public @Nullable List onTabComplete(@NotNull CommandSender sender, + @NotNull Command cmd, + @NotNull String label, + @NotNull String[] args) { + if (!(sender instanceof Player player)) return List.of(); UUID playerUUID = player.getUniqueId(); + + // Erste Ebene der Subcommands if (args.length == 1) { if (clans.isLeader(playerUUID)) { - return Stream.of("info", "invite", "kick", "transfer", "promote", "demote", "disband", "leave", "accept", "deny", "modify") - .filter(s -> s.startsWith(args[0])).toList(); + return Stream.of("info", "invite", "kick", "transfer", "promote", + "demote", "disband", "leave", "accept", "deny", + "modify", "list") + .filter(s -> s.startsWith(args[0])) + .collect(Collectors.toList()); } else if (clans.isVice(playerUUID)) { - return Stream.of("info", "invite", "kick", "demote", "leave", "accept", "deny") - .filter(s -> s.startsWith(args[0])).toList(); + return Stream.of("info", "invite", "kick", "demote", + "leave", "accept", "deny", "list") + .filter(s -> s.startsWith(args[0])) + .collect(Collectors.toList()); } else if (clans.isMember(playerUUID)) { - return Stream.of("info", "leave") - .filter(s -> s.startsWith(args[0])).toList(); + return Stream.of("info", "leave", "list") + .filter(s -> s.startsWith(args[0])) + .collect(Collectors.toList()); } else { - return Stream.of("create", "join", "accept", "deny") - .filter(s -> s.startsWith(args[0])).toList(); + return Stream.of("create", "join", "accept", "deny", "list") + .filter(s -> s.startsWith(args[0])) + .collect(Collectors.toList()); } - } else if (args.length == 2) { + } + + // Zweite Ebene + if (args.length == 2) { if (clans.isLeader(playerUUID)) { - if (args[0].equalsIgnoreCase("invite")) { - return Bukkit.getOnlinePlayers().stream() - .filter(p -> !clans.isMember(p.getUniqueId())) - .map(Player::getName) - .filter(name -> name.startsWith(args[1])).collect(Collectors.toList()); - } else if (args[0].equalsIgnoreCase("kick")) { - return clans.getClanByMember(playerUUID).getMembers().stream() - .map(UUID::toString) - .filter(s -> s.startsWith(args[1])).collect(Collectors.toList()); - } else if (args[0].equalsIgnoreCase("promote")) { - return clans.getClanByMember(playerUUID).getMembers().stream() - .map(UUID::toString) - .filter(s -> s.startsWith(args[1])).collect(Collectors.toList()); - } else if (args[0].equalsIgnoreCase("demote")) { - return Collections.singletonList(plugin.getServer().getOfflinePlayer(clans.getClanByMember(playerUUID).getViceUUID()).getName()); - } else if (args[0].equalsIgnoreCase("accept")) { - List joins = getClanJoinRequests(args, playerUUID); - if (joins != null) return joins; - } else if (args[0].equalsIgnoreCase("deny")) { - List joins = getClanJoinRequests(args, playerUUID); - if (joins != null) return joins; - } else if (args[0].equalsIgnoreCase("modify")) { - return Stream.of("name", "tag").filter(s -> s.startsWith(args[1])).toList(); + switch (args[0].toLowerCase()) { + case "invite" -> { + return Bukkit.getOnlinePlayers().stream() + .filter(p -> !clans.isMember(p.getUniqueId())) + .map(Player::getName) + .filter(name -> name.startsWith(args[1])) + .collect(Collectors.toList()); + } + case "kick", "promote" -> { + Clan clan = clans.getClanByMember(playerUUID); + if (clan == null) return List.of(); + return clan.getMembers().stream() + .map(uuid -> Bukkit.getOfflinePlayer(uuid).getName()) + .filter(Objects::nonNull) + .filter(name -> name.startsWith(args[1])) + .collect(Collectors.toList()); + } + case "demote" -> { + Clan clan = clans.getClanByMember(playerUUID); + if (clan == null || clan.getViceUUID() == null) return List.of(); + String viceName = Optional.ofNullable( + Bukkit.getOfflinePlayer(clan.getViceUUID()).getName()) + .orElse(clan.getViceUUID().toString()); + return viceName.startsWith(args[1]) + ? List.of(viceName) + : List.of(); + } + case "accept", "deny" -> { + List joins = getClanJoinRequests(args, playerUUID); + if (joins != null) return joins; + } + case "modify" -> { + return Stream.of("name", "tag") + .filter(s -> s.startsWith(args[1])) + .collect(Collectors.toList()); + } + default -> {} } } else if (clans.isVice(playerUUID)) { - if (args[0].equalsIgnoreCase("invite")) { - return Bukkit.getOnlinePlayers().stream() - .filter(p -> !clans.isMember(p.getUniqueId())) - .map(Player::getName) - .filter(name -> name.startsWith(args[1])).collect(Collectors.toList()); - } else if (args[0].equalsIgnoreCase("kick")) { - return clans.getClanByMember(playerUUID).getMembers().stream() - .map(UUID::toString) - .filter(s -> s.startsWith(args[1])).collect(Collectors.toList()); - } else if (args[0].equalsIgnoreCase("accept")) { - List joins = getClanJoinRequests(args, playerUUID); - if (joins != null) return joins; - } else if (args[0].equalsIgnoreCase("deny")) { - List joins = getClanJoinRequests(args, playerUUID); - if (joins != null) return joins; - } else if (args[0].equalsIgnoreCase("demote")) { - return Collections.singletonList(plugin.getServer().getOfflinePlayer(clans.getClanByMember(playerUUID).getViceUUID()).getName()); + switch (args[0].toLowerCase()) { + case "invite" -> { + return Bukkit.getOnlinePlayers().stream() + .filter(p -> !clans.isMember(p.getUniqueId())) + .map(Player::getName) + .filter(name -> name.startsWith(args[1])) + .collect(Collectors.toList()); + } + case "kick" -> { + Clan clan = clans.getClanByMember(playerUUID); + if (clan == null) return List.of(); + return clan.getMembers().stream() + .map(uuid -> Bukkit.getOfflinePlayer(uuid).getName()) + .filter(Objects::nonNull) + .filter(name -> name.startsWith(args[1])) + .collect(Collectors.toList()); + } + case "demote" -> { + Clan clan = clans.getClanByMember(playerUUID); + if (clan == null || clan.getViceUUID() == null) return List.of(); + String viceName = Optional.ofNullable( + Bukkit.getOfflinePlayer(clan.getViceUUID()).getName()) + .orElse(clan.getViceUUID().toString()); + return viceName.startsWith(args[1]) + ? List.of(viceName) + : List.of(); + } + case "accept", "deny" -> { + List joins = getClanJoinRequests(args, playerUUID); + if (joins != null) return joins; + } + default -> {} } } else { - if (args[0].equalsIgnoreCase("accept")) { - return clanInvites.entrySet().stream() - .filter(entry -> entry.getValue().contains(playerUUID)) - .map(entry -> entry.getKey().getName()) - .collect(Collectors.toList()); - } else if (args[0].equalsIgnoreCase("deny")) { - return clanInvites.entrySet().stream() - .filter(entry -> entry.getValue().contains(playerUUID)) - .map(entry -> entry.getKey().getName()) - .collect(Collectors.toList()); - } else if (args[0].equalsIgnoreCase("join")) { - return clans.getClans().stream() - .map(Clan::getName) - .filter(s -> s.startsWith(args[1])).collect(Collectors.toList()); - } else if (args[0].equalsIgnoreCase("create")) { - return Collections.singletonList(""); + switch (args[0].toLowerCase()) { + case "accept", "deny" -> { + // Zeige alle Clan-Einladungen an + return clanInvites.entrySet().stream() + .filter(entry -> entry.getValue().contains(playerUUID)) + .map(entry -> entry.getKey().getName()) + .filter(name -> name.startsWith(args[1])) + .collect(Collectors.toList()); + } + case "join" -> { + // Zeige alle Clans an + return clans.getClans().stream() + .map(Clan::getName) + .filter(s -> s.startsWith(args[1])) + .collect(Collectors.toList()); + } + case "create" -> { + return Collections.singletonList(""); + } + default -> {} } } - } else if (args.length == 3) { + } + + // Dritte Ebene (z. B. /clan modify name ) + if (args.length == 3) { if (clans.isLeader(playerUUID)) { - if (args[1].equalsIgnoreCase("name")) { - return Collections.singletonList(""); - } else if (args[1].equalsIgnoreCase("tag")) { - return Collections.singletonList(""); - } - } else { - if (args[0].equalsIgnoreCase("create")) { - return Collections.singletonList(""); + if (args[0].equalsIgnoreCase("modify")) { + if (args[1].equalsIgnoreCase("name")) { + return Collections.singletonList(""); + } else if (args[1].equalsIgnoreCase("tag")) { + return Collections.singletonList(""); + } } + } else if (args[0].equalsIgnoreCase("create")) { + return Collections.singletonList(""); } } return List.of(); } + /** + * Liefert zu einem Namen die passende UUID aus einer UUID-Liste (z. B. Join-Anfragen). + */ @Nullable - private List getClanJoinRequests(@NotNull String[] args, UUID playerUUID) { - LinkedList joins = clanJoins.get(clans.getClanByMember(playerUUID)); - if (joins != null) { - return joins.stream() - .map(uuid -> plugin.getServer().getOfflinePlayer(uuid).getName()) - .filter(Objects::nonNull) - .filter(s -> s.startsWith(args[1])).collect(Collectors.toList()); + private UUID getUuidByName(List uuidList, String playerName) { + for (UUID uuid : uuidList) { + OfflinePlayer off = Bukkit.getOfflinePlayer(uuid); + if (off.getName() != null && off.getName().equalsIgnoreCase(playerName)) { + return uuid; + } } return null; } + + /** + * Hilfsfunktion für Tab-Completion (Zeigt Spielernamen von Join-Anfragen). + */ + @Nullable + private List getClanJoinRequests(@NotNull String[] args, UUID playerUUID) { + Clan clan = clans.getClanByMember(playerUUID); + if (clan == null) return null; + + LinkedList joins = clanJoins.get(clan); + if (joins == null) return null; + + return joins.stream() + .map(uuid -> Bukkit.getOfflinePlayer(uuid).getName()) + .filter(Objects::nonNull) + .filter(name -> name.startsWith(args[1])) + .collect(Collectors.toList()); + } }