diff --git a/common/src/main/kotlin/entity/Member.kt b/common/src/main/kotlin/entity/Member.kt index 815c7dd71398..ba7f84e7689c 100644 --- a/common/src/main/kotlin/entity/Member.kt +++ b/common/src/main/kotlin/entity/Member.kt @@ -3,6 +3,7 @@ package dev.kord.common.entity import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalBoolean import dev.kord.common.entity.optional.OptionalSnowflake +import kotlinx.datetime.Instant import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @@ -23,6 +24,8 @@ data class DiscordGuildMember( val mute: OptionalBoolean = OptionalBoolean.Missing, val pending: OptionalBoolean = OptionalBoolean.Missing, val avatar: Optional = Optional.Missing(), + @SerialName("communication_disabled_until") + val communicationDisabledUntil: Optional = Optional.Missing() ) @@ -42,6 +45,8 @@ data class DiscordInteractionGuildMember( val permissions: Permissions, val pending: OptionalBoolean = OptionalBoolean.Missing, val avatar: Optional = Optional.Missing(), + @SerialName("communication_disabled_until") + val communicationDisabledUntil: Optional = Optional.Missing() ) @@ -64,6 +69,8 @@ data class DiscordAddedGuildMember( val guildId: Snowflake, val pending: OptionalBoolean = OptionalBoolean.Missing, val avatar: Optional = Optional.Missing(), + @SerialName("communication_disabled_until") + val communicationDisabledUntil: Optional = Optional.Missing() ) @Serializable @@ -86,6 +93,8 @@ data class DiscordUpdatedGuildMember( val premiumSince: Optional = Optional.Missing(), val pending: OptionalBoolean = OptionalBoolean.Missing, val avatar: Optional = Optional.Missing(), + @SerialName("communication_disabled_until") + val communicationDisabledUntil: Optional = Optional.Missing() ) @Serializable @@ -96,4 +105,4 @@ data class DiscordThreadMember( @SerialName("join_timestamp") val joinTimestamp: String, val flags: Int -) \ No newline at end of file +) diff --git a/common/src/main/kotlin/entity/Permission.kt b/common/src/main/kotlin/entity/Permission.kt index 995207814e9f..4ca92c6d76ce 100644 --- a/common/src/main/kotlin/entity/Permission.kt +++ b/common/src/main/kotlin/entity/Permission.kt @@ -160,6 +160,7 @@ sealed class Permission(val code: DiscordBitSet) { object CreatePublicThreads : Permission(0x0800000000) object CreatePrivateThreads : Permission(0x1000000000) object SendMessagesInThreads : Permission(0x4000000000) + object ModerateMembers : Permission(0x0000010000000000) object All : Permission(values.fold(EmptyBitSet()) { acc, value -> acc.add(value.code); acc }) companion object { @@ -200,7 +201,8 @@ sealed class Permission(val code: DiscordBitSet) { ManageThreads, CreatePublicThreads, CreatePrivateThreads, - SendMessagesInThreads + SendMessagesInThreads, + ModerateMembers ) } } diff --git a/core/src/main/kotlin/cache/data/MemberData.kt b/core/src/main/kotlin/cache/data/MemberData.kt index 0f36028b2aee..baf44c5b1d18 100644 --- a/core/src/main/kotlin/cache/data/MemberData.kt +++ b/core/src/main/kotlin/cache/data/MemberData.kt @@ -5,6 +5,7 @@ import dev.kord.cache.api.data.description import dev.kord.common.entity.* import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalBoolean +import kotlinx.datetime.Instant import kotlinx.serialization.Serializable private val MemberData.id get() = "$userId$guildId" @@ -18,28 +19,66 @@ public data class MemberData( val joinedAt: String, val premiumSince: Optional = Optional.Missing(), val pending: OptionalBoolean = OptionalBoolean.Missing, - val avatar: Optional = Optional.Missing() + val avatar: Optional = Optional.Missing(), + val communicationDisabledUntil: Optional = Optional.Missing() ) { public companion object { public val description: DataDescription = description(MemberData::id) public fun from(userId: Snowflake, guildId: Snowflake, entity: DiscordGuildMember): MemberData = with(entity) { - MemberData(userId = userId, guildId = guildId, nick, roles, joinedAt, premiumSince, avatar = avatar) + MemberData( + userId = userId, + guildId = guildId, + nick, + roles, + joinedAt, + premiumSince, + avatar = avatar, + communicationDisabledUntil = communicationDisabledUntil + ) } public fun from(userId: Snowflake, guildId: Snowflake, entity: DiscordInteractionGuildMember): MemberData = with(entity) { - MemberData(userId = userId, guildId = guildId, nick, roles, joinedAt, premiumSince, avatar = avatar) + MemberData( + userId = userId, + guildId = guildId, + nick, + roles, + joinedAt, + premiumSince, + avatar = avatar, + communicationDisabledUntil = communicationDisabledUntil + ) } public fun from(userId: Snowflake, entity: DiscordAddedGuildMember): MemberData = with(entity) { - MemberData(userId = userId, guildId = guildId, nick, roles, joinedAt, premiumSince, avatar = avatar) + MemberData( + userId = userId, + guildId = guildId, + nick, + roles, + joinedAt, + premiumSince, + avatar = avatar, + communicationDisabledUntil = communicationDisabledUntil + ) } public fun from(entity: DiscordUpdatedGuildMember): MemberData = with(entity) { - MemberData(userId = user.id, guildId = guildId, nick, roles, joinedAt, premiumSince, pending, avatar = avatar) + MemberData( + userId = user.id, + guildId = guildId, + nick, + roles, + joinedAt, + premiumSince, + pending, + avatar = avatar, + communicationDisabledUntil + ) } } diff --git a/core/src/main/kotlin/entity/Member.kt b/core/src/main/kotlin/entity/Member.kt index 17bb980f745a..a46273ec5250 100644 --- a/core/src/main/kotlin/entity/Member.kt +++ b/core/src/main/kotlin/entity/Member.kt @@ -85,6 +85,11 @@ public class Member( */ public val isPending: Boolean get() = memberData.pending.discordBoolean + /** + * The [Instant] until the user's timeout expires, or `null` if the user does not have a timeout. + */ + public val communicationDisabledUntil: Instant? get() = memberData.communicationDisabledUntil.value + /** * Whether this member's [id] equals the [Guild.ownerId]. * diff --git a/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt b/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt index 52c9e3f1bda6..d1f0dc457238 100644 --- a/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt +++ b/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt @@ -1,13 +1,14 @@ package dev.kord.rest.builder.member -import dev.kord.rest.builder.AuditRequestBuilder import dev.kord.common.annotation.KordDsl import dev.kord.common.entity.Snowflake import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalBoolean import dev.kord.common.entity.optional.OptionalSnowflake import dev.kord.common.entity.optional.delegate.delegate +import dev.kord.rest.builder.AuditRequestBuilder import dev.kord.rest.json.request.GuildMemberModifyRequest +import kotlinx.datetime.Instant @KordDsl class MemberModifyBuilder : AuditRequestBuilder { @@ -25,6 +26,9 @@ class MemberModifyBuilder : AuditRequestBuilder { private var _nickname: Optional = Optional.Missing() var nickname: String? by ::_nickname.delegate() + private var _communicationDisabledUntil: Optional = Optional.Missing() + var communicationDisabledUntil: Instant? by ::_communicationDisabledUntil.delegate() + private var _roles: Optional?> = Optional.Missing() var roles: MutableSet? by ::_roles.delegate() @@ -33,6 +37,7 @@ class MemberModifyBuilder : AuditRequestBuilder { channelId = _voiceChannelId, mute = _muted, deaf = _deafened, - roles = _roles + roles = _roles, + communicationDisabledUntil = _communicationDisabledUntil ) -} \ No newline at end of file +} diff --git a/rest/src/main/kotlin/json/request/GuildRequests.kt b/rest/src/main/kotlin/json/request/GuildRequests.kt index e3b0042cc44a..d02abf96ac1f 100644 --- a/rest/src/main/kotlin/json/request/GuildRequests.kt +++ b/rest/src/main/kotlin/json/request/GuildRequests.kt @@ -16,6 +16,7 @@ import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalBoolean import dev.kord.common.entity.optional.OptionalInt import dev.kord.common.entity.optional.OptionalSnowflake +import kotlinx.datetime.Instant import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.InternalSerializationApi import kotlinx.serialization.KSerializer @@ -108,6 +109,8 @@ data class GuildMemberAddRequest( val roles: Optional> = Optional.Missing(), val mute: OptionalBoolean = OptionalBoolean.Missing, val deaf: OptionalBoolean = OptionalBoolean.Missing, + @SerialName("communication_disabled_until") + val communicationDisabledUntil: Optional = Optional.Missing() ) @Serializable @@ -118,6 +121,8 @@ data class GuildMemberModifyRequest( val deaf: OptionalBoolean? = OptionalBoolean.Missing, @SerialName("channel_id") val channelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("communication_disabled_until") + val communicationDisabledUntil: Optional = Optional.Missing() )