diff --git a/pom.xml b/pom.xml
index 4abe401..05e7b8e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -113,7 +113,7 @@
com.github.BTEUK
Network
- c8a9ff8b97
+ e05f892a0e
provided
diff --git a/src/main/java/net/bteuk/plotsystem/PlotSystem.java b/src/main/java/net/bteuk/plotsystem/PlotSystem.java
index 1cfb765..b6969c7 100644
--- a/src/main/java/net/bteuk/plotsystem/PlotSystem.java
+++ b/src/main/java/net/bteuk/plotsystem/PlotSystem.java
@@ -139,9 +139,8 @@ public void enablePlugin() {
// Create list of users.
users = new ArrayList<>();
- // Remove all plots 'under review' on this server.
- plotSQL.update(
- "UPDATE plot_data AS pd INNER JOIN location_data AS ld ON ld.name=pd.location SET pd.status='submitted' WHERE pd.status='reviewing' AND ld.server='" + SERVER_NAME + "';");
+ plotSQL.update("UPDATE plot_submission AS ps INNER JOIN plot_data AS pd ON ps.plot_id=pd.id SET ps.status='submitted' WHERE ps.status='under review' AND pd.location IN (SELECT name FROM location_data WHERE server='" + SERVER_NAME + "');");
+ plotSQL.update("UPDATE plot_submission AS ps INNER JOIN plot_data AS pd ON ps.plot_id=pd.id SET ps.status='awaiting verification' WHERE ps.status='under verification' AND pd.location IN (SELECT name FROM location_data WHERE server='" + SERVER_NAME + "');");
// Create gui item
gui = new ItemStack(Material.NETHER_STAR);
@@ -188,7 +187,7 @@ public void enablePlugin() {
// Get all active plots (unclaimed, claimed, submitted, reviewing) and add holograms.
List active_plots = plotSQL.getIntList(
- "SELECT pd.id FROM plot_data AS pd INNER JOIN location_data AS ld ON ld.name=pd.location WHERE pd.status IN ('unclaimed','claimed','submitted','reviewing') AND " +
+ "SELECT pd.id FROM plot_data AS pd INNER JOIN location_data AS ld ON ld.name=pd.location WHERE pd.status IN ('unclaimed','claimed','submitted') AND " +
"ld.server='" + SERVER_NAME + "';");
active_plots.forEach(plot -> PlotHelper.addPlotHologram(new PlotHologram(plot)));
}
diff --git a/src/main/java/net/bteuk/plotsystem/commands/CreateCommand.java b/src/main/java/net/bteuk/plotsystem/commands/CreateCommand.java
index 3b0f4c8..be98b04 100644
--- a/src/main/java/net/bteuk/plotsystem/commands/CreateCommand.java
+++ b/src/main/java/net/bteuk/plotsystem/commands/CreateCommand.java
@@ -1,49 +1,23 @@
package net.bteuk.plotsystem.commands;
-import com.sk89q.worldedit.math.BlockVector3;
import net.bteuk.network.Network;
-import net.bteuk.network.eventing.events.EventManager;
import net.bteuk.network.lib.utils.ChatUtils;
-import net.bteuk.network.sql.GlobalSQL;
import net.bteuk.network.sql.PlotSQL;
import net.bteuk.network.utils.NetworkUser;
import net.bteuk.plotsystem.PlotSystem;
import net.bteuk.plotsystem.gui.CreatePlotGui;
import net.bteuk.plotsystem.gui.CreateZoneGui;
-import net.bteuk.plotsystem.utils.CopyRegionFormat;
import net.bteuk.plotsystem.utils.User;
-import net.bteuk.plotsystem.utils.plugins.Multiverse;
-import net.bteuk.plotsystem.utils.plugins.WorldEditor;
-import net.kyori.adventure.text.Component;
-import net.kyori.adventure.text.format.NamedTextColor;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import java.util.ArrayList;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-import static java.lang.Math.max;
-import static java.lang.Math.min;
-import static net.bteuk.network.utils.Constants.MAX_Y;
-import static net.bteuk.network.utils.Constants.MIN_Y;
-import static net.bteuk.plotsystem.PlotSystem.LOGGER;
-
-public class CreateCommand {
-
- private final GlobalSQL globalSQL;
- private final PlotSQL plotSQL;
-
- public CreateCommand(GlobalSQL globalSQL, PlotSQL plotSQL) {
-
- this.globalSQL = globalSQL;
- this.plotSQL = plotSQL;
+public final class CreateCommand {
+ private CreateCommand() {
+ // Do nothing
}
- public void create(CommandSender sender, String[] args) {
+ public static void create(CommandSender sender, String[] args) {
if (args.length < 2) {
@@ -54,14 +28,14 @@ public void create(CommandSender sender, String[] args) {
switch (args[1]) {
case "plot" -> createPlot(sender);
- case "location" -> createLocation(sender, args);
+ case "location" -> LocationCommand.createLocation(sender, args);
case "zone" -> createZone(sender);
default -> sender.sendMessage(ChatUtils.error("/plotsystem create [plot, location, zone]"));
}
}
- private void createPlot(CommandSender sender) {
+ private static void createPlot(CommandSender sender) {
// Check if the sender is a player
if (!(sender instanceof Player)) {
@@ -104,249 +78,7 @@ private void createPlot(CommandSender sender) {
}
- private void createLocation(CommandSender sender, String[] args) {
-
- // Check if the sender is a player.
- // If so, check if they have permission.
- if (sender instanceof Player p) {
- if (!p.hasPermission("uknet.plots.create.location")) {
-
- p.sendMessage(ChatUtils.error("You do not have permission to use this command!"));
- return;
-
- }
- }
-
- // Check if they have enough args.
- if (args.length < 9) {
-
- sender.sendMessage(ChatUtils.error("/plotsystem create location [name] "));
- return;
-
- }
-
- int xmin;
- int ymin;
- int zmin;
-
- int xmax;
- int ymax;
- int zmax;
-
- // Check if the coordinates are actual numbers.
- try {
-
- xmin = Integer.parseInt(args[3]);
- ymin = Integer.parseInt(args[4]);
- zmin = Integer.parseInt(args[5]);
-
- xmax = Integer.parseInt(args[6]);
- ymax = Integer.parseInt(args[7]);
- zmax = Integer.parseInt(args[8]);
-
- } catch (NumberFormatException e) {
-
- sender.sendMessage(ChatUtils.error("/plotsystem create location [name] "));
- return;
-
- }
-
- // Check if the location name is unique.
- if (plotSQL.hasRow("SELECT name FROM location_data WHERE name='" + args[2] + "';")) {
-
- sender.sendMessage(ChatUtils.error("The location ")
- .append(Component.text(args[2], NamedTextColor.DARK_RED))
- .append(ChatUtils.error(" already exists.")));
- return;
-
- }
-
- // Get the exact regions of the selected coordinates.
- int regionXMin = Math.floorDiv(xmin, 512);
- int regionZMin = Math.floorDiv(zmin, 512);
-
- int regionXMax = Math.floorDiv(xmax, 512);
- int regionZMax = Math.floorDiv(zmax, 512);
-
- // Calculate the coordinate transformation.
- int xTransform = -(regionXMin * 512);
- int zTransform = -(regionZMin * 512);
-
- // Create the world and add the regions.
- Multiverse.createVoidWorld(args[2]);
-
- String saveWorld = PlotSystem.getInstance().getConfig().getString("save_world");
-
- if (saveWorld == null) {
- sender.sendMessage(ChatUtils.error("The save world is not set in config."));
- return;
- }
-
- // Get worlds.
- World copy = Bukkit.getWorld(saveWorld);
- World paste = Bukkit.getWorld(args[2]);
-
- // Check that the worlds are not null, else delete the Multiverse world.
- if (copy == null || paste == null) {
-
- sender.sendMessage("An error occurred, please contact an admin.");
- Multiverse.deleteWorld(args[2]);
- return;
-
- }
-
- // Copy paste the regions in the save world.
- // Iterate through the regions one-by-one.
- // Run it asynchronously to not freeze the server.
- sender.sendMessage(ChatUtils.success("Transferring terrain, this may take a while."));
-
- // Create atomic boolean to query whether a region can be copied.
- AtomicBoolean isReady = new AtomicBoolean(true);
-
- // Create a list of regions to copy paste.
- ArrayList regions = new ArrayList<>();
-
- final int yMin = max(ymin, MIN_Y);
- final int yMax = min(ymax, MAX_Y - 1);
-
- for (int i = regionXMin; i <= regionXMax; i++) {
- for (int j = regionZMin; j <= regionZMax; j++) {
-
- // Split the region into 4 equal segments of 256x256.
- regions.add(new CopyRegionFormat(
- copy, paste,
- BlockVector3.at(i * 512, yMin, j * 512),
- BlockVector3.at(i * 512 + 255, yMax, j * 512 + 255),
- BlockVector3.at(i * 512 + xTransform, yMin, j * 512 + zTransform))
- );
-
- regions.add(new CopyRegionFormat(
- copy, paste,
- BlockVector3.at(i * 512 + 256, yMin, j * 512),
- BlockVector3.at(i * 512 + 511, yMax, j * 512 + 255),
- BlockVector3.at(i * 512 + 256 + xTransform, yMin, j * 512 + zTransform))
- );
-
- regions.add(new CopyRegionFormat(
- copy, paste,
- BlockVector3.at(i * 512, yMin, j * 512 + 256),
- BlockVector3.at(i * 512 + 255, yMax, j * 512 + 511),
- BlockVector3.at(i * 512 + xTransform, yMin, j * 512 + 256 + zTransform))
- );
-
- regions.add(new CopyRegionFormat(
- copy, paste,
- BlockVector3.at(i * 512 + 256, yMin, j * 512 + 256),
- BlockVector3.at(i * 512 + 511, yMax, j * 512 + 511),
- BlockVector3.at(i * 512 + 256 + xTransform, yMin, j * 512 + 256 + zTransform))
- );
- }
- }
-
- LOGGER.info("Add segments to list, there are " + regions.size());
- sender.sendMessage(ChatUtils.success("Added " + regions.size() + " segments of 256x256 to the list to be copied."));
-
- // Iterate until all regions are done.
- Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getInstance(), () -> {
-
- while (!regions.isEmpty()) {
-
- if (isReady.get()) {
-
- // Set isReady to false so the loop will wait until the previous copy-paste is done.
- isReady.set(false);
-
- CopyRegionFormat regionFormat = regions.getFirst();
-
- Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getInstance(), () -> {
-
- if (!WorldEditor.largeCopy(regionFormat.minPoint, regionFormat.maxPoint, regionFormat.pasteMinPoint, copy, paste)) {
- sender.sendMessage(ChatUtils.error("An error occured while transferring the terrain."));
- } else {
- regions.remove(regionFormat);
- sender.sendMessage(ChatUtils.success("Segment copied, there are ")
- .append(Component.text(regions.size(), NamedTextColor.DARK_AQUA))
- .append(ChatUtils.success(" remaining.")));
- LOGGER.info("Segment copied, there are " + regions.size() + " remaining.");
- isReady.set(true);
- }
-
- });
- }
- }
-
- sender.sendMessage(ChatUtils.success("Terrain transfer has been completed."));
-
- int coordMin = globalSQL.addCoordinate(new Location(
- Bukkit.getWorld(args[2]),
- (regionXMin * 512), MIN_Y, (regionZMin * 512), 0, 0));
-
- int coordMax = globalSQL.addCoordinate(new Location(
- Bukkit.getWorld(args[2]),
- ((regionXMax * 512) + 511), MAX_Y - 1, ((regionZMax * 512) + 511), 0, 0));
-
- // Add the location to the database.
- if (plotSQL.update("INSERT INTO location_data(name, alias, server, coordMin, coordMax, xTransform, zTransform) VALUES('"
- + args[2] + "','" + args[2] + "','" + PlotSystem.SERVER_NAME + "'," + coordMin + "," + coordMax + "," + xTransform + "," + zTransform + ");")) {
-
- sender.sendMessage(ChatUtils.success("Created new location ")
- .append(Component.text(args[2], NamedTextColor.DARK_AQUA)));
-
- // Set the status of all effected regions in the region database.
- for (int i = regionXMin; i <= regionXMax; i++) {
- for (int j = regionZMin; j <= regionZMax; j++) {
-
- String region = i + "," + j;
-
- // Change region status in region database.
- // If it already exists remove members.
- globalSQL.update("INSERT INTO server_events(uuid,type,server,event) VALUES(NULL,'network','"
- + globalSQL.getString("SELECT name FROM server_data WHERE type='EARTH';") + "'," +
- "'region set plotsystem " + region + "');");
-
- // Add region to database.
- plotSQL.update("INSERT INTO regions(region,server,location) VALUES('" + region + "','" + PlotSystem.SERVER_NAME + "','" + args[2] + "');");
-
- }
- }
-
- } else {
-
- sender.sendMessage(ChatUtils.error("An error occurred, please check the console for more info."));
- LOGGER.warning("An error occured while adding new location!");
-
- }
-
- // If sender is a player teleport them to the location.
- if (sender instanceof Player p) {
-
- // Get middle.
- double x = ((globalSQL.getDouble("SELECT x FROM coordinates WHERE id=" + coordMax + ";") +
- globalSQL.getDouble("SELECT x FROM coordinates WHERE id=" + coordMin + ";")) / 2) +
- plotSQL.getInt("SELECT xTransform FROM location_data WHERE name='" + args[2] + "';");
-
- double z = ((globalSQL.getDouble("SELECT z FROM coordinates WHERE id=" + coordMax + ";") +
- globalSQL.getDouble("SELECT z FROM coordinates WHERE id=" + coordMin + ";")) / 2) +
- plotSQL.getInt("SELECT zTransform FROM location_data WHERE name='" + args[2] + "';");
-
- // Teleport to the location.
- World world = Bukkit.getWorld(args[2]);
-
- double y = 64;
- if (world != null) {
- y = world.getHighestBlockYAt((int) x, (int) z);
- y++;
- }
-
- EventManager.createTeleportEvent(false, p.getUniqueId().toString(), "network", "teleport " + args[2] + " " + x + " " + y + " " + z + " "
- + p.getLocation().getYaw() + " " + p.getLocation().getPitch(),
- "&aTeleported to location &3" + plotSQL.getString("SELECT alias FROM location_data WHERE name='" + args[2] + "';"), p.getLocation());
- }
-
- });
- }
-
- public void createZone(CommandSender sender) {
+ public static void createZone(CommandSender sender) {
// Check if the sender is a player
if (!(sender instanceof Player)) {
@@ -375,6 +107,8 @@ public void createZone(CommandSender sender) {
}
+ PlotSQL plotSQL = Network.getInstance().getPlotSQL();
+
// If the player already has a zones, cancel, as this is the maximum.
// Lastly there is a limit of 21 total zones at a time.
if (plotSQL.hasRow("SELECT id FROM zone_members WHERE uuid='" + u.player.getUniqueId() + "' AND is_owner=1;")) {
diff --git a/src/main/java/net/bteuk/plotsystem/commands/DeleteCommand.java b/src/main/java/net/bteuk/plotsystem/commands/DeleteCommand.java
index 405123b..660c33c 100644
--- a/src/main/java/net/bteuk/plotsystem/commands/DeleteCommand.java
+++ b/src/main/java/net/bteuk/plotsystem/commands/DeleteCommand.java
@@ -8,7 +8,6 @@
import net.bteuk.plotsystem.exceptions.RegionManagerNotFoundException;
import net.bteuk.plotsystem.utils.PlotHelper;
import net.bteuk.plotsystem.utils.User;
-import net.bteuk.plotsystem.utils.plugins.Multiverse;
import net.bteuk.plotsystem.utils.plugins.WorldGuardFunctions;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
@@ -17,8 +16,6 @@
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
-import java.util.ArrayList;
-
import static net.bteuk.plotsystem.PlotSystem.LOGGER;
public class DeleteCommand {
@@ -27,10 +24,8 @@ public class DeleteCommand {
private final PlotSQL plotSQL;
public DeleteCommand(GlobalSQL globalSQL, PlotSQL plotSQL) {
-
this.globalSQL = globalSQL;
this.plotSQL = plotSQL;
-
}
public void delete(CommandSender sender, String[] args) {
@@ -51,7 +46,7 @@ public void delete(CommandSender sender, String[] args) {
case "location":
- deleteLocation(sender, args);
+ LocationCommand.deleteLocation(sender, args);
break;
case "zone":
@@ -63,7 +58,6 @@ public void delete(CommandSender sender, String[] args) {
sender.sendMessage(ChatUtils.error("/plotsystem delete [plot, location, zone]"));
}
-
}
private void deletePlot(CommandSender sender, String[] args) {
@@ -162,80 +156,4 @@ private void deletePlot(CommandSender sender, String[] args) {
e.printStackTrace();
}
}
-
- private void deleteLocation(CommandSender sender, String[] args) {
-
- // If sender is a player, check for permission.
- if (sender instanceof Player p) {
-
- if (!(p.hasPermission("uknet.plots.delete.location"))) {
- p.sendMessage(ChatUtils.error("You do not have permission to use this command."));
- return;
- }
-
- }
-
- // Check arg count.
- if (args.length < 3) {
-
- sender.sendMessage(ChatUtils.error("/plotsystem delete location [name]"));
- return;
-
- }
-
- // Check if location exists.
- if (!(plotSQL.hasRow("SELECT name FROM location_data WHERE name='" + args[2] + "';"))) {
-
- sender.sendMessage(ChatUtils.error("The location ")
- .append(Component.text(args[2], NamedTextColor.DARK_RED))
- .append(ChatUtils.error(" does not exist.")));
- return;
-
- }
-
- // Check if the location is on this server.
- if (!(plotSQL.getString("SELECT server FROM location_data WHERE name='" + args[2] + "';").equals(PlotSystem.SERVER_NAME))) {
-
- sender.sendMessage(ChatUtils.error("This location is not on this server."));
- return;
-
- }
-
- // If location has plots, cancel.
- if (plotSQL.hasRow("SELECT id FROM plot_data WHERE location='" + args[2] + "' AND status<>'completed' AND status<>'deleted';")) {
-
- sender.sendMessage(ChatUtils.error("This location active has plots, all plots must be deleted or completed to remove the location."));
- return;
-
- }
-
- // Delete location.
- if (Multiverse.deleteWorld(args[2])) {
-
- // Delete location from database.
- plotSQL.update("DELETE FROM location_data WHERE name='" + args[2] + "';");
- sender.sendMessage(ChatUtils.success("Deleted location ")
- .append(Component.text(args[2], NamedTextColor.DARK_AQUA)));
- LOGGER.info("Deleted location " + args[2] + ".");
-
- // Get regions from database.
- ArrayList regions = plotSQL.getStringList("SELECT region FROM regions WHERE location='" + args[2] + "';");
-
- // Delete regions from database.
- plotSQL.update("DELETE FROM regions WHERE location='" + args[2] + "';");
-
- // Iterate through regions to unlock them on Earth.
- for (String region : regions) {
- globalSQL.update("INSERT INTO server_events(uuid,type,server,event) VALUES(NULL,'network','"
- + globalSQL.getString("SELECT name FROM server_data WHERE type='earth';") + "'," +
- "'region set default " + region + "');");
- }
-
- } else {
-
- sender.sendMessage(ChatUtils.error("An error occurred while deleting the world."));
- LOGGER.warning("An error occurred while deleting world " + args[2] + ".");
-
- }
- }
}
diff --git a/src/main/java/net/bteuk/plotsystem/commands/LocationCommand.java b/src/main/java/net/bteuk/plotsystem/commands/LocationCommand.java
new file mode 100644
index 0000000..ca92c26
--- /dev/null
+++ b/src/main/java/net/bteuk/plotsystem/commands/LocationCommand.java
@@ -0,0 +1,528 @@
+package net.bteuk.plotsystem.commands;
+
+import com.sk89q.worldedit.math.BlockVector3;
+import net.bteuk.network.Network;
+import net.bteuk.network.eventing.events.EventManager;
+import net.bteuk.network.lib.utils.ChatUtils;
+import net.bteuk.network.sql.GlobalSQL;
+import net.bteuk.network.sql.PlotSQL;
+import net.bteuk.network.utils.Coordinate;
+import net.bteuk.network.utils.Utils;
+import net.bteuk.plotsystem.PlotSystem;
+import net.bteuk.plotsystem.utils.CopyRegionFormat;
+import net.bteuk.plotsystem.utils.plugins.Multiverse;
+import net.bteuk.plotsystem.utils.plugins.WorldEditor;
+import net.kyori.adventure.text.Component;
+import net.kyori.adventure.text.format.NamedTextColor;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.World;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static java.lang.Math.max;
+import static java.lang.Math.min;
+import static net.bteuk.network.utils.Constants.MAX_Y;
+import static net.bteuk.network.utils.Constants.MIN_Y;
+import static net.bteuk.plotsystem.PlotSystem.LOGGER;
+
+public final class LocationCommand {
+
+ private static final Component LOCATION_CREATE_COMMAND_FORMAT = ChatUtils.error("/plotsystem create location [name] ");
+ private static final Component LOCATION_UPDATE_COMMAND_FORMAT = ChatUtils.error("/plotsystem update location [name] ");
+
+ private LocationCommand() {
+ // Do nothing
+ }
+
+ public static void createLocation(CommandSender sender, String[] args) {
+
+ // Check if the sender is a player.
+ // If so, check if they have permission.
+ if (sender instanceof Player p) {
+ if (!p.hasPermission("uknet.plots.create.location")) {
+ p.sendMessage(ChatUtils.error("You do not have permission to use this command!"));
+ return;
+ }
+ }
+
+ CommandArguments commandArguments = parseCommandArguments(sender, args, LOCATION_CREATE_COMMAND_FORMAT);
+ if (commandArguments == null) {
+ return;
+ }
+
+ final PlotSQL plotSQL = Network.getInstance().getPlotSQL();
+
+ // Check if the location name is unique.
+ if (plotSQL.hasRow("SELECT name FROM location_data WHERE name='" + commandArguments.location() + "';")) {
+ sender.sendMessage(ChatUtils.error("The location ")
+ .append(Component.text(commandArguments.location(), NamedTextColor.DARK_RED))
+ .append(ChatUtils.error(" already exists.")));
+ return;
+ }
+
+ // Get the exact regions of the selected coordinates.
+ int regionXMin = Math.floorDiv(commandArguments.xmin(), 512);
+ int regionZMin = Math.floorDiv(commandArguments.zmin(), 512);
+
+ int regionXMax = Math.floorDiv(commandArguments.xmax(), 512);
+ int regionZMax = Math.floorDiv(commandArguments.zmax(), 512);
+
+ // Calculate the coordinate transformation.
+ int xTransform = -(regionXMin * 512);
+ int zTransform = -(regionZMin * 512);
+
+ // Create the world and add the regions.
+ Multiverse.createVoidWorld(commandArguments.location());
+
+ String saveWorld = PlotSystem.getInstance().getConfig().getString("save_world");
+
+ if (saveWorld == null) {
+ sender.sendMessage(ChatUtils.error("The save world is not set in config."));
+ return;
+ }
+
+ // Get worlds.
+ World copy = Bukkit.getWorld(saveWorld);
+ World paste = Bukkit.getWorld(commandArguments.location());
+
+ // Check that the worlds are not null, else delete the Multiverse world.
+ if (copy == null || paste == null) {
+ sender.sendMessage("An error occurred, please contact an admin.");
+ Multiverse.deleteWorld(commandArguments.location());
+ return;
+ }
+
+ // Determine which regions are new, only copy them.
+ List regionsToAdd = new ArrayList<>();
+ for (int i = regionXMin; i <= regionXMax; i++) {
+ for (int j = regionZMin; j <= regionZMax; j++) {
+ String region = String.format("%d,%d", i, j);
+ regionsToAdd.add(new Region(region, i, j));
+ }
+ }
+
+ // Create a list of regions to copy-paste.
+ RegionHolder regionHolder = new RegionHolder(regionsToAdd, commandArguments.ymin(), commandArguments.ymax(), copy, paste, xTransform, zTransform);
+ List regions = getCopyRegions(sender, regionHolder);
+
+ // Copy-paste the regions in the save world.
+ // Iterate through the regions one-by-one.
+ // Run it asynchronously to not freeze the server.
+ Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getInstance(), () -> {
+
+ copyRegions(sender, regions);
+
+ final GlobalSQL globalSQL = Network.getInstance().getGlobalSQL();
+
+ int coordMin = globalSQL.addCoordinate(new Location(
+ Bukkit.getWorld(commandArguments.location()),
+ (regionXMin * 512), MIN_Y, (regionZMin * 512), 0, 0));
+
+ int coordMax = globalSQL.addCoordinate(new Location(
+ Bukkit.getWorld(commandArguments.location()),
+ ((regionXMax * 512) + 511), MAX_Y - 1, ((regionZMax * 512) + 511), 0, 0));
+
+ // Add the location to the database.
+ if (plotSQL.update("INSERT INTO location_data(name, alias, server, coordMin, coordMax, xTransform, zTransform) VALUES('"
+ + commandArguments.location() + "','" + commandArguments.location() + "','" + PlotSystem.SERVER_NAME + "'," + coordMin + "," + coordMax + "," + xTransform +
+ "," + zTransform + ");")) {
+
+ sender.sendMessage(ChatUtils.success("Created new location ")
+ .append(Component.text(commandArguments.location(), NamedTextColor.DARK_AQUA)));
+
+ // Set the status of all effected regions in the region database.
+ for (int i = regionXMin; i <= regionXMax; i++) {
+ for (int j = regionZMin; j <= regionZMax; j++) {
+
+ String region = i + "," + j;
+
+ // Change region status in region database.
+ // If it already exists remove members.
+ globalSQL.update("INSERT INTO server_events(uuid,type,server,event) VALUES(NULL,'network','"
+ + globalSQL.getString("SELECT name FROM server_data WHERE type='EARTH';") + "'," +
+ "'region set plotsystem " + region + "');");
+
+ // Add region to database.
+ plotSQL.update(
+ "INSERT INTO regions(region,server,location) VALUES('" + region + "','" + PlotSystem.SERVER_NAME + "','" + commandArguments.location() + "');");
+
+ }
+ }
+
+ } else {
+
+ sender.sendMessage(ChatUtils.error("An error occurred, please check the console for more info."));
+ LOGGER.warning("An error occured while adding new location!");
+
+ }
+
+ teleportToLocation(sender, globalSQL, plotSQL, commandArguments.location(), coordMin, coordMax);
+ });
+ }
+
+ public static void updateLocation(CommandSender sender, String[] args) {
+
+ // Check if the sender is a player.
+ // If so, check if they have permission.
+ if (sender instanceof Player p) {
+ if (!p.hasPermission("uknet.plots.update.location")) {
+ p.sendMessage(ChatUtils.error("You do not have permission to use this command!"));
+ return;
+ }
+ }
+
+ CommandArguments commandArguments = parseCommandArguments(sender, args, LOCATION_UPDATE_COMMAND_FORMAT);
+ if (commandArguments == null) {
+ return;
+ }
+
+ final PlotSQL plotSQL = Network.getInstance().getPlotSQL();
+ final GlobalSQL globalSQL = Network.getInstance().getGlobalSQL();
+
+ // Check if the location name exists.
+ if (!plotSQL.hasRow("SELECT name FROM location_data WHERE name='" + commandArguments.location() + "';")) {
+ sender.sendMessage(ChatUtils.error("Location %s does not exist.", commandArguments.location()));
+ return;
+ }
+
+ // Check if the new area is equal or larger than the existing area.
+ final int minCoordinateId = plotSQL.getInt("SELECT coordMin FROM location_data WHERE name='" + commandArguments.location() + "';");
+ final int maxCoordinateId = plotSQL.getInt("SELECT coordMax FROM location_data WHERE name='" + commandArguments.location() + "';");
+
+ Coordinate minCoordinate = globalSQL.getCoordinate(minCoordinateId);
+ Coordinate maxCoordinate = globalSQL.getCoordinate(maxCoordinateId);
+
+ if (commandArguments.isSmallerThan(minCoordinate, maxCoordinate)) {
+ sender.sendMessage(ChatUtils.error("The new area must not be smaller than the current area."));
+ return;
+ }
+
+ // Get the exact regions of the selected coordinates.
+ int regionXMin = Math.floorDiv(commandArguments.xmin(), 512);
+ int regionZMin = Math.floorDiv(commandArguments.zmin(), 512);
+
+ int regionXMax = Math.floorDiv(commandArguments.xmax(), 512);
+ int regionZMax = Math.floorDiv(commandArguments.zmax(), 512);
+
+ // Get the coordinate transformation of the location.
+ int xTransform = plotSQL.getInt("SELECT xTransform FROM location_data WHERE name='" + commandArguments.location() + "';");
+ int zTransform = plotSQL.getInt("SELECT zTransform FROM location_data WHERE name='" + commandArguments.location() + "';");
+
+ // Get the worlds.
+ String saveWorld = PlotSystem.getInstance().getConfig().getString("save_world");
+ if (saveWorld == null) {
+ sender.sendMessage(ChatUtils.error("The save world is not set in config."));
+ return;
+ }
+
+ // Get worlds.
+ World copy = Bukkit.getWorld(saveWorld);
+ World paste = Bukkit.getWorld(commandArguments.location());
+
+ // Check that the worlds are not null, else delete the Multiverse world.
+ if (copy == null || paste == null) {
+ sender.sendMessage("An error occurred, please contact an admin.");
+ return;
+ }
+
+ // Determine which regions are new, only copy them.
+ List existingRegions = plotSQL.getStringList("SELECT region FROM regions WHERE location='" + commandArguments.location() + "';");
+ List regionsToAdd = new ArrayList<>();
+ for (int i = regionXMin; i <= regionXMax; i++) {
+ for (int j = regionZMin; j <= regionZMax; j++) {
+ String region = String.format("%d,%d", i, j);
+ if (!existingRegions.contains(region)) {
+ regionsToAdd.add(new Region(region, i, j));
+ }
+ }
+ }
+
+ // Create a list of regions to copy-paste.
+ RegionHolder regionHolder = new RegionHolder(regionsToAdd, (int) minCoordinate.getY(), (int) maxCoordinate.getY(), copy, paste, xTransform, zTransform);
+ List regions = getCopyRegions(sender, regionHolder);
+
+ // Copy-paste the regions in the save world.
+ // Iterate through the regions one-by-one.
+ // Run it asynchronously to not freeze the server.
+ Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getInstance(), () -> {
+
+ copyRegions(sender, regions);
+
+ globalSQL.updateCoordinate(minCoordinateId, new Location(Bukkit.getWorld(commandArguments.location()), (regionXMin * 512), MIN_Y, (regionZMin * 512), 0, 0));
+ globalSQL.updateCoordinate(maxCoordinateId,
+ new Location(Bukkit.getWorld(commandArguments.location()), ((regionXMax * 512) + 511), MAX_Y - 1, ((regionZMax * 512) + 511), 0, 0));
+
+ // Add the location to the database.
+ for (Region region : regionsToAdd) {
+ // Change region status in region database.
+ // If it already exists remove members.
+ globalSQL.update("INSERT INTO server_events(uuid,type,server,event) VALUES(NULL,'network','" + globalSQL.getString(
+ "SELECT name FROM server_data WHERE type='EARTH';") + "'," + "'region set plotsystem " + region.name() + "');");
+
+ // Add region to database.
+ plotSQL.update(
+ "INSERT INTO regions(region,server,location) VALUES('" + region.name() + "','" + PlotSystem.SERVER_NAME + "','" + commandArguments.location() + "');");
+ }
+
+ sender.sendMessage(ChatUtils.success("Updated location %s", commandArguments.location()));
+
+ teleportToLocation(sender, globalSQL, plotSQL, commandArguments.location(), minCoordinateId, maxCoordinateId);
+ });
+ }
+
+ public static void deleteLocation(CommandSender sender, String[] args) {
+
+ // If sender is a player, check for permission.
+ if (sender instanceof Player p) {
+ if (!(p.hasPermission("uknet.plots.delete.location"))) {
+ p.sendMessage(ChatUtils.error("You do not have permission to use this command."));
+ return;
+ }
+ }
+
+ // Check arg count.
+ if (args.length < 3) {
+ sender.sendMessage(ChatUtils.error("/plotsystem delete location [name]"));
+ return;
+ }
+
+ PlotSQL plotSQL = Network.getInstance().getPlotSQL();
+ GlobalSQL globalSQL = Network.getInstance().getGlobalSQL();
+
+ // Check if location exists.
+ if (!(plotSQL.hasRow("SELECT name FROM location_data WHERE name='" + args[2] + "';"))) {
+ sender.sendMessage(ChatUtils.error("The location %s does not exist.", args[2]));
+ return;
+ }
+
+ // Check if the location is on this server.
+ if (!(plotSQL.getString("SELECT server FROM location_data WHERE name='" + args[2] + "';").equals(PlotSystem.SERVER_NAME))) {
+ sender.sendMessage(ChatUtils.error("This location is not on this server."));
+ return;
+ }
+
+ // If location has plots, cancel.
+ if (plotSQL.hasRow("SELECT id FROM plot_data WHERE location='" + args[2] + "' AND status<>'completed' AND status<>'deleted';")) {
+ sender.sendMessage(ChatUtils.error("This location active has plots, all plots must be deleted or completed to remove the location."));
+ return;
+ }
+
+ // Teleport all players out of the world, so it can be deleted.
+ // Get the worlds.
+ String saveWorldName = PlotSystem.getInstance().getConfig().getString("save_world");
+ if (saveWorldName == null) {
+ sender.sendMessage(ChatUtils.error("The save world is not set in config."));
+ return;
+ }
+
+ // Get save world.
+ World saveWorld = Bukkit.getWorld(saveWorldName);
+
+ teleportPlayersFromLocation(args[2], saveWorld, plotSQL, globalSQL);
+
+ // Delete location.
+ if (Multiverse.deleteWorld(args[2])) {
+
+ // Delete location from database.
+ plotSQL.update("DELETE FROM location_data WHERE name='" + args[2] + "';");
+ sender.sendMessage(ChatUtils.success("Deleted location ")
+ .append(Component.text(args[2], NamedTextColor.DARK_AQUA)));
+ LOGGER.info("Deleted location " + args[2] + ".");
+
+ // Get regions from database.
+ ArrayList regions = plotSQL.getStringList("SELECT region FROM regions WHERE location='" + args[2] + "';");
+
+ // Delete regions from database.
+ plotSQL.update("DELETE FROM regions WHERE location='" + args[2] + "';");
+
+ // Iterate through regions to unlock them on Earth.
+ for (String region : regions) {
+ globalSQL.update("INSERT INTO server_events(uuid,type,server,event) VALUES(NULL,'network','"
+ + globalSQL.getString("SELECT name FROM server_data WHERE type='earth';") + "'," +
+ "'region set default " + region + "');");
+ }
+ } else {
+ sender.sendMessage(ChatUtils.error("An error occurred while deleting the world."));
+ LOGGER.warning("An error occurred while deleting world " + args[2] + ".");
+ }
+ }
+
+ private static CommandArguments parseCommandArguments(CommandSender sender, String[] args, Component error) {
+ // Check if they have enough args.
+ if (args.length < 9) {
+ sender.sendMessage(error);
+ return null;
+ }
+
+ int xmin;
+ int ymin;
+ int zmin;
+
+ int xmax;
+ int ymax;
+ int zmax;
+
+ // Check if the coordinates are actual numbers.
+ try {
+ xmin = Integer.parseInt(args[3]);
+ ymin = Integer.parseInt(args[4]);
+ zmin = Integer.parseInt(args[5]);
+
+ xmax = Integer.parseInt(args[6]);
+ ymax = Integer.parseInt(args[7]);
+ zmax = Integer.parseInt(args[8]);
+ } catch (NumberFormatException e) {
+ sender.sendMessage(error);
+ return null;
+ }
+
+ return new CommandArguments(args[2], xmin, ymin, zmin, xmax, ymax, zmax);
+ }
+
+ private static List getCopyRegions(CommandSender sender, RegionHolder regionHolder) {
+ List regionsToCopy = new ArrayList<>();
+
+ final int yMin = max(regionHolder.ymin(), MIN_Y);
+ final int yMax = min(regionHolder.ymax(), MAX_Y - 1);
+
+ for (Region region : regionHolder.regionsToAdd()) {
+ // Split the region into 4 equal segments of 256x256.
+ regionsToCopy.add(new CopyRegionFormat(regionHolder.copyWorld(), regionHolder.pasteWorld(), BlockVector3.at(region.regionX() * 512, yMin, region.regionZ() * 512),
+ BlockVector3.at(region.regionX() * 512 + 255, yMax, region.regionZ() * 512 + 255),
+ BlockVector3.at(region.regionX() * 512 + regionHolder.xTransform(), yMin, region.regionZ() * 512 + regionHolder.zTransform())));
+
+ regionsToCopy.add(new CopyRegionFormat(regionHolder.copyWorld(), regionHolder.pasteWorld(), BlockVector3.at(region.regionX() * 512 + 256, yMin, region.regionZ() * 512),
+ BlockVector3.at(region.regionX() * 512 + 511, yMax, region.regionZ() * 512 + 255),
+ BlockVector3.at(region.regionX() * 512 + 256 + regionHolder.xTransform(), yMin, region.regionZ() * 512 + regionHolder.zTransform())));
+
+ regionsToCopy.add(new CopyRegionFormat(regionHolder.copyWorld(), regionHolder.pasteWorld(), BlockVector3.at(region.regionX() * 512, yMin, region.regionZ() * 512 + 256),
+ BlockVector3.at(region.regionX() * 512 + 255, yMax, region.regionZ() * 512 + 511),
+ BlockVector3.at(region.regionX() * 512 + regionHolder.xTransform(), yMin, region.regionZ() * 512 + 256 + regionHolder.zTransform())));
+
+ regionsToCopy.add(
+ new CopyRegionFormat(regionHolder.copyWorld(), regionHolder.pasteWorld(), BlockVector3.at(region.regionX() * 512 + 256, yMin, region.regionZ() * 512 + 256),
+ BlockVector3.at(region.regionX() * 512 + 511, yMax, region.regionZ() * 512 + 511),
+ BlockVector3.at(region.regionX() * 512 + 256 + regionHolder.xTransform(), yMin, region.regionZ() * 512 + 256 + regionHolder.zTransform())));
+ }
+
+ LOGGER.info("Add segments to list, there are " + regionsToCopy.size());
+ sender.sendMessage(ChatUtils.success("Added " + regionsToCopy.size() + " segments of 256x256 to the list to be copied."));
+
+ return regionsToCopy;
+ }
+
+ private static void copyRegions(CommandSender sender, List regions) {
+
+ sender.sendMessage(ChatUtils.success("Transferring terrain, this may take a while."));
+ sender.sendMessage(ChatUtils.success("Please don't leave this server while this is in progress."));
+
+ // Create atomic boolean to query whether a region can be copied.
+ AtomicBoolean isReady = new AtomicBoolean(true);
+
+ while (!regions.isEmpty()) {
+ if (isReady.get()) {
+ // Set isReady to false so the loop will wait until the previous copy-paste is done.
+ isReady.set(false);
+
+ CopyRegionFormat regionFormat = regions.getFirst();
+
+ Bukkit.getScheduler().runTaskAsynchronously(PlotSystem.getInstance(), () -> {
+ if (!WorldEditor.largeCopy(regionFormat.minPoint(), regionFormat.maxPoint(), regionFormat.pasteMinPoint(), regionFormat.copyWorld(),
+ regionFormat.pasteWorld())) {
+ sender.sendMessage(ChatUtils.error("An error occured while transferring the terrain."));
+ } else {
+ regions.remove(regionFormat);
+ sender.sendMessage(ChatUtils.success("Segment copied, there are ").append(Component.text(regions.size(), NamedTextColor.DARK_AQUA))
+ .append(ChatUtils.success(" remaining.")));
+ LOGGER.info("Segment copied, there are " + regions.size() + " remaining.");
+ isReady.set(true);
+ }
+ });
+ }
+ }
+
+ sender.sendMessage(ChatUtils.success("Terrain transfer has been completed."));
+ }
+
+ private static void teleportToLocation(CommandSender sender, GlobalSQL globalSQL, PlotSQL plotSQL, String location, int coordMin, int coordMax) {
+ // If sender is a player teleport them to the location.
+ if (sender instanceof Player p) {
+
+ // Get middle.
+ double x = ((globalSQL.getDouble("SELECT x FROM coordinates WHERE id=" + coordMax + ";") +
+ globalSQL.getDouble("SELECT x FROM coordinates WHERE id=" + coordMin + ";")) / 2) +
+ plotSQL.getInt("SELECT xTransform FROM location_data WHERE name='" + location + "';");
+
+ double z = ((globalSQL.getDouble("SELECT z FROM coordinates WHERE id=" + coordMax + ";") +
+ globalSQL.getDouble("SELECT z FROM coordinates WHERE id=" + coordMin + ";")) / 2) +
+ plotSQL.getInt("SELECT zTransform FROM location_data WHERE name='" + location + "';");
+
+ // Teleport to the location.
+ World world = Bukkit.getWorld(location);
+
+ double y = 64;
+ if (world != null) {
+ y = world.getHighestBlockYAt((int) x, (int) z);
+ y++;
+ }
+
+ EventManager.createTeleportEvent(false, p.getUniqueId().toString(), "network", "teleport " + location + " " + x + " " + y + " " + z + " "
+ + p.getLocation().getYaw() + " " + p.getLocation().getPitch(),
+ "&aTeleported to location &3" + plotSQL.getString("SELECT alias FROM location_data WHERE name='" + location + "';"), p.getLocation());
+ }
+ }
+
+ private static void teleportPlayersFromLocation(String location, World saveWorld, PlotSQL plotSQL, GlobalSQL globalSQL) {
+ int coordMin = plotSQL.getInt("SELECT coordMin FROM location_data WHERE name='" + location + "';");
+ int coordMax = plotSQL.getInt("SELECT coordMax FROM location_data WHERE name='" + location + "';");
+
+ // Get middle.
+ double x = ((globalSQL.getDouble("SELECT x FROM coordinates WHERE id=" + coordMax + ";") +
+ globalSQL.getDouble("SELECT x FROM coordinates WHERE id=" + coordMin + ";")) / 2) +
+ plotSQL.getInt("SELECT xTransform FROM location_data WHERE name='" + location + "';");
+
+ double z = ((globalSQL.getDouble("SELECT z FROM coordinates WHERE id=" + coordMax + ";") +
+ globalSQL.getDouble("SELECT z FROM coordinates WHERE id=" + coordMin + ";")) / 2) +
+ plotSQL.getInt("SELECT zTransform FROM location_data WHERE name='" + location + "';");
+
+ x -= plotSQL.getInt("SELECT xTransform FROM location_data WHERE name='" + location + "';");
+ z -= plotSQL.getInt("SELECT zTransform FROM location_data WHERE name='" + location + "';");
+
+ // Teleport all players away from the location.
+ Location teleportLocation = new Location(saveWorld, x, Utils.getHighestYAt(saveWorld, (int) x, (int) z), z);
+ PlotSystem.getInstance().getServer().getOnlinePlayers().forEach(player -> {
+ player.teleport(teleportLocation);
+ player.sendMessage(ChatUtils.success("Teleported to save world, location %s is being deleted.", location));
+ });
+ }
+
+ private record CommandArguments(String location, int xmin, int ymin, int zmin, int xmax, int ymax, int zmax) {
+
+ /**
+ * Checks whether the area defined by the command arguments is smaller than the area defined by the given coordinates.
+ *
+ * @param coordMin the min coordinate
+ * @param coordMax the max coordinate
+ * @return whether the area is smaller than the input coordinates
+ */
+ private boolean isSmallerThan(Coordinate coordMin, Coordinate coordMax) {
+ boolean smaller = coordMin == null || coordMax == null;
+ smaller = smaller || (xmin > coordMin.getX());
+ smaller = smaller || (zmin > coordMin.getZ());
+ smaller = smaller || (xmax < coordMax.getX());
+ smaller = smaller || (zmax < coordMax.getZ());
+ return smaller;
+ }
+ }
+
+ private record Region(String name, int regionX, int regionZ) {
+ }
+
+ private record RegionHolder(List regionsToAdd, int ymin, int ymax, World copyWorld, World pasteWorld, int xTransform, int zTransform) {
+ }
+}
diff --git a/src/main/java/net/bteuk/plotsystem/commands/PlotSystemCommand.java b/src/main/java/net/bteuk/plotsystem/commands/PlotSystemCommand.java
index bbf3df9..4d937a0 100644
--- a/src/main/java/net/bteuk/plotsystem/commands/PlotSystemCommand.java
+++ b/src/main/java/net/bteuk/plotsystem/commands/PlotSystemCommand.java
@@ -29,7 +29,7 @@ public PlotSystemCommand(GlobalSQL globalSQL, PlotSQL plotSQL) {
this.plotSQL = plotSQL;
this.globalSQL = globalSQL;
- setTabCompleter(new FixedArgSelector(Arrays.asList("create", "selectiontool", "delete", "help", "setalias", "movemarker"), 0));
+ setTabCompleter(new FixedArgSelector(Arrays.asList("create", "selectiontool", "delete", "help", "setalias", "movemarker", "update"), 0));
}
@Override
@@ -46,14 +46,12 @@ public void execute(CommandSourceStack stack, String[] args) {
switch (args[0]) {
case "selectiontool" -> selectionTool(sender);
- case "create" -> {
- CreateCommand createCommand = new CreateCommand(globalSQL, plotSQL);
- createCommand.create(sender, args);
- }
+ case "create" -> CreateCommand.create(sender, args);
case "delete" -> {
DeleteCommand deleteCommand = new DeleteCommand(globalSQL, plotSQL);
deleteCommand.delete(sender, args);
}
+ case "update" -> UpdateCommand.update(sender, args);
case "help" -> help(sender);
case "setalias" -> {
diff --git a/src/main/java/net/bteuk/plotsystem/commands/UpdateCommand.java b/src/main/java/net/bteuk/plotsystem/commands/UpdateCommand.java
new file mode 100644
index 0000000..277e3e7
--- /dev/null
+++ b/src/main/java/net/bteuk/plotsystem/commands/UpdateCommand.java
@@ -0,0 +1,84 @@
+package net.bteuk.plotsystem.commands;
+
+import net.bteuk.network.Network;
+import net.bteuk.network.lib.enums.PlotDifficulties;
+import net.bteuk.network.lib.utils.ChatUtils;
+import net.bteuk.network.sql.PlotSQL;
+import net.bteuk.plotsystem.PlotSystem;
+import net.kyori.adventure.text.Component;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+public final class UpdateCommand {
+
+ private static final Component GENERIC_ERROR_MESSAGE = ChatUtils.error("/plotsystem update [plot, location]");
+
+ private static final Component PLOT_ERROR_MESSAGE = ChatUtils.error("/plotsystem update plot set difficulty [easy|normal|hard]");
+
+ private UpdateCommand() {
+ // Do nothing
+ }
+
+ public static void update(CommandSender sender, String[] args) {
+
+ if (args.length < 2) {
+ sender.sendMessage(GENERIC_ERROR_MESSAGE);
+ return;
+ }
+
+ switch (args[1]) {
+ case "plot" -> updatePlot(sender, args);
+ case "location" -> LocationCommand.updateLocation(sender, args);
+ default -> sender.sendMessage(GENERIC_ERROR_MESSAGE);
+ }
+ }
+
+ private static void updatePlot(CommandSender sender, String[] args) {
+ // Check if the sender is a player.
+ // If so, check if they have permission.
+ if (sender instanceof Player p) {
+ if (!p.hasPermission("uknet.plots.update.plot")) {
+ p.sendMessage(ChatUtils.error("You do not have permission to use this command!"));
+ return;
+ }
+ }
+
+ // Check if they have enough args and that the correct args have been given.
+ if (args.length < 6 || !args[3].equalsIgnoreCase("set") || !args[4].equalsIgnoreCase("difficulty")) {
+ sender.sendMessage(PLOT_ERROR_MESSAGE);
+ return;
+ }
+
+ int plotID;
+ try {
+ plotID = Integer.parseInt(args[2]);
+ } catch (NumberFormatException e) {
+ sender.sendMessage(PLOT_ERROR_MESSAGE);
+ return;
+ }
+
+ // Check if a valid difficulty was selected.
+ PlotDifficulties plotDifficulty;
+ try {
+ plotDifficulty = PlotDifficulties.valueOf(args[5].toUpperCase());
+ } catch (IllegalArgumentException e) {
+ sender.sendMessage(PLOT_ERROR_MESSAGE);
+ return;
+ }
+
+ PlotSQL plotSQL = Network.getInstance().getPlotSQL();
+
+ // Check if plot exists.
+ if (!plotSQL.hasRow("SELECT id FROM plot_data WHERE id=" + plotID + " AND status IN ('unclaimed','claimed','submitted');")) {
+ sender.sendMessage(ChatUtils.error("Plot %s does not exist.", args[2]));
+ return;
+ }
+
+ // Update the plot difficulty.
+ plotSQL.update("UPDATE plot_data SET difficulty=" + plotDifficulty.getValue() + " WHERE id=" + plotID + ";");
+ sender.sendMessage(ChatUtils.success("Updated difficulty of plot %s to %s.", args[2], args[5]));
+
+ // Update the plot outlines.
+ PlotSystem.getInstance().getUsers().forEach(PlotSystem.getInstance().getOutlines()::addNearbyOutlines);
+ }
+}
diff --git a/src/main/java/net/bteuk/plotsystem/events/TeleportEvent.java b/src/main/java/net/bteuk/plotsystem/events/TeleportEvent.java
index fbb6200..03958bc 100644
--- a/src/main/java/net/bteuk/plotsystem/events/TeleportEvent.java
+++ b/src/main/java/net/bteuk/plotsystem/events/TeleportEvent.java
@@ -11,6 +11,7 @@
import net.bteuk.plotsystem.exceptions.RegionNotFoundException;
import net.bteuk.plotsystem.utils.User;
import net.bteuk.plotsystem.utils.plugins.WorldGuardFunctions;
+import org.apache.commons.lang3.StringUtils;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.World;
@@ -50,11 +51,16 @@ public static void event(String uuid, String[] event) {
// If the plot is on the current server teleport them directly.
// Else teleport them to the correct server and them teleport them to the plot.
- if (server.equals(SERVER_NAME)) {
+ if (StringUtils.equals(server, SERVER_NAME)) {
// Get world of plot.
World world = Bukkit.getWorld(u.plotSQL.getString("SELECT location FROM plot_data WHERE id=" + id + ";"));
+ if (world == null) {
+ u.player.sendMessage(ChatUtils.error("An error occurred while teleporting to plot %s", String.valueOf(id)));
+ return;
+ }
+
// Get the plot status
PlotStatus status = PlotStatus.fromDatabaseValue(u.plotSQL.getString("SELECT status FROM plot_data WHERE id=" + id + ";"));
if (status == PlotStatus.COMPLETED) {
@@ -72,6 +78,11 @@ public static void event(String uuid, String[] event) {
}
double x = sumX / (double) corners.length;
double z = sumZ / (double) corners.length;
+
+ // Add the coordinate transform to find the location in the build world.
+ x += u.plotSQL.getInt("SELECT xTransform FROM location_data WHERE name='" + world.getName() + "';");
+ z += u.plotSQL.getInt("SELECT zTransform FROM location_data WHERE name='" + world.getName() + "';");
+
Location l = new Location(world, x, Utils.getHighestYAt(world, (int) x, (int) z), z);
PaperLib.teleportAsync(u.player, l);
} else {
@@ -146,5 +157,4 @@ public static void event(String uuid, String[] event) {
}
}
-
}
diff --git a/src/main/java/net/bteuk/plotsystem/utils/CopyRegionFormat.java b/src/main/java/net/bteuk/plotsystem/utils/CopyRegionFormat.java
index 719666e..5ac423a 100644
--- a/src/main/java/net/bteuk/plotsystem/utils/CopyRegionFormat.java
+++ b/src/main/java/net/bteuk/plotsystem/utils/CopyRegionFormat.java
@@ -3,25 +3,4 @@
import com.sk89q.worldedit.math.BlockVector3;
import org.bukkit.World;
-public class CopyRegionFormat {
-
- public final World copyWorld;
- public final World pasteWorld;
-
- public final BlockVector3 minPoint;
- public final BlockVector3 maxPoint;
-
- public final BlockVector3 pasteMinPoint;
-
- public CopyRegionFormat(World copyWorld, World pasteWorld, BlockVector3 minPoint, BlockVector3 maxPoint, BlockVector3 pasteMinPoint) {
-
- this.copyWorld = copyWorld;
- this.pasteWorld = pasteWorld;
-
- this.minPoint = minPoint;
- this.maxPoint = maxPoint;
-
- this.pasteMinPoint = pasteMinPoint;
-
- }
-}
+public record CopyRegionFormat(World copyWorld, World pasteWorld, BlockVector3 minPoint, BlockVector3 maxPoint, BlockVector3 pasteMinPoint) {}
diff --git a/src/main/java/net/bteuk/plotsystem/utils/SelectionTool.java b/src/main/java/net/bteuk/plotsystem/utils/SelectionTool.java
index 08cdb46..4a64d43 100644
--- a/src/main/java/net/bteuk/plotsystem/utils/SelectionTool.java
+++ b/src/main/java/net/bteuk/plotsystem/utils/SelectionTool.java
@@ -252,14 +252,15 @@ public void createPlot() {
// Create the plot.
if (createPlot(u.player, world, location, vector, plotSQL, size, difficulty)) {
- // Store plot bounds.
+ int xTransform = plotSQL.getInt("SELECT xTransform FROM location_data WHERE name='" + location + "';");
+ int zTransform = plotSQL.getInt("SELECT zTransform FROM location_data WHERE name='" + location + "';");
+
+ // Store the plot corners with coordinate transform.
int i = 1;
for (BlockVector2 point : vector) {
-
plotSQL.update("INSERT INTO plot_corners(id,corner,x,z) VALUES(" +
- plotID + "," + i + "," + point.getX() + "," + point.getZ() + ");");
+ plotID + "," + i + "," + (point.getX() - xTransform) + "," + (point.getZ() - zTransform) + ");");
i++;
-
}
// Send feedback.
diff --git a/src/main/java/net/bteuk/plotsystem/utils/plugins/Multiverse.java b/src/main/java/net/bteuk/plotsystem/utils/plugins/Multiverse.java
index a5ce15e..95ffebc 100644
--- a/src/main/java/net/bteuk/plotsystem/utils/plugins/Multiverse.java
+++ b/src/main/java/net/bteuk/plotsystem/utils/plugins/Multiverse.java
@@ -72,6 +72,9 @@ public static boolean createVoidWorld(String name) {
// Disable random tick.
world.setGameRule(GameRule.RANDOM_TICK_SPEED, 0);
+ // Disable wandering traders.
+ world.setGameRule(GameRule.DO_TRADER_SPAWNING, false);
+
// Get worldguard.
WorldGuard wg = WorldGuard.getInstance();
RegionManager regions = wg.getPlatform().getRegionContainer().get(BukkitAdapter.adapt(world));
diff --git a/src/main/resources/paper-plugin.yml b/src/main/resources/paper-plugin.yml
index a017cda..0706d5c 100644
--- a/src/main/resources/paper-plugin.yml
+++ b/src/main/resources/paper-plugin.yml
@@ -1,7 +1,7 @@
name: PlotSystem
version: '${project.version}'
main: net.bteuk.plotsystem.PlotSystem
-api-version: '1.21.1'
+api-version: '1.21.4'
dependencies:
server: