diff --git a/README.md b/README.md
index 913dc72..b6ba100 100644
--- a/README.md
+++ b/README.md
@@ -74,3 +74,5 @@ This project is licensed under the [GNU GPL v3 License](https://www.gnu.org/lice
+
+
diff --git a/pom.xml b/pom.xml
index 3b88267..6fffc8e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,19 +2,19 @@
+ * Each flag should be provided in the format {@code key=value}. + * Multiple flags will be joined using {@code ;}. + *
+ * + * @param host The database host + * @param port The database port + * @param database The database name + * @param user The database user + * @param password The database password + * @param additionalFlags Optional JDBC connection flags + */ + public MSSQLTemplate(String host, int port, String database, String user, String password, String... additionalFlags) { + super(host, port, database, user, password); + this.additionalFlags = String.join(";", additionalFlags); + } + + /** + * Returns the fully qualified Microsoft SQL Server JDBC driver class name. + * + * @return The SQL Server JDBC driver class + */ + @Override + protected String getDriverClass() { + return "com.microsoft.sqlserver.jdbc.SQLServerDriver"; + } + + /** + * Builds the Microsoft SQL Server JDBC connection URL. + *+ * The URL follows the format: + * {@code jdbc:sqlserver://host:port;databaseName=database} + * and optionally appends additional connection properties. + *
+ * + * @return The JDBC connection URL template + */ + @Override + protected String getConnectionUrl() { + String url = "jdbc:sqlserver://%host%:%port%;databaseName=%database%"; + return url + (hasAdditionalFlags() ? ";" + additionalFlags : ""); + } + + /** + * Checks whether any additional JDBC connection flags are defined. + * + * @return {@code true} if additional flags are present, otherwise {@code false} + */ + public boolean hasAdditionalFlags() { + return additionalFlags != null && !additionalFlags.isBlank(); + } + +} diff --git a/src/main/java/de/codeblocksmc/codelib/database/MySQLTemplate.java b/src/main/java/de/codeblocksmc/codelib/database/MySQLTemplate.java new file mode 100644 index 0000000..149e210 --- /dev/null +++ b/src/main/java/de/codeblocksmc/codelib/database/MySQLTemplate.java @@ -0,0 +1,88 @@ +package de.codeblocksmc.codelib.database; + +import lombok.Getter; + +/** + * Abstract MySQL-specific implementation of {@link SQLTemplate}. + * + * @author JustCody + * @author CrAfTs_ArMy + * @version 2.0 + */ +public abstract non-sealed class MySQLTemplate extends SQLTemplate { + + /** + * Additional JDBC connection flags appended to the connection URL. + */ + @Getter + private final String additionalFlags; + + /** + * Creates a new MySQLTemplate without any additional connection flags. + * + * @param host The database host + * @param port The database port + * @param database The database name + * @param user The database user + * @param password The database password + */ + public MySQLTemplate(String host, int port, String database, String user, String password) { + super(host, port, database, user, password); + this.additionalFlags = ""; + } + + /** + * Creates a new MySQLTemplate with additional JDBC connection flags. + *+ * Each flag should be provided in the format {@code key=value}. + * Multiple flags will be joined using {@code &}. + *
+ * + * @param host The database host + * @param port The database port + * @param database The database name + * @param user The database user + * @param password The database password + * @param additionalFlags Optional JDBC connection flags + */ + public MySQLTemplate(String host, int port, String database, String user, String password, String... additionalFlags) { + super(host, port, database, user, password); + this.additionalFlags = String.join("&", additionalFlags); + } + + /** + * Returns the fully qualified MySQL JDBC driver class name. + * + * @return The MySQL JDBC driver class + */ + @Override + protected String getDriverClass() { + return "com.mysql.cj.jdbc.Driver"; + } + + /** + * Builds the MySQL JDBC connection URL. + *+ * The URL follows the format: + * {@code jdbc:mysql://host:port/database} + * and optionally appends query parameters if additional flags are present. + *
+ * + * @return The JDBC connection URL template + */ + @Override + protected String getConnectionUrl() { + String url = "jdbc:mysql://%host%:%port%/%database%"; + return url + (hasAdditionalFlags() ? "?" + additionalFlags : ""); + } + + /** + * Checks whether any additional JDBC connection flags are defined. + * + * @return {@code true} if additional flags are present, otherwise {@code false} + */ + public boolean hasAdditionalFlags() { + return additionalFlags != null && !additionalFlags.isBlank(); + } + +} diff --git a/src/main/java/de/codeblocksmc/codelib/database/SQLTemplate.java b/src/main/java/de/codeblocksmc/codelib/database/SQLTemplate.java new file mode 100644 index 0000000..58bf9b4 --- /dev/null +++ b/src/main/java/de/codeblocksmc/codelib/database/SQLTemplate.java @@ -0,0 +1,161 @@ +package de.codeblocksmc.codelib.database; + +import lombok.Getter; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; + +/** + * Abstract base class for SQL database templates. + * + * @author CrAfTs_ArMy + * @version 1.0 + */ +public sealed abstract class SQLTemplate permits MSSQLTemplate, MySQLTemplate { + + /** + * The database host address. + */ + private final String host; + + /** + * The port on which the database server is running. + */ + private final int port; + + /** + * The name of the database schema to connect to. + */ + private final String database; + + /** + * The username used for database authentication. + */ + private final String user; + + /** + * The password used for database authentication. + */ + private final String password; + + /** + * The active JDBC connection. + */ + @Getter + private Connection connection; + + /** + * Creates a new {@link SQLTemplate} with the given connection parameters. + * + * @param host The database host + * @param port The database port + * @param database The database name + * @param user The database user + * @param password The database password + */ + public SQLTemplate(String host, int port, String database, String user, String password) { + this.host = host; + this.port = port; + this.database = database; + this.user = user; + this.password = password; + } + + /** + * Hook method that is called after a successful database connection. + */ + protected abstract void afterSuccessfulConnection(); + + /** + * Returns the JDBC connection URL template. + *+ * The returned string may contain the placeholders: + *
+ * If {@code null} is returned, no explicit driver loading will be attempted. + *
+ * + * @return The JDBC driver class name or {@code null} + */ + protected abstract String getDriverClass(); + + /** + * Establishes a connection to the database. + *+ * This method loads the JDBC driver (if provided), builds the connection URL, + * and opens a connection using {@link DriverManager}. + *
+ * + * @return The established {@link Connection} + * @throws RuntimeException If the driver cannot be loaded or the connection fails + */ + public Connection connect() { + try { + String driverClass = getDriverClass(); + if (driverClass != null) { + Class.forName(driverClass); + } + + String connectionUrl = getConnectionUrl() + .replace("%host%", host) + .replace("%port%", String.valueOf(port)) + .replace("%database%", database); + + connection = DriverManager.getConnection(connectionUrl, user, password); + afterSuccessfulConnection(); + return connection; + } catch (ClassNotFoundException e) { + throw new RuntimeException("Failed to load driver: " + e.getMessage()); + } catch (SQLException e) { + throw new RuntimeException("Failed to connect: " + e.getMessage(), e); + } + } + + /** + * Closes the current database connection. + * + * @throws RuntimeException if closing the connection fails + */ + public void disconnect() { + try { + getConnection().close(); + } catch (SQLException e) { + throw new RuntimeException("Failed to disconnect: " + e.getMessage(), e); + } + } + + /** + * Checks whether the database connection is active. + *+ * If the connection is {@code null} or already closed, + * a new connection will be established automatically. + *
+ * + * @throws RuntimeException if checking the connection fails + */ + public void checkConnection() { + try { + Connection connection = getConnection(); + if (connection == null || connection.isClosed()) { + this.connect(); + } + } catch (SQLException e) { + throw new RuntimeException("Failed to check the connection: " + e.getMessage(), e); + } + } + +} diff --git a/src/main/java/de/codeblocksmc/codelib/databsae/DatabaseObject.java b/src/main/java/de/codeblocksmc/codelib/databsae/DatabaseObject.java deleted file mode 100644 index eb40cc9..0000000 --- a/src/main/java/de/codeblocksmc/codelib/databsae/DatabaseObject.java +++ /dev/null @@ -1,4 +0,0 @@ -package de.codeblocksmc.codelib.databsae; - -public class DatabaseObject { -} diff --git a/src/main/java/de/codeblocksmc/codelib/databsae/MSSQLTemplate.java b/src/main/java/de/codeblocksmc/codelib/databsae/MSSQLTemplate.java deleted file mode 100644 index cc7b197..0000000 --- a/src/main/java/de/codeblocksmc/codelib/databsae/MSSQLTemplate.java +++ /dev/null @@ -1,58 +0,0 @@ -package de.codeblocksmc.codelib.databsae; - -import lombok.Getter; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.logging.Logger; - -public class MSSQLTemplate extends DatabaseObject { - @Getter - public Connection conn; - private final Logger log; - private final String DB_NAME; - private final String DB_USER; - private final String DB_PASSWORD; - private final int DB_PORT; - private final String DB_HOST; - - public MSSQLTemplate(Logger log, String DB_NAME, String DB_USER, String DB_PASSWORD, int DB_PORT, String DB_HOST) { - this.log = log; - this.DB_NAME = DB_NAME; - this.DB_USER = DB_USER; - this.DB_PASSWORD = DB_PASSWORD; - this.DB_PORT = DB_PORT; - this.DB_HOST = DB_HOST; - } - - public Connection connect() { - String CONNECTION_STRING = "jdbc:sqlserver://HOST;databaseName=DATABASE;encrypt=false;trustServerCertificate=true;" - .replace("HOST", DB_HOST).replace("DATABASE", DB_NAME); - try { - Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver"); - conn = DriverManager.getConnection(CONNECTION_STRING, DB_USER, DB_PASSWORD); - log.info("MSSQL Connection established."); - conn.createStatement().execute("USE " + DB_NAME); - return conn; - } - catch(Exception ex) { - log.warning(ex.getMessage()); - } - return null; - } - - public void checkConnection() { - try { - if (conn == null || conn.isClosed()) connect(); - } catch (SQLException ignored) {} - } - public void disconnect() { - try { - conn.close(); - log.info("SQL Connection destroyed."); - } catch (SQLException e) { - log.severe(e.getMessage()); - } - } -} diff --git a/src/main/java/de/codeblocksmc/codelib/databsae/MySQLTemplate.java b/src/main/java/de/codeblocksmc/codelib/databsae/MySQLTemplate.java deleted file mode 100644 index 0596f8d..0000000 --- a/src/main/java/de/codeblocksmc/codelib/databsae/MySQLTemplate.java +++ /dev/null @@ -1,98 +0,0 @@ -package de.codeblocksmc.codelib.databsae; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.logging.Logger; - -/** - * Template class for creating MySQL connections. - * This class provides methods for connecting to a MySQL database and checking the connection status. - * It works in conjunction with {@link Logger} for logging any issues or errors during the connection process. - * This is commonly used in Bukkit and Paper plugins for logging database-related activities. - * - * @author JustCody - * @version 1.0 - */ -public abstract class MySQLTemplate extends DatabaseObject { - - // The connection object to the MySQL database - public Connection conn; - - // Logger for logging messages related to the connection - public final Logger log; - - // MySQL connection details - public final String host; - public final int port; - public final String database; - public final String user; - public final String password; - - /** - * Constructor for initializing the MySQL connection template. - * - * @param log {@link Logger} of the plugin, typically used to log connection issues. - * @param host Hostname of the MySQL server (e.g., "localhost"). - * @param port Port of the MySQL server. Default is 3306. - * @param database Name of the MySQL database to connect to. - * @param user Username to authenticate with the MySQL server. - * @param password Password for the given username. - */ - public MySQLTemplate(Logger log, String host, int port, String database, String user, String password) { - this.log = log; - this.host = host; - this.port = port; - this.database = database; - this.user = user; - this.password = password; - } - - /** - * Establishes a connection to the MySQL server and creates a {@link Connection} object. - * This method loads the MySQL JDBC driver, attempts to connect to the database, - * and logs any exceptions if the connection fails. - */ - public void connect() { - final String DB_NAME = "jdbc:mysql://"+host+":"+port+"/"+database+"?useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC&autoReconnect=true"; - - try { - // Load MySQL JDBC driver class - Class.forName("com.mysql.cj.jdbc.Driver"); - - // Establish a connection using the provided connection details - conn = DriverManager.getConnection(DB_NAME, user, password); - - afterSuccessfulConnection(); - } catch (Exception ex) { - // Log any exception that occurs during the connection process - log.warning("MySQL connection failed: " + ex.getMessage()); - } - } - - /** - * Checks the current MySQL connection to verify if it is still open and valid. - * If the connection is closed or null, this method will attempt to reconnect using {@link MySQLTemplate#connect()}. - */ - public void checkConnection() { - try { - if (conn == null || conn.isClosed()) { - // Attempt to reconnect if the connection is null or closed - connect(); - } - } catch (SQLException e) { - // Log any exceptions encountered while checking the connection status - log.warning("MySQL connection check failed: " + e.getMessage()); - } - } - - public void disconnect() { - try { - conn.close(); - } catch (SQLException e) { - log.severe(e.getMessage()); - } - } - - public abstract void afterSuccessfulConnection(); -} diff --git a/src/main/java/de/codeblocksmc/codelib/databsae/MySQLTemplateVelocity.java b/src/main/java/de/codeblocksmc/codelib/databsae/MySQLTemplateVelocity.java deleted file mode 100644 index 0f33d84..0000000 --- a/src/main/java/de/codeblocksmc/codelib/databsae/MySQLTemplateVelocity.java +++ /dev/null @@ -1,73 +0,0 @@ -package de.codeblocksmc.codelib.databsae; - -import org.slf4j.Logger; - -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; - - -/** - * Template class for creating MySQL connections - */ -public abstract class MySQLTemplateVelocity extends DatabaseObject { - - public Connection conn; - public final Logger log; - - private final String host; - private final int port; - private final String database; - private final String user; - private final String password; - - /** - * - * @param log {@link Logger} of the Plugin - * @param host Hostname - * @param port Port of the server. Default: 3306 - * @param database Database name - * @param user Username - * @param password Password - */ - public MySQLTemplateVelocity(Logger log, String host, int port, String database, String user, String password) { - this.log = log; - this.host = host; - this.port = port; - this.database = database; - this.user = user; - this.password = password; - } - - /** - * Connects to the MySQL server and creates a {@link Connection} object - */ - public void connect() { - final String DB_NAME = "jdbc:mysql://"+host+":"+port+"/"+database+"?useJDBCCompliantTimezoneShift=true&useLeg" + - "acyDatetimeCode=false&serverTimezone=UTC&autoReconnect=true"; - - try { - Class.forName("com.mysql.cj.jdbc.Driver"); //Gets the driver class - - conn = DriverManager.getConnection(DB_NAME, user, password); //Gets a connection to the database using the details you provided. - afterSuccessfulConnection(); - - } - catch(Exception ex) { - log.warn(ex.getMessage()); - } - } - - /** - * Checks if the connection is ok, otherwise it will try to {@link MySQLTemplate#connect()} to the server - */ - public void checkConnection() { - try { - if (conn == null || conn.isClosed()) connect(); - } catch (SQLException e) { - log.warn(e.getMessage()); - } - } - - public abstract void afterSuccessfulConnection(); -} diff --git a/src/main/java/de/codeblocksmc/codelib/locations/LocationWrapper.java b/src/main/java/de/codeblocksmc/codelib/locations/LocationWrapper.java index d161785..32f093a 100644 --- a/src/main/java/de/codeblocksmc/codelib/locations/LocationWrapper.java +++ b/src/main/java/de/codeblocksmc/codelib/locations/LocationWrapper.java @@ -4,7 +4,10 @@ import lombok.Setter; import lombok.NoArgsConstructor; +import java.util.Objects; + /** + * @author Try * A wrapper class for representing and saving positions in JSON files. * *This class is designed to store positional data in a safe and @@ -18,55 +21,16 @@ @Getter @Setter @NoArgsConstructor -public class LocationWrapper { +public class LocationWrapper extends LocationWrapperReduced { /** * The name of the world where the location exists. */ private String world; - /** - * The X-coordinate of the location. - */ - private double x; - - /** - * The Y-coordinate of the location. - */ - private double y; - - /** - * The Z-coordinate of the location. - */ - private double z; - - /** - * The yaw (rotation on the Y-axis) of the location. - */ - private float yaw; - - /** - * The pitch (rotation on the X-axis) of the location. - */ - private float pitch; - - /** - * Constructs a {@link LocationWrapper} with the specified values. - * - * @param world the name of the {@link org.bukkit.World} where the location exists. - * @param x the X-coordinate of the location. - * @param y the Y-coordinate of the location. - * @param z the Z-coordinate of the location. - * @param yaw the yaw (rotation on the Y-axis) of the location. - * @param pitch the pitch (rotation on the X-axis) of the location. - */ public LocationWrapper(String world, double x, double y, double z, float yaw, float pitch) { + super(x,y,z,yaw,pitch); this.world = world; - this.x = x; - this.y = y; - this.z = z; - this.yaw = yaw; - this.pitch = pitch; } /** @@ -80,6 +44,7 @@ public boolean isValid() { return world != null && !world.isEmpty(); } + /** * Provides a string representation of the {@link LocationWrapper}. * @@ -88,7 +53,7 @@ public boolean isValid() { @Override public String toString() { return String.format("LocationWrapper[world=%s, x=%.2f, y=%.2f, z=%.2f, yaw=%.2f, pitch=%.2f]", - world, x, y, z, yaw, pitch); + world, getX(), getY(), getZ(), getYaw(), getPitch()); } /** @@ -101,35 +66,17 @@ public String toString() { */ @Override public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null || getClass() != obj.getClass()) return false; + boolean result = super.equals(obj); - LocationWrapper other = (LocationWrapper) obj; - return Double.compare(other.x, x) == 0 && - Double.compare(other.y, y) == 0 && - Double.compare(other.z, z) == 0 && - Float.compare(other.yaw, yaw) == 0 && - Float.compare(other.pitch, pitch) == 0 && - (world != null ? world.equals(other.world) : other.world == null); + if (obj instanceof LocationWrapper other) + return result&& (Objects.equals(world, other.world)); + else{ + return false; + } } - /** - * Generates a hash code for the {@link LocationWrapper}. - * - * @return a hash code based on the fields of the object. - */ @Override public int hashCode() { - int result = (world != null ? world.hashCode() : 0); - long temp; - temp = Double.doubleToLongBits(x); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(y); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - temp = Double.doubleToLongBits(z); - result = 31 * result + (int) (temp ^ (temp >>> 32)); - result = 31 * result + Float.floatToIntBits(yaw); - result = 31 * result + Float.floatToIntBits(pitch); - return result; + return Objects.hash(super.hashCode(), world); } } diff --git a/src/main/java/de/codeblocksmc/codelib/locations/LocationWrapperReduced.java b/src/main/java/de/codeblocksmc/codelib/locations/LocationWrapperReduced.java index 25a49a2..dd50aaa 100644 --- a/src/main/java/de/codeblocksmc/codelib/locations/LocationWrapperReduced.java +++ b/src/main/java/de/codeblocksmc/codelib/locations/LocationWrapperReduced.java @@ -4,7 +4,10 @@ import lombok.NoArgsConstructor; import lombok.Setter; +import java.util.Objects; + /** + * @author Try * A wrapper class for representing and saving positions in JSON files. * *
This class is designed to store positional data in a safe and
@@ -84,8 +87,8 @@ public LocationWrapper toWrapper(String world) {
*/
@Override
public String toString() {
- return String.format("LocationWrapper[world=%s, x=%.2f, y=%.2f, z=%.2f, yaw=%.2f, pitch=%.2f]",
- "unknown", x, y, z, yaw, pitch);
+ return String.format("LocationWrapperReduced[ x=%.2f, y=%.2f, z=%.2f, yaw=%.2f, pitch=%.2f]",
+ x, y, z, yaw, pitch);
}
/**
@@ -98,15 +101,19 @@ public String toString() {
*/
@Override
public boolean equals(Object obj) {
+ if (obj == null ) return false;
if (this == obj) return true;
- if (obj == null || getClass() != obj.getClass()) return false;
-
- LocationWrapperReduced other = (LocationWrapperReduced) obj;
- return Double.compare(other.x, x) == 0 &&
- Double.compare(other.y, y) == 0 &&
- Double.compare(other.z, z) == 0 &&
- Float.compare(other.yaw, yaw) == 0 &&
- Float.compare(other.pitch, pitch) == 0;
+
+ if(obj instanceof LocationWrapperReduced other){
+ return Double.compare(other.x, x) == 0 &&
+ Double.compare(other.y, y) == 0 &&
+ Double.compare(other.z, z) == 0 &&
+ Float.compare(other.yaw, yaw) == 0 &&
+ Float.compare(other.pitch, pitch) == 0;
+ }
+
+ return false;
+
}
/**
@@ -114,14 +121,9 @@ public boolean equals(Object obj) {
*
* @return a hash code based on the fields of the object.
*/
+
@Override
public int hashCode() {
- int result = 0;
- result = 31 * result + Double.hashCode(x);
- result = 31 * result + Double.hashCode(y);
- result = 31 * result + Double.hashCode(z);
- result = 31 * result + Float.floatToIntBits(yaw);
- result = 31 * result + Float.floatToIntBits(pitch);
- return result;
+ return Objects.hash(x, y, z, yaw, pitch);
}
}
diff --git a/src/main/java/de/codeblocksmc/codelib/util/ParticleUtil.java b/src/main/java/de/codeblocksmc/codelib/util/ParticleUtil.java
index e01ed6f..0b5b161 100644
--- a/src/main/java/de/codeblocksmc/codelib/util/ParticleUtil.java
+++ b/src/main/java/de/codeblocksmc/codelib/util/ParticleUtil.java
@@ -1,12 +1,20 @@
package de.codeblocksmc.codelib.util;
+import com.google.common.util.concurrent.AtomicDouble;
+import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
+import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector;
+/*
+ * @author Try
+ * @version 1.1
+ */
+
public class ParticleUtil {
public static void spawnParticleCircle(Location center, double radius, Particle particle, int points) {
World world = center.getWorld();
@@ -25,29 +33,25 @@ public static void spawnRotatingCircle(Location center, double radius, Particle
World world = center.getWorld();
if (world == null) return;
- new BukkitRunnable() {
- int ticks = 0;
- double angleOffset = 0;
- @Override
- public void run() {
- if (ticks >= durationTicks) {
- cancel();
- return;
- }
- for (int i = 0; i < points; i++) {
- double angle = 2 * Math.PI * i / points + angleOffset;
- double x = Math.cos(angle) * radius;
- double z = Math.sin(angle) * radius;
- Location loc = center.clone().add(new Vector(x, 0, z));
- world.spawnParticle(particle, loc, 1, 0, 0, 0, 0);
- }
- angleOffset += angularVelocity;
- ticks += 2;
+ final AtomicDouble angleOffset = new AtomicDouble(0);
+
+ BukkitTask particleTask = Bukkit.getScheduler().runTaskTimer(plugin,()->{
+
+ for (int i = 0; i < points; i++) {
+ double angle = 2 * Math.PI * i / points + angleOffset.get();
+ double x = Math.cos(angle) * radius;
+ double z = Math.sin(angle) * radius;
+ Location loc = center.clone().add(new Vector(x, 0, z));
+ world.spawnParticle(particle, loc, 1, 0, 0, 0, 0);
}
- }.runTaskTimer(plugin, 0, 2L);
+ angleOffset.addAndGet(angularVelocity);
+
+ }, 0, 2L);
+
+ Bukkit.getScheduler().runTaskLater(plugin, particleTask::cancel, durationTicks);
}
diff --git a/src/main/java/de/codeblocksmc/codelib/util/ServerConnector.java b/src/main/java/de/codeblocksmc/codelib/util/ServerConnector.java
index 6d4ea1a..86d6a0e 100644
--- a/src/main/java/de/codeblocksmc/codelib/util/ServerConnector.java
+++ b/src/main/java/de/codeblocksmc/codelib/util/ServerConnector.java
@@ -1,11 +1,15 @@
package de.codeblocksmc.codelib.util;
import io.github.leonardosnt.bungeechannelapi.BungeeChannelApi;
+import lombok.Getter;
+import lombok.Setter;
+import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
-import org.bukkit.scheduler.BukkitRunnable;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.regex.Pattern;
/**
* This class handles the connection of players to available servers, taking into account party-related restrictions.
@@ -18,9 +22,15 @@
* This class operates asynchronously, querying the BungeeCord server list and checking for server availability.
*
* @author JustCody
- * @version 1.0
+ * @author Try
+ * @version 1.1
*/
public class ServerConnector {
+ private final ConcurrentHashMap
* The method will search for a server that is less than 30 players, and if found, it will connect the player to it.
*
- * @param player The player to be connected.
- * @param servername The name of the server to connect to (partial match).
+ * @param player The player to be connected.
+ * @param serverPattern A pattern to match server names.
+ * @param searchDescription The description which is show to the player when the searching is starting.
*/
- public void connect(Player player, String servername) {
- // Check if the player is in a party and not the leader
- //TODO: Use new party system
+ public void connect(Player player, Pattern serverPattern, String searchDescription) {
+
+ //If the pattern is not known register it with the default player count.
+ if (!serverMaxPlayerCount.containsKey(serverPattern))
+ serverMaxPlayerCount.put(serverPattern, defaultMaxPlayerCount);
+
- // Notify the player that the search for a free server is starting
- player.sendMessage(prefix + "§aLooking for free server in §e" + servername + "§a...");
+ player.sendMessage(prefix + "§aLooking for free server in §e" + searchDescription + "§a...");
- // Get the BungeeChannelApi instance to interact with BungeeCord
BungeeChannelApi api = BungeeChannelApi.of(plugin);
- // Run the connection task asynchronously
- new BukkitRunnable() {
-
- @Override
- public void run() {
- // Fetch the list of available servers
- api.getServers().whenComplete((result, error) -> {
- AtomicBoolean found = new AtomicBoolean(false);
-
- // Loop through the servers and check if one matches the specified servername
- for (String server : result) {
- if (!server.startsWith(servername)) continue;
-
- // Get the player count for the current server
- api.getPlayerCount(server).whenComplete((count, err) -> {
- // If the server has less than 30 players, connect the player
- if (count < 30) {
- api.connect(player, server);
- found.set(true);
- }
- });
- }
+ Bukkit.getScheduler().runTaskLater(plugin, () -> {
+ api.getServers().whenComplete((result, error) -> {
+ AtomicBoolean found = new AtomicBoolean(false);
+
- // Notify the player if no free server was found after the search
- new BukkitRunnable() {
- @Override
- public void run() {
- try {
- if (!found.get()) {
- player.sendMessage(prefix + "§7We could not find a free server. Sorry for the inconvenience!");
- }
- } catch (Exception e) {
- // Handle any errors when notifying the player
- plugin.getLogger().warning(e.getMessage());
- }
+ for (String server : result) {
+ if (!serverPattern.matcher(server).hasMatch()) continue;
+
+
+
+ api.getPlayerCount(server).whenComplete((count, err) -> {
+
+ if (count < serverMaxPlayerCount.get(serverPattern)) {
+ api.connect(player, server);
+ found.set(true);
}
- }.runTaskLater(plugin, 5); // Delay to allow for the server search to complete
- });
- }
+ });
+
+ //stop the search if a server is found
+ if(found.get())
+ break;
+ }
+
+ //There is no reason to start a task if the server is found.
+ if (found.get()) return;
+
+ Bukkit.getScheduler().runTaskLater(plugin, () -> {
+
+ try {
+ player.sendMessage(prefix + "§7We could not find a free server. Sorry for the inconvenience!");
+ } catch (Exception e) {
+ plugin.getLogger().warning(e.getMessage());
+ }
+
+ }, 5);
+ });
+
+ }, 0);
+
+ }
+
- }.runTaskLater(plugin, 0); // Run the task immediately
+ public void setServerMaxPlayerCount(Pattern serverPattern, int playerCount) {
+ this.serverMaxPlayerCount.put(serverPattern, playerCount);
}
}