diff --git a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/player/playtime/Playtime.kt b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/player/playtime/Playtime.kt index c0596c0c..0c318854 100644 --- a/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/player/playtime/Playtime.kt +++ b/surf-cloud-api/surf-cloud-api-common/src/main/kotlin/dev/slne/surf/cloud/api/common/player/playtime/Playtime.kt @@ -88,7 +88,7 @@ interface Playtime { * @param since Optional start time to filter playtime. * @return An [Object2ObjectMap] where keys are server names and values are durations. */ - fun playtimesPerServer(since: ZonedDateTime? = null): Object2ObjectMap + fun playtimesPerServer(since: ZonedDateTime? = null, sortByPlaytime: Boolean = true): Object2ObjectMap /** * Returns a mapping of categories to their respective total playtime durations. @@ -96,9 +96,9 @@ interface Playtime { * @param since Optional start time to filter playtime. * @return An [Object2ObjectMap] where keys are category names and values are durations. */ - fun playtimesPerCategory(since: ZonedDateTime? = null): Object2ObjectMap + fun playtimesPerCategory(since: ZonedDateTime? = null, sortByPlaytime: Boolean = true): Object2ObjectMap - fun playtimePerCategoryPerServer(since: ZonedDateTime? = null): Object2ObjectMap> + fun playtimePerCategoryPerServer(since: ZonedDateTime? = null, sortByPlaytime: Boolean = true): Object2ObjectMap> /** * Returns the average playtime per server, optionally filtered by category and start time. diff --git a/surf-cloud-bukkit/src/main/kotlin/dev/slne/surf/cloud/bukkit/command/playtime/PlaytimeCommand.kt b/surf-cloud-bukkit/src/main/kotlin/dev/slne/surf/cloud/bukkit/command/playtime/PlaytimeCommand.kt index b4eb15e9..8562f1b0 100644 --- a/surf-cloud-bukkit/src/main/kotlin/dev/slne/surf/cloud/bukkit/command/playtime/PlaytimeCommand.kt +++ b/surf-cloud-bukkit/src/main/kotlin/dev/slne/surf/cloud/bukkit/command/playtime/PlaytimeCommand.kt @@ -39,7 +39,7 @@ private fun sendPlaytime(sender: CommandSender, player: OfflineCloudPlayer) = pl variableValue("${player.name()} (${player.uuid})") appendNewPrefixedLine() appendNewPrefixedLine { - variableKey("Total") + variableKey("Gesamt") spacer(": ") variableValue(complete.toString()) } diff --git a/surf-cloud-core/surf-cloud-core-common/src/main/kotlin/dev/slne/surf/cloud/core/common/player/playtime/PlaytimeImpl.kt b/surf-cloud-core/surf-cloud-core-common/src/main/kotlin/dev/slne/surf/cloud/core/common/player/playtime/PlaytimeImpl.kt index f8e4ae2a..3e0028e8 100644 --- a/surf-cloud-core/surf-cloud-core-common/src/main/kotlin/dev/slne/surf/cloud/core/common/player/playtime/PlaytimeImpl.kt +++ b/surf-cloud-core/surf-cloud-core-common/src/main/kotlin/dev/slne/surf/cloud/core/common/player/playtime/PlaytimeImpl.kt @@ -61,30 +61,83 @@ class PlaytimeImpl(private val entries: ObjectList) : Playtime { .sumOf { it.durationSeconds } .seconds - override fun playtimesPerServer(since: ZonedDateTime?): Object2ObjectMap = - entries.filter { since == null || it.createdAt.isAfter(since) } + override fun playtimesPerServer( + since: ZonedDateTime?, + sortByPlaytime: Boolean + ): Object2ObjectMap { + val result = entries + .filter { since == null || it.createdAt.isAfter(since) } .groupBy { it.server } .mapValuesTo(mutableObject2ObjectMapOf()) { (_, group) -> group.sumOf { it.durationSeconds }.seconds } - override fun playtimesPerCategory(since: ZonedDateTime?): Object2ObjectMap = - entries.filter { since == null || it.createdAt.isAfter(since) } + return if (sortByPlaytime) { + result.entries + .sortedByDescending { it.value } + .associateTo(mutableObject2ObjectMapOf()) { it.toPair() } + } else result + } + + + override fun playtimesPerCategory( + since: ZonedDateTime?, + sortByPlaytime: Boolean + ): Object2ObjectMap { + val result = entries + .filter { since == null || it.createdAt.isAfter(since) } .groupBy { it.category } .mapValuesTo(mutableObject2ObjectMapOf()) { (_, group) -> group.sumOf { it.durationSeconds }.seconds } - override fun playtimePerCategoryPerServer(since: ZonedDateTime?): Object2ObjectMap> = - entries.filter { since == null || it.createdAt.isAfter(since) } - .groupBy { it.category } - .mapValuesTo(mutableObject2ObjectMapOf()) { (_, groupEntries) -> - groupEntries.groupBy { it.server } - .mapValuesTo(mutableObject2ObjectMapOf()) { (_, serverEntries) -> - serverEntries.sumOf { it.durationSeconds }.seconds - } + return if (sortByPlaytime) { + result.entries + .sortedByDescending { it.value } + .associateTo(mutableObject2ObjectMapOf()) { it.toPair() } + } else result + } + + + override fun playtimePerCategoryPerServer( + since: ZonedDateTime?, + sortByPlaytime: Boolean + ): Object2ObjectMap> { + val filtered = entries + .filter { since == null || it.createdAt.isAfter(since) } + + val grouped = filtered.groupBy { it.category } + .mapValues { (_, entriesByCategory) -> + val serverDurations = entriesByCategory + .groupingBy { it.server } + .fold(0L) { acc, e -> acc + e.durationSeconds } + .mapValues { it.value.seconds } + + val sorted = if (sortByPlaytime) + serverDurations.entries.sortedByDescending { it.value } + else serverDurations.entries + + mutableObject2ObjectMapOf().apply { + sorted.forEach { (k, v) -> this[k] = v } + } } + val categorySums = grouped.mapValues { (_, serverDurations) -> + serverDurations.values.sumOf { it.inWholeSeconds } + } + + val finalResult = if (sortByPlaytime) + grouped.entries.sortedByDescending { categorySums[it.key] } + else grouped.entries + + return mutableObject2ObjectMapOf>().apply { + finalResult.forEach { (k, v) -> this[k] = v } + } + } + + + + override fun averagePlaytimePerServer( category: String?,