Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add cronjob to restart webhook #2

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/modules/discordmc.main.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ webhook = "https://discord.com/api/webhooks/123456/abcdef" # remove if you don't
times = ["00:00", "06:00", "12:00", "18:00"] # HH:MM format, in the server's timezone
periods = [30, 10, 5, 4, 3, 2, 1] # minutes before restart
content = "The `restart` event was triggered..." # remove if you don't want content
cron = "* * * * *" # leave as is to ignore or change to ignore restart.times
[restart.embed] # remove if you don't want an embed
title = "Restart"
description = "..."
Expand Down
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

group = "me.duro"
version = "1.0-SNAPSHOT"
version = "1.0.1-SNAPSHOT"

repositories {
mavenCentral()
Expand All @@ -23,6 +23,7 @@ dependencies {
compileOnly("io.papermc.paper:paper-api:1.21.1-R0.1-SNAPSHOT")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("cc.ekblad:4koma:1.2.0")
implementation("com.cronutils:cron-utils:9.2.1")
}

val targetJavaVersion = 21
Expand Down
1 change: 1 addition & 0 deletions src/main/kotlin/me/duro/discordmc/DiscordMC.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class DiscordMC : JavaPlugin() {

commands.forEach { getCommand(it.first)?.setExecutor(it.second) }
events.forEach { server.pluginManager.registerEvents(it, this) }
this.logger.info("Enabled Plugin")
}

override fun onDisable() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import org.bukkit.command.CommandSender
import org.bukkit.command.TabExecutor

class DiscordMCCommand : CommandExecutor, TabExecutor {
private val GREEN = "\u001B[32m"
private val RESET = "\u001B[0m"
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>?): Boolean {
if (!sender.hasPermission("discordmc.reload")) {
sender.sendMessage("§cYou do not have permission to use this command")
Expand All @@ -30,6 +32,7 @@ class DiscordMCCommand : CommandExecutor, TabExecutor {
return true
}
sender.sendMessage("§aReloaded DiscordMC config")
DiscordMC.instance.logger.info("${GREEN}Reloaded DiscordMC config${RESET}")
}

else -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,16 @@ import org.bukkit.event.Listener
import org.bukkit.scheduler.BukkitRunnable
import java.time.Duration
import java.time.LocalDateTime
import java.time.ZoneId
import com.cronutils.model.definition.CronDefinitionBuilder
import com.cronutils.model.time.ExecutionTime
import com.cronutils.parser.CronParser
import com.cronutils.model.CronType

class ScheduledRestartListener : Listener {

private val config = DiscordMC.instance.toml.restart

class ScheduledRestartListener() : Listener {
init {
object : BukkitRunnable() {
override fun run() {
Expand All @@ -19,25 +26,43 @@ class ScheduledRestartListener() : Listener {

private fun checkForRestart() {
val now = LocalDateTime.now()
val restartTimes = (DiscordMC.instance.toml.restart?.times ?: emptyList()).map {
val (hours, minutes) = it.split(":").map(String::toInt)
LocalDateTime.of(now.year, now.month, now.dayOfMonth, hours, minutes)
}.filter { it.isAfter(now) }
val zoneId = ZoneId.systemDefault()
val cronExpression = config?.cron

cronExpression?.takeIf { it != "* * * * *" }?.let {
try {
val cron = CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX)).parse(it)
ExecutionTime.forCron(cron).nextExecution(now.atZone(zoneId))?.ifPresent { next ->
handleRestart(now, next.toLocalDateTime())
}
} catch (e: Exception) {
println("Error parsing cron: ${e.message}")
}
}

if (restartTimes.isEmpty()) return
(config?.times ?: emptyList()).mapNotNull { parseTime(it, now) }
.firstOrNull { it.isAfter(now) || Duration.between(now, it).toMinutes().toInt() == 0 }
?.let { handleRestart(now, it) }
}

val nextRestartTime = restartTimes.first()
val minutesLeft = Duration.between(now, nextRestartTime).toMinutes().toInt()
private fun parseTime(time: String, now: LocalDateTime): LocalDateTime? {
return try {
val (hours, minutes) = time.split(":").map(String::toInt)
LocalDateTime.of(now.year, now.month, now.dayOfMonth, hours, minutes)
} catch (e: Exception) {
null
}
}

if (DiscordMC.instance.toml.restart?.periods?.contains(minutesLeft) == true) {
private fun handleRestart(now: LocalDateTime, time: LocalDateTime) {
val minutesLeft = Duration.between(now, time).toMinutes().toInt()
if (config?.periods?.contains(minutesLeft) == true || minutesLeft == 0) {
val message = when (minutesLeft) {
0 -> "Server is restarting!"
0 -> "Server is restarting now!"
5 -> "Detected 5 minutes until restart, initiating server backup..."
else -> "Server restarting in $minutesLeft minutes!"
}

Webhook.sendWebhook(
DiscordMC.instance.toml.restart, mapOf("{message}" to message)
)
Webhook.sendWebhook(config, mapOf("{message}" to message))
}
}
}
2 changes: 2 additions & 0 deletions src/main/kotlin/me/duro/discordmc/utils/ConfigLoader.kt
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ data class EventConfig(
data class RestartConfig(
val times: List<String>? = emptyList(),
val periods: List<Int>? = emptyList(),
val cron: String,
override val webhook: String? = null,
override val embed: Webhook.Embed? = null,
override val content: String? = null
Expand Down Expand Up @@ -135,6 +136,7 @@ object ConfigLoader {
"times = [\"00:00\", \"06:00\", \"12:00\", \"18:00\"] # HH:MM format, in the server's timezone"
)
options.add(webhookIdx + 2, "periods = [30, 10, 5, 4, 3, 2, 1] # minutes before restart")
options.add(webhookIdx + 3, "#cron = \"* * * * *\" # remove the comment tag to use cron jobs, setting this will ignore restart.times")
}
}

Expand Down