package club.mcscrims.speedhg.command import club.mcscrims.speedhg.SpeedHG import club.mcscrims.speedhg.game.GameState import club.mcscrims.speedhg.team.TeamManager import club.mcscrims.speedhg.util.sendMsg import org.bukkit.command.Command import org.bukkit.command.CommandExecutor import org.bukkit.command.CommandSender import org.bukkit.command.TabCompleter import org.bukkit.entity.Player class TeamCommand : CommandExecutor, TabCompleter { private val plugin get() = SpeedHG.instance // ── Guard: Teams nur in Lobby-Phasen ändern ────────────────────────────── private fun isLobbyPhase(): Boolean = when (plugin.gameManager.currentState) { GameState.LOBBY, GameState.STARTING -> true else -> false } // ========================================================================= // onCommand dispatch // ========================================================================= override fun onCommand( sender: CommandSender, command: Command, label: String, args: Array ): Boolean { val player = sender as? Player ?: run { sender.sendMessage("§cOnly players can use this command.") return true } if (!plugin.teamManager.isEnabled) { player.sendMsg("team.disabled") return true } when (args.firstOrNull()?.lowercase()) { "invite" -> handleInvite(player, args) "accept" -> handleAccept(player, args) "deny" -> handleDeny(player, args) "leave" -> handleLeave(player) "kick" -> handleKick(player, args) "info" -> handleInfo(player) else -> player.sendMsg("team.usage") } return true } // ========================================================================= // Subcommand Handlers // ========================================================================= private fun handleInvite(player: Player, args: Array) { if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return } val targetName = args.getOrNull(1) ?: run { player.sendMsg("team.invite.usage"); return } val target = plugin.server.getPlayerExact(targetName) ?: run { player.sendMsg("team.player_not_found", "name" to targetName); return } when (plugin.teamManager.invite(player, target)) { is TeamManager.InviteResult.Success -> { player.sendMsg("team.invite.sent", "name" to target.name) target.sendMsg("team.invite.received", "name" to player.name, "time" to (TeamManager.INVITE_TTL_MS / 1000).toString() ) } is TeamManager.InviteResult.TeamsDisabled -> player.sendMsg("team.disabled") is TeamManager.InviteResult.InvitedSelf -> player.sendMsg("team.invite.self") is TeamManager.InviteResult.AlreadyInSameTeam -> player.sendMsg("team.invite.already_teammate") is TeamManager.InviteResult.TargetAlreadyInTeam -> player.sendMsg("team.invite.target_has_team", "name" to target.name) is TeamManager.InviteResult.SenderAlreadyInFullTeam -> player.sendMsg("team.invite.team_full") is TeamManager.InviteResult.InviteAlreadyPending -> player.sendMsg("team.invite.already_pending", "name" to target.name) } } private fun handleAccept(player: Player, args: Array) { if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return } val inviterName = args.getOrNull(1) ?: run { player.sendMsg("team.accept.usage"); return } val inviter = plugin.server.getPlayerExact(inviterName) ?: run { player.sendMsg("team.player_not_found", "name" to inviterName); return } when (val result = plugin.teamManager.accept(player, inviter.uniqueId)) { is TeamManager.AcceptResult.Success -> { val memberNames = result.team.members .mapNotNull { plugin.server.getPlayer(it)?.name } .joinToString(", ") // Alle Teammitglieder benachrichtigen result.team.members.forEach { uuid -> plugin.server.getPlayer(uuid)?.sendMsg( "team.accept.joined", "name" to player.name, "members" to memberNames ) } } is TeamManager.AcceptResult.TeamsDisabled -> player.sendMsg("team.disabled") is TeamManager.AcceptResult.NoInvite -> player.sendMsg("team.accept.no_invite", "name" to inviterName) is TeamManager.AcceptResult.WrongInviter -> player.sendMsg("team.accept.no_invite", "name" to inviterName) is TeamManager.AcceptResult.InviteExpired -> player.sendMsg("team.accept.expired", "name" to inviterName) is TeamManager.AcceptResult.AlreadyInTeam -> player.sendMsg("team.already_in_team") is TeamManager.AcceptResult.TeamFull -> player.sendMsg("team.invite.team_full") is TeamManager.AcceptResult.InviterNotFound -> player.sendMsg("team.player_not_found", "name" to inviterName) } } private fun handleDeny(player: Player, args: Array) { if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return } val inviterName = args.getOrNull(1) ?: run { player.sendMsg("team.deny.usage"); return } val inviter = plugin.server.getPlayerExact(inviterName) ?: run { player.sendMsg("team.player_not_found", "name" to inviterName); return } if (plugin.teamManager.deny(player, inviter.uniqueId)) { player.sendMsg("team.deny.success", "name" to inviterName) inviter.sendMsg("team.deny.received", "name" to player.name) } else { player.sendMsg("team.accept.no_invite", "name" to inviterName) } } private fun handleLeave(player: Player) { if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return } val team = plugin.teamManager.getTeam(player) when (plugin.teamManager.leave(player)) { is TeamManager.LeaveResult.NotInTeam -> { player.sendMsg("team.not_in_team") } is TeamManager.LeaveResult.TeamDisbanded -> { // Alle Ex-Mitglieder (außer dem Verlassenden) benachrichtigen team?.members?.forEach { uuid -> plugin.server.getPlayer(uuid)?.sendMsg("team.leave.disbanded") } player.sendMsg("team.leave.disbanded") } is TeamManager.LeaveResult.Success -> { player.sendMsg("team.leave.success") // Verbleibende Mitglieder informieren team?.members?.forEach { uuid -> plugin.server.getPlayer(uuid)?.sendMsg( "team.leave.member_left", "name" to player.name ) } } } } private fun handleKick(player: Player, args: Array) { if (!isLobbyPhase()) { player.sendMsg("team.game_running"); return } val targetName = args.getOrNull(1) ?: run { player.sendMsg("team.kick.usage"); return } val target = plugin.server.getPlayerExact(targetName) ?: run { player.sendMsg("team.player_not_found", "name" to targetName); return } when (plugin.teamManager.kick(player, target)) { is TeamManager.KickResult.Success -> { player.sendMsg("team.kick.success", "name" to target.name) target.sendMsg("team.kick.received", "name" to player.name) } is TeamManager.KickResult.NotInTeam -> player.sendMsg("team.not_in_team") is TeamManager.KickResult.NotLeader -> player.sendMsg("team.kick.not_leader") is TeamManager.KickResult.TargetNotInTeam -> player.sendMsg("team.kick.not_in_your_team", "name" to targetName) is TeamManager.KickResult.CannotKickSelf -> player.sendMsg("team.kick.self") } } private fun handleInfo(player: Player) { val team = plugin.teamManager.getTeam(player) ?: run { player.sendMsg("team.not_in_team"); return } player.sendMsg("team.info.header") team.members.forEachIndexed { i, uuid -> val name = plugin.server.getPlayer(uuid)?.name ?: uuid.toString().take(8) val isLeader = team.isLeader(uuid) player.sendMsg( "team.info.member", "index" to (i + 1).toString(), "name" to name, "leader" to if (isLeader) " ★" else "" ) } player.sendMsg("team.info.footer", "size" to team.size.toString(), "max" to plugin.teamManager.maxTeamSize.toString()) } // ========================================================================= // Tab Completion // ========================================================================= override fun onTabComplete( sender: CommandSender, command: Command, label: String, args: Array ): List { if (sender !is Player) return emptyList() if (args.size == 1) { return listOf("invite", "accept", "deny", "leave", "kick", "info") .filter { it.startsWith(args[0], ignoreCase = true) } } if (args.size == 2) { return when (args[0].lowercase()) { "invite", "accept", "deny", "kick" -> plugin.server.onlinePlayers .filter { it != sender } .map { it.name } .filter { it.startsWith(args[1], ignoreCase = true) } else -> emptyList() } } return emptyList() } }