From 942f654ba04d2311d6b7ce11d4e46bfe4fbf4897 Mon Sep 17 00:00:00 2001 From: Telesphoreo Date: Sun, 28 Jan 2024 13:43:17 -0600 Subject: [PATCH] Switch to Kotlin + consistency improvements --- README.md | 3 +- build.gradle | 56 -------- build.gradle.kts | 109 ++++++++++++++++ settings.gradle | 1 - settings.gradle.kts | 1 + src/main/java/dev/plex/futura/Futura.java | 54 ++++---- .../java/dev/plex/futura/bot/BotHandler.java | 4 - .../futura/bot/listener/StatusListener.java | 4 - .../java/dev/plex/futura/config/Config.java | 123 ++++++++++++++++++ .../futura/event/DiscordBridgeChatEvent.java | 9 +- .../plex/futura/listener/ChatListener.java | 34 +++-- .../futura/util/FuturaLibraryManager.java | 4 - .../java/dev/plex/futura/util/FuturaLog.java | 25 ++-- 13 files changed, 303 insertions(+), 124 deletions(-) delete mode 100644 build.gradle create mode 100644 build.gradle.kts delete mode 100644 settings.gradle create mode 100644 settings.gradle.kts create mode 100644 src/main/java/dev/plex/futura/config/Config.java diff --git a/README.md b/README.md index 58b74b5..4240ced 100644 --- a/README.md +++ b/README.md @@ -1 +1,2 @@ -# Futura +# Futura [![Build Status](https://ci.plex.us.org/job/Futura/badge/icon)](https://ci.plex.us.org/job/Futura/) +Discord plugin bridge for Minecraft \ No newline at end of file diff --git a/build.gradle b/build.gradle deleted file mode 100644 index e30b16f..0000000 --- a/build.gradle +++ /dev/null @@ -1,56 +0,0 @@ -plugins { - id 'java' - id 'net.minecrell.plugin-yml.paper' version '0.6.0' -} - -group = 'dev.taah' -version = '0.0.1' - -repositories { - mavenCentral() - maven { - name = "papermc-repo" - url = "https://repo.papermc.io/repository/maven-public/" - } - maven { - name = "sonatype" - url = "https://oss.sonatype.org/content/groups/public/" - } -} - -dependencies { - compileOnly "io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT" - paperLibrary("net.dv8tion:JDA:5.0.0-beta.20") { - exclude module: "opus-java" - } -} - -def targetJavaVersion = 17 -java { - def javaVersion = JavaVersion.toVersion(targetJavaVersion) - sourceCompatibility = javaVersion - targetCompatibility = javaVersion - if (JavaVersion.current() < javaVersion) { - toolchain.languageVersion = JavaLanguageVersion.of(targetJavaVersion) - } -} - -tasks.withType(JavaCompile).configureEach { - options.encoding = 'UTF-8' - - if (targetJavaVersion >= 10 || JavaVersion.current().isJava10Compatible()) { - options.release.set(targetJavaVersion) - } -} - -paper { - name = "Futura" - version = project.version - main = "dev.plex.futura.Futura" - apiVersion = "1.20" - authors = List.of("Taah") - description = "Discord plugin bridge for Minecraft" - website = "https://plex.us.org" - loader = "dev.plex.futura.util.FuturaLibraryManager" - generateLibrariesJson = true -} diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..843bc58 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,109 @@ +plugins { + id("java") + `maven-publish` + id("net.minecrell.plugin-yml.paper") version "0.6.0" + id("com.github.johnrengelman.shadow") version "8.1.1" +} + +group = "dev.plex" +version = "1.0-SNAPSHOT" +description = "Futura" + +repositories { + mavenCentral() + maven { + name = "papermc-repo" + url = uri("https://repo.papermc.io/repository/maven-public/") + } + maven { + name = "sonatype" + url = uri("https://oss.sonatype.org/content/groups/public/") + } +} + +dependencies { + compileOnly("io.papermc.paper:paper-api:1.20.4-R0.1-SNAPSHOT") + library("net.dv8tion:JDA:5.0.0-beta.20") { + exclude(module = "opus-java") + } + implementation("org.bstats:bstats-base:3.0.2") + implementation("org.bstats:bstats-bukkit:3.0.2") +} + +paper { + name = "Futura" + version = project.version.toString() + main = "dev.plex.futura.Futura" + apiVersion = "1.20" + authors = listOf("Telesphoreo", "Taah") + description = "Discord plugin bridge for Minecraft" + website = "https://plex.us.org" + loader = "dev.plex.futura.util.FuturaLibraryManager" + generateLibrariesJson = true +} + +java { + toolchain.languageVersion.set(JavaLanguageVersion.of(17)) +} + +tasks { + compileJava { + options.encoding = Charsets.UTF_8.name() + } + javadoc { + options.encoding = Charsets.UTF_8.name() + } + processResources { + filteringCharset = Charsets.UTF_8.name() + } + + build { + dependsOn(shadowJar) + } + + jar { + enabled = false + } + + shadowJar { + archiveBaseName.set("Futura") + archiveClassifier.set("") + relocate("org.bstats", "dev.plex") + } +} + +publishing { + repositories { + maven { + val releasesRepoUrl = uri("https://nexus.telesphoreo.me/repository/plex-releases/") + val snapshotsRepoUrl = uri("https://nexus.telesphoreo.me/repository/plex-snapshots/") + url = if (rootProject.version.toString().endsWith("SNAPSHOT")) snapshotsRepoUrl else releasesRepoUrl + credentials { + username = System.getenv("plexUser") + password = System.getenv("plexPassword") + } + } + } + publications { + create("maven") { + pom.withXml { + val dependenciesNode = asNode().appendNode("dependencies") + configurations.getByName("library").allDependencies.configureEach { + dependenciesNode.appendNode("dependency") + .appendNode("groupId", group).parent() + .appendNode("artifactId", name).parent() + .appendNode("version", version).parent() + .appendNode("scope", "provided").parent() + } + configurations.getByName("implementation").allDependencies.configureEach { + dependenciesNode.appendNode("dependency") + .appendNode("groupId", group).parent() + .appendNode("artifactId", name).parent() + .appendNode("version", version).parent() + .appendNode("scope", "provided").parent() + } + } + artifacts.artifact(tasks.shadowJar) + } + } +} diff --git a/settings.gradle b/settings.gradle deleted file mode 100644 index da5d9b9..0000000 --- a/settings.gradle +++ /dev/null @@ -1 +0,0 @@ -rootProject.name = 'futura' diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 0000000..f58b465 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "Futura" \ No newline at end of file diff --git a/src/main/java/dev/plex/futura/Futura.java b/src/main/java/dev/plex/futura/Futura.java index 66ef129..3ca27cb 100644 --- a/src/main/java/dev/plex/futura/Futura.java +++ b/src/main/java/dev/plex/futura/Futura.java @@ -1,58 +1,62 @@ package dev.plex.futura; import dev.plex.futura.bot.BotHandler; +import dev.plex.futura.config.Config; import dev.plex.futura.listener.ChatListener; -import org.bukkit.configuration.file.FileConfiguration; -import org.bukkit.configuration.file.YamlConfiguration; +import org.bstats.bukkit.Metrics; import org.bukkit.plugin.java.JavaPlugin; import java.io.File; -public final class Futura extends JavaPlugin { +public final class Futura extends JavaPlugin +{ private static Futura plugin; - private YamlConfiguration messages; - private BotHandler botHandler; + public Config config; + public Config messages; + @Override - public void onLoad() { + public void onLoad() + { + super.onLoad(); plugin = this; - - if (!this.getDataFolder().exists()) this.getDataFolder().mkdir(); - - this.getConfig().options().copyDefaults(true); - saveConfig(); + config = new Config(this, "config.yml"); + messages = new Config(this, "messages.yml"); final File messagesFile = new File(this.getDataFolder(), "messages.yml"); - if (!messagesFile.exists()) { + if (!messagesFile.exists()) + { this.saveResource("messages.yml", false); } - messages = YamlConfiguration.loadConfiguration(messagesFile); - botHandler = new BotHandler(); } @Override - public void onEnable() { + public void onEnable() + { + config.load(); + messages.load(); final ChatListener chatListener = new ChatListener(); this.getServer().getPluginManager().registerEvents(chatListener, this); - if (this.botHandler.ready()) { + if (this.botHandler.ready()) + { this.botHandler.jda().addEventListener(chatListener); } + + // Metrics @ https://bstats.org/plugin/bukkit/Futura/20848 + Metrics metrics = new Metrics(this, 20848); } @Override - public void onDisable() { - } - - public static Futura plugin() { - return plugin; - } - - public FileConfiguration messages() + public void onDisable() { - return this.messages; + } + + public static Futura plugin() + { + return plugin; } public BotHandler botHandler() diff --git a/src/main/java/dev/plex/futura/bot/BotHandler.java b/src/main/java/dev/plex/futura/bot/BotHandler.java index c350f1d..a640fda 100644 --- a/src/main/java/dev/plex/futura/bot/BotHandler.java +++ b/src/main/java/dev/plex/futura/bot/BotHandler.java @@ -9,10 +9,6 @@ import net.dv8tion.jda.api.requests.GatewayIntent; import net.dv8tion.jda.api.utils.MemberCachePolicy; import org.bukkit.Bukkit; -/** - * @author Taah - * @since 7:01 PM [01-25-2024] - */ public class BotHandler { private final JDA jda; diff --git a/src/main/java/dev/plex/futura/bot/listener/StatusListener.java b/src/main/java/dev/plex/futura/bot/listener/StatusListener.java index a181464..3f00b20 100644 --- a/src/main/java/dev/plex/futura/bot/listener/StatusListener.java +++ b/src/main/java/dev/plex/futura/bot/listener/StatusListener.java @@ -8,10 +8,6 @@ import org.bukkit.event.Listener; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerQuitEvent; -/** - * @author Taah - * @since 8:34 PM [01-27-2024] - */ public class StatusListener implements Listener { @EventHandler diff --git a/src/main/java/dev/plex/futura/config/Config.java b/src/main/java/dev/plex/futura/config/Config.java new file mode 100644 index 0000000..f2d1bf2 --- /dev/null +++ b/src/main/java/dev/plex/futura/config/Config.java @@ -0,0 +1,123 @@ +package dev.plex.futura.config; + +import dev.plex.futura.Futura; +import dev.plex.futura.util.FuturaLog; +import org.bukkit.configuration.file.YamlConfiguration; + +import java.io.File; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +/** + * Creates a custom Config object + */ +public class Config extends YamlConfiguration +{ + /** + * The plugin instance + */ + private Futura plugin; + + /** + * The File instance + */ + private File file; + + /** + * The file name + */ + private String name; + + /** + * Whether new entries were added to the file automatically + */ + private boolean added = false; + + /** + * Creates a config object + * + * @param plugin The plugin instance + * @param name The file name + */ + public Config(Futura plugin, String name) + { + this.plugin = plugin; + this.file = new File(plugin.getDataFolder(), name); + this.name = name; + + if (!file.exists()) + { + saveDefault(); + } + } + + public void load() + { + this.load(true); + } + + /** + * Loads the configuration file + */ + public void load(boolean loadFromFile) + { + try + { + if (loadFromFile) + { + YamlConfiguration externalYamlConfig = YamlConfiguration.loadConfiguration(file); + InputStreamReader internalConfigFileStream = new InputStreamReader(plugin.getResource(name), StandardCharsets.UTF_8); + YamlConfiguration internalYamlConfig = YamlConfiguration.loadConfiguration(internalConfigFileStream); + + // Gets all the keys inside the internal file and iterates through all of it's key pairs + for (String string : internalYamlConfig.getKeys(true)) + { + // Checks if the external file contains the key already. + if (!externalYamlConfig.contains(string)) + { + // If it doesn't contain the key, we set the key based off what was found inside the plugin jar + externalYamlConfig.setComments(string, internalYamlConfig.getComments(string)); + externalYamlConfig.setInlineComments(string, internalYamlConfig.getInlineComments(string)); + externalYamlConfig.set(string, internalYamlConfig.get(string)); + FuturaLog.info("Setting key: " + string + " in " + this.name + " to the default value(s) since it does not exist!"); + added = true; + } + } + if (added) + { + externalYamlConfig.save(file); + FuturaLog.info("Saving new file..."); + added = false; + } + } + super.load(file); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + /** + * Saves the configuration file + */ + public void save() + { + try + { + super.save(file); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + + /** + * Moves the configuration file from the plugin's resources folder to the data folder (plugins/Plex/) + */ + private void saveDefault() + { + plugin.saveResource(name, false); + } +} \ No newline at end of file diff --git a/src/main/java/dev/plex/futura/event/DiscordBridgeChatEvent.java b/src/main/java/dev/plex/futura/event/DiscordBridgeChatEvent.java index a80b162..8d571db 100644 --- a/src/main/java/dev/plex/futura/event/DiscordBridgeChatEvent.java +++ b/src/main/java/dev/plex/futura/event/DiscordBridgeChatEvent.java @@ -8,12 +8,6 @@ import org.bukkit.event.Event; import org.bukkit.event.HandlerList; import org.jetbrains.annotations.NotNull; -import java.security.Guard; - -/** - * @author Taah - * @since 8:49 PM [01-27-2024] - */ public class DiscordBridgeChatEvent extends Event implements Cancellable { private final HandlerList HANDLER_LIST = new HandlerList(); @@ -66,7 +60,8 @@ public class DiscordBridgeChatEvent extends Event implements Cancellable this.cancelled = cancel; } - public enum BridgeType { + public enum BridgeType + { DISCORD_TO_MINECRAFT, MINECRAFT_TO_DISCORD } diff --git a/src/main/java/dev/plex/futura/listener/ChatListener.java b/src/main/java/dev/plex/futura/listener/ChatListener.java index 4f10800..bc09476 100644 --- a/src/main/java/dev/plex/futura/listener/ChatListener.java +++ b/src/main/java/dev/plex/futura/listener/ChatListener.java @@ -18,15 +18,10 @@ import org.bukkit.Bukkit; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; -import org.bukkit.util.StringUtil; import org.jetbrains.annotations.NotNull; import java.awt.*; -/** - * @author Taah - * @since 7:40 PM [01-25-2024] - */ public class ChatListener extends ListenerAdapter implements Listener { private final static MiniMessage MINI = MiniMessage.miniMessage(); @@ -46,41 +41,60 @@ public class ChatListener extends ListenerAdapter implements Listener public void onMessageReceived(@NotNull MessageReceivedEvent event) { if (event.getAuthor().isBot()) + { return; + } final String channelId = Futura.plugin().getConfig().getString("discord.chat", ""); if (channelId.isEmpty()) + { return; + } if (!event.getChannel().getId().equals(channelId)) + { return; + } + + if (event.getMessage().toString().length() > 256) + { + // TODO: Add a reaction to the message in Discord to indicate it wasn't sent + return; + } final Member member = event.getMember(); final Role role = member.getRoles().isEmpty() ? event.getGuild().getPublicRole() : member.getRoles().get(0); final String format = StringUtils.normalizeSpace( - Futura.plugin().messages().getString("discordToMinecraft", "") + Futura.plugin().messages.getString("discordToMinecraft", "") .replace("%role-color%", "<" + String.format("#%06x", role.getColor() != null ? role.getColor().getRGB() & 0xFFFFFF : 0xFFFFFF) + ">") .replace("%role%", role.getName()) .replace("%username%", member.getUser().getName()) .replace("%message%", event.getMessage().getContentRaw()) ); - Bukkit.getScheduler().runTask(Futura.plugin(), () -> { + Bukkit.getScheduler().runTask(Futura.plugin(), () -> + { final DiscordBridgeChatEvent discordBridgeChatEvent = new DiscordBridgeChatEvent(event.getGuild(), member, event.getMessage(), DiscordBridgeChatEvent.BridgeType.DISCORD_TO_MINECRAFT); Bukkit.getPluginManager().callEvent(discordBridgeChatEvent); if (discordBridgeChatEvent.isCancelled()) + { return; + } final Component component = MINI.deserialize(format); Bukkit.broadcast(component); - try { + try + { event.getChannel().sendMessageEmbeds( new EmbedBuilder().setColor(Color.GREEN).setDescription(PLAIN.serialize(component)).build() ).queue(); - event.getMessage().delete().queue(null, throwable -> { + event.getMessage().delete().queue(null, throwable -> + { FuturaLog.error("Couldn't delete user's message sent in Discord due to: " + throwable.getMessage()); }); - } catch (InsufficientPermissionException e) { + } + catch (InsufficientPermissionException e) + { FuturaLog.error("Bot could not send embed in channel! Missing permission: " + e.getPermission().getName()); } }); diff --git a/src/main/java/dev/plex/futura/util/FuturaLibraryManager.java b/src/main/java/dev/plex/futura/util/FuturaLibraryManager.java index 2a539ac..c476f97 100644 --- a/src/main/java/dev/plex/futura/util/FuturaLibraryManager.java +++ b/src/main/java/dev/plex/futura/util/FuturaLibraryManager.java @@ -16,10 +16,6 @@ import java.util.List; import java.util.Map; import java.util.stream.Stream; -/** - * @author Taah - * @since 8:26 PM [01-27-2024] - */ public class FuturaLibraryManager implements PluginLoader { @Override diff --git a/src/main/java/dev/plex/futura/util/FuturaLog.java b/src/main/java/dev/plex/futura/util/FuturaLog.java index 27a700a..c8ad6da 100644 --- a/src/main/java/dev/plex/futura/util/FuturaLog.java +++ b/src/main/java/dev/plex/futura/util/FuturaLog.java @@ -1,33 +1,34 @@ package dev.plex.futura.util; -import dev.plex.futura.Futura; -import net.kyori.adventure.text.logger.slf4j.ComponentLogger; import net.kyori.adventure.text.minimessage.MiniMessage; import org.bukkit.Bukkit; -/** - * @author Taah - * @since 8:02 PM [01-27-2024] - */ public class FuturaLog { private static final MiniMessage MINI = MiniMessage.miniMessage(); - public static void debug(String s, Object... object) { - for (int i = 0; i < object.length; i++) { + + public static void debug(String s, Object... object) + { + for (int i = 0; i < object.length; i++) + { s = s.replace("{" + i + "}", object[i].toString()); } Bukkit.getConsoleSender().sendMessage(MINI.deserialize("[Futura | DEBUG] " + s)); } - public static void info(String s, Object... object) { - for (int i = 0; i < object.length; i++) { + public static void info(String s, Object... object) + { + for (int i = 0; i < object.length; i++) + { s = s.replace("{" + i + "}", object[i].toString()); } Bukkit.getConsoleSender().sendMessage(MINI.deserialize("[Futura | INFO] " + s)); } - public static void error(String s, Object... object) { - for (int i = 0; i < object.length; i++) { + public static void error(String s, Object... object) + { + for (int i = 0; i < object.length; i++) + { s = s.replace("{" + i + "}", object[i].toString()); } Bukkit.getConsoleSender().sendMessage(MINI.deserialize("[Futura | ERROR] " + s));