diff --git a/src/main/java/com/sk89q/worldedit/LocalSession.java b/src/main/java/com/sk89q/worldedit/LocalSession.java index 39e7dd3db..5b4a709e0 100644 --- a/src/main/java/com/sk89q/worldedit/LocalSession.java +++ b/src/main/java/com/sk89q/worldedit/LocalSession.java @@ -38,6 +38,7 @@ import com.sk89q.worldedit.internal.cui.SelectionShapeEvent; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.RegionSelector; import com.sk89q.worldedit.regions.selector.CuboidRegionSelector; +import com.sk89q.worldedit.regions.selector.RegionSelectorType; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.session.request.Request; import com.sk89q.worldedit.world.World; @@ -85,6 +86,7 @@ public class LocalSession { // Saved properties private String lastScript; + private RegionSelectorType defaultSelector; /** * Construct the object. @@ -114,6 +116,15 @@ public class LocalSession { this.config = config; } + /** + * Called on post load of the session from persistent storage. + */ + public void postLoad() { + if (defaultSelector != null) { + this.selector = defaultSelector.createSelector(); + } + } + /** * Get whether this session is "dirty" and has changes that needs to * be committed. @@ -260,6 +271,26 @@ public class LocalSession { return null; } + /** + * Get the default region selector. + * + * @return the default region selector + */ + public RegionSelectorType getDefaultRegionSelector() { + return defaultSelector; + } + + /** + * Set the default region selector. + * + * @param defaultSelector the default region selector + */ + public void setDefaultRegionSelector(RegionSelectorType defaultSelector) { + checkNotNull(defaultSelector); + this.defaultSelector = defaultSelector; + setDirty(); + } + /** * @deprecated Use {@link #getRegionSelector(World)} */ @@ -277,15 +308,15 @@ public class LocalSession { */ public RegionSelector getRegionSelector(World world) { checkNotNull(world); - if (selector.getIncompleteRegion().getWorld() == null) { - selector = new CuboidRegionSelector(world); - } else if (!selector.getIncompleteRegion().getWorld().equals(world)) { - selector.getIncompleteRegion().setWorld(world); + if (selector.getWorld() == null || !selector.getWorld().equals(world)) { + selector.setWorld(world); selector.clear(); } return selector; } + + /** * @deprecated use {@link #getRegionSelector(World)} */ @@ -311,7 +342,7 @@ public class LocalSession { public void setRegionSelector(World world, RegionSelector selector) { checkNotNull(world); checkNotNull(selector); - selector.getIncompleteRegion().setWorld(world); + selector.setWorld(world); this.selector = selector; } diff --git a/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java b/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java index 6d7a28bde..e4b5c4662 100644 --- a/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java +++ b/src/main/java/com/sk89q/worldedit/command/SelectionCommands.java @@ -45,6 +45,7 @@ import com.sk89q.worldedit.regions.selector.CylinderRegionSelector; import com.sk89q.worldedit.regions.selector.EllipsoidRegionSelector; import com.sk89q.worldedit.regions.selector.ExtendingCuboidRegionSelector; import com.sk89q.worldedit.regions.selector.Polygonal2DRegionSelector; +import com.sk89q.worldedit.regions.selector.RegionSelectorType; import com.sk89q.worldedit.regions.selector.SphereRegionSelector; import com.sk89q.worldedit.session.ClipboardHolder; import com.sk89q.worldedit.util.Countable; @@ -709,13 +710,13 @@ public class SelectionCommands { @Command( aliases = { "/sel", ";", "/desel", "/deselect" }, + flags = "d", usage = "[cuboid|extend|poly|ellipsoid|sphere|cyl|convex]", desc = "Choose a region selector", min = 0, max = 1 ) public void select(Player player, LocalSession session, EditSession editSession, CommandContext args) throws WorldEditException { - final World world = player.getWorld(); if (args.argsLength() == 0) { session.getRegionSelector(world).clear(); @@ -775,6 +776,23 @@ public class SelectionCommands { return; } + if (args.hasFlag('d')) { + RegionSelectorType found = null; + for (RegionSelectorType type : RegionSelectorType.values()) { + if (type.getSelectorClass() == selector.getClass()) { + found = type; + break; + } + } + + if (found != null) { + session.setDefaultRegionSelector(found); + player.print("Your default region selector is now " + found.name() + "."); + } else { + throw new RuntimeException("Something unexpected happened. Please report this."); + } + } + session.setRegionSelector(world, selector); session.dispatchCUISelection(player); } diff --git a/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java index 71a30f309..1e7e723f6 100644 --- a/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/RegionSelector.java @@ -25,7 +25,9 @@ import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.regions.selector.limit.SelectorLimits; +import com.sk89q.worldedit.world.World; +import javax.annotation.Nullable; import java.util.List; /** @@ -35,6 +37,21 @@ import java.util.List; */ public interface RegionSelector { + /** + * Get the world for the region selector. + * + * @return a world, which may be null + */ + @Nullable + public World getWorld(); + + /** + * Set the world for the region selector. + * + * @param world the world, which may be null + */ + public void setWorld(@Nullable World world); + /** * Called when the first point is selected. * diff --git a/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java index fdfb6fcb0..5dc3af057 100644 --- a/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/selector/ConvexPolyhedralRegionSelector.java @@ -50,8 +50,8 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class ConvexPolyhedralRegionSelector extends com.sk89q.worldedit.regions.ConvexPolyhedralRegionSelector implements RegionSelector, CUIRegion { - private final ConvexPolyhedralRegion region; - private BlockVector pos1; + private final transient ConvexPolyhedralRegion region; + private transient BlockVector pos1; /** * Create a new selector with a {@code null} world. @@ -105,6 +105,17 @@ public class ConvexPolyhedralRegionSelector extends com.sk89q.worldedit.regions. } } + @Nullable + @Override + public World getWorld() { + return region.getWorld(); + } + + @Override + public void setWorld(@Nullable World world) { + region.setWorld(world); + } + @Override public boolean selectPrimary(Vector position, SelectorLimits limits) { checkNotNull(position); diff --git a/src/main/java/com/sk89q/worldedit/regions/selector/CuboidRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/selector/CuboidRegionSelector.java index 36d47fc69..4265490f1 100644 --- a/src/main/java/com/sk89q/worldedit/regions/selector/CuboidRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/selector/CuboidRegionSelector.java @@ -40,9 +40,9 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class CuboidRegionSelector extends com.sk89q.worldedit.regions.CuboidRegionSelector implements RegionSelector, CUIRegion { - protected BlockVector position1; - protected BlockVector position2; - protected CuboidRegion region; + protected transient BlockVector position1; + protected transient BlockVector position2; + protected transient CuboidRegion region; /** * Create a new region selector with a {@code null} world. @@ -106,6 +106,17 @@ public class CuboidRegionSelector extends com.sk89q.worldedit.regions.CuboidRegi region.setPos2(position2); } + @Nullable + @Override + public World getWorld() { + return region.getWorld(); + } + + @Override + public void setWorld(@Nullable World world) { + region.setWorld(world); + } + @Override public boolean selectPrimary(Vector position, SelectorLimits limits) { checkNotNull(position); diff --git a/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java index 1a9297c76..b2d3002c2 100644 --- a/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/selector/CylinderRegionSelector.java @@ -40,12 +40,12 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class CylinderRegionSelector extends com.sk89q.worldedit.regions.CylinderRegionSelector implements RegionSelector, CUIRegion { - protected CylinderRegion region; - protected static final NumberFormat format; + protected static transient final NumberFormat NUMBER_FORMAT; + protected transient CylinderRegion region; static { - format = (NumberFormat) NumberFormat.getInstance().clone(); - format.setMaximumFractionDigits(3); + NUMBER_FORMAT = (NumberFormat) NumberFormat.getInstance().clone(); + NUMBER_FORMAT.setMaximumFractionDigits(3); } /** @@ -115,6 +115,17 @@ public class CylinderRegionSelector extends com.sk89q.worldedit.regions.Cylinder region.setMaximumY(Math.max(minY, maxY)); } + @Nullable + @Override + public World getWorld() { + return region.getWorld(); + } + + @Override + public void setWorld(@Nullable World world) { + region.setWorld(world); + } + @Override public boolean selectPrimary(Vector position, SelectorLimits limits) { if (!region.getCenter().equals(Vector.ZERO) && position.compareTo(region.getCenter()) == 0) { @@ -156,7 +167,7 @@ public class CylinderRegionSelector extends com.sk89q.worldedit.regions.Cylinder Vector center = region.getCenter(); if (!center.equals(Vector.ZERO)) { - player.print("Radius set to " + format.format(region.getRadius().getX()) + "/" + format.format(region.getRadius().getZ()) + " blocks. (" + region.getArea() + ")."); + player.print("Radius set to " + NUMBER_FORMAT.format(region.getRadius().getX()) + "/" + NUMBER_FORMAT.format(region.getRadius().getZ()) + " blocks. (" + region.getArea() + ")."); } else { player.printError("You must select the center point before setting the radius."); return; diff --git a/src/main/java/com/sk89q/worldedit/regions/selector/EllipsoidRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/selector/EllipsoidRegionSelector.java index f2d2e6971..5f3a956d4 100644 --- a/src/main/java/com/sk89q/worldedit/regions/selector/EllipsoidRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/selector/EllipsoidRegionSelector.java @@ -41,8 +41,8 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class EllipsoidRegionSelector extends com.sk89q.worldedit.regions.EllipsoidRegionSelector implements RegionSelector, CUIRegion { - protected EllipsoidRegion region; - protected boolean started = false; + protected transient EllipsoidRegion region; + protected transient boolean started = false; /** * Create a new selector with a {@code null} world. @@ -102,6 +102,17 @@ public class EllipsoidRegionSelector extends com.sk89q.worldedit.regions.Ellipso region.setRadius(radius); } + @Nullable + @Override + public World getWorld() { + return region.getWorld(); + } + + @Override + public void setWorld(@Nullable World world) { + region.setWorld(world); + } + @Override public boolean selectPrimary(Vector position, SelectorLimits limits) { if (position.equals(region.getCenter()) && region.getRadius().lengthSq() == 0) { diff --git a/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java b/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java index 767f17e36..c9611c05f 100644 --- a/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java +++ b/src/main/java/com/sk89q/worldedit/regions/selector/Polygonal2DRegionSelector.java @@ -43,8 +43,8 @@ import static com.google.common.base.Preconditions.checkNotNull; */ public class Polygonal2DRegionSelector extends com.sk89q.worldedit.regions.Polygonal2DRegionSelector implements RegionSelector, CUIRegion { - private BlockVector pos1; - private Polygonal2DRegion region; + private transient BlockVector pos1; + private transient Polygonal2DRegion region; /** * Create a new selector with a {@code null} world. @@ -117,6 +117,17 @@ public class Polygonal2DRegionSelector extends com.sk89q.worldedit.regions.Polyg region = new Polygonal2DRegion(world, points, minY, maxY); } + @Nullable + @Override + public World getWorld() { + return region.getWorld(); + } + + @Override + public void setWorld(@Nullable World world) { + region.setWorld(world); + } + @Override public boolean selectPrimary(Vector position, SelectorLimits limits) { if (position.equals(pos1)) { diff --git a/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java b/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java new file mode 100644 index 000000000..c522ed532 --- /dev/null +++ b/src/main/java/com/sk89q/worldedit/regions/selector/RegionSelectorType.java @@ -0,0 +1,67 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.regions.selector; + +import com.sk89q.worldedit.regions.RegionSelector; + +/** + * An enum of default region selector types. + */ +public enum RegionSelectorType { + + CUBOID(CuboidRegionSelector.class), + EXTENDING_CUBOID(ExtendingCuboidRegionSelector.class), + CYLINDER(CylinderRegionSelector.class), + SPHERE(SphereRegionSelector.class), + ELLIPSOID(EllipsoidRegionSelector.class), + POLYGON(Polygonal2DRegionSelector.class), + CONVEX_POLYHEDRON(ConvexPolyhedralRegionSelector.class); + + private final Class selectorClass; + + private RegionSelectorType(Class selectorClass) { + this.selectorClass = selectorClass; + } + + /** + * Get the selector class. + * + * @return a selector class + */ + public Class getSelectorClass() { + return selectorClass; + } + + /** + * Create a new selector instance. + * + * @return a selector + */ + public RegionSelector createSelector() { + try { + return getSelectorClass().newInstance(); + } catch (InstantiationException e) { + throw new RuntimeException("Could not create selector", e); + } catch (IllegalAccessException e) { + throw new RuntimeException("Could not create selector", e); + } + } + +} diff --git a/src/main/java/com/sk89q/worldedit/session/SessionManager.java b/src/main/java/com/sk89q/worldedit/session/SessionManager.java index 3a3260aa1..60c788ca9 100644 --- a/src/main/java/com/sk89q/worldedit/session/SessionManager.java +++ b/src/main/java/com/sk89q/worldedit/session/SessionManager.java @@ -145,6 +145,7 @@ public class SessionManager { if (session == null) { try { session = store.load(getKey(sessionKey)); + session.postLoad(); } catch (IOException e) { log.log(Level.WARNING, "Failed to load saved session", e); session = new LocalSession();