Clearing the plot needs to only consider removing the blocks - This implementation has
- * used the setCuboidAsync function, as it is fast, and uses NMS code - It also makes use of the
- * fact that deleting chunks is a lot faster than block updates This code is very messy, but you
- * don't need to do something quite as complex unless you happen to have 512x512 sized plots.
- *
- */
- @Override public boolean clearPlot(@Nonnull final Plot plot, @Nullable final Runnable whenDone, @Nullable QueueCoordinator queue) {
+ @Override public boolean clearPlot(@Nonnull final Plot plot,
+ @Nullable final Runnable whenDone,
+ @Nullable PlotPlayer> actor,
+ @Nullable QueueCoordinator queue) {
if (this.regionManager.notifyClear(this)) {
//If this returns false, the clear didn't work
- if (this.regionManager.handleClear(plot, whenDone, this)) {
+ if (this.regionManager.handleClear(plot, whenDone, this, actor)) {
return true;
}
}
diff --git a/Core/src/main/java/com/plotsquared/core/generator/SquarePlotManager.java b/Core/src/main/java/com/plotsquared/core/generator/SquarePlotManager.java
index 8c4b09fdd..e69c5c63a 100644
--- a/Core/src/main/java/com/plotsquared/core/generator/SquarePlotManager.java
+++ b/Core/src/main/java/com/plotsquared/core/generator/SquarePlotManager.java
@@ -27,6 +27,7 @@ package com.plotsquared.core.generator;
import com.plotsquared.core.location.Direction;
import com.plotsquared.core.location.Location;
+import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotId;
@@ -59,7 +60,10 @@ public abstract class SquarePlotManager extends GridPlotManager {
this.regionManager = regionManager;
}
- @Override public boolean clearPlot(final @NotNull Plot plot, final @Nullable Runnable whenDone, @Nullable QueueCoordinator queue) {
+ @Override public boolean clearPlot(final @NotNull Plot plot,
+ final @Nullable Runnable whenDone,
+ @Nullable PlotPlayer> actor,
+ @Nullable QueueCoordinator queue) {
final Set regions = plot.getRegions();
Runnable run = new Runnable() {
@Override public void run() {
diff --git a/Core/src/main/java/com/plotsquared/core/inject/factory/ProgressSubscriberFactory.java b/Core/src/main/java/com/plotsquared/core/inject/factory/ProgressSubscriberFactory.java
index e83f59357..29079d07c 100644
--- a/Core/src/main/java/com/plotsquared/core/inject/factory/ProgressSubscriberFactory.java
+++ b/Core/src/main/java/com/plotsquared/core/inject/factory/ProgressSubscriberFactory.java
@@ -26,6 +26,7 @@
package com.plotsquared.core.inject.factory;
import com.google.inject.assistedinject.Assisted;
+import com.plotsquared.core.configuration.caption.Caption;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
import com.plotsquared.core.util.task.TaskManager;
@@ -35,8 +36,12 @@ import javax.annotation.Nullable;
public interface ProgressSubscriberFactory {
- @Nonnull ProgressSubscriber create(@Nullable @Assisted("subscriber") PlotPlayer actor,
+ @Nonnull ProgressSubscriber create(@Nonnull @Assisted("subscriber") PlotPlayer> actor);
+
+ @Nonnull ProgressSubscriber create(@Nonnull @Assisted("subscriber") PlotPlayer> actor,
+ @Nonnull TaskManager taskManager,
@Assisted("progressInterval") final long interval,
- @Nonnull TaskManager taskManager);
+ @Assisted("progressInterval") final long wait,
+ @Nullable @Assisted("caption") Caption caption);
}
diff --git a/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java b/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java
index 97f0bff81..2b3fdf764 100644
--- a/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java
+++ b/Core/src/main/java/com/plotsquared/core/player/PlotPlayer.java
@@ -576,7 +576,7 @@ public abstract class PlotPlayer implements CommandCaller, OfflinePlotPlayer,
}
if (Settings.Enabled_Components.BAN_DELETER && isBanned()) {
for (Plot owned : getPlots()) {
- owned.getPlotModificationManager().deletePlot(null);
+ owned.getPlotModificationManager().deletePlot(null, null);
if (Settings.DEBUG) {
logger.info("Plot {} was deleted + cleared due to {} getting banned", owned.getId(), getName());
}
diff --git a/Core/src/main/java/com/plotsquared/core/plot/Plot.java b/Core/src/main/java/com/plotsquared/core/plot/Plot.java
index c2689461e..62c9f28e8 100644
--- a/Core/src/main/java/com/plotsquared/core/plot/Plot.java
+++ b/Core/src/main/java/com/plotsquared/core/plot/Plot.java
@@ -1623,7 +1623,7 @@ public class Plot {
e.printStackTrace();
return true;
}
- schematicHandler.paste(sch, this, 0, 1, 0, Settings.Schematics.PASTE_ON_TOP, new RunnableVal() {
+ schematicHandler.paste(sch, this, 0, 1, 0, Settings.Schematics.PASTE_ON_TOP, player, new RunnableVal() {
@Override public void run(Boolean value) {
if (value) {
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_success"));
diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotManager.java b/Core/src/main/java/com/plotsquared/core/plot/PlotManager.java
index 21b810072..3dc8c6a36 100644
--- a/Core/src/main/java/com/plotsquared/core/plot/PlotManager.java
+++ b/Core/src/main/java/com/plotsquared/core/plot/PlotManager.java
@@ -28,6 +28,7 @@ package com.plotsquared.core.plot;
import com.plotsquared.core.command.Template;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.location.Location;
+import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.queue.QueueCoordinator;
import com.plotsquared.core.util.FileBytes;
import com.sk89q.worldedit.function.pattern.Pattern;
@@ -61,7 +62,10 @@ public abstract class PlotManager {
// the same applies here
public abstract Location getPlotTopLocAbs(@Nonnull PlotId plotId);
- public abstract boolean clearPlot(@Nonnull Plot plot, @Nullable Runnable whenDone, @Nullable QueueCoordinator queue);
+ public abstract boolean clearPlot(@Nonnull Plot plot,
+ @Nullable Runnable whenDone,
+ @Nullable PlotPlayer> actor,
+ @Nullable QueueCoordinator queue);
public abstract boolean claimPlot(@Nonnull Plot plot, @Nullable QueueCoordinator queue);
@@ -98,6 +102,7 @@ public abstract class PlotManager {
* @param plotId id of plot to set component to
* @param component FLOOR, WALL, AIR, MAIN, MIDDLE, OUTLINE, BORDER, ALL (floor, air and main).
* @param blocks Pattern to set component to
+ * @param actor The player executing the task
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
* otherwise writes to the queue but does not enqueue.
* @return success or not
@@ -105,6 +110,7 @@ public abstract class PlotManager {
public abstract boolean setComponent(@Nonnull PlotId plotId,
@Nonnull String component,
@Nonnull Pattern blocks,
+ @Nullable PlotPlayer> actor,
@Nullable QueueCoordinator queue);
/**
diff --git a/Core/src/main/java/com/plotsquared/core/plot/PlotModificationManager.java b/Core/src/main/java/com/plotsquared/core/plot/PlotModificationManager.java
index cf56fe1a3..2db54b448 100644
--- a/Core/src/main/java/com/plotsquared/core/plot/PlotModificationManager.java
+++ b/Core/src/main/java/com/plotsquared/core/plot/PlotModificationManager.java
@@ -25,8 +25,10 @@
*/
package com.plotsquared.core.plot;
+import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.ConfigurationUtil;
+import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.Caption;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc;
@@ -35,6 +37,7 @@ import com.plotsquared.core.events.PlotMergeEvent;
import com.plotsquared.core.events.PlotUnlinkEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.generator.SquarePlotWorld;
+import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
import com.plotsquared.core.location.Direction;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer;
@@ -75,8 +78,9 @@ public final class PlotModificationManager {
private static final Logger logger = LoggerFactory.getLogger("P2/" + PlotModificationManager.class.getSimpleName());
private final Plot plot;
+ @Inject private ProgressSubscriberFactory subscriberFactory;
- PlotModificationManager(@Nonnull final Plot plot) {
+ @Inject PlotModificationManager(@Nonnull final Plot plot) {
this.plot = plot;
}
@@ -85,9 +89,10 @@ public final class PlotModificationManager {
* Copy a plot to a location, both physically and the settings
*
* @param destination destination plot
+ * @param actor the actor associated with the copy
* @return Future that completes with {@code true} if the copy was successful, else {@code false}
*/
- public CompletableFuture copy(@Nonnull final Plot destination) {
+ public CompletableFuture copy(@Nonnull final Plot destination, @Nullable PlotPlayer> actor) {
final CompletableFuture future = new CompletableFuture<>();
final PlotId offset = PlotId.of(destination.getId().getX() - this.plot.getId().getX(), destination.getId().getY() - this.plot.getId().getY());
final Location db = destination.getBottomAbs();
@@ -169,7 +174,7 @@ public final class PlotModificationManager {
Location pos1 = corners[0];
Location pos2 = corners[1];
Location newPos = pos1.add(offsetX, 0, offsetZ).withWorld(destination.getWorldName());
- PlotSquared.platform().getRegionManager().copyRegion(pos1, pos2, newPos, this);
+ PlotSquared.platform().getRegionManager().copyRegion(pos1, pos2, newPos, actor, this);
}
};
run.run();
@@ -180,22 +185,26 @@ public final class PlotModificationManager {
* Clear the plot
*
* @param whenDone A runnable to execute when clearing finishes, or null
- * @see #clear(boolean, boolean, Runnable)
- * @see #deletePlot(Runnable) to clear and delete a plot
+ * @see #clear(boolean, boolean, PlotPlayer, Runnable)
+ * @see #deletePlot(PlotPlayer, Runnable) to clear and delete a plot
*/
public void clear(@Nullable final Runnable whenDone) {
- this.clear(false, false, whenDone);
+ this.clear(false, false, null, whenDone);
}
/**
* Clear the plot
*
* @param checkRunning Whether or not already executing tasks should be checked
- * @param isDelete Whether or not the plot is being deleted
- * @param whenDone A runnable to execute when clearing finishes, or null
- * @see #deletePlot(Runnable) to clear and delete a plot
+ * @param isDelete Whether or not the plot is being deleted
+ * @param actor The actor clearing the plot
+ * @param whenDone A runnable to execute when clearing finishes, or null
+ * @see #deletePlot(PlotPlayer, Runnable) to clear and delete a plot
*/
- public boolean clear(final boolean checkRunning, final boolean isDelete, @Nullable final Runnable whenDone) {
+ public boolean clear(final boolean checkRunning,
+ final boolean isDelete,
+ @Nullable final PlotPlayer> actor,
+ @Nullable final Runnable whenDone) {
if (checkRunning && this.plot.getRunning() != 0) {
return false;
}
@@ -229,6 +238,9 @@ public final class PlotModificationManager {
manager.claimPlot(current, queue);
}
}
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ queue.addProgressSubscriber(subscriberFactory.create(actor));
+ }
if (queue.size() > 0) {
queue.enqueue();
}
@@ -245,7 +257,7 @@ public final class PlotModificationManager {
}
return;
}
- manager.clearPlot(current, this, null);
+ manager.clearPlot(current, this, actor, null);
}
};
run.run();
@@ -352,11 +364,8 @@ public final class PlotModificationManager {
if (this.plot.getArea().allowSigns()) {
Location location = manager.getSignLoc(this.plot);
String id = this.plot.getId().toString();
- Caption[] lines =
- new Caption[] {TranslatableCaption.of("signs.owner_sign_line_1"),
- TranslatableCaption.of("signs.owner_sign_line_2"),
- TranslatableCaption.of("signs.owner_sign_line_3"),
- TranslatableCaption.of("signs.owner_sign_line_4")};
+ Caption[] lines = new Caption[] {TranslatableCaption.of("signs.owner_sign_line_1"), TranslatableCaption.of("signs.owner_sign_line_2"),
+ TranslatableCaption.of("signs.owner_sign_line_3"), TranslatableCaption.of("signs.owner_sign_line_4")};
PlotSquared.platform().getWorldUtil().setSign(location, lines, Template.of("id", id), Template.of("owner", name));
}
}
@@ -387,8 +396,8 @@ public final class PlotModificationManager {
return;
}
Location location = manager.getSignLoc(this.plot);
- QueueCoordinator queue = PlotSquared.platform().getGlobalBlockQueue()
- .getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(this.plot.getWorldName()));
+ QueueCoordinator queue =
+ PlotSquared.platform().getGlobalBlockQueue().getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(this.plot.getWorldName()));
queue.setBlock(location.getX(), location.getY(), location.getZ(), BlockTypes.AIR.getDefaultState());
queue.enqueue();
}
@@ -450,17 +459,15 @@ public final class PlotModificationManager {
if (notify && plotworld.isAutoMerge()) {
final PlotPlayer> player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid);
- PlotMergeEvent
- event = PlotSquared.get().getEventDispatcher().callMerge(this.plot, Direction.ALL, Integer.MAX_VALUE, player);
+ PlotMergeEvent event = PlotSquared.get().getEventDispatcher().callMerge(this.plot, Direction.ALL, Integer.MAX_VALUE, player);
if (event.getEventResult() == Result.DENY) {
if (player != null) {
- player.sendMessage(TranslatableCaption.of("events.event_denied"),
- Template.of("value", "Auto merge on claim"));
+ player.sendMessage(TranslatableCaption.of("events.event_denied"), Template.of("value", "Auto merge on claim"));
}
return;
}
- plot.getPlotModificationManager().autoMerge(event.getDir(), event.getMax(), uuid, true);
+ plot.getPlotModificationManager().autoMerge(event.getDir(), event.getMax(), uuid, player, true);
}
});
return true;
@@ -495,10 +502,15 @@ public final class PlotModificationManager {
* @param dir the direction to merge
* @param max the max number of merges to do
* @param uuid the UUID it is allowed to merge with
+ * @param actor The actor executing the task
* @param removeRoads whether to remove roads
* @return {@code true} if a merge takes place, else {@code false}
*/
- public boolean autoMerge(@Nonnull final Direction dir, int max, @Nonnull final UUID uuid, final boolean removeRoads) {
+ public boolean autoMerge(@Nonnull final Direction dir,
+ int max,
+ @Nonnull final UUID uuid,
+ @Nullable PlotPlayer> actor,
+ final boolean removeRoads) {
//Ignore merging if there is no owner for the plot
if (!this.plot.hasOwner()) {
return false;
@@ -584,6 +596,9 @@ public final class PlotModificationManager {
}
}
}
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ queue.addProgressSubscriber(subscriberFactory.create(actor));
+ }
if (queue.size() > 0) {
queue.enqueue();
}
@@ -595,11 +610,13 @@ public final class PlotModificationManager {
* Moves a plot physically, as well as the corresponding settings.
*
* @param destination Plot moved to
+ * @param actor The actor executing the task
* @param whenDone task when done
* @param allowSwap whether to swap plots
* @return {@code true} if the move was successful, else {@code false}
*/
@Nonnull public CompletableFuture move(@Nonnull final Plot destination,
+ @Nullable final PlotPlayer> actor,
@Nonnull final Runnable whenDone,
final boolean allowSwap) {
final PlotId offset = PlotId.of(destination.getId().getX() - this.plot.getId().getX(), destination.getId().getY() - this.plot.getId().getY());
@@ -669,7 +686,7 @@ public final class PlotModificationManager {
Location pos1 = corners[0];
Location pos2 = corners[1];
Location pos3 = pos1.add(offsetX, 0, offsetZ).withWorld(destination.getWorldName());
- PlotSquared.platform().getRegionManager().swap(pos1, pos2, pos3, this);
+ PlotSquared.platform().getRegionManager().swap(pos1, pos2, pos3, actor, this);
}
}
}.run();
@@ -678,7 +695,8 @@ public final class PlotModificationManager {
@Override public void run() {
if (regions.isEmpty()) {
Plot plot = destination.getRelative(0, 0);
- Plot originPlot = originArea.getPlotAbs(PlotId.of(plot.getId().getX() - offset.getX(), plot.getId().getY() - offset.getY()));
+ Plot originPlot =
+ originArea.getPlotAbs(PlotId.of(plot.getId().getX() - offset.getX(), plot.getId().getY() - offset.getY()));
final Runnable clearDone = () -> {
QueueCoordinator queue = PlotModificationManager.this.plot.getArea().getQueue();
for (final Plot current : plot.getConnectedPlots()) {
@@ -691,7 +709,7 @@ public final class PlotModificationManager {
TaskManager.runTask(whenDone);
};
if (originPlot != null) {
- originPlot.getPlotModificationManager().clear(false, true, clearDone);
+ originPlot.getPlotModificationManager().clear(false, true, actor, clearDone);
} else {
clearDone.run();
}
@@ -703,7 +721,7 @@ public final class PlotModificationManager {
final Location pos1 = corners[0];
final Location pos2 = corners[1];
Location newPos = pos1.add(offsetX, 0, offsetZ).withWorld(destination.getWorldName());
- PlotSquared.platform().getRegionManager().copyRegion(pos1, pos2, newPos, task);
+ PlotSquared.platform().getRegionManager().copyRegion(pos1, pos2, newPos, actor, task);
}
}.run();
}
@@ -726,11 +744,14 @@ public final class PlotModificationManager {
* - The destination must correspond to a valid plot of equal dimensions
*
* @param destination The other plot to swap with
+ * @param actor The actor executing the task
* @param whenDone A task to run when finished, or null
* @return Future that completes with {@code true} if the swap was successful, else {@code false}
*/
- @Nonnull public CompletableFuture swap(@Nonnull final Plot destination, @Nonnull final Runnable whenDone) {
- return this.move(destination, whenDone, true);
+ @Nonnull public CompletableFuture swap(@Nonnull final Plot destination,
+ @Nullable PlotPlayer> actor,
+ @Nonnull final Runnable whenDone) {
+ return this.move(destination, actor, whenDone, true);
}
/**
@@ -738,11 +759,14 @@ public final class PlotModificationManager {
* - The location must be empty
*
* @param destination Where to move the plot
+ * @param actor The actor executing the task
* @param whenDone A task to run when done, or null
* @return Future that completes with {@code true} if the move was successful, else {@code false}
*/
- @Nonnull public CompletableFuture move(@Nonnull final Plot destination, @Nonnull final Runnable whenDone) {
- return this.move(destination, whenDone, false);
+ @Nonnull public CompletableFuture move(@Nonnull final Plot destination,
+ @Nullable PlotPlayer> actor,
+ @Nonnull final Runnable whenDone) {
+ return this.move(destination, actor, whenDone, false);
}
/**
@@ -752,31 +776,34 @@ public final class PlotModificationManager {
*
* @param component Component to set
* @param blocks Pattern to use the generation
- * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
- * otherwise writes to the queue but does not enqueue.
+ * @param actor The actor executing the task
+ * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
+ * otherwise writes to the queue but does not enqueue.
* @return {@code true} if the component was set successfully, else {@code false}
*/
- public boolean setComponent(@Nonnull final String component, @Nonnull final Pattern blocks, @Nullable final QueueCoordinator queue) {
+ public boolean setComponent(@Nonnull final String component,
+ @Nonnull final Pattern blocks,
+ @Nullable PlotPlayer> actor,
+ @Nullable final QueueCoordinator queue) {
final PlotComponentSetEvent event = PlotSquared.get().getEventDispatcher().callComponentSet(this.plot, component, blocks);
- return this.plot.getManager().setComponent(this.plot.getId(), event.getComponent(), event.getPattern(), queue);
+ return this.plot.getManager().setComponent(this.plot.getId(), event.getComponent(), event.getPattern(), actor, queue);
}
/**
* Delete a plot (use null for the runnable if you don't need to be notified on completion)
*
- * @see PlotSquared#removePlot(Plot, boolean)
- * @see PlotModificationManager#clear(boolean, boolean, Runnable) to simply clear a plot
- *
+ * @param actor The actor executing the task
* @param whenDone task to run when plot has been deleted. Nullable
- *
* @return {@code true} if the deletion was successful, {@code false} if not
+ * @see PlotSquared#removePlot(Plot, boolean)
+ * @see PlotModificationManager#clear(boolean, boolean, PlotPlayer, Runnable) to simply clear a plot
*/
- public boolean deletePlot(final Runnable whenDone) {
+ public boolean deletePlot(@Nullable PlotPlayer> actor, final Runnable whenDone) {
if (!this.plot.hasOwner()) {
return false;
}
final Set plots = this.plot.getConnectedPlots();
- this.clear(false, true, () -> {
+ this.clear(false, true, actor, () -> {
for (Plot current : plots) {
current.unclaim();
}
@@ -790,18 +817,18 @@ public final class PlotModificationManager {
* (components are generator specific)
*
* @param component component to set
- * @param blocks string of block(s) to set component to
- * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
- * otherwise writes to the queue but does not enqueue.
- *
+ * @param blocks string of block(s) to set component to
+ * @param actor The player executing the task
+ * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
+ * otherwise writes to the queue but does not enqueue.
* @return {@code true} if the update was successful, {@code false} if not
*/
- @Deprecated public boolean setComponent(String component, String blocks, QueueCoordinator queue) {
+ @Deprecated public boolean setComponent(String component, String blocks, @Nullable PlotPlayer> actor, @Nullable QueueCoordinator queue) {
final BlockBucket parsed = ConfigurationUtil.BLOCK_BUCKET.parseString(blocks);
if (parsed != null && parsed.isEmpty()) {
return false;
}
- return this.setComponent(component, parsed.toPattern(), queue);
+ return this.setComponent(component, parsed.toPattern(), actor, queue);
}
/**
diff --git a/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java b/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java
index 65e9c876c..14120818f 100644
--- a/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java
+++ b/Core/src/main/java/com/plotsquared/core/plot/expiration/ExpireManager.java
@@ -426,7 +426,7 @@ public class ExpireManager {
Templates.of("plot", plot.toString()));
}
}
- plot.getPlotModificationManager().deletePlot(whenDone);
+ plot.getPlotModificationManager().deletePlot(null, whenDone);
}
public long getAge(UUID uuid) {
diff --git a/Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotManager.java b/Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotManager.java
index c76c522b9..1dd291ef1 100644
--- a/Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotManager.java
+++ b/Core/src/main/java/com/plotsquared/core/plot/world/SinglePlotManager.java
@@ -27,6 +27,7 @@ package com.plotsquared.core.plot.world;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.location.Location;
+import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotId;
@@ -64,7 +65,7 @@ public class SinglePlotManager extends PlotManager {
return Location.at(plotId.toCommaSeparatedString(), 30000000, 0, 30000000);
}
- @Override public boolean clearPlot(@NotNull Plot plot, final Runnable whenDone, @Nullable QueueCoordinator queue) {
+ @Override public boolean clearPlot(@NotNull Plot plot, final Runnable whenDone, @Nullable PlotPlayer> actor, @Nullable QueueCoordinator queue) {
PlotSquared.platform().getSetupUtils().unload(plot.getWorldName(), false);
final File worldFolder = new File(PlotSquared.platform().getWorldContainer(), plot.getWorldName());
TaskManager.getPlatformImplementation().taskAsync(() -> {
@@ -96,8 +97,11 @@ public class SinglePlotManager extends PlotManager {
return new String[0];
}
- @Override
- public boolean setComponent(@NotNull PlotId plotId, @NotNull String component, @NotNull Pattern blocks, @Nullable QueueCoordinator queue) {
+ @Override public boolean setComponent(@NotNull PlotId plotId,
+ @NotNull String component,
+ @NotNull Pattern blocks,
+ @Nullable PlotPlayer> actor,
+ @Nullable QueueCoordinator queue) {
return false;
}
diff --git a/Core/src/main/java/com/plotsquared/core/queue/ChunkCoordinatorBuilder.java b/Core/src/main/java/com/plotsquared/core/queue/ChunkCoordinatorBuilder.java
index 592e852c7..0899527e8 100644
--- a/Core/src/main/java/com/plotsquared/core/queue/ChunkCoordinatorBuilder.java
+++ b/Core/src/main/java/com/plotsquared/core/queue/ChunkCoordinatorBuilder.java
@@ -27,6 +27,7 @@ package com.plotsquared.core.queue;
import com.google.common.base.Preconditions;
import com.google.inject.Inject;
+import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
@@ -54,8 +55,8 @@ public class ChunkCoordinatorBuilder {
private Consumer chunkConsumer;
private Runnable whenDone = () -> {
};
- private long maxIterationTime = 60; // A little over 1 tick;
- private int initialBatchSize = 4;
+ private long maxIterationTime = Settings.QUEUE.MAX_ITERATION_TIME; // A little over 1 tick;
+ private int initialBatchSize = Settings.QUEUE.INITIAL_BATCH_SIZE;
private boolean unloadAfter = true;
@Inject public ChunkCoordinatorBuilder(@Nonnull ChunkCoordinatorFactory chunkCoordinatorFactory) {
diff --git a/Core/src/main/java/com/plotsquared/core/queue/DelegateQueueCoordinator.java b/Core/src/main/java/com/plotsquared/core/queue/DelegateQueueCoordinator.java
index 826990294..21dee819f 100644
--- a/Core/src/main/java/com/plotsquared/core/queue/DelegateQueueCoordinator.java
+++ b/Core/src/main/java/com/plotsquared/core/queue/DelegateQueueCoordinator.java
@@ -25,6 +25,7 @@
*/
package com.plotsquared.core.queue;
+import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.pattern.Pattern;
@@ -203,6 +204,12 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
}
}
+ @Override public void addProgressSubscriber(@Nonnull ProgressSubscriber progressSubscriber) {
+ if (parent != null) {
+ parent.addProgressSubscriber(progressSubscriber);
+ }
+ }
+
@Override @Nonnull public List getReadChunks() {
if (parent != null) {
return parent.getReadChunks();
@@ -246,6 +253,5 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
if (parent != null) {
parent.setRegenRegion(regenRegion);
}
-
}
}
diff --git a/Core/src/main/java/com/plotsquared/core/queue/subscriber/DefaultProgressSubscriber.java b/Core/src/main/java/com/plotsquared/core/queue/subscriber/DefaultProgressSubscriber.java
index 710262a8f..006d2d87a 100644
--- a/Core/src/main/java/com/plotsquared/core/queue/subscriber/DefaultProgressSubscriber.java
+++ b/Core/src/main/java/com/plotsquared/core/queue/subscriber/DefaultProgressSubscriber.java
@@ -26,8 +26,12 @@
package com.plotsquared.core.queue.subscriber;
+import com.google.common.base.Preconditions;
import com.google.common.util.concurrent.AtomicDouble;
+import com.google.inject.Inject;
+import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.Caption;
+import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.queue.ChunkCoordinator;
import com.plotsquared.core.util.task.PlotSquaredTask;
@@ -48,33 +52,43 @@ public class DefaultProgressSubscriber implements ProgressSubscriber {
@Nonnull private final AtomicDouble progress = new AtomicDouble(0);
@Nonnull private final AtomicBoolean started = new AtomicBoolean(false);
- @Nonnull private final TaskManager taskManager;
@Nonnull private final TaskTime interval;
+ @Nonnull private final TaskTime wait;
@Nonnull private final PlotPlayer> actor;
@Nonnull private final Caption caption;
+ @Inject @Nonnull private TaskManager taskManager;
private PlotSquaredTask task;
- public DefaultProgressSubscriber(@Nullable final PlotPlayer> actor,
- @Nonnull final TaskTime interval,
- @Nonnull TaskManager taskManager,
- @Nullable Caption caption) {
- if (actor == null) {
- throw new NullPointerException(
- "Actor cannot be null when using DefaultProgressSubscriber! Make sure if attempting to use custom Subscribers it is correctly parsed to the queue!");
- }
- if (caption == null) {
- throw new NullPointerException(
- "Caption cannot be null when using DefaultProgressSubscriber! Make sure if attempting to use custom Subscribers it is correctly parsed to the queue!");
- }
- this.interval = interval;
- this.taskManager = taskManager;
+ @Inject public DefaultProgressSubscriber(@Nonnull final PlotPlayer> actor) {
+ Preconditions.checkNotNull(actor,
+ "Actor cannot be null when using DefaultProgressSubscriber! Make sure if attempting to use custom Subscribers it is correctly parsed to the queue!");
this.actor = actor;
- this.caption = caption;
+ this.interval = TaskTime.ms(Settings.QUEUE.NOTIFY_INTERVAL);
+ this.wait = TaskTime.ms(Settings.QUEUE.NOTIFY_WAIT);
+ this.caption = TranslatableCaption.of("working.progress");
+ }
+
+ public DefaultProgressSubscriber(@Nonnull final PlotPlayer> actor,
+ @Nonnull final TaskManager taskManager,
+ final long interval,
+ final long wait,
+ @Nullable final Caption caption) {
+ Preconditions.checkNotNull(actor,
+ "Actor cannot be null when using DefaultProgressSubscriber! Make sure if attempting to use custom Subscribers it is correctly parsed to the queue!");
+ this.actor = actor;
+ this.interval = TaskTime.ms(interval);
+ this.wait = TaskTime.ms(wait);
+ this.taskManager = taskManager;
+ if (caption == null) {
+ this.caption = TranslatableCaption.of("working.progress");
+ } else {
+ this.caption = caption;
+ }
}
@Override public void notifyProgress(@Nonnull ChunkCoordinator coordinator, float progress) {
- this.progress.set((double) Math.round(progress * 100) / 100);
- if (coordinator.isCancelled() || progress == 1) {
+ this.progress.set(progress);
+ if (coordinator.isCancelled() || progress >= 1) {
if (task != null) {
task.cancel();
}
@@ -83,8 +97,8 @@ public class DefaultProgressSubscriber implements ProgressSubscriber {
if (!started.get()) {
return;
}
- actor.sendMessage(caption, Template.of("%s", this.progress.toString()));
- }, interval), interval);
+ actor.sendMessage(caption, Template.of("progress", String.valueOf((double) Math.round(this.progress.doubleValue() * 100) / 100)));
+ }, interval), wait);
}
}
}
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 20f5361b3..c51e8b19e 100644
--- a/Core/src/main/java/com/plotsquared/core/util/RegionManager.java
+++ b/Core/src/main/java/com/plotsquared/core/util/RegionManager.java
@@ -27,7 +27,11 @@ package com.plotsquared.core.util;
import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
+import com.plotsquared.core.configuration.Settings;
+import com.plotsquared.core.configuration.caption.StaticCaption;
+import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
import com.plotsquared.core.location.Location;
+import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotManager;
@@ -59,6 +63,8 @@ public abstract class RegionManager {
public static RegionManager manager = null;
private final WorldUtil worldUtil;
private final GlobalBlockQueue blockQueue;
+ @Inject private ProgressSubscriberFactory subscriberFactory;
+ @Inject private TaskManager taskManager;
@Inject public RegionManager(@Nonnull WorldUtil worldUtil, @Nonnull GlobalBlockQueue blockQueue) {
this.worldUtil = worldUtil;
@@ -106,20 +112,25 @@ public abstract class RegionManager {
* @param blocks pattern
* @param minY y to set from
* @param maxY y to set to
+ * @param actor the actor associated with the cuboid set
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
* otherwise writes to the queue but does not enqueue.
* @return true if not enqueued, otherwise whether the created queue enqueued.
*/
- public boolean setCuboids(final PlotArea area,
- final Set regions,
- final Pattern blocks,
+ public boolean setCuboids(@Nonnull final PlotArea area,
+ @Nonnull final Set regions,
+ @Nonnull final Pattern blocks,
int minY,
int maxY,
+ @Nullable PlotPlayer> actor,
@Nullable QueueCoordinator queue) {
boolean enqueue = false;
if (queue == null) {
queue = area.getQueue();
enqueue = true;
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ queue.addProgressSubscriber(subscriberFactory.create(actor));
+ }
}
for (CuboidRegion region : regions) {
Location pos1 = Location.at(area.getWorldName(), region.getMinimumPoint().getX(), minY, region.getMinimumPoint().getZ());
@@ -145,9 +156,13 @@ public abstract class RegionManager {
* @param plot plot
* @param whenDone task to run when complete
* @param manager plot manager
+ * @param actor the player running the clear
* @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);
+ public abstract boolean handleClear(@Nonnull Plot plot,
+ @Nullable final Runnable whenDone,
+ @Nonnull PlotManager manager,
+ @Nullable PlotPlayer> actor);
/**
* Copy a region to a new location (in the same world)
@@ -155,10 +170,15 @@ public abstract class RegionManager {
* @param pos1 position 1
* @param pos2 position 2
* @param newPos position to move pos1 to
+ * @param actor the actor associated with the region copy
* @param whenDone task to run when complete
* @return success or not
*/
- public boolean copyRegion(final Location pos1, final Location pos2, final Location newPos, final Runnable whenDone) {
+ public boolean copyRegion(@Nonnull final Location pos1,
+ @Nonnull final Location pos2,
+ @Nonnull final Location newPos,
+ @Nullable final PlotPlayer> actor,
+ @Nonnull final Runnable whenDone) {
final int relX = newPos.getX() - pos1.getX();
final int relZ = newPos.getZ() - pos1.getZ();
final com.sk89q.worldedit.world.World oldWorld = worldUtil.getWeWorld(pos1.getWorldName());
@@ -167,9 +187,17 @@ public abstract class RegionManager {
final BasicQueueCoordinator copyTo = (BasicQueueCoordinator) blockQueue.getNewQueue(newWorld);
copyFromTo(pos1, pos2, relX, relZ, oldWorld, copyFrom, copyTo, false);
copyFrom.setCompleteTask(copyTo::enqueue);
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ copyFrom.addProgressSubscriber(subscriberFactory.create(actor, taskManager, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT,
+ StaticCaption.of("Current copy progress: %")));
+ }
copyFrom
.addReadChunks(new CuboidRegion(BlockVector3.at(pos1.getX(), 0, pos1.getZ()), BlockVector3.at(pos2.getX(), 0, pos2.getZ())).getChunks());
copyTo.setCompleteTask(whenDone);
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ copyTo.addProgressSubscriber(subscriberFactory.create(actor, taskManager, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT,
+ StaticCaption.of("Current paste progress: %")));
+ }
return copyFrom.enqueue();
}
@@ -188,7 +216,16 @@ public abstract class RegionManager {
public abstract void clearAllEntities(Location pos1, Location pos2);
- public void swap(Location pos1, Location pos2, Location swapPos, final Runnable whenDone) {
+ /**
+ * Swap two regions withn the same world
+ *
+ * @param pos1 position 1
+ * @param pos2 position 2
+ * @param swapPos position to swap with
+ * @param actor the actor associated with the region copy
+ * @param whenDone task to run when complete
+ */
+ public void swap(Location pos1, Location pos2, Location swapPos, @Nullable final PlotPlayer> actor, final Runnable whenDone) {
int relX = swapPos.getX() - pos1.getX();
int relZ = swapPos.getZ() - pos1.getZ();
@@ -208,9 +245,26 @@ public abstract class RegionManager {
copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue1, toQueue2, true);
copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue2, toQueue1, true);
fromQueue1.setCompleteTask(fromQueue2::enqueue);
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ fromQueue1.addProgressSubscriber(subscriberFactory.create(actor, taskManager, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT,
+ StaticCaption.of("Current region 1 copy progress: %")));
+ }
fromQueue2.setCompleteTask(toQueue1::enqueue);
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ fromQueue2.addProgressSubscriber(subscriberFactory.create(actor, taskManager, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT,
+ StaticCaption.of("Current region 2 copy progress: %")));
+ }
toQueue1.setCompleteTask(toQueue2::enqueue);
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ toQueue1.addProgressSubscriber(subscriberFactory.create(actor, taskManager, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT,
+ StaticCaption.of("Current region 1 paste progress: %")));
+ }
toQueue2.setCompleteTask(whenDone);
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ toQueue2.addProgressSubscriber(subscriberFactory.create(actor, taskManager, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT,
+ StaticCaption.of("Current region 2 paste progress: %")));
+ }
+ fromQueue1.enqueue();
}
private void copyFromTo(Location pos1,
diff --git a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java
index e40da7f5b..d405ce210 100644
--- a/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java
+++ b/Core/src/main/java/com/plotsquared/core/util/SchematicHandler.java
@@ -25,10 +25,13 @@
*/
package com.plotsquared.core.util;
+import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.generator.ClassicPlotWorld;
+import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
import com.plotsquared.core.location.Location;
+import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.schematic.Schematic;
@@ -109,8 +112,9 @@ public abstract class SchematicHandler {
public static SchematicHandler manager;
private final WorldUtil worldUtil;
private boolean exportAll = false;
+ @Inject private ProgressSubscriberFactory subscriberFactory;
- public SchematicHandler(@Nonnull final WorldUtil worldUtil) {
+ @Inject public SchematicHandler(@Nonnull final WorldUtil worldUtil) {
this.worldUtil = worldUtil;
}
@@ -257,6 +261,7 @@ public abstract class SchematicHandler {
* @param yOffset offset y to paste it from plot origin
* @param zOffset offset z to paste it from plot origin
* @param autoHeight if to automatically choose height to paste from
+ * @param actor the actor pasting the schematic
* @param whenDone task to run when schematic is pasted
*/
public void paste(final Schematic schematic,
@@ -265,6 +270,7 @@ public abstract class SchematicHandler {
final int yOffset,
final int zOffset,
final boolean autoHeight,
+ final PlotPlayer> actor,
final RunnableVal whenDone) {
TaskManager.runTask(() -> {
@@ -344,6 +350,9 @@ public abstract class SchematicHandler {
if (whenDone != null) {
whenDone.value = true;
}
+ if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
+ queue.addProgressSubscriber(subscriberFactory.create(actor));
+ }
queue.setCompleteTask(whenDone);
queue.enqueue();
} catch (Exception e) {
diff --git a/Core/src/main/java/com/plotsquared/core/util/task/AutoClaimFinishTask.java b/Core/src/main/java/com/plotsquared/core/util/task/AutoClaimFinishTask.java
index 7dac88333..ded5f1c35 100644
--- a/Core/src/main/java/com/plotsquared/core/util/task/AutoClaimFinishTask.java
+++ b/Core/src/main/java/com/plotsquared/core/util/task/AutoClaimFinishTask.java
@@ -41,13 +41,13 @@ import java.util.concurrent.Callable;
public final class AutoClaimFinishTask implements Callable {
- private final PlotPlayer player;
+ private final PlotPlayer> player;
private final Plot plot;
private final PlotArea area;
private final String schematic;
private final EventDispatcher eventDispatcher;
- public AutoClaimFinishTask(final PlotPlayer player, final Plot plot, final PlotArea area,
+ public AutoClaimFinishTask(final PlotPlayer> player, final Plot plot, final PlotArea area,
final String schematic, final EventDispatcher eventDispatcher) {
this.player = player;
this.plot = plot;
@@ -72,7 +72,7 @@ public final class AutoClaimFinishTask implements Callable {
player.sendMessage(TranslatableCaption.of("events.event_denied"),
Templates.of("value", "Auto Merge"));
} else {
- plot.getPlotModificationManager().autoMerge(event.getDir(), event.getMax(), player.getUUID(), true);
+ plot.getPlotModificationManager().autoMerge(event.getDir(), event.getMax(), player.getUUID(), player, true);
}
}
return true;
diff --git a/Core/src/main/resources/lang/messages_en.json b/Core/src/main/resources/lang/messages_en.json
index b625a0d79..d7a8046ad 100644
--- a/Core/src/main/resources/lang/messages_en.json
+++ b/Core/src/main/resources/lang/messages_en.json
@@ -410,6 +410,7 @@
"working.plot_not_claimed": "Plot not claimed.",
"working.plot_is_claimed": "This plot is already claimed.",
"working.claimed": "You successfully claimed the plot.",
+ "working.progress": "Current progress: %",
"list.comment_list_header_paged": "(Page /) List of comments",
"list.comment_list_comment": "[#[;][]\n",