diff --git a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java index ffa7a6ac7..29925f895 100644 --- a/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java +++ b/Bukkit/src/main/java/com/plotsquared/bukkit/BukkitMain.java @@ -10,91 +10,32 @@ import com.intellectualcrafters.plot.generator.GeneratorWrapper; import com.intellectualcrafters.plot.generator.HybridGen; import com.intellectualcrafters.plot.generator.HybridUtils; import com.intellectualcrafters.plot.generator.IndependentPlotGenerator; -import com.intellectualcrafters.plot.object.Plot; -import com.intellectualcrafters.plot.object.PlotArea; -import com.intellectualcrafters.plot.object.PlotId; -import com.intellectualcrafters.plot.object.PlotPlayer; -import com.intellectualcrafters.plot.object.RunnableVal; -import com.intellectualcrafters.plot.object.SetupObject; +import com.intellectualcrafters.plot.object.*; import com.intellectualcrafters.plot.object.chat.PlainChatManager; import com.intellectualcrafters.plot.object.worlds.PlotAreaManager; import com.intellectualcrafters.plot.object.worlds.SinglePlotArea; import com.intellectualcrafters.plot.object.worlds.SinglePlotAreaManager; import com.intellectualcrafters.plot.object.worlds.SingleWorldGenerator; -import com.intellectualcrafters.plot.util.AbstractTitle; -import com.intellectualcrafters.plot.util.ChatManager; -import com.intellectualcrafters.plot.util.ChunkManager; -import com.intellectualcrafters.plot.util.ConsoleColors; -import com.intellectualcrafters.plot.util.EconHandler; -import com.intellectualcrafters.plot.util.EventUtil; -import com.intellectualcrafters.plot.util.InventoryUtil; -import com.intellectualcrafters.plot.util.MainUtil; -import com.intellectualcrafters.plot.util.SchematicHandler; -import com.intellectualcrafters.plot.util.SetupUtils; -import com.intellectualcrafters.plot.util.StringMan; -import com.intellectualcrafters.plot.util.TaskManager; -import com.intellectualcrafters.plot.util.UUIDHandler; -import com.intellectualcrafters.plot.util.UUIDHandlerImplementation; -import com.intellectualcrafters.plot.util.WorldUtil; +import com.intellectualcrafters.plot.util.*; import com.intellectualcrafters.plot.util.block.QueueProvider; import com.intellectualcrafters.plot.uuid.UUIDWrapper; import com.plotsquared.bukkit.database.plotme.ClassicPlotMeConnector; import com.plotsquared.bukkit.database.plotme.LikePlotMeConverter; import com.plotsquared.bukkit.database.plotme.PlotMeConnector_017; import com.plotsquared.bukkit.generator.BukkitPlotGenerator; -import com.plotsquared.bukkit.listeners.ChunkListener; -import com.plotsquared.bukkit.listeners.EntitySpawnListener; -import com.plotsquared.bukkit.listeners.PlayerEvents; -import com.plotsquared.bukkit.listeners.PlayerEvents183; -import com.plotsquared.bukkit.listeners.PlayerEvents_1_8; -import com.plotsquared.bukkit.listeners.PlayerEvents_1_9; -import com.plotsquared.bukkit.listeners.PlotPlusListener; -import com.plotsquared.bukkit.listeners.PlotPlusListener_1_12; -import com.plotsquared.bukkit.listeners.PlotPlusListener_Legacy; -import com.plotsquared.bukkit.listeners.SingleWorldListener; -import com.plotsquared.bukkit.listeners.WorldEvents; +import com.plotsquared.bukkit.listeners.*; import com.plotsquared.bukkit.titles.DefaultTitle_111; -import com.plotsquared.bukkit.util.BukkitChatManager; -import com.plotsquared.bukkit.util.BukkitChunkManager; -import com.plotsquared.bukkit.util.BukkitCommand; -import com.plotsquared.bukkit.util.BukkitEconHandler; -import com.plotsquared.bukkit.util.BukkitEventUtil; -import com.plotsquared.bukkit.util.BukkitHybridUtils; -import com.plotsquared.bukkit.util.BukkitInventoryUtil; -import com.plotsquared.bukkit.util.BukkitSchematicHandler; -import com.plotsquared.bukkit.util.BukkitSetupUtils; -import com.plotsquared.bukkit.util.BukkitTaskManager; -import com.plotsquared.bukkit.util.BukkitUtil; -import com.plotsquared.bukkit.util.BukkitVersion; -import com.plotsquared.bukkit.util.Metrics; -import com.plotsquared.bukkit.util.SendChunk; -import com.plotsquared.bukkit.util.SetGenCB; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_7; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_8; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_8_3; -import com.plotsquared.bukkit.util.block.BukkitLocalQueue_1_9; -import com.plotsquared.bukkit.uuid.DefaultUUIDWrapper; -import com.plotsquared.bukkit.uuid.FileUUIDHandler; -import com.plotsquared.bukkit.uuid.LowerOfflineUUIDWrapper; -import com.plotsquared.bukkit.uuid.OfflineUUIDWrapper; -import com.plotsquared.bukkit.uuid.SQLUUIDHandler; +import com.plotsquared.bukkit.util.*; +import com.plotsquared.bukkit.util.block.*; +import com.plotsquared.bukkit.uuid.*; import com.sk89q.worldedit.WorldEdit; import java.io.File; import java.lang.reflect.Field; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.lang.reflect.Method; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Chunk; +import org.bukkit.*; import org.bukkit.Location; -import org.bukkit.OfflinePlayer; -import org.bukkit.World; import org.bukkit.command.PluginCommand; import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; @@ -107,6 +48,9 @@ import org.bukkit.plugin.Plugin; import org.bukkit.plugin.PluginManager; import org.bukkit.plugin.java.JavaPlugin; + +import static com.intellectualcrafters.plot.util.ReflectionUtils.getRefClass; + public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain { private static ConcurrentHashMap pluginMap; @@ -216,16 +160,32 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain return singleWorldListener; } + private Method methodUnloadChunk0; + private boolean methodUnloadSetup = false; + public void unload() { + if (!methodUnloadSetup) { + methodUnloadSetup = true; + try { + ReflectionUtils.RefClass classCraftWorld = getRefClass("{cb}.CraftWorld"); + methodUnloadChunk0 = classCraftWorld.getRealClass().getDeclaredMethod("unloadChunk0", int.class, int.class, boolean.class); + methodUnloadChunk0.setAccessible(true); + } catch (Throwable ignore) { + ignore.printStackTrace(); + } + } PlotAreaManager manager = PS.get().getPlotAreaManager(); if (manager instanceof SinglePlotAreaManager) { long start = System.currentTimeMillis(); SinglePlotArea area = ((SinglePlotAreaManager) manager).getArea(); + outer: for (World world : Bukkit.getWorlds()) { String name = world.getName(); char char0 = name.charAt(0); if (!Character.isDigit(char0) && char0 != '-') continue; - if (!world.getPlayers().isEmpty()) continue; + if (!world.getPlayers().isEmpty()) { + continue; + } PlotId id = PlotId.fromString(name); if (id != null) { @@ -242,6 +202,27 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain PS.debug("Failed to unload " + world.getName()); } return; + } else { + int index = 0; + do { + Chunk chunkI = chunks[index++]; + boolean result; + if (methodUnloadChunk0 != null) { + try { + result = (boolean) methodUnloadChunk0.invoke(world, chunkI.getX(), chunkI.getZ(), true); + } catch (Throwable e) { + methodUnloadChunk0 = null; + e.printStackTrace(); + continue outer; + } + } else { + result = world.unloadChunk(chunkI.getX(), chunkI.getZ(), true, false); + } + if (!result) { + continue outer; + } + } while (index < chunks.length && System.currentTimeMillis() - start < 5); + return; } } } diff --git a/Core/src/main/java/com/intellectualcrafters/plot/commands/Grant.java b/Core/src/main/java/com/intellectualcrafters/plot/commands/Grant.java index 89dba90a6..7917d6f14 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/commands/Grant.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/commands/Grant.java @@ -54,7 +54,14 @@ public class Grant extends Command { } else { // add int amount = 1 + (array == null ? 0 : ByteArrayUtilities.bytesToInteger(array)); boolean replace = array != null; - DBFunc.addPersistentMeta(uuid, "grantedPlots", ByteArrayUtilities.integerToBytes(amount), replace); + String key = "grantedPlots"; + byte[] rawData = ByteArrayUtilities.integerToBytes(amount); + PlotPlayer online = UUIDHandler.getPlayer(uuid); + if (online != null) { + online.setPersistentMeta(key, rawData); + } else { + DBFunc.addPersistentMeta(uuid, key, rawData, replace); + } } } }); diff --git a/Core/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java b/Core/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java index 6e82443fe..4693dbfb4 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java @@ -2611,7 +2611,7 @@ public class SQLManager implements AbstractDB { @Override public PreparedStatement get() throws SQLException { - return SQLManager.this.connection.prepareStatement("SELECT * FROM `" + SQLManager.this.prefix + "player_meta` WHERE `uuid` = ?"); + return SQLManager.this.connection.prepareStatement("SELECT * FROM `" + SQLManager.this.prefix + "player_meta` WHERE `uuid` = ? ORDER BY `meta_id` ASC"); } @Override @@ -2621,7 +2621,7 @@ public class SQLManager implements AbstractDB { public void addBatch(PreparedStatement statement) throws SQLException { ResultSet resultSet = statement.executeQuery(); - Map metaMap = new HashMap<>(); + final Map metaMap = new HashMap<>(); while (resultSet.next()) { String key = resultSet.getString("key"); @@ -2630,7 +2630,12 @@ public class SQLManager implements AbstractDB { } resultSet.close(); - result.run(metaMap); + TaskManager.runTaskAsync(new Runnable() { + @Override + public void run() { + result.run(metaMap); + } + }); } }); diff --git a/Core/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java b/Core/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java index c5a70ba13..b1d3983bb 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/object/PlotPlayer.java @@ -2,27 +2,18 @@ package com.intellectualcrafters.plot.object; import com.intellectualcrafters.plot.PS; import com.intellectualcrafters.plot.commands.RequiredType; +import com.intellectualcrafters.plot.config.C; import com.intellectualcrafters.plot.config.Settings; import com.intellectualcrafters.plot.database.DBFunc; import com.intellectualcrafters.plot.flag.Flags; import com.intellectualcrafters.plot.object.worlds.PlotAreaManager; import com.intellectualcrafters.plot.object.worlds.SinglePlotArea; import com.intellectualcrafters.plot.object.worlds.SinglePlotAreaManager; -import com.intellectualcrafters.plot.util.EconHandler; -import com.intellectualcrafters.plot.util.EventUtil; -import com.intellectualcrafters.plot.util.Permissions; -import com.intellectualcrafters.plot.util.PlotGameMode; -import com.intellectualcrafters.plot.util.PlotWeather; -import com.intellectualcrafters.plot.util.TaskManager; -import com.intellectualcrafters.plot.util.UUIDHandler; +import com.intellectualcrafters.plot.util.*; import com.intellectualcrafters.plot.util.expiry.ExpireManager; import com.plotsquared.general.commands.CommandCaller; import java.nio.ByteBuffer; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.UUID; +import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicInteger; @@ -489,34 +480,61 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer { DBFunc.getPersistentMeta(getUUID(), new RunnableVal>() { @Override public void run(Map value) { - PlotPlayer.this.metaMap = value; - if (!value.isEmpty()) { - if (Settings.Enabled_Components.PERSISTENT_META) { - PlotAreaManager manager = PS.get().getPlotAreaManager(); - if (manager instanceof SinglePlotAreaManager) { - PlotArea area = ((SinglePlotAreaManager) manager).getArea(); - byte[] arr = PlotPlayer.this.getPersistentMeta("quitLoc"); - if (arr != null && getMeta("teleportOnLogin", true)) { - ByteBuffer quitWorld = ByteBuffer.wrap(arr); - PlotId id = new PlotId(quitWorld.getShort(), quitWorld.getShort()); - int x = quitWorld.getInt(); - int y = quitWorld.get() & 0xFF; - int z = quitWorld.getInt(); - Plot plot = area.getOwnedPlot(id); - if (plot != null && plot.isLoaded()) { - final Location loc = new Location(plot.getWorldName(), x, y, z); - TaskManager.IMP.sync(new RunnableVal() { - @Override - public void run(Object o) { - if (getMeta("teleportOnLogin", true)) { - teleport(loc); + try { + PlotPlayer.this.metaMap = value; + if (!value.isEmpty()) { + if (Settings.Enabled_Components.PERSISTENT_META) { + PlotAreaManager manager = PS.get().getPlotAreaManager(); + if (manager instanceof SinglePlotAreaManager) { + PlotArea area = ((SinglePlotAreaManager) manager).getArea(); + byte[] arr = PlotPlayer.this.getPersistentMeta("quitLoc"); + if (arr != null) { + removePersistentMeta("quitLoc"); + + if (getMeta("teleportOnLogin", true)) { + ByteBuffer quitWorld = ByteBuffer.wrap(arr); + final int plotX = quitWorld.getShort(); + final int plotZ = quitWorld.getShort(); + PlotId id = new PlotId(plotX, plotZ); + int x = quitWorld.getInt(); + int y = quitWorld.get() & 0xFF; + int z = quitWorld.getInt(); + Plot plot = area.getOwnedPlot(id); + if (plot != null) { + final Location loc = new Location(plot.getWorldName(), x, y, z); + if (plot.isLoaded()) { + TaskManager.runTask(new Runnable() { + @Override + public void run() { + if (getMeta("teleportOnLogin", true)) { + teleport(loc); + sendMessage(C.TELEPORTED_TO_PLOT.f() + " (quitLoc) (" + plotX + "," + plotZ + ")"); + } + } + }); + } else if (!PS.get().isMainThread(Thread.currentThread())) { + if (getMeta("teleportOnLogin", true)) { + if (plot.teleportPlayer(PlotPlayer.this)) { + TaskManager.runTask(new Runnable() { + @Override + public void run() { + if (getMeta("teleportOnLogin", true)) { + teleport(loc); + sendMessage(C.TELEPORTED_TO_PLOT.f() + " (quitLoc-unloaded) (" + plotX + "," + plotZ + ")"); + } + } + }); + } + } } } - }); + } } } } } + } catch (Throwable e) { + e.printStackTrace(); } } }); diff --git a/Core/src/main/java/com/intellectualcrafters/plot/util/EventUtil.java b/Core/src/main/java/com/intellectualcrafters/plot/util/EventUtil.java index 6e34d3d9e..33759c4cf 100644 --- a/Core/src/main/java/com/intellectualcrafters/plot/util/EventUtil.java +++ b/Core/src/main/java/com/intellectualcrafters/plot/util/EventUtil.java @@ -78,7 +78,7 @@ public abstract class EventUtil { plot.teleportPlayer(player); } }); - MainUtil.sendMessage(player, C.TELEPORTED_TO_ROAD); + MainUtil.sendMessage(player, C.TELEPORTED_TO_ROAD.f() + " (on-login) " + "(" + plot.getId().x + ";" + plot.getId().y + ")"); } }