Skip to content

Commit

Permalink
Merge branch 'main' into migrate-on-disconnect
Browse files Browse the repository at this point in the history
  • Loading branch information
freyacodes authored Dec 3, 2023
2 parents 44d1e99 + 521b9c6 commit dfab077
Show file tree
Hide file tree
Showing 22 changed files with 319 additions and 39 deletions.
5 changes: 5 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion .idea/kotlinc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ allprojects {
maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
maven("https://oss.sonatype.org/content/repositories/snapshots")
maven("https://maven.topi.wtf/snapshots")
maven("https://maven.topi.wtf/releases")
}
}

Expand Down
6 changes: 2 additions & 4 deletions buildSrc/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
groovy
`kotlin-dsl`
Expand All @@ -11,12 +9,12 @@ repositories {
}

dependencies {
val kotlinVersion = "1.9.0"
val kotlinVersion = "1.9.21"
implementation(kotlin("gradle-plugin", kotlinVersion))
implementation(kotlin("serialization", kotlinVersion))
implementation(kotlin("gradle-plugin-api", kotlinVersion))
implementation("com.vanniktech:gradle-maven-publish-plugin:0.25.3")
implementation("org.jetbrains.dokka", "dokka-gradle-plugin", "1.8.20")
implementation("org.jetbrains.dokka", "dokka-gradle-plugin", "1.9.10")
implementation(gradleApi())
implementation(localGroovy())
}
8 changes: 8 additions & 0 deletions buildSrc/src/main/kotlin/lavalink-module.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ kotlin {
// Apart from that why would you need Lavalink in your browser?
}

targets.all {
compilations.all {
compilerOptions.configure {
freeCompilerArgs.add("-Xexpect-actual-classes")
}
}
}

