From 5d1c4003a5679e3ec392770dc3f85b6ff15c1d6d Mon Sep 17 00:00:00 2001 From: Hope Date: Wed, 17 Aug 2022 17:59:47 +0300 Subject: [PATCH 1/2] Consider Unavailable Guild Create Events --- common/src/main/kotlin/entity/DiscordGuild.kt | 70 ++++++++--- common/src/test/kotlin/json/GuildTest.kt | 9 +- core/src/main/kotlin/cache/data/GuildData.kt | 56 ++++++++- .../kotlin/cache/data/PartialGuildData.kt | 118 ++++++++++++++---- core/src/main/kotlin/entity/Guild.kt | 12 -- core/src/main/kotlin/entity/PartialGuild.kt | 10 +- .../kotlin/event/guild/GuildCreateEvent.kt | 1 + .../guild/UnavailableGuildCreateEvent.kt | 14 +++ .../gateway/handler/GuildEventHandler.kt | 41 +++++- core/src/test/kotlin/live/LiveGuildTest.kt | 29 +++-- .../kotlin/performance/KordEventDropTest.kt | 32 ++--- gateway/src/main/kotlin/Event.kt | 4 +- 12 files changed, 290 insertions(+), 106 deletions(-) create mode 100644 core/src/main/kotlin/event/guild/UnavailableGuildCreateEvent.kt diff --git a/common/src/main/kotlin/entity/DiscordGuild.kt b/common/src/main/kotlin/entity/DiscordGuild.kt index dec49a83fba..c2d2a4f6c84 100644 --- a/common/src/main/kotlin/entity/DiscordGuild.kt +++ b/common/src/main/kotlin/entity/DiscordGuild.kt @@ -153,28 +153,60 @@ public data class DiscordGuild( */ @Serializable public data class DiscordPartialGuild( - val id: Snowflake, - val name: String, - val icon: String?, - val owner: OptionalBoolean = OptionalBoolean.Missing, - val permissions: Optional = Optional.Missing(), - val features: List, - @SerialName("welcome_screen") val welcomeScreen: Optional = Optional.Missing(), - @SerialName("vanity_url_code") val vanityUrlCode: Optional = Optional.Missing(), - val description: Optional = Optional.Missing(), - val banner: Optional = Optional.Missing(), - val splash: Optional = Optional.Missing(), - @SerialName("nsfw_level") val nsfwLevel: Optional = Optional.Missing(), - @SerialName("verification_level") - val verificationLevel: Optional = Optional.Missing(), + public val id: Snowflake, + public val name: Optional = Optional.Missing(), + public val icon: Optional? = Optional.Missing(), + @SerialName("icon_hash") public val iconHash: Optional = Optional.Missing(), + public val splash: Optional = Optional.Missing(), + @SerialName("discovery_splash") public val discoverySplash: Optional = Optional.Missing(), + public val owner: OptionalBoolean = OptionalBoolean.Missing, + @SerialName("owner_id") public val ownerId: OptionalSnowflake = OptionalSnowflake.Missing, + public val permissions: Optional = Optional.Missing(), + @SerialName("afk_channel_id") public val afkChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("afk_timeout") public val afkTimeout: Optional = Optional.Missing(), + @SerialName("widget_enabled") public val widgetEnabled: OptionalBoolean = OptionalBoolean.Missing, + @SerialName("widget_channel_id") public val widgetChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("verification_level") public val verificationLevel: Optional = Optional.Missing(), + @SerialName("default_message_notifications") public val defaultMessageNotifications: Optional = Optional.Missing(), + @SerialName("explicit_content_filter") public val explicitContentFilter: Optional = Optional.Missing(), + public val roles: List = emptyList(), + public val emojis: List = emptyList(), + public val features: List = emptyList(), + @SerialName("mfa_level") public val mfaLevel: Optional = Optional.Missing(), + @SerialName("application_id") public val applicationId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("system_channel_id") public val systemChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("system_channel_flags") public val systemChannelFlags: Optional = Optional.Missing(), + @SerialName("rules_channel_id") public val rulesChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("joined_at") public val joinedAt: Optional = Optional.Missing(), + public val large: OptionalBoolean = OptionalBoolean.Missing, + public val unavailable: OptionalBoolean = OptionalBoolean.Missing, + @SerialName("member_count") public val memberCount: OptionalInt = OptionalInt.Missing, + @SerialName("voice_states") public val voiceStates: Optional> = Optional.Missing(), + public val members: Optional> = Optional.Missing(), + public val channels: Optional> = Optional.Missing(), + public val threads: Optional> = Optional.Missing(), + public val presences: Optional> = Optional.Missing(), + @SerialName("max_presences") public val maxPresences: OptionalInt? = OptionalInt.Missing, + @SerialName("max_members") public val maxMembers: OptionalInt = OptionalInt.Missing, + @SerialName("vanity_url_code") public val vanityUrlCode: Optional? = Optional.Missing(), + public val description: Optional? = Optional.Missing(), + public val banner: Optional? = Optional.Missing(), + @SerialName("premium_tier") public val premiumTier: Optional = Optional.Missing(), + @SerialName("premium_subscription_count") public val premiumSubscriptionCount: OptionalInt = OptionalInt.Missing, + @SerialName("preferred_locale") public val preferredLocale: Optional = Optional.Missing(), + @SerialName("public_updates_channel_id") public val publicUpdatesChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("max_video_channel_users") public val maxVideoChannelUsers: OptionalInt = OptionalInt.Missing, + @SerialName("approximate_member_count") public val approximateMemberCount: OptionalInt = OptionalInt.Missing, + @SerialName("approximate_presence_count") public val approximatePresenceCount: OptionalInt = OptionalInt.Missing, + @SerialName("welcome_screen") public val welcomeScreen: Optional = Optional.Missing(), + @SerialName("nsfw_level") public val nsfwLevel: Optional = Optional.Missing(), @SerialName("stage_instances") - val stageInstances: Optional> = Optional.Missing(), - val stickers: Optional> = Optional.Missing(), + public val stageInstances: Optional> = Optional.Missing(), + public val stickers: Optional> = Optional.Missing(), @SerialName("guild_scheduled_events") - val guildScheduledEvents: Optional> = Optional.Missing(), + public val guildScheduledEvents: Optional> = Optional.Missing(), @SerialName("premium_progress_bar_enabled") - val premiumProgressBarEnabled: OptionalBoolean = OptionalBoolean.Missing - + public val premiumProgressBarEnabled: OptionalBoolean = OptionalBoolean.Missing ) /** diff --git a/common/src/test/kotlin/json/GuildTest.kt b/common/src/test/kotlin/json/GuildTest.kt index f047b82ff18..2e018a1fa70 100644 --- a/common/src/test/kotlin/json/GuildTest.kt +++ b/common/src/test/kotlin/json/GuildTest.kt @@ -1,6 +1,7 @@ package json import dev.kord.common.entity.* +import dev.kord.common.entity.optional.value import kotlinx.datetime.Instant import kotlinx.serialization.json.Json import org.junit.jupiter.api.Test @@ -94,10 +95,10 @@ class GuildTest { with(guild) { id shouldBe "80351110224678912" - name shouldBe "1337 Krew" - icon shouldBe "8342729096ea3675442027381ff50dfe" - owner shouldBe true - permissions shouldBe Permissions("36953089") + name.value shouldBe "1337 Krew" + icon?.value shouldBe "8342729096ea3675442027381ff50dfe" + owner.value shouldBe true + permissions.value shouldBe Permissions("36953089") features shouldBe listOf(GuildFeature.Community, GuildFeature.News) } } diff --git a/core/src/main/kotlin/cache/data/GuildData.kt b/core/src/main/kotlin/cache/data/GuildData.kt index a9c71d2e8cc..29cb6c24a3c 100644 --- a/core/src/main/kotlin/cache/data/GuildData.kt +++ b/core/src/main/kotlin/cache/data/GuildData.kt @@ -23,8 +23,6 @@ public data class GuildData( //val owner: OptionalBoolean = OptionalBoolean.Missing, useless? val ownerId: Snowflake, val permissions: Optional = Optional.Missing(), - @Deprecated("The region field has been moved to Channel#rtcRegion in Discord API v9", ReplaceWith("ChannelData#rtcRegion")) - val region: String, val afkChannelId: Snowflake? = null, val afkTimeout: DurationInSeconds, val widgetEnabled: OptionalBoolean = OptionalBoolean.Missing, @@ -90,7 +88,6 @@ public data class GuildData( //owner = owner, ownerId = ownerId, permissions = permissions, - region = @Suppress("DEPRECATION") region, afkChannelId = afkChannelId, afkTimeout = afkTimeout, widgetEnabled = widgetEnabled, @@ -133,7 +130,58 @@ public data class GuildData( premiumProgressBarEnabled = premiumProgressBarEnabled ) } + + public fun from(entity: DiscordPartialGuild): GuildData = with(entity) { + return GuildData( + id = id, + name = name.value!!, + icon = icon?.value!!, + iconHash = iconHash, + splash = splash, + discoverySplash = discoverySplash, + //owner = owner, + ownerId = ownerId.value!!, + permissions = permissions, + afkChannelId = afkChannelId.value, + afkTimeout = afkTimeout.value!!, + widgetEnabled = widgetEnabled, + widgetChannelId = widgetChannelId, + verificationLevel = verificationLevel.value!!, + defaultMessageNotifications = defaultMessageNotifications.value!!, + explicitContentFilter = explicitContentFilter.value!!, + roles = roles.orEmpty().map { it.id }, + emojis = emojis.orEmpty().map { it.id!! }, + features = features.orEmpty(), + mfaLevel = mfaLevel.value!!, + applicationId = applicationId.value, + systemChannelId = systemChannelId.value, + systemChannelFlags = systemChannelFlags.value!!, + rulesChannelId = rulesChannelId.value, + joinedAt = joinedAt, + large = large, + memberCount = memberCount, + channels = channels.mapList { it.id }, + maxPresences = maxPresences, + maxMembers = maxMembers, + vanityUrlCode = vanityUrlCode?.value, + description = description?.value, + banner = banner?.value, + premiumTier = premiumTier.value!!, + premiumSubscriptionCount = premiumSubscriptionCount, + preferredLocale = preferredLocale.value!!, + publicUpdatesChannelId = publicUpdatesChannelId.value, + maxVideoChannelUsers = maxVideoChannelUsers, + approximateMemberCount = approximateMemberCount, + approximatePresenceCount = approximatePresenceCount, + welcomeScreen = welcomeScreen.map { WelcomeScreenData.from(it) }, + nsfwLevel = nsfwLevel.value!!, + threads = threads.mapList { it.toData() }, + stageInstances = stageInstances.mapList { StageInstanceData.from(it) }, + stickers = stickers.mapList { StickerData.from(it) }, + guildScheduledEvents = guildScheduledEvents.mapList { GuildScheduledEventData.from(it) }, + premiumProgressBarEnabled = premiumProgressBarEnabled.value!! + ) + } } } - public fun DiscordGuild.toData(): GuildData = GuildData.from(this) diff --git a/core/src/main/kotlin/cache/data/PartialGuildData.kt b/core/src/main/kotlin/cache/data/PartialGuildData.kt index 092edd8acf9..01e42398699 100644 --- a/core/src/main/kotlin/cache/data/PartialGuildData.kt +++ b/core/src/main/kotlin/cache/data/PartialGuildData.kt @@ -1,51 +1,115 @@ package dev.kord.core.cache.data import dev.kord.common.entity.* -import dev.kord.common.entity.optional.Optional -import dev.kord.common.entity.optional.OptionalBoolean -import dev.kord.common.entity.optional.map -import dev.kord.common.entity.optional.mapList +import dev.kord.common.entity.optional.* +import dev.kord.common.serialization.DurationInSeconds +import kotlinx.datetime.Instant import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable public class PartialGuildData( public val id: Snowflake, - public val name: String, - public val icon: String? = null, + public val name: Optional = Optional.Missing(), + public val icon: Optional? = Optional.Missing(), + @SerialName("icon_hash") public val iconHash: Optional = Optional.Missing(), + public val splash: Optional = Optional.Missing(), + @SerialName("discovery_splash") public val discoverySplash: Optional = Optional.Missing(), public val owner: OptionalBoolean = OptionalBoolean.Missing, + @SerialName("owner_id") public val ownerId: OptionalSnowflake, public val permissions: Optional = Optional.Missing(), - public val features: List, - public val welcomeScreen: Optional = Optional.Missing(), - @SerialName("vanity_url_code") public val vanityUrlCode: Optional = Optional.Missing(), - public val description: Optional = Optional.Missing(), - public val banner: Optional = Optional.Missing(), - public val splash: Optional = Optional.Missing(), + @SerialName("afk_channel_id") public val afkChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("afk_timeout") public val afkTimeout: Optional = Optional.Missing(), + @SerialName("widget_enabled") public val widgetEnabled: OptionalBoolean = OptionalBoolean.Missing, + @SerialName("widget_channel_id") public val widgetChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("verification_level") public val verificationLevel: Optional = Optional.Missing(), + @SerialName("default_message_notifications") public val defaultMessageNotifications: Optional = Optional.Missing(), + @SerialName("explicit_content_filter") public val explicitContentFilter: Optional = Optional.Missing(), + public val roles: List = emptyList(), + public val emojis: List = emptyList(), + public val features: List = emptyList(), + @SerialName("mfa_level") public val mfaLevel: Optional = Optional.Missing(), + @SerialName("application_id") public val applicationId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("system_channel_id") public val systemChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("system_channel_flags") public val systemChannelFlags: Optional = Optional.Missing(), + @SerialName("rules_channel_id") public val rulesChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("joined_at") public val joinedAt: Optional = Optional.Missing(), + public val large: OptionalBoolean = OptionalBoolean.Missing, + @SerialName("member_count") public val memberCount: OptionalInt = OptionalInt.Missing, + @SerialName("voice_states") public val voiceStates: Optional> = Optional.Missing(), + public val members: Optional> = Optional.Missing(), + public val channels: Optional> = Optional.Missing(), + public val threads: Optional> = Optional.Missing(), + public val presences: Optional> = Optional.Missing(), + @SerialName("max_presences") public val maxPresences: OptionalInt? = OptionalInt.Missing, + @SerialName("max_members") public val maxMembers: OptionalInt = OptionalInt.Missing, + @SerialName("vanity_url_code") public val vanityUrlCode: Optional? = Optional.Missing(), + public val description: Optional? = Optional.Missing(), + public val banner: Optional? = Optional.Missing(), + @SerialName("premium_tier") public val premiumTier: Optional = Optional.Missing(), + @SerialName("premium_subscription_count") public val premiumSubscriptionCount: OptionalInt = OptionalInt.Missing, + @SerialName("preferred_locale") public val preferredLocale: Optional = Optional.Missing(), + @SerialName("public_updates_channel_id") public val publicUpdatesChannelId: OptionalSnowflake? = OptionalSnowflake.Missing, + @SerialName("max_video_channel_users") public val maxVideoChannelUsers: OptionalInt = OptionalInt.Missing, + @SerialName("approximate_member_count") public val approximateMemberCount: OptionalInt = OptionalInt.Missing, + @SerialName("approximate_presence_count") public val approximatePresenceCount: OptionalInt = OptionalInt.Missing, + @SerialName("welcome_screen") public val welcomeScreen: Optional = Optional.Missing(), @SerialName("nsfw_level") public val nsfwLevel: Optional = Optional.Missing(), - @SerialName("verification_level") - public val verificationLevel: Optional = Optional.Missing(), + @SerialName("stage_instances") public val stageInstances: Optional> = Optional.Missing(), public val stickers: Optional> = Optional.Missing(), + @SerialName("guild_scheduled_events") public val guildScheduledEvents: Optional> = Optional.Missing(), + @SerialName("premium_progress_bar_enabled") public val premiumProgressBarEnabled: OptionalBoolean = OptionalBoolean.Missing ) { public companion object { public fun from(partialGuild: DiscordPartialGuild): PartialGuildData = with(partialGuild) { PartialGuildData( - id, - name, - icon, - owner, - permissions, - features, - welcomeScreen.map { WelcomeScreenData.from(it) }, - vanityUrlCode, - description, - banner, - splash, - nsfwLevel, - verificationLevel, + id = id, + name = name, + icon = icon, + iconHash = iconHash, + splash = splash, + discoverySplash = discoverySplash, + //owner = owner, + ownerId = ownerId, + permissions = permissions, + afkChannelId = afkChannelId, + afkTimeout = afkTimeout, + widgetEnabled = widgetEnabled, + widgetChannelId = widgetChannelId, + verificationLevel = verificationLevel, + defaultMessageNotifications = defaultMessageNotifications, + explicitContentFilter = explicitContentFilter, + roles = roles.map { it.id }, + emojis = emojis.map { it.id!! }, + features = features, + mfaLevel = mfaLevel, + applicationId = applicationId, + systemChannelId = systemChannelId, + systemChannelFlags = systemChannelFlags, + rulesChannelId = rulesChannelId, + joinedAt = joinedAt, + large = large, + memberCount = memberCount, + channels = channels.mapList { it.id }, + maxPresences = maxPresences, + maxMembers = maxMembers, + vanityUrlCode = vanityUrlCode, + description = description, + banner = banner, + premiumTier = premiumTier, + premiumSubscriptionCount = premiumSubscriptionCount, + preferredLocale = preferredLocale, + publicUpdatesChannelId = publicUpdatesChannelId, + maxVideoChannelUsers = maxVideoChannelUsers, + approximateMemberCount = approximateMemberCount, + approximatePresenceCount = approximatePresenceCount, + welcomeScreen = welcomeScreen.map { WelcomeScreenData.from(it) }, + nsfwLevel = nsfwLevel, + threads = threads.mapList { it.toData() }, stageInstances = stageInstances.mapList { StageInstanceData.from(it) }, stickers = stickers.mapList { StickerData.from(it) }, guildScheduledEvents = guildScheduledEvents.mapList { GuildScheduledEventData.from(it) }, diff --git a/core/src/main/kotlin/entity/Guild.kt b/core/src/main/kotlin/entity/Guild.kt index eafe4c9a522..b3b04cb581c 100644 --- a/core/src/main/kotlin/entity/Guild.kt +++ b/core/src/main/kotlin/entity/Guild.kt @@ -262,18 +262,6 @@ public class Guild( */ public val defaultMessageNotificationLevel: DefaultMessageNotificationLevel get() = data.defaultMessageNotifications - - /** - * The voice region id for the guild. - */ - @Suppress("DEPRECATION") - @Deprecated( - "The region field has been moved to Channel#rtcRegion in Discord API v9", - ReplaceWith("Channel#rtcRegion") - ) - public val regionId: String - get() = data.region - /** * The id of the channel in which a discoverable server's rules should be found **/ diff --git a/core/src/main/kotlin/entity/PartialGuild.kt b/core/src/main/kotlin/entity/PartialGuild.kt index 24d960e7d28..72dcce16680 100644 --- a/core/src/main/kotlin/entity/PartialGuild.kt +++ b/core/src/main/kotlin/entity/PartialGuild.kt @@ -26,7 +26,7 @@ public class PartialGuild( /** * The name of this guild. */ - public val name: String get() = data.name + public val name: String? get() = data.name.value override val id: Snowflake get() = data.id @@ -34,7 +34,7 @@ public class PartialGuild( /** * The icon hash, if present. */ - public val iconHash: String? get() = data.icon + public val iconHash: String? get() = data.icon?.value /** * wither who created the invite is the owner or not. @@ -60,7 +60,7 @@ public class PartialGuild( /** * The vanity code of this server used in the [vanityUrl], if present. */ - public val vanityCode: String? get() = data.vanityUrlCode.value + public val vanityCode: String? get() = data.vanityUrlCode?.value /** * The vanity invite URL of this server, if present. @@ -70,7 +70,7 @@ public class PartialGuild( /** * The description of this guild, if present. */ - public val description: String? get() = data.description.value + public val description: String? get() = data.description?.value /** @@ -125,7 +125,7 @@ public class PartialGuild( * Gets the banner url in the specified format. */ public fun getBannerUrl(format: Image.Format): String? = - data.banner.value?.let { "https://cdn.discordapp.com/banners/$id/$it.${format.extension}" } + data.banner?.value?.let { "https://cdn.discordapp.com/banners/$id/$it.${format.extension}" } /** * Requests to get the banner image in the specified [format], if present. diff --git a/core/src/main/kotlin/event/guild/GuildCreateEvent.kt b/core/src/main/kotlin/event/guild/GuildCreateEvent.kt index 7d5365a0e5e..dc7c3c7e041 100644 --- a/core/src/main/kotlin/event/guild/GuildCreateEvent.kt +++ b/core/src/main/kotlin/event/guild/GuildCreateEvent.kt @@ -2,6 +2,7 @@ package dev.kord.core.event.guild import dev.kord.core.Kord import dev.kord.core.entity.Guild +import dev.kord.core.entity.PartialGuild import dev.kord.core.event.Event import dev.kord.core.event.kordCoroutineScope import kotlinx.coroutines.CoroutineScope diff --git a/core/src/main/kotlin/event/guild/UnavailableGuildCreateEvent.kt b/core/src/main/kotlin/event/guild/UnavailableGuildCreateEvent.kt new file mode 100644 index 00000000000..d7bd0e3feba --- /dev/null +++ b/core/src/main/kotlin/event/guild/UnavailableGuildCreateEvent.kt @@ -0,0 +1,14 @@ +package dev.kord.core.event.guild + +import dev.kord.common.entity.Snowflake +import dev.kord.core.Kord +import dev.kord.core.event.Event +import dev.kord.core.event.kordCoroutineScope +import kotlinx.coroutines.CoroutineScope + +public class UnavailableGuildCreateEvent( + public val guildId: Snowflake, + override val shard: Int, + override val kord: Kord, + public val coroutineScope: CoroutineScope = kordCoroutineScope(kord) +) : Event, CoroutineScope by coroutineScope \ No newline at end of file diff --git a/core/src/main/kotlin/gateway/handler/GuildEventHandler.kt b/core/src/main/kotlin/gateway/handler/GuildEventHandler.kt index 5c742e8c6d3..251f879411c 100644 --- a/core/src/main/kotlin/gateway/handler/GuildEventHandler.kt +++ b/core/src/main/kotlin/gateway/handler/GuildEventHandler.kt @@ -4,6 +4,9 @@ import dev.kord.cache.api.DataCache import dev.kord.cache.api.put import dev.kord.cache.api.putAll import dev.kord.cache.api.query +import dev.kord.common.entity.DiscordGuild +import dev.kord.common.entity.DiscordPartialGuild +import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.common.entity.optional.orEmpty import dev.kord.core.Kord @@ -53,8 +56,7 @@ internal class GuildEventHandler( is InviteDelete -> handle(event, shard, kord, coroutineScope) else -> null } - - private suspend fun GatewayGuild.cache() { + private suspend fun GatewayGuild.cache() { for (member in members.orEmpty()) { cache.put(MemberData.from(member.user.value!!.id, id, member)) cache.put(UserData.from(member.user.value!!)) @@ -84,13 +86,46 @@ internal class GuildEventHandler( cache.put(EmojiData.from(id, emoji.id!!, emoji)) } } + private suspend fun DiscordPartialGuild.cache() { + for (member in members.orEmpty()) { + cache.put(MemberData.from(member.user.value!!.id, id, member)) + cache.put(UserData.from(member.user.value!!)) + } + + for (role in roles.orEmpty()) { + cache.put(RoleData.from(id, role)) + } + + for (channel in channels.orEmpty()) { + cache.put(ChannelData.from(channel.copy(guildId = this.id.optionalSnowflake()))) //guild id always empty + } + + for (thread in threads.orEmpty()) { + cache.put(ChannelData.from(thread.copy(guildId = this.id.optionalSnowflake()))) //guild id always empty + } + + for (presence in presences.orEmpty()) { + cache.put(PresenceData.from(id, presence)) + } + + for (voiceState in voiceStates.orEmpty()) { + cache.put(VoiceStateData.from(id, voiceState)) + } + + for (emoji in emojis.orEmpty()) { + cache.put(EmojiData.from(id, emoji.id!!, emoji)) + } + } private suspend fun handle( event: GuildCreate, shard: Int, kord: Kord, coroutineScope: CoroutineScope - ): GuildCreateEvent { + ): CoreEvent { + if (event.guild.name is Optional.Missing<*>) { + return UnavailableGuildCreateEvent(event.guild.id, shard, kord) + } val data = GuildData.from(event.guild) cache.put(data) event.guild.cache() diff --git a/core/src/test/kotlin/live/LiveGuildTest.kt b/core/src/test/kotlin/live/LiveGuildTest.kt index d798db21a7f..21c13d6aac4 100644 --- a/core/src/test/kotlin/live/LiveGuildTest.kt +++ b/core/src/test/kotlin/live/LiveGuildTest.kt @@ -2,6 +2,7 @@ package live import dev.kord.common.entity.* import dev.kord.common.entity.optional.Optional +import dev.kord.common.entity.optional.optional import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.cache.data.GuildData import dev.kord.core.entity.Guild @@ -38,7 +39,6 @@ class LiveGuildTest : AbstractLiveEntityTest() { id = guildId, name = "", ownerId = randomId(), - region = "", afkTimeout = 0.seconds, verificationLevel = VerificationLevel.None, defaultMessageNotifications = DefaultMessageNotificationLevel.AllMessages, @@ -690,33 +690,32 @@ class LiveGuildTest : AbstractLiveEntityTest() { sendEventValidAndRandomId(guildId) { GuildCreate( - DiscordGuild( + DiscordPartialGuild( id = it, - name = "", + name = "".optional(), icon = null, - ownerId = randomId(), - region = "", + ownerId = randomId().optionalSnowflake(), afkChannelId = null, - afkTimeout = 0.seconds, - verificationLevel = VerificationLevel.None, - defaultMessageNotifications = DefaultMessageNotificationLevel.AllMessages, - explicitContentFilter = ExplicitContentFilter.Disabled, + afkTimeout = 0.seconds.optional(), + verificationLevel = VerificationLevel.None.optional(), + defaultMessageNotifications = DefaultMessageNotificationLevel.AllMessages.optional(), + explicitContentFilter = ExplicitContentFilter.Disabled.optional(), roles = emptyList(), emojis = emptyList(), features = emptyList(), - mfaLevel = MFALevel.None, + mfaLevel = MFALevel.None.optional(), applicationId = null, systemChannelId = null, - systemChannelFlags = SystemChannelFlags(0), + systemChannelFlags = SystemChannelFlags(0).optional(), rulesChannelId = null, vanityUrlCode = null, description = null, banner = null, - premiumTier = PremiumTier.None, - preferredLocale = "", + premiumTier = PremiumTier.None.optional(), + preferredLocale = "".optional(), publicUpdatesChannelId = null, - nsfwLevel = NsfwLevel.Default, - premiumProgressBarEnabled = false + nsfwLevel = NsfwLevel.Default.optional(), + premiumProgressBarEnabled = false.optional() ), 0 ) diff --git a/core/src/test/kotlin/performance/KordEventDropTest.kt b/core/src/test/kotlin/performance/KordEventDropTest.kt index 8d71fbee585..e07d73bfa7a 100644 --- a/core/src/test/kotlin/performance/KordEventDropTest.kt +++ b/core/src/test/kotlin/performance/KordEventDropTest.kt @@ -2,8 +2,11 @@ package dev.kord.core.performance import dev.kord.cache.api.DataCache import dev.kord.common.entity.* +import dev.kord.common.entity.optional.optional +import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.ClientResources import dev.kord.core.Kord +import dev.kord.core.entity.PartialGuild import dev.kord.core.event.guild.GuildCreateEvent import dev.kord.core.gateway.DefaultMasterGateway import dev.kord.core.on @@ -62,33 +65,32 @@ class KordEventDropTest { val amount = 1_000 val event = GuildCreate( - DiscordGuild( + DiscordPartialGuild( Snowflake("1337"), - "discord guild", - afkTimeout = 0.seconds, - defaultMessageNotifications = DefaultMessageNotificationLevel.AllMessages, + "discord guild".optional(), + afkTimeout = 0.seconds.optional(), + defaultMessageNotifications = DefaultMessageNotificationLevel.AllMessages.optional(), emojis = emptyList(), - explicitContentFilter = ExplicitContentFilter.AllMembers, + explicitContentFilter = ExplicitContentFilter.AllMembers.optional(), features = emptyList(), - mfaLevel = MFALevel.Elevated, - ownerId = Snowflake("123"), - preferredLocale = "en", - description = "A not really real guild", - premiumTier = PremiumTier.None, - region = "idk", + mfaLevel = MFALevel.Elevated.optional(), + ownerId = Snowflake("123").optionalSnowflake(), + preferredLocale = "en".optional(), + description = "A not really real guild".optional(), + premiumTier = PremiumTier.None.optional(), roles = emptyList(), - verificationLevel = VerificationLevel.High, + verificationLevel = VerificationLevel.High.optional(), icon = null, afkChannelId = null, applicationId = null, - systemChannelFlags = SystemChannelFlags(0), + systemChannelFlags = SystemChannelFlags(0).optional(), systemChannelId = null, rulesChannelId = null, vanityUrlCode = null, banner = null, publicUpdatesChannelId = null, - nsfwLevel = NsfwLevel.Default, - premiumProgressBarEnabled = false + nsfwLevel = NsfwLevel.Default.optional(), + premiumProgressBarEnabled = false.optional() ), 0 ) diff --git a/gateway/src/main/kotlin/Event.kt b/gateway/src/main/kotlin/Event.kt index 88e1d74867a..e2bc04bcd79 100644 --- a/gateway/src/main/kotlin/Event.kt +++ b/gateway/src/main/kotlin/Event.kt @@ -168,7 +168,7 @@ public sealed class Event { decoder.decodeSerializableElement( descriptor, index, - DiscordGuild.serializer() + DiscordPartialGuild.serializer() ), sequence ) "GUILD_UPDATE" -> GuildUpdate( @@ -591,7 +591,7 @@ public data class ChannelDelete(val channel: DiscordChannel, override val sequen public data class ChannelPinsUpdate(val pins: DiscordPinsUpdateData, override val sequence: Int?) : DispatchEvent() public data class TypingStart(val data: DiscordTyping, override val sequence: Int?) : DispatchEvent() -public data class GuildCreate(val guild: DiscordGuild, override val sequence: Int?) : DispatchEvent() +public data class GuildCreate(val guild: DiscordPartialGuild, override val sequence: Int?) : DispatchEvent() public data class GuildUpdate(val guild: DiscordGuild, override val sequence: Int?) : DispatchEvent() public data class GuildDelete(val guild: DiscordUnavailableGuild, override val sequence: Int?) : DispatchEvent() public data class GuildBanAdd(val ban: DiscordGuildBan, override val sequence: Int?) : DispatchEvent() From 1a9c531d9943b91146f9f07ffd50c3f13fbbad8e Mon Sep 17 00:00:00 2001 From: Hope Date: Thu, 18 Aug 2022 09:04:58 +0300 Subject: [PATCH 2/2] Fix asserting null value on GuildData --- core/src/main/kotlin/cache/data/GuildData.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/kotlin/cache/data/GuildData.kt b/core/src/main/kotlin/cache/data/GuildData.kt index 29cb6c24a3c..bf2054b0933 100644 --- a/core/src/main/kotlin/cache/data/GuildData.kt +++ b/core/src/main/kotlin/cache/data/GuildData.kt @@ -135,7 +135,7 @@ public data class GuildData( return GuildData( id = id, name = name.value!!, - icon = icon?.value!!, + icon = icon?.value, iconHash = iconHash, splash = splash, discoverySplash = discoverySplash,