diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..0b6a882
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,3 @@
+**.nils
+/run
+/run/
diff --git a/README.md b/README.md
index 2b9d0bc..4e4c0f6 100644
--- a/README.md
+++ b/README.md
@@ -25,9 +25,10 @@ A Discord Bot for Splatoon Teams
- Features
- Time Planner -- Make the bot send messages and reactions into a selected channel in order to make planning easier
-## Maybe upcoming features
+## (Maybe) upcoming features
- Match Planner (Send Notifications some time before a match starts)
+- Planning Notifier (Make it possible to ping people, who have time at a specific time)
- Game Tracker (Save the results of the last matches)
- Replay Saver (Maybe; will save the replay code to a database)
diff --git a/build.gradle.kts b/build.gradle.kts
index 53e1b78..4d4b3c5 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -32,7 +32,7 @@ val ownerID = 372703841151614976L
group = "net.moonleay.liljudd"
version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_SHORT_SHA")}-prod" }
?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" }
- ?: "2.2.0"
+ ?: "2.2.1"
val kordver = "1.5.6"
val coroutinesver = "1.1.0"
@@ -88,8 +88,6 @@ dependencies {
shadow("org.slf4j:slf4j-simple:2.0.3")
//Database
- shadow("io.ktor:ktor-client-core:$ktor_version")
- shadow("io.ktor:ktor-client-cio:$ktor_version")
shadow("org.jetbrains.exposed:exposed-core:$exposedver")
shadow("org.jetbrains.exposed:exposed-dao:$exposedver")
shadow("org.jetbrains.exposed:exposed-jdbc:$exposedver")
@@ -97,6 +95,8 @@ dependencies {
//Korntab
shadow("dev.inmo:krontab:$krontabver")
+ "shadow"("io.ktor:ktor-client-core-jvm:2.3.1")
+ "shadow"("io.ktor:ktor-client-cio-jvm:2.3.1")
}
diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt
index 413e0bf..66208c7 100644
--- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt
+++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt
@@ -33,7 +33,7 @@ import net.moonleay.lilJudd.data.DB
import net.moonleay.lilJudd.extensions.FeatureManageExtension
import net.moonleay.lilJudd.extensions.SendPlannerExtension
import net.moonleay.lilJudd.extensions.VersionExtension
-import net.moonleay.lilJudd.features.TimePlanner
+import net.moonleay.lilJudd.features.TimeManager
import net.moonleay.lilJudd.util.Logger
import net.moonleay.lilJudd.util.MessageUtil
import kotlin.system.exitProcess
@@ -69,7 +69,7 @@ object Bot {
// Register the TimePlanner thread
val coroutineJob = GlobalScope.launch {
- TimePlanner.registerThread()
+ TimeManager.registerThread()
}
// Add a shutdown hook to cancel the coroutine when the application is terminated
diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt
new file mode 100644
index 0000000..0798ccc
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt
@@ -0,0 +1,26 @@
+/*
+ * lilJudd
+ * Copyright (C) 2023 moonleay
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package net.moonleay.lilJudd.data.entry
+
+data class PlanningNotifierRolesData(
+ val serverID: String,
+ val channelId: String,
+ val hastimeroleid: String,
+ val wantstobenotifid: String
+)
diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifyerRoles.kt b/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt
similarity index 91%
rename from src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifyerRoles.kt
rename to src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt
index 069bcc0..65e8b0e 100644
--- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifyerRoles.kt
+++ b/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt
@@ -20,10 +20,9 @@ package net.moonleay.lilJudd.data.tables
import org.jetbrains.exposed.dao.id.IntIdTable
-object PlanningNotifyerRoles : IntIdTable() {
+object PlanningNotifierRoles : IntIdTable() {
var serverid = varchar("serverid", 50)
var channelid = varchar("channelid", 50)
var hastimeroleid = varchar("hastimeroleid", 50)
- var hastovoteid = varchar("hastovoteid", 50)
var wantstobenotifid = varchar("wantstobenotifid", 50)
}
diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt
index 373fcc7..7384c56 100644
--- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt
+++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt
@@ -29,7 +29,7 @@ import dev.kord.common.Color
import dev.kord.common.entity.Permission
import dev.kord.common.entity.Snowflake
import dev.kord.core.behavior.createRole
-import net.moonleay.lilJudd.data.tables.PlanningNotifyerRoles
+import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles
import net.moonleay.lilJudd.data.tables.TimePlanningChannels
import net.moonleay.lilJudd.extensions.component.EnableOrDisable
import net.moonleay.lilJudd.extensions.component.FeatureEnum
@@ -47,7 +47,7 @@ class FeatureManageExtension : Extension() {
/*
* Note: This has to be rewritten at some point to better support more features
- * and remove this mess of a class.
+ * and improve this mess of a class.
* */
override suspend fun setup() {
publicSlashCommand(::FeatureManagerArgs) {
@@ -62,7 +62,7 @@ class FeatureManageExtension : Extension() {
MessageUtil.getEmbed(
Color(0xE0311A),
"403: Forbidden",
- "You cannot edit features, as you don't have the Administratior permission.",
+ "You cannot edit features, as you don't have the Administrator permission.",
u.asUser().username + "#" + u.asUser().discriminator
)
)
@@ -118,37 +118,31 @@ class FeatureManageExtension : Extension() {
FeatureEnum.PLANNINGNOTIFIER -> {
var alreadyExists = false
transaction {
- alreadyExists = PlanningNotifyerRoles.select {
- (PlanningNotifyerRoles.serverid eq gID) and (PlanningNotifyerRoles.channelid eq cID)
+ alreadyExists = PlanningNotifierRoles.select {
+ (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID)
}.count() > 0
}
if (!alreadyExists) {
- val hasToVoteRole = this.guild!!.createRole {
- this.name = "Hasn't voted [${channel.data.name.value}]"
- this.mentionable = true
- }
- val htvr = hasToVoteRole.id.toString()
val hasTimeRole = this.guild!!.createRole {
- this.name = "Has time [${channel.data.name.value}]"
+ this.name = "available [${channel.data.name.value}]"
this.mentionable = true
}
val htr = hasTimeRole.id.toString()
val wantsNotifsRole = this.guild!!.createRole {
- this.name = "Wants to be notified [${channel.data.name.value}]"
+ this.name = "notifications [${channel.data.name.value}]"
this.mentionable = true
}
val wnr = wantsNotifsRole.id.toString()
transaction {
- PlanningNotifyerRoles.insert {
- it[PlanningNotifyerRoles.serverid] = gID
- it[PlanningNotifyerRoles.channelid] = cID
- it[PlanningNotifyerRoles.hastovoteid] = htvr
- it[PlanningNotifyerRoles.hastimeroleid] = htr
- it[PlanningNotifyerRoles.wantstobenotifid] = wnr
- } get PlanningNotifyerRoles.id
+ PlanningNotifierRoles.insert {
+ it[PlanningNotifierRoles.serverid] = gID
+ it[PlanningNotifierRoles.channelid] = cID
+ it[PlanningNotifierRoles.hastimeroleid] = htr
+ it[PlanningNotifierRoles.wantstobenotifid] = wnr
+ } get PlanningNotifierRoles.id
}
this.respond {
@@ -156,7 +150,7 @@ class FeatureManageExtension : Extension() {
MessageUtil.getEmbed(
Color(0x52E01A),
"200: Success",
- "The feature was enabled in channel ${args.channel.data.name.value} with roles ${hasToVoteRole.mention}, ${hasTimeRole.mention} & ${wantsNotifsRole.mention}.",
+ "The feature was enabled in channel ${args.channel.data.name.value} with roles ${hasTimeRole.mention} & ${wantsNotifsRole.mention}.",
u.asUser().username + "#" + u.asUser().discriminator
)
)
@@ -225,28 +219,27 @@ class FeatureManageExtension : Extension() {
FeatureEnum.PLANNINGNOTIFIER -> {
var alreadyExists = false
transaction {
- alreadyExists = PlanningNotifyerRoles.select {
- (PlanningNotifyerRoles.serverid eq gID) and (PlanningNotifyerRoles.channelid eq cID)
+ alreadyExists = PlanningNotifierRoles.select {
+ (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID)
}.count() > 0
}
if (alreadyExists) {
var matchingEntries: List = mutableListOf()
transaction {
- matchingEntries = PlanningNotifyerRoles.select {
- (PlanningNotifyerRoles.serverid eq gID) and
- (PlanningNotifyerRoles.channelid eq cID)
+ matchingEntries = PlanningNotifierRoles.select {
+ (PlanningNotifierRoles.serverid eq gID) and
+ (PlanningNotifierRoles.channelid eq cID)
}.toList()
}
for (e in matchingEntries) {
- this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifyerRoles.hastovoteid]))?.delete()
- this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifyerRoles.hastimeroleid]))?.delete()
- this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifyerRoles.wantstobenotifid]))
+ this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifierRoles.hastimeroleid]))?.delete()
+ this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifierRoles.wantstobenotifid]))
?.delete()
}
transaction {
matchingEntries.forEach { entry ->
- PlanningNotifyerRoles.deleteWhere { id eq entry[id] }
+ PlanningNotifierRoles.deleteWhere { id eq entry[id] }
}
}
this.respond {
diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt
index 4d3defb..2482bbf 100644
--- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt
+++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt
@@ -18,8 +18,6 @@
package net.moonleay.lilJudd.extensions
-import com.kotlindiscord.kord.extensions.commands.Arguments
-import com.kotlindiscord.kord.extensions.commands.converters.impl.int
import com.kotlindiscord.kord.extensions.extensions.Extension
import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand
import com.kotlindiscord.kord.extensions.types.respond
@@ -44,11 +42,11 @@ class SendPlannerExtension : Extension() {
get() = false
override suspend fun setup() {
- publicSlashCommand(::PlannerArgs) {
+ publicSlashCommand() {
name = "sendplanner"
description = "Send the planner for the current and x next weeks"
this.action {
- if (this.arguments.weeks == 0 || !this.member!!.asMember(this.guild!!.id)
+ if (!this.member!!.asMember(this.guild!!.id)
.hasPermission(Permission.Administrator)
) {
val res = this.respond {
@@ -65,42 +63,39 @@ class SendPlannerExtension : Extension() {
var then =
ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withDayOfMonth(getMondayDayOfMonth()).withHour(4)
.withMinute(0).withSecond(0)
- repeat(this.arguments.weeks) {
+ c.createMessage {
+ this.embeds.add(
+ MessageUtil.getEmbed(
+ Color(0X4C4645),
+ "Time Planning Feature",
+ "Do you have time on the following Days?",
+ "Automated Message"
+ )
+ )
+ }
+ delay(1000)
+ repeat(7) {
c.createMessage {
this.embeds.add(
- MessageUtil.getEmbed(
+ MessageUtil.getEmbedWithTable(
Color(0X4C4645),
- "Time Planning Feature",
- "Do you have time on the following Days?",
- "Automated Message"
- )
- )
- }
- delay(1000)
- repeat(7) {
- c.createMessage {
- this.embeds.add(
- MessageUtil.getEmbedWithTable(
- Color(0X4C4645),
- "",
- "${then.dayOfWeek.name}, ${then.dayOfMonth}.${then.monthValue}.${then.year} /${it + 1}. weekday",
- mapOf(
- "Is available" to listOf(),
- "May be available" to listOf(),
- "Is not available" to listOf()
- )
+ "",
+ "${then.dayOfWeek.name}, ${then.dayOfMonth}.${then.monthValue}.${then.year} /${it + 1}. weekday",
+ mapOf(
+ "Is available" to listOf(),
+ "May be available" to listOf(),
+ "Is not available" to listOf()
)
)
+ )
- this.actionRow {
- this.components.addAll(ButtonUtil.getTimePlannerButtons().components)
- }
+ this.actionRow {
+ this.components.addAll(ButtonUtil.getTimePlannerButtons().components)
}
- then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0)
- Logger.out("Finished sending day $it")
- delay(1000)
}
- Logger.out("Finished week $it")
+ then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0)
+ Logger.out("Finished sending day $it")
+ delay(1000)
}
Logger.out("Finished with ${c.data.guildId.value}")
}
@@ -112,12 +107,4 @@ class SendPlannerExtension : Extension() {
val monday = now.with(DayOfWeek.MONDAY)
return monday.dayOfMonth
}
-
- inner class PlannerArgs : Arguments() {
- val weeks by int {
- name = "weeks"
- description = "Amount of weeks to send. Needs to be at least 1."
- minValue = 1
- }
- }
}
diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt b/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt
new file mode 100644
index 0000000..3aab7e5
--- /dev/null
+++ b/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt
@@ -0,0 +1,36 @@
+/*
+ * lilJudd
+ * Copyright (C) 2023 moonleay
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+
+package net.moonleay.lilJudd.features
+
+import dev.inmo.krontab.buildSchedule
+import dev.inmo.krontab.doInfinity
+import net.moonleay.lilJudd.util.Logger
+
+object PlanningNotifier {
+ suspend fun registerThread() {
+ Logger.out("Adding ping scheduler...")
+ val scheduler = buildSchedule("0 00 23 * * * 0o *") // 0 0 4 * * * 0o 1w // 0o is UTC
+ scheduler.doInfinity {
+ Logger.out("Starting to update roles...")
+
+ Logger.out("Done! Until tomorrow! <3 ")
+ }
+
+ }
+}
diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimePlanner.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt
similarity index 73%
rename from src/main/kotlin/net/moonleay/lilJudd/features/TimePlanner.kt
rename to src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt
index 778673a..0da325b 100644
--- a/src/main/kotlin/net/moonleay/lilJudd/features/TimePlanner.kt
+++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt
@@ -27,6 +27,8 @@ import dev.kord.core.entity.channel.MessageChannel
import dev.kord.rest.builder.message.create.actionRow
import kotlinx.coroutines.delay
import net.moonleay.lilJudd.Bot
+import net.moonleay.lilJudd.data.entry.PlanningNotifierRolesData
+import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles
import net.moonleay.lilJudd.data.tables.TimePlanningChannels
import net.moonleay.lilJudd.util.ButtonUtil
import net.moonleay.lilJudd.util.Logger
@@ -37,7 +39,7 @@ import java.time.ZoneId
import java.time.ZonedDateTime
-object TimePlanner {
+object TimeManager {
/* /--------------- Seconds
| /------------- Minutes
| | /----------- Hours
@@ -49,23 +51,43 @@ object TimePlanner {
* * * * * * 0o *w*/
suspend fun registerThread() {
- Logger.out("Adding scheduler...")
- val scheduler = buildSchedule("0 0 4 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC
+ Logger.out("Adding message scheduler...")
+ val scheduler = buildSchedule("0 00 23 * * * 0o *") // 0 0 4 * * * 0o 1w // 0o is UTC
scheduler.doInfinity {
Logger.out("Starting to notify...")
- val channelList = mutableListOf()
+
+
+ // ChannelID, ServerID
+ val channelList = mutableMapOf()
+ // ChannelID, Data
+ val roleList = mutableMapOf()
+
transaction {
for (tp in TimePlanningChannels.selectAll()) {
- channelList.add(Snowflake(tp[TimePlanningChannels.channelid]))
+ channelList[Snowflake(tp[TimePlanningChannels.channelid])] =
+ Snowflake(tp[TimePlanningChannels.serverid])
Logger.out("Have to notify channel with ID ${tp[TimePlanningChannels.channelid]}.")
}
+
+ for (pnr in PlanningNotifierRoles.selectAll()) {
+ roleList[Snowflake(pnr[PlanningNotifierRoles.channelid])] = PlanningNotifierRolesData(
+ pnr[PlanningNotifierRoles.serverid],
+ pnr[PlanningNotifierRoles.channelid],
+ pnr[PlanningNotifierRoles.hastimeroleid],
+ pnr[PlanningNotifierRoles.wantstobenotifid]
+ )
+ Logger.out("Have to ping roles: ${pnr[PlanningNotifierRoles.wantstobenotifid]}}")
+ }
}
- Logger.out("${channelList.count()} Channels to notify!")
- for (ch in channelList) {
+ Logger.out("${channelList.count()} Channels to notify with ${roleList.count()} Roles to ping!")
+ for (ch in channelList.keys) {
if (Bot.bot.kordRef.getChannel(ch) == null)
continue // TODO: Check if the channel is valid in another shard
val c = Bot.bot.kordRef.getChannelOf(ch)!!
c.createMessage {
+ if (roleList[ch] != null) {
+ this.content = "<@&${Snowflake(roleList[ch]?.wantstobenotifid!!)}>"
+ }
this.embeds.add(
MessageUtil.getEmbed(
Color(0X4C4645),
@@ -75,7 +97,7 @@ object TimePlanner {
)
)
}
- delay(3000)
+ delay(2000)
var then = ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withHour(4).withMinute(0).withSecond(0)
repeat(7) {
c.createMessage {
@@ -98,6 +120,7 @@ object TimePlanner {
}
then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0)
Logger.out("Finished sending day $it")
+
delay(1000)
}
Logger.out("Finished with ${c.data.guildId.value}")