diff --git a/CHANGELOG.md b/CHANGELOG.md index 93cf7c2a1cb..13a28149219 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 0.5.3 + +## Fixes + +* `getGuildMembers` returns the correct limit for both Cache and Rest suppliers. + # 0.5.2 ## Additions * Add missing mention property for unicode emojis. diff --git a/core/src/main/kotlin/com/gitlab/kordlib/core/behavior/GuildBehavior.kt b/core/src/main/kotlin/com/gitlab/kordlib/core/behavior/GuildBehavior.kt index 51828abd0f6..c102f2a75c5 100644 --- a/core/src/main/kotlin/com/gitlab/kordlib/core/behavior/GuildBehavior.kt +++ b/core/src/main/kotlin/com/gitlab/kordlib/core/behavior/GuildBehavior.kt @@ -100,7 +100,7 @@ interface GuildBehavior : Entity, Strategizable { * [terminal operators](https://kotlinlang.org/docs/reference/coroutines/flow.html#terminal-flow-operators) instead. */ val members: Flow - get() = supplier.getGuildMembers(id, 1000) + get() = supplier.getGuildMembers(id) /** * Requests to get the present voice regions for this guild. diff --git a/core/src/main/kotlin/com/gitlab/kordlib/core/supplier/CacheEntitySupplier.kt b/core/src/main/kotlin/com/gitlab/kordlib/core/supplier/CacheEntitySupplier.kt index ba56bd3d561..636258d7378 100644 --- a/core/src/main/kotlin/com/gitlab/kordlib/core/supplier/CacheEntitySupplier.kt +++ b/core/src/main/kotlin/com/gitlab/kordlib/core/supplier/CacheEntitySupplier.kt @@ -176,11 +176,12 @@ class CacheEntitySupplier(private val kord: Kord) : EntitySupplier { }.asFlow().map { Ban(it, kord) } override fun getGuildMembers(guildId: Snowflake, limit: Int): Flow { + require(limit > 0) { "At least 1 item should be requested, but got $limit." } return kord.cache.query().asFlow().flatMapConcat { userData -> kord.cache.query { MemberData::userId eq userData.id MemberData::guildId eq guildId - }.asFlow().map { Member(it, userData, kord) } + }.asFlow().map { Member(it, userData, kord) }.take(limit) } } diff --git a/core/src/main/kotlin/com/gitlab/kordlib/core/supplier/RestEntitySupplier.kt b/core/src/main/kotlin/com/gitlab/kordlib/core/supplier/RestEntitySupplier.kt index 6d4b3048916..3c8c9b60d5f 100644 --- a/core/src/main/kotlin/com/gitlab/kordlib/core/supplier/RestEntitySupplier.kt +++ b/core/src/main/kotlin/com/gitlab/kordlib/core/supplier/RestEntitySupplier.kt @@ -1,5 +1,6 @@ package com.gitlab.kordlib.core.supplier +import com.gitlab.kordlib.common.entity.DiscordGuildMember import com.gitlab.kordlib.common.entity.DiscordPartialGuild import com.gitlab.kordlib.common.entity.Snowflake import com.gitlab.kordlib.core.Kord @@ -88,8 +89,9 @@ class RestEntitySupplier(val kord: Kord) : EntitySupplier { } override suspend fun getMemberOrNull(guildId: Snowflake, userId: Snowflake): Member? = catchNotFound { - val memberData = guild.getGuildMember(guildId = guildId.value, userId = userId.value).toData(guildId = guildId.value, userId = userId.value) - val userData = user.getUser(userId.value).toData() + val member = guild.getGuildMember(guildId = guildId.value, userId = userId.value) + val memberData = member.toData(guildId = guildId.value, userId = userId.value) + val userData = member.user!!.toData() return Member(memberData, userData, kord) } @@ -158,11 +160,24 @@ class RestEntitySupplier(val kord: Kord) : EntitySupplier { emit(Ban(BanData.from(guildId.value, banData), kord)) } - override fun getGuildMembers(guildId: Snowflake, limit: Int): Flow = flow { - for (memberData in guild.getGuildMembers(guildId.value)) - emit(Member(memberData.toData(memberData.user!!.id, guildId.value), memberData.user!!.toData(), kord)) + override fun getGuildMembers(guildId: Snowflake, limit: Int): Flow { + require(limit > 0) { "At least 1 item should be requested, but got $limit." } + val batchSize = min(1000, limit) + + val flow = paginateForwards(idSelector = { it.user!!.id }, batchSize = batchSize) { position -> + kord.rest.guild.getGuildMembers(guildId = guildId.value, position = position, limit = batchSize) + }.map { + val userData = it.user!!.toData() + val memberData = it.toData(guildId = guildId.value, userId = it.user!!.id) + Member(memberData, userData, kord) + } + + + return if (limit != Int.MAX_VALUE) flow.take(limit) + else flow } + override fun getGuildVoiceRegions(guildId: Snowflake): Flow = flow { for (region in guild.getGuildVoiceRegions(guildId.value)) { val data = RegionData.from(guildId.value, region)