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 dfb63f4..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
@@ -4,7 +4,9 @@ import me.freezy.plugins.papermc.blazesmp.BlazeSMP;
import me.freezy.plugins.papermc.blazesmp.command.util.SimpleCommand;
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;
@@ -15,144 +17,953 @@ import java.util.*;
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;
- private final LinkedHashMap> clanInvites = new LinkedHashMap<>();
+ // Mapping: Clan -> Liste der Join-Anfragen (Spieler, die einer bestehenden Clan beitreten möchten)
private final LinkedHashMap> clanJoins = new LinkedHashMap<>();
+ // Mapping: Clan -> Liste der Einladungen (Spieler, die vom Clan eingeladen wurden)
+ private final LinkedHashMap> clanInvites = new LinkedHashMap<>();
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 list, @NotNull String[] args) {
- return false;
+ 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!"));
+ return true;
+ }
+ UUID playerUUID = player.getUniqueId();
+
+ // Keine Subcommands -> zeige Hilfe
+ if (args.length == 0) {
+ 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!"));
+ return true;
+ }
+ if (args.length < 3) {
+ 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!"));
+ return true;
+ }
+
+ // ========== JOIN ==========
+ case "join" -> {
+ if (clans.isInClan(playerUUID)) {
+ player.sendMessage(miniMessage().deserialize("You are already in a clan!"));
+ return true;
+ }
+ if (args.length < 2) {
+ 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!"));
+ return true;
+ }
+
+ 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."));
+ return true;
+ }
+ joinRequests.add(playerUUID);
+ 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(
+ 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!"));
+ return true;
+ }
+ if (args.length < 2) {
+ 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(String.format("Player %s is not online!", inviteeName)));
+ return true;
+ }
+ if (clans.isInClan(invitee.getUniqueId())) {
+ 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."));
+ return true;
+ }
+ clanInvites.computeIfAbsent(inviterClan, k -> new LinkedList<>());
+ LinkedList inviteList = clanInvites.get(inviterClan);
+
+ if (inviteList.contains(invitee.getUniqueId())) {
+ player.sendMessage(miniMessage().deserialize(String.format("Player %s has already been invited!", inviteeName)));
+ return true;
+ }
+ inviteList.add(invitee.getUniqueId());
+ 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(
+ 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" -> {
+ // 1) Spieler ist noch in keinem Clan -> Einladung annehmen
+ if (!clans.isInClan(playerUUID)) {
+ if (args.length < 2) {
+ player.sendMessage(miniMessage().deserialize("Usage: /clan accept "));
+ return true;
+ }
+ String clanNameForInvite = args[1];
+ Clan invitedClan = null;
+ 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(String.format("No invite found from clan %s.", clanNameForInvite)));
+ return true;
+ }
+ invitedClan.getMembers().add(playerUUID);
+ clanInvites.get(invitedClan).remove(playerUUID);
+
+ 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(
+ String.format("%s has accepted the clan invite.", player.getName())));
+ }
+ invitedClan.save();
+ } else {
+ // 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."));
+ return true;
+ }
+ if (args.length < 2) {
+ 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."));
+ return true;
+ }
+ LinkedList joinReqs = clanJoins.get(currentClan);
+ if (joinReqs == null || joinReqs.isEmpty()) {
+ player.sendMessage(miniMessage().deserialize("No join requests available."));
+ return true;
+ }
+ UUID requesterUUID = getUuidByName(joinReqs, joinRequesterName);
+ if (requesterUUID == null) {
+ 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(
+ String.format("You have accepted %s's join request.", joinRequesterName)));
+
+ Player requester = Bukkit.getPlayer(requesterUUID);
+ if (requester != null && requester.isOnline()) {
+ 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 "));
+ return true;
+ }
+ String clanNameForInvite = args[1];
+ Clan invitedClan = null;
+ 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(String.format("No invite found from clan %s.", clanNameForInvite)));
+ return true;
+ }
+ clanInvites.get(invitedClan).remove(playerUUID);
+ 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(
+ 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."));
+ return true;
+ }
+ if (args.length < 2) {
+ 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."));
+ return true;
+ }
+ LinkedList joinReqs = clanJoins.get(currentClan);
+ if (joinReqs == null || joinReqs.isEmpty()) {
+ player.sendMessage(miniMessage().deserialize("No join requests available."));
+ return true;
+ }
+ UUID requesterUUID = getUuidByName(joinReqs, joinRequesterName);
+ if (requesterUUID == null) {
+ player.sendMessage(miniMessage().deserialize(String.format("No join request found from %s.", joinRequesterName)));
+ return true;
+ }
+ joinReqs.remove(requesterUUID);
+
+ 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(
+ 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."));
+ 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(" -