sourceSets {
all {
languageSettings {
Expand Down
13 changes: 9 additions & 4 deletions core/src/commonMain/kotlin/dev/schlaubi/lavakord/LavaKord.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
package dev.schlaubi.lavakord

import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.audio.Node
import dev.schlaubi.lavakord.audio.RestNode
import dev.schlaubi.lavakord.audio.*
import io.ktor.http.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow

/**
* Representation of a Lavalink cluster.
Expand All @@ -13,11 +12,17 @@ import kotlinx.coroutines.CoroutineScope
* @property userId the id of the Discord bot user
* @property options Configuration options (See [LavaKordOptions]
*/
public interface LavaKord : CoroutineScope {
public interface LavaKord : CoroutineScope, EventSource<Event> {
public val nodes: List<Node>
public val userId: ULong
public val options: LavaKordOptions

/** A merged [Flow] of [Event]s produced by this instance's [Node]s */
public override val events: Flow<Event>

/** This simply returns [this][LavaKord]. It is required for implementations of [EventSource]*/
public override val coroutineScope: CoroutineScope get() = this

/**
* Returns the corresponding [Link] for the [guildId].
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package dev.schlaubi.lavakord.audio.internal

import dev.arbjerg.lavalink.protocol.v4.*
import dev.arbjerg.lavalink.protocol.v4.Error
import dev.arbjerg.lavalink.protocol.v4.LavalinkSerializersModule
import dev.arbjerg.lavalink.protocol.v4.Message
import dev.arbjerg.lavalink.protocol.v4.VoiceState
import dev.schlaubi.lavakord.LavaKord
import dev.schlaubi.lavakord.LavaKordOptions
import dev.schlaubi.lavakord.RestException
import dev.schlaubi.lavakord.audio.Link
import dev.schlaubi.lavakord.audio.Node
import dev.schlaubi.lavakord.audio.RestNode
import dev.schlaubi.lavakord.audio.*
import dev.schlaubi.lavakord.internal.HttpEngine
import dev.schlaubi.lavakord.internal.RestNodeImpl
import dev.schlaubi.lavakord.rest.updatePlayer
import io.ktor.client.*
import io.ktor.client.call.*
import io.ktor.client.engine.*
Expand All @@ -23,6 +23,10 @@ import io.ktor.serialization.kotlinx.*
import io.ktor.serialization.kotlinx.json.*
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.joinAll
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.newCoroutineContext
import kotlinx.serialization.modules.SerializersModule
Expand Down Expand Up @@ -58,6 +62,10 @@ public abstract class AbstractLavakord internal constructor(
private val nodesMap = mutableMapOf<String, Node>()
protected val linksMap: MutableMap<ULong, Link> = mutableMapOf()

private val eventPublisher: MutableSharedFlow<Event> = MutableSharedFlow(extraBufferCapacity = Channel.UNLIMITED)
override val events: SharedFlow<Event>
get() = eventPublisher.asSharedFlow()

internal val json = kotlinx.serialization.json.Json {
ignoreUnknownKeys = true
serializersModule = LavalinkSerializersModule + SerializersModule {
Expand Down Expand Up @@ -146,6 +154,7 @@ public abstract class AbstractLavakord internal constructor(
val finalName = name ?: "Lavalink_Node_#${nodeCounter.incrementAndGet()}"
val node =
NodeImpl(serverUri, finalName, password, this)
node.on<Event> { eventPublisher.tryEmit(this) }
nodesMap[finalName] = node
launch {
node.check()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ internal actual suspend fun NodeImpl.connect(
)
} catch (e: ConnectTimeoutException) {
internalReconnect(IllegalStateException("The connection to the node timed out", e))
} catch (e: ClientRequestException) {
internalReconnect(e)
} catch (e: ConnectException) {
} catch (e: Exception) {
internalReconnect(e)
}
}
4 changes: 2 additions & 2 deletions example/src/commonMain/kotlin/Lavakord.kt
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ suspend fun main() {
val followUpCreator = FollowupPermittingInteractionResponseBehavior(
interaction.applicationId, interaction.token, interaction.kord, interaction.supplier
)
player.on<Event> {
player.on<Event> event@{
try {
followUpCreator.createEphemeralFollowup { content = "Event: ${this@on}" }
followUpCreator.createEphemeralFollowup { content = "Event: ${this@event}" }
} catch (e: Exception) {
e.printStackTrace()
}
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
17 changes: 9 additions & 8 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
Expand Down Expand Up @@ -144,15 +145,15 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
# shellcheck disable=SC2039,SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
Expand Down Expand Up @@ -201,11 +202,11 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package dev.schlaubi.lavakord.kord

import dev.arbjerg.lavalink.protocol.v4.Player
import dev.arbjerg.lavalink.protocol.v4.PlayerUpdate
import dev.kord.common.DiscordBitSet
import dev.kord.common.entity.Permissions
import dev.kord.common.entity.Snowflake
import dev.kord.core.behavior.GuildBehavior
Expand Down Expand Up @@ -43,7 +44,7 @@ public suspend fun Link.connectAudio(snowflake: Snowflake): Unit = connectAudio(
* The [Permissions] that were missing.
*/
public val InsufficientPermissionException.kordPermission: Permissions
get() = Permissions(permission)
get() = Permissions.Builder(DiscordBitSet(permission)).build()


/**
Expand Down
53 changes: 53 additions & 0 deletions plugins/lavasearch/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import com.vanniktech.maven.publish.JavadocJar
import com.vanniktech.maven.publish.KotlinMultiplatform
import org.jetbrains.kotlin.gradle.dsl.JvmTarget

plugins {
`lavalink-module`
`lavalink-publishing`
kotlin("plugin.serialization")
alias(libs.plugins.ksp)
}

kotlin {
jvm {
compilations.all {
compilerOptions.configure {
jvmTarget = JvmTarget.JVM_11
}
}
}
sourceSets {
all {
languageSettings.optIn("kotlin.contracts.ExperimentalContracts")
languageSettings.optIn("dev.schlaubi.lavakord.PluginApi")
languageSettings.optIn("dev.schlaubi.lavakord.UnsafeRestApi")
}
commonMain {
kotlin.srcDir(layout.buildDirectory.dir("generated/ksp/metadata/commonMain/kotlin"))
dependencies {
api(projects.core)
api(libs.lavasearch.protocol)

implementation(libs.ktor.client.resources)
implementation(libs.kord.ksp.annotations)
}
}
}
}

dependencies {
kspCommonMainMetadata(libs.kord.ksp.processors)
}

tasks {
listOf("sourcesJar", "jsSourcesJar", "jvmSourcesJar", "compileKotlinJs", "compileKotlinJvm", "dokkaHtml").forEach {
named(it) {
dependsOn("kspCommonMainKotlinMetadata")
}
}
}

mavenPublishing {
configure(KotlinMultiplatform(JavadocJar.Dokka("dokkaHtml")))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// THIS FILE IS AUTO-GENERATED BY KordEnumProcessor.kt, DO NOT EDIT!
@file:Suppress(names = arrayOf("RedundantVisibilityModifier", "IncorrectFormatting",
"ReplaceArrayOfWithLiteral", "SpellCheckingInspection", "GrazieInspection"))

package dev.schlaubi.lavakord.plugins.lavasearch.model

import kotlin.Any
import kotlin.Boolean
import kotlin.Int
import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.String
import kotlin.Suppress
import kotlin.collections.List
import kotlinx.serialization.KSerializer
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

/**
* See [SearchType]s in the
* [Discord Developer Documentation](https://github.com/topi314/LavaSearch?tab=readme-ov-file#api).
*/
@Serializable(with = SearchType.Serializer::class)
public sealed class SearchType(
/**
* The raw value used by Discord.
*/
public val `value`: String,
) {
public final override fun equals(other: Any?): Boolean = this === other ||
(other is SearchType && this.value == other.value)

public final override fun hashCode(): Int = value.hashCode()

public final override fun toString(): String =
"SearchType.${this::class.simpleName}(value=$value)"

/**
* An unknown [SearchType].
*
* This is used as a fallback for [SearchType]s that haven't been added to Kord yet.
*/
public class Unknown(
`value`: String,
) : SearchType(value)

public object Track : SearchType("track")

public object Album : SearchType("album")

public object Artist : SearchType("artist")

public object Playlist : SearchType("playlist")

/**
* Search suggestions
*/
public object Text : SearchType("text")

internal object Serializer : KSerializer<SearchType> {
public override val descriptor: SerialDescriptor =
PrimitiveSerialDescriptor("dev.schlaubi.lavakord.plugins.lavasearch.model.SearchType",
PrimitiveKind.STRING)

public override fun serialize(encoder: Encoder, `value`: SearchType) =
encoder.encodeString(value.value)

public override fun deserialize(decoder: Decoder) =
when (val value = decoder.decodeString()) {
"track" -> Track
"album" -> Album
"artist" -> Artist
"playlist" -> Playlist
"text" -> Text
else -> Unknown(value)
}
}

public companion object {
/**
* A [List] of all known [SearchType]s.
*/
public val entries: List<SearchType> by lazy(mode = PUBLICATION) {
listOf(
Track,
Album,
Artist,
Playlist,
Text,
)
}

}
}
Loading

0 comments on commit dfab077

Please sign in to comment.