Merge branch 'root' into refactor/different-loading-system

# Conflicts:
#	src/main/kotlin/dev/jansel/feixiao/App.kt
This commit is contained in:
Jannik Reimers 2024-11-28 08:43:47 +01:00
commit a3f31b64d0
Signed by: jansel
GPG key ID: 39C62D7D5233CFD0
17 changed files with 162 additions and 46 deletions

View file

@ -3,16 +3,20 @@
*/
package dev.jansel.feixiao
import com.github.philippheuer.events4j.reactor.ReactorEventHandler
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.StreamerCommand
import dev.jansel.feixiao.utils.*
import dev.jansel.feixiao.utils.database
import dev.jansel.feixiao.utils.token
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.data.api.DataCollection
import dev.kordex.core.i18n.SupportedLocales
import io.github.oshai.kotlinlogging.KotlinLogging
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
@ -25,11 +29,13 @@ suspend fun main() {
botRef = ExtensibleBot(token) {
database(true)
twitch(true)
dataCollectionMode = DataCollection.None
extensions {
add(::EventHooks)
add(::StreamerCommand)
}
i18n {
applicationCommandLocale(SupportedLocales.ENGLISH, SupportedLocales.GERMAN)
}
}
botRef!!.start()

View file

@ -20,26 +20,38 @@ class StreamerCollection : KordExKoinComponent {
suspend fun getData(channelName: String): StreamerData? =
collection.findOne(StreamerData::name eq channelName)
suspend fun updateData(guildId: Snowflake, channelId: Snowflake, streamerName: String, roleId: Snowflake?) {
suspend fun updateData(
guildId: Snowflake,
channelId: Snowflake,
streamerName: String,
roleId: Snowflake?,
liveMessage: String?
) {
val coll = collection.findOne(StreamerData::name eq streamerName)
if (coll != null) {
collection.updateOne(
StreamerData::name eq streamerName,
setValue(StreamerData::servers, coll.servers + listOf(Server(guildId, channelId, roleId)))
setValue(StreamerData::servers, coll.servers + listOf(Server(guildId, channelId, roleId, liveMessage)))
)
} else {
collection.insertOne(
StreamerData(streamerName, listOf(Server(guildId, channelId, roleId)))
StreamerData(streamerName, listOf(Server(guildId, channelId, roleId, liveMessage)))
)
}
}
suspend fun removeData(guildId: Snowflake, channelId: Snowflake, streamerName: String, roleId: Snowflake?) {
suspend fun removeData(
guildId: Snowflake,
channelId: Snowflake,
streamerName: String,
roleId: Snowflake?,
liveMessage: String?
) {
val coll = collection.findOne(StreamerData::name eq streamerName)
if (coll != null) {
collection.updateOne(
StreamerData::name eq streamerName,
setValue(StreamerData::servers, coll.servers - Server(guildId, channelId, roleId))
setValue(StreamerData::servers, coll.servers - Server(guildId, channelId, roleId, liveMessage))
)
}
}

View file

@ -13,5 +13,6 @@ data class StreamerData(
data class Server(
val guildId: Snowflake,
val channelId: Snowflake,
val roleId: Snowflake?
val roleId: Snowflake?,
val liveMessage: String?
)

View file

@ -1,11 +1,17 @@
package dev.jansel.feixiao.extensions
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.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.kordex.core.extensions.Extension
import dev.kordex.core.extensions.event
import org.litote.kmongo.eq
class EventHooks : Extension() {
override val name = "eventhooks"
@ -14,11 +20,19 @@ class EventHooks : Extension() {
event<ReadyEvent> {
action {
logger.info { "Bot is ready!" }
val onlineLog =
kord.getGuildOrNull(tserverid)?.getChannelOf<GuildMessageChannel>(tchannelid)
onlineLog?.createMessage("Bot Online!")
kord.editPresence { listening("the database") }
// check every entry in the database and enable the stream event listener
// 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 {
twitchClient!!.clientHelper.enableStreamEventListener(it.name)
logger.info { "Enabled stream event listener for ${it.name}" }
if (it.servers.isNotEmpty()) {
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,6 +1,7 @@
package dev.jansel.feixiao.extensions
import dev.jansel.feixiao.database.collections.StreamerCollection
import dev.jansel.feixiao.i18n.Translations
import dev.jansel.feixiao.twitchClient
import dev.kord.common.entity.Permission
import dev.kordex.core.checks.anyGuild
@ -9,6 +10,7 @@ import dev.kordex.core.commands.Arguments
import dev.kordex.core.commands.application.slash.publicSubCommand
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
@ -17,19 +19,25 @@ class StreamerCommand : Extension() {
override val name = "streaming"
override suspend fun setup() {
publicSlashCommand {
name = "streamer"
description = "Streamer commands"
name = Translations.Streamer.Command.name
description = Translations.Streamer.Command.description
publicSubCommand(::AddStreamerArgs) {
name = "add"
description = "Add a streamer to the listener of this server"
name = Translations.Streamer.Command.Add.name
description = Translations.Streamer.Command.Add.description
check {
anyGuild()
hasPermission(Permission.ManageGuild)
}
action {
val streamer = arguments.streamer
StreamerCollection().updateData(guild!!.id, arguments.channel.id, streamer, arguments.role?.id)
StreamerCollection().updateData(
guild!!.id,
arguments.channel.id,
streamer,
arguments.role?.id,
arguments.message
)
twitchClient!!.clientHelper.enableStreamEventListener(streamer)
respond {
content = "Added streamer $streamer"
@ -38,15 +46,15 @@ class StreamerCommand : Extension() {
}
publicSubCommand(::RemoveStreamerArgs) {
name = "remove"
description = "Remove a streamer from the listener of this server"
name = Translations.Streamer.Command.Remove.name
description = Translations.Streamer.Command.Remove.description
check {
anyGuild()
hasPermission(Permission.ManageGuild)
}
action {
val streamer = arguments.streamer
StreamerCollection().removeData(guild!!.id, channel.id, streamer, null)
StreamerCollection().removeData(guild!!.id, channel.id, streamer, null, null)
respond {
content = "Removed streamer $streamer"
}
@ -57,25 +65,29 @@ class StreamerCommand : Extension() {
inner class AddStreamerArgs : Arguments() {
val streamer by string {
name = "streamer"
description = "The streamer to add"
name = Translations.Streamer.Command.Arguments.Add.Streamer.name
description = Translations.Streamer.Command.Arguments.Add.Streamer.description
require(true)
}
val channel by channel {
name = "announcechannel"
description = "Channel where the bot will send a message when the streamer goes live"
name = Translations.Streamer.Command.Arguments.Add.Channel.name
description = Translations.Streamer.Command.Arguments.Add.Channel.description
require(true)
}
val role by optionalRole {
name = "role"
description = "Role to ping when the streamer goes live"
name = Translations.Streamer.Command.Arguments.Add.Role.name
description = Translations.Streamer.Command.Arguments.Add.Role.description
}
val message by optionalString {
name = Translations.Streamer.Command.Arguments.Add.Message.name
description = Translations.Streamer.Command.Arguments.Add.Message.description
}
}
inner class RemoveStreamerArgs : Arguments() {
val streamer by string {
name = "streamer"
description = "The streamer to remove"
name = Translations.Streamer.Command.Arguments.Remove.name
description = Translations.Streamer.Command.Arguments.Remove.description
require(true)
}
}

View file

@ -0,0 +1,20 @@
# Streamer Command
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.arguments.add.streamer.name=streamer
streamer.command.arguments.add.streamer.description=The streamer to add
streamer.command.arguments.add.channel.name=channel
streamer.command.arguments.add.channel.description=The channel to add the streamer to
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
# more to come...