Various fixes & improvements (#246)

* HuskClaims Support

* Bump Lombok for compilation and fix other obscure issues

* Resolve database locking

* Have the executor service perform in multiple places

* Utilize a ConcurrentHashMap instead of a HashMap for player data management to mitigate fast connections and thread switching

* Reapply modifications with UUID checking for this particular instance

* Apply additional null checks to mitigate player reading exceptions once again

* Fix RTP on death on custom worlds and add it to debug print

* Migrate to newer FoliaLib module and fix compilation again

* Fix Min-Max Radius

Co-authored-by: ZepsiZola <zepsizola@gmail.com>

* Implement labeled HuskClaims support since it's internally implemented

* Rebase

* Likely make thread-safe

* Resolve obscure and rare ArrayIndexOutOfBoundsException

---------

Co-authored-by: JMaleta <13309090+JMeta0@users.noreply.github.com>
Co-authored-by: ZepsiZola <zepsizola@gmail.com>
This commit is contained in:
R00tB33rMan
2026-07-06 20:00:51 -04:00
committed by GitHub
parent 15fc3eba67
commit 4697f06163
13 changed files with 206 additions and 318 deletions
+20 -32
View File
@@ -25,7 +25,7 @@
<!-- Local Server Building --> <!-- Local Server Building -->
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId> <artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version> <version>3.4.2</version>
<configuration> <configuration>
<outputDirectory>../../Java/plugins</outputDirectory> <outputDirectory>../../Java/plugins</outputDirectory>
</configuration> </configuration>
@@ -47,13 +47,13 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId> <artifactId>maven-install-plugin</artifactId>
<version>3.1.0</version> <version>3.1.4</version>
</plugin> </plugin>
<plugin> <plugin>
<!-- Shade PaperLib into project --> <!-- Shade PaperLib into project -->
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>
<version>3.5.0</version> <version>3.6.0</version>
<configuration> <configuration>
<dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml <dependencyReducedPomLocation>${project.build.directory}/dependency-reduced-pom.xml
</dependencyReducedPomLocation> </dependencyReducedPomLocation>
@@ -66,10 +66,6 @@
<pattern>com.tcoded.folialib</pattern> <pattern>com.tcoded.folialib</pattern>
<shadedPattern>me.SuperRonanCraft.BetterRTP.lib.folialib</shadedPattern> <shadedPattern>me.SuperRonanCraft.BetterRTP.lib.folialib</shadedPattern>
</relocation> </relocation>
<!--relocation>
<pattern>xyz.xenondevs.particle</pattern>
<shadedPattern>me.SuperRonanCraft.BetterRTP.particleLib</shadedPattern>
</relocation-->
</relocations> </relocations>
</configuration> </configuration>
<executions> <executions>
@@ -84,7 +80,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version> <version>3.14.0</version>
<configuration> <configuration>
<source>1.8</source> <source>1.8</source>
<target>1.8</target> <target>1.8</target>
@@ -105,6 +101,11 @@
<id>jitpack.io</id> <id>jitpack.io</id>
<url>https://jitpack.io</url> <url>https://jitpack.io</url>
</repository> </repository>
<!-- FoliaLib Repo -->
<repository>
<id>tcoded-releases</id>
<url>https://repo.tcoded.com/releases</url>
</repository>
<!-- Spigot Repo --> <!-- Spigot Repo -->
<repository> <repository>
<id>spigot-repo</id> <id>spigot-repo</id>
@@ -120,7 +121,7 @@
<id>vault-repo</id> <id>vault-repo</id>
<url>https://nexus.hc.to/content/repositories/pub_releases</url> <url>https://nexus.hc.to/content/repositories/pub_releases</url>
</repository> </repository>
<!-- Worldguard Repo --> <!-- WorldGuard Repo -->
<repository> <repository>
<id>sk89q-repo</id> <id>sk89q-repo</id>
<url>https://maven.enginehub.org/repo/</url> <url>https://maven.enginehub.org/repo/</url>
@@ -191,7 +192,7 @@
<version>1.0.8</version> <version>1.0.8</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!-- Worldguard (https://dev.bukkit.org/projects/worldguard) --> <!-- WorldGuard (https://dev.bukkit.org/projects/worldguard) -->
<dependency> <!-- Saber Factions screws up if updated --> <dependency> <!-- Saber Factions screws up if updated -->
<groupId>com.sk89q.worldguard</groupId> <groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId> <artifactId>worldguard-bukkit</artifactId>
@@ -229,7 +230,7 @@
<dependency> <dependency>
<groupId>com.comphenix.protocol</groupId> <groupId>com.comphenix.protocol</groupId>
<artifactId>ProtocolLib</artifactId> <artifactId>ProtocolLib</artifactId>
<version>4.8.0</version> <version>5.3.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- Towny (https://www.spigotmc.org/resources/towny.72694/) --> <!-- Towny (https://www.spigotmc.org/resources/towny.72694/) -->
@@ -243,10 +244,10 @@
<dependency> <dependency>
<groupId>com.github.TechFortress</groupId> <groupId>com.github.TechFortress</groupId>
<artifactId>GriefPrevention</artifactId> <artifactId>GriefPrevention</artifactId>
<version>16.18</version> <version>17.0.0</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- KingdomsX v1.10.5.2 (https://www.spigotmc.org/resources/kingdomsx.77670/) --> <!-- KingdomsX (https://www.spigotmc.org/resources/kingdomsx.77670/) -->
<dependency> <dependency>
<groupId>com.github.cryptomorin</groupId> <groupId>com.github.cryptomorin</groupId>
<artifactId>kingdoms</artifactId> <artifactId>kingdoms</artifactId>
@@ -286,14 +287,14 @@
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.18.26</version> <version>1.18.38</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- EssentialsX --> <!-- EssentialsX -->
<dependency> <dependency>
<groupId>net.essentialsx</groupId> <groupId>net.essentialsx</groupId>
<artifactId>EssentialsX</artifactId> <artifactId>EssentialsX</artifactId>
<version>2.20.1</version> <version>2.21.0</version>
<scope>provided</scope> <scope>provided</scope>
<exclusions> <exclusions>
<exclusion> <exclusion>
@@ -319,14 +320,14 @@
<dependency> <dependency>
<groupId>me.clip</groupId> <groupId>me.clip</groupId>
<artifactId>placeholderapi</artifactId> <artifactId>placeholderapi</artifactId>
<version>2.11.2</version> <version>2.11.6</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- HuskClaims (https://www.spigotmc.org/resources/huskclaims.114467/) (Added in 3.6.13)--> <!-- HuskClaims (https://www.spigotmc.org/resources/huskclaims.114467/) (Added in 3.6.13)-->
<dependency> <dependency>
<groupId>net.william278.huskclaims</groupId> <groupId>net.william278.huskclaims</groupId>
<artifactId>huskclaims-bukkit</artifactId> <artifactId>huskclaims-bukkit</artifactId>
<version>1.5.2</version> <version>1.5.10</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- Husktown (https://www.spigotmc.org/resources/husktowns.92672/) (Added in 3.4.5)--> <!-- Husktown (https://www.spigotmc.org/resources/husktowns.92672/) (Added in 3.4.5)-->
@@ -345,9 +346,9 @@
</dependency> </dependency>
<!-- FoliaLib --> <!-- FoliaLib -->
<dependency> <dependency>
<groupId>com.github.TechnicallyCoded</groupId> <groupId>com.tcoded</groupId>
<artifactId>FoliaLib</artifactId> <artifactId>FoliaLib</artifactId>
<version>0.4.3</version> <version>0.5.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<!-- FactionsBridge --> <!-- FactionsBridge -->
@@ -364,19 +365,6 @@
<version>c697d3e9ef</version> <version>c697d3e9ef</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<!-- CAN BE UNCOMMENTED IF YOU HAVE ACCESS TO THE PLUGIN -->
<!-- Private Repoed -->
<!-- This is uploaded to our private repo on https://repo.ronanplugins.com -->
<!-- hClaims (https://www.spigotmc.org/resources/90540/) -->
<!--<dependency>
<groupId>com.ronanplugins</groupId>
<artifactId>hClaims</artifactId>
<version>2.5.3</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>-->
<!-- Provided by repo: devmart-public -->
<dependency> <dependency>
<groupId>com.bekvon.bukkit.residence</groupId> <groupId>com.bekvon.bukkit.residence</groupId>
<artifactId>Residence</artifactId> <artifactId>Residence</artifactId>
@@ -20,9 +20,7 @@ public class Join {
static void event(PlayerJoinEvent e) { static void event(PlayerJoinEvent e) {
Player p = e.getPlayer(); Player p = e.getPlayer();
updater(p); updater(p);
AsyncHandler.async(() -> { AsyncHandler.async(() -> getPl().getCooldowns().loadPlayer(p));
getPl().getCooldowns().loadPlayer(p);
});
rtpOnFirstJoin(p); rtpOnFirstJoin(p);
} }
@@ -42,10 +40,7 @@ public class Join {
//RTP on first join //RTP on first join
private static void rtpOnFirstJoin(Player p) { private static void rtpOnFirstJoin(Player p) {
if (getPl().getSettings().isRtpOnFirstJoin_Enabled() && !p.hasPlayedBefore()) if (getPl().getSettings().isRtpOnFirstJoin_Enabled() && !p.hasPlayedBefore())
HelperRTP.tp(p, Bukkit.getConsoleSender(), HelperRTP.tp(p, Bukkit.getConsoleSender(), Bukkit.getWorld(getPl().getSettings().getRtpOnFirstJoin_World()), null, RTP_TYPE.JOIN, true, true);
Bukkit.getWorld(getPl().getSettings().getRtpOnFirstJoin_World()),
null, RTP_TYPE.JOIN, true, true);
//Fixed via @kazigk on Github
} }
private static BetterRTP getPl() { private static BetterRTP getPl() {
@@ -6,8 +6,6 @@ import com.comphenix.protocol.events.PacketContainer;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.lang.reflect.InvocationTargetException;
public abstract class AbstractPacket { public abstract class AbstractPacket {
// The packet we will be modifying // The packet we will be modifying
protected PacketContainer handle; protected PacketContainer handle;
@@ -42,15 +40,9 @@ public abstract class AbstractPacket {
* Send the current packet to the given receiver. * Send the current packet to the given receiver.
* *
* @param receiver - the receiver. * @param receiver - the receiver.
* @throws RuntimeException If the packet cannot be sent.
*/ */
public void sendPacket(Player receiver) { public void sendPacket(Player receiver) {
try { ProtocolLibrary.getProtocolManager().sendServerPacket(receiver, getHandle());
ProtocolLibrary.getProtocolManager().sendServerPacket(receiver,
getHandle());
} catch (InvocationTargetException e) {
throw new RuntimeException("Cannot send packet.", e);
}
} }
/** /**
@@ -71,7 +63,7 @@ public abstract class AbstractPacket {
@Deprecated @Deprecated
public void recievePacket(Player sender) { public void recievePacket(Player sender) {
try { try {
ProtocolLibrary.getProtocolManager().recieveClientPacket(sender, ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
getHandle()); getHandle());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Cannot recieve packet.", e); throw new RuntimeException("Cannot recieve packet.", e);
@@ -86,7 +78,7 @@ public abstract class AbstractPacket {
*/ */
public void receivePacket(Player sender) { public void receivePacket(Player sender) {
try { try {
ProtocolLibrary.getProtocolManager().recieveClientPacket(sender, ProtocolLibrary.getProtocolManager().receiveClientPacket(sender,
getHandle()); getHandle());
} catch (Exception e) { } catch (Exception e) {
throw new RuntimeException("Cannot receive packet.", e); throw new RuntimeException("Cannot receive packet.", e);
@@ -6,6 +6,7 @@ import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.concurrent.Future;
import java.util.logging.Level; import java.util.logging.Level;
import me.SuperRonanCraft.BetterRTP.BetterRTP; import me.SuperRonanCraft.BetterRTP.BetterRTP;
@@ -29,7 +30,6 @@ public class DatabasePlayers extends SQLite {
//COOLDOWN DATA //COOLDOWN DATA
COUNT("count", "long"), COUNT("count", "long"),
LAST_COOLDOWN_DATE("last_rtp_date", "long"), LAST_COOLDOWN_DATE("last_rtp_date", "long"),
//USES("uses", "integer"),
; ;
public final String name; public final String name;
@@ -42,43 +42,55 @@ public class DatabasePlayers extends SQLite {
} }
public void setupData(PlayerData data) { public void setupData(PlayerData data) {
Connection conn = null; if (data == null || data.player == null) {
PreparedStatement ps = null; return;
ResultSet rs = null; }
try { try {
conn = getSQLConnection(); Future<?> task = SQLiteExecutor.EXECUTOR.submit(() -> {
ps = conn.prepareStatement("SELECT * FROM " + tables.get(0) + " WHERE " + COLUMNS.UUID.name + " = ?"); Connection conn = null;
ps.setString(1, data.player.getUniqueId().toString()); PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = getSQLConnection();
ps = conn.prepareStatement("SELECT * FROM " + tables.get(0) + " WHERE " + COLUMNS.UUID.name + " = ?");
ps.setString(1, data.player.getUniqueId().toString());
rs = ps.executeQuery(); rs = ps.executeQuery();
if (rs.next()) { if (rs.next()) {
long count = rs.getLong(COLUMNS.COUNT.name); long count = rs.getLong(COLUMNS.COUNT.name);
long time = rs.getLong(COLUMNS.LAST_COOLDOWN_DATE.name); long time = rs.getLong(COLUMNS.LAST_COOLDOWN_DATE.name);
data.setRtpCount(Math.toIntExact(count)); data.setRtpCount(Math.toIntExact(count));
data.setGlobalCooldown(time); data.setGlobalCooldown(time);
} }
} catch (SQLException ex) { } catch (SQLException ex) {
BetterRTP.getInstance().getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex); BetterRTP.getInstance().getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
} finally { } finally {
close(ps, rs, conn); close(ps, rs, conn);
}
});
task.get();
} catch (Exception ex) {
ex.printStackTrace();
} }
} }
//Set a player Cooldown //Set a player Cooldown
public void setData(PlayerData data) { public void setData(PlayerData data) {
String pre = "INSERT OR REPLACE INTO "; try {
String sql = pre + tables.get(0) + " (" SQLiteExecutor.EXECUTOR.submit(() -> {
+ COLUMNS.UUID.name + ", " String sql = "INSERT OR REPLACE INTO " + tables.get(0) + " ("
+ COLUMNS.COUNT.name + ", " + COLUMNS.UUID.name + ", "
+ COLUMNS.LAST_COOLDOWN_DATE.name + " " + COLUMNS.COUNT.name + ", "
//+ COLUMNS.USES.name + " " + COLUMNS.LAST_COOLDOWN_DATE.name + ") VALUES(?, ?, ?)";
+ ") VALUES(?, ?, ?)"; List<Object> params = new ArrayList<Object>() {{
List<Object> params = new ArrayList<Object>() {{ add(data.player.getUniqueId().toString());
add(data.player.getUniqueId().toString()); add(data.getRtpCount());
add(data.getRtpCount()); add(data.getGlobalCooldown());
add(data.getGlobalCooldown()); }};
//add(data.getUses()); sqlUpdate(sql, params);
}}; });
sqlUpdate(sql, params); } catch (Exception ex) {
ex.printStackTrace();
}
} }
} }
@@ -11,7 +11,11 @@ import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.World; import org.bukkit.World;
import java.sql.*; import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
@@ -48,124 +52,72 @@ public class DatabaseQueue extends SQLite {
} }
} }
/*public List<QueueData> getAll() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<QueueData> queueDataList = new ArrayList<>();
try {
conn = getSQLConnection();
ps = conn.prepareStatement("SELECT * FROM " + tables.get(0));
rs = ps.executeQuery();
while (rs.next()) {
long x = rs.getLong(COLUMNS.X.name);
long z = rs.getLong(COLUMNS.Z.name);
String worldName = rs.getString(COLUMNS.WORLD.name);
int id = rs.getInt(COLUMNS.ID.name);
long generated = rs.getLong(COLUMNS.GENERATED.name);
World world = Bukkit.getWorld(worldName);
if (world != null) {
queueDataList.add(new QueueData(new Location(world, x, 69, z), generated, id));
}
}
} catch (SQLException ex) {
BetterRTP.getInstance().getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
} finally {
close(ps, rs, conn);
}
return queueDataList;
}*/
@Override public void load() { @Override public void load() {
if (QueueHandler.isEnabled()) if (QueueHandler.isEnabled())
super.load(); super.load();
} }
public List<QueueData> getInRange(QueueRangeData range) { public List<QueueData> getInRange(QueueRangeData range) {
Connection conn = null; final List<QueueData> queueDataList = new ArrayList<>();
PreparedStatement ps = null;
ResultSet rs = null;
List<QueueData> queueDataList = new ArrayList<>();
try { try {
conn = getSQLConnection(); SQLiteExecutor.EXECUTOR.submit(() -> {
//ps = conn.prepareStatement("SELECT * FROM " + tables.get(0) + " WHERE ? BETWEEN ? AND ? AND ? BETWEEN ? AND ?"); Connection conn = null;
ps = conn.prepareStatement("SELECT * FROM " + tables.get(0) + " WHERE " PreparedStatement ps = null;
+ COLUMNS.WORLD.name + " = '" + range.getWorld().getName() + "' AND " ResultSet rs = null;
+ COLUMNS.X.name + " BETWEEN " + range.getXLow() + " AND " + range.getXHigh() try {
+ " AND " + COLUMNS.Z.name + " BETWEEN " + range.getZLow() + " AND " + range.getZHigh() conn = getSQLConnection();
+ " ORDER BY RANDOM() LIMIT " + (QueueGenerator.queueMax + 1) ps = conn.prepareStatement("SELECT * FROM " + tables.get(0) + " WHERE "
); + COLUMNS.WORLD.name + " = '" + range.getWorld().getName() + "' AND "
/*ps.setString(1, COLUMNS.X.name); + COLUMNS.X.name + " BETWEEN " + range.getXLow() + " AND " + range.getXHigh()
ps.setInt(2, range.getXLow()); + " AND " + COLUMNS.Z.name + " BETWEEN " + range.getZLow() + " AND " + range.getZHigh()
ps.setInt(3, range.getXHigh()); + " ORDER BY RANDOM() LIMIT " + (QueueGenerator.queueMax + 1)
ps.setString(4, COLUMNS.Z.name); );
ps.setInt(5, range.getZLow()); rs = ps.executeQuery();
ps.setInt(6, range.getZHigh());*/ while (rs.next()) {
long x = rs.getLong(COLUMNS.X.name);
//BetterRTP.getInstance().getLogger().info(ps.toString()); long z = rs.getLong(COLUMNS.Z.name);
rs = ps.executeQuery(); String worldName = rs.getString(COLUMNS.WORLD.name);
while (rs.next()) { int id = rs.getInt(COLUMNS.ID.name);
long x = rs.getLong(COLUMNS.X.name); long generated = rs.getLong(COLUMNS.GENERATED.name);
long z = rs.getLong(COLUMNS.Z.name); World world = Bukkit.getWorld(worldName);
String worldName = rs.getString(COLUMNS.WORLD.name); if (world != null) {
int id = rs.getInt(COLUMNS.ID.name); queueDataList.add(new QueueData(new Location(world, x, 69, z), generated, id));
long generated = rs.getLong(COLUMNS.GENERATED.name); }
World world = Bukkit.getWorld(worldName); }
if (world != null) { } catch (SQLException ex) {
queueDataList.add(new QueueData(new Location(world, x, 69 /*giggity*/, z), generated, id)); BetterRTP.getInstance().getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex);
//queueDataList.add(data); } finally {
close(ps, rs, conn);
} }
} }).get();
} catch (SQLException ex) { } catch (Exception ex) {
BetterRTP.getInstance().getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex); ex.printStackTrace();
} finally {
close(ps, rs, conn);
} }
return queueDataList; return queueDataList;
} }
//Set a queue to save //Set a queue to save
public QueueData addQueue(Location loc) { public QueueData addQueue(Location loc) {
String pre = "INSERT INTO ";
String sql = pre + tables.get(0) + " ("
+ COLUMNS.X.name + ", "
+ COLUMNS.Z.name + ", "
+ COLUMNS.WORLD.name + ", "
+ COLUMNS.GENERATED.name + " "
//+ COLUMNS.USES.name + " "
+ ") VALUES(?, ?, ?, ?)";
List<Object> params = new ArrayList<Object>() {{
add(loc.getBlockX());
add(loc.getBlockZ());
add(loc.getWorld().getName());
add(System.currentTimeMillis());
//add(data.getUses());
}};
//return sqlUpdate(sql, params);
int database_id = createQueue(sql, params);
if (database_id >= 0)
return new QueueData(loc, System.currentTimeMillis(), database_id);
return null;
}
public int getCount() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
int count = 0;
try { try {
conn = getSQLConnection(); return SQLiteExecutor.EXECUTOR.submit(() -> {
ps = conn.prepareStatement("SELECT * FROM " + tables.get(0)); String sql = "INSERT INTO " + tables.get(0) + " ("
+ COLUMNS.X.name + ", "
rs = ps.executeQuery(); + COLUMNS.Z.name + ", "
count = rs.getFetchSize(); + COLUMNS.WORLD.name + ", "
} catch (SQLException ex) { + COLUMNS.GENERATED.name + ") VALUES(?, ?, ?, ?)";
BetterRTP.getInstance().getLogger().log(Level.SEVERE, Errors.sqlConnectionExecute(), ex); List<Object> params = new ArrayList<Object>() {{
} finally { add(loc.getBlockX());
close(ps, rs, conn); add(loc.getBlockZ());
add(loc.getWorld().getName());
add(System.currentTimeMillis());
}};
int database_id = createQueue(sql, params);
return database_id >= 0 ? new QueueData(loc, System.currentTimeMillis(), database_id) : null;
}).get();
} catch (Exception ex) {
ex.printStackTrace();
return null;
} }
return count;
} }
private int createQueue(String statement, @NonNull List<Object> params) { private int createQueue(String statement, @NonNull List<Object> params) {
@@ -195,24 +147,31 @@ public class DatabaseQueue extends SQLite {
} }
public boolean removeLocation(Location loc) { public boolean removeLocation(Location loc) {
String sql = "DELETE FROM " + tables.get(0) + " WHERE " try {
+ COLUMNS.X.name + " = ? AND " return SQLiteExecutor.EXECUTOR.submit(() -> {
+ COLUMNS.Z.name + " = ? AND " String sql = "DELETE FROM " + tables.get(0) + " WHERE "
+ COLUMNS.WORLD.name + " = ?" + COLUMNS.X.name + " = ? AND "
; + COLUMNS.Z.name + " = ? AND "
List<Object> params = new ArrayList<Object>() {{ + COLUMNS.WORLD.name + " = ?";
add(loc.getBlockX()); List<Object> params = new ArrayList<Object>() {{
add(loc.getBlockZ()); add(loc.getBlockX());
add(loc.getWorld().getName()); add(loc.getBlockZ());
}}; add(loc.getWorld().getName());
return sqlUpdate(sql, params); }};
return sqlUpdate(sql, params);
}).get();
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
} }
@Getter
public static class QueueRangeData { public static class QueueRangeData {
@Getter int xLow, xHigh; int xLow, xHigh;
@Getter int zLow, zHigh; int zLow, zHigh;
@Getter World world; World world;
public QueueRangeData(RTPWorld rtpWorld) { public QueueRangeData(RTPWorld rtpWorld) {
this.xLow = rtpWorld.getCenterX() - rtpWorld.getMaxRadius(); this.xLow = rtpWorld.getCenterX() - rtpWorld.getMaxRadius();
@@ -221,6 +180,5 @@ public class DatabaseQueue extends SQLite {
this.zHigh = rtpWorld.getCenterZ() + rtpWorld.getMaxRadius(); this.zHigh = rtpWorld.getCenterZ() + rtpWorld.getMaxRadius();
this.world = rtpWorld.getWorld(); this.world = rtpWorld.getWorld();
} }
} }
} }
@@ -0,0 +1,8 @@
package me.SuperRonanCraft.BetterRTP.references.database;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class SQLiteExecutor {
public static final ExecutorService EXECUTOR = Executors.newSingleThreadExecutor();
}
@@ -19,9 +19,6 @@ public class RTP_WorldGuard implements RegionPluginCheck {
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer(); RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery(); RegionQuery query = container.createQuery();
ApplicableRegionSet set = query.getApplicableRegions(BukkitAdapter.adapt(loc)); ApplicableRegionSet set = query.getApplicableRegions(BukkitAdapter.adapt(loc));
//for (ProtectedRegion region : set.getRegions()) {
// region.getId()
//}
result = set.size() == 0; result = set.size() == 0;
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
@@ -1,6 +1,7 @@
package me.SuperRonanCraft.BetterRTP.references.player.playerdata; package me.SuperRonanCraft.BetterRTP.references.player.playerdata;
import java.util.HashMap; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@@ -16,7 +17,7 @@ public class PlayerData {
//Menus //Menus
@Getter final PlayerData_Menus menu = new PlayerData_Menus(); @Getter final PlayerData_Menus menu = new PlayerData_Menus();
//Player Data //Player Data
@Getter final HashMap<World, CooldownData> cooldowns = new HashMap<>(); @Getter final Map<World, CooldownData> cooldowns = new ConcurrentHashMap<>();
//@Getter @Setter CooldownData globalCooldown; //@Getter @Setter CooldownData globalCooldown;
@Getter @Setter boolean rtping; @Getter @Setter boolean rtping;
@Getter @Setter int rtpCount; @Getter @Setter int rtpCount;
@@ -4,25 +4,21 @@ import lombok.NonNull;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.HashMap; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
public class PlayerDataManager { public class PlayerDataManager {
private final HashMap<Player, PlayerData> playerData = new HashMap<>(); private final Map<UUID, PlayerData> playerData = new ConcurrentHashMap<>();
public PlayerData getData(@NonNull Player p) { public PlayerData getData(@NonNull Player p) {
if (!playerData.containsKey(p)) return playerData.computeIfAbsent(p.getUniqueId(), uuid -> new PlayerData(p));
playerData.put(p, new PlayerData(p));
return playerData.get(p);
} }
@Nullable @Nullable
public PlayerData getData(UUID id) { public PlayerData getData(UUID id) {
for (Player p : playerData.keySet()) return playerData.get(id);
if (p.getUniqueId().equals(id))
return playerData.get(p);
return null;
} }
public void clear() { public void clear() {
@@ -30,6 +26,6 @@ public class PlayerDataManager {
} }
public void clear(Player p) { public void clear(Player p) {
playerData.remove(p); playerData.remove(p.getUniqueId());
} }
} }
@@ -1,8 +1,8 @@
package me.SuperRonanCraft.BetterRTP.references.rtpinfo; package me.SuperRonanCraft.BetterRTP.references.rtpinfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@@ -26,11 +26,9 @@ public class CooldownHandler {
@Getter boolean enabled, loaded, cooldownByWorld; @Getter boolean enabled, loaded, cooldownByWorld;
@Getter private int defaultCooldownTime; //Global Cooldown timer @Getter private int defaultCooldownTime; //Global Cooldown timer
private int lockedAfter; //Rtp's before being locked private int lockedAfter; //Rtp's before being locked
private final List<Player> downloading = new ArrayList<>(); private final List<Player> downloading = new CopyOnWriteArrayList<>();
//private final DatabaseCooldownsGlobal globalCooldown = new DatabaseCooldownsGlobal();
public void load() { public void load() {
//configfile = new File(BetterRTP.getInstance().getDataFolder(), "data/cooldowns.yml");
FileOther.FILETYPE config = FileOther.FILETYPE.CONFIG; FileOther.FILETYPE config = FileOther.FILETYPE.CONFIG;
enabled = config.getBoolean("Settings.Cooldown.Enabled"); enabled = config.getBoolean("Settings.Cooldown.Enabled");
downloading.clear(); downloading.clear();
@@ -54,7 +52,6 @@ public class CooldownHandler {
queueDownload(); queueDownload();
return; return;
} }
//OldCooldownConverter.loadOldCooldowns();
//Load any online players cooldowns (mostly after a reload) //Load any online players cooldowns (mostly after a reload)
for (Player p : Bukkit.getOnlinePlayers()) for (Player p : Bukkit.getOnlinePlayers())
loadPlayer(p); loadPlayer(p);
@@ -66,7 +63,7 @@ public class CooldownHandler {
if (!enabled) return; if (!enabled) return;
PlayerData playerData = getData(player); PlayerData playerData = getData(player);
if (cooldownByWorld) { if (cooldownByWorld) {
HashMap<World, CooldownData> cooldowns = playerData.getCooldowns(); Map<World, CooldownData> cooldowns = playerData.getCooldowns();
CooldownData data = cooldowns.getOrDefault(world, new CooldownData(player.getUniqueId(), 0L)); CooldownData data = cooldowns.getOrDefault(world, new CooldownData(player.getUniqueId(), 0L));
playerData.setRtpCount(playerData.getRtpCount() + 1); playerData.setRtpCount(playerData.getRtpCount() + 1);
data.setTime(System.currentTimeMillis()); data.setTime(System.currentTimeMillis());
@@ -89,7 +86,7 @@ public class CooldownHandler {
public CooldownData get(Player p, World world) { public CooldownData get(Player p, World world) {
PlayerData data = getData(p); PlayerData data = getData(p);
if (cooldownByWorld) { if (cooldownByWorld) {
HashMap<World, CooldownData> cooldownData = getData(p).getCooldowns(); Map<World, CooldownData> cooldownData = getData(p).getCooldowns();
if (data != null) if (data != null)
return cooldownData.getOrDefault(world, null); return cooldownData.getOrDefault(world, null);
} else if (data.getGlobalCooldown() > 0) { } else if (data.getGlobalCooldown() > 0) {
@@ -101,8 +98,6 @@ public class CooldownHandler {
public long timeLeft(CommandSender sendi, CooldownData data, WorldPlayer pWorld) { public long timeLeft(CommandSender sendi, CooldownData data, WorldPlayer pWorld) {
long cooldown = data.getTime(); long cooldown = data.getTime();
long timeLeft = ((cooldown / 1000) + pWorld.getCooldown()) - (System.currentTimeMillis() / 1000); long timeLeft = ((cooldown / 1000) + pWorld.getCooldown()) - (System.currentTimeMillis() / 1000);
//if (BetterRTP.getInstance().getSettings().isDelayEnabled() && !PermissionNode.BYPASS_DELAY.check(sendi))
// timeLeft = timeLeft + BetterRTP.getInstance().getSettings().getDelayTime();
return timeLeft * 1000L; return timeLeft * 1000L;
} }
@@ -116,7 +111,6 @@ public class CooldownHandler {
CooldownData cooldownData = playerData.getCooldowns().getOrDefault(world, null); CooldownData cooldownData = playerData.getCooldowns().getOrDefault(world, null);
if (cooldownData != null) { if (cooldownData != null) {
if (lockedAfter > 0) { if (lockedAfter > 0) {
//uses.put(id, uses.getOrDefault(id, 1) - 1);
if (playerData.getRtpCount() <= 0) { //Remove from file as well if (playerData.getRtpCount() <= 0) { //Remove from file as well
savePlayer(player, world, cooldownData, true); savePlayer(player, world, cooldownData, true);
getData(player).getCooldowns().put(world, null); getData(player).getCooldowns().put(world, null);
@@ -146,19 +140,31 @@ public class CooldownHandler {
} }
public void loadPlayer(Player player) { public void loadPlayer(Player player) {
if (!isEnabled()) return; if (!isEnabled()) {
downloading.add(player); return;
}
PlayerData playerData = getData(player); PlayerData playerData = getData(player);
if (getDatabaseWorlds() != null) //Per World enabled? if (playerData == null) {
for (World world : Bukkit.getWorlds()) { return;
//Cooldowns }
CooldownData cooldown = getDatabaseWorlds().getCooldown(player.getUniqueId(), world);
if (cooldown != null) downloading.add(player);
playerData.getCooldowns().put(world, cooldown);
try {
if (getDatabaseWorlds() != null) { //Per World enabled?
for (World world : Bukkit.getWorlds()) {
//Cooldowns
CooldownData cooldown = getDatabaseWorlds().getCooldown(player.getUniqueId(), world);
if (cooldown != null)
playerData.getCooldowns().put(world, cooldown);
}
} }
//Player Data //Player Data
DatabaseHandler.getPlayers().setupData(playerData); DatabaseHandler.getPlayers().setupData(playerData);
downloading.remove(player); } finally {
downloading.remove(player);
}
} }
public boolean loadedPlayer(Player player) { public boolean loadedPlayer(Player player) {
@@ -176,51 +182,3 @@ public class CooldownHandler {
return HelperPlayer.getData(p); return HelperPlayer.getData(p);
} }
} }
//Old yaml file based system, no longer useful as of 3.3.1
/*@Deprecated
static class OldCooldownConverter {
static void loadOldCooldowns() {
File file = new File(BetterRTP.getInstance().getDataFolder(), "data/cooldowns.yml");
YamlConfiguration config = getFile(file);
if (config == null) return;
if (config.getBoolean("Converted")) return;
List<CooldownData> cooldownData = new ArrayList<>();
for (String id : config.getConfigurationSection("").getKeys(false)) {
try {
Long time = config.getLong(id + ".Time");
UUID uuid = UUID.fromString(id);
int uses = config.getInt(id + ".Attempts");
cooldownData.add(new CooldownData(uuid, time, uses));
} catch (IllegalArgumentException e) {
//Invalid UUID
}
}
config.set("Converted", true);
try {
config.save(file);
} catch (IOException e) {
e.printStackTrace();
}
BetterRTP.getInstance().getLogger().info("Cooldowns converting to new database...");
Bukkit.getScheduler().runTaskAsynchronously(BetterRTP.getInstance(), () -> {
BetterRTP.getInstance().getDatabaseCooldowns().setCooldown(cooldownData);
BetterRTP.getInstance().getLogger().info("Cooldowns have been converted to the new database!");
});
}
private static YamlConfiguration getFile(File configfile) {
if (!configfile.exists()) {
return null;
}
try {
YamlConfiguration config = new YamlConfiguration();
config.load(configfile);
return config;
} catch (IOException | InvalidConfigurationException e) {
e.printStackTrace();
}
return null;
}
}*/
@@ -25,44 +25,32 @@ public class RandomLocation {
} }
private static Location generateSquare(RTPWorld rtpWorld) { private static Location generateSquare(RTPWorld rtpWorld) {
//Generate a random X and Z based off the quadrant selected // Return a Location where a random X and Z are within the bounds defined by MinRadius and MaxRadius
int min = rtpWorld.getMinRadius(); int radius_min = rtpWorld.getMinRadius();
int max = rtpWorld.getMaxRadius() - min; int radius_max = rtpWorld.getMaxRadius();
int x, z;
int quadrant = new Random().nextInt(4);
try { try {
switch (quadrant) { if (radius_min < 0 || radius_max < 0 || radius_min >= radius_max) {
case 0: // Positive X and Z throw new IllegalArgumentException(); // If MinRadius or MaxRadius is negative, throw an exception
x = new Random().nextInt(max) + min;
z = new Random().nextInt(max) + min;
break;
case 1: // Negative X and Z
x = -new Random().nextInt(max) - min;
z = -(new Random().nextInt(max) + min);
break;
case 2: // Negative X and Positive Z
x = -new Random().nextInt(max) - min;
z = new Random().nextInt(max) + min;
break;
default: // Positive X and Negative Z
x = new Random().nextInt(max) + min;
z = -(new Random().nextInt(max) + min);
break;
} }
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
e.printStackTrace(); e.printStackTrace();
BetterRTP.getInstance().getLogger().warning("A bounding location was negative! Please check your config only has positive x/z for max/min radius!"); BetterRTP.getInstance().getLogger().warning("Incorrect configuration! Check your config and confirm that MinRadius is smaller than MaxRadius and that they are both positive numbers!");
BetterRTP.getInstance().getLogger().warning("Max: " + rtpWorld.getMaxRadius() + " Min: " + rtpWorld.getMinRadius()); BetterRTP.getInstance().getLogger().warning("Max: " + rtpWorld.getMaxRadius() + " Min: " + rtpWorld.getMinRadius());
return null; return null;
} }
// Generate a random X and Z based off the radius. No quadrants voodoo.
Random random = new Random();
int x = random.nextInt(radius_max * 2) - radius_max;
int z = (Math.abs(x) >= radius_min)
? random.nextInt(radius_max * 2) - radius_max
: (random.nextBoolean() ? 1 : -1) * (radius_min + random.nextInt(radius_max - radius_min));
x += rtpWorld.getCenterX(); x += rtpWorld.getCenterX();
z += rtpWorld.getCenterZ(); z += rtpWorld.getCenterZ();
//System.out.println(quadrant);
return new Location(rtpWorld.getWorld(), x, 69, z); return new Location(rtpWorld.getWorld(), x, 69, z);
} }
private static Location generateRound(RTPWorld rtpWorld) { private static Location generateRound(RTPWorld rtpWorld) {
//Generate a random X and Z based off location on a spiral curve // Return a random X and Z based off location on a spiral curve
int min = rtpWorld.getMinRadius(); int min = rtpWorld.getMinRadius();
int max = rtpWorld.getMaxRadius() - min; int max = rtpWorld.getMaxRadius() - min;
int x, z; int x, z;
@@ -9,26 +9,21 @@ public class AsyncHandler {
public static void async(Runnable runnable) { public static void async(Runnable runnable) {
getFolia().runAsync(task -> runnable.run()); getFolia().runAsync(task -> runnable.run());
//Bukkit.getScheduler().runTaskAsynchronously(BetterRTP.getInstance(), runnable);
} }
public static void sync(Runnable runnable) { public static void sync(Runnable runnable) {
getFolia().runNextTick(task -> runnable.run()); getFolia().runNextTick(task -> runnable.run());
//Bukkit.getScheduler().runTask(BetterRTP.getInstance(), runnable);
} }
public static void syncAtEntity(Entity entity, Runnable runnable) { public static void syncAtEntity(Entity entity, Runnable runnable) {
getFolia().runAtEntity(entity, task -> runnable.run()); getFolia().runAtEntity(entity, task -> runnable.run());
//Bukkit.getScheduler().runTask(BetterRTP.getInstance(), runnable);
} }
public static WrappedTask asyncLater(Runnable runnable, long ticks) { public static WrappedTask asyncLater(Runnable runnable, long ticks) {
return getFolia().runLaterAsync(runnable, ticks); return getFolia().runLaterAsync(runnable, ticks);
//return Bukkit.getScheduler().runTaskLaterAsynchronously(BetterRTP.getInstance(), runnable, ticks);
} }
public static WrappedTask syncLater(Runnable runnable, long ticks) { public static WrappedTask syncLater(Runnable runnable, long ticks) {
return getFolia().runLater(runnable, ticks); return getFolia().runLater(runnable, ticks);
//return Bukkit.getScheduler().runTaskLater(BetterRTP.getInstance(), runnable, ticks);
} }
private static ServerImplementation getFolia() { private static ServerImplementation getFolia() {
+1 -1
View File
@@ -25,7 +25,7 @@ softdepend:
- Multiverse-Core #Forcing Multiverse to load BEFORE BetterRTP - Multiverse-Core #Forcing Multiverse to load BEFORE BetterRTP
- Essentials #adds `/back` support - Essentials #adds `/back` support
- PlaceholderAPI - PlaceholderAPI
- HuskClaims #fixed condition race which breaks hooking - HuskClaims #Respect HuskClaims areas (https://www.spigotmc.org/resources/huskclaims-1-17-1-21-modern-golden-shovel-land-claiming-fully-cross-server-compatible.114467/) (fixes race condition that breaks hooking)
api-version: '1.13' api-version: '1.13'
commands: commands: