From b45d8ffd6e74d2a88327154018cb8800b3df5197 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 5 Jun 2023 12:10:25 +0200 Subject: [PATCH 001/168] chore: progress commit. refactored TimePlanner, added stuff to Feature Manage Extension, added db stuff Signed-off-by: limited_dev --- README.md | 3 +- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 4 +- .../data/entry/PlanningNotifierRolesData.kt | 26 ++++++++++ ...ifyerRoles.kt => PlanningNotifierRoles.kt} | 3 +- .../extensions/FeatureManageExtension.kt | 51 ++++++++----------- .../lilJudd/features/PlanningNotifier.kt | 36 +++++++++++++ .../{TimePlanner.kt => TimeManager.kt} | 42 +++++++++++---- 7 files changed, 122 insertions(+), 43 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt rename src/main/kotlin/net/moonleay/lilJudd/data/tables/{PlanningNotifyerRoles.kt => PlanningNotifierRoles.kt} (91%) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt rename src/main/kotlin/net/moonleay/lilJudd/features/{TimePlanner.kt => TimeManager.kt} (71%) 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/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index eef040b..311616d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -32,7 +32,7 @@ import net.moonleay.lilJudd.data.CredentialManager import net.moonleay.lilJudd.data.DB import net.moonleay.lilJudd.extensions.FeatureManageExtension 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 @@ -68,7 +68,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 43cfbd4..582a079 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 @@ -45,7 +45,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) { @@ -60,7 +60,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 ) ) @@ -116,37 +116,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 { @@ -154,7 +148,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 ) ) @@ -223,28 +217,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/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 71% rename from src/main/kotlin/net/moonleay/lilJudd/features/TimePlanner.kt rename to src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index a8bb189..403dec8 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 { @@ -96,8 +118,10 @@ object TimePlanner { this.components.addAll(ButtonUtil.getTimePlannerButtons().components) } } - then = then.plusDays(1).withHour(20).withMinute(24).withSecond(0) + 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}") -- 2.45.2 From 8bebe08b150301a956c7213121332b93812a7d3d Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 15 Jun 2023 08:06:35 +0200 Subject: [PATCH 002/168] feat: added .dockerignore Signed-off-by: limited_dev --- .dockerignore | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 .dockerignore diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0b6a882 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,3 @@ +**.nils +/run +/run/ -- 2.45.2 From 9885466ed580aa8b1e1d00338699a61f01332adb Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 15 Jun 2023 08:07:15 +0200 Subject: [PATCH 003/168] !fix: removed not properly usable sendplanner command Signed-off-by: limited_dev --- .../extensions/SendPlannerExtension.kt | 67 ++++++++----------- 1 file changed, 27 insertions(+), 40 deletions(-) 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 - } - } } -- 2.45.2 From bcf9b2cf9ba2671e8713ff1410a54bc03e85dd7f Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 15 Jun 2023 08:07:26 +0200 Subject: [PATCH 004/168] chore: bump version Signed-off-by: limited_dev --- build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) 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") } -- 2.45.2 From 27b721ae1fdfa070da7e669e9a22b4f6dc47de11 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 15 Jun 2023 08:51:32 +0200 Subject: [PATCH 005/168] fix: removed nonexistent feature in feature command, fixed timing on timeplanner. Signed-off-by: limited_dev --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 3 ++- .../lilJudd/extensions/FeatureManageExtension.kt | 15 +++++++++------ .../lilJudd/extensions/component/FeatureEnum.kt | 2 +- .../moonleay/lilJudd/features/PlanningNotifier.kt | 2 +- .../net/moonleay/lilJudd/features/TimeManager.kt | 2 +- 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 66208c7..e0c4a41 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -53,7 +53,7 @@ object Bot { exitProcess(3) } - // Check if the credentials for the Database are existent + // Check if the credentials for the Database are existent, don't run if they are missing if (CredentialManager.dbDomain == "empty" || CredentialManager.dbName == "empty" || CredentialManager.dbUser == "empty" || CredentialManager.dbPassword == "empty") { Logger.out("The config does not contain the whole Database credentials.") exitProcess(3) @@ -70,6 +70,7 @@ object Bot { // Register the TimePlanner thread val coroutineJob = GlobalScope.launch { TimeManager.registerThread() + //PlanningNotifier.registerThread() } // Add a shutdown hook to cancel the coroutine when the application is terminated diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index 7384c56..712eb8b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -27,16 +27,16 @@ import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission 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.PlanningNotifierRoles import net.moonleay.lilJudd.data.tables.TimePlanningChannels import net.moonleay.lilJudd.extensions.component.EnableOrDisable import net.moonleay.lilJudd.extensions.component.FeatureEnum import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil -import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.transactions.transaction class FeatureManageExtension : Extension() { @@ -115,6 +115,8 @@ class FeatureManageExtension : Extension() { } } + + /* FeatureEnum.PLANNINGNOTIFIER -> { var alreadyExists = false transaction { @@ -167,7 +169,7 @@ class FeatureManageExtension : Extension() { ) ) } - } + } */ } return@action } @@ -216,6 +218,7 @@ class FeatureManageExtension : Extension() { } } + /* FeatureEnum.PLANNINGNOTIFIER -> { var alreadyExists = false transaction { @@ -264,7 +267,7 @@ class FeatureManageExtension : Extension() { ) ) } - } + } */ } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/FeatureEnum.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/component/FeatureEnum.kt index 7766f39..3c590fc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/FeatureEnum.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/component/FeatureEnum.kt @@ -22,5 +22,5 @@ import com.kotlindiscord.kord.extensions.commands.application.slash.converters.C enum class FeatureEnum(override val readableName: String) : ChoiceEnum { TIMEPLANNINGFEATURE("Time Planning Feature"), - PLANNINGNOTIFIER("Planning Notifier") + //PLANNINGNOTIFIER("Planning Notifier") } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt b/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt index 3aab7e5..fd9329c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt @@ -25,7 +25,7 @@ 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 + val scheduler = buildSchedule("0 0 4 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { Logger.out("Starting to update roles...") diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 0da325b..91fcd80 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -52,7 +52,7 @@ object TimeManager { suspend fun registerThread() { Logger.out("Adding message scheduler...") - val scheduler = buildSchedule("0 00 23 * * * 0o *") // 0 0 4 * * * 0o 1w // 0o is UTC + val scheduler = buildSchedule("0 0 4 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { Logger.out("Starting to notify...") -- 2.45.2 From 89e1c750f9e6b9c733a942ecb8f4883706509966 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 15 Jun 2023 08:52:00 +0200 Subject: [PATCH 006/168] chore: bump version Signed-off-by: limited_dev --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4d4b3c5..b949e67 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.1" + ?: "2.2.1.1" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From cea3e17617f1e0670c45a9c9f596aee5cdac2e41 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 15 Jun 2023 09:08:55 +0200 Subject: [PATCH 007/168] chore: update README.md Signed-off-by: limited_dev --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 4e4c0f6..3f46d3a 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,7 @@ A Discord Bot for Splatoon Teams ## Known issues -- There is a bug with the TimePlanning feature. This bug makes the bot not remove the user properly, the result looks - like [this](https://cdn.discordapp.com/attachments/1015606848797290566/1110671293436661812/image.png) +- None. (yet) If you encounter any bugs, message me (moonleay) on Discord or send me a mail. (issues@moonleay.net) ## Commands & Features -- 2.45.2 From fe70c3f6bbdfff4a02ce38782e968e1e90775e5a Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 18 Jun 2023 18:16:17 +0200 Subject: [PATCH 008/168] chore: update README.md Signed-off-by: limited_dev --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f46d3a..104d6b9 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,10 @@ A Discord Bot for Splatoon Teams ## Known issues -- None. (yet) If you encounter any bugs, message me (moonleay) on Discord or send me a mail. (issues@moonleay.net) +- There is a bug with being able to register the same feature in the same channel without checking if it is already + active + +##### If you encounter any bugs, message me on Discord (@moonleay) or send me a mail (issues@moonleay.net). ## Commands & Features -- 2.45.2 From 48b0384628089aaf3f4851c7e3f59942af9f1dfb Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 22 Jun 2023 07:49:08 +0200 Subject: [PATCH 009/168] chore: upgrade krontab Signed-off-by: limited_dev --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index b949e67..135459a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,7 +39,7 @@ val coroutinesver = "1.1.0" val ktor_version = "2.3.0" val exposedver = "0.40.1" val postgresver = "42.3.8" -val krontabver = "1.0.0" +val krontabver = "2.0.0" val mavenArtifact = "lilJudd" project.base.archivesName.set(mavenArtifact) -- 2.45.2 From da0edb762cbe1bb9a8fb9a6c2b8749322803cb33 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Sat, 24 Jun 2023 15:58:49 +0200 Subject: [PATCH 010/168] chore: update README.md Signed-off-by: limited_dev --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 104d6b9..981e03c 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,12 @@ A Discord Bot for Splatoon Teams - Game Tracker (Save the results of the last matches) - Replay Saver (Maybe; will save the replay code to a database) +## TODO + +- Rewrite the feature system +- Rewrite the Cronjob system +- Rewrite the Database connection system (from transactions all over the place to a single package with transactions) + ## How to self-host (using the Docker container) 1. Pull the container -- 2.45.2 From 7115a74e1615b499217f11e49813b9f69b59a60b Mon Sep 17 00:00:00 2001 From: limited_dev Date: Sat, 24 Jun 2023 16:18:26 +0200 Subject: [PATCH 011/168] chore: bump version Signed-off-by: limited_dev --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 135459a..6fd7fe7 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.1.1" + ?: "2.3.0" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From 865964aebe4b7c3b2b9443cf572d4875864630a8 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:35:04 +0200 Subject: [PATCH 012/168] chore: update README.md Signed-off-by: limited_dev --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 981e03c..f6d28e8 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ A Discord Bot for Splatoon Teams - 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) +- Rndm map command ## TODO -- 2.45.2 From 0a16994e61c7e8e4c7eae2bc45ea9165acd94971 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 28 Jun 2023 22:38:26 +0200 Subject: [PATCH 013/168] feat: add MemberIntent Signed-off-by: limited_dev --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index e0c4a41..e7247a7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -24,6 +24,8 @@ import dev.kord.common.entity.PresenceStatus import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.event.interaction.ButtonInteractionCreateEvent import dev.kord.core.on +import dev.kord.gateway.Intent +import dev.kord.gateway.PrivilegedIntent import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.launch import net.moonleay.botendo.build.BuildConstants @@ -41,6 +43,8 @@ import kotlin.system.exitProcess object Bot { //The kord object gets set at app launch lateinit var bot: ExtensibleBot + + @OptIn(PrivilegedIntent::class) suspend fun start() { Logger.out("Starting Bot...") @@ -89,6 +93,7 @@ object Bot { add(::VersionExtension) add(::FeatureManageExtension) add(::SendPlannerExtension) + //add(::UpdateRolesExtension) // This command is only for debugging purposes //add(::TestExtension) // See comment in TestExtension.kt } @@ -97,7 +102,11 @@ object Bot { this.playing("v." + BuildConstants.version) } - // Sharding will be added if the load of the bot cannot be handled by one instance + this.intents { + +Intent.GuildMembers + } + + // Will add Sharding someday, I promise /* sharding { recommended -> Shards(recommended) -- 2.45.2 From 8bca3838bc3e1be2246528b043e0a4746e56524a Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:39:15 +0200 Subject: [PATCH 014/168] feat: split getDelay function into three different getDelay functions Signed-off-by: limited_dev --- .../net/moonleay/lilJudd/util/TimeUtil.kt | 20 +++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt index 1edfe17..7e5fbec 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt @@ -18,7 +18,10 @@ package net.moonleay.lilJudd.util +import kotlinx.datetime.DayOfWeek import java.time.Duration +import java.time.ZoneId +import java.time.ZonedDateTime import java.util.concurrent.TimeUnit @@ -123,7 +126,20 @@ object TimeUtil { } } - fun getDelay(day: String): Int { - return DaysUntilMonday[day]!! + + // Returns the day of the month of the monday of this week + fun getMondayDayOfMonth(): Int { + return ZonedDateTime.now().with(DayOfWeek.MONDAY).dayOfMonth + } + + // Returns the day of the week as an int. Monday = 0; Sunday = 6 + fun getDayOfMonthInt(dow: DayOfWeek): Int { + return dow.value + } + + // Returns the day of the month of the monday of the current week + fun getWeekStamp(): ZonedDateTime { + return ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withDayOfMonth(getMondayDayOfMonth()).withHour(4) + .withMinute(0).withSecond(0) } } -- 2.45.2 From 4bc2fe69301aa03c4b45672776c432bf9826b643 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:40:27 +0200 Subject: [PATCH 015/168] feat: added get Users in the first X fields fix: fixed typo in May be available button chore: renamed ButtonUtil to EmbedUtil Signed-off-by: limited_dev --- .../util/{ButtonUtil.kt => EmbedUtil.kt} | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) rename src/main/kotlin/net/moonleay/lilJudd/util/{ButtonUtil.kt => EmbedUtil.kt} (82%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/ButtonUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt similarity index 82% rename from src/main/kotlin/net/moonleay/lilJudd/util/ButtonUtil.kt rename to src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt index a172965..831d4e7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/ButtonUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt @@ -23,14 +23,14 @@ import dev.kord.core.entity.Embed import dev.kord.rest.builder.component.ActionRowBuilder import dev.kord.rest.builder.message.EmbedBuilder -object ButtonUtil { +object EmbedUtil { fun getTimePlannerButtons(): ActionRowBuilder { val ar = ActionRowBuilder() ar.interactionButton(ButtonStyle.Success, "public.edit.btn.timemanagement.available") { this.label = "Available" } ar.interactionButton(ButtonStyle.Primary, "public.edit.btn.timemanagement.maybeavailable") { - this.label = "Maybe available" + this.label = "May be available" } ar.interactionButton(ButtonStyle.Danger, "public.edit.btn.timemanagement.notavailable") { this.label = "Not available" @@ -60,6 +60,21 @@ object ButtonUtil { return ebb } + fun getAllUsersInTheFirstXTables(amountOfTables: Int, e: Embed): List { + val users = mutableListOf() + for (i in 0 until amountOfTables - 1) { + val f = e.fields[i] + if (!f.value.contains("@")) + continue // check next one. this one does not have any entries + val v = f.value.split("\n").toMutableList() + for (l in v) { + Logger.out(l) + users.add(l.subSequence(2, l.indexOf(">")).toString()) + } + } + return users + } + fun addXToValuesAtTable(x: String, e: Embed, table: Int): EmbedBuilder { val ebb = MessageUtil.getAClonedEmbedd(e) for ((i, f) in e.fields.withIndex()) { -- 2.45.2 From ce25b20a353339663fe340e0b7f67a0a4689e3fb Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:41:53 +0200 Subject: [PATCH 016/168] feat: add TimePlanningMessagesTable Signed-off-by: limited_dev --- .../data/tables/TimePlanningMessages.kt | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt b/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt new file mode 100644 index 0000000..7498edb --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt @@ -0,0 +1,28 @@ +/* + * 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.tables + +import org.jetbrains.exposed.dao.id.IntIdTable + +object TimePlanningMessages : IntIdTable() { + var serverid = varchar("serverid", 50) + var channelid = varchar("channelid", 50) + var weekstamp = varchar("weekstamp", 50) + var messageids = varchar("messageids", 200) +} -- 2.45.2 From d99d4686802f145748e838d9353a32ae221c7aa3 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:42:22 +0200 Subject: [PATCH 017/168] fix: fixed wantstobenotifiedid in PlanningNotifierRoles Signed-off-by: limited_dev --- .../net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt b/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt index 65e8b0e..d8d3b9d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt @@ -24,5 +24,5 @@ object PlanningNotifierRoles : IntIdTable() { var serverid = varchar("serverid", 50) var channelid = varchar("channelid", 50) var hastimeroleid = varchar("hastimeroleid", 50) - var wantstobenotifid = varchar("wantstobenotifid", 50) + var wantstobenotifiedid = varchar("wantstobenotifiedid", 50) } -- 2.45.2 From 46df0a1371f05114edea50c9bb572e6e3ff9179f Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:42:43 +0200 Subject: [PATCH 018/168] chore: add comments to PlanningNotifierRolesData Signed-off-by: limited_dev --- .../lilJudd/data/entry/PlanningNotifierRolesData.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt index 0798ccc..8cba107 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt @@ -19,8 +19,8 @@ package net.moonleay.lilJudd.data.entry data class PlanningNotifierRolesData( - val serverID: String, - val channelId: String, - val hastimeroleid: String, - val wantstobenotifid: String + val serverID: String, // The id of the server + val channelId: String, // The id of the channel + val hastimeroleid: String, // The id of the role that has time today + val wantstobenotifid: String // The id of the role that wants to be notified ) -- 2.45.2 From 3aeefefd32ad70cc69b25fedf44bdd6cb02ab015 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:43:08 +0200 Subject: [PATCH 019/168] feat: added TimePlanningMessagesData Signed-off-by: limited_dev --- .../data/entry/TimePlanningMessagesData.kt | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt new file mode 100644 index 0000000..3da4ba8 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.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 TimePlanningMessagesData( + val serverid: String, // The discord server id + val channelid: String, // The discord channel id + val weekstamp: String, // The timestamp of the monday of the week at 4am UTC + val messageids: String // IDs are in the following format: "{weekdayNr}:{id};{weekdayNr}:{id};[etc.]" +) -- 2.45.2 From 03fa8a51a78c14535f7bb04f95ac2d266c1ceadd Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:43:55 +0200 Subject: [PATCH 020/168] feat: save messageids to database Signed-off-by: limited_dev --- .../moonleay/lilJudd/features/TimeManager.kt | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 91fcd80..a920e02 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -30,9 +30,12 @@ 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.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.lilJudd.util.TimeUtil +import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction import java.time.ZoneId @@ -62,6 +65,8 @@ object TimeManager { // ChannelID, Data val roleList = mutableMapOf() + var msgStr = "" + transaction { for (tp in TimePlanningChannels.selectAll()) { channelList[Snowflake(tp[TimePlanningChannels.channelid])] = @@ -74,9 +79,9 @@ object TimeManager { pnr[PlanningNotifierRoles.serverid], pnr[PlanningNotifierRoles.channelid], pnr[PlanningNotifierRoles.hastimeroleid], - pnr[PlanningNotifierRoles.wantstobenotifid] + pnr[PlanningNotifierRoles.wantstobenotifiedid] ) - Logger.out("Have to ping roles: ${pnr[PlanningNotifierRoles.wantstobenotifid]}}") + Logger.out("Have to ping roles: ${pnr[PlanningNotifierRoles.wantstobenotifiedid]}}") } } Logger.out("${channelList.count()} Channels to notify with ${roleList.count()} Roles to ping!") @@ -86,7 +91,8 @@ object TimeManager { val c = Bot.bot.kordRef.getChannelOf(ch)!! c.createMessage { if (roleList[ch] != null) { - this.content = "<@&${Snowflake(roleList[ch]?.wantstobenotifid!!)}>" + this.content = + "The weekly planning starts now <@&${Snowflake(roleList[ch]?.wantstobenotifid!!)}>" } this.embeds.add( MessageUtil.getEmbed( @@ -100,7 +106,7 @@ object TimeManager { delay(2000) var then = ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withHour(4).withMinute(0).withSecond(0) repeat(7) { - c.createMessage { + val msg = c.createMessage { this.embeds.add( MessageUtil.getEmbedWithTable( Color(0X4C4645), @@ -115,14 +121,25 @@ object TimeManager { ) this.actionRow { - this.components.addAll(ButtonUtil.getTimePlannerButtons().components) + this.components.addAll(EmbedUtil.getTimePlannerButtons().components) } } + msgStr += "${it}:${msg.id.value};" then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0) Logger.out("Finished sending day $it") delay(1000) } + + // Save the message ids + transaction { + TimePlanningMessages.insert { + it[TimePlanningMessages.serverid] = c.data.guildId.value.toString() + it[TimePlanningMessages.channelid] = c.id.value.toString() + it[TimePlanningMessages.weekstamp] = TimeUtil.getWeekStamp().toOffsetDateTime().toString() + it[TimePlanningMessages.messageids] = msgStr + } get PlanningNotifierRoles.id + } Logger.out("Finished with ${c.data.guildId.value}") } Logger.out("Done! Until next Monday! <3 ") -- 2.45.2 From 2e63bee9a6849feecc243af3a86dac9eb5367830 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 28 Jun 2023 22:44:52 +0200 Subject: [PATCH 021/168] feat: added PlanningRoles feature to FeatureEnum, added AvailabilityManager with Cronjob chore: moved FeatureEnum from .extensions.component to .features.component Signed-off-by: limited_dev --- .../lilJudd/features/AvailabilityManager.kt | 146 ++++++++++++++++++ .../component/FeatureEnum.kt | 4 +- 2 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt rename src/main/kotlin/net/moonleay/lilJudd/{extensions => features}/component/FeatureEnum.kt (90%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt new file mode 100644 index 0000000..8961ef1 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -0,0 +1,146 @@ +/* + * 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 dev.kord.common.entity.Snowflake +import dev.kord.core.behavior.requestMembers +import dev.kord.core.entity.channel.MessageChannel +import dev.kord.gateway.PrivilegedIntent +import net.moonleay.lilJudd.Bot +import net.moonleay.lilJudd.data.entry.PlanningNotifierRolesData +import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData +import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles +import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.util.EmbedUtil +import net.moonleay.lilJudd.util.Logger +import net.moonleay.lilJudd.util.TimeUtil +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.transactions.transaction +import java.time.ZonedDateTime + +object AvailabilityManager { + + // This runs during the cronjob. + @OptIn(PrivilegedIntent::class) + suspend fun runThread() { + // ChannelID, Data + val messageMap = mutableMapOf() + // ChannelID, Data + val roleMap = mutableMapOf() + + transaction { + for (pnr in TimePlanningMessages.select { + TimePlanningMessages.weekstamp eq (TimeUtil.getWeekStamp().toEpochSecond() * 1000).toString() + }) { + messageMap[Snowflake(pnr[TimePlanningMessages.channelid])] = + TimePlanningMessagesData( + pnr[TimePlanningMessages.serverid], + pnr[TimePlanningMessages.channelid], + pnr[TimePlanningMessages.weekstamp], + pnr[TimePlanningMessages.messageids] + ) + } + for (pnr in PlanningNotifierRoles.selectAll()) { + roleMap[pnr[PlanningNotifierRoles.channelid]] = + PlanningNotifierRolesData( + pnr[PlanningNotifierRoles.serverid], + pnr[PlanningNotifierRoles.channelid], + pnr[PlanningNotifierRoles.hastimeroleid], + pnr[PlanningNotifierRoles.wantstobenotifiedid] + ) + } + } + + val weekday = ZonedDateTime.now().dayOfWeek // The current week day + val weekStamp = TimeUtil.getWeekStamp().toEpochSecond() * 1000 // The current week time stamp + Logger.out("It is week ${weekStamp} and day ${weekday}/${TimeUtil.getDayOfMonthInt(weekday)} of the week.") + for (snf in messageMap.keys) { // snf = Snowflake + val data = messageMap[snf]!! // this is the data of the table + if (Bot.bot.kordRef.getChannel(Snowflake(data.channelid)) == null) + continue // This channel does not exist anymore. + val c = + Bot.bot.kordRef.getChannelOf(Snowflake(data.channelid))!! // Get the channel as MessageChannel + val roleData = roleMap[data.channelid]!! // Get the role data + val g = Bot.bot.kordRef.getGuildOrThrow(Snowflake(data.serverid)) + // Get all members with the role + val mce = g.requestMembers { + this.requestAllMembers() + } + mce.collect { it1 -> + it1.members.forEach { + Logger.out("Checking member ${it.id.value}") + if (it.roleIds.contains(Snowflake(roleData.hastimeroleid))) + it.removeRole(Snowflake(roleData.hastimeroleid)) + } + } + + Logger.out("Got through all members") + // This stores the ids of the messages. + // The format is weekdaNR:ID + // The last entry (nr 8) is empty, so we can ignore it + val messageIdSplit = data.messageids.split(";").subList(0, 7) + for (mid in messageIdSplit) { + Logger.out("Checking id $mid") + if (!mid.startsWith((TimeUtil.getDayOfMonthInt(weekday) - 1).toString(), true)) + continue // This is not the right message, check the next one + val idFiltered = mid.split(":")[1] // This is the target message id + val message = c.getMessageOrNull(Snowflake(idFiltered)) // Get the message from the channel + if (message == null) { + Logger.out("Could not find message.") + break // This message does not exist anymore. Nothing we can do about that. + } + if (message.data.embeds.isEmpty()) { + Logger.out("There are no embeds.") + break // There are no embeds or there are not enough embeds + } + val targets = EmbedUtil.getAllUsersInTheFirstXTables(2, message.embeds[0]) + for (tid in targets) { + Logger.out("Checking id $tid") + if (Bot.bot.kordRef.getGuildOrNull(Snowflake(data.serverid))!! + .getMemberOrNull(Snowflake(tid)) == null + ) + continue // This member does not exist anymore. + val member = Bot.bot.kordRef.getGuildOrThrow(Snowflake(data.serverid)) + .getMember(Snowflake(tid)) // Get the member + if (member.roleIds.contains(Snowflake(roleData.hastimeroleid))) + continue // This member already has the role + member.addRole(Snowflake(roleData.hastimeroleid)) // Add the role + Logger.out("Added role to ${member.username}") + } + Logger.out("Done with message. Moving on...") + // We found the right message. We don't need to check the others. + break + } + } + Logger.out("Done! Until tomorrow! <3 ") + } + + suspend fun registerThread() { + Logger.out("Adding availability scheduler...") + val scheduler = buildSchedule("0 0 5 * * * 0o *w") // 0 0 4 * * * 0o 1w // 0o is UTC + scheduler.doInfinity { + + this.runThread() + } + Logger.out("Starting to update roles...") + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/FeatureEnum.kt b/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureEnum.kt similarity index 90% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/component/FeatureEnum.kt rename to src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureEnum.kt index 3c590fc..8b3a0a8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/FeatureEnum.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureEnum.kt @@ -16,11 +16,11 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions.component +package net.moonleay.lilJudd.features.component import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum enum class FeatureEnum(override val readableName: String) : ChoiceEnum { TIMEPLANNINGFEATURE("Time Planning Feature"), - //PLANNINGNOTIFIER("Planning Notifier") + PLANNINGROLES("Planning Roles") } -- 2.45.2 From 04ff442d86858f06d80eda33175a94da5070ad5e Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:47:13 +0200 Subject: [PATCH 022/168] feat: started working on improving feature system, added Feature, added FeatureManager to store all Features Signed-off-by: limited_dev --- .../Feature.kt} | 20 ++++++---------- .../features/component/FeatureManager.kt | 24 +++++++++++++++++++ 2 files changed, 31 insertions(+), 13 deletions(-) rename src/main/kotlin/net/moonleay/lilJudd/features/{PlanningNotifier.kt => component/Feature.kt} (58%) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt b/src/main/kotlin/net/moonleay/lilJudd/features/component/Feature.kt similarity index 58% rename from src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt rename to src/main/kotlin/net/moonleay/lilJudd/features/component/Feature.kt index fd9329c..da04430 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/PlanningNotifier.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/component/Feature.kt @@ -16,21 +16,15 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.features +package net.moonleay.lilJudd.features.component -import dev.inmo.krontab.buildSchedule -import dev.inmo.krontab.doInfinity -import net.moonleay.lilJudd.util.Logger +import dev.kord.core.entity.Message -object PlanningNotifier { - suspend fun registerThread() { - Logger.out("Adding ping scheduler...") - val scheduler = buildSchedule("0 0 4 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC - scheduler.doInfinity { - Logger.out("Starting to update roles...") +interface Feature { + val feature: FeatureEnum - Logger.out("Done! Until tomorrow! <3 ") - } + fun enable(): Message + fun disable(): Message - } + suspend fun registerThread() } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt new file mode 100644 index 0000000..76af6f1 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt @@ -0,0 +1,24 @@ +/* + * 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.component + +object FeatureManager { + // See note in Feature.kt + val features = mutableListOf() +} -- 2.45.2 From fb287b24cf29381da7ae37180a004bed1337b390 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:48:27 +0200 Subject: [PATCH 023/168] chore: Renamed ButtonUtil to EmbedUtil Signed-off-by: limited_dev --- .../lilJudd/buttons/timeplanner/IsAvailableEditButton.kt | 6 +++--- .../lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt | 6 +++--- .../lilJudd/buttons/timeplanner/NotAvailableEditButton.kt | 6 +++--- .../kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt index aa9f5d6..5d9802c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt @@ -27,7 +27,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.EditButton -import net.moonleay.lilJudd.util.ButtonUtil +import net.moonleay.lilJudd.util.EmbedUtil class IsAvailableEditButton : EditButton("public.edit.btn.timemanagement.available") { override suspend fun onInteraction( @@ -40,7 +40,7 @@ class IsAvailableEditButton : EditButton("public.edit.btn.timemanagement.availab if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { this.embed { - val temp = ButtonUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 1) + val temp = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 1) this.color = temp.color this.title = temp.title this.description = temp.description @@ -51,7 +51,7 @@ class IsAvailableEditButton : EditButton("public.edit.btn.timemanagement.availab } else { Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { this.embed { - val temp = ButtonUtil.addXToValuesAtTable(user.id.value.toString(), m.embeds[0], 1) + val temp = EmbedUtil.addXToValuesAtTable(user.id.value.toString(), m.embeds[0], 1) this.color = temp.color this.title = temp.title this.description = temp.description diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt index 8c4c8ca..bac99ac 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt @@ -27,7 +27,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.EditButton -import net.moonleay.lilJudd.util.ButtonUtil +import net.moonleay.lilJudd.util.EmbedUtil class MaybeAvailableEditButton : EditButton("public.edit.btn.timemanagement.maybeavailable") { override suspend fun onInteraction( @@ -40,7 +40,7 @@ class MaybeAvailableEditButton : EditButton("public.edit.btn.timemanagement.mayb if (m.embeds[0].fields[1].value.contains(user.id.value.toString())) { Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { this.embed { - val temp = ButtonUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 2) + val temp = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 2) this.color = temp.color this.title = temp.title this.description = temp.description @@ -51,7 +51,7 @@ class MaybeAvailableEditButton : EditButton("public.edit.btn.timemanagement.mayb } else { Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { this.embed { - val temp = ButtonUtil.addXToValuesAtTable(user.id.value.toString(), m.embeds[0], 2) + val temp = EmbedUtil.addXToValuesAtTable(user.id.value.toString(), m.embeds[0], 2) this.color = temp.color this.title = temp.title this.description = temp.description diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt index dddb720..4c691e4 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt @@ -27,7 +27,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.EditButton -import net.moonleay.lilJudd.util.ButtonUtil +import net.moonleay.lilJudd.util.EmbedUtil class NotAvailableEditButton : EditButton("public.edit.btn.timemanagement.notavailable") { @@ -41,7 +41,7 @@ class NotAvailableEditButton : EditButton("public.edit.btn.timemanagement.notava if (m.embeds[0].fields[2].value.contains(user.id.value.toString())) { Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { this.embed { - val temp = ButtonUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 3) + val temp = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 3) this.color = temp.color this.title = temp.title this.description = temp.description @@ -52,7 +52,7 @@ class NotAvailableEditButton : EditButton("public.edit.btn.timemanagement.notava } else { Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { this.embed { - val temp = ButtonUtil.addXToValuesAtTable(user.id.value.toString(), m.embeds[0], 3) + val temp = EmbedUtil.addXToValuesAtTable(user.id.value.toString(), m.embeds[0], 3) this.color = temp.color this.title = temp.title this.description = temp.description diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt index 049b2e5..90cda76 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt @@ -23,7 +23,7 @@ import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.types.respond import dev.kord.common.Color import dev.kord.rest.builder.message.create.actionRow -import net.moonleay.lilJudd.util.ButtonUtil +import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.MessageUtil /* This extension has no proper use. @@ -53,7 +53,7 @@ class TestExtension : Extension() { ) this.actionRow { - this.components.addAll(ButtonUtil.getTimePlannerButtons().components) + this.components.addAll(EmbedUtil.getTimePlannerButtons().components) } } } -- 2.45.2 From ae0d67f3fdb4f5984e0a12a19b8949463645f18b Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:48:46 +0200 Subject: [PATCH 024/168] feat: added UpdateRolesExtension for debugging Signed-off-by: limited_dev --- .../extensions/UpdateRolesExtension.kt | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt new file mode 100644 index 0000000..109e3c7 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt @@ -0,0 +1,62 @@ +/* + * 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.extensions + +import com.kotlindiscord.kord.extensions.extensions.Extension +import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import com.kotlindiscord.kord.extensions.types.respond +import com.kotlindiscord.kord.extensions.utils.hasPermission +import dev.kord.common.entity.Permission +import dev.kord.gateway.PrivilegedIntent +import net.moonleay.lilJudd.features.AvailabilityManager +import net.moonleay.lilJudd.util.Logger + +class UpdateRolesExtension : Extension() { + override val name = "updateroles" + override val allowApplicationCommandInDMs: Boolean + get() = false + + @OptIn(PrivilegedIntent::class) + override suspend fun setup() { + publicSlashCommand() { + name = "updateroles" + description = "Update the roles of the members in the current server" + this.action { + if (!this.member!!.asMember(this.guild!!.id) + .hasPermission(Permission.Administrator) + ) { + val res = this.respond { + this.content = "no." + } + res.delete() + return@action + } + val res = this.respond { + this.content = "OK." + } + + + // -- below here is the code of the cronjob -- + Logger.out("Starting to update roles...") + + AvailabilityManager.runThread() + } + } + } +} -- 2.45.2 From 5c488fa91df110b5a742ec8ba381d6a3a9781363 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:50:34 +0200 Subject: [PATCH 025/168] feat: (re)added PlanningRolesFeature fix: fixed being able to register TimePlanningFeature multiple times in the same channel chore: added comments Signed-off-by: limited_dev --- .../extensions/FeatureManageExtension.kt | 39 ++++++++++++------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index 712eb8b..901387c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -27,16 +27,16 @@ import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission 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.PlanningNotifierRoles import net.moonleay.lilJudd.data.tables.TimePlanningChannels import net.moonleay.lilJudd.extensions.component.EnableOrDisable -import net.moonleay.lilJudd.extensions.component.FeatureEnum +import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil +import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.deleteWhere -import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.select import org.jetbrains.exposed.sql.transactions.transaction class FeatureManageExtension : Extension() { @@ -80,7 +80,7 @@ class FeatureManageExtension : Extension() { var alreadyExists = false transaction { alreadyExists = TimePlanningChannels.select { - (TimePlanningChannels.channelid eq gID) and + (TimePlanningChannels.serverid eq gID) and (TimePlanningChannels.channelid eq cID) }.count() > 0 } @@ -116,9 +116,9 @@ class FeatureManageExtension : Extension() { } - /* - FeatureEnum.PLANNINGNOTIFIER -> { + FeatureEnum.PLANNINGROLES -> { var alreadyExists = false + // Check if the channel and guild already exist in the db transaction { alreadyExists = PlanningNotifierRoles.select { (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID) @@ -126,6 +126,7 @@ class FeatureManageExtension : Extension() { } if (!alreadyExists) { + // Create the roles in Discord val hasTimeRole = this.guild!!.createRole { this.name = "available [${channel.data.name.value}]" this.mentionable = true @@ -138,12 +139,13 @@ class FeatureManageExtension : Extension() { } val wnr = wantsNotifsRole.id.toString() + // Save the role ids to db transaction { PlanningNotifierRoles.insert { it[PlanningNotifierRoles.serverid] = gID it[PlanningNotifierRoles.channelid] = cID it[PlanningNotifierRoles.hastimeroleid] = htr - it[PlanningNotifierRoles.wantstobenotifid] = wnr + it[PlanningNotifierRoles.wantstobenotifiedid] = wnr } get PlanningNotifierRoles.id } @@ -159,6 +161,8 @@ class FeatureManageExtension : Extension() { } return@action } + + // They exist, do not add them this.respond { embeds.add( MessageUtil.getEmbed( @@ -169,13 +173,14 @@ class FeatureManageExtension : Extension() { ) ) } - } */ + } } return@action } //Disable when (this.arguments.feature) { FeatureEnum.TIMEPLANNINGFEATURE -> { + // Check if entry exists in db var alreadyExists = false transaction { alreadyExists = TimePlanningChannels.select { @@ -184,6 +189,7 @@ class FeatureManageExtension : Extension() { }.count() > 0 } if (alreadyExists) { + // delete all entrys for this channel transaction { val matchingEntries = TimePlanningChannels.select { (TimePlanningChannels.serverid eq gID) and @@ -206,6 +212,7 @@ class FeatureManageExtension : Extension() { } return@action } + // Do nothing; not in db this.respond { embeds.add( MessageUtil.getEmbed( @@ -218,8 +225,9 @@ class FeatureManageExtension : Extension() { } } - /* - FeatureEnum.PLANNINGNOTIFIER -> { + + FeatureEnum.PLANNINGROLES -> { + // Check if entry exists in db var alreadyExists = false transaction { alreadyExists = PlanningNotifierRoles.select { @@ -234,12 +242,14 @@ class FeatureManageExtension : Extension() { (PlanningNotifierRoles.channelid eq cID) }.toList() } + // delete all entries for this guild and channel combo for (e in matchingEntries) { this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifierRoles.hastimeroleid]))?.delete() - this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifierRoles.wantstobenotifid])) + this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifierRoles.wantstobenotifiedid])) ?.delete() } + // delete all found entries transaction { matchingEntries.forEach { entry -> PlanningNotifierRoles.deleteWhere { id eq entry[id] } @@ -257,6 +267,7 @@ class FeatureManageExtension : Extension() { } return@action } + // not in db, do nothing this.respond { embeds.add( MessageUtil.getEmbed( @@ -267,7 +278,7 @@ class FeatureManageExtension : Extension() { ) ) } - } */ + } } } } -- 2.45.2 From 72670d4dd4e535c421f1f1c6a6ced040344ad511 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 22:52:44 +0200 Subject: [PATCH 026/168] feat: added saving of the messageids, chore: moved getMondayDayOfMonth function to TimeUtil Signed-off-by: limited_dev --- .../extensions/SendPlannerExtension.kt | 34 ++++++++++++------- 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index 2482bbf..f038602 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -27,10 +27,13 @@ import dev.kord.common.entity.Permission import dev.kord.core.behavior.channel.createMessage import dev.kord.rest.builder.message.create.actionRow import kotlinx.coroutines.delay -import kotlinx.datetime.DayOfWeek -import net.moonleay.lilJudd.util.ButtonUtil +import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.lilJudd.util.TimeUtil +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.transactions.transaction import java.time.ZoneId import java.time.ZonedDateTime @@ -58,10 +61,12 @@ class SendPlannerExtension : Extension() { val res = this.respond { this.content = "OK." } - res.delete() + res.delete() // Delete the response val c = this.getChannel().asChannel() + var msgStr = "" var then = - ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withDayOfMonth(getMondayDayOfMonth()).withHour(4) + ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withDayOfMonth(TimeUtil.getMondayDayOfMonth()) + .withHour(4) .withMinute(0).withSecond(0) c.createMessage { this.embeds.add( @@ -75,7 +80,7 @@ class SendPlannerExtension : Extension() { } delay(1000) repeat(7) { - c.createMessage { + val msg = c.createMessage { this.embeds.add( MessageUtil.getEmbedWithTable( Color(0X4C4645), @@ -90,21 +95,26 @@ class SendPlannerExtension : Extension() { ) this.actionRow { - this.components.addAll(ButtonUtil.getTimePlannerButtons().components) + this.components.addAll(EmbedUtil.getTimePlannerButtons().components) } } + msgStr += "${it}:${msg.id.value};" then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0) Logger.out("Finished sending day $it") delay(1000) } + + // Save the message ids + transaction { + TimePlanningMessages.insert { + it[serverid] = c.data.guildId.value.toString() + it[channelid] = c.id.value.toString() + it[weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000).toString() + it[messageids] = msgStr + } get TimePlanningMessages.id + } Logger.out("Finished with ${c.data.guildId.value}") } } } - - fun getMondayDayOfMonth(): Int { - val now = ZonedDateTime.now() - val monday = now.with(DayOfWeek.MONDAY) - return monday.dayOfMonth - } } -- 2.45.2 From 15d2aec85e8b1b425d03180f36edc06c73b17351 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 23:15:11 +0200 Subject: [PATCH 027/168] feat: improved feature / cronjob system Changes by silenium-dev Signed-off-by: limited_dev --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 8 ++------ .../net/moonleay/lilJudd/features/AvailabilityManager.kt | 4 ++-- .../kotlin/net/moonleay/lilJudd/features/TimeManager.kt | 4 ++-- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index e7247a7..4090477 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -44,6 +44,8 @@ object Bot { //The kord object gets set at app launch lateinit var bot: ExtensibleBot + private val jobs = mutableListOf() + @OptIn(PrivilegedIntent::class) suspend fun start() { Logger.out("Starting Bot...") @@ -77,12 +79,6 @@ object Bot { //PlanningNotifier.registerThread() } - // Add a shutdown hook to cancel the coroutine when the application is terminated - Runtime.getRuntime().addShutdownHook(Thread { - coroutineJob.cancel() - }) - - // Add bot token to kord bot = ExtensibleBot(CredentialManager.token) { applicationCommands { diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 8961ef1..8aa8ca7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -37,7 +37,7 @@ import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction import java.time.ZonedDateTime -object AvailabilityManager { +object AvailabilityManager : IFeature { // This runs during the cronjob. @OptIn(PrivilegedIntent::class) @@ -134,7 +134,7 @@ object AvailabilityManager { Logger.out("Done! Until tomorrow! <3 ") } - suspend fun registerThread() { + override suspend fun registerThread() { Logger.out("Adding availability scheduler...") val scheduler = buildSchedule("0 0 5 * * * 0o *w") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index a920e02..519e162 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -42,7 +42,7 @@ import java.time.ZoneId import java.time.ZonedDateTime -object TimeManager { +object TimeManager : IFeature { /* /--------------- Seconds | /------------- Minutes | | /----------- Hours @@ -53,7 +53,7 @@ object TimeManager { | | | | | | | / (optional) Week days * * * * * * 0o *w*/ - suspend fun registerThread() { + override suspend fun registerThread() { Logger.out("Adding message scheduler...") val scheduler = buildSchedule("0 0 4 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { -- 2.45.2 From e0228c65cd7d947b267150ecf02f4d97d380e2c0 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 28 Jun 2023 23:15:26 +0200 Subject: [PATCH 028/168] feat: removed old Feature interface, removed manager temp, moved IFeature into .feature.component chore: add credits, add comments Signed-off-by: limited_dev --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 22 ++++++++++---- .../lilJudd/features/AvailabilityManager.kt | 6 ++-- .../moonleay/lilJudd/features/TimeManager.kt | 1 + .../lilJudd/features/component/Feature.kt | 30 ------------------- .../{FeatureManager.kt => IFeature.kt} | 5 ++-- 5 files changed, 22 insertions(+), 42 deletions(-) delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/features/component/Feature.kt rename src/main/kotlin/net/moonleay/lilJudd/features/component/{FeatureManager.kt => IFeature.kt} (88%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 4090477..b8c138e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -26,7 +26,9 @@ import dev.kord.core.event.interaction.ButtonInteractionCreateEvent import dev.kord.core.on import dev.kord.gateway.Intent import dev.kord.gateway.PrivilegedIntent -import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job import kotlinx.coroutines.launch import net.moonleay.botendo.build.BuildConstants import net.moonleay.lilJudd.buttons.component.EditButtonManager @@ -35,6 +37,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.AvailabilityManager import net.moonleay.lilJudd.features.TimeManager import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil @@ -73,11 +76,18 @@ object Bot { CredentialManager.dbPassword ) - // Register the TimePlanner thread - val coroutineJob = GlobalScope.launch { - TimeManager.registerThread() - //PlanningNotifier.registerThread() - } + // Register all the jobs + jobs.addAll( + listOf( + TimeManager, + AvailabilityManager, + ).map { + CoroutineScope(Dispatchers.Default).launch { + it.registerThread() + } + } + ) + // Thanks silenium-dev <3 // Add bot token to kord bot = ExtensibleBot(CredentialManager.token) { diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 8aa8ca7..943b1b5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -29,6 +29,7 @@ import net.moonleay.lilJudd.data.entry.PlanningNotifierRolesData import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.features.component.IFeature import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.TimeUtil @@ -136,11 +137,10 @@ object AvailabilityManager : IFeature { override suspend fun registerThread() { Logger.out("Adding availability scheduler...") - val scheduler = buildSchedule("0 0 5 * * * 0o *w") // 0 0 4 * * * 0o 1w // 0o is UTC + val scheduler = buildSchedule("0 0 5 * * * 0o *") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { - + Logger.out("Starting to update roles...") this.runThread() } - Logger.out("Starting to update roles...") } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 519e162..5df369e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -31,6 +31,7 @@ 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.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.features.component.IFeature import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/Feature.kt b/src/main/kotlin/net/moonleay/lilJudd/features/component/Feature.kt deleted file mode 100644 index da04430..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/features/component/Feature.kt +++ /dev/null @@ -1,30 +0,0 @@ -/* - * 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.component - -import dev.kord.core.entity.Message - -interface Feature { - val feature: FeatureEnum - - fun enable(): Message - fun disable(): Message - - suspend fun registerThread() -} diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt similarity index 88% rename from src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt rename to src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt index 76af6f1..da5630a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt @@ -18,7 +18,6 @@ package net.moonleay.lilJudd.features.component -object FeatureManager { - // See note in Feature.kt - val features = mutableListOf() +interface IFeature { + suspend fun registerThread() } -- 2.45.2 From 5ffd3c7ccc3035f4a44b02f6f6431e6445021793 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 28 Jun 2023 23:15:37 +0200 Subject: [PATCH 029/168] chore: bump version Signed-off-by: limited_dev --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6fd7fe7..34075f9 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.3.0" + ?: "2.3.0.1" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From e8667dca5b4f1c09ea51b08c2136ba06306d77e0 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 00:05:12 +0200 Subject: [PATCH 030/168] feat: upgrade README.md Signed-off-by: limited_dev --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index f6d28e8..97584ab 100644 --- a/README.md +++ b/README.md @@ -14,9 +14,6 @@ A Discord Bot for Splatoon Teams ## Known issues -- There is a bug with being able to register the same feature in the same channel without checking if it is already - active - ##### If you encounter any bugs, message me on Discord (@moonleay) or send me a mail (issues@moonleay.net). ## Commands & Features @@ -26,6 +23,7 @@ A Discord Bot for Splatoon Teams - feature -- Manage bot features - Features - Time Planner -- Make the bot send messages and reactions into a selected channel in order to make planning easier + - Availability Manager -- Make the bot assign users roles every day, so it is possible to notify available people ## (Maybe) upcoming features -- 2.45.2 From e64569c7485eb2c601a52bdc04d6ccdf37a74fea Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 08:25:37 +0200 Subject: [PATCH 031/168] feat: improved feature system Signed-off-by: limited_dev --- .../extensions/FeatureManageExtension.kt | 226 ++------------- .../lilJudd/features/AvailabilityManager.kt | 124 +++++++- .../moonleay/lilJudd/features/TimeManager.kt | 266 ++++++++++++------ .../features/component/FeatureManager.kt | 30 ++ .../lilJudd/features/component/IFeature.kt | 22 ++ 5 files changed, 371 insertions(+), 297 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index 901387c..30d52d1 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -27,17 +27,11 @@ import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission 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.PlanningNotifierRoles -import net.moonleay.lilJudd.data.tables.TimePlanningChannels import net.moonleay.lilJudd.extensions.component.EnableOrDisable import net.moonleay.lilJudd.features.component.FeatureEnum +import net.moonleay.lilJudd.features.component.FeatureManager import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.transactions.transaction class FeatureManageExtension : Extension() { @@ -74,211 +68,29 @@ class FeatureManageExtension : Extension() { val channel = this.arguments.channel val args = this.arguments Logger.out("${args.feature.readableName} ${args.setStatus.readableName} ${channel.data.name.value}") - if (this.arguments.setStatus == EnableOrDisable.ENABLE) { - when (this.arguments.feature) { - FeatureEnum.TIMEPLANNINGFEATURE -> { - var alreadyExists = false - transaction { - alreadyExists = TimePlanningChannels.select { - (TimePlanningChannels.serverid eq gID) and - (TimePlanningChannels.channelid eq cID) - }.count() > 0 - } - if (!alreadyExists) { - transaction { - TimePlanningChannels.insert { - it[TimePlanningChannels.serverid] = gID - it[TimePlanningChannels.channelid] = cID - } get TimePlanningChannels.id - } - this.respond { - embeds.add( - MessageUtil.getEmbed( - Color(0x52E01A), - "200: Success", - "The feature was enabled in channel ${args.channel.data.name.value}", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) - } - return@action - } - this.respond { - embeds.add( - MessageUtil.getEmbed( - Color(0xE0311A), - "403: Forbidden", - "The feature is already enabled in this channel.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) - } - } - - - FeatureEnum.PLANNINGROLES -> { - var alreadyExists = false - // Check if the channel and guild already exist in the db - transaction { - alreadyExists = PlanningNotifierRoles.select { - (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID) - }.count() > 0 - } - if (!alreadyExists) { - - // Create the roles in Discord - val hasTimeRole = this.guild!!.createRole { - this.name = "available [${channel.data.name.value}]" - this.mentionable = true - } - val htr = hasTimeRole.id.toString() - - val wantsNotifsRole = this.guild!!.createRole { - this.name = "notifications [${channel.data.name.value}]" - this.mentionable = true - } - val wnr = wantsNotifsRole.id.toString() - - // Save the role ids to db - transaction { - PlanningNotifierRoles.insert { - it[PlanningNotifierRoles.serverid] = gID - it[PlanningNotifierRoles.channelid] = cID - it[PlanningNotifierRoles.hastimeroleid] = htr - it[PlanningNotifierRoles.wantstobenotifiedid] = wnr - } get PlanningNotifierRoles.id - } - - this.respond { - embeds.add( - MessageUtil.getEmbed( - Color(0x52E01A), - "200: Success", - "The feature was enabled in channel ${args.channel.data.name.value} with roles ${hasTimeRole.mention} & ${wantsNotifsRole.mention}.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) - } - return@action - } - - // They exist, do not add them - this.respond { - embeds.add( - MessageUtil.getEmbed( - Color(0xE0311A), - "403: Forbidden", - "The feature is already enabled in this channel.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) - } - } + val f = FeatureManager.getFeature(args.feature) + if (f == null) { + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + Color(0xE0311A), + "404: Not Found", + "The feature you are trying to edit does not exist.", + u.asUser().username + "#" + u.asUser().discriminator + ) + ) } return@action } - //Disable - when (this.arguments.feature) { - FeatureEnum.TIMEPLANNINGFEATURE -> { - // Check if entry exists in db - var alreadyExists = false - transaction { - alreadyExists = TimePlanningChannels.select { - (TimePlanningChannels.serverid eq gID) and - (TimePlanningChannels.channelid eq cID) - }.count() > 0 - } - if (alreadyExists) { - // delete all entrys for this channel - transaction { - val matchingEntries = TimePlanningChannels.select { - (TimePlanningChannels.serverid eq gID) and - (TimePlanningChannels.channelid eq cID) - }.toList() - matchingEntries.forEach { entry -> - TimePlanningChannels.deleteWhere { id eq entry[id] } - } - } - this.respond { - embeds.add( - MessageUtil.getEmbed( - Color(0x52E019), - "200: Success", - "The feature was disabled.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) - } - return@action - } - // Do nothing; not in db - this.respond { - embeds.add( - MessageUtil.getEmbed( - Color(0xE0311A), - "403: Forbidden", - "The feature is already disabled in this channel.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) - } - } - - - FeatureEnum.PLANNINGROLES -> { - // Check if entry exists in db - var alreadyExists = false - transaction { - alreadyExists = PlanningNotifierRoles.select { - (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID) - }.count() > 0 - } - if (alreadyExists) { - var matchingEntries: List = mutableListOf() - transaction { - matchingEntries = PlanningNotifierRoles.select { - (PlanningNotifierRoles.serverid eq gID) and - (PlanningNotifierRoles.channelid eq cID) - }.toList() - } - // delete all entries for this guild and channel combo - for (e in matchingEntries) { - this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifierRoles.hastimeroleid]))?.delete() - this.guild!!.getRoleOrNull(Snowflake(e[PlanningNotifierRoles.wantstobenotifiedid])) - ?.delete() - } - - // delete all found entries - transaction { - matchingEntries.forEach { entry -> - PlanningNotifierRoles.deleteWhere { id eq entry[id] } - } - } - this.respond { - embeds.add( - MessageUtil.getEmbed( - Color(0x52E019), - "200: Success", - "The feature was disabled.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) - } - return@action - } - // not in db, do nothing - this.respond { - embeds.add( - MessageUtil.getEmbed( - Color(0xE0311A), - "403: Forbidden", - "The feature is already disabled in this channel.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) - } + if (this.arguments.setStatus == EnableOrDisable.ENABLE) { + this.respond { + this.embeds.add(f.enable(u, gID, cID, channel, args)) } + return@action + } + this.respond { + this.embeds.add(f.disable(u, gID, cID, channel, args)) } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 943b1b5..d31b4ea 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -20,21 +20,29 @@ package net.moonleay.lilJudd.features import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.doInfinity +import dev.kord.common.Color import dev.kord.common.entity.Snowflake +import dev.kord.core.behavior.UserBehavior +import dev.kord.core.behavior.createRole import dev.kord.core.behavior.requestMembers +import dev.kord.core.entity.channel.Channel import dev.kord.core.entity.channel.MessageChannel import dev.kord.gateway.PrivilegedIntent +import dev.kord.rest.builder.message.EmbedBuilder import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.data.entry.PlanningNotifierRolesData import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.extensions.FeatureManageExtension +import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.IFeature import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger +import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.lilJudd.util.TimeUtil -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction import java.time.ZonedDateTime @@ -135,6 +143,9 @@ object AvailabilityManager : IFeature { Logger.out("Done! Until tomorrow! <3 ") } + override val feat: FeatureEnum + get() = FeatureEnum.PLANNINGROLES + override suspend fun registerThread() { Logger.out("Adding availability scheduler...") val scheduler = buildSchedule("0 0 5 * * * 0o *") // 0 0 4 * * * 0o 1w // 0o is UTC @@ -143,4 +154,113 @@ object AvailabilityManager : IFeature { this.runThread() } } + + override suspend fun enable( + u: UserBehavior, + gID: String, + cID: String, + ch: Channel, + args: FeatureManageExtension.FeatureManagerArgs + ): EmbedBuilder { + var alreadyExists = false + // Check if the channel and guild already exist in the db + transaction { + alreadyExists = PlanningNotifierRoles.select { + (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID) + }.count() > 0 + } + if (!alreadyExists) { + + // Create the roles in Discord + val hasTimeRole = Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)).createRole { + this.name = "available [${ch.data.name.value}]" + this.mentionable = true + } + val htr = hasTimeRole.id.toString() + + val wantsNotifsRole = Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)).createRole { + this.name = "notifications [${ch.data.name.value}]" + this.mentionable = true + } + val wnr = wantsNotifsRole.id.toString() + + // Save the role ids to db + transaction { + PlanningNotifierRoles.insert { + it[PlanningNotifierRoles.serverid] = gID + it[PlanningNotifierRoles.channelid] = cID + it[PlanningNotifierRoles.hastimeroleid] = htr + it[PlanningNotifierRoles.wantstobenotifiedid] = wnr + } get PlanningNotifierRoles.id + } + + return MessageUtil.getEmbed( + Color(0x52E01A), + "200: Success", + "The feature was enabled in channel ${args.channel.data.name.value} with roles ${hasTimeRole.mention} & ${wantsNotifsRole.mention}.", + u.asUser().username + "#" + u.asUser().discriminator + ) + } + + // They exist, do not add them + return MessageUtil.getEmbed( + Color(0xE0311A), + "403: Forbidden", + "The feature is already enabled in this channel.", + u.asUser().username + "#" + u.asUser().discriminator + ) + } + + override suspend fun disable( + u: UserBehavior, + gID: String, + cID: String, + ch: Channel, + args: FeatureManageExtension.FeatureManagerArgs + ): EmbedBuilder { + // Check if entry exists in db + var alreadyExists = false + transaction { + alreadyExists = PlanningNotifierRoles.select { + (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID) + }.count() > 0 + } + if (alreadyExists) { + var matchingEntries: List = mutableListOf() + transaction { + matchingEntries = PlanningNotifierRoles.select { + (PlanningNotifierRoles.serverid eq gID) and + (PlanningNotifierRoles.channelid eq cID) + }.toList() + } + // delete all entries for this guild and channel combo + for (e in matchingEntries) { + Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)) + .getRoleOrNull(Snowflake(e[PlanningNotifierRoles.hastimeroleid]))?.delete() + Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)) + .getRoleOrNull(Snowflake(e[PlanningNotifierRoles.wantstobenotifiedid])) + ?.delete() + } + + // delete all found entries + transaction { + matchingEntries.forEach { entry -> + PlanningNotifierRoles.deleteWhere { id eq entry[id] } + } + } + return MessageUtil.getEmbed( + Color(0x52E019), + "200: Success", + "The feature was disabled.", + u.asUser().username + "#" + u.asUser().discriminator + ) + } + // not in db, do nothing + return MessageUtil.getEmbed( + Color(0xE0311A), + "403: Forbidden", + "The feature is already disabled in this channel.", + u.asUser().username + "#" + u.asUser().discriminator + ) + } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 5df369e..4de7152 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -22,8 +22,11 @@ import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.doInfinity import dev.kord.common.Color import dev.kord.common.entity.Snowflake +import dev.kord.core.behavior.UserBehavior import dev.kord.core.behavior.channel.createMessage +import dev.kord.core.entity.channel.Channel import dev.kord.core.entity.channel.MessageChannel +import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.builder.message.create.actionRow import kotlinx.coroutines.delay import net.moonleay.lilJudd.Bot @@ -31,19 +34,23 @@ 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.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.extensions.FeatureManageExtension +import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.IFeature import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.lilJudd.util.TimeUtil -import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction import java.time.ZoneId import java.time.ZonedDateTime object TimeManager : IFeature { + override val feat: FeatureEnum + get() = FeatureEnum.TIMEPLANNINGFEATURE /* /--------------- Seconds | /------------- Minutes | | /----------- Hours @@ -58,92 +65,175 @@ object TimeManager : IFeature { Logger.out("Adding message scheduler...") val scheduler = buildSchedule("0 0 4 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { - Logger.out("Starting to notify...") - - - // ChannelID, ServerID - val channelList = mutableMapOf() - // ChannelID, Data - val roleList = mutableMapOf() - - var msgStr = "" - - transaction { - for (tp in TimePlanningChannels.selectAll()) { - 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.wantstobenotifiedid] - ) - Logger.out("Have to ping roles: ${pnr[PlanningNotifierRoles.wantstobenotifiedid]}}") - } - } - 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 = - "The weekly planning starts now <@&${Snowflake(roleList[ch]?.wantstobenotifid!!)}>" - } - this.embeds.add( - MessageUtil.getEmbed( - Color(0X4C4645), - "Time Planning Feature", - "Do you have time on the following Days?", - "Automated Message" - ) - ) - } - delay(2000) - var then = ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withHour(4).withMinute(0).withSecond(0) - repeat(7) { - val msg = 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() - ) - ) - ) - - this.actionRow { - this.components.addAll(EmbedUtil.getTimePlannerButtons().components) - } - } - msgStr += "${it}:${msg.id.value};" - then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0) - Logger.out("Finished sending day $it") - - delay(1000) - } - - // Save the message ids - transaction { - TimePlanningMessages.insert { - it[TimePlanningMessages.serverid] = c.data.guildId.value.toString() - it[TimePlanningMessages.channelid] = c.id.value.toString() - it[TimePlanningMessages.weekstamp] = TimeUtil.getWeekStamp().toOffsetDateTime().toString() - it[TimePlanningMessages.messageids] = msgStr - } get PlanningNotifierRoles.id - } - Logger.out("Finished with ${c.data.guildId.value}") - } - Logger.out("Done! Until next Monday! <3 ") + this.runThread() } } + + private suspend fun runThread() { + Logger.out("Starting to notify...") + + + // ChannelID, ServerID + val channelList = mutableMapOf() + // ChannelID, Data + val roleList = mutableMapOf() + + var msgStr = "" + + transaction { + for (tp in TimePlanningChannels.selectAll()) { + 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.wantstobenotifiedid] + ) + Logger.out("Have to ping roles: ${pnr[PlanningNotifierRoles.wantstobenotifiedid]}}") + } + } + 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 = + "The weekly planning starts now <@&${Snowflake(roleList[ch]?.wantstobenotifid!!)}>" + } + this.embeds.add( + MessageUtil.getEmbed( + Color(0X4C4645), + "Time Planning Feature", + "Do you have time on the following Days?", + "Automated Message" + ) + ) + } + delay(2000) + var then = ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withHour(4).withMinute(0).withSecond(0) + repeat(7) { + val msg = 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() + ) + ) + ) + + this.actionRow { + this.components.addAll(EmbedUtil.getTimePlannerButtons().components) + } + } + msgStr += "${it}:${msg.id.value};" + then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0) + Logger.out("Finished sending day $it") + + delay(1000) + } + + // Save the message ids + transaction { + TimePlanningMessages.insert { + it[TimePlanningMessages.serverid] = c.data.guildId.value.toString() + it[TimePlanningMessages.channelid] = c.id.value.toString() + it[TimePlanningMessages.weekstamp] = TimeUtil.getWeekStamp().toOffsetDateTime().toString() + it[TimePlanningMessages.messageids] = msgStr + } get PlanningNotifierRoles.id + } + Logger.out("Finished with ${c.data.guildId.value}") + } + Logger.out("Done! Until next Monday! <3 ") + } + + override suspend fun enable( + u: UserBehavior, + gID: String, + cID: String, + ch: Channel, + args: FeatureManageExtension.FeatureManagerArgs + ): EmbedBuilder { + var alreadyExists = false + transaction { + alreadyExists = TimePlanningChannels.select { + (TimePlanningChannels.serverid eq gID) and + (TimePlanningChannels.channelid eq cID) + }.count() > 0 + } + if (!alreadyExists) { + transaction { + TimePlanningChannels.insert { + it[TimePlanningChannels.serverid] = gID + it[TimePlanningChannels.channelid] = cID + } get TimePlanningChannels.id + } + return MessageUtil.getEmbed( + Color(0x52E01A), + "200: Success", + "The feature was enabled in channel ${args.channel.data.name.value}", + u.asUser().username + "#" + u.asUser().discriminator + ) + } + return MessageUtil.getEmbed( + Color(0xE0311A), + "403: Forbidden", + "The feature is already enabled in this channel.", + u.asUser().username + "#" + u.asUser().discriminator + ) + } + + override suspend fun disable( + u: UserBehavior, + gID: String, + cID: String, + ch: Channel, + args: FeatureManageExtension.FeatureManagerArgs + ): EmbedBuilder { + // Check if entry exists in db + var alreadyExists = false + transaction { + alreadyExists = TimePlanningChannels.select { + (TimePlanningChannels.serverid eq gID) and + (TimePlanningChannels.channelid eq cID) + }.count() > 0 + } + if (alreadyExists) { + // delete all entrys for this channel + transaction { + val matchingEntries = TimePlanningChannels.select { + (TimePlanningChannels.serverid eq gID) and + (TimePlanningChannels.channelid eq cID) + }.toList() + + matchingEntries.forEach { entry -> + TimePlanningChannels.deleteWhere { id eq entry[id] } + } + } + return MessageUtil.getEmbed( + Color(0x52E019), + "200: Success", + "The feature was disabled.", + u.asUser().username + "#" + u.asUser().discriminator + ) + } + // Do nothing; not in db + return MessageUtil.getEmbed( + Color(0xE0311A), + "403: Forbidden", + "The feature is already disabled in this channel.", + u.asUser().username + "#" + u.asUser().discriminator + ) + } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt new file mode 100644 index 0000000..d380d9c --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt @@ -0,0 +1,30 @@ +/* + * 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.component + +import net.moonleay.lilJudd.features.AvailabilityManager +import net.moonleay.lilJudd.features.TimeManager + +object FeatureManager { + val features = mutableListOf(AvailabilityManager, TimeManager) // Stores all features + + fun getFeature(feat: FeatureEnum): IFeature? { + return features.find { it.feat == feat } + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt b/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt index da5630a..aa27536 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt @@ -18,6 +18,28 @@ package net.moonleay.lilJudd.features.component +import dev.kord.core.behavior.UserBehavior +import dev.kord.core.entity.channel.Channel +import dev.kord.rest.builder.message.EmbedBuilder +import net.moonleay.lilJudd.extensions.FeatureManageExtension + interface IFeature { + val feat: FeatureEnum suspend fun registerThread() + + suspend fun enable( + u: UserBehavior, + gID: String, + cID: String, + ch: Channel, + args: FeatureManageExtension.FeatureManagerArgs + ): EmbedBuilder + + suspend fun disable( + u: UserBehavior, + gID: String, + cID: String, + ch: Channel, + args: FeatureManageExtension.FeatureManagerArgs + ): EmbedBuilder } -- 2.45.2 From 5b1b9682ff621099bc8ab9a3c4cf65c4dea06796 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 08:26:11 +0200 Subject: [PATCH 032/168] chore: update README.md Signed-off-by: limited_dev --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 97584ab..3ea0579 100644 --- a/README.md +++ b/README.md @@ -35,8 +35,6 @@ A Discord Bot for Splatoon Teams ## TODO -- Rewrite the feature system -- Rewrite the Cronjob system - Rewrite the Database connection system (from transactions all over the place to a single package with transactions) ## How to self-host (using the Docker container) -- 2.45.2 From f87ef82e667d3ae03b04c00470705d6cf0450c62 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 08:27:02 +0200 Subject: [PATCH 033/168] chore: update README.md Signed-off-by: limited_dev --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3ea0579..eda8fcc 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ A Discord Bot for Splatoon Teams - Game Tracker (Save the results of the last matches) - Replay Saver (Maybe; will save the replay code to a database) - Rndm map command +- Maybe a DSB / DSL API ## TODO -- 2.45.2 From a42016961ffdd74c4f87d2d88ed74e6f2db4b069 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 08:39:43 +0200 Subject: [PATCH 034/168] feat: timemanager cronjob now runs at 0:01 AM utc Signed-off-by: limited_dev --- src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 4de7152..0f469e7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -61,9 +61,10 @@ object TimeManager : IFeature { | | | | | | | / (optional) Week days * * * * * * 0o *w*/ + // Register the cronjob to run at 0:01 AM UTC every Monday override suspend fun registerThread() { Logger.out("Adding message scheduler...") - val scheduler = buildSchedule("0 0 4 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC + val scheduler = buildSchedule("0 1 0 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { this.runThread() } -- 2.45.2 From 4fac341c1157e4f88a0900e1701839bc4b1fe034 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 08:39:57 +0200 Subject: [PATCH 035/168] feat: AvailabilityManager cronjob now runs at 1:00 AM utc Signed-off-by: limited_dev --- .../net/moonleay/lilJudd/features/AvailabilityManager.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index d31b4ea..7d10ef7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -146,9 +146,10 @@ object AvailabilityManager : IFeature { override val feat: FeatureEnum get() = FeatureEnum.PLANNINGROLES + // Register the cronjob to run at 1AM UTC every day override suspend fun registerThread() { Logger.out("Adding availability scheduler...") - val scheduler = buildSchedule("0 0 5 * * * 0o *") // 0 0 4 * * * 0o 1w // 0o is UTC + val scheduler = buildSchedule("0 0 1 * * * 0o *") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { Logger.out("Starting to update roles...") this.runThread() -- 2.45.2 From 948ac8a1843fb99f9858551d7177b489571bf9fc Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 08:40:10 +0200 Subject: [PATCH 036/168] chore: update README.md Signed-off-by: limited_dev --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index eda8fcc..14b1834 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,6 @@ A Discord Bot for Splatoon Teams ## (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) - Rndm map command -- 2.45.2 From d6bf2e7bc98337b357b27232785784c5ba0feea0 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 08:57:22 +0200 Subject: [PATCH 037/168] chore: update .gitlab-ci.yml to only run at tag creation Signed-off-by: limited_dev --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6fcd41c..ba0f4a1 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -21,6 +21,8 @@ cache: - build build: + only: + - tags stage: build script: - gradle shadowJar @@ -28,6 +30,8 @@ build: - tags publish: + only: + - tags stage: publish script: - gradle publish -- 2.45.2 From 196bb378b4dee133ecb551def795f92b398f99ef Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 09:57:36 +0200 Subject: [PATCH 038/168] feat: make the bot update the roles on startup fix: fixed the bot throwing Errors when there is no role for a channel Signed-off-by: limited_dev --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 6 ++++++ .../lilJudd/features/AvailabilityManager.kt | 14 +++++++++++--- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index b8c138e..c12a304 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -22,6 +22,7 @@ import com.kotlindiscord.kord.extensions.ExtensibleBot import dev.kord.common.Color import dev.kord.common.entity.PresenceStatus import dev.kord.core.behavior.interaction.response.respond +import dev.kord.core.event.gateway.ReadyEvent import dev.kord.core.event.interaction.ButtonInteractionCreateEvent import dev.kord.core.on import dev.kord.gateway.Intent @@ -151,6 +152,11 @@ object Bot { } } + // Update roles + bot.kordRef.on { + AvailabilityManager.runThread() + } + //Start the bot bot.start() diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 7d10ef7..9dd66aa 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -88,14 +88,22 @@ object AvailabilityManager : IFeature { continue // This channel does not exist anymore. val c = Bot.bot.kordRef.getChannelOf(Snowflake(data.channelid))!! // Get the channel as MessageChannel - val roleData = roleMap[data.channelid]!! // Get the role data + if (roleMap.size < 1) { + Logger.out("No saved roles. Canceling.") + return + } + val roleData = roleMap[data.channelid] // Get the role data + if (roleData == null) { + Logger.out("Role for this channel does not exist") + return + } val g = Bot.bot.kordRef.getGuildOrThrow(Snowflake(data.serverid)) // Get all members with the role val mce = g.requestMembers { this.requestAllMembers() } - mce.collect { it1 -> - it1.members.forEach { + mce.collect { memberchunkevent -> + memberchunkevent.members.forEach { Logger.out("Checking member ${it.id.value}") if (it.roleIds.contains(Snowflake(roleData.hastimeroleid))) it.removeRole(Snowflake(roleData.hastimeroleid)) -- 2.45.2 From d92396784ebe6e7ccef1e10e881153b68e40874a Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 11:14:13 +0200 Subject: [PATCH 039/168] feat: improved isEmpty check Signed-off-by: limited_dev --- .../kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 9dd66aa..3a19477 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -88,7 +88,7 @@ object AvailabilityManager : IFeature { continue // This channel does not exist anymore. val c = Bot.bot.kordRef.getChannelOf(Snowflake(data.channelid))!! // Get the channel as MessageChannel - if (roleMap.size < 1) { + if (roleMap.isEmpty()) { Logger.out("No saved roles. Canceling.") return } -- 2.45.2 From 063ef3ef9105e149651dca2417d7a260c250d63f Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 29 Jun 2023 12:12:57 +0200 Subject: [PATCH 040/168] chore: removed comment, as the function has been cleaned up Signed-off-by: limited_dev --- .../moonleay/lilJudd/extensions/FeatureManageExtension.kt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index 30d52d1..48f68e9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -39,10 +39,7 @@ class FeatureManageExtension : Extension() { override val allowApplicationCommandInDMs: Boolean get() = false - /* - * Note: This has to be rewritten at some point to better support more features - * and improve this mess of a class. - * */ + override suspend fun setup() { publicSlashCommand(::FeatureManagerArgs) { name = "feature" -- 2.45.2 From aabc50952bcd12213fc92de1b6bba8736e4cfd71 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 12:51:28 +0200 Subject: [PATCH 041/168] chore: upgrade krontab version, bump version Signed-off-by: limited_dev --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 34075f9..dd2e5fe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,14 +32,14 @@ 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.3.0.1" + ?: "2.4.0" val kordver = "1.5.6" val coroutinesver = "1.1.0" val ktor_version = "2.3.0" val exposedver = "0.40.1" val postgresver = "42.3.8" -val krontabver = "2.0.0" +val krontabver = "2.1.2" val mavenArtifact = "lilJudd" project.base.archivesName.set(mavenArtifact) -- 2.45.2 From f79e1b15822b4d381e8ab924aca9c1857fa832aa Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 12:55:54 +0200 Subject: [PATCH 042/168] feat: added info output to SendPlannerExtension Signed-off-by: limited_dev --- .../net/moonleay/lilJudd/extensions/SendPlannerExtension.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index f038602..2a56745 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -100,7 +100,7 @@ class SendPlannerExtension : Extension() { } msgStr += "${it}:${msg.id.value};" then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0) - Logger.out("Finished sending day $it") + Logger.out("Finished sending day $it/ This was manually triggered") delay(1000) } -- 2.45.2 From ad6040ebf3df8beeafa46505ca385b33fdc219f5 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 12:57:22 +0200 Subject: [PATCH 043/168] feat: added EmbedWithTableWithFooter to MessageUtil Signed-off-by: limited_dev --- .../kotlin/net/moonleay/lilJudd/util/MessageUtil.kt | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt index bc1d660..dc0a34a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt @@ -80,6 +80,19 @@ object MessageUtil { return ebb } + fun getEmbedWithTableWithFooter( + color: Color, + title: String, + description: String, + values: Map>?, + footer: String + ): EmbedBuilder { + val ebb = getEmbedWithTable(color, title, description, values) + ebb.footer = EmbedBuilder.Footer() + ebb.footer!!.text = ">m.id/$footer" + return ebb + } + ///Get an embedded msg with image, title and description fun getEmbedWithTable( color: Color, -- 2.45.2 From 7ab73765e44286f1669edcf9e8c3c10fa27f6d0a Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:05:12 +0200 Subject: [PATCH 044/168] feat: added function to get a ZonedDateTimeObject from a string, added function to generate a cronjob string from a ZonedDateTime object Signed-off-by: limited_dev --- .../kotlin/net/moonleay/lilJudd/util/TimeUtil.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt index 7e5fbec..c3c3e54 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt @@ -20,8 +20,10 @@ package net.moonleay.lilJudd.util import kotlinx.datetime.DayOfWeek import java.time.Duration +import java.time.LocalDateTime import java.time.ZoneId import java.time.ZonedDateTime +import java.time.format.DateTimeFormatter import java.util.concurrent.TimeUnit @@ -142,4 +144,18 @@ object TimeUtil { return ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withDayOfMonth(getMondayDayOfMonth()).withHour(4) .withMinute(0).withSecond(0) } + + fun getDateFromString(input: String): ZonedDateTime { + val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm") + val localDateTime = LocalDateTime.parse(input, formatter) + val zoneId = ZoneId.of("UTC+2") // TODO: Add the possibility to set your timezone + return ZonedDateTime.of(localDateTime, zoneId) + } + + fun getCronjobStringFromDate(zdt: ZonedDateTime): String { + // I'll have to add the possibility to set your timezone in the future + // Only subtracting 1 hour, because I want to run the job 1 hour later + val zdt_ = zdt.minusHours(1) + return "0 ${zdt_.minute} ${zdt_.hour} ${zdt_.dayOfMonth - 1} ${zdt_.month.value - 1} ${zdt_.year}"// 0o *w" + } } -- 2.45.2 From 1b2b35e10a08752e0279bc71049298281fddfcec Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:12:55 +0200 Subject: [PATCH 045/168] fix: fixed errors with the TimeManager if there is no notifier role Signed-off-by: limited_dev --- .../moonleay/lilJudd/features/TimeManager.kt | 50 ++++++++++--------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 0f469e7..43165db 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -51,20 +51,11 @@ import java.time.ZonedDateTime object TimeManager : IFeature { override val feat: FeatureEnum get() = FeatureEnum.TIMEPLANNINGFEATURE - /* /--------------- Seconds - | /------------- Minutes - | | /----------- Hours - | | | /--------- Days of months - | | | | /------- Months - | | | | | /----- (optional) Year - | | | | | | /--- (optional) Timezone offset - | | | | | | | / (optional) Week days - * * * * * * 0o *w*/ // Register the cronjob to run at 0:01 AM UTC every Monday override suspend fun registerThread() { Logger.out("Adding message scheduler...") - val scheduler = buildSchedule("0 1 0 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC + val scheduler = buildSchedule("0 0 1 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { this.runThread() } @@ -77,7 +68,7 @@ object TimeManager : IFeature { // ChannelID, ServerID val channelList = mutableMapOf() // ChannelID, Data - val roleList = mutableMapOf() + val roleMap = mutableMapOf() var msgStr = "" @@ -89,7 +80,7 @@ object TimeManager : IFeature { } for (pnr in PlanningNotifierRoles.selectAll()) { - roleList[Snowflake(pnr[PlanningNotifierRoles.channelid])] = PlanningNotifierRolesData( + roleMap[Snowflake(pnr[PlanningNotifierRoles.channelid])] = PlanningNotifierRolesData( pnr[PlanningNotifierRoles.serverid], pnr[PlanningNotifierRoles.channelid], pnr[PlanningNotifierRoles.hastimeroleid], @@ -98,24 +89,35 @@ object TimeManager : IFeature { Logger.out("Have to ping roles: ${pnr[PlanningNotifierRoles.wantstobenotifiedid]}}") } } - Logger.out("${channelList.count()} Channels to notify with ${roleList.count()} Roles to ping!") + Logger.out("${channelList.count()} Channels to notify with ${roleMap.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) { + if (roleMap != null && roleMap.keys.contains(ch) && roleMap[ch] != null) { + c.createMessage { this.content = - "The weekly planning starts now <@&${Snowflake(roleList[ch]?.wantstobenotifid!!)}>" - } - this.embeds.add( - MessageUtil.getEmbed( - Color(0X4C4645), - "Time Planning Feature", - "Do you have time on the following Days?", - "Automated Message" + "The weekly planning starts now <@&${Snowflake(roleMap[ch]?.wantstobenotifid!!)}>" + this.embeds.add( + MessageUtil.getEmbed( + Color(0X4C4645), + "Time Planning Feature", + "Do you have time on the following Days?", + "Automated Message" + ) ) - ) + } + } else { + c.createMessage { + this.embeds.add( + MessageUtil.getEmbed( + Color(0X4C4645), + "Time Planning Feature", + "Do you have time on the following Days?", + "Automated Message" + ) + ) + } } delay(2000) var then = ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withHour(4).withMinute(0).withSecond(0) -- 2.45.2 From e03e5bbd9e28ebedc9010c77b43eac35129253ae Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:15:31 +0200 Subject: [PATCH 046/168] chore: moved Logger info to runThread function Signed-off-by: limited_dev --- .../net/moonleay/lilJudd/features/AvailabilityManager.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 3a19477..77fb1ea 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -51,6 +51,8 @@ object AvailabilityManager : IFeature { // This runs during the cronjob. @OptIn(PrivilegedIntent::class) suspend fun runThread() { + Logger.out("Starting to update roles...") + // ChannelID, Data val messageMap = mutableMapOf() // ChannelID, Data @@ -157,9 +159,8 @@ object AvailabilityManager : IFeature { // Register the cronjob to run at 1AM UTC every day override suspend fun registerThread() { Logger.out("Adding availability scheduler...") - val scheduler = buildSchedule("0 0 1 * * * 0o *") // 0 0 4 * * * 0o 1w // 0o is UTC + val scheduler = buildSchedule("0 0 2 * * *") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { - Logger.out("Starting to update roles...") this.runThread() } } -- 2.45.2 From 97fc2975c5fc2d27e1ce712d243bcbfa499f2e12 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:17:47 +0200 Subject: [PATCH 047/168] feat: added MatchPlanningData and MatchPlanningDataData Signed-off-by: limited_dev --- .../data/entry/MatchPlanningDataData.kt | 32 ++++++++++++++++++ .../lilJudd/data/tables/MatchPlanningData.kt | 33 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt new file mode 100644 index 0000000..ca0bd32 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt @@ -0,0 +1,32 @@ +/* + * 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 MatchPlanningDataData( + val id: Int, + val serverid: String, + val channelid: String, + val matchtype: String, + val registererid: String, + val roleid: String, + val opponentname: String, + val messageid: String, + val timestamp: String, + val jobstr: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt new file mode 100644 index 0000000..2de3ece --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt @@ -0,0 +1,33 @@ +/* + * 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.tables + +import org.jetbrains.exposed.dao.id.IntIdTable + +object MatchPlanningData : IntIdTable() { + var serverid = varchar("serverid", 50) + var channelid = varchar("channelid", 50) + var matchtype = varchar("matchtype", 50) + var registererid = varchar("registererid", 50) + var roleid = varchar("roleid", 50) + var opponentName = varchar("opponentname", 100) + var messageid = varchar("messageid", 50) + var timestamp = varchar("timestamp", 50) + var jobstr = varchar("jobstr", 50) +} -- 2.45.2 From cd4e881e607294a086ca213f7acb226eaef7fa64 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:19:28 +0200 Subject: [PATCH 048/168] feat: added MatchTypes enum Signed-off-by: limited_dev --- .../extensions/component/MatchTypes.kt | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/extensions/component/MatchTypes.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/MatchTypes.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/component/MatchTypes.kt new file mode 100644 index 0000000..3cde91b --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/component/MatchTypes.kt @@ -0,0 +1,29 @@ +/* + * 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.extensions.component + +import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum + +enum class MatchTypes(override val readableName: String) : ChoiceEnum { + TOURNEY("Tourney Match"), + LADDER("Ladder Match"), + SCRIM("Scrim"), + LAN("LAN Match"), + OPEN("Anarchy Open"); +} -- 2.45.2 From 62e230777ba8bef03fd0c2e3d8f967e0fc032dbc Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:19:48 +0200 Subject: [PATCH 049/168] feat: added MatchExtension Signed-off-by: limited_dev --- .../lilJudd/extensions/MatchExtension.kt | 149 ++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt new file mode 100644 index 0000000..be28081 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -0,0 +1,149 @@ +/* + * 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.extensions + +import com.kotlindiscord.kord.extensions.commands.Arguments +import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.enumChoice +import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalString +import com.kotlindiscord.kord.extensions.commands.converters.impl.string +import com.kotlindiscord.kord.extensions.extensions.Extension +import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import com.kotlindiscord.kord.extensions.types.respond +import dev.kord.common.Color +import dev.kord.core.behavior.channel.createMessage +import dev.kord.core.behavior.createRole +import dev.kord.rest.builder.message.create.actionRow +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.extensions.component.MatchTypes +import net.moonleay.lilJudd.jobs.MatchJob +import net.moonleay.lilJudd.jobs.component.JobManager +import net.moonleay.lilJudd.util.EmbedUtil +import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.lilJudd.util.TimeUtil +import org.jetbrains.exposed.dao.id.EntityID +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.transactions.transaction + +class MatchExtension : Extension() { + + override val name = "match" + override val allowApplicationCommandInDMs: Boolean + get() = false + + + override suspend fun setup() { + publicSlashCommand(::MatchArguments) { + name = "match" + description = "Create a match" + this.action { + val args = this.arguments + val m = this.member!! + val gID = this.guild!!.id.value.toString() + val cID = this.channel.id.value.toString() + val opponent = args.opponent ?: "?" + val msg = this.respond { + this.embeds.add( + MessageUtil.getEmbedWithTable( + Color(0X4C4645), + args.matchType.readableName, + "***Vs. $opponent***\n" + + "At ${args.timeStamp}\n" + + "Registered by ${m.mention}", + mapOf( + "Signed up" to listOf(), + ) + ) + ) + + this.actionRow { + this.components.addAll(EmbedUtil.getMatchButtons().components) + } + } // filter time to date: + val zdt = TimeUtil.getDateFromString(args.timeStamp) + // get the string for the cronjob + val jobString = TimeUtil.getCronjobStringFromDate(zdt) + // create the role + val role = this.guild!!.createRole { + this.name = + "${args.matchType.readableName} Vs ${opponent} At ${zdt.dayOfMonth}/${zdt.month}/${zdt.year} ${zdt.hour}:${zdt.minute}" + this.mentionable = true + } + // Check if the role was created successfully + if (role == null) { + this.channel.createMessage { + this.embeds.add( + MessageUtil.getEmbed( + Color(0xE0311A), + "500: Internal Error", + "Could not find created role.\n" + + "It seems, that said role could not be created.", + "system message" + ) + ) + } + return@action + } + lateinit var tableID: EntityID + transaction { + tableID = MatchPlanningData.insert { + it[MatchPlanningData.serverid] = gID + it[MatchPlanningData.channelid] = cID + it[MatchPlanningData.messageid] = msg.id.value.toString() + it[MatchPlanningData.matchtype] = args.matchType.readableName + it[MatchPlanningData.roleid] = role.id.value.toString() + it[MatchPlanningData.registererid] = m.id.value.toString() + it[MatchPlanningData.opponentName] = opponent + it[MatchPlanningData.timestamp] = (zdt.toEpochSecond() * 1000).toString() + it[MatchPlanningData.jobstr] = jobString + } get MatchPlanningData.id + } + if (tableID == null) { + return@action // Not saved to db + } + JobManager.addJob( + MatchJob( + jobString, + tableID.value, + "${args.matchType.readableName}_Vs_${opponent}_[${tableID.value}]-${gID}_${cID}" + ) + ) + } + } + } + + inner class MatchArguments : Arguments() { + + val matchType by enumChoice { + this.name = "match" + this.description = "The type of match" + this.typeName = "en_US" + } + + + val timeStamp by string { + this.name = "timestamp" + this.description = "The timestamp of the match. Format \"dd.MM.yyyy HH:mm\"." + } + + val opponent by optionalString { + this.name = "opponent" + this.description = "The opponent" + } + } +} -- 2.45.2 From 3f3fb87ebd349250848215793ee8015ed9c4d314 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:20:01 +0200 Subject: [PATCH 050/168] feat: added MatchManager Signed-off-by: limited_dev --- .../moonleay/lilJudd/features/MatchManager.kt | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt new file mode 100644 index 0000000..a92ad6a --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt @@ -0,0 +1,88 @@ +/* + * 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.kord.common.entity.Snowflake +import net.moonleay.lilJudd.Bot +import net.moonleay.lilJudd.data.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.jobs.MatchJob +import net.moonleay.lilJudd.jobs.component.JobManager +import net.moonleay.lilJudd.util.Logger +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.selectAll +import org.jetbrains.exposed.sql.transactions.transaction + +object MatchManager { + suspend fun update() { + Logger.out("Updating match roles...") + val dataList = mutableListOf() + transaction { + MatchPlanningData.selectAll().forEach { + dataList.add( + MatchPlanningDataData( + it[MatchPlanningData.id].value, + it[MatchPlanningData.serverid], + it[MatchPlanningData.channelid], + it[MatchPlanningData.matchtype], + it[MatchPlanningData.registererid], + it[MatchPlanningData.roleid], + it[MatchPlanningData.opponentName], + it[MatchPlanningData.messageid], + it[MatchPlanningData.timestamp], + it[MatchPlanningData.jobstr] + ) + ) + } + } + + for (data in dataList) { + Logger.out("Checking match role ${data.id}...") + if (data.timestamp.toLong() < System.currentTimeMillis()) { + Logger.out("Match role ${data.id} is expired, removing...") + this.removeRoleFromGuild(data.serverid, data.roleid) + transaction { + MatchPlanningData.deleteWhere { MatchPlanningData.messageid eq data.messageid } + } + continue + } + this.registerJob(data) + } + Logger.out("Done. Until next time! <3 ") + } + + private fun registerJob(data: MatchPlanningDataData) { + JobManager.addJob( + MatchJob( + data.jobstr, + data.id, + "fromdb-${data.matchtype}_Vs_${data.opponentname}_[${data.id}]-${data.serverid}_${data.channelid}" + ) + ) + Logger.out("Registered job for match ${data.id}...") + } + + private suspend fun removeRoleFromGuild(gid: String, rid: String): Boolean { + val guild = Bot.bot.kordRef.getGuildOrNull(Snowflake(gid.toLong())) ?: return false + val role = guild.getRoleOrNull(Snowflake(rid.toLong())) ?: return false + role.delete() + return true + } +} -- 2.45.2 From 407f0ff1eaed10c64001edecdc05aab24ff765d8 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:21:08 +0200 Subject: [PATCH 051/168] feat: changed EditButton to an interface Signed-off-by: limited_dev --- .../buttons/component/{EditButton.kt => IEditButton.kt} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename src/main/kotlin/net/moonleay/lilJudd/buttons/component/{EditButton.kt => IEditButton.kt} (96%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt similarity index 96% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButton.kt rename to src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt index 45b2611..84e8a5b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt @@ -23,8 +23,9 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.interaction.ButtonInteraction -open class EditButton(val id: String) { +interface IEditButton { + val id: String open suspend fun onInteraction( interaction: ButtonInteraction, response: PublicMessageInteractionResponseBehavior, -- 2.45.2 From ad99e2767ea6ffbff28361cfea38aad46b69827e Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:23:03 +0200 Subject: [PATCH 052/168] feat: updated buttons and ButtonManager Signed-off-by: limited_dev --- .../moonleay/lilJudd/buttons/component/EditButtonManager.kt | 6 +++++- .../lilJudd/buttons/timeplanner/IsAvailableEditButton.kt | 6 ++++-- .../lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt | 6 ++++-- .../lilJudd/buttons/timeplanner/NotAvailableEditButton.kt | 5 +++-- 4 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt index 7f253f7..070f25a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt @@ -18,6 +18,8 @@ package net.moonleay.lilJudd.buttons.component +import net.moonleay.lilJudd.buttons.matchplanner.CancelEditButton +import net.moonleay.lilJudd.buttons.matchplanner.SignMeUpEditButton import net.moonleay.lilJudd.buttons.timeplanner.IsAvailableEditButton import net.moonleay.lilJudd.buttons.timeplanner.MaybeAvailableEditButton import net.moonleay.lilJudd.buttons.timeplanner.NotAvailableEditButton @@ -26,6 +28,8 @@ object EditButtonManager { val buttons = listOf( IsAvailableEditButton(), MaybeAvailableEditButton(), - NotAvailableEditButton() + NotAvailableEditButton(), + SignMeUpEditButton(), + CancelEditButton() ) } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt index 5d9802c..2acfe55 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt @@ -26,10 +26,12 @@ import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.EditButton +import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.util.EmbedUtil -class IsAvailableEditButton : EditButton("public.edit.btn.timemanagement.available") { +class IsAvailableEditButton : IEditButton { + override val id: String = "public.edit.btn.timemanagement.available" + override suspend fun onInteraction( interaction: ButtonInteraction, response: PublicMessageInteractionResponseBehavior, diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt index bac99ac..3696a54 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt @@ -26,10 +26,12 @@ import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.EditButton +import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.util.EmbedUtil -class MaybeAvailableEditButton : EditButton("public.edit.btn.timemanagement.maybeavailable") { +class MaybeAvailableEditButton : IEditButton { + override val id: String = "public.edit.btn.timemanagement.maybeavailable" + override suspend fun onInteraction( interaction: ButtonInteraction, response: PublicMessageInteractionResponseBehavior, diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt index 4c691e4..698993f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt @@ -26,10 +26,11 @@ import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.EditButton +import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.util.EmbedUtil -class NotAvailableEditButton : EditButton("public.edit.btn.timemanagement.notavailable") { +class NotAvailableEditButton : IEditButton { + override val id: String = "public.edit.btn.timemanagement.notavailable" override suspend fun onInteraction( interaction: ButtonInteraction, -- 2.45.2 From e04956a80091d6c5f1583aee73f434a16cc37e83 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:24:04 +0200 Subject: [PATCH 053/168] feat: added SignMeUpEditButton Signed-off-by: limited_dev --- .../matchplanner/SignMeUpEditButton.kt | 94 +++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/SignMeUpEditButton.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/SignMeUpEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/SignMeUpEditButton.kt new file mode 100644 index 0000000..fa47749 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/SignMeUpEditButton.kt @@ -0,0 +1,94 @@ +/* + * 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.buttons.matchplanner + +import dev.kord.common.entity.Snowflake +import dev.kord.core.behavior.edit +import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.kord.core.entity.channel.MessageChannel +import dev.kord.core.entity.interaction.ButtonInteraction +import dev.kord.rest.builder.message.modify.embed +import net.moonleay.lilJudd.Bot +import net.moonleay.lilJudd.buttons.component.IEditButton +import net.moonleay.lilJudd.data.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.util.EmbedUtil +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.transaction + +class SignMeUpEditButton() : IEditButton { + override val id: String = "public.edit.btn.matchmanagement.accept" + + override suspend fun onInteraction( + interaction: ButtonInteraction, + response: PublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val m = interaction.message + if (!m.embeds[0].fields[0].value.contains(user.id.value.toString())) { + lateinit var mpdd: MatchPlanningDataData + var found = false + transaction { + for (pnr in MatchPlanningData.select { + MatchPlanningData.messageid eq (interaction.message.id.value.toString()) and ( + MatchPlanningData.serverid eq (guild.id.value.toString())) and ( + MatchPlanningData.channelid eq (interaction.channelId.value.toString())) + }) { + mpdd = MatchPlanningDataData( + pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.serverid], + pnr[MatchPlanningData.channelid], + pnr[MatchPlanningData.matchtype], + pnr[MatchPlanningData.registererid], + pnr[MatchPlanningData.roleid], + pnr[MatchPlanningData.opponentName], + pnr[MatchPlanningData.messageid], + pnr[MatchPlanningData.timestamp], + pnr[MatchPlanningData.jobstr] + ) + found = true + } + } + if (!found || mpdd == null) { + return + } + val role = guild.getRoleOrNull(Snowflake(mpdd.roleid)) ?: return + val member = interaction.user.asMember(guild.id) + if (!member.roleIds.contains(Snowflake(mpdd.roleid))) { + member.addRole(role.id) + } + + //Add the user to the list in the embed + Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { + this.embed { + val temp = EmbedUtil.addXToValuesAtTable(user.id.value.toString(), m.embeds[0], 1) + this.color = temp.color + this.title = temp.title + this.description = temp.description + this.fields = temp.fields + this.footer = temp.footer + } + } + } + } +} -- 2.45.2 From 187da815e266125c7cd6fd0dbe7c981079d04e71 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:24:12 +0200 Subject: [PATCH 054/168] feat: added CancelEditButton Signed-off-by: limited_dev --- .../buttons/matchplanner/CancelEditButton.kt | 92 +++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt new file mode 100644 index 0000000..3925cd3 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt @@ -0,0 +1,92 @@ +/* + * 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.buttons.matchplanner + +import dev.kord.common.entity.Snowflake +import dev.kord.core.behavior.edit +import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.kord.core.entity.channel.MessageChannel +import dev.kord.core.entity.interaction.ButtonInteraction +import dev.kord.rest.builder.message.modify.embed +import net.moonleay.lilJudd.Bot +import net.moonleay.lilJudd.buttons.component.IEditButton +import net.moonleay.lilJudd.data.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.util.EmbedUtil +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.transaction + +class CancelEditButton : IEditButton { + override val id: String = "public.edit.btn.matchmanagement.cancel" + + override suspend fun onInteraction( + interaction: ButtonInteraction, + response: PublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val m = interaction.message + if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { + lateinit var mpdd: MatchPlanningDataData + var found = false + transaction { + for (pnr in MatchPlanningData.select { + MatchPlanningData.messageid eq (interaction.message.id.value.toString()) and ( + MatchPlanningData.serverid eq (guild.id.value.toString())) and ( + MatchPlanningData.channelid eq (interaction.channelId.value.toString())) + }) { + mpdd = MatchPlanningDataData( + pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.serverid], + pnr[MatchPlanningData.channelid], + pnr[MatchPlanningData.matchtype], + pnr[MatchPlanningData.registererid], + pnr[MatchPlanningData.roleid], + pnr[MatchPlanningData.opponentName], + pnr[MatchPlanningData.messageid], + pnr[MatchPlanningData.timestamp], + pnr[MatchPlanningData.jobstr] + ) + found = true + } + } + if (!found || mpdd == null) { + return + } + val role = guild.getRoleOrNull(Snowflake(mpdd.roleid)) ?: return + val member = interaction.user.asMember(guild.id) + if (member.roleIds.contains(Snowflake(mpdd.roleid))) { + member.removeRole(role.id) + } + Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { + this.embed { + val temp = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 1) + this.color = temp.color + this.title = temp.title + this.description = temp.description + this.fields = temp.fields + this.footer = temp.footer + } + } + } + } +} -- 2.45.2 From ef28b08214378ed1aca78430d012b508d6527363 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:25:03 +0200 Subject: [PATCH 055/168] feat: added cronjob system Signed-off-by: limited_dev --- .../lilJudd/jobs/component/CronjobType.kt | 25 +++++ .../lilJudd/jobs/component/ICronjob.kt | 47 +++++++++ .../lilJudd/jobs/component/JobManager.kt | 96 +++++++++++++++++++ 3 files changed, 168 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/component/CronjobType.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/component/ICronjob.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/component/JobManager.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/CronjobType.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/component/CronjobType.kt new file mode 100644 index 0000000..fa34b60 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/component/CronjobType.kt @@ -0,0 +1,25 @@ +/* + * 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.jobs.component + +enum class CronjobType { + INFINITE, + ONCE, + WHILE +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/ICronjob.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/component/ICronjob.kt new file mode 100644 index 0000000..d3f6700 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/component/ICronjob.kt @@ -0,0 +1,47 @@ +/* + * 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.jobs.component + +import dev.inmo.krontab.KronScheduler +import kotlinx.coroutines.Job + +interface ICronjob { + val jobName: String + + /* /--------------- Seconds + | /------------- Minutes + | | /----------- Hours + | | | /--------- Days of months + | | | | /------- Months + | | | | | /----- (optional) Year + | | | | | | /--- (optional) Timezone offset + | | | | | | | / (optional) Week days + * * * * * * 0o *w + */ + + val jobIncoming: String + val jobType: CronjobType + + val continueJob: Boolean + + var cronjobJob: Job + var scheduler: KronScheduler + suspend fun jobFunction() + +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/JobManager.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/component/JobManager.kt new file mode 100644 index 0000000..cc55256 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/component/JobManager.kt @@ -0,0 +1,96 @@ +/* + * 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.jobs.component + +import dev.inmo.krontab.buildSchedule +import dev.inmo.krontab.doInfinityTz +import dev.inmo.krontab.doOnceTz +import dev.inmo.krontab.doWhileTz +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import net.moonleay.lilJudd.util.Logger +import java.time.LocalDateTime +import java.time.format.DateTimeFormatter + +object JobManager { + private val jobs: MutableList = mutableListOf() + + // Add a cronjob and register it + fun addJob(job: ICronjob) { + if (jobs.contains(job)) { + killJob(job) + } + registerJob(job) + jobs.add(job) + Logger.out("Registered job \"${job.jobName}\" of type \"${job.javaClass.name}\".") + } + + // Register a cronjob + private fun registerJob(job: ICronjob) { + Logger.out( + "INFO: Registering job \"${job.jobName}\"of type ${job.javaClass.name} at ${ + LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + }" + ) + job.cronjobJob = CoroutineScope(Dispatchers.Default).launch { + job.scheduler = buildSchedule(job.jobIncoming) + Logger.out("Registered job \"${job.jobName}\"of type ${job.javaClass.name} to run at timer \"${job.jobIncoming}\".") + when (job.jobType) { + // Runs the job once at the specified time + CronjobType.ONCE -> { + job.scheduler.doOnceTz { + job.jobFunction() + } + } + // Runs the job whiles the variable is set to true + CronjobType.WHILE -> { + job.scheduler.doWhileTz { + job.jobFunction() + job.continueJob + } + } + // Run this job until the programm stops + CronjobType.INFINITE -> { + job.scheduler.doInfinityTz { + job.jobFunction() + } + } + } + } + } + + // Kill all cronjobs + fun killAllJobs() { + for (j in jobs) { + killJob(j) + } + } + + // Kill a cronjob + fun killJob(j: ICronjob) { + if (!jobs.contains(j)) { + Logger.out("This job does not exist.") + return + } + Logger.out("Killing job \"${j.jobName}\" of type ${j.javaClass.name}.") + j.cronjobJob.cancel() + jobs.remove(j) + } +} -- 2.45.2 From 9099d02bf4901b7c91536b2d6e663310985581df Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:26:00 +0200 Subject: [PATCH 056/168] feat: added getMatchButtons to EmbedUtil Signed-off-by: limited_dev --- .../kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt index 831d4e7..d367709 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt @@ -38,6 +38,17 @@ object EmbedUtil { return ar } + fun getMatchButtons(): ActionRowBuilder { + val ar = ActionRowBuilder() + ar.interactionButton(ButtonStyle.Success, "public.edit.btn.matchmanagement.accept") { + this.label = "Sign me up!" + } + ar.interactionButton(ButtonStyle.Danger, "public.edit.btn.matchmanagement.cancel") { + this.label = "Cancel" + } + return ar + } + fun replaceXWithYinValuesAtTable(x: String, y: String, e: Embed, table: Int): EmbedBuilder { val ebb = MessageUtil.getAClonedEmbedd(e) for ((i, f) in e.fields.withIndex()) { -- 2.45.2 From 9fa7f38228ed31ee7a92c8360c15738bc396991d Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:26:27 +0200 Subject: [PATCH 057/168] feat: added MatchJob to clean up roles Signed-off-by: limited_dev --- .../net/moonleay/lilJudd/jobs/MatchJob.kt | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt new file mode 100644 index 0000000..394758a --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt @@ -0,0 +1,90 @@ +/* + * 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.jobs + +import dev.inmo.krontab.KronScheduler +import dev.kord.common.entity.Snowflake +import kotlinx.coroutines.Job +import net.moonleay.lilJudd.Bot +import net.moonleay.lilJudd.data.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.jobs.component.CronjobType +import net.moonleay.lilJudd.jobs.component.ICronjob +import net.moonleay.lilJudd.jobs.component.JobManager +import net.moonleay.lilJudd.util.Logger +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.transaction + +class MatchJob( + override val jobIncoming: String, + private val tableId: Int, + override val jobName: String, +) : ICronjob { + override val jobType: CronjobType = CronjobType.ONCE + override val continueJob: Boolean = true + override lateinit var cronjobJob: Job + override lateinit var scheduler: KronScheduler + + /* + * This job should delete the role, which was created for the match. + * */ + override suspend fun jobFunction() { + Logger.out("Running MatchJob \"${this.jobName}\"") + lateinit var mpdd: MatchPlanningDataData + transaction { + for (pnr in MatchPlanningData.select { + MatchPlanningData.id eq (tableId) + }) { + mpdd = MatchPlanningDataData( + pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.serverid], + pnr[MatchPlanningData.channelid], + pnr[MatchPlanningData.matchtype], + pnr[MatchPlanningData.registererid], + pnr[MatchPlanningData.roleid], + pnr[MatchPlanningData.opponentName], + pnr[MatchPlanningData.messageid], + pnr[MatchPlanningData.timestamp], + pnr[MatchPlanningData.jobstr] + ) + } + } + val guild = Bot.bot.kordRef.getGuildOrNull(Snowflake(mpdd.serverid)) + if (guild == null) { + Logger.out("Guild not found.") + return + } + val r = guild.getRoleOrNull(Snowflake(mpdd.roleid)) + if (r == null) { + Logger.out("Role not found.") + return + } + r.delete() + transaction { + MatchPlanningData.deleteWhere { + MatchPlanningData.id eq (tableId) + } + } + Logger.out("MatchJob \"${this.jobName}\" finished.") + Logger.out("Killing job \"${this.jobName}\"..") + JobManager.killJob(this) + } +} -- 2.45.2 From 6b0bf40e0a6427dc79e29b3f444e7c535e49b504 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:28:24 +0200 Subject: [PATCH 058/168] feat: added MatchExtension, added MatchManager updater chore: updated comments Signed-off-by: limited_dev --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index c12a304..be764de 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -36,9 +36,11 @@ import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager import net.moonleay.lilJudd.data.DB import net.moonleay.lilJudd.extensions.FeatureManageExtension +import net.moonleay.lilJudd.extensions.MatchExtension import net.moonleay.lilJudd.extensions.SendPlannerExtension import net.moonleay.lilJudd.extensions.VersionExtension import net.moonleay.lilJudd.features.AvailabilityManager +import net.moonleay.lilJudd.features.MatchManager import net.moonleay.lilJudd.features.TimeManager import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil @@ -90,7 +92,7 @@ object Bot { ) // Thanks silenium-dev <3 - // Add bot token to kord + // Create the bot object bot = ExtensibleBot(CredentialManager.token) { applicationCommands { enabled = true @@ -100,6 +102,7 @@ object Bot { add(::VersionExtension) add(::FeatureManageExtension) add(::SendPlannerExtension) + add(::MatchExtension) //add(::UpdateRolesExtension) // This command is only for debugging purposes //add(::TestExtension) // See comment in TestExtension.kt } @@ -118,6 +121,7 @@ object Bot { sharding { recommended -> Shards(recommended) } */ + // Same goes for a Database table rewrite } // Register button presses @@ -152,9 +156,9 @@ object Bot { } } - // Update roles bot.kordRef.on { - AvailabilityManager.runThread() + AvailabilityManager.runThread() // Update Availabilities + MatchManager.update() // Update Matches } -- 2.45.2 From 213cb45d6cc6a07441429b04ee2fc27a0056fb61 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Wed, 12 Jul 2023 13:35:09 +0200 Subject: [PATCH 059/168] fix: fixed gitlab-ci.yml Signed-off-by: limited_dev --- .gitlab-ci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ba0f4a1..9a371db 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -26,8 +26,6 @@ build: stage: build script: - gradle shadowJar - except: - - tags publish: only: -- 2.45.2 From c663641e4290c2764b5e92128ff01c18950e9f00 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 13 Jul 2023 00:58:43 +0200 Subject: [PATCH 060/168] fix: fixed AvailabilityManager not being able to set the right roles Signed-off-by: limited_dev --- .../kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt | 1 - src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 77fb1ea..1359f50 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -180,7 +180,6 @@ object AvailabilityManager : IFeature { }.count() > 0 } if (!alreadyExists) { - // Create the roles in Discord val hasTimeRole = Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)).createRole { this.name = "available [${ch.data.name.value}]" diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 43165db..0ac7b1b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -154,7 +154,7 @@ object TimeManager : IFeature { it[TimePlanningMessages.channelid] = c.id.value.toString() it[TimePlanningMessages.weekstamp] = TimeUtil.getWeekStamp().toOffsetDateTime().toString() it[TimePlanningMessages.messageids] = msgStr - } get PlanningNotifierRoles.id + } get TimePlanningMessages.id } Logger.out("Finished with ${c.data.guildId.value}") } -- 2.45.2 From 86771a36fb39242d018014bdd1fe62cfef0b54e2 Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 13 Jul 2023 00:58:51 +0200 Subject: [PATCH 061/168] chore: formatting Signed-off-by: limited_dev --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9a371db..bcdee2b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -33,4 +33,3 @@ publish: stage: publish script: - gradle publish - -- 2.45.2 From bf9754f40424ffa18d1ea55e4f4e32bd22a0c28e Mon Sep 17 00:00:00 2001 From: limited_dev Date: Thu, 13 Jul 2023 01:15:24 +0200 Subject: [PATCH 062/168] chore: bump version Signed-off-by: limited_dev --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index dd2e5fe..f62ca80 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.4.0" + ?: "2.4.2" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From 4ae3b0052bfb5dfa7291890dfaccd2ce157334da Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 4 Aug 2023 21:17:15 +0200 Subject: [PATCH 063/168] feat: add build.yml Signed-off-by: moonleay --- .forgejo/workflows/build.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .forgejo/workflows/build.yml diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml new file mode 100644 index 0000000..d7453ff --- /dev/null +++ b/.forgejo/workflows/build.yml @@ -0,0 +1,15 @@ +on: [ push ] +jobs: + build_and_publish: + runs-on: gradle + steps: + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + - name: Clean Caches + run: | + rm -f .gradle/caches/modules-2/modules-2.lock + rm -fr .gradle/caches/*/plugin-resolution/ + - name: Run shadowJar + run: ./gradlew shadowJar + - name: Run publish + run: ./gradlew publish -- 2.45.2 From 0c363391baecc43f2a0592cfa979ab4911d03fe1 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 4 Aug 2023 21:17:52 +0200 Subject: [PATCH 064/168] fix: fixed build.yml Signed-off-by: moonleay --- .forgejo/workflows/action.yml | 22 ++++++++++++++++++++++ .forgejo/workflows/build.yml | 15 --------------- 2 files changed, 22 insertions(+), 15 deletions(-) create mode 100644 .forgejo/workflows/action.yml delete mode 100644 .forgejo/workflows/build.yml diff --git a/.forgejo/workflows/action.yml b/.forgejo/workflows/action.yml new file mode 100644 index 0000000..dc16848 --- /dev/null +++ b/.forgejo/workflows/action.yml @@ -0,0 +1,22 @@ +on: [ push ] +jobs: + build_and_publish: + runs-on: docker + container: + image: gradle + steps: + steps: + - name: Checkout code + uses: actions/checkout@v2 + - name: Build and Package JAR with Gradle + uses: docker://gradle:latest # Use the official Gradle Docker image + with: + args: shadowJar + - name: Clean Caches + run: | + rm -f .gradle/caches/modules-2/modules-2.lock + rm -fr .gradle/caches/*/plugin-resolution/ + - name: Run shadowJar + run: gradle shadowJar + - name: Run publish + run: gradle publish diff --git a/.forgejo/workflows/build.yml b/.forgejo/workflows/build.yml deleted file mode 100644 index d7453ff..0000000 --- a/.forgejo/workflows/build.yml +++ /dev/null @@ -1,15 +0,0 @@ -on: [ push ] -jobs: - build_and_publish: - runs-on: gradle - steps: - - name: Setup Gradle - uses: gradle/gradle-build-action@v2 - - name: Clean Caches - run: | - rm -f .gradle/caches/modules-2/modules-2.lock - rm -fr .gradle/caches/*/plugin-resolution/ - - name: Run shadowJar - run: ./gradlew shadowJar - - name: Run publish - run: ./gradlew publish -- 2.45.2 From a3d3005ff06f5ea1657b3e781326bd55bab598c2 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Sep 2023 21:59:41 +0200 Subject: [PATCH 065/168] chore: improved imports Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index be764de..1c6e337 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -35,10 +35,7 @@ import net.moonleay.botendo.build.BuildConstants import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager import net.moonleay.lilJudd.data.DB -import net.moonleay.lilJudd.extensions.FeatureManageExtension -import net.moonleay.lilJudd.extensions.MatchExtension -import net.moonleay.lilJudd.extensions.SendPlannerExtension -import net.moonleay.lilJudd.extensions.VersionExtension +import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.features.MatchManager import net.moonleay.lilJudd.features.TimeManager @@ -103,7 +100,7 @@ object Bot { add(::FeatureManageExtension) add(::SendPlannerExtension) add(::MatchExtension) - //add(::UpdateRolesExtension) // This command is only for debugging purposes + add(::UpdateRolesExtension) // This command is only for debugging purposes //add(::TestExtension) // See comment in TestExtension.kt } -- 2.45.2 From 6ab6aa1279364df7a1e8a626db74d301c255450b Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Sep 2023 22:03:50 +0200 Subject: [PATCH 066/168] fix: fixed weekstamp Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 0ac7b1b..9acbc33 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -94,6 +94,7 @@ object TimeManager : IFeature { 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)!! + msgStr = "" if (roleMap != null && roleMap.keys.contains(ch) && roleMap[ch] != null) { c.createMessage { this.content = @@ -152,7 +153,7 @@ object TimeManager : IFeature { TimePlanningMessages.insert { it[TimePlanningMessages.serverid] = c.data.guildId.value.toString() it[TimePlanningMessages.channelid] = c.id.value.toString() - it[TimePlanningMessages.weekstamp] = TimeUtil.getWeekStamp().toOffsetDateTime().toString() + it[TimePlanningMessages.weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000).toString() it[TimePlanningMessages.messageids] = msgStr } get TimePlanningMessages.id } -- 2.45.2 From 4f3c76910cba591c05561ba27eac03fe98579d5b Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Sep 2023 22:05:29 +0200 Subject: [PATCH 067/168] fix: fixed AvailabilityManager Signed-off-by: moonleay --- .../moonleay/lilJudd/features/AvailabilityManager.kt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 1359f50..2a980dc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -96,8 +96,8 @@ object AvailabilityManager : IFeature { } val roleData = roleMap[data.channelid] // Get the role data if (roleData == null) { - Logger.out("Role for this channel does not exist") - return + Logger.out("Role for channel ${data.channelid} does not exist") + continue // this took way to long to find out that this was the issue } val g = Bot.bot.kordRef.getGuildOrThrow(Snowflake(data.serverid)) // Get all members with the role @@ -106,9 +106,11 @@ object AvailabilityManager : IFeature { } mce.collect { memberchunkevent -> memberchunkevent.members.forEach { - Logger.out("Checking member ${it.id.value}") - if (it.roleIds.contains(Snowflake(roleData.hastimeroleid))) + Logger.out("Checking member ${it.id.value} (${it.username})") + if (it.roleIds.contains(Snowflake(roleData.hastimeroleid))) { it.removeRole(Snowflake(roleData.hastimeroleid)) + Logger.out("Removed role from ${it.username}") // Removed the role + } } } -- 2.45.2 From c16ff4bdbacac420636036b4260cb0fb0f5e0989 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Sep 2023 22:06:14 +0200 Subject: [PATCH 068/168] chore: improved readability Signed-off-by: moonleay --- .../moonleay/lilJudd/extensions/SendPlannerExtension.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index 2a56745..c02294e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -107,10 +107,10 @@ class SendPlannerExtension : Extension() { // Save the message ids transaction { TimePlanningMessages.insert { - it[serverid] = c.data.guildId.value.toString() - it[channelid] = c.id.value.toString() - it[weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000).toString() - it[messageids] = msgStr + it[TimePlanningMessages.serverid] = c.data.guildId.value.toString() + it[TimePlanningMessages.channelid] = c.id.value.toString() + it[TimePlanningMessages.weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000).toString() + it[TimePlanningMessages.messageids] = msgStr } get TimePlanningMessages.id } Logger.out("Finished with ${c.data.guildId.value}") -- 2.45.2 From e051335d84e3bce4be7d3e4c0754e7bf86fcf38d Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Sep 2023 22:09:59 +0200 Subject: [PATCH 069/168] feat: Roles now update on button press Signed-off-by: moonleay --- .../lilJudd/buttons/timeplanner/IsAvailableEditButton.kt | 2 ++ .../lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt | 2 ++ .../lilJudd/buttons/timeplanner/NotAvailableEditButton.kt | 2 ++ 3 files changed, 6 insertions(+) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt index 2acfe55..6140d4d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt @@ -27,6 +27,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton +import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.util.EmbedUtil class IsAvailableEditButton : IEditButton { @@ -62,5 +63,6 @@ class IsAvailableEditButton : IEditButton { } } } + AvailabilityManager.runThread() } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt index 3696a54..c3eaec2 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt @@ -27,6 +27,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton +import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.util.EmbedUtil class MaybeAvailableEditButton : IEditButton { @@ -62,5 +63,6 @@ class MaybeAvailableEditButton : IEditButton { } } } + AvailabilityManager.runThread() } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt index 698993f..b56db11 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt @@ -27,6 +27,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton +import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.util.EmbedUtil class NotAvailableEditButton : IEditButton { @@ -62,5 +63,6 @@ class NotAvailableEditButton : IEditButton { } } } + AvailabilityManager.runThread() } } -- 2.45.2 From b8915cfefa085c3b9a02b5960309021f2089aaef Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Sep 2023 22:10:17 +0200 Subject: [PATCH 070/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index f62ca80..3292b17 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.4.2" + ?: "2.4.3" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From 9c27e13ec6aee946af024a0eb5eb279a24819476 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sat, 12 Aug 2023 13:47:55 +0200 Subject: [PATCH 071/168] Update .forgejo/workflows/action.yml Signed-off-by: moonleay --- .forgejo/workflows/action.yml | 43 +++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/.forgejo/workflows/action.yml b/.forgejo/workflows/action.yml index dc16848..d9e4272 100644 --- a/.forgejo/workflows/action.yml +++ b/.forgejo/workflows/action.yml @@ -1,22 +1,25 @@ -on: [ push ] +name: Build Gradle project + +on: + push: + jobs: - build_and_publish: - runs-on: docker - container: - image: gradle + build-gradle-project: + runs-on: ubuntu-latest steps: - steps: - - name: Checkout code - uses: actions/checkout@v2 - - name: Build and Package JAR with Gradle - uses: docker://gradle:latest # Use the official Gradle Docker image - with: - args: shadowJar - - name: Clean Caches - run: | - rm -f .gradle/caches/modules-2/modules-2.lock - rm -fr .gradle/caches/*/plugin-resolution/ - - name: Run shadowJar - run: gradle shadowJar - - name: Run publish - run: gradle publish + - name: apt 1 + run: apt update + - name: apt 2 + run: apt upgrade -y + - name: install prerequisits + run: apt install openjdk-17-jdk ca-certificates-java ssl-cert openssl ca-certificates -y + - name: Checkout project sources + uses: actions/checkout@v3 + - name: Setup Gradle + uses: gradle/gradle-build-action@v2 + - name: Run build with Gradle Wrapper + run: ./gradlew shadowJar + - uses: actions/upload-artifact@v3 + with: + name: lilJudd.jar + path: build/libs/ \ No newline at end of file -- 2.45.2 From 54315159765e9b39feccdc2c4e83dcd16646ef36 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 12:44:34 +0200 Subject: [PATCH 072/168] feat: improved getAClonedEmbed function, added an equivalent using a EmbedBuilder Signed-off-by: moonleay --- .../net/moonleay/lilJudd/util/MessageUtil.kt | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt index dc0a34a..0e34571 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt @@ -71,11 +71,33 @@ object MessageUtil { } } - ///Get a cloned embedded message, missing only the fields - fun getAClonedEmbedd(e: Embed): EmbedBuilder { + ///Get a cloned embedded message + fun getAClonedEmbed(e: Embed): EmbedBuilder { val ebb = EmbedBuilder() ebb.color = e.color ebb.title = e.title + e.fields.forEach { + val fb = EmbedBuilder.Field() + fb.name = it.name + fb.value = it.value + fb.inline = it.inline + ebb.fields.add(fb) + } + ebb.description = e.description + return ebb + } + + fun getAClonedEmbed(e: EmbedBuilder): EmbedBuilder { + val ebb = EmbedBuilder() + ebb.color = e.color + ebb.title = e.title + e.fields.forEach { + val fb = EmbedBuilder.Field() + fb.name = it.name + fb.value = it.value + fb.inline = it.inline + ebb.fields.add(fb) + } ebb.description = e.description return ebb } -- 2.45.2 From 8dd123fe44a57848a634167dcab0cf7375e1eccf Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 12:45:51 +0200 Subject: [PATCH 073/168] feat: improved replaceXWithYinValuesAtTable function, edited MatchButtons Signed-off-by: moonleay --- .../net/moonleay/lilJudd/util/EmbedUtil.kt | 36 +++++++++++++------ 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt index d367709..e9dbbaf 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt @@ -41,17 +41,26 @@ object EmbedUtil { fun getMatchButtons(): ActionRowBuilder { val ar = ActionRowBuilder() ar.interactionButton(ButtonStyle.Success, "public.edit.btn.matchmanagement.accept") { - this.label = "Sign me up!" + this.label = "I'm in!" } - ar.interactionButton(ButtonStyle.Danger, "public.edit.btn.matchmanagement.cancel") { - this.label = "Cancel" + ar.interactionButton(ButtonStyle.Danger, "public.edit.btn.matchmanagement.decline") { + this.label = "I'm out!" } + /* + ar.interactionButton(ButtonStyle.Secondary, "public.edit.btn.matchmanagement.cancel") { + this.label = "Cancel this match..." + } */ return ar } fun replaceXWithYinValuesAtTable(x: String, y: String, e: Embed, table: Int): EmbedBuilder { - val ebb = MessageUtil.getAClonedEmbedd(e) - for ((i, f) in e.fields.withIndex()) { + return replaceXWithYinValuesAtTable(x, y, MessageUtil.getAClonedEmbed(e), table) + } + + fun replaceXWithYinValuesAtTable(x: String, y: String, ebb: EmbedBuilder, table: Int): EmbedBuilder { + val ebbb = MessageUtil.getAClonedEmbed(ebb) + ebbb.fields = mutableListOf() + for ((i, f) in ebb.fields.withIndex()) { val fb = EmbedBuilder.Field() fb.name = f.name if (i == table - 1) { @@ -66,9 +75,9 @@ object EmbedUtil { } else fb.value = f.value fb.inline = true - ebb.fields.add(fb) + ebbb.fields.add(fb) } - return ebb + return ebbb } fun getAllUsersInTheFirstXTables(amountOfTables: Int, e: Embed): List { @@ -87,8 +96,13 @@ object EmbedUtil { } fun addXToValuesAtTable(x: String, e: Embed, table: Int): EmbedBuilder { - val ebb = MessageUtil.getAClonedEmbedd(e) - for ((i, f) in e.fields.withIndex()) { + return addXToValuesAtTable(x, MessageUtil.getAClonedEmbed(e), table) + } + + fun addXToValuesAtTable(x: String, ebb: EmbedBuilder, table: Int): EmbedBuilder { + val ebbb = MessageUtil.getAClonedEmbed(ebb) + ebbb.fields = mutableListOf() + ebb.fields.forEachIndexed { i, f -> val fb = EmbedBuilder.Field() fb.name = f.name if (i == table - 1) @@ -105,9 +119,9 @@ object EmbedUtil { } fb.inline = true - ebb.fields.add(fb) + ebbb.fields.add(fb) } - return ebb + return ebbb } } -- 2.45.2 From 6b612dcec69103864829d07b19c70dacedadfad0 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 12:46:33 +0200 Subject: [PATCH 074/168] feat: added Unavailable to MatchExtension table Signed-off-by: moonleay --- .../kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index be28081..4eb1db0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -67,6 +67,7 @@ class MatchExtension : Extension() { "Registered by ${m.mention}", mapOf( "Signed up" to listOf(), + "Unavailable" to listOf(), ) ) ) @@ -120,7 +121,7 @@ class MatchExtension : Extension() { MatchJob( jobString, tableID.value, - "${args.matchType.readableName}_Vs_${opponent}_[${tableID.value}]-${gID}_${cID}" + "${args.matchType.readableName}_Vs_${opponent}_[${tableID.value}]-${gID}_${cID}", ) ) } -- 2.45.2 From 5d2ef4fc44469cf99bfb59d2c14006b90a7906f9 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 12:47:06 +0200 Subject: [PATCH 075/168] feat: improved function of AcceptEditButton Signed-off-by: moonleay --- .../buttons/matchplanner/AcceptEditButton.kt | 119 ++++++++++++++++++ .../matchplanner/SignMeUpEditButton.kt | 94 -------------- 2 files changed, 119 insertions(+), 94 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/SignMeUpEditButton.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt new file mode 100644 index 0000000..c9f33e7 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt @@ -0,0 +1,119 @@ +/* + * 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.buttons.matchplanner + +import dev.kord.common.entity.Snowflake +import dev.kord.core.behavior.edit +import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.kord.core.entity.channel.MessageChannel +import dev.kord.core.entity.interaction.ButtonInteraction +import dev.kord.rest.builder.message.modify.embed +import net.moonleay.lilJudd.Bot +import net.moonleay.lilJudd.buttons.component.IEditButton +import net.moonleay.lilJudd.data.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.util.EmbedUtil +import net.moonleay.lilJudd.util.Logger +import net.moonleay.lilJudd.util.MessageUtil +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.transaction + +class AcceptEditButton() : IEditButton { + override val id: String = "public.edit.btn.matchmanagement.accept" + + override suspend fun onInteraction( + interaction: ButtonInteraction, + response: PublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val m = interaction.message + val eb = MessageUtil.getAClonedEmbed(m.embeds[0]) + var shouldEditButton = false + lateinit var mpdd: MatchPlanningDataData + var found = false + transaction { + for (pnr in MatchPlanningData.select { + MatchPlanningData.messageid eq (interaction.message.id.value.toString()) and ( + MatchPlanningData.serverid eq (guild.id.value.toString())) and ( + MatchPlanningData.channelid eq (interaction.channelId.value.toString())) + }) { + mpdd = MatchPlanningDataData( + pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.serverid], + pnr[MatchPlanningData.channelid], + pnr[MatchPlanningData.matchtype], + pnr[MatchPlanningData.registererid], + pnr[MatchPlanningData.roleid], + pnr[MatchPlanningData.opponentName], + pnr[MatchPlanningData.messageid], + pnr[MatchPlanningData.timestamp], + pnr[MatchPlanningData.jobstr] + ) + found = true + } + } + if (!found || mpdd == null) { + return + } + val role = guild.getRoleOrNull(Snowflake(mpdd.roleid)) ?: return + val member = interaction.user.asMember(guild.id) ?: return + // do the checks and update + if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { + if (member.roleIds.contains(Snowflake(mpdd.roleid))) { + Logger.out("Removing role from ${member.username}") + member.removeRole(role.id) + } + // remove the user from the 1st list in the embed + Logger.out("Removing ${user.username} from the 1st list in the embed") + eb.fields = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", eb, 1).fields + shouldEditButton = true + } + if (m.embeds[0].fields[1].value.contains(user.id.value.toString())) { + Logger.out("Removing ${user.username} from the 2nd list in the embed") + eb.fields = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", eb, 2).fields + shouldEditButton = true + } + if (!m.embeds[0].fields[0].value.contains(user.id.value.toString())) { + if (!member.roleIds.contains(Snowflake(mpdd.roleid))) { + Logger.out("Adding role to ${member.username}") + member.addRole(role.id) + } + //Add the user to the list in the embed + Logger.out("Adding ${user.username} to the 1st list in the embed") + eb.fields = EmbedUtil.addXToValuesAtTable(user.id.value.toString(), eb, 1).fields + shouldEditButton = true + } + if (shouldEditButton) { + // update the message + Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { + this.embed { + this.color = eb.color + this.title = eb.title + this.description = eb.description + this.fields = eb.fields + this.footer = eb.footer + } + } + } + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/SignMeUpEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/SignMeUpEditButton.kt deleted file mode 100644 index fa47749..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/SignMeUpEditButton.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * 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.buttons.matchplanner - -import dev.kord.common.entity.Snowflake -import dev.kord.core.behavior.edit -import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior -import dev.kord.core.entity.Guild -import dev.kord.core.entity.User -import dev.kord.core.entity.channel.MessageChannel -import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.tables.MatchPlanningData -import net.moonleay.lilJudd.util.EmbedUtil -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.transactions.transaction - -class SignMeUpEditButton() : IEditButton { - override val id: String = "public.edit.btn.matchmanagement.accept" - - override suspend fun onInteraction( - interaction: ButtonInteraction, - response: PublicMessageInteractionResponseBehavior, - guild: Guild, - user: User - ) { - val m = interaction.message - if (!m.embeds[0].fields[0].value.contains(user.id.value.toString())) { - lateinit var mpdd: MatchPlanningDataData - var found = false - transaction { - for (pnr in MatchPlanningData.select { - MatchPlanningData.messageid eq (interaction.message.id.value.toString()) and ( - MatchPlanningData.serverid eq (guild.id.value.toString())) and ( - MatchPlanningData.channelid eq (interaction.channelId.value.toString())) - }) { - mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id].value, - pnr[MatchPlanningData.serverid], - pnr[MatchPlanningData.channelid], - pnr[MatchPlanningData.matchtype], - pnr[MatchPlanningData.registererid], - pnr[MatchPlanningData.roleid], - pnr[MatchPlanningData.opponentName], - pnr[MatchPlanningData.messageid], - pnr[MatchPlanningData.timestamp], - pnr[MatchPlanningData.jobstr] - ) - found = true - } - } - if (!found || mpdd == null) { - return - } - val role = guild.getRoleOrNull(Snowflake(mpdd.roleid)) ?: return - val member = interaction.user.asMember(guild.id) - if (!member.roleIds.contains(Snowflake(mpdd.roleid))) { - member.addRole(role.id) - } - - //Add the user to the list in the embed - Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { - this.embed { - val temp = EmbedUtil.addXToValuesAtTable(user.id.value.toString(), m.embeds[0], 1) - this.color = temp.color - this.title = temp.title - this.description = temp.description - this.fields = temp.fields - this.footer = temp.footer - } - } - } - } -} -- 2.45.2 From 998de8bae55ce48b652168f2a5481bff25425b44 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 12:47:31 +0200 Subject: [PATCH 076/168] feat: added DeclineEditButton Signed-off-by: moonleay --- .../buttons/component/EditButtonManager.kt | 8 +- .../buttons/matchplanner/DeclineEditButton.kt | 119 ++++++++++++++++++ 2 files changed, 124 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt index 070f25a..f0df57f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt @@ -18,8 +18,9 @@ package net.moonleay.lilJudd.buttons.component +import net.moonleay.lilJudd.buttons.matchplanner.AcceptEditButton import net.moonleay.lilJudd.buttons.matchplanner.CancelEditButton -import net.moonleay.lilJudd.buttons.matchplanner.SignMeUpEditButton +import net.moonleay.lilJudd.buttons.matchplanner.DeclineEditButton import net.moonleay.lilJudd.buttons.timeplanner.IsAvailableEditButton import net.moonleay.lilJudd.buttons.timeplanner.MaybeAvailableEditButton import net.moonleay.lilJudd.buttons.timeplanner.NotAvailableEditButton @@ -29,7 +30,8 @@ object EditButtonManager { IsAvailableEditButton(), MaybeAvailableEditButton(), NotAvailableEditButton(), - SignMeUpEditButton(), - CancelEditButton() + AcceptEditButton(), + CancelEditButton(), + DeclineEditButton(), ) } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt new file mode 100644 index 0000000..67b193e --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt @@ -0,0 +1,119 @@ +/* + * 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.buttons.matchplanner + +import dev.kord.common.entity.Snowflake +import dev.kord.core.behavior.edit +import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior +import dev.kord.core.entity.Guild +import dev.kord.core.entity.User +import dev.kord.core.entity.channel.MessageChannel +import dev.kord.core.entity.interaction.ButtonInteraction +import dev.kord.rest.builder.message.modify.embed +import net.moonleay.lilJudd.Bot +import net.moonleay.lilJudd.buttons.component.IEditButton +import net.moonleay.lilJudd.data.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.util.EmbedUtil +import net.moonleay.lilJudd.util.Logger +import net.moonleay.lilJudd.util.MessageUtil +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.transaction + +class DeclineEditButton : IEditButton { + override val id: String = "public.edit.btn.matchmanagement.decline" + + override suspend fun onInteraction( + interaction: ButtonInteraction, + response: PublicMessageInteractionResponseBehavior, + guild: Guild, + user: User + ) { + val m = interaction.message + val eb = MessageUtil.getAClonedEmbed(m.embeds[0]) + var shouldEditButton = false + lateinit var mpdd: MatchPlanningDataData + var found = false + transaction { + for (pnr in MatchPlanningData.select { + MatchPlanningData.messageid eq (interaction.message.id.value.toString()) and ( + MatchPlanningData.serverid eq (guild.id.value.toString())) and ( + MatchPlanningData.channelid eq (interaction.channelId.value.toString())) + }) { + mpdd = MatchPlanningDataData( + pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.serverid], + pnr[MatchPlanningData.channelid], + pnr[MatchPlanningData.matchtype], + pnr[MatchPlanningData.registererid], + pnr[MatchPlanningData.roleid], + pnr[MatchPlanningData.opponentName], + pnr[MatchPlanningData.messageid], + pnr[MatchPlanningData.timestamp], + pnr[MatchPlanningData.jobstr] + ) + found = true + } + } + if (!found || mpdd == null) { + return + } + val role = guild.getRoleOrNull(Snowflake(mpdd.roleid)) ?: return + val member = interaction.user.asMember(guild.id) ?: return + if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { + if (member.roleIds.contains(Snowflake(mpdd.roleid))) { + Logger.out("Removing role from ${member.username}") + member.removeRole(role.id) + } + // remove the user from the 1st list in the embed + Logger.out("Removing ${user.username} from the 1st list in the embed") + eb.fields = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", eb, 1).fields + shouldEditButton = true + } + if (!m.embeds[0].fields[1].value.contains(user.id.value.toString())) { + if (member.roleIds.contains(Snowflake(mpdd.roleid))) { + Logger.out("Removing role from ${member.username}") + member.removeRole(role.id) + } + // Add the user to the list in the embed + Logger.out("Adding ${user.username} to the 2nd list in the embed") + eb.fields = EmbedUtil.addXToValuesAtTable(user.id.value.toString(), eb, 2).fields + shouldEditButton = true + } + if (m.embeds[0].fields[1].value.contains(user.id.value.toString())) { + // Remove the user from all tables + Logger.out("Removing ${user.username} from the 2nd list in the embed") + eb.fields = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", eb, 2).fields + shouldEditButton = true + } + if (shouldEditButton) { + // update the message + Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { + this.embed { + this.color = eb.color + this.title = eb.title + this.description = eb.description + this.fields = eb.fields + this.footer = eb.footer + } + } + } + } +} -- 2.45.2 From fa0ba09412e291872e25395480f0bacebf1e16c9 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 12:48:33 +0200 Subject: [PATCH 077/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 3292b17..fed49e9 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.4.3" + ?: "2.5.0" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From 266b331699a5221a2412485fc305424b285a4f3c Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 13:35:17 +0200 Subject: [PATCH 078/168] chore: moved to proper data types in columns Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 3 +++ .../buttons/matchplanner/AcceptEditButton.kt | 8 +++---- .../buttons/matchplanner/CancelEditButton.kt | 8 +++---- .../buttons/matchplanner/DeclineEditButton.kt | 8 +++---- .../kotlin/net/moonleay/lilJudd/data/DB.kt | 20 ++++++++++++++++ .../data/entry/MatchPlanningDataData.kt | 12 +++++----- .../data/entry/PlanningNotifierRolesData.kt | 8 +++---- .../data/entry/TimePlanningMessagesData.kt | 6 ++--- .../lilJudd/data/tables/MatchPlanningData.kt | 17 ++++++------- .../data/tables/PlanningNotifierRoles.kt | 13 +++++----- .../data/tables/TimePlanningChannels.kt | 10 ++++---- .../data/tables/TimePlanningMessages.kt | 11 +++++---- .../extensions/FeatureManageExtension.kt | 4 ++-- .../lilJudd/extensions/MatchExtension.kt | 24 +++++++++---------- .../extensions/SendPlannerExtension.kt | 6 ++--- .../lilJudd/features/AvailabilityManager.kt | 16 ++++++------- .../moonleay/lilJudd/features/MatchManager.kt | 8 +++---- .../moonleay/lilJudd/features/TimeManager.kt | 14 +++++------ .../lilJudd/features/component/IFeature.kt | 8 +++---- .../net/moonleay/lilJudd/jobs/MatchJob.kt | 2 +- 20 files changed, 117 insertions(+), 89 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 1c6e337..6f6d47f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -76,6 +76,9 @@ object Bot { CredentialManager.dbPassword ) + // Make sure the database is up-to-date + DB.register() + // Register all the jobs jobs.addAll( listOf( diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt index c9f33e7..55765ee 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt @@ -53,12 +53,12 @@ class AcceptEditButton() : IEditButton { var found = false transaction { for (pnr in MatchPlanningData.select { - MatchPlanningData.messageid eq (interaction.message.id.value.toString()) and ( - MatchPlanningData.serverid eq (guild.id.value.toString())) and ( - MatchPlanningData.channelid eq (interaction.channelId.value.toString())) + MatchPlanningData.messageid eq (interaction.message.id.value.toLong()) and ( + MatchPlanningData.serverid eq (guild.id.value.toLong())) and ( + MatchPlanningData.channelid eq (interaction.channelId.value.toLong())) }) { mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.id], pnr[MatchPlanningData.serverid], pnr[MatchPlanningData.channelid], pnr[MatchPlanningData.matchtype], diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt index 3925cd3..4f70ab7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt @@ -50,12 +50,12 @@ class CancelEditButton : IEditButton { var found = false transaction { for (pnr in MatchPlanningData.select { - MatchPlanningData.messageid eq (interaction.message.id.value.toString()) and ( - MatchPlanningData.serverid eq (guild.id.value.toString())) and ( - MatchPlanningData.channelid eq (interaction.channelId.value.toString())) + MatchPlanningData.messageid eq (interaction.message.id.value.toLong()) and ( + MatchPlanningData.serverid eq (guild.id.value.toLong())) and ( + MatchPlanningData.channelid eq (interaction.channelId.value.toLong())) }) { mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.id], pnr[MatchPlanningData.serverid], pnr[MatchPlanningData.channelid], pnr[MatchPlanningData.matchtype], diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt index 67b193e..3d0e0bd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt @@ -53,12 +53,12 @@ class DeclineEditButton : IEditButton { var found = false transaction { for (pnr in MatchPlanningData.select { - MatchPlanningData.messageid eq (interaction.message.id.value.toString()) and ( - MatchPlanningData.serverid eq (guild.id.value.toString())) and ( - MatchPlanningData.channelid eq (interaction.channelId.value.toString())) + MatchPlanningData.messageid eq (interaction.message.id.value.toLong()) and ( + MatchPlanningData.serverid eq (guild.id.value.toLong())) and ( + MatchPlanningData.channelid eq (interaction.channelId.value.toLong())) }) { mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.id], pnr[MatchPlanningData.serverid], pnr[MatchPlanningData.channelid], pnr[MatchPlanningData.matchtype], diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt b/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt index b1ff4b7..f0711de 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt @@ -19,9 +19,16 @@ package net.moonleay.lilJudd.data +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles +import net.moonleay.lilJudd.data.tables.TimePlanningChannels +import net.moonleay.lilJudd.data.tables.TimePlanningMessages import org.jetbrains.exposed.sql.Database +import org.jetbrains.exposed.sql.SchemaUtils +import org.jetbrains.exposed.sql.transactions.transaction object DB { + private var connected = false //Connect to the provided DB; trows errors, if the DB is not avalible. fun connect(dbDomain: String, dbName: String, dbUser: String, dbPasswd: String) { Database.connect( @@ -30,5 +37,18 @@ object DB { user = dbUser, password = dbPasswd ) + connected = true + } + + fun register() { + if (!connected) + return + // Register tables here + transaction { + SchemaUtils.create(TimePlanningChannels) + SchemaUtils.create(TimePlanningMessages) + SchemaUtils.create(MatchPlanningData) + SchemaUtils.create(PlanningNotifierRoles) + } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt index ca0bd32..451278e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt @@ -20,13 +20,13 @@ package net.moonleay.lilJudd.data.entry data class MatchPlanningDataData( val id: Int, - val serverid: String, - val channelid: String, + val serverid: Long, + val channelid: Long, val matchtype: String, - val registererid: String, - val roleid: String, + val registererid: Long, + val roleid: Long, val opponentname: String, - val messageid: String, - val timestamp: String, + val messageid: Long, + val timestamp: Long, val jobstr: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt index 8cba107..fc15729 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt @@ -19,8 +19,8 @@ package net.moonleay.lilJudd.data.entry data class PlanningNotifierRolesData( - val serverID: String, // The id of the server - val channelId: String, // The id of the channel - val hastimeroleid: String, // The id of the role that has time today - val wantstobenotifid: String // The id of the role that wants to be notified + val serverID: Long, // The id of the server + val channelId: Long, // The id of the channel + val hastimeroleid: Long, // The id of the role that has time today + val wantstobenotifid: Long // The id of the role that wants to be notified ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt index 3da4ba8..c4de368 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt @@ -19,8 +19,8 @@ package net.moonleay.lilJudd.data.entry data class TimePlanningMessagesData( - val serverid: String, // The discord server id - val channelid: String, // The discord channel id - val weekstamp: String, // The timestamp of the monday of the week at 4am UTC + val serverid: Long, // The discord server id + val channelid: Long, // The discord channel id + val weekstamp: Long, // The timestamp of the monday of the week at 4am UTC val messageids: String // IDs are in the following format: "{weekdayNr}:{id};{weekdayNr}:{id};[etc.]" ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt index 2de3ece..e2e8afa 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt @@ -18,16 +18,17 @@ package net.moonleay.lilJudd.data.tables -import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.sql.Table -object MatchPlanningData : IntIdTable() { - var serverid = varchar("serverid", 50) - var channelid = varchar("channelid", 50) +object MatchPlanningData : Table(name = "new_matchplanning_data") { + var id = integer("id").autoIncrement() + var serverid = long("serverid") + var channelid = long("channelid") var matchtype = varchar("matchtype", 50) - var registererid = varchar("registererid", 50) - var roleid = varchar("roleid", 50) + var registererid = long("registererid") + var roleid = long("roleid") var opponentName = varchar("opponentname", 100) - var messageid = varchar("messageid", 50) - var timestamp = varchar("timestamp", 50) + var messageid = long("messageid") + var timestamp = long("timestamp") var jobstr = varchar("jobstr", 50) } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt b/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt index d8d3b9d..e2fc9e0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt @@ -18,11 +18,12 @@ package net.moonleay.lilJudd.data.tables -import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.sql.Table -object PlanningNotifierRoles : IntIdTable() { - var serverid = varchar("serverid", 50) - var channelid = varchar("channelid", 50) - var hastimeroleid = varchar("hastimeroleid", 50) - var wantstobenotifiedid = varchar("wantstobenotifiedid", 50) +object PlanningNotifierRoles : Table(name = "new_planningnotifier_roles") { + var id = integer("id").autoIncrement() + var serverid = long("serverid") + var channelid = long("channelid") + var hastimeroleid = long("hastimeroleid") + var wantstobenotifiedid = long("wantstobenotifiedid") } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningChannels.kt b/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningChannels.kt index a746aa1..a521838 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningChannels.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningChannels.kt @@ -18,9 +18,11 @@ package net.moonleay.lilJudd.data.tables -import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.sql.Table -object TimePlanningChannels : IntIdTable() { - var serverid = varchar("serverid", 50) - val channelid = varchar("channelid", 50) + +object TimePlanningChannels : Table(name = "new_timeplanning_channels") { + var id = integer("id").autoIncrement() + var serverid = long("serverid") + val channelid = long("channelid") } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt b/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt index 7498edb..8f8a01b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt @@ -18,11 +18,12 @@ package net.moonleay.lilJudd.data.tables -import org.jetbrains.exposed.dao.id.IntIdTable +import org.jetbrains.exposed.sql.Table -object TimePlanningMessages : IntIdTable() { - var serverid = varchar("serverid", 50) - var channelid = varchar("channelid", 50) - var weekstamp = varchar("weekstamp", 50) +object TimePlanningMessages : Table(name = "new_timeplanning_messages") { + var id = integer("id").autoIncrement() + var serverid = long("serverid") + var channelid = long("channelid") + var weekstamp = long("weekstamp") var messageids = varchar("messageids", 200) } diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index 48f68e9..eac08c6 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -60,8 +60,8 @@ class FeatureManageExtension : Extension() { } return@action } - val gID = this.guild!!.id.toString() - val cID = this.arguments.channel.id.toString() + val gID = this.guild!!.id.value.toLong() + val cID = this.arguments.channel.id.value.toLong() val channel = this.arguments.channel val args = this.arguments Logger.out("${args.feature.readableName} ${args.setStatus.readableName} ${channel.data.name.value}") diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index 4eb1db0..3be70f7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -36,9 +36,9 @@ import net.moonleay.lilJudd.jobs.component.JobManager import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.lilJudd.util.TimeUtil -import org.jetbrains.exposed.dao.id.EntityID import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.transactions.transaction +import kotlin.properties.Delegates class MatchExtension : Extension() { @@ -54,8 +54,8 @@ class MatchExtension : Extension() { this.action { val args = this.arguments val m = this.member!! - val gID = this.guild!!.id.value.toString() - val cID = this.channel.id.value.toString() + val gID = this.guild!!.id.value + val cID = this.channel.id.value val opponent = args.opponent ?: "?" val msg = this.respond { this.embeds.add( @@ -100,17 +100,17 @@ class MatchExtension : Extension() { } return@action } - lateinit var tableID: EntityID + var tableID by Delegates.notNull() transaction { tableID = MatchPlanningData.insert { - it[MatchPlanningData.serverid] = gID - it[MatchPlanningData.channelid] = cID - it[MatchPlanningData.messageid] = msg.id.value.toString() + it[MatchPlanningData.serverid] = gID.toLong() + it[MatchPlanningData.channelid] = cID.toLong() + it[MatchPlanningData.messageid] = msg.id.value.toLong() it[MatchPlanningData.matchtype] = args.matchType.readableName - it[MatchPlanningData.roleid] = role.id.value.toString() - it[MatchPlanningData.registererid] = m.id.value.toString() + it[MatchPlanningData.roleid] = role.id.value.toLong() + it[MatchPlanningData.registererid] = m.id.value.toLong() it[MatchPlanningData.opponentName] = opponent - it[MatchPlanningData.timestamp] = (zdt.toEpochSecond() * 1000).toString() + it[MatchPlanningData.timestamp] = (zdt.toEpochSecond() * 1000) it[MatchPlanningData.jobstr] = jobString } get MatchPlanningData.id } @@ -120,8 +120,8 @@ class MatchExtension : Extension() { JobManager.addJob( MatchJob( jobString, - tableID.value, - "${args.matchType.readableName}_Vs_${opponent}_[${tableID.value}]-${gID}_${cID}", + tableID, + "${args.matchType.readableName}_Vs_${opponent}_[${tableID}]-${gID}_${cID}", ) ) } diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index c02294e..0e53f7b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -107,9 +107,9 @@ class SendPlannerExtension : Extension() { // Save the message ids transaction { TimePlanningMessages.insert { - it[TimePlanningMessages.serverid] = c.data.guildId.value.toString() - it[TimePlanningMessages.channelid] = c.id.value.toString() - it[TimePlanningMessages.weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000).toString() + it[TimePlanningMessages.serverid] = c.data.guildId.value?.value!!.toLong() + it[TimePlanningMessages.channelid] = c.id.value.toLong() + it[TimePlanningMessages.weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000) it[TimePlanningMessages.messageids] = msgStr } get TimePlanningMessages.id } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 2a980dc..d9fff00 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -56,11 +56,11 @@ object AvailabilityManager : IFeature { // ChannelID, Data val messageMap = mutableMapOf() // ChannelID, Data - val roleMap = mutableMapOf() + val roleMap = mutableMapOf() transaction { for (pnr in TimePlanningMessages.select { - TimePlanningMessages.weekstamp eq (TimeUtil.getWeekStamp().toEpochSecond() * 1000).toString() + TimePlanningMessages.weekstamp eq (TimeUtil.getWeekStamp().toEpochSecond() * 1000) }) { messageMap[Snowflake(pnr[TimePlanningMessages.channelid])] = TimePlanningMessagesData( @@ -169,8 +169,8 @@ object AvailabilityManager : IFeature { override suspend fun enable( u: UserBehavior, - gID: String, - cID: String, + gID: Long, + cID: Long, ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { @@ -187,13 +187,13 @@ object AvailabilityManager : IFeature { this.name = "available [${ch.data.name.value}]" this.mentionable = true } - val htr = hasTimeRole.id.toString() + val htr = hasTimeRole.id.value.toLong() val wantsNotifsRole = Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)).createRole { this.name = "notifications [${ch.data.name.value}]" this.mentionable = true } - val wnr = wantsNotifsRole.id.toString() + val wnr = wantsNotifsRole.id.value.toLong() // Save the role ids to db transaction { @@ -224,8 +224,8 @@ object AvailabilityManager : IFeature { override suspend fun disable( u: UserBehavior, - gID: String, - cID: String, + gID: Long, + cID: Long, ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt index a92ad6a..1591545 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt @@ -38,7 +38,7 @@ object MatchManager { MatchPlanningData.selectAll().forEach { dataList.add( MatchPlanningDataData( - it[MatchPlanningData.id].value, + it[MatchPlanningData.id], it[MatchPlanningData.serverid], it[MatchPlanningData.channelid], it[MatchPlanningData.matchtype], @@ -79,9 +79,9 @@ object MatchManager { Logger.out("Registered job for match ${data.id}...") } - private suspend fun removeRoleFromGuild(gid: String, rid: String): Boolean { - val guild = Bot.bot.kordRef.getGuildOrNull(Snowflake(gid.toLong())) ?: return false - val role = guild.getRoleOrNull(Snowflake(rid.toLong())) ?: return false + private suspend fun removeRoleFromGuild(gid: Long, rid: Long): Boolean { + val guild = Bot.bot.kordRef.getGuildOrNull(Snowflake(gid)) ?: return false + val role = guild.getRoleOrNull(Snowflake(rid)) ?: return false role.delete() return true } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 9acbc33..2058c11 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -151,9 +151,9 @@ object TimeManager : IFeature { // Save the message ids transaction { TimePlanningMessages.insert { - it[TimePlanningMessages.serverid] = c.data.guildId.value.toString() - it[TimePlanningMessages.channelid] = c.id.value.toString() - it[TimePlanningMessages.weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000).toString() + it[TimePlanningMessages.serverid] = c.data.guildId.value?.value!!.toLong() + it[TimePlanningMessages.channelid] = c.id.value.toLong() + it[TimePlanningMessages.weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000) it[TimePlanningMessages.messageids] = msgStr } get TimePlanningMessages.id } @@ -164,8 +164,8 @@ object TimeManager : IFeature { override suspend fun enable( u: UserBehavior, - gID: String, - cID: String, + gID: Long, + cID: Long, ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { @@ -200,8 +200,8 @@ object TimeManager : IFeature { override suspend fun disable( u: UserBehavior, - gID: String, - cID: String, + gID: Long, + cID: Long, ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt b/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt index aa27536..1145797 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt @@ -29,16 +29,16 @@ interface IFeature { suspend fun enable( u: UserBehavior, - gID: String, - cID: String, + gID: Long, + cID: Long, ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder suspend fun disable( u: UserBehavior, - gID: String, - cID: String, + gID: Long, + cID: Long, ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt index 394758a..89b33e4 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt @@ -54,7 +54,7 @@ class MatchJob( MatchPlanningData.id eq (tableId) }) { mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id].value, + pnr[MatchPlanningData.id], pnr[MatchPlanningData.serverid], pnr[MatchPlanningData.channelid], pnr[MatchPlanningData.matchtype], -- 2.45.2 From 7d1952d870dfa60aa2aebc40278da24a192e4cc6 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 14:26:43 +0200 Subject: [PATCH 079/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index fed49e9..0bc0943 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.5.0" + ?: "2.5.1" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From 5ce99c904ebcc87822b3e62248913bee70f193a4 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 11 Sep 2023 14:46:40 +0200 Subject: [PATCH 080/168] fix: fixed grammar Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/data/DB.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt b/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt index f0711de..f02009e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt @@ -29,7 +29,8 @@ import org.jetbrains.exposed.sql.transactions.transaction object DB { private var connected = false - //Connect to the provided DB; trows errors, if the DB is not avalible. + + //Connect to the provided DB; trows errors, if the DB is not available. fun connect(dbDomain: String, dbName: String, dbUser: String, dbPasswd: String) { Database.connect( "jdbc:postgresql://$dbDomain/$dbName", -- 2.45.2 From e0e522f56188c202fb9ccbb1afcc2e3935257fb8 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 07:44:43 +0200 Subject: [PATCH 081/168] feat: moved update logic into "updateInChannel" function, updated the function in Timeplanner buttons Signed-off-by: moonleay --- .../timeplanner/IsAvailableEditButton.kt | 2 +- .../timeplanner/MaybeAvailableEditButton.kt | 2 +- .../timeplanner/NotAvailableEditButton.kt | 2 +- .../lilJudd/features/AvailabilityManager.kt | 168 ++++++++++++------ 4 files changed, 114 insertions(+), 60 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt index 6140d4d..9dbae16 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt @@ -63,6 +63,6 @@ class IsAvailableEditButton : IEditButton { } } } - AvailabilityManager.runThread() + AvailabilityManager.updateInChannel(interaction.channelId) } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt index c3eaec2..01cf792 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt @@ -63,6 +63,6 @@ class MaybeAvailableEditButton : IEditButton { } } } - AvailabilityManager.runThread() + AvailabilityManager.updateInChannel(interaction.channelId) } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt index b56db11..ade9557 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt @@ -63,6 +63,6 @@ class NotAvailableEditButton : IEditButton { } } } - AvailabilityManager.runThread() + AvailabilityManager.updateInChannel(interaction.channelId) } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index d9fff00..f414967 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -81,15 +81,10 @@ object AvailabilityManager : IFeature { } } - val weekday = ZonedDateTime.now().dayOfWeek // The current week day - val weekStamp = TimeUtil.getWeekStamp().toEpochSecond() * 1000 // The current week time stamp - Logger.out("It is week ${weekStamp} and day ${weekday}/${TimeUtil.getDayOfMonthInt(weekday)} of the week.") for (snf in messageMap.keys) { // snf = Snowflake val data = messageMap[snf]!! // this is the data of the table if (Bot.bot.kordRef.getChannel(Snowflake(data.channelid)) == null) continue // This channel does not exist anymore. - val c = - Bot.bot.kordRef.getChannelOf(Snowflake(data.channelid))!! // Get the channel as MessageChannel if (roleMap.isEmpty()) { Logger.out("No saved roles. Canceling.") return @@ -99,62 +94,121 @@ object AvailabilityManager : IFeature { Logger.out("Role for channel ${data.channelid} does not exist") continue // this took way to long to find out that this was the issue } - val g = Bot.bot.kordRef.getGuildOrThrow(Snowflake(data.serverid)) - // Get all members with the role - val mce = g.requestMembers { - this.requestAllMembers() - } - mce.collect { memberchunkevent -> - memberchunkevent.members.forEach { - Logger.out("Checking member ${it.id.value} (${it.username})") - if (it.roleIds.contains(Snowflake(roleData.hastimeroleid))) { - it.removeRole(Snowflake(roleData.hastimeroleid)) - Logger.out("Removed role from ${it.username}") // Removed the role - } - } - } - - Logger.out("Got through all members") - // This stores the ids of the messages. - // The format is weekdaNR:ID - // The last entry (nr 8) is empty, so we can ignore it - val messageIdSplit = data.messageids.split(";").subList(0, 7) - for (mid in messageIdSplit) { - Logger.out("Checking id $mid") - if (!mid.startsWith((TimeUtil.getDayOfMonthInt(weekday) - 1).toString(), true)) - continue // This is not the right message, check the next one - val idFiltered = mid.split(":")[1] // This is the target message id - val message = c.getMessageOrNull(Snowflake(idFiltered)) // Get the message from the channel - if (message == null) { - Logger.out("Could not find message.") - break // This message does not exist anymore. Nothing we can do about that. - } - if (message.data.embeds.isEmpty()) { - Logger.out("There are no embeds.") - break // There are no embeds or there are not enough embeds - } - val targets = EmbedUtil.getAllUsersInTheFirstXTables(2, message.embeds[0]) - for (tid in targets) { - Logger.out("Checking id $tid") - if (Bot.bot.kordRef.getGuildOrNull(Snowflake(data.serverid))!! - .getMemberOrNull(Snowflake(tid)) == null - ) - continue // This member does not exist anymore. - val member = Bot.bot.kordRef.getGuildOrThrow(Snowflake(data.serverid)) - .getMember(Snowflake(tid)) // Get the member - if (member.roleIds.contains(Snowflake(roleData.hastimeroleid))) - continue // This member already has the role - member.addRole(Snowflake(roleData.hastimeroleid)) // Add the role - Logger.out("Added role to ${member.username}") - } - Logger.out("Done with message. Moving on...") - // We found the right message. We don't need to check the others. - break - } + this.updateInChannel(snf, data, roleData) } Logger.out("Done! Until tomorrow! <3 ") } + suspend fun updateInChannel(snf: Snowflake) { + lateinit var data: TimePlanningMessagesData + lateinit var roleData: PlanningNotifierRolesData + var found1 = false + var found2 = false + for (pnr in TimePlanningMessages.select { + TimePlanningMessages.weekstamp eq (TimeUtil.getWeekStamp() + .toEpochSecond() * 1000) and (TimePlanningMessages.channelid eq (snf.value.toLong())) + }) { + data = + TimePlanningMessagesData( + pnr[TimePlanningMessages.serverid], + pnr[TimePlanningMessages.channelid], + pnr[TimePlanningMessages.weekstamp], + pnr[TimePlanningMessages.messageids] + ) + found1 = true + } + for (pnr in PlanningNotifierRoles.select { + PlanningNotifierRoles.channelid eq (snf.value.toLong()) + }) { + roleData = + PlanningNotifierRolesData( + pnr[PlanningNotifierRoles.serverid], + pnr[PlanningNotifierRoles.channelid], + pnr[PlanningNotifierRoles.hastimeroleid], + pnr[PlanningNotifierRoles.wantstobenotifiedid] + ) + found2 = true + } + if (!found1 || !found2) { + Logger.out("Could not find data for channel ${snf.value}") + return + } + if (Bot.bot.kordRef.getChannel(Snowflake(data.channelid)) == null) + return // This channel does not exist anymore. + if (roleData == null) { + Logger.out("Role for channel ${data.channelid} does not exist") + return // this took way to long to find out that this was the issue + } + updateInChannel(snf, data, roleData) + } + + @OptIn(PrivilegedIntent::class) + suspend fun updateInChannel(snf: Snowflake, tpmd: TimePlanningMessagesData, pnrd: PlanningNotifierRolesData) { + if (Bot.bot.kordRef.getChannel(Snowflake(tpmd.channelid)) == null) + return // This channel does not exist anymore. + val c = + Bot.bot.kordRef.getChannelOf(Snowflake(tpmd.channelid))!! // Get the channel as MessageChannel + if (Bot.bot.kordRef.getGuildOrNull(Snowflake(tpmd.serverid)) == null) { + Logger.out("Guild not found.") + return + } + val weekday = ZonedDateTime.now().dayOfWeek // The current week day + val weekStamp = TimeUtil.getWeekStamp().toEpochSecond() * 1000 // The current week time stamp + Logger.out("It is week ${weekStamp} and day ${weekday}/${TimeUtil.getDayOfMonthInt(weekday)} of the week.") + val g = Bot.bot.kordRef.getGuildOrThrow(Snowflake(tpmd.serverid)) + // Get all members with the role + val mce = g.requestMembers { + this.requestAllMembers() + } + mce.collect { memberchunkevent -> + memberchunkevent.members.forEach { + Logger.out("Checking member ${it.id.value} (${it.username})") + if (it.roleIds.contains(Snowflake(pnrd.hastimeroleid))) { + it.removeRole(Snowflake(pnrd.hastimeroleid)) + Logger.out("Removed role from ${it.username}") // Removed the role + } + } + } + + Logger.out("Got through all members") + // This stores the ids of the messages. + // The format is weekdaNR:ID + // The last entry (nr 8) is empty, so we can ignore it + val messageIdSplit = tpmd.messageids.split(";").subList(0, 7) + for (mid in messageIdSplit) { + Logger.out("Checking id $mid") + if (!mid.startsWith((TimeUtil.getDayOfMonthInt(weekday) - 1).toString(), true)) + continue// This is not the right message, check the next one + val idFiltered = mid.split(":")[1] // This is the target message id + val message = c.getMessageOrNull(Snowflake(idFiltered)) // Get the message from the channel + if (message == null) { + Logger.out("Could not find message.") + return // This message does not exist anymore. Nothing we can do about that. + } + if (message.data.embeds.isEmpty()) { + Logger.out("There are no embeds.") + return // There are no embeds or there are not enough embeds + } + val targets = EmbedUtil.getAllUsersInTheFirstXTables(2, message.embeds[0]) + for (tid in targets) { + Logger.out("Checking id $tid") + if (Bot.bot.kordRef.getGuildOrNull(Snowflake(tpmd.serverid))!! + .getMemberOrNull(Snowflake(tid)) == null + ) + continue// This member does not exist anymore. + val member = Bot.bot.kordRef.getGuildOrThrow(Snowflake(tpmd.serverid)) + .getMember(Snowflake(tid)) // Get the member + if (member.roleIds.contains(Snowflake(pnrd.hastimeroleid))) + continue // This member already has the role + member.addRole(Snowflake(pnrd.hastimeroleid)) // Add the role + Logger.out("Added role to ${member.username}") + } + Logger.out("Done with message. Moving on...") + // We found the right message. We don't need to check the others. + break + } + } + override val feat: FeatureEnum get() = FeatureEnum.PLANNINGROLES -- 2.45.2 From 8a2d2be5053ca2baab66f6f19e5f83f557af3830 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 07:46:07 +0200 Subject: [PATCH 082/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 0bc0943..7844542 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.5.1" + ?: "2.5.3" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From eee820917d84415e12785c854b7c4137cb18fa6c Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 09:41:27 +0200 Subject: [PATCH 083/168] feat: Bot now skips Bot Users Signed-off-by: moonleay --- .../moonleay/lilJudd/features/AvailabilityManager.kt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index f414967..a6b2d3a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -18,6 +18,7 @@ package net.moonleay.lilJudd.features +import com.kotlindiscord.kord.extensions.utils.isNullOrBot import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.doInfinity import dev.kord.common.Color @@ -162,11 +163,14 @@ object AvailabilityManager : IFeature { } mce.collect { memberchunkevent -> memberchunkevent.members.forEach { - Logger.out("Checking member ${it.id.value} (${it.username})") - if (it.roleIds.contains(Snowflake(pnrd.hastimeroleid))) { - it.removeRole(Snowflake(pnrd.hastimeroleid)) - Logger.out("Removed role from ${it.username}") // Removed the role + if (!it.isNullOrBot()) { // Check if the member is a bot + Logger.out("Checking member ${it.id.value} (${it.username})") + if (it.roleIds.contains(Snowflake(pnrd.hastimeroleid))) { + it.removeRole(Snowflake(pnrd.hastimeroleid)) + Logger.out("Removed role from ${it.username}") // Removed the role + } } + // I cant use continue here, because it does not work with .forEach } } -- 2.45.2 From 50ab9c0b0dd030b648a2ad4f7870dedffaf472fb Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 09:41:43 +0200 Subject: [PATCH 084/168] !feat: removed TestExtension.kt Signed-off-by: moonleay --- .../lilJudd/extensions/TestExtension.kt | 62 ------------------- 1 file changed, 62 deletions(-) delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt deleted file mode 100644 index 90cda76..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/TestExtension.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.extensions - -import com.kotlindiscord.kord.extensions.extensions.Extension -import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond -import dev.kord.common.Color -import dev.kord.rest.builder.message.create.actionRow -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.MessageUtil - -/* This extension has no proper use. - It is used in testing to test stuff, without having to wait for certain events to trigger. */ -class TestExtension : Extension() { - override val name = "test" - override val allowApplicationCommandInDMs: Boolean - get() = false - - override suspend fun setup() { - publicSlashCommand { - name = "test" - description = "Test game" - this.action { - this.respond { - this.embeds.add( - MessageUtil.getEmbedWithTable( - Color(0X4C4645), - "", - "MONDAY, 22.05.2023", - mapOf( - "Is available" to listOf(), - "May be available" to listOf(), - "Is not available" to listOf() - ) - ) - ) - - this.actionRow { - this.components.addAll(EmbedUtil.getTimePlannerButtons().components) - } - } - } - } - } -} -- 2.45.2 From 1cd622a77834267fa89efee0428316353496b359 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 09:42:08 +0200 Subject: [PATCH 085/168] chore: updated SendPlannerExtension documentation Signed-off-by: moonleay --- .../net/moonleay/lilJudd/extensions/SendPlannerExtension.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index 0e53f7b..d4b8808 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -47,13 +47,13 @@ class SendPlannerExtension : Extension() { override suspend fun setup() { publicSlashCommand() { name = "sendplanner" - description = "Send the planner for the current and x next weeks" + description = "Send the planner for the current week" this.action { if (!this.member!!.asMember(this.guild!!.id) .hasPermission(Permission.Administrator) ) { val res = this.respond { - this.content = "no." + this.content = "You need to be an administrator to use this command." } res.delete() return@action -- 2.45.2 From 24687d4060d1280d93cfde5f65be8f8c8749ece5 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 09:43:36 +0200 Subject: [PATCH 086/168] feat: improved UpdateRolesExtension chore: updated UpdateRolesExtension Documentation Signed-off-by: moonleay --- .../net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt index 109e3c7..65d5430 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt @@ -42,7 +42,7 @@ class UpdateRolesExtension : Extension() { .hasPermission(Permission.Administrator) ) { val res = this.respond { - this.content = "no." + this.content = "You need to be an administrator to use this command." } res.delete() return@action @@ -55,7 +55,7 @@ class UpdateRolesExtension : Extension() { // -- below here is the code of the cronjob -- Logger.out("Starting to update roles...") - AvailabilityManager.runThread() + AvailabilityManager.updateInChannel(this.channel.id) } } } -- 2.45.2 From 0a2368417abb000238ac188b9da455c86b9e9f70 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 09:46:19 +0200 Subject: [PATCH 087/168] chore: removed unused open modifier in IEditButton Signed-off-by: moonleay --- .../net/moonleay/lilJudd/buttons/component/IEditButton.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt index 84e8a5b..0fbe64e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt @@ -26,7 +26,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction interface IEditButton { val id: String - open suspend fun onInteraction( + suspend fun onInteraction( interaction: ButtonInteraction, response: PublicMessageInteractionResponseBehavior, guild: Guild, -- 2.45.2 From 266376f7cb4d9e48f0ff710711fde36cc5157c76 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 12:27:53 +0200 Subject: [PATCH 088/168] feat: added EmbedColor Signed-off-by: moonleay --- .../net/moonleay/lilJudd/util/EmbedColor.kt | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/util/EmbedColor.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedColor.kt b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedColor.kt new file mode 100644 index 0000000..cb3e983 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedColor.kt @@ -0,0 +1,28 @@ +/* + * 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.util + +import dev.kord.common.Color + +enum class EmbedColor(val color: Color) { + ERROR(Color(0xE0311A)), + WARNING(Color(0xFFA500)), + SUCCESS(Color(0x52E01A)), + INFO(Color(0x4C4645)), +} -- 2.45.2 From 79b0dd8d6a6a36fb8568b64f40983630d74336be Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 12:34:27 +0200 Subject: [PATCH 089/168] feat: make embed helper functions use EmbedColor instead of color Signed-off-by: moonleay --- .../net/moonleay/lilJudd/util/MessageUtil.kt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt index 0e34571..6dfb545 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt @@ -22,7 +22,6 @@ import com.kotlindiscord.kord.extensions.commands.Arguments import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext import com.kotlindiscord.kord.extensions.components.forms.ModalForm import com.kotlindiscord.kord.extensions.types.respond -import dev.kord.common.Color import dev.kord.core.entity.Embed import dev.kord.rest.builder.message.EmbedBuilder import java.time.LocalDateTime @@ -34,7 +33,7 @@ object MessageUtil { ///Send an embedded message as a reply suspend fun sendEmbedForPublicSlashCommand( ctx: PublicSlashCommandContext, - color: Color, + color: EmbedColor, title: String, description: String ) { @@ -53,7 +52,7 @@ object MessageUtil { ///Send an embedded message with an image as a reply suspend fun sendEmbedForPublicSlashCommandWithImage( ctx: PublicSlashCommandContext, - color: Color, + color: EmbedColor, title: String, description: String, thumbnailUrl: String @@ -103,7 +102,7 @@ object MessageUtil { } fun getEmbedWithTableWithFooter( - color: Color, + color: EmbedColor, title: String, description: String, values: Map>?, @@ -117,7 +116,7 @@ object MessageUtil { ///Get an embedded msg with image, title and description fun getEmbedWithTable( - color: Color, + color: EmbedColor, title: String, description: String, values: Map>? @@ -140,20 +139,20 @@ object MessageUtil { ///Get an embedded msg with title and description fun getEmbedSmall( - color: Color, + color: EmbedColor, title: String, description: String ): EmbedBuilder { val ebb = EmbedBuilder() ebb.title = title ebb.description = description - ebb.color = color + ebb.color = color.color return ebb } ///Get an embedded msg with title, description and a src fun getEmbed( - color: Color, + color: EmbedColor, title: String, description: String, source: String @@ -167,7 +166,7 @@ object MessageUtil { ///Get an embedded msg with image, title, description and a src fun getEmbedWithImage( - color: Color, + color: EmbedColor, title: String, description: String, source: String, -- 2.45.2 From 2b42ef5decf51d8fb1e35d918ed14b5b5616f132 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 12:36:19 +0200 Subject: [PATCH 090/168] fix!: Changed all colors to EmbedColor Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 9 +++--- .../extensions/FeatureManageExtension.kt | 6 ++-- .../lilJudd/extensions/MatchExtension.kt | 6 ++-- .../extensions/SendPlannerExtension.kt | 10 ++----- .../extensions/UpdateRolesExtension.kt | 29 ++++++++++++++----- .../lilJudd/extensions/VersionExtension.kt | 4 +-- .../lilJudd/features/AvailabilityManager.kt | 14 ++++----- .../moonleay/lilJudd/features/TimeManager.kt | 20 +++++-------- 8 files changed, 50 insertions(+), 48 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 6f6d47f..64e0314 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -19,7 +19,6 @@ package net.moonleay.lilJudd import com.kotlindiscord.kord.extensions.ExtensibleBot -import dev.kord.common.Color import dev.kord.common.entity.PresenceStatus import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.event.gateway.ReadyEvent @@ -39,6 +38,7 @@ import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.features.MatchManager import net.moonleay.lilJudd.features.TimeManager +import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil import kotlin.system.exitProcess @@ -146,9 +146,10 @@ object Bot { response.respond { this.embeds = mutableListOf( MessageUtil.getEmbed( - Color(0xE0311A), - "Error", - "Could not find button with id \"${inter.componentId}\".\nPlease report this.", + EmbedColor.ERROR, + "404: Not Found", + "Could not find button with id \"${inter.componentId}\"." + + "\nPlease report this.", u.asUser().username + "#" + u.asUser().discriminator ) ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index eac08c6..e09786c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -25,11 +25,11 @@ import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission -import dev.kord.common.Color import dev.kord.common.entity.Permission import net.moonleay.lilJudd.extensions.component.EnableOrDisable import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.FeatureManager +import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil @@ -51,7 +51,7 @@ class FeatureManageExtension : Extension() { this.respond { embeds.add( MessageUtil.getEmbed( - Color(0xE0311A), + EmbedColor.ERROR, "403: Forbidden", "You cannot edit features, as you don't have the Administrator permission.", u.asUser().username + "#" + u.asUser().discriminator @@ -70,7 +70,7 @@ class FeatureManageExtension : Extension() { this.respond { this.embeds.add( MessageUtil.getEmbed( - Color(0xE0311A), + EmbedColor.ERROR, "404: Not Found", "The feature you are trying to edit does not exist.", u.asUser().username + "#" + u.asUser().discriminator diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index 3be70f7..40787d4 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -25,7 +25,6 @@ import com.kotlindiscord.kord.extensions.commands.converters.impl.string import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.types.respond -import dev.kord.common.Color import dev.kord.core.behavior.channel.createMessage import dev.kord.core.behavior.createRole import dev.kord.rest.builder.message.create.actionRow @@ -33,6 +32,7 @@ import net.moonleay.lilJudd.data.tables.MatchPlanningData import net.moonleay.lilJudd.extensions.component.MatchTypes import net.moonleay.lilJudd.jobs.MatchJob import net.moonleay.lilJudd.jobs.component.JobManager +import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.lilJudd.util.TimeUtil @@ -60,7 +60,7 @@ class MatchExtension : Extension() { val msg = this.respond { this.embeds.add( MessageUtil.getEmbedWithTable( - Color(0X4C4645), + EmbedColor.INFO, args.matchType.readableName, "***Vs. $opponent***\n" + "At ${args.timeStamp}\n" + @@ -90,7 +90,7 @@ class MatchExtension : Extension() { this.channel.createMessage { this.embeds.add( MessageUtil.getEmbed( - Color(0xE0311A), + EmbedColor.ERROR, "500: Internal Error", "Could not find created role.\n" + "It seems, that said role could not be created.", diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index d4b8808..fd293d9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -22,16 +22,12 @@ import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission -import dev.kord.common.Color import dev.kord.common.entity.Permission import dev.kord.core.behavior.channel.createMessage import dev.kord.rest.builder.message.create.actionRow import kotlinx.coroutines.delay import net.moonleay.lilJudd.data.tables.TimePlanningMessages -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil -import net.moonleay.lilJudd.util.TimeUtil +import net.moonleay.lilJudd.util.* import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.transactions.transaction import java.time.ZoneId @@ -71,7 +67,7 @@ class SendPlannerExtension : Extension() { c.createMessage { this.embeds.add( MessageUtil.getEmbed( - Color(0X4C4645), + EmbedColor.INFO, "Time Planning Feature", "Do you have time on the following Days?", "Automated Message" @@ -83,7 +79,7 @@ class SendPlannerExtension : Extension() { val msg = c.createMessage { this.embeds.add( MessageUtil.getEmbedWithTable( - Color(0X4C4645), + EmbedColor.INFO, "", "${then.dayOfWeek.name}, ${then.dayOfMonth}.${then.monthValue}.${then.year} /${it + 1}. weekday", mapOf( diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt index 65d5430..be6ba80 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt @@ -23,16 +23,16 @@ import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission -import dev.kord.gateway.PrivilegedIntent import net.moonleay.lilJudd.features.AvailabilityManager +import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger +import net.moonleay.lilJudd.util.MessageUtil class UpdateRolesExtension : Extension() { override val name = "updateroles" override val allowApplicationCommandInDMs: Boolean get() = false - @OptIn(PrivilegedIntent::class) override suspend fun setup() { publicSlashCommand() { name = "updateroles" @@ -41,17 +41,30 @@ class UpdateRolesExtension : Extension() { if (!this.member!!.asMember(this.guild!!.id) .hasPermission(Permission.Administrator) ) { - val res = this.respond { - this.content = "You need to be an administrator to use this command." + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + EmbedColor.ERROR, + "403: Forbidden", + "You need to be an administrator to use this command.", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) } - res.delete() return@action } - val res = this.respond { - this.content = "OK." + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + EmbedColor.SUCCESS, + "200: Success", + "Updating roles.\n" + + "This may take a while, please be patient.", + user.asUser().username + "#" + user.asUser().discriminator + ) + ) } - // -- below here is the code of the cronjob -- Logger.out("Starting to update roles...") diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/VersionExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/VersionExtension.kt index c116c02..3554f72 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/VersionExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/VersionExtension.kt @@ -20,8 +20,8 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import dev.kord.common.Color import net.moonleay.botendo.build.BuildConstants +import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.MessageUtil class VersionExtension : Extension() { @@ -33,7 +33,7 @@ class VersionExtension : Extension() { this.action { MessageUtil.sendEmbedForPublicSlashCommand( this, - Color(0x52E01A), + EmbedColor.INFO, "Lil' Judd", "Lil' Judd ***v." + BuildConstants.version + "***\n" + "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" + diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index a6b2d3a..f883347 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -21,7 +21,6 @@ package net.moonleay.lilJudd.features import com.kotlindiscord.kord.extensions.utils.isNullOrBot import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.doInfinity -import dev.kord.common.Color import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.UserBehavior import dev.kord.core.behavior.createRole @@ -38,10 +37,7 @@ import net.moonleay.lilJudd.data.tables.TimePlanningMessages import net.moonleay.lilJudd.extensions.FeatureManageExtension import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.IFeature -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil -import net.moonleay.lilJudd.util.TimeUtil +import net.moonleay.lilJudd.util.* import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction @@ -264,7 +260,7 @@ object AvailabilityManager : IFeature { } return MessageUtil.getEmbed( - Color(0x52E01A), + EmbedColor.SUCCESS, "200: Success", "The feature was enabled in channel ${args.channel.data.name.value} with roles ${hasTimeRole.mention} & ${wantsNotifsRole.mention}.", u.asUser().username + "#" + u.asUser().discriminator @@ -273,7 +269,7 @@ object AvailabilityManager : IFeature { // They exist, do not add them return MessageUtil.getEmbed( - Color(0xE0311A), + EmbedColor.ERROR, "403: Forbidden", "The feature is already enabled in this channel.", u.asUser().username + "#" + u.asUser().discriminator @@ -318,7 +314,7 @@ object AvailabilityManager : IFeature { } } return MessageUtil.getEmbed( - Color(0x52E019), + EmbedColor.SUCCESS, "200: Success", "The feature was disabled.", u.asUser().username + "#" + u.asUser().discriminator @@ -326,7 +322,7 @@ object AvailabilityManager : IFeature { } // not in db, do nothing return MessageUtil.getEmbed( - Color(0xE0311A), + EmbedColor.ERROR, "403: Forbidden", "The feature is already disabled in this channel.", u.asUser().username + "#" + u.asUser().discriminator diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 2058c11..677520d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -20,7 +20,6 @@ package net.moonleay.lilJudd.features import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.doInfinity -import dev.kord.common.Color import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.UserBehavior import dev.kord.core.behavior.channel.createMessage @@ -37,10 +36,7 @@ import net.moonleay.lilJudd.data.tables.TimePlanningMessages import net.moonleay.lilJudd.extensions.FeatureManageExtension import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.IFeature -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil -import net.moonleay.lilJudd.util.TimeUtil +import net.moonleay.lilJudd.util.* import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction @@ -101,7 +97,7 @@ object TimeManager : IFeature { "The weekly planning starts now <@&${Snowflake(roleMap[ch]?.wantstobenotifid!!)}>" this.embeds.add( MessageUtil.getEmbed( - Color(0X4C4645), + EmbedColor.INFO, "Time Planning Feature", "Do you have time on the following Days?", "Automated Message" @@ -112,7 +108,7 @@ object TimeManager : IFeature { c.createMessage { this.embeds.add( MessageUtil.getEmbed( - Color(0X4C4645), + EmbedColor.INFO, "Time Planning Feature", "Do you have time on the following Days?", "Automated Message" @@ -126,7 +122,7 @@ object TimeManager : IFeature { val msg = c.createMessage { this.embeds.add( MessageUtil.getEmbedWithTable( - Color(0X4C4645), + EmbedColor.INFO, "", "${then.dayOfWeek.name}, ${then.dayOfMonth}.${then.monthValue}.${then.year} /${it + 1}. weekday", mapOf( @@ -184,14 +180,14 @@ object TimeManager : IFeature { } get TimePlanningChannels.id } return MessageUtil.getEmbed( - Color(0x52E01A), + EmbedColor.SUCCESS, "200: Success", "The feature was enabled in channel ${args.channel.data.name.value}", u.asUser().username + "#" + u.asUser().discriminator ) } return MessageUtil.getEmbed( - Color(0xE0311A), + EmbedColor.ERROR, "403: Forbidden", "The feature is already enabled in this channel.", u.asUser().username + "#" + u.asUser().discriminator @@ -226,7 +222,7 @@ object TimeManager : IFeature { } } return MessageUtil.getEmbed( - Color(0x52E019), + EmbedColor.SUCCESS, "200: Success", "The feature was disabled.", u.asUser().username + "#" + u.asUser().discriminator @@ -234,7 +230,7 @@ object TimeManager : IFeature { } // Do nothing; not in db return MessageUtil.getEmbed( - Color(0xE0311A), + EmbedColor.ERROR, "403: Forbidden", "The feature is already disabled in this channel.", u.asUser().username + "#" + u.asUser().discriminator -- 2.45.2 From 4e4876a61dcf9622db710938d00ff6010faed9f4 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 12:42:49 +0200 Subject: [PATCH 091/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7844542..dcda691 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.5.3" + ?: "2.5.4" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From 3695f716ed312c69a3705e5920b92e4117230c60 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 18:30:12 +0200 Subject: [PATCH 092/168] feat: added TimePlanningChannelsData Signed-off-by: moonleay --- .../data/entry/TimePlanningChannelsData.kt | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt new file mode 100644 index 0000000..2eebba4 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt @@ -0,0 +1,24 @@ +/* + * 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 TimePlanningChannelsData( + val serverID: Long, + val channelID: Long, +) -- 2.45.2 From 3d1b2750e556dc95889b40a5826851b376a3952e Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 14 Sep 2023 18:31:45 +0200 Subject: [PATCH 093/168] chore: fixed naming in data objects Signed-off-by: moonleay --- .../buttons/matchplanner/AcceptEditButton.kt | 6 ++-- .../buttons/matchplanner/CancelEditButton.kt | 4 +-- .../buttons/matchplanner/DeclineEditButton.kt | 6 ++-- .../data/entry/MatchPlanningDataData.kt | 16 +++++----- .../data/entry/PlanningNotifierRolesData.kt | 6 ++-- .../data/entry/TimePlanningMessagesData.kt | 6 ++-- .../lilJudd/features/AvailabilityManager.kt | 32 +++++++++---------- .../moonleay/lilJudd/features/MatchManager.kt | 8 ++--- .../moonleay/lilJudd/features/TimeManager.kt | 2 +- .../net/moonleay/lilJudd/jobs/MatchJob.kt | 4 +-- 10 files changed, 45 insertions(+), 45 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt index 55765ee..3dd02d7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt @@ -75,11 +75,11 @@ class AcceptEditButton() : IEditButton { if (!found || mpdd == null) { return } - val role = guild.getRoleOrNull(Snowflake(mpdd.roleid)) ?: return + val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) ?: return val member = interaction.user.asMember(guild.id) ?: return // do the checks and update if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { - if (member.roleIds.contains(Snowflake(mpdd.roleid))) { + if (member.roleIds.contains(Snowflake(mpdd.roleID))) { Logger.out("Removing role from ${member.username}") member.removeRole(role.id) } @@ -94,7 +94,7 @@ class AcceptEditButton() : IEditButton { shouldEditButton = true } if (!m.embeds[0].fields[0].value.contains(user.id.value.toString())) { - if (!member.roleIds.contains(Snowflake(mpdd.roleid))) { + if (!member.roleIds.contains(Snowflake(mpdd.roleID))) { Logger.out("Adding role to ${member.username}") member.addRole(role.id) } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt index 4f70ab7..be99232 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt @@ -72,9 +72,9 @@ class CancelEditButton : IEditButton { if (!found || mpdd == null) { return } - val role = guild.getRoleOrNull(Snowflake(mpdd.roleid)) ?: return + val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) ?: return val member = interaction.user.asMember(guild.id) - if (member.roleIds.contains(Snowflake(mpdd.roleid))) { + if (member.roleIds.contains(Snowflake(mpdd.roleID))) { member.removeRole(role.id) } Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt index 3d0e0bd..9a3de97 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt @@ -75,10 +75,10 @@ class DeclineEditButton : IEditButton { if (!found || mpdd == null) { return } - val role = guild.getRoleOrNull(Snowflake(mpdd.roleid)) ?: return + val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) ?: return val member = interaction.user.asMember(guild.id) ?: return if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { - if (member.roleIds.contains(Snowflake(mpdd.roleid))) { + if (member.roleIds.contains(Snowflake(mpdd.roleID))) { Logger.out("Removing role from ${member.username}") member.removeRole(role.id) } @@ -88,7 +88,7 @@ class DeclineEditButton : IEditButton { shouldEditButton = true } if (!m.embeds[0].fields[1].value.contains(user.id.value.toString())) { - if (member.roleIds.contains(Snowflake(mpdd.roleid))) { + if (member.roleIds.contains(Snowflake(mpdd.roleID))) { Logger.out("Removing role from ${member.username}") member.removeRole(role.id) } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt index 451278e..f48dc28 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt @@ -20,13 +20,13 @@ package net.moonleay.lilJudd.data.entry data class MatchPlanningDataData( val id: Int, - val serverid: Long, - val channelid: Long, - val matchtype: String, - val registererid: Long, - val roleid: Long, - val opponentname: String, - val messageid: Long, + val serverID: Long, + val channelID: Long, + val matchType: String, + val registererID: Long, + val roleID: Long, + val opponentName: String, + val messageID: Long, val timestamp: Long, - val jobstr: String + val jobString: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt index fc15729..a36f351 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt @@ -20,7 +20,7 @@ package net.moonleay.lilJudd.data.entry data class PlanningNotifierRolesData( val serverID: Long, // The id of the server - val channelId: Long, // The id of the channel - val hastimeroleid: Long, // The id of the role that has time today - val wantstobenotifid: Long // The id of the role that wants to be notified + val channelID: Long, // The id of the channel + val hasTimeRoleID: Long, // The id of the role that has time today + val wantsToBeNotifiedID: Long // The id of the role that wants to be notified ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt index c4de368..6c5b2fc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt @@ -19,8 +19,8 @@ package net.moonleay.lilJudd.data.entry data class TimePlanningMessagesData( - val serverid: Long, // The discord server id - val channelid: Long, // The discord channel id + val serverID: Long, // The discord server id + val channelID: Long, // The discord channel id val weekstamp: Long, // The timestamp of the monday of the week at 4am UTC - val messageids: String // IDs are in the following format: "{weekdayNr}:{id};{weekdayNr}:{id};[etc.]" + val messageIDs: String // IDs are in the following format: "{weekdayNr}:{id};{weekdayNr}:{id};[etc.]" ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index f883347..8683dd5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -80,15 +80,15 @@ object AvailabilityManager : IFeature { for (snf in messageMap.keys) { // snf = Snowflake val data = messageMap[snf]!! // this is the data of the table - if (Bot.bot.kordRef.getChannel(Snowflake(data.channelid)) == null) + if (Bot.bot.kordRef.getChannel(Snowflake(data.channelID)) == null) continue // This channel does not exist anymore. if (roleMap.isEmpty()) { Logger.out("No saved roles. Canceling.") return } - val roleData = roleMap[data.channelid] // Get the role data + val roleData = roleMap[data.channelID] // Get the role data if (roleData == null) { - Logger.out("Role for channel ${data.channelid} does not exist") + Logger.out("Role for channel ${data.channelID} does not exist") continue // this took way to long to find out that this was the issue } this.updateInChannel(snf, data, roleData) @@ -130,10 +130,10 @@ object AvailabilityManager : IFeature { Logger.out("Could not find data for channel ${snf.value}") return } - if (Bot.bot.kordRef.getChannel(Snowflake(data.channelid)) == null) + if (Bot.bot.kordRef.getChannel(Snowflake(data.channelID)) == null) return // This channel does not exist anymore. if (roleData == null) { - Logger.out("Role for channel ${data.channelid} does not exist") + Logger.out("Role for channel ${data.channelID} does not exist") return // this took way to long to find out that this was the issue } updateInChannel(snf, data, roleData) @@ -141,18 +141,18 @@ object AvailabilityManager : IFeature { @OptIn(PrivilegedIntent::class) suspend fun updateInChannel(snf: Snowflake, tpmd: TimePlanningMessagesData, pnrd: PlanningNotifierRolesData) { - if (Bot.bot.kordRef.getChannel(Snowflake(tpmd.channelid)) == null) + if (Bot.bot.kordRef.getChannel(Snowflake(tpmd.channelID)) == null) return // This channel does not exist anymore. val c = - Bot.bot.kordRef.getChannelOf(Snowflake(tpmd.channelid))!! // Get the channel as MessageChannel - if (Bot.bot.kordRef.getGuildOrNull(Snowflake(tpmd.serverid)) == null) { + Bot.bot.kordRef.getChannelOf(Snowflake(tpmd.channelID))!! // Get the channel as MessageChannel + if (Bot.bot.kordRef.getGuildOrNull(Snowflake(tpmd.serverID)) == null) { Logger.out("Guild not found.") return } val weekday = ZonedDateTime.now().dayOfWeek // The current week day val weekStamp = TimeUtil.getWeekStamp().toEpochSecond() * 1000 // The current week time stamp Logger.out("It is week ${weekStamp} and day ${weekday}/${TimeUtil.getDayOfMonthInt(weekday)} of the week.") - val g = Bot.bot.kordRef.getGuildOrThrow(Snowflake(tpmd.serverid)) + val g = Bot.bot.kordRef.getGuildOrThrow(Snowflake(tpmd.serverID)) // Get all members with the role val mce = g.requestMembers { this.requestAllMembers() @@ -161,8 +161,8 @@ object AvailabilityManager : IFeature { memberchunkevent.members.forEach { if (!it.isNullOrBot()) { // Check if the member is a bot Logger.out("Checking member ${it.id.value} (${it.username})") - if (it.roleIds.contains(Snowflake(pnrd.hastimeroleid))) { - it.removeRole(Snowflake(pnrd.hastimeroleid)) + if (it.roleIds.contains(Snowflake(pnrd.hasTimeRoleID))) { + it.removeRole(Snowflake(pnrd.hasTimeRoleID)) Logger.out("Removed role from ${it.username}") // Removed the role } } @@ -174,7 +174,7 @@ object AvailabilityManager : IFeature { // This stores the ids of the messages. // The format is weekdaNR:ID // The last entry (nr 8) is empty, so we can ignore it - val messageIdSplit = tpmd.messageids.split(";").subList(0, 7) + val messageIdSplit = tpmd.messageIDs.split(";").subList(0, 7) for (mid in messageIdSplit) { Logger.out("Checking id $mid") if (!mid.startsWith((TimeUtil.getDayOfMonthInt(weekday) - 1).toString(), true)) @@ -192,15 +192,15 @@ object AvailabilityManager : IFeature { val targets = EmbedUtil.getAllUsersInTheFirstXTables(2, message.embeds[0]) for (tid in targets) { Logger.out("Checking id $tid") - if (Bot.bot.kordRef.getGuildOrNull(Snowflake(tpmd.serverid))!! + if (Bot.bot.kordRef.getGuildOrNull(Snowflake(tpmd.serverID))!! .getMemberOrNull(Snowflake(tid)) == null ) continue// This member does not exist anymore. - val member = Bot.bot.kordRef.getGuildOrThrow(Snowflake(tpmd.serverid)) + val member = Bot.bot.kordRef.getGuildOrThrow(Snowflake(tpmd.serverID)) .getMember(Snowflake(tid)) // Get the member - if (member.roleIds.contains(Snowflake(pnrd.hastimeroleid))) + if (member.roleIds.contains(Snowflake(pnrd.hasTimeRoleID))) continue // This member already has the role - member.addRole(Snowflake(pnrd.hastimeroleid)) // Add the role + member.addRole(Snowflake(pnrd.hasTimeRoleID)) // Add the role Logger.out("Added role to ${member.username}") } Logger.out("Done with message. Moving on...") diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt index 1591545..aeb2203 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt @@ -57,9 +57,9 @@ object MatchManager { Logger.out("Checking match role ${data.id}...") if (data.timestamp.toLong() < System.currentTimeMillis()) { Logger.out("Match role ${data.id} is expired, removing...") - this.removeRoleFromGuild(data.serverid, data.roleid) + this.removeRoleFromGuild(data.serverID, data.roleID) transaction { - MatchPlanningData.deleteWhere { MatchPlanningData.messageid eq data.messageid } + MatchPlanningData.deleteWhere { MatchPlanningData.messageid eq data.messageID } } continue } @@ -71,9 +71,9 @@ object MatchManager { private fun registerJob(data: MatchPlanningDataData) { JobManager.addJob( MatchJob( - data.jobstr, + data.jobString, data.id, - "fromdb-${data.matchtype}_Vs_${data.opponentname}_[${data.id}]-${data.serverid}_${data.channelid}" + "fromdb-${data.matchType}_Vs_${data.opponentName}_[${data.id}]-${data.serverID}_${data.channelID}" ) ) Logger.out("Registered job for match ${data.id}...") diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 677520d..8a66ee7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -94,7 +94,7 @@ object TimeManager : IFeature { if (roleMap != null && roleMap.keys.contains(ch) && roleMap[ch] != null) { c.createMessage { this.content = - "The weekly planning starts now <@&${Snowflake(roleMap[ch]?.wantstobenotifid!!)}>" + "The weekly planning starts now <@&${Snowflake(roleMap[ch]?.wantsToBeNotifiedID!!)}>" this.embeds.add( MessageUtil.getEmbed( EmbedColor.INFO, diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt index 89b33e4..f350b86 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt @@ -67,12 +67,12 @@ class MatchJob( ) } } - val guild = Bot.bot.kordRef.getGuildOrNull(Snowflake(mpdd.serverid)) + val guild = Bot.bot.kordRef.getGuildOrNull(Snowflake(mpdd.serverID)) if (guild == null) { Logger.out("Guild not found.") return } - val r = guild.getRoleOrNull(Snowflake(mpdd.roleid)) + val r = guild.getRoleOrNull(Snowflake(mpdd.roleID)) if (r == null) { Logger.out("Role not found.") return -- 2.45.2 From 47a703156c6f370d23c00f9b4e08bca001c652e9 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 15 Sep 2023 22:49:12 +0200 Subject: [PATCH 094/168] chore: removed unused comment Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 64e0314..750eb8c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -103,8 +103,7 @@ object Bot { add(::FeatureManageExtension) add(::SendPlannerExtension) add(::MatchExtension) - add(::UpdateRolesExtension) // This command is only for debugging purposes - //add(::TestExtension) // See comment in TestExtension.kt + add(::UpdateRolesExtension) } this.presence { -- 2.45.2 From 39c88677228032b25533a0656d2d2b8c1f0195a7 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 15 Sep 2023 22:50:16 +0200 Subject: [PATCH 095/168] feat: moved all transactions into one package for reuse and simplicity Signed-off-by: moonleay --- .../buttons/matchplanner/AcceptEditButton.kt | 43 ++--- .../buttons/matchplanner/CancelEditButton.kt | 44 ++--- .../buttons/matchplanner/DeclineEditButton.kt | 43 ++--- .../data/entry/PlanningNotifierRolesData.kt | 1 + .../data/entry/TimePlanningChannelsData.kt | 1 + .../data/entry/TimePlanningMessagesData.kt | 1 + .../repository/MatchPlanningDataRepository.kt | 112 +++++++++++++ .../PlanningNotifierRolesRepository.kt | 104 ++++++++++++ .../TimePlanningChannelsRepository.kt | 69 ++++++++ .../TimePlanningMessagesRepository.kt | 76 +++++++++ .../lilJudd/extensions/MatchExtension.kt | 40 +++-- .../extensions/SendPlannerExtension.kt | 22 +-- .../lilJudd/features/AvailabilityManager.kt | 154 +++++------------- .../moonleay/lilJudd/features/MatchManager.kt | 32 +--- .../moonleay/lilJudd/features/TimeManager.kt | 106 ++++-------- .../net/moonleay/lilJudd/jobs/MatchJob.kt | 33 +--- 16 files changed, 509 insertions(+), 372 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/repository/MatchPlanningDataRepository.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/repository/PlanningNotifierRolesRepository.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningChannelsRepository.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningMessagesRepository.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt index 3dd02d7..115a7e5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt @@ -28,14 +28,10 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.transactions.transaction class AcceptEditButton() : IEditButton { override val id: String = "public.edit.btn.matchmanagement.accept" @@ -49,33 +45,20 @@ class AcceptEditButton() : IEditButton { val m = interaction.message val eb = MessageUtil.getAClonedEmbed(m.embeds[0]) var shouldEditButton = false - lateinit var mpdd: MatchPlanningDataData - var found = false - transaction { - for (pnr in MatchPlanningData.select { - MatchPlanningData.messageid eq (interaction.message.id.value.toLong()) and ( - MatchPlanningData.serverid eq (guild.id.value.toLong())) and ( - MatchPlanningData.channelid eq (interaction.channelId.value.toLong())) - }) { - mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id], - pnr[MatchPlanningData.serverid], - pnr[MatchPlanningData.channelid], - pnr[MatchPlanningData.matchtype], - pnr[MatchPlanningData.registererid], - pnr[MatchPlanningData.roleid], - pnr[MatchPlanningData.opponentName], - pnr[MatchPlanningData.messageid], - pnr[MatchPlanningData.timestamp], - pnr[MatchPlanningData.jobstr] - ) - found = true - } - } - if (!found || mpdd == null) { + val mpdd = MatchPlanningDataRepository.getFromMessageInChannelInServer( + m.id.value.toLong(), + interaction.channelId.value.toLong(), + guild.id.value.toLong() + ) + if (mpdd == null) { + Logger.out("mpdd is null") + return + } + val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) + if (role == null) { + Logger.out("role is null") return } - val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) ?: return val member = interaction.user.asMember(guild.id) ?: return // do the checks and update if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt index be99232..c7cebc3 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt @@ -28,12 +28,9 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.util.EmbedUtil -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.transactions.transaction +import net.moonleay.lilJudd.util.Logger class CancelEditButton : IEditButton { override val id: String = "public.edit.btn.matchmanagement.cancel" @@ -46,33 +43,20 @@ class CancelEditButton : IEditButton { ) { val m = interaction.message if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { - lateinit var mpdd: MatchPlanningDataData - var found = false - transaction { - for (pnr in MatchPlanningData.select { - MatchPlanningData.messageid eq (interaction.message.id.value.toLong()) and ( - MatchPlanningData.serverid eq (guild.id.value.toLong())) and ( - MatchPlanningData.channelid eq (interaction.channelId.value.toLong())) - }) { - mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id], - pnr[MatchPlanningData.serverid], - pnr[MatchPlanningData.channelid], - pnr[MatchPlanningData.matchtype], - pnr[MatchPlanningData.registererid], - pnr[MatchPlanningData.roleid], - pnr[MatchPlanningData.opponentName], - pnr[MatchPlanningData.messageid], - pnr[MatchPlanningData.timestamp], - pnr[MatchPlanningData.jobstr] - ) - found = true - } - } - if (!found || mpdd == null) { + val mpdd = MatchPlanningDataRepository.getFromMessageInChannelInServer( + m.id.value.toLong(), + interaction.channelId.value.toLong(), + guild.id.value.toLong() + ) + if (mpdd == null) { + Logger.out("mpdd is null") + return + } + val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) + if (role == null) { + Logger.out("role is null") return } - val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) ?: return val member = interaction.user.asMember(guild.id) if (member.roleIds.contains(Snowflake(mpdd.roleID))) { member.removeRole(role.id) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt index 9a3de97..d775a29 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt @@ -28,14 +28,10 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.transactions.transaction class DeclineEditButton : IEditButton { override val id: String = "public.edit.btn.matchmanagement.decline" @@ -49,33 +45,20 @@ class DeclineEditButton : IEditButton { val m = interaction.message val eb = MessageUtil.getAClonedEmbed(m.embeds[0]) var shouldEditButton = false - lateinit var mpdd: MatchPlanningDataData - var found = false - transaction { - for (pnr in MatchPlanningData.select { - MatchPlanningData.messageid eq (interaction.message.id.value.toLong()) and ( - MatchPlanningData.serverid eq (guild.id.value.toLong())) and ( - MatchPlanningData.channelid eq (interaction.channelId.value.toLong())) - }) { - mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id], - pnr[MatchPlanningData.serverid], - pnr[MatchPlanningData.channelid], - pnr[MatchPlanningData.matchtype], - pnr[MatchPlanningData.registererid], - pnr[MatchPlanningData.roleid], - pnr[MatchPlanningData.opponentName], - pnr[MatchPlanningData.messageid], - pnr[MatchPlanningData.timestamp], - pnr[MatchPlanningData.jobstr] - ) - found = true - } - } - if (!found || mpdd == null) { + val mpdd = MatchPlanningDataRepository.getFromMessageInChannelInServer( + m.id.value.toLong(), + interaction.channelId.value.toLong(), + guild.id.value.toLong() + ) + if (mpdd == null) { + Logger.out("mpdd is null") + return + } + val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) + if (role == null) { + Logger.out("role is null") return } - val role = guild.getRoleOrNull(Snowflake(mpdd.roleID)) ?: return val member = interaction.user.asMember(guild.id) ?: return if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { if (member.roleIds.contains(Snowflake(mpdd.roleID))) { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt index a36f351..730e7fe 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt @@ -19,6 +19,7 @@ package net.moonleay.lilJudd.data.entry data class PlanningNotifierRolesData( + val id: Int, // The id of the entry val serverID: Long, // The id of the server val channelID: Long, // The id of the channel val hasTimeRoleID: Long, // The id of the role that has time today diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt index 2eebba4..fba9898 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt @@ -19,6 +19,7 @@ package net.moonleay.lilJudd.data.entry data class TimePlanningChannelsData( + val id: Int, val serverID: Long, val channelID: Long, ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt index 6c5b2fc..fcb283b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt @@ -19,6 +19,7 @@ package net.moonleay.lilJudd.data.entry data class TimePlanningMessagesData( + val id: Int, // The id of the entry val serverID: Long, // The discord server id val channelID: Long, // The discord channel id val weekstamp: Long, // The timestamp of the monday of the week at 4am UTC diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/repository/MatchPlanningDataRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/repository/MatchPlanningDataRepository.kt new file mode 100644 index 0000000..385eb69 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/repository/MatchPlanningDataRepository.kt @@ -0,0 +1,112 @@ +/* + * 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.repository + +import net.moonleay.lilJudd.data.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.tables.MatchPlanningData +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.transactions.transaction + +object MatchPlanningDataRepository { + + fun getAll(): List { + val dataList = mutableListOf() + transaction { + MatchPlanningData.selectAll().forEach { + dataList.add( + MatchPlanningDataData( + it[MatchPlanningData.id], + it[MatchPlanningData.serverid], + it[MatchPlanningData.channelid], + it[MatchPlanningData.matchtype], + it[MatchPlanningData.registererid], + it[MatchPlanningData.roleid], + it[MatchPlanningData.opponentName], + it[MatchPlanningData.messageid], + it[MatchPlanningData.timestamp], + it[MatchPlanningData.jobstr] + ) + ) + } + } + return dataList + } + + fun get(id: Int): MatchPlanningDataData? = + transaction { + MatchPlanningData.select { MatchPlanningData.id eq id }.firstOrNull()?.let { + MatchPlanningDataData( + it[MatchPlanningData.id], + it[MatchPlanningData.serverid], + it[MatchPlanningData.channelid], + it[MatchPlanningData.matchtype], + it[MatchPlanningData.registererid], + it[MatchPlanningData.roleid], + it[MatchPlanningData.opponentName], + it[MatchPlanningData.messageid], + it[MatchPlanningData.timestamp], + it[MatchPlanningData.jobstr] + ) + } + } + + fun getFromMessageInChannelInServer(messageID: Long, channelID: Long, serverID: Long): MatchPlanningDataData? = + transaction { + MatchPlanningData.select { + MatchPlanningData.messageid eq (messageID) and ( + MatchPlanningData.serverid eq (serverID)) and ( + MatchPlanningData.channelid eq (channelID)) + }.firstOrNull()?.let { + MatchPlanningDataData( + it[MatchPlanningData.id], + it[MatchPlanningData.serverid], + it[MatchPlanningData.channelid], + it[MatchPlanningData.matchtype], + it[MatchPlanningData.registererid], + it[MatchPlanningData.roleid], + it[MatchPlanningData.opponentName], + it[MatchPlanningData.messageid], + it[MatchPlanningData.timestamp], + it[MatchPlanningData.jobstr] + ) + } + } + + fun delete(id: Int) { + transaction { + MatchPlanningData.deleteWhere { MatchPlanningData.id eq id } + } + } + + fun write(data: MatchPlanningDataData): Int = + transaction { + MatchPlanningData.insert { + it[MatchPlanningData.serverid] = data.serverID + it[MatchPlanningData.channelid] = data.channelID + it[MatchPlanningData.matchtype] = data.matchType + it[MatchPlanningData.registererid] = data.registererID + it[MatchPlanningData.roleid] = data.roleID + it[MatchPlanningData.opponentName] = data.opponentName + it[MatchPlanningData.messageid] = data.messageID + it[MatchPlanningData.timestamp] = data.timestamp + it[MatchPlanningData.jobstr] = data.jobString + } get MatchPlanningData.id + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/repository/PlanningNotifierRolesRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/repository/PlanningNotifierRolesRepository.kt new file mode 100644 index 0000000..2603081 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/repository/PlanningNotifierRolesRepository.kt @@ -0,0 +1,104 @@ +/* + * 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.repository + +import net.moonleay.lilJudd.data.entry.PlanningNotifierRolesData +import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.transactions.transaction + +object PlanningNotifierRolesRepository { + + fun getAll(): List { + val dataList = mutableListOf() + transaction { + for (pnr in PlanningNotifierRoles.selectAll()) { + dataList.add( + PlanningNotifierRolesData( + pnr[PlanningNotifierRoles.id], + pnr[PlanningNotifierRoles.serverid], + pnr[PlanningNotifierRoles.channelid], + pnr[PlanningNotifierRoles.hastimeroleid], + pnr[PlanningNotifierRoles.wantstobenotifiedid] + ) + ) + } + } + return dataList + } + + fun getForChannel(channelID: Long): PlanningNotifierRolesData? = + transaction { + PlanningNotifierRoles.select { + PlanningNotifierRoles.channelid eq channelID + }.firstOrNull()?.let { + PlanningNotifierRolesData( + it[PlanningNotifierRoles.id], + it[PlanningNotifierRoles.serverid], + it[PlanningNotifierRoles.channelid], + it[PlanningNotifierRoles.hastimeroleid], + it[PlanningNotifierRoles.wantstobenotifiedid] + ) + } + } + + fun getForChannelInServer(channelID: Long, serverID: Long): PlanningNotifierRolesData? = + transaction { + PlanningNotifierRoles.select { + PlanningNotifierRoles.channelid eq channelID and (PlanningNotifierRoles.serverid eq serverID) + }.firstOrNull()?.let { + PlanningNotifierRolesData( + it[PlanningNotifierRoles.id], + it[PlanningNotifierRoles.serverid], + it[PlanningNotifierRoles.channelid], + it[PlanningNotifierRoles.hastimeroleid], + it[PlanningNotifierRoles.wantstobenotifiedid] + ) + } + } + + fun existsInChannel(channelID: Long): Boolean = + transaction { + PlanningNotifierRoles.select { PlanningNotifierRoles.channelid eq channelID }.count() > 0 + } + + fun existsInChannelFromSever(channelID: Long, serverID: Long): Boolean = + transaction { + PlanningNotifierRoles.select { PlanningNotifierRoles.channelid eq channelID and (PlanningNotifierRoles.serverid eq serverID) } + .count() > 0 + } + + fun write(data: PlanningNotifierRolesData) { + transaction { + PlanningNotifierRoles.insert { + it[PlanningNotifierRoles.serverid] = data.serverID + it[PlanningNotifierRoles.channelid] = data.channelID + it[PlanningNotifierRoles.hastimeroleid] = data.hasTimeRoleID + it[PlanningNotifierRoles.wantstobenotifiedid] = data.wantsToBeNotifiedID + } get PlanningNotifierRoles.id + } + } + + fun delete(id: Int) { + transaction { + PlanningNotifierRoles.deleteWhere { PlanningNotifierRoles.id eq id } + } + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningChannelsRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningChannelsRepository.kt new file mode 100644 index 0000000..7756802 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningChannelsRepository.kt @@ -0,0 +1,69 @@ +/* + * 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.repository + +import net.moonleay.lilJudd.data.entry.TimePlanningChannelsData +import net.moonleay.lilJudd.data.tables.TimePlanningChannels +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.transactions.transaction + +object TimePlanningChannelsRepository { + + fun getAll(): List { + val dataList = mutableListOf() + transaction { + for (tp in TimePlanningChannels.selectAll()) + dataList.add( + TimePlanningChannelsData( + id = tp[TimePlanningChannels.id], + serverID = tp[TimePlanningChannels.serverid], + channelID = tp[TimePlanningChannels.channelid], + ) + ) + } + return dataList + } + + fun exists(channelID: Long, serverID: Long): Boolean = + transaction { + TimePlanningChannels.select { TimePlanningChannels.channelid eq channelID and (TimePlanningChannels.serverid eq serverID) } + .firstOrNull() != null + } + + fun delete(id: Int) { + transaction { + TimePlanningChannels.deleteWhere { TimePlanningChannels.id eq id } + } + } + + fun deleteFromChannelInServer(channelID: Long, serverID: Long) { + transaction { + TimePlanningChannels.deleteWhere { TimePlanningChannels.channelid eq channelID and (TimePlanningChannels.serverid eq serverID) } + } + } + + fun write(data: TimePlanningChannelsData): Int = + transaction { + TimePlanningChannels.insert { + it[TimePlanningChannels.serverid] = data.serverID + it[TimePlanningChannels.channelid] = data.channelID + } get TimePlanningChannels.id + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningMessagesRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningMessagesRepository.kt new file mode 100644 index 0000000..5e2f273 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningMessagesRepository.kt @@ -0,0 +1,76 @@ +/* + * 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.repository + +import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData +import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.transactions.transaction + +object TimePlanningMessagesRepository { + + fun write(data: TimePlanningMessagesData): Int = + transaction { + TimePlanningMessages.insert { + it[serverid] = data.serverID + it[channelid] = data.channelID + it[weekstamp] = data.weekstamp + it[messageids] = data.messageIDs + } get TimePlanningMessages.id + } + + fun getWeek(stamp: Long): List { + val dataList = mutableListOf() + transaction { + for (pnr in TimePlanningMessages.select { + TimePlanningMessages.weekstamp eq (stamp) + }) { + dataList.add( + TimePlanningMessagesData( + pnr[TimePlanningMessages.id], + pnr[TimePlanningMessages.serverid], + pnr[TimePlanningMessages.channelid], + pnr[TimePlanningMessages.weekstamp], + pnr[TimePlanningMessages.messageids] + ) + ) + } + } + return dataList + } + + fun getWeekInChannel(stamp: Long, channelID: Long): TimePlanningMessagesData? = + transaction { + TimePlanningMessages.select { + TimePlanningMessages.weekstamp eq (stamp) and (TimePlanningMessages.channelid eq channelID) + }.firstOrNull()?.let { + TimePlanningMessagesData( + it[TimePlanningMessages.id], + it[TimePlanningMessages.serverid], + it[TimePlanningMessages.channelid], + it[TimePlanningMessages.weekstamp], + it[TimePlanningMessages.messageids] + ) + } + } + + +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index 40787d4..17592e6 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -28,7 +28,8 @@ import com.kotlindiscord.kord.extensions.types.respond import dev.kord.core.behavior.channel.createMessage import dev.kord.core.behavior.createRole import dev.kord.rest.builder.message.create.actionRow -import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.data.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.extensions.component.MatchTypes import net.moonleay.lilJudd.jobs.MatchJob import net.moonleay.lilJudd.jobs.component.JobManager @@ -36,9 +37,6 @@ import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.lilJudd.util.TimeUtil -import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.transactions.transaction -import kotlin.properties.Delegates class MatchExtension : Extension() { @@ -100,28 +98,28 @@ class MatchExtension : Extension() { } return@action } - var tableID by Delegates.notNull() - transaction { - tableID = MatchPlanningData.insert { - it[MatchPlanningData.serverid] = gID.toLong() - it[MatchPlanningData.channelid] = cID.toLong() - it[MatchPlanningData.messageid] = msg.id.value.toLong() - it[MatchPlanningData.matchtype] = args.matchType.readableName - it[MatchPlanningData.roleid] = role.id.value.toLong() - it[MatchPlanningData.registererid] = m.id.value.toLong() - it[MatchPlanningData.opponentName] = opponent - it[MatchPlanningData.timestamp] = (zdt.toEpochSecond() * 1000) - it[MatchPlanningData.jobstr] = jobString - } get MatchPlanningData.id - } - if (tableID == null) { + val tID = MatchPlanningDataRepository.write( + MatchPlanningDataData( + 0, + gID.toLong(), + cID.toLong(), + args.matchType.readableName, + m.id.value.toLong(), + role.id.value.toLong(), + opponent, + msg.id.value.toLong(), + (zdt.toEpochSecond() * 1000), + jobString + ) + ) + if (tID == null || tID <= 0) { return@action // Not saved to db } JobManager.addJob( MatchJob( jobString, - tableID, - "${args.matchType.readableName}_Vs_${opponent}_[${tableID}]-${gID}_${cID}", + tID, + "${args.matchType.readableName}_Vs_${opponent}_[${tID}]-${gID}_${cID}", ) ) } diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index fd293d9..ee85372 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -26,10 +26,9 @@ import dev.kord.common.entity.Permission import dev.kord.core.behavior.channel.createMessage import dev.kord.rest.builder.message.create.actionRow import kotlinx.coroutines.delay -import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData +import net.moonleay.lilJudd.data.repository.TimePlanningMessagesRepository import net.moonleay.lilJudd.util.* -import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.transactions.transaction import java.time.ZoneId import java.time.ZonedDateTime @@ -101,14 +100,15 @@ class SendPlannerExtension : Extension() { } // Save the message ids - transaction { - TimePlanningMessages.insert { - it[TimePlanningMessages.serverid] = c.data.guildId.value?.value!!.toLong() - it[TimePlanningMessages.channelid] = c.id.value.toLong() - it[TimePlanningMessages.weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000) - it[TimePlanningMessages.messageids] = msgStr - } get TimePlanningMessages.id - } + TimePlanningMessagesRepository.write( + TimePlanningMessagesData( + -1, + c.data.guildId.value?.value!!.toLong(), + c.id.value.toLong(), + (TimeUtil.getWeekStamp().toEpochSecond() * 1000), + msgStr + ) + ) Logger.out("Finished with ${c.data.guildId.value}") } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 8683dd5..6a42046 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -32,61 +32,35 @@ import dev.kord.rest.builder.message.EmbedBuilder import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.data.entry.PlanningNotifierRolesData import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles -import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.data.repository.PlanningNotifierRolesRepository +import net.moonleay.lilJudd.data.repository.TimePlanningMessagesRepository import net.moonleay.lilJudd.extensions.FeatureManageExtension import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.IFeature import net.moonleay.lilJudd.util.* -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.transactions.transaction import java.time.ZonedDateTime object AvailabilityManager : IFeature { // This runs during the cronjob. - @OptIn(PrivilegedIntent::class) suspend fun runThread() { Logger.out("Starting to update roles...") // ChannelID, Data - val messageMap = mutableMapOf() - // ChannelID, Data - val roleMap = mutableMapOf() + val messages = TimePlanningMessagesRepository.getWeek(TimeUtil.getWeekStamp().toEpochSecond() * 1000) + .associateBy { it.channelID } + val targetedRoles = PlanningNotifierRolesRepository.getAll().associateBy { it.channelID } - transaction { - for (pnr in TimePlanningMessages.select { - TimePlanningMessages.weekstamp eq (TimeUtil.getWeekStamp().toEpochSecond() * 1000) - }) { - messageMap[Snowflake(pnr[TimePlanningMessages.channelid])] = - TimePlanningMessagesData( - pnr[TimePlanningMessages.serverid], - pnr[TimePlanningMessages.channelid], - pnr[TimePlanningMessages.weekstamp], - pnr[TimePlanningMessages.messageids] - ) - } - for (pnr in PlanningNotifierRoles.selectAll()) { - roleMap[pnr[PlanningNotifierRoles.channelid]] = - PlanningNotifierRolesData( - pnr[PlanningNotifierRoles.serverid], - pnr[PlanningNotifierRoles.channelid], - pnr[PlanningNotifierRoles.hastimeroleid], - pnr[PlanningNotifierRoles.wantstobenotifiedid] - ) - } - } - - for (snf in messageMap.keys) { // snf = Snowflake - val data = messageMap[snf]!! // this is the data of the table + for (id in messages.keys) { + val snf = Snowflake(id) // snf = Snowflake + val data = messages[id]!! // this is the data of the table if (Bot.bot.kordRef.getChannel(Snowflake(data.channelID)) == null) continue // This channel does not exist anymore. - if (roleMap.isEmpty()) { + if (targetedRoles.isEmpty()) { Logger.out("No saved roles. Canceling.") return } - val roleData = roleMap[data.channelID] // Get the role data + val roleData = targetedRoles[data.channelID] // Get the role data if (roleData == null) { Logger.out("Role for channel ${data.channelID} does not exist") continue // this took way to long to find out that this was the issue @@ -97,58 +71,27 @@ object AvailabilityManager : IFeature { } suspend fun updateInChannel(snf: Snowflake) { - lateinit var data: TimePlanningMessagesData - lateinit var roleData: PlanningNotifierRolesData - var found1 = false - var found2 = false - for (pnr in TimePlanningMessages.select { - TimePlanningMessages.weekstamp eq (TimeUtil.getWeekStamp() - .toEpochSecond() * 1000) and (TimePlanningMessages.channelid eq (snf.value.toLong())) - }) { - data = - TimePlanningMessagesData( - pnr[TimePlanningMessages.serverid], - pnr[TimePlanningMessages.channelid], - pnr[TimePlanningMessages.weekstamp], - pnr[TimePlanningMessages.messageids] - ) - found1 = true - } - for (pnr in PlanningNotifierRoles.select { - PlanningNotifierRoles.channelid eq (snf.value.toLong()) - }) { - roleData = - PlanningNotifierRolesData( - pnr[PlanningNotifierRoles.serverid], - pnr[PlanningNotifierRoles.channelid], - pnr[PlanningNotifierRoles.hastimeroleid], - pnr[PlanningNotifierRoles.wantstobenotifiedid] - ) - found2 = true - } - if (!found1 || !found2) { + val messageData = TimePlanningMessagesRepository.getWeekInChannel( + TimeUtil.getWeekStamp().toEpochSecond() * 1000, + snf.value.toLong() + ) + val roleData = PlanningNotifierRolesRepository.getForChannel(snf.value.toLong()) + if (messageData == null) { Logger.out("Could not find data for channel ${snf.value}") return } - if (Bot.bot.kordRef.getChannel(Snowflake(data.channelID)) == null) - return // This channel does not exist anymore. if (roleData == null) { - Logger.out("Role for channel ${data.channelID} does not exist") + Logger.out("Role for channel ${messageData.channelID} does not exist") return // this took way to long to find out that this was the issue } - updateInChannel(snf, data, roleData) + updateInChannel(snf, messageData, roleData) } @OptIn(PrivilegedIntent::class) suspend fun updateInChannel(snf: Snowflake, tpmd: TimePlanningMessagesData, pnrd: PlanningNotifierRolesData) { - if (Bot.bot.kordRef.getChannel(Snowflake(tpmd.channelID)) == null) + if (Bot.bot.kordRef.getChannel(snf) == null) return // This channel does not exist anymore. - val c = - Bot.bot.kordRef.getChannelOf(Snowflake(tpmd.channelID))!! // Get the channel as MessageChannel - if (Bot.bot.kordRef.getGuildOrNull(Snowflake(tpmd.serverID)) == null) { - Logger.out("Guild not found.") - return - } + val c = Bot.bot.kordRef.getChannelOf(snf)!! // Get the channel as MessageChannel val weekday = ZonedDateTime.now().dayOfWeek // The current week day val weekStamp = TimeUtil.getWeekStamp().toEpochSecond() * 1000 // The current week time stamp Logger.out("It is week ${weekStamp} and day ${weekday}/${TimeUtil.getDayOfMonthInt(weekday)} of the week.") @@ -228,13 +171,8 @@ object AvailabilityManager : IFeature { ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { - var alreadyExists = false + var alreadyExists = PlanningNotifierRolesRepository.existsInChannel(cID) // Check if the channel and guild already exist in the db - transaction { - alreadyExists = PlanningNotifierRoles.select { - (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID) - }.count() > 0 - } if (!alreadyExists) { // Create the roles in Discord val hasTimeRole = Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)).createRole { @@ -250,14 +188,15 @@ object AvailabilityManager : IFeature { val wnr = wantsNotifsRole.id.value.toLong() // Save the role ids to db - transaction { - PlanningNotifierRoles.insert { - it[PlanningNotifierRoles.serverid] = gID - it[PlanningNotifierRoles.channelid] = cID - it[PlanningNotifierRoles.hastimeroleid] = htr - it[PlanningNotifierRoles.wantstobenotifiedid] = wnr - } get PlanningNotifierRoles.id - } + PlanningNotifierRolesRepository.write( + PlanningNotifierRolesData( + id = -1, + serverID = gID, + channelID = cID, + hasTimeRoleID = htr, + wantsToBeNotifiedID = wnr + ) + ) return MessageUtil.getEmbed( EmbedColor.SUCCESS, @@ -284,35 +223,16 @@ object AvailabilityManager : IFeature { args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { // Check if entry exists in db - var alreadyExists = false - transaction { - alreadyExists = PlanningNotifierRoles.select { - (PlanningNotifierRoles.serverid eq gID) and (PlanningNotifierRoles.channelid eq cID) - }.count() > 0 - } - if (alreadyExists) { - var matchingEntries: List = mutableListOf() - transaction { - matchingEntries = PlanningNotifierRoles.select { - (PlanningNotifierRoles.serverid eq gID) and - (PlanningNotifierRoles.channelid eq cID) - }.toList() - } + if (PlanningNotifierRolesRepository.existsInChannelFromSever(cID, gID)) { + val entry = PlanningNotifierRolesRepository.getForChannelInServer(cID, gID)!! // delete all entries for this guild and channel combo - for (e in matchingEntries) { - Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)) - .getRoleOrNull(Snowflake(e[PlanningNotifierRoles.hastimeroleid]))?.delete() - Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)) - .getRoleOrNull(Snowflake(e[PlanningNotifierRoles.wantstobenotifiedid])) - ?.delete() - } + Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)) + .getRoleOrNull(Snowflake(entry.hasTimeRoleID))?.delete() + Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)) + .getRoleOrNull(Snowflake(entry.wantsToBeNotifiedID))?.delete() // delete all found entries - transaction { - matchingEntries.forEach { entry -> - PlanningNotifierRoles.deleteWhere { id eq entry[id] } - } - } + PlanningNotifierRolesRepository.delete(entry.id) return MessageUtil.getEmbed( EmbedColor.SUCCESS, "200: Success", diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt index aeb2203..fc89dc9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt @@ -21,46 +21,22 @@ package net.moonleay.lilJudd.features import dev.kord.common.entity.Snowflake import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.jobs.MatchJob import net.moonleay.lilJudd.jobs.component.JobManager import net.moonleay.lilJudd.util.Logger -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.deleteWhere -import org.jetbrains.exposed.sql.selectAll -import org.jetbrains.exposed.sql.transactions.transaction object MatchManager { suspend fun update() { Logger.out("Updating match roles...") - val dataList = mutableListOf() - transaction { - MatchPlanningData.selectAll().forEach { - dataList.add( - MatchPlanningDataData( - it[MatchPlanningData.id], - it[MatchPlanningData.serverid], - it[MatchPlanningData.channelid], - it[MatchPlanningData.matchtype], - it[MatchPlanningData.registererid], - it[MatchPlanningData.roleid], - it[MatchPlanningData.opponentName], - it[MatchPlanningData.messageid], - it[MatchPlanningData.timestamp], - it[MatchPlanningData.jobstr] - ) - ) - } - } + val dataList = MatchPlanningDataRepository.getAll() for (data in dataList) { Logger.out("Checking match role ${data.id}...") - if (data.timestamp.toLong() < System.currentTimeMillis()) { + if (data.timestamp < System.currentTimeMillis()) { Logger.out("Match role ${data.id} is expired, removing...") this.removeRoleFromGuild(data.serverID, data.roleID) - transaction { - MatchPlanningData.deleteWhere { MatchPlanningData.messageid eq data.messageID } - } + MatchPlanningDataRepository.delete(data.id) continue } this.registerJob(data) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 8a66ee7..d986440 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -29,17 +29,18 @@ import dev.kord.rest.builder.message.EmbedBuilder 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.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.data.entry.TimePlanningChannelsData +import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData +import net.moonleay.lilJudd.data.repository.PlanningNotifierRolesRepository +import net.moonleay.lilJudd.data.repository.TimePlanningChannelsRepository +import net.moonleay.lilJudd.data.repository.TimePlanningMessagesRepository import net.moonleay.lilJudd.extensions.FeatureManageExtension import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.IFeature -import net.moonleay.lilJudd.util.* -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.transactions.transaction +import net.moonleay.lilJudd.util.EmbedColor +import net.moonleay.lilJudd.util.EmbedUtil +import net.moonleay.lilJudd.util.Logger +import net.moonleay.lilJudd.util.MessageUtil import java.time.ZoneId import java.time.ZonedDateTime @@ -60,41 +61,23 @@ object TimeManager : IFeature { private suspend fun runThread() { Logger.out("Starting to notify...") + // ChannelID -> Data + val targetedChannels = TimePlanningChannelsRepository.getAll().associateBy { it.channelID } + val targetedRoles = PlanningNotifierRolesRepository.getAll().associateBy { it.channelID } - // ChannelID, ServerID - val channelList = mutableMapOf() - // ChannelID, Data - val roleMap = mutableMapOf() + lateinit var msgStr: String - var msgStr = "" - - transaction { - for (tp in TimePlanningChannels.selectAll()) { - 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()) { - roleMap[Snowflake(pnr[PlanningNotifierRoles.channelid])] = PlanningNotifierRolesData( - pnr[PlanningNotifierRoles.serverid], - pnr[PlanningNotifierRoles.channelid], - pnr[PlanningNotifierRoles.hastimeroleid], - pnr[PlanningNotifierRoles.wantstobenotifiedid] - ) - Logger.out("Have to ping roles: ${pnr[PlanningNotifierRoles.wantstobenotifiedid]}}") - } - } - Logger.out("${channelList.count()} Channels to notify with ${roleMap.count()} Roles to ping!") - for (ch in channelList.keys) { + Logger.out("${targetedChannels.count()} Channels to notify with ${targetedRoles.count()} Roles to ping!") + for (ch2 in targetedChannels.keys) { + val ch = Snowflake(ch2) 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)!! msgStr = "" - if (roleMap != null && roleMap.keys.contains(ch) && roleMap[ch] != null) { + if (targetedRoles != null && targetedRoles.keys.contains(ch2) && targetedRoles[ch2] != null) { c.createMessage { this.content = - "The weekly planning starts now <@&${Snowflake(roleMap[ch]?.wantsToBeNotifiedID!!)}>" + "The weekly planning starts now <@&${Snowflake(targetedRoles[ch2]?.wantsToBeNotifiedID!!)}>" this.embeds.add( MessageUtil.getEmbed( EmbedColor.INFO, @@ -145,14 +128,15 @@ object TimeManager : IFeature { } // Save the message ids - transaction { - TimePlanningMessages.insert { - it[TimePlanningMessages.serverid] = c.data.guildId.value?.value!!.toLong() - it[TimePlanningMessages.channelid] = c.id.value.toLong() - it[TimePlanningMessages.weekstamp] = (TimeUtil.getWeekStamp().toEpochSecond() * 1000) - it[TimePlanningMessages.messageids] = msgStr - } get TimePlanningMessages.id - } + TimePlanningMessagesRepository.write( + TimePlanningMessagesData( + id = -1, + serverID = c.data.guildId.value?.value!!.toLong(), + channelID = c.data.id.value.toLong(), + weekstamp = then.minusDays(7).toEpochSecond(), + messageIDs = msgStr + ) + ) Logger.out("Finished with ${c.data.guildId.value}") } Logger.out("Done! Until next Monday! <3 ") @@ -165,20 +149,8 @@ object TimeManager : IFeature { ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { - var alreadyExists = false - transaction { - alreadyExists = TimePlanningChannels.select { - (TimePlanningChannels.serverid eq gID) and - (TimePlanningChannels.channelid eq cID) - }.count() > 0 - } - if (!alreadyExists) { - transaction { - TimePlanningChannels.insert { - it[TimePlanningChannels.serverid] = gID - it[TimePlanningChannels.channelid] = cID - } get TimePlanningChannels.id - } + if (!TimePlanningChannelsRepository.exists(cID, gID)) { + TimePlanningChannelsRepository.write(TimePlanningChannelsData(id = -1, serverID = gID, channelID = cID)) return MessageUtil.getEmbed( EmbedColor.SUCCESS, "200: Success", @@ -202,25 +174,9 @@ object TimeManager : IFeature { args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { // Check if entry exists in db - var alreadyExists = false - transaction { - alreadyExists = TimePlanningChannels.select { - (TimePlanningChannels.serverid eq gID) and - (TimePlanningChannels.channelid eq cID) - }.count() > 0 - } - if (alreadyExists) { + if (TimePlanningChannelsRepository.exists(cID, gID)) { // delete all entrys for this channel - transaction { - val matchingEntries = TimePlanningChannels.select { - (TimePlanningChannels.serverid eq gID) and - (TimePlanningChannels.channelid eq cID) - }.toList() - - matchingEntries.forEach { entry -> - TimePlanningChannels.deleteWhere { id eq entry[id] } - } - } + TimePlanningChannelsRepository.deleteFromChannelInServer(cID, gID) return MessageUtil.getEmbed( EmbedColor.SUCCESS, "200: Success", diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt index f350b86..8360f62 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt @@ -22,16 +22,11 @@ import dev.inmo.krontab.KronScheduler import dev.kord.common.entity.Snowflake import kotlinx.coroutines.Job import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.jobs.component.CronjobType import net.moonleay.lilJudd.jobs.component.ICronjob import net.moonleay.lilJudd.jobs.component.JobManager import net.moonleay.lilJudd.util.Logger -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq -import org.jetbrains.exposed.sql.deleteWhere -import org.jetbrains.exposed.sql.select -import org.jetbrains.exposed.sql.transactions.transaction class MatchJob( override val jobIncoming: String, @@ -48,25 +43,7 @@ class MatchJob( * */ override suspend fun jobFunction() { Logger.out("Running MatchJob \"${this.jobName}\"") - lateinit var mpdd: MatchPlanningDataData - transaction { - for (pnr in MatchPlanningData.select { - MatchPlanningData.id eq (tableId) - }) { - mpdd = MatchPlanningDataData( - pnr[MatchPlanningData.id], - pnr[MatchPlanningData.serverid], - pnr[MatchPlanningData.channelid], - pnr[MatchPlanningData.matchtype], - pnr[MatchPlanningData.registererid], - pnr[MatchPlanningData.roleid], - pnr[MatchPlanningData.opponentName], - pnr[MatchPlanningData.messageid], - pnr[MatchPlanningData.timestamp], - pnr[MatchPlanningData.jobstr] - ) - } - } + val mpdd = MatchPlanningDataRepository.get(tableId)!! val guild = Bot.bot.kordRef.getGuildOrNull(Snowflake(mpdd.serverID)) if (guild == null) { Logger.out("Guild not found.") @@ -78,11 +55,7 @@ class MatchJob( return } r.delete() - transaction { - MatchPlanningData.deleteWhere { - MatchPlanningData.id eq (tableId) - } - } + MatchPlanningDataRepository.delete(tableId) Logger.out("MatchJob \"${this.jobName}\" finished.") Logger.out("Killing job \"${this.jobName}\"..") JobManager.killJob(this) -- 2.45.2 From a730bdffa523c805d5333f7d91a3d3271693c7d6 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 15 Sep 2023 23:37:06 +0200 Subject: [PATCH 096/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index dcda691..ceda37c 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.5.4" + ?: "2.5.5" val kordver = "1.5.6" val coroutinesver = "1.1.0" -- 2.45.2 From 9072109b34248b352e910261e4929c0b4794133a Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 17 Sep 2023 12:58:15 +0200 Subject: [PATCH 097/168] chore!: upgrade dependencies & gradle (7.4.2 -> 8.3) Signed-off-by: moonleay --- build.gradle.kts | 34 ++++++++++++++--------- gradle/wrapper/gradle-wrapper.jar | Bin 60756 -> 59821 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index ceda37c..a90bf54 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -21,9 +21,9 @@ import org.jetbrains.gradle.ext.TaskTriggersConfig import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version "1.8.20" - id("com.github.johnrengelman.shadow") version "7.1.2" - id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.6" + kotlin("jvm") version "1.9.10" + id("com.github.johnrengelman.shadow") version "8.1.1" + id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7" `maven-publish` } @@ -32,14 +32,14 @@ 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.5.5" + ?: "2.5.6" -val kordver = "1.5.6" -val coroutinesver = "1.1.0" -val ktor_version = "2.3.0" -val exposedver = "0.40.1" -val postgresver = "42.3.8" -val krontabver = "2.1.2" +val kordver = "1.5.9-SNAPSHOT" +val coroutinesver = "1.7.3" +val ktor_version = "2.3.4" +val exposedver = "0.43.0" +val postgresver = "42.6.0" +val krontabver = "2.2.0" val mavenArtifact = "lilJudd" project.base.archivesName.set(mavenArtifact) @@ -72,6 +72,14 @@ repositories { } } } + maven { + name = "sonatype" + url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots") + } + maven { + name = "sonatype 2" + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + } } val shadow by configurations.getting @@ -95,14 +103,14 @@ 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") + "shadow"("io.ktor:ktor-client-core-jvm:2.3.4") + "shadow"("io.ktor:ktor-client-cio-jvm:2.3.4") } val targetJavaVersion = 17 val templateSrc = project.rootDir.resolve("src/main/templates") -val templateDest = project.buildDir.resolve("generated/templates") +val templateDest = project.projectDir.resolve("build/generated/templates") val templateProps = mapOf( "version" to project.version as String, "ownerID" to ownerID, diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 249e5832f090a2944b7473328c07c9755baa3196..41d9927a4d4fb3f96a785543079b8df6723c946b 100644 GIT binary patch delta 9308 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 delta 10197 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 Date: Sun, 17 Sep 2023 12:59:54 +0200 Subject: [PATCH 098/168] fix: fixed removed functions Signed-off-by: moonleay --- .../moonleay/lilJudd/features/AvailabilityManager.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 6a42046..df88ee1 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -95,7 +95,7 @@ object AvailabilityManager : IFeature { val weekday = ZonedDateTime.now().dayOfWeek // The current week day val weekStamp = TimeUtil.getWeekStamp().toEpochSecond() * 1000 // The current week time stamp Logger.out("It is week ${weekStamp} and day ${weekday}/${TimeUtil.getDayOfMonthInt(weekday)} of the week.") - val g = Bot.bot.kordRef.getGuildOrThrow(Snowflake(tpmd.serverID)) + val g = Bot.bot.kordRef.getGuild(Snowflake(tpmd.serverID)) // Get all members with the role val mce = g.requestMembers { this.requestAllMembers() @@ -139,7 +139,7 @@ object AvailabilityManager : IFeature { .getMemberOrNull(Snowflake(tid)) == null ) continue// This member does not exist anymore. - val member = Bot.bot.kordRef.getGuildOrThrow(Snowflake(tpmd.serverID)) + val member = Bot.bot.kordRef.getGuild(Snowflake(tpmd.serverID)) .getMember(Snowflake(tid)) // Get the member if (member.roleIds.contains(Snowflake(pnrd.hasTimeRoleID))) continue // This member already has the role @@ -175,13 +175,13 @@ object AvailabilityManager : IFeature { // Check if the channel and guild already exist in the db if (!alreadyExists) { // Create the roles in Discord - val hasTimeRole = Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)).createRole { + val hasTimeRole = Bot.bot.kordRef.getGuild(Snowflake(gID)).createRole { this.name = "available [${ch.data.name.value}]" this.mentionable = true } val htr = hasTimeRole.id.value.toLong() - val wantsNotifsRole = Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)).createRole { + val wantsNotifsRole = Bot.bot.kordRef.getGuild(Snowflake(gID)).createRole { this.name = "notifications [${ch.data.name.value}]" this.mentionable = true } @@ -226,9 +226,9 @@ object AvailabilityManager : IFeature { if (PlanningNotifierRolesRepository.existsInChannelFromSever(cID, gID)) { val entry = PlanningNotifierRolesRepository.getForChannelInServer(cID, gID)!! // delete all entries for this guild and channel combo - Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)) + Bot.bot.kordRef.getGuild(Snowflake(gID)) .getRoleOrNull(Snowflake(entry.hasTimeRoleID))?.delete() - Bot.bot.kordRef.getGuildOrThrow(Snowflake(gID)) + Bot.bot.kordRef.getGuild(Snowflake(gID)) .getRoleOrNull(Snowflake(entry.wantsToBeNotifiedID))?.delete() // delete all found entries -- 2.45.2 From ea505a1395b57717f6c33de9456ca1db7465bc79 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 17 Sep 2023 13:17:14 +0200 Subject: [PATCH 099/168] chore: update README.md Signed-off-by: moonleay --- README.md | 29 ++++++++++------------------- 1 file changed, 10 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 14b1834..acb019b 100644 --- a/README.md +++ b/README.md @@ -4,10 +4,6 @@ A Discord Bot for Splatoon Teams -[![Latest Release](https://gitlab.com/moonleay/liljudd/-/badges/release.svg)](https://gitlab.com/moonleay/liljudd/-/releases) -[![pipeline status](https://gitlab.com/moonleay/liljudd/badges/master/pipeline.svg)](https://gitlab.com/moonleay/liljudd/-/commits/master) -[![License](https://img.shields.io/badge/license-GPL--3.0-brightgreen)](https://gitlab.com/moonleay/liljudd/-/blob/master/LICENSE) - ## Contributors [![Developer](https://img.shields.io/badge/moonleay-Developer-red)](https://gitlab.com/moonleay) @@ -33,36 +29,31 @@ A Discord Bot for Splatoon Teams - Rndm map command - Maybe a DSB / DSL API -## TODO - -- Rewrite the Database connection system (from transactions all over the place to a single package with transactions) - ## How to self-host (using the Docker container) -1. Pull the container +1. Pull the container from [Docker Hub](https://hub.docker.com/repository/docker/limiteddev/liljudd/general) 2. Map /data/ to a folder on disk 3. Run the Bot once -4. Follow step 4 - 7 of "How to self-host (using the JAR)" +4. follow step 4 and 5 from the JAR section +5. Run the Bot again +6. Profit. +7. ## How to self-host (using the JAR) -1. Download the latest release from the Package Registry ("Packages and registries" > "Package Registry") - 1. It should be called something like this: "lilJudd-X.X.X-xxxxxxxx-prod.jar" (replace "X.X.X" with the latest - version and xxxxxxxx" with the commit its based on.) - 2. If you want to run an early version, which may be (very) unsable, you can run a development version. Just use an - entry ending in "-dev.jar" +1. Download the latest release from the Releases page. 2. Place it anywhere you want. 3. Run the following command: - > java -jar lilJudd-X.X.X-xxxxxxxx-prod.jar + > java -jar lilJudd.jar 4. The bot should start and create a config file named "credentials.nils" in a folder called "data" 5. Open it and put in your credentials. 1. token: your Discord bot token 2. dbDomain: the domain and port of your postgresql database (e.g.: 192.168.178.1:5432) - 3. dbName: the name of your database + 3. dbName: the name of the database 4. dbUser: the username of the database - 5. dbPassword: the password to your user + 5. dbPassword: the password to the db user 6. Rerun the command - > java -jar lilJudd-X.X.X-xxxxxxxx-prod.jar + > java -jar lilJudd.jar 7. The bot should now be up and running. ## How to set up workspace -- 2.45.2 From 8c331924723cedf73a0ba2d80dd12b1f5e141aa7 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 17 Sep 2023 13:20:41 +0200 Subject: [PATCH 100/168] chore: update README.md Signed-off-by: moonleay --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index acb019b..cfc9bea 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,9 @@ "Oh boy, here we go again" ~ me -A Discord Bot for Splatoon Teams +A Discord Bot for Splatoon Teams. + +More information can be found on the [Homepage](https://moonleay.net/projects/liljudd/). ## Contributors @@ -17,9 +19,13 @@ A Discord Bot for Splatoon Teams - Commands - version -- Show the versions of the bot and the most important dependencies - feature -- Manage bot features + - match -- Create a new match + - updateroles -- Update the roles of all users + - sendplanner -- Send the planner message - Features - Time Planner -- Make the bot send messages and reactions into a selected channel in order to make planning easier - Availability Manager -- Make the bot assign users roles every day, so it is possible to notify available people + - Match Planner -- Make a match, for which players can sign up and the bot will assign teams and roles to them ## (Maybe) upcoming features @@ -37,7 +43,6 @@ A Discord Bot for Splatoon Teams 4. follow step 4 and 5 from the JAR section 5. Run the Bot again 6. Profit. -7. ## How to self-host (using the JAR) -- 2.45.2 From 76571f10e4660fce11c1d1f16f1e04e58577d190 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 17 Sep 2023 13:22:34 +0200 Subject: [PATCH 101/168] chore: update names in action.yml Signed-off-by: moonleay --- .forgejo/workflows/action.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.forgejo/workflows/action.yml b/.forgejo/workflows/action.yml index d9e4272..222014e 100644 --- a/.forgejo/workflows/action.yml +++ b/.forgejo/workflows/action.yml @@ -7,10 +7,10 @@ jobs: build-gradle-project: runs-on: ubuntu-latest steps: - - name: apt 1 + - name: apt update run: apt update - - name: apt 2 - run: apt upgrade -y + - name: apt upgrade + run: apt upgrade -y - name: install prerequisits run: apt install openjdk-17-jdk ca-certificates-java ssl-cert openssl ca-certificates -y - name: Checkout project sources @@ -22,4 +22,4 @@ jobs: - uses: actions/upload-artifact@v3 with: name: lilJudd.jar - path: build/libs/ \ No newline at end of file + path: build/libs/ -- 2.45.2 From 1cdcef209bb49b01ef08ee7e9adb27cbd25ea841 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 17 Sep 2023 13:23:13 +0200 Subject: [PATCH 102/168] Update .forgejo/workflows/action.yml --- .forgejo/workflows/action.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/action.yml b/.forgejo/workflows/action.yml index 222014e..470b719 100644 --- a/.forgejo/workflows/action.yml +++ b/.forgejo/workflows/action.yml @@ -6,7 +6,7 @@ on: jobs: build-gradle-project: runs-on: ubuntu-latest - steps: + - steps: - name: apt update run: apt update - name: apt upgrade -- 2.45.2 From 9e1a06bdd5351ea05776658be1d89477eb1e6ba6 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 17 Sep 2023 13:24:33 +0200 Subject: [PATCH 103/168] chore: update names in action.yml Signed-off-by: moonleay --- .forgejo/workflows/action.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.forgejo/workflows/action.yml b/.forgejo/workflows/action.yml index 470b719..8418c1c 100644 --- a/.forgejo/workflows/action.yml +++ b/.forgejo/workflows/action.yml @@ -6,10 +6,10 @@ on: jobs: build-gradle-project: runs-on: ubuntu-latest - - steps: - - name: apt update + steps: + - name: apt update run: apt update - - name: apt upgrade + - name: apt upgrade run: apt upgrade -y - name: install prerequisits run: apt install openjdk-17-jdk ca-certificates-java ssl-cert openssl ca-certificates -y -- 2.45.2 From 59c399d41f6677d893686cd0e262a5e4580be67d Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 18 Sep 2023 16:07:55 +0200 Subject: [PATCH 104/168] chore: moved Database stuff in /database package Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 2 +- .../lilJudd/buttons/matchplanner/AcceptEditButton.kt | 2 +- .../lilJudd/buttons/matchplanner/CancelEditButton.kt | 2 +- .../lilJudd/buttons/matchplanner/DeclineEditButton.kt | 2 +- .../net/moonleay/lilJudd/data/{ => database}/DB.kt | 10 +++++----- .../data/{ => database}/entry/MatchPlanningDataData.kt | 2 +- .../{ => database}/entry/PlanningNotifierRolesData.kt | 2 +- .../{ => database}/entry/TimePlanningChannelsData.kt | 2 +- .../{ => database}/entry/TimePlanningMessagesData.kt | 2 +- .../repository/MatchPlanningDataRepository.kt | 6 +++--- .../repository/PlanningNotifierRolesRepository.kt | 6 +++--- .../repository/TimePlanningChannelsRepository.kt | 6 +++--- .../repository/TimePlanningMessagesRepository.kt | 6 +++--- .../data/{ => database}/tables/MatchPlanningData.kt | 2 +- .../{ => database}/tables/PlanningNotifierRoles.kt | 2 +- .../data/{ => database}/tables/TimePlanningChannels.kt | 2 +- .../data/{ => database}/tables/TimePlanningMessages.kt | 2 +- .../net/moonleay/lilJudd/extensions/MatchExtension.kt | 4 ++-- .../lilJudd/extensions/SendPlannerExtension.kt | 4 ++-- .../moonleay/lilJudd/features/AvailabilityManager.kt | 8 ++++---- .../net/moonleay/lilJudd/features/MatchManager.kt | 4 ++-- .../net/moonleay/lilJudd/features/TimeManager.kt | 10 +++++----- src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt | 2 +- 23 files changed, 45 insertions(+), 45 deletions(-) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/DB.kt (83%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/entry/MatchPlanningDataData.kt (95%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/entry/PlanningNotifierRolesData.kt (95%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/entry/TimePlanningChannelsData.kt (94%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/entry/TimePlanningMessagesData.kt (95%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/repository/MatchPlanningDataRepository.kt (95%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/repository/PlanningNotifierRolesRepository.kt (95%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/repository/TimePlanningChannelsRepository.kt (92%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/repository/TimePlanningMessagesRepository.kt (93%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/tables/MatchPlanningData.kt (96%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/tables/PlanningNotifierRoles.kt (95%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/tables/TimePlanningChannels.kt (94%) rename src/main/kotlin/net/moonleay/lilJudd/data/{ => database}/tables/TimePlanningMessages.kt (95%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 750eb8c..1201560 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -33,7 +33,7 @@ import kotlinx.coroutines.launch import net.moonleay.botendo.build.BuildConstants import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager -import net.moonleay.lilJudd.data.DB +import net.moonleay.lilJudd.data.database.DB import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.features.MatchManager diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt index 115a7e5..4e04fa1 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt @@ -28,7 +28,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository +import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt index c7cebc3..348446c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt @@ -28,7 +28,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository +import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt index d775a29..93f6b36 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt @@ -28,7 +28,7 @@ import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.modify.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository +import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/DB.kt similarity index 83% rename from src/main/kotlin/net/moonleay/lilJudd/data/DB.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/DB.kt index f02009e..7c58ea0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/DB.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/DB.kt @@ -16,13 +16,13 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data +package net.moonleay.lilJudd.data.database -import net.moonleay.lilJudd.data.tables.MatchPlanningData -import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles -import net.moonleay.lilJudd.data.tables.TimePlanningChannels -import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.data.database.tables.MatchPlanningData +import net.moonleay.lilJudd.data.database.tables.PlanningNotifierRoles +import net.moonleay.lilJudd.data.database.tables.TimePlanningChannels +import net.moonleay.lilJudd.data.database.tables.TimePlanningMessages import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.SchemaUtils import org.jetbrains.exposed.sql.transactions.transaction diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/MatchPlanningDataData.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/entry/MatchPlanningDataData.kt index f48dc28..b19c5e7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/MatchPlanningDataData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/MatchPlanningDataData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.entry +package net.moonleay.lilJudd.data.database.entry data class MatchPlanningDataData( val id: Int, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/PlanningNotifierRolesData.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/entry/PlanningNotifierRolesData.kt index 730e7fe..c58130a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/PlanningNotifierRolesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/PlanningNotifierRolesData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.entry +package net.moonleay.lilJudd.data.database.entry data class PlanningNotifierRolesData( val id: Int, // The id of the entry diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningChannelsData.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningChannelsData.kt index fba9898..7edd496 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningChannelsData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningChannelsData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.entry +package net.moonleay.lilJudd.data.database.entry data class TimePlanningChannelsData( val id: Int, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningMessagesData.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningMessagesData.kt index fcb283b..3126e2c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/entry/TimePlanningMessagesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningMessagesData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.entry +package net.moonleay.lilJudd.data.database.entry data class TimePlanningMessagesData( val id: Int, // The id of the entry diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/repository/MatchPlanningDataRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/repository/MatchPlanningDataRepository.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt index 385eb69..84a1e66 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/repository/MatchPlanningDataRepository.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt @@ -16,10 +16,10 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.repository +package net.moonleay.lilJudd.data.database.repository -import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.tables.MatchPlanningData +import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.database.tables.MatchPlanningData import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/repository/PlanningNotifierRolesRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/repository/PlanningNotifierRolesRepository.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt index 2603081..4059e70 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/repository/PlanningNotifierRolesRepository.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt @@ -16,10 +16,10 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.repository +package net.moonleay.lilJudd.data.database.repository -import net.moonleay.lilJudd.data.entry.PlanningNotifierRolesData -import net.moonleay.lilJudd.data.tables.PlanningNotifierRoles +import net.moonleay.lilJudd.data.database.entry.PlanningNotifierRolesData +import net.moonleay.lilJudd.data.database.tables.PlanningNotifierRoles import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningChannelsRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningChannelsRepository.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt index 7756802..f5fd171 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningChannelsRepository.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt @@ -16,10 +16,10 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.repository +package net.moonleay.lilJudd.data.database.repository -import net.moonleay.lilJudd.data.entry.TimePlanningChannelsData -import net.moonleay.lilJudd.data.tables.TimePlanningChannels +import net.moonleay.lilJudd.data.database.entry.TimePlanningChannelsData +import net.moonleay.lilJudd.data.database.tables.TimePlanningChannels import org.jetbrains.exposed.sql.* import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningMessagesRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningMessagesRepository.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt index 5e2f273..780a939 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/repository/TimePlanningMessagesRepository.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt @@ -16,10 +16,10 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.repository +package net.moonleay.lilJudd.data.database.repository -import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.tables.TimePlanningMessages +import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData +import net.moonleay.lilJudd.data.database.tables.TimePlanningMessages import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.insert import org.jetbrains.exposed.sql.select diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/MatchPlanningData.kt similarity index 96% rename from src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/tables/MatchPlanningData.kt index e2e8afa..391b3e8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/MatchPlanningData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/MatchPlanningData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.tables +package net.moonleay.lilJudd.data.database.tables import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/PlanningNotifierRoles.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/tables/PlanningNotifierRoles.kt index e2fc9e0..66fe906 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/PlanningNotifierRoles.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/PlanningNotifierRoles.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.tables +package net.moonleay.lilJudd.data.database.tables import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningChannels.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningChannels.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningChannels.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningChannels.kt index a521838..d3b31e3 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningChannels.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningChannels.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.tables +package net.moonleay.lilJudd.data.database.tables import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningMessages.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningMessages.kt index 8f8a01b..dd48838 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/tables/TimePlanningMessages.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningMessages.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.tables +package net.moonleay.lilJudd.data.database.tables import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index 17592e6..9f2674d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -28,8 +28,8 @@ import com.kotlindiscord.kord.extensions.types.respond import dev.kord.core.behavior.channel.createMessage import dev.kord.core.behavior.createRole import dev.kord.rest.builder.message.create.actionRow -import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository +import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.extensions.component.MatchTypes import net.moonleay.lilJudd.jobs.MatchJob import net.moonleay.lilJudd.jobs.component.JobManager diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index ee85372..7b85b1d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -26,8 +26,8 @@ import dev.kord.common.entity.Permission import dev.kord.core.behavior.channel.createMessage import dev.kord.rest.builder.message.create.actionRow import kotlinx.coroutines.delay -import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.repository.TimePlanningMessagesRepository +import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData +import net.moonleay.lilJudd.data.database.repository.TimePlanningMessagesRepository import net.moonleay.lilJudd.util.* import java.time.ZoneId import java.time.ZonedDateTime diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index df88ee1..148c251 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -30,10 +30,10 @@ import dev.kord.core.entity.channel.MessageChannel import dev.kord.gateway.PrivilegedIntent import dev.kord.rest.builder.message.EmbedBuilder import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.entry.PlanningNotifierRolesData -import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.repository.PlanningNotifierRolesRepository -import net.moonleay.lilJudd.data.repository.TimePlanningMessagesRepository +import net.moonleay.lilJudd.data.database.entry.PlanningNotifierRolesData +import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData +import net.moonleay.lilJudd.data.database.repository.PlanningNotifierRolesRepository +import net.moonleay.lilJudd.data.database.repository.TimePlanningMessagesRepository import net.moonleay.lilJudd.extensions.FeatureManageExtension import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.IFeature diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt index fc89dc9..129fdc0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt @@ -20,8 +20,8 @@ package net.moonleay.lilJudd.features import dev.kord.common.entity.Snowflake import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository +import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData +import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.jobs.MatchJob import net.moonleay.lilJudd.jobs.component.JobManager import net.moonleay.lilJudd.util.Logger diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index d986440..ec073ac 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -29,11 +29,11 @@ import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.builder.message.create.actionRow import kotlinx.coroutines.delay import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.entry.TimePlanningChannelsData -import net.moonleay.lilJudd.data.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.repository.PlanningNotifierRolesRepository -import net.moonleay.lilJudd.data.repository.TimePlanningChannelsRepository -import net.moonleay.lilJudd.data.repository.TimePlanningMessagesRepository +import net.moonleay.lilJudd.data.database.entry.TimePlanningChannelsData +import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData +import net.moonleay.lilJudd.data.database.repository.PlanningNotifierRolesRepository +import net.moonleay.lilJudd.data.database.repository.TimePlanningChannelsRepository +import net.moonleay.lilJudd.data.database.repository.TimePlanningMessagesRepository import net.moonleay.lilJudd.extensions.FeatureManageExtension import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.IFeature diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt index 8360f62..6f13dfa 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt @@ -22,7 +22,7 @@ import dev.inmo.krontab.KronScheduler import dev.kord.common.entity.Snowflake import kotlinx.coroutines.Job import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.repository.MatchPlanningDataRepository +import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.jobs.component.CronjobType import net.moonleay.lilJudd.jobs.component.ICronjob import net.moonleay.lilJudd.jobs.component.JobManager -- 2.45.2 From 11cc32ce72d043c8ad15d537662079868bb83fbf Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 26 Sep 2023 07:43:37 +0200 Subject: [PATCH 105/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index a90bf54..34a37f1 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.5.6" + ?: "2.6.0" val kordver = "1.5.9-SNAPSHOT" val coroutinesver = "1.7.3" @@ -103,8 +103,8 @@ dependencies { //Korntab shadow("dev.inmo:krontab:$krontabver") - "shadow"("io.ktor:ktor-client-core-jvm:2.3.4") - "shadow"("io.ktor:ktor-client-cio-jvm:2.3.4") + shadow("io.ktor:ktor-client-core-jvm:2.3.4") + shadow("io.ktor:ktor-client-cio-jvm:2.3.4") } -- 2.45.2 From 984c9653d95b3613f7644dcd6cf43daea84a3b60 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 26 Sep 2023 07:43:56 +0200 Subject: [PATCH 106/168] chore: upgrade crontab Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 34a37f1..bb2560b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -39,7 +39,7 @@ val coroutinesver = "1.7.3" val ktor_version = "2.3.4" val exposedver = "0.43.0" val postgresver = "42.6.0" -val krontabver = "2.2.0" +val krontabver = "2.2.1" val mavenArtifact = "lilJudd" project.base.archivesName.set(mavenArtifact) -- 2.45.2 From 028e566c70179da76829e4a900ac7ecae16bbcc3 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 10:29:27 +0200 Subject: [PATCH 107/168] fix: fixed issues with timestamps Signed-off-by: moonleay --- .../lilJudd/extensions/MatchExtension.kt | 2 +- .../extensions/SendPlannerExtension.kt | 2 +- .../lilJudd/features/AvailabilityManager.kt | 23 +++++++++++-------- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index 9f2674d..ff47b9b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -108,7 +108,7 @@ class MatchExtension : Extension() { role.id.value.toLong(), opponent, msg.id.value.toLong(), - (zdt.toEpochSecond() * 1000), + (zdt.toEpochSecond()), jobString ) ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index 7b85b1d..781de2c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -105,7 +105,7 @@ class SendPlannerExtension : Extension() { -1, c.data.guildId.value?.value!!.toLong(), c.id.value.toLong(), - (TimeUtil.getWeekStamp().toEpochSecond() * 1000), + (TimeUtil.getWeekStamp().toEpochSecond()), msgStr ) ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt index 148c251..cc49d1c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt @@ -47,18 +47,21 @@ object AvailabilityManager : IFeature { Logger.out("Starting to update roles...") // ChannelID, Data - val messages = TimePlanningMessagesRepository.getWeek(TimeUtil.getWeekStamp().toEpochSecond() * 1000) + val messages = TimePlanningMessagesRepository.getWeek(TimeUtil.getWeekStamp().toEpochSecond()) .associateBy { it.channelID } val targetedRoles = PlanningNotifierRolesRepository.getAll().associateBy { it.channelID } + if (targetedRoles.isEmpty()) { + Logger.out("No saved roles. Canceling.") + return + } for (id in messages.keys) { val snf = Snowflake(id) // snf = Snowflake val data = messages[id]!! // this is the data of the table - if (Bot.bot.kordRef.getChannel(Snowflake(data.channelID)) == null) - continue // This channel does not exist anymore. - if (targetedRoles.isEmpty()) { - Logger.out("No saved roles. Canceling.") - return + if (Bot.bot.kordRef.getChannel(Snowflake(data.channelID)) == null) { + // This channel does not exist anymore. + Logger.out("Warning: Channel ${data.channelID} does not exist anymore. Skipping.") + continue } val roleData = targetedRoles[data.channelID] // Get the role data if (roleData == null) { @@ -71,15 +74,17 @@ object AvailabilityManager : IFeature { } suspend fun updateInChannel(snf: Snowflake) { + val stamp = TimeUtil.getWeekStamp().toEpochSecond() + Logger.out("Weekstamp: $stamp") val messageData = TimePlanningMessagesRepository.getWeekInChannel( - TimeUtil.getWeekStamp().toEpochSecond() * 1000, + stamp, snf.value.toLong() ) - val roleData = PlanningNotifierRolesRepository.getForChannel(snf.value.toLong()) if (messageData == null) { Logger.out("Could not find data for channel ${snf.value}") return } + val roleData = PlanningNotifierRolesRepository.getForChannel(snf.value.toLong()) if (roleData == null) { Logger.out("Role for channel ${messageData.channelID} does not exist") return // this took way to long to find out that this was the issue @@ -93,7 +98,7 @@ object AvailabilityManager : IFeature { return // This channel does not exist anymore. val c = Bot.bot.kordRef.getChannelOf(snf)!! // Get the channel as MessageChannel val weekday = ZonedDateTime.now().dayOfWeek // The current week day - val weekStamp = TimeUtil.getWeekStamp().toEpochSecond() * 1000 // The current week time stamp + val weekStamp = TimeUtil.getWeekStamp().toEpochSecond() // The current week time stamp Logger.out("It is week ${weekStamp} and day ${weekday}/${TimeUtil.getDayOfMonthInt(weekday)} of the week.") val g = Bot.bot.kordRef.getGuild(Snowflake(tpmd.serverID)) // Get all members with the role -- 2.45.2 From 06edbb9288b1f1fa5b3e0e98d3ed287ae7a0d37e Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:38:14 +0200 Subject: [PATCH 108/168] feat: added Splatoon3.ink API Signed-off-by: moonleay --- .../moonleay/lilJudd/data/api/Splatoon3Api.kt | 117 ++++ .../lilJudd/data/api/Splatoon3ApiCache.kt | 535 ++++++++++++++++++ .../data/api/entry/coop/CoopGearData.kt | 28 + .../api/entry/schedule/ChallengeModeData.kt | 34 ++ .../data/api/entry/schedule/MapData.kt | 27 + .../data/api/entry/schedule/ModeData.kt | 30 + .../data/api/entry/schedule/ShiftData.kt | 34 ++ .../data/api/entry/schedule/TimePeriodData.kt | 24 + .../data/api/entry/schedule/WeaponData.kt | 26 + .../api/entry/splatfest/SplatfestColor.kt | 26 + .../data/api/entry/splatfest/SplatfestData.kt | 33 ++ .../api/entry/splatfest/SplatfestTeamData.kt | 25 + .../entry/splatfest/SplatfestTeamResults.kt | 33 ++ .../data/api/entry/splatnet/BrandData.kt | 28 + .../api/entry/splatnet/GearAbilityData.kt | 27 + .../api/entry/splatnet/SplatnetItemData.kt | 32 ++ .../lilJudd/data/api/type/ApiDataType.kt | 27 + .../lilJudd/data/api/type/ApiRequestType.kt | 26 + 18 files changed, 1112 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/coop/CoopGearData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ChallengeModeData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/MapData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ModeData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ShiftData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/TimePeriodData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/WeaponData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestColor.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamResults.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/BrandData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/GearAbilityData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/SplatnetItemData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiDataType.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiRequestType.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt new file mode 100644 index 0000000..b0192e5 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt @@ -0,0 +1,117 @@ +/* + * 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.api + +import net.moonleay.lilJudd.data.api.entry.schedule.ModeData +import net.moonleay.lilJudd.util.TimeUtil + +object Splatoon3Api { + private fun getRegularMode(timestamp: Long): ModeData { + Splatoon3ApiCache.cachedRegularModeData.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + return modeData + } + } + throw Exception("No current mode found") + } + + private fun getOpenMode(timestamp: Long): ModeData { + Splatoon3ApiCache.cachedCompetitiveOpenModeData.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + return modeData + } + } + throw Exception("No current mode found") + } + + private fun getXMode(timestamp: Long): ModeData { + Splatoon3ApiCache.cachedXModeData.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + return modeData + } + } + throw Exception("No current mode found") + } + + private fun getSeriesMode(timestamp: Long): ModeData { + Splatoon3ApiCache.cachedCompetitiveSeriesModeData.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + return modeData + } + } + throw Exception("No current mode found") + } + + fun getRegularMapsFormatted(timestamp: Long): String { + val modeData = getRegularMode(timestamp) + val map1 = modeData.map1!!.name.split(" ")[0] + val map2 = modeData.map2!!.name.split(" ")[0] + return "R: $map1 & $map2" + } + + fun getOpenModeFormatted(timestamp: Long): String { + val modeData = getOpenMode(timestamp) + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) + return "O: ${modeData.ruleSetName} $diffStamp left" + } + + fun getOpenMapFormatted(timestamp: Long): String { + val modeData = getOpenMode(timestamp) + val map1 = modeData.map1!!.name.split(" ")[0] + val map2 = modeData.map2!!.name.split(" ")[0] + return "O: $map1 & $map2" + } + + fun getSeriesModeFormatted(timestamp: Long): String { + val modeData = getSeriesMode(timestamp) + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) + return "S: ${modeData.ruleSetName} $diffStamp left" + } + + fun getSeriesMapsFormatted(timestamp: Long): String { + val modeData = getSeriesMode(timestamp) + val map1 = modeData.map1!!.name.split(" ")[0] + val map2 = modeData.map2!!.name.split(" ")[0] + return "S: $map1 & $map2" + } + + fun getXModeFormatted(timestamp: Long): String { + val modeData = getXMode(timestamp) + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) + return "X: ${modeData.ruleSetName} $diffStamp left" + } + + fun getXMapFormatted(timestamp: Long): String { + val modeData = getXMode(timestamp) + val map1 = modeData.map1!!.name.split(" ")[0] + val map2 = modeData.map2!!.name.split(" ")[0] + return "X: $map1 & $map2" + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt new file mode 100644 index 0000000..42ff01c --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt @@ -0,0 +1,535 @@ +/* + * 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.api + +import io.ktor.http.* +import kotlinx.serialization.json.* +import net.moonleay.botendo.build.BuildConstants +import net.moonleay.lilJudd.data.api.entry.coop.CoopGearData +import net.moonleay.lilJudd.data.api.entry.schedule.* +import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestColor +import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestData +import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestTeamData +import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestTeamResults +import net.moonleay.lilJudd.data.api.entry.splatnet.BrandData +import net.moonleay.lilJudd.data.api.entry.splatnet.GearAbilityData +import net.moonleay.lilJudd.data.api.entry.splatnet.SplatnetItemData +import net.moonleay.lilJudd.data.api.type.ApiDataType +import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.util.Logger +import net.moonleay.lilJudd.util.NetUtil + +object Splatoon3ApiCache { + private val user_agent = + "lilJudd/${BuildConstants.version} (${System.getProperty("os.name")}/${System.getProperty("os.version")}) [contact@moonleay.net]" + private val base_url = "https://splatoon3.ink/data/" // Thank god there is an API + + internal var cachedSplatfestData = mutableListOf() + internal var cachedMapData = mutableMapOf() + internal var cachedRegularModeData = mutableListOf() + internal var cachedCompetitiveSeriesModeData = mutableListOf() + internal var cachedCompetitiveOpenModeData = mutableListOf() + internal var cachedXModeData = mutableListOf() + internal var cachedChallengesData = mutableListOf() + internal var cachedShiftData = mutableListOf() + internal var cachedBigRunShiftData = mutableListOf() + internal var cachedCoopRewardsData = mutableListOf() + internal var cachedSplatnetItemData = mutableListOf() + internal var cachedSplatnetLimitedItemData = mutableListOf() + internal lateinit var splatnetShopBrandData: BrandData + internal lateinit var splatnetShopNextBrandData: BrandData + fun updateData(dataType: ApiDataType, requestType: ApiRequestType) { + Logger.out("Updating data for $dataType with USER-AGENT: $user_agent") + Logger.out("Reason for update: $requestType") + when (dataType) { + ApiDataType.SCHEDULES -> { + updateScheduleCache(user_agent) + } + + ApiDataType.SPLATNETGEAR -> { + updateSplatnetGearCache(user_agent) + } + + ApiDataType.COOP -> { + updateCOOPCache(user_agent) + } + + ApiDataType.SPLATFESTS -> { + updateSplatfestCache(user_agent) + } + + ApiDataType.ALL -> { + updateScheduleCache(user_agent) + updateSplatnetGearCache(user_agent) + updateSplatfestCache(user_agent) + updateCOOPCache(user_agent) + } + } + Logger.out("Finished updating data for $dataType") + } + + private fun updateSplatnetGearCache(uag: String) { + val apiResponse = NetUtil.GETJsonData("${base_url}gear.json", uag) + if (apiResponse.startsWith("Error")) { + Logger.out("Error getting splatnet data: $apiResponse") + return + } + val json = Json.parseToJsonElement(apiResponse) + val pickupBrandData = json.jsonObject["data"]!!.jsonObject["gesotown"]!!.jsonObject["pickupBrand"]!!.jsonObject + + val brand = pickupBrandData["brand"]!!.jsonObject + splatnetShopBrandData = + BrandData( + brand["name"]!!.jsonPrimitive.content, + Url(pickupBrandData["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + GearAbilityData( + brand["usualGearPower"]!!.jsonObject["name"]!!.jsonPrimitive.content, + brand["usualGearPower"]!!.jsonObject["desc"]!!.jsonPrimitive.content, + Url(brand["usualGearPower"]!!.jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + pickupBrandData["saleEndTime"]!!.jsonPrimitive.content + ) + val nextBrand = pickupBrandData["nextBrand"]!!.jsonObject + splatnetShopNextBrandData = + BrandData( + nextBrand["name"]!!.jsonPrimitive.content, + Url(pickupBrandData["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + null, + null + ) + cachedSplatnetItemData = mutableListOf() + val items = pickupBrandData["brandGears"]!!.jsonArray + items.forEach { + val obj = it as JsonObject + val gear = it["gear"]!!.jsonObject + val primaryGearPower = gear["primaryGearPower"]!!.jsonObject + val additionalGearPowers = gear["additionalGearPowers"]!!.jsonArray + val additionalGearPowersList = mutableListOf() + additionalGearPowers.forEach { + val ob = it as JsonObject + additionalGearPowersList.add( + GearAbilityData( + ob["name"]!!.jsonPrimitive.content, + null, + Url(ob["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ) + ) + } + cachedSplatnetItemData.add( + SplatnetItemData( + obj["saleEndTime"]!!.jsonPrimitive.content, + obj["price"]!!.jsonPrimitive.int, + gear["__typename"]!!.jsonPrimitive.content, + gear["name"]!!.jsonPrimitive.content, + GearAbilityData( + primaryGearPower["name"]!!.jsonPrimitive.content, + null, + Url(primaryGearPower["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + additionalGearPowersList, + Url(gear["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + splatnetShopBrandData + ) + ) + } + Logger.out("Updated gear data") + + val limitedItemData = json.jsonObject["data"]!!.jsonObject["gesotown"]!!.jsonObject["limitedGears"]!!.jsonArray + cachedSplatnetLimitedItemData = mutableListOf() + limitedItemData.forEach { + val obj = it as JsonObject + val gear = obj["gear"]!!.jsonObject + val additionalGearPowers = gear["additionalGearPowers"]!!.jsonArray + val additionalGearPowersList = mutableListOf() + additionalGearPowers.forEach { + val ob = it as JsonObject + additionalGearPowersList.add( + GearAbilityData( + ob["name"]!!.jsonPrimitive.content, + null, + Url(ob["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ) + ) + } + cachedSplatnetLimitedItemData.add( + SplatnetItemData( + obj["saleEndTime"]!!.jsonPrimitive.content, + obj["price"]!!.jsonPrimitive.int, + gear["__typename"]!!.jsonPrimitive.content, + gear["name"]!!.jsonPrimitive.content, + GearAbilityData( + gear["primaryGearPower"]!!.jsonObject["name"]!!.jsonPrimitive.content, + null, + Url(gear["primaryGearPower"]!!.jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + additionalGearPowersList, + Url(gear["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + splatnetShopBrandData + ) + ) + } + } + + private fun updateCOOPCache(uag: String) { + val apiResponse = NetUtil.GETJsonData("${base_url}coop.json", uag) + if (apiResponse.startsWith("Error")) { + Logger.out("Error getting coop data: $apiResponse") + return + } + val json = Json.parseToJsonElement(apiResponse) + val data = json.jsonObject["data"]!!.jsonObject["coopResult"]!!.jsonObject["monthlyGear"]!!.jsonObject + cachedCoopRewardsData = mutableListOf() + cachedCoopRewardsData.add( + CoopGearData( + data["name"]!!.jsonPrimitive.content, + Url(data["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + data["__typename"]!!.jsonPrimitive.content + ) + ) + Logger.out("Updated COOP data") + } + + private fun updateScheduleCache(uag: String) { + val apiResponse = NetUtil.GETJsonData("${base_url}schedules.json", uag) + if (apiResponse.startsWith("Error")) { + Logger.out("Error getting schedule data: $apiResponse") + return + } + val json = Json.decodeFromString(apiResponse) as JsonObject + val data = json["data"]!!.jsonObject + + val mapList = data["vsStages"]!!.jsonObject["nodes"]!!.jsonArray + cachedMapData = mutableMapOf() + mapList.forEach { + val obj = it as JsonObject + val imageURL = Url(obj.jsonObject["originalImage"]!!.jsonObject["url"]!!.jsonPrimitive.content) + val id = obj.jsonObject["vsStageId"]!!.jsonPrimitive.int + cachedMapData[id] = MapData( + id, + imageURL, + it.jsonObject["name"]!!.jsonPrimitive.content + ) + } + Logger.out("Updated maplist data") + + val regularMatches = data["regularSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedRegularModeData = mutableListOf() + regularMatches.forEach { + val obj = it as JsonObject + val setting = obj["regularMatchSetting"]!!.jsonObject + cachedRegularModeData.add( + ModeData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + setting["__typename"]!!.jsonPrimitive.content, + cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + "TURF_WAR" + ) + ) + } + Logger.out("Updated Regular match data") + + val compMatches = data["bankaraSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedCompetitiveSeriesModeData = mutableListOf() + cachedCompetitiveOpenModeData = mutableListOf() + compMatches.forEach { + val obj = it as JsonObject + val setting = obj["bankaraMatchSettings"]!!.jsonArray + setting.forEach { + val ob = it as JsonObject + val mode = ob["bankaraMode"]!!.jsonPrimitive.content + if (mode == "CHALLENGE") { + cachedCompetitiveSeriesModeData.add( + ModeData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + ob["__typename"]!!.jsonPrimitive.content, + cachedMapData[ob["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[ob["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + ob["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + ob["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + mode + ) + ) + } else if (mode == "OPEN") { + cachedCompetitiveOpenModeData.add( + ModeData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + ob["__typename"]!!.jsonPrimitive.content, + cachedMapData[ob["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[ob["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + ob["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + ob["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + mode + ) + ) + } + } + } + Logger.out("Updated Competitive match data") + + val xMatches = data["xSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedXModeData = mutableListOf() + xMatches.forEach { + val obj = it as JsonObject + val setting = obj["xMatchSetting"]!!.jsonObject + cachedXModeData.add( + ModeData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + setting["__typename"]!!.jsonPrimitive.content, + cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + "X" + ) + ) + } + Logger.out("Updated X match data") + + val challengeData = data["eventSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedChallengesData = mutableListOf() + challengeData.forEach { + val obj = it as JsonObject + val tpd = obj["timePeriods"]!!.jsonArray + val setting = obj["leagueMatchSetting"]!!.jsonObject + val event = setting["leagueMatchEvent"]!!.jsonObject + cachedChallengesData.add( + ChallengeModeData( + event["leagueMatchEventId"]!!.jsonPrimitive.content, + event["name"]!!.jsonPrimitive.content, + event["desc"]!!.jsonPrimitive.content, + event["regulation"]!!.jsonPrimitive.content, + cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + setting["__typename"]!!.jsonPrimitive.content, + setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + TimePeriodData( + tpd[0].jsonObject["startTime"]!!.jsonPrimitive.content, + tpd[0].jsonObject["endTime"]!!.jsonPrimitive.content + ), + TimePeriodData( + tpd[1].jsonObject["startTime"]!!.jsonPrimitive.content, + tpd[1].jsonObject["endTime"]!!.jsonPrimitive.content + ), + TimePeriodData( + tpd[2].jsonObject["startTime"]!!.jsonPrimitive.content, + tpd[2].jsonObject["endTime"]!!.jsonPrimitive.content + ) + ) + ) + } + Logger.out("Updated Challenge data") + + val shiftData = data["coopGroupingSchedule"]!!.jsonObject["regularSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedShiftData = mutableListOf() + shiftData.forEach { + val obj = it as JsonObject + val setting = obj["setting"]!!.jsonObject + val stage = setting["coopStage"]!!.jsonObject + val weapons = setting["weapons"]!!.jsonArray + cachedShiftData.add( + ShiftData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + obj["__splatoon3ink_king_salmonid_guess"]!!.jsonPrimitive.content, + setting["__typename"]!!.jsonPrimitive.content, + stage["name"]!!.jsonPrimitive.content, + Url(stage["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + WeaponData( + weapons[0].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[0].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[1].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[1].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[2].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[2].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[3].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[3].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ) + ) + ) + } + + val bigRunData = data["coopGroupingSchedule"]!!.jsonObject["bigRunSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedBigRunShiftData = mutableListOf() + bigRunData.forEach { + val obj = it as JsonObject + val setting = obj["setting"]!!.jsonObject + val stage = setting["coopStage"]!!.jsonObject + val weapons = setting["weapons"]!!.jsonArray + cachedBigRunShiftData.add( + ShiftData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + obj["__splatoon3ink_king_salmonid_guess"]!!.jsonPrimitive.content, + setting["__typename"]!!.jsonPrimitive.content, + stage["name"]!!.jsonPrimitive.content, + Url(stage["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + WeaponData( + weapons[0].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[0].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[1].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[1].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[2].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[2].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[3].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[3].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ) + ) + ) + } + Logger.out("Updated big run data") + + Logger.out("Updated all Schedules") + } + + private fun updateSplatfestCache(uag: String) { + val apiResponse = NetUtil.GETJsonData("${base_url}festivals.json", uag) + if (apiResponse.startsWith("Error")) { + Logger.out("Error getting splatfest data: $apiResponse") + return + } + val json = Json.decodeFromString(apiResponse) as JsonObject + val festivals = json["US"]!!.jsonObject["data"]!!.jsonObject["festRecords"]!!.jsonObject["nodes"]!!.jsonArray + cachedSplatfestData = mutableListOf() + festivals.forEach { + val fest = it as JsonObject + val teams = fest.jsonObject["teams"]!!.jsonArray + val team1 = teams[0].jsonObject + val team1Color = team1["color"]!!.jsonObject + var team1Result: JsonObject? = null + if (team1["result"] !is JsonNull) { + team1Result = team1["result"]!!.jsonObject + } + val team2 = teams[1].jsonObject + val team2Color = team2["color"]!!.jsonObject + var team2Result: JsonObject? = null + if (team2["result"] !is JsonNull) { + team2Result = team2["result"]!!.jsonObject + } + val team3 = teams[2].jsonObject + val team3Color = team3["color"]!!.jsonObject + var team3Result: JsonObject? = null + if (team3["result"] !is JsonNull) { + team3Result = team3["result"]!!.jsonObject + } + cachedSplatfestData.add( + SplatfestData( + fest.jsonObject["id"]!!.jsonPrimitive.content, + fest.jsonObject["state"]!!.jsonPrimitive.content, + fest.jsonObject["startTime"]!!.jsonPrimitive.content, + fest.jsonObject["endTime"]!!.jsonPrimitive.content, + fest.jsonObject["title"]!!.jsonPrimitive.content, + Url(fest.jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + SplatfestTeamData( + team1["teamName"]!!.jsonPrimitive.content, + SplatfestColor( + team1Color["a"]!!.jsonPrimitive.int, + team1Color["b"]!!.jsonPrimitive.double, + team1Color["g"]!!.jsonPrimitive.double, + team1Color["r"]!!.jsonPrimitive.double + ), + if (team1Result.isNullOrEmpty() || team1Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) + null + else SplatfestTeamResults( + team1Result["isWinner"]!!.jsonPrimitive.boolean, + team1Result["horagaiRatio"]!!.jsonPrimitive.double, + team1Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, + team1Result["voteRatio"]!!.jsonPrimitive.double, + team1Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, + team1Result["regularContributionRatio"]!!.jsonPrimitive.double, + team1Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, + team1Result["challengeContributionRatio"]!!.jsonPrimitive.double, + team1Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, + team1Result["tricolorContributionRatio"]!!.jsonPrimitive.double, + team1Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, + ) + ), + SplatfestTeamData( + team2["teamName"]!!.jsonPrimitive.content, + SplatfestColor( + team2Color["a"]!!.jsonPrimitive.int, + team2Color["b"]!!.jsonPrimitive.double, + team2Color["g"]!!.jsonPrimitive.double, + team2Color["r"]!!.jsonPrimitive.double + ), + if (team2Result.isNullOrEmpty() || team2Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) + null + else SplatfestTeamResults( + team2Result["isWinner"]!!.jsonPrimitive.boolean, + team2Result["horagaiRatio"]!!.jsonPrimitive.double, + team2Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, + team2Result["voteRatio"]!!.jsonPrimitive.double, + team2Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, + team2Result["regularContributionRatio"]!!.jsonPrimitive.double, + team2Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, + team2Result["challengeContributionRatio"]!!.jsonPrimitive.double, + team2Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, + team2Result["tricolorContributionRatio"]!!.jsonPrimitive.double, + team2Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, + ) + ), + SplatfestTeamData( + team3["teamName"]!!.jsonPrimitive.content, + SplatfestColor( + team3Color["a"]!!.jsonPrimitive.int, + team3Color["b"]!!.jsonPrimitive.double, + team3Color["g"]!!.jsonPrimitive.double, + team3Color["r"]!!.jsonPrimitive.double + ), + if (team3Result.isNullOrEmpty() || team3Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) + null + else SplatfestTeamResults( + team3Result["isWinner"]!!.jsonPrimitive.boolean, + team3Result["horagaiRatio"]!!.jsonPrimitive.double, + team3Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, + team3Result["voteRatio"]!!.jsonPrimitive.double, + team3Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, + team3Result["regularContributionRatio"]!!.jsonPrimitive.double, + team3Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, + team3Result["challengeContributionRatio"]!!.jsonPrimitive.double, + team3Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, + team3Result["tricolorContributionRatio"]!!.jsonPrimitive.double, + team3Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, + ) + ), + ) + ) + } + Logger.out("Updated Splatfest data") + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/coop/CoopGearData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/coop/CoopGearData.kt new file mode 100644 index 0000000..4f46642 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/coop/CoopGearData.kt @@ -0,0 +1,28 @@ +/* + * 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.api.entry.coop + +import io.ktor.http.* + +data class CoopGearData( + val name: String, + val image: Url, + val __typename: String, + + ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ChallengeModeData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ChallengeModeData.kt new file mode 100644 index 0000000..c288fe9 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ChallengeModeData.kt @@ -0,0 +1,34 @@ +/* + * 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.api.entry.schedule + +data class ChallengeModeData( + val leagueMatchEventId: String, + val name: String, + val description: String, + val regulation: String, + val map1: MapData?, + val map2: MapData?, + val __typename: String, + val ruleSet: String, + val ruleSetName: String, + val timePeriod1: TimePeriodData, + val timePeriod2: TimePeriodData, + val timePeriod3: TimePeriodData, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/MapData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/MapData.kt new file mode 100644 index 0000000..422783c --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/MapData.kt @@ -0,0 +1,27 @@ +/* + * 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.api.entry.schedule + +import io.ktor.http.* + +data class MapData( + val stageID: Int, + val image: Url, + val name: String, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ModeData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ModeData.kt new file mode 100644 index 0000000..8295a1a --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ModeData.kt @@ -0,0 +1,30 @@ +/* + * 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.api.entry.schedule + +data class ModeData( + val startTime: String, + val endTime: String, + val matchType: String, + val map1: MapData?, + val map2: MapData?, + val ruleSetName: String, + val ruleSet: String, + val mode: String, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ShiftData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ShiftData.kt new file mode 100644 index 0000000..a4d28ae --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ShiftData.kt @@ -0,0 +1,34 @@ +/* + * 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.api.entry.schedule + +import io.ktor.http.* + +data class ShiftData( + val startTime: String, + val endTime: String, + val __splatoon3ink_king_salmonid_guess: String, + val __typename: String, + val stageName: String, + val image: Url, + val weapon1: WeaponData, + val weapon2: WeaponData, + val weapon3: WeaponData, + val weapon4: WeaponData, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/TimePeriodData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/TimePeriodData.kt new file mode 100644 index 0000000..53edb96 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/TimePeriodData.kt @@ -0,0 +1,24 @@ +/* + * 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.api.entry.schedule + +data class TimePeriodData( + val startTime: String, + val endTime: String, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/WeaponData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/WeaponData.kt new file mode 100644 index 0000000..997a24b --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/WeaponData.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.api.entry.schedule + +import io.ktor.http.* + +data class WeaponData( + val name: String, + val image: Url, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestColor.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestColor.kt new file mode 100644 index 0000000..391ccb3 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestColor.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.api.entry.splatfest + +data class SplatfestColor( + val a: Int, + val b: Double, + val g: Double, + val r: Double, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestData.kt new file mode 100644 index 0000000..f52b9b4 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestData.kt @@ -0,0 +1,33 @@ +/* + * 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.api.entry.splatfest + +import io.ktor.http.* + +data class SplatfestData( + val id: String, + val state: String, + val startTime: String, + val endTime: String, + val title: String, + val image: Url, + val team1: SplatfestTeamData, + val team2: SplatfestTeamData, + val team3: SplatfestTeamData, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamData.kt new file mode 100644 index 0000000..9ea2e72 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamData.kt @@ -0,0 +1,25 @@ +/* + * 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.api.entry.splatfest + +data class SplatfestTeamData( + val teamName: String, + val color: SplatfestColor, + val results: SplatfestTeamResults?, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamResults.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamResults.kt new file mode 100644 index 0000000..4888adc --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamResults.kt @@ -0,0 +1,33 @@ +/* + * 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.api.entry.splatfest + +data class SplatfestTeamResults( + val isWinner: Boolean, + val horagaiRatio: Double, + val horagaiRatioTop: Boolean, + val voteRatio: Double, + val voteRatioTop: Boolean, + val regularRatio: Double, + val regularRatioTop: Boolean, + val challengeRatio: Double, + val challengeRatioTop: Boolean, + val tricolorRatio: Double, + val tricolorRatioTop: Boolean, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/BrandData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/BrandData.kt new file mode 100644 index 0000000..6781172 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/BrandData.kt @@ -0,0 +1,28 @@ +/* + * 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.api.entry.splatnet + +import io.ktor.http.* + +data class BrandData( + val name: String, + val image: Url, + val usualGearPower: GearAbilityData?, + val saleEndTime: String?, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/GearAbilityData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/GearAbilityData.kt new file mode 100644 index 0000000..713d946 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/GearAbilityData.kt @@ -0,0 +1,27 @@ +/* + * 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.api.entry.splatnet + +import io.ktor.http.* + +data class GearAbilityData( + val name: String, + val description: String?, + val image: Url, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/SplatnetItemData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/SplatnetItemData.kt new file mode 100644 index 0000000..43df20b --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/SplatnetItemData.kt @@ -0,0 +1,32 @@ +/* + * 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.api.entry.splatnet + +import io.ktor.http.* + +data class SplatnetItemData( + val saleEndTime: String, + val price: Int, + val typeName: String, + val name: String, + val primaryGearPower: GearAbilityData, + val additionalGearPowers: List, + val image: Url, + val brand: BrandData, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiDataType.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiDataType.kt new file mode 100644 index 0000000..7123b0d --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiDataType.kt @@ -0,0 +1,27 @@ +/* + * 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.api.type + +enum class ApiDataType { + SCHEDULES, + SPLATNETGEAR, + COOP, + SPLATFESTS, + ALL +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiRequestType.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiRequestType.kt new file mode 100644 index 0000000..da20371 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiRequestType.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.api.type + +enum class ApiRequestType(val nameToDisplay: String) { + AUTOMATIC_CACHE_UPDATE("automatic request to update the cache"), + AUTOMATIC_CACHE_CREATION_AT_STARTUP("automatic request to create cache at startup"), + MANUAL("manual request"), + DEBUG("debug request") +} -- 2.45.2 From 886d8917878334e12d6b2fefba1e6179c704ce95 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:38:34 +0200 Subject: [PATCH 109/168] chore: added credits for the provided data Signed-off-by: moonleay --- .../extensions/{VersionExtension.kt => InfoExtension.kt} | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) rename src/main/kotlin/net/moonleay/lilJudd/extensions/{VersionExtension.kt => InfoExtension.kt} (89%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/VersionExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt similarity index 89% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/VersionExtension.kt rename to src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt index 3554f72..ff5a61a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/VersionExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt @@ -24,11 +24,11 @@ import net.moonleay.botendo.build.BuildConstants import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.MessageUtil -class VersionExtension : Extension() { - override val name = "version" +class InfoExtension : Extension() { + override val name = "info" override suspend fun setup() { publicSlashCommand { - name = "version" + name = "info" description = "Show infos about the bot" this.action { MessageUtil.sendEmbedForPublicSlashCommand( @@ -38,7 +38,8 @@ class VersionExtension : Extension() { "Lil' Judd ***v." + BuildConstants.version + "***\n" + "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" + "Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n" + - "Krontab ***v." + BuildConstants.krontabVersion + "***" + "Krontab ***v." + BuildConstants.krontabVersion + "***\n\n" + + "Splatoon 3 api data provided by splatoon3.ink" ) } } -- 2.45.2 From 1c17a5d2beceec8ef4184362043883a69d1fc5f1 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:39:23 +0200 Subject: [PATCH 110/168] feat: added cacheUpdateJobs Signed-off-by: moonleay --- ...atoon3ApiFestivalAndCoopUpdateScheduler.kt | 50 +++++++++++++++++++ .../Splatoon3ApiScheduleUpdateScheduler.kt | 48 ++++++++++++++++++ ...Splatoon3ApiSplatnetGearUpdateScheduler.kt | 47 +++++++++++++++++ 3 files changed, 145 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt new file mode 100644 index 0000000..8e05cb1 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt @@ -0,0 +1,50 @@ +/* + * 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.jobs + +import dev.inmo.krontab.KronScheduler +import kotlinx.coroutines.Job +import net.moonleay.lilJudd.data.api.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.type.ApiDataType +import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.jobs.component.CronjobType +import net.moonleay.lilJudd.jobs.component.ICronjob +import net.moonleay.lilJudd.util.Logger + +object Splatoon3ApiFestivalAndCoopUpdateScheduler : ICronjob { + override val jobName: String + get() = "Splatoon3ApiFestivalAndCoopUpdateScheduler" + override val jobIncoming: String + get() = "0 0 0 /1 *" // once a day + override val jobType: CronjobType + get() = CronjobType.INFINITE + override val continueJob: Boolean + get() = true + override lateinit var cronjobJob: Job + override lateinit var scheduler: KronScheduler + + override suspend fun jobFunction() { + Logger.out("Running Splatoon3ApiFestivalUpdateScheduler.") + Splatoon3ApiCache.updateData(ApiDataType.SPLATFESTS, ApiRequestType.AUTOMATIC_CACHE_UPDATE) + Logger.out("Splatoon3ApiFestivalUpdateScheduler finished.") + Logger.out("Running Splatoon3ApiCoopUpdateScheduler.") + Splatoon3ApiCache.updateData(ApiDataType.COOP, ApiRequestType.AUTOMATIC_CACHE_UPDATE) + Logger.out("Splatoon3ApiCoopUpdateScheduler finished.") + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt new file mode 100644 index 0000000..70d7c58 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt @@ -0,0 +1,48 @@ +/* + * 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.jobs + +import dev.inmo.krontab.KronScheduler +import kotlinx.coroutines.Job +import net.moonleay.lilJudd.data.api.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.type.ApiDataType +import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.jobs.component.CronjobType +import net.moonleay.lilJudd.jobs.component.ICronjob +import net.moonleay.lilJudd.util.Logger + +object Splatoon3ApiScheduleUpdateScheduler : ICronjob { + override val jobName: String + get() = "Splatoon3ApiScheduleUpdateScheduler" + override val jobIncoming: String + get() = "0 /30 * * *" //Every 30 minutes + override val jobType: CronjobType + get() = CronjobType.INFINITE + override val continueJob: Boolean + get() = true + override lateinit var cronjobJob: Job + override lateinit var scheduler: KronScheduler + + override suspend fun jobFunction() { + Logger.out("Running Splatoon3ApiScheduleUpdateScheduler.") + Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_UPDATE) + StatusUpdater.refreshStatusList(System.currentTimeMillis()) + Logger.out("Splatoon3ApiScheduleUpdateScheduler finished.") + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt new file mode 100644 index 0000000..3db9fda --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt @@ -0,0 +1,47 @@ +/* + * 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.jobs + +import dev.inmo.krontab.KronScheduler +import kotlinx.coroutines.Job +import net.moonleay.lilJudd.data.api.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.type.ApiDataType +import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.jobs.component.CronjobType +import net.moonleay.lilJudd.jobs.component.ICronjob +import net.moonleay.lilJudd.util.Logger + +object Splatoon3ApiSplatnetGearUpdateScheduler : ICronjob { + override val jobName: String + get() = "Splatoon3ApiSplatnetGearUpdateScheduler" + override val jobIncoming: String + get() = "* * /6 * *" //Every 6 hours + override val jobType: CronjobType + get() = CronjobType.INFINITE + override val continueJob: Boolean + get() = true + override lateinit var cronjobJob: Job + override lateinit var scheduler: KronScheduler + + override suspend fun jobFunction() { + Logger.out("Running Splatoon3ApiSplatnetGearUpdateScheduler.") + Splatoon3ApiCache.updateData(ApiDataType.SPLATNETGEAR, ApiRequestType.AUTOMATIC_CACHE_UPDATE) + Logger.out("Splatoon3ApiSplatnetGearUpdateScheduler finished.") + } +} -- 2.45.2 From 1b24a9b7d7f735f5588a742bb9d6e4fb0c260bc4 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:39:46 +0200 Subject: [PATCH 111/168] feat: added NetUtil for web requests Signed-off-by: moonleay --- .../net/moonleay/lilJudd/util/NetUtil.kt | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/util/NetUtil.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/NetUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/NetUtil.kt new file mode 100644 index 0000000..5b43bbc --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/util/NetUtil.kt @@ -0,0 +1,45 @@ +/* + * 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.util + +import java.net.URL +import javax.net.ssl.HttpsURLConnection + +object NetUtil { + fun GETJsonData(urlIN: String, userAgent: String): String { + val startTime = System.currentTimeMillis() + val url = URL(urlIN) + val connection = url.openConnection() as HttpsURLConnection + connection.requestMethod = "GET" + connection.setRequestProperty("User-Agent", userAgent) + connection.setRequestProperty("Accept", "application/json") + val responseCode = connection.responseCode + val timeDiff = System.currentTimeMillis() - startTime + Logger.out("GET took $timeDiff ms (from: $urlIN, as $userAgent)") + return if (responseCode == HttpsURLConnection.HTTP_OK) { + val inputStream = connection.inputStream + val inputStreamReader = inputStream.reader() + val inputAsString = inputStreamReader.readText() + inputStream.close() + inputAsString + } else { + "Error $responseCode" + } + } +} -- 2.45.2 From ef6820da11ba3b4e83af866e0823381de858ae2b Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:40:16 +0200 Subject: [PATCH 112/168] feat: added JSON deformatter to TimeUtil Signed-off-by: moonleay --- .../net/moonleay/lilJudd/util/TimeUtil.kt | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt index c3c3e54..5287bc3 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt @@ -29,7 +29,7 @@ import java.util.concurrent.TimeUnit object TimeUtil { - fun getTimeFormatedShortend(time2: Long): String { + fun getTimeFormatedShortend(time2: Long, showS: Boolean): String { var time = time2 val days: Long = TimeUnit.MILLISECONDS .toDays(time) @@ -52,7 +52,7 @@ object TimeUtil { if (minutes >= 1) { s += minutes.toString() + "m " } - if (seconds >= 1 && hours < 1) { + if (seconds >= 1 && hours < 1 && showS) { s += seconds.toString() + "s" } if (s.isEmpty() || s.isBlank()) { @@ -158,4 +158,17 @@ object TimeUtil { val zdt_ = zdt.minusHours(1) return "0 ${zdt_.minute} ${zdt_.hour} ${zdt_.dayOfMonth - 1} ${zdt_.month.value - 1} ${zdt_.year}"// 0o *w" } + + fun deformatJSONTime(inp: String, zone: String): Long { + // 2023-10-05T08:00:00Z + val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'") + val localDateTime = LocalDateTime.parse(inp, formatter) + val zoneId = ZoneId.of(zone) // TODO: Add the possibility to set your timezone + return ZonedDateTime.of(localDateTime, zoneId).toEpochSecond() * 1000 + } + + fun getTimeDifferenceFormatted(start: Long, end: Long): String { + val diff = end - start + return getTimeFormatedShortend(diff, false) + } } -- 2.45.2 From 594050dd619344005a395d70314cc8ad7da8c434 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:40:45 +0200 Subject: [PATCH 113/168] feat: added StatusUpdater to update the status of the bot Signed-off-by: moonleay --- .../moonleay/lilJudd/jobs/StatusUpdater.kt | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt new file mode 100644 index 0000000..7f70859 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -0,0 +1,68 @@ +/* + * 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.jobs + +import dev.inmo.krontab.KronScheduler +import dev.kord.common.entity.PresenceStatus +import kotlinx.coroutines.Job +import net.moonleay.lilJudd.Bot +import net.moonleay.lilJudd.data.api.Splatoon3Api +import net.moonleay.lilJudd.jobs.component.CronjobType +import net.moonleay.lilJudd.jobs.component.ICronjob +import net.moonleay.lilJudd.util.Logger + +object StatusUpdater : ICronjob { + override val jobName: String + get() = "StatusUpdater" + override val jobIncoming: String + get() = "/6 * * * *" //Every 10 seconds + override val jobType: CronjobType + get() = CronjobType.INFINITE + override val continueJob: Boolean + get() = true + override lateinit var cronjobJob: Job + override lateinit var scheduler: KronScheduler + + private var statusList = listOf() + private var index = 0 + + override suspend fun jobFunction() { + Logger.out("Updating status.") + Bot.bot.kordRef.editPresence { + this.status = PresenceStatus.DoNotDisturb + this.playing(statusList[index]) + } + ++index + if (index >= statusList.size) { + index = 0 + } + } + + fun refreshStatusList(timestamp: Long) { + statusList = listOf( + Splatoon3Api.getRegularMapsFormatted(timestamp), + Splatoon3Api.getSeriesModeFormatted(timestamp), + Splatoon3Api.getSeriesMapsFormatted(timestamp), + Splatoon3Api.getOpenModeFormatted(timestamp), + Splatoon3Api.getOpenMapFormatted(timestamp), + Splatoon3Api.getXModeFormatted(timestamp), + Splatoon3Api.getXMapFormatted(timestamp), + ) + } +} -- 2.45.2 From e02117fa3631ffa07d7ae4eaee3f24df7a5117f0 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:41:46 +0200 Subject: [PATCH 114/168] feat: registered new jobs and features Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 26 ++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 1201560..dc78d89 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -33,11 +33,17 @@ import kotlinx.coroutines.launch import net.moonleay.botendo.build.BuildConstants import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager +import net.moonleay.lilJudd.data.api.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.type.ApiDataType +import net.moonleay.lilJudd.data.api.type.ApiRequestType import net.moonleay.lilJudd.data.database.DB import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.features.MatchManager import net.moonleay.lilJudd.features.TimeManager +import net.moonleay.lilJudd.jobs.Splatoon3ApiScheduleUpdateScheduler +import net.moonleay.lilJudd.jobs.StatusUpdater +import net.moonleay.lilJudd.jobs.component.JobManager import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil @@ -99,7 +105,7 @@ object Bot { } extensions { - add(::VersionExtension) + add(::InfoExtension) add(::FeatureManageExtension) add(::SendPlannerExtension) add(::MatchExtension) @@ -120,7 +126,6 @@ object Bot { sharding { recommended -> Shards(recommended) } */ - // Same goes for a Database table rewrite } // Register button presses @@ -141,7 +146,6 @@ object Bot { } if (inter.componentId.startsWith("public.message.")) { val response = inter.deferPublicResponse() - val g = this.interaction.getOriginalInteractionResponse().getGuild() response.respond { this.embeds = mutableListOf( MessageUtil.getEmbed( @@ -161,6 +165,22 @@ object Bot { MatchManager.update() // Update Matches } + // Update the Splatoon 3 api data and make sure it stays up-to-date + Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_CREATION_AT_STARTUP) + JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) + /* + Other caches will be added when implemented + its not used yet in order to reduce load on the api, + which i am using. + */ + //JobManager.addJob(Splatoon3ApiFestivalAndCoopUpdateScheduler) + //JobManager.addJob(Splatoon3ApiSplatnetGearUpdateScheduler) + + // Make the bot update the status every 10 seconds + JobManager.addJob(StatusUpdater) + // Update the status messages for the bot + StatusUpdater.refreshStatusList(System.currentTimeMillis()) + //Start the bot bot.start() -- 2.45.2 From 390cd2a345d38fa297f0bbf3fa144ac370630048 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:52:42 +0200 Subject: [PATCH 115/168] feat: made the status refresh every time it updates Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index 7f70859..84d4660 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -25,7 +25,6 @@ import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.data.api.Splatoon3Api import net.moonleay.lilJudd.jobs.component.CronjobType import net.moonleay.lilJudd.jobs.component.ICronjob -import net.moonleay.lilJudd.util.Logger object StatusUpdater : ICronjob { override val jobName: String @@ -43,7 +42,7 @@ object StatusUpdater : ICronjob { private var index = 0 override suspend fun jobFunction() { - Logger.out("Updating status.") + refreshStatusList(System.currentTimeMillis()) Bot.bot.kordRef.editPresence { this.status = PresenceStatus.DoNotDisturb this.playing(statusList[index]) -- 2.45.2 From 89e6142ebfb39209fe971cd4b9cc1f373c1408be Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 11:53:18 +0200 Subject: [PATCH 116/168] feat: removed the not needed status refreshes Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 3 --- .../lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt | 1 - 2 files changed, 4 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index dc78d89..ab169a6 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -178,9 +178,6 @@ object Bot { // Make the bot update the status every 10 seconds JobManager.addJob(StatusUpdater) - // Update the status messages for the bot - StatusUpdater.refreshStatusList(System.currentTimeMillis()) - //Start the bot bot.start() diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt index 70d7c58..3a4c8ed 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt @@ -42,7 +42,6 @@ object Splatoon3ApiScheduleUpdateScheduler : ICronjob { override suspend fun jobFunction() { Logger.out("Running Splatoon3ApiScheduleUpdateScheduler.") Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_UPDATE) - StatusUpdater.refreshStatusList(System.currentTimeMillis()) Logger.out("Splatoon3ApiScheduleUpdateScheduler finished.") } } -- 2.45.2 From daf3ed0c21a2f6f5deb67532c005f5dda2b3df93 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 15:09:30 +0200 Subject: [PATCH 117/168] fix: StatusUpdater now starts after the bot is online Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index ab169a6..6a5bf7b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -163,6 +163,8 @@ object Bot { bot.kordRef.on { AvailabilityManager.runThread() // Update Availabilities MatchManager.update() // Update Matches + // Make the bot update the status every 6 seconds + JobManager.addJob(StatusUpdater) } // Update the Splatoon 3 api data and make sure it stays up-to-date @@ -176,9 +178,6 @@ object Bot { //JobManager.addJob(Splatoon3ApiFestivalAndCoopUpdateScheduler) //JobManager.addJob(Splatoon3ApiSplatnetGearUpdateScheduler) - // Make the bot update the status every 10 seconds - JobManager.addJob(StatusUpdater) - //Start the bot bot.start() } -- 2.45.2 From a2fa3c0d5135b87e39c3f964b09f0f025d33ee2e Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 15:09:45 +0200 Subject: [PATCH 118/168] chore: updated comment Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index 84d4660..f022950 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -30,7 +30,7 @@ object StatusUpdater : ICronjob { override val jobName: String get() = "StatusUpdater" override val jobIncoming: String - get() = "/6 * * * *" //Every 10 seconds + get() = "/6 * * * *" //Every 6 seconds override val jobType: CronjobType get() = CronjobType.INFINITE override val continueJob: Boolean -- 2.45.2 From 486417b3830de3b20640a03b2045f7d6aa5aa03c Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 5 Oct 2023 15:09:58 +0200 Subject: [PATCH 119/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index bb2560b..71eb2dd 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.6.0" + ?: "2.6.2" val kordver = "1.5.9-SNAPSHOT" val coroutinesver = "1.7.3" -- 2.45.2 From 2834989bbb895664649f8274f79480bdd858e74b Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 6 Oct 2023 09:42:50 +0200 Subject: [PATCH 120/168] fix: fixed api schedulers Signed-off-by: moonleay --- .../lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt | 2 +- .../lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt | 2 +- .../lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt | 2 +- src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt index 8e05cb1..ff299fc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt @@ -31,7 +31,7 @@ object Splatoon3ApiFestivalAndCoopUpdateScheduler : ICronjob { override val jobName: String get() = "Splatoon3ApiFestivalAndCoopUpdateScheduler" override val jobIncoming: String - get() = "0 0 0 /1 *" // once a day + get() = "0 0 0 /1 * * 0o *" // once a day override val jobType: CronjobType get() = CronjobType.INFINITE override val continueJob: Boolean diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt index 3a4c8ed..5c38b15 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt @@ -31,7 +31,7 @@ object Splatoon3ApiScheduleUpdateScheduler : ICronjob { override val jobName: String get() = "Splatoon3ApiScheduleUpdateScheduler" override val jobIncoming: String - get() = "0 /30 * * *" //Every 30 minutes + get() = "0 0 /1 * * * 0o *" //Every hour override val jobType: CronjobType get() = CronjobType.INFINITE override val continueJob: Boolean diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt index 3db9fda..51048f2 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt @@ -31,7 +31,7 @@ object Splatoon3ApiSplatnetGearUpdateScheduler : ICronjob { override val jobName: String get() = "Splatoon3ApiSplatnetGearUpdateScheduler" override val jobIncoming: String - get() = "* * /6 * *" //Every 6 hours + get() = "0 0 /6 * * * 0o *" //Every 6 hours override val jobType: CronjobType get() = CronjobType.INFINITE override val continueJob: Boolean diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index f022950..7df554b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -30,7 +30,7 @@ object StatusUpdater : ICronjob { override val jobName: String get() = "StatusUpdater" override val jobIncoming: String - get() = "/6 * * * *" //Every 6 seconds + get() = "/5 * * * * * 0o *" //Every 5 seconds override val jobType: CronjobType get() = CronjobType.INFINITE override val continueJob: Boolean -- 2.45.2 From 75b8321ba6fa5f9b48e9391582a7835a0bcbb6cb Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 6 Oct 2023 09:43:21 +0200 Subject: [PATCH 121/168] fix: fixed issue with time in the match extension Signed-off-by: moonleay --- .../kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index ff47b9b..9f2674d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -108,7 +108,7 @@ class MatchExtension : Extension() { role.id.value.toLong(), opponent, msg.id.value.toLong(), - (zdt.toEpochSecond()), + (zdt.toEpochSecond() * 1000), jobString ) ) -- 2.45.2 From dac2bdd6d3edf8235ba419b66f6e9b5095873437 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 6 Oct 2023 09:43:32 +0200 Subject: [PATCH 122/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 71eb2dd..549c10f 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -32,11 +32,11 @@ 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.6.2" + ?: "2.6.4" val kordver = "1.5.9-SNAPSHOT" val coroutinesver = "1.7.3" -val ktor_version = "2.3.4" +val ktorver = "2.3.5" val exposedver = "0.43.0" val postgresver = "42.6.0" val krontabver = "2.2.1" @@ -89,6 +89,8 @@ implementation.extendsFrom(shadow) dependencies { //Discord shadow("com.kotlindiscord.kord.extensions:kord-extensions:$kordver") + + //Coroutines shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver") //Logging @@ -101,10 +103,10 @@ dependencies { shadow("org.jetbrains.exposed:exposed-jdbc:$exposedver") shadow("org.postgresql:postgresql:$postgresver") - //Korntab + //Krontab shadow("dev.inmo:krontab:$krontabver") - shadow("io.ktor:ktor-client-core-jvm:2.3.4") - shadow("io.ktor:ktor-client-cio-jvm:2.3.4") + shadow("io.ktor:ktor-client-core-jvm:2.3.5") + shadow("io.ktor:ktor-client-cio-jvm:2.3.5") } @@ -116,7 +118,7 @@ val templateProps = mapOf( "ownerID" to ownerID, "kordversion" to kordver, "coroutinesversion" to coroutinesver, - "ktorversion" to ktor_version, + "ktorversion" to ktorver, "exposedversion" to exposedver, "postgresversion" to postgresver, "krontabversion" to krontabver -- 2.45.2 From bf057dd317df36fe85239c834c52db91288b3bc5 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 26 Oct 2023 18:53:22 +0200 Subject: [PATCH 123/168] fix!: temp. stopped the StatusUpdater and Cache updater from running to make the bot run again, fixed package names Signed-off-by: moonleay --- .gitignore | 1 + build.gradle.kts | 2 +- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 18 ++++++++---------- src/main/kotlin/net/moonleay/lilJudd/Main.kt | 3 ++- .../lilJudd/data/api/Splatoon3ApiCache.kt | 2 +- .../lilJudd/extensions/InfoExtension.kt | 2 +- .../moonleay/lilJudd/build/BuildConstants.kt | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.gitignore b/.gitignore index ce11a8e..f970cd0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ run/ +/data/ .gradle build/ diff --git a/build.gradle.kts b/build.gradle.kts index 549c10f..48416b1 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.6.4" + ?: "2.6.5" val kordver = "1.5.9-SNAPSHOT" val coroutinesver = "1.7.3" diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 6a5bf7b..05f7ba8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -30,23 +30,17 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import net.moonleay.botendo.build.BuildConstants import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager -import net.moonleay.lilJudd.data.api.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.type.ApiDataType -import net.moonleay.lilJudd.data.api.type.ApiRequestType import net.moonleay.lilJudd.data.database.DB import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.features.MatchManager import net.moonleay.lilJudd.features.TimeManager -import net.moonleay.lilJudd.jobs.Splatoon3ApiScheduleUpdateScheduler -import net.moonleay.lilJudd.jobs.StatusUpdater -import net.moonleay.lilJudd.jobs.component.JobManager import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.liljudd.build.BuildConstants import kotlin.system.exitProcess object Bot { @@ -164,17 +158,21 @@ object Bot { AvailabilityManager.runThread() // Update Availabilities MatchManager.update() // Update Matches // Make the bot update the status every 6 seconds - JobManager.addJob(StatusUpdater) + // JobManager.addJob(StatusUpdater) } // Update the Splatoon 3 api data and make sure it stays up-to-date - Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_CREATION_AT_STARTUP) - JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) + // Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_CREATION_AT_STARTUP) + // JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) /* Other caches will be added when implemented its not used yet in order to reduce load on the api, which i am using. */ + // Had to disable bc of an error. + // Will fix when I have time + + //JobManager.addJob(Splatoon3ApiFestivalAndCoopUpdateScheduler) //JobManager.addJob(Splatoon3ApiSplatnetGearUpdateScheduler) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Main.kt b/src/main/kotlin/net/moonleay/lilJudd/Main.kt index 9d00d29..36be8b3 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Main.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Main.kt @@ -17,7 +17,8 @@ */ package net.moonleay.lilJudd -import net.moonleay.botendo.build.BuildConstants +import net.moonleay.liljudd.build.BuildConstants + suspend fun main() { println( diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt index 42ff01c..714ff1e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt @@ -20,7 +20,6 @@ package net.moonleay.lilJudd.data.api import io.ktor.http.* import kotlinx.serialization.json.* -import net.moonleay.botendo.build.BuildConstants import net.moonleay.lilJudd.data.api.entry.coop.CoopGearData import net.moonleay.lilJudd.data.api.entry.schedule.* import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestColor @@ -34,6 +33,7 @@ import net.moonleay.lilJudd.data.api.type.ApiDataType import net.moonleay.lilJudd.data.api.type.ApiRequestType import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.NetUtil +import net.moonleay.liljudd.build.BuildConstants object Splatoon3ApiCache { private val user_agent = diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt index ff5a61a..6445faf 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt @@ -20,9 +20,9 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import net.moonleay.botendo.build.BuildConstants import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.liljudd.build.BuildConstants class InfoExtension : Extension() { override val name = "info" diff --git a/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt b/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt index fdcf269..d75d861 100644 --- a/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt +++ b/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.botendo.build +package net.moonleay.liljudd.build internal object BuildConstants { const val version = "${version}" -- 2.45.2 From 5b613d25f215858e43b70caf49954ed2ea6c5c04 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Dec 2023 16:02:32 +0100 Subject: [PATCH 124/168] chore: update README.md Signed-off-by: moonleay --- README.md | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index cfc9bea..42c3d06 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ More information can be found on the [Homepage](https://moonleay.net/projects/li ## Known issues -##### If you encounter any bugs, message me on Discord (@moonleay) or send me a mail (issues@moonleay.net). +##### If you encounter any bugs, message me on Discord (@moonleay) or send me a mail (issues@moonleay.net). You can also open a ticket [on the support server](https://discord.gg/HTZRktfH4A). ## Commands & Features @@ -29,11 +29,7 @@ More information can be found on the [Homepage](https://moonleay.net/projects/li ## (Maybe) upcoming features -- Match Planner (Send Notifications some time before a match starts) -- Game Tracker (Save the results of the last matches) -- Replay Saver (Maybe; will save the replay code to a database) -- Rndm map command -- Maybe a DSB / DSL API +##### See the [todo list](https://todo.moonleay.net/share/OmisuzgPDdsrCAXKjGrTfYzWwqNDNclOMGJWeMsi/auth?view=kanban) for more information. ## How to self-host (using the Docker container) -- 2.45.2 From 05d2d1a6b906db52cd841d5e3f0a963590e019a4 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 6 Dec 2023 16:03:41 +0100 Subject: [PATCH 125/168] chore: update README.md Signed-off-by: moonleay --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 42c3d06..6d87924 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ A Discord Bot for Splatoon Teams. -More information can be found on the [Homepage](https://moonleay.net/projects/liljudd/). +More information can be found on the [Homepage](https://liljudd.ink). ## Contributors -- 2.45.2 From 0bf527b6e0c777da62ee6d29f3ebdd1640bdd4d5 Mon Sep 17 00:00:00 2001 From: cookieso Date: Wed, 6 Dec 2023 18:12:41 +0100 Subject: [PATCH 126/168] fix: off-by-one error in EmbedUtil --- src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt index e9dbbaf..17615b3 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt @@ -82,7 +82,7 @@ object EmbedUtil { fun getAllUsersInTheFirstXTables(amountOfTables: Int, e: Embed): List { val users = mutableListOf() - for (i in 0 until amountOfTables - 1) { + for (i in 0 until amountOfTables) { val f = e.fields[i] if (!f.value.contains("@")) continue // check next one. this one does not have any entries -- 2.45.2 From 94149e427295a1e40d9d8f3bab081d5ac1e5c401 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 7 Dec 2023 08:57:35 +0100 Subject: [PATCH 127/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 48416b1..4931cd8 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.6.5" + ?: "2.6.6" val kordver = "1.5.9-SNAPSHOT" val coroutinesver = "1.7.3" -- 2.45.2 From 984bcabd0c70c624961c11baee74f469d4e0f499 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 7 Dec 2023 08:58:16 +0100 Subject: [PATCH 128/168] fix: added try-catch to Splatoon3Api, fixed Statusupdater Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 12 +- .../lilJudd/data/api/Splatoon3ApiCache.kt | 632 ++++++++++-------- .../moonleay/lilJudd/jobs/StatusUpdater.kt | 4 +- .../net/moonleay/lilJudd/util/TimeUtil.kt | 10 + 4 files changed, 357 insertions(+), 301 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 05f7ba8..9dba1b2 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -32,11 +32,17 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager +import net.moonleay.lilJudd.data.api.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.type.ApiDataType +import net.moonleay.lilJudd.data.api.type.ApiRequestType import net.moonleay.lilJudd.data.database.DB import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.features.MatchManager import net.moonleay.lilJudd.features.TimeManager +import net.moonleay.lilJudd.jobs.Splatoon3ApiScheduleUpdateScheduler +import net.moonleay.lilJudd.jobs.StatusUpdater +import net.moonleay.lilJudd.jobs.component.JobManager import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil @@ -158,12 +164,12 @@ object Bot { AvailabilityManager.runThread() // Update Availabilities MatchManager.update() // Update Matches // Make the bot update the status every 6 seconds - // JobManager.addJob(StatusUpdater) + JobManager.addJob(StatusUpdater) } // Update the Splatoon 3 api data and make sure it stays up-to-date - // Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_CREATION_AT_STARTUP) - // JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) + Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_CREATION_AT_STARTUP) + JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) /* Other caches will be added when implemented its not used yet in order to reduce load on the api, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt index 714ff1e..daba96d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt @@ -192,17 +192,21 @@ object Splatoon3ApiCache { Logger.out("Error getting coop data: $apiResponse") return } - val json = Json.parseToJsonElement(apiResponse) - val data = json.jsonObject["data"]!!.jsonObject["coopResult"]!!.jsonObject["monthlyGear"]!!.jsonObject - cachedCoopRewardsData = mutableListOf() - cachedCoopRewardsData.add( - CoopGearData( - data["name"]!!.jsonPrimitive.content, - Url(data["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - data["__typename"]!!.jsonPrimitive.content + try { + val json = Json.parseToJsonElement(apiResponse) + val data = json.jsonObject["data"]!!.jsonObject["coopResult"]!!.jsonObject["monthlyGear"]!!.jsonObject + cachedCoopRewardsData = mutableListOf() + cachedCoopRewardsData.add( + CoopGearData( + data["name"]!!.jsonPrimitive.content, + Url(data["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + data["__typename"]!!.jsonPrimitive.content + ) ) - ) - Logger.out("Updated COOP data") + Logger.out("Updated COOP data") + } catch (e: Exception) { + Logger.out("Error getting coop data: ${e.cause}") + } } private fun updateScheduleCache(uag: String) { @@ -214,205 +218,236 @@ object Splatoon3ApiCache { val json = Json.decodeFromString(apiResponse) as JsonObject val data = json["data"]!!.jsonObject - val mapList = data["vsStages"]!!.jsonObject["nodes"]!!.jsonArray - cachedMapData = mutableMapOf() - mapList.forEach { - val obj = it as JsonObject - val imageURL = Url(obj.jsonObject["originalImage"]!!.jsonObject["url"]!!.jsonPrimitive.content) - val id = obj.jsonObject["vsStageId"]!!.jsonPrimitive.int - cachedMapData[id] = MapData( - id, - imageURL, - it.jsonObject["name"]!!.jsonPrimitive.content - ) - } - Logger.out("Updated maplist data") - - val regularMatches = data["regularSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedRegularModeData = mutableListOf() - regularMatches.forEach { - val obj = it as JsonObject - val setting = obj["regularMatchSetting"]!!.jsonObject - cachedRegularModeData.add( - ModeData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - setting["__typename"]!!.jsonPrimitive.content, - cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - "TURF_WAR" + try { + val mapList = data["vsStages"]!!.jsonObject["nodes"]!!.jsonArray + cachedMapData = mutableMapOf() + mapList.forEach { + val obj = it as JsonObject + val imageURL = Url(obj.jsonObject["originalImage"]!!.jsonObject["url"]!!.jsonPrimitive.content) + val id = obj.jsonObject["vsStageId"]!!.jsonPrimitive.int + cachedMapData[id] = MapData( + id, + imageURL, + it.jsonObject["name"]!!.jsonPrimitive.content ) - ) + } + Logger.out("Updated maplist data") + } catch (e: Exception) { + Logger.out("Error getting maplist data: ${e.cause}") } - Logger.out("Updated Regular match data") - val compMatches = data["bankaraSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedCompetitiveSeriesModeData = mutableListOf() - cachedCompetitiveOpenModeData = mutableListOf() - compMatches.forEach { - val obj = it as JsonObject - val setting = obj["bankaraMatchSettings"]!!.jsonArray - setting.forEach { - val ob = it as JsonObject - val mode = ob["bankaraMode"]!!.jsonPrimitive.content - if (mode == "CHALLENGE") { - cachedCompetitiveSeriesModeData.add( - ModeData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - ob["__typename"]!!.jsonPrimitive.content, - cachedMapData[ob["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[ob["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - ob["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - ob["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - mode - ) + try { + val regularMatches = data["regularSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedRegularModeData = mutableListOf() + regularMatches.forEach { + val obj = it as JsonObject + val setting = obj["regularMatchSetting"]!!.jsonObject + cachedRegularModeData.add( + ModeData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + setting["__typename"]!!.jsonPrimitive.content, + cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + "TURF_WAR" ) - } else if (mode == "OPEN") { - cachedCompetitiveOpenModeData.add( - ModeData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - ob["__typename"]!!.jsonPrimitive.content, - cachedMapData[ob["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[ob["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - ob["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - ob["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - mode + ) + } + Logger.out("Updated Regular match data") + } catch (e: Exception) { + Logger.out("Error getting regular match data: ${e.cause}") + } + + try { + val compMatches = data["bankaraSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedCompetitiveSeriesModeData = mutableListOf() + cachedCompetitiveOpenModeData = mutableListOf() + compMatches.forEach { + val obj = it as JsonObject + val setting = obj["bankaraMatchSettings"]!!.jsonArray + setting.forEach { + val ob = it as JsonObject + val mode = ob["bankaraMode"]!!.jsonPrimitive.content + if (mode == "CHALLENGE") { + cachedCompetitiveSeriesModeData.add( + ModeData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + ob["__typename"]!!.jsonPrimitive.content, + cachedMapData[ob["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[ob["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + ob["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + ob["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + mode + ) ) - ) + } else if (mode == "OPEN") { + cachedCompetitiveOpenModeData.add( + ModeData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + ob["__typename"]!!.jsonPrimitive.content, + cachedMapData[ob["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[ob["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + ob["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + ob["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + mode + ) + ) + } } } - } - Logger.out("Updated Competitive match data") + Logger.out("Updated Competitive match data") - val xMatches = data["xSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedXModeData = mutableListOf() - xMatches.forEach { - val obj = it as JsonObject - val setting = obj["xMatchSetting"]!!.jsonObject - cachedXModeData.add( - ModeData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - setting["__typename"]!!.jsonPrimitive.content, - cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - "X" - ) - ) + } catch (e: Exception) { + Logger.out("Error getting competitive match data: ${e.cause}") } - Logger.out("Updated X match data") - - val challengeData = data["eventSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedChallengesData = mutableListOf() - challengeData.forEach { - val obj = it as JsonObject - val tpd = obj["timePeriods"]!!.jsonArray - val setting = obj["leagueMatchSetting"]!!.jsonObject - val event = setting["leagueMatchEvent"]!!.jsonObject - cachedChallengesData.add( - ChallengeModeData( - event["leagueMatchEventId"]!!.jsonPrimitive.content, - event["name"]!!.jsonPrimitive.content, - event["desc"]!!.jsonPrimitive.content, - event["regulation"]!!.jsonPrimitive.content, - cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - setting["__typename"]!!.jsonPrimitive.content, - setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - TimePeriodData( - tpd[0].jsonObject["startTime"]!!.jsonPrimitive.content, - tpd[0].jsonObject["endTime"]!!.jsonPrimitive.content - ), - TimePeriodData( - tpd[1].jsonObject["startTime"]!!.jsonPrimitive.content, - tpd[1].jsonObject["endTime"]!!.jsonPrimitive.content - ), - TimePeriodData( - tpd[2].jsonObject["startTime"]!!.jsonPrimitive.content, - tpd[2].jsonObject["endTime"]!!.jsonPrimitive.content + try { + val xMatches = data["xSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedXModeData = mutableListOf() + xMatches.forEach { + val obj = it as JsonObject + val setting = obj["xMatchSetting"]!!.jsonObject + cachedXModeData.add( + ModeData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + setting["__typename"]!!.jsonPrimitive.content, + cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + "X" ) ) - ) - } - Logger.out("Updated Challenge data") - - val shiftData = data["coopGroupingSchedule"]!!.jsonObject["regularSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedShiftData = mutableListOf() - shiftData.forEach { - val obj = it as JsonObject - val setting = obj["setting"]!!.jsonObject - val stage = setting["coopStage"]!!.jsonObject - val weapons = setting["weapons"]!!.jsonArray - cachedShiftData.add( - ShiftData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - obj["__splatoon3ink_king_salmonid_guess"]!!.jsonPrimitive.content, - setting["__typename"]!!.jsonPrimitive.content, - stage["name"]!!.jsonPrimitive.content, - Url(stage["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - WeaponData( - weapons[0].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[0].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[1].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[1].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[2].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[2].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[3].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[3].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ) - ) - ) + } + Logger.out("Updated X match data") + } catch (e: Exception) { + Logger.out("Error getting X match data: ${e.cause}") } - val bigRunData = data["coopGroupingSchedule"]!!.jsonObject["bigRunSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedBigRunShiftData = mutableListOf() - bigRunData.forEach { - val obj = it as JsonObject - val setting = obj["setting"]!!.jsonObject - val stage = setting["coopStage"]!!.jsonObject - val weapons = setting["weapons"]!!.jsonArray - cachedBigRunShiftData.add( - ShiftData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - obj["__splatoon3ink_king_salmonid_guess"]!!.jsonPrimitive.content, - setting["__typename"]!!.jsonPrimitive.content, - stage["name"]!!.jsonPrimitive.content, - Url(stage["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - WeaponData( - weapons[0].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[0].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[1].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[1].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[2].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[2].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[3].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[3].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + try { + val challengeData = data["eventSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedChallengesData = mutableListOf() + challengeData.forEach { + val obj = it as JsonObject + val tpd = obj["timePeriods"]!!.jsonArray + val setting = obj["leagueMatchSetting"]!!.jsonObject + val event = setting["leagueMatchEvent"]!!.jsonObject + cachedChallengesData.add( + ChallengeModeData( + event["leagueMatchEventId"]!!.jsonPrimitive.content, + event["name"]!!.jsonPrimitive.content, + event["desc"]!!.jsonPrimitive.content, + event["regulation"]!!.jsonPrimitive.content, + cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], + cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], + setting["__typename"]!!.jsonPrimitive.content, + setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, + setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, + TimePeriodData( + tpd[0].jsonObject["startTime"]!!.jsonPrimitive.content, + tpd[0].jsonObject["endTime"]!!.jsonPrimitive.content + ), + TimePeriodData( + tpd[1].jsonObject["startTime"]!!.jsonPrimitive.content, + tpd[1].jsonObject["endTime"]!!.jsonPrimitive.content + ), + TimePeriodData( + tpd[2].jsonObject["startTime"]!!.jsonPrimitive.content, + tpd[2].jsonObject["endTime"]!!.jsonPrimitive.content + ) ) ) - ) + } + Logger.out("Updated Challenge data") + } catch (e: Exception) { + Logger.out("Error getting Challenge data: ${e.cause}") + } + + try { + val shiftData = + data["coopGroupingSchedule"]!!.jsonObject["regularSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedShiftData = mutableListOf() + shiftData.forEach { + val obj = it as JsonObject + val setting = obj["setting"]!!.jsonObject + val stage = setting["coopStage"]!!.jsonObject + val weapons = setting["weapons"]!!.jsonArray + cachedShiftData.add( + ShiftData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + obj["__splatoon3ink_king_salmonid_guess"]!!.jsonPrimitive.content, + setting["__typename"]!!.jsonPrimitive.content, + stage["name"]!!.jsonPrimitive.content, + Url(stage["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + WeaponData( + weapons[0].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[0].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[1].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[1].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[2].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[2].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[3].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[3].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ) + ) + ) + } + Logger.out("Updated shift data") + } catch (e: Exception) { + Logger.out("Error getting coopGrouping data: ${e.cause}") + } + + try { + val bigRunData = + data["coopGroupingSchedule"]!!.jsonObject["bigRunSchedules"]!!.jsonObject["nodes"]!!.jsonArray + cachedBigRunShiftData = mutableListOf() + bigRunData.forEach { + val obj = it as JsonObject + val setting = obj["setting"]!!.jsonObject + val stage = setting["coopStage"]!!.jsonObject + val weapons = setting["weapons"]!!.jsonArray + cachedBigRunShiftData.add( + ShiftData( + obj["startTime"]!!.jsonPrimitive.content, + obj["endTime"]!!.jsonPrimitive.content, + obj["__splatoon3ink_king_salmonid_guess"]!!.jsonPrimitive.content, + setting["__typename"]!!.jsonPrimitive.content, + stage["name"]!!.jsonPrimitive.content, + Url(stage["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + WeaponData( + weapons[0].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[0].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[1].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[1].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[2].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[2].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ), + WeaponData( + weapons[3].jsonObject["name"]!!.jsonPrimitive.content, + Url(weapons[3].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) + ) + ) + ) + } + Logger.out("Updated big run data") + } catch (e: Exception) { + Logger.out("Error getting big run data: ${e.cause}") } - Logger.out("Updated big run data") Logger.out("Updated all Schedules") } @@ -423,113 +458,118 @@ object Splatoon3ApiCache { Logger.out("Error getting splatfest data: $apiResponse") return } - val json = Json.decodeFromString(apiResponse) as JsonObject - val festivals = json["US"]!!.jsonObject["data"]!!.jsonObject["festRecords"]!!.jsonObject["nodes"]!!.jsonArray - cachedSplatfestData = mutableListOf() - festivals.forEach { - val fest = it as JsonObject - val teams = fest.jsonObject["teams"]!!.jsonArray - val team1 = teams[0].jsonObject - val team1Color = team1["color"]!!.jsonObject - var team1Result: JsonObject? = null - if (team1["result"] !is JsonNull) { - team1Result = team1["result"]!!.jsonObject - } - val team2 = teams[1].jsonObject - val team2Color = team2["color"]!!.jsonObject - var team2Result: JsonObject? = null - if (team2["result"] !is JsonNull) { - team2Result = team2["result"]!!.jsonObject - } - val team3 = teams[2].jsonObject - val team3Color = team3["color"]!!.jsonObject - var team3Result: JsonObject? = null - if (team3["result"] !is JsonNull) { - team3Result = team3["result"]!!.jsonObject - } - cachedSplatfestData.add( - SplatfestData( - fest.jsonObject["id"]!!.jsonPrimitive.content, - fest.jsonObject["state"]!!.jsonPrimitive.content, - fest.jsonObject["startTime"]!!.jsonPrimitive.content, - fest.jsonObject["endTime"]!!.jsonPrimitive.content, - fest.jsonObject["title"]!!.jsonPrimitive.content, - Url(fest.jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - SplatfestTeamData( - team1["teamName"]!!.jsonPrimitive.content, - SplatfestColor( - team1Color["a"]!!.jsonPrimitive.int, - team1Color["b"]!!.jsonPrimitive.double, - team1Color["g"]!!.jsonPrimitive.double, - team1Color["r"]!!.jsonPrimitive.double + try { + val json = Json.decodeFromString(apiResponse) as JsonObject + val festivals = + json["US"]!!.jsonObject["data"]!!.jsonObject["festRecords"]!!.jsonObject["nodes"]!!.jsonArray + cachedSplatfestData = mutableListOf() + festivals.forEach { + val fest = it as JsonObject + val teams = fest.jsonObject["teams"]!!.jsonArray + val team1 = teams[0].jsonObject + val team1Color = team1["color"]!!.jsonObject + var team1Result: JsonObject? = null + if (team1["result"] !is JsonNull) { + team1Result = team1["result"]!!.jsonObject + } + val team2 = teams[1].jsonObject + val team2Color = team2["color"]!!.jsonObject + var team2Result: JsonObject? = null + if (team2["result"] !is JsonNull) { + team2Result = team2["result"]!!.jsonObject + } + val team3 = teams[2].jsonObject + val team3Color = team3["color"]!!.jsonObject + var team3Result: JsonObject? = null + if (team3["result"] !is JsonNull) { + team3Result = team3["result"]!!.jsonObject + } + cachedSplatfestData.add( + SplatfestData( + fest.jsonObject["id"]!!.jsonPrimitive.content, + fest.jsonObject["state"]!!.jsonPrimitive.content, + fest.jsonObject["startTime"]!!.jsonPrimitive.content, + fest.jsonObject["endTime"]!!.jsonPrimitive.content, + fest.jsonObject["title"]!!.jsonPrimitive.content, + Url(fest.jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), + SplatfestTeamData( + team1["teamName"]!!.jsonPrimitive.content, + SplatfestColor( + team1Color["a"]!!.jsonPrimitive.int, + team1Color["b"]!!.jsonPrimitive.double, + team1Color["g"]!!.jsonPrimitive.double, + team1Color["r"]!!.jsonPrimitive.double + ), + if (team1Result.isNullOrEmpty() || team1Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) + null + else SplatfestTeamResults( + team1Result["isWinner"]!!.jsonPrimitive.boolean, + team1Result["horagaiRatio"]!!.jsonPrimitive.double, + team1Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, + team1Result["voteRatio"]!!.jsonPrimitive.double, + team1Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, + team1Result["regularContributionRatio"]!!.jsonPrimitive.double, + team1Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, + team1Result["challengeContributionRatio"]!!.jsonPrimitive.double, + team1Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, + team1Result["tricolorContributionRatio"]!!.jsonPrimitive.double, + team1Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, + ) ), - if (team1Result.isNullOrEmpty() || team1Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) - null - else SplatfestTeamResults( - team1Result["isWinner"]!!.jsonPrimitive.boolean, - team1Result["horagaiRatio"]!!.jsonPrimitive.double, - team1Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, - team1Result["voteRatio"]!!.jsonPrimitive.double, - team1Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, - team1Result["regularContributionRatio"]!!.jsonPrimitive.double, - team1Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, - team1Result["challengeContributionRatio"]!!.jsonPrimitive.double, - team1Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, - team1Result["tricolorContributionRatio"]!!.jsonPrimitive.double, - team1Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, - ) - ), - SplatfestTeamData( - team2["teamName"]!!.jsonPrimitive.content, - SplatfestColor( - team2Color["a"]!!.jsonPrimitive.int, - team2Color["b"]!!.jsonPrimitive.double, - team2Color["g"]!!.jsonPrimitive.double, - team2Color["r"]!!.jsonPrimitive.double + SplatfestTeamData( + team2["teamName"]!!.jsonPrimitive.content, + SplatfestColor( + team2Color["a"]!!.jsonPrimitive.int, + team2Color["b"]!!.jsonPrimitive.double, + team2Color["g"]!!.jsonPrimitive.double, + team2Color["r"]!!.jsonPrimitive.double + ), + if (team2Result.isNullOrEmpty() || team2Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) + null + else SplatfestTeamResults( + team2Result["isWinner"]!!.jsonPrimitive.boolean, + team2Result["horagaiRatio"]!!.jsonPrimitive.double, + team2Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, + team2Result["voteRatio"]!!.jsonPrimitive.double, + team2Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, + team2Result["regularContributionRatio"]!!.jsonPrimitive.double, + team2Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, + team2Result["challengeContributionRatio"]!!.jsonPrimitive.double, + team2Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, + team2Result["tricolorContributionRatio"]!!.jsonPrimitive.double, + team2Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, + ) ), - if (team2Result.isNullOrEmpty() || team2Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) - null - else SplatfestTeamResults( - team2Result["isWinner"]!!.jsonPrimitive.boolean, - team2Result["horagaiRatio"]!!.jsonPrimitive.double, - team2Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, - team2Result["voteRatio"]!!.jsonPrimitive.double, - team2Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, - team2Result["regularContributionRatio"]!!.jsonPrimitive.double, - team2Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, - team2Result["challengeContributionRatio"]!!.jsonPrimitive.double, - team2Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, - team2Result["tricolorContributionRatio"]!!.jsonPrimitive.double, - team2Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, - ) - ), - SplatfestTeamData( - team3["teamName"]!!.jsonPrimitive.content, - SplatfestColor( - team3Color["a"]!!.jsonPrimitive.int, - team3Color["b"]!!.jsonPrimitive.double, - team3Color["g"]!!.jsonPrimitive.double, - team3Color["r"]!!.jsonPrimitive.double + SplatfestTeamData( + team3["teamName"]!!.jsonPrimitive.content, + SplatfestColor( + team3Color["a"]!!.jsonPrimitive.int, + team3Color["b"]!!.jsonPrimitive.double, + team3Color["g"]!!.jsonPrimitive.double, + team3Color["r"]!!.jsonPrimitive.double + ), + if (team3Result.isNullOrEmpty() || team3Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) + null + else SplatfestTeamResults( + team3Result["isWinner"]!!.jsonPrimitive.boolean, + team3Result["horagaiRatio"]!!.jsonPrimitive.double, + team3Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, + team3Result["voteRatio"]!!.jsonPrimitive.double, + team3Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, + team3Result["regularContributionRatio"]!!.jsonPrimitive.double, + team3Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, + team3Result["challengeContributionRatio"]!!.jsonPrimitive.double, + team3Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, + team3Result["tricolorContributionRatio"]!!.jsonPrimitive.double, + team3Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, + ) ), - if (team3Result.isNullOrEmpty() || team3Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) - null - else SplatfestTeamResults( - team3Result["isWinner"]!!.jsonPrimitive.boolean, - team3Result["horagaiRatio"]!!.jsonPrimitive.double, - team3Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, - team3Result["voteRatio"]!!.jsonPrimitive.double, - team3Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, - team3Result["regularContributionRatio"]!!.jsonPrimitive.double, - team3Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, - team3Result["challengeContributionRatio"]!!.jsonPrimitive.double, - team3Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, - team3Result["tricolorContributionRatio"]!!.jsonPrimitive.double, - team3Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, - ) - ), + ) ) - ) + } + Logger.out("Updated Splatfest data") + } catch (e: Exception) { + Logger.out("Error getting splatfest data: ${e.cause}") } - Logger.out("Updated Splatfest data") } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index 7df554b..31b687c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -30,7 +30,7 @@ object StatusUpdater : ICronjob { override val jobName: String get() = "StatusUpdater" override val jobIncoming: String - get() = "/5 * * * * * 0o *" //Every 5 seconds + get() = "/10 * * * * * 0o *" //Every 5 seconds override val jobType: CronjobType get() = CronjobType.INFINITE override val continueJob: Boolean @@ -45,7 +45,7 @@ object StatusUpdater : ICronjob { refreshStatusList(System.currentTimeMillis()) Bot.bot.kordRef.editPresence { this.status = PresenceStatus.DoNotDisturb - this.playing(statusList[index]) + this.competing(statusList[index]) } ++index if (index >= statusList.size) { diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt index 5287bc3..dba203c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt @@ -145,6 +145,16 @@ object TimeUtil { .withMinute(0).withSecond(0) } + fun validateDateString(input: String): Boolean { + val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm") + return try { + LocalDateTime.parse(input, formatter) + true + } catch (e: Exception) { + false + } + } + fun getDateFromString(input: String): ZonedDateTime { val formatter = DateTimeFormatter.ofPattern("dd.MM.yyyy HH:mm") val localDateTime = LocalDateTime.parse(input, formatter) -- 2.45.2 From 52703b4b6110c56ed0f1f6e8431c54472096dd5d Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 7 Dec 2023 08:59:06 +0100 Subject: [PATCH 129/168] fix: fixed match command throwing exceptions when being run with false inputs Signed-off-by: moonleay --- .../lilJudd/extensions/MatchExtension.kt | 70 +++++++++++-------- 1 file changed, 42 insertions(+), 28 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index 9f2674d..118d368 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -20,12 +20,10 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.commands.Arguments import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.enumChoice -import com.kotlindiscord.kord.extensions.commands.converters.impl.optionalString import com.kotlindiscord.kord.extensions.commands.converters.impl.string import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.types.respond -import dev.kord.core.behavior.channel.createMessage import dev.kord.core.behavior.createRole import dev.kord.rest.builder.message.create.actionRow import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData @@ -54,7 +52,46 @@ class MatchExtension : Extension() { val m = this.member!! val gID = this.guild!!.id.value val cID = this.channel.id.value - val opponent = args.opponent ?: "?" + val opponent = args.opponent + if (!TimeUtil.validateDateString(args.timeStamp)) { + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + EmbedColor.ERROR, + "400: Bad Request", + "The given timestamp is invalid.\n" + + "Please use the format \"dd.MM.yyyy HH:mm\".", + m.asUser().username + ) + ) + } + return@action + } + // filter time to date: + val zdt = TimeUtil.getDateFromString(args.timeStamp) + // get the string for the cronjob + val jobString = TimeUtil.getCronjobStringFromDate(zdt) + // create the role + val role = this.guild!!.createRole { + this.name = + "${args.matchType.readableName} Vs ${opponent} At ${zdt.dayOfMonth}/${zdt.month}/${zdt.year} ${zdt.hour}:${zdt.minute}" + this.mentionable = true + } + // Check if the role was created successfully + if (role == null) { + this.respond { + this.embeds.add( + MessageUtil.getEmbed( + EmbedColor.ERROR, + "500: Internal Error", + "Could not find created role.\n" + + "It seems, that said role could not be created.", + m.asUser().username + ) + ) + } + return@action + } val msg = this.respond { this.embeds.add( MessageUtil.getEmbedWithTable( @@ -73,30 +110,6 @@ class MatchExtension : Extension() { this.actionRow { this.components.addAll(EmbedUtil.getMatchButtons().components) } - } // filter time to date: - val zdt = TimeUtil.getDateFromString(args.timeStamp) - // get the string for the cronjob - val jobString = TimeUtil.getCronjobStringFromDate(zdt) - // create the role - val role = this.guild!!.createRole { - this.name = - "${args.matchType.readableName} Vs ${opponent} At ${zdt.dayOfMonth}/${zdt.month}/${zdt.year} ${zdt.hour}:${zdt.minute}" - this.mentionable = true - } - // Check if the role was created successfully - if (role == null) { - this.channel.createMessage { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "500: Internal Error", - "Could not find created role.\n" + - "It seems, that said role could not be created.", - "system message" - ) - ) - } - return@action } val tID = MatchPlanningDataRepository.write( MatchPlanningDataData( @@ -114,6 +127,7 @@ class MatchExtension : Extension() { ) if (tID == null || tID <= 0) { return@action // Not saved to db + // TODO: Add error message } JobManager.addJob( MatchJob( @@ -140,7 +154,7 @@ class MatchExtension : Extension() { this.description = "The timestamp of the match. Format \"dd.MM.yyyy HH:mm\"." } - val opponent by optionalString { + val opponent by string { this.name = "opponent" this.description = "The opponent" } -- 2.45.2 From 5ad7fe0ae6ce84f14f850eb3123d041985a9c9a5 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 4 Aug 2023 21:17:52 +0200 Subject: [PATCH 130/168] chore: improve documentation of self-hosting using docker / docker-compose Signed-off-by: moonleay --- .dockerignore | 1 + README.md | 22 ++++++++++++++++------ docker-compose.yml | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 49 insertions(+), 6 deletions(-) create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore index 0b6a882..1c7ce56 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,4 @@ **.nils /run /run/ +docker-compose.yml diff --git a/README.md b/README.md index 6d87924..333bc9a 100644 --- a/README.md +++ b/README.md @@ -33,12 +33,22 @@ More information can be found on the [Homepage](https://liljudd.ink). ## How to self-host (using the Docker container) -1. Pull the container from [Docker Hub](https://hub.docker.com/repository/docker/limiteddev/liljudd/general) -2. Map /data/ to a folder on disk -3. Run the Bot once -4. follow step 4 and 5 from the JAR section -5. Run the Bot again -6. Profit. +1. Copy the docker-compose.yml file from the repository. +2. Install docker and docker-compose. +3. Create a directory called "data" in the same directory as the docker-compose.yml file. +4. Create a directory called "config" in the same directory as the docker-compose.yml file. +5. Start the bot once. +6. After 10 seconds, stop the bot. +7. Open the config file "credentials.nils" in the config directory. +8. Put in your credentials. + 1. token: your Discord bot token + 2. dbDomain: the domain and port of your postgresql database (e.g.: "postgresql", when using the docker-compose.yml + file) + 3. dbName: the name of the database + 4. dbUser: the username of the database + 5. dbPassword: the password to the db user +9. Start the bot again. +10. The bot should now be up and running. ## How to self-host (using the JAR) diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..af8faef --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,32 @@ +version: "3" +services: + lilJudd: + container_name: liljudd + image: limiteddev/liljudd:x.x.x + deploy: + resources: + limits: + cpus: "1" + memory: 1G + networks: + - traefik + restart: unless-stopped + volumes: + - ./config/liljudd/:/data/ + postgresql: + container_name: postgresql + image: postgres:13.3-alpine + deploy: + resources: + limits: + cpus: "1" + memory: 1G + environment: + - POSTGRES_USER=liljudd + - POSTGRES_PASSWORD=changeme + - POSTGRES_DB=liljudd + networks: + - traefik + restart: unless-stopped + volumes: + - ./data/postgresql/:/var/lib/postgresql/data/ -- 2.45.2 From 60c30af3e91a9152cb93a8a5a9a0c8da515f8e5a Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 7 Dec 2023 18:17:20 +0100 Subject: [PATCH 131/168] feat: reworked Rotation Status Signed-off-by: moonleay --- .../moonleay/lilJudd/data/api/Splatoon3Api.kt | 48 +++++++++---------- .../moonleay/lilJudd/jobs/StatusUpdater.kt | 19 ++++---- 2 files changed, 32 insertions(+), 35 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt index b0192e5..92ad889 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt @@ -66,52 +66,50 @@ object Splatoon3Api { throw Exception("No current mode found") } + fun getRotationTime(timestamp: Long): String { + val modeData = getRegularMode(timestamp) + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) + return "$diffStamp left in rotation" + } + fun getRegularMapsFormatted(timestamp: Long): String { val modeData = getRegularMode(timestamp) val map1 = modeData.map1!!.name.split(" ")[0] val map2 = modeData.map2!!.name.split(" ")[0] - return "R: $map1 & $map2" - } - - fun getOpenModeFormatted(timestamp: Long): String { - val modeData = getOpenMode(timestamp) - val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") - val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) - return "O: ${modeData.ruleSetName} $diffStamp left" + return "R: $map1, $map2" } fun getOpenMapFormatted(timestamp: Long): String { val modeData = getOpenMode(timestamp) val map1 = modeData.map1!!.name.split(" ")[0] val map2 = modeData.map2!!.name.split(" ")[0] - return "O: $map1 & $map2" - } - - fun getSeriesModeFormatted(timestamp: Long): String { - val modeData = getSeriesMode(timestamp) - val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") - val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) - return "S: ${modeData.ruleSetName} $diffStamp left" + return "O: ${modeData.ruleSetName}: $map1, $map2" + .replace("Rainmaker", "RMK") + .replace("Tower Control", "TC") + .replace("Splat Zones", "SZ") + .replace("Clam Blitz", "CB") } fun getSeriesMapsFormatted(timestamp: Long): String { val modeData = getSeriesMode(timestamp) val map1 = modeData.map1!!.name.split(" ")[0] val map2 = modeData.map2!!.name.split(" ")[0] - return "S: $map1 & $map2" - } - - fun getXModeFormatted(timestamp: Long): String { - val modeData = getXMode(timestamp) - val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") - val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) - return "X: ${modeData.ruleSetName} $diffStamp left" + return "S: ${modeData.ruleSetName}: $map1, $map2" + .replace("Rainmaker", "RMK") + .replace("Tower Control", "TC") + .replace("Splat Zones", "SZ") + .replace("Clam Blitz", "CB") } fun getXMapFormatted(timestamp: Long): String { val modeData = getXMode(timestamp) val map1 = modeData.map1!!.name.split(" ")[0] val map2 = modeData.map2!!.name.split(" ")[0] - return "X: $map1 & $map2" + return "X: ${modeData.ruleSetName}: $map1, $map2" + .replace("Rainmaker", "RMK") + .replace("Tower Control", "TC") + .replace("Splat Zones", "SZ") + .replace("Clam Blitz", "CB") } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index 31b687c..9f5688d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -41,27 +41,26 @@ object StatusUpdater : ICronjob { private var statusList = listOf() private var index = 0 + // I h8 this job. I'll recode this someday. override suspend fun jobFunction() { - refreshStatusList(System.currentTimeMillis()) + if (index >= statusList.size) { + index = 0 + refreshStatusList(System.currentTimeMillis()) + } Bot.bot.kordRef.editPresence { this.status = PresenceStatus.DoNotDisturb this.competing(statusList[index]) } ++index - if (index >= statusList.size) { - index = 0 - } } - fun refreshStatusList(timestamp: Long) { + private fun refreshStatusList(timestamp: Long) { statusList = listOf( + Splatoon3Api.getRotationTime(timestamp), Splatoon3Api.getRegularMapsFormatted(timestamp), - Splatoon3Api.getSeriesModeFormatted(timestamp), - Splatoon3Api.getSeriesMapsFormatted(timestamp), - Splatoon3Api.getOpenModeFormatted(timestamp), Splatoon3Api.getOpenMapFormatted(timestamp), - Splatoon3Api.getXModeFormatted(timestamp), - Splatoon3Api.getXMapFormatted(timestamp), + Splatoon3Api.getSeriesMapsFormatted(timestamp), + Splatoon3Api.getXMapFormatted(timestamp) ) } } -- 2.45.2 From d71db45532de2dd5be6c9acc3187944e510a3bdc Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 7 Dec 2023 18:20:07 +0100 Subject: [PATCH 132/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4931cd8..4b5ed07 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.6.6" + ?: "2.6.7" val kordver = "1.5.9-SNAPSHOT" val coroutinesver = "1.7.3" -- 2.45.2 From 32da9ac7af44454e575403e19b24ca19d970844c Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 19 Dec 2023 09:31:50 +0100 Subject: [PATCH 133/168] chore: upgrade gradle Signed-off-by: moonleay --- gradle/wrapper/gradle-wrapper.jar | Bin 59821 -> 63721 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++- gradlew | 31 +++++++++++++++++------ gradlew.bat | 15 ++++++----- 4 files changed, 35 insertions(+), 15 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 41d9927a4d4fb3f96a785543079b8df6723c946b..7f93135c49b765f8051ef9d0a6055ff8e46073d8 100644 GIT binary patch delta 44451 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 W0}GkPe@wIjfE;Yd41Mt9+y4Mm#rGos delta 40585 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�Kz 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 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 14cf480..488e2ca 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -18,6 +18,8 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip +networkTimeout=10000 +validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index 99d219e..6e2d6e1 100755 --- a/gradlew +++ b/gradlew @@ -57,7 +57,7 @@ # Darwin, MinGW, and NonStop. # # (3) This script is generated from the Groovy template -# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt # within the Gradle project. # # You can find Gradle at https://github.com/gradle/gradle/. @@ -82,13 +82,11 @@ do esac done -APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit - -APP_NAME="Gradle" +# This is normally unused +# shellcheck disable=SC2034 APP_BASE_NAME=${0##*/} - -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit # Use the maximum available, or set MAX_FD != -1 to use that value. MAX_FD=maximum @@ -135,22 +133,29 @@ location of your Java installation." fi else JAVACMD=java - which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + if ! command -v java >/dev/null 2>&1 + then + die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the location of your Java installation." + fi fi # Increase the maximum file descriptors if we can. if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac case $MAX_FD in #( '' | soft) :;; #( *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -195,6 +200,10 @@ if "$cygwin" || "$msys" ; then done fi + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + # Collect all arguments for the java command; # * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of # shell script including quotes and variable substitutions, so put them in @@ -207,6 +216,12 @@ set -- \ org.gradle.wrapper.GradleWrapperMain \ "$@" +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + # Use "xargs" to parse quoted args. # # With -n1 it outputs one arg per line, with the quotes and backslashes removed. diff --git a/gradlew.bat b/gradlew.bat index 107acd3..93e3f59 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -14,7 +14,7 @@ @rem limitations under the License. @rem -@if "%DEBUG%" == "" @echo off +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -25,7 +25,8 @@ if "%OS%"=="Windows_NT" setlocal set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% @@ -40,7 +41,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto execute +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -75,13 +76,15 @@ set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal -- 2.45.2 From b2c43e2c0491efcbdab02b0a57febb9465067cc9 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 19 Dec 2023 10:28:04 +0100 Subject: [PATCH 134/168] chore: upgrade dependencies Signed-off-by: moonleay --- build.gradle.kts | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4b5ed07..00e0104 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -34,12 +34,12 @@ version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_ ?: System.getenv("CI_COMMIT_SHORT_SHA")?.let { "$it-dev" } ?: "2.6.7" -val kordver = "1.5.9-SNAPSHOT" +val kordver = "1.7.1-SNAPSHOT" val coroutinesver = "1.7.3" -val ktorver = "2.3.5" -val exposedver = "0.43.0" -val postgresver = "42.6.0" -val krontabver = "2.2.1" +val ktorver = "2.3.7" +val exposedver = "0.45.0" +val postgresver = "42.7.1" +val krontabver = "2.2.4" val mavenArtifact = "lilJudd" project.base.archivesName.set(mavenArtifact) @@ -105,8 +105,8 @@ dependencies { //Krontab shadow("dev.inmo:krontab:$krontabver") - shadow("io.ktor:ktor-client-core-jvm:2.3.5") - shadow("io.ktor:ktor-client-cio-jvm:2.3.5") + shadow("io.ktor:ktor-client-core-jvm:$ktorver") + shadow("io.ktor:ktor-client-cio-jvm:$ktorver") } -- 2.45.2 From fc7edc0d0d05ede2bad6cec9e9e764b426535721 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 19 Dec 2023 10:28:49 +0100 Subject: [PATCH 135/168] feat!: improved MessageUtil Signed-off-by: moonleay --- .../net/moonleay/lilJudd/util/MessageUtil.kt | 74 +------------------ 1 file changed, 4 insertions(+), 70 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt index 6dfb545..3307f58 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt @@ -18,10 +18,7 @@ package net.moonleay.lilJudd.util -import com.kotlindiscord.kord.extensions.commands.Arguments -import com.kotlindiscord.kord.extensions.commands.application.slash.PublicSlashCommandContext -import com.kotlindiscord.kord.extensions.components.forms.ModalForm -import com.kotlindiscord.kord.extensions.types.respond +import dev.kord.core.behavior.UserBehavior import dev.kord.core.entity.Embed import dev.kord.rest.builder.message.EmbedBuilder import java.time.LocalDateTime @@ -30,44 +27,9 @@ import java.time.format.DateTimeFormatter object MessageUtil { private val dtf: DateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy @ HH:mm:ss") - ///Send an embedded message as a reply - suspend fun sendEmbedForPublicSlashCommand( - ctx: PublicSlashCommandContext, - color: EmbedColor, - title: String, - description: String - ) { - ctx.respond { - embeds.add( - getEmbed( - color, - title, - description, - ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator - ) - ) - } - } - - ///Send an embedded message with an image as a reply - suspend fun sendEmbedForPublicSlashCommandWithImage( - ctx: PublicSlashCommandContext, - color: EmbedColor, - title: String, - description: String, - thumbnailUrl: String - ) { - ctx.respond { - embeds.add( - getEmbedWithImage( - color, - title, - description, - ctx.user.asUser().username + "#" + ctx.user.asUser().discriminator, - thumbnailUrl - ) - ) - } + suspend fun getFooter(u: UserBehavior? = null): String { + val now: LocalDateTime = LocalDateTime.now() + return ">" + dtf.format(now) + " - ${u?.asUser()?.username ?: "Automated Message"}" } ///Get a cloned embedded message @@ -101,20 +63,6 @@ object MessageUtil { return ebb } - fun getEmbedWithTableWithFooter( - color: EmbedColor, - title: String, - description: String, - values: Map>?, - footer: String - ): EmbedBuilder { - val ebb = getEmbedWithTable(color, title, description, values) - ebb.footer = EmbedBuilder.Footer() - ebb.footer!!.text = ">m.id/$footer" - return ebb - } - - ///Get an embedded msg with image, title and description fun getEmbedWithTable( color: EmbedColor, title: String, @@ -136,7 +84,6 @@ object MessageUtil { return ebb } - ///Get an embedded msg with title and description fun getEmbedSmall( color: EmbedColor, @@ -164,17 +111,4 @@ object MessageUtil { return ebb } - ///Get an embedded msg with image, title, description and a src - fun getEmbedWithImage( - color: EmbedColor, - title: String, - description: String, - source: String, - thumbnailUrl: String - ): EmbedBuilder { - val ebb = getEmbed(color, title, description, source) - ebb.thumbnail = EmbedBuilder.Thumbnail() - ebb.thumbnail!!.url = thumbnailUrl - return ebb - } } -- 2.45.2 From a2dafa5c7229628cf887076342ac46a94634d795 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 19 Dec 2023 10:29:53 +0100 Subject: [PATCH 136/168] fix: fixed all exceptions, which were caused by upgrading dependencies Signed-off-by: moonleay --- .../buttons/matchplanner/AcceptEditButton.kt | 17 ++--- .../buttons/matchplanner/CancelEditButton.kt | 17 ++--- .../buttons/matchplanner/DeclineEditButton.kt | 17 ++--- .../timeplanner/IsAvailableEditButton.kt | 2 +- .../timeplanner/MaybeAvailableEditButton.kt | 2 +- .../timeplanner/NotAvailableEditButton.kt | 2 +- .../extensions/FeatureManageExtension.kt | 59 ++++++++++----- .../lilJudd/extensions/InfoExtension.kt | 23 +++--- .../lilJudd/extensions/MatchExtension.kt | 72 +++++++++++-------- .../extensions/SendPlannerExtension.kt | 55 ++++++++------ .../extensions/UpdateRolesExtension.kt | 41 +++++------ .../moonleay/lilJudd/features/TimeManager.kt | 69 ++++++++++-------- .../moonleay/lilJudd/jobs/StatusUpdater.kt | 2 +- 13 files changed, 218 insertions(+), 160 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt index 4e04fa1..ffb7759 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt @@ -25,7 +25,8 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.EmbedBuilder +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository @@ -89,13 +90,13 @@ class AcceptEditButton() : IEditButton { if (shouldEditButton) { // update the message Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { - this.embed { - this.color = eb.color - this.title = eb.title - this.description = eb.description - this.fields = eb.fields - this.footer = eb.footer - } + this.embed(fun EmbedBuilder.() { + color = eb.color + title = eb.title + description = eb.description + fields = eb.fields + footer = eb.footer + }) } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt index 348446c..12eaea1 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt @@ -25,7 +25,8 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.EmbedBuilder +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository @@ -62,14 +63,14 @@ class CancelEditButton : IEditButton { member.removeRole(role.id) } Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { - this.embed { + this.embed(fun EmbedBuilder.() { val temp = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 1) - this.color = temp.color - this.title = temp.title - this.description = temp.description - this.fields = temp.fields - this.footer = temp.footer - } + color = temp.color + title = temp.title + description = temp.description + fields = temp.fields + footer = temp.footer + }) } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt index 93f6b36..12c8375 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt @@ -25,7 +25,8 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.EmbedBuilder +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository @@ -89,13 +90,13 @@ class DeclineEditButton : IEditButton { if (shouldEditButton) { // update the message Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { - this.embed { - this.color = eb.color - this.title = eb.title - this.description = eb.description - this.fields = eb.fields - this.footer = eb.footer - } + this.embed(fun EmbedBuilder.() { + color = eb.color + title = eb.title + description = eb.description + fields = eb.fields + footer = eb.footer + }) } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt index 9dbae16..ccc67fd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt @@ -24,7 +24,7 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.features.AvailabilityManager diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt index 01cf792..a8b174c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt @@ -24,7 +24,7 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.features.AvailabilityManager diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt index ade9557..e5e8103 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt @@ -24,7 +24,7 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.features.AvailabilityManager diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index e09786c..ef1c52a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -23,9 +23,9 @@ import com.kotlindiscord.kord.extensions.commands.application.slash.converters.i import com.kotlindiscord.kord.extensions.commands.converters.impl.channel import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.extensions.component.EnableOrDisable import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.FeatureManager @@ -49,14 +49,16 @@ class FeatureManageExtension : Extension() { val u = this.user if (!u.asMember(this.guild!!.id).hasPermission(Permission.Administrator)) { this.respond { - embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "403: Forbidden", - "You cannot edit features, as you don't have the Administrator permission.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "403: Forbidden" + this.description = + "You cannot edit features, as you don't have the Administrator permission." + this.footer { + this.icon = u.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(u) + } + } } return@action } @@ -68,26 +70,45 @@ class FeatureManageExtension : Extension() { val f = FeatureManager.getFeature(args.feature) if (f == null) { this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "404: Not Found", - "The feature you are trying to edit does not exist.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "404: Not Found" + this.description = "The feature you are trying to edit does not exist." + this.footer { + this.icon = u.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(u) + } + } } return@action } if (this.arguments.setStatus == EnableOrDisable.ENABLE) { + val enabled = f.enable(u, gID, cID, channel, args) this.respond { - this.embeds.add(f.enable(u, gID, cID, channel, args)) + this.embed { + this.color = enabled.color + this.title = enabled.title + this.description = enabled.description + this.footer { + this.icon = u.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(u) + } + } } return@action } + val disabled = f.disable(u, gID, cID, channel, args) this.respond { - this.embeds.add(f.disable(u, gID, cID, channel, args)) + this.embed { + this.color = disabled.color + this.title = disabled.title + this.description = disabled.description + this.footer { + this.icon = u.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(u) + } + } } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt index 6445faf..4928043 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt @@ -20,8 +20,8 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.util.EmbedColor -import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.liljudd.build.BuildConstants class InfoExtension : Extension() { @@ -31,16 +31,17 @@ class InfoExtension : Extension() { name = "info" description = "Show infos about the bot" this.action { - MessageUtil.sendEmbedForPublicSlashCommand( - this, - EmbedColor.INFO, - "Lil' Judd", - "Lil' Judd ***v." + BuildConstants.version + "***\n" + - "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" + - "Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n" + - "Krontab ***v." + BuildConstants.krontabVersion + "***\n\n" + - "Splatoon 3 api data provided by splatoon3.ink" - ) + this.respond { + this.embed { + this.color = EmbedColor.INFO.color + this.title = "Li'l Judd" + this.description = "Li'l Judd ***v." + BuildConstants.version + "***\n" + + "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" + + "Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n" + + "Krontab ***v." + BuildConstants.krontabVersion + "***\n\n" + + "Splatoon 3 api data provided by splatoon3.ink" + } + } } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index 118d368..e825baa 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -23,9 +23,9 @@ import com.kotlindiscord.kord.extensions.commands.application.slash.converters.i import com.kotlindiscord.kord.extensions.commands.converters.impl.string import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond import dev.kord.core.behavior.createRole -import dev.kord.rest.builder.message.create.actionRow +import dev.kord.rest.builder.message.actionRow +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.extensions.component.MatchTypes @@ -55,15 +55,16 @@ class MatchExtension : Extension() { val opponent = args.opponent if (!TimeUtil.validateDateString(args.timeStamp)) { this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "400: Bad Request", - "The given timestamp is invalid.\n" + - "Please use the format \"dd.MM.yyyy HH:mm\".", - m.asUser().username - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "400: Bad Request" + this.description = "The given timestamp is invalid.\n" + + "Please use the format \"dd.MM.yyyy HH:mm\"." + this.footer { + this.icon = m.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(m.asUser()) + } + } } return@action } @@ -80,32 +81,41 @@ class MatchExtension : Extension() { // Check if the role was created successfully if (role == null) { this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "500: Internal Error", - "Could not find created role.\n" + - "It seems, that said role could not be created.", - m.asUser().username - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "500: Internal Error" + this.description = "Could not find created role.\n" + + "It seems, that said role could not be created." + this.footer { + this.icon = m.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(m.asUser()) + } + } } return@action } val msg = this.respond { - this.embeds.add( - MessageUtil.getEmbedWithTable( - EmbedColor.INFO, - args.matchType.readableName, - "***Vs. $opponent***\n" + - "At ${args.timeStamp}\n" + - "Registered by ${m.mention}", - mapOf( - "Signed up" to listOf(), - "Unavailable" to listOf(), - ) + val eb = MessageUtil.getEmbedWithTable( + EmbedColor.INFO, + args.matchType.readableName, + "***Vs. $opponent***\n" + + "At ${args.timeStamp}\n" + + "Registered by ${m.mention}", + mapOf( + "Signed up" to listOf(), + "Unavailable" to listOf(), ) ) + this.embed { + this.color = eb.color + this.title = eb.title + this.description = eb.description + this.fields = eb.fields + this.footer { + this.icon = m.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(m.asUser()) + } + } this.actionRow { this.components.addAll(EmbedUtil.getMatchButtons().components) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index 781de2c..87a6abb 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -20,12 +20,13 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission import dev.kord.core.behavior.channel.createMessage -import dev.kord.rest.builder.message.create.actionRow +import dev.kord.rest.builder.message.actionRow +import dev.kord.rest.builder.message.embed import kotlinx.coroutines.delay +import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData import net.moonleay.lilJudd.data.database.repository.TimePlanningMessagesRepository import net.moonleay.lilJudd.util.* @@ -64,30 +65,40 @@ class SendPlannerExtension : Extension() { .withHour(4) .withMinute(0).withSecond(0) c.createMessage { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.INFO, - "Time Planning Feature", - "Do you have time on the following Days?", - "Automated Message" - ) - ) + this.embed { + this.color = EmbedColor.INFO.color + this.title = "Time Planning Feature" + this.description = "Do you have time on the following Days?" + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } } delay(1000) repeat(7) { - val msg = c.createMessage { - this.embeds.add( - MessageUtil.getEmbedWithTable( - EmbedColor.INFO, - "", - "${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() - ) - ) + val eb = MessageUtil.getEmbedWithTable( + EmbedColor.INFO, + "", + "${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() ) + ) + + val msg = c.createMessage { + this.embed { + this.color = eb.color + this.title = eb.title + this.description = eb.description + this.fields = eb.fields + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } this.actionRow { this.components.addAll(EmbedUtil.getTimePlannerButtons().components) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt index be6ba80..8d8e986 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt @@ -20,9 +20,9 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger @@ -42,30 +42,31 @@ class UpdateRolesExtension : Extension() { .hasPermission(Permission.Administrator) ) { this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "403: Forbidden", - "You need to be an administrator to use this command.", - user.asUser().username + "#" + user.asUser().discriminator - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "403: Forbidden" + this.description = + "You cannot update roles, as you don't have the Administrator permission." + this.footer { + this.icon = user.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(user) + } + } } return@action } this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.SUCCESS, - "200: Success", - "Updating roles.\n" + - "This may take a while, please be patient.", - user.asUser().username + "#" + user.asUser().discriminator - ) - ) + this.embed { + this.color = EmbedColor.INFO.color + this.title = "200: Success" + this.description = "Updating roles.\n" + + "This may take a while, please be patient." + this.footer { + this.icon = user.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(user) + } + } } - - // -- below here is the code of the cronjob -- Logger.out("Starting to update roles...") AvailabilityManager.updateInChannel(this.channel.id) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index ec073ac..87018df 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -26,7 +26,8 @@ import dev.kord.core.behavior.channel.createMessage import dev.kord.core.entity.channel.Channel import dev.kord.core.entity.channel.MessageChannel import dev.kord.rest.builder.message.EmbedBuilder -import dev.kord.rest.builder.message.create.actionRow +import dev.kord.rest.builder.message.actionRow +import dev.kord.rest.builder.message.embed import kotlinx.coroutines.delay import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.data.database.entry.TimePlanningChannelsData @@ -78,43 +79,53 @@ object TimeManager : IFeature { c.createMessage { this.content = "The weekly planning starts now <@&${Snowflake(targetedRoles[ch2]?.wantsToBeNotifiedID!!)}>" - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.INFO, - "Time Planning Feature", - "Do you have time on the following Days?", - "Automated Message" - ) - ) + this.embed { + this.color = EmbedColor.INFO.color + this.title = "Time Planning Feature" + this.description = "Do you have time on the following Days?" + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } } } else { c.createMessage { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.INFO, - "Time Planning Feature", - "Do you have time on the following Days?", - "Automated Message" - ) - ) + this.embed { + this.color = EmbedColor.INFO.color + this.title = "Time Planning Feature" + this.description = "Do you have time on the following Days?" + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } } } delay(2000) var then = ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withHour(4).withMinute(0).withSecond(0) repeat(7) { - val msg = c.createMessage { - this.embeds.add( - MessageUtil.getEmbedWithTable( - EmbedColor.INFO, - "", - "${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() - ) - ) + val eb = MessageUtil.getEmbedWithTable( + EmbedColor.INFO, + "", + "${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() ) + ) + val msg = c.createMessage { + this.embed { + this.color = eb.color + this.title = eb.title + this.description = eb.description + this.fields = eb.fields + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } this.actionRow { this.components.addAll(EmbedUtil.getTimePlannerButtons().components) diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index 9f5688d..762b498 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -41,7 +41,7 @@ object StatusUpdater : ICronjob { private var statusList = listOf() private var index = 0 - // I h8 this job. I'll recode this someday. + // I h8 this cronjob. I'll recode this someday. override suspend fun jobFunction() { if (index >= statusList.size) { index = 0 -- 2.45.2 From 5581f8f34885add387dff2d7129fe25a134856ad Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 19 Dec 2023 10:29:53 +0100 Subject: [PATCH 137/168] fix: fixed all exceptions, which were caused by upgrading dependencies chore!: rewrote all embeds as a result Signed-off-by: moonleay --- .../buttons/matchplanner/AcceptEditButton.kt | 17 ++--- .../buttons/matchplanner/CancelEditButton.kt | 17 ++--- .../buttons/matchplanner/DeclineEditButton.kt | 17 ++--- .../timeplanner/IsAvailableEditButton.kt | 2 +- .../timeplanner/MaybeAvailableEditButton.kt | 2 +- .../timeplanner/NotAvailableEditButton.kt | 2 +- .../extensions/FeatureManageExtension.kt | 59 ++++++++++----- .../lilJudd/extensions/InfoExtension.kt | 23 +++--- .../lilJudd/extensions/MatchExtension.kt | 72 +++++++++++-------- .../extensions/SendPlannerExtension.kt | 55 ++++++++------ .../extensions/UpdateRolesExtension.kt | 41 +++++------ .../moonleay/lilJudd/features/TimeManager.kt | 69 ++++++++++-------- .../moonleay/lilJudd/jobs/StatusUpdater.kt | 2 +- 13 files changed, 218 insertions(+), 160 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt index 4e04fa1..ffb7759 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt @@ -25,7 +25,8 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.EmbedBuilder +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository @@ -89,13 +90,13 @@ class AcceptEditButton() : IEditButton { if (shouldEditButton) { // update the message Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { - this.embed { - this.color = eb.color - this.title = eb.title - this.description = eb.description - this.fields = eb.fields - this.footer = eb.footer - } + this.embed(fun EmbedBuilder.() { + color = eb.color + title = eb.title + description = eb.description + fields = eb.fields + footer = eb.footer + }) } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt index 348446c..12eaea1 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt @@ -25,7 +25,8 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.EmbedBuilder +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository @@ -62,14 +63,14 @@ class CancelEditButton : IEditButton { member.removeRole(role.id) } Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { - this.embed { + this.embed(fun EmbedBuilder.() { val temp = EmbedUtil.replaceXWithYinValuesAtTable(user.id.value.toString(), "", m.embeds[0], 1) - this.color = temp.color - this.title = temp.title - this.description = temp.description - this.fields = temp.fields - this.footer = temp.footer - } + color = temp.color + title = temp.title + description = temp.description + fields = temp.fields + footer = temp.footer + }) } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt index 93f6b36..12c8375 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt @@ -25,7 +25,8 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.EmbedBuilder +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository @@ -89,13 +90,13 @@ class DeclineEditButton : IEditButton { if (shouldEditButton) { // update the message Bot.bot.kordRef.getChannelOf(interaction.channelId)!!.getMessage(m.id).edit { - this.embed { - this.color = eb.color - this.title = eb.title - this.description = eb.description - this.fields = eb.fields - this.footer = eb.footer - } + this.embed(fun EmbedBuilder.() { + color = eb.color + title = eb.title + description = eb.description + fields = eb.fields + footer = eb.footer + }) } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt index 9dbae16..ccc67fd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt @@ -24,7 +24,7 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.features.AvailabilityManager diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt index 01cf792..a8b174c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt @@ -24,7 +24,7 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.features.AvailabilityManager diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt index ade9557..e5e8103 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt @@ -24,7 +24,7 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction -import dev.kord.rest.builder.message.modify.embed +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.buttons.component.IEditButton import net.moonleay.lilJudd.features.AvailabilityManager diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index e09786c..ef1c52a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -23,9 +23,9 @@ import com.kotlindiscord.kord.extensions.commands.application.slash.converters.i import com.kotlindiscord.kord.extensions.commands.converters.impl.channel import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.extensions.component.EnableOrDisable import net.moonleay.lilJudd.features.component.FeatureEnum import net.moonleay.lilJudd.features.component.FeatureManager @@ -49,14 +49,16 @@ class FeatureManageExtension : Extension() { val u = this.user if (!u.asMember(this.guild!!.id).hasPermission(Permission.Administrator)) { this.respond { - embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "403: Forbidden", - "You cannot edit features, as you don't have the Administrator permission.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "403: Forbidden" + this.description = + "You cannot edit features, as you don't have the Administrator permission." + this.footer { + this.icon = u.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(u) + } + } } return@action } @@ -68,26 +70,45 @@ class FeatureManageExtension : Extension() { val f = FeatureManager.getFeature(args.feature) if (f == null) { this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "404: Not Found", - "The feature you are trying to edit does not exist.", - u.asUser().username + "#" + u.asUser().discriminator - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "404: Not Found" + this.description = "The feature you are trying to edit does not exist." + this.footer { + this.icon = u.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(u) + } + } } return@action } if (this.arguments.setStatus == EnableOrDisable.ENABLE) { + val enabled = f.enable(u, gID, cID, channel, args) this.respond { - this.embeds.add(f.enable(u, gID, cID, channel, args)) + this.embed { + this.color = enabled.color + this.title = enabled.title + this.description = enabled.description + this.footer { + this.icon = u.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(u) + } + } } return@action } + val disabled = f.disable(u, gID, cID, channel, args) this.respond { - this.embeds.add(f.disable(u, gID, cID, channel, args)) + this.embed { + this.color = disabled.color + this.title = disabled.title + this.description = disabled.description + this.footer { + this.icon = u.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(u) + } + } } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt index 6445faf..4928043 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt @@ -20,8 +20,8 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.util.EmbedColor -import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.liljudd.build.BuildConstants class InfoExtension : Extension() { @@ -31,16 +31,17 @@ class InfoExtension : Extension() { name = "info" description = "Show infos about the bot" this.action { - MessageUtil.sendEmbedForPublicSlashCommand( - this, - EmbedColor.INFO, - "Lil' Judd", - "Lil' Judd ***v." + BuildConstants.version + "***\n" + - "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" + - "Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n" + - "Krontab ***v." + BuildConstants.krontabVersion + "***\n\n" + - "Splatoon 3 api data provided by splatoon3.ink" - ) + this.respond { + this.embed { + this.color = EmbedColor.INFO.color + this.title = "Li'l Judd" + this.description = "Li'l Judd ***v." + BuildConstants.version + "***\n" + + "Kord-Extensions ***v." + BuildConstants.kordVersion + "***\n" + + "Coroutines ***v." + BuildConstants.coroutinesVersion + "***\n" + + "Krontab ***v." + BuildConstants.krontabVersion + "***\n\n" + + "Splatoon 3 api data provided by splatoon3.ink" + } + } } } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt index 118d368..e825baa 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt @@ -23,9 +23,9 @@ import com.kotlindiscord.kord.extensions.commands.application.slash.converters.i import com.kotlindiscord.kord.extensions.commands.converters.impl.string import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond import dev.kord.core.behavior.createRole -import dev.kord.rest.builder.message.create.actionRow +import dev.kord.rest.builder.message.actionRow +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository import net.moonleay.lilJudd.extensions.component.MatchTypes @@ -55,15 +55,16 @@ class MatchExtension : Extension() { val opponent = args.opponent if (!TimeUtil.validateDateString(args.timeStamp)) { this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "400: Bad Request", - "The given timestamp is invalid.\n" + - "Please use the format \"dd.MM.yyyy HH:mm\".", - m.asUser().username - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "400: Bad Request" + this.description = "The given timestamp is invalid.\n" + + "Please use the format \"dd.MM.yyyy HH:mm\"." + this.footer { + this.icon = m.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(m.asUser()) + } + } } return@action } @@ -80,32 +81,41 @@ class MatchExtension : Extension() { // Check if the role was created successfully if (role == null) { this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "500: Internal Error", - "Could not find created role.\n" + - "It seems, that said role could not be created.", - m.asUser().username - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "500: Internal Error" + this.description = "Could not find created role.\n" + + "It seems, that said role could not be created." + this.footer { + this.icon = m.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(m.asUser()) + } + } } return@action } val msg = this.respond { - this.embeds.add( - MessageUtil.getEmbedWithTable( - EmbedColor.INFO, - args.matchType.readableName, - "***Vs. $opponent***\n" + - "At ${args.timeStamp}\n" + - "Registered by ${m.mention}", - mapOf( - "Signed up" to listOf(), - "Unavailable" to listOf(), - ) + val eb = MessageUtil.getEmbedWithTable( + EmbedColor.INFO, + args.matchType.readableName, + "***Vs. $opponent***\n" + + "At ${args.timeStamp}\n" + + "Registered by ${m.mention}", + mapOf( + "Signed up" to listOf(), + "Unavailable" to listOf(), ) ) + this.embed { + this.color = eb.color + this.title = eb.title + this.description = eb.description + this.fields = eb.fields + this.footer { + this.icon = m.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(m.asUser()) + } + } this.actionRow { this.components.addAll(EmbedUtil.getMatchButtons().components) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index 781de2c..87a6abb 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -20,12 +20,13 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission import dev.kord.core.behavior.channel.createMessage -import dev.kord.rest.builder.message.create.actionRow +import dev.kord.rest.builder.message.actionRow +import dev.kord.rest.builder.message.embed import kotlinx.coroutines.delay +import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData import net.moonleay.lilJudd.data.database.repository.TimePlanningMessagesRepository import net.moonleay.lilJudd.util.* @@ -64,30 +65,40 @@ class SendPlannerExtension : Extension() { .withHour(4) .withMinute(0).withSecond(0) c.createMessage { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.INFO, - "Time Planning Feature", - "Do you have time on the following Days?", - "Automated Message" - ) - ) + this.embed { + this.color = EmbedColor.INFO.color + this.title = "Time Planning Feature" + this.description = "Do you have time on the following Days?" + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } } delay(1000) repeat(7) { - val msg = c.createMessage { - this.embeds.add( - MessageUtil.getEmbedWithTable( - EmbedColor.INFO, - "", - "${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() - ) - ) + val eb = MessageUtil.getEmbedWithTable( + EmbedColor.INFO, + "", + "${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() ) + ) + + val msg = c.createMessage { + this.embed { + this.color = eb.color + this.title = eb.title + this.description = eb.description + this.fields = eb.fields + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } this.actionRow { this.components.addAll(EmbedUtil.getTimePlannerButtons().components) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt index be6ba80..8d8e986 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt @@ -20,9 +20,9 @@ package net.moonleay.lilJudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand -import com.kotlindiscord.kord.extensions.types.respond import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission +import dev.kord.rest.builder.message.embed import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger @@ -42,30 +42,31 @@ class UpdateRolesExtension : Extension() { .hasPermission(Permission.Administrator) ) { this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.ERROR, - "403: Forbidden", - "You need to be an administrator to use this command.", - user.asUser().username + "#" + user.asUser().discriminator - ) - ) + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "403: Forbidden" + this.description = + "You cannot update roles, as you don't have the Administrator permission." + this.footer { + this.icon = user.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(user) + } + } } return@action } this.respond { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.SUCCESS, - "200: Success", - "Updating roles.\n" + - "This may take a while, please be patient.", - user.asUser().username + "#" + user.asUser().discriminator - ) - ) + this.embed { + this.color = EmbedColor.INFO.color + this.title = "200: Success" + this.description = "Updating roles.\n" + + "This may take a while, please be patient." + this.footer { + this.icon = user.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(user) + } + } } - - // -- below here is the code of the cronjob -- Logger.out("Starting to update roles...") AvailabilityManager.updateInChannel(this.channel.id) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index ec073ac..87018df 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -26,7 +26,8 @@ import dev.kord.core.behavior.channel.createMessage import dev.kord.core.entity.channel.Channel import dev.kord.core.entity.channel.MessageChannel import dev.kord.rest.builder.message.EmbedBuilder -import dev.kord.rest.builder.message.create.actionRow +import dev.kord.rest.builder.message.actionRow +import dev.kord.rest.builder.message.embed import kotlinx.coroutines.delay import net.moonleay.lilJudd.Bot import net.moonleay.lilJudd.data.database.entry.TimePlanningChannelsData @@ -78,43 +79,53 @@ object TimeManager : IFeature { c.createMessage { this.content = "The weekly planning starts now <@&${Snowflake(targetedRoles[ch2]?.wantsToBeNotifiedID!!)}>" - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.INFO, - "Time Planning Feature", - "Do you have time on the following Days?", - "Automated Message" - ) - ) + this.embed { + this.color = EmbedColor.INFO.color + this.title = "Time Planning Feature" + this.description = "Do you have time on the following Days?" + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } } } else { c.createMessage { - this.embeds.add( - MessageUtil.getEmbed( - EmbedColor.INFO, - "Time Planning Feature", - "Do you have time on the following Days?", - "Automated Message" - ) - ) + this.embed { + this.color = EmbedColor.INFO.color + this.title = "Time Planning Feature" + this.description = "Do you have time on the following Days?" + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } } } delay(2000) var then = ZonedDateTime.now(ZoneId.of("Europe/Berlin")).withHour(4).withMinute(0).withSecond(0) repeat(7) { - val msg = c.createMessage { - this.embeds.add( - MessageUtil.getEmbedWithTable( - EmbedColor.INFO, - "", - "${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() - ) - ) + val eb = MessageUtil.getEmbedWithTable( + EmbedColor.INFO, + "", + "${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() ) + ) + val msg = c.createMessage { + this.embed { + this.color = eb.color + this.title = eb.title + this.description = eb.description + this.fields = eb.fields + this.footer { + this.icon = Bot.bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } this.actionRow { this.components.addAll(EmbedUtil.getTimePlannerButtons().components) diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index 9f5688d..762b498 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -41,7 +41,7 @@ object StatusUpdater : ICronjob { private var statusList = listOf() private var index = 0 - // I h8 this job. I'll recode this someday. + // I h8 this cronjob. I'll recode this someday. override suspend fun jobFunction() { if (index >= statusList.size) { index = 0 -- 2.45.2 From c1536b259b9741b4057e3632eec50bd28cc3cb07 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 19 Dec 2023 10:37:39 +0100 Subject: [PATCH 138/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 00e0104..f2891f1 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.6.7" + ?: "2.6.8" val kordver = "1.7.1-SNAPSHOT" val coroutinesver = "1.7.3" -- 2.45.2 From d8753a8c1fed1264388c99b63a5f0b7586410ac6 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 19 Dec 2023 10:59:31 +0100 Subject: [PATCH 139/168] fix: updated Error messages to better fit the HTTP standard Signed-off-by: moonleay --- .../extensions/FeatureManageExtension.kt | 2 +- .../extensions/SendPlannerExtension.kt | 22 +++++++++++++++++-- .../extensions/UpdateRolesExtension.kt | 4 ++-- .../moonleay/lilJudd/features/TimeManager.kt | 12 +++++----- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt index ef1c52a..21e7bec 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt @@ -51,7 +51,7 @@ class FeatureManageExtension : Extension() { this.respond { this.embed { this.color = EmbedColor.ERROR.color - this.title = "403: Forbidden" + this.title = "401: Not Authorized" this.description = "You cannot edit features, as you don't have the Administrator permission." this.footer { diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index 87a6abb..acd59f4 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -49,13 +49,31 @@ class SendPlannerExtension : Extension() { .hasPermission(Permission.Administrator) ) { val res = this.respond { - this.content = "You need to be an administrator to use this command." + this.embed { + this.color = EmbedColor.ERROR.color + this.title = "401: Not Authorized" + this.description = + "You need the Administrator permission to use this command." + this.footer { + this.icon = user.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(user) + } + } } res.delete() return@action } val res = this.respond { - this.content = "OK." + this.embed { + this.color = EmbedColor.INFO.color + this.title = "200: Success" + this.description = "Sending the planner.\n" + + "This may take a while, please be patient." + this.footer { + this.icon = user.asUser().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter(user) + } + } } res.delete() // Delete the response val c = this.getChannel().asChannel() diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt index 8d8e986..1d0ad06 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt @@ -44,9 +44,9 @@ class UpdateRolesExtension : Extension() { this.respond { this.embed { this.color = EmbedColor.ERROR.color - this.title = "403: Forbidden" + this.title = "401: Not Authorized" this.description = - "You cannot update roles, as you don't have the Administrator permission." + "You need the Administrator permission to use this command." this.footer { this.icon = user.asUser().avatar?.cdnUrl?.toUrl() this.text = MessageUtil.getFooter(user) diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt index 87018df..a9cc7be 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt @@ -166,14 +166,14 @@ object TimeManager : IFeature { EmbedColor.SUCCESS, "200: Success", "The feature was enabled in channel ${args.channel.data.name.value}", - u.asUser().username + "#" + u.asUser().discriminator + u.asUser().username ) } return MessageUtil.getEmbed( EmbedColor.ERROR, - "403: Forbidden", + "409: Conflict", "The feature is already enabled in this channel.", - u.asUser().username + "#" + u.asUser().discriminator + u.asUser().username ) } @@ -192,15 +192,15 @@ object TimeManager : IFeature { EmbedColor.SUCCESS, "200: Success", "The feature was disabled.", - u.asUser().username + "#" + u.asUser().discriminator + u.asUser().username ) } // Do nothing; not in db return MessageUtil.getEmbed( EmbedColor.ERROR, - "403: Forbidden", + "409: Conflict", "The feature is already disabled in this channel.", - u.asUser().username + "#" + u.asUser().discriminator + u.asUser().username ) } } -- 2.45.2 From f3b28ac392998334d9ed547bb5487e4b010fac9e Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 31 Dec 2023 22:02:59 +0100 Subject: [PATCH 140/168] refactor: splatoon3ink api Signed-off-by: moonleay --- .../api/{ => splatoon3ink}/Splatoon3Api.kt | 4 +- .../{ => splatoon3ink}/Splatoon3ApiCache.kt | 40 ++++++++++--------- .../entry/coop/CoopGearData.kt | 2 +- .../entry/schedule/ChallengeModeData.kt | 2 +- .../entry/schedule/MapData.kt | 2 +- .../entry/schedule/ModeData.kt | 2 +- .../entry/schedule/ShiftData.kt | 2 +- .../entry/schedule/TimePeriodData.kt | 2 +- .../entry/schedule/WeaponData.kt | 2 +- .../entry/splatfest/SplatfestColor.kt | 2 +- .../entry/splatfest/SplatfestData.kt | 2 +- .../entry/splatfest/SplatfestTeamData.kt | 2 +- .../entry/splatfest/SplatfestTeamResults.kt | 2 +- .../entry/splatnet/BrandData.kt | 2 +- .../entry/splatnet/GearAbilityData.kt | 2 +- .../entry/splatnet/SplatnetItemData.kt | 2 +- .../{ => splatoon3ink}/type/ApiDataType.kt | 2 +- .../{ => splatoon3ink}/type/ApiRequestType.kt | 2 +- 18 files changed, 39 insertions(+), 37 deletions(-) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/Splatoon3Api.kt (97%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/Splatoon3ApiCache.kt (95%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/coop/CoopGearData.kt (93%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/schedule/ChallengeModeData.kt (94%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/schedule/MapData.kt (92%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/schedule/ModeData.kt (93%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/schedule/ShiftData.kt (94%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/schedule/TimePeriodData.kt (92%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/schedule/WeaponData.kt (92%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/splatfest/SplatfestColor.kt (92%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/splatfest/SplatfestData.kt (93%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/splatfest/SplatfestTeamData.kt (92%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/splatfest/SplatfestTeamResults.kt (94%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/splatnet/BrandData.kt (92%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/splatnet/GearAbilityData.kt (92%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/entry/splatnet/SplatnetItemData.kt (93%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/type/ApiDataType.kt (93%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/{ => splatoon3ink}/type/ApiRequestType.kt (94%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt similarity index 97% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt index 92ad889..8f097c3 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3Api.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt @@ -16,9 +16,9 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api +package net.moonleay.lilJudd.data.api.splatoon3ink -import net.moonleay.lilJudd.data.api.entry.schedule.ModeData +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule.ModeData import net.moonleay.lilJudd.util.TimeUtil object Splatoon3Api { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiCache.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiCache.kt index daba96d..30a9129 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/Splatoon3ApiCache.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiCache.kt @@ -16,21 +16,21 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api +package net.moonleay.lilJudd.data.api.splatoon3ink import io.ktor.http.* import kotlinx.serialization.json.* -import net.moonleay.lilJudd.data.api.entry.coop.CoopGearData -import net.moonleay.lilJudd.data.api.entry.schedule.* -import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestColor -import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestData -import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestTeamData -import net.moonleay.lilJudd.data.api.entry.splatfest.SplatfestTeamResults -import net.moonleay.lilJudd.data.api.entry.splatnet.BrandData -import net.moonleay.lilJudd.data.api.entry.splatnet.GearAbilityData -import net.moonleay.lilJudd.data.api.entry.splatnet.SplatnetItemData -import net.moonleay.lilJudd.data.api.type.ApiDataType -import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.coop.CoopGearData +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule.* +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest.SplatfestColor +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest.SplatfestData +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest.SplatfestTeamData +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest.SplatfestTeamResults +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet.BrandData +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet.GearAbilityData +import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet.SplatnetItemData +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.NetUtil import net.moonleay.liljudd.build.BuildConstants @@ -49,13 +49,14 @@ object Splatoon3ApiCache { internal var cachedChallengesData = mutableListOf() internal var cachedShiftData = mutableListOf() internal var cachedBigRunShiftData = mutableListOf() - internal var cachedCoopRewardsData = mutableListOf() + internal var cachedCoopRewardsData = + mutableListOf() internal var cachedSplatnetItemData = mutableListOf() internal var cachedSplatnetLimitedItemData = mutableListOf() internal lateinit var splatnetShopBrandData: BrandData internal lateinit var splatnetShopNextBrandData: BrandData fun updateData(dataType: ApiDataType, requestType: ApiRequestType) { - Logger.out("Updating data for $dataType with USER-AGENT: $user_agent") + Logger.out("Updating data for $dataType with USER-AGENT: ${user_agent}") Logger.out("Reason for update: $requestType") when (dataType) { ApiDataType.SCHEDULES -> { @@ -225,11 +226,12 @@ object Splatoon3ApiCache { val obj = it as JsonObject val imageURL = Url(obj.jsonObject["originalImage"]!!.jsonObject["url"]!!.jsonPrimitive.content) val id = obj.jsonObject["vsStageId"]!!.jsonPrimitive.int - cachedMapData[id] = MapData( - id, - imageURL, - it.jsonObject["name"]!!.jsonPrimitive.content - ) + cachedMapData[id] = + MapData( + id, + imageURL, + it.jsonObject["name"]!!.jsonPrimitive.content + ) } Logger.out("Updated maplist data") } catch (e: Exception) { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/coop/CoopGearData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/coop/CoopGearData.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/coop/CoopGearData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/coop/CoopGearData.kt index 4f46642..817a80a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/coop/CoopGearData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/coop/CoopGearData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.coop +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.coop import io.ktor.http.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ChallengeModeData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ChallengeModeData.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ChallengeModeData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ChallengeModeData.kt index c288fe9..87efd9d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ChallengeModeData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ChallengeModeData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule data class ChallengeModeData( val leagueMatchEventId: String, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/MapData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/MapData.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/MapData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/MapData.kt index 422783c..b64755d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/MapData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/MapData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule import io.ktor.http.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ModeData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ModeData.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ModeData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ModeData.kt index 8295a1a..c3ad3dc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ModeData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ModeData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule data class ModeData( val startTime: String, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ShiftData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ShiftData.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ShiftData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ShiftData.kt index a4d28ae..f6f29f1 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/ShiftData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ShiftData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule import io.ktor.http.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/TimePeriodData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/TimePeriodData.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/TimePeriodData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/TimePeriodData.kt index 53edb96..dc66844 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/TimePeriodData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/TimePeriodData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule data class TimePeriodData( val startTime: String, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/WeaponData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/WeaponData.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/WeaponData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/WeaponData.kt index 997a24b..025ef87 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/schedule/WeaponData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/WeaponData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule import io.ktor.http.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestColor.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestColor.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestColor.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestColor.kt index 391ccb3..9f61bd7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestColor.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestColor.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.splatfest +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest data class SplatfestColor( val a: Int, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestData.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestData.kt index f52b9b4..fb11b19 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.splatfest +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest import io.ktor.http.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamData.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamData.kt index 9ea2e72..b29ee85 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.splatfest +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest data class SplatfestTeamData( val teamName: String, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamResults.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamResults.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamResults.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamResults.kt index 4888adc..ff7b531 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatfest/SplatfestTeamResults.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamResults.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.splatfest +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest data class SplatfestTeamResults( val isWinner: Boolean, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/BrandData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/BrandData.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/BrandData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/BrandData.kt index 6781172..2c80240 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/BrandData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/BrandData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.splatnet +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet import io.ktor.http.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/GearAbilityData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/GearAbilityData.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/GearAbilityData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/GearAbilityData.kt index 713d946..81f2ee7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/GearAbilityData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/GearAbilityData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.splatnet +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet import io.ktor.http.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/SplatnetItemData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/SplatnetItemData.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/SplatnetItemData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/SplatnetItemData.kt index 43df20b..72268dd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/entry/splatnet/SplatnetItemData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/SplatnetItemData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.entry.splatnet +package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet import io.ktor.http.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiDataType.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiDataType.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiDataType.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiDataType.kt index 7123b0d..7cb7361 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiDataType.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiDataType.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.type +package net.moonleay.lilJudd.data.api.splatoon3ink.type enum class ApiDataType { SCHEDULES, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiRequestType.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiRequestType.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiRequestType.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiRequestType.kt index da20371..03a9add 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/type/ApiRequestType.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiRequestType.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.type +package net.moonleay.lilJudd.data.api.splatoon3ink.type enum class ApiRequestType(val nameToDisplay: String) { AUTOMATIC_CACHE_UPDATE("automatic request to update the cache"), -- 2.45.2 From e6803f6474bf2775e001ad074540d216e27477ab Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 1 Jan 2024 04:11:49 +0100 Subject: [PATCH 141/168] fix: finished removing useless paths from the refactor Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 13 +++++++++---- .../Splatoon3ApiFestivalAndCoopUpdateScheduler.kt | 8 ++++---- .../jobs/Splatoon3ApiScheduleUpdateScheduler.kt | 8 ++++---- .../jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt | 8 ++++---- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 9dba1b2..fcdc5e6 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -32,9 +32,9 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager -import net.moonleay.lilJudd.data.api.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.type.ApiDataType -import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType import net.moonleay.lilJudd.data.database.DB import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager @@ -74,6 +74,11 @@ object Bot { exitProcess(3) } + if (CredentialManager.apiDomain == "empty" || CredentialManager.apiToken == "empty") { + Logger.out("The config does not contain the whole API credentials.") + exitProcess(3) + } + // Connect to the database DB.connect( CredentialManager.dbDomain, diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt index ff299fc..07f4a4b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -20,9 +20,9 @@ package net.moonleay.lilJudd.jobs import dev.inmo.krontab.KronScheduler import kotlinx.coroutines.Job -import net.moonleay.lilJudd.data.api.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.type.ApiDataType -import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType import net.moonleay.lilJudd.jobs.component.CronjobType import net.moonleay.lilJudd.jobs.component.ICronjob import net.moonleay.lilJudd.util.Logger diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt index 5c38b15..2a47939 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -20,9 +20,9 @@ package net.moonleay.lilJudd.jobs import dev.inmo.krontab.KronScheduler import kotlinx.coroutines.Job -import net.moonleay.lilJudd.data.api.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.type.ApiDataType -import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType import net.moonleay.lilJudd.jobs.component.CronjobType import net.moonleay.lilJudd.jobs.component.ICronjob import net.moonleay.lilJudd.util.Logger diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt index 51048f2..7bbc020 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -20,9 +20,9 @@ package net.moonleay.lilJudd.jobs import dev.inmo.krontab.KronScheduler import kotlinx.coroutines.Job -import net.moonleay.lilJudd.data.api.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.type.ApiDataType -import net.moonleay.lilJudd.data.api.type.ApiRequestType +import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiCache +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType +import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType import net.moonleay.lilJudd.jobs.component.CronjobType import net.moonleay.lilJudd.jobs.component.ICronjob import net.moonleay.lilJudd.util.Logger -- 2.45.2 From 734ac1b74cbdc5451765b4558652361b1462a4ba Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 1 Jan 2024 04:12:23 +0100 Subject: [PATCH 142/168] WIP: started working on lilJuddApi implementation Signed-off-by: moonleay --- .../lilJudd/data/CredentialManager.kt | 8 ++++- .../lilJudd/data/api/liljudd/LilJuddApi.kt | 36 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/liljudd/LilJuddApi.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/CredentialManager.kt b/src/main/kotlin/net/moonleay/lilJudd/data/CredentialManager.kt index 0320d82..e406414 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/CredentialManager.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/CredentialManager.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -29,6 +29,8 @@ object CredentialManager { lateinit var dbName: String lateinit var dbUser: String lateinit var dbPassword: String + lateinit var apiDomain: String + lateinit var apiToken: String ///Load the needed credentials, generate a config if there is none fun load() { @@ -51,6 +53,8 @@ object CredentialManager { dbName = prop.getProperty("dbName") dbUser = prop.getProperty("dbUser") dbPassword = prop.getProperty("dbPassword") + apiDomain = prop.getProperty("apiDomain") + apiToken = prop.getProperty("apiToken") input.close() } catch (e: IOException) { e.printStackTrace() @@ -83,6 +87,8 @@ object CredentialManager { prop.setProperty("dbName", "empty") prop.setProperty("dbUser", "empty") prop.setProperty("dbPassword", "empty") + prop.setProperty("apiDomain", "empty") + prop.setProperty("apiToken", "empty") prop.store(output, null) output.close() diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/liljudd/LilJuddApi.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/liljudd/LilJuddApi.kt new file mode 100644 index 0000000..d6379fa --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/liljudd/LilJuddApi.kt @@ -0,0 +1,36 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.liljudd + +import net.moonleay.lilJudd.data.CredentialManager + +object LilJuddApi { + val CONFIG_BASE = "${CredentialManager.apiDomain}/config/" + val MATCH_BASE = "${CredentialManager.apiDomain}/match/" + val TIMEPLANNINGMESSAGES_BASE = "${CredentialManager.apiDomain}/tp_messages/" + + // GET https://liljudd.ink/api/config// + // DELETE https://liljudd.ink/api/config// + // GET https://liljudd.ink/api/tp_messages// + // PUT https://liljudd.ink/api/tp_messages// + // POST https://liljudd.ink/api/match/// + // PUT https://liljudd.ink/api/match//// + // GET https://liljudd.ink/api/match// + +} -- 2.45.2 From 0f2410c7c1dfc4231b2f66dff10a99f563dcf4bb Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 18 Jan 2024 18:31:57 +0100 Subject: [PATCH 143/168] chore: added KotlinxSerialization to project, bumped kotlin version Signed-off-by: moonleay --- build.gradle.kts | 12 +++++++++--- .../net/moonleay/lilJudd/build/BuildConstants.kt | 3 ++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index f2891f1..d7251f9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -21,7 +21,8 @@ import org.jetbrains.gradle.ext.TaskTriggersConfig import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - kotlin("jvm") version "1.9.10" + kotlin("jvm") version "1.9.22" + kotlin("plugin.serialization") version "1.9.22" id("com.github.johnrengelman.shadow") version "8.1.1" id("org.jetbrains.gradle.plugin.idea-ext") version "1.1.7" `maven-publish` @@ -40,6 +41,7 @@ val ktorver = "2.3.7" val exposedver = "0.45.0" val postgresver = "42.7.1" val krontabver = "2.2.4" +val kotlinxserializationver = "1.6.0" val mavenArtifact = "lilJudd" project.base.archivesName.set(mavenArtifact) @@ -93,6 +95,9 @@ dependencies { //Coroutines shadow("org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutinesver") + //JSON Stuff + shadow("org.jetbrains.kotlinx:kotlinx-serialization-json:$kotlinxserializationver") + //Logging shadow("org.slf4j:slf4j-api:2.0.3") shadow("org.slf4j:slf4j-simple:2.0.3") @@ -121,7 +126,8 @@ val templateProps = mapOf( "ktorversion" to ktorver, "exposedversion" to exposedver, "postgresversion" to postgresver, - "krontabversion" to krontabver + "krontabversion" to krontabver, + "kotlinxserializationversion" to kotlinxserializationver ) diff --git a/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt b/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt index d75d861..44c46b3 100644 --- a/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt +++ b/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -27,4 +27,5 @@ internal object BuildConstants { const val exposedVersion = "${exposedversion}" const val postgresVersion = "${postgresversion}" const val krontabVersion = "${krontabversion}" + const val kotlinXSerializationVerson = "${kotlinxserializationversion}" } -- 2.45.2 From ec92cac2e7a866019f18688357240330b5c9bf77 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 18 Jan 2024 18:34:11 +0100 Subject: [PATCH 144/168] feat!: completely rewrote API code to use KotlinXSerialization instead of pasing it manually (WTF was I thinking when I did that??) Signed-off-by: moonleay --- .../lilJudd/data/api/liljudd/LilJuddApi.kt | 36 -- .../data/api/splatoon3ink/Splatoon3Api.kt | 105 +--- .../api/splatoon3ink/Splatoon3ApiCache.kt | 577 ------------------ .../splatoon3ink/Splatoon3ApiDataGrabber.kt | 129 ++++ .../splatoon3ink/entry/coop/CoopGearData.kt | 28 - .../entry/splatfest/SplatfestTeamData.kt | 25 - .../entry/splatfest/SplatfestTeamResults.kt | 33 - .../entry/splatnet/SplatnetItemData.kt | 32 - .../schedules/BankaraMatchSetting.kt | 37 ++ .../api/splatoon3ink/schedules/BankaraNode.kt | 35 ++ .../schedules/BankaraSchedules.kt | 29 + .../schedules/BigRunScheduleNode.kt | 35 ++ .../splatoon3ink/schedules/BigRunSchedules.kt | 29 + .../data/api/splatoon3ink/schedules/Boss.kt | 31 + .../SplatfestColor.kt => schedules/Color.kt} | 17 +- .../schedules/CoopGroupingSchedule.kt | 35 ++ .../api/splatoon3ink/schedules/CoopStage.kt | 35 ++ .../api/splatoon3ink/schedules/CurrentFest.kt | 43 ++ .../splatoon3ink/schedules/CurrentPlayer.kt | 29 + .../api/splatoon3ink/schedules/EventNode.kt | 31 + .../splatoon3ink/schedules/EventSchedules.kt | 29 + .../schedules/FestMatchSettingX.kt | 35 ++ .../schedules/FestMatchSettingXX.kt | 28 + .../ShiftData.kt => schedules/FestNode.kt} | 25 +- .../splatoon3ink/schedules/FestSchedules.kt | 29 + .../WeaponData.kt => schedules/Image.kt} | 15 +- .../LeagueMatchEvent.kt} | 29 +- .../schedules/LeagueMatchSetting.kt | 37 ++ .../api/splatoon3ink/schedules/MapNode.kt | 37 ++ .../OriginalImage.kt} | 17 +- .../schedules/RegularMatchSetting.kt | 35 ++ .../api/splatoon3ink/schedules/RegularNode.kt | 35 ++ .../schedules/RegularSchedules.kt | 29 + .../schedules/RegularSchedulesX.kt | 29 + .../api/splatoon3ink/schedules/Schedules.kt | 29 + .../splatoon3ink/schedules/SchedulesData.kt | 45 ++ .../api/splatoon3ink/schedules/Setting.kt | 37 ++ .../data/api/splatoon3ink/schedules/Team.kt | 33 + .../schedules/TeamContestSchedules.kt | 30 + .../ThumbnailImage.kt} | 16 +- .../TimePeriod.kt} | 15 +- .../TricolorStage.kt} | 24 +- .../MapData.kt => schedules/UserIcon.kt} | 16 +- .../data/api/splatoon3ink/schedules/VsRule.kt | 33 + .../api/splatoon3ink/schedules/VsStage.kt | 35 ++ .../api/splatoon3ink/schedules/VsStages.kt | 29 + .../data/api/splatoon3ink/schedules/Weapon.kt | 33 + .../splatoon3ink/schedules/XMatchSetting.kt | 35 ++ .../ModeData.kt => schedules/XNode.kt} | 25 +- .../api/splatoon3ink/schedules/XSchedules.kt | 29 + .../data/api/splatoon3ink/type/ApiDataType.kt | 27 - .../api/splatoon3ink/type/ApiRequestType.kt | 26 - 52 files changed, 1319 insertions(+), 958 deletions(-) delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/liljudd/LilJuddApi.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiCache.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/coop/CoopGearData.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamData.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamResults.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/SplatnetItemData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Boss.kt rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/splatfest/SplatfestColor.kt => schedules/Color.kt} (70%) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/schedule/ShiftData.kt => schedules/FestNode.kt} (61%) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/schedule/WeaponData.kt => schedules/Image.kt} (72%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/schedule/ChallengeModeData.kt => schedules/LeagueMatchEvent.kt} (61%) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/splatnet/BrandData.kt => schedules/OriginalImage.kt} (72%) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/splatnet/GearAbilityData.kt => schedules/ThumbnailImage.kt} (72%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/schedule/TimePeriodData.kt => schedules/TimePeriod.kt} (70%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/splatfest/SplatfestData.kt => schedules/TricolorStage.kt} (64%) rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/schedule/MapData.kt => schedules/UserIcon.kt} (72%) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsRule.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/{entry/schedule/ModeData.kt => schedules/XNode.kt} (57%) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiDataType.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiRequestType.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/liljudd/LilJuddApi.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/liljudd/LilJuddApi.kt deleted file mode 100644 index d6379fa..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/liljudd/LilJuddApi.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * lilJudd - * Copyright (C) 2024 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.api.liljudd - -import net.moonleay.lilJudd.data.CredentialManager - -object LilJuddApi { - val CONFIG_BASE = "${CredentialManager.apiDomain}/config/" - val MATCH_BASE = "${CredentialManager.apiDomain}/match/" - val TIMEPLANNINGMESSAGES_BASE = "${CredentialManager.apiDomain}/tp_messages/" - - // GET https://liljudd.ink/api/config// - // DELETE https://liljudd.ink/api/config// - // GET https://liljudd.ink/api/tp_messages// - // PUT https://liljudd.ink/api/tp_messages// - // POST https://liljudd.ink/api/match/// - // PUT https://liljudd.ink/api/match//// - // GET https://liljudd.ink/api/match// - -} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt index 8f097c3..bce9a62 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -18,98 +18,21 @@ package net.moonleay.lilJudd.data.api.splatoon3ink -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule.ModeData -import net.moonleay.lilJudd.util.TimeUtil +import kotlinx.serialization.json.Json +import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Schedules +import net.moonleay.lilJudd.util.NetUtil +import net.moonleay.liljudd.build.BuildConstants object Splatoon3Api { - private fun getRegularMode(timestamp: Long): ModeData { - Splatoon3ApiCache.cachedRegularModeData.map { modeData -> - val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") - val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") - if (timestamp in startTime..endTime) { - return modeData - } + + var schedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Schedules? = null + + fun updateSchedule() { + val response = NetUtil.GETJsonData("https://splatoon3.ink/data/schedules.json", "lilJudd/${BuildConstants.version}") + if (response.startsWith("error")){ + println("Error: $response") + return } - throw Exception("No current mode found") - } - - private fun getOpenMode(timestamp: Long): ModeData { - Splatoon3ApiCache.cachedCompetitiveOpenModeData.map { modeData -> - val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") - val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") - if (timestamp in startTime..endTime) { - return modeData - } - } - throw Exception("No current mode found") - } - - private fun getXMode(timestamp: Long): ModeData { - Splatoon3ApiCache.cachedXModeData.map { modeData -> - val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") - val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") - if (timestamp in startTime..endTime) { - return modeData - } - } - throw Exception("No current mode found") - } - - private fun getSeriesMode(timestamp: Long): ModeData { - Splatoon3ApiCache.cachedCompetitiveSeriesModeData.map { modeData -> - val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") - val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") - if (timestamp in startTime..endTime) { - return modeData - } - } - throw Exception("No current mode found") - } - - fun getRotationTime(timestamp: Long): String { - val modeData = getRegularMode(timestamp) - val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") - val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) - return "$diffStamp left in rotation" - } - - fun getRegularMapsFormatted(timestamp: Long): String { - val modeData = getRegularMode(timestamp) - val map1 = modeData.map1!!.name.split(" ")[0] - val map2 = modeData.map2!!.name.split(" ")[0] - return "R: $map1, $map2" - } - - fun getOpenMapFormatted(timestamp: Long): String { - val modeData = getOpenMode(timestamp) - val map1 = modeData.map1!!.name.split(" ")[0] - val map2 = modeData.map2!!.name.split(" ")[0] - return "O: ${modeData.ruleSetName}: $map1, $map2" - .replace("Rainmaker", "RMK") - .replace("Tower Control", "TC") - .replace("Splat Zones", "SZ") - .replace("Clam Blitz", "CB") - } - - fun getSeriesMapsFormatted(timestamp: Long): String { - val modeData = getSeriesMode(timestamp) - val map1 = modeData.map1!!.name.split(" ")[0] - val map2 = modeData.map2!!.name.split(" ")[0] - return "S: ${modeData.ruleSetName}: $map1, $map2" - .replace("Rainmaker", "RMK") - .replace("Tower Control", "TC") - .replace("Splat Zones", "SZ") - .replace("Clam Blitz", "CB") - } - - fun getXMapFormatted(timestamp: Long): String { - val modeData = getXMode(timestamp) - val map1 = modeData.map1!!.name.split(" ")[0] - val map2 = modeData.map2!!.name.split(" ")[0] - return "X: ${modeData.ruleSetName}: $map1, $map2" - .replace("Rainmaker", "RMK") - .replace("Tower Control", "TC") - .replace("Splat Zones", "SZ") - .replace("Clam Blitz", "CB") + schedules = Json.decodeFromString(response) } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiCache.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiCache.kt deleted file mode 100644 index 30a9129..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiCache.kt +++ /dev/null @@ -1,577 +0,0 @@ -/* - * 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.api.splatoon3ink - -import io.ktor.http.* -import kotlinx.serialization.json.* -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.coop.CoopGearData -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule.* -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest.SplatfestColor -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest.SplatfestData -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest.SplatfestTeamData -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest.SplatfestTeamResults -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet.BrandData -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet.GearAbilityData -import net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet.SplatnetItemData -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.NetUtil -import net.moonleay.liljudd.build.BuildConstants - -object Splatoon3ApiCache { - private val user_agent = - "lilJudd/${BuildConstants.version} (${System.getProperty("os.name")}/${System.getProperty("os.version")}) [contact@moonleay.net]" - private val base_url = "https://splatoon3.ink/data/" // Thank god there is an API - - internal var cachedSplatfestData = mutableListOf() - internal var cachedMapData = mutableMapOf() - internal var cachedRegularModeData = mutableListOf() - internal var cachedCompetitiveSeriesModeData = mutableListOf() - internal var cachedCompetitiveOpenModeData = mutableListOf() - internal var cachedXModeData = mutableListOf() - internal var cachedChallengesData = mutableListOf() - internal var cachedShiftData = mutableListOf() - internal var cachedBigRunShiftData = mutableListOf() - internal var cachedCoopRewardsData = - mutableListOf() - internal var cachedSplatnetItemData = mutableListOf() - internal var cachedSplatnetLimitedItemData = mutableListOf() - internal lateinit var splatnetShopBrandData: BrandData - internal lateinit var splatnetShopNextBrandData: BrandData - fun updateData(dataType: ApiDataType, requestType: ApiRequestType) { - Logger.out("Updating data for $dataType with USER-AGENT: ${user_agent}") - Logger.out("Reason for update: $requestType") - when (dataType) { - ApiDataType.SCHEDULES -> { - updateScheduleCache(user_agent) - } - - ApiDataType.SPLATNETGEAR -> { - updateSplatnetGearCache(user_agent) - } - - ApiDataType.COOP -> { - updateCOOPCache(user_agent) - } - - ApiDataType.SPLATFESTS -> { - updateSplatfestCache(user_agent) - } - - ApiDataType.ALL -> { - updateScheduleCache(user_agent) - updateSplatnetGearCache(user_agent) - updateSplatfestCache(user_agent) - updateCOOPCache(user_agent) - } - } - Logger.out("Finished updating data for $dataType") - } - - private fun updateSplatnetGearCache(uag: String) { - val apiResponse = NetUtil.GETJsonData("${base_url}gear.json", uag) - if (apiResponse.startsWith("Error")) { - Logger.out("Error getting splatnet data: $apiResponse") - return - } - val json = Json.parseToJsonElement(apiResponse) - val pickupBrandData = json.jsonObject["data"]!!.jsonObject["gesotown"]!!.jsonObject["pickupBrand"]!!.jsonObject - - val brand = pickupBrandData["brand"]!!.jsonObject - splatnetShopBrandData = - BrandData( - brand["name"]!!.jsonPrimitive.content, - Url(pickupBrandData["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - GearAbilityData( - brand["usualGearPower"]!!.jsonObject["name"]!!.jsonPrimitive.content, - brand["usualGearPower"]!!.jsonObject["desc"]!!.jsonPrimitive.content, - Url(brand["usualGearPower"]!!.jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - pickupBrandData["saleEndTime"]!!.jsonPrimitive.content - ) - val nextBrand = pickupBrandData["nextBrand"]!!.jsonObject - splatnetShopNextBrandData = - BrandData( - nextBrand["name"]!!.jsonPrimitive.content, - Url(pickupBrandData["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - null, - null - ) - cachedSplatnetItemData = mutableListOf() - val items = pickupBrandData["brandGears"]!!.jsonArray - items.forEach { - val obj = it as JsonObject - val gear = it["gear"]!!.jsonObject - val primaryGearPower = gear["primaryGearPower"]!!.jsonObject - val additionalGearPowers = gear["additionalGearPowers"]!!.jsonArray - val additionalGearPowersList = mutableListOf() - additionalGearPowers.forEach { - val ob = it as JsonObject - additionalGearPowersList.add( - GearAbilityData( - ob["name"]!!.jsonPrimitive.content, - null, - Url(ob["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ) - ) - } - cachedSplatnetItemData.add( - SplatnetItemData( - obj["saleEndTime"]!!.jsonPrimitive.content, - obj["price"]!!.jsonPrimitive.int, - gear["__typename"]!!.jsonPrimitive.content, - gear["name"]!!.jsonPrimitive.content, - GearAbilityData( - primaryGearPower["name"]!!.jsonPrimitive.content, - null, - Url(primaryGearPower["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - additionalGearPowersList, - Url(gear["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - splatnetShopBrandData - ) - ) - } - Logger.out("Updated gear data") - - val limitedItemData = json.jsonObject["data"]!!.jsonObject["gesotown"]!!.jsonObject["limitedGears"]!!.jsonArray - cachedSplatnetLimitedItemData = mutableListOf() - limitedItemData.forEach { - val obj = it as JsonObject - val gear = obj["gear"]!!.jsonObject - val additionalGearPowers = gear["additionalGearPowers"]!!.jsonArray - val additionalGearPowersList = mutableListOf() - additionalGearPowers.forEach { - val ob = it as JsonObject - additionalGearPowersList.add( - GearAbilityData( - ob["name"]!!.jsonPrimitive.content, - null, - Url(ob["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ) - ) - } - cachedSplatnetLimitedItemData.add( - SplatnetItemData( - obj["saleEndTime"]!!.jsonPrimitive.content, - obj["price"]!!.jsonPrimitive.int, - gear["__typename"]!!.jsonPrimitive.content, - gear["name"]!!.jsonPrimitive.content, - GearAbilityData( - gear["primaryGearPower"]!!.jsonObject["name"]!!.jsonPrimitive.content, - null, - Url(gear["primaryGearPower"]!!.jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - additionalGearPowersList, - Url(gear["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - splatnetShopBrandData - ) - ) - } - } - - private fun updateCOOPCache(uag: String) { - val apiResponse = NetUtil.GETJsonData("${base_url}coop.json", uag) - if (apiResponse.startsWith("Error")) { - Logger.out("Error getting coop data: $apiResponse") - return - } - try { - val json = Json.parseToJsonElement(apiResponse) - val data = json.jsonObject["data"]!!.jsonObject["coopResult"]!!.jsonObject["monthlyGear"]!!.jsonObject - cachedCoopRewardsData = mutableListOf() - cachedCoopRewardsData.add( - CoopGearData( - data["name"]!!.jsonPrimitive.content, - Url(data["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - data["__typename"]!!.jsonPrimitive.content - ) - ) - Logger.out("Updated COOP data") - } catch (e: Exception) { - Logger.out("Error getting coop data: ${e.cause}") - } - } - - private fun updateScheduleCache(uag: String) { - val apiResponse = NetUtil.GETJsonData("${base_url}schedules.json", uag) - if (apiResponse.startsWith("Error")) { - Logger.out("Error getting schedule data: $apiResponse") - return - } - val json = Json.decodeFromString(apiResponse) as JsonObject - val data = json["data"]!!.jsonObject - - try { - val mapList = data["vsStages"]!!.jsonObject["nodes"]!!.jsonArray - cachedMapData = mutableMapOf() - mapList.forEach { - val obj = it as JsonObject - val imageURL = Url(obj.jsonObject["originalImage"]!!.jsonObject["url"]!!.jsonPrimitive.content) - val id = obj.jsonObject["vsStageId"]!!.jsonPrimitive.int - cachedMapData[id] = - MapData( - id, - imageURL, - it.jsonObject["name"]!!.jsonPrimitive.content - ) - } - Logger.out("Updated maplist data") - } catch (e: Exception) { - Logger.out("Error getting maplist data: ${e.cause}") - } - - try { - val regularMatches = data["regularSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedRegularModeData = mutableListOf() - regularMatches.forEach { - val obj = it as JsonObject - val setting = obj["regularMatchSetting"]!!.jsonObject - cachedRegularModeData.add( - ModeData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - setting["__typename"]!!.jsonPrimitive.content, - cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - "TURF_WAR" - ) - ) - } - Logger.out("Updated Regular match data") - } catch (e: Exception) { - Logger.out("Error getting regular match data: ${e.cause}") - } - - try { - val compMatches = data["bankaraSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedCompetitiveSeriesModeData = mutableListOf() - cachedCompetitiveOpenModeData = mutableListOf() - compMatches.forEach { - val obj = it as JsonObject - val setting = obj["bankaraMatchSettings"]!!.jsonArray - setting.forEach { - val ob = it as JsonObject - val mode = ob["bankaraMode"]!!.jsonPrimitive.content - if (mode == "CHALLENGE") { - cachedCompetitiveSeriesModeData.add( - ModeData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - ob["__typename"]!!.jsonPrimitive.content, - cachedMapData[ob["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[ob["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - ob["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - ob["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - mode - ) - ) - } else if (mode == "OPEN") { - cachedCompetitiveOpenModeData.add( - ModeData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - ob["__typename"]!!.jsonPrimitive.content, - cachedMapData[ob["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[ob["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - ob["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - ob["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - mode - ) - ) - } - } - } - Logger.out("Updated Competitive match data") - - } catch (e: Exception) { - Logger.out("Error getting competitive match data: ${e.cause}") - } - try { - val xMatches = data["xSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedXModeData = mutableListOf() - xMatches.forEach { - val obj = it as JsonObject - val setting = obj["xMatchSetting"]!!.jsonObject - cachedXModeData.add( - ModeData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - setting["__typename"]!!.jsonPrimitive.content, - cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - "X" - ) - ) - } - Logger.out("Updated X match data") - } catch (e: Exception) { - Logger.out("Error getting X match data: ${e.cause}") - } - - try { - val challengeData = data["eventSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedChallengesData = mutableListOf() - challengeData.forEach { - val obj = it as JsonObject - val tpd = obj["timePeriods"]!!.jsonArray - val setting = obj["leagueMatchSetting"]!!.jsonObject - val event = setting["leagueMatchEvent"]!!.jsonObject - cachedChallengesData.add( - ChallengeModeData( - event["leagueMatchEventId"]!!.jsonPrimitive.content, - event["name"]!!.jsonPrimitive.content, - event["desc"]!!.jsonPrimitive.content, - event["regulation"]!!.jsonPrimitive.content, - cachedMapData[setting["vsStages"]!!.jsonArray[0].jsonObject["vsStageId"]!!.jsonPrimitive.int], - cachedMapData[setting["vsStages"]!!.jsonArray[1].jsonObject["vsStageId"]!!.jsonPrimitive.int], - setting["__typename"]!!.jsonPrimitive.content, - setting["vsRule"]!!.jsonObject["rule"]!!.jsonPrimitive.content, - setting["vsRule"]!!.jsonObject["name"]!!.jsonPrimitive.content, - TimePeriodData( - tpd[0].jsonObject["startTime"]!!.jsonPrimitive.content, - tpd[0].jsonObject["endTime"]!!.jsonPrimitive.content - ), - TimePeriodData( - tpd[1].jsonObject["startTime"]!!.jsonPrimitive.content, - tpd[1].jsonObject["endTime"]!!.jsonPrimitive.content - ), - TimePeriodData( - tpd[2].jsonObject["startTime"]!!.jsonPrimitive.content, - tpd[2].jsonObject["endTime"]!!.jsonPrimitive.content - ) - ) - ) - } - Logger.out("Updated Challenge data") - } catch (e: Exception) { - Logger.out("Error getting Challenge data: ${e.cause}") - } - - try { - val shiftData = - data["coopGroupingSchedule"]!!.jsonObject["regularSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedShiftData = mutableListOf() - shiftData.forEach { - val obj = it as JsonObject - val setting = obj["setting"]!!.jsonObject - val stage = setting["coopStage"]!!.jsonObject - val weapons = setting["weapons"]!!.jsonArray - cachedShiftData.add( - ShiftData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - obj["__splatoon3ink_king_salmonid_guess"]!!.jsonPrimitive.content, - setting["__typename"]!!.jsonPrimitive.content, - stage["name"]!!.jsonPrimitive.content, - Url(stage["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - WeaponData( - weapons[0].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[0].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[1].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[1].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[2].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[2].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[3].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[3].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ) - ) - ) - } - Logger.out("Updated shift data") - } catch (e: Exception) { - Logger.out("Error getting coopGrouping data: ${e.cause}") - } - - try { - val bigRunData = - data["coopGroupingSchedule"]!!.jsonObject["bigRunSchedules"]!!.jsonObject["nodes"]!!.jsonArray - cachedBigRunShiftData = mutableListOf() - bigRunData.forEach { - val obj = it as JsonObject - val setting = obj["setting"]!!.jsonObject - val stage = setting["coopStage"]!!.jsonObject - val weapons = setting["weapons"]!!.jsonArray - cachedBigRunShiftData.add( - ShiftData( - obj["startTime"]!!.jsonPrimitive.content, - obj["endTime"]!!.jsonPrimitive.content, - obj["__splatoon3ink_king_salmonid_guess"]!!.jsonPrimitive.content, - setting["__typename"]!!.jsonPrimitive.content, - stage["name"]!!.jsonPrimitive.content, - Url(stage["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - WeaponData( - weapons[0].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[0].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[1].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[1].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[2].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[2].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ), - WeaponData( - weapons[3].jsonObject["name"]!!.jsonPrimitive.content, - Url(weapons[3].jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content) - ) - ) - ) - } - Logger.out("Updated big run data") - } catch (e: Exception) { - Logger.out("Error getting big run data: ${e.cause}") - } - - Logger.out("Updated all Schedules") - } - - private fun updateSplatfestCache(uag: String) { - val apiResponse = NetUtil.GETJsonData("${base_url}festivals.json", uag) - if (apiResponse.startsWith("Error")) { - Logger.out("Error getting splatfest data: $apiResponse") - return - } - try { - val json = Json.decodeFromString(apiResponse) as JsonObject - val festivals = - json["US"]!!.jsonObject["data"]!!.jsonObject["festRecords"]!!.jsonObject["nodes"]!!.jsonArray - cachedSplatfestData = mutableListOf() - festivals.forEach { - val fest = it as JsonObject - val teams = fest.jsonObject["teams"]!!.jsonArray - val team1 = teams[0].jsonObject - val team1Color = team1["color"]!!.jsonObject - var team1Result: JsonObject? = null - if (team1["result"] !is JsonNull) { - team1Result = team1["result"]!!.jsonObject - } - val team2 = teams[1].jsonObject - val team2Color = team2["color"]!!.jsonObject - var team2Result: JsonObject? = null - if (team2["result"] !is JsonNull) { - team2Result = team2["result"]!!.jsonObject - } - val team3 = teams[2].jsonObject - val team3Color = team3["color"]!!.jsonObject - var team3Result: JsonObject? = null - if (team3["result"] !is JsonNull) { - team3Result = team3["result"]!!.jsonObject - } - cachedSplatfestData.add( - SplatfestData( - fest.jsonObject["id"]!!.jsonPrimitive.content, - fest.jsonObject["state"]!!.jsonPrimitive.content, - fest.jsonObject["startTime"]!!.jsonPrimitive.content, - fest.jsonObject["endTime"]!!.jsonPrimitive.content, - fest.jsonObject["title"]!!.jsonPrimitive.content, - Url(fest.jsonObject["image"]!!.jsonObject["url"]!!.jsonPrimitive.content), - SplatfestTeamData( - team1["teamName"]!!.jsonPrimitive.content, - SplatfestColor( - team1Color["a"]!!.jsonPrimitive.int, - team1Color["b"]!!.jsonPrimitive.double, - team1Color["g"]!!.jsonPrimitive.double, - team1Color["r"]!!.jsonPrimitive.double - ), - if (team1Result.isNullOrEmpty() || team1Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) - null - else SplatfestTeamResults( - team1Result["isWinner"]!!.jsonPrimitive.boolean, - team1Result["horagaiRatio"]!!.jsonPrimitive.double, - team1Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, - team1Result["voteRatio"]!!.jsonPrimitive.double, - team1Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, - team1Result["regularContributionRatio"]!!.jsonPrimitive.double, - team1Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, - team1Result["challengeContributionRatio"]!!.jsonPrimitive.double, - team1Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, - team1Result["tricolorContributionRatio"]!!.jsonPrimitive.double, - team1Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, - ) - ), - SplatfestTeamData( - team2["teamName"]!!.jsonPrimitive.content, - SplatfestColor( - team2Color["a"]!!.jsonPrimitive.int, - team2Color["b"]!!.jsonPrimitive.double, - team2Color["g"]!!.jsonPrimitive.double, - team2Color["r"]!!.jsonPrimitive.double - ), - if (team2Result.isNullOrEmpty() || team2Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) - null - else SplatfestTeamResults( - team2Result["isWinner"]!!.jsonPrimitive.boolean, - team2Result["horagaiRatio"]!!.jsonPrimitive.double, - team2Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, - team2Result["voteRatio"]!!.jsonPrimitive.double, - team2Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, - team2Result["regularContributionRatio"]!!.jsonPrimitive.double, - team2Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, - team2Result["challengeContributionRatio"]!!.jsonPrimitive.double, - team2Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, - team2Result["tricolorContributionRatio"]!!.jsonPrimitive.double, - team2Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, - ) - ), - SplatfestTeamData( - team3["teamName"]!!.jsonPrimitive.content, - SplatfestColor( - team3Color["a"]!!.jsonPrimitive.int, - team3Color["b"]!!.jsonPrimitive.double, - team3Color["g"]!!.jsonPrimitive.double, - team3Color["r"]!!.jsonPrimitive.double - ), - if (team3Result.isNullOrEmpty() || team3Result["tricolorContributionRatio"]!!.jsonPrimitive.doubleOrNull == null) - null - else SplatfestTeamResults( - team3Result["isWinner"]!!.jsonPrimitive.boolean, - team3Result["horagaiRatio"]!!.jsonPrimitive.double, - team3Result["isHoragaiRatioTop"]!!.jsonPrimitive.boolean, - team3Result["voteRatio"]!!.jsonPrimitive.double, - team3Result["isVoteRatioTop"]!!.jsonPrimitive.boolean, - team3Result["regularContributionRatio"]!!.jsonPrimitive.double, - team3Result["isRegularContributionRatioTop"]!!.jsonPrimitive.boolean, - team3Result["challengeContributionRatio"]!!.jsonPrimitive.double, - team3Result["isChallengeContributionRatioTop"]!!.jsonPrimitive.boolean, - team3Result["tricolorContributionRatio"]!!.jsonPrimitive.double, - team3Result["isTricolorContributionRatioTop"]!!.jsonPrimitive.boolean, - ) - ), - ) - ) - } - Logger.out("Updated Splatfest data") - } catch (e: Exception) { - Logger.out("Error getting splatfest data: ${e.cause}") - } - } -} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt new file mode 100644 index 0000000..6a9eedf --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt @@ -0,0 +1,129 @@ +/* + * 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.api.splatoon3ink + +import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraNode +import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularNode +import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XNode +import net.moonleay.lilJudd.util.TimeUtil + +object Splatoon3ApiDataGrabber { + private fun getRegularMode(timestamp: Long): net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularNode { + Splatoon3Api.schedules!!.data.regularSchedules.nodes.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + return modeData + } + } + throw Exception("No current mode found") + } + + private fun getOpenMode(timestamp: Long): net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraNode { + Splatoon3Api.schedules!!.data.bankaraSchedules.nodes.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + modeData.bankaraMatchSettings!!.map { matchSetting -> + if (matchSetting.bankaraMode == "OPEN") + return modeData + } + } + } + throw Exception("No current mode found") + } + + private fun getXMode(timestamp: Long): net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XNode { + Splatoon3Api.schedules!!.data.xSchedules.nodes.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + return modeData + } + } + throw Exception("No current mode found") + } + + private fun getSeriesMode(timestamp: Long): net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraNode { + Splatoon3Api.schedules!!.data.bankaraSchedules.nodes.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + modeData.bankaraMatchSettings!!.map { matchSetting -> + if (matchSetting.bankaraMode == "CHALLENGE") + return modeData + } + } + } + throw Exception("No current mode found") + } + + fun getRotationTime(timestamp: Long): String { + val modeData = getRegularMode(timestamp) + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + val diffStamp = TimeUtil.getTimeDifferenceFormatted(System.currentTimeMillis(), endTime) + return "$diffStamp left in rotation" + } + + fun getRegularMapsFormatted(timestamp: Long): String { + val modeData = getRegularMode(timestamp) + val map1 = modeData.regularMatchSetting.vsStages[0].name.split(" ")[0] + val map2 = modeData.regularMatchSetting.vsStages[1].name.split(" ")[0] + return "R: $map1, $map2" + } + + fun getOpenMapFormatted(timestamp: Long): String { + val modeData = getOpenMode(timestamp) + // FIXME: This may cause issues if there is a Splatfest going on + // TODO: Check if this works during splatfest + // The Open Mode should always be the second mode in the list + // FIXME: Add check if 2nd itm in list is open mode + val map1 = modeData.bankaraMatchSettings!![1].vsStages[0].name.split(" ")[0] + val map2 = modeData.bankaraMatchSettings[1].vsStages[1].name.split(" ")[0] + return "O: ${modeData.bankaraMatchSettings[1].vsRule.name}: $map1, $map2" + .replace("Rainmaker", "RMK") + .replace("Tower Control", "TC") + .replace("Splat Zones", "SZ") + .replace("Clam Blitz", "CB") + } + + fun getSeriesMapsFormatted(timestamp: Long): String { + val modeData = getSeriesMode(timestamp) + // FIXME: This may cause issues if there is a Splatfest going on + // TODO: Check all the same things as in getOpenMapFormatted + val map1 = modeData.bankaraMatchSettings!![0].vsStages[0].name.split(" ")[0] + val map2 = modeData.bankaraMatchSettings[0].vsStages[1].name.split(" ")[0] + return "S: ${modeData.bankaraMatchSettings[0].vsRule.name}: $map1, $map2" + .replace("Rainmaker", "RMK") + .replace("Tower Control", "TC") + .replace("Splat Zones", "SZ") + .replace("Clam Blitz", "CB") + } + + fun getXMapFormatted(timestamp: Long): String { + val modeData = getXMode(timestamp) + val map1 = modeData.xMatchSetting.vsStages[0].name.split(" ")[0] + val map2 = modeData.xMatchSetting.vsStages[1].name.split(" ")[0] + return "X: ${modeData.xMatchSetting.vsRule.name}: $map1, $map2" + .replace("Rainmaker", "RMK") + .replace("Tower Control", "TC") + .replace("Splat Zones", "SZ") + .replace("Clam Blitz", "CB") + } +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/coop/CoopGearData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/coop/CoopGearData.kt deleted file mode 100644 index 817a80a..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/coop/CoopGearData.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * 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.api.splatoon3ink.entry.coop - -import io.ktor.http.* - -data class CoopGearData( - val name: String, - val image: Url, - val __typename: String, - - ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamData.kt deleted file mode 100644 index b29ee85..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamData.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.api.splatoon3ink.entry.splatfest - -data class SplatfestTeamData( - val teamName: String, - val color: SplatfestColor, - val results: SplatfestTeamResults?, -) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamResults.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamResults.kt deleted file mode 100644 index ff7b531..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestTeamResults.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * 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.api.splatoon3ink.entry.splatfest - -data class SplatfestTeamResults( - val isWinner: Boolean, - val horagaiRatio: Double, - val horagaiRatioTop: Boolean, - val voteRatio: Double, - val voteRatioTop: Boolean, - val regularRatio: Double, - val regularRatioTop: Boolean, - val challengeRatio: Double, - val challengeRatioTop: Boolean, - val tricolorRatio: Double, - val tricolorRatioTop: Boolean, -) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/SplatnetItemData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/SplatnetItemData.kt deleted file mode 100644 index 72268dd..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/SplatnetItemData.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * 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.api.splatoon3ink.entry.splatnet - -import io.ktor.http.* - -data class SplatnetItemData( - val saleEndTime: String, - val price: Int, - val typeName: String, - val name: String, - val primaryGearPower: GearAbilityData, - val additionalGearPowers: List, - val image: Url, - val brand: BrandData, -) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt new file mode 100644 index 0000000..a73a448 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt @@ -0,0 +1,37 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class BankaraMatchSetting( + @SerialName("bankaraMode") + val bankaraMode: String, + @SerialName("__isVsSetting") + val isVsSetting: String, + @SerialName("__typename") + val typename: String, + @SerialName("vsRule") + val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + @SerialName("vsStages") + val vsStages: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt new file mode 100644 index 0000000..e40379c --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class BankaraNode( + @SerialName("bankaraMatchSettings") + val bankaraMatchSettings: List?, + @SerialName("endTime") + val endTime: String, + @SerialName("festMatchSettings") + val festMatchSettings: List?, + @SerialName("startTime") + val startTime: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt new file mode 100644 index 0000000..0363b5f --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class BankaraSchedules( + @SerialName("nodes") + val nodes: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt new file mode 100644 index 0000000..e51551e --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class BigRunScheduleNode( + @SerialName("endTime") + val endTime: String, + @SerialName("setting") + val setting: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Setting, + @SerialName("__splatoon3ink_king_salmonid_guess") + val splatoon3inkKingSalmonidGuess: String, + @SerialName("startTime") + val startTime: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt new file mode 100644 index 0000000..de77938 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class BigRunSchedules( + @SerialName("nodes") + val nodes: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Boss.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Boss.kt new file mode 100644 index 0000000..1501727 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Boss.kt @@ -0,0 +1,31 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Boss( + @SerialName("id") + val id: String, + @SerialName("name") + val name: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestColor.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Color.kt similarity index 70% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestColor.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Color.kt index 9f61bd7..7ed55be 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestColor.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Color.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,11 +16,20 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -data class SplatfestColor( + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Color( + @SerialName("a") val a: Int, + @SerialName("b") val b: Double, + @SerialName("g") val g: Double, - val r: Double, + @SerialName("r") + val r: Double ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt new file mode 100644 index 0000000..baefdf1 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class CoopGroupingSchedule( + @SerialName("bannerImage") + val bannerImage: String?, // is null + @SerialName("bigRunSchedules") + val bigRunSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BigRunSchedules, + @SerialName("regularSchedules") + val regularSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularSchedules, + @SerialName("teamContestSchedules") + val teamContestSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.TeamContestSchedules? +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt new file mode 100644 index 0000000..ddfb9da --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class CoopStage( + @SerialName("id") + val id: String, + @SerialName("image") + val image: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Image, + @SerialName("name") + val name: String, + @SerialName("thumbnailImage") + val thumbnailImage: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.ThumbnailImage +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt new file mode 100644 index 0000000..63d995e --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt @@ -0,0 +1,43 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class CurrentFest( + @SerialName("endTime") + val endTime: String, + @SerialName("id") + val id: String, + @SerialName("midtermTime") + val midtermTime: String, + @SerialName("startTime") + val startTime: String, + @SerialName("state") + val state: String, + @SerialName("teams") + val teams: List, + @SerialName("title") + val title: String, + @SerialName("tricolorStage") + val tricolorStage: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.TricolorStage +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt new file mode 100644 index 0000000..3bab50b --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class CurrentPlayer( + @SerialName("userIcon") + val userIcon: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.UserIcon +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt new file mode 100644 index 0000000..7b7f011 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt @@ -0,0 +1,31 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EventNode( + @SerialName("leagueMatchSetting") + val leagueMatchSetting: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.LeagueMatchSetting, + @SerialName("timePeriods") + val timePeriods: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt new file mode 100644 index 0000000..f5f3fe3 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class EventSchedules( + @SerialName("nodes") + val nodes: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt new file mode 100644 index 0000000..c759a30 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class FestMatchSettingX( + @SerialName("__isVsSetting") + val isVsSetting: String, + @SerialName("__typename") + val typename: String, + @SerialName("vsRule") + val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + @SerialName("vsStages") + val vsStages: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt new file mode 100644 index 0000000..a1f5d3d --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt @@ -0,0 +1,28 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class FestMatchSettingXX( + @SerialName("__typename") + val typename: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ShiftData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt similarity index 61% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ShiftData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt index f6f29f1..e8a438d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ShiftData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,19 +16,18 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -import io.ktor.http.* -data class ShiftData( - val startTime: String, +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class FestNode( + @SerialName("endTime") val endTime: String, - val __splatoon3ink_king_salmonid_guess: String, - val __typename: String, - val stageName: String, - val image: Url, - val weapon1: WeaponData, - val weapon2: WeaponData, - val weapon3: WeaponData, - val weapon4: WeaponData, + @SerialName("festMatchSettings") + val festMatchSettings: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.FestMatchSettingX?, + @SerialName("startTime") + val startTime: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt new file mode 100644 index 0000000..8eed590 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class FestSchedules( + @SerialName("nodes") + val nodes: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/WeaponData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Image.kt similarity index 72% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/WeaponData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Image.kt index 025ef87..f635fa6 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/WeaponData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Image.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,11 +16,14 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -import io.ktor.http.* -data class WeaponData( - val name: String, - val image: Url, +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Image( + @SerialName("url") + val url: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ChallengeModeData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt similarity index 61% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ChallengeModeData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt index 87efd9d..64fe6b9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ChallengeModeData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,19 +16,24 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -data class ChallengeModeData( + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class LeagueMatchEvent( + @SerialName("desc") + val desc: String, + @SerialName("id") + val id: String, + @SerialName("leagueMatchEventId") val leagueMatchEventId: String, + @SerialName("name") val name: String, - val description: String, + @SerialName("regulation") val regulation: String, - val map1: MapData?, - val map2: MapData?, - val __typename: String, - val ruleSet: String, - val ruleSetName: String, - val timePeriod1: TimePeriodData, - val timePeriod2: TimePeriodData, - val timePeriod3: TimePeriodData, + @SerialName("regulationUrl") + val regulationUrl: String? // is null ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt new file mode 100644 index 0000000..c8e4ba1 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt @@ -0,0 +1,37 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class LeagueMatchSetting( + @SerialName("__isVsSetting") + val isVsSetting: String, + @SerialName("leagueMatchEvent") + val leagueMatchEvent: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.LeagueMatchEvent, + @SerialName("__typename") + val typename: String, + @SerialName("vsRule") + val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + @SerialName("vsStages") + val vsStages: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt new file mode 100644 index 0000000..107545f --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt @@ -0,0 +1,37 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class MapNode( + @SerialName("id") + val id: String, + @SerialName("name") + val name: String, + @SerialName("originalImage") + val originalImage: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.OriginalImage, + @SerialName("stats") + val stats: String?, // is null + @SerialName("vsStageId") + val vsStageId: Int +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/BrandData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/OriginalImage.kt similarity index 72% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/BrandData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/OriginalImage.kt index 2c80240..e294963 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/BrandData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/OriginalImage.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,13 +16,14 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -import io.ktor.http.* -data class BrandData( - val name: String, - val image: Url, - val usualGearPower: GearAbilityData?, - val saleEndTime: String?, +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class OriginalImage( + @SerialName("url") + val url: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt new file mode 100644 index 0000000..ffb1d51 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RegularMatchSetting( + @SerialName("__isVsSetting") + val isVsSetting: String, + @SerialName("__typename") + val typename: String, + @SerialName("vsRule") + val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + @SerialName("vsStages") + val vsStages: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt new file mode 100644 index 0000000..48d08fa --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RegularNode( + @SerialName("endTime") + val endTime: String, + @SerialName("festMatchSettings") + val festMatchSettings: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.FestMatchSettingXX?, + @SerialName("regularMatchSetting") + val regularMatchSetting: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularMatchSetting, + @SerialName("startTime") + val startTime: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt new file mode 100644 index 0000000..6dc058f --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RegularSchedules( + @SerialName("nodes") + val nodes: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt new file mode 100644 index 0000000..6995bf3 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class RegularSchedulesX( + @SerialName("nodes") + val nodes: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt new file mode 100644 index 0000000..2d058c6 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Schedules( + @SerialName("data") + val data: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.SchedulesData +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt new file mode 100644 index 0000000..9dd136b --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt @@ -0,0 +1,45 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class SchedulesData( + @SerialName("bankaraSchedules") + val bankaraSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraSchedules, + @SerialName("coopGroupingSchedule") + val coopGroupingSchedule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.CoopGroupingSchedule, + @SerialName("currentFest") + val currentFest: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.CurrentFest?, + @SerialName("currentPlayer") + val currentPlayer: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.CurrentPlayer, + @SerialName("eventSchedules") + val eventSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.EventSchedules, + @SerialName("festSchedules") + val festSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.FestSchedules, + @SerialName("regularSchedules") + val regularSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularSchedulesX, + @SerialName("vsStages") + val vsStages: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsStages, + @SerialName("xSchedules") + val xSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XSchedules +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt new file mode 100644 index 0000000..ef98cfa --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt @@ -0,0 +1,37 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Setting( + @SerialName("boss") + val boss: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Boss, + @SerialName("coopStage") + val coopStage: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.CoopStage, + @SerialName("__isCoopSetting") + val isCoopSetting: String, + @SerialName("__typename") + val typename: String, + @SerialName("weapons") + val weapons: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt new file mode 100644 index 0000000..f015188 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt @@ -0,0 +1,33 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Team( + @SerialName("color") + val color: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Color, + @SerialName("id") + val id: String, +// @SerialName("myVoteState") +// val myVoteState: Any? +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt new file mode 100644 index 0000000..e328191 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt @@ -0,0 +1,30 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +// TODO: Please check what goes here. +data class TeamContestSchedules( + @SerialName("nodes") + val nodes: List // This is a placeholder. +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/GearAbilityData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt similarity index 72% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/GearAbilityData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt index 81f2ee7..cb357a9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatnet/GearAbilityData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,12 +16,14 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatnet +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -import io.ktor.http.* -data class GearAbilityData( - val name: String, - val description: String?, - val image: Url, +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class ThumbnailImage( + @SerialName("url") + val url: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/TimePeriodData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TimePeriod.kt similarity index 70% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/TimePeriodData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TimePeriod.kt index dc66844..99037bf 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/TimePeriodData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TimePeriod.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,9 +16,16 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -data class TimePeriodData( - val startTime: String, + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class TimePeriod( + @SerialName("endTime") val endTime: String, + @SerialName("startTime") + val startTime: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt similarity index 64% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt index fb11b19..958d1a5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/splatfest/SplatfestData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,18 +16,18 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.splatfest +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -import io.ktor.http.* -data class SplatfestData( +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class TricolorStage( + @SerialName("id") val id: String, - val state: String, - val startTime: String, - val endTime: String, - val title: String, - val image: Url, - val team1: SplatfestTeamData, - val team2: SplatfestTeamData, - val team3: SplatfestTeamData, + @SerialName("image") + val image: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Image, + @SerialName("name") + val name: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/MapData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/UserIcon.kt similarity index 72% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/MapData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/UserIcon.kt index b64755d..74ee2eb 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/MapData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/UserIcon.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,12 +16,14 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -import io.ktor.http.* -data class MapData( - val stageID: Int, - val image: Url, - val name: String, +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class UserIcon( + @SerialName("url") + val url: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsRule.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsRule.kt new file mode 100644 index 0000000..5e47251 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsRule.kt @@ -0,0 +1,33 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class VsRule( + @SerialName("id") + val id: String, + @SerialName("name") + val name: String, + @SerialName("rule") + val rule: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt new file mode 100644 index 0000000..9d9ecb3 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class VsStage( + @SerialName("id") + val id: String, + @SerialName("image") + val image: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Image, + @SerialName("name") + val name: String, + @SerialName("vsStageId") + val vsStageId: Int +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt new file mode 100644 index 0000000..21d32f1 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class VsStages( + @SerialName("nodes") + val nodes: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt new file mode 100644 index 0000000..9b47a82 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt @@ -0,0 +1,33 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class Weapon( + @SerialName("image") + val image: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Image, + @SerialName("name") + val name: String, + @SerialName("__splatoon3ink_id") + val splatoon3inkId: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt new file mode 100644 index 0000000..7467db1 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt @@ -0,0 +1,35 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class XMatchSetting( + @SerialName("__isVsSetting") + val isVsSetting: String, + @SerialName("__typename") + val typename: String, + @SerialName("vsRule") + val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + @SerialName("vsStages") + val vsStages: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ModeData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt similarity index 57% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ModeData.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt index c3ad3dc..1a55bc5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/entry/schedule/ModeData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -16,15 +16,20 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.entry.schedule +package net.moonleay.lilJudd.data.api.splatoon3ink.schedules -data class ModeData( - val startTime: String, + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class XNode( + @SerialName("endTime") val endTime: String, - val matchType: String, - val map1: MapData?, - val map2: MapData?, - val ruleSetName: String, - val ruleSet: String, - val mode: String, + @SerialName("festMatchSettings") + val festMatchSettings: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.FestMatchSettingXX?, + @SerialName("startTime") + val startTime: String, + @SerialName("xMatchSetting") + val xMatchSetting: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XMatchSetting ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt new file mode 100644 index 0000000..a3939c3 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class XSchedules( + @SerialName("nodes") + val nodes: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiDataType.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiDataType.kt deleted file mode 100644 index 7cb7361..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiDataType.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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.api.splatoon3ink.type - -enum class ApiDataType { - SCHEDULES, - SPLATNETGEAR, - COOP, - SPLATFESTS, - ALL -} diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiRequestType.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiRequestType.kt deleted file mode 100644 index 03a9add..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/type/ApiRequestType.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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.api.splatoon3ink.type - -enum class ApiRequestType(val nameToDisplay: String) { - AUTOMATIC_CACHE_UPDATE("automatic request to update the cache"), - AUTOMATIC_CACHE_CREATION_AT_STARTUP("automatic request to create cache at startup"), - MANUAL("manual request"), - DEBUG("debug request") -} -- 2.45.2 From abd17b32568f823e87798d48d94325e4cf41fe0e Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 18 Jan 2024 18:34:53 +0100 Subject: [PATCH 145/168] chore!: removed unused updater cronjobs Signed-off-by: moonleay --- ...atoon3ApiFestivalAndCoopUpdateScheduler.kt | 50 ------------------- ...Splatoon3ApiSplatnetGearUpdateScheduler.kt | 47 ----------------- 2 files changed, 97 deletions(-) delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt delete mode 100644 src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt deleted file mode 100644 index 07f4a4b..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiFestivalAndCoopUpdateScheduler.kt +++ /dev/null @@ -1,50 +0,0 @@ -/* - * lilJudd - * Copyright (C) 2024 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.jobs - -import dev.inmo.krontab.KronScheduler -import kotlinx.coroutines.Job -import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType -import net.moonleay.lilJudd.jobs.component.CronjobType -import net.moonleay.lilJudd.jobs.component.ICronjob -import net.moonleay.lilJudd.util.Logger - -object Splatoon3ApiFestivalAndCoopUpdateScheduler : ICronjob { - override val jobName: String - get() = "Splatoon3ApiFestivalAndCoopUpdateScheduler" - override val jobIncoming: String - get() = "0 0 0 /1 * * 0o *" // once a day - override val jobType: CronjobType - get() = CronjobType.INFINITE - override val continueJob: Boolean - get() = true - override lateinit var cronjobJob: Job - override lateinit var scheduler: KronScheduler - - override suspend fun jobFunction() { - Logger.out("Running Splatoon3ApiFestivalUpdateScheduler.") - Splatoon3ApiCache.updateData(ApiDataType.SPLATFESTS, ApiRequestType.AUTOMATIC_CACHE_UPDATE) - Logger.out("Splatoon3ApiFestivalUpdateScheduler finished.") - Logger.out("Running Splatoon3ApiCoopUpdateScheduler.") - Splatoon3ApiCache.updateData(ApiDataType.COOP, ApiRequestType.AUTOMATIC_CACHE_UPDATE) - Logger.out("Splatoon3ApiCoopUpdateScheduler finished.") - } -} diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt deleted file mode 100644 index 7bbc020..0000000 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiSplatnetGearUpdateScheduler.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * lilJudd - * Copyright (C) 2024 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.jobs - -import dev.inmo.krontab.KronScheduler -import kotlinx.coroutines.Job -import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType -import net.moonleay.lilJudd.jobs.component.CronjobType -import net.moonleay.lilJudd.jobs.component.ICronjob -import net.moonleay.lilJudd.util.Logger - -object Splatoon3ApiSplatnetGearUpdateScheduler : ICronjob { - override val jobName: String - get() = "Splatoon3ApiSplatnetGearUpdateScheduler" - override val jobIncoming: String - get() = "0 0 /6 * * * 0o *" //Every 6 hours - override val jobType: CronjobType - get() = CronjobType.INFINITE - override val continueJob: Boolean - get() = true - override lateinit var cronjobJob: Job - override lateinit var scheduler: KronScheduler - - override suspend fun jobFunction() { - Logger.out("Running Splatoon3ApiSplatnetGearUpdateScheduler.") - Splatoon3ApiCache.updateData(ApiDataType.SPLATNETGEAR, ApiRequestType.AUTOMATIC_CACHE_UPDATE) - Logger.out("Splatoon3ApiSplatnetGearUpdateScheduler finished.") - } -} -- 2.45.2 From 894e03c9c6dda206863084204762b6769e56f37c Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 18 Jan 2024 18:35:17 +0100 Subject: [PATCH 146/168] feat!: updated rest of the code to use new API system Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 10 ++-------- .../jobs/Splatoon3ApiScheduleUpdateScheduler.kt | 10 ++++------ .../net/moonleay/lilJudd/jobs/StatusUpdater.kt | 14 +++++++------- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index fcdc5e6..8282212 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -32,9 +32,7 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager -import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType +import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3Api import net.moonleay.lilJudd.data.database.DB import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager @@ -173,7 +171,7 @@ object Bot { } // Update the Splatoon 3 api data and make sure it stays up-to-date - Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_CREATION_AT_STARTUP) + Splatoon3Api.updateSchedule() JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) /* Other caches will be added when implemented @@ -183,10 +181,6 @@ object Bot { // Had to disable bc of an error. // Will fix when I have time - - //JobManager.addJob(Splatoon3ApiFestivalAndCoopUpdateScheduler) - //JobManager.addJob(Splatoon3ApiSplatnetGearUpdateScheduler) - //Start the bot bot.start() } diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt index 2a47939..6ec76f9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt @@ -20,9 +20,7 @@ package net.moonleay.lilJudd.jobs import dev.inmo.krontab.KronScheduler import kotlinx.coroutines.Job -import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiCache -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiDataType -import net.moonleay.lilJudd.data.api.splatoon3ink.type.ApiRequestType +import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3Api import net.moonleay.lilJudd.jobs.component.CronjobType import net.moonleay.lilJudd.jobs.component.ICronjob import net.moonleay.lilJudd.util.Logger @@ -40,8 +38,8 @@ object Splatoon3ApiScheduleUpdateScheduler : ICronjob { override lateinit var scheduler: KronScheduler override suspend fun jobFunction() { - Logger.out("Running Splatoon3ApiScheduleUpdateScheduler.") - Splatoon3ApiCache.updateData(ApiDataType.SCHEDULES, ApiRequestType.AUTOMATIC_CACHE_UPDATE) - Logger.out("Splatoon3ApiScheduleUpdateScheduler finished.") + Logger.out("Updating Schedules...") + Splatoon3Api.updateSchedule() + Logger.out("Updating finished.") } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index 762b498..4aa8fb3 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -22,7 +22,7 @@ import dev.inmo.krontab.KronScheduler import dev.kord.common.entity.PresenceStatus import kotlinx.coroutines.Job import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.api.Splatoon3Api +import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiDataGrabber import net.moonleay.lilJudd.jobs.component.CronjobType import net.moonleay.lilJudd.jobs.component.ICronjob @@ -56,11 +56,11 @@ object StatusUpdater : ICronjob { private fun refreshStatusList(timestamp: Long) { statusList = listOf( - Splatoon3Api.getRotationTime(timestamp), - Splatoon3Api.getRegularMapsFormatted(timestamp), - Splatoon3Api.getOpenMapFormatted(timestamp), - Splatoon3Api.getSeriesMapsFormatted(timestamp), - Splatoon3Api.getXMapFormatted(timestamp) + Splatoon3ApiDataGrabber.getRotationTime(timestamp), + Splatoon3ApiDataGrabber.getRegularMapsFormatted(timestamp), + Splatoon3ApiDataGrabber.getOpenMapFormatted(timestamp), + Splatoon3ApiDataGrabber.getSeriesMapsFormatted(timestamp), + Splatoon3ApiDataGrabber.getXMapFormatted(timestamp) ) } } -- 2.45.2 From 2182f8751a5cb0c3ed294ad06456e5bbc0b7713f Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 18 Jan 2024 18:46:34 +0100 Subject: [PATCH 147/168] chore: upgraded gradle to 8.5 Signed-off-by: moonleay --- gradle/wrapper/gradle-wrapper.jar | Bin 63721 -> 43462 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 16 ++++++++-------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 7f93135c49b765f8051ef9d0a6055ff8e46073d8..d64cd4917707c1f8861d8cb53dd15194d4248596 100644 GIT binary patch literal 43462 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 literal 63721 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鯊%1Et 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⁢ zv5o9#E7!G0XmdzfsS{efPNi`1b44~SZ4Z8fuX!I}#8g+(wxzQwUT#Xb2(tbY1+EUhGKoT@KEU9Ktl>_0 z%bjDJg;#*gtJZv!-Zs`?^}v5eKmnbjqlvnSzE@_SP|LG_PJ6CYU+6zY6>92%E+ z=j@TZf-iW4(%U{lnYxQA;7Q!b;^brF8n0D>)`q5>|WDDXLrqYU_tKN2>=#@~OE7grMnNh?UOz-O~6 z6%rHy{#h9K0AT+lDC7q4{hw^|q6*Ry;;L%Q@)Ga}$60_q%D)rv(CtS$CQbpq9|y1e zRSrN4;$Jyl{m5bZw`$8TGvb}(LpY{-cQ)fcyJv7l3S52TLXVDsphtv&aPuDk1OzCA z4A^QtC(!11`IsNx_HnSy?>EKpHJWT^wmS~hc^p^zIIh@9f6U@I2 zC=Mve{j2^)mS#U$e{@Q?SO6%LDsXz@SY+=cK_QMmXBIU)j!$ajc-zLx3V60EXJ!qC zi<%2x8Q24YN+&8U@CIlN zrZkcT9yh%LrlGS9`G)KdP(@9Eo-AQz@8GEFWcb7U=a0H^ZVbLmz{+&M7W(nXJ4sN8 zJLR7eeK(K8`2-}j(T7JsO`L!+CvbueT%izanm-^A1Dn{`1Nw`9P?cq;7no+XfC`K(GO9?O^5zNIt4M+M8LM0=7Gz8UA@Z0N+lg+cX)NfazRu z5D)~HA^(u%w^cz+@2@_#S|u>GpB+j4KzQ^&Wcl9f z&hG#bCA(Yk0D&t&aJE^xME^&E-&xGHhXn%}psEIj641H+Nl-}boj;)Zt*t(4wZ5DN z@GXF$bL=&pBq-#vkTkh>7hl%K5|3 z{`Vn9b$iR-SoGENp}bn4;fR3>9sA%X2@1L3aE9yTra;Wb#_`xWwLSLdfu+PAu+o3| zGVnpzPr=ch{uuoHjtw7+_!L_2;knQ!DuDl0R`|%jr+}jFzXtrHIKc323?JO{l&;VF z*L1+}JU7%QJOg|5|Tc|D8fN zJORAg=_vsy{ak|o);@)Yh8Lkcg@$FG3k@ep36BRa^>~UmnRPziS>Z=`Jb2x*Q#`%A zU*i3&Vg?TluO@X0O;r2Jl6LKLUOVhSqg1*qOt^|8*c7 zo(298@+r$k_wQNGHv{|$tW(T8L+4_`FQ{kEW5Jgg{yf7ey4ss_(SNKfz(N9lx&a;< je(UuV8hP?p&}TPdm1I$XmG#(RzlD&B2izSj9sl%y5~4qc diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 488e2ca..3ba58b0 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ # # lilJudd -# Copyright (C) 2023 moonleay +# Copyright (C) 2024 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 diff --git a/gradlew b/gradlew index 6e2d6e1..bf6021c 100755 --- a/gradlew +++ b/gradlew @@ -2,7 +2,7 @@ # # lilJudd -# Copyright (C) 2023 moonleay +# Copyright (C) 2024 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 @@ -147,7 +147,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then case $MAX_FD in #( max*) # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 MAX_FD=$( ulimit -H -n ) || warn "Could not query maximum file descriptor limit" esac @@ -155,7 +155,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then '' | soft) :;; #( *) # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. - # shellcheck disable=SC3045 + # shellcheck disable=SC2039,SC3045 ulimit -n "$MAX_FD" || warn "Could not set maximum file descriptor limit to $MAX_FD" esac @@ -204,11 +204,11 @@ fi # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' -# Collect all arguments for the java command; -# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of -# shell script including quotes and variable substitutions, so put them in -# double quotes to make sure that they get re-expanded; and -# * put everything else in single quotes, so that it's not re-expanded. +# Collect all arguments for the java command: +# * 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. set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -- 2.45.2 From 38d61ae8625a8900077c9b600b3e4734dfbf3545 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 18 Jan 2024 18:49:53 +0100 Subject: [PATCH 148/168] chore: upgraded dependencies Signed-off-by: moonleay --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index d7251f9..5b2caaa 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -38,9 +38,9 @@ version = System.getenv("CI_COMMIT_TAG")?.let { "$it-${System.getenv("CI_COMMIT_ val kordver = "1.7.1-SNAPSHOT" val coroutinesver = "1.7.3" val ktorver = "2.3.7" -val exposedver = "0.45.0" +val exposedver = "0.46.0" val postgresver = "42.7.1" -val krontabver = "2.2.4" +val krontabver = "2.2.6" val kotlinxserializationver = "1.6.0" val mavenArtifact = "lilJudd" -- 2.45.2 From b65dadd42f906c1240dfcde36da99e3152a118db Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 19 Jan 2024 10:53:49 +0100 Subject: [PATCH 149/168] chore: code cleanup Signed-off-by: moonleay --- .../buttons/matchplanner/AcceptEditButton.kt | 4 ++-- .../buttons/matchplanner/DeclineEditButton.kt | 2 +- .../data/api/splatoon3ink/Splatoon3Api.kt | 2 +- .../splatoon3ink/Splatoon3ApiDataGrabber.kt | 8 +++---- .../schedules/BankaraMatchSetting.kt | 4 ++-- .../api/splatoon3ink/schedules/BankaraNode.kt | 4 ++-- .../schedules/BankaraSchedules.kt | 2 +- .../schedules/BigRunScheduleNode.kt | 2 +- .../splatoon3ink/schedules/BigRunSchedules.kt | 2 +- .../schedules/CoopGroupingSchedule.kt | 6 ++--- .../api/splatoon3ink/schedules/CoopStage.kt | 4 ++-- .../api/splatoon3ink/schedules/CurrentFest.kt | 4 ++-- .../splatoon3ink/schedules/CurrentPlayer.kt | 2 +- .../api/splatoon3ink/schedules/EventNode.kt | 4 ++-- .../splatoon3ink/schedules/EventSchedules.kt | 2 +- .../schedules/FestMatchSettingX.kt | 4 ++-- .../api/splatoon3ink/schedules/FestNode.kt | 2 +- .../splatoon3ink/schedules/FestSchedules.kt | 2 +- .../schedules/LeagueMatchSetting.kt | 6 ++--- .../api/splatoon3ink/schedules/MapNode.kt | 2 +- .../schedules/RegularMatchSetting.kt | 4 ++-- .../api/splatoon3ink/schedules/RegularNode.kt | 4 ++-- .../schedules/RegularSchedules.kt | 2 +- .../schedules/RegularSchedulesX.kt | 2 +- .../api/splatoon3ink/schedules/Schedules.kt | 2 +- .../splatoon3ink/schedules/SchedulesData.kt | 18 +++++++-------- .../api/splatoon3ink/schedules/Setting.kt | 6 ++--- .../data/api/splatoon3ink/schedules/Team.kt | 2 +- .../splatoon3ink/schedules/TricolorStage.kt | 2 +- .../api/splatoon3ink/schedules/VsStage.kt | 2 +- .../api/splatoon3ink/schedules/VsStages.kt | 2 +- .../data/api/splatoon3ink/schedules/Weapon.kt | 2 +- .../splatoon3ink/schedules/XMatchSetting.kt | 4 ++-- .../data/api/splatoon3ink/schedules/XNode.kt | 4 ++-- .../api/splatoon3ink/schedules/XSchedules.kt | 2 +- .../repository/MatchPlanningDataRepository.kt | 22 +++++++++--------- .../PlanningNotifierRolesRepository.kt | 23 +++++++++---------- .../TimePlanningChannelsRepository.kt | 9 ++++---- .../TimePlanningMessagesRepository.kt | 14 ++++------- .../extensions/SendPlannerExtension.kt | 2 +- .../extensions/UpdateRolesExtension.kt | 2 +- 41 files changed, 97 insertions(+), 101 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt index ffb7759..ff4d4cf 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt @@ -34,7 +34,7 @@ import net.moonleay.lilJudd.util.EmbedUtil import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil -class AcceptEditButton() : IEditButton { +class AcceptEditButton : IEditButton { override val id: String = "public.edit.btn.matchmanagement.accept" override suspend fun onInteraction( @@ -60,7 +60,7 @@ class AcceptEditButton() : IEditButton { Logger.out("role is null") return } - val member = interaction.user.asMember(guild.id) ?: return + val member = interaction.user.asMember(guild.id) // do the checks and update if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { if (member.roleIds.contains(Snowflake(mpdd.roleID))) { diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt index 12c8375..d205b05 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt @@ -60,7 +60,7 @@ class DeclineEditButton : IEditButton { Logger.out("role is null") return } - val member = interaction.user.asMember(guild.id) ?: return + val member = interaction.user.asMember(guild.id) if (m.embeds[0].fields[0].value.contains(user.id.value.toString())) { if (member.roleIds.contains(Snowflake(mpdd.roleID))) { Logger.out("Removing role from ${member.username}") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt index bce9a62..100c9dc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt @@ -25,7 +25,7 @@ import net.moonleay.liljudd.build.BuildConstants object Splatoon3Api { - var schedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Schedules? = null + var schedules: Schedules? = null fun updateSchedule() { val response = NetUtil.GETJsonData("https://splatoon3.ink/data/schedules.json", "lilJudd/${BuildConstants.version}") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt index 6a9eedf..298e943 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt @@ -24,7 +24,7 @@ import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XNode import net.moonleay.lilJudd.util.TimeUtil object Splatoon3ApiDataGrabber { - private fun getRegularMode(timestamp: Long): net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularNode { + private fun getRegularMode(timestamp: Long): RegularNode { Splatoon3Api.schedules!!.data.regularSchedules.nodes.map { modeData -> val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") @@ -35,7 +35,7 @@ object Splatoon3ApiDataGrabber { throw Exception("No current mode found") } - private fun getOpenMode(timestamp: Long): net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraNode { + private fun getOpenMode(timestamp: Long): BankaraNode { Splatoon3Api.schedules!!.data.bankaraSchedules.nodes.map { modeData -> val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") @@ -49,7 +49,7 @@ object Splatoon3ApiDataGrabber { throw Exception("No current mode found") } - private fun getXMode(timestamp: Long): net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XNode { + private fun getXMode(timestamp: Long): XNode { Splatoon3Api.schedules!!.data.xSchedules.nodes.map { modeData -> val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") @@ -60,7 +60,7 @@ object Splatoon3ApiDataGrabber { throw Exception("No current mode found") } - private fun getSeriesMode(timestamp: Long): net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraNode { + private fun getSeriesMode(timestamp: Long): BankaraNode { Splatoon3Api.schedules!!.data.bankaraSchedules.nodes.map { modeData -> val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt index a73a448..773f4e8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt @@ -31,7 +31,7 @@ data class BankaraMatchSetting( @SerialName("__typename") val typename: String, @SerialName("vsRule") - val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + val vsRule: VsRule, @SerialName("vsStages") - val vsStages: List + val vsStages: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt index e40379c..953c79a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt @@ -25,11 +25,11 @@ import kotlinx.serialization.Serializable @Serializable data class BankaraNode( @SerialName("bankaraMatchSettings") - val bankaraMatchSettings: List?, + val bankaraMatchSettings: List?, @SerialName("endTime") val endTime: String, @SerialName("festMatchSettings") - val festMatchSettings: List?, + val festMatchSettings: List?, @SerialName("startTime") val startTime: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt index 0363b5f..a770703 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class BankaraSchedules( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt index e51551e..583e7c4 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt @@ -27,7 +27,7 @@ data class BigRunScheduleNode( @SerialName("endTime") val endTime: String, @SerialName("setting") - val setting: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Setting, + val setting: Setting, @SerialName("__splatoon3ink_king_salmonid_guess") val splatoon3inkKingSalmonidGuess: String, @SerialName("startTime") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt index de77938..f6ff9f0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class BigRunSchedules( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt index baefdf1..412e5fd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt @@ -27,9 +27,9 @@ data class CoopGroupingSchedule( @SerialName("bannerImage") val bannerImage: String?, // is null @SerialName("bigRunSchedules") - val bigRunSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BigRunSchedules, + val bigRunSchedules: BigRunSchedules, @SerialName("regularSchedules") - val regularSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularSchedules, + val regularSchedules: RegularSchedules, @SerialName("teamContestSchedules") - val teamContestSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.TeamContestSchedules? + val teamContestSchedules: TeamContestSchedules? ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt index ddfb9da..2cb21da 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt @@ -27,9 +27,9 @@ data class CoopStage( @SerialName("id") val id: String, @SerialName("image") - val image: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Image, + val image: Image, @SerialName("name") val name: String, @SerialName("thumbnailImage") - val thumbnailImage: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.ThumbnailImage + val thumbnailImage: ThumbnailImage ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt index 63d995e..d13d8fd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt @@ -35,9 +35,9 @@ data class CurrentFest( @SerialName("state") val state: String, @SerialName("teams") - val teams: List, + val teams: List, @SerialName("title") val title: String, @SerialName("tricolorStage") - val tricolorStage: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.TricolorStage + val tricolorStage: TricolorStage ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt index 3bab50b..5abc31b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class CurrentPlayer( @SerialName("userIcon") - val userIcon: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.UserIcon + val userIcon: UserIcon ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt index 7b7f011..96e1419 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt @@ -25,7 +25,7 @@ import kotlinx.serialization.Serializable @Serializable data class EventNode( @SerialName("leagueMatchSetting") - val leagueMatchSetting: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.LeagueMatchSetting, + val leagueMatchSetting: LeagueMatchSetting, @SerialName("timePeriods") - val timePeriods: List + val timePeriods: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt index f5f3fe3..c86ea33 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class EventSchedules( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt index c759a30..8b212c8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt @@ -29,7 +29,7 @@ data class FestMatchSettingX( @SerialName("__typename") val typename: String, @SerialName("vsRule") - val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + val vsRule: VsRule, @SerialName("vsStages") - val vsStages: List + val vsStages: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt index e8a438d..b9b4262 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt @@ -27,7 +27,7 @@ data class FestNode( @SerialName("endTime") val endTime: String, @SerialName("festMatchSettings") - val festMatchSettings: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.FestMatchSettingX?, + val festMatchSettings: FestMatchSettingX?, @SerialName("startTime") val startTime: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt index 8eed590..d606246 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class FestSchedules( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt index c8e4ba1..8008afc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt @@ -27,11 +27,11 @@ data class LeagueMatchSetting( @SerialName("__isVsSetting") val isVsSetting: String, @SerialName("leagueMatchEvent") - val leagueMatchEvent: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.LeagueMatchEvent, + val leagueMatchEvent: LeagueMatchEvent, @SerialName("__typename") val typename: String, @SerialName("vsRule") - val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + val vsRule: VsRule, @SerialName("vsStages") - val vsStages: List + val vsStages: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt index 107545f..b1c3813 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt @@ -29,7 +29,7 @@ data class MapNode( @SerialName("name") val name: String, @SerialName("originalImage") - val originalImage: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.OriginalImage, + val originalImage: OriginalImage, @SerialName("stats") val stats: String?, // is null @SerialName("vsStageId") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt index ffb1d51..44da86c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt @@ -29,7 +29,7 @@ data class RegularMatchSetting( @SerialName("__typename") val typename: String, @SerialName("vsRule") - val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + val vsRule: VsRule, @SerialName("vsStages") - val vsStages: List + val vsStages: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt index 48d08fa..321e0be 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt @@ -27,9 +27,9 @@ data class RegularNode( @SerialName("endTime") val endTime: String, @SerialName("festMatchSettings") - val festMatchSettings: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.FestMatchSettingXX?, + val festMatchSettings: FestMatchSettingXX?, @SerialName("regularMatchSetting") - val regularMatchSetting: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularMatchSetting, + val regularMatchSetting: RegularMatchSetting, @SerialName("startTime") val startTime: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt index 6dc058f..4b96d47 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class RegularSchedules( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt index 6995bf3..132b607 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class RegularSchedulesX( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt index 2d058c6..10c9412 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class Schedules( @SerialName("data") - val data: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.SchedulesData + val data: SchedulesData ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt index 9dd136b..21e4c48 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt @@ -25,21 +25,21 @@ import kotlinx.serialization.Serializable @Serializable data class SchedulesData( @SerialName("bankaraSchedules") - val bankaraSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraSchedules, + val bankaraSchedules: BankaraSchedules, @SerialName("coopGroupingSchedule") - val coopGroupingSchedule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.CoopGroupingSchedule, + val coopGroupingSchedule: CoopGroupingSchedule, @SerialName("currentFest") - val currentFest: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.CurrentFest?, + val currentFest: CurrentFest?, @SerialName("currentPlayer") - val currentPlayer: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.CurrentPlayer, + val currentPlayer: CurrentPlayer, @SerialName("eventSchedules") - val eventSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.EventSchedules, + val eventSchedules: EventSchedules, @SerialName("festSchedules") - val festSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.FestSchedules, + val festSchedules: FestSchedules, @SerialName("regularSchedules") - val regularSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularSchedulesX, + val regularSchedules: RegularSchedulesX, @SerialName("vsStages") - val vsStages: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsStages, + val vsStages: VsStages, @SerialName("xSchedules") - val xSchedules: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XSchedules + val xSchedules: XSchedules ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt index ef98cfa..8d1529b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt @@ -25,13 +25,13 @@ import kotlinx.serialization.Serializable @Serializable data class Setting( @SerialName("boss") - val boss: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Boss, + val boss: Boss, @SerialName("coopStage") - val coopStage: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.CoopStage, + val coopStage: CoopStage, @SerialName("__isCoopSetting") val isCoopSetting: String, @SerialName("__typename") val typename: String, @SerialName("weapons") - val weapons: List + val weapons: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt index f015188..2ee6032 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt @@ -25,7 +25,7 @@ import kotlinx.serialization.Serializable @Serializable data class Team( @SerialName("color") - val color: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Color, + val color: Color, @SerialName("id") val id: String, // @SerialName("myVoteState") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt index 958d1a5..21ba8c5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt @@ -27,7 +27,7 @@ data class TricolorStage( @SerialName("id") val id: String, @SerialName("image") - val image: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Image, + val image: Image, @SerialName("name") val name: String ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt index 9d9ecb3..3225c3d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt @@ -27,7 +27,7 @@ data class VsStage( @SerialName("id") val id: String, @SerialName("image") - val image: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Image, + val image: Image, @SerialName("name") val name: String, @SerialName("vsStageId") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt index 21d32f1..08501f9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class VsStages( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt index 9b47a82..66f880c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt @@ -25,7 +25,7 @@ import kotlinx.serialization.Serializable @Serializable data class Weapon( @SerialName("image") - val image: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Image, + val image: Image, @SerialName("name") val name: String, @SerialName("__splatoon3ink_id") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt index 7467db1..5a1dc64 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt @@ -29,7 +29,7 @@ data class XMatchSetting( @SerialName("__typename") val typename: String, @SerialName("vsRule") - val vsRule: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.VsRule, + val vsRule: VsRule, @SerialName("vsStages") - val vsStages: List + val vsStages: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt index 1a55bc5..95b8435 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt @@ -27,9 +27,9 @@ data class XNode( @SerialName("endTime") val endTime: String, @SerialName("festMatchSettings") - val festMatchSettings: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.FestMatchSettingXX?, + val festMatchSettings: FestMatchSettingXX?, @SerialName("startTime") val startTime: String, @SerialName("xMatchSetting") - val xMatchSetting: net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XMatchSetting + val xMatchSetting: XMatchSetting ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt index a3939c3..ba079aa 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class XSchedules( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt index 84a1e66..6b0bbd9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt @@ -51,7 +51,7 @@ object MatchPlanningDataRepository { fun get(id: Int): MatchPlanningDataData? = transaction { - MatchPlanningData.select { MatchPlanningData.id eq id }.firstOrNull()?.let { + MatchPlanningData.selectAll().where { MatchPlanningData.id eq id }.firstOrNull()?.let { MatchPlanningDataData( it[MatchPlanningData.id], it[MatchPlanningData.serverid], @@ -69,7 +69,7 @@ object MatchPlanningDataRepository { fun getFromMessageInChannelInServer(messageID: Long, channelID: Long, serverID: Long): MatchPlanningDataData? = transaction { - MatchPlanningData.select { + MatchPlanningData.selectAll().where { MatchPlanningData.messageid eq (messageID) and ( MatchPlanningData.serverid eq (serverID)) and ( MatchPlanningData.channelid eq (channelID)) @@ -98,15 +98,15 @@ object MatchPlanningDataRepository { fun write(data: MatchPlanningDataData): Int = transaction { MatchPlanningData.insert { - it[MatchPlanningData.serverid] = data.serverID - it[MatchPlanningData.channelid] = data.channelID - it[MatchPlanningData.matchtype] = data.matchType - it[MatchPlanningData.registererid] = data.registererID - it[MatchPlanningData.roleid] = data.roleID - it[MatchPlanningData.opponentName] = data.opponentName - it[MatchPlanningData.messageid] = data.messageID - it[MatchPlanningData.timestamp] = data.timestamp - it[MatchPlanningData.jobstr] = data.jobString + it[serverid] = data.serverID + it[channelid] = data.channelID + it[matchtype] = data.matchType + it[registererid] = data.registererID + it[roleid] = data.roleID + it[opponentName] = data.opponentName + it[messageid] = data.messageID + it[timestamp] = data.timestamp + it[jobstr] = data.jobString } get MatchPlanningData.id } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt index 4059e70..eea22df 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt @@ -46,9 +46,7 @@ object PlanningNotifierRolesRepository { fun getForChannel(channelID: Long): PlanningNotifierRolesData? = transaction { - PlanningNotifierRoles.select { - PlanningNotifierRoles.channelid eq channelID - }.firstOrNull()?.let { + PlanningNotifierRoles.selectAll().where { PlanningNotifierRoles.channelid eq channelID }.firstOrNull()?.let { PlanningNotifierRolesData( it[PlanningNotifierRoles.id], it[PlanningNotifierRoles.serverid], @@ -61,9 +59,9 @@ object PlanningNotifierRolesRepository { fun getForChannelInServer(channelID: Long, serverID: Long): PlanningNotifierRolesData? = transaction { - PlanningNotifierRoles.select { - PlanningNotifierRoles.channelid eq channelID and (PlanningNotifierRoles.serverid eq serverID) - }.firstOrNull()?.let { + PlanningNotifierRoles.selectAll() + .where { PlanningNotifierRoles.channelid eq channelID and (PlanningNotifierRoles.serverid eq serverID) } + .firstOrNull()?.let { PlanningNotifierRolesData( it[PlanningNotifierRoles.id], it[PlanningNotifierRoles.serverid], @@ -76,22 +74,23 @@ object PlanningNotifierRolesRepository { fun existsInChannel(channelID: Long): Boolean = transaction { - PlanningNotifierRoles.select { PlanningNotifierRoles.channelid eq channelID }.count() > 0 + PlanningNotifierRoles.selectAll().where { PlanningNotifierRoles.channelid eq channelID }.count() > 0 } fun existsInChannelFromSever(channelID: Long, serverID: Long): Boolean = transaction { - PlanningNotifierRoles.select { PlanningNotifierRoles.channelid eq channelID and (PlanningNotifierRoles.serverid eq serverID) } + PlanningNotifierRoles.selectAll() + .where { PlanningNotifierRoles.channelid eq channelID and (PlanningNotifierRoles.serverid eq serverID) } .count() > 0 } fun write(data: PlanningNotifierRolesData) { transaction { PlanningNotifierRoles.insert { - it[PlanningNotifierRoles.serverid] = data.serverID - it[PlanningNotifierRoles.channelid] = data.channelID - it[PlanningNotifierRoles.hastimeroleid] = data.hasTimeRoleID - it[PlanningNotifierRoles.wantstobenotifiedid] = data.wantsToBeNotifiedID + it[serverid] = data.serverID + it[channelid] = data.channelID + it[hastimeroleid] = data.hasTimeRoleID + it[wantstobenotifiedid] = data.wantsToBeNotifiedID } get PlanningNotifierRoles.id } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt index f5fd171..305a8b5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt @@ -43,7 +43,8 @@ object TimePlanningChannelsRepository { fun exists(channelID: Long, serverID: Long): Boolean = transaction { - TimePlanningChannels.select { TimePlanningChannels.channelid eq channelID and (TimePlanningChannels.serverid eq serverID) } + TimePlanningChannels.selectAll() + .where { TimePlanningChannels.channelid eq channelID and (TimePlanningChannels.serverid eq serverID) } .firstOrNull() != null } @@ -55,15 +56,15 @@ object TimePlanningChannelsRepository { fun deleteFromChannelInServer(channelID: Long, serverID: Long) { transaction { - TimePlanningChannels.deleteWhere { TimePlanningChannels.channelid eq channelID and (TimePlanningChannels.serverid eq serverID) } + TimePlanningChannels.deleteWhere { channelid eq channelID and (serverid eq serverID) } } } fun write(data: TimePlanningChannelsData): Int = transaction { TimePlanningChannels.insert { - it[TimePlanningChannels.serverid] = data.serverID - it[TimePlanningChannels.channelid] = data.channelID + it[serverid] = data.serverID + it[channelid] = data.channelID } get TimePlanningChannels.id } } diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt index 780a939..fad3a7c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt @@ -20,9 +20,8 @@ package net.moonleay.lilJudd.data.database.repository import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData import net.moonleay.lilJudd.data.database.tables.TimePlanningMessages -import org.jetbrains.exposed.sql.and -import org.jetbrains.exposed.sql.insert -import org.jetbrains.exposed.sql.select +import org.jetbrains.exposed.sql.* +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.transactions.transaction object TimePlanningMessagesRepository { @@ -40,9 +39,7 @@ object TimePlanningMessagesRepository { fun getWeek(stamp: Long): List { val dataList = mutableListOf() transaction { - for (pnr in TimePlanningMessages.select { - TimePlanningMessages.weekstamp eq (stamp) - }) { + for (pnr in TimePlanningMessages.selectAll().where { TimePlanningMessages.weekstamp eq (stamp) }) { dataList.add( TimePlanningMessagesData( pnr[TimePlanningMessages.id], @@ -59,9 +56,8 @@ object TimePlanningMessagesRepository { fun getWeekInChannel(stamp: Long, channelID: Long): TimePlanningMessagesData? = transaction { - TimePlanningMessages.select { - TimePlanningMessages.weekstamp eq (stamp) and (TimePlanningMessages.channelid eq channelID) - }.firstOrNull()?.let { + TimePlanningMessages.selectAll() + .where { TimePlanningMessages.weekstamp eq (stamp) and (TimePlanningMessages.channelid eq channelID) }.firstOrNull()?.let { TimePlanningMessagesData( it[TimePlanningMessages.id], it[TimePlanningMessages.serverid], diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt index acd59f4..f5d7c32 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt @@ -41,7 +41,7 @@ class SendPlannerExtension : Extension() { get() = false override suspend fun setup() { - publicSlashCommand() { + publicSlashCommand { name = "sendplanner" description = "Send the planner for the current week" this.action { diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt index 1d0ad06..6d29add 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt @@ -34,7 +34,7 @@ class UpdateRolesExtension : Extension() { get() = false override suspend fun setup() { - publicSlashCommand() { + publicSlashCommand { name = "updateroles" description = "Update the roles of the members in the current server" this.action { -- 2.45.2 From 97d4143cda475737404c4e4fa58c711074f1bc34 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 19 Jan 2024 22:39:43 +0100 Subject: [PATCH 150/168] chore: fixed wrong class naming Signed-off-by: moonleay --- .../lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt | 2 +- .../lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt | 2 +- .../schedules/{BigRunScheduleNode.kt => SalmonRunNode.kt} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/{BigRunScheduleNode.kt => SalmonRunNode.kt} (97%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt index f6ff9f0..47b5890 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class BigRunSchedules( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt index 4b96d47..ab2ccd8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt @@ -25,5 +25,5 @@ import kotlinx.serialization.Serializable @Serializable data class RegularSchedules( @SerialName("nodes") - val nodes: List + val nodes: List ) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt similarity index 97% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt rename to src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt index 583e7c4..85c4c8a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunScheduleNode.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt @@ -23,7 +23,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -data class BigRunScheduleNode( +data class SalmonRunNode( @SerialName("endTime") val endTime: String, @SerialName("setting") -- 2.45.2 From 39917e4b5a633277055a138b7913c13ac548dacf Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 19 Jan 2024 22:40:08 +0100 Subject: [PATCH 151/168] feat: updated and improved DataGrabber methods Signed-off-by: moonleay --- .../splatoon3ink/Splatoon3ApiDataGrabber.kt | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt index 298e943..f24a46f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -20,11 +20,12 @@ package net.moonleay.lilJudd.data.api.splatoon3ink import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraNode import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularNode +import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.SalmonRunNode import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XNode import net.moonleay.lilJudd.util.TimeUtil object Splatoon3ApiDataGrabber { - private fun getRegularMode(timestamp: Long): RegularNode { + fun getRegularMode(timestamp: Long): RegularNode { Splatoon3Api.schedules!!.data.regularSchedules.nodes.map { modeData -> val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") @@ -35,7 +36,7 @@ object Splatoon3ApiDataGrabber { throw Exception("No current mode found") } - private fun getOpenMode(timestamp: Long): BankaraNode { + fun getOpenMode(timestamp: Long): BankaraNode { Splatoon3Api.schedules!!.data.bankaraSchedules.nodes.map { modeData -> val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") @@ -49,7 +50,7 @@ object Splatoon3ApiDataGrabber { throw Exception("No current mode found") } - private fun getXMode(timestamp: Long): XNode { + fun getXMode(timestamp: Long): XNode { Splatoon3Api.schedules!!.data.xSchedules.nodes.map { modeData -> val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") @@ -60,7 +61,7 @@ object Splatoon3ApiDataGrabber { throw Exception("No current mode found") } - private fun getSeriesMode(timestamp: Long): BankaraNode { + fun getSeriesMode(timestamp: Long): BankaraNode { Splatoon3Api.schedules!!.data.bankaraSchedules.nodes.map { modeData -> val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") @@ -74,6 +75,16 @@ object Splatoon3ApiDataGrabber { throw Exception("No current mode found") } + fun getSalmonRun(timestamp: Long): SalmonRunNode { + Splatoon3Api.schedules!!.data.coopGroupingSchedule.regularSchedules.nodes.map { modeData -> + val startTime = TimeUtil.deformatJSONTime(modeData.startTime, "UTC") + val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") + if (timestamp in startTime..endTime) { + return modeData + } + } + throw Exception("No current mode found") + } fun getRotationTime(timestamp: Long): String { val modeData = getRegularMode(timestamp) val endTime = TimeUtil.deformatJSONTime(modeData.endTime, "UTC") -- 2.45.2 From 58f2379f45979736441f9d1817016c2aadb5bf39 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 19 Jan 2024 22:41:29 +0100 Subject: [PATCH 152/168] fix: make the StatusUpdater Run every 30 seconds instead of 10 to reduce the nr of status updates sent to Discord and avoid issues with updating the status Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt index 4aa8fb3..7fed538 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt @@ -30,7 +30,7 @@ object StatusUpdater : ICronjob { override val jobName: String get() = "StatusUpdater" override val jobIncoming: String - get() = "/10 * * * * * 0o *" //Every 5 seconds + get() = "/30 * * * * * 0o *" //Every 30 seconds override val jobType: CronjobType get() = CronjobType.INFINITE override val continueJob: Boolean -- 2.45.2 From 05b4dc39b51c045eb4849c4c9e62b2e66cd223bf Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 19 Jan 2024 22:41:52 +0100 Subject: [PATCH 153/168] feat: added new JSON time getter Signed-off-by: moonleay --- .../net/moonleay/lilJudd/util/TimeUtil.kt | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt index dba203c..acf0da8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -177,6 +177,24 @@ object TimeUtil { return ZonedDateTime.of(localDateTime, zoneId).toEpochSecond() * 1000 } + fun getTimeFromJSONTime(inp: String, zone: String): String { + // 2023-10-05T08:00:00Z + val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'") + val localDateTime = LocalDateTime.parse(inp, formatter) + val zoneId = ZoneId.of(zone) // TODO: Add the possibility to set your timezone + val returnFormat = DateTimeFormatter.ofPattern("HH:mm") + return ZonedDateTime.of(localDateTime, zoneId).format(returnFormat) + } + + fun getTimeFromJSONTimeLong(inp: String, zone: String): String { + // 2023-10-05T08:00:00Z + val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'") + val localDateTime = LocalDateTime.parse(inp, formatter) + val zoneId = ZoneId.of(zone) // TODO: Add the possibility to set your timezone + val returnFormat = DateTimeFormatter.ofPattern("dd'/'MM',' HH:mm") + return ZonedDateTime.of(localDateTime, zoneId).format(returnFormat) + } + fun getTimeDifferenceFormatted(start: Long, end: Long): String { val diff = end - start return getTimeFormatedShortend(diff, false) -- 2.45.2 From 98cdbebf795b1ba71f7639a822fd41426da0aee8 Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 19 Jan 2024 22:42:14 +0100 Subject: [PATCH 154/168] feat: added RotationExtension Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 1 + .../lilJudd/extensions/RotationExtension.kt | 464 ++++++++++++++++++ .../component/SplatoonOnlineMode.kt | 30 ++ 3 files changed, 495 insertions(+) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/extensions/RotationExtension.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/extensions/component/SplatoonOnlineMode.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 8282212..4196213 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -113,6 +113,7 @@ object Bot { add(::SendPlannerExtension) add(::MatchExtension) add(::UpdateRolesExtension) + add(::RotationExtension) } this.presence { diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/RotationExtension.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/RotationExtension.kt new file mode 100644 index 0000000..9c458b5 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/RotationExtension.kt @@ -0,0 +1,464 @@ +/* + * lilJudd + * Copyright (C) 2024 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.extensions + +import com.kotlindiscord.kord.extensions.commands.Arguments +import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.enumChoice +import com.kotlindiscord.kord.extensions.extensions.Extension +import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand +import dev.kord.common.Color +import dev.kord.rest.builder.message.embed +import kotlinx.datetime.Clock +import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiDataGrabber +import net.moonleay.lilJudd.extensions.component.SplatoonOnlineMode +import net.moonleay.lilJudd.util.TimeUtil + +class RotationExtension : Extension() { + + override val name = "rotation" + override val allowApplicationCommandInDMs: Boolean + get() = false + + + override suspend fun setup() { + publicSlashCommand(::RotationArguments) { + name = "rotation" + description = "Check the current rotations" + this.action { + val mode = this.arguments.mode + when (mode) { + SplatoonOnlineMode.ALL -> { + val regSched = Splatoon3ApiDataGrabber.getRegularMode(System.currentTimeMillis()) + val regMaps = regSched.regularMatchSetting.vsStages + val regMap1 = regMaps[0] + val regMap2 = regMaps[1] + + val serSched = Splatoon3ApiDataGrabber.getSeriesMode(System.currentTimeMillis()) + val serMaps = serSched.bankaraMatchSettings!!.first().vsStages + val serMap1 = serMaps[0] + val serMap2 = serMaps[1] + + val opnSched = Splatoon3ApiDataGrabber.getSeriesMode(System.currentTimeMillis()) + val opnMaps = opnSched.bankaraMatchSettings!!.last().vsStages + val opnMap1 = opnMaps[0] + val opnMap2 = opnMaps[1] + + val xSched = Splatoon3ApiDataGrabber.getXMode(System.currentTimeMillis()) + val xMaps = xSched.xMatchSetting.vsStages + val xMap1 = xMaps[0] + val xMap2 = xMaps[1] + + val salSched = Splatoon3ApiDataGrabber.getSalmonRun(System.currentTimeMillis()) + val salMap = salSched.setting.coopStage.name + val salBoss = salSched.setting.boss.name + val salWeapons = salSched.setting.weapons + + this.respond { + this.embed { + this.author { + this.name = "Current rotation for" + } + this.title = "All Modes" + this.description = "[[Open on website](https://splatoon3.ink/)]" + this.color = Color(0x1437FF) + + this.thumbnail { + this.url = "https://static.moonleay.net/img/lilJudd/deepcut.png" + } + + this.field { + this.name = "Regular (${ + TimeUtil.getTimeFromJSONTime( + regSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(regSched.endTime, "UTC")})" + this.value = + "${regSched.regularMatchSetting.vsRule.name} on ${regMap1.name} & ${regMap2.name}" + this.inline = false + } + + this.field { + this.name = "Series (${ + TimeUtil.getTimeFromJSONTime( + serSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(serSched.endTime, "UTC")})" + this.value = + "${serSched.bankaraMatchSettings.first().vsRule.name} on ${serMap1.name} & ${serMap2.name}" + this.inline = false + } + + this.field { + this.name = "Open (${ + TimeUtil.getTimeFromJSONTime( + opnSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(opnSched.endTime, "UTC")})" + this.value = + "${opnSched.bankaraMatchSettings.last().vsRule.name} on ${opnMap1.name} & ${opnMap2.name}" + this.inline = false + } + + this.field { + this.name = "X (${ + TimeUtil.getTimeFromJSONTime( + xSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(xSched.endTime, "UTC")})" + this.value = "${xSched.xMatchSetting.vsRule.name} on ${xMap1.name} & ${xMap2.name}" + this.inline = false + } + + this.field { + this.name = "Salmon Run (${ + TimeUtil.getTimeFromJSONTimeLong( + salSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTimeLong(salSched.endTime, "UTC")})" + this.value = + "${salBoss} on ${salMap} with ${salWeapons[0].name}, ${salWeapons[1].name}, ${salWeapons[2].name} & ${salWeapons[3].name}" + this.inline = false + } + + this.timestamp = Clock.System.now() + this.footer { + this.text = "Data provided by splatoon3.ink" + this.icon = "https://fedi.splatoon3.ink/favicon.png" + } + + } + } + } + + SplatoonOnlineMode.REGULAR -> { + val regSched = Splatoon3ApiDataGrabber.getRegularMode(System.currentTimeMillis()) + val regMaps = regSched.regularMatchSetting.vsStages + val regMap1 = regMaps[0] + val regMap2 = regMaps[1] + + val regSched2 = + Splatoon3ApiDataGrabber.getRegularMode(System.currentTimeMillis() + 1000 * 60 * 60 * 2) + val regMaps2 = regSched2.regularMatchSetting.vsStages + val regMap12 = regMaps2[0] + val regMap22 = regMaps2[1] + + this.respond { + this.embed { + this.author { + this.name = "Current rotation for" + } + this.title = "Regular Mode" + this.description = "[[Open on website](https://splatoon3.ink/)]" + this.color = Color(0x18c81b) + + this.thumbnail { + this.url = "https://static.moonleay.net/img/lilJudd/regular.png" + } + + this.field { + this.name = "Current (${ + TimeUtil.getTimeFromJSONTime( + regSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(regSched.endTime, "UTC")})" + this.value = + "${regSched.regularMatchSetting.vsRule.name} on ${regMap1.name} & ${regMap2.name}" + this.inline = false + } + + this.field { + this.name = "${ + TimeUtil.getTimeFromJSONTime( + regSched2.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(regSched2.endTime, "UTC")}" + this.value = + "${regSched2.regularMatchSetting.vsRule.name} on ${regMap12.name} & ${regMap22.name}" + this.inline = false + } + + + this.timestamp = Clock.System.now() + this.footer { + this.text = "Data provided by splatoon3.ink" + this.icon = "https://fedi.splatoon3.ink/favicon.png" + } + + } + } + } + + SplatoonOnlineMode.SERIES -> { + val serSched = Splatoon3ApiDataGrabber.getSeriesMode(System.currentTimeMillis()) + val serMaps = serSched.bankaraMatchSettings!!.first().vsStages + val serMap1 = serMaps[0] + val serMap2 = serMaps[1] + + val serSched2 = + Splatoon3ApiDataGrabber.getSeriesMode(System.currentTimeMillis() + 1000 * 60 * 60 * 2) + val serMaps2 = serSched2.bankaraMatchSettings!!.first().vsStages + val serMap12 = serMaps2[0] + val serMap22 = serMaps2[1] + + this.respond { + this.embed { + this.author { + this.name = "Current rotation for" + } + this.title = "Ranked Series Mode" + this.description = "[[Open on website](https://splatoon3.ink/)]" + this.color = Color(0xE14412) + + this.thumbnail { + this.url = "https://static.moonleay.net/img/lilJudd/bankara.png" + } + + this.field { + this.name = "Current (${ + TimeUtil.getTimeFromJSONTime( + serSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(serSched.endTime, "UTC")})" + this.value = + "${serSched.bankaraMatchSettings.first().vsRule.name} on ${serMap1.name} & ${serMap2.name}" + this.inline = false + } + + this.field { + this.name = "${ + TimeUtil.getTimeFromJSONTime( + serSched2.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(serSched2.endTime, "UTC")}" + this.value = + "${serSched2.bankaraMatchSettings.first().vsRule.name} on ${serMap12.name} & ${serMap22.name}" + this.inline = false + } + + + this.timestamp = Clock.System.now() + this.footer { + this.text = "Data provided by splatoon3.ink" + this.icon = "https://fedi.splatoon3.ink/favicon.png" + } + + } + } + } + + SplatoonOnlineMode.OPEN -> { + val opnSched = Splatoon3ApiDataGrabber.getSeriesMode(System.currentTimeMillis()) + val opnMaps = opnSched.bankaraMatchSettings!!.last().vsStages + val opnMap1 = opnMaps[0] + val opnMap2 = opnMaps[1] + + val opnSched2 = + Splatoon3ApiDataGrabber.getSeriesMode(System.currentTimeMillis() + 1000 * 60 * 60 * 2) + val opnMaps2 = opnSched2.bankaraMatchSettings!!.last().vsStages + val opnMap12 = opnMaps2[0] + val opnMap22 = opnMaps2[1] + + this.respond { + this.embed { + this.author { + this.name = "Current rotation for" + } + this.title = "Ranked Open Mode" + this.description = "[[Open on website](https://splatoon3.ink/)]" + this.color = Color(0xE14412) + + this.thumbnail { + this.url = "https://static.moonleay.net/img/lilJudd/bankara.png" + } + + this.field { + this.name = "Current (${ + TimeUtil.getTimeFromJSONTime( + opnSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(opnSched.endTime, "UTC")})" + this.value = + "${opnSched.bankaraMatchSettings.last().vsRule.name} on ${opnMap1.name} & ${opnMap2.name}" + this.inline = false + } + + this.field { + this.name = "${ + TimeUtil.getTimeFromJSONTime( + opnSched2.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(opnSched2.endTime, "UTC")}" + this.value = + "${opnSched2.bankaraMatchSettings.last().vsRule.name} on ${opnMap12.name} & ${opnMap22.name}" + this.inline = false + } + + + this.timestamp = Clock.System.now() + this.footer { + this.text = "Data provided by splatoon3.ink" + this.icon = "https://fedi.splatoon3.ink/favicon.png" + } + + } + } + } + + SplatoonOnlineMode.X -> { + val xSched = Splatoon3ApiDataGrabber.getXMode(System.currentTimeMillis()) + val xMaps = xSched.xMatchSetting.vsStages + val xMap1 = xMaps[0] + val xMap2 = xMaps[1] + + val xSched2 = Splatoon3ApiDataGrabber.getXMode(System.currentTimeMillis() + 1000 * 60 * 60 * 2) + val xMaps2 = xSched2.xMatchSetting.vsStages + val xMap12 = xMaps2[0] + val xMap22 = xMaps2[1] + + this.respond { + this.embed { + this.author { + this.name = "Current rotation for" + } + this.title = "X Mode" + this.description = "[[Open on website](https://splatoon3.ink/)]" + this.color = Color(0x0ECB93) + + this.thumbnail { + this.url = "https://static.moonleay.net/img/lilJudd/x.png" + } + + this.field { + this.name = "Current (${ + TimeUtil.getTimeFromJSONTime( + xSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(xSched.endTime, "UTC")})" + this.value = "${xSched.xMatchSetting.vsRule.name} on ${xMap1.name} & ${xMap2.name}" + this.inline = false + } + + this.field { + this.name = "${ + TimeUtil.getTimeFromJSONTime( + xSched2.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTime(xSched2.endTime, "UTC")}" + this.value = + "${xSched2.xMatchSetting.vsRule.name} on ${xMap12.name} & ${xMap22.name}" + this.inline = false + } + + + this.timestamp = Clock.System.now() + this.footer { + this.text = "Data provided by splatoon3.ink" + this.icon = "https://fedi.splatoon3.ink/favicon.png" + } + + } + } + } + + SplatoonOnlineMode.SALMON_RUN -> { + val salSched = Splatoon3ApiDataGrabber.getSalmonRun(System.currentTimeMillis()) + val salMap = salSched.setting.coopStage.name + val salBoss = salSched.setting.boss.name + val salWeapons = salSched.setting.weapons + + val salSched2 = + Splatoon3ApiDataGrabber.getSalmonRun(System.currentTimeMillis() + 1000 * 60 * 60 * 24 * 2) + val salMap2 = salSched2.setting.coopStage.name + val salBoss2 = salSched2.setting.boss.name + val salWeapons2 = salSched2.setting.weapons + + this.respond { + this.embed { + this.author { + this.name = "Current rotation for" + } + this.title = "Salmon Run" + this.description = "[[Open on website](https://splatoon3.ink/salmonrun)]" + this.color = Color(0xEA4F03) + + this.thumbnail { + this.url = "https://static.moonleay.net/img/lilJudd/grizz.png" + } + + this.field { + this.name = "Current (${ + TimeUtil.getTimeFromJSONTimeLong( + salSched.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTimeLong(salSched.endTime, "UTC")})" + this.value = + "${salBoss} on ${salMap} with ${salWeapons[0].name}, ${salWeapons[1].name}, ${salWeapons[2].name} & ${salWeapons[3].name}" + this.inline = false + } + + this.field { + this.name = "${ + TimeUtil.getTimeFromJSONTimeLong( + salSched2.startTime, + "UTC" + ) + } - ${TimeUtil.getTimeFromJSONTimeLong(salSched2.endTime, "UTC")}" + this.value = + "${salBoss2} on ${salMap2} with ${salWeapons2[0].name}, ${salWeapons2[1].name}, ${salWeapons2[2].name} & ${salWeapons2[3].name}" + this.inline = false + } + + + this.timestamp = Clock.System.now() + this.footer { + this.text = "Data provided by splatoon3.ink" + this.icon = "https://fedi.splatoon3.ink/favicon.png" + } + } + } + } + } + } + } + } + + inner class RotationArguments : Arguments() { + + val mode by enumChoice { + this.name = "mode" + this.description = "The mode you want to check the rotation for" + this.typeName = "en_US" + } + } + +} diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/SplatoonOnlineMode.kt b/src/main/kotlin/net/moonleay/lilJudd/extensions/component/SplatoonOnlineMode.kt new file mode 100644 index 0000000..c6ae569 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/extensions/component/SplatoonOnlineMode.kt @@ -0,0 +1,30 @@ +/* + * lilJudd + * Copyright (C) 2024 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.extensions.component + +import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum + +enum class SplatoonOnlineMode(override val readableName: String) : ChoiceEnum { + ALL("All Modes"), + REGULAR("Regular Battle"), + SERIES("Ranked Battle (Series)"), + OPEN("Ranked Battle (Open)"), + X("X Battle"), + SALMON_RUN("Salmon Run"), +} -- 2.45.2 From 02b29da5fdcd77d6ffb1ba63f28197ea87f945ad Mon Sep 17 00:00:00 2001 From: moonleay Date: Fri, 19 Jan 2024 22:42:22 +0100 Subject: [PATCH 155/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 5b2caaa..2da3144 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,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.6.8" + ?: "2.7.0" val kordver = "1.7.1-SNAPSHOT" val coroutinesver = "1.7.3" -- 2.45.2 From 46ee7997608b5565d263f76cf8e19f9de725dfcf Mon Sep 17 00:00:00 2001 From: moonleay Date: Sat, 20 Jan 2024 18:32:00 +0100 Subject: [PATCH 156/168] fix: fixed ci pipeline --- .forgejo/workflows/action.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.forgejo/workflows/action.yml b/.forgejo/workflows/action.yml index 8418c1c..4eff152 100644 --- a/.forgejo/workflows/action.yml +++ b/.forgejo/workflows/action.yml @@ -5,12 +5,10 @@ on: jobs: build-gradle-project: - runs-on: ubuntu-latest + runs-on: docker steps: - name: apt update run: apt update - - name: apt upgrade - run: apt upgrade -y - name: install prerequisits run: apt install openjdk-17-jdk ca-certificates-java ssl-cert openssl ca-certificates -y - name: Checkout project sources -- 2.45.2 From d0ae43e42071c65820ef880a984c37fd0676cd60 Mon Sep 17 00:00:00 2001 From: moonleay Date: Sun, 21 Jan 2024 01:58:25 +0100 Subject: [PATCH 157/168] chore: updated README.md Signed-off-by: moonleay --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 333bc9a..e1768f6 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,13 @@ A Discord Bot for Splatoon Teams. -More information can be found on the [Homepage](https://liljudd.ink). - ## Contributors [![Developer](https://img.shields.io/badge/moonleay-Developer-red)](https://gitlab.com/moonleay) ## Known issues -##### If you encounter any bugs, message me on Discord (@moonleay) or send me a mail (issues@moonleay.net). You can also open a ticket [on the support server](https://discord.gg/HTZRktfH4A). +##### If you encounter any bugs, message me on Discord (@moonleay) or email me (issues@moonleay.net). You can also open a ticket [on the support server](https://discord.gg/HTZRktfH4A). ## Commands & Features @@ -22,12 +20,13 @@ More information can be found on the [Homepage](https://liljudd.ink). - match -- Create a new match - updateroles -- Update the roles of all users - sendplanner -- Send the planner message + - rotation -- See the current rotation - Features - Time Planner -- Make the bot send messages and reactions into a selected channel in order to make planning easier - Availability Manager -- Make the bot assign users roles every day, so it is possible to notify available people - Match Planner -- Make a match, for which players can sign up and the bot will assign teams and roles to them -## (Maybe) upcoming features +## The todo list ##### See the [todo list](https://todo.moonleay.net/share/OmisuzgPDdsrCAXKjGrTfYzWwqNDNclOMGJWeMsi/auth?view=kanban) for more information. -- 2.45.2 From 95321b4895dd0ba09282e5f482e9870830c6f97b Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 29 Jan 2024 16:40:38 +0100 Subject: [PATCH 158/168] fix: fixed schedules not being deserialized correctly Signed-off-by: moonleay --- .../api/splatoon3ink/schedules/BannerImage.kt | 29 ++++++++++++++ .../schedules/CoopGroupingSchedule.kt | 2 +- .../api/splatoon3ink/schedules/CoopSetting.kt | 39 +++++++++++++++++++ .../splatoon3ink/schedules/TeamContestNode.kt | 33 ++++++++++++++++ .../schedules/TeamContestSchedules.kt | 3 +- 5 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BannerImage.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopSetting.kt create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestNode.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BannerImage.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BannerImage.kt new file mode 100644 index 0000000..3713c22 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BannerImage.kt @@ -0,0 +1,29 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class BannerImage( + @SerialName("url") + val url: String, +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt index 412e5fd..23770d9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt @@ -25,7 +25,7 @@ import kotlinx.serialization.Serializable @Serializable data class CoopGroupingSchedule( @SerialName("bannerImage") - val bannerImage: String?, // is null + val bannerImage: BannerImage?, // is null @SerialName("bigRunSchedules") val bigRunSchedules: BigRunSchedules, @SerialName("regularSchedules") diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopSetting.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopSetting.kt new file mode 100644 index 0000000..c4dce9f --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopSetting.kt @@ -0,0 +1,39 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class CoopSetting( + @SerialName("boss") + val boss: String?, // Not really String, but idk + @SerialName("coopStage") + val coopStage: CoopStage, + @SerialName("__isCoopSetting") + val isCoopSetting: String, + @SerialName("rule") + val rule: String, + @SerialName("__typename") + val typename: String, + @SerialName("weapons") + val weapons: List +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestNode.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestNode.kt new file mode 100644 index 0000000..309b1f9 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestNode.kt @@ -0,0 +1,33 @@ +/* + * lilJudd + * Copyright (C) 2024 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.api.splatoon3ink.schedules + + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class TeamContestNode( + @SerialName("endTime") + val endTime: String, + @SerialName("setting") + val setting: CoopSetting, + @SerialName("startTime") + val startTime: String +) diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt index e328191..f4e9adc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt @@ -23,8 +23,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -// TODO: Please check what goes here. data class TeamContestSchedules( @SerialName("nodes") - val nodes: List // This is a placeholder. + val nodes: List // This is a placeholder. ) -- 2.45.2 From 0f399cb58caad859f6657bf1651929a6f7d55dc1 Mon Sep 17 00:00:00 2001 From: moonleay Date: Mon, 29 Jan 2024 16:41:09 +0100 Subject: [PATCH 159/168] chore: bump version Signed-off-by: moonleay --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 2da3144..7fb8244 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,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.7.0" + ?: "2.7.1" val kordver = "1.7.1-SNAPSHOT" val coroutinesver = "1.7.3" -- 2.45.2 From 906c41be88fb87bfa43626ff5d403a29bade0841 Mon Sep 17 00:00:00 2001 From: moonleay Date: Wed, 31 Jan 2024 13:47:14 +0100 Subject: [PATCH 160/168] feat: make the bot save a stacktrace, if an error occurs during a command or interaction Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 26 +++++++++++-- .../moonleay/lilJudd/data/StacktraceSaver.kt | 37 +++++++++++++++++++ 2 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/StacktraceSaver.kt diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 4196213..7064745 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -26,12 +26,15 @@ import dev.kord.core.event.interaction.ButtonInteractionCreateEvent import dev.kord.core.on import dev.kord.gateway.Intent import dev.kord.gateway.PrivilegedIntent +import dev.kord.gateway.builder.Shards +import dev.kord.rest.builder.message.embed import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager +import net.moonleay.lilJudd.data.StacktraceSaver import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3Api import net.moonleay.lilJudd.data.database.DB import net.moonleay.lilJudd.extensions.* @@ -125,11 +128,26 @@ object Bot { +Intent.GuildMembers } - // Will add Sharding someday, I promise - /* - sharding { recommended -> + errorResponse { _, type -> + val stamp = System.currentTimeMillis() + this.embed { + this.title = "Oops. Something went wrong." + this.description = "The bot encountered an error during execution.\n" + + "Please report this to <@${BuildConstants.ownerID}>.\n" + + "The errorid is \"$stamp.stk\"" + this.field { + this.name = "Error message:" + this.value = type.error.message.toString() + this.inline = false + } + } + + StacktraceSaver.saveStacktrace(type.error, stamp) + } + + this.sharding { recommended -> Shards(recommended) - } */ + } } // Register button presses diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/StacktraceSaver.kt b/src/main/kotlin/net/moonleay/lilJudd/data/StacktraceSaver.kt new file mode 100644 index 0000000..b84ea13 --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/StacktraceSaver.kt @@ -0,0 +1,37 @@ +/* + * lilJudd + * Copyright (C) 2024 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 + +import java.io.File + +object StacktraceSaver { + fun saveStacktrace(stacktrace: Throwable, timestamp: Long) { + createFolder() + val dir = File("data", "stacktraces") + File(dir, "$timestamp.stk").bufferedWriter().use { out -> + out.write(stacktrace.stackTraceToString()) + } + } + + private fun createFolder() { + val dir = File("data", "stacktraces") + if (!dir.exists()) + dir.mkdir() + } +} -- 2.45.2 From 4dceef6a1fa39cdd636d5d4fe7fa7c54c60671cc Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 1 Feb 2024 23:15:04 +0100 Subject: [PATCH 161/168] feat!: (temp) dropped the Splatoon3ink api support --- build.gradle.kts | 2 +- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 7fb8244..eac9d28 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,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.7.1" + ?: "2.7.2" val kordver = "1.7.1-SNAPSHOT" val coroutinesver = "1.7.3" diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 7064745..3ba03e8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -186,12 +186,12 @@ object Bot { AvailabilityManager.runThread() // Update Availabilities MatchManager.update() // Update Matches // Make the bot update the status every 6 seconds - JobManager.addJob(StatusUpdater) +// JobManager.addJob(StatusUpdater) } // Update the Splatoon 3 api data and make sure it stays up-to-date - Splatoon3Api.updateSchedule() - JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) +// Splatoon3Api.updateSchedule() +// JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) /* Other caches will be added when implemented its not used yet in order to reduce load on the api, -- 2.45.2 From 8e1551cd6c3bcdc9867e1f3a438eea5bb985c9b3 Mon Sep 17 00:00:00 2001 From: moonleay Date: Thu, 1 Feb 2024 23:15:04 +0100 Subject: [PATCH 162/168] feat: added NewsManager, made bot dm news, when there are any at boot --- build.gradle.kts | 2 +- src/main/kotlin/net/moonleay/lilJudd/Bot.kt | 35 ++++- .../net/moonleay/lilJudd/data/NewsManager.kt | 120 ++++++++++++++++++ 3 files changed, 149 insertions(+), 8 deletions(-) create mode 100644 src/main/kotlin/net/moonleay/lilJudd/data/NewsManager.kt diff --git a/build.gradle.kts b/build.gradle.kts index 7fb8244..eac9d28 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,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.7.1" + ?: "2.7.2" val kordver = "1.7.1-SNAPSHOT" val coroutinesver = "1.7.3" diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt index 7064745..23796dd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/lilJudd/Bot.kt @@ -19,6 +19,7 @@ package net.moonleay.lilJudd import com.kotlindiscord.kord.extensions.ExtensibleBot +import com.kotlindiscord.kord.extensions.utils.dm import dev.kord.common.entity.PresenceStatus import dev.kord.core.behavior.interaction.response.respond import dev.kord.core.event.gateway.ReadyEvent @@ -34,22 +35,20 @@ import kotlinx.coroutines.Job import kotlinx.coroutines.launch import net.moonleay.lilJudd.buttons.component.EditButtonManager import net.moonleay.lilJudd.data.CredentialManager +import net.moonleay.lilJudd.data.NewsManager import net.moonleay.lilJudd.data.StacktraceSaver -import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3Api import net.moonleay.lilJudd.data.database.DB import net.moonleay.lilJudd.extensions.* import net.moonleay.lilJudd.features.AvailabilityManager import net.moonleay.lilJudd.features.MatchManager import net.moonleay.lilJudd.features.TimeManager -import net.moonleay.lilJudd.jobs.Splatoon3ApiScheduleUpdateScheduler -import net.moonleay.lilJudd.jobs.StatusUpdater -import net.moonleay.lilJudd.jobs.component.JobManager import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.lilJudd.util.Logger import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.liljudd.build.BuildConstants import kotlin.system.exitProcess + object Bot { //The kord object gets set at app launch lateinit var bot: ExtensibleBot @@ -185,13 +184,35 @@ object Bot { bot.kordRef.on { AvailabilityManager.runThread() // Update Availabilities MatchManager.update() // Update Matches + // Load news + NewsManager.load() + if(NewsManager.shouldPost == "yes"){ + bot.kordRef.guilds.collect { + val owner = it.owner.asUser() + Logger.out("Sent News to ${owner.username} from ${it.name}") + owner.dm { + this.embed { + this.title = NewsManager.title + this.description = NewsManager.news + this.footer { + this.icon = bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } + } + } + } + NewsManager.shouldPost = "no" + NewsManager.update() + } + + // Make the bot update the status every 6 seconds - JobManager.addJob(StatusUpdater) +// JobManager.addJob(StatusUpdater) } // Update the Splatoon 3 api data and make sure it stays up-to-date - Splatoon3Api.updateSchedule() - JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) +// Splatoon3Api.updateSchedule() +// JobManager.addJob(Splatoon3ApiScheduleUpdateScheduler) /* Other caches will be added when implemented its not used yet in order to reduce load on the api, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/NewsManager.kt b/src/main/kotlin/net/moonleay/lilJudd/data/NewsManager.kt new file mode 100644 index 0000000..9db6a8c --- /dev/null +++ b/src/main/kotlin/net/moonleay/lilJudd/data/NewsManager.kt @@ -0,0 +1,120 @@ +/* + * lilJudd + * Copyright (C) 2024 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 + +import java.io.* +import java.util.* + +object NewsManager { + private const val foldername = "data" + private const val filename = "news.nick" + lateinit var shouldPost: String + lateinit var title: String + lateinit var news: String + + ///Load the needed credentials, generate a config if there is none + fun load() { + val folder = File(foldername) + if (!folder.exists()) { + save() + return + } + val configFile = File(folder, filename) + if (!configFile.exists()) { + save() + return + } + try { + val input: InputStream = FileInputStream(foldername + File.separator + filename) + val prop = Properties() + prop.load(input) + shouldPost = prop.getProperty("shouldPost") + title = prop.getProperty("title") + news = prop.getProperty("news") + input.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + + fun update(){ + val folder = File(foldername) + if (!folder.exists()) { + try { + folder.mkdirs() + } catch (e: IOException) { + e.printStackTrace() + } + } + val configFile = File(foldername + File.separator + filename) + if (!configFile.exists()) { + try { + configFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + try { + val output: OutputStream = FileOutputStream(foldername + File.separator + filename) + val prop = Properties() + prop.setProperty("shouldPost", shouldPost) + prop.setProperty("title", title) + prop.setProperty("news", news) + prop.store(output, null) + output.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + + ///generate a new sample config + private fun save() { + val folder = File(foldername) + if (!folder.exists()) { + try { + folder.mkdirs() + } catch (e: IOException) { + e.printStackTrace() + } + } + val configFile = File(foldername + File.separator + filename) + if (!configFile.exists()) { + try { + configFile.createNewFile() + } catch (e: IOException) { + e.printStackTrace() + } + } + try { + val output: OutputStream = FileOutputStream(foldername + File.separator + filename) + val prop = Properties() + prop.setProperty("shouldPost", "no") + prop.setProperty("title", "empty") + prop.setProperty("news", "empty") + prop.store(output, null) + output.close() + + shouldPost = "no" + title = "empty" + news = "empty" + } catch (e: IOException) { + e.printStackTrace() + } + } +} -- 2.45.2 From ab7016cdb348e3ee5caad5c492b105ebeadf405b Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 13 Feb 2024 18:47:24 +0100 Subject: [PATCH 163/168] feat: added little note at boot fix!: fixed compilation issues on Winblows (This resulted in a new base package.) Signed-off-by: moonleay --- .../net/moonleay/{lilJudd => liljudd}/Bot.kt | 26 ++++++++--------- .../net/moonleay/{lilJudd => liljudd}/Main.kt | 9 ++++-- .../buttons/component/EditButtonManager.kt | 14 +++++----- .../buttons/component/IEditButton.kt | 2 +- .../buttons/matchplanner/AcceptEditButton.kt | 14 +++++----- .../buttons/matchplanner/CancelEditButton.kt | 12 ++++---- .../buttons/matchplanner/DeclineEditButton.kt | 14 +++++----- .../timeplanner/IsAvailableEditButton.kt | 10 +++---- .../timeplanner/MaybeAvailableEditButton.kt | 10 +++---- .../timeplanner/NotAvailableEditButton.kt | 10 +++---- .../data/CredentialManager.kt | 2 +- .../{lilJudd => liljudd}/data/NewsManager.kt | 2 +- .../data/StacktraceSaver.kt | 2 +- .../data/api/splatoon3ink/Splatoon3Api.kt | 6 ++-- .../splatoon3ink/Splatoon3ApiDataGrabber.kt | 12 ++++---- .../schedules/BankaraMatchSetting.kt | 2 +- .../api/splatoon3ink/schedules/BankaraNode.kt | 2 +- .../schedules/BankaraSchedules.kt | 2 +- .../api/splatoon3ink/schedules/BannerImage.kt | 2 +- .../splatoon3ink/schedules/BigRunSchedules.kt | 2 +- .../data/api/splatoon3ink/schedules/Boss.kt | 2 +- .../data/api/splatoon3ink/schedules/Color.kt | 2 +- .../schedules/CoopGroupingSchedule.kt | 2 +- .../api/splatoon3ink/schedules/CoopSetting.kt | 2 +- .../api/splatoon3ink/schedules/CoopStage.kt | 2 +- .../api/splatoon3ink/schedules/CurrentFest.kt | 2 +- .../splatoon3ink/schedules/CurrentPlayer.kt | 2 +- .../api/splatoon3ink/schedules/EventNode.kt | 2 +- .../splatoon3ink/schedules/EventSchedules.kt | 2 +- .../schedules/FestMatchSettingX.kt | 2 +- .../schedules/FestMatchSettingXX.kt | 2 +- .../api/splatoon3ink/schedules/FestNode.kt | 2 +- .../splatoon3ink/schedules/FestSchedules.kt | 2 +- .../data/api/splatoon3ink/schedules/Image.kt | 2 +- .../schedules/LeagueMatchEvent.kt | 2 +- .../schedules/LeagueMatchSetting.kt | 2 +- .../api/splatoon3ink/schedules/MapNode.kt | 2 +- .../splatoon3ink/schedules/OriginalImage.kt | 2 +- .../schedules/RegularMatchSetting.kt | 2 +- .../api/splatoon3ink/schedules/RegularNode.kt | 2 +- .../schedules/RegularSchedules.kt | 2 +- .../schedules/RegularSchedulesX.kt | 2 +- .../splatoon3ink/schedules/SalmonRunNode.kt | 2 +- .../api/splatoon3ink/schedules/Schedules.kt | 2 +- .../splatoon3ink/schedules/SchedulesData.kt | 2 +- .../api/splatoon3ink/schedules/Setting.kt | 2 +- .../data/api/splatoon3ink/schedules/Team.kt | 2 +- .../splatoon3ink/schedules/TeamContestNode.kt | 2 +- .../schedules/TeamContestSchedules.kt | 2 +- .../splatoon3ink/schedules/ThumbnailImage.kt | 2 +- .../api/splatoon3ink/schedules/TimePeriod.kt | 2 +- .../splatoon3ink/schedules/TricolorStage.kt | 2 +- .../api/splatoon3ink/schedules/UserIcon.kt | 2 +- .../data/api/splatoon3ink/schedules/VsRule.kt | 2 +- .../api/splatoon3ink/schedules/VsStage.kt | 2 +- .../api/splatoon3ink/schedules/VsStages.kt | 2 +- .../data/api/splatoon3ink/schedules/Weapon.kt | 2 +- .../splatoon3ink/schedules/XMatchSetting.kt | 2 +- .../data/api/splatoon3ink/schedules/XNode.kt | 2 +- .../api/splatoon3ink/schedules/XSchedules.kt | 2 +- .../{lilJudd => liljudd}/data/database/DB.kt | 10 +++---- .../database/entry/MatchPlanningDataData.kt | 2 +- .../entry/PlanningNotifierRolesData.kt | 2 +- .../entry/TimePlanningChannelsData.kt | 2 +- .../entry/TimePlanningMessagesData.kt | 2 +- .../repository/MatchPlanningDataRepository.kt | 11 +++++--- .../PlanningNotifierRolesRepository.kt | 11 +++++--- .../TimePlanningChannelsRepository.kt | 11 +++++--- .../TimePlanningMessagesRepository.kt | 11 ++++---- .../data/database/tables/MatchPlanningData.kt | 2 +- .../database/tables/PlanningNotifierRoles.kt | 2 +- .../database/tables/TimePlanningChannels.kt | 2 +- .../database/tables/TimePlanningMessages.kt | 2 +- .../extensions/FeatureManageExtension.kt | 14 +++++----- .../extensions/InfoExtension.kt | 4 +-- .../extensions/MatchExtension.kt | 20 ++++++------- .../extensions/RotationExtension.kt | 8 +++--- .../extensions/SendPlannerExtension.kt | 10 +++---- .../extensions/UpdateRolesExtension.kt | 10 +++---- .../extensions/component/EnableOrDisable.kt | 2 +- .../extensions/component/MatchTypes.kt | 2 +- .../component/SplatoonOnlineMode.kt | 2 +- .../features/AvailabilityManager.kt | 20 ++++++------- .../features/MatchManager.kt | 14 +++++----- .../features/TimeManager.kt | 28 +++++++++---------- .../features/component/FeatureEnum.kt | 2 +- .../features/component/FeatureManager.kt | 6 ++-- .../features/component/IFeature.kt | 4 +-- .../{lilJudd => liljudd}/jobs/MatchJob.kt | 14 +++++----- .../Splatoon3ApiScheduleUpdateScheduler.kt | 10 +++---- .../jobs/StatusUpdater.kt | 10 +++---- .../jobs/component/CronjobType.kt | 2 +- .../jobs/component/ICronjob.kt | 2 +- .../jobs/component/JobManager.kt | 4 +-- .../{lilJudd => liljudd}/util/EmbedColor.kt | 2 +- .../{lilJudd => liljudd}/util/EmbedUtil.kt | 2 +- .../{lilJudd => liljudd}/util/Logger.kt | 2 +- .../{lilJudd => liljudd}/util/MessageUtil.kt | 2 +- .../{lilJudd => liljudd}/util/NetUtil.kt | 2 +- .../{lilJudd => liljudd}/util/TimeUtil.kt | 2 +- 100 files changed, 259 insertions(+), 246 deletions(-) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/Bot.kt (92%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/Main.kt (74%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/buttons/component/EditButtonManager.kt (69%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/buttons/component/IEditButton.kt (96%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/buttons/matchplanner/AcceptEditButton.kt (92%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/buttons/matchplanner/CancelEditButton.kt (90%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/buttons/matchplanner/DeclineEditButton.kt (92%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/buttons/timeplanner/IsAvailableEditButton.kt (91%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/buttons/timeplanner/MaybeAvailableEditButton.kt (91%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/buttons/timeplanner/NotAvailableEditButton.kt (91%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/CredentialManager.kt (99%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/NewsManager.kt (99%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/StacktraceSaver.kt (97%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/Splatoon3Api.kt (88%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/BankaraNode.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/BankaraSchedules.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/BannerImage.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/BigRunSchedules.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/Boss.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/Color.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/CoopSetting.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/CoopStage.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/CurrentFest.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/CurrentPlayer.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/EventNode.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/EventSchedules.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/FestMatchSettingX.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/FestNode.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/FestSchedules.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/Image.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/MapNode.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/OriginalImage.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/RegularMatchSetting.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/RegularNode.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/RegularSchedules.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/RegularSchedulesX.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/SalmonRunNode.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/Schedules.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/SchedulesData.kt (96%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/Setting.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/Team.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/TeamContestNode.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/TeamContestSchedules.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/ThumbnailImage.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/TimePeriod.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/TricolorStage.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/UserIcon.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/VsRule.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/VsStage.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/VsStages.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/Weapon.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/XMatchSetting.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/XNode.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/api/splatoon3ink/schedules/XSchedules.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/DB.kt (84%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/entry/MatchPlanningDataData.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/entry/PlanningNotifierRolesData.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/entry/TimePlanningChannelsData.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/entry/TimePlanningMessagesData.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/repository/MatchPlanningDataRepository.kt (92%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/repository/PlanningNotifierRolesRepository.kt (91%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/repository/TimePlanningChannelsRepository.kt (87%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/repository/TimePlanningMessagesRepository.kt (89%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/tables/MatchPlanningData.kt (96%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/tables/PlanningNotifierRoles.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/tables/TimePlanningChannels.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/data/database/tables/TimePlanningMessages.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/FeatureManageExtension.kt (93%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/InfoExtension.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/MatchExtension.kt (92%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/RotationExtension.kt (99%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/SendPlannerExtension.kt (96%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/UpdateRolesExtension.kt (92%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/component/EnableOrDisable.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/component/MatchTypes.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/extensions/component/SplatoonOnlineMode.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/features/AvailabilityManager.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/features/MatchManager.kt (86%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/features/TimeManager.kt (91%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/features/component/FeatureEnum.kt (95%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/features/component/FeatureManager.kt (85%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/features/component/IFeature.kt (92%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/jobs/MatchJob.kt (85%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/jobs/Splatoon3ApiScheduleUpdateScheduler.kt (85%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/jobs/StatusUpdater.kt (90%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/jobs/component/CronjobType.kt (94%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/jobs/component/ICronjob.kt (96%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/jobs/component/JobManager.kt (97%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/util/EmbedColor.kt (96%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/util/EmbedUtil.kt (99%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/util/Logger.kt (97%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/util/MessageUtil.kt (99%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/util/NetUtil.kt (98%) rename src/main/kotlin/net/moonleay/{lilJudd => liljudd}/util/TimeUtil.kt (99%) diff --git a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt b/src/main/kotlin/net/moonleay/liljudd/Bot.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/Bot.kt rename to src/main/kotlin/net/moonleay/liljudd/Bot.kt index 23796dd..9f4c42e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/liljudd/Bot.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd +package net.moonleay.liljudd import com.kotlindiscord.kord.extensions.ExtensibleBot import com.kotlindiscord.kord.extensions.utils.dm @@ -33,19 +33,19 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.launch -import net.moonleay.lilJudd.buttons.component.EditButtonManager -import net.moonleay.lilJudd.data.CredentialManager -import net.moonleay.lilJudd.data.NewsManager -import net.moonleay.lilJudd.data.StacktraceSaver -import net.moonleay.lilJudd.data.database.DB -import net.moonleay.lilJudd.extensions.* -import net.moonleay.lilJudd.features.AvailabilityManager -import net.moonleay.lilJudd.features.MatchManager -import net.moonleay.lilJudd.features.TimeManager -import net.moonleay.lilJudd.util.EmbedColor -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil import net.moonleay.liljudd.build.BuildConstants +import net.moonleay.liljudd.buttons.component.EditButtonManager +import net.moonleay.liljudd.data.CredentialManager +import net.moonleay.liljudd.data.NewsManager +import net.moonleay.liljudd.data.StacktraceSaver +import net.moonleay.liljudd.data.database.DB +import net.moonleay.liljudd.extensions.* +import net.moonleay.liljudd.features.AvailabilityManager +import net.moonleay.liljudd.features.MatchManager +import net.moonleay.liljudd.features.TimeManager +import net.moonleay.liljudd.util.EmbedColor +import net.moonleay.liljudd.util.Logger +import net.moonleay.liljudd.util.MessageUtil import kotlin.system.exitProcess diff --git a/src/main/kotlin/net/moonleay/lilJudd/Main.kt b/src/main/kotlin/net/moonleay/liljudd/Main.kt similarity index 74% rename from src/main/kotlin/net/moonleay/lilJudd/Main.kt rename to src/main/kotlin/net/moonleay/liljudd/Main.kt index 36be8b3..d8e4dce 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/Main.kt +++ b/src/main/kotlin/net/moonleay/liljudd/Main.kt @@ -15,9 +15,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ -package net.moonleay.lilJudd +package net.moonleay.liljudd import net.moonleay.liljudd.build.BuildConstants +import net.moonleay.liljudd.util.Logger suspend fun main() { @@ -27,9 +28,11 @@ suspend fun main() { "| |_| |__| |_ _ _| |_| |\n" + "| | | | | | | | . | . |\n" + "|_|_|_|_____|___|___|___|\n" + - " " + "v.${BuildConstants.version}\n" ) - println("v.${BuildConstants.version}") + + Logger.out("li'l Judd made by moonleay (https://moonleay.net). Web UI made by IchLiebeZuege (https://mal-noh.de).") + Logger.out("For more information check out https://liljudd.ink and https://git.moonleay.net/DiscordBots/lilJudd") Bot.start() } diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/component/EditButtonManager.kt similarity index 69% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt rename to src/main/kotlin/net/moonleay/liljudd/buttons/component/EditButtonManager.kt index f0df57f..38690ea 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/EditButtonManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/component/EditButtonManager.kt @@ -16,14 +16,14 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.buttons.component +package net.moonleay.liljudd.buttons.component -import net.moonleay.lilJudd.buttons.matchplanner.AcceptEditButton -import net.moonleay.lilJudd.buttons.matchplanner.CancelEditButton -import net.moonleay.lilJudd.buttons.matchplanner.DeclineEditButton -import net.moonleay.lilJudd.buttons.timeplanner.IsAvailableEditButton -import net.moonleay.lilJudd.buttons.timeplanner.MaybeAvailableEditButton -import net.moonleay.lilJudd.buttons.timeplanner.NotAvailableEditButton +import net.moonleay.liljudd.buttons.matchplanner.AcceptEditButton +import net.moonleay.liljudd.buttons.matchplanner.CancelEditButton +import net.moonleay.liljudd.buttons.matchplanner.DeclineEditButton +import net.moonleay.liljudd.buttons.timeplanner.IsAvailableEditButton +import net.moonleay.liljudd.buttons.timeplanner.MaybeAvailableEditButton +import net.moonleay.liljudd.buttons.timeplanner.NotAvailableEditButton object EditButtonManager { val buttons = listOf( diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/component/IEditButton.kt similarity index 96% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt rename to src/main/kotlin/net/moonleay/liljudd/buttons/component/IEditButton.kt index 0fbe64e..3c32805 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/component/IEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/component/IEditButton.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.buttons.component +package net.moonleay.liljudd.buttons.component import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior import dev.kord.core.entity.Guild diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/AcceptEditButton.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt rename to src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/AcceptEditButton.kt index ff4d4cf..8a32c1c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/AcceptEditButton.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.buttons.matchplanner +package net.moonleay.liljudd.buttons.matchplanner import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.edit @@ -27,12 +27,12 @@ import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.buttons.component.IEditButton +import net.moonleay.liljudd.data.database.repository.MatchPlanningDataRepository +import net.moonleay.liljudd.util.EmbedUtil +import net.moonleay.liljudd.util.Logger +import net.moonleay.liljudd.util.MessageUtil class AcceptEditButton : IEditButton { override val id: String = "public.edit.btn.matchmanagement.accept" diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/CancelEditButton.kt similarity index 90% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt rename to src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/CancelEditButton.kt index 12eaea1..c1a54a7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/CancelEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/CancelEditButton.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.buttons.matchplanner +package net.moonleay.liljudd.buttons.matchplanner import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.edit @@ -27,11 +27,11 @@ import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.Logger +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.buttons.component.IEditButton +import net.moonleay.liljudd.data.database.repository.MatchPlanningDataRepository +import net.moonleay.liljudd.util.EmbedUtil +import net.moonleay.liljudd.util.Logger class CancelEditButton : IEditButton { override val id: String = "public.edit.btn.matchmanagement.cancel" diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/DeclineEditButton.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt rename to src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/DeclineEditButton.kt index d205b05..a2bacde 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/DeclineEditButton.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.buttons.matchplanner +package net.moonleay.liljudd.buttons.matchplanner import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.edit @@ -27,12 +27,12 @@ import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.buttons.component.IEditButton +import net.moonleay.liljudd.data.database.repository.MatchPlanningDataRepository +import net.moonleay.liljudd.util.EmbedUtil +import net.moonleay.liljudd.util.Logger +import net.moonleay.liljudd.util.MessageUtil class DeclineEditButton : IEditButton { override val id: String = "public.edit.btn.matchmanagement.decline" diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/IsAvailableEditButton.kt similarity index 91% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt rename to src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/IsAvailableEditButton.kt index ccc67fd..f13a732 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/IsAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/IsAvailableEditButton.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.buttons.timeplanner +package net.moonleay.liljudd.buttons.timeplanner import dev.kord.core.behavior.edit import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior @@ -25,10 +25,10 @@ import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.features.AvailabilityManager -import net.moonleay.lilJudd.util.EmbedUtil +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.buttons.component.IEditButton +import net.moonleay.liljudd.features.AvailabilityManager +import net.moonleay.liljudd.util.EmbedUtil class IsAvailableEditButton : IEditButton { override val id: String = "public.edit.btn.timemanagement.available" diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/MaybeAvailableEditButton.kt similarity index 91% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt rename to src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/MaybeAvailableEditButton.kt index a8b174c..5d17f4d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/MaybeAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/MaybeAvailableEditButton.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.buttons.timeplanner +package net.moonleay.liljudd.buttons.timeplanner import dev.kord.core.behavior.edit import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior @@ -25,10 +25,10 @@ import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.features.AvailabilityManager -import net.moonleay.lilJudd.util.EmbedUtil +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.buttons.component.IEditButton +import net.moonleay.liljudd.features.AvailabilityManager +import net.moonleay.liljudd.util.EmbedUtil class MaybeAvailableEditButton : IEditButton { override val id: String = "public.edit.btn.timemanagement.maybeavailable" diff --git a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/NotAvailableEditButton.kt similarity index 91% rename from src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt rename to src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/NotAvailableEditButton.kt index e5e8103..14527be 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/buttons/timeplanner/NotAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/NotAvailableEditButton.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.buttons.timeplanner +package net.moonleay.liljudd.buttons.timeplanner import dev.kord.core.behavior.edit import dev.kord.core.behavior.interaction.response.PublicMessageInteractionResponseBehavior @@ -25,10 +25,10 @@ import dev.kord.core.entity.User import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.entity.interaction.ButtonInteraction import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.buttons.component.IEditButton -import net.moonleay.lilJudd.features.AvailabilityManager -import net.moonleay.lilJudd.util.EmbedUtil +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.buttons.component.IEditButton +import net.moonleay.liljudd.features.AvailabilityManager +import net.moonleay.liljudd.util.EmbedUtil class NotAvailableEditButton : IEditButton { override val id: String = "public.edit.btn.timemanagement.notavailable" diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/CredentialManager.kt b/src/main/kotlin/net/moonleay/liljudd/data/CredentialManager.kt similarity index 99% rename from src/main/kotlin/net/moonleay/lilJudd/data/CredentialManager.kt rename to src/main/kotlin/net/moonleay/liljudd/data/CredentialManager.kt index e406414..7a92197 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/CredentialManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/CredentialManager.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data +package net.moonleay.liljudd.data import java.io.* import java.util.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/NewsManager.kt b/src/main/kotlin/net/moonleay/liljudd/data/NewsManager.kt similarity index 99% rename from src/main/kotlin/net/moonleay/lilJudd/data/NewsManager.kt rename to src/main/kotlin/net/moonleay/liljudd/data/NewsManager.kt index 9db6a8c..30dc1e4 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/NewsManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/NewsManager.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data +package net.moonleay.liljudd.data import java.io.* import java.util.* diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/StacktraceSaver.kt b/src/main/kotlin/net/moonleay/liljudd/data/StacktraceSaver.kt similarity index 97% rename from src/main/kotlin/net/moonleay/lilJudd/data/StacktraceSaver.kt rename to src/main/kotlin/net/moonleay/liljudd/data/StacktraceSaver.kt index b84ea13..84828c2 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/StacktraceSaver.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/StacktraceSaver.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data +package net.moonleay.liljudd.data import java.io.File diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/Splatoon3Api.kt similarity index 88% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/Splatoon3Api.kt index 100c9dc..2b7fa40 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3Api.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/Splatoon3Api.kt @@ -16,12 +16,12 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink +package net.moonleay.liljudd.data.api.splatoon3ink import kotlinx.serialization.json.Json -import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.Schedules -import net.moonleay.lilJudd.util.NetUtil import net.moonleay.liljudd.build.BuildConstants +import net.moonleay.liljudd.data.api.splatoon3ink.schedules.Schedules +import net.moonleay.liljudd.util.NetUtil object Splatoon3Api { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt index f24a46f..5357116 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/Splatoon3ApiDataGrabber.kt @@ -16,13 +16,13 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink +package net.moonleay.liljudd.data.api.splatoon3ink -import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.BankaraNode -import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.RegularNode -import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.SalmonRunNode -import net.moonleay.lilJudd.data.api.splatoon3ink.schedules.XNode -import net.moonleay.lilJudd.util.TimeUtil +import net.moonleay.liljudd.data.api.splatoon3ink.schedules.BankaraNode +import net.moonleay.liljudd.data.api.splatoon3ink.schedules.RegularNode +import net.moonleay.liljudd.data.api.splatoon3ink.schedules.SalmonRunNode +import net.moonleay.liljudd.data.api.splatoon3ink.schedules.XNode +import net.moonleay.liljudd.util.TimeUtil object Splatoon3ApiDataGrabber { fun getRegularMode(timestamp: Long): RegularNode { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt index 773f4e8..d4188cd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraMatchSetting.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraNode.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraNode.kt index 953c79a..20f0c9a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraNode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraNode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt index a770703..7f6cd90 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BankaraSchedules.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BannerImage.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BannerImage.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BannerImage.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BannerImage.kt index 3713c22..245536a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BannerImage.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BannerImage.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt index 47b5890..476dc59 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/BigRunSchedules.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Boss.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Boss.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Boss.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Boss.kt index 1501727..abf1858 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Boss.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Boss.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Color.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Color.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Color.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Color.kt index 7ed55be..b359a33 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Color.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Color.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt index 23770d9..1a5d5be 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopGroupingSchedule.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopSetting.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopSetting.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopSetting.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopSetting.kt index c4dce9f..7f20c4c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopSetting.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopSetting.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopStage.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopStage.kt index 2cb21da..6441baa 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CoopStage.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CoopStage.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CurrentFest.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CurrentFest.kt index d13d8fd..e2fe9ed 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentFest.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CurrentFest.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt index 5abc31b..50c8f74 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/CurrentPlayer.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/EventNode.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/EventNode.kt index 96e1419..2e66a3c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventNode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/EventNode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/EventSchedules.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/EventSchedules.kt index c86ea33..fb6ed6f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/EventSchedules.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/EventSchedules.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt index 8b212c8..db4e294 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestMatchSettingX.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt index a1f5d3d..d2fbfc5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestMatchSettingXX.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestNode.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestNode.kt index b9b4262..8e869a9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestNode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestNode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestSchedules.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestSchedules.kt index d606246..9a1acc7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/FestSchedules.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/FestSchedules.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Image.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Image.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Image.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Image.kt index f635fa6..9543b8a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Image.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Image.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt index 64fe6b9..494703b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/LeagueMatchEvent.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt index 8008afc..41cf553 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/LeagueMatchSetting.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/MapNode.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/MapNode.kt index b1c3813..f17d17c 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/MapNode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/MapNode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/OriginalImage.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/OriginalImage.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/OriginalImage.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/OriginalImage.kt index e294963..0393f71 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/OriginalImage.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/OriginalImage.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt index 44da86c..ea899be 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularMatchSetting.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularNode.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularNode.kt index 321e0be..9a6935f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularNode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularNode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularSchedules.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularSchedules.kt index ab2ccd8..b6c55db 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedules.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularSchedules.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt index 132b607..04418e0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/RegularSchedulesX.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt index 85c4c8a..ad53d45 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/SalmonRunNode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Schedules.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Schedules.kt index 10c9412..f3d08c7 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Schedules.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Schedules.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/SchedulesData.kt similarity index 96% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/SchedulesData.kt index 21e4c48..0bf967a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/SchedulesData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/SchedulesData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Setting.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Setting.kt index 8d1529b..3ebd2f2 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Setting.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Setting.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Team.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Team.kt index 2ee6032..8043c5d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Team.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Team.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestNode.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TeamContestNode.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestNode.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TeamContestNode.kt index 309b1f9..22b36d8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestNode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TeamContestNode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt index f4e9adc..1265efc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TeamContestSchedules.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt index cb357a9..9fb03cd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/ThumbnailImage.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TimePeriod.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TimePeriod.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TimePeriod.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TimePeriod.kt index 99037bf..d86de17 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TimePeriod.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TimePeriod.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TricolorStage.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TricolorStage.kt index 21ba8c5..b5685cc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/TricolorStage.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/TricolorStage.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/UserIcon.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/UserIcon.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/UserIcon.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/UserIcon.kt index 74ee2eb..673f73a 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/UserIcon.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/UserIcon.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsRule.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsRule.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsRule.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsRule.kt index 5e47251..bddb5a5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsRule.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsRule.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsStage.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsStage.kt index 3225c3d..0b9cebf 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStage.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsStage.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsStages.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsStages.kt index 08501f9..142508d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/VsStages.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/VsStages.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Weapon.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Weapon.kt index 66f880c..a65820d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/Weapon.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/Weapon.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XMatchSetting.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XMatchSetting.kt index 5a1dc64..edca851 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XMatchSetting.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XMatchSetting.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XNode.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XNode.kt index 95b8435..0242771 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XNode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XNode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XSchedules.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt rename to src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XSchedules.kt index ba079aa..9de2887 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/api/splatoon3ink/schedules/XSchedules.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/api/splatoon3ink/schedules/XSchedules.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.api.splatoon3ink.schedules +package net.moonleay.liljudd.data.api.splatoon3ink.schedules import kotlinx.serialization.SerialName diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/DB.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/DB.kt similarity index 84% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/DB.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/DB.kt index 7c58ea0..9dd9943 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/DB.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/DB.kt @@ -16,13 +16,13 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database +package net.moonleay.liljudd.data.database -import net.moonleay.lilJudd.data.database.tables.MatchPlanningData -import net.moonleay.lilJudd.data.database.tables.PlanningNotifierRoles -import net.moonleay.lilJudd.data.database.tables.TimePlanningChannels -import net.moonleay.lilJudd.data.database.tables.TimePlanningMessages +import net.moonleay.liljudd.data.database.tables.MatchPlanningData +import net.moonleay.liljudd.data.database.tables.PlanningNotifierRoles +import net.moonleay.liljudd.data.database.tables.TimePlanningChannels +import net.moonleay.liljudd.data.database.tables.TimePlanningMessages import org.jetbrains.exposed.sql.Database import org.jetbrains.exposed.sql.SchemaUtils import org.jetbrains.exposed.sql.transactions.transaction diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/MatchPlanningDataData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/MatchPlanningDataData.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/entry/MatchPlanningDataData.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/entry/MatchPlanningDataData.kt index b19c5e7..c430527 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/MatchPlanningDataData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/MatchPlanningDataData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.entry +package net.moonleay.liljudd.data.database.entry data class MatchPlanningDataData( val id: Int, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/PlanningNotifierRolesData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/PlanningNotifierRolesData.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/entry/PlanningNotifierRolesData.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/entry/PlanningNotifierRolesData.kt index c58130a..ab809c5 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/PlanningNotifierRolesData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/PlanningNotifierRolesData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.entry +package net.moonleay.liljudd.data.database.entry data class PlanningNotifierRolesData( val id: Int, // The id of the entry diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningChannelsData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningChannelsData.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningChannelsData.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningChannelsData.kt index 7edd496..a0c6988 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningChannelsData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningChannelsData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.entry +package net.moonleay.liljudd.data.database.entry data class TimePlanningChannelsData( val id: Int, diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningMessagesData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningMessagesData.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningMessagesData.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningMessagesData.kt index 3126e2c..fa4d6f6 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/entry/TimePlanningMessagesData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningMessagesData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.entry +package net.moonleay.liljudd.data.database.entry data class TimePlanningMessagesData( val id: Int, // The id of the entry diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/MatchPlanningDataRepository.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/repository/MatchPlanningDataRepository.kt index 6b0bbd9..a4c078f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/MatchPlanningDataRepository.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/MatchPlanningDataRepository.kt @@ -16,12 +16,15 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.repository +package net.moonleay.liljudd.data.database.repository -import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.database.tables.MatchPlanningData -import org.jetbrains.exposed.sql.* +import net.moonleay.liljudd.data.database.entry.MatchPlanningDataData +import net.moonleay.liljudd.data.database.tables.MatchPlanningData import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction object MatchPlanningDataRepository { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/PlanningNotifierRolesRepository.kt similarity index 91% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/repository/PlanningNotifierRolesRepository.kt index eea22df..0b02f39 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/PlanningNotifierRolesRepository.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/PlanningNotifierRolesRepository.kt @@ -16,12 +16,15 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.repository +package net.moonleay.liljudd.data.database.repository -import net.moonleay.lilJudd.data.database.entry.PlanningNotifierRolesData -import net.moonleay.lilJudd.data.database.tables.PlanningNotifierRoles -import org.jetbrains.exposed.sql.* +import net.moonleay.liljudd.data.database.entry.PlanningNotifierRolesData +import net.moonleay.liljudd.data.database.tables.PlanningNotifierRoles import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction object PlanningNotifierRolesRepository { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningChannelsRepository.kt similarity index 87% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningChannelsRepository.kt index 305a8b5..2c878f0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningChannelsRepository.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningChannelsRepository.kt @@ -16,12 +16,15 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.repository +package net.moonleay.liljudd.data.database.repository -import net.moonleay.lilJudd.data.database.entry.TimePlanningChannelsData -import net.moonleay.lilJudd.data.database.tables.TimePlanningChannels -import org.jetbrains.exposed.sql.* +import net.moonleay.liljudd.data.database.entry.TimePlanningChannelsData +import net.moonleay.liljudd.data.database.tables.TimePlanningChannels import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.deleteWhere +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction object TimePlanningChannelsRepository { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningMessagesRepository.kt similarity index 89% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningMessagesRepository.kt index fad3a7c..d10459b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/repository/TimePlanningMessagesRepository.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningMessagesRepository.kt @@ -16,12 +16,13 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.repository +package net.moonleay.liljudd.data.database.repository -import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.database.tables.TimePlanningMessages -import org.jetbrains.exposed.sql.* -import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq +import net.moonleay.liljudd.data.database.entry.TimePlanningMessagesData +import net.moonleay.liljudd.data.database.tables.TimePlanningMessages +import org.jetbrains.exposed.sql.and +import org.jetbrains.exposed.sql.insert +import org.jetbrains.exposed.sql.selectAll import org.jetbrains.exposed.sql.transactions.transaction object TimePlanningMessagesRepository { diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/MatchPlanningData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/MatchPlanningData.kt similarity index 96% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/tables/MatchPlanningData.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/tables/MatchPlanningData.kt index 391b3e8..9081bbd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/MatchPlanningData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/MatchPlanningData.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.tables +package net.moonleay.liljudd.data.database.tables import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/PlanningNotifierRoles.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/PlanningNotifierRoles.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/tables/PlanningNotifierRoles.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/tables/PlanningNotifierRoles.kt index 66fe906..90c8dbd 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/PlanningNotifierRoles.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/PlanningNotifierRoles.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.tables +package net.moonleay.liljudd.data.database.tables import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningChannels.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningChannels.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningChannels.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningChannels.kt index d3b31e3..976fdb8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningChannels.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningChannels.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.tables +package net.moonleay.liljudd.data.database.tables import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningMessages.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningMessages.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningMessages.kt rename to src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningMessages.kt index dd48838..93a51a9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/data/database/tables/TimePlanningMessages.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningMessages.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.data.database.tables +package net.moonleay.liljudd.data.database.tables import org.jetbrains.exposed.sql.Table diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/FeatureManageExtension.kt similarity index 93% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/FeatureManageExtension.kt index 21e7bec..92decf8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/FeatureManageExtension.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions +package net.moonleay.liljudd.extensions import com.kotlindiscord.kord.extensions.commands.Arguments import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.enumChoice @@ -26,12 +26,12 @@ import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.extensions.component.EnableOrDisable -import net.moonleay.lilJudd.features.component.FeatureEnum -import net.moonleay.lilJudd.features.component.FeatureManager -import net.moonleay.lilJudd.util.EmbedColor -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.liljudd.extensions.component.EnableOrDisable +import net.moonleay.liljudd.features.component.FeatureEnum +import net.moonleay.liljudd.features.component.FeatureManager +import net.moonleay.liljudd.util.EmbedColor +import net.moonleay.liljudd.util.Logger +import net.moonleay.liljudd.util.MessageUtil class FeatureManageExtension : Extension() { diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/InfoExtension.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/InfoExtension.kt index 4928043..e202731 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/InfoExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/InfoExtension.kt @@ -16,13 +16,13 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions +package net.moonleay.liljudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.util.EmbedColor import net.moonleay.liljudd.build.BuildConstants +import net.moonleay.liljudd.util.EmbedColor class InfoExtension : Extension() { override val name = "info" diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/MatchExtension.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/MatchExtension.kt index e825baa..25e05d0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/MatchExtension.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions +package net.moonleay.liljudd.extensions import com.kotlindiscord.kord.extensions.commands.Arguments import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.enumChoice @@ -26,15 +26,15 @@ import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import dev.kord.core.behavior.createRole import dev.kord.rest.builder.message.actionRow import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository -import net.moonleay.lilJudd.extensions.component.MatchTypes -import net.moonleay.lilJudd.jobs.MatchJob -import net.moonleay.lilJudd.jobs.component.JobManager -import net.moonleay.lilJudd.util.EmbedColor -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.MessageUtil -import net.moonleay.lilJudd.util.TimeUtil +import net.moonleay.liljudd.data.database.entry.MatchPlanningDataData +import net.moonleay.liljudd.data.database.repository.MatchPlanningDataRepository +import net.moonleay.liljudd.extensions.component.MatchTypes +import net.moonleay.liljudd.jobs.MatchJob +import net.moonleay.liljudd.jobs.component.JobManager +import net.moonleay.liljudd.util.EmbedColor +import net.moonleay.liljudd.util.EmbedUtil +import net.moonleay.liljudd.util.MessageUtil +import net.moonleay.liljudd.util.TimeUtil class MatchExtension : Extension() { diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/RotationExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/RotationExtension.kt similarity index 99% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/RotationExtension.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/RotationExtension.kt index 9c458b5..d5b0d7e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/RotationExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/RotationExtension.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions +package net.moonleay.liljudd.extensions import com.kotlindiscord.kord.extensions.commands.Arguments import com.kotlindiscord.kord.extensions.commands.application.slash.converters.impl.enumChoice @@ -25,9 +25,9 @@ import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import dev.kord.common.Color import dev.kord.rest.builder.message.embed import kotlinx.datetime.Clock -import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiDataGrabber -import net.moonleay.lilJudd.extensions.component.SplatoonOnlineMode -import net.moonleay.lilJudd.util.TimeUtil +import net.moonleay.liljudd.data.api.splatoon3ink.Splatoon3ApiDataGrabber +import net.moonleay.liljudd.extensions.component.SplatoonOnlineMode +import net.moonleay.liljudd.util.TimeUtil class RotationExtension : Extension() { diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/SendPlannerExtension.kt similarity index 96% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/SendPlannerExtension.kt index f5d7c32..5673da3 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/SendPlannerExtension.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions +package net.moonleay.liljudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand @@ -26,10 +26,10 @@ import dev.kord.core.behavior.channel.createMessage import dev.kord.rest.builder.message.actionRow import dev.kord.rest.builder.message.embed import kotlinx.coroutines.delay -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.database.repository.TimePlanningMessagesRepository -import net.moonleay.lilJudd.util.* +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.data.database.entry.TimePlanningMessagesData +import net.moonleay.liljudd.data.database.repository.TimePlanningMessagesRepository +import net.moonleay.liljudd.util.* import java.time.ZoneId import java.time.ZonedDateTime diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/UpdateRolesExtension.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/UpdateRolesExtension.kt index 6d29add..3b69404 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/UpdateRolesExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/UpdateRolesExtension.kt @@ -16,17 +16,17 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions +package net.moonleay.liljudd.extensions import com.kotlindiscord.kord.extensions.extensions.Extension import com.kotlindiscord.kord.extensions.extensions.publicSlashCommand import com.kotlindiscord.kord.extensions.utils.hasPermission import dev.kord.common.entity.Permission import dev.kord.rest.builder.message.embed -import net.moonleay.lilJudd.features.AvailabilityManager -import net.moonleay.lilJudd.util.EmbedColor -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.liljudd.features.AvailabilityManager +import net.moonleay.liljudd.util.EmbedColor +import net.moonleay.liljudd.util.Logger +import net.moonleay.liljudd.util.MessageUtil class UpdateRolesExtension : Extension() { override val name = "updateroles" diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/EnableOrDisable.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/component/EnableOrDisable.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/component/EnableOrDisable.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/component/EnableOrDisable.kt index 6d5e614..331637f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/EnableOrDisable.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/component/EnableOrDisable.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions.component +package net.moonleay.liljudd.extensions.component import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/MatchTypes.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/component/MatchTypes.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/component/MatchTypes.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/component/MatchTypes.kt index 3cde91b..d75071b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/MatchTypes.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/component/MatchTypes.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions.component +package net.moonleay.liljudd.extensions.component import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum diff --git a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/SplatoonOnlineMode.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/component/SplatoonOnlineMode.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/extensions/component/SplatoonOnlineMode.kt rename to src/main/kotlin/net/moonleay/liljudd/extensions/component/SplatoonOnlineMode.kt index c6ae569..92e587e 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/extensions/component/SplatoonOnlineMode.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/component/SplatoonOnlineMode.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.extensions.component +package net.moonleay.liljudd.extensions.component import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt rename to src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt index cc49d1c..a27cfca 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.features +package net.moonleay.liljudd.features import com.kotlindiscord.kord.extensions.utils.isNullOrBot import dev.inmo.krontab.buildSchedule @@ -29,15 +29,15 @@ import dev.kord.core.entity.channel.Channel import dev.kord.core.entity.channel.MessageChannel import dev.kord.gateway.PrivilegedIntent import dev.kord.rest.builder.message.EmbedBuilder -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.database.entry.PlanningNotifierRolesData -import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.database.repository.PlanningNotifierRolesRepository -import net.moonleay.lilJudd.data.database.repository.TimePlanningMessagesRepository -import net.moonleay.lilJudd.extensions.FeatureManageExtension -import net.moonleay.lilJudd.features.component.FeatureEnum -import net.moonleay.lilJudd.features.component.IFeature -import net.moonleay.lilJudd.util.* +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.data.database.entry.PlanningNotifierRolesData +import net.moonleay.liljudd.data.database.entry.TimePlanningMessagesData +import net.moonleay.liljudd.data.database.repository.PlanningNotifierRolesRepository +import net.moonleay.liljudd.data.database.repository.TimePlanningMessagesRepository +import net.moonleay.liljudd.extensions.FeatureManageExtension +import net.moonleay.liljudd.features.component.FeatureEnum +import net.moonleay.liljudd.features.component.IFeature +import net.moonleay.liljudd.util.* import java.time.ZonedDateTime object AvailabilityManager : IFeature { diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt similarity index 86% rename from src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt rename to src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt index 129fdc0..6941657 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/MatchManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt @@ -16,15 +16,15 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.features +package net.moonleay.liljudd.features import dev.kord.common.entity.Snowflake -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.database.entry.MatchPlanningDataData -import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository -import net.moonleay.lilJudd.jobs.MatchJob -import net.moonleay.lilJudd.jobs.component.JobManager -import net.moonleay.lilJudd.util.Logger +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.data.database.entry.MatchPlanningDataData +import net.moonleay.liljudd.data.database.repository.MatchPlanningDataRepository +import net.moonleay.liljudd.jobs.MatchJob +import net.moonleay.liljudd.jobs.component.JobManager +import net.moonleay.liljudd.util.Logger object MatchManager { suspend fun update() { diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt similarity index 91% rename from src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt rename to src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt index a9cc7be..d9f7f2b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.features +package net.moonleay.liljudd.features import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.doInfinity @@ -29,19 +29,19 @@ import dev.kord.rest.builder.message.EmbedBuilder import dev.kord.rest.builder.message.actionRow import dev.kord.rest.builder.message.embed import kotlinx.coroutines.delay -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.database.entry.TimePlanningChannelsData -import net.moonleay.lilJudd.data.database.entry.TimePlanningMessagesData -import net.moonleay.lilJudd.data.database.repository.PlanningNotifierRolesRepository -import net.moonleay.lilJudd.data.database.repository.TimePlanningChannelsRepository -import net.moonleay.lilJudd.data.database.repository.TimePlanningMessagesRepository -import net.moonleay.lilJudd.extensions.FeatureManageExtension -import net.moonleay.lilJudd.features.component.FeatureEnum -import net.moonleay.lilJudd.features.component.IFeature -import net.moonleay.lilJudd.util.EmbedColor -import net.moonleay.lilJudd.util.EmbedUtil -import net.moonleay.lilJudd.util.Logger -import net.moonleay.lilJudd.util.MessageUtil +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.data.database.entry.TimePlanningChannelsData +import net.moonleay.liljudd.data.database.entry.TimePlanningMessagesData +import net.moonleay.liljudd.data.database.repository.PlanningNotifierRolesRepository +import net.moonleay.liljudd.data.database.repository.TimePlanningChannelsRepository +import net.moonleay.liljudd.data.database.repository.TimePlanningMessagesRepository +import net.moonleay.liljudd.extensions.FeatureManageExtension +import net.moonleay.liljudd.features.component.FeatureEnum +import net.moonleay.liljudd.features.component.IFeature +import net.moonleay.liljudd.util.EmbedColor +import net.moonleay.liljudd.util.EmbedUtil +import net.moonleay.liljudd.util.Logger +import net.moonleay.liljudd.util.MessageUtil import java.time.ZoneId import java.time.ZonedDateTime diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureEnum.kt b/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureEnum.kt similarity index 95% rename from src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureEnum.kt rename to src/main/kotlin/net/moonleay/liljudd/features/component/FeatureEnum.kt index 8b3a0a8..68c87d8 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureEnum.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureEnum.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.features.component +package net.moonleay.liljudd.features.component import com.kotlindiscord.kord.extensions.commands.application.slash.converters.ChoiceEnum diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureManager.kt similarity index 85% rename from src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt rename to src/main/kotlin/net/moonleay/liljudd/features/component/FeatureManager.kt index d380d9c..1f8d45d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/component/FeatureManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureManager.kt @@ -16,10 +16,10 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.features.component +package net.moonleay.liljudd.features.component -import net.moonleay.lilJudd.features.AvailabilityManager -import net.moonleay.lilJudd.features.TimeManager +import net.moonleay.liljudd.features.AvailabilityManager +import net.moonleay.liljudd.features.TimeManager object FeatureManager { val features = mutableListOf(AvailabilityManager, TimeManager) // Stores all features diff --git a/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt b/src/main/kotlin/net/moonleay/liljudd/features/component/IFeature.kt similarity index 92% rename from src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt rename to src/main/kotlin/net/moonleay/liljudd/features/component/IFeature.kt index 1145797..d623f27 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/features/component/IFeature.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/component/IFeature.kt @@ -16,12 +16,12 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.features.component +package net.moonleay.liljudd.features.component import dev.kord.core.behavior.UserBehavior import dev.kord.core.entity.channel.Channel import dev.kord.rest.builder.message.EmbedBuilder -import net.moonleay.lilJudd.extensions.FeatureManageExtension +import net.moonleay.liljudd.extensions.FeatureManageExtension interface IFeature { val feat: FeatureEnum diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/MatchJob.kt similarity index 85% rename from src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt rename to src/main/kotlin/net/moonleay/liljudd/jobs/MatchJob.kt index 6f13dfa..84a7068 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/MatchJob.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/MatchJob.kt @@ -16,17 +16,17 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.jobs +package net.moonleay.liljudd.jobs import dev.inmo.krontab.KronScheduler import dev.kord.common.entity.Snowflake import kotlinx.coroutines.Job -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.database.repository.MatchPlanningDataRepository -import net.moonleay.lilJudd.jobs.component.CronjobType -import net.moonleay.lilJudd.jobs.component.ICronjob -import net.moonleay.lilJudd.jobs.component.JobManager -import net.moonleay.lilJudd.util.Logger +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.data.database.repository.MatchPlanningDataRepository +import net.moonleay.liljudd.jobs.component.CronjobType +import net.moonleay.liljudd.jobs.component.ICronjob +import net.moonleay.liljudd.jobs.component.JobManager +import net.moonleay.liljudd.util.Logger class MatchJob( override val jobIncoming: String, diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt similarity index 85% rename from src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt rename to src/main/kotlin/net/moonleay/liljudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt index 6ec76f9..b5701c0 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/Splatoon3ApiScheduleUpdateScheduler.kt @@ -16,14 +16,14 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.jobs +package net.moonleay.liljudd.jobs import dev.inmo.krontab.KronScheduler import kotlinx.coroutines.Job -import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3Api -import net.moonleay.lilJudd.jobs.component.CronjobType -import net.moonleay.lilJudd.jobs.component.ICronjob -import net.moonleay.lilJudd.util.Logger +import net.moonleay.liljudd.data.api.splatoon3ink.Splatoon3Api +import net.moonleay.liljudd.jobs.component.CronjobType +import net.moonleay.liljudd.jobs.component.ICronjob +import net.moonleay.liljudd.util.Logger object Splatoon3ApiScheduleUpdateScheduler : ICronjob { override val jobName: String diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/StatusUpdater.kt similarity index 90% rename from src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt rename to src/main/kotlin/net/moonleay/liljudd/jobs/StatusUpdater.kt index 7fed538..fdb421b 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/StatusUpdater.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/StatusUpdater.kt @@ -16,15 +16,15 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.jobs +package net.moonleay.liljudd.jobs import dev.inmo.krontab.KronScheduler import dev.kord.common.entity.PresenceStatus import kotlinx.coroutines.Job -import net.moonleay.lilJudd.Bot -import net.moonleay.lilJudd.data.api.splatoon3ink.Splatoon3ApiDataGrabber -import net.moonleay.lilJudd.jobs.component.CronjobType -import net.moonleay.lilJudd.jobs.component.ICronjob +import net.moonleay.liljudd.Bot +import net.moonleay.liljudd.data.api.splatoon3ink.Splatoon3ApiDataGrabber +import net.moonleay.liljudd.jobs.component.CronjobType +import net.moonleay.liljudd.jobs.component.ICronjob object StatusUpdater : ICronjob { override val jobName: String diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/CronjobType.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/component/CronjobType.kt similarity index 94% rename from src/main/kotlin/net/moonleay/lilJudd/jobs/component/CronjobType.kt rename to src/main/kotlin/net/moonleay/liljudd/jobs/component/CronjobType.kt index fa34b60..4584cc9 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/CronjobType.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/component/CronjobType.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.jobs.component +package net.moonleay.liljudd.jobs.component enum class CronjobType { INFINITE, diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/ICronjob.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/component/ICronjob.kt similarity index 96% rename from src/main/kotlin/net/moonleay/lilJudd/jobs/component/ICronjob.kt rename to src/main/kotlin/net/moonleay/liljudd/jobs/component/ICronjob.kt index d3f6700..2f25513 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/ICronjob.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/component/ICronjob.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.jobs.component +package net.moonleay.liljudd.jobs.component import dev.inmo.krontab.KronScheduler import kotlinx.coroutines.Job diff --git a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/JobManager.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/component/JobManager.kt similarity index 97% rename from src/main/kotlin/net/moonleay/lilJudd/jobs/component/JobManager.kt rename to src/main/kotlin/net/moonleay/liljudd/jobs/component/JobManager.kt index cc55256..56cecce 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/jobs/component/JobManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/component/JobManager.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.jobs.component +package net.moonleay.liljudd.jobs.component import dev.inmo.krontab.buildSchedule import dev.inmo.krontab.doInfinityTz @@ -25,7 +25,7 @@ import dev.inmo.krontab.doWhileTz import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch -import net.moonleay.lilJudd.util.Logger +import net.moonleay.liljudd.util.Logger import java.time.LocalDateTime import java.time.format.DateTimeFormatter diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedColor.kt b/src/main/kotlin/net/moonleay/liljudd/util/EmbedColor.kt similarity index 96% rename from src/main/kotlin/net/moonleay/lilJudd/util/EmbedColor.kt rename to src/main/kotlin/net/moonleay/liljudd/util/EmbedColor.kt index cb3e983..a1ee222 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedColor.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/EmbedColor.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.util +package net.moonleay.liljudd.util import dev.kord.common.Color diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt b/src/main/kotlin/net/moonleay/liljudd/util/EmbedUtil.kt similarity index 99% rename from src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt rename to src/main/kotlin/net/moonleay/liljudd/util/EmbedUtil.kt index 17615b3..89069ae 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/EmbedUtil.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/EmbedUtil.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.util +package net.moonleay.liljudd.util import dev.kord.common.entity.ButtonStyle import dev.kord.core.entity.Embed diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/Logger.kt b/src/main/kotlin/net/moonleay/liljudd/util/Logger.kt similarity index 97% rename from src/main/kotlin/net/moonleay/lilJudd/util/Logger.kt rename to src/main/kotlin/net/moonleay/liljudd/util/Logger.kt index 446609c..e07c94f 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/Logger.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/Logger.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.util +package net.moonleay.liljudd.util import java.time.LocalDateTime import java.time.format.DateTimeFormatter diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt b/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt similarity index 99% rename from src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt rename to src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt index 3307f58..f49e3cc 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/MessageUtil.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.util +package net.moonleay.liljudd.util import dev.kord.core.behavior.UserBehavior import dev.kord.core.entity.Embed diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/NetUtil.kt b/src/main/kotlin/net/moonleay/liljudd/util/NetUtil.kt similarity index 98% rename from src/main/kotlin/net/moonleay/lilJudd/util/NetUtil.kt rename to src/main/kotlin/net/moonleay/liljudd/util/NetUtil.kt index 5b43bbc..19dfa4d 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/NetUtil.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/NetUtil.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.util +package net.moonleay.liljudd.util import java.net.URL import javax.net.ssl.HttpsURLConnection diff --git a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt b/src/main/kotlin/net/moonleay/liljudd/util/TimeUtil.kt similarity index 99% rename from src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt rename to src/main/kotlin/net/moonleay/liljudd/util/TimeUtil.kt index acf0da8..bddc8b1 100644 --- a/src/main/kotlin/net/moonleay/lilJudd/util/TimeUtil.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/TimeUtil.kt @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -package net.moonleay.lilJudd.util +package net.moonleay.liljudd.util import kotlinx.datetime.DayOfWeek import java.time.Duration -- 2.45.2 From c65e4031d9556841d8f14725b780c4a91aaca34b Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 13 Feb 2024 19:24:48 +0100 Subject: [PATCH 164/168] chore: update copyright Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/liljudd/Bot.kt | 21 ++++++++++++------- src/main/kotlin/net/moonleay/liljudd/Main.kt | 2 +- .../buttons/component/EditButtonManager.kt | 2 +- .../liljudd/buttons/component/IEditButton.kt | 2 +- .../buttons/matchplanner/AcceptEditButton.kt | 2 +- .../buttons/matchplanner/CancelEditButton.kt | 2 +- .../buttons/matchplanner/DeclineEditButton.kt | 2 +- .../timeplanner/IsAvailableEditButton.kt | 2 +- .../timeplanner/MaybeAvailableEditButton.kt | 2 +- .../timeplanner/NotAvailableEditButton.kt | 2 +- .../net/moonleay/liljudd/data/database/DB.kt | 2 +- .../database/entry/MatchPlanningDataData.kt | 2 +- .../entry/PlanningNotifierRolesData.kt | 2 +- .../entry/TimePlanningChannelsData.kt | 2 +- .../entry/TimePlanningMessagesData.kt | 2 +- .../repository/MatchPlanningDataRepository.kt | 2 +- .../PlanningNotifierRolesRepository.kt | 2 +- .../TimePlanningChannelsRepository.kt | 2 +- .../TimePlanningMessagesRepository.kt | 2 +- .../data/database/tables/MatchPlanningData.kt | 2 +- .../database/tables/PlanningNotifierRoles.kt | 2 +- .../database/tables/TimePlanningChannels.kt | 2 +- .../database/tables/TimePlanningMessages.kt | 2 +- .../extensions/FeatureManageExtension.kt | 2 +- .../liljudd/extensions/InfoExtension.kt | 2 +- .../liljudd/extensions/MatchExtension.kt | 2 +- .../extensions/SendPlannerExtension.kt | 2 +- .../extensions/UpdateRolesExtension.kt | 2 +- .../extensions/component/EnableOrDisable.kt | 2 +- .../extensions/component/MatchTypes.kt | 2 +- .../liljudd/features/AvailabilityManager.kt | 2 +- .../moonleay/liljudd/features/MatchManager.kt | 2 +- .../moonleay/liljudd/features/TimeManager.kt | 2 +- .../liljudd/features/component/FeatureEnum.kt | 2 +- .../features/component/FeatureManager.kt | 2 +- .../liljudd/features/component/IFeature.kt | 2 +- .../net/moonleay/liljudd/jobs/MatchJob.kt | 2 +- .../liljudd/jobs/component/CronjobType.kt | 2 +- .../liljudd/jobs/component/ICronjob.kt | 2 +- .../liljudd/jobs/component/JobManager.kt | 2 +- .../net/moonleay/liljudd/util/EmbedColor.kt | 2 +- .../net/moonleay/liljudd/util/EmbedUtil.kt | 2 +- .../net/moonleay/liljudd/util/Logger.kt | 2 +- .../net/moonleay/liljudd/util/MessageUtil.kt | 11 +++++++++- .../net/moonleay/liljudd/util/NetUtil.kt | 2 +- 45 files changed, 66 insertions(+), 52 deletions(-) diff --git a/src/main/kotlin/net/moonleay/liljudd/Bot.kt b/src/main/kotlin/net/moonleay/liljudd/Bot.kt index 9f4c42e..5ea1197 100644 --- a/src/main/kotlin/net/moonleay/liljudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/liljudd/Bot.kt @@ -74,6 +74,7 @@ object Bot { exitProcess(3) } + // Check if there are api credentials if (CredentialManager.apiDomain == "empty" || CredentialManager.apiToken == "empty") { Logger.out("The config does not contain the whole API credentials.") exitProcess(3) @@ -187,18 +188,22 @@ object Bot { // Load news NewsManager.load() if(NewsManager.shouldPost == "yes"){ + val contactedOwners = mutableListOf() bot.kordRef.guilds.collect { val owner = it.owner.asUser() - Logger.out("Sent News to ${owner.username} from ${it.name}") - owner.dm { - this.embed { - this.title = NewsManager.title - this.description = NewsManager.news - this.footer { - this.icon = bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() - this.text = MessageUtil.getFooter() + if (!contactedOwners.contains(owner.id.value)) { + Logger.out("Sent News to ${owner.username} from ${it.name}") + owner.dm { + this.embed { + this.title = NewsManager.title + this.description = NewsManager.news + this.footer { + this.icon = bot.kordRef.getSelf().avatar?.cdnUrl?.toUrl() + this.text = MessageUtil.getFooter() + } } } + contactedOwners.add(owner.id.value) } } NewsManager.shouldPost = "no" diff --git a/src/main/kotlin/net/moonleay/liljudd/Main.kt b/src/main/kotlin/net/moonleay/liljudd/Main.kt index d8e4dce..e60782b 100644 --- a/src/main/kotlin/net/moonleay/liljudd/Main.kt +++ b/src/main/kotlin/net/moonleay/liljudd/Main.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/buttons/component/EditButtonManager.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/component/EditButtonManager.kt index 38690ea..384a09d 100644 --- a/src/main/kotlin/net/moonleay/liljudd/buttons/component/EditButtonManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/component/EditButtonManager.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/buttons/component/IEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/component/IEditButton.kt index 3c32805..d973ceb 100644 --- a/src/main/kotlin/net/moonleay/liljudd/buttons/component/IEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/component/IEditButton.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/AcceptEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/AcceptEditButton.kt index 8a32c1c..7e7e382 100644 --- a/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/AcceptEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/AcceptEditButton.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/CancelEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/CancelEditButton.kt index c1a54a7..07e1016 100644 --- a/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/CancelEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/CancelEditButton.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/DeclineEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/DeclineEditButton.kt index a2bacde..06f7e44 100644 --- a/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/DeclineEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/matchplanner/DeclineEditButton.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/IsAvailableEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/IsAvailableEditButton.kt index f13a732..b4cdfef 100644 --- a/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/IsAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/IsAvailableEditButton.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/MaybeAvailableEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/MaybeAvailableEditButton.kt index 5d17f4d..23b9c61 100644 --- a/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/MaybeAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/MaybeAvailableEditButton.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/NotAvailableEditButton.kt b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/NotAvailableEditButton.kt index 14527be..0fd5390 100644 --- a/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/NotAvailableEditButton.kt +++ b/src/main/kotlin/net/moonleay/liljudd/buttons/timeplanner/NotAvailableEditButton.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/DB.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/DB.kt index 9dd9943..2475f28 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/DB.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/DB.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/entry/MatchPlanningDataData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/MatchPlanningDataData.kt index c430527..77bfcc8 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/entry/MatchPlanningDataData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/MatchPlanningDataData.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/entry/PlanningNotifierRolesData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/PlanningNotifierRolesData.kt index ab809c5..b6d0abf 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/entry/PlanningNotifierRolesData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/PlanningNotifierRolesData.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningChannelsData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningChannelsData.kt index a0c6988..0f93b9e 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningChannelsData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningChannelsData.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningMessagesData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningMessagesData.kt index fa4d6f6..c1192fc 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningMessagesData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/entry/TimePlanningMessagesData.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/repository/MatchPlanningDataRepository.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/MatchPlanningDataRepository.kt index a4c078f..5c93b43 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/repository/MatchPlanningDataRepository.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/MatchPlanningDataRepository.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/repository/PlanningNotifierRolesRepository.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/PlanningNotifierRolesRepository.kt index 0b02f39..3333471 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/repository/PlanningNotifierRolesRepository.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/PlanningNotifierRolesRepository.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningChannelsRepository.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningChannelsRepository.kt index 2c878f0..f809420 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningChannelsRepository.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningChannelsRepository.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningMessagesRepository.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningMessagesRepository.kt index d10459b..4c92a08 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningMessagesRepository.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/repository/TimePlanningMessagesRepository.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/tables/MatchPlanningData.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/MatchPlanningData.kt index 9081bbd..1ba4ae3 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/tables/MatchPlanningData.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/MatchPlanningData.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/tables/PlanningNotifierRoles.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/PlanningNotifierRoles.kt index 90c8dbd..0e44813 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/tables/PlanningNotifierRoles.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/PlanningNotifierRoles.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningChannels.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningChannels.kt index 976fdb8..7b81b0b 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningChannels.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningChannels.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningMessages.kt b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningMessages.kt index 93a51a9..f7061ac 100644 --- a/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningMessages.kt +++ b/src/main/kotlin/net/moonleay/liljudd/data/database/tables/TimePlanningMessages.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/extensions/FeatureManageExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/FeatureManageExtension.kt index 92decf8..309e433 100644 --- a/src/main/kotlin/net/moonleay/liljudd/extensions/FeatureManageExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/FeatureManageExtension.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/extensions/InfoExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/InfoExtension.kt index e202731..b47af0b 100644 --- a/src/main/kotlin/net/moonleay/liljudd/extensions/InfoExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/InfoExtension.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/extensions/MatchExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/MatchExtension.kt index 25e05d0..7d6a8c6 100644 --- a/src/main/kotlin/net/moonleay/liljudd/extensions/MatchExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/MatchExtension.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/extensions/SendPlannerExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/SendPlannerExtension.kt index 5673da3..a2d98dc 100644 --- a/src/main/kotlin/net/moonleay/liljudd/extensions/SendPlannerExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/SendPlannerExtension.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/extensions/UpdateRolesExtension.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/UpdateRolesExtension.kt index 3b69404..7ffe5e9 100644 --- a/src/main/kotlin/net/moonleay/liljudd/extensions/UpdateRolesExtension.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/UpdateRolesExtension.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/extensions/component/EnableOrDisable.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/component/EnableOrDisable.kt index 331637f..4cd9a92 100644 --- a/src/main/kotlin/net/moonleay/liljudd/extensions/component/EnableOrDisable.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/component/EnableOrDisable.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/extensions/component/MatchTypes.kt b/src/main/kotlin/net/moonleay/liljudd/extensions/component/MatchTypes.kt index d75071b..cc60220 100644 --- a/src/main/kotlin/net/moonleay/liljudd/extensions/component/MatchTypes.kt +++ b/src/main/kotlin/net/moonleay/liljudd/extensions/component/MatchTypes.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt index a27cfca..c62fcdb 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt index 6941657..abe847a 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt index d9f7f2b..44d261a 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureEnum.kt b/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureEnum.kt index 68c87d8..b06fc3b 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureEnum.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureEnum.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureManager.kt index 1f8d45d..a9212b4 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/component/FeatureManager.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/features/component/IFeature.kt b/src/main/kotlin/net/moonleay/liljudd/features/component/IFeature.kt index d623f27..77170f3 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/component/IFeature.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/component/IFeature.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/jobs/MatchJob.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/MatchJob.kt index 84a7068..130e304 100644 --- a/src/main/kotlin/net/moonleay/liljudd/jobs/MatchJob.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/MatchJob.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/jobs/component/CronjobType.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/component/CronjobType.kt index 4584cc9..fa1992b 100644 --- a/src/main/kotlin/net/moonleay/liljudd/jobs/component/CronjobType.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/component/CronjobType.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/jobs/component/ICronjob.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/component/ICronjob.kt index 2f25513..8e3f946 100644 --- a/src/main/kotlin/net/moonleay/liljudd/jobs/component/ICronjob.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/component/ICronjob.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/jobs/component/JobManager.kt b/src/main/kotlin/net/moonleay/liljudd/jobs/component/JobManager.kt index 56cecce..ce62d1c 100644 --- a/src/main/kotlin/net/moonleay/liljudd/jobs/component/JobManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/jobs/component/JobManager.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/util/EmbedColor.kt b/src/main/kotlin/net/moonleay/liljudd/util/EmbedColor.kt index a1ee222..7d9def4 100644 --- a/src/main/kotlin/net/moonleay/liljudd/util/EmbedColor.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/EmbedColor.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/util/EmbedUtil.kt b/src/main/kotlin/net/moonleay/liljudd/util/EmbedUtil.kt index 89069ae..f109ed3 100644 --- a/src/main/kotlin/net/moonleay/liljudd/util/EmbedUtil.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/EmbedUtil.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/util/Logger.kt b/src/main/kotlin/net/moonleay/liljudd/util/Logger.kt index e07c94f..25a5804 100644 --- a/src/main/kotlin/net/moonleay/liljudd/util/Logger.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/Logger.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 diff --git a/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt b/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt index f49e3cc..98503d6 100644 --- a/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 @@ -52,6 +52,11 @@ object MessageUtil { val ebb = EmbedBuilder() ebb.color = e.color ebb.title = e.title + ebb.author { + this.icon = e.author?.url + this.name = e.author?.name.toString() + this.url = e.author?.url + } e.fields.forEach { val fb = EmbedBuilder.Field() fb.name = it.name @@ -59,6 +64,10 @@ object MessageUtil { fb.inline = it.inline ebb.fields.add(fb) } + ebb.footer { + this.icon = e.footer?.icon + this.text = e.footer?.text.toString() + } ebb.description = e.description return ebb } diff --git a/src/main/kotlin/net/moonleay/liljudd/util/NetUtil.kt b/src/main/kotlin/net/moonleay/liljudd/util/NetUtil.kt index 19dfa4d..665d0bb 100644 --- a/src/main/kotlin/net/moonleay/liljudd/util/NetUtil.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/NetUtil.kt @@ -1,6 +1,6 @@ /* * lilJudd - * Copyright (C) 2023 moonleay + * Copyright (C) 2024 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 -- 2.45.2 From 404e043da1f9e3ee3d751a5a0ab430b86dfc3b33 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 13 Feb 2024 19:43:09 +0100 Subject: [PATCH 165/168] chore: improved logging messages of features Signed-off-by: moonleay --- .../net/moonleay/liljudd/features/AvailabilityManager.kt | 2 +- .../kotlin/net/moonleay/liljudd/features/MatchManager.kt | 4 ++-- .../kotlin/net/moonleay/liljudd/features/TimeManager.kt | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt index c62fcdb..2cc7ec8 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt @@ -70,7 +70,7 @@ object AvailabilityManager : IFeature { } this.updateInChannel(snf, data, roleData) } - Logger.out("Done! Until tomorrow! <3 ") + Logger.out("Finished updating roles") } suspend fun updateInChannel(snf: Snowflake) { diff --git a/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt index abe847a..1bdeafe 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/MatchManager.kt @@ -28,7 +28,7 @@ import net.moonleay.liljudd.util.Logger object MatchManager { suspend fun update() { - Logger.out("Updating match roles...") + Logger.out("Updating matches") val dataList = MatchPlanningDataRepository.getAll() for (data in dataList) { @@ -41,7 +41,7 @@ object MatchManager { } this.registerJob(data) } - Logger.out("Done. Until next time! <3 ") + Logger.out("Finished updating matches") } private fun registerJob(data: MatchPlanningDataData) { diff --git a/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt index 44d261a..b5dbe9e 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt @@ -60,7 +60,7 @@ object TimeManager : IFeature { } private suspend fun runThread() { - Logger.out("Starting to notify...") + Logger.out("Starting to send out weekly planning messages") // ChannelID -> Data val targetedChannels = TimePlanningChannelsRepository.getAll().associateBy { it.channelID } @@ -72,7 +72,7 @@ object TimeManager : IFeature { for (ch2 in targetedChannels.keys) { val ch = Snowflake(ch2) if (Bot.bot.kordRef.getChannel(ch) == null) - continue // TODO: Check if the channel is valid in another shard + continue val c = Bot.bot.kordRef.getChannelOf(ch)!! msgStr = "" if (targetedRoles != null && targetedRoles.keys.contains(ch2) && targetedRoles[ch2] != null) { @@ -133,7 +133,7 @@ object TimeManager : IFeature { } msgStr += "${it}:${msg.id.value};" then = then.plusDays(1).withHour(4).withMinute(0).withSecond(0) - Logger.out("Finished sending day $it") + Logger.out("Finished sending day $it in $ch") delay(1000) } @@ -186,7 +186,7 @@ object TimeManager : IFeature { ): EmbedBuilder { // Check if entry exists in db if (TimePlanningChannelsRepository.exists(cID, gID)) { - // delete all entrys for this channel + // delete all entries for this channel TimePlanningChannelsRepository.deleteFromChannelInServer(cID, gID) return MessageUtil.getEmbed( EmbedColor.SUCCESS, -- 2.45.2 From a7e656bcbe6b0628ef34e151835d9ea116914ba9 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 13 Feb 2024 19:44:09 +0100 Subject: [PATCH 166/168] refactor: renamed ownerID to creatorID Signed-off-by: moonleay --- build.gradle.kts | 4 ++-- src/main/kotlin/net/moonleay/liljudd/Bot.kt | 2 +- .../templates/net/moonleay/lilJudd/build/BuildConstants.kt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index eac9d28..0ad11dc 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -29,7 +29,7 @@ plugins { } //lilJudd version 2 -val ownerID = 372703841151614976L +val creatorID = 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" } @@ -120,7 +120,7 @@ val templateSrc = project.rootDir.resolve("src/main/templates") val templateDest = project.projectDir.resolve("build/generated/templates") val templateProps = mapOf( "version" to project.version as String, - "ownerID" to ownerID, + "creatorID" to creatorID, "kordversion" to kordver, "coroutinesversion" to coroutinesver, "ktorversion" to ktorver, diff --git a/src/main/kotlin/net/moonleay/liljudd/Bot.kt b/src/main/kotlin/net/moonleay/liljudd/Bot.kt index 5ea1197..2e5e5aa 100644 --- a/src/main/kotlin/net/moonleay/liljudd/Bot.kt +++ b/src/main/kotlin/net/moonleay/liljudd/Bot.kt @@ -133,7 +133,7 @@ object Bot { this.embed { this.title = "Oops. Something went wrong." this.description = "The bot encountered an error during execution.\n" + - "Please report this to <@${BuildConstants.ownerID}>.\n" + + "Please report this to <@${BuildConstants.creatorID}>.\n" + "The errorid is \"$stamp.stk\"" this.field { this.name = "Error message:" diff --git a/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt b/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt index 44c46b3..73a4fdd 100644 --- a/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt +++ b/src/main/templates/net/moonleay/lilJudd/build/BuildConstants.kt @@ -20,7 +20,7 @@ package net.moonleay.liljudd.build internal object BuildConstants { const val version = "${version}" - const val ownerID = "${ownerID}" + const val creatorID = "${creatorID}" const val kordVersion = "${kordversion}" const val coroutinesVersion = "${coroutinesversion}" const val ktorVersion = "${ktorversion}" -- 2.45.2 From 0cd3e4d6a8b8d38077c3c632b932b74d41b359ab Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 13 Feb 2024 20:04:13 +0100 Subject: [PATCH 167/168] fix: fixed issue with cloned embeds not implementing the footer correctly Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt b/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt index 98503d6..f531dd0 100644 --- a/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt +++ b/src/main/kotlin/net/moonleay/liljudd/util/MessageUtil.kt @@ -37,6 +37,11 @@ object MessageUtil { val ebb = EmbedBuilder() ebb.color = e.color ebb.title = e.title + ebb.author { + this.icon = e.author?.url + this.name = e.author?.name.toString() + this.url = e.author?.url + } e.fields.forEach { val fb = EmbedBuilder.Field() fb.name = it.name @@ -44,6 +49,10 @@ object MessageUtil { fb.inline = it.inline ebb.fields.add(fb) } + ebb.footer { + this.icon = e.footer?.iconUrl + this.text = e.footer?.text.toString() + } ebb.description = e.description return ebb } -- 2.45.2 From 4b46d34f45d7685b3e201fd5df029b5a270764f3 Mon Sep 17 00:00:00 2001 From: moonleay Date: Tue, 13 Feb 2024 20:07:50 +0100 Subject: [PATCH 168/168] chore: improved logging further Signed-off-by: moonleay --- src/main/kotlin/net/moonleay/liljudd/Main.kt | 2 +- .../net/moonleay/liljudd/features/AvailabilityManager.kt | 6 +++--- .../kotlin/net/moonleay/liljudd/features/TimeManager.kt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/net/moonleay/liljudd/Main.kt b/src/main/kotlin/net/moonleay/liljudd/Main.kt index e60782b..a1196f8 100644 --- a/src/main/kotlin/net/moonleay/liljudd/Main.kt +++ b/src/main/kotlin/net/moonleay/liljudd/Main.kt @@ -31,7 +31,7 @@ suspend fun main() { "v.${BuildConstants.version}\n" ) - Logger.out("li'l Judd made by moonleay (https://moonleay.net). Web UI made by IchLiebeZuege (https://mal-noh.de).") + Logger.out("li'l Judd made by moonleay (https://moonleay.net). Web UI made by aronmal (https://mal-noh.de).") Logger.out("For more information check out https://liljudd.ink and https://git.moonleay.net/DiscordBots/lilJudd") Bot.start() diff --git a/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt index 2cc7ec8..e4d0441 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/AvailabilityManager.kt @@ -44,7 +44,7 @@ object AvailabilityManager : IFeature { // This runs during the cronjob. suspend fun runThread() { - Logger.out("Starting to update roles...") + Logger.out("Updating match roles") // ChannelID, Data val messages = TimePlanningMessagesRepository.getWeek(TimeUtil.getWeekStamp().toEpochSecond()) @@ -162,7 +162,7 @@ object AvailabilityManager : IFeature { // Register the cronjob to run at 1AM UTC every day override suspend fun registerThread() { - Logger.out("Adding availability scheduler...") + Logger.out("Registering daily planning message role update coroutine") val scheduler = buildSchedule("0 0 2 * * *") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { this.runThread() @@ -176,7 +176,7 @@ object AvailabilityManager : IFeature { ch: Channel, args: FeatureManageExtension.FeatureManagerArgs ): EmbedBuilder { - var alreadyExists = PlanningNotifierRolesRepository.existsInChannel(cID) + val alreadyExists = PlanningNotifierRolesRepository.existsInChannel(cID) // Check if the channel and guild already exist in the db if (!alreadyExists) { // Create the roles in Discord diff --git a/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt b/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt index b5dbe9e..0496dff 100644 --- a/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt +++ b/src/main/kotlin/net/moonleay/liljudd/features/TimeManager.kt @@ -52,7 +52,7 @@ object TimeManager : IFeature { // Register the cronjob to run at 0:01 AM UTC every Monday override suspend fun registerThread() { - Logger.out("Adding message scheduler...") + Logger.out("Registering weekly planning message posting coroutine") val scheduler = buildSchedule("0 0 1 * * * 0o 1w") // 0 0 4 * * * 0o 1w // 0o is UTC scheduler.doInfinity { this.runThread() -- 2.45.2