From 44ad93a12e279e6a23a4eebcc03510dc78995e3b Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Fri, 24 Jan 2025 14:32:34 -0500 Subject: [PATCH 01/10] add restart announcements --- ansible/build.gradle.kts | 2 + gradle/libs.versions.toml | 5 + .../announcements-velocity/build.gradle.kts | 13 ++ .../announcements/AnnouncementsConfig.java | 36 +++++ .../announcements/AnnouncementsPlugin.java | 134 ++++++++++++++++++ .../civmc/announcements/ProxyListener.java | 5 + .../src/main/resources/config.yml | 10 ++ settings.gradle.kts | 1 + 8 files changed, 206 insertions(+) create mode 100644 plugins/announcements-velocity/build.gradle.kts create mode 100644 plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java create mode 100644 plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java create mode 100644 plugins/announcements-velocity/src/main/java/net/civmc/announcements/ProxyListener.java create mode 100644 plugins/announcements-velocity/src/main/resources/config.yml diff --git a/ansible/build.gradle.kts b/ansible/build.gradle.kts index f5d77db1c..71836bf84 100644 --- a/ansible/build.gradle.kts +++ b/ansible/build.gradle.kts @@ -38,6 +38,8 @@ dependencies { pvpPlugin(project(path = ":plugins:namelayer-paper")) pvpPlugin(project(path = ":plugins:civchat2-paper")) pvpPlugin(project(path = ":plugins:namecolors-paper")) + + proxyPlugin(project(path = ":plugins:announcements-velocity", configuration = "shadow")) } val copyPaperPlugins = tasks.register("copyPaperPlugins") { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 5018afda2..470f8f362 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -2,6 +2,7 @@ paper = "1.21.3-R0.1-SNAPSHOT" junit = "5.8.2" nuotifier = "2.7.2" +velocity = "3.4.0-SNAPSHOT" [plugins] paper-userdev = { id = "io.papermc.paperweight.userdev", version = "2.0.0-beta.11" } @@ -10,6 +11,7 @@ runpaper = { id = "xyz.jpenilla.run-paper", version = "2.3.1" } [libraries] paper-api = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper" } +velocity-api = { group = "com.velocitypowered", name = "velocity-api", version.ref = "velocity"} aikar-acf = { group = "co.aikar", name = "acf-bukkit", version = "0.5.1-SNAPSHOT" } aikar-taskchain = { group = "co.aikar", name = "taskchain-bukkit", version = "3.7.2" } @@ -18,6 +20,9 @@ commons-lang3 = { group = "org.apache.commons", name = "commons-lang3", version commons-collections4 = { group = "org.apache.commons", name = "commons-collections4", version = "4.4" } commons-math3 = { group = "org.apache.commons", name = "commons-math3", version = "3.6.1" } +cron-utils = { group = "com.cronutils", name = "cron-utils", version = "9.2.1" } +snakeyaml = { group = "org.yaml", name = "snakeyaml", version = "2.3"} + rabbitmq-client = { group = "com.rabbitmq", name = "amqp-client", version = "5.17.1" } nuvotifier-api = { group = "com.github.NuVotifier.NuVotifier", name = "nuvotifier-api", version.ref = "nuotifier" } diff --git a/plugins/announcements-velocity/build.gradle.kts b/plugins/announcements-velocity/build.gradle.kts new file mode 100644 index 000000000..8826f99e3 --- /dev/null +++ b/plugins/announcements-velocity/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + id("com.github.johnrengelman.shadow") +} + +version = "1.0.0" + +dependencies { + compileOnly(libs.velocity.api) + annotationProcessor(libs.velocity.api) + + implementation(libs.cron.utils) + implementation(libs.snakeyaml) +} diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java new file mode 100644 index 000000000..ef81226ba --- /dev/null +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java @@ -0,0 +1,36 @@ +package net.civmc.announcements; + +import java.util.List; + +/** + * @implNote property must be named the same as in the config file, must also have getters and setters else snakeyaml doesn't like it + */ +public class AnnouncementsConfig { + + public static class ScheduledAnnouncement { + private String cron; + private String message; + + public String getMessage() { + return message; + } + public void setMessage(String message) { + this.message = message; + } + public String getCron() { + return cron; + } + public void setCron(String cron) { + this.cron = cron; + } + } + + private List scheduledAnnouncements; + + public List getScheduledAnnouncements() { + return scheduledAnnouncements; + } + public void setScheduledAnnouncements(List scheduledAnnouncements) { + this.scheduledAnnouncements = scheduledAnnouncements; + } +} diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java new file mode 100644 index 000000000..f3a0e4af2 --- /dev/null +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java @@ -0,0 +1,134 @@ +package net.civmc.announcements; + +import com.cronutils.model.Cron; +import com.cronutils.model.CronType; +import com.cronutils.model.definition.CronDefinitionBuilder; +import com.cronutils.model.time.ExecutionTime; +import com.cronutils.parser.CronParser; +import com.google.inject.Inject; +import com.velocitypowered.api.event.Subscribe; +import com.velocitypowered.api.event.proxy.ProxyInitializeEvent; +import com.velocitypowered.api.plugin.Plugin; +import com.velocitypowered.api.plugin.annotation.DataDirectory; +import com.velocitypowered.api.proxy.ProxyServer; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.ZonedDateTime; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.TimeUnit; +import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.serializer.json.JSONComponentSerializer; +import org.slf4j.Logger; +import org.yaml.snakeyaml.LoaderOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; + +@Plugin(id = "civannouncements", name = "Civ Announcements", version = "1.0.0", + url = "https://civmc.net", description = "Sends various announcements", authors = {"Huskydog9988"}) +public class AnnouncementsPlugin { + + private final CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX)); + + private final ProxyServer server; + private final Logger logger; + private final Path dataDirectory; + + private final Map scheduledAnnouncements = new ConcurrentHashMap<>(); + private AnnouncementsConfig config; + + + @Inject + public AnnouncementsPlugin(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { + this.server = server; + this.logger = logger; + this.dataDirectory = dataDirectory; + + logger.info("Initializing Announcements plugin"); + + loadConfig(); + scheduleTasks(); + } + + private void scheduleTasks() { + var serializer = JSONComponentSerializer.json(); + + // ensure config exists + if (config == null) { + logger.info("Config is null"); + return; + } + + for (AnnouncementsConfig.ScheduledAnnouncement item : config.getScheduledAnnouncements()) { + Cron cron = parser.parse(item.getCron()); + // convert json message to Component + var formatedMsg = serializer.deserialize(item.getMessage()); + + scheduledAnnouncements.put(cron, formatedMsg); + } + } + + @Subscribe + public void onProxyInitialization(ProxyInitializeEvent event) { + // when server is initialized, register listeners + server.getEventManager().register(this, new ProxyListener()); + + // task to check if a scheduled announcement should be sent + server.getScheduler().buildTask(this, this::sendScheduledMessages).repeat(1, TimeUnit.SECONDS).schedule(); + } + + /** + * Checks if a scheduled message needs to be sent, and sends them if so + */ + private void sendScheduledMessages() { + ZonedDateTime now = ZonedDateTime.now(); + + for (Cron cron : scheduledAnnouncements.keySet()) { + var executionTime = ExecutionTime.forCron(cron); + + // if now is a time the + if (executionTime.isMatch(now)) { + server.sendMessage(scheduledAnnouncements.get(cron)); + } + } + } + + /** + * Loads the config from disk, and creates it if necessary + */ + private void loadConfig() { + try { + if (!Files.exists(dataDirectory)) { + Files.createDirectories(dataDirectory); + } + } catch (IOException e) { + logger.error("Could not create data directory: {}", dataDirectory, e); + return; + } + + Path configFile = dataDirectory.resolve("config.yml"); + if (!Files.exists(configFile)) { + try (InputStream in = getClass().getResourceAsStream("/config.yml")) { + if (in != null) { + Files.copy(in, configFile); + logger.info("Default configuration file created."); + } else { + logger.error("Default configuration file is missing in resources!"); + return; + } + } catch (IOException e) { + logger.error("Could not create default configuration file: {}", configFile, e); + } + } + + try (InputStream in = Files.newInputStream(configFile)) { + // register config class with snakeyaml so it knows how to populate the config + Yaml yaml = new Yaml(new Constructor(AnnouncementsConfig.class, new LoaderOptions())); + config = yaml.load(in); + } catch (IOException e) { + logger.error("Could not read config file: {}", configFile, e); + } + } +} diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/ProxyListener.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/ProxyListener.java new file mode 100644 index 000000000..24df42fb9 --- /dev/null +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/ProxyListener.java @@ -0,0 +1,5 @@ +package net.civmc.announcements; + +public class ProxyListener { + +} diff --git a/plugins/announcements-velocity/src/main/resources/config.yml b/plugins/announcements-velocity/src/main/resources/config.yml new file mode 100644 index 000000000..72385ca81 --- /dev/null +++ b/plugins/announcements-velocity/src/main/resources/config.yml @@ -0,0 +1,10 @@ + +# messages must be in json format +# https://minecraft.tools/en/json_text.php +scheduledAnnouncements: + - cron: "45 1 * * *" + message: "{\"text\":\"Restart in 15 minutes\",\"color\":\"gold\"}" + - cron: "55 1 * * *" + message: "{\"text\":\"Restart in 5 minutes\",\"color\":\"gold\"}" + - cron: "59 1 * * *" + message: "{\"text\":\"Restart in 1 minute\",\"color\":\"gold\"}" diff --git a/settings.gradle.kts b/settings.gradle.kts index 9985b1d82..febb93fee 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -13,6 +13,7 @@ plugins { include(":ansible") +include(":plugins:announcements-velocity") include(":plugins:banstick-paper") include(":plugins:bastion-paper") include(":plugins:castlegates-paper") From fa4e354deb1f186c21c2121ccfe9b781b0b55b0b Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Fri, 21 Feb 2025 14:20:28 -0500 Subject: [PATCH 02/10] remove proxy listener --- .../java/net/civmc/announcements/AnnouncementsPlugin.java | 2 -- .../src/main/java/net/civmc/announcements/ProxyListener.java | 5 ----- 2 files changed, 7 deletions(-) delete mode 100644 plugins/announcements-velocity/src/main/java/net/civmc/announcements/ProxyListener.java diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java index f3a0e4af2..1840baa0f 100644 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java @@ -72,8 +72,6 @@ public class AnnouncementsPlugin { @Subscribe public void onProxyInitialization(ProxyInitializeEvent event) { - // when server is initialized, register listeners - server.getEventManager().register(this, new ProxyListener()); // task to check if a scheduled announcement should be sent server.getScheduler().buildTask(this, this::sendScheduledMessages).repeat(1, TimeUnit.SECONDS).schedule(); diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/ProxyListener.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/ProxyListener.java deleted file mode 100644 index 24df42fb9..000000000 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/ProxyListener.java +++ /dev/null @@ -1,5 +0,0 @@ -package net.civmc.announcements; - -public class ProxyListener { - -} From 8322cdb73be2c5b4eeb631436e75b3587cc59a46 Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Fri, 21 Feb 2025 14:29:20 -0500 Subject: [PATCH 03/10] add minimessage support to announcements --- .../civmc/announcements/AnnouncementsConfig.java | 5 +++++ .../civmc/announcements/AnnouncementsPlugin.java | 13 +++++++++++-- .../src/main/resources/config.yml | 4 +++- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java index ef81226ba..cbe4ced03 100644 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java @@ -10,6 +10,7 @@ public class AnnouncementsConfig { public static class ScheduledAnnouncement { private String cron; private String message; + private boolean minimessage = false; public String getMessage() { return message; @@ -23,6 +24,10 @@ public class AnnouncementsConfig { public void setCron(String cron) { this.cron = cron; } + + public boolean isMinimessage() {return minimessage;} + public boolean getMinimessage() {return minimessage;} + public void setMinimessage(boolean minimessage) {this.minimessage = minimessage;} } private List scheduledAnnouncements; diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java index 1840baa0f..a7ebcbf9d 100644 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java @@ -20,6 +20,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.Component; +import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.serializer.json.JSONComponentSerializer; import org.slf4j.Logger; import org.yaml.snakeyaml.LoaderOptions; @@ -53,7 +54,8 @@ public class AnnouncementsPlugin { } private void scheduleTasks() { - var serializer = JSONComponentSerializer.json(); + var jsonSerializer = JSONComponentSerializer.json(); + var minimessageSerializer = MiniMessage.miniMessage(); // ensure config exists if (config == null) { @@ -64,7 +66,14 @@ public class AnnouncementsPlugin { for (AnnouncementsConfig.ScheduledAnnouncement item : config.getScheduledAnnouncements()) { Cron cron = parser.parse(item.getCron()); // convert json message to Component - var formatedMsg = serializer.deserialize(item.getMessage()); + Component formatedMsg; + + if (item.isMinimessage()) { + formatedMsg = minimessageSerializer.deserialize(item.getMessage()); + } else { + // message is in json format + formatedMsg = jsonSerializer.deserialize(item.getMessage()); + } scheduledAnnouncements.put(cron, formatedMsg); } diff --git a/plugins/announcements-velocity/src/main/resources/config.yml b/plugins/announcements-velocity/src/main/resources/config.yml index 72385ca81..5374ee7d9 100644 --- a/plugins/announcements-velocity/src/main/resources/config.yml +++ b/plugins/announcements-velocity/src/main/resources/config.yml @@ -1,10 +1,12 @@ # messages must be in json format # https://minecraft.tools/en/json_text.php +# or minimessage if selected scheduledAnnouncements: - cron: "45 1 * * *" message: "{\"text\":\"Restart in 15 minutes\",\"color\":\"gold\"}" - cron: "55 1 * * *" message: "{\"text\":\"Restart in 5 minutes\",\"color\":\"gold\"}" - cron: "59 1 * * *" - message: "{\"text\":\"Restart in 1 minute\",\"color\":\"gold\"}" + message: "Restart in 1 minute" + minimessage: true From b84e7db9c55c59bce63a831b42320b6461c1d6f4 Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Fri, 4 Apr 2025 20:58:13 -0400 Subject: [PATCH 04/10] fix proxy not saving --- docker-compose.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker-compose.yml b/docker-compose.yml index 80b0c7d14..e7b13e98b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -38,7 +38,7 @@ services: ports: - "25565:25577" volumes: - - ./containers/data/proxy:/data + - ./containers/data/proxy:/server - ./ansible/files/proxy-config:/config - ./ansible/build/proxy-plugins:/plugins From f9212d4b620712a427ab4b3f3697774e898ed7af Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Fri, 4 Apr 2025 21:02:03 -0400 Subject: [PATCH 05/10] fix cron running every second within scheduled time --- .../announcements/AnnouncementsPlugin.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java index a7ebcbf9d..f3dad16a0 100644 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java @@ -15,6 +15,7 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; +import java.time.Duration; import java.time.ZonedDateTime; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -38,6 +39,7 @@ public class AnnouncementsPlugin { private final Path dataDirectory; private final Map scheduledAnnouncements = new ConcurrentHashMap<>(); + private final Map lastExecutionTimes = new ConcurrentHashMap<>(); private AnnouncementsConfig config; @@ -83,22 +85,27 @@ public class AnnouncementsPlugin { public void onProxyInitialization(ProxyInitializeEvent event) { // task to check if a scheduled announcement should be sent - server.getScheduler().buildTask(this, this::sendScheduledMessages).repeat(1, TimeUnit.SECONDS).schedule(); + server.getScheduler().buildTask(this, this::sendScheduledMessages).repeat(5, TimeUnit.SECONDS).schedule(); } /** * Checks if a scheduled message needs to be sent, and sends them if so */ private void sendScheduledMessages() { - ZonedDateTime now = ZonedDateTime.now(); + ZonedDateTime now = ZonedDateTime.now().withNano(0); for (Cron cron : scheduledAnnouncements.keySet()) { var executionTime = ExecutionTime.forCron(cron); - // if now is a time the - if (executionTime.isMatch(now)) { - server.sendMessage(scheduledAnnouncements.get(cron)); - } + // get last time a cron *should* have run + executionTime.lastExecution(now).ifPresent(lastExecution -> { + // Check if we should execute, and if con already executed at that time + if (executionTime.isMatch(now) && !lastExecution.equals(lastExecutionTimes.get(cron))) { + // Execute and update the last execution time + server.sendMessage(scheduledAnnouncements.get(cron)); + lastExecutionTimes.put(cron, lastExecution); + } + }); } } From 683856c5cd8dc22fc552b8f5471afe52b18de284 Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Wed, 10 Sep 2025 22:31:21 -0400 Subject: [PATCH 06/10] switch to configurate & fully use mini message --- gradle/libs.versions.toml | 5 +- .../announcements-velocity/build.gradle.kts | 4 +- .../announcements/AnnouncementsConfig.java | 41 ------------- .../announcements/AnnouncementsPlugin.java | 57 +++++++++---------- .../src/main/resources/config.yml | 7 +-- 5 files changed, 35 insertions(+), 79 deletions(-) delete mode 100644 plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b55d93d2f..8951987b7 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,6 +3,7 @@ paper = "1.21.8-R0.1-SNAPSHOT" junit = "5.8.2" nuotifier = "2.7.2" velocity = "3.4.0-SNAPSHOT" +configurate = "4.2.0" [plugins] paper-userdev = { id = "io.papermc.paperweight.userdev", version = "2.0.0-beta.17" } @@ -21,7 +22,9 @@ commons-collections4 = { group = "org.apache.commons", name = "commons-collectio commons-math3 = { group = "org.apache.commons", name = "commons-math3", version = "3.6.1" } cron-utils = { group = "com.cronutils", name = "cron-utils", version = "9.2.1" } -snakeyaml = { group = "org.yaml", name = "snakeyaml", version = "2.3"} + +configurate-yaml = { group = "org.spongepowered", name = "configurate-yaml", version.ref = "configurate" } +configurate-kotlin = { group = "org.spongepowered", name = "configurate-extra-kotlin", version.ref = "configurate" } rabbitmq-client = { group = "com.rabbitmq", name = "amqp-client", version = "5.17.1" } diff --git a/plugins/announcements-velocity/build.gradle.kts b/plugins/announcements-velocity/build.gradle.kts index 8826f99e3..9a5da4709 100644 --- a/plugins/announcements-velocity/build.gradle.kts +++ b/plugins/announcements-velocity/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("com.github.johnrengelman.shadow") + alias(libs.plugins.shadow) } version = "1.0.0" @@ -9,5 +9,5 @@ dependencies { annotationProcessor(libs.velocity.api) implementation(libs.cron.utils) - implementation(libs.snakeyaml) + implementation(libs.configurate.yaml) } diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java deleted file mode 100644 index cbe4ced03..000000000 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsConfig.java +++ /dev/null @@ -1,41 +0,0 @@ -package net.civmc.announcements; - -import java.util.List; - -/** - * @implNote property must be named the same as in the config file, must also have getters and setters else snakeyaml doesn't like it - */ -public class AnnouncementsConfig { - - public static class ScheduledAnnouncement { - private String cron; - private String message; - private boolean minimessage = false; - - public String getMessage() { - return message; - } - public void setMessage(String message) { - this.message = message; - } - public String getCron() { - return cron; - } - public void setCron(String cron) { - this.cron = cron; - } - - public boolean isMinimessage() {return minimessage;} - public boolean getMinimessage() {return minimessage;} - public void setMinimessage(boolean minimessage) {this.minimessage = minimessage;} - } - - private List scheduledAnnouncements; - - public List getScheduledAnnouncements() { - return scheduledAnnouncements; - } - public void setScheduledAnnouncements(List scheduledAnnouncements) { - this.scheduledAnnouncements = scheduledAnnouncements; - } -} diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java index f3dad16a0..fb1991ce1 100644 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java @@ -15,24 +15,25 @@ import java.io.IOException; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; -import java.time.Duration; import java.time.ZonedDateTime; +import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; -import net.kyori.adventure.text.serializer.json.JSONComponentSerializer; +import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; -import org.yaml.snakeyaml.LoaderOptions; -import org.yaml.snakeyaml.Yaml; -import org.yaml.snakeyaml.constructor.Constructor; +import org.spongepowered.configurate.CommentedConfigurationNode; +import org.spongepowered.configurate.ConfigurationNode; +import org.spongepowered.configurate.yaml.YamlConfigurationLoader; @Plugin(id = "civannouncements", name = "Civ Announcements", version = "1.0.0", url = "https://civmc.net", description = "Sends various announcements", authors = {"Huskydog9988"}) public class AnnouncementsPlugin { - private final CronParser parser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX)); + private final CronParser cronParser = new CronParser(CronDefinitionBuilder.instanceDefinitionFor(CronType.UNIX)); private final ProxyServer server; private final Logger logger; @@ -40,7 +41,7 @@ public class AnnouncementsPlugin { private final Map scheduledAnnouncements = new ConcurrentHashMap<>(); private final Map lastExecutionTimes = new ConcurrentHashMap<>(); - private AnnouncementsConfig config; + private @Nullable CommentedConfigurationNode config; @Inject @@ -48,15 +49,20 @@ public class AnnouncementsPlugin { this.server = server; this.logger = logger; this.dataDirectory = dataDirectory; + } + @Subscribe + public void onProxyInitialization(ProxyInitializeEvent event) { logger.info("Initializing Announcements plugin"); loadConfig(); scheduleTasks(); + + // task to check if a scheduled announcement should be sent + server.getScheduler().buildTask(this, this::sendScheduledMessages).repeat(5, TimeUnit.SECONDS).schedule(); } private void scheduleTasks() { - var jsonSerializer = JSONComponentSerializer.json(); var minimessageSerializer = MiniMessage.miniMessage(); // ensure config exists @@ -65,29 +71,16 @@ public class AnnouncementsPlugin { return; } - for (AnnouncementsConfig.ScheduledAnnouncement item : config.getScheduledAnnouncements()) { - Cron cron = parser.parse(item.getCron()); - // convert json message to Component - Component formatedMsg; - - if (item.isMinimessage()) { - formatedMsg = minimessageSerializer.deserialize(item.getMessage()); - } else { - // message is in json format - formatedMsg = jsonSerializer.deserialize(item.getMessage()); - } - + // read scheduled announcements from config + List announcements = config.node("scheduledAnnouncements").childrenList(); + for (ConfigurationNode announcement : announcements) { + Cron cron = cronParser.parse(Objects.requireNonNull(announcement.node("cron").getString())); + // convert message to Component + Component formatedMsg = minimessageSerializer.deserialize(Objects.requireNonNull(announcement.node("message").getString())); scheduledAnnouncements.put(cron, formatedMsg); } } - @Subscribe - public void onProxyInitialization(ProxyInitializeEvent event) { - - // task to check if a scheduled announcement should be sent - server.getScheduler().buildTask(this, this::sendScheduledMessages).repeat(5, TimeUnit.SECONDS).schedule(); - } - /** * Checks if a scheduled message needs to be sent, and sends them if so */ @@ -114,6 +107,7 @@ public class AnnouncementsPlugin { */ private void loadConfig() { try { + // ensure data directory exists if (!Files.exists(dataDirectory)) { Files.createDirectories(dataDirectory); } @@ -122,6 +116,7 @@ public class AnnouncementsPlugin { return; } + // create config file if it doesn't exist Path configFile = dataDirectory.resolve("config.yml"); if (!Files.exists(configFile)) { try (InputStream in = getClass().getResourceAsStream("/config.yml")) { @@ -137,12 +132,12 @@ public class AnnouncementsPlugin { } } - try (InputStream in = Files.newInputStream(configFile)) { - // register config class with snakeyaml so it knows how to populate the config - Yaml yaml = new Yaml(new Constructor(AnnouncementsConfig.class, new LoaderOptions())); - config = yaml.load(in); + YamlConfigurationLoader loader = YamlConfigurationLoader.builder().path(configFile).build(); + try { + config = loader.load(); } catch (IOException e) { logger.error("Could not read config file: {}", configFile, e); + throw new RuntimeException("Could not load configuration file: " + configFile, e); } } } diff --git a/plugins/announcements-velocity/src/main/resources/config.yml b/plugins/announcements-velocity/src/main/resources/config.yml index 5374ee7d9..2e837f61d 100644 --- a/plugins/announcements-velocity/src/main/resources/config.yml +++ b/plugins/announcements-velocity/src/main/resources/config.yml @@ -4,9 +4,8 @@ # or minimessage if selected scheduledAnnouncements: - cron: "45 1 * * *" - message: "{\"text\":\"Restart in 15 minutes\",\"color\":\"gold\"}" + message: "Restart in 15 minutes" - cron: "55 1 * * *" - message: "{\"text\":\"Restart in 5 minutes\",\"color\":\"gold\"}" + message: "Restart in 5 minutes" - cron: "59 1 * * *" - message: "Restart in 1 minute" - minimessage: true + message: "Restart in 1 minute" From 744182a0046a8230771a0dcb3380278636eb6566 Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Wed, 10 Sep 2025 22:43:15 -0400 Subject: [PATCH 07/10] plugins should also use version catalogue --- build.gradle.kts | 1 + plugins/banstick-paper/build.gradle.kts | 4 ++-- plugins/bastion-paper/build.gradle.kts | 2 +- plugins/castlegates-paper/build.gradle.kts | 2 +- plugins/citadel-paper/build.gradle.kts | 2 +- plugins/civchat2-paper/build.gradle.kts | 2 +- plugins/civduties-paper/build.gradle.kts | 2 +- plugins/civmodcore-paper/build.gradle.kts | 6 +++--- plugins/civproxy-velocity/build.gradle.kts | 6 ------ plugins/combattagplus-paper/build.gradle.kts | 4 ++-- plugins/essenceglue-paper/build.gradle.kts | 2 +- plugins/exilepearl-paper/build.gradle.kts | 2 +- plugins/factorymod-paper/build.gradle.kts | 2 +- plugins/finale-paper/build.gradle.kts | 6 +----- plugins/heliodor-paper/build.gradle.kts | 2 +- plugins/hiddenore-paper/build.gradle.kts | 2 +- plugins/itemexchange-paper/build.gradle.kts | 2 +- plugins/jukealert-paper/build.gradle.kts | 4 ++-- plugins/kirabukkitgateway-paper/build.gradle.kts | 4 ++-- plugins/kitpvp-paper/build.gradle.kts | 4 ++-- plugins/namecolors-paper/build.gradle.kts | 2 +- plugins/namelayer-paper/build.gradle.kts | 2 +- plugins/railswitch-paper/build.gradle.kts | 2 +- plugins/randomspawn-paper/build.gradle.kts | 2 +- plugins/realisticbiomes-paper/build.gradle.kts | 4 ++-- plugins/realisticbiomes2-paper/build.gradle.kts | 4 ++-- plugins/simpleadminhacks-paper/build.gradle.kts | 2 +- plugins/voidworld-paper/build.gradle.kts | 2 +- 28 files changed, 36 insertions(+), 45 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 99087b8ea..920aea729 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -30,5 +30,6 @@ allprojects { maven("https://repo.infernalsuite.com/repository/maven-snapshots/") maven("https://repo.rapture.pw/repository/maven-releases/") maven("https://jitpack.io") + maven("https://repo.ajg0702.us/releases") } } diff --git a/plugins/banstick-paper/build.gradle.kts b/plugins/banstick-paper/build.gradle.kts index 78cc5e9da..0f52f7dcc 100644 --- a/plugins/banstick-paper/build.gradle.kts +++ b/plugins/banstick-paper/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("io.papermc.paperweight.userdev") - id("com.gradleup.shadow") + alias(libs.plugins.paper.userdev) + alias(libs.plugins.shadow) } version = "2.0.1" diff --git a/plugins/bastion-paper/build.gradle.kts b/plugins/bastion-paper/build.gradle.kts index 37c8ed89a..360c479c3 100644 --- a/plugins/bastion-paper/build.gradle.kts +++ b/plugins/bastion-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "3.0.1" diff --git a/plugins/castlegates-paper/build.gradle.kts b/plugins/castlegates-paper/build.gradle.kts index 8c4d23298..d2c7cff82 100644 --- a/plugins/castlegates-paper/build.gradle.kts +++ b/plugins/castlegates-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.0.2" diff --git a/plugins/citadel-paper/build.gradle.kts b/plugins/citadel-paper/build.gradle.kts index 3035765c7..96052f0ea 100644 --- a/plugins/citadel-paper/build.gradle.kts +++ b/plugins/citadel-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "5.2.4" diff --git a/plugins/civchat2-paper/build.gradle.kts b/plugins/civchat2-paper/build.gradle.kts index e7b72eecb..459a86591 100644 --- a/plugins/civchat2-paper/build.gradle.kts +++ b/plugins/civchat2-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.2.2" diff --git a/plugins/civduties-paper/build.gradle.kts b/plugins/civduties-paper/build.gradle.kts index 2263e7fb0..56031b19f 100644 --- a/plugins/civduties-paper/build.gradle.kts +++ b/plugins/civduties-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "1.5.0-SNAPSHOT" diff --git a/plugins/civmodcore-paper/build.gradle.kts b/plugins/civmodcore-paper/build.gradle.kts index 4ada58f38..14f074574 100644 --- a/plugins/civmodcore-paper/build.gradle.kts +++ b/plugins/civmodcore-paper/build.gradle.kts @@ -1,7 +1,7 @@ plugins { - id("io.papermc.paperweight.userdev") - id("com.gradleup.shadow") - id("xyz.jpenilla.run-paper") + alias(libs.plugins.paper.userdev) + alias(libs.plugins.shadow) + alias(libs.plugins.runpaper) } version = "3.0.6" diff --git a/plugins/civproxy-velocity/build.gradle.kts b/plugins/civproxy-velocity/build.gradle.kts index 2c5b57157..d62eefe8b 100644 --- a/plugins/civproxy-velocity/build.gradle.kts +++ b/plugins/civproxy-velocity/build.gradle.kts @@ -1,11 +1,5 @@ version = "1.0.0" -repositories { - maven { - url = uri("https://repo.ajg0702.us/releases") - } -} - dependencies { compileOnly("com.velocitypowered:velocity-api:3.4.0-SNAPSHOT") compileOnly("us.ajg0702.queue.api:api:2.8.0") diff --git a/plugins/combattagplus-paper/build.gradle.kts b/plugins/combattagplus-paper/build.gradle.kts index 78587a87f..7847d5a94 100644 --- a/plugins/combattagplus-paper/build.gradle.kts +++ b/plugins/combattagplus-paper/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("io.papermc.paperweight.userdev") - id("xyz.jpenilla.run-paper") + alias(libs.plugins.paper.userdev) + alias(libs.plugins.runpaper) } version = "2.0.1" diff --git a/plugins/essenceglue-paper/build.gradle.kts b/plugins/essenceglue-paper/build.gradle.kts index 54ee29144..340775fda 100644 --- a/plugins/essenceglue-paper/build.gradle.kts +++ b/plugins/essenceglue-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.0.0-SNAPSHOT" diff --git a/plugins/exilepearl-paper/build.gradle.kts b/plugins/exilepearl-paper/build.gradle.kts index 0938d56c1..eb6928273 100644 --- a/plugins/exilepearl-paper/build.gradle.kts +++ b/plugins/exilepearl-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.1.6" diff --git a/plugins/factorymod-paper/build.gradle.kts b/plugins/factorymod-paper/build.gradle.kts index 77053c962..a0af4c9ae 100644 --- a/plugins/factorymod-paper/build.gradle.kts +++ b/plugins/factorymod-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "3.1.0" diff --git a/plugins/finale-paper/build.gradle.kts b/plugins/finale-paper/build.gradle.kts index 374d9b3c4..967894b2a 100644 --- a/plugins/finale-paper/build.gradle.kts +++ b/plugins/finale-paper/build.gradle.kts @@ -1,9 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") -} - -repositories { - maven("https://repo.dmulloy2.net/repository/public") + alias(libs.plugins.paper.userdev) } version = "2.1.0" diff --git a/plugins/heliodor-paper/build.gradle.kts b/plugins/heliodor-paper/build.gradle.kts index f3ded5a51..1521a452b 100644 --- a/plugins/heliodor-paper/build.gradle.kts +++ b/plugins/heliodor-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "1.0.0" diff --git a/plugins/hiddenore-paper/build.gradle.kts b/plugins/hiddenore-paper/build.gradle.kts index fd5a358cc..287545ff8 100644 --- a/plugins/hiddenore-paper/build.gradle.kts +++ b/plugins/hiddenore-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.0.0-SNAPSHOT" diff --git a/plugins/itemexchange-paper/build.gradle.kts b/plugins/itemexchange-paper/build.gradle.kts index 5fe6095b1..d2e56285a 100644 --- a/plugins/itemexchange-paper/build.gradle.kts +++ b/plugins/itemexchange-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.0.2" diff --git a/plugins/jukealert-paper/build.gradle.kts b/plugins/jukealert-paper/build.gradle.kts index 210636884..b01165870 100644 --- a/plugins/jukealert-paper/build.gradle.kts +++ b/plugins/jukealert-paper/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("io.papermc.paperweight.userdev") - id("com.gradleup.shadow") + alias(libs.plugins.paper.userdev) + alias(libs.plugins.shadow) } version = "3.0.8" diff --git a/plugins/kirabukkitgateway-paper/build.gradle.kts b/plugins/kirabukkitgateway-paper/build.gradle.kts index b829debf3..a4fa7d830 100644 --- a/plugins/kirabukkitgateway-paper/build.gradle.kts +++ b/plugins/kirabukkitgateway-paper/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("io.papermc.paperweight.userdev") - id("com.gradleup.shadow") + alias(libs.plugins.paper.userdev) + alias(libs.plugins.shadow) } version = "2.0.3" diff --git a/plugins/kitpvp-paper/build.gradle.kts b/plugins/kitpvp-paper/build.gradle.kts index d1fedb0bb..57e2fed64 100644 --- a/plugins/kitpvp-paper/build.gradle.kts +++ b/plugins/kitpvp-paper/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("io.papermc.paperweight.userdev") - id("com.gradleup.shadow") + alias(libs.plugins.paper.userdev) + alias(libs.plugins.shadow) } version = "1.0.0" diff --git a/plugins/namecolors-paper/build.gradle.kts b/plugins/namecolors-paper/build.gradle.kts index ddc9d2aad..8b3cb90d4 100644 --- a/plugins/namecolors-paper/build.gradle.kts +++ b/plugins/namecolors-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.0.0-SNAPSHOT" diff --git a/plugins/namelayer-paper/build.gradle.kts b/plugins/namelayer-paper/build.gradle.kts index cb2f1612d..95c3e8372 100644 --- a/plugins/namelayer-paper/build.gradle.kts +++ b/plugins/namelayer-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "3.0.6" diff --git a/plugins/railswitch-paper/build.gradle.kts b/plugins/railswitch-paper/build.gradle.kts index dd8441e83..699fbacf8 100644 --- a/plugins/railswitch-paper/build.gradle.kts +++ b/plugins/railswitch-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.0.0-SNAPSHOT" diff --git a/plugins/randomspawn-paper/build.gradle.kts b/plugins/randomspawn-paper/build.gradle.kts index 6a92fb9c8..46f5d2ff4 100644 --- a/plugins/randomspawn-paper/build.gradle.kts +++ b/plugins/randomspawn-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "3.0.4" diff --git a/plugins/realisticbiomes-paper/build.gradle.kts b/plugins/realisticbiomes-paper/build.gradle.kts index 34acfb202..e3a5b57bb 100644 --- a/plugins/realisticbiomes-paper/build.gradle.kts +++ b/plugins/realisticbiomes-paper/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("io.papermc.paperweight.userdev") - id("xyz.jpenilla.run-paper") + alias(libs.plugins.paper.userdev) + alias(libs.plugins.runpaper) } version = "3.2.3" diff --git a/plugins/realisticbiomes2-paper/build.gradle.kts b/plugins/realisticbiomes2-paper/build.gradle.kts index 34acfb202..e3a5b57bb 100644 --- a/plugins/realisticbiomes2-paper/build.gradle.kts +++ b/plugins/realisticbiomes2-paper/build.gradle.kts @@ -1,6 +1,6 @@ plugins { - id("io.papermc.paperweight.userdev") - id("xyz.jpenilla.run-paper") + alias(libs.plugins.paper.userdev) + alias(libs.plugins.runpaper) } version = "3.2.3" diff --git a/plugins/simpleadminhacks-paper/build.gradle.kts b/plugins/simpleadminhacks-paper/build.gradle.kts index 53a11e5f7..eac80be8a 100644 --- a/plugins/simpleadminhacks-paper/build.gradle.kts +++ b/plugins/simpleadminhacks-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "2.3.2" diff --git a/plugins/voidworld-paper/build.gradle.kts b/plugins/voidworld-paper/build.gradle.kts index 4b3f82978..435c1ff42 100644 --- a/plugins/voidworld-paper/build.gradle.kts +++ b/plugins/voidworld-paper/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("io.papermc.paperweight.userdev") + alias(libs.plugins.paper.userdev) } version = "1.0.0" From 5ab2baf16e162a549320c323597503d6c3b6689f Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Wed, 10 Sep 2025 22:51:59 -0400 Subject: [PATCH 08/10] kotlin = banned --- gradle/libs.versions.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 8951987b7..8eaf3b652 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,7 +24,6 @@ commons-math3 = { group = "org.apache.commons", name = "commons-math3", version cron-utils = { group = "com.cronutils", name = "cron-utils", version = "9.2.1" } configurate-yaml = { group = "org.spongepowered", name = "configurate-yaml", version.ref = "configurate" } -configurate-kotlin = { group = "org.spongepowered", name = "configurate-extra-kotlin", version.ref = "configurate" } rabbitmq-client = { group = "com.rabbitmq", name = "amqp-client", version = "5.17.1" } From ea3fa617a7337304bc17e331159728b5ab8eac6e Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Wed, 10 Sep 2025 22:54:18 -0400 Subject: [PATCH 09/10] remove useless log --- .../main/java/net/civmc/announcements/AnnouncementsPlugin.java | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java index fb1991ce1..5434f79ca 100644 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java @@ -136,7 +136,6 @@ public class AnnouncementsPlugin { try { config = loader.load(); } catch (IOException e) { - logger.error("Could not read config file: {}", configFile, e); throw new RuntimeException("Could not load configuration file: " + configFile, e); } } From 175ab1d60674844c09b51dd83ee9e85e1ec8c3f4 Mon Sep 17 00:00:00 2001 From: Husky <39809509+Huskydog9988@users.noreply.github.com> Date: Thu, 11 Sep 2025 17:31:01 -0400 Subject: [PATCH 10/10] announcements now also appear as titles --- .../announcements/AnnouncementsPlugin.java | 21 +++++++++++++++---- .../src/main/resources/config.yml | 10 ++++++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java index 5434f79ca..5448fe10c 100644 --- a/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java +++ b/plugins/announcements-velocity/src/main/java/net/civmc/announcements/AnnouncementsPlugin.java @@ -23,6 +23,7 @@ import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; import net.kyori.adventure.text.Component; import net.kyori.adventure.text.minimessage.MiniMessage; +import net.kyori.adventure.title.Title; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; import org.spongepowered.configurate.CommentedConfigurationNode; @@ -39,11 +40,12 @@ public class AnnouncementsPlugin { private final Logger logger; private final Path dataDirectory; - private final Map scheduledAnnouncements = new ConcurrentHashMap<>(); + private record Announcement(Component message, Boolean showTitle) {} + + private final Map scheduledAnnouncements = new ConcurrentHashMap<>(); private final Map lastExecutionTimes = new ConcurrentHashMap<>(); private @Nullable CommentedConfigurationNode config; - @Inject public AnnouncementsPlugin(ProxyServer server, Logger logger, @DataDirectory Path dataDirectory) { this.server = server; @@ -77,7 +79,8 @@ public class AnnouncementsPlugin { Cron cron = cronParser.parse(Objects.requireNonNull(announcement.node("cron").getString())); // convert message to Component Component formatedMsg = minimessageSerializer.deserialize(Objects.requireNonNull(announcement.node("message").getString())); - scheduledAnnouncements.put(cron, formatedMsg); + Boolean showTitle = announcement.node("showTitle").getBoolean(); + scheduledAnnouncements.put(cron, new Announcement(formatedMsg, showTitle)); } } @@ -95,8 +98,18 @@ public class AnnouncementsPlugin { // Check if we should execute, and if con already executed at that time if (executionTime.isMatch(now) && !lastExecution.equals(lastExecutionTimes.get(cron))) { // Execute and update the last execution time - server.sendMessage(scheduledAnnouncements.get(cron)); + var announcement = scheduledAnnouncements.get(cron); + server.sendMessage(announcement.message); lastExecutionTimes.put(cron, lastExecution); + if (announcement.showTitle) { + // send title to all players + var title = Title.title(announcement.message, Component.empty()); + server.getAllPlayers().parallelStream().forEach(player -> + player.showTitle(title) + ); + } + + logger.info("Announcement sent: {}", announcement.message); } }); } diff --git a/plugins/announcements-velocity/src/main/resources/config.yml b/plugins/announcements-velocity/src/main/resources/config.yml index 2e837f61d..e4fa6968a 100644 --- a/plugins/announcements-velocity/src/main/resources/config.yml +++ b/plugins/announcements-velocity/src/main/resources/config.yml @@ -1,11 +1,15 @@ -# messages must be in json format -# https://minecraft.tools/en/json_text.php -# or minimessage if selected +# messages must be in minimessage format +# https://webui.advntr.dev/ scheduledAnnouncements: + - cron: "0 1 * * *" + message: "Restart in 1 hour" - cron: "45 1 * * *" message: "Restart in 15 minutes" + showTitle: false - cron: "55 1 * * *" message: "Restart in 5 minutes" + showTitle: true - cron: "59 1 * * *" message: "Restart in 1 minute" + showTitle: true