Switch to Kotlin + consistency improvements

This commit is contained in:
Telesphoreo 2024-01-28 13:43:17 -06:00
parent f93b26011f
commit 942f654ba0
13 changed files with 303 additions and 124 deletions

View File

@ -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

View File

@ -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
}

109
build.gradle.kts Normal file
View File

@ -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<MavenPublication>("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)
}
}
}

View File

@ -1 +0,0 @@
rootProject.name = 'futura'

1
settings.gradle.kts Normal file
View File

@ -0,0 +1 @@
rootProject.name = "Futura"

View File

@ -1,58 +1,62 @@
package dev.plex.futura; package dev.plex.futura;
import dev.plex.futura.bot.BotHandler; import dev.plex.futura.bot.BotHandler;
import dev.plex.futura.config.Config;
import dev.plex.futura.listener.ChatListener; import dev.plex.futura.listener.ChatListener;
import org.bukkit.configuration.file.FileConfiguration; import org.bstats.bukkit.Metrics;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import java.io.File; import java.io.File;
public final class Futura extends JavaPlugin { public final class Futura extends JavaPlugin
{
private static Futura plugin; private static Futura plugin;
private YamlConfiguration messages;
private BotHandler botHandler; private BotHandler botHandler;
public Config config;
public Config messages;
@Override @Override
public void onLoad() { public void onLoad()
{
super.onLoad();
plugin = this; plugin = this;
config = new Config(this, "config.yml");
if (!this.getDataFolder().exists()) this.getDataFolder().mkdir(); messages = new Config(this, "messages.yml");
this.getConfig().options().copyDefaults(true);
saveConfig();
final File messagesFile = new File(this.getDataFolder(), "messages.yml"); final File messagesFile = new File(this.getDataFolder(), "messages.yml");
if (!messagesFile.exists()) { if (!messagesFile.exists())
{
this.saveResource("messages.yml", false); this.saveResource("messages.yml", false);
} }
messages = YamlConfiguration.loadConfiguration(messagesFile);
botHandler = new BotHandler(); botHandler = new BotHandler();
} }
@Override @Override
public void onEnable() { public void onEnable()
{
config.load();
messages.load();
final ChatListener chatListener = new ChatListener(); final ChatListener chatListener = new ChatListener();
this.getServer().getPluginManager().registerEvents(chatListener, this); this.getServer().getPluginManager().registerEvents(chatListener, this);
if (this.botHandler.ready()) { if (this.botHandler.ready())
{
this.botHandler.jda().addEventListener(chatListener); this.botHandler.jda().addEventListener(chatListener);
} }
// Metrics @ https://bstats.org/plugin/bukkit/Futura/20848
Metrics metrics = new Metrics(this, 20848);
} }
@Override @Override
public void onDisable() { public void onDisable()
}
public static Futura plugin() {
return plugin;
}
public FileConfiguration messages()
{ {
return this.messages; }
public static Futura plugin()
{
return plugin;
} }
public BotHandler botHandler() public BotHandler botHandler()

View File

@ -9,10 +9,6 @@ import net.dv8tion.jda.api.requests.GatewayIntent;
import net.dv8tion.jda.api.utils.MemberCachePolicy; import net.dv8tion.jda.api.utils.MemberCachePolicy;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
/**
* @author Taah
* @since 7:01 PM [01-25-2024]
*/
public class BotHandler public class BotHandler
{ {
private final JDA jda; private final JDA jda;

View File

@ -8,10 +8,6 @@ import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
/**
* @author Taah
* @since 8:34 PM [01-27-2024]
*/
public class StatusListener implements Listener public class StatusListener implements Listener
{ {
@EventHandler @EventHandler

View File

@ -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);
}
}

View File

@ -8,12 +8,6 @@ import org.bukkit.event.Event;
import org.bukkit.event.HandlerList; import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull; 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 public class DiscordBridgeChatEvent extends Event implements Cancellable
{ {
private final HandlerList HANDLER_LIST = new HandlerList(); private final HandlerList HANDLER_LIST = new HandlerList();
@ -66,7 +60,8 @@ public class DiscordBridgeChatEvent extends Event implements Cancellable
this.cancelled = cancel; this.cancelled = cancel;
} }
public enum BridgeType { public enum BridgeType
{
DISCORD_TO_MINECRAFT, DISCORD_TO_MINECRAFT,
MINECRAFT_TO_DISCORD MINECRAFT_TO_DISCORD
} }

View File

@ -18,15 +18,10 @@ import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler; import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority; import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.awt.*; import java.awt.*;
/**
* @author Taah
* @since 7:40 PM [01-25-2024]
*/
public class ChatListener extends ListenerAdapter implements Listener public class ChatListener extends ListenerAdapter implements Listener
{ {
private final static MiniMessage MINI = MiniMessage.miniMessage(); private final static MiniMessage MINI = MiniMessage.miniMessage();
@ -46,41 +41,60 @@ public class ChatListener extends ListenerAdapter implements Listener
public void onMessageReceived(@NotNull MessageReceivedEvent event) public void onMessageReceived(@NotNull MessageReceivedEvent event)
{ {
if (event.getAuthor().isBot()) if (event.getAuthor().isBot())
{
return; return;
}
final String channelId = Futura.plugin().getConfig().getString("discord.chat", ""); final String channelId = Futura.plugin().getConfig().getString("discord.chat", "");
if (channelId.isEmpty()) if (channelId.isEmpty())
{
return; return;
}
if (!event.getChannel().getId().equals(channelId)) if (!event.getChannel().getId().equals(channelId))
{
return; 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 Member member = event.getMember();
final Role role = member.getRoles().isEmpty() ? event.getGuild().getPublicRole() : member.getRoles().get(0); final Role role = member.getRoles().isEmpty() ? event.getGuild().getPublicRole() : member.getRoles().get(0);
final String format = StringUtils.normalizeSpace( 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-color%", "<" + String.format("#%06x", role.getColor() != null ? role.getColor().getRGB() & 0xFFFFFF : 0xFFFFFF) + ">")
.replace("%role%", role.getName()) .replace("%role%", role.getName())
.replace("%username%", member.getUser().getName()) .replace("%username%", member.getUser().getName())
.replace("%message%", event.getMessage().getContentRaw()) .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); final DiscordBridgeChatEvent discordBridgeChatEvent = new DiscordBridgeChatEvent(event.getGuild(), member, event.getMessage(), DiscordBridgeChatEvent.BridgeType.DISCORD_TO_MINECRAFT);
Bukkit.getPluginManager().callEvent(discordBridgeChatEvent); Bukkit.getPluginManager().callEvent(discordBridgeChatEvent);
if (discordBridgeChatEvent.isCancelled()) if (discordBridgeChatEvent.isCancelled())
{
return; return;
}
final Component component = MINI.deserialize(format); final Component component = MINI.deserialize(format);
Bukkit.broadcast(component); Bukkit.broadcast(component);
try { try
{
event.getChannel().sendMessageEmbeds( event.getChannel().sendMessageEmbeds(
new EmbedBuilder().setColor(Color.GREEN).setDescription(PLAIN.serialize(component)).build() new EmbedBuilder().setColor(Color.GREEN).setDescription(PLAIN.serialize(component)).build()
).queue(); ).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()); 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()); FuturaLog.error("Bot could not send embed in channel! Missing permission: " + e.getPermission().getName());
} }
}); });

View File

@ -16,10 +16,6 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
/**
* @author Taah
* @since 8:26 PM [01-27-2024]
*/
public class FuturaLibraryManager implements PluginLoader public class FuturaLibraryManager implements PluginLoader
{ {
@Override @Override

View File

@ -1,33 +1,34 @@
package dev.plex.futura.util; 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 net.kyori.adventure.text.minimessage.MiniMessage;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
/**
* @author Taah
* @since 8:02 PM [01-27-2024]
*/
public class FuturaLog public class FuturaLog
{ {
private static final MiniMessage MINI = MiniMessage.miniMessage(); 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()); s = s.replace("{" + i + "}", object[i].toString());
} }
Bukkit.getConsoleSender().sendMessage(MINI.deserialize("<dark_purple>[Futura | DEBUG] <gold>" + s)); Bukkit.getConsoleSender().sendMessage(MINI.deserialize("<dark_purple>[Futura | DEBUG] <gold>" + s));
} }
public static void info(String s, Object... object) { public static void info(String s, Object... object)
for (int i = 0; i < object.length; i++) { {
for (int i = 0; i < object.length; i++)
{
s = s.replace("{" + i + "}", object[i].toString()); s = s.replace("{" + i + "}", object[i].toString());
} }
Bukkit.getConsoleSender().sendMessage(MINI.deserialize("<dark_gray>[Futura | INFO] <yellow>" + s)); Bukkit.getConsoleSender().sendMessage(MINI.deserialize("<dark_gray>[Futura | INFO] <yellow>" + s));
} }
public static void error(String s, Object... object) { public static void error(String s, Object... object)
for (int i = 0; i < object.length; i++) { {
for (int i = 0; i < object.length; i++)
{
s = s.replace("{" + i + "}", object[i].toString()); s = s.replace("{" + i + "}", object[i].toString());
} }
Bukkit.getConsoleSender().sendMessage(MINI.deserialize("<dark_red>[Futura | ERROR] <red>" + s)); Bukkit.getConsoleSender().sendMessage(MINI.deserialize("<dark_red>[Futura | ERROR] <red>" + s));