From 858f8d3c368ee136a7b5c4714f7ed021b79df266 Mon Sep 17 00:00:00 2001 From: James Robinson Date: Thu, 7 Jul 2011 18:23:12 +0100 Subject: [PATCH 1/2] Add multiworld snapshot support --- .../sk89q/worldedit/LocalConfiguration.java | 3 +- .../com/sk89q/worldedit/LocalSession.java | 14 +-- .../java/com/sk89q/worldedit/LocalWorld.java | 7 ++ .../worldedit/bukkit/BukkitConfiguration.java | 9 +- .../sk89q/worldedit/bukkit/BukkitWorld.java | 9 ++ .../worldedit/commands/SnapshotCommands.java | 85 +++++++++++-------- .../commands/SnapshotUtilCommands.java | 15 ++-- .../util/PropertiesConfiguration.java | 8 +- 8 files changed, 95 insertions(+), 55 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/src/main/java/com/sk89q/worldedit/LocalConfiguration.java index f43608660..60b6ce2d0 100644 --- a/src/main/java/com/sk89q/worldedit/LocalConfiguration.java +++ b/src/main/java/com/sk89q/worldedit/LocalConfiguration.java @@ -24,6 +24,7 @@ import java.util.HashSet; import java.util.Set; import com.sk89q.worldedit.snapshots.SnapshotRepository; +import java.util.Map; /** * Represents WorldEdit's configuration. @@ -42,7 +43,7 @@ public abstract class LocalConfiguration { public int defaultChangeLimit = -1; public int maxChangeLimit = -1; public String shellSaveType = ""; - public SnapshotRepository snapshotRepo = null; + public Map snapshotRepositories = null; public int maxRadius = -1; public int maxSuperPickaxeSize = 5; public int maxBrushRadius = 6; diff --git a/src/main/java/com/sk89q/worldedit/LocalSession.java b/src/main/java/com/sk89q/worldedit/LocalSession.java index 477cc2021..12ae40fff 100644 --- a/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -70,7 +70,7 @@ public class LocalSession { = new HashMap(); private int maxBlocksChanged = -1; private boolean useInventory; - private Snapshot snapshot; + private Map snapshots = new HashMap(); private String lastScript; private boolean beenToldVersion = false; private boolean hasCUISupport = false; @@ -410,8 +410,8 @@ public class LocalSession { * * @return the snapshot */ - public Snapshot getSnapshot() { - return snapshot; + public Snapshot getSnapshot(LocalWorld world) { + return snapshots.get(world); } /** @@ -419,8 +419,12 @@ public class LocalSession { * * @param snapshot */ - public void setSnapshot(Snapshot snapshot) { - this.snapshot = snapshot; + public void setSnapshot(LocalWorld world, Snapshot snapshot) { + if (snapshot == null && snapshots.containsKey(world)) { + snapshots.remove(world); + } else { + snapshots.put(world, snapshot); + } } /** diff --git a/src/main/java/com/sk89q/worldedit/LocalWorld.java b/src/main/java/com/sk89q/worldedit/LocalWorld.java index cdd8fafee..d202bc885 100644 --- a/src/main/java/com/sk89q/worldedit/LocalWorld.java +++ b/src/main/java/com/sk89q/worldedit/LocalWorld.java @@ -34,6 +34,13 @@ public abstract class LocalWorld { * Random generator. */ protected Random random = new Random(); + + /** + * Get the name of the world. + * + * @return + */ + public abstract String getName(); /** * Set block type. diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java index 6b10681e5..cf9673d98 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitConfiguration.java @@ -30,6 +30,8 @@ import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.LogFormat; import com.sk89q.worldedit.snapshots.SnapshotRepository; +import java.io.File; +import java.util.HashMap; public class BukkitConfiguration extends LocalConfiguration { private Configuration config; @@ -86,10 +88,11 @@ public class BukkitConfiguration extends LocalConfiguration { LocalSession.EXPIRATION_GRACE = config.getInt("history.expiration", 10) * 60 * 1000; String snapshotsDir = config.getString("snapshots.directory", ""); + snapshotRepositories = new HashMap(); if (!snapshotsDir.trim().equals("")) { - snapshotRepo = new SnapshotRepository(snapshotsDir); - } else { - snapshotRepo = null; + for (File repository : new File(snapshotsDir).listFiles()) { + snapshotRepositories.put(repository.getName(), new SnapshotRepository(repository)); + } } String type = config.getString("shell-save-type", "").trim(); diff --git a/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java b/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java index 0b309d01b..a1865ae92 100644 --- a/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java +++ b/src/main/java/com/sk89q/worldedit/bukkit/BukkitWorld.java @@ -69,6 +69,15 @@ public class BukkitWorld extends LocalWorld { public World getWorld() { return world; } + + /** + * Get the name of the world + * + * @return + */ + public String getName() { + return world.getName(); + } /** * Set block type. diff --git a/src/main/java/com/sk89q/worldedit/commands/SnapshotCommands.java b/src/main/java/com/sk89q/worldedit/commands/SnapshotCommands.java index bff22425c..491b07e1b 100644 --- a/src/main/java/com/sk89q/worldedit/commands/SnapshotCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/SnapshotCommands.java @@ -32,6 +32,7 @@ import com.sk89q.minecraft.util.commands.CommandPermissions; import com.sk89q.worldedit.*; import com.sk89q.worldedit.snapshots.InvalidSnapshotException; import com.sk89q.worldedit.snapshots.Snapshot; +import com.sk89q.worldedit.snapshots.SnapshotRepository; /** * Snapshot commands. @@ -58,33 +59,37 @@ public class SnapshotCommands { int num = args.argsLength() > 0 ? Math.min(40, Math.max(5, args.getInteger(0))) : 5; + + String worldName = player.getWorld().getName(); + SnapshotRepository repo = config.snapshotRepositories.get(worldName); + + if (repo == null) { + player.printError("Snapshot/backup restore is not configured for this world."); + return; + } + + List snapshots = repo.getSnapshots(true); - if (config.snapshotRepo != null) { - List snapshots = config.snapshotRepo.getSnapshots(true); - - if (snapshots.size() > 0) { - for (byte i = 0; i < Math.min(num, snapshots.size()); i++) { - player.print((i + 1) + ". " + snapshots.get(i).getName()); - } - - player.print("Use /snap use [snapshot] or /snap use latest."); - } else { - player.printError("No snapshots are available. See console for details."); - - // Okay, let's toss some debugging information! - File dir = config.snapshotRepo.getDirectory(); - - try { - logger.info("WorldEdit found no snapshots: looked in: " + - dir.getCanonicalPath()); - } catch (IOException e) { - logger.info("WorldEdit found no snapshots: looked in " - + "(NON-RESOLVABLE PATH - does it exist?): " + - dir.getPath()); - } + if (snapshots.size() > 0) { + for (byte i = 0; i < Math.min(num, snapshots.size()); i++) { + player.print((i + 1) + ". " + snapshots.get(i).getName()); } + + player.print("Use /snap use [snapshot] or /snap use latest."); } else { - player.printError("Snapshot/backup restore is not configured."); + player.printError("No snapshots are available. See console for details."); + + // Okay, let's toss some debugging information! + File dir = repo.getDirectory(); + + try { + logger.info("WorldEdit found no snapshots: looked in: " + + dir.getCanonicalPath()); + } catch (IOException e) { + logger.info("WorldEdit found no snapshots: looked in " + + "(NON-RESOLVABLE PATH - does it exist?): " + + dir.getPath()); + } } } @@ -101,9 +106,11 @@ public class SnapshotCommands { throws WorldEditException { LocalConfiguration config = we.getConfiguration(); + String worldName = player.getWorld().getName(); + SnapshotRepository repo = config.snapshotRepositories.get(worldName); - if (config.snapshotRepo == null) { - player.printError("Snapshot/backup restore is not configured."); + if (repo == null) { + player.printError("Snapshot/backup restore is not configured for this world."); return; } @@ -111,17 +118,17 @@ public class SnapshotCommands { // Want the latest snapshot? if (name.equalsIgnoreCase("latest")) { - Snapshot snapshot = config.snapshotRepo.getDefaultSnapshot(); + Snapshot snapshot = repo.getDefaultSnapshot(); if (snapshot != null) { - session.setSnapshot(null); + session.setSnapshot(player.getWorld(), null); player.print("Now using newest snapshot."); } else { player.printError("No snapshots were found."); } } else { try { - session.setSnapshot(config.snapshotRepo.getSnapshot(name)); + session.setSnapshot(player.getWorld(), repo.getSnapshot(name)); player.print("Snapshot set to: " + name); } catch (InvalidSnapshotException e) { player.printError("That snapshot does not exist or is not available."); @@ -142,9 +149,11 @@ public class SnapshotCommands { throws WorldEditException { LocalConfiguration config = we.getConfiguration(); + String worldName = player.getWorld().getName(); + SnapshotRepository repo = config.snapshotRepositories.get(worldName); - if (config.snapshotRepo == null) { - player.printError("Snapshot/backup restore is not configured."); + if (repo == null) { + player.printError("Snapshot/backup restore is not configured for this world."); return; } @@ -155,12 +164,12 @@ public class SnapshotCommands { } else { dateFormat.setTimeZone(session.getTimeZone()); - Snapshot snapshot = config.snapshotRepo.getSnapshotBefore(date); + Snapshot snapshot = repo.getSnapshotBefore(date); if (snapshot == null) { player.printError("Couldn't find a snapshot before " + dateFormat.format(date.getTime()) + "."); } else { - session.setSnapshot(snapshot); + session.setSnapshot(player.getWorld(), snapshot); player.print("Snapshot set to: " + snapshot.getName()); } } @@ -179,9 +188,11 @@ public class SnapshotCommands { throws WorldEditException { LocalConfiguration config = we.getConfiguration(); + String worldName = player.getWorld().getName(); + SnapshotRepository repo = config.snapshotRepositories.get(worldName); - if (config.snapshotRepo == null) { - player.printError("Snapshot/backup restore is not configured."); + if (repo == null) { + player.printError("Snapshot/backup restore is not configured for this world."); return; } @@ -192,12 +203,12 @@ public class SnapshotCommands { } else { dateFormat.setTimeZone(session.getTimeZone()); - Snapshot snapshot = config.snapshotRepo.getSnapshotAfter(date); + Snapshot snapshot = repo.getSnapshotAfter(date); if (snapshot == null) { player.printError("Couldn't find a snapshot after " + dateFormat.format(date.getTime()) + "."); } else { - session.setSnapshot(snapshot); + session.setSnapshot(player.getWorld(), snapshot); player.print("Snapshot set to: " + snapshot.getName()); } } diff --git a/src/main/java/com/sk89q/worldedit/commands/SnapshotUtilCommands.java b/src/main/java/com/sk89q/worldedit/commands/SnapshotUtilCommands.java index f7178bf4a..60ccb2665 100644 --- a/src/main/java/com/sk89q/worldedit/commands/SnapshotUtilCommands.java +++ b/src/main/java/com/sk89q/worldedit/commands/SnapshotUtilCommands.java @@ -37,6 +37,7 @@ import com.sk89q.worldedit.data.DataException; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.snapshots.InvalidSnapshotException; import com.sk89q.worldedit.snapshots.Snapshot; +import com.sk89q.worldedit.snapshots.SnapshotRepository; import com.sk89q.worldedit.snapshots.SnapshotRestore; public class SnapshotUtilCommands { @@ -65,9 +66,11 @@ public class SnapshotUtilCommands { throws WorldEditException { LocalConfiguration config = we.getConfiguration(); + String worldName = player.getWorld().getName(); + SnapshotRepository repo = config.snapshotRepositories.get(worldName); - if (config.snapshotRepo == null) { - player.printError("Snapshot/backup restore is not configured."); + if (repo == null) { + player.printError("Snapshot/backup restore is not configured for this world."); return; } @@ -76,26 +79,26 @@ public class SnapshotUtilCommands { if (args.argsLength() > 0) { try { - snapshot = config.snapshotRepo.getSnapshot(args.getString(0)); + snapshot = repo.getSnapshot(args.getString(0)); } catch (InvalidSnapshotException e) { player.printError("That snapshot does not exist or is not available."); return; } } else { - snapshot = session.getSnapshot(); + snapshot = session.getSnapshot(player.getWorld()); } ChunkStore chunkStore = null; // No snapshot set? if (snapshot == null) { - snapshot = config.snapshotRepo.getDefaultSnapshot(); + snapshot = repo.getDefaultSnapshot(); if (snapshot == null) { player.printError("No snapshots were found. See console for details."); // Okay, let's toss some debugging information! - File dir = config.snapshotRepo.getDirectory(); + File dir = repo.getDirectory(); try { logger.info("WorldEdit found no snapshots: looked in: " + diff --git a/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java index dc52eb82b..78e5763ca 100644 --- a/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java +++ b/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java @@ -27,6 +27,7 @@ import com.sk89q.util.StringUtil; import com.sk89q.worldedit.LocalConfiguration; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.snapshots.SnapshotRepository; +import java.util.HashMap; /** * Simple LocalConfiguration that loads settings using @@ -93,10 +94,11 @@ public class PropertiesConfiguration extends LocalConfiguration { LocalSession.MAX_HISTORY_SIZE = Math.max(15, getInt("history-size", 15)); String snapshotsDir = getString("snapshots-dir", ""); + snapshotRepositories = new HashMap(); if (!snapshotsDir.trim().equals("")) { - snapshotRepo = new SnapshotRepository(snapshotsDir); - } else { - snapshotRepo = null; + for (File repository : new File(snapshotsDir).listFiles()) { + snapshotRepositories.put(repository.getName(), new SnapshotRepository(repository)); + } } OutputStream output = null; From 73a86468feb60e1668a83e3916737a981d8d11e0 Mon Sep 17 00:00:00 2001 From: James Robinson Date: Thu, 7 Jul 2011 19:10:36 +0100 Subject: [PATCH 2/2] Add nether snapshot support --- .../data/FileMcRegionChunkStore.java | 12 ++++-- .../data/TrueZipMcRegionChunkStore.java | 40 +++++-------------- .../data/ZippedMcRegionChunkStore.java | 40 +++++-------------- 3 files changed, 30 insertions(+), 62 deletions(-) diff --git a/src/main/java/com/sk89q/worldedit/data/FileMcRegionChunkStore.java b/src/main/java/com/sk89q/worldedit/data/FileMcRegionChunkStore.java index f6c2ce33f..291d1a000 100644 --- a/src/main/java/com/sk89q/worldedit/data/FileMcRegionChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/data/FileMcRegionChunkStore.java @@ -44,11 +44,14 @@ public class FileMcRegionChunkStore extends McRegionChunkStore { @Override protected InputStream getInputStream(String name) throws IOException, DataException { - - String file = "region" + File.separator + name; + String fileName = "region" + File.separator + name; + File file = new File(path, fileName); + if (!file.exists()) { + file = new File(path, "DIM-1" + File.separator + fileName); + } try { - return new FileInputStream(new File(path, file)); + return new FileInputStream(file); } catch (FileNotFoundException e) { throw new MissingChunkException(); } @@ -56,7 +59,8 @@ public class FileMcRegionChunkStore extends McRegionChunkStore { @Override public boolean isValid() { - return new File(path, "region").isDirectory(); + return new File(path, "region").isDirectory() || + new File(path, "DIM-1" + File.separator + "region").isDirectory(); } } diff --git a/src/main/java/com/sk89q/worldedit/data/TrueZipMcRegionChunkStore.java b/src/main/java/com/sk89q/worldedit/data/TrueZipMcRegionChunkStore.java index b066d73d2..763caf246 100644 --- a/src/main/java/com/sk89q/worldedit/data/TrueZipMcRegionChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/data/TrueZipMcRegionChunkStore.java @@ -90,52 +90,34 @@ public class TrueZipMcRegionChunkStore extends McRegionChunkStore { @SuppressWarnings("unchecked") protected InputStream getInputStream(String name) throws IOException, DataException { - String file = "region/" + name; // Detect subfolder for the world's files if (folder != null) { if (!folder.equals("")) { - file = folder + "/" + file; + name = folder + "/" + name; } } else { - ZipEntry testEntry = zip.getEntry("level.dat"); - - // So, the data is not in the root directory - if (testEntry == null) { - // Let's try a world/ sub-directory - testEntry = getEntry("world/level.dat"); + Pattern pattern = Pattern.compile(".*\\.mcr$"); + for (Enumeration e = zip.entries(); + e.hasMoreElements(); ) { + ZipEntry testEntry = (ZipEntry)e.nextElement(); - Pattern pattern = Pattern.compile(".*[\\\\/]level\\.dat$"); - - // So not there either... - if (testEntry == null) { - for (Enumeration e = zip.entries(); - e.hasMoreElements(); ) { - - testEntry = e.nextElement(); - - // Whoo, found level.dat! - if (pattern.matcher(testEntry.getName()).matches()) { - folder = testEntry.getName().replaceAll("level\\.dat$", ""); - folder = folder.substring(0, folder.length() - 1); - file = folder + file; - break; - } - } - } else { - file = "world/" + file; + if (pattern.matcher(testEntry.getName()).matches()) { + folder = testEntry.getName().substring(0, testEntry.getName().lastIndexOf("/")); + name = folder + "/" + name; + break; } } } - ZipEntry entry = getEntry(file); + ZipEntry entry = getEntry(name); if (entry == null) { throw new MissingChunkException(); } try { return zip.getInputStream(entry); } catch (ZipException e) { - throw new IOException("Failed to read " + file + " in ZIP"); + throw new IOException("Failed to read " + name + " in ZIP"); } } diff --git a/src/main/java/com/sk89q/worldedit/data/ZippedMcRegionChunkStore.java b/src/main/java/com/sk89q/worldedit/data/ZippedMcRegionChunkStore.java index 124b43c02..10365d514 100644 --- a/src/main/java/com/sk89q/worldedit/data/ZippedMcRegionChunkStore.java +++ b/src/main/java/com/sk89q/worldedit/data/ZippedMcRegionChunkStore.java @@ -87,52 +87,34 @@ public class ZippedMcRegionChunkStore extends McRegionChunkStore { @Override protected InputStream getInputStream(String name) throws IOException, DataException { - String file = "region/" + name; // Detect subfolder for the world's files if (folder != null) { if (!folder.equals("")) { - file = folder + "/" + file; + name = folder + "/" + name; } } else { - ZipEntry testEntry = zip.getEntry("level.dat"); - - // So, the data is not in the root directory - if (testEntry == null) { - // Let's try a world/ sub-directory - testEntry = getEntry("world/level.dat"); + Pattern pattern = Pattern.compile(".*\\.mcr$"); + for (Enumeration e = zip.entries(); + e.hasMoreElements(); ) { + ZipEntry testEntry = (ZipEntry)e.nextElement(); - Pattern pattern = Pattern.compile(".*[\\\\/]level\\.dat$"); - - // So not there either... - if (testEntry == null) { - for (Enumeration e = zip.entries(); - e.hasMoreElements(); ) { - - testEntry = (ZipEntry)e.nextElement(); - - // Whoo, found level.dat! - if (pattern.matcher(testEntry.getName()).matches()) { - folder = testEntry.getName().replaceAll("level\\.dat$", ""); - folder = folder.substring(0, folder.length() - 1); - file = folder + file; - break; - } - } - } else { - file = "world/" + file; + if (pattern.matcher(testEntry.getName()).matches()) { + folder = testEntry.getName().substring(0, testEntry.getName().lastIndexOf("/")); + name = folder + "/" + name; + break; } } } - ZipEntry entry = getEntry(file); + ZipEntry entry = getEntry(name); if (entry == null) { throw new MissingChunkException(); } try { return zip.getInputStream(entry); } catch (ZipException e) { - throw new IOException("Failed to read " + file + " in ZIP"); + throw new IOException("Failed to read " + name + " in ZIP"); } }