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

Update Kotlin 1.5 branch to upstream #292

Merged
merged 13 commits into from
May 14, 2021
Merged
2 changes: 2 additions & 0 deletions .github/workflows/deployment-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ name: Kotlin CI

on:
push:
branches:
- '**' # We want to run this on all branch pushes
tags-ignore:
- '**' # We don't want this to run on tags pushes
branches:
Expand Down
4 changes: 2 additions & 2 deletions common/src/main/kotlin/DiscordBitSet.kt
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,15 @@ class DiscordBitSet(internal var data: LongArray) {
}

operator fun plus(another: DiscordBitSet): DiscordBitSet {
val dist = LongArray(size)
val dist = LongArray(data.size)
data.copyInto(dist)
val copy = DiscordBitSet(dist)
copy.add(another)
return copy
}

operator fun minus(another: DiscordBitSet): DiscordBitSet {
val dist = LongArray(size)
val dist = LongArray(data.size)
data.copyInto(dist)
val copy = DiscordBitSet(dist)
copy.remove(another)
Expand Down
6 changes: 4 additions & 2 deletions common/src/main/kotlin/entity/DiscordActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ data class DiscordActivity(
val assets: Optional<DiscordActivityAssets> = Optional.Missing(),
val secrets: Optional<DiscordActivitySecrets> = Optional.Missing(),
val instance: OptionalBoolean = OptionalBoolean.Missing,
val flags: Optional<ActivityFlags> = Optional.Missing()
val flags: Optional<ActivityFlags> = Optional.Missing(),
val buttons: Optional<List<String>> = Optional.Missing()
)

enum class ActivityFlag(val value: Int) {
Expand Down Expand Up @@ -136,7 +137,8 @@ enum class ActivityType(val code: Int) {
Streaming(1),
Listening(2),
Watching(3),
Custom(4);
Custom(4),
Competing(5);

companion object ActivityTypeSerializer : KSerializer<ActivityType> {
override val descriptor: SerialDescriptor
Expand Down
3 changes: 3 additions & 0 deletions common/src/main/kotlin/entity/DiscordChannel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ sealed class ChannelType(val value: Int) {
/** A channel in which game developers can sell their game on Discord. */
object GuildStore : ChannelType(6)

object GuildStageVoice : ChannelType(13)

companion object;

internal object Serializer : KSerializer<ChannelType> {
Expand All @@ -108,6 +110,7 @@ sealed class ChannelType(val value: Int) {
4 -> GuildCategory
5 -> GuildNews
6 -> GuildStore
13 -> GuildStageVoice
else -> Unknown(code)
}

Expand Down
7 changes: 6 additions & 1 deletion common/src/main/kotlin/entity/DiscordGuild.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ data class DiscordUnavailableGuild(
* @param approximateMemberCount The approximate number of members in this guild, returned from the `GET /guild/<id>` endpoint when `with_counts` is `true`.
* @param approximatePresenceCount The approximate number of non-offline members in this guild, returned from the `GET /guild/<id>` endpoint when `with_counts` is `true`.
* @param welcomeScreen The welcome screen of a Community guild, shown to new members.
* @param nsfw true if this guild is [designated as NSFW](https://support.discord.com/hc/en-us/articles/1500005389362-NSFW-Server-Designation)
*/
@Serializable
data class DiscordGuild(
Expand Down Expand Up @@ -150,7 +151,9 @@ data class DiscordGuild(
val approximateMemberCount: OptionalInt = OptionalInt.Missing,
@SerialName("approximate_presence_count")
val approximatePresenceCount: OptionalInt = OptionalInt.Missing,

@SerialName("welcome_screen")
val welcomeScreen: Optional<DiscordWelcomeScreen> = Optional.Missing(),
val nsfw: Boolean
)

/**
Expand Down Expand Up @@ -372,6 +375,8 @@ data class DiscordVoiceState(
@SerialName("self_stream")
val selfStream: OptionalBoolean = OptionalBoolean.Missing,
val suppress: Boolean,
@SerialName("request_to_speak_timestamp")
val requestToSpeakTimestamp: String?
)

/**
Expand Down
78 changes: 58 additions & 20 deletions common/src/main/kotlin/entity/DiscordMessage.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import kotlin.contracts.contract
* @param flags Message flags.
* @param stickers The stickers sent with the message (bots currently can only receive messages with stickers, not send).
* @param referencedMessage the message associated with [messageReference].
* @param applicationId if the message is a response to an [Interaction][DiscordInteraction], this is the id of the interaction's application
*/
@Serializable
data class DiscordMessage(
Expand Down Expand Up @@ -93,6 +94,8 @@ data class DiscordMessage(
val type: MessageType,
val activity: Optional<MessageActivity> = Optional.Missing(),
val application: Optional<MessageApplication> = Optional.Missing(),
@SerialName("application_id")
val applicationId: OptionalSnowflake = OptionalSnowflake.Missing,
@SerialName("message_reference")
val messageReference: Optional<DiscordMessageReference> = Optional.Missing(),
val flags: Optional<MessageFlags> = Optional.Missing(),
Expand Down Expand Up @@ -719,42 +722,77 @@ data class AllRemovedMessageReactions(
)

@Serializable(with = MessageType.MessageTypeSerializer::class)
enum class MessageType(val code: Int) {
sealed class MessageType(val code: Int) {
/** The default code for unknown values. */
Unknown(Int.MIN_VALUE),
Default(0),
RecipientAdd(1),
RecipientRemove(2),
Call(3),
ChannelNameChange(4),
ChannelIconChange(5),
ChannelPinnedMessage(6),
GuildMemberJoin(7),
UserPremiumGuildSubscription(8),
UserPremiumGuildSubscriptionTierOne(9),
UserPremiumGuildSubscriptionTwo(10),
UserPremiumGuildSubscriptionThree(11),
ChannelFollowAdd(12),
GuildDiscoveryDisqualified(14),
class Unknown(code: Int) : MessageType(code)
object Default : MessageType(0)
object RecipientAdd : MessageType(1)
object RecipientRemove : MessageType(2)
object Call : MessageType(3)
object ChannelNameChange : MessageType(4)
object ChannelIconChange : MessageType(5)
object ChannelPinnedMessage : MessageType(6)
object GuildMemberJoin : MessageType(7)
object UserPremiumGuildSubscription : MessageType(8)
object UserPremiumGuildSubscriptionTierOne : MessageType(9)
object UserPremiumGuildSubscriptionTwo : MessageType(10)
object UserPremiumGuildSubscriptionThree : MessageType(11)
object ChannelFollowAdd : MessageType(12)
object GuildDiscoveryDisqualified : MessageType(14)

@Suppress("SpellCheckingInspection")
GuildDiscoveryRequalified(15),
Reply(19);
object GuildDiscoveryRequalified : MessageType(15)
object GuildDiscoveryGracePeriodInitialWarning : MessageType(16)
object GuildDiscoveryGracePeriodFinalWarning : MessageType(17)
object ThreadCreated : MessageType(18)
object Reply : MessageType(19)
object ApplicationCommand : MessageType(20)
object ThreadStarterMessage : MessageType(21)
object GuildInviteReminder : MessageType(22)

companion object MessageTypeSerializer : KSerializer<MessageType> {
internal object MessageTypeSerializer : KSerializer<MessageType> {

override val descriptor: SerialDescriptor
get() = PrimitiveSerialDescriptor("type", PrimitiveKind.INT)

override fun deserialize(decoder: Decoder): MessageType {
val code = decoder.decodeInt()
return values().firstOrNull { it.code == code } ?: Unknown
return values.firstOrNull { it.code == code } ?: Unknown(code)
}

override fun serialize(encoder: Encoder, value: MessageType) {
encoder.encodeInt(value.code)
}
}

companion object {
val values: Set<MessageType>
get() = setOf(
Default,
RecipientAdd,
RecipientRemove,
Call,
ChannelNameChange,
ChannelIconChange,
ChannelPinnedMessage,
GuildMemberJoin,
UserPremiumGuildSubscription,
UserPremiumGuildSubscriptionTierOne,
UserPremiumGuildSubscriptionTwo,
UserPremiumGuildSubscriptionThree,
ChannelFollowAdd,
GuildDiscoveryDisqualified,
GuildDiscoveryRequalified,
Reply,
GuildDiscoveryGracePeriodInitialWarning,
GuildDiscoveryGracePeriodFinalWarning,
ThreadCreated,
ApplicationCommand,
ThreadStarterMessage,
GuildInviteReminder,

)
}
}

@Serializable(with = AllowedMentionType.Serializer::class)
Expand Down
8 changes: 6 additions & 2 deletions common/src/main/kotlin/entity/Permission.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package dev.kord.common.entity

import dev.kord.common.DiscordBitSet
import dev.kord.common.EmptyBitSet
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.descriptors.PrimitiveKind
Expand All @@ -18,7 +19,7 @@ class Permissions constructor(val code: DiscordBitSet) {
/**
* Returns this [Permissions] as a [Set] of [Permission]
*/
val values = Permission.values.filter { it.code in code }.toSet()
val values = Permission.values.filter { it.code in code }.toSet()

operator fun plus(permission: Permission): Permissions = Permissions(code + permission.code)

Expand Down Expand Up @@ -130,6 +131,7 @@ sealed class Permission(val code: DiscordBitSet) {
object ManageGuild : Permission(0x00000020)
object AddReactions : Permission(0x00000040)
object ViewAuditLog : Permission(0x00000080)
object Stream : Permission(0x00000200)
object ViewChannel : Permission(0x00000400)
object SendMessages : Permission(0x00000800)
object SendTTSMessages : Permission(0x00001000)
Expand All @@ -153,7 +155,8 @@ sealed class Permission(val code: DiscordBitSet) {
object ManageWebhooks : Permission(0x20000000)
object ManageEmojis : Permission(0x40000000)
object UseSlashCommands : Permission(0x80000000)
object All : Permission(0xFFFFFDFF)
object RequestToSpeak : Permission(0x100000000)
object All : Permission(values.fold(EmptyBitSet()) { acc, value -> acc.add(value.code); acc })

companion object {
val values: Set<Permission>
Expand Down Expand Up @@ -189,6 +192,7 @@ sealed class Permission(val code: DiscordBitSet) {
ManageWebhooks,
ManageEmojis,
UseSlashCommands,
RequestToSpeak
)
}
}
1 change: 1 addition & 0 deletions common/src/test/kotlin/json/GuildTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class GuildTest {
preferredLocale shouldBe "en-US"
rulesChannelId shouldBe "441688182833020939"
publicUpdatesChannelId shouldBe "281283303326089216"
nsfw shouldBe true
}

}
Expand Down
17 changes: 15 additions & 2 deletions common/src/test/kotlin/json/PermissionsTest.kt
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
package json

import dev.kord.common.DiscordBitSet
import dev.kord.common.entity.DiscordRole
import dev.kord.common.entity.Permissions
import dev.kord.common.EmptyBitSet
import dev.kord.common.entity.*
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.put
import org.junit.jupiter.api.Test

class PermissionsTest {

@Test
fun `adding permissions together does not swallow the universe`() {
Permission.values.fold(Permissions(DiscordBitSet(0))) { acc, permission ->
acc + permission
}
}

@Test
fun `Permission All does not swallow the universe`() {
Permission.All //oh yeah, this is worthy of a test
}

@Test
fun `permissions serialization test`() {
val expected = buildJsonObject {
Expand Down
3 changes: 2 additions & 1 deletion common/src/test/resources/json/guild/guild.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,6 @@
"system_channel_flags": 0,
"preferred_locale": "en-US",
"rules_channel_id": "441688182833020939",
"public_updates_channel_id": "281283303326089216"
"public_updates_channel_id": "281283303326089216",
"nsfw": true
}
17 changes: 17 additions & 0 deletions core/src/main/kotlin/Unsafe.kt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import dev.kord.common.annotation.KordUnsafe
import dev.kord.common.entity.Snowflake
import dev.kord.core.behavior.*
import dev.kord.core.behavior.channel.*
import dev.kord.rest.service.InteractionService

/**
* A class that exposes the creation of `{Entity}Behavior` classes.
Expand Down Expand Up @@ -71,4 +72,20 @@ class Unsafe(private val kord: Kord) {
return "Unsafe"
}

fun guildApplicationCommand(
guildId: Snowflake,
applicationId: Snowflake,
commandId: Snowflake,
service: InteractionService = kord.rest.interaction
): GuildApplicationCommandBehavior =
GuildApplicationCommandBehavior(guildId, applicationId, commandId, service)

fun globalApplicationCommand(
applicationId: Snowflake,
commandId: Snowflake,
service: InteractionService = kord.rest.interaction
): GlobalApplicationCommandBehavior =
GlobalApplicationCommandBehavior(applicationId, commandId, service)


}
33 changes: 33 additions & 0 deletions core/src/main/kotlin/behavior/GlobalApplicationCommandBehavior.kt
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,37 @@ interface GuildApplicationCommandBehavior : ApplicationCommandBehavior {
override suspend fun delete() {
service.deleteGuildApplicationCommand(applicationId, guildId, id)
}

}

@KordPreview
fun GuildApplicationCommandBehavior(
guildId: Snowflake,
applicationId: Snowflake,
id: Snowflake,
service: InteractionService
): GuildApplicationCommandBehavior = object : GuildApplicationCommandBehavior {
override val guildId: Snowflake
get() = guildId
override val applicationId: Snowflake
get() = applicationId
override val service: InteractionService
get() = service
override val id: Snowflake
get() = id
}


@KordPreview
fun GlobalApplicationCommandBehavior(
applicationId: Snowflake,
id: Snowflake,
service: InteractionService
): GlobalApplicationCommandBehavior = object : GlobalApplicationCommandBehavior {
override val applicationId: Snowflake
get() = applicationId
override val service: InteractionService
get() = service
override val id: Snowflake
get() = id
}
26 changes: 26 additions & 0 deletions core/src/main/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package dev.kord.core.behavior.channel

import dev.kord.cache.api.query
import dev.kord.common.exception.RequestException
import dev.kord.core.cache.data.VoiceStateData
import dev.kord.core.cache.idEq
import dev.kord.core.entity.VoiceState
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map

interface BaseVoiceChannelBehavior : GuildChannelBehavior {

/**
* Requests to retrieve the present voice states of this channel.
*
* This property is not resolvable through REST and will always use [KordCache] instead.
*
* The returned flow is lazily executed, any [RequestException] will be thrown on
* [terminal operators](https://kotlinlang.org/docs/reference/coroutines/flow.html#terminal-flow-operators) instead.
*/
val voiceStates: Flow<VoiceState>
get() = kord.cache.query<VoiceStateData> { idEq(VoiceStateData::channelId, id) }
.asFlow()
.map { VoiceState(it, kord) }

}
Loading