From 1b4473d017c9d2e4d3d99465bb21ea2bfa3c9686 Mon Sep 17 00:00:00 2001
From: len <40720638+destro174@users.noreply.github.com>
Date: Sun, 2 May 2021 19:40:27 +0200
Subject: [PATCH] Add basic plugin, config and message command
---
.gitignore | 39 +++++
pom.xml | 118 +++++++++++++
src/main/java/com/alttd/chat/ChatPlugin.java | 72 ++++++++
.../java/com/alttd/chat/api/MessageEvent.java | 29 ++++
.../java/com/alttd/chat/commands/Message.java | 68 ++++++++
.../java/com/alttd/chat/config/Config.java | 156 ++++++++++++++++++
.../com/alttd/chat/config/ServerConfig.java | 60 +++++++
.../alttd/chat/listeners/ChatListener.java | 43 +++++
8 files changed, 585 insertions(+)
create mode 100644 .gitignore
create mode 100644 pom.xml
create mode 100644 src/main/java/com/alttd/chat/ChatPlugin.java
create mode 100644 src/main/java/com/alttd/chat/api/MessageEvent.java
create mode 100644 src/main/java/com/alttd/chat/commands/Message.java
create mode 100644 src/main/java/com/alttd/chat/config/Config.java
create mode 100644 src/main/java/com/alttd/chat/config/ServerConfig.java
create mode 100644 src/main/java/com/alttd/chat/listeners/ChatListener.java
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..9103db8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,39 @@
+# ProxyUtils
+.idea
+testserver
+run
+
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# IntelliJ
+*.iml
+*.ipr
+*.iws
+.idea/
+out/
+
+# Maven
+target/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..f7e7fc1
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,118 @@
+
+
+ 4.0.0
+
+ com.alttd.chat
+ Chat
+ 1.0
+ jar
+
+ Chat
+
+
+ UTF-8
+ 11
+ 11
+
+
+
+ clean package
+ ${project.name}
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.7.0
+
+ 11
+ 11
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
+ net.kyori:*
+
+ META-INF/*.MF
+
+
+
+
+
+ net.kyori:adventure-text-minimessage
+
+
+ META-INF/*.MF
+
+
+
+
+
+
+
+
+
+ src/main
+ true
+
+
+
+
+
+
+ velocitypowered-repo
+ https://repo.velocitypowered.com/releases/
+
+
+ minecraft-libraries
+ https://libraries.minecraft.net/
+
+
+ jcenter
+ jcenter-bintray
+ https://jcenter.bintray.com
+
+
+ sonatype-oss-snapshots
+ https://oss.sonatype.org/content/repositories/snapshots/
+
+
+
+
+
+ com.velocitypowered
+ velocity-api
+ 1.1.4
+ provided
+
+
+ net.luckperms
+ api
+ 5.3
+ provided
+
+
+ net.dv8tion
+ JDA
+ 4.2.0_168
+ provided
+
+
+ net.kyori
+ adventure-text-minimessage
+ 4.1.0-SNAPSHOT
+
+
+
diff --git a/src/main/java/com/alttd/chat/ChatPlugin.java b/src/main/java/com/alttd/chat/ChatPlugin.java
new file mode 100644
index 0000000..d805f3b
--- /dev/null
+++ b/src/main/java/com/alttd/chat/ChatPlugin.java
@@ -0,0 +1,72 @@
+package com.alttd.chat;
+
+import com.alttd.chat.config.Config;
+import com.alttd.chat.listeners.ChatListener;
+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 net.luckperms.api.LuckPerms;
+import net.luckperms.api.LuckPermsProvider;
+import org.slf4j.Logger;
+
+import java.io.File;
+import java.nio.file.Path;
+
+@Plugin(id = "chatplugin", name = "ChatPlugin", version = "1.0.0",
+ description = "A chat plugin for Altitude Minecraft Server",
+ authors = {"destro174", "teri"}
+ )
+public class ChatPlugin {
+
+ private static ChatPlugin plugin;
+ private final ProxyServer server;
+ private final Logger logger;
+ private final Path dataDirectory;
+ private LuckPerms luckPerms;
+
+ @Inject
+ public ChatPlugin(ProxyServer proxyServer, Logger proxylogger, @DataDirectory Path proxydataDirectory) {
+ plugin = this;
+ server = proxyServer;
+ logger = proxylogger;
+ dataDirectory = proxydataDirectory;
+ }
+
+ @Subscribe
+ public void onProxyInitialization(ProxyInitializeEvent event) {
+ Config.init(getDataDirectory());
+ loadCommands();
+ server.getEventManager().register(this, new ChatListener());
+ //statusTask = new StatusTask();
+ //statusTask.init();
+ }
+
+ public File getDataDirectory() {
+ return dataDirectory.toFile();
+ }
+
+ public static ChatPlugin getInstance() {
+ return plugin;
+ }
+
+ public LuckPerms getLuckPerms() {
+ if(luckPerms == null)
+ luckPerms = LuckPermsProvider.get();
+ return luckPerms;
+ }
+
+ public Logger getLogger() {
+ return logger;
+ }
+
+ public ProxyServer getProxy() {
+ return server;
+ }
+
+ public void loadCommands() {
+ // all commands go here
+ }
+}
diff --git a/src/main/java/com/alttd/chat/api/MessageEvent.java b/src/main/java/com/alttd/chat/api/MessageEvent.java
new file mode 100644
index 0000000..d5e161c
--- /dev/null
+++ b/src/main/java/com/alttd/chat/api/MessageEvent.java
@@ -0,0 +1,29 @@
+package com.alttd.chat.api;
+
+
+import com.velocitypowered.api.command.CommandSource;
+import com.velocitypowered.api.proxy.Player;
+
+public class MessageEvent {
+ private final CommandSource sender;
+ private final Player recipient;
+ private final String message;
+
+ public MessageEvent(CommandSource sender, Player recipient, String message) {
+ this.sender = sender;
+ this.recipient = recipient;
+ this.message = message;
+ }
+
+ public CommandSource getSender() {
+ return sender;
+ }
+
+ public Player getRecipient() {
+ return recipient;
+ }
+
+ public String getMessage() {
+ return message;
+ }
+}
diff --git a/src/main/java/com/alttd/chat/commands/Message.java b/src/main/java/com/alttd/chat/commands/Message.java
new file mode 100644
index 0000000..8183dde
--- /dev/null
+++ b/src/main/java/com/alttd/chat/commands/Message.java
@@ -0,0 +1,68 @@
+package com.alttd.chat.commands;
+
+import com.alttd.chat.api.MessageEvent;
+import com.alttd.chat.config.Config;
+import com.mojang.brigadier.arguments.StringArgumentType;
+import com.mojang.brigadier.builder.LiteralArgumentBuilder;
+import com.mojang.brigadier.builder.RequiredArgumentBuilder;
+import com.mojang.brigadier.tree.LiteralCommandNode;
+import com.velocitypowered.api.command.BrigadierCommand;
+import com.velocitypowered.api.command.CommandMeta;
+import com.velocitypowered.api.command.CommandSource;
+import com.velocitypowered.api.event.Subscribe;
+import com.velocitypowered.api.proxy.Player;
+import com.velocitypowered.api.proxy.ProxyServer;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Optional;
+
+public class Message {
+
+ public Message(ProxyServer proxyServer) {
+ LiteralCommandNode command = LiteralArgumentBuilder
+ .literal("message")
+ .requires(ctx -> ctx.hasPermission("command.proxy.message"))// TODO permission system? load permissions from config?
+ .then(RequiredArgumentBuilder
+ .argument("player", StringArgumentType.word())
+ .suggests((context, builder) -> {
+ for (Player player : proxyServer.getAllPlayers()) {
+ builder.suggest(player.getGameProfile().getName());
+ }
+ return builder.buildFuture();
+ })
+ .then(RequiredArgumentBuilder
+ .argument("message", StringArgumentType.greedyString())
+ .executes(context -> {
+ Optional playerOptional = proxyServer.getPlayer(context.getArgument("player", String.class));
+
+ if (playerOptional.isPresent()) {
+ Player receiver = playerOptional.get();
+ proxyServer.getEventManager().fire(new MessageEvent(context.getSource(), receiver, context.getArgument("message", String.class)));
+
+ return 1;
+ }
+ return 0;
+ })
+ )
+ .executes(context -> 0)
+ )
+ .executes(context -> 0)
+ .build();
+
+ BrigadierCommand brigadierCommand = new BrigadierCommand(command);
+
+ CommandMeta.Builder metaBuilder = proxyServer.getCommandManager().metaBuilder(brigadierCommand);
+
+ for (String alias : Config.MESSAGECOMMANDALIASES) {
+ metaBuilder.aliases(alias);
+ }
+
+ CommandMeta meta = metaBuilder.build();
+
+ proxyServer.getCommandManager().register(meta, brigadierCommand);
+ }
+
+}
diff --git a/src/main/java/com/alttd/chat/config/Config.java b/src/main/java/com/alttd/chat/config/Config.java
new file mode 100644
index 0000000..5fc4069
--- /dev/null
+++ b/src/main/java/com/alttd/chat/config/Config.java
@@ -0,0 +1,156 @@
+package com.alttd.chat.config;
+
+import com.google.common.base.Throwables;
+import com.google.common.reflect.TypeToken;
+import ninja.leaping.configurate.ConfigurationNode;
+import ninja.leaping.configurate.objectmapping.ObjectMappingException;
+import ninja.leaping.configurate.yaml.YAMLConfigurationLoader;
+import org.yaml.snakeyaml.DumperOptions;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public final class Config {
+ private static final Pattern PATH_PATTERN = Pattern.compile("\\.");
+ private static final String HEADER = "";
+
+ private static File CONFIG_FILE;
+ public static ConfigurationNode config;
+ public static YAMLConfigurationLoader configLoader;
+
+ static int version;
+ static boolean verbose;
+
+ public static void init(File path) {
+ CONFIG_FILE = new File(path, "config.yml");;
+ configLoader = YAMLConfigurationLoader.builder()
+ .setFile(CONFIG_FILE)
+ .setFlowStyle(DumperOptions.FlowStyle.BLOCK)
+ .build();
+ if (!CONFIG_FILE.getParentFile().exists()) {
+ CONFIG_FILE.getParentFile().mkdirs();
+ }
+ if (!CONFIG_FILE.exists()) {
+ try {
+ CONFIG_FILE.createNewFile();
+ } catch (IOException error) {
+ error.printStackTrace();
+ }
+ }
+
+ try {
+ config = configLoader.load();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+ configLoader.getDefaultOptions().setHeader(HEADER);
+ configLoader.getDefaultOptions().withShouldCopyDefaults(true);
+
+ verbose = getBoolean("verbose", true);
+ version = getInt("config-version", 1);
+
+ readConfig(Config.class, null);
+ try {
+ configLoader.save(config);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void readConfig(Class> clazz, Object instance) {
+ for (Method method : clazz.getDeclaredMethods()) {
+ if (Modifier.isPrivate(method.getModifiers())) {
+ if (method.getParameterTypes().length == 0 && method.getReturnType() == Void.TYPE) {
+ try {
+ method.setAccessible(true);
+ method.invoke(instance);
+ } catch (InvocationTargetException ex) {
+ throw Throwables.propagate(ex.getCause());
+ } catch (Exception ex) {
+ }
+ }
+ }
+ }
+ try {
+ configLoader.save(config);
+ } catch (IOException ex) {
+ }
+ }
+
+ public static boolean saveConfig() {
+ try {
+ configLoader.save(config);
+ return true;
+ } catch (IOException ex) {
+ return false;
+ }
+ }
+
+ private static Object[] splitPath(String key) {
+ return PATH_PATTERN.split(key);
+ }
+
+ private static void set(String path, Object def) {
+ if(config.getNode(splitPath(path)).isVirtual())
+ config.getNode(splitPath(path)).setValue(def);
+ }
+
+ private static boolean getBoolean(String path, boolean def) {
+ set(path, def);
+ return config.getNode(splitPath(path)).getBoolean(def);
+ }
+
+ private static double getDouble(String path, double def) {
+ set(path, def);
+ return config.getNode(splitPath(path)).getDouble(def);
+ }
+
+ private static int getInt(String path, int def) {
+ set(path, def);
+ return config.getNode(splitPath(path)).getInt(def);
+ }
+
+ private static String getString(String path, String def) {
+ set(path, def);
+ return config.getNode(splitPath(path)).getString(def);
+ }
+
+ private static Long getLong(String path, Long def) {
+ set(path, def);
+ return config.getNode(splitPath(path)).getLong(def);
+ }
+
+ private static List getList(String path, T def) {
+ try {
+ set(path, def);
+ return config.getNode(splitPath(path)).getList(TypeToken.of(String.class));
+ } catch(ObjectMappingException ex) {
+ }
+ return new ArrayList<>();
+ }
+
+ /** ONLY EDIT ANYTHING BELOW THIS LINE **/
+
+ public static List MESSAGECOMMANDALIASES = new ArrayList<>();
+ public static String MESSAGESENDER = " '>(Me -> ) ";
+ public static String MESSAGERECIEVER = " '>( on -> Me) ";
+ private static void messageCommand() {
+ MESSAGECOMMANDALIASES.clear();
+ getList("commands.message.aliases", new ArrayList(){{
+ add("msg");
+ add("whisper");
+ add("tell");
+ }}).forEach(key -> {
+ MESSAGECOMMANDALIASES.add(key.toString());
+ });
+ MESSAGESENDER = getString("commands.message.sender-message", MESSAGESENDER);
+ MESSAGERECIEVER = getString("commands.message.reciever-message", MESSAGERECIEVER);
+ }
+}
diff --git a/src/main/java/com/alttd/chat/config/ServerConfig.java b/src/main/java/com/alttd/chat/config/ServerConfig.java
new file mode 100644
index 0000000..eaf8a6e
--- /dev/null
+++ b/src/main/java/com/alttd/chat/config/ServerConfig.java
@@ -0,0 +1,60 @@
+package com.alttd.chat.config;
+
+import java.util.regex.Pattern;
+
+public final class ServerConfig {
+ private static final Pattern PATH_PATTERN = Pattern.compile("\\.");
+
+ private final String serverName;
+ private final String configPath;
+ private final String defaultPath;
+
+ public ServerConfig(String serverName) {
+ this.serverName = serverName;
+ this.configPath = "server-settings." + this.serverName + ".";
+ this.defaultPath = "server-settings.default.";
+ init();
+ }
+
+ public void init() {
+ Config.readConfig(ServerConfig.class, this);
+ Config.saveConfig();
+ }
+
+ public static Object[] splitPath(String key) {
+ return PATH_PATTERN.split(key);
+ }
+
+ private static void set(String path, Object def) {
+ if(Config.config.getNode(splitPath(path)).isVirtual()) {
+ Config.config.getNode(splitPath(path)).setValue(def);
+ }
+ }
+
+ private boolean getBoolean(String path, boolean def) {
+ set(defaultPath +path, def);
+ return Config.config.getNode(splitPath(configPath+path)).getBoolean(
+ Config.config.getNode(splitPath(defaultPath +path)).getBoolean(def));
+ }
+
+ private double getDouble(String path, double def) {
+ set(defaultPath +path, def);
+ return Config.config.getNode(splitPath(configPath+path)).getDouble(
+ Config.config.getNode(splitPath(defaultPath +path)).getDouble(def));
+ }
+
+ private int getInt(String path, int def) {
+ set(defaultPath +path, def);
+ return Config.config.getNode(splitPath(configPath+path)).getInt(
+ Config.config.getNode(splitPath(defaultPath +path)).getInt(def));
+ }
+
+ private String getString(String path, String def) {
+ set(defaultPath +path, def);
+ return Config.config.getNode(splitPath(configPath+path)).getString(
+ Config.config.getNode(splitPath(defaultPath +path)).getString(def));
+ }
+
+ /** DO NOT EDIT ANYTHING ABOVE **/
+
+}
diff --git a/src/main/java/com/alttd/chat/listeners/ChatListener.java b/src/main/java/com/alttd/chat/listeners/ChatListener.java
new file mode 100644
index 0000000..2c32d66
--- /dev/null
+++ b/src/main/java/com/alttd/chat/listeners/ChatListener.java
@@ -0,0 +1,43 @@
+package com.alttd.chat.listeners;
+
+import com.alttd.chat.api.MessageEvent;
+import com.alttd.chat.config.Config;
+import com.velocitypowered.api.event.Subscribe;
+import com.velocitypowered.api.proxy.Player;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.minimessage.MiniMessage;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class ChatListener {
+
+ @Subscribe
+ public void onMessage(MessageEvent event) {
+ String senderName;
+ String receiverName;
+
+ if (event.getSender() instanceof Player) {
+ Player sender = (Player) event.getSender();
+ senderName = sender.getUsername();
+ } else {
+ senderName = "UNKNOWN";
+ }
+ receiverName = event.getRecipient().getUsername();
+
+ MiniMessage miniMessage = MiniMessage.get();
+
+ Map map = new HashMap<>();
+
+ map.put("sender", senderName);
+ map.put("receiver", receiverName);
+ map.put("message", event.getMessage());
+ map.put("server", event.getRecipient().getCurrentServer().isPresent() ? event.getRecipient().getCurrentServer().get().getServerInfo().getName() : "Altitude");
+
+ Component senderMessage = miniMessage.parse(Config.MESSAGESENDER, map);
+ Component receiverMessage = miniMessage.parse(Config.MESSAGERECIEVER, map);
+
+ event.getSender().sendMessage(senderMessage);
+ event.getRecipient().sendMessage(receiverMessage);
+ }
+}