Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Stage events #421

Merged
merged 12 commits into from
Nov 25, 2021
57 changes: 51 additions & 6 deletions common/src/main/kotlin/entity/AuditLog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,25 @@ package dev.kord.common.entity
import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalSnowflake
import dev.kord.common.entity.optional.orEmpty
import kotlinx.serialization.*
import kotlinx.serialization.Contextual
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.SerializationException
import kotlinx.serialization.builtins.serializer
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
import kotlinx.serialization.descriptors.element
import kotlinx.serialization.encoding.CompositeDecoder
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.encoding.decodeStructure
import kotlinx.serialization.encoding.encodeStructure
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.serializer
import dev.kord.common.Color as CommonColor
import dev.kord.common.entity.DefaultMessageNotificationLevel as CommonDefaultMessageNotificationLevel
import dev.kord.common.entity.ExplicitContentFilter as CommonExplicitContentFilter
Expand Down Expand Up @@ -92,7 +105,7 @@ data class AuditLogEntryOptionalInfo(
2020-11-12 field is described as present but is in fact optional
*/
@SerialName("role_name")
val roleName: Optional<String> = Optional.Missing(),
val roleName: Optional<String> = Optional.Missing()
)

@Serializable(with = AuditLogChange.Serializer::class)
Expand Down Expand Up @@ -263,6 +276,9 @@ sealed class AuditLogChangeKey<T>(val name: String, val serializer: KSerializer<
@SerialName("inviter_id")
object InviterId : AuditLogChangeKey<Snowflake>("inviter_id", serializer())

@SerialName("location")
object Location : AuditLogChangeKey<String>("location", serializer())

@SerialName("max_uses")
object MaxUses : AuditLogChangeKey<Int>("max_uses", serializer())

Expand Down Expand Up @@ -315,7 +331,26 @@ sealed class AuditLogChangeKey<T>(val name: String, val serializer: KSerializer<
object AutoArchiveDuration : AuditLogChangeKey<ArchiveDuration>("auto_archive_duration", serializer())

@SerialName("default_auto_archive_duration")
object DefaultAutoArchiveDuration : AuditLogChangeKey<ArchiveDuration>("default_auto_archive_duration", serializer())
object DefaultAutoArchiveDuration :
AuditLogChangeKey<ArchiveDuration>("default_auto_archive_duration", serializer())

@SerialName("entity_type")
object EntityType : AuditLogChangeKey<ScheduledEntityType>(
"entity_type",
serializer()
)

@SerialName("status")
object Status : AuditLogChangeKey<GuildScheduledEventStatus>(
"status",
serializer()
)

@SerialName("sku_ids")
object SkuIds : AuditLogChangeKey<List<Snowflake>>(
"sku_ids",
serializer()
)

internal class Serializer<T>(val type: KSerializer<T>) : KSerializer<AuditLogChangeKey<T>> {
override val descriptor: SerialDescriptor
Expand Down Expand Up @@ -363,6 +398,7 @@ sealed class AuditLogChangeKey<T>(val name: String, val serializer: KSerializer<
"code" -> Code
"channel_id" -> ChannelId
"inviter_id" -> InviterId
"location" -> Location
"max_uses" -> MaxUses
"uses" -> Uses
"max_age" -> MaxAges
Expand All @@ -381,6 +417,9 @@ sealed class AuditLogChangeKey<T>(val name: String, val serializer: KSerializer<
"archived" -> Archived
"auto_archive_duration" -> AutoArchiveDuration
"default_auto_archive_duration" -> DefaultAutoArchiveDuration
"entity_type" -> EntityType
"status" -> Status
"sku_ids" -> SkuIds
else -> Unknown(name)
} as AuditLogChangeKey<T>
}
Expand Down Expand Up @@ -431,6 +470,9 @@ sealed class AuditLogEvent(val value: Int) {
object StickerCreate : AuditLogEvent(90)
object StickerUpdate : AuditLogEvent(91)
object StickerDelete : AuditLogEvent(92)
object GuildScheduledEventCreate : AuditLogEvent(100)
object GuildScheduledEventUpdate : AuditLogEvent(101)
object GuildScheduledEventDelete : AuditLogEvent(102)
object ThreadCreate : AuditLogEvent(110)
object ThreadUpdate : AuditLogEvent(111)
object ThreadDelete : AuditLogEvent(112)
Expand Down Expand Up @@ -486,11 +528,14 @@ sealed class AuditLogEvent(val value: Int) {
90 -> StickerCreate
91 -> StickerUpdate
92 -> StickerDelete
100 -> GuildScheduledEventCreate
101 -> GuildScheduledEventUpdate
102 -> GuildScheduledEventDelete
110 -> ThreadCreate
111 -> ThreadUpdate
112 -> ThreadDelete
else -> Unknown(value)
}
}

}
}
2 changes: 1 addition & 1 deletion common/src/main/kotlin/entity/DiscordGuild.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ data class DiscordUnavailableGuild(
)

/**
* A representation of a [Discord Guild structure](https://discord.com/developers/docs/resources/guild#guild-object
* A representation of a [Discord Guild structure](https://discord.com/developers/docs/resources/guild#guild-object)
*
* @param id The guild id.
* @param name The guild name (2-100 characters, excluding trailing and leading whitespace)
Expand Down
124 changes: 124 additions & 0 deletions common/src/main/kotlin/entity/DiscordGuildScheduledEvent.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
package dev.kord.common.entity

import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalSnowflake
import kotlinx.datetime.Instant
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder

/**
* Representation of a [Guild Scheduled Event Structure](ADD LINK).
*
* @property id the id of the event
* @property guildId the id of the guild the event is on
* @property channelId the id of the channel the event is in
* @property creatorId the id of the user that created the scheduled event
* @property name the name of the event
* @property description the description of the event
* @property scheduledStartTime the [Instant] in which the event will start
* @property scheduledEndTime the [Instant] in which the event wil stop, if any
* @property privacyLevel the [event privacy level][StageInstancePrivacyLevel]
* @property status the [event status][GuildScheduledEventStatus]
* @property entityType the [ScheduledEntityType] of the event
* @property entityId entity id
* @property entityMetadata [metadata][GuildScheduledEventEntityMetadata] for the event
* @property creator the [user][DiscordUser] that created the scheduled event
* @property userCount users subscribed to the event
*/
@Serializable
data class DiscordGuildScheduledEvent(
val id: Snowflake,
@SerialName("guild_id")
val guildId: Snowflake,
val channelId: Snowflake?,
@SerialName("creator_id")
val creatorId: OptionalSnowflake,
val name: String,
val description: Optional<String> = Optional.Missing(),
@SerialName("scheduled_start_time")
val scheduledStartTime: Instant,
@SerialName("scheduled_end_time")
val scheduledEndTime: Instant?,
@SerialName("privacy_level")
val privacyLevel: StageInstancePrivacyLevel,
val status: GuildScheduledEventStatus,
@SerialName("entity_type")
val entityType: ScheduledEntityType,
@SerialName("entity_id")
val entityId: Snowflake?,
@SerialName("entity_metadata")
val entityMetadata: GuildScheduledEventEntityMetadata,
val creator: Optional<DiscordUser>,
@SerialName("user_count")
val userCount: Int
)

@Serializable(with = ScheduledEntityType.Serializer::class)
sealed class ScheduledEntityType(val value: Int) {
object None : ScheduledEntityType(0)
object StageInstance : ScheduledEntityType(1)
object Voice : ScheduledEntityType(2)
object External : ScheduledEntityType(3)
class Unknown(value: Int) : ScheduledEntityType(value)

companion object Serializer : KSerializer<ScheduledEntityType> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("ScheduledEntityType", PrimitiveKind.INT)

override fun deserialize(decoder: Decoder): ScheduledEntityType {
return when (val value = decoder.decodeInt()) {
0 -> None
1 -> StageInstance
2 -> Voice
3 -> External
else -> Unknown(value)
}
}

override fun serialize(encoder: Encoder, value: ScheduledEntityType) = encoder.encodeInt(value.value)

}
}

