diff --git a/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/CommonExtensions.kt b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/CommonExtensions.kt new file mode 100644 index 0000000..c4d87ba --- /dev/null +++ b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/CommonExtensions.kt @@ -0,0 +1,8 @@ +package cloud.kubelet.foundation.core + +fun > Collection.sortedBy(order: SortOrder, selector: (T) -> R?): List = + if (order == SortOrder.Ascending) { + sortedBy(selector) + } else { + sortedByDescending(selector) + } diff --git a/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/FoundationCorePlugin.kt b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/FoundationCorePlugin.kt index 6eb1bc3..08d91f1 100644 --- a/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/FoundationCorePlugin.kt +++ b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/FoundationCorePlugin.kt @@ -2,6 +2,7 @@ package cloud.kubelet.foundation.core import cloud.kubelet.foundation.core.command.BackupCommand import cloud.kubelet.foundation.core.command.GamemodeCommand +import cloud.kubelet.foundation.core.command.LeaderboardCommand import net.kyori.adventure.text.Component import org.bukkit.GameMode import org.bukkit.command.CommandExecutor @@ -44,6 +45,7 @@ class FoundationCorePlugin : JavaPlugin(), Listener { registerCommandExecutor(listOf("creative", "c"), GamemodeCommand(GameMode.CREATIVE)) registerCommandExecutor(listOf("adventure", "a"), GamemodeCommand(GameMode.ADVENTURE)) registerCommandExecutor(listOf("spectator", "sp"), GamemodeCommand(GameMode.SPECTATOR)) + registerCommandExecutor(listOf("leaderboard", "lb"), LeaderboardCommand()) val log = slF4JLogger log.info("Features:") diff --git a/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/ServerExtensions.kt b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/ServerExtensions.kt new file mode 100644 index 0000000..7d992c2 --- /dev/null +++ b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/ServerExtensions.kt @@ -0,0 +1,30 @@ +package cloud.kubelet.foundation.core + +import org.bukkit.Material +import org.bukkit.OfflinePlayer +import org.bukkit.Server +import org.bukkit.Statistic +import org.bukkit.entity.EntityType + +val Server.allPlayers: List + get() = listOf(onlinePlayers, offlinePlayers.filter { !isPlayerOnline(it) }.toList()).flatten() + +fun Server.isPlayerOnline(player: OfflinePlayer) = + onlinePlayers.any { onlinePlayer -> onlinePlayer.name == player.name } + +fun Server.allPlayerStatisticsOf( + statistic: Statistic, + material: Material? = null, + entityType: EntityType? = null, + order: SortOrder = SortOrder.Ascending +) = allPlayers + .map { player -> + player to if (material != null) { + player.getStatistic(statistic, material) + } else if (entityType != null) { + player.getStatistic(statistic, entityType) + } else { + player.getStatistic(statistic) + } + } + .sortedBy(order) { it.second } diff --git a/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/SortOrder.kt b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/SortOrder.kt new file mode 100644 index 0000000..8be4619 --- /dev/null +++ b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/SortOrder.kt @@ -0,0 +1,6 @@ +package cloud.kubelet.foundation.core + +enum class SortOrder { + Ascending, + Descending +} diff --git a/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/command/LeaderboardCommand.kt b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/command/LeaderboardCommand.kt new file mode 100644 index 0000000..4d9dc04 --- /dev/null +++ b/foundation-core/src/main/kotlin/cloud/kubelet/foundation/core/command/LeaderboardCommand.kt @@ -0,0 +1,39 @@ +package cloud.kubelet.foundation.core.command + +import cloud.kubelet.foundation.core.SortOrder +import cloud.kubelet.foundation.core.allPlayerStatisticsOf +import org.bukkit.Statistic +import org.bukkit.command.Command +import org.bukkit.command.CommandExecutor +import org.bukkit.command.CommandSender + +class LeaderboardCommand : CommandExecutor { + private val leaderboards = listOf( + LeaderboardType("player-kills", Statistic.PLAYER_KILLS, "Player Kills", "kills"), + LeaderboardType("mob-kills", Statistic.MOB_KILLS, "Mob Kills", "kills"), + LeaderboardType("animals-bred", Statistic.ANIMALS_BRED, "Animals Bred", "animals"), + LeaderboardType("chest-opens", Statistic.CHEST_OPENED, "Chest Opens", "opens") + ) + + override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array): Boolean { + if (args.size != 1) { + sender.sendMessage("Leaderboard type not specified.") + return true + } + + val leaderboardType = leaderboards.firstOrNull { it.id == args[0] } + if (leaderboardType == null) { + sender.sendMessage("Leaderboard type is unknown.") + return true + } + val statistics = sender.server.allPlayerStatisticsOf(leaderboardType.statistic, order = SortOrder.Descending) + val topFivePlayers = statistics.take(5) + sender.sendMessage( + "${leaderboardType.friendlyName} Leaderboard:", + *topFivePlayers.map { "* ${it.first.name}: ${it.second} ${leaderboardType.unit}" }.toTypedArray() + ) + return true + } + + class LeaderboardType(val id: String, val statistic: Statistic, val friendlyName: String, val unit: String) +} diff --git a/foundation-core/src/main/resources/plugin.yml b/foundation-core/src/main/resources/plugin.yml index bd633e3..46c27ee 100644 --- a/foundation-core/src/main/resources/plugin.yml +++ b/foundation-core/src/main/resources/plugin.yml @@ -35,3 +35,9 @@ commands: aliases: - sp permission: foundation.command.spectator + leaderboard: + description: Leaderboard + usage: /leaderboard + aliases: + - lb + permission: foundation.command.leaderboard