Compare commits

..

No commits in common. "root" and "refactor/different-loading-system" have entirely different histories.

29 changed files with 183 additions and 445 deletions

15
.github/renovate.json vendored Normal file
View file

@ -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
}
]
}

36
.github/workflows/ci.yml vendored Normal file
View file

@ -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

33
.github/workflows/develop.yml vendored Normal file
View file

@ -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

View file

@ -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

2
.idea/kotlinc.xml generated
View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="KotlinJpsPluginSettings">
<option name="version" value="2.1.21" />
<option name="version" value="2.0.21" />
</component>
</project>

View file

@ -1,12 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MaterialThemeProjectNewConfig">
<option name="metadata">
<MTProjectMetadataState>
<option name="migrated" value="true" />
<option name="pristineConfig" value="false" />
<option name="userId" value="-7d6c680f:19397de9638:-7ffe" />
</MTProjectMetadataState>
</option>
</component>
</project>

2
.idea/misc.xml generated
View file

@ -5,7 +5,7 @@
<file type="web" url="file://$PROJECT_DIR$/../ext-common" />
<file type="web" url="file://$PROJECT_DIR$" />
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="temurin-21" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="azul-21" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

8
.idea/modules.xml generated Normal file
View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/modules/feixiao.iml" filepath="$PROJECT_DIR$/.idea/modules/feixiao.iml" />
</modules>
</component>
</project>

View file

@ -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)

View file

@ -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
}

View file

@ -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" }
@ -25,11 +24,3 @@ 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" }

Binary file not shown.

View file

@ -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

9
gradlew vendored
View file

@ -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.

4
gradlew.bat vendored
View file

@ -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

View file

@ -1,15 +0,0 @@
{
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
"extends": [
"config:recommended"
],
"packageRules": [
{
"matchUpdateTypes": [
"minor",
"patch"
]
}
],
"prHourlyLimit": 0
}

View file

@ -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()

View file

@ -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,10 +8,10 @@ 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 { }

View file

@ -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)

View file

@ -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,

View file

@ -6,7 +6,6 @@ import kotlinx.serialization.Serializable
@Serializable
data class StreamerData(
val name: String,
val id: String?,
val servers: List<Server>
)

View file

@ -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>("streamerData").findOne(StreamerData::id eq null)?.let {
db.getCollection<StreamerData>("streamerData").updateOne(
StreamerData::name eq it.name,
setValue(StreamerData::id, getTwitchIdByName(it.name))
)
}
}

View file

@ -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)

View file

@ -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
}
}
}

View file

@ -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<GuildMessageChannel>(server.channelId)
val role = server.roleId
val livemessage = server.liveMessage
val channel = botRef!!.kordRef.getChannelOf<GuildMessageChannel>(streamer!!.servers.first().channelId)
val role = streamer.servers.first().roleId
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}")
}
}
channel?.createMessage("${it.channel.name} went live: ${it.stream.title}")
}
}
}
@ -63,4 +38,5 @@ class Twitch : KordExKoinComponent {
}
}

View file

@ -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
}

View file

@ -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...