diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java index 2132fefac..39a763d24 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java @@ -125,7 +125,6 @@ import org.bukkit.World; import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.PluginCommand; import org.bukkit.entity.Entity; -import org.bukkit.entity.EntityType; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.event.Listener; @@ -354,7 +353,10 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain< } impromptuPipeline.storeImmediately("*", DBFunc.EVERYONE); - this.startUuidCatching(sqLiteUUIDService, cacheUUIDService); + + if (Settings.UUID.BACKGROUND_CACHING_ENABLED) { + this.startUuidCaching(sqLiteUUIDService, cacheUUIDService); + } if (Bukkit.getPluginManager().getPlugin("PlaceholderAPI") != null) { new Placeholders().register(); @@ -491,7 +493,7 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain< } } - private void startUuidCatching(@NotNull final SQLiteUUIDService sqLiteUUIDService, + private void startUuidCaching(@NotNull final SQLiteUUIDService sqLiteUUIDService, @NotNull final CacheUUIDService cacheUUIDService) { // Load all uuids into a big chunky boi queue final Queue uuidQueue = new LinkedBlockingQueue<>(); diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/chat/FancyMessage.java b/Bukkit/src/main/java/com/plotsquared/bukkit/chat/FancyMessage.java index 173d49e95..739d3bbd4 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/chat/FancyMessage.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/chat/FancyMessage.java @@ -56,6 +56,7 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.UUID; import java.util.logging.Level; /** @@ -74,6 +75,7 @@ public class FancyMessage private static Constructor nmsPacketPlayOutChatConstructor; // The ChatSerializer's instance of Gson private static Object nmsChatSerializerGsonInstance; + private static Object chatMessageType; private static Method fromJsonMethod; private static JsonParser _stringParser = new JsonParser(); @@ -101,8 +103,16 @@ public class FancyMessage dirty = false; if (nmsPacketPlayOutChatConstructor == null) { try { - nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat") - .getDeclaredConstructor(Reflection.getNMSClass("IChatBaseComponent")); + Class componentClass = Reflection.getNMSClass("IChatBaseComponent"); + if (!Reflection.getVersion().startsWith("v1_16")) { // < 1.16 TODO needs to be fixed before 1.17 :P + nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat") + .getDeclaredConstructor(componentClass); + } else { + Class chatMessageTypeClass = (Class) Reflection.getNMSClass("ChatMessageType"); + nmsPacketPlayOutChatConstructor = Reflection.getNMSClass("PacketPlayOutChat") + .getDeclaredConstructor(componentClass, chatMessageTypeClass, UUID.class); + chatMessageType = Enum.valueOf(chatMessageTypeClass, "SYSTEM"); + } nmsPacketPlayOutChatConstructor.setAccessible(true); } catch (NoSuchMethodException e) { Bukkit.getLogger() @@ -773,7 +783,7 @@ public class FancyMessage Reflection.getField(handle.getClass(), "playerConnection").get(handle); Reflection .getMethod(connection.getClass(), "sendPacket", Reflection.getNMSClass("Packet")) - .invoke(connection, createChatPacket(jsonString)); + .invoke(connection, createChatPacket(jsonString, ((Player) sender).getUniqueId())); } catch (IllegalArgumentException e) { Bukkit.getLogger().log(Level.WARNING, "Argument could not be passed.", e); } catch (IllegalAccessException e) { @@ -790,7 +800,7 @@ public class FancyMessage } } - private Object createChatPacket(String json) + private Object createChatPacket(String json, UUID receiver) throws IllegalArgumentException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, ClassNotFoundException { if (nmsChatSerializerGsonInstance == null) { @@ -838,7 +848,11 @@ public class FancyMessage Object serializedChatComponent = fromJsonMethod.invoke(nmsChatSerializerGsonInstance, json, Reflection.getNMSClass("IChatBaseComponent")); - return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent); + if (!Reflection.getVersion().startsWith("v1_16")) { + return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent); + } else { + return nmsPacketPlayOutChatConstructor.newInstance(serializedChatComponent, chatMessageType, receiver); + } } /** diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java index 158f90928..fc71c9d31 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/util/BukkitRegionManager.java @@ -32,6 +32,7 @@ import com.plotsquared.core.location.Location; import com.plotsquared.core.location.PlotLoc; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotManager; import com.plotsquared.core.queue.GlobalBlockQueue; import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.queue.ScopedLocalBlockQueue; @@ -109,6 +110,10 @@ public class BukkitRegionManager extends RegionManager { return chunks; } + @Override public boolean handleClear(Plot plot, Runnable whenDone, PlotManager manager) { + return false; + } + @Override public int[] countEntities(Plot plot) { int[] existing = (int[]) plot.getMeta("EntityCount"); if (existing != null && (System.currentTimeMillis() - (long) plot.getMeta("EntityCountTime") diff --git a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java index 80d103882..db22c46be 100644 --- a/Core/src/main/java/com/plotsquared/core/configuration/Settings.java +++ b/Core/src/main/java/com/plotsquared/core/configuration/Settings.java @@ -257,6 +257,9 @@ public class Settings extends Config { public static boolean LEGACY_DATABASE_SUPPORT = true; @Comment("Whether or not PlotSquared should return Unknown if it fails to fulfill a request") public static boolean UNKNOWN_AS_DEFAULT = true; + @Comment("Whether or not automatic background caching should be enabled. It is HIGHLY recommended to keep this turned on." + + " This should only be disabled if the server has a very large number of plots (>100k)") + public static boolean BACKGROUND_CACHING_ENABLED = true; } diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java index 3fd91eb3c..67ad6eb8b 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotManager.java @@ -40,12 +40,14 @@ import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.FileBytes; import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MathMan; +import com.plotsquared.core.util.RegionManager; import com.plotsquared.core.util.task.RunnableVal; import com.sk89q.worldedit.function.pattern.Pattern; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockTypes; +import lombok.Getter; import java.io.File; import java.io.IOException; @@ -56,7 +58,7 @@ public class HybridPlotManager extends ClassicPlotManager { public static boolean REGENERATIVE_CLEAR = true; - private final HybridPlotWorld hybridPlotWorld; + @Getter private final HybridPlotWorld hybridPlotWorld; public HybridPlotManager(HybridPlotWorld hybridPlotWorld) { super(hybridPlotWorld); @@ -199,6 +201,12 @@ public class HybridPlotManager extends ClassicPlotManager { *

*/ @Override public boolean clearPlot(Plot plot, final Runnable whenDone) { + if (RegionManager.manager.notifyClear(this)) { + //If this returns false, the clear didn't work + if (RegionManager.manager.handleClear(plot, whenDone, this)) { + return true; + } + } final String world = hybridPlotWorld.getWorldName(); Location pos1 = plot.getBottomAbs(); Location pos2 = plot.getExtendedTopAbs(); diff --git a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java index e322072df..a561a9ac3 100644 --- a/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java +++ b/Core/src/main/java/com/plotsquared/core/generator/HybridPlotWorld.java @@ -50,6 +50,7 @@ import com.sk89q.worldedit.math.transform.AffineTransform; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.block.BaseBlock; +import lombok.Getter; import org.jetbrains.annotations.NotNull; import java.io.File; @@ -69,6 +70,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { public HashMap G_SCH_B; public int SCHEM_Y; private Location SIGN_LOCATION; + @Getter private File root = null; public HybridPlotWorld(String worldName, String id, @NotNull IndependentPlotGenerator generator, PlotId min, PlotId max) { @@ -198,7 +200,6 @@ public class HybridPlotWorld extends ClassicPlotWorld { // Try to determine root. This means that plot areas can have separate schematic // directories - File root; if (!(root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), "schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName() + "/" + this.getId())).exists()) { root = MainUtil.getFile(PlotSquared.get().IMP.getDirectory(), diff --git a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java index ab3333a19..1349e6c9a 100644 --- a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java +++ b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java @@ -29,6 +29,7 @@ import com.plotsquared.core.PlotSquared; import com.plotsquared.core.location.Location; import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.PlotArea; +import com.plotsquared.core.plot.PlotManager; import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.TaskManager; @@ -163,6 +164,22 @@ public abstract class RegionManager { return queue.enqueue(); } + /** + * Notify any plugins that may want to modify clear behaviour that a clear is occuring + * + * @return true if the notified will accept the clear task + */ + public boolean notifyClear(PlotManager manager) { + return false; + } + + /** + * Only called when {@link RegionManager#notifyClear(PlotManager)} returns true in specific PlotManagers + * + * @return true if the clear worked. False if someone went wrong so P2 can then handle the clear + */ + public abstract boolean handleClear(Plot plot, final Runnable whenDone, PlotManager manager); + /** * Copy a region to a new location (in the same world) */