Compare commits
No commits in common. "root" and "refactor/translations-and-latest-kordex" have entirely different histories.
root
...
refactor/t
30 changed files with 206 additions and 524 deletions
36
.github/workflows/ci.yml
vendored
Normal file
36
.github/workflows/ci.yml
vendored
Normal 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@v3
|
||||||
|
|
||||||
|
with:
|
||||||
|
name: Build and Deploy Artifacts
|
||||||
|
path: build/libs/*.jar
|
33
.github/workflows/develop.yml
vendored
Normal file
33
.github/workflows/develop.yml
vendored
Normal 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@v3
|
||||||
|
|
||||||
|
with:
|
||||||
|
name: Build and Deploy Artifacts
|
||||||
|
path: build/libs/*.jar
|
60
.github/workflows/root.yml
vendored
60
.github/workflows/root.yml
vendored
|
@ -1,7 +1,6 @@
|
||||||
name: Build & Publish
|
name: Build & Publish
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- root
|
- root
|
||||||
|
@ -9,73 +8,40 @@ on:
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout code
|
- uses: actions/checkout@v4
|
||||||
uses: https://github.com/actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: https://github.com/docker/setup-qemu-action@v3
|
uses: docker/setup-qemu-action@v3
|
||||||
with:
|
|
||||||
cache-image: false
|
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: https://github.com/docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Set up Java
|
- name: Set up Java
|
||||||
uses: https://github.com/actions/setup-java@v4
|
uses: actions/setup-java@v4
|
||||||
|
|
||||||
with:
|
with:
|
||||||
java-version: 21
|
java-version: 17
|
||||||
distribution: temurin
|
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
|
- name: Grant execute permission for gradlew
|
||||||
run: chmod +x 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)
|
- name: Gradle (Build)
|
||||||
run: "./gradlew build"
|
run: "./gradlew build"
|
||||||
|
|
||||||
- name: Login to DigitalOcean Registry
|
- name: Login to GitHub Container Registry
|
||||||
uses: https://github.com/docker/login-action@v3
|
uses: docker/login-action@v2
|
||||||
|
|
||||||
with:
|
with:
|
||||||
registry: registry.digitalocean.com
|
registry: ghcr.io
|
||||||
username: ${{ secrets.DOMAIL }}
|
username: ${{ github.repository_owner }}
|
||||||
password: ${{ secrets.DOKEY }}
|
password: ${{ secrets.CR_PAT }}
|
||||||
|
|
||||||
- name: Build and push
|
- name: Build and push
|
||||||
uses: https://github.com/docker/build-push-action@v6
|
uses: docker/build-push-action@v5
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/arm64
|
||||||
push: true
|
push: true
|
||||||
tags: registry.digitalocean.com/jansel/feixiao:latest,registry.digitalocean.com/jansel/feixiao:${{ steps.date.outputs.date }}
|
tags: ghcr.io/notjansel/feixiao:latest
|
||||||
|
|
||||||
- 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 }}
|
|
||||||
|
|
9
.idea/Feixiao.iml
generated
9
.idea/Feixiao.iml
generated
|
@ -1,9 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module type="JAVA_MODULE" version="4">
|
|
||||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
|
||||||
<exclude-output />
|
|
||||||
<content url="file://$MODULE_DIR$" />
|
|
||||||
<orderEntry type="inheritedJdk" />
|
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
|
||||||
</component>
|
|
||||||
</module>
|
|
2
.idea/compiler.xml
generated
2
.idea/compiler.xml
generated
|
@ -1,7 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="CompilerConfiguration">
|
<component name="CompilerConfiguration">
|
||||||
<bytecodeTargetLevel target="21">
|
<bytecodeTargetLevel target="13">
|
||||||
<module name="ext-common" target="1.8" />
|
<module name="ext-common" target="1.8" />
|
||||||
<module name="ext-common.main" target="1.8" />
|
<module name="ext-common.main" target="1.8" />
|
||||||
<module name="ext-common.test" target="1.8" />
|
<module name="ext-common.test" target="1.8" />
|
||||||
|
|
2
.idea/kotlinc.xml
generated
2
.idea/kotlinc.xml
generated
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="KotlinJpsPluginSettings">
|
<component name="KotlinJpsPluginSettings">
|
||||||
<option name="version" value="2.1.21" />
|
<option name="version" value="2.0.21" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
12
.idea/material_theme_project_new.xml
generated
12
.idea/material_theme_project_new.xml
generated
|
@ -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
2
.idea/misc.xml
generated
|
@ -5,7 +5,7 @@
|
||||||
<file type="web" url="file://$PROJECT_DIR$/../ext-common" />
|
<file type="web" url="file://$PROJECT_DIR$/../ext-common" />
|
||||||
<file type="web" url="file://$PROJECT_DIR$" />
|
<file type="web" url="file://$PROJECT_DIR$" />
|
||||||
</component>
|
</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_13" project-jdk-name="azul-21" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/out" />
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
8
.idea/modules/feixiao.iml
generated
8
.idea/modules/feixiao.iml
generated
|
@ -1,8 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<module version="4">
|
|
||||||
<component name="AdditionalModuleElements">
|
|
||||||
<content url="file://$MODULE_DIR$/../.." dumb="true">
|
|
||||||
<excludeFolder url="file://$MODULE_DIR$/../../.kotlin" />
|
|
||||||
</content>
|
|
||||||
</component>
|
|
||||||
</module>
|
|
|
@ -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.
|
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.
|
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)
|
|
|
@ -2,17 +2,17 @@ import dev.kordex.gradle.plugins.docker.file.*
|
||||||
import dev.kordex.gradle.plugins.kordex.DataCollection
|
import dev.kordex.gradle.plugins.kordex.DataCollection
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
distribution
|
kotlin("jvm")
|
||||||
|
kotlin("plugin.serialization")
|
||||||
|
|
||||||
alias(libs.plugins.kotlin.jvm)
|
id("com.github.johnrengelman.shadow")
|
||||||
alias(libs.plugins.kotlin.serialization)
|
|
||||||
|
|
||||||
alias(libs.plugins.kordex.plugin)
|
id("dev.kordex.gradle.docker")
|
||||||
alias(libs.plugins.kordex.docker)
|
id("dev.kordex.gradle.kordex")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "dev.jansel"
|
group = "dev.jansel"
|
||||||
version = "1.2-SNAPSHOT"
|
version = "1.0-SNAPSHOT"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
|
@ -31,26 +31,9 @@ dependencies {
|
||||||
implementation(libs.logging)
|
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 {
|
kordEx {
|
||||||
kordExVersion = "2.3.1-SNAPSHOT"
|
kordExVersion = "2.3.1-SNAPSHOT"
|
||||||
jvmTarget = 21
|
jvmTarget = 21
|
||||||
ignoreIncompatibleKotlinVersion = true
|
|
||||||
|
|
||||||
bot {
|
bot {
|
||||||
// See https://docs.kordex.dev/data-collection.html
|
// See https://docs.kordex.dev/data-collection.html
|
||||||
|
@ -75,51 +58,37 @@ docker {
|
||||||
// Each function (aside from comment/emptyLine) corresponds to a Dockerfile instruction.
|
// Each function (aside from comment/emptyLine) corresponds to a Dockerfile instruction.
|
||||||
// See: https://docs.docker.com/reference/dockerfile/
|
// See: https://docs.docker.com/reference/dockerfile/
|
||||||
|
|
||||||
from("openjdk:21-jdk-slim")
|
from("azul/zulu-openjdk-alpine:21-jre-headless-latest")
|
||||||
|
|
||||||
emptyLine()
|
emptyLine()
|
||||||
|
|
||||||
comment("Create required directories")
|
|
||||||
runShell("mkdir -p /bot/plugins")
|
runShell("mkdir -p /bot/plugins")
|
||||||
runShell("mkdir -p /bot/data")
|
runShell("mkdir -p /bot/data")
|
||||||
runShell("mkdir -p /dist/out")
|
|
||||||
|
emptyLine()
|
||||||
|
|
||||||
|
copy("build/libs/$name-*-all.jar", "/bot/bot.jar")
|
||||||
|
|
||||||
emptyLine()
|
emptyLine()
|
||||||
|
|
||||||
// Add volumes for locations that you need to persist. This is important!
|
// 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/data") // Storage for data files
|
||||||
volume("/bot/plugins") // Plugin ZIP/JAR location
|
volume("/bot/plugins") // Plugin ZIP/JAR location
|
||||||
|
|
||||||
emptyLine()
|
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")
|
workdir("/bot")
|
||||||
|
|
||||||
emptyLine()
|
emptyLine()
|
||||||
|
|
||||||
comment("Run the distribution start script")
|
entryPointExec(
|
||||||
entryPointExec("/dist/out/${project.name}-${project.version}/bin/$name")
|
"java", "-Xms2G", "-Xmx2G",
|
||||||
|
"-jar", "/bot/bot.jar"
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.wrapper {
|
||||||
|
gradleVersion = "8.11.1"
|
||||||
|
distributionType = Wrapper.DistributionType.BIN
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
[versions]
|
[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"
|
groovy = "3.0.22"
|
||||||
jansi = "2.4.2"
|
jansi = "2.4.1"
|
||||||
kx-ser = "1.8.1"
|
kx-ser = "1.7.3"
|
||||||
logback = "1.5.18"
|
logback = "1.5.12"
|
||||||
logback-groovy = "1.14.5"
|
logback-groovy = "1.14.5"
|
||||||
logging = "7.0.7"
|
logging = "7.0.0"
|
||||||
twitch4j = "1.25.0"
|
twitch4j = "1.22.0"
|
||||||
events4j = "0.12.2"
|
events4j = "0.12.2"
|
||||||
kx-coroutines = "1.10.2"
|
kx-coroutines = "1.9.0"
|
||||||
kmongo = "5.2.1"
|
kmongo = "4.9.0"
|
||||||
kordex-gradle = "1.7.1"
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
groovy = { module = "org.codehaus.groovy:groovy", version.ref = "groovy" }
|
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" }
|
twitch4j = { module = "com.github.twitch4j:twitch4j", version.ref = "twitch4j" }
|
||||||
events4j = { module = "com.github.philippheuer.events4j:events4j-handler-reactor", version.ref = "events4j" }
|
events4j = { module = "com.github.philippheuer.events4j:events4j-handler-reactor", version.ref = "events4j" }
|
||||||
kmongo = { module="org.litote.kmongo:kmongo-coroutine-serialization", version.ref = "kmongo"}
|
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" }
|
|
||||||
|
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
|
@ -1,6 +1,6 @@
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
networkTimeout=10000
|
||||||
validateDistributionUrl=true
|
validateDistributionUrl=true
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|
9
gradlew
vendored
9
gradlew
vendored
|
@ -86,7 +86,8 @@ done
|
||||||
# shellcheck disable=SC2034
|
# shellcheck disable=SC2034
|
||||||
APP_BASE_NAME=${0##*/}
|
APP_BASE_NAME=${0##*/}
|
||||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
# 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.
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
MAX_FD=maximum
|
MAX_FD=maximum
|
||||||
|
@ -114,7 +115,7 @@ case "$( uname )" in #(
|
||||||
NONSTOP* ) nonstop=true ;;
|
NONSTOP* ) nonstop=true ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
CLASSPATH="\\\"\\\""
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
# Determine the Java command to use to start the JVM.
|
# Determine the Java command to use to start the JVM.
|
||||||
|
@ -205,7 +206,7 @@ fi
|
||||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
# Collect all arguments for the java command:
|
# 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.
|
# 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
|
# * 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.
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
@ -213,7 +214,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
set -- \
|
set -- \
|
||||||
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
-classpath "$CLASSPATH" \
|
-classpath "$CLASSPATH" \
|
||||||
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
"$@"
|
"$@"
|
||||||
|
|
||||||
# Stop when "xargs" is not available.
|
# Stop when "xargs" is not available.
|
||||||
|
|
4
gradlew.bat
vendored
4
gradlew.bat
vendored
|
@ -70,11 +70,11 @@ goto fail
|
||||||
:execute
|
:execute
|
||||||
@rem Setup the command line
|
@rem Setup the command line
|
||||||
|
|
||||||
set CLASSPATH=
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
@rem Execute Gradle
|
@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
|
:end
|
||||||
@rem End local scope for the variables with windows NT shell
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
{
|
|
||||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
||||||
"extends": [
|
|
||||||
"config:recommended"
|
|
||||||
],
|
|
||||||
"packageRules": [
|
|
||||||
{
|
|
||||||
"matchUpdateTypes": [
|
|
||||||
"minor",
|
|
||||||
"patch"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"prHourlyLimit": 0
|
|
||||||
}
|
|
|
@ -1,10 +1,20 @@
|
||||||
pluginManagement {
|
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 {
|
repositories {
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|
||||||
maven("https://releases-repo.kordex.dev")
|
|
||||||
maven("https://snapshots-repo.kordex.dev")
|
maven("https://snapshots-repo.kordex.dev")
|
||||||
|
maven("https://releases-repo.kordex.dev")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,32 @@
|
||||||
|
/*
|
||||||
|
* This Kotlin source file was generated by the Gradle 'init' task.
|
||||||
|
*/
|
||||||
package dev.jansel.feixiao
|
package dev.jansel.feixiao
|
||||||
|
|
||||||
|
import com.github.philippheuer.events4j.reactor.ReactorEventHandler
|
||||||
import com.github.twitch4j.TwitchClient
|
import com.github.twitch4j.TwitchClient
|
||||||
|
import com.github.twitch4j.TwitchClientBuilder
|
||||||
|
import com.github.twitch4j.events.ChannelGoLiveEvent
|
||||||
|
import dev.jansel.feixiao.database.collections.StreamerCollection
|
||||||
import dev.jansel.feixiao.extensions.EventHooks
|
import dev.jansel.feixiao.extensions.EventHooks
|
||||||
import dev.jansel.feixiao.extensions.StreamerCommand
|
import dev.jansel.feixiao.extensions.StreamerCommand
|
||||||
import dev.jansel.feixiao.utils.database
|
import dev.jansel.feixiao.utils.database
|
||||||
import dev.jansel.feixiao.utils.token
|
import dev.jansel.feixiao.utils.token
|
||||||
import dev.jansel.feixiao.utils.twitch
|
import dev.jansel.feixiao.utils.twitchcid
|
||||||
|
import dev.jansel.feixiao.utils.twitchcs
|
||||||
|
import dev.kord.core.entity.channel.GuildMessageChannel
|
||||||
import dev.kordex.core.ExtensibleBot
|
import dev.kordex.core.ExtensibleBot
|
||||||
import dev.kordex.core.i18n.SupportedLocales
|
import dev.kordex.core.i18n.SupportedLocales
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
var twitchClient: TwitchClient? = null
|
var twitchClient: TwitchClient? = null
|
||||||
val logger = KotlinLogging.logger { }
|
val logger = KotlinLogging.logger { }
|
||||||
var botRef: ExtensibleBot? = null
|
|
||||||
|
|
||||||
suspend fun main() {
|
suspend fun main() {
|
||||||
botRef = ExtensibleBot(token) {
|
val bot = ExtensibleBot(token) {
|
||||||
database(true)
|
database(true)
|
||||||
twitch(true)
|
|
||||||
extensions {
|
extensions {
|
||||||
add(::EventHooks)
|
add(::EventHooks)
|
||||||
add(::StreamerCommand)
|
add(::StreamerCommand)
|
||||||
|
@ -26,8 +35,55 @@ suspend fun main() {
|
||||||
applicationCommandLocale(SupportedLocales.ENGLISH, SupportedLocales.GERMAN)
|
applicationCommandLocale(SupportedLocales.ENGLISH, SupportedLocales.GERMAN)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
twitchClient = TwitchClientBuilder.builder()
|
||||||
|
.withEnableHelix(true)
|
||||||
|
.withClientId(twitchcid)
|
||||||
|
.withClientSecret(twitchcs)
|
||||||
|
.withDefaultEventHandler(ReactorEventHandler::class.java)
|
||||||
|
.build()
|
||||||
|
|
||||||
botRef!!.start()
|
twitchClient!!.eventManager.onEvent(ChannelGoLiveEvent::class.java) {
|
||||||
|
logger.info { "${it.channel.name} went live!" }
|
||||||
|
runBlocking {
|
||||||
|
launch {
|
||||||
|
val streamer = StreamerCollection().getData(it.channel.name)
|
||||||
|
for (server in streamer!!.servers) {
|
||||||
|
val channel = bot.kordRef.getChannelOf<GuildMessageChannel>(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}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bot.start()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,8 @@
|
||||||
package dev.jansel.feixiao.database
|
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.collections.MetaCollection
|
||||||
import dev.jansel.feixiao.database.entities.MetaData
|
import dev.jansel.feixiao.database.entities.MetaData
|
||||||
import dev.jansel.feixiao.database.migrations.v1
|
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 dev.kordex.core.koin.KordExKoinComponent
|
||||||
import io.github.oshai.kotlinlogging.KotlinLogging
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
import org.koin.core.component.inject
|
import org.koin.core.component.inject
|
||||||
|
@ -21,13 +15,6 @@ object Migrator : KordExKoinComponent {
|
||||||
|
|
||||||
suspend fun migrate() {
|
suspend fun migrate() {
|
||||||
logger.info { "Starting main database migration" }
|
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()
|
var meta = mainMetaCollection.get()
|
||||||
|
|
||||||
|
@ -48,7 +35,6 @@ object Migrator : KordExKoinComponent {
|
||||||
try {
|
try {
|
||||||
when (nextVersion) {
|
when (nextVersion) {
|
||||||
1 -> ::v1
|
1 -> ::v1
|
||||||
2 -> ::v2
|
|
||||||
else -> break
|
else -> break
|
||||||
}(db.mongo)
|
}(db.mongo)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ package dev.jansel.feixiao.database.collections
|
||||||
import dev.jansel.feixiao.database.Database
|
import dev.jansel.feixiao.database.Database
|
||||||
import dev.jansel.feixiao.database.entities.Server
|
import dev.jansel.feixiao.database.entities.Server
|
||||||
import dev.jansel.feixiao.database.entities.StreamerData
|
import dev.jansel.feixiao.database.entities.StreamerData
|
||||||
import dev.jansel.feixiao.utils.getTwitchIdByName
|
|
||||||
import dev.kord.common.entity.Snowflake
|
import dev.kord.common.entity.Snowflake
|
||||||
import dev.kordex.core.koin.KordExKoinComponent
|
import dev.kordex.core.koin.KordExKoinComponent
|
||||||
import org.koin.core.component.inject
|
import org.koin.core.component.inject
|
||||||
|
@ -21,7 +20,7 @@ class StreamerCollection : KordExKoinComponent {
|
||||||
suspend fun getData(channelName: String): StreamerData? =
|
suspend fun getData(channelName: String): StreamerData? =
|
||||||
collection.findOne(StreamerData::name eq channelName)
|
collection.findOne(StreamerData::name eq channelName)
|
||||||
|
|
||||||
suspend fun addData(
|
suspend fun updateData(
|
||||||
guildId: Snowflake,
|
guildId: Snowflake,
|
||||||
channelId: Snowflake,
|
channelId: Snowflake,
|
||||||
streamerName: String,
|
streamerName: String,
|
||||||
|
@ -36,98 +35,11 @@ class StreamerCollection : KordExKoinComponent {
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
collection.insertOne(
|
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(
|
suspend fun removeData(
|
||||||
guildId: Snowflake,
|
guildId: Snowflake,
|
||||||
channelId: Snowflake,
|
channelId: Snowflake,
|
||||||
|
|
|
@ -6,7 +6,6 @@ import kotlinx.serialization.Serializable
|
||||||
@Serializable
|
@Serializable
|
||||||
data class StreamerData(
|
data class StreamerData(
|
||||||
val name: String,
|
val name: String,
|
||||||
val id: String?,
|
|
||||||
val servers: List<Server>
|
val servers: List<Server>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -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))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -4,17 +4,10 @@ import dev.jansel.feixiao.database.collections.StreamerCollection
|
||||||
import dev.jansel.feixiao.database.entities.StreamerData
|
import dev.jansel.feixiao.database.entities.StreamerData
|
||||||
import dev.jansel.feixiao.logger
|
import dev.jansel.feixiao.logger
|
||||||
import dev.jansel.feixiao.twitchClient
|
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
|
|
||||||
import dev.kord.core.entity.channel.GuildMessageChannel
|
|
||||||
import dev.kord.core.event.gateway.ReadyEvent
|
import dev.kord.core.event.gateway.ReadyEvent
|
||||||
import dev.kordex.core.extensions.Extension
|
import dev.kordex.core.extensions.Extension
|
||||||
import dev.kordex.core.extensions.event
|
import dev.kordex.core.extensions.event
|
||||||
import org.litote.kmongo.eq
|
import org.litote.kmongo.eq
|
||||||
import org.litote.kmongo.setValue
|
|
||||||
|
|
||||||
class EventHooks : Extension() {
|
class EventHooks : Extension() {
|
||||||
override val name = "eventhooks"
|
override val name = "eventhooks"
|
||||||
|
@ -23,17 +16,12 @@ class EventHooks : Extension() {
|
||||||
event<ReadyEvent> {
|
event<ReadyEvent> {
|
||||||
action {
|
action {
|
||||||
logger.info { "Bot is ready!" }
|
logger.info { "Bot is ready!" }
|
||||||
val onlineLog =
|
|
||||||
kord.getGuildOrNull(tserverid)?.getChannelOf<GuildMessageChannel>(tchannelid)
|
|
||||||
onlineLog?.createMessage("Bot Online!")
|
|
||||||
kord.editPresence { listening("the database") }
|
kord.editPresence { listening("the database") }
|
||||||
// check every entry in the database and enable the stream event listener if a server is listening to the streamer
|
// 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 {
|
StreamerCollection().collection.find().toList().forEach {
|
||||||
if (it.servers.isNotEmpty()) {
|
if (it.servers.isNotEmpty()) {
|
||||||
val currentName = getTwitchNameById(it.id!!)
|
twitchClient!!.clientHelper.enableStreamEventListener(it.name)
|
||||||
twitchClient!!.clientHelper.enableStreamEventListener(currentName)
|
logger.info { "Enabled stream event listener for ${it.name}" }
|
||||||
logger.info { "Enabled stream event listener for $currentName" }
|
|
||||||
StreamerCollection().collection.updateOne(StreamerData::name eq it.name, setValue(StreamerData::name, currentName))
|
|
||||||
} else {
|
} else {
|
||||||
logger.info { "No servers are listening to ${it.name}, deleting from the database..." }
|
logger.info { "No servers are listening to ${it.name}, deleting from the database..." }
|
||||||
StreamerCollection().collection.deleteMany(StreamerData::name eq it.name)
|
StreamerCollection().collection.deleteMany(StreamerData::name eq it.name)
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package dev.jansel.feixiao.extensions
|
package dev.jansel.feixiao.extensions
|
||||||
|
|
||||||
import dev.jansel.feixiao.database.collections.StreamerCollection
|
import dev.jansel.feixiao.database.collections.StreamerCollection
|
||||||
import dev.jansel.feixiao.database.entities.StreamerData
|
|
||||||
import dev.jansel.feixiao.i18n.Translations
|
import dev.jansel.feixiao.i18n.Translations
|
||||||
import dev.jansel.feixiao.twitchClient
|
import dev.jansel.feixiao.twitchClient
|
||||||
import dev.kord.common.entity.Permission
|
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.checks.hasPermission
|
||||||
import dev.kordex.core.commands.Arguments
|
import dev.kordex.core.commands.Arguments
|
||||||
import dev.kordex.core.commands.application.slash.publicSubCommand
|
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.Extension
|
||||||
import dev.kordex.core.extensions.publicSlashCommand
|
import dev.kordex.core.extensions.publicSlashCommand
|
||||||
import org.litote.kmongo.eq
|
|
||||||
|
|
||||||
class StreamerCommand : Extension() {
|
class StreamerCommand : Extension() {
|
||||||
override val name = "streaming"
|
override val name = "streaming"
|
||||||
|
@ -30,21 +31,7 @@ class StreamerCommand : Extension() {
|
||||||
}
|
}
|
||||||
action {
|
action {
|
||||||
val streamer = arguments.streamer
|
val streamer = arguments.streamer
|
||||||
StreamerCollection().getData(streamer)?.servers?.forEach {
|
StreamerCollection().updateData(
|
||||||
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(
|
|
||||||
guild!!.id,
|
guild!!.id,
|
||||||
arguments.channel.id,
|
arguments.channel.id,
|
||||||
streamer,
|
streamer,
|
||||||
|
@ -67,63 +54,12 @@ class StreamerCommand : Extension() {
|
||||||
}
|
}
|
||||||
action {
|
action {
|
||||||
val streamer = arguments.streamer
|
val streamer = arguments.streamer
|
||||||
StreamerCollection().collection.findOne(StreamerData::name eq streamer)?.servers?.forEach {
|
StreamerCollection().removeData(guild!!.id, channel.id, streamer, null, null)
|
||||||
StreamerCollection().removeData(it.guildId, it.channelId, streamer, it.roleId, it.liveMessage)
|
|
||||||
}
|
|
||||||
respond {
|
respond {
|
||||||
content = "Removed streamer $streamer"
|
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)
|
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
package dev.jansel.feixiao.utils
|
|
||||||
|
|
||||||
import com.github.philippheuer.events4j.reactor.ReactorEventHandler
|
|
||||||
import com.github.twitch4j.TwitchClientBuilder
|
|
||||||
import com.github.twitch4j.events.ChannelGoLiveEvent
|
|
||||||
import dev.jansel.feixiao.botRef
|
|
||||||
import dev.jansel.feixiao.database.collections.StreamerCollection
|
|
||||||
import dev.jansel.feixiao.twitchClient
|
|
||||||
import dev.kord.core.entity.channel.GuildMessageChannel
|
|
||||||
import dev.kordex.core.koin.KordExKoinComponent
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
|
|
||||||
class Twitch : KordExKoinComponent {
|
|
||||||
suspend fun init() {
|
|
||||||
twitchClient = TwitchClientBuilder.builder()
|
|
||||||
.withEnableHelix(true)
|
|
||||||
.withDefaultEventHandler(ReactorEventHandler::class.java)
|
|
||||||
.withClientId(twitchcid)
|
|
||||||
.withClientSecret(twitchcs)
|
|
||||||
.build()
|
|
||||||
|
|
||||||
twitchClient!!.eventManager.onEvent(ChannelGoLiveEvent::class.java) {
|
|
||||||
dev.jansel.feixiao.logger.info { "${it.channel.name} went live!" }
|
|
||||||
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
|
|
||||||
|
|
||||||
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}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -3,7 +3,6 @@ package dev.jansel.feixiao.utils
|
||||||
import dev.jansel.feixiao.database.Database
|
import dev.jansel.feixiao.database.Database
|
||||||
import dev.jansel.feixiao.database.collections.MetaCollection
|
import dev.jansel.feixiao.database.collections.MetaCollection
|
||||||
import dev.jansel.feixiao.database.collections.StreamerCollection
|
import dev.jansel.feixiao.database.collections.StreamerCollection
|
||||||
import dev.jansel.feixiao.twitchClient
|
|
||||||
import dev.kord.common.entity.Snowflake
|
import dev.kord.common.entity.Snowflake
|
||||||
import dev.kordex.core.builders.ExtensibleBotBuilder
|
import dev.kordex.core.builders.ExtensibleBotBuilder
|
||||||
import dev.kordex.core.utils.env
|
import dev.kordex.core.utils.env
|
||||||
|
@ -38,38 +37,3 @@ suspend inline fun ExtensibleBotBuilder.database(migrate: Boolean) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend inline fun ExtensibleBotBuilder.twitch(active: Boolean) {
|
|
||||||
hooks {
|
|
||||||
beforeKoinSetup {
|
|
||||||
loadModule {
|
|
||||||
single { Twitch() } bind Twitch::class
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
Twitch().init()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
|
@ -2,16 +2,10 @@
|
||||||
|
|
||||||
streamer.command.name=streamer
|
streamer.command.name=streamer
|
||||||
streamer.command.description=A bundle of Streamer commands
|
streamer.command.description=A bundle of Streamer commands
|
||||||
|
|
||||||
streamer.command.add.name=add
|
streamer.command.add.name=add
|
||||||
streamer.command.add.description=Add a new streamer to the listener
|
streamer.command.add.description=Add a new streamer to the listener
|
||||||
|
|
||||||
streamer.command.remove.name=remove
|
streamer.command.remove.name=remove
|
||||||
streamer.command.remove.description=Remove a streamer from the listener
|
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.name=streamer
|
||||||
streamer.command.arguments.add.streamer.description=The streamer to add
|
streamer.command.arguments.add.streamer.description=The streamer to add
|
||||||
streamer.command.arguments.add.channel.name=channel
|
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.role.description=The role to assign to the streamer
|
||||||
streamer.command.arguments.add.message.name=message
|
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.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.name=streamer
|
||||||
streamer.command.arguments.remove.description=The streamer to remove
|
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...
|
# more to come...
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue