diff --git a/.github/renovate.json b/.github/renovate.json new file mode 100644 index 0000000..ba1d693 --- /dev/null +++ b/.github/renovate.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://docs.renovatebot.com/renovate-schema.json", + "extends": [ + "config:recommended" + ], + "commitBody": "[skip ci]", + "baseBranches": ["refactor/depUpdates"], + "prHourlyLimit": 0, + "packageRules": [ + { + "matchUpdateTypes": ["patch", "pin", "digest"], + "automerge": true + } + ] +} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..d7a094d --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,36 @@ +name: Build (CI) + +on: + push: + branches-ignore: + - root + - develop + + pull_request: + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v4 + + with: + java-version: 17 + distribution: temurin + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Gradle (Build) + run: "./gradlew build" + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + + with: + name: Build and Deploy Artifacts + path: build/libs/*.jar diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml new file mode 100644 index 0000000..eb0ab25 --- /dev/null +++ b/.github/workflows/develop.yml @@ -0,0 +1,33 @@ +name: Build & Publish + +on: + push: + branches: + - develop + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Set up Java + uses: actions/setup-java@v4 + + with: + java-version: 17 + distribution: temurin + + - name: Grant execute permission for gradlew + run: chmod +x gradlew + + - name: Gradle (Build) + run: "./gradlew build" + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + + with: + name: Build and Deploy Artifacts + path: build/libs/*.jar diff --git a/.github/workflows/root.yml b/.github/workflows/root.yml index 2ebd1de..a59dafc 100644 --- a/.github/workflows/root.yml +++ b/.github/workflows/root.yml @@ -1,7 +1,6 @@ name: Build & Publish on: - workflow_dispatch: push: branches: - root @@ -9,73 +8,40 @@ on: jobs: build: runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: https://github.com/actions/checkout@v4 + - uses: actions/checkout@v4 - name: Set up QEMU - uses: https://github.com/docker/setup-qemu-action@v3 - with: - cache-image: false + uses: docker/setup-qemu-action@v3 - name: Set up Docker Buildx - uses: https://github.com/docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@v3 - name: Set up Java - uses: https://github.com/actions/setup-java@v4 + uses: actions/setup-java@v4 with: - java-version: 21 + java-version: 17 distribution: temurin - - name: "Restore Cache" - id: restore-cache - uses: https://data.forgejo.org/actions/cache/restore@v4 - - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - ~/.m2/repository - key: gradle-store - - name: Grant execute permission for gradlew run: chmod +x gradlew - with: - dependency-graph: generate-and-submit - cache-disabled: true - - - name: Get current date - id: date - run: echo "::set-output name=date::$(date +'%Y-%m-%d')" - - name: Gradle (Build) run: "./gradlew build" - - name: Login to DigitalOcean Registry - uses: https://github.com/docker/login-action@v3 + - name: Login to GitHub Container Registry + uses: docker/login-action@v3 with: - registry: registry.digitalocean.com - username: ${{ secrets.DOMAIL }} - password: ${{ secrets.DOKEY }} + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.CR_PAT }} - name: Build and push - uses: https://github.com/docker/build-push-action@v6 + uses: docker/build-push-action@v6 with: context: . - platforms: linux/amd64,linux/arm64 + platforms: linux/arm64 push: true - tags: registry.digitalocean.com/jansel/feixiao:latest,registry.digitalocean.com/jansel/feixiao:${{ steps.date.outputs.date }} - - - name: "Save Cache" - uses: https://data.forgejo.org/actions/cache/save@v4 - - with: - path: | - ~/.gradle/caches - ~/.gradle/wrapper - ~/.m2/repository - key: ${{ steps.restore-cache.outputs.cache-primary-key }} + tags: ghcr.io/notjansel/feixiao:latest diff --git a/.idea/kotlinc.xml b/.idea/kotlinc.xml index 1e16934..c224ad5 100644 --- a/.idea/kotlinc.xml +++ b/.idea/kotlinc.xml @@ -1,6 +1,6 @@ - \ No newline at end of file diff --git a/.idea/material_theme_project_new.xml b/.idea/material_theme_project_new.xml deleted file mode 100644 index 8d28a9e..0000000 --- a/.idea/material_theme_project_new.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 0b1ec52..a4abeb1 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -5,7 +5,7 @@ - + - + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..4787ae5 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/README.md b/README.md index 80fee11..afc06e6 100644 --- a/README.md +++ b/README.md @@ -5,5 +5,3 @@ Blanketbot is a Discord bot, coded to notify you when your favorite twitch streamer goes live. To simply set it up, add the Bot to your server through the Invite link above and use the `/streamer add` command to add your favorite streamer. The bot will then notify you when the streamer goes live. If issues arise, please don't hesitate to create an issue here on GitHub. - -Info if you're looking at this from GitHub and not the Gitea Instance: This repo now is used as a mirror, Issues will still be looked at here on GitHub. For PR's, I will create a patchfile from that pr and apply it manually on the [origin repo](https://git.jansel.dev/jansel/feixiao) \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 1dff957..e53343b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -2,17 +2,17 @@ import dev.kordex.gradle.plugins.docker.file.* import dev.kordex.gradle.plugins.kordex.DataCollection plugins { - distribution + kotlin("jvm") + kotlin("plugin.serialization") - alias(libs.plugins.kotlin.jvm) - alias(libs.plugins.kotlin.serialization) + id("com.github.johnrengelman.shadow") - alias(libs.plugins.kordex.plugin) - alias(libs.plugins.kordex.docker) + id("dev.kordex.gradle.docker") + id("dev.kordex.gradle.kordex") } group = "dev.jansel" -version = "1.2-SNAPSHOT" +version = "1.0-SNAPSHOT" dependencies { @@ -31,26 +31,9 @@ dependencies { implementation(libs.logging) } -// Configure distributions plugin -distributions { - main { - distributionBaseName = project.name - - contents { - // Copy the LICENSE file into the distribution - from("LICENSE") - - // Exclude src/main/dist/README.md - exclude("README.md") - } - } -} - - kordEx { kordExVersion = "2.3.1-SNAPSHOT" jvmTarget = 21 - ignoreIncompatibleKotlinVersion = true bot { // See https://docs.kordex.dev/data-collection.html @@ -75,51 +58,37 @@ docker { // Each function (aside from comment/emptyLine) corresponds to a Dockerfile instruction. // See: https://docs.docker.com/reference/dockerfile/ - from("openjdk:21-jdk-slim") + from("azul/zulu-openjdk-alpine:21-jre-headless-latest") emptyLine() - comment("Create required directories") runShell("mkdir -p /bot/plugins") runShell("mkdir -p /bot/data") - runShell("mkdir -p /dist/out") + + emptyLine() + + copy("build/libs/$name-*-all.jar", "/bot/bot.jar") emptyLine() // Add volumes for locations that you need to persist. This is important! - comment("Declare required volumes") volume("/bot/data") // Storage for data files volume("/bot/plugins") // Plugin ZIP/JAR location emptyLine() - comment("Copy the distribution files into the container") - copy("build/distributions/${project.name}-${project.version}.tar", "/dist") - - emptyLine() - - comment("Extract the distribution files, and prepare them for use") - runShell("tar -xf /dist/${project.name}-${project.version}.tar -C /dist/out") - - if (file("src/main/dist/plugins").isDirectory) { - runShell("mv /dist/out/${project.name}-${project.version}/plugins/* /bot/plugins") - } - - runShell("chmod +x /dist/out/${project.name}-${project.version}/bin/$name") - - emptyLine() - - comment("Clean up unnecessary files") - runShell("rm /dist/${project.name}-${project.version}.tar") - - emptyLine() - - comment("Set the correct working directory") workdir("/bot") emptyLine() - comment("Run the distribution start script") - entryPointExec("/dist/out/${project.name}-${project.version}/bin/$name") + entryPointExec( + "java", "-Xms2G", "-Xmx2G", + "-jar", "/bot/bot.jar" + ) } } + +tasks.wrapper { + gradleVersion = "8.10.2" + distributionType = Wrapper.DistributionType.BIN +} diff --git a/privacy-policy.md b/docs/privacy-policy.md similarity index 100% rename from privacy-policy.md rename to docs/privacy-policy.md diff --git a/terms-of-service.md b/docs/terms-of-service.md similarity index 100% rename from terms-of-service.md rename to docs/terms-of-service.md diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4766e0d..b20ea0c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,17 +1,16 @@ [versions] -kotlin = "2.1.21" # Note: Plugin versions must be updated in the settings.gradle.kts too +kotlin = "2.0.21" # Note: Plugin versions must be updated in the settings.gradle.kts too -groovy = "3.0.25" -jansi = "2.4.2" -kx-ser = "1.8.1" -logback = "1.5.18" +groovy = "3.0.23" +jansi = "2.4.1" +kx-ser = "1.7.3" +logback = "1.5.12" logback-groovy = "1.14.5" -logging = "7.0.7" -twitch4j = "1.25.0" +logging = "7.0.0" +twitch4j = "1.23.0" events4j = "0.12.2" -kx-coroutines = "1.10.2" -kmongo = "5.2.1" -kordex-gradle = "1.7.1" +kx-coroutines = "1.9.0" +kmongo = "5.1.0" [libraries] groovy = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" } @@ -24,12 +23,4 @@ logback-groovy = { module = "io.github.virtualdogbert:logback-groovy-config", ve logging = { module = "io.github.oshai:kotlin-logging", version.ref = "logging" } twitch4j = { module = "com.github.twitch4j:twitch4j", version.ref = "twitch4j" } events4j = { module = "com.github.philippheuer.events4j:events4j-handler-reactor", version.ref = "events4j" } -kmongo = { module="org.litote.kmongo:kmongo-coroutine-serialization", version.ref = "kmongo" } - - -[plugins] -kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } -kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlin" } - -kordex-docker = { id = "dev.kordex.gradle.docker", version.ref = "kordex-gradle" } -kordex-plugin = { id = "dev.kordex.gradle.kordex", version.ref = "kordex-gradle" } +kmongo = { module="org.litote.kmongo:kmongo-coroutine-serialization", version.ref = "kmongo"} diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1b33c55..a4b76b9 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ff23a68..df97d72 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 23d15a9..f5feea6 100755 --- a/gradlew +++ b/gradlew @@ -86,7 +86,8 @@ done # shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) -APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s +' "$PWD" ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -114,7 +115,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -205,7 +206,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * 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. @@ -213,7 +214,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + org.gradle.wrapper.GradleWrapperMain \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index db3a6ac..9d21a21 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH= +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell diff --git a/renovate.json b/renovate.json deleted file mode 100644 index e655623..0000000 --- a/renovate.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "extends": [ - "config:recommended" - ], - "packageRules": [ - { - "matchUpdateTypes": [ - "minor", - "patch" - ] - } - ], - "prHourlyLimit": 0 -} diff --git a/settings.gradle.kts b/settings.gradle.kts index ebc20a7..fc0b921 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,4 +1,14 @@ pluginManagement { + plugins { + // Update this in libs.version.toml when you change it here. + kotlin("jvm") version "2.0.21" + kotlin("plugin.serialization") version "2.0.21" + + id("com.github.johnrengelman.shadow") version "8.1.1" + + id("dev.kordex.gradle.docker") version "1.5.8" + id("dev.kordex.gradle.kordex") version "1.5.8" + } repositories { gradlePluginPortal() mavenCentral() diff --git a/src/main/kotlin/dev/jansel/feixiao/App.kt b/src/main/kotlin/dev/jansel/feixiao/App.kt index eabdacc..afdfc21 100644 --- a/src/main/kotlin/dev/jansel/feixiao/App.kt +++ b/src/main/kotlin/dev/jansel/feixiao/App.kt @@ -1,3 +1,6 @@ +/* + * This Kotlin source file was generated by the Gradle 'init' task. + */ package dev.jansel.feixiao import com.github.twitch4j.TwitchClient @@ -5,14 +8,14 @@ import dev.jansel.feixiao.extensions.EventHooks import dev.jansel.feixiao.extensions.StreamerCommand import dev.jansel.feixiao.utils.database import dev.jansel.feixiao.utils.token -import dev.jansel.feixiao.utils.twitch import dev.kordex.core.ExtensibleBot import dev.kordex.core.i18n.SupportedLocales import io.github.oshai.kotlinlogging.KotlinLogging +import dev.jansel.feixiao.utils.twitch var twitchClient: TwitchClient? = null -val logger = KotlinLogging.logger { } -var botRef: ExtensibleBot? = null +val logger = KotlinLogging.logger { } +var botRef : ExtensibleBot? = null suspend fun main() { botRef = ExtensibleBot(token) { diff --git a/src/main/kotlin/dev/jansel/feixiao/database/Migrator.kt b/src/main/kotlin/dev/jansel/feixiao/database/Migrator.kt index 5e539eb..2043779 100644 --- a/src/main/kotlin/dev/jansel/feixiao/database/Migrator.kt +++ b/src/main/kotlin/dev/jansel/feixiao/database/Migrator.kt @@ -1,14 +1,8 @@ package dev.jansel.feixiao.database -import com.github.philippheuer.events4j.reactor.ReactorEventHandler -import com.github.twitch4j.TwitchClientBuilder import dev.jansel.feixiao.database.collections.MetaCollection import dev.jansel.feixiao.database.entities.MetaData import dev.jansel.feixiao.database.migrations.v1 -import dev.jansel.feixiao.database.migrations.v2 -import dev.jansel.feixiao.twitchClient -import dev.jansel.feixiao.utils.twitchcid -import dev.jansel.feixiao.utils.twitchcs import dev.kordex.core.koin.KordExKoinComponent import io.github.oshai.kotlinlogging.KotlinLogging import org.koin.core.component.inject @@ -21,13 +15,6 @@ object Migrator : KordExKoinComponent { suspend fun migrate() { logger.info { "Starting main database migration" } - logger.info { "Initializing Twitch client just in case" } - twitchClient = TwitchClientBuilder.builder() - .withEnableHelix(true) - .withDefaultEventHandler(ReactorEventHandler::class.java) - .withClientId(twitchcid) - .withClientSecret(twitchcs) - .build() var meta = mainMetaCollection.get() @@ -48,7 +35,6 @@ object Migrator : KordExKoinComponent { try { when (nextVersion) { 1 -> ::v1 - 2 -> ::v2 else -> break }(db.mongo) diff --git a/src/main/kotlin/dev/jansel/feixiao/database/collections/StreamerCollection.kt b/src/main/kotlin/dev/jansel/feixiao/database/collections/StreamerCollection.kt index 3471e94..651df09 100644 --- a/src/main/kotlin/dev/jansel/feixiao/database/collections/StreamerCollection.kt +++ b/src/main/kotlin/dev/jansel/feixiao/database/collections/StreamerCollection.kt @@ -3,7 +3,6 @@ package dev.jansel.feixiao.database.collections import dev.jansel.feixiao.database.Database import dev.jansel.feixiao.database.entities.Server import dev.jansel.feixiao.database.entities.StreamerData -import dev.jansel.feixiao.utils.getTwitchIdByName import dev.kord.common.entity.Snowflake import dev.kordex.core.koin.KordExKoinComponent import org.koin.core.component.inject @@ -21,7 +20,7 @@ class StreamerCollection : KordExKoinComponent { suspend fun getData(channelName: String): StreamerData? = collection.findOne(StreamerData::name eq channelName) - suspend fun addData( + suspend fun updateData( guildId: Snowflake, channelId: Snowflake, streamerName: String, @@ -36,98 +35,11 @@ class StreamerCollection : KordExKoinComponent { ) } else { collection.insertOne( - StreamerData(streamerName, getTwitchIdByName(streamerName), listOf(Server(guildId, channelId, roleId, liveMessage))) + StreamerData(streamerName, listOf(Server(guildId, channelId, roleId, liveMessage))) ) } } - /** - * Update the roleId - * @param streamerName: The name of the streamer - * @param roleId: The roleId to update - * @param guildId: The guildId to update - * @param noOverload: This is needed to avoid a conflict with the other updateData function, set to true or false, doesn't matter - * @return 0 = success, 1 = no Server associated with the guildId, 2 = no StreamerData associated with the streamerName - */ - - suspend fun updateData( - streamerName: String, - roleId: Snowflake, - guildId: Snowflake, - noOverload: Boolean = false // this is needed to avoid a conflict with the other updateData function - ): Int { - val coll = collection.findOne(StreamerData::name eq streamerName) - if (coll != null) { - val temp = coll.servers.find { server -> server.guildId == guildId } - if (temp == null) return 1 - collection.updateMany( - StreamerData::name eq streamerName, - setValue( - StreamerData::servers, - coll.servers - temp + Server(guildId, temp.channelId, roleId, temp.liveMessage) - ) - ) - return 0 - } - return 2 - } - - /** - * Update the liveMessage - * @param streamerName: The name of the streamer - * @param liveMessage: The liveMessage to update - * @param guildId: The guildId to update - * @return 0 = success, 1 = no Server associated with the guildId, 2 = no StreamerData associated with the streamerName - */ - suspend fun updateData( - streamerName: String, - liveMessage: String?, - guildId: Snowflake - ): Int { - val coll = collection.findOne(StreamerData::name eq streamerName) - if (coll != null) { - val temp = coll.servers.find { server -> server.guildId == guildId } - if (temp == null) return 1 - collection.updateMany( - StreamerData::name eq streamerName, - setValue( - StreamerData::servers, - coll.servers - temp + Server(guildId, temp.channelId, temp.roleId, liveMessage) - ) - ) - return 0 - } - return 2 - } - - /** - * Update the channelId - * @param streamerName: The name of the streamer - * @param channelId: The channelId to update - * @param guildId: The guildId to update - * @return 0 = success, 1 = no Server associated with the guildId, 2 = no StreamerData associated with the streamerName - */ - suspend fun updateData( - streamerName: String, - channelId: Snowflake, - guildId: Snowflake - ): Int { - val coll = collection.findOne(StreamerData::name eq streamerName) - if (coll != null) { - val temp = coll.servers.find { server -> server.guildId == guildId } - if (temp == null) return 1 - collection.updateMany( - StreamerData::name eq streamerName, - setValue( - StreamerData::servers, - coll.servers - temp + Server(guildId, channelId, temp.roleId, temp.liveMessage) - ) - ) - return 0 - } - return 2 - } - suspend fun removeData( guildId: Snowflake, channelId: Snowflake, diff --git a/src/main/kotlin/dev/jansel/feixiao/database/entities/StreamerData.kt b/src/main/kotlin/dev/jansel/feixiao/database/entities/StreamerData.kt index 9e79d75..3425532 100644 --- a/src/main/kotlin/dev/jansel/feixiao/database/entities/StreamerData.kt +++ b/src/main/kotlin/dev/jansel/feixiao/database/entities/StreamerData.kt @@ -6,7 +6,6 @@ import kotlinx.serialization.Serializable @Serializable data class StreamerData( val name: String, - val id: String?, val servers: List ) diff --git a/src/main/kotlin/dev/jansel/feixiao/database/migrations/v2.kt b/src/main/kotlin/dev/jansel/feixiao/database/migrations/v2.kt deleted file mode 100644 index df0f783..0000000 --- a/src/main/kotlin/dev/jansel/feixiao/database/migrations/v2.kt +++ /dev/null @@ -1,16 +0,0 @@ -package dev.jansel.feixiao.database.migrations - -import dev.jansel.feixiao.database.entities.StreamerData -import dev.jansel.feixiao.utils.getTwitchIdByName -import org.litote.kmongo.coroutine.CoroutineDatabase -import org.litote.kmongo.eq -import org.litote.kmongo.setValue - -suspend fun v2(db: CoroutineDatabase) { - db.getCollection("streamerData").findOne(StreamerData::id eq null)?.let { - db.getCollection("streamerData").updateOne( - StreamerData::name eq it.name, - setValue(StreamerData::id, getTwitchIdByName(it.name)) - ) - } -} diff --git a/src/main/kotlin/dev/jansel/feixiao/extensions/EventHooks.kt b/src/main/kotlin/dev/jansel/feixiao/extensions/EventHooks.kt index c9a4ca6..5fb0e0d 100644 --- a/src/main/kotlin/dev/jansel/feixiao/extensions/EventHooks.kt +++ b/src/main/kotlin/dev/jansel/feixiao/extensions/EventHooks.kt @@ -4,8 +4,6 @@ import dev.jansel.feixiao.database.collections.StreamerCollection import dev.jansel.feixiao.database.entities.StreamerData import dev.jansel.feixiao.logger import dev.jansel.feixiao.twitchClient -import dev.jansel.feixiao.utils.getTwitchIdByName -import dev.jansel.feixiao.utils.getTwitchNameById import dev.jansel.feixiao.utils.tchannelid import dev.jansel.feixiao.utils.tserverid import dev.kord.core.behavior.getChannelOf @@ -14,7 +12,6 @@ import dev.kord.core.event.gateway.ReadyEvent import dev.kordex.core.extensions.Extension import dev.kordex.core.extensions.event import org.litote.kmongo.eq -import org.litote.kmongo.setValue class EventHooks : Extension() { override val name = "eventhooks" @@ -30,10 +27,8 @@ class EventHooks : Extension() { // check every entry in the database and enable the stream event listener if a server is listening to the streamer StreamerCollection().collection.find().toList().forEach { if (it.servers.isNotEmpty()) { - val currentName = getTwitchNameById(it.id!!) - twitchClient!!.clientHelper.enableStreamEventListener(currentName) - logger.info { "Enabled stream event listener for $currentName" } - StreamerCollection().collection.updateOne(StreamerData::name eq it.name, setValue(StreamerData::name, currentName)) + twitchClient!!.clientHelper.enableStreamEventListener(it.name) + logger.info { "Enabled stream event listener for ${it.name}" } } else { logger.info { "No servers are listening to ${it.name}, deleting from the database..." } StreamerCollection().collection.deleteMany(StreamerData::name eq it.name) diff --git a/src/main/kotlin/dev/jansel/feixiao/extensions/StreamerCommand.kt b/src/main/kotlin/dev/jansel/feixiao/extensions/StreamerCommand.kt index 4f014d1..efafbac 100644 --- a/src/main/kotlin/dev/jansel/feixiao/extensions/StreamerCommand.kt +++ b/src/main/kotlin/dev/jansel/feixiao/extensions/StreamerCommand.kt @@ -1,7 +1,6 @@ package dev.jansel.feixiao.extensions import dev.jansel.feixiao.database.collections.StreamerCollection -import dev.jansel.feixiao.database.entities.StreamerData import dev.jansel.feixiao.i18n.Translations import dev.jansel.feixiao.twitchClient import dev.kord.common.entity.Permission @@ -9,10 +8,12 @@ import dev.kordex.core.checks.anyGuild import dev.kordex.core.checks.hasPermission import dev.kordex.core.commands.Arguments import dev.kordex.core.commands.application.slash.publicSubCommand -import dev.kordex.core.commands.converters.impl.* +import dev.kordex.core.commands.converters.impl.channel +import dev.kordex.core.commands.converters.impl.optionalRole +import dev.kordex.core.commands.converters.impl.optionalString +import dev.kordex.core.commands.converters.impl.string import dev.kordex.core.extensions.Extension import dev.kordex.core.extensions.publicSlashCommand -import org.litote.kmongo.eq class StreamerCommand : Extension() { override val name = "streaming" @@ -30,21 +31,7 @@ class StreamerCommand : Extension() { } action { val streamer = arguments.streamer - StreamerCollection().getData(streamer)?.servers?.forEach { - if (it.guildId == guild!!.id) { - respond { - content = "Streamer already exists in this server" - } - return@action - } - } - if (arguments.role?.id == guild!!.id) { - respond { - content = "This action would implement a everyone ping, which is due to how role pings are implemented right now not possible. If you want to make an everyone ping regardless, make a role-less ping and write the everyone ping manually." - } - return@action - } - StreamerCollection().addData( + StreamerCollection().updateData( guild!!.id, arguments.channel.id, streamer, @@ -67,63 +54,12 @@ class StreamerCommand : Extension() { } action { val streamer = arguments.streamer - StreamerCollection().collection.findOne(StreamerData::name eq streamer)?.servers?.forEach { - StreamerCollection().removeData(it.guildId, it.channelId, streamer, it.roleId, it.liveMessage) - } + StreamerCollection().removeData(guild!!.id, channel.id, streamer, null, null) respond { content = "Removed streamer $streamer" } } } - - publicSubCommand(::UpdateStreamerArgs) { - name = Translations.Streamer.Command.Update.name - description = Translations.Streamer.Command.Update.description - check { - anyGuild() - hasPermission(Permission.ManageGuild) - } - action { - val streamer = arguments.streamer - val data = StreamerCollection().collection.findOne(StreamerData::name eq streamer) - if (data != null) { - val servers = data.servers - val guildId = guild!!.id - val roleId = arguments.role - val channelId = arguments.channel - val message = arguments.message - val temp = servers.find { it.guildId == guildId } - if (roleId?.id== guildId) { - respond { - content = "This action would implement a everyone ping, which is due to how role pings are implemented right now not possible. If you want to make an everyone ping regardless, make a role-less ping and write the everyone ping manually." - } - return@action - } - if (temp != null) { - if (channelId != null) { - StreamerCollection().updateData(streamer, channelId.id, guildId) - } - if (roleId != null) { - StreamerCollection().updateData(streamer, roleId.id, guildId, false) - } - if (message != null) { - StreamerCollection().updateData(streamer, message, guildId) - } - respond { - content = "Updated streamer $streamer" - } - } else { - respond { - content = "No server associated with the guildId" - } - } - } else { - respond { - content = "No StreamerData associated with the streamerName" - } - } - } - } } } @@ -155,23 +91,4 @@ class StreamerCommand : Extension() { require(true) } } - - inner class UpdateStreamerArgs : Arguments() { - val streamer by string { - name = Translations.Streamer.Command.Arguments.Update.Streamer.name - description = Translations.Streamer.Command.Arguments.Update.Streamer.description - } - val channel by optionalChannel { - name = Translations.Streamer.Command.Arguments.Update.Channel.name - description = Translations.Streamer.Command.Arguments.Update.Channel.description - } - val role by optionalRole { - name = Translations.Streamer.Command.Arguments.Update.Role.name - description = Translations.Streamer.Command.Arguments.Update.Role.description - } - val message by optionalString { - name = Translations.Streamer.Command.Arguments.Update.Message.name - description = Translations.Streamer.Command.Arguments.Update.Message.description - } - } } diff --git a/src/main/kotlin/dev/jansel/feixiao/utils/Twitch.kt b/src/main/kotlin/dev/jansel/feixiao/utils/Twitch.kt index 0aa7ca8..07b3d2e 100644 --- a/src/main/kotlin/dev/jansel/feixiao/utils/Twitch.kt +++ b/src/main/kotlin/dev/jansel/feixiao/utils/Twitch.kt @@ -25,37 +25,12 @@ class Twitch : KordExKoinComponent { runBlocking { launch { val streamer = StreamerCollection().getData(it.channel.name) - for (server in streamer!!.servers) { - val channel = botRef!!.kordRef.getChannelOf(server.channelId) - val role = server.roleId - val livemessage = server.liveMessage - - if (role != null) { - if (livemessage != null) { - channel?.createMessage( - livemessage - .replace("{name}", it.channel.name) - .replace("{category}", it.stream.gameName) - .replace("{title}", it.stream.title) - .replace("{url}", "https://twitch.tv/${it.channel.name}") - .replace("{role}", "<@&$role>") - ) - } else { - channel?.createMessage("<@&$role> https://twitch.tv/${it.channel.name} went live streaming ${it.stream.gameName}: ${it.stream.title}") - } - } else { - if (livemessage != null) { - channel?.createMessage( - livemessage - .replace("{name}", it.channel.name) - .replace("{category}", it.stream.gameName) - .replace("{title}", it.stream.title) - .replace("{url}", "https://twitch.tv/${it.channel.name}") - ) - } else { - channel?.createMessage("https://twitch.tv/${it.channel.name} went live streaming ${it.stream.gameName}: ${it.stream.title}") - } - } + val channel = botRef!!.kordRef.getChannelOf(streamer!!.servers.first().channelId) + val role = streamer.servers.first().roleId + if (role != null) { + channel?.createMessage("<@&$role> https://twitch.tv/${it.channel.name} went live streaming ${it.stream.gameName}: ${it.stream.title}") + } else { + channel?.createMessage("${it.channel.name} went live: ${it.stream.title}") } } } @@ -63,4 +38,5 @@ class Twitch : KordExKoinComponent { } + } diff --git a/src/main/kotlin/dev/jansel/feixiao/utils/_Utils.kt b/src/main/kotlin/dev/jansel/feixiao/utils/_Utils.kt index 97ece69..a7c9ec5 100644 --- a/src/main/kotlin/dev/jansel/feixiao/utils/_Utils.kt +++ b/src/main/kotlin/dev/jansel/feixiao/utils/_Utils.kt @@ -1,13 +1,17 @@ package dev.jansel.feixiao.utils +import com.github.twitch4j.TwitchClientBuilder +import com.github.twitch4j.events.ChannelGoLiveEvent import dev.jansel.feixiao.database.Database import dev.jansel.feixiao.database.collections.MetaCollection import dev.jansel.feixiao.database.collections.StreamerCollection import dev.jansel.feixiao.twitchClient import dev.kord.common.entity.Snowflake +import dev.kord.core.entity.channel.GuildMessageChannel import dev.kordex.core.builders.ExtensibleBotBuilder import dev.kordex.core.utils.env import dev.kordex.core.utils.loadModule +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import org.koin.dsl.bind @@ -53,23 +57,3 @@ suspend inline fun ExtensibleBotBuilder.twitch(active: Boolean) { } } - -fun getTwitchNameById(id: String): String? { - val resultList = twitchClient!!.helix?.getUsers(null, listOf(id), null)?.execute() - resultList?.users?.forEach { user -> - if (user.id == id) { - return user.displayName - } - } - return null -} - -fun getTwitchIdByName(name: String): String? { - val resultList = twitchClient!!.helix?.getUsers(null, null, listOf(name))?.execute() - resultList?.users?.forEach { user -> - if (user.displayName == name) { - return user.id - } - } - return null -} diff --git a/src/main/resources/translations/feixiao/strings.properties b/src/main/resources/translations/feixiao/strings.properties index 81c90c9..95535d7 100644 --- a/src/main/resources/translations/feixiao/strings.properties +++ b/src/main/resources/translations/feixiao/strings.properties @@ -2,16 +2,10 @@ streamer.command.name=streamer streamer.command.description=A bundle of Streamer commands - streamer.command.add.name=add streamer.command.add.description=Add a new streamer to the listener - streamer.command.remove.name=remove streamer.command.remove.description=Remove a streamer from the listener - -streamer.command.update.name=update -streamer.command.update.description=Update a streamer listener's settings for this guild - streamer.command.arguments.add.streamer.name=streamer streamer.command.arguments.add.streamer.description=The streamer to add streamer.command.arguments.add.channel.name=channel @@ -20,19 +14,7 @@ streamer.command.arguments.add.role.name=role streamer.command.arguments.add.role.description=The role to assign to the streamer streamer.command.arguments.add.message.name=message streamer.command.arguments.add.message.description=Custom Announce message. Placeholders (in curly braces): url, name, title, category, role (if set) - streamer.command.arguments.remove.name=streamer streamer.command.arguments.remove.description=The streamer to remove -streamer.command.arguments.update.streamer.name=streamer -streamer.command.arguments.update.streamer.description=The streamer to edit -streamer.command.arguments.update.channel.name=channel -streamer.command.arguments.update.channel.description=The channel to add the streamer to -streamer.command.arguments.update.role.name=role -streamer.command.arguments.update.role.description=The role to assign to the streamer -streamer.command.arguments.update.message.name=message -streamer.command.arguments.update.message.description=Custom Announce message. Placeholders (in curly braces): url, name, title, category, role (if set) - - - # more to come...