@Serializable(with = GuildScheduledEventStatus.Serializer::class)
sealed class GuildScheduledEventStatus(val value: Int) {
object Scheduled : GuildScheduledEventStatus(1)
object Active : GuildScheduledEventStatus(2)
object Completed : GuildScheduledEventStatus(3)
object Cancelled : GuildScheduledEventStatus(4)
class Unknown(value: Int) : GuildScheduledEventStatus(value)

companion object Serializer : KSerializer<GuildScheduledEventStatus> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("GuildScheduledEventStatus", PrimitiveKind.INT)

override fun deserialize(decoder: Decoder): GuildScheduledEventStatus {
return when (val value = decoder.decodeInt()) {
1 -> Scheduled
2 -> Active
3 -> Completed
4 -> Cancelled
else -> Unknown(value)
}
}

override fun serialize(encoder: Encoder, value: GuildScheduledEventStatus) = encoder.encodeInt(value.value)

}
}

/**
* Entity metadata for [DiscordGuildScheduledEvent].
*
* @property speakerIds the speakers of the stage channel
* @property location location of the event
*/
@Serializable
data class GuildScheduledEventEntityMetadata(
val speakerIds: Optional<List<Snowflake>> = Optional.Missing(),
val location: Optional<String> = Optional.Missing()
)
9 changes: 8 additions & 1 deletion common/src/main/kotlin/entity/DiscordInvite.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dev.kord.common.entity

