diff --git a/pom.xml b/pom.xml
index c75ffd4..b6eac05 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.modnmetl
virtualrealty
- 2.5.6
+ 2.6.0
jar
A plot creation and management plugin for Minecraft
diff --git a/src/main/java/com/modnmetl/virtualrealty/VirtualRealty.java b/src/main/java/com/modnmetl/virtualrealty/VirtualRealty.java
index 8b58d2b..35a4369 100644
--- a/src/main/java/com/modnmetl/virtualrealty/VirtualRealty.java
+++ b/src/main/java/com/modnmetl/virtualrealty/VirtualRealty.java
@@ -6,6 +6,7 @@
import com.modnmetl.virtualrealty.commands.plot.PlotCommand;
import com.modnmetl.virtualrealty.commands.vrplot.VirtualRealtyCommand;
import com.modnmetl.virtualrealty.configs.*;
+import com.modnmetl.virtualrealty.listener.player.PlayerListener;
import com.modnmetl.virtualrealty.model.plot.PlotSize;
import com.modnmetl.virtualrealty.model.other.ServerVersion;
import com.modnmetl.virtualrealty.exception.MaterialMatchException;
@@ -46,6 +47,7 @@
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.logging.Level;
+import java.util.stream.Collectors;
public final class VirtualRealty extends JavaPlugin {
@@ -149,6 +151,7 @@ public void onEnable() {
loadDynMapHook();
registerCommands();
loadCommandsConfiguration();
+ updateCommandsConfig();
registerListeners();
registerPlaceholders();
debug("Server version: " + this.getServer().getBukkitVersion() + " | " + this.getServer().getVersion());
@@ -190,6 +193,43 @@ public void registerPlaceholders() {
debug("Registered new placeholders");
}
+ private void updateCommandsConfig() {
+ {
+ List messages = VirtualRealty.getCommands().plotCommandsHelp.get("plot");
+ Set subCommands = VirtualRealty.getCommands().plotAliases.getAliasesMap().keySet();
+ List missingSubCommands = subCommands.stream()
+ .filter(subCommand -> messages
+ .stream()
+ .noneMatch(helpMessage -> helpMessage.contains("%" + subCommand + "_command%"))
+ ).collect(Collectors.toList());
+ for (String subCommand : missingSubCommands) {
+ PlotCommand.HELP_LIST.stream()
+ .filter(helpMessage -> helpMessage.contains("%" + subCommand + "_command%"))
+ .forEach(messages::add);
+ }
+ if (!missingSubCommands.isEmpty()) {
+ VirtualRealty.getCommands().save();
+ }
+ }
+ {
+ List messages = VirtualRealty.getCommands().vrplotCommandsHelp.get("vrplot");
+ Set subCommands = VirtualRealty.getCommands().vrplotAliases.keySet();
+ List missingSubCommands = subCommands.stream()
+ .filter(subCommand -> messages
+ .stream()
+ .noneMatch(helpMessage -> helpMessage.contains("%" + subCommand + "_command%"))
+ ).collect(Collectors.toList());
+ for (String subCommand : missingSubCommands) {
+ VirtualRealtyCommand.HELP_LIST.stream()
+ .filter(helpMessage -> helpMessage.contains("%" + subCommand + "_command%"))
+ .forEach(messages::add);
+ }
+ if (!missingSubCommands.isEmpty()) {
+ VirtualRealty.getCommands().save();
+ }
+ }
+ }
+
public void checkUpdates() {
String[] currentVersionNumbers = this.getDescription().getVersion().split("\\.");
String[] updateCheck = UpdateChecker.getUpdate();
@@ -332,6 +372,7 @@ public void registerSubCommands(Class> mainCommandClass, String... names) {
private void registerListeners() {
new BorderProtectionListener(this);
+ new PlayerListener(this);
new PlotProtectionListener(this);
new WorldProtectionListener(this);
new PlotEntranceListener(this);
diff --git a/src/main/java/com/modnmetl/virtualrealty/commands/CommandManager.java b/src/main/java/com/modnmetl/virtualrealty/commands/CommandManager.java
index 1725bc6..8b30a1c 100644
--- a/src/main/java/com/modnmetl/virtualrealty/commands/CommandManager.java
+++ b/src/main/java/com/modnmetl/virtualrealty/commands/CommandManager.java
@@ -409,6 +409,19 @@ public List onTabComplete(@NotNull CommandSender sender, @NotNull Comman
}
break;
}
+ case "LEAVE": {
+ if (args.length == 2) {
+ String trim = finalArgs[1].trim();
+ PlotManager.getInstance().getMembershipPlots(player.getUniqueId()).forEach((integer, plot) -> {
+ if (trim.isEmpty()) {
+ tabCompleter.add(String.valueOf(plot.getID()));
+ } else if (String.valueOf(plot.getID()).toLowerCase().startsWith(trim.toLowerCase())) {
+ tabCompleter.add(String.valueOf(plot.getID()));
+ }
+ });
+ }
+ return tabCompleter;
+ }
case "KICK": {
if (args.length == 2) {
PlotManager.getInstance().getAccessPlots(player.getUniqueId()).forEach((integer, plot) -> {
@@ -422,7 +435,13 @@ public List onTabComplete(@NotNull CommandSender sender, @NotNull Comman
return tabCompleter;
}
if (args.length == 3) {
- Plot plot = PlotManager.getInstance().getPlot(Integer.parseInt(args[1]));
+ String arg = args[1];
+ try {
+ Integer.parseInt(arg.trim());
+ } catch (NumberFormatException e) {
+ return tabCompleter;
+ }
+ Plot plot = PlotManager.getInstance().getPlot(Integer.parseInt(arg));
if (plot == null) return null;
for (OfflinePlayer offlinePlayer : plot.getPlayerMembers()) {
if (Objects.equals(offlinePlayer.getName(), player.getName())) continue;
diff --git a/src/main/java/com/modnmetl/virtualrealty/commands/SubCommand.java b/src/main/java/com/modnmetl/virtualrealty/commands/SubCommand.java
index 1b55ab9..cda598e 100644
--- a/src/main/java/com/modnmetl/virtualrealty/commands/SubCommand.java
+++ b/src/main/java/com/modnmetl/virtualrealty/commands/SubCommand.java
@@ -1,7 +1,6 @@
package com.modnmetl.virtualrealty.commands;
import com.modnmetl.virtualrealty.VirtualRealty;
-import com.modnmetl.virtualrealty.commands.vrplot.VirtualRealtyCommand;
import com.modnmetl.virtualrealty.model.other.CommandType;
import com.modnmetl.virtualrealty.exception.FailedCommandException;
import com.modnmetl.virtualrealty.exception.InsufficientPermissionsException;
@@ -11,12 +10,12 @@
import lombok.Setter;
import lombok.SneakyThrows;
import org.bukkit.command.Command;
-import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import java.lang.reflect.Method;
import java.util.LinkedList;
+import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -27,7 +26,7 @@ public abstract class SubCommand {
private final String[] args;
private final CommandSender commandSender;
@Getter
- public LinkedList HELP_LIST;
+ public LinkedList helpMessages;
private final boolean bypass;
@Getter
@Setter
@@ -37,15 +36,15 @@ public abstract class SubCommand {
public SubCommand() {
this.args = null;
this.commandSender = null;
- this.HELP_LIST = null;
+ this.helpMessages = null;
this.bypass = false;
this.alias = null;
}
@SneakyThrows
- public SubCommand(CommandSender sender, Command command, String label, String[] args, boolean bypass, LinkedList HELP_LIST) throws FailedCommandException {
+ public SubCommand(CommandSender sender, Command command, String label, String[] args, boolean bypass, LinkedList helpMessages) throws FailedCommandException {
this.args = args;
- this.HELP_LIST = HELP_LIST;
+ this.helpMessages = helpMessages;
this.commandSender = sender;
this.bypass = bypass;
this.alias = null;
@@ -53,9 +52,9 @@ public SubCommand(CommandSender sender, Command command, String label, String[]
}
@SneakyThrows
- public SubCommand(CommandSender sender, Command command, String label, String[] args, LinkedList HELP_LIST) throws FailedCommandException {
+ public SubCommand(CommandSender sender, Command command, String label, String[] args, LinkedList helpMessages) throws FailedCommandException {
this.args = args;
- this.HELP_LIST = HELP_LIST;
+ this.helpMessages = helpMessages;
this.commandSender = sender;
this.bypass = false;
this.alias = null;
@@ -140,7 +139,13 @@ public void printHelp(CommandType commandType) throws FailedCommandException {
}
String subCommandName = getSubCommandName();
String keyByValue = MapUtils.getKeyByValue(commandsAliases, subCommandName);
- for (String s : commandsHelp.get(keyByValue)) {
+ List subCommandHelpMessages = commandsHelp.get(keyByValue);
+ if (subCommandHelpMessages == null) {
+ commandsHelp.put(subCommandName, getHelpMessages());
+ subCommandHelpMessages = getHelpMessages();
+ VirtualRealty.getCommands().save();
+ }
+ for (String s : subCommandHelpMessages) {
String message = s.replaceAll("%command%", subCommandName);
ChatMessage.of(message).send(commandSender);
}
diff --git a/src/main/java/com/modnmetl/virtualrealty/commands/plot/PlotCommand.java b/src/main/java/com/modnmetl/virtualrealty/commands/plot/PlotCommand.java
index d3b608d..b26c6d0 100644
--- a/src/main/java/com/modnmetl/virtualrealty/commands/plot/PlotCommand.java
+++ b/src/main/java/com/modnmetl/virtualrealty/commands/plot/PlotCommand.java
@@ -15,6 +15,7 @@
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.logging.Level;
+import java.util.stream.Collectors;
public class PlotCommand implements CommandExecutor {
@@ -28,6 +29,7 @@ public class PlotCommand implements CommandExecutor {
HELP_LIST.add(" §a/plot %gm_command% §8- §7Changes gamemode");
HELP_LIST.add(" §a/plot %add_command% §8- §7Adds a member");
HELP_LIST.add(" §a/plot %kick_command% §8- §7Kicks a member");
+ HELP_LIST.add(" §a/plot %leave_command% §8- §7Leaves a plot");
HELP_LIST.add(" §a/plot %list_command% §8- §7Shows your plots");
HELP_LIST.add(" §a/plot %tp_command% §8- §7Teleports to the plot");
}
@@ -81,7 +83,7 @@ public boolean onCommand(CommandSender sender, Command command, String label, St
private static void printHelp(CommandSender sender) {
for (String message : VirtualRealty.getCommands().plotCommandsHelp.get("plot")) {
- final String[] finalMessage = { message };
+ final String[] finalMessage = {message};
CommandRegistry.PLOT_PLACEHOLDERS.forEach((s, s2) -> {
finalMessage[0] = finalMessage[0].replaceAll(s, s2);
});
diff --git a/src/main/java/com/modnmetl/virtualrealty/commands/plot/subcommand/LeaveSubCommand.java b/src/main/java/com/modnmetl/virtualrealty/commands/plot/subcommand/LeaveSubCommand.java
new file mode 100644
index 0000000..a230d56
--- /dev/null
+++ b/src/main/java/com/modnmetl/virtualrealty/commands/plot/subcommand/LeaveSubCommand.java
@@ -0,0 +1,70 @@
+package com.modnmetl.virtualrealty.commands.plot.subcommand;
+
+import com.modnmetl.virtualrealty.VirtualRealty;
+import com.modnmetl.virtualrealty.commands.SubCommand;
+import com.modnmetl.virtualrealty.exception.FailedCommandException;
+import com.modnmetl.virtualrealty.manager.PlotManager;
+import com.modnmetl.virtualrealty.model.other.ChatMessage;
+import com.modnmetl.virtualrealty.model.other.CommandType;
+import com.modnmetl.virtualrealty.model.permission.ManagementPermission;
+import com.modnmetl.virtualrealty.model.plot.Plot;
+import com.modnmetl.virtualrealty.model.plot.PlotMember;
+import org.bukkit.Bukkit;
+import org.bukkit.OfflinePlayer;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+
+import java.time.LocalDateTime;
+import java.util.LinkedList;
+
+public class LeaveSubCommand extends SubCommand {
+
+ public static LinkedList HELP = new LinkedList<>();
+
+ static {
+ HELP.add(" ");
+ HELP.add(" §8§l«§8§m §8[§aVirtualRealty§8]§m §8§l»");
+ HELP.add(" §a/plot %command% §8<§7plot§8>");
+ }
+
+ public LeaveSubCommand() {}
+
+ public LeaveSubCommand(CommandSender sender, Command command, String label, String[] args) throws FailedCommandException {
+ super(sender, command, label, args, HELP);
+ }
+
+ @Override
+ public void exec(CommandSender sender, Command command, String label, String[] args) throws FailedCommandException {
+ assertPlayer();
+ Player player = ((Player) sender);
+ if (args.length < 2) {
+ printHelp(CommandType.PLOT);
+ return;
+ }
+ int plotID;
+ try {
+ plotID = Integer.parseInt(args[1]);
+ } catch (IllegalArgumentException e) {
+ ChatMessage.of(VirtualRealty.getMessages().useNaturalNumbersOnly).sendWithPrefix(sender);
+ return;
+ }
+ Plot plot = PlotManager.getInstance().getPlot(plotID);
+ if (plot == null) {
+ ChatMessage.of(VirtualRealty.getMessages().noPlotFound).sendWithPrefix(sender);
+ return;
+ }
+ if (!plot.hasMembershipAccess(player.getUniqueId())) {
+ ChatMessage.of(VirtualRealty.getMessages().notYourPlot).sendWithPrefix(sender);
+ return;
+ }
+ PlotMember plotMember = plot.getMember(player.getUniqueId());
+ if (plot.getOwnedBy().equals(player.getUniqueId())) {
+ ChatMessage.of(VirtualRealty.getMessages().cantLeaveOwnPlot).sendWithPrefix(sender);
+ return;
+ }
+ plot.removeMember(plotMember);
+ ChatMessage.of(VirtualRealty.getMessages().plotLeave.replaceAll("%plot_id%", String.valueOf(plot.getID()))).sendWithPrefix(sender);
+ }
+
+}
diff --git a/src/main/java/com/modnmetl/virtualrealty/commands/plot/subcommand/TpSubCommand.java b/src/main/java/com/modnmetl/virtualrealty/commands/plot/subcommand/TpSubCommand.java
index 401123a..8a572d2 100644
--- a/src/main/java/com/modnmetl/virtualrealty/commands/plot/subcommand/TpSubCommand.java
+++ b/src/main/java/com/modnmetl/virtualrealty/commands/plot/subcommand/TpSubCommand.java
@@ -53,10 +53,6 @@ public void exec(CommandSender sender, Command command, String label, String[] a
ChatMessage.of(VirtualRealty.getMessages().notYourPlot).sendWithPrefix(sender);
return;
}
- if (plot.isOwnershipExpired()) {
- ChatMessage.of(VirtualRealty.getMessages().ownershipExpired).sendWithPrefix(sender);
- return;
- }
plot.teleportPlayer(player);
ChatMessage.of(VirtualRealty.getMessages().teleportedToPlot).sendWithPrefix(sender);
}
diff --git a/src/main/java/com/modnmetl/virtualrealty/configs/CommandsConfiguration.java b/src/main/java/com/modnmetl/virtualrealty/configs/CommandsConfiguration.java
index a999411..75ea78f 100644
--- a/src/main/java/com/modnmetl/virtualrealty/configs/CommandsConfiguration.java
+++ b/src/main/java/com/modnmetl/virtualrealty/configs/CommandsConfiguration.java
@@ -28,7 +28,6 @@ public class CommandsConfiguration extends OkaeriConfig {
public Map> vrplotCommandsHelp = getCommandsHelp(CommandType.VRPLOT);
-
@Names(strategy = NameStrategy.HYPHEN_CASE)
public static class PlotAliases extends OkaeriConfig {
@@ -37,6 +36,7 @@ public static class PlotAliases extends OkaeriConfig {
public String gm = "gm";
public String info = "info";
public String kick = "kick";
+ public String leave = "leave";
public String list = "list";
public String tp = "tp";
diff --git a/src/main/java/com/modnmetl/virtualrealty/configs/MessagesConfiguration.java b/src/main/java/com/modnmetl/virtualrealty/configs/MessagesConfiguration.java
index 32de2f7..7b4beb5 100644
--- a/src/main/java/com/modnmetl/virtualrealty/configs/MessagesConfiguration.java
+++ b/src/main/java/com/modnmetl/virtualrealty/configs/MessagesConfiguration.java
@@ -58,6 +58,10 @@ public class MessagesConfiguration extends OkaeriConfig {
public String noPlotFound = "§cCouldn't get plot with specified ID!";
public String notYourPlot = "§cIt's not your plot!";
public String ownershipExpired = "§cYour ownership has expired!";
+ public String ownershipExpiredJoinMessage = "§cYour %plot_size% plot %plot_id% has expired!";
+ public String daysUntilExpirationThresholdMessage = "§6Your %plot_size% plot %plot_id% is due to expire in %days% days and %hours% hours," +
+ " use another plot claim item of the same size type while standing inside it to extend its lease," +
+ " or it could be claimed by another player after that time!";
public String teleportedToPlot = "§aYou have been teleported to the plot!";
public String gamemodeFeatureDisabled = "§cGamemode feature is disabled!";
public String gamemodeDisabled = "§cThis gamemode is disabled!";
@@ -84,6 +88,8 @@ public class MessagesConfiguration extends OkaeriConfig {
public String standingOnPlot = "§cYou are standing on a plot!";
public String notStandingOnPlot = "§cYou aren't standing on any plot!";
public String playerKick = "§aPlayer §7%player% §ahas been kicked out of your plot!";
+ public String plotLeave = "§aYou have left the plot with id %plot_id%!";
+ public String cantLeaveOwnPlot = "§6You can't leave your own plot!";
public String playerAdd = "§aPlayer §7%player% §ahas been added to your plot!";
public String gamemodeSwitched = "§aYour gamemode has changed!";
public String gamemodeAlreadySelected = "§cThis gamemode is already selected!";
diff --git a/src/main/java/com/modnmetl/virtualrealty/configs/PluginConfiguration.java b/src/main/java/com/modnmetl/virtualrealty/configs/PluginConfiguration.java
index e57facd..da00fa9 100644
--- a/src/main/java/com/modnmetl/virtualrealty/configs/PluginConfiguration.java
+++ b/src/main/java/com/modnmetl/virtualrealty/configs/PluginConfiguration.java
@@ -55,6 +55,9 @@ public static class License extends OkaeriConfig {
@CustomKey("default-plot-gamemode")
public String plotGamemode = "SURVIVAL";
+ @Comment("The number of days before plot expiration when players should be notified")
+ public int daysUntilExpirationThreshold = 2;
+
@Comment("Disable natural spawning of all mobs in plots/areas")
public boolean disablePlotMobsSpawn = false;
diff --git a/src/main/java/com/modnmetl/virtualrealty/listener/player/PlayerListener.java b/src/main/java/com/modnmetl/virtualrealty/listener/player/PlayerListener.java
new file mode 100644
index 0000000..84c1999
--- /dev/null
+++ b/src/main/java/com/modnmetl/virtualrealty/listener/player/PlayerListener.java
@@ -0,0 +1,51 @@
+package com.modnmetl.virtualrealty.listener.player;
+
+import com.modnmetl.virtualrealty.VirtualRealty;
+import com.modnmetl.virtualrealty.listener.VirtualListener;
+import com.modnmetl.virtualrealty.manager.PlotManager;
+import com.modnmetl.virtualrealty.model.other.ChatMessage;
+import com.modnmetl.virtualrealty.model.plot.Plot;
+import org.bukkit.entity.Player;
+import org.bukkit.event.EventHandler;
+import org.bukkit.event.EventPriority;
+import org.bukkit.event.player.PlayerJoinEvent;
+
+import java.time.Duration;
+import java.time.LocalDateTime;
+import java.time.temporal.ChronoUnit;
+import java.util.List;
+
+public class PlayerListener extends VirtualListener {
+
+ public PlayerListener(VirtualRealty plugin) {
+ super(plugin);
+ }
+
+ @EventHandler (priority = EventPriority.MONITOR)
+ public void onPlayerJoin(PlayerJoinEvent event) {
+ Player player = event.getPlayer();
+ PlotManager plotManager = PlotManager.getInstance();
+ List playerPlots = plotManager.getPlayerPlots(player.getUniqueId());
+ LocalDateTime now = LocalDateTime.now();
+ for (Plot playerPlot : playerPlots) {
+ LocalDateTime expirationDate = playerPlot.getOwnedUntilDate();
+ long daysUntilExpiration = ChronoUnit.DAYS.between(now, expirationDate);
+ Duration durationUntilExpiration = Duration.between(now, expirationDate);
+ if (durationUntilExpiration.isNegative()) {
+ String message = VirtualRealty.getMessages().ownershipExpiredJoinMessage
+ .replaceAll("%plot_size%", playerPlot.getPlotSize().name().toLowerCase())
+ .replaceAll("%plot_id%", String.valueOf(playerPlot.getID()));
+ ChatMessage.of(message).sendWithPrefix(player);
+ } else if (daysUntilExpiration <= VirtualRealty.getPluginConfiguration().daysUntilExpirationThreshold) {
+ long hoursUntilExpiration = durationUntilExpiration.toHours() % 24;
+ String message = VirtualRealty.getMessages().daysUntilExpirationThresholdMessage
+ .replaceAll("%plot_size%", playerPlot.getPlotSize().name().toLowerCase())
+ .replaceAll("%plot_id%", String.valueOf(playerPlot.getID()))
+ .replaceAll("%days%", String.valueOf(daysUntilExpiration))
+ .replaceAll("%hours%", String.valueOf(hoursUntilExpiration));
+ ChatMessage.of(message).sendWithPrefix(player);
+ }
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/com/modnmetl/virtualrealty/manager/DynmapManager.java b/src/main/java/com/modnmetl/virtualrealty/manager/DynmapManager.java
index 6e8d41d..329f959 100644
--- a/src/main/java/com/modnmetl/virtualrealty/manager/DynmapManager.java
+++ b/src/main/java/com/modnmetl/virtualrealty/manager/DynmapManager.java
@@ -105,7 +105,7 @@ public static void resetPlotMarker(Plot plot) {
if (marker == null) {
marker = VirtualRealty.getDynmapManager().markerset.createAreaMarker("virtualrealty.plots." + plot.getID(),
plot.getOwnedBy() == null ? String.format(MARKER_STRING, plot.getID()) : String.format(MARKER_OWNED_STRING, plot.getID(), ownedBy, dateTimeFormatter.format(localDateTime)), true,
- plot.getCreatedWorldString(), new double[]{plot.getXMin(), plot.getXMax()}, new double[]{plot.getZMin(), plot.getZMax()}, true);
+ plot.getCreatedWorldRaw(), new double[]{plot.getXMin(), plot.getXMax()}, new double[]{plot.getZMin(), plot.getZMax()}, true);
areaMarkers.add(marker);
} else {
marker.setLabel(
diff --git a/src/main/java/com/modnmetl/virtualrealty/manager/PlotManager.java b/src/main/java/com/modnmetl/virtualrealty/manager/PlotManager.java
index e42faa5..c9a2d0a 100644
--- a/src/main/java/com/modnmetl/virtualrealty/manager/PlotManager.java
+++ b/src/main/java/com/modnmetl/virtualrealty/manager/PlotManager.java
@@ -10,6 +10,7 @@
import lombok.Data;
import org.bukkit.Location;
import org.bukkit.Material;
+import org.bukkit.World;
import java.sql.Connection;
import java.sql.PreparedStatement;
@@ -157,7 +158,7 @@ public Plot getPlot(int ID) {
public List getPlots(String world) {
List newPlots = new LinkedList<>();
for (Plot plot : plots)
- if (plot.getCreatedWorldString().equals(world)) newPlots.add(plot);
+ if (plot.getCreatedWorldRaw().equals(world)) newPlots.add(plot);
return newPlots;
}
@@ -170,10 +171,19 @@ public HashMap getPlots(UUID owner) {
return plotHashMap;
}
+ public HashMap getMembershipPlots(UUID player) {
+ HashMap membershipMap = new HashMap<>();
+ for (Plot plot : plots) {
+ if (plot.getMember(player) != null)
+ membershipMap.put(plot.getID(), plot);
+ }
+ return membershipMap;
+ }
+
public HashMap getAccessPlots(UUID player) {
HashMap plotHashMap = new HashMap<>();
for (Plot plot : plots) {
- if (plot.getMember(player) != null || (plot.getOwnedBy() != null && plot.getPlotOwner().getUniqueId() == player))
+ if (plot.getMember(player) != null || (plot.getOwnedBy() != null && plot.getPlotOwner().getUniqueId().equals(player)))
plotHashMap.put(plot.getID(), plot);
}
return plotHashMap;
@@ -208,18 +218,6 @@ public boolean isLocationInPlot(Location location, Plot plot) {
return region.isIn(newVector, location.getWorld());
}
-// public Plot getPlot(Location location) {
-// BlockVector3 newVector = BlockVector3.at(location.getBlockX(), location.getBlockY(), location.getBlockZ());
-// for (Plot plot : plots) {
-// Cuboid region = new Cuboid(plot.getBottomLeftCorner(), plot.getTopRightCorner(), location.getWorld());
-// if (region.isIn(newVector, plot.getCreatedWorld())) {
-// return plot;
-// }
-// }
-// return null;
-// }
-//
-
public Plot getPlot(Location location) {
BlockVector3 newVector = BlockVector3.at(location.getBlockX(), location.getBlockY(), location.getBlockZ());
for (Plot plot : plots) {
@@ -240,7 +238,11 @@ public Plot getPlot(Location location, boolean withBorder) {
if (withBorder) {
return getBorderedPlot(location);
} else {
- Cuboid region = new Cuboid(plot.getBottomLeftCorner(), plot.getTopRightCorner(), location.getWorld());
+ World world = location.getWorld();
+ assert world != null;
+ Cuboid region = plot.getCuboid();
+ if (!region.getWorld().getName().equals(world.getName()))
+ continue;
if (region.isIn(newVector, plot.getCreatedWorld()))
return plot;
}
@@ -251,8 +253,12 @@ public Plot getPlot(Location location, boolean withBorder) {
private Plot getBorderedPlot(Location location) {
BlockVector3 newVector = BlockVector3.at(location.getBlockX(), location.getBlockY(), location.getBlockZ());
for (Plot plot : plots) {
- Cuboid region = new Cuboid(plot.getBorderBottomLeftCorner(), plot.getBorderTopRightCorner(), location.getWorld());
- if (region.isIn(newVector, plot.getCreatedWorld()))
+ World world = location.getWorld();
+ assert world != null;
+ Cuboid borderedRegion = plot.getBorderedCuboid();
+ if (!borderedRegion.getWorld().getName().equals(world.getName()))
+ continue;
+ if (borderedRegion.isIn(newVector, plot.getCreatedWorld()))
return plot;
}
return null;
diff --git a/src/main/java/com/modnmetl/virtualrealty/model/plot/Plot.java b/src/main/java/com/modnmetl/virtualrealty/model/plot/Plot.java
index f6d233d..e5d5864 100644
--- a/src/main/java/com/modnmetl/virtualrealty/model/plot/Plot.java
+++ b/src/main/java/com/modnmetl/virtualrealty/model/plot/Plot.java
@@ -54,6 +54,9 @@ public final class Plot {
private Instant modified;
private LocalDateTime createdAt;
+ private transient Cuboid cachedCuboid;
+ private transient Cuboid cachedBorderedCuboid;
+
public Plot(Location location, Material floorMaterial, Material borderMaterial, PlotSize plotSize, int length, int width, int height, boolean natural) {
this.ID = PlotManager.getInstance().getPlots().isEmpty() ? 10000 : PlotManager.getInstance().getPlotMaxID() + 1;
this.ownedBy = null;
@@ -280,14 +283,32 @@ public BlockVector3 getCenter() {
}
public Cuboid getCuboid() {
- return new Cuboid(bottomLeftCorner, topRightCorner, getCreatedWorld());
+ if (cachedCuboid == null) {
+ cachedCuboid = new Cuboid(
+ bottomLeftCorner,
+ topRightCorner,
+ getCreatedWorld()
+ );
+ }
+ return cachedCuboid;
+ }
+
+ public Cuboid getBorderedCuboid() {
+ if (cachedBorderedCuboid == null) {
+ cachedBorderedCuboid = new Cuboid(
+ borderBottomLeftCorner,
+ borderTopRightCorner,
+ getCreatedWorld()
+ );
+ }
+ return cachedBorderedCuboid;
}
public org.bukkit.World getCreatedWorld() {
return Bukkit.getWorld(createdWorld);
}
- public String getCreatedWorldString() {
+ public String getCreatedWorldRaw() {
return createdWorld;
}
diff --git a/src/main/java/com/modnmetl/virtualrealty/model/region/Cuboid.java b/src/main/java/com/modnmetl/virtualrealty/model/region/Cuboid.java
index a923e03..3f6895c 100644
--- a/src/main/java/com/modnmetl/virtualrealty/model/region/Cuboid.java
+++ b/src/main/java/com/modnmetl/virtualrealty/model/region/Cuboid.java
@@ -17,6 +17,8 @@ public class Cuboid {
private final int zMin;
private final int zMax;
private final World world;
+ private BlockVector3 centerVector; // Lazy initialization
+ private List walls; // Lazy initialization
public Cuboid(Location point1, Location point2) {
this.xMin = Math.min(point1.getBlockX(), point2.getBlockX());
@@ -38,6 +40,21 @@ public Cuboid(BlockVector3 point1, BlockVector3 point2, World world) {
this.world = world;
}
+ public List getWalls() {
+ if (walls == null) {
+ walls = new ArrayList<>();
+ for (int z = zMin; z <= zMax; z++) {
+ walls.add(BlockVector2.at(xMin, z));
+ walls.add(BlockVector2.at(xMax, z));
+ }
+ for (int x = xMin; x < xMax; x++) {
+ walls.add(BlockVector2.at(x, zMin));
+ walls.add(BlockVector2.at(x, zMax));
+ }
+ }
+ return walls;
+ }
+
public List getBlocks() {
List blocks = new ArrayList<>();
for (int x = this.xMin; x <= this.xMax; ++x) {
@@ -73,8 +90,16 @@ public Location getCenter() {
return new Location(this.world, (this.xMax - this.xMin) / 2 + this.xMin + 1, (this.yMax - this.yMin) / 2 + this.yMin, (this.zMax - this.zMin) / 2 + this.zMin + 1);
}
+ // Suggestion 3 - Lazy calculation and cached results
public BlockVector3 getCenterVector() {
- return BlockVector3.at((this.xMax - this.xMin) / 2 + this.xMin + 1, (this.yMax - this.yMin) / 2 + this.yMin, (this.zMax - this.zMin) / 2 + this.zMin + 1);
+ if (centerVector == null) {
+ centerVector = BlockVector3.at(
+ (xMax - xMin) / 2 + xMin,
+ (yMax - yMin) / 2 + yMin,
+ (zMax - zMin) / 2 + zMin
+ );
+ }
+ return centerVector;
}
public double getDistance() {
@@ -105,9 +130,11 @@ public Location getPoint2() {
return new Location(this.world, this.xMax, this.yMax, this.zMax);
}
- public boolean isIn(BlockVector3 vector3, World world) {
- return world == this.world && vector3.getBlockX() >= this.xMin && vector3.getBlockX() <= this.xMax && vector3.getBlockY() >= this.yMin && vector3.getBlockY() <= this.yMax && vector3
- .getBlockZ() >= this.zMin && vector3.getBlockZ() <= this.zMax;
+ public boolean isIn(BlockVector3 vector3, String world) {
+ return world.equals(this.world.getName())
+ && vector3.getBlockX() >= this.xMin && vector3.getBlockX() <= this.xMax
+ && vector3.getBlockY() >= this.yMin && vector3.getBlockY() <= this.yMax
+ && vector3.getBlockZ() >= this.zMin && vector3.getBlockZ() <= this.zMax;
}
public int getCuboidSize() {
@@ -123,8 +150,10 @@ public int getZWidth() {
}
public boolean isIn(Location loc) {
- return loc.getWorld() == this.world && loc.getBlockX() >= this.xMin && loc.getBlockX() <= this.xMax && loc.getBlockY() >= this.yMin && loc.getBlockY() <= this.yMax && loc
- .getBlockZ() >= this.zMin && loc.getBlockZ() <= this.zMax;
+ return loc.getWorld() == this.world
+ && loc.getBlockX() >= this.xMin && loc.getBlockX() <= this.xMax
+ && loc.getBlockY() >= this.yMin && loc.getBlockY() <= this.yMax
+ && loc.getBlockZ() >= this.zMin && loc.getBlockZ() <= this.zMax;
}
public boolean isIn(BlockVector2 vector2, World world, int spacing) {
@@ -136,15 +165,23 @@ public boolean isIn(BlockVector2 vector2, World world) {
return this.isIn(vector2, world, 0);
}
- public boolean isColliding(Cuboid cuboid) {
- if (cuboid.getWorld() != world) return false;
- List flatRegion1 = new ArrayList<>(this.getFlatRegion());
- List flatRegion2 = new ArrayList<>(cuboid.getFlatRegion());
- for (BlockVector2 vector1 : flatRegion1) {
- for (BlockVector2 vector2 : flatRegion2)
- if (vector1.getBlockX() == vector2.getBlockX() && vector1.getBlockZ() == vector2.getBlockZ()) return true;
- }
- return false;
+ public boolean isColliding(Cuboid other) {
+ return this.world == other.world &&
+ this.xMax >= other.xMin && this.xMin <= other.xMax &&
+ this.yMax >= other.yMin && this.yMin <= other.yMax &&
+ this.zMax >= other.zMin && this.zMin <= other.zMax;
+ }
+
+ public boolean isColliding2D(Cuboid other) {
+ return this.world.equals(other.world) &&
+ this.xMax >= other.xMin && this.xMin <= other.xMax &&
+ this.zMax >= other.zMin && this.zMin <= other.zMax;
+ }
+
+ public boolean isWithin2D(Cuboid other) {
+ return this.world.equals(other.world) &&
+ this.xMin >= other.xMin && this.xMax <= other.xMax &&
+ this.zMin >= other.zMin && this.zMax <= other.zMax;
}
public boolean containsBlock(Block block) {
@@ -156,19 +193,6 @@ public boolean containsBlock(Block block) {
return false;
}
- public List getWalls() {
- List walls = new ArrayList<>();
- for (int z = zMin; z <= zMax; z++) {
- walls.add(BlockVector2.at(xMin, z));
- walls.add(BlockVector2.at(xMax, z));
- }
- for (int x = xMin; x < xMax; x++) {
- walls.add(BlockVector2.at(x, zMin));
- walls.add(BlockVector2.at(x, zMax));
- }
- return walls;
- }
-
public World getWorld() {
return world;
}
diff --git a/src/main/java/com/modnmetl/virtualrealty/util/RegionUtil.java b/src/main/java/com/modnmetl/virtualrealty/util/RegionUtil.java
index 696a2e4..bbc280e 100644
--- a/src/main/java/com/modnmetl/virtualrealty/util/RegionUtil.java
+++ b/src/main/java/com/modnmetl/virtualrealty/util/RegionUtil.java
@@ -46,23 +46,49 @@ public static Cuboid getRegion(Location location, Direction direction, int lengt
public static boolean isCollidingWithBedrock(Cuboid cuboid) {
for (Block block : cuboid.getBlocks()) {
- if (block.getType() == Material.BEDROCK) return true;
+ if (block.getType() == Material.BEDROCK)
+ return true;
}
return false;
}
public static boolean isCollidingWithAnotherPlot(Cuboid cuboid) {
long time = System.currentTimeMillis();
+ int spacing = VirtualRealty.getPluginConfiguration().plotSpacing;
+
+ // Adjust the cuboid boundaries to include the spacing
+ Cuboid expandedCuboid = new Cuboid(
+ BlockVector3.at(cuboid.getMinimumPoint().getBlockX() - spacing,
+ cuboid.getMinimumPoint().getBlockY(),
+ cuboid.getMinimumPoint().getBlockZ() - spacing),
+ BlockVector3.at(cuboid.getMaximumPoint().getBlockX() + spacing,
+ cuboid.getMaximumPoint().getBlockY(),
+ cuboid.getMaximumPoint().getBlockZ() + spacing),
+ cuboid.getWorld()
+ );
+
for (Plot plot : PlotManager.getInstance().getPlots(cuboid.getWorld().getName())) {
- for (BlockVector2 blockVector2 : plot.getCuboid().getFlatRegion()) {
- if (cuboid.isIn(blockVector2, cuboid.getWorld(), VirtualRealty.getPluginConfiguration().plotSpacing)) {
- VirtualRealty.debug("Collision checked! (Found) " + (System.currentTimeMillis() - time) + " ms | Spacing: " + VirtualRealty.getPluginConfiguration().plotSpacing);
- return true;
- }
+ if (expandedCuboid.isColliding2D(plot.getCuboid()) || expandedCuboid.isWithin2D(plot.getCuboid())) {
+ VirtualRealty.debug("Collision checked! (Found) " + (System.currentTimeMillis() - time) + " ms | Spacing: " + spacing);
+ return true;
}
}
- VirtualRealty.debug("Collision checked! " + (System.currentTimeMillis() - time) + " ms | Spacing: " + VirtualRealty.getPluginConfiguration().plotSpacing);
+ VirtualRealty.debug("Collision checked! " + (System.currentTimeMillis() - time) + " ms | Spacing: " + spacing);
return false;
}
+// public static boolean isCollidingWithAnotherPlot(Cuboid cuboid) {
+// long time = System.currentTimeMillis();
+// for (Plot plot : PlotManager.getInstance().getPlots(cuboid.getWorld().getName())) {
+// for (BlockVector2 blockVector2 : plot.getCuboid().getFlatRegion()) {
+// if (cuboid.isIn(blockVector2, cuboid.getWorld(), VirtualRealty.getPluginConfiguration().plotSpacing)) {
+// VirtualRealty.debug("Collision checked! (Found) " + (System.currentTimeMillis() - time) + " ms | Spacing: " + VirtualRealty.getPluginConfiguration().plotSpacing);
+// return true;
+// }
+// }
+// }
+// VirtualRealty.debug("Collision checked! " + (System.currentTimeMillis() - time) + " ms | Spacing: " + VirtualRealty.getPluginConfiguration().plotSpacing);
+// return false;
+// }
+
}