diff --git a/.gitignore b/.gitignore
index 2d513a0..9a2c893 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
/.idea/
/target/
+/*.iml
+/dependency-reduced-pom.xml
diff --git a/pom.xml b/pom.xml
index fe9f9f1..c4991fe 100644
--- a/pom.xml
+++ b/pom.xml
@@ -52,6 +52,20 @@
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.2.4
+
+
+ package
+
+ shade
+
+
+
+
@@ -60,9 +74,20 @@
spigot-repo
https://hub.spigotmc.org/nexus/content/repositories/snapshots/
+
+
+ papermc
+ https://repo.papermc.io/repository/maven-public/
+
+
+ com.velocitypowered
+ velocity-api
+ 3.0.1
+ provided
+
org.spigotmc
spigot-api
@@ -76,6 +101,16 @@
provided
remapped-mojang
+
+ com.zaxxer
+ HikariCP
+ 5.0.1
+ compile
+
+
+ mysql
+ mysql-connector-java
+ 8.0.29
+
-
\ No newline at end of file
diff --git a/src/main/java/com/grubnest/game/core/GrubnestCorePlugin.java b/src/main/java/com/grubnest/game/core/GrubnestCorePlugin.java
deleted file mode 100644
index f16b6bd..0000000
--- a/src/main/java/com/grubnest/game/core/GrubnestCorePlugin.java
+++ /dev/null
@@ -1,22 +0,0 @@
-package com.grubnest.game.core;
-
-import org.bukkit.plugin.java.JavaPlugin;
-
-public class GrubnestCorePlugin extends JavaPlugin {
-
- /**
- * Runs when plugin is enabled
- */
- @Override
- public void onEnable() {
-
- }
-
- /**
- * Runs when plugin is disabled
- */
- @Override
- public void onDisable() {
-
- }
-}
diff --git a/src/main/java/com/grubnest/game/core/PluginMessage.java b/src/main/java/com/grubnest/game/core/PluginMessage.java
new file mode 100644
index 0000000..e1f76fa
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/PluginMessage.java
@@ -0,0 +1,313 @@
+package com.grubnest.game.core;
+
+import com.google.common.io.ByteArrayDataInput;
+import com.google.common.io.ByteArrayDataOutput;
+import com.google.common.io.ByteStreams;
+import com.grubnest.game.core.paper.GrubnestCorePlugin;
+import org.bukkit.ChatColor;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.messaging.PluginMessageListener;
+
+import java.io.*;
+
+/**
+ * @author tamilpp25
+ * @created 15/05/2022
+ */
+public class PluginMessage implements PluginMessageListener {
+
+ /**
+ * Plugin message receiver
+ * triggers when there is a response from a subchannel
+ * //todo fix forward method later
+ * @param channel Subchannel as given in spigot docs
+ * @param player Player that send plugin message to server
+ * @param message Message
+ */
+ @Override
+ public void onPluginMessageReceived(String channel, Player player, byte[] message) {
+ if (!channel.equals("BungeeCord")) {
+ return;
+ }
+ ByteArrayDataInput in = ByteStreams.newDataInput(message);
+ String subchannel = in.readUTF();
+ if (subchannel.equals("PlayerCount")) {
+ String server = in.readUTF(); // Name of server, as given in the arguments
+ int playercount = in.readInt(); // list of players
+ } else if(subchannel.equals("PlayerList")){
+ String server = in.readUTF(); // The name of the server you got the player list of, as given in args.
+ String[] playerList = in.readUTF().split(", "); // gets all players in the server or ALL for whole proxy
+ } else if(subchannel.equals("GetServers")){
+ String[] serverList = in.readUTF().split(", "); // Gets the list of servers defined
+ } else if(subchannel.equals("GetServer")){
+ String servername = in.readUTF(); // get the current server name
+ }else if(subchannel.equals("UUID")){
+ String uuid = in.readUTF(); // get the uuid of sent player
+ }else if(subchannel.equals("UUIDOther")){
+ String playerName = in.readUTF(); // player name
+ String uuid = in.readUTF(); // player uuid
+ } else if(subchannel.equals("ServerIP")){
+ String serverName = in.readUTF();
+ String ip = in.readUTF();
+ int port = in.readUnsignedShort();
+ }else if(subchannel.equals("Custom sub channel")){ // todo change later the name for custom sub channel
+ short len = in.readShort();
+ byte[] msgbytes = new byte[len];
+ in.readFully(msgbytes);
+
+ DataInputStream msgin = new DataInputStream(new ByteArrayInputStream(msgbytes));
+ try {
+ String somedata = msgin.readUTF(); // Read the data in the same way you wrote it
+ short somenumber = msgin.readShort();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ /**
+ * Connects a player to said subserver.
+ *
+ * @receiver player to be teleported
+ *
+ * @param player Player to send plugin message to
+ * @param server name of server to connect to, as defined in BungeeCord config.yml
+ */
+ public static void connect(Player player, String server){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("Connect");
+ output.writeUTF(server);
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ player.sendMessage(ChatColor.DARK_GRAY + "sending you to " + server + "...");
+ }
+
+ /**
+ * Connect a named player to said subserver
+ *
+ * @receiver any player
+ *
+ * @param player Player to send plugin message to
+ * @param named_player name of the player to teleport
+ * @param server name of server to connect to, as defined in BungeeCord config.yml
+ */
+ public static void connectOther(Player player, String named_player, String server){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("ConnectOther");
+ output.writeUTF(named_player);
+ output.writeUTF(server);
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Get the amount of players on a certain server, or on ALL the servers.
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ * @param server the name of the server to get the player count of, or ALL to get the global player count
+ */
+ public static void getPlayerCount(Player player, String server){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("PlayerCount");
+ output.writeUTF(server);
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Get a list of players connected on a certain server, or on ALL of the servers.
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ * @param server the name of the server to get the list of connected players, or ALL for global online player list
+ */
+ public static void getPlayerList(Player player, String server){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("PlayerList");
+ output.writeUTF(server);
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Get a list of server name strings, as defined in BungeeCord's config.yml
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ */
+ public static void getServers(Player player){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("GetServers");
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Send a message (as in, a chat message) to the specified player.
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ * @param proxyPlayer the name of the player to send the chat message, or ALL to send to all players
+ * @param message the message to send to the player , supports color codes with "&" as translator
+ */
+ public static void sendMessage(Player player,String proxyPlayer,String message){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("Message");
+ output.writeUTF(proxyPlayer);
+ output.writeUTF(ChatColor.translateAlternateColorCodes('&',message));
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Send a raw message (as in, a chat message) to the specified player. The advantage of this method over Message
+ * is that you can include click events and hover events.
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ * @param proxyPlayer the name of the player to send the chat message, or ALL to send to all players
+ * @param message the message to send to the player
+ */
+ public static void sendRawMessage(Player player,String proxyPlayer,String message){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("MessageRaw");
+ output.writeUTF(proxyPlayer);
+ output.writeUTF(message);
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Get this server's name, as defined in BungeeCord's config.yml
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ */
+ public static void getServer(Player player){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("GetServer");
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Request the UUID of this player
+ *
+ * @receiver The player whose UUID you requested
+ *
+ * @param player player
+ */
+ public static void getUUID(Player player){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("UUID");
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Request the UUID of any player connected to the BungeeCord proxy
+ *
+ * @receiver the sender
+ *
+ * @param player packet carrier and receiver
+ * @param oplayername the name of the player whose UUID you would like
+ */
+ public static void getUUIDOther(Player player,String oplayername){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("UUIDOther");
+ output.writeUTF(oplayername);
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Request the IP of any server on this proxy
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ * @param server the name of the server
+ */
+ public static void getServerIP(Player player,String server){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("ServerIP");
+ output.writeUTF(server);
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Kick any player on this proxy
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ * @param playerToKick player to be kicked
+ * @param reason reason for kick
+ */
+ public static void kickPlayer(Player player,String playerToKick,String reason){
+ ByteArrayDataOutput output = ByteStreams.newDataOutput();
+ output.writeUTF("KickPlayer");
+ output.writeUTF(playerToKick);
+ output.writeUTF(reason);
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", output.toByteArray());
+ }
+
+ /**
+ * Send a custom plugin message to said server. This is one of the most useful channels ever.
+ * Remember, the sending and receiving server(s) need to have a player online.
+ *
+ * @receiver any player
+ *
+ * @param player packet carrier
+ * @param server server to send to, ALL to send to every server (except the one sending the plugin message),
+ * or ONLINE to send to every server that's online (except the one sending the plugin message)
+ * @param subchannel Subchannel for plugin usage.
+ * @param data message to send //todo change stuff so can send anything
+ */
+ public static void forward(Player player,String server,String subchannel,String data){
+ ByteArrayDataOutput out = ByteStreams.newDataOutput();
+ out.writeUTF("Forward"); // So BungeeCord knows to forward it
+ out.writeUTF(server); // server to send to
+ out.writeUTF(subchannel); // The channel name to check if this your data
+
+ ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
+ DataOutputStream msgout = new DataOutputStream(msgbytes);
+ try {
+ //THESE ARE DATA WE WANT TO SEND (example) // remove later
+ msgout.writeUTF(data); // You can do anything you want with msgout
+ msgout.writeShort(123); // checking needed
+ } catch (IOException exception){
+ exception.printStackTrace();
+ }
+
+ out.writeShort(msgbytes.toByteArray().length);
+ out.write(msgbytes.toByteArray());
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", out.toByteArray());
+ }
+
+ /**
+ * Send a custom plugin message to specific player.
+ * @param player packet carrier
+ * @param playerToForwardTo Playername to send to.
+ * @param subchannel Subchannel for plugin usage.
+ * @param data message to send. //todo change stuff so can send anything
+ */
+ public static void forwardToPlayer(Player player,String playerToForwardTo,String subchannel,String data){
+ ByteArrayDataOutput out = ByteStreams.newDataOutput();
+ out.writeUTF("ForwardToPlayer"); // So BungeeCord knows to forward it
+ out.writeUTF(playerToForwardTo); // server to send to
+ out.writeUTF(subchannel); // The channel name to check if this your data
+
+ ByteArrayOutputStream msgbytes = new ByteArrayOutputStream();
+ DataOutputStream msgout = new DataOutputStream(msgbytes);
+ try {
+ //THESE ARE DATA WE WANT TO SEND (example) //remove later
+ msgout.writeUTF(data); // You can do anything you want with msgout
+ msgout.writeShort(123); // checking needed
+ } catch (IOException exception){
+ exception.printStackTrace();
+ }
+
+ out.writeShort(msgbytes.toByteArray().length);
+ out.write(msgbytes.toByteArray());
+ player.sendPluginMessage(GrubnestCorePlugin.getInstance(), "BungeeCord", out.toByteArray());
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/grubnest/game/core/bridge/entities/GrubnestPlayer.java b/src/main/java/com/grubnest/game/core/bridge/entities/GrubnestPlayer.java
new file mode 100644
index 0000000..8c19c5c
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/bridge/entities/GrubnestPlayer.java
@@ -0,0 +1,7 @@
+package com.grubnest.game.core.bridge.entities;
+
+public interface GrubnestPlayer {
+
+ void updateUsername();
+
+}
diff --git a/src/main/java/com/grubnest/game/core/databasehandler/ConnectionPoolManager.java b/src/main/java/com/grubnest/game/core/databasehandler/ConnectionPoolManager.java
new file mode 100644
index 0000000..befe4f1
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/databasehandler/ConnectionPoolManager.java
@@ -0,0 +1,108 @@
+package com.grubnest.game.core.databasehandler;
+
+import com.grubnest.game.core.databasehandler.utils.Deactivated;
+import com.grubnest.game.core.databasehandler.utils.Disabler;
+import com.zaxxer.hikari.HikariConfig;
+import com.zaxxer.hikari.HikariDataSource;
+
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * Handles connection from mysql and uses HikariCP
+ *
+ * @author tamilpp25
+ * @version 1.0 at 15-5-2022
+ */
+public class ConnectionPoolManager implements Deactivated {
+
+ private final MySQLData data;
+ private HikariDataSource dataSource;
+
+ /**
+ * Construct mysql HikariCP
+ *
+ * @param data MysqlDATA
+ */
+ public ConnectionPoolManager(MySQLData data) {
+ this.data = data;
+ setupPool();
+ Disabler.getInstance().registerDeactivated(this);
+ }
+
+ /**
+ * Setup mysql connection Pool with HikariCP to get multiple connections.
+ */
+ private void setupPool() {
+ HikariConfig config = new HikariConfig();
+ config.setJdbcUrl(
+ "jdbc:mysql://" +
+ data.HOST +
+ ":" +
+ data.PORT +
+ "/" +
+ data.DATABASE
+ );
+
+ config.setDriverClassName("com.mysql.cj.jdbc.Driver");
+ config.setUsername(data.USERNAME);
+ config.setPassword(data.PASSWORD);
+ config.setMinimumIdle(data.minimumConnections);
+ config.setMaximumPoolSize(data.maximumConnections);
+ config.setConnectionTimeout(data.connectionTimeout);
+ config.setConnectionTestQuery("SELECT 1");
+ dataSource = new HikariDataSource(config);
+ }
+
+ /**
+ * Get MySQL Pool connection
+ *
+ * @return Sql Connection
+ * @throws SQLException if some error..
+ */
+ public Connection getConnection() throws SQLException {
+ return dataSource.getConnection();
+ }
+
+ /**
+ * Temp close method can close using try-with statement too
+ * Recommending using try-with statement to close automatically!
+ *
+ * @param conn Connection
+ * @param ps PreparedStatement
+ * @param res ResultSet
+ */
+ public void close(Connection conn, PreparedStatement ps, ResultSet res) {
+ if (conn != null) try {
+ conn.close();
+ } catch (SQLException ignored) {
+ }
+ if (ps != null) try {
+ ps.close();
+ } catch (SQLException ignored) {
+ }
+ if (res != null) try {
+ res.close();
+ } catch (SQLException ignored) {
+ }
+ }
+
+ /**
+ * Close pool when everything done...
+ */
+ public void closePool() {
+ if (dataSource != null && !dataSource.isClosed()) {
+ dataSource.close();
+ }
+ }
+
+ /**
+ * Auto disable classes on disable if multiple instance are there too
+ */
+ @Override
+ public void onDisable() {
+ closePool();
+ }
+}
diff --git a/src/main/java/com/grubnest/game/core/databasehandler/MySQL.java b/src/main/java/com/grubnest/game/core/databasehandler/MySQL.java
new file mode 100644
index 0000000..068df00
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/databasehandler/MySQL.java
@@ -0,0 +1,73 @@
+package com.grubnest.game.core.databasehandler;
+
+import com.velocitypowered.api.proxy.Player;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+/**
+ * Main class for handling mysql data
+ * make your methods for getting / setting here in async!
+ * new MySQL class can be initialized outside main class too!
+ *
+ * Recommend using getMySQL method from main class as it properly does the work and closes connection on disable!
+ * make a new instance of this if you really know what you are doing!
+ *
+ * @author tamilpp25
+ * @version 1.0 at 15-5-2022
+ */
+public class MySQL extends ConnectionPoolManager {
+ public MySQL(MySQLData data) {
+ super(data);
+ }
+
+ /**
+ * Close pool on plugin Disable
+ */
+ public void onDisable() {
+ closePool();
+ }
+
+ /**
+ * Creates any tables required for the database. Runs at proxy server initialization
+ */
+ public void createTables() {
+ try {
+ PreparedStatement statement = getConnection().prepareStatement("""
+ CREATE TABLE IF NOT EXISTS `player` (
+ uuid varchar(36) PRIMARY KEY,
+ username varchar(16)
+ )
+ """);
+ statement.executeUpdate();
+ statement.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+ /**
+ * Updates a players username stored in the database
+ *
+ * @param player the player to store
+ */
+ public void updatePlayerUsername(Player player) {
+ try {
+ PreparedStatement statement = getConnection().prepareStatement("""
+ INSERT INTO player
+ (uuid, username)
+ VALUES
+ (?, ?)
+ ON DUPLICATE KEY UPDATE
+ username = ?;
+ """);
+ statement.setString(1, player.getUniqueId().toString());
+ statement.setString(2, player.getUsername());
+ statement.setString(3, player.getUsername());
+ statement.executeUpdate();
+ statement.close();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/main/java/com/grubnest/game/core/databasehandler/MySQLData.java b/src/main/java/com/grubnest/game/core/databasehandler/MySQLData.java
new file mode 100644
index 0000000..beadfb5
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/databasehandler/MySQLData.java
@@ -0,0 +1,59 @@
+package com.grubnest.game.core.databasehandler;
+
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * MysqlData object to store credentials etc
+ *
+ * @author tamilpp25, Theeef
+ * @version 1.0 at 5/26/2022
+ */
+public class MySQLData {
+ public final String HOST;
+ public final String USERNAME;
+ public final String PASSWORD;
+ public final int PORT;
+ public final String DATABASE;
+
+ public final int minimumConnections;
+ public final int maximumConnections;
+ public final long connectionTimeout;
+
+ public MySQLData(String host, String username, String password, int port, String database, int minimumConnections, int maximumConnections, long connectionTimeout) {
+ HOST = host;
+ USERNAME = username;
+ PASSWORD = password;
+ PORT = port;
+ DATABASE = database;
+ this.minimumConnections = minimumConnections;
+ this.maximumConnections = maximumConnections;
+ this.connectionTimeout = connectionTimeout;
+ }
+
+ /**
+ * Initialize data from config.yml
+ *
+ * @return MySQLData
+ */
+ public static MySQLData dataInitializer() {
+ Yaml yaml = new Yaml();
+ InputStream inputStream = MySQLData.class.getClassLoader().getResourceAsStream("config.yml");
+ Map config;
+ config = (Map) ((Map) yaml.load(inputStream)).get("Database");
+
+ String host = (String) config.get("hostname");
+ int port = (int) config.get("port");
+ String database = (String) config.get("database");
+ String username = (String) config.get("username");
+ String password = (String) config.get("password");
+
+ int minimumConnections = (int) config.get("minimumConnections");
+ int maximumConnections = (int) config.get("maximumConnections");
+ long connectionTimeout = (long) (int) config.get("connectionTimeout");
+
+ return new MySQLData(host, username, password, port, database, minimumConnections, maximumConnections, connectionTimeout);
+ }
+}
diff --git a/src/main/java/com/grubnest/game/core/databasehandler/utils/Deactivated.java b/src/main/java/com/grubnest/game/core/databasehandler/utils/Deactivated.java
new file mode 100644
index 0000000..332901c
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/databasehandler/utils/Deactivated.java
@@ -0,0 +1,12 @@
+package com.grubnest.game.core.databasehandler.utils;
+
+/**
+ * Utility class to prevent Memory leak.
+ * @author tamilpp25
+ * @version 1.0 at 15-5-2022
+ */
+public interface Deactivated {
+
+ void onDisable();
+
+}
diff --git a/src/main/java/com/grubnest/game/core/databasehandler/utils/Disabler.java b/src/main/java/com/grubnest/game/core/databasehandler/utils/Disabler.java
new file mode 100644
index 0000000..e248f40
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/databasehandler/utils/Disabler.java
@@ -0,0 +1,44 @@
+package com.grubnest.game.core.databasehandler.utils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Disabler instance to auto disable any used instance of sql
+ * @author tamilpp25
+ * @version 1.0 at 15-5-2022
+ */
+public class Disabler {
+ private static Disabler instance = null;
+ private final List toDisable = new ArrayList<>();
+
+ public static Disabler getInstance() {
+ if (instance != null) return instance;
+ return instance = new Disabler();
+ }
+
+ /**
+ * close all active mysql connections
+ */
+ public void disableAll() {
+ for (Deactivated toDeactivated : toDisable)
+ toDeactivated.onDisable();
+ }
+
+ /**
+ * Disable specific class with mysql connection
+ * @param sqlinstance SQL instance
+ */
+ public void disable(Deactivated sqlinstance) {
+ sqlinstance.onDisable();
+ }
+
+ /**
+ * Register a class as mysql connection pool
+ * @param pDeactivated Class to be registered
+ */
+ public void registerDeactivated(Deactivated pDeactivated) {
+ toDisable.add(pDeactivated);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/grubnest/game/core/paper/GrubnestCorePlugin.java b/src/main/java/com/grubnest/game/core/paper/GrubnestCorePlugin.java
new file mode 100644
index 0000000..de7eaa8
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/paper/GrubnestCorePlugin.java
@@ -0,0 +1,69 @@
+package com.grubnest.game.core.paper;
+
+import com.grubnest.game.core.PluginMessage;
+import com.grubnest.game.core.databasehandler.MySQL;
+import com.grubnest.game.core.databasehandler.MySQLData;
+import com.grubnest.game.core.databasehandler.utils.Disabler;
+import org.bukkit.ChatColor;
+import org.bukkit.plugin.java.JavaPlugin;
+
+public class GrubnestCorePlugin extends JavaPlugin {
+
+ private MySQL sql;
+ private static GrubnestCorePlugin instance;
+
+ /**
+ * Runs when plugin is enabled
+ */
+ @Override
+ public void onEnable() {
+ instance = this;
+
+ //Register Plugin messaging channels on enable
+ this.getServer().getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
+ this.getServer().getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new PluginMessage());
+
+ getServer().getConsoleSender().sendMessage(ChatColor.AQUA + "GrubnestCore is Enabled");
+
+ loadConfig();
+ this.sql = new MySQL(MySQLData.dataInitializer());
+ }
+
+ /**
+ * Loads the config and enables copying defaults
+ */
+ public void loadConfig() {
+ getConfig().options().copyDefaults(true);
+ saveConfig();
+ }
+
+ /**
+ * Runs when plugin is disabled
+ */
+ @Override
+ public void onDisable() {
+ Disabler.getInstance().disableAll();
+ //Unregister channels on disable
+ this.getServer().getMessenger().unregisterOutgoingPluginChannel(this);
+ this.getServer().getMessenger().unregisterIncomingPluginChannel(this);
+ }
+
+ /**
+ * Get SQL Object
+ *
+ * @return SQL object
+ */
+ public MySQL getMySQL() {
+ return sql;
+ }
+
+ /**
+ * Get Plugin Instance
+ *
+ * @return Plugin Instance
+ */
+ public static GrubnestCorePlugin getInstance() {
+ return instance;
+ }
+
+}
diff --git a/src/main/java/com/grubnest/game/core/velocity/VelocityPlugin.java b/src/main/java/com/grubnest/game/core/velocity/VelocityPlugin.java
new file mode 100644
index 0000000..c7dd5a0
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/velocity/VelocityPlugin.java
@@ -0,0 +1,89 @@
+package com.grubnest.game.core.velocity;
+
+import com.google.inject.Inject;
+import com.grubnest.game.core.databasehandler.MySQL;
+import com.grubnest.game.core.databasehandler.MySQLData;
+import com.grubnest.game.core.velocity.events.CoreEventListener;
+import com.velocitypowered.api.event.Subscribe;
+import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
+import com.velocitypowered.api.plugin.Plugin;
+import com.velocitypowered.api.proxy.ProxyServer;
+import net.kyori.adventure.text.Component;
+import org.slf4j.Logger;
+import org.yaml.snakeyaml.Yaml;
+
+import java.io.InputStream;
+import java.util.Map;
+
+/**
+ * The VelocityPlugin class is an implementation of the Velocity API.
+ * It provides communication to and from the Velocity Proxy server
+ * running on the Grubnest network
+ *
+ * @author Theeef
+ * @version 1.2 at 5/26/2022
+ */
+@Plugin(id = "grubnestcore", name = "Grubnest Core Plugin", version = "0.1.0-SNAPSHOT",
+ url = "htts://grubnest.com", description = "Grubnest Core running on Velocity", authors = {"Theeef"})
+public class VelocityPlugin {
+
+ private final ProxyServer server;
+ private final MySQL sql;
+ private static VelocityPlugin instance;
+
+
+ /**
+ * Creates an instance of the Velocity Plugin and injects it
+ *
+ * @param server The velocity proxy server
+ * @param logger The proxy server's logger
+ */
+ @Inject
+ public VelocityPlugin(ProxyServer server, Logger logger) {
+ this.server = server;
+
+ this.server.sendMessage(Component.text("GrubnestCore is enabled on Velocity!"));
+ this.sql = new MySQL(MySQLData.dataInitializer());
+
+ instance = this;
+ }
+
+ /**
+ * Runs when the Proxy server initializes
+ *
+ * @param event event used in callback
+ */
+ @Subscribe
+ public void onInitialize(ProxyInitializeEvent event) {
+ this.server.getEventManager().register(this, new CoreEventListener());
+
+ getMySQL().createTables();
+ }
+
+ /**
+ * Get SQL Object
+ *
+ * @return SQL object
+ */
+ public MySQL getMySQL() {
+ return this.sql;
+ }
+
+ /**
+ * Get the ProxyServer object
+ *
+ * @return ProxyServer object
+ */
+ public ProxyServer getServer() {
+ return this.server;
+ }
+
+ /**
+ * Get Plugin Instance
+ *
+ * @return Plugin Instance
+ */
+ public static VelocityPlugin getInstance() {
+ return instance;
+ }
+}
diff --git a/src/main/java/com/grubnest/game/core/velocity/entities/VPlayer.java b/src/main/java/com/grubnest/game/core/velocity/entities/VPlayer.java
new file mode 100644
index 0000000..0371918
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/velocity/entities/VPlayer.java
@@ -0,0 +1,33 @@
+package com.grubnest.game.core.velocity.entities;
+
+import com.grubnest.game.core.bridge.entities.GrubnestPlayer;
+import com.grubnest.game.core.velocity.VelocityPlugin;
+import com.velocitypowered.api.proxy.Player;
+
+/**
+ * Represents a custom player entity on the Velocity server
+ *
+ * @author Theeef
+ * @version 1.0 at 5/26/2022
+ */
+public class VPlayer implements GrubnestPlayer {
+
+ private Player player;
+
+ /**
+ * Creates a custom player instance for Velocity
+ *
+ * @param player the player this represents
+ */
+ public VPlayer(Player player) {
+ this.player = player;
+ }
+
+ /**
+ * Updates the cached username of this player in the database
+ */
+ public void updateUsername() {
+ VelocityPlugin.getInstance().getMySQL().updatePlayerUsername(this.player);
+ }
+
+}
diff --git a/src/main/java/com/grubnest/game/core/velocity/events/CoreEventListener.java b/src/main/java/com/grubnest/game/core/velocity/events/CoreEventListener.java
new file mode 100644
index 0000000..a82996a
--- /dev/null
+++ b/src/main/java/com/grubnest/game/core/velocity/events/CoreEventListener.java
@@ -0,0 +1,28 @@
+package com.grubnest.game.core.velocity.events;
+
+import com.grubnest.game.core.velocity.entities.VPlayer;
+import com.velocitypowered.api.event.Subscribe;
+import com.velocitypowered.api.event.player.ServerConnectedEvent;
+
+/**
+ * Listens for core events, like Server Connection for Velocity
+ *
+ *
+ * @author Theeef
+ * @version 1.0 at 5/23/2022
+ */
+public class CoreEventListener {
+
+ /**
+ * Logs basic user data to the server database when a user connects
+ * to a server on our network
+ *
+ * @param event The connection event that occurs
+ */
+ @Subscribe
+ public void onServerConnect(ServerConnectedEvent event) {
+ VPlayer player = new VPlayer(event.getPlayer());
+ player.updateUsername();
+ }
+
+}
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
new file mode 100644
index 0000000..866e8db
--- /dev/null
+++ b/src/main/resources/config.yml
@@ -0,0 +1,10 @@
+# DEFAULT VALUES FOR MYSQL DATABASE update later!!
+Database:
+ hostname: grubnest.com
+ port: 3306
+ database: s4_grubnest
+ username: u4_xb6o263UWu
+ password: Sf^R4vzWq6nKl!av!u+JTo81
+ minimumConnections: 5
+ maximumConnections: 10
+ connectionTimeout: 5000
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 2cb97c0..ac3f33d 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -1,6 +1,7 @@
name: GrubnestCore
-main: com.grubnest.game.core.GrubnestCorePlugin
+main: com.grubnest.game.core.paper.GrubnestCorePlugin
version: 1.0
authors:
- Theeef
-api-version: 1.13
\ No newline at end of file
+ - tamilpp25
+api-version: 1.18
\ No newline at end of file