import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalInt
import kotlinx.datetime.Instant
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable

Expand All @@ -19,6 +20,12 @@ data class DiscordInvite(
val approximatePresenceCount: OptionalInt = OptionalInt.Missing,
@SerialName("approximate_member_count")
val approximateMemberCount: OptionalInt = OptionalInt.Missing,
@SerialName("expires_at")
val expiresAt: Optional<Instant?> = Optional.Missing(),
@SerialName("stage_instance")
val stageInstance: Optional<DiscordStageInstance> = Optional.Missing(),
@SerialName("guild_scheduled_event")
val guildScheduledEvent: Optional<DiscordGuildScheduledEvent> = Optional.Missing(),
)

@Serializable
Expand All @@ -42,4 +49,4 @@ data class DiscordInviteMetadata(
val temporary: Boolean,
@SerialName("created_at")
val createdAt: String,
)
)
50 changes: 49 additions & 1 deletion common/src/main/kotlin/entity/DiscordStageInstance.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
package dev.kord.common.entity

import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder


/**
Expand All @@ -11,6 +17,8 @@ import kotlinx.serialization.Serializable
* @property guildId The guild id of the associated Stage channel
* @property channelId The id of the associated Stage channel
* @property topic The topic of the Stage instance (1-120 characters)
* @property privacyLevel The [privacy level][StageInstancePrivacyLevel] of the Stage instance
* @property discoverableDisabled Whether or not Stage Discovery is disabled
*/
@Serializable
data class DiscordStageInstance(
Expand All @@ -19,5 +27,45 @@ data class DiscordStageInstance(
val guildId: Snowflake,
@SerialName("channel_id")
val channelId: Snowflake,
val topic: String
val topic: String,
@SerialName("privacy_level")
val privacyLevel: StageInstancePrivacyLevel,
@SerialName("discoverable_disabled")
val discoverableDisabled: Boolean
)

/**
* Privacy level of a [DiscordStageInstance].
*/
@Serializable(with = StageInstancePrivacyLevel.Serializer::class)
sealed class StageInstancePrivacyLevel(val value: Int) {
/**
* The Stage instance is visible publicly, such as on Stage Discovery.
*/
object Public : StageInstancePrivacyLevel(1)

/**
* The Stage instance is visible to only guild members.
*/
object GuildOnly : StageInstancePrivacyLevel(2)

/**
* An unknown privacy level.
*/
class Unknown(value: Int) : StageInstancePrivacyLevel(value)

companion object Serializer : KSerializer<StageInstancePrivacyLevel> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("StageInstancePrivacyLevel", PrimitiveKind.INT)

override fun deserialize(decoder: Decoder): StageInstancePrivacyLevel {
return when (val value = decoder.decodeInt()) {
1 -> Public
2 -> GuildOnly
else -> Unknown(value)
}
}

override fun serialize(encoder: Encoder, value: StageInstancePrivacyLevel) = encoder.encodeInt(value.value)

}
}
6 changes: 5 additions & 1 deletion common/src/main/kotlin/entity/DiscordUser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dev.kord.common.entity

import dev.kord.common.entity.optional.Optional
import dev.kord.common.entity.optional.OptionalBoolean
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.KSerializer
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
Expand All @@ -10,6 +11,7 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
import kotlinx.serialization.descriptors.SerialDescriptor
import kotlinx.serialization.encoding.Decoder
import kotlinx.serialization.encoding.Encoder
import kotlinx.serialization.json.JsonNames
import kotlin.contracts.ExperimentalContracts
import kotlin.contracts.InvocationKind
import kotlin.contracts.contract
Expand Down Expand Up @@ -72,6 +74,7 @@ data class DiscordUser(
* @param premiumType The type of Nitro subscription on a user's account.
* @param publicFlags The public flags on a user's account. Unlike [flags], these **are** visible ot other users.
*/
@OptIn(ExperimentalSerializationApi::class)
@Serializable
data class DiscordOptionallyMemberUser(
val id: Snowflake,
Expand All @@ -90,6 +93,7 @@ data class DiscordOptionallyMemberUser(
val premiumType: Optional<UserPremium> = Optional.Missing(),
@SerialName("public_flags")
val publicFlags: Optional<UserFlags> = Optional.Missing(),
@JsonNames("member", "guild_member")
val member: Optional<DiscordGuildMember> = Optional.Missing(),
)

Expand Down Expand Up @@ -207,4 +211,4 @@ sealed class UserPremium(val value: Int) {
encoder.encodeInt(value.value)
}
}
}
}
Loading