From 42a34fc44a54392fffe7d03034f6a1fd1a429ead Mon Sep 17 00:00:00 2001 From: boy0001 Date: Mon, 27 Apr 2015 19:07:42 +1000 Subject: [PATCH] UUID mode conversion (untested) --- .../intellectualcrafters/plot/BukkitMain.java | 7 + .../intellectualcrafters/plot/IPlotMain.java | 3 + .../plot/PlotSquared.java | 3 + .../plot/commands/DebugUUID.java | 192 ++++++++++++++++++ .../plot/database/AbstractDB.java | 7 + .../plot/database/SQLManager.java | 29 +++ .../plot/object/Plot.java | 20 +- .../plot/object/PlotId.java | 31 +-- .../plot/util/PlayerManager.java | 9 + .../plot/util/bukkit/BukkitPlayerManager.java | 14 ++ 10 files changed, 284 insertions(+), 31 deletions(-) create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/util/PlayerManager.java create mode 100644 PlotSquared/src/main/java/com/intellectualcrafters/plot/util/bukkit/BukkitPlayerManager.java diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java index e2a3cbd76..71f0d8c20 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/BukkitMain.java @@ -102,10 +102,12 @@ import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.ConsoleColors; import com.intellectualcrafters.plot.util.EventUtil; import com.intellectualcrafters.plot.util.MainUtil; +import com.intellectualcrafters.plot.util.PlayerManager; import com.intellectualcrafters.plot.util.SetupUtils; import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.bukkit.BukkitChunkManager; import com.intellectualcrafters.plot.util.bukkit.BukkitEventUtil; +import com.intellectualcrafters.plot.util.bukkit.BukkitPlayerManager; import com.intellectualcrafters.plot.util.bukkit.BukkitSetBlockManager; import com.intellectualcrafters.plot.util.bukkit.BukkitSetupUtils; import com.intellectualcrafters.plot.util.bukkit.BukkitTaskManager; @@ -510,4 +512,9 @@ public class BukkitMain extends JavaPlugin implements Listener, IPlotMain { public void registerWorldEvents() { getServer().getPluginManager().registerEvents(new WorldEvents(), this); } + + @Override + public PlayerManager initPlayerManager() { + return new BukkitPlayerManager(); + } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/IPlotMain.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/IPlotMain.java index 5f1cb2e68..20401bbc6 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/IPlotMain.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/IPlotMain.java @@ -12,6 +12,7 @@ import com.intellectualcrafters.plot.object.PlotPlayer; import com.intellectualcrafters.plot.util.BlockManager; import com.intellectualcrafters.plot.util.ChunkManager; import com.intellectualcrafters.plot.util.EventUtil; +import com.intellectualcrafters.plot.util.PlayerManager; import com.intellectualcrafters.plot.util.SetupUtils; import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.uuid.UUIDWrapper; @@ -68,4 +69,6 @@ public interface IPlotMain { public void registerChunkProcessor(); public void registerWorldEvents(); + + public PlayerManager initPlayerManager(); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java index 3427babc1..75b10fa7c 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/PlotSquared.java @@ -67,6 +67,7 @@ import com.intellectualcrafters.plot.util.ExpireManager; import com.intellectualcrafters.plot.util.Logger; import com.intellectualcrafters.plot.util.Logger.LogLevel; import com.intellectualcrafters.plot.util.MainUtil; +import com.intellectualcrafters.plot.util.PlayerManager; import com.intellectualcrafters.plot.util.SetupUtils; import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.bukkit.UUIDHandler; @@ -547,6 +548,8 @@ public class PlotSquared { ChunkManager.manager = IMP.initChunkManager(); // Plot listener APlotListener.manager = IMP.initPlotListener(); + // Player manager + PlayerManager.manager = IMP.initPlayerManager(); // PlotMe if (Settings.CONVERT_PLOTME || Settings.CACHE_PLOTME) { diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugUUID.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugUUID.java index ecb69eeee..56653ff0c 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugUUID.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/commands/DebugUUID.java @@ -20,9 +20,28 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// package com.intellectualcrafters.plot.commands; +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map.Entry; +import java.util.UUID; + +import org.bukkit.Bukkit; + +import com.intellectualcrafters.plot.PlotSquared; import com.intellectualcrafters.plot.config.C; +import com.intellectualcrafters.plot.database.AbstractDB; +import com.intellectualcrafters.plot.database.DBFunc; +import com.intellectualcrafters.plot.database.SQLManager; +import com.intellectualcrafters.plot.object.OfflinePlotPlayer; +import com.intellectualcrafters.plot.object.Plot; import com.intellectualcrafters.plot.object.PlotPlayer; +import com.intellectualcrafters.plot.object.StringWrapper; import com.intellectualcrafters.plot.util.MainUtil; +import com.intellectualcrafters.plot.util.PlayerManager; +import com.intellectualcrafters.plot.util.TaskManager; import com.intellectualcrafters.plot.util.bukkit.UUIDHandler; import com.intellectualcrafters.plot.uuid.DefaultUUIDWrapper; import com.intellectualcrafters.plot.uuid.LowerOfflineUUIDWrapper; @@ -73,11 +92,184 @@ public class DebugUUID extends SubCommand { } } + if (args.length != 2 || !args[1].equals("-o")) { + MainUtil.sendMessage(player, C.COMMAND_SYNTAX, "/plot uuidconvert " + args[0] + " - o"); + MainUtil.sendMessage(player, "&cBe aware of the following!"); + MainUtil.sendMessage(player, "&8 - &cIf the process is interrupted, all plots could be deleted"); + MainUtil.sendMessage(player, "&8 - &cIf an error occurs, all plots could be deleted"); + MainUtil.sendMessage(player, "&8 - &cPlot settings WILL be lost upon conversion"); + MainUtil.sendMessage(player, "&cBACK UP YOUR DATABASE BEFORE USING THIS!!!"); + MainUtil.sendMessage(player, "&7Retype the command with the override parameter when ready"); + return false; + } + if (currentUUIDWrapper.getClass().getCanonicalName().equals(newWrapper.getClass().getCanonicalName())) { MainUtil.sendMessage(player, "&cUUID mode already in use!"); return false; } + MainUtil.sendConsoleMessage("&6Beginning UUID mode conversion"); + MainUtil.sendConsoleMessage("&7 - Disconnecting players"); + for (PlotPlayer user : UUIDHandler.players.values()) { + PlayerManager.manager.kickPlayer(user, "PlotSquared UUID conversion has been initiated. You may reconnect when finished."); + } + MainUtil.sendConsoleMessage("&7 - Initializing map"); + + HashMap uCMap = new HashMap(); + HashMap uCReverse = new HashMap(); + + MainUtil.sendConsoleMessage("&7 - Collecting playerdata"); + + final HashSet worlds = new HashSet<>(); + worlds.add(Bukkit.getWorlds().get(0).getName()); + worlds.add("world"); + final HashSet uuids = new HashSet<>(); + final HashSet names = new HashSet<>(); + for (final String worldname : worlds) { + final File playerdataFolder = new File(worldname + File.separator + "playerdata"); + String[] dat = playerdataFolder.list(new FilenameFilter() { + @Override + public boolean accept(final File f, final String s) { + return s.endsWith(".dat"); + } + }); + if (dat != null) { + for (final String current : dat) { + final String s = current.replaceAll(".dat$", ""); + try { + final UUID uuid = UUID.fromString(s); + uuids.add(uuid); + } catch (final Exception e) { + PlotSquared.log(C.PREFIX.s() + "Invalid playerdata: " + current); + } + } + } + final File playersFolder = new File(worldname + File.separator + "players"); + dat = playersFolder.list(new FilenameFilter() { + @Override + public boolean accept(final File f, final String s) { + return s.endsWith(".dat"); + } + }); + if (dat != null) { + for (final String current : dat) { + names.add(current.replaceAll(".dat$", "")); + } + } + } + + MainUtil.sendConsoleMessage("&7 - Populating map"); + UUID uuid2; + final UUIDWrapper wrapper = new DefaultUUIDWrapper(); + for (UUID uuid : uuids) { + try { + final OfflinePlotPlayer op = wrapper.getOfflinePlayer(uuid); + uuid = currentUUIDWrapper.getUUID(op); + uuid2 = newWrapper.getUUID(op); + if (!uuid.equals(uuid2)) { + uCMap.put(uuid, uuid2); + uCReverse.put(uuid2, uuid); + } + } catch (final Throwable e) { + PlotSquared.log(C.PREFIX.s() + "&6Invalid playerdata: " + uuid.toString() + ".dat"); + } + } + for (final String name : names) { + final UUID uuid = currentUUIDWrapper.getUUID(name); + uuid2 = newWrapper.getUUID(name); + if (!uuid.equals(uuid2)) { + uCMap.put(uuid, uuid2); + uCReverse.put(uuid2, uuid); + } + } + if (uCMap.size() == 0) { + MainUtil.sendConsoleMessage("&c - Error! Attempting to repopulate"); + for (OfflinePlotPlayer op : currentUUIDWrapper.getOfflinePlayers()) { + if (op.getLastPlayed() != 0) { + String name = op.getName(); + StringWrapper wrap = new StringWrapper(name); + UUID uuid = currentUUIDWrapper.getUUID(op); + uuid2 = newWrapper.getUUID(op); + if (!uuid.equals(uuid2)) { + uCMap.put(uuid, uuid2); + uCReverse.put(uuid2, uuid); + } + } + } + if (uCMap.size() == 0) { + MainUtil.sendConsoleMessage("&cError. Failed to collect UUIDs!"); + return false; + } + else { + MainUtil.sendConsoleMessage("&a - Successfully repopulated"); + } + } + + MainUtil.sendConsoleMessage("&7 - Replacing cache"); + for (Entry entry : uCMap.entrySet()) { + String name = UUIDHandler.getName(entry.getKey()); + UUIDHandler.add(new StringWrapper(name), entry.getValue()); + } + + MainUtil.sendConsoleMessage("&7 - Replacing wrapper"); + UUIDHandler.uuidWrapper = newWrapper; + + MainUtil.sendConsoleMessage("&7 - Updating plot objects"); + + for (Plot plot : PlotSquared.getPlots()) { + UUID value = uCMap.get(plot.owner); + if (value != null) { + plot.owner = value; + } + plot.helpers = new ArrayList<>(); + plot.trusted = new ArrayList<>(); + plot.denied = new ArrayList<>(); + } + + MainUtil.sendConsoleMessage("&7 - Deleting database"); + final AbstractDB database = DBFunc.dbManager; + boolean result = database.deleteTables(); + + MainUtil.sendConsoleMessage("&7 - Creating tables"); + + try { + database.createTables(PlotSquared.getMySQL() != null ? "mysql" : "sqlite", true); + if (!result) { + MainUtil.sendConsoleMessage("&cConversion failed! Attempting recovery"); + for (Plot plot : PlotSquared.getPlots()) { + UUID value = uCReverse.get(plot.owner); + if (value != null) { + plot.owner = value; + } + } + database.createPlots(new ArrayList<>(PlotSquared.getPlots())); + return false; + } + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + + MainUtil.sendConsoleMessage("&7 - Populating tables"); + + TaskManager.runTaskAsync(new Runnable() { + @Override + public void run() { + ArrayList plots = new ArrayList<>(PlotSquared.getPlots()); + database.createPlots(plots); + int size = plots.size(); + ArrayList ids = new ArrayList(); + for (int i = 1; i <= size; i++) { + ids.add(i); + } + database.createSettings(ids); + MainUtil.sendConsoleMessage("&aConversion complete!"); + } + }); + + MainUtil.sendConsoleMessage("&aIt is now safe for players to join"); + MainUtil.sendConsoleMessage("&cConversion is still in progress, you will be notified when it is complete"); return true; } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/AbstractDB.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/AbstractDB.java index 55d22898f..32b590264 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/AbstractDB.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/AbstractDB.java @@ -337,4 +337,11 @@ public interface AbstractDB { public void resizeCluster(PlotCluster current, PlotClusterId resize); public void movePlot(Plot originalPlot, Plot newPlot); + + public void createSettings(final ArrayList mylist); + + /** + * Don't fuck with this one, unless you enjoy it rough + */ + public boolean deleteTables(); } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java index dd041ef22..d4c598ccf 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/database/SQLManager.java @@ -1888,4 +1888,33 @@ public class SQLManager implements AbstractDB { } }); } + + @Override + public boolean deleteTables() { + try { + SQLManager.this.connection = PlotSquared.getMySQL().forceConnection(); + final Statement stmt = this.connection.createStatement(); + stmt.addBatch("DROP TABLE `" + prefix + "cluster_invited`"); + stmt.addBatch("DROP TABLE `" + prefix + "cluster_helpers`"); + stmt.addBatch("DROP TABLE `" + prefix + "cluster`"); + stmt.addBatch("DROP TABLE `" + prefix + "plot_ratings`"); + stmt.addBatch("DROP TABLE `" + prefix + "plot_settings`"); + stmt.addBatch("DROP TABLE `" + prefix + "plot_comments`"); + stmt.addBatch("DROP TABLE `" + prefix + "plot_trusted`"); + stmt.addBatch("DROP TABLE `" + prefix + "plot_helpers`"); + stmt.addBatch("DROP TABLE `" + prefix + "plot_denied`"); + stmt.executeBatch(); + stmt.clearBatch(); + stmt.close(); + + PreparedStatement statement = connection.prepareStatement("DROP TABLE `" + prefix + "plot`"); + statement.executeUpdate(); + statement.close(); + return true; + } + catch (Exception e) { + e.printStackTrace(); + return false; + } + } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/Plot.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/Plot.java index dc465c000..ec372d6f1 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/Plot.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/Plot.java @@ -275,6 +275,7 @@ public class Plot implements Cloneable { return ((this.id.x.equals(other.id.x)) && (this.id.y.equals(other.id.y)) && (this.world.equals(other.world))); } + /** * Get the plot hashcode * @@ -283,23 +284,6 @@ public class Plot implements Cloneable { */ @Override public int hashCode() { - final int x = this.id.x; - final int y = this.id.y; - if (x >= 0) { - if (y >= 0) { - return (x * x) + (3 * x) + (2 * x * y) + y + (y * y); - } else { - final int y1 = -y; - return (x * x) + (3 * x) + (2 * x * y1) + y1 + (y1 * y1) + 1; - } - } else { - final int x1 = -x; - if (y >= 0) { - return -((x1 * x1) + (3 * x1) + (2 * x1 * y) + y + (y * y)); - } else { - final int y1 = -y; - return -((x1 * x1) + (3 * x1) + (2 * x1 * y1) + y1 + (y1 * y1) + 1); - } - } + return this.id.hashCode(); } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotId.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotId.java index 5ff26a5ba..d769154a1 100644 --- a/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotId.java +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/object/PlotId.java @@ -124,23 +124,28 @@ public class PlotId { } } + private int hash; + @Override public int hashCode() { - if (this.x >= 0) { - if (this.y >= 0) { - return (this.x * this.x) + (3 * this.x) + (2 * this.x * this.y) + this.y + (this.y * this.y); + if (hash == 0) { + if (x >= 0) { + if (y >= 0) { + hash = (x * x) + (3 * x) + (2 * x * y) + y + (y * y); + } else { + final int y1 = -y; + hash = (x * x) + (3 * x) + (2 * x * y1) + y1 + (y1 * y1) + 1; + } } else { - final int y1 = -this.y; - return (this.x * this.x) + (3 * this.x) + (2 * this.x * y1) + y1 + (y1 * y1) + 1; - } - } else { - final int x1 = -this.x; - if (this.y >= 0) { - return -((x1 * x1) + (3 * x1) + (2 * x1 * this.y) + this.y + (this.y * this.y)); - } else { - final int y1 = -this.y; - return -((x1 * x1) + (3 * x1) + (2 * x1 * y1) + y1 + (y1 * y1) + 1); + final int x1 = -x; + if (y >= 0) { + hash = -((x1 * x1) + (3 * x1) + (2 * x1 * y) + y + (y * y)); + } else { + final int y1 = -y; + hash = -((x1 * x1) + (3 * x1) + (2 * x1 * y1) + y1 + (y1 * y1) + 1); + } } } + return hash; } } diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/PlayerManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/PlayerManager.java new file mode 100644 index 000000000..cfcdcb137 --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/PlayerManager.java @@ -0,0 +1,9 @@ +package com.intellectualcrafters.plot.util; + +import com.intellectualcrafters.plot.object.PlotPlayer; + +public abstract class PlayerManager { + public static PlayerManager manager; + + public abstract void kickPlayer(PlotPlayer player, String reason); +} diff --git a/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/bukkit/BukkitPlayerManager.java b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/bukkit/BukkitPlayerManager.java new file mode 100644 index 000000000..b654f22dc --- /dev/null +++ b/PlotSquared/src/main/java/com/intellectualcrafters/plot/util/bukkit/BukkitPlayerManager.java @@ -0,0 +1,14 @@ +package com.intellectualcrafters.plot.util.bukkit; + +import com.intellectualcrafters.plot.object.BukkitPlayer; +import com.intellectualcrafters.plot.object.PlotPlayer; +import com.intellectualcrafters.plot.util.PlayerManager; + +public class BukkitPlayerManager extends PlayerManager { + + @Override + public void kickPlayer(PlotPlayer player, String reason) { + ((BukkitPlayer) player).player.kickPlayer(reason); + } + +}