mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-22 13:16:45 +01:00
Merge pull request #2913 from IntellectualSites/features/v6/queue-features
Features/v6/queue features
This commit is contained in:
commit
3f7f6af051
@ -29,6 +29,7 @@ import com.google.inject.AbstractModule;
|
|||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
|
import com.google.inject.assistedinject.FactoryProvider;
|
||||||
import com.plotsquared.bukkit.BukkitPlatform;
|
import com.plotsquared.bukkit.BukkitPlatform;
|
||||||
import com.plotsquared.bukkit.player.BukkitPlayerManager;
|
import com.plotsquared.bukkit.player.BukkitPlayerManager;
|
||||||
import com.plotsquared.bukkit.queue.BukkitChunkCoordinator;
|
import com.plotsquared.bukkit.queue.BukkitChunkCoordinator;
|
||||||
@ -49,12 +50,15 @@ import com.plotsquared.core.inject.annotations.DefaultGenerator;
|
|||||||
import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory;
|
import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory;
|
||||||
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
|
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
|
||||||
import com.plotsquared.core.inject.factory.HybridPlotWorldFactory;
|
import com.plotsquared.core.inject.factory.HybridPlotWorldFactory;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
|
import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
|
||||||
import com.plotsquared.core.plot.world.PlotAreaManager;
|
import com.plotsquared.core.plot.world.PlotAreaManager;
|
||||||
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
import com.plotsquared.core.plot.world.SinglePlotAreaManager;
|
||||||
import com.plotsquared.core.queue.ChunkCoordinator;
|
import com.plotsquared.core.queue.ChunkCoordinator;
|
||||||
import com.plotsquared.core.queue.GlobalBlockQueue;
|
import com.plotsquared.core.queue.GlobalBlockQueue;
|
||||||
import com.plotsquared.core.queue.QueueProvider;
|
import com.plotsquared.core.queue.QueueProvider;
|
||||||
|
import com.plotsquared.core.queue.subscriber.DefaultProgressSubscriber;
|
||||||
|
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
|
||||||
import com.plotsquared.core.util.ChunkManager;
|
import com.plotsquared.core.util.ChunkManager;
|
||||||
import com.plotsquared.core.util.EconHandler;
|
import com.plotsquared.core.util.EconHandler;
|
||||||
import com.plotsquared.core.util.InventoryUtil;
|
import com.plotsquared.core.util.InventoryUtil;
|
||||||
@ -93,6 +97,7 @@ public class BukkitModule extends AbstractModule {
|
|||||||
bind(InventoryUtil.class).to(BukkitInventoryUtil.class);
|
bind(InventoryUtil.class).to(BukkitInventoryUtil.class);
|
||||||
bind(SetupUtils.class).to(BukkitSetupUtils.class);
|
bind(SetupUtils.class).to(BukkitSetupUtils.class);
|
||||||
bind(WorldUtil.class).to(BukkitUtil.class);
|
bind(WorldUtil.class).to(BukkitUtil.class);
|
||||||
|
install(new FactoryModuleBuilder().implement(ProgressSubscriber.class, DefaultProgressSubscriber.class).build(ProgressSubscriberFactory.class));
|
||||||
bind(GlobalBlockQueue.class).toInstance(new GlobalBlockQueue(QueueProvider.of(BukkitQueueCoordinator.class)));
|
bind(GlobalBlockQueue.class).toInstance(new GlobalBlockQueue(QueueProvider.of(BukkitQueueCoordinator.class)));
|
||||||
bind(ChunkManager.class).to(BukkitChunkManager.class);
|
bind(ChunkManager.class).to(BukkitChunkManager.class);
|
||||||
bind(RegionManager.class).to(BukkitRegionManager.class);
|
bind(RegionManager.class).to(BukkitRegionManager.class);
|
||||||
|
@ -29,6 +29,7 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.plotsquared.bukkit.BukkitPlatform;
|
import com.plotsquared.bukkit.BukkitPlatform;
|
||||||
import com.plotsquared.core.queue.ChunkCoordinator;
|
import com.plotsquared.core.queue.ChunkCoordinator;
|
||||||
|
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
|
||||||
import com.plotsquared.core.util.task.TaskManager;
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
import com.plotsquared.core.util.task.TaskTime;
|
import com.plotsquared.core.util.task.TaskTime;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
@ -82,7 +83,8 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
|
|||||||
@Assisted @Nonnull final Collection<BlockVector2> requestedChunks,
|
@Assisted @Nonnull final Collection<BlockVector2> requestedChunks,
|
||||||
@Assisted @Nonnull final Runnable whenDone,
|
@Assisted @Nonnull final Runnable whenDone,
|
||||||
@Assisted @Nonnull final Consumer<Throwable> throwableConsumer,
|
@Assisted @Nonnull final Consumer<Throwable> throwableConsumer,
|
||||||
@Assisted final boolean unloadAfter) {
|
@Assisted final boolean unloadAfter,
|
||||||
|
@Assisted @Nonnull final Collection<ProgressSubscriber> progressSubscribers) {
|
||||||
this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks);
|
this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks);
|
||||||
this.availableChunks = new LinkedBlockingQueue<>();
|
this.availableChunks = new LinkedBlockingQueue<>();
|
||||||
this.totalSize = requestedChunks.size();
|
this.totalSize = requestedChunks.size();
|
||||||
@ -95,6 +97,7 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
|
|||||||
this.unloadAfter = unloadAfter;
|
this.unloadAfter = unloadAfter;
|
||||||
this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class);
|
this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class);
|
||||||
this.bukkitWorld = Bukkit.getWorld(world.getName());
|
this.bukkitWorld = Bukkit.getWorld(world.getName());
|
||||||
|
this.progressSubscribers.addAll(progressSubscribers);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void start() {
|
@Override public void start() {
|
||||||
@ -109,7 +112,7 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
|
|||||||
if (chunk == null) {
|
if (chunk == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
long iterationTime;
|
long[] iterationTime = new long[2];
|
||||||
int processedChunks = 0;
|
int processedChunks = 0;
|
||||||
do {
|
do {
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
@ -124,8 +127,9 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
|
|||||||
processedChunks++;
|
processedChunks++;
|
||||||
final long end = System.currentTimeMillis();
|
final long end = System.currentTimeMillis();
|
||||||
// Update iteration time
|
// Update iteration time
|
||||||
iterationTime = end - start;
|
iterationTime[0] = iterationTime[1];
|
||||||
} while (2 * iterationTime /* last chunk + next chunk */ < this.maxIterationTime && (chunk = availableChunks.poll()) != null);
|
iterationTime[1] = end - start;
|
||||||
|
} while (iterationTime[0] + iterationTime[1] < this.maxIterationTime * 2 && (chunk = availableChunks.poll()) != null);
|
||||||
if (processedChunks < this.batchSize) {
|
if (processedChunks < this.batchSize) {
|
||||||
// Adjust batch size based on the amount of processed chunks per tick
|
// Adjust batch size based on the amount of processed chunks per tick
|
||||||
this.batchSize = processedChunks;
|
this.batchSize = processedChunks;
|
||||||
@ -133,20 +137,23 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
|
|||||||
|
|
||||||
final int expected = this.expectedSize.addAndGet(-processedChunks);
|
final int expected = this.expectedSize.addAndGet(-processedChunks);
|
||||||
|
|
||||||
final float progress = ((float) totalSize - (float) expected) / (float) totalSize;
|
|
||||||
for (final ProgressSubscriber subscriber : this.progressSubscribers) {
|
|
||||||
subscriber.notifyProgress(this, progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expected <= 0) {
|
if (expected <= 0) {
|
||||||
try {
|
try {
|
||||||
this.whenDone.run();
|
this.whenDone.run();
|
||||||
} catch (final Throwable throwable) {
|
} catch (final Throwable throwable) {
|
||||||
this.throwableConsumer.accept(throwable);
|
this.throwableConsumer.accept(throwable);
|
||||||
|
} finally {
|
||||||
|
for (final ProgressSubscriber subscriber : this.progressSubscribers) {
|
||||||
|
subscriber.notifyEnd();
|
||||||
|
}
|
||||||
|
this.cancel();
|
||||||
}
|
}
|
||||||
this.cancel();
|
|
||||||
} else {
|
} else {
|
||||||
if (this.availableChunks.size() < processedChunks) {
|
if (this.availableChunks.size() < processedChunks) {
|
||||||
|
final double progress = ((double) totalSize - (double) expected) / (double) totalSize;
|
||||||
|
for (final ProgressSubscriber subscriber : this.progressSubscribers) {
|
||||||
|
subscriber.notifyProgress(this, progress);
|
||||||
|
}
|
||||||
this.requestBatch();
|
this.requestBatch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,21 +212,8 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
|
|||||||
*
|
*
|
||||||
* @param subscriber Subscriber
|
* @param subscriber Subscriber
|
||||||
*/
|
*/
|
||||||
public void subscribeToProgress(@Nonnull final BukkitChunkCoordinator.ProgressSubscriber subscriber) {
|
public void subscribeToProgress(@Nonnull final ProgressSubscriber subscriber) {
|
||||||
this.progressSubscribers.add(subscriber);
|
this.progressSubscribers.add(subscriber);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ProgressSubscriber {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify about a progress update in the coordinator
|
|
||||||
*
|
|
||||||
* @param coordinator Coordinator instance that triggered the notification
|
|
||||||
* @param progress Progress in the range [0, 1]
|
|
||||||
*/
|
|
||||||
void notifyProgress(@Nonnull final BukkitChunkCoordinator coordinator, final float progress);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,8 @@ import java.util.function.Consumer;
|
|||||||
|
|
||||||
public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
||||||
|
|
||||||
private final SideEffectSet sideEffectSet;
|
private final SideEffectSet noSideEffectSet;
|
||||||
|
private final SideEffectSet lightingSideEffectSet;
|
||||||
private org.bukkit.World bukkitWorld;
|
private org.bukkit.World bukkitWorld;
|
||||||
@Inject private ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory;
|
@Inject private ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory;
|
||||||
@Inject private ChunkCoordinatorFactory chunkCoordinatorFactory;
|
@Inject private ChunkCoordinatorFactory chunkCoordinatorFactory;
|
||||||
@ -71,7 +72,8 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
|
|
||||||
@Inject public BukkitQueueCoordinator(@Nonnull World world) {
|
@Inject public BukkitQueueCoordinator(@Nonnull World world) {
|
||||||
super(world);
|
super(world);
|
||||||
sideEffectSet = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF).with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
|
noSideEffectSet = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF).with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
|
||||||
|
lightingSideEffectSet = SideEffectSet.none().with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public BlockState getBlock(int x, int y, int z) {
|
@Override public BlockState getBlock(int x, int y, int z) {
|
||||||
@ -177,7 +179,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
localChunk.getTiles().forEach(((blockVector3, tag) -> {
|
localChunk.getTiles().forEach(((blockVector3, tag) -> {
|
||||||
try {
|
try {
|
||||||
BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag);
|
BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag);
|
||||||
getWorld().setBlock(blockVector3, block, sideEffectSet);
|
getWorld().setBlock(blockVector3, block, noSideEffectSet);
|
||||||
} catch (WorldEditException ignored) {
|
} catch (WorldEditException ignored) {
|
||||||
StateWrapper sw = new StateWrapper(tag);
|
StateWrapper sw = new StateWrapper(tag);
|
||||||
sw.restoreTag(getWorld().getName(), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
|
sw.restoreTag(getWorld().getName(), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
|
||||||
@ -185,9 +187,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
if (localChunk.getEntities().size() > 0) {
|
if (localChunk.getEntities().size() > 0) {
|
||||||
localChunk.getEntities().forEach((location, entity) -> {
|
localChunk.getEntities().forEach((location, entity) -> getWorld().createEntity(location, entity));
|
||||||
getWorld().createEntity(location, entity);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -198,7 +198,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
chunkCoordinator =
|
chunkCoordinator =
|
||||||
chunkCoordinatorBuilderFactory.create(chunkCoordinatorFactory).inWorld(getWorld()).withChunks(getBlockChunks().keySet()).withChunks(read)
|
chunkCoordinatorBuilderFactory.create(chunkCoordinatorFactory).inWorld(getWorld()).withChunks(getBlockChunks().keySet()).withChunks(read)
|
||||||
.withInitialBatchSize(3).withMaxIterationTime(40).withThrowableConsumer(Throwable::printStackTrace).withFinalAction(getCompleteTask())
|
.withInitialBatchSize(3).withMaxIterationTime(40).withThrowableConsumer(Throwable::printStackTrace).withFinalAction(getCompleteTask())
|
||||||
.withConsumer(consumer).unloadAfter(isUnloadAfter()).build();
|
.withConsumer(consumer).unloadAfter(isUnloadAfter()).withProgressSubscribers(getProgressSubscribers()).build();
|
||||||
return super.enqueue();
|
return super.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +207,23 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
|
|||||||
*/
|
*/
|
||||||
private void setWorldBlock(int x, int y, int z, @Nonnull BaseBlock block, @Nonnull BlockVector2 blockVector2) {
|
private void setWorldBlock(int x, int y, int z, @Nonnull BaseBlock block, @Nonnull BlockVector2 blockVector2) {
|
||||||
try {
|
try {
|
||||||
getWorld().setBlock(BlockVector3.at(x, y, z), block, sideEffectSet);
|
BlockVector3 loc = BlockVector3.at(x, y, z);
|
||||||
|
boolean lighting = false;
|
||||||
|
switch (getLightingMode()) {
|
||||||
|
case NONE:
|
||||||
|
break;
|
||||||
|
case PLACEMENT:
|
||||||
|
lighting = block.getBlockType().getMaterial().getLightValue() > 0;
|
||||||
|
break;
|
||||||
|
case REPLACEMENT:
|
||||||
|
lighting = block.getBlockType().getMaterial().getLightValue() > 0
|
||||||
|
|| getWorld().getBlock(loc).getBlockType().getMaterial().getLightValue() > 0;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Can only be "all"
|
||||||
|
lighting = true;
|
||||||
|
}
|
||||||
|
getWorld().setBlock(loc, block, lighting ? lightingSideEffectSet : noSideEffectSet);
|
||||||
} catch (WorldEditException ignored) {
|
} catch (WorldEditException ignored) {
|
||||||
// Fallback to not so nice method
|
// Fallback to not so nice method
|
||||||
BlockData blockData = BukkitAdapter.adapt(block);
|
BlockData blockData = BukkitAdapter.adapt(block);
|
||||||
|
@ -1,326 +0,0 @@
|
|||||||
/*
|
|
||||||
* _____ _ _ _____ _
|
|
||||||
* | __ \| | | | / ____| | |
|
|
||||||
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
|
||||||
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
|
||||||
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
|
||||||
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
|
||||||
* | |
|
|
||||||
* |_|
|
|
||||||
* PlotSquared plot management system for Minecraft
|
|
||||||
* Copyright (C) 2020 IntellectualSites
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU 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 General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.plotsquared.bukkit.queue;
|
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.plotsquared.bukkit.BukkitPlatform;
|
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
|
||||||
import io.papermc.lib.PaperLib;
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.plugin.Plugin;
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility that allows for the loading and coordination of chunk actions
|
|
||||||
* <p>
|
|
||||||
* The coordinator takes in collection of chunk coordinates, loads them
|
|
||||||
* and allows the caller to specify a sink for the loaded chunks. The
|
|
||||||
* coordinator will prevent the chunks from being unloaded until the sink
|
|
||||||
* has fully consumed the chunk
|
|
||||||
* <p>
|
|
||||||
* Usage:
|
|
||||||
* <pre>{@code
|
|
||||||
* final ChunkCoordinator chunkCoordinator = ChunkCoordinator.builder()
|
|
||||||
* .inWorld(Objects.requireNonNull(Bukkit.getWorld("world"))).withChunk(BlockVector2.at(0, 0))
|
|
||||||
* .withConsumer(chunk -> System.out.printf("Got chunk %d;%d", chunk.getX(), chunk.getZ()))
|
|
||||||
* .withFinalAction(() -> System.out.println("All chunks have been loaded"))
|
|
||||||
* .withThrowableConsumer(throwable -> System.err.println("Something went wrong... =("))
|
|
||||||
* .withMaxIterationTime(25L)
|
|
||||||
* .build();
|
|
||||||
* chunkCoordinator.subscribeToProgress((coordinator, progress) ->
|
|
||||||
* System.out.printf("Progress: %.1f", progress * 100.0f));
|
|
||||||
* chunkCoordinator.start();
|
|
||||||
* }</pre>
|
|
||||||
*
|
|
||||||
* @author Alexander Söderberg
|
|
||||||
* @see #builder() To create a new coordinator instance
|
|
||||||
*/
|
|
||||||
public final class ChunkCoordinator extends BukkitRunnable {
|
|
||||||
|
|
||||||
private final List<ProgressSubscriber> progressSubscribers = new LinkedList<>();
|
|
||||||
|
|
||||||
private final Queue<BlockVector2> requestedChunks;
|
|
||||||
private final Queue<Chunk> availableChunks;
|
|
||||||
private final long maxIterationTime;
|
|
||||||
private final Plugin plugin;
|
|
||||||
private final Consumer<Chunk> chunkConsumer;
|
|
||||||
private final World world;
|
|
||||||
private final Runnable whenDone;
|
|
||||||
private final Consumer<Throwable> throwableConsumer;
|
|
||||||
private final int totalSize;
|
|
||||||
|
|
||||||
private AtomicInteger expectedSize;
|
|
||||||
private int batchSize;
|
|
||||||
|
|
||||||
private ChunkCoordinator(final long maxIterationTime, final int initialBatchSize,
|
|
||||||
@Nonnull final Consumer<Chunk> chunkConsumer, @Nonnull final World world,
|
|
||||||
@Nonnull final Collection<BlockVector2> requestedChunks, @Nonnull final Runnable whenDone,
|
|
||||||
@Nonnull final Consumer<Throwable> throwableConsumer) {
|
|
||||||
this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks);
|
|
||||||
this.availableChunks = new LinkedBlockingQueue<>();
|
|
||||||
this.totalSize = requestedChunks.size();
|
|
||||||
this.expectedSize = new AtomicInteger(this.totalSize);
|
|
||||||
this.world = world;
|
|
||||||
this.batchSize = initialBatchSize;
|
|
||||||
this.chunkConsumer = chunkConsumer;
|
|
||||||
this.maxIterationTime = maxIterationTime;
|
|
||||||
this.whenDone = whenDone;
|
|
||||||
this.throwableConsumer = throwableConsumer;
|
|
||||||
this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new {@link ChunkCoordinator} instance
|
|
||||||
*
|
|
||||||
* @return Coordinator builder instance
|
|
||||||
*/
|
|
||||||
@Nonnull public static ChunkCoordinatorBuilder builder() {
|
|
||||||
return new ChunkCoordinatorBuilder();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start the coordinator instance
|
|
||||||
*/
|
|
||||||
public void start() {
|
|
||||||
// Request initial batch
|
|
||||||
this.requestBatch();
|
|
||||||
// Wait until next tick to give the chunks a chance to be loaded
|
|
||||||
this.runTaskTimer(this.plugin, 1L, 1L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void run() {
|
|
||||||
Chunk chunk = this.availableChunks.poll();
|
|
||||||
if (chunk == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
long iterationTime;
|
|
||||||
int processedChunks = 0;
|
|
||||||
do {
|
|
||||||
final long start = System.currentTimeMillis();
|
|
||||||
try {
|
|
||||||
this.chunkConsumer.accept(chunk);
|
|
||||||
} catch (final Throwable throwable) {
|
|
||||||
this.throwableConsumer.accept(throwable);
|
|
||||||
}
|
|
||||||
this.freeChunk(chunk);
|
|
||||||
processedChunks++;
|
|
||||||
final long end = System.currentTimeMillis();
|
|
||||||
// Update iteration time
|
|
||||||
iterationTime = end - start;
|
|
||||||
} while (2 * iterationTime /* last chunk + next chunk */ < this.maxIterationTime
|
|
||||||
&& (chunk = availableChunks.poll()) != null);
|
|
||||||
if (processedChunks < this.batchSize) {
|
|
||||||
// Adjust batch size based on the amount of processed chunks per tick
|
|
||||||
this.batchSize = processedChunks;
|
|
||||||
}
|
|
||||||
|
|
||||||
final int expected = this.expectedSize.addAndGet(-processedChunks);
|
|
||||||
|
|
||||||
final float progress = ((float) totalSize - (float) expected) / (float) totalSize;
|
|
||||||
for (final ProgressSubscriber subscriber : this.progressSubscribers) {
|
|
||||||
subscriber.notifyProgress(this, progress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (expected <= 0) {
|
|
||||||
try {
|
|
||||||
this.whenDone.run();
|
|
||||||
} catch (final Throwable throwable) {
|
|
||||||
this.throwableConsumer.accept(throwable);
|
|
||||||
}
|
|
||||||
this.cancel();
|
|
||||||
} else {
|
|
||||||
if (this.availableChunks.size() < processedChunks) {
|
|
||||||
this.requestBatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void requestBatch() {
|
|
||||||
BlockVector2 chunk;
|
|
||||||
for (int i = 0; i < this.batchSize && (chunk = this.requestedChunks.poll()) != null; i++) {
|
|
||||||
// This required PaperLib to be bumped to version 1.0.4 to mark the request as urgent
|
|
||||||
PaperLib.getChunkAtAsync(this.world, chunk.getX(), chunk.getZ(), true, true)
|
|
||||||
.whenComplete((chunkObject, throwable) -> {
|
|
||||||
if (throwable != null) {
|
|
||||||
throwable.printStackTrace();
|
|
||||||
// We want one less because this couldn't be processed
|
|
||||||
this.expectedSize.decrementAndGet();
|
|
||||||
} else {
|
|
||||||
this.processChunk(chunkObject);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void processChunk(@Nonnull final Chunk chunk) {
|
|
||||||
if (!chunk.isLoaded()) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
String.format("Chunk %d;%d is is not loaded", chunk.getX(), chunk.getZ()));
|
|
||||||
}
|
|
||||||
chunk.addPluginChunkTicket(this.plugin);
|
|
||||||
this.availableChunks.add(chunk);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void freeChunk(@Nonnull final Chunk chunk) {
|
|
||||||
if (!chunk.isLoaded()) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
String.format("Chunk %d;%d is is not loaded", chunk.getX(), chunk.getZ()));
|
|
||||||
}
|
|
||||||
chunk.removePluginChunkTicket(this.plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the amount of remaining chunks (at the time of the method call)
|
|
||||||
*
|
|
||||||
* @return Snapshot view of remaining chunk count
|
|
||||||
*/
|
|
||||||
public int getRemainingChunks() {
|
|
||||||
return this.expectedSize.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the amount of requested chunks
|
|
||||||
*
|
|
||||||
* @return Requested chunk count
|
|
||||||
*/
|
|
||||||
public int getTotalChunks() {
|
|
||||||
return this.totalSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to coordinator progress updates
|
|
||||||
*
|
|
||||||
* @param subscriber Subscriber
|
|
||||||
*/
|
|
||||||
public void subscribeToProgress(@Nonnull final ChunkCoordinator.ProgressSubscriber subscriber) {
|
|
||||||
this.progressSubscribers.add(subscriber);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ProgressSubscriber {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Notify about a progress update in the coordinator
|
|
||||||
*
|
|
||||||
* @param coordinator Coordinator instance that triggered the notification
|
|
||||||
* @param progress Progress in the range [0, 1]
|
|
||||||
*/
|
|
||||||
void notifyProgress(@Nonnull final ChunkCoordinator coordinator, final float progress);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static final class ChunkCoordinatorBuilder {
|
|
||||||
|
|
||||||
private final List<BlockVector2> requestedChunks = new LinkedList<>();
|
|
||||||
private Consumer<Throwable> throwableConsumer = Throwable::printStackTrace;
|
|
||||||
private World world;
|
|
||||||
private Consumer<Chunk> chunkConsumer;
|
|
||||||
private Runnable whenDone = () -> {
|
|
||||||
};
|
|
||||||
private long maxIterationTime = 60; // A little over 1 tick;
|
|
||||||
private int initialBatchSize = 4;
|
|
||||||
|
|
||||||
private ChunkCoordinatorBuilder() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull public ChunkCoordinatorBuilder inWorld(@Nonnull final World world) {
|
|
||||||
this.world = Preconditions.checkNotNull(world, "World may not be null");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public ChunkCoordinatorBuilder withChunk(@Nonnull final BlockVector2 chunkLocation) {
|
|
||||||
this.requestedChunks
|
|
||||||
.add(Preconditions.checkNotNull(chunkLocation, "Chunk location may not be null"));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull public ChunkCoordinatorBuilder withChunks(
|
|
||||||
@Nonnull final Collection<BlockVector2> chunkLocations) {
|
|
||||||
chunkLocations.forEach(this::withChunk);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull
|
|
||||||
public ChunkCoordinatorBuilder withConsumer(@Nonnull final Consumer<Chunk> chunkConsumer) {
|
|
||||||
this.chunkConsumer =
|
|
||||||
Preconditions.checkNotNull(chunkConsumer, "Chunk consumer may not be null");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull public ChunkCoordinatorBuilder withFinalAction(@Nonnull final Runnable whenDone) {
|
|
||||||
this.whenDone = Preconditions.checkNotNull(whenDone, "Final action may not be null");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull public ChunkCoordinatorBuilder withMaxIterationTime(final long maxIterationTime) {
|
|
||||||
Preconditions
|
|
||||||
.checkArgument(maxIterationTime > 0, "Max iteration time must be positive");
|
|
||||||
this.maxIterationTime = maxIterationTime;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull public ChunkCoordinatorBuilder withInitialBatchSize(final int initialBatchSize) {
|
|
||||||
Preconditions
|
|
||||||
.checkArgument(initialBatchSize > 0, "Initial batch size must be positive");
|
|
||||||
this.initialBatchSize = initialBatchSize;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull public ChunkCoordinatorBuilder withThrowableConsumer(
|
|
||||||
@Nonnull final Consumer<Throwable> throwableConsumer) {
|
|
||||||
this.throwableConsumer =
|
|
||||||
Preconditions.checkNotNull(throwableConsumer, "Throwable consumer may not be null");
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nonnull public ChunkCoordinator build() {
|
|
||||||
Preconditions.checkNotNull(this.world, "No world was supplied");
|
|
||||||
Preconditions.checkNotNull(this.chunkConsumer, "No chunk consumer was supplied");
|
|
||||||
Preconditions.checkNotNull(this.whenDone, "No final action was supplied");
|
|
||||||
Preconditions
|
|
||||||
.checkNotNull(this.throwableConsumer, "No throwable consumer was supplied");
|
|
||||||
return new ChunkCoordinator(this.maxIterationTime, this.initialBatchSize,
|
|
||||||
this.chunkConsumer, this.world, this.requestedChunks, this.whenDone,
|
|
||||||
this.throwableConsumer);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -27,6 +27,7 @@ package com.plotsquared.bukkit.schematic;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.queue.QueueCoordinator;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.SchematicHandler;
|
import com.plotsquared.core.util.SchematicHandler;
|
||||||
import com.plotsquared.core.util.WorldUtil;
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
@ -39,8 +40,8 @@ import javax.annotation.Nonnull;
|
|||||||
*/
|
*/
|
||||||
@Singleton public class BukkitSchematicHandler extends SchematicHandler {
|
@Singleton public class BukkitSchematicHandler extends SchematicHandler {
|
||||||
|
|
||||||
@Inject public BukkitSchematicHandler(@Nonnull final WorldUtil worldUtil) {
|
@Inject public BukkitSchematicHandler(@Nonnull final WorldUtil worldUtil, @Nonnull ProgressSubscriberFactory subscriberFactory) {
|
||||||
super(worldUtil);
|
super(worldUtil, subscriberFactory);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -28,8 +28,10 @@ package com.plotsquared.bukkit.util;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.plotsquared.core.generator.AugmentedUtils;
|
import com.plotsquared.core.generator.AugmentedUtils;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.location.PlotLoc;
|
import com.plotsquared.core.location.PlotLoc;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
@ -53,10 +55,9 @@ import org.bukkit.Chunk;
|
|||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -72,24 +73,22 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
|
|||||||
@Singleton
|
@Singleton
|
||||||
public class BukkitRegionManager extends RegionManager {
|
public class BukkitRegionManager extends RegionManager {
|
||||||
|
|
||||||
private static final Logger logger =
|
|
||||||
LoggerFactory.getLogger("P2/" + BukkitRegionManager.class.getSimpleName());
|
|
||||||
private final GlobalBlockQueue blockQueue;
|
private final GlobalBlockQueue blockQueue;
|
||||||
|
|
||||||
@Inject
|
@Inject public BukkitRegionManager(@Nonnull WorldUtil worldUtil, @Nonnull GlobalBlockQueue blockQueue, @Nonnull
|
||||||
public BukkitRegionManager(@Nonnull WorldUtil worldUtil, @Nonnull GlobalBlockQueue blockQueue) {
|
ProgressSubscriberFactory subscriberFactory) {
|
||||||
super(worldUtil, blockQueue);
|
super(worldUtil, blockQueue, subscriberFactory);
|
||||||
this.blockQueue = blockQueue;
|
this.blockQueue = blockQueue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean handleClear(Plot plot, Runnable whenDone, PlotManager manager) {
|
@Override
|
||||||
|
public boolean handleClear(@Nonnull Plot plot, @Nullable Runnable whenDone, @Nonnull PlotManager manager, @Nullable PlotPlayer<?> player) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public int[] countEntities(Plot plot) {
|
@Override public int[] countEntities(@Nonnull Plot plot) {
|
||||||
int[] existing = (int[]) plot.getMeta("EntityCount");
|
int[] existing = (int[]) plot.getMeta("EntityCount");
|
||||||
if (existing != null && (System.currentTimeMillis() - (long) plot.getMeta("EntityCountTime")
|
if (existing != null && (System.currentTimeMillis() - (long) plot.getMeta("EntityCountTime") < 1000)) {
|
||||||
< 1000)) {
|
|
||||||
return existing;
|
return existing;
|
||||||
}
|
}
|
||||||
PlotArea area = plot.getArea();
|
PlotArea area = plot.getArea();
|
||||||
@ -161,8 +160,10 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean regenerateRegion(final Location pos1, final Location pos2,
|
@Override public boolean regenerateRegion(@Nonnull final Location pos1,
|
||||||
final boolean ignoreAugment, final Runnable whenDone) {
|
@Nonnull final Location pos2,
|
||||||
|
final boolean ignoreAugment,
|
||||||
|
@Nullable final Runnable whenDone) {
|
||||||
final BukkitWorld world = new BukkitWorld((World) pos1.getWorld());
|
final BukkitWorld world = new BukkitWorld((World) pos1.getWorld());
|
||||||
|
|
||||||
final int p1x = pos1.getX();
|
final int p1x = pos1.getX();
|
||||||
@ -176,8 +177,7 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
|
|
||||||
final QueueCoordinator queue = blockQueue.getNewQueue(world);
|
final QueueCoordinator queue = blockQueue.getNewQueue(world);
|
||||||
final QueueCoordinator regenQueue = blockQueue.getNewQueue(world);
|
final QueueCoordinator regenQueue = blockQueue.getNewQueue(world);
|
||||||
queue.addReadChunks(
|
queue.addReadChunks(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()).getChunks());
|
||||||
new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()).getChunks());
|
|
||||||
queue.setChunkConsumer(chunk -> {
|
queue.setChunkConsumer(chunk -> {
|
||||||
|
|
||||||
int x = chunk.getX();
|
int x = chunk.getX();
|
||||||
@ -187,8 +187,7 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
int xxt = xxb + 15;
|
int xxt = xxb + 15;
|
||||||
int zzt = zzb + 15;
|
int zzt = zzb + 15;
|
||||||
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z) {
|
if (xxb >= p1x && xxt <= p2x && zzb >= p1z && zzt <= p2z) {
|
||||||
AugmentedUtils
|
AugmentedUtils.bypass(ignoreAugment, () -> regenQueue.regenChunk(chunk.getX(), chunk.getZ()));
|
||||||
.bypass(ignoreAugment, () -> regenQueue.regenChunk(chunk.getX(), chunk.getZ()));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean checkX1 = false;
|
boolean checkX1 = false;
|
||||||
@ -250,41 +249,37 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
if (checkX2 && checkZ2) {
|
if (checkX2 && checkZ2) {
|
||||||
map.saveRegion(world, xxt2, xxt, zzt2, zzt); //
|
map.saveRegion(world, xxt2, xxt, zzt2, zzt); //
|
||||||
}
|
}
|
||||||
CuboidRegion currentPlotClear =
|
CuboidRegion currentPlotClear = RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
||||||
RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
|
map.saveEntitiesOut(Bukkit.getWorld(world.getName()).getChunkAt(x, z), currentPlotClear);
|
||||||
map.saveEntitiesOut(Bukkit.getWorld(world.getName()).getChunkAt(x, z),
|
AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager.setChunkInPlotArea(null, new RunnableVal<ScopedQueueCoordinator>() {
|
||||||
currentPlotClear);
|
@Override public void run(ScopedQueueCoordinator value) {
|
||||||
AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager
|
Location min = value.getMin();
|
||||||
.setChunkInPlotArea(null, new RunnableVal<ScopedQueueCoordinator>() {
|
int bx = min.getX();
|
||||||
@Override public void run(ScopedQueueCoordinator value) {
|
int bz = min.getZ();
|
||||||
Location min = value.getMin();
|
for (int x1 = 0; x1 < 16; x1++) {
|
||||||
int bx = min.getX();
|
for (int z1 = 0; z1 < 16; z1++) {
|
||||||
int bz = min.getZ();
|
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
|
||||||
for (int x1 = 0; x1 < 16; x1++) {
|
BaseBlock[] ids = map.allBlocks.get(plotLoc);
|
||||||
for (int z1 = 0; z1 < 16; z1++) {
|
if (ids != null) {
|
||||||
PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1);
|
for (int y = 0; y < Math.min(128, ids.length); y++) {
|
||||||
BaseBlock[] ids = map.allBlocks.get(plotLoc);
|
BaseBlock id = ids[y];
|
||||||
if (ids != null) {
|
if (id != null) {
|
||||||
for (int y = 0; y < Math.min(128, ids.length); y++) {
|
value.setBlock(x1, y, z1, id);
|
||||||
BaseBlock id = ids[y];
|
} else {
|
||||||
if (id != null) {
|
value.setBlock(x1, y, z1, BlockTypes.AIR.getDefaultState());
|
||||||
value.setBlock(x1, y, z1, id);
|
|
||||||
} else {
|
|
||||||
value.setBlock(x1, y, z1,
|
|
||||||
BlockTypes.AIR.getDefaultState());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (int y = Math.min(128, ids.length); y < ids.length; y++) {
|
}
|
||||||
BaseBlock id = ids[y];
|
for (int y = Math.min(128, ids.length); y < ids.length; y++) {
|
||||||
if (id != null) {
|
BaseBlock id = ids[y];
|
||||||
value.setBlock(x1, y, z1, id);
|
if (id != null) {
|
||||||
}
|
value.setBlock(x1, y, z1, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, world.getName(), chunk));
|
}
|
||||||
|
}, world.getName(), chunk));
|
||||||
//map.restoreBlocks(worldObj, 0, 0);
|
//map.restoreBlocks(worldObj, 0, 0);
|
||||||
map.restoreEntities(Bukkit.getWorld(world.getName()), 0, 0);
|
map.restoreEntities(Bukkit.getWorld(world.getName()), 0, 0);
|
||||||
});
|
});
|
||||||
@ -294,7 +289,7 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void clearAllEntities(Location pos1, Location pos2) {
|
@Override public void clearAllEntities(@Nonnull Location pos1, @Nonnull Location pos2) {
|
||||||
String world = pos1.getWorldName();
|
String world = pos1.getWorldName();
|
||||||
|
|
||||||
final World bukkitWorld = BukkitUtil.getWorld(world);
|
final World bukkitWorld = BukkitUtil.getWorld(world);
|
||||||
@ -312,8 +307,7 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
for (Entity entity : entities) {
|
for (Entity entity : entities) {
|
||||||
if (!(entity instanceof Player)) {
|
if (!(entity instanceof Player)) {
|
||||||
org.bukkit.Location location = entity.getLocation();
|
org.bukkit.Location location = entity.getLocation();
|
||||||
if (location.getX() >= bx && location.getX() <= tx && location.getZ() >= bz
|
if (location.getX() >= bx && location.getX() <= tx && location.getZ() >= bz && location.getZ() <= tz) {
|
||||||
&& location.getZ() <= tz) {
|
|
||||||
if (entity.hasMetadata("ps-tmp-teleport")) {
|
if (entity.hasMetadata("ps-tmp-teleport")) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -323,17 +317,16 @@ public class BukkitRegionManager extends RegionManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void count(int[] count, Entity entity) {
|
private void count(int[] count, @Nonnull Entity entity) {
|
||||||
final com.sk89q.worldedit.world.entity.EntityType entityType =
|
final com.sk89q.worldedit.world.entity.EntityType entityType = BukkitAdapter.adapt(entity.getType());
|
||||||
BukkitAdapter.adapt(entity.getType());
|
|
||||||
|
|
||||||
if (EntityCategories.PLAYER.contains(entityType)) {
|
if (EntityCategories.PLAYER.contains(entityType)) {
|
||||||
return;
|
return;
|
||||||
} else if (EntityCategories.PROJECTILE.contains(entityType) || EntityCategories.OTHER
|
} else if (EntityCategories.PROJECTILE.contains(entityType) || EntityCategories.OTHER.contains(entityType) || EntityCategories.HANGING
|
||||||
.contains(entityType) || EntityCategories.HANGING.contains(entityType)) {
|
.contains(entityType)) {
|
||||||
count[CAP_MISC]++;
|
count[CAP_MISC]++;
|
||||||
} else if (EntityCategories.ANIMAL.contains(entityType) || EntityCategories.VILLAGER
|
} else if (EntityCategories.ANIMAL.contains(entityType) || EntityCategories.VILLAGER.contains(entityType) || EntityCategories.TAMEABLE
|
||||||
.contains(entityType) || EntityCategories.TAMEABLE.contains(entityType)) {
|
.contains(entityType)) {
|
||||||
count[CAP_MOB]++;
|
count[CAP_MOB]++;
|
||||||
count[CAP_ANIMAL]++;
|
count[CAP_ANIMAL]++;
|
||||||
} else if (EntityCategories.VEHICLE.contains(entityType)) {
|
} else if (EntityCategories.VEHICLE.contains(entityType)) {
|
||||||
|
@ -25,7 +25,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.backup;
|
package com.plotsquared.core.backup;
|
||||||
|
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
@ -64,8 +67,9 @@ public interface BackupProfile {
|
|||||||
* Restore a backup
|
* Restore a backup
|
||||||
*
|
*
|
||||||
* @param backup Backup to restore
|
* @param backup Backup to restore
|
||||||
|
* @param player The player restoring the backup
|
||||||
* @return Future that completes when the backup has finished
|
* @return Future that completes when the backup has finished
|
||||||
*/
|
*/
|
||||||
@Nonnull CompletableFuture<Void> restoreBackup(@Nonnull final Backup backup);
|
@Nonnull CompletableFuture<Void> restoreBackup(@Nonnull final Backup backup, @Nullable PlotPlayer<?> player);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.backup;
|
package com.plotsquared.core.backup;
|
||||||
|
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@ -53,7 +56,7 @@ public class NullBackupProfile implements BackupProfile {
|
|||||||
throw new UnsupportedOperationException("Cannot create backup of an unowned plot");
|
throw new UnsupportedOperationException("Cannot create backup of an unowned plot");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public CompletableFuture<Void> restoreBackup(@Nonnull final Backup backup) {
|
@Override @Nonnull public CompletableFuture<Void> restoreBackup(@Nonnull final Backup backup, @Nullable PlotPlayer<?> player) {
|
||||||
return CompletableFuture.completedFuture(null);
|
return CompletableFuture.completedFuture(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ import com.google.inject.Inject;
|
|||||||
import com.google.inject.assistedinject.Assisted;
|
import com.google.inject.assistedinject.Assisted;
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
import com.plotsquared.core.player.ConsolePlayer;
|
import com.plotsquared.core.player.ConsolePlayer;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.schematic.Schematic;
|
import com.plotsquared.core.plot.schematic.Schematic;
|
||||||
import com.plotsquared.core.util.SchematicHandler;
|
import com.plotsquared.core.util.SchematicHandler;
|
||||||
@ -37,6 +38,7 @@ import com.plotsquared.core.util.task.TaskManager;
|
|||||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
@ -166,7 +168,7 @@ public class PlayerBackupProfile implements BackupProfile {
|
|||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override @Nonnull public CompletableFuture<Void> restoreBackup(@Nonnull final Backup backup) {
|
@Override @Nonnull public CompletableFuture<Void> restoreBackup(@Nonnull final Backup backup, @Nullable PlotPlayer<?> player) {
|
||||||
final CompletableFuture<Void> future = new CompletableFuture<>();
|
final CompletableFuture<Void> future = new CompletableFuture<>();
|
||||||
if (backup.getFile() == null || !Files.exists(backup.getFile())) {
|
if (backup.getFile() == null || !Files.exists(backup.getFile())) {
|
||||||
future.completeExceptionally(new IllegalArgumentException("The specific backup does not exist"));
|
future.completeExceptionally(new IllegalArgumentException("The specific backup does not exist"));
|
||||||
@ -181,7 +183,7 @@ public class PlayerBackupProfile implements BackupProfile {
|
|||||||
if (schematic == null) {
|
if (schematic == null) {
|
||||||
future.completeExceptionally(new IllegalArgumentException("The backup is non-existent or not in the correct format"));
|
future.completeExceptionally(new IllegalArgumentException("The backup is non-existent or not in the correct format"));
|
||||||
} else {
|
} else {
|
||||||
this.schematicHandler.paste(schematic, plot, 0, 1, 0, false, new RunnableVal<Boolean>() {
|
this.schematicHandler.paste(schematic, plot, 0, 1, 0, false, player, new RunnableVal<Boolean>() {
|
||||||
@Override public void run(Boolean value) {
|
@Override public void run(Boolean value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
future.complete(null);
|
future.complete(null);
|
||||||
|
@ -314,7 +314,7 @@ public final class Backup extends Command {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
CmdConfirm.addPending(player, "/plot backup load " + number,
|
CmdConfirm.addPending(player, "/plot backup load " + number,
|
||||||
() -> backupProfile.restoreBackup(backup)
|
() -> backupProfile.restoreBackup(backup, player)
|
||||||
.whenComplete((n, error) -> {
|
.whenComplete((n, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
player.sendMessage(
|
player.sendMessage(
|
||||||
|
@ -50,7 +50,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import javax.annotation.Nullable;
|
|
||||||
|
|
||||||
@CommandDeclaration(
|
@CommandDeclaration(
|
||||||
command = "claim",
|
command = "claim",
|
||||||
@ -186,7 +185,7 @@ public class Claim extends SubCommand {
|
|||||||
Template.of("value", "Auto merge on claim")
|
Template.of("value", "Auto merge on claim")
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
plot.getPlotModificationManager().autoMerge(mergeEvent.getDir(), mergeEvent.getMax(), player.getUUID(), true);
|
plot.getPlotModificationManager().autoMerge(mergeEvent.getDir(), mergeEvent.getMax(), player.getUUID(), player, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -91,7 +91,7 @@ public class Clear extends Command {
|
|||||||
confirm.run(this, () -> {
|
confirm.run(this, () -> {
|
||||||
BackupManager.backup(player, plot, () -> {
|
BackupManager.backup(player, plot, () -> {
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
boolean result = plot.getPlotModificationManager().clear(true, false, () -> {
|
boolean result = plot.getPlotModificationManager().clear(true, false, player, () -> {
|
||||||
plot.getPlotModificationManager().unlink();
|
plot.getPlotModificationManager().unlink();
|
||||||
TaskManager.runTask(() -> {
|
TaskManager.runTask(() -> {
|
||||||
plot.removeRunning();
|
plot.removeRunning();
|
||||||
|
@ -178,7 +178,7 @@ public class Condense extends SubCommand {
|
|||||||
i++;
|
i++;
|
||||||
final AtomicBoolean result = new AtomicBoolean(false);
|
final AtomicBoolean result = new AtomicBoolean(false);
|
||||||
try {
|
try {
|
||||||
result.set(origin.getPlotModificationManager().move(possible, () -> {
|
result.set(origin.getPlotModificationManager().move(possible, player, () -> {
|
||||||
if (result.get()) {
|
if (result.get()) {
|
||||||
player.sendMessage(
|
player.sendMessage(
|
||||||
TranslatableCaption.of("condense.moving"),
|
TranslatableCaption.of("condense.moving"),
|
||||||
|
@ -77,7 +77,7 @@ public class Copy extends SubCommand {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
plot1.getPlotModificationManager().copy(plot2).thenAccept(result -> {
|
plot1.getPlotModificationManager().copy(plot2, player).thenAccept(result -> {
|
||||||
if (result) {
|
if (result) {
|
||||||
player.sendMessage(TranslatableCaption.of("move.copy_success"));
|
player.sendMessage(TranslatableCaption.of("move.copy_success"));
|
||||||
} else {
|
} else {
|
||||||
|
@ -98,7 +98,7 @@ public class Delete extends SubCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
final long start = System.currentTimeMillis();
|
final long start = System.currentTimeMillis();
|
||||||
boolean result = plot.getPlotModificationManager().deletePlot(() -> {
|
boolean result = plot.getPlotModificationManager().deletePlot(player, () -> {
|
||||||
plot.removeRunning();
|
plot.removeRunning();
|
||||||
if (this.econHandler.isEnabled(plotArea)) {
|
if (this.econHandler.isEnabled(plotArea)) {
|
||||||
Expression<Double> valueExr = plotArea.getPrices().get("sell");
|
Expression<Double> valueExr = plotArea.getPrices().get("sell");
|
||||||
|
@ -26,10 +26,10 @@
|
|||||||
package com.plotsquared.core.command;
|
package com.plotsquared.core.command;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.plotsquared.core.permissions.Permission;
|
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.configuration.caption.StaticCaption;
|
import com.plotsquared.core.configuration.caption.StaticCaption;
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
|
import com.plotsquared.core.permissions.Permission;
|
||||||
import com.plotsquared.core.player.MetaDataAccess;
|
import com.plotsquared.core.player.MetaDataAccess;
|
||||||
import com.plotsquared.core.player.PlayerMetaDataKeys;
|
import com.plotsquared.core.player.PlayerMetaDataKeys;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
@ -137,17 +137,16 @@ public class Load extends SubCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
PlotArea area = plot.getArea();
|
PlotArea area = plot.getArea();
|
||||||
this.schematicHandler
|
this.schematicHandler.paste(taskSchematic, plot, 0, area.getMinBuildHeight(), 0, false, player, new RunnableVal<Boolean>() {
|
||||||
.paste(taskSchematic, plot, 0, area.getMinBuildHeight(), 0, false, new RunnableVal<Boolean>() {
|
@Override public void run(Boolean value) {
|
||||||
@Override public void run(Boolean value) {
|
plot.removeRunning();
|
||||||
plot.removeRunning();
|
if (value) {
|
||||||
if (value) {
|
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_success"));
|
||||||
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_success"));
|
} else {
|
||||||
} else {
|
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_failed"));
|
||||||
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_failed"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -180,7 +180,7 @@ public class Merge extends SubCommand {
|
|||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (plot.getPlotModificationManager().autoMerge(Direction.ALL, maxSize, uuid, terrain)) {
|
if (plot.getPlotModificationManager().autoMerge(Direction.ALL, maxSize, uuid, player, terrain)) {
|
||||||
if (this.econHandler.isEnabled(plotArea) && price > 0d) {
|
if (this.econHandler.isEnabled(plotArea) && price > 0d) {
|
||||||
this.econHandler.withdrawMoney(player, price);
|
this.econHandler.withdrawMoney(player, price);
|
||||||
player.sendMessage(
|
player.sendMessage(
|
||||||
@ -224,7 +224,7 @@ public class Merge extends SubCommand {
|
|||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (plot.getPlotModificationManager().autoMerge(direction, maxSize - size, uuid, terrain)) {
|
if (plot.getPlotModificationManager().autoMerge(direction, maxSize - size, uuid, player, terrain)) {
|
||||||
if (this.econHandler.isEnabled(plotArea) && price > 0d) {
|
if (this.econHandler.isEnabled(plotArea) && price > 0d) {
|
||||||
this.econHandler.withdrawMoney(player, price);
|
this.econHandler.withdrawMoney(player, price);
|
||||||
player.sendMessage(
|
player.sendMessage(
|
||||||
@ -259,7 +259,7 @@ public class Merge extends SubCommand {
|
|||||||
final Direction dir = direction;
|
final Direction dir = direction;
|
||||||
Runnable run = () -> {
|
Runnable run = () -> {
|
||||||
accepter.sendMessage(TranslatableCaption.of("merge.merge_accepted"));
|
accepter.sendMessage(TranslatableCaption.of("merge.merge_accepted"));
|
||||||
plot.getPlotModificationManager().autoMerge(dir, maxSize - size, owner, terrain);
|
plot.getPlotModificationManager().autoMerge(dir, maxSize - size, owner, player, terrain);
|
||||||
PlotPlayer<?> plotPlayer = PlotSquared.platform().getPlayerManager().getPlayerIfExists(player.getUUID());
|
PlotPlayer<?> plotPlayer = PlotSquared.platform().getPlayerManager().getPlayerIfExists(player.getUUID());
|
||||||
if (plotPlayer == null) {
|
if (plotPlayer == null) {
|
||||||
accepter.sendMessage(TranslatableCaption.of("merge.merge_not_valid"));
|
accepter.sendMessage(TranslatableCaption.of("merge.merge_not_valid"));
|
||||||
|
@ -106,7 +106,7 @@ public class Move extends SubCommand {
|
|||||||
return CompletableFuture.completedFuture(false);
|
return CompletableFuture.completedFuture(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return plot1.getPlotModificationManager().move(plot2, () -> {
|
return plot1.getPlotModificationManager().move(plot2, player, () -> {
|
||||||
}, false).thenApply(result -> {
|
}, false).thenApply(result -> {
|
||||||
if (result) {
|
if (result) {
|
||||||
player.sendMessage(TranslatableCaption.of("move.move_success"));
|
player.sendMessage(TranslatableCaption.of("move.move_success"));
|
||||||
|
@ -214,7 +214,7 @@ public class Purge extends SubCommand {
|
|||||||
try {
|
try {
|
||||||
ids.add(plot.temp);
|
ids.add(plot.temp);
|
||||||
if (finalClear) {
|
if (finalClear) {
|
||||||
plot.getPlotModificationManager().clear(false, true, () -> {
|
plot.getPlotModificationManager().clear(false, true, player, () -> {
|
||||||
if (Settings.DEBUG) {
|
if (Settings.DEBUG) {
|
||||||
logger.info("Plot {} cleared by purge", plot.getId());
|
logger.info("Plot {} cleared by purge", plot.getId());
|
||||||
}
|
}
|
||||||
|
@ -27,10 +27,10 @@ package com.plotsquared.core.command;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.plotsquared.core.permissions.Permission;
|
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.permissions.Permission;
|
||||||
import com.plotsquared.core.player.ConsolePlayer;
|
import com.plotsquared.core.player.ConsolePlayer;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
@ -149,16 +149,16 @@ public class SchematicCmd extends SubCommand {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.schematicHandler.paste(schematic, plot, 0, 1, 0, false, new RunnableVal<Boolean>() {
|
this.schematicHandler.paste(schematic, plot, 0, 1, 0, false, player, new RunnableVal<Boolean>() {
|
||||||
@Override public void run(Boolean value) {
|
@Override public void run(Boolean value) {
|
||||||
SchematicCmd.this.running = false;
|
SchematicCmd.this.running = false;
|
||||||
if (value) {
|
if (value) {
|
||||||
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_success"));
|
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_success"));
|
||||||
} else {
|
} else {
|
||||||
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_failed"));
|
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_failed"));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -26,10 +26,12 @@
|
|||||||
package com.plotsquared.core.command;
|
package com.plotsquared.core.command;
|
||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.backup.BackupManager;
|
import com.plotsquared.core.backup.BackupManager;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.configuration.caption.StaticCaption;
|
import com.plotsquared.core.configuration.caption.StaticCaption;
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.permissions.Permission;
|
import com.plotsquared.core.permissions.Permission;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
@ -45,19 +47,18 @@ import com.sk89q.worldedit.function.pattern.Pattern;
|
|||||||
import com.sk89q.worldedit.world.block.BlockCategory;
|
import com.sk89q.worldedit.world.block.BlockCategory;
|
||||||
import com.sk89q.worldedit.world.block.BlockType;
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import net.kyori.adventure.text.minimessage.Template;
|
import net.kyori.adventure.text.minimessage.Template;
|
||||||
|
|
||||||
import javax.annotation.Nonnull;
|
import javax.annotation.Nonnull;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
@CommandDeclaration(command = "set",
|
@CommandDeclaration(command = "set",
|
||||||
aliases = {"s"},
|
aliases = {"s"},
|
||||||
@ -156,9 +157,16 @@ public class Set extends SubCommand {
|
|||||||
plot.addRunning();
|
plot.addRunning();
|
||||||
QueueCoordinator queue = plotArea.getQueue();
|
QueueCoordinator queue = plotArea.getQueue();
|
||||||
for (final Plot current : plot.getConnectedPlots()) {
|
for (final Plot current : plot.getConnectedPlots()) {
|
||||||
current.getPlotModificationManager().setComponent(component, pattern, queue);
|
current.getPlotModificationManager().setComponent(component, pattern, player, queue);
|
||||||
|
}
|
||||||
|
queue.setCompleteTask(() -> {
|
||||||
|
plot.removeRunning();
|
||||||
|
player.sendMessage(TranslatableCaption.of("working.component_complete"));
|
||||||
|
});
|
||||||
|
if (Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
queue.addProgressSubscriber(
|
||||||
|
PlotSquared.platform().getInjector().getInstance(ProgressSubscriberFactory.class).createWithActor(player));
|
||||||
}
|
}
|
||||||
queue.setCompleteTask(plot::removeRunning);
|
|
||||||
queue.enqueue();
|
queue.enqueue();
|
||||||
player.sendMessage(TranslatableCaption.of("working.generating_component"));
|
player.sendMessage(TranslatableCaption.of("working.generating_component"));
|
||||||
});
|
});
|
||||||
|
@ -84,7 +84,7 @@ public class Swap extends SubCommand {
|
|||||||
return CompletableFuture.completedFuture(false);
|
return CompletableFuture.completedFuture(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return plot1.getPlotModificationManager().move(plot2, () -> {
|
return plot1.getPlotModificationManager().move(plot2, player, () -> {
|
||||||
}, true).thenApply(result -> {
|
}, true).thenApply(result -> {
|
||||||
if (result) {
|
if (result) {
|
||||||
player.sendMessage(TranslatableCaption.of("swap.swap_success"));
|
player.sendMessage(TranslatableCaption.of("swap.swap_success"));
|
||||||
|
@ -194,7 +194,7 @@ public class ComponentPresetManager {
|
|||||||
plot.addRunning();
|
plot.addRunning();
|
||||||
QueueCoordinator queue = plot.getArea().getQueue();
|
QueueCoordinator queue = plot.getArea().getQueue();
|
||||||
for (Plot current : plot.getConnectedPlots()) {
|
for (Plot current : plot.getConnectedPlots()) {
|
||||||
current.getPlotModificationManager().setComponent(componentPreset.getComponent().name(), pattern, queue);
|
current.getPlotModificationManager().setComponent(componentPreset.getComponent().name(), pattern, player, queue);
|
||||||
}
|
}
|
||||||
queue.setCompleteTask(plot::removeRunning);
|
queue.setCompleteTask(plot::removeRunning);
|
||||||
queue.enqueue();
|
queue.enqueue();
|
||||||
|
@ -529,8 +529,24 @@ public class Settings extends Config {
|
|||||||
@Comment("Settings relating to PlotSquared's GlobalBlockQueue")
|
@Comment("Settings relating to PlotSquared's GlobalBlockQueue")
|
||||||
public static final class QUEUE {
|
public static final class QUEUE {
|
||||||
@Comment({"Average time per tick spent completing chunk tasks in ms.",
|
@Comment({"Average time per tick spent completing chunk tasks in ms.",
|
||||||
"Waits (chunk task time / target_time) ticks before completely the next task."})
|
"Queue will adjust the batch size to match this."})
|
||||||
public static int TARGET_TIME = 65;
|
public static int MAX_ITERATION_TIME = 30;
|
||||||
|
@Comment({"Initial number of chunks to process by the queue. This can be increased or",
|
||||||
|
"decreased by the queue based on the actual iteration time compared to above."})
|
||||||
|
public static int INITIAL_BATCH_SIZE = 5;
|
||||||
|
@Comment("Notify progress of the queue to the player or console.")
|
||||||
|
public static boolean NOTIFY_PROGRESS = true;
|
||||||
|
@Comment("Interval in ms to notify player or console of progress.")
|
||||||
|
public static int NOTIFY_INTERVAL = 5000;
|
||||||
|
@Comment({"Time to wait in ms before beginning to notify player or console of progress.",
|
||||||
|
"Prevent needless notification of progress for short queues."})
|
||||||
|
public static int NOTIFY_WAIT = 5000;
|
||||||
|
@Comment({"How lighitng should be handled by the queue. Modes:",
|
||||||
|
" - 0 - Do not do any lighting (fastest)",
|
||||||
|
" - 1 - Only execute lighting where blocks with light values are placed",
|
||||||
|
" - 2 - Only execute lighting where blocks with light values are placed or removed/replaced",
|
||||||
|
" - 3 - Always execute lighting (slowest)"})
|
||||||
|
public static int LIGHTING_MODE = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Comment("Settings related to tab completion")
|
@Comment("Settings related to tab completion")
|
||||||
|
@ -25,9 +25,13 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.generator;
|
package com.plotsquared.core.generator;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.location.Direction;
|
import com.plotsquared.core.location.Direction;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.BlockBucket;
|
import com.plotsquared.core.plot.BlockBucket;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
||||||
@ -53,44 +57,49 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
|
|
||||||
private final ClassicPlotWorld classicPlotWorld;
|
private final ClassicPlotWorld classicPlotWorld;
|
||||||
private final RegionManager regionManager;
|
private final RegionManager regionManager;
|
||||||
|
private final ProgressSubscriberFactory subscriberFactory;
|
||||||
|
|
||||||
public ClassicPlotManager(@Nonnull final ClassicPlotWorld classicPlotWorld, @Nonnull final RegionManager regionManager) {
|
@Inject public ClassicPlotManager(@Nonnull final ClassicPlotWorld classicPlotWorld, @Nonnull final RegionManager regionManager) {
|
||||||
super(classicPlotWorld, regionManager);
|
super(classicPlotWorld, regionManager);
|
||||||
this.classicPlotWorld = classicPlotWorld;
|
this.classicPlotWorld = classicPlotWorld;
|
||||||
this.regionManager = regionManager;
|
this.regionManager = regionManager;
|
||||||
|
this.subscriberFactory = PlotSquared.platform().getInjector().getInstance(ProgressSubscriberFactory.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public boolean setComponent(@Nonnull PlotId plotId,
|
||||||
public boolean setComponent(@Nonnull PlotId plotId, @Nonnull String component, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
@Nonnull String component,
|
||||||
|
@Nonnull Pattern blocks,
|
||||||
|
@Nullable PlotPlayer<?> actor,
|
||||||
|
@Nullable QueueCoordinator queue) {
|
||||||
final Optional<ClassicPlotManagerComponent> componentOptional = ClassicPlotManagerComponent.fromString(component);
|
final Optional<ClassicPlotManagerComponent> componentOptional = ClassicPlotManagerComponent.fromString(component);
|
||||||
if (componentOptional.isPresent()) {
|
if (componentOptional.isPresent()) {
|
||||||
switch (componentOptional.get()) {
|
switch (componentOptional.get()) {
|
||||||
case FLOOR:
|
case FLOOR:
|
||||||
return setFloor(plotId, blocks, queue);
|
return setFloor(plotId, blocks, actor, queue);
|
||||||
case WALL:
|
case WALL:
|
||||||
return setWallFilling(plotId, blocks, queue);
|
return setWallFilling(plotId, blocks, actor, queue);
|
||||||
case AIR:
|
case AIR:
|
||||||
return setAir(plotId, blocks, queue);
|
return setAir(plotId, blocks, actor, queue);
|
||||||
case MAIN:
|
case MAIN:
|
||||||
return setMain(plotId, blocks, queue);
|
return setMain(plotId, blocks, actor, queue);
|
||||||
case MIDDLE:
|
case MIDDLE:
|
||||||
return setMiddle(plotId, blocks, queue);
|
return setMiddle(plotId, blocks, queue);
|
||||||
case OUTLINE:
|
case OUTLINE:
|
||||||
return setOutline(plotId, blocks, queue);
|
return setOutline(plotId, blocks, actor, queue);
|
||||||
case BORDER:
|
case BORDER:
|
||||||
return setWall(plotId, blocks, queue);
|
return setWall(plotId, blocks, actor, queue);
|
||||||
case ALL:
|
case ALL:
|
||||||
return setAll(plotId, blocks, queue);
|
return setAll(plotId, blocks, actor, queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean unClaimPlot(@Nonnull Plot plot, @Nullable Runnable whenDone, @Nullable QueueCoordinator queue) {
|
@Override public boolean unClaimPlot(@Nonnull Plot plot, @Nullable Runnable whenDone, @Nullable QueueCoordinator queue) {
|
||||||
setWallFilling(plot.getId(), classicPlotWorld.WALL_FILLING.toPattern(), queue);
|
setWallFilling(plot.getId(), classicPlotWorld.WALL_FILLING.toPattern(), null, queue);
|
||||||
if (classicPlotWorld.PLACE_TOP_BLOCK && (!classicPlotWorld.WALL_BLOCK.isAir() || !classicPlotWorld.WALL_BLOCK
|
if (classicPlotWorld.PLACE_TOP_BLOCK && (!classicPlotWorld.WALL_BLOCK.isAir() || !classicPlotWorld.WALL_BLOCK
|
||||||
.equals(classicPlotWorld.CLAIMED_WALL_BLOCK))) {
|
.equals(classicPlotWorld.CLAIMED_WALL_BLOCK))) {
|
||||||
setWall(plot.getId(), classicPlotWorld.WALL_BLOCK.toPattern(), queue);
|
setWall(plot.getId(), classicPlotWorld.WALL_BLOCK.toPattern(), null, queue);
|
||||||
}
|
}
|
||||||
TaskManager.runTask(whenDone);
|
TaskManager.runTask(whenDone);
|
||||||
return true;
|
return true;
|
||||||
@ -105,11 +114,11 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return success or not
|
* @return success or not
|
||||||
*/
|
*/
|
||||||
public boolean setFloor(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
public boolean setFloor(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable PlotPlayer<?> actor, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (plot != null && plot.isBasePlot()) {
|
if (plot != null && plot.isBasePlot()) {
|
||||||
return this.regionManager
|
return this.regionManager
|
||||||
.setCuboids(classicPlotWorld, plot.getRegions(), blocks, classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.PLOT_HEIGHT, queue);
|
.setCuboids(classicPlotWorld, plot.getRegions(), blocks, classicPlotWorld.PLOT_HEIGHT, classicPlotWorld.PLOT_HEIGHT, actor, queue);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -123,10 +132,10 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return success or not
|
* @return success or not
|
||||||
*/
|
*/
|
||||||
public boolean setAll(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
public boolean setAll(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable PlotPlayer<?> actor, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (plot != null && plot.isBasePlot()) {
|
if (plot != null && plot.isBasePlot()) {
|
||||||
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, getWorldHeight(), queue);
|
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, getWorldHeight(), actor, queue);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -140,11 +149,11 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return success or not
|
* @return success or not
|
||||||
*/
|
*/
|
||||||
public boolean setAir(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
public boolean setAir(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable PlotPlayer<?> actor, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (plot != null && plot.isBasePlot()) {
|
if (plot != null && plot.isBasePlot()) {
|
||||||
return this.regionManager
|
return this.regionManager
|
||||||
.setCuboids(classicPlotWorld, plot.getRegions(), blocks, classicPlotWorld.PLOT_HEIGHT + 1, getWorldHeight(), queue);
|
.setCuboids(classicPlotWorld, plot.getRegions(), blocks, classicPlotWorld.PLOT_HEIGHT + 1, getWorldHeight(), actor, queue);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -158,10 +167,10 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return success or not
|
* @return success or not
|
||||||
*/
|
*/
|
||||||
public boolean setMain(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
public boolean setMain(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable PlotPlayer<?> actor, @Nullable QueueCoordinator queue) {
|
||||||
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
Plot plot = classicPlotWorld.getPlotAbs(plotId);
|
||||||
if (plot == null || plot.isBasePlot()) {
|
if (plot == null || plot.isBasePlot()) {
|
||||||
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, classicPlotWorld.PLOT_HEIGHT - 1, queue);
|
return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, classicPlotWorld.PLOT_HEIGHT - 1, actor, queue);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -203,7 +212,7 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return success or not
|
* @return success or not
|
||||||
*/
|
*/
|
||||||
public boolean setOutline(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
public boolean setOutline(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable PlotPlayer<?> actor, @Nullable QueueCoordinator queue) {
|
||||||
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -224,6 +233,9 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
queue = classicPlotWorld.getQueue();
|
queue = classicPlotWorld.getQueue();
|
||||||
enqueue = true;
|
enqueue = true;
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
queue.addProgressSubscriber(subscriberFactory.createWithActor(actor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxY = classicPlotWorld.getPlotManager().getWorldHeight();
|
int maxY = classicPlotWorld.getPlotManager().getWorldHeight();
|
||||||
@ -279,7 +291,7 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return success or not
|
* @return success or not
|
||||||
*/
|
*/
|
||||||
public boolean setWallFilling(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
public boolean setWallFilling(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable PlotPlayer<?> actor, @Nullable QueueCoordinator queue) {
|
||||||
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -300,6 +312,9 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
queue = classicPlotWorld.getQueue();
|
queue = classicPlotWorld.getQueue();
|
||||||
enqueue = true;
|
enqueue = true;
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
queue.addProgressSubscriber(subscriberFactory.createWithActor(actor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!plot.isMerged(Direction.NORTH)) {
|
if (!plot.isMerged(Direction.NORTH)) {
|
||||||
@ -346,7 +361,7 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return success or not
|
* @return success or not
|
||||||
*/
|
*/
|
||||||
public boolean setWall(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
public boolean setWall(@Nonnull PlotId plotId, @Nonnull Pattern blocks, @Nullable PlotPlayer<?> actor, @Nullable QueueCoordinator queue) {
|
||||||
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
if (classicPlotWorld.ROAD_WIDTH == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -367,6 +382,9 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
enqueue = true;
|
enqueue = true;
|
||||||
queue = classicPlotWorld.getQueue();
|
queue = classicPlotWorld.getQueue();
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
queue.addProgressSubscriber(subscriberFactory.createWithActor(actor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int y = classicPlotWorld.WALL_HEIGHT + 1;
|
int y = classicPlotWorld.WALL_HEIGHT + 1;
|
||||||
@ -578,13 +596,13 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
||||||
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
||||||
for (PlotId plotId : plotIds) {
|
for (PlotId plotId : plotIds) {
|
||||||
setWall(plotId, claim.toPattern(), queue);
|
setWall(plotId, claim.toPattern(), null, queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Settings.General.MERGE_REPLACE_WALL) {
|
if (Settings.General.MERGE_REPLACE_WALL) {
|
||||||
final BlockBucket wallBlock = classicPlotWorld.WALL_FILLING;
|
final BlockBucket wallBlock = classicPlotWorld.WALL_FILLING;
|
||||||
for (PlotId id : plotIds) {
|
for (PlotId id : plotIds) {
|
||||||
setWallFilling(id, wallBlock.toPattern(), queue);
|
setWallFilling(id, wallBlock.toPattern(), null, queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -594,7 +612,7 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
||||||
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
||||||
for (PlotId id : plotIds) {
|
for (PlotId id : plotIds) {
|
||||||
setWall(id, claim.toPattern(), queue);
|
setWall(id, claim.toPattern(), null, queue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true; // return false if unlink has been denied
|
return true; // return false if unlink has been denied
|
||||||
@ -611,7 +629,7 @@ public class ClassicPlotManager extends SquarePlotManager {
|
|||||||
@Override public boolean claimPlot(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
@Override public boolean claimPlot(@Nonnull Plot plot, @Nullable QueueCoordinator queue) {
|
||||||
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
final BlockBucket claim = classicPlotWorld.CLAIMED_WALL_BLOCK;
|
||||||
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
if (classicPlotWorld.PLACE_TOP_BLOCK && (!claim.isAir() || !claim.equals(classicPlotWorld.WALL_BLOCK))) {
|
||||||
return setWall(plot.getId(), claim.toPattern(), queue);
|
return setWall(plot.getId(), claim.toPattern(), null, queue);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,9 @@ import com.google.common.collect.Sets;
|
|||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.command.Template;
|
import com.plotsquared.core.command.Template;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
import com.plotsquared.core.plot.PlotAreaTerrainType;
|
||||||
import com.plotsquared.core.plot.PlotAreaType;
|
import com.plotsquared.core.plot.PlotAreaType;
|
||||||
@ -61,11 +63,15 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
|
|
||||||
private final HybridPlotWorld hybridPlotWorld;
|
private final HybridPlotWorld hybridPlotWorld;
|
||||||
private final RegionManager regionManager;
|
private final RegionManager regionManager;
|
||||||
|
private final ProgressSubscriberFactory subscriberFactory;
|
||||||
|
|
||||||
public HybridPlotManager(@Nonnull final HybridPlotWorld hybridPlotWorld, @Nonnull final RegionManager regionManager) {
|
public HybridPlotManager(@Nonnull final HybridPlotWorld hybridPlotWorld,
|
||||||
|
@Nonnull final RegionManager regionManager,
|
||||||
|
@Nonnull ProgressSubscriberFactory subscriberFactory) {
|
||||||
super(hybridPlotWorld, regionManager);
|
super(hybridPlotWorld, regionManager);
|
||||||
this.hybridPlotWorld = hybridPlotWorld;
|
this.hybridPlotWorld = hybridPlotWorld;
|
||||||
this.regionManager = regionManager;
|
this.regionManager = regionManager;
|
||||||
|
this.subscriberFactory = subscriberFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void exportTemplate() throws IOException {
|
@Override public void exportTemplate() throws IOException {
|
||||||
@ -199,21 +205,16 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
return !enqueue || queue.enqueue();
|
return !enqueue || queue.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override public boolean clearPlot(@Nonnull final Plot plot,
|
||||||
* <p>Clearing the plot needs to only consider removing the blocks - This implementation has
|
@Nullable final Runnable whenDone,
|
||||||
* used the setCuboidAsync function, as it is fast, and uses NMS code - It also makes use of the
|
@Nullable PlotPlayer<?> actor,
|
||||||
* fact that deleting chunks is a lot faster than block updates This code is very messy, but you
|
@Nullable QueueCoordinator queue) {
|
||||||
* don't need to do something quite as complex unless you happen to have 512x512 sized plots.
|
|
||||||
* </p>
|
|
||||||
*/
|
|
||||||
@Override public boolean clearPlot(@Nonnull final Plot plot, @Nullable final Runnable whenDone, @Nullable QueueCoordinator queue) {
|
|
||||||
if (this.regionManager.notifyClear(this)) {
|
if (this.regionManager.notifyClear(this)) {
|
||||||
//If this returns false, the clear didn't work
|
//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;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final String world = hybridPlotWorld.getWorldName();
|
|
||||||
final Location pos1 = plot.getBottomAbs();
|
final Location pos1 = plot.getBottomAbs();
|
||||||
final Location pos2 = plot.getExtendedTopAbs();
|
final Location pos2 = plot.getExtendedTopAbs();
|
||||||
// If augmented
|
// If augmented
|
||||||
@ -248,6 +249,9 @@ public class HybridPlotManager extends ClassicPlotManager {
|
|||||||
queue.setRegenRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()));
|
queue.setRegenRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()));
|
||||||
}
|
}
|
||||||
pastePlotSchematic(queue, pos1, pos2);
|
pastePlotSchematic(queue, pos1, pos2);
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
queue.addProgressSubscriber(subscriberFactory.createWithActor(actor));
|
||||||
|
}
|
||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
queue.setCompleteTask(whenDone);
|
queue.setCompleteTask(whenDone);
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ import com.plotsquared.core.configuration.ConfigurationSection;
|
|||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
||||||
import com.plotsquared.core.inject.annotations.WorldConfig;
|
import com.plotsquared.core.inject.annotations.WorldConfig;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
@ -138,7 +139,8 @@ public class HybridPlotWorld extends ClassicPlotWorld {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nonnull @Override protected PlotManager createManager() {
|
@Nonnull @Override protected PlotManager createManager() {
|
||||||
return new HybridPlotManager(this, PlotSquared.platform().getRegionManager());
|
return new HybridPlotManager(this, PlotSquared.platform().getRegionManager(),
|
||||||
|
PlotSquared.platform().getInjector().getInstance(ProgressSubscriberFactory.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Location getSignLocation(@Nonnull Plot plot) {
|
public Location getSignLocation(@Nonnull Plot plot) {
|
||||||
|
@ -27,6 +27,7 @@ package com.plotsquared.core.generator;
|
|||||||
|
|
||||||
import com.plotsquared.core.location.Direction;
|
import com.plotsquared.core.location.Direction;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
@ -58,7 +59,10 @@ public abstract class SquarePlotManager extends GridPlotManager {
|
|||||||
this.regionManager = regionManager;
|
this.regionManager = regionManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean clearPlot(final @Nonnull Plot plot, final @Nullable Runnable whenDone, @Nullable QueueCoordinator queue) {
|
@Override public boolean clearPlot(final @Nonnull Plot plot,
|
||||||
|
final @Nullable Runnable whenDone,
|
||||||
|
@Nullable PlotPlayer<?> actor,
|
||||||
|
@Nullable QueueCoordinator queue) {
|
||||||
final Set<CuboidRegion> regions = plot.getRegions();
|
final Set<CuboidRegion> regions = plot.getRegions();
|
||||||
Runnable run = new Runnable() {
|
Runnable run = new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
package com.plotsquared.core.inject.factory;
|
package com.plotsquared.core.inject.factory;
|
||||||
|
|
||||||
import com.plotsquared.core.queue.ChunkCoordinator;
|
import com.plotsquared.core.queue.ChunkCoordinator;
|
||||||
|
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
|
||||||
@ -42,6 +43,7 @@ public interface ChunkCoordinatorFactory {
|
|||||||
@Nonnull final Collection<BlockVector2> requestedChunks,
|
@Nonnull final Collection<BlockVector2> requestedChunks,
|
||||||
@Nonnull final Runnable whenDone,
|
@Nonnull final Runnable whenDone,
|
||||||
@Nonnull final Consumer<Throwable> throwableConsumer,
|
@Nonnull final Consumer<Throwable> throwableConsumer,
|
||||||
final boolean unloadAfter);
|
final boolean unloadAfter,
|
||||||
|
@Nonnull final Collection<ProgressSubscriber> progressSubscribers);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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 javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
public interface ProgressSubscriberFactory {
|
||||||
|
|
||||||
|
@Nonnull ProgressSubscriber create();
|
||||||
|
|
||||||
|
@Nonnull ProgressSubscriber createWithActor(@Nullable @Assisted("subscriber") PlotPlayer<?> actor);
|
||||||
|
|
||||||
|
@Nonnull ProgressSubscriber createFull(@Nullable @Assisted("subscriber") PlotPlayer<?> actor,
|
||||||
|
@Assisted("progressInterval") final long interval,
|
||||||
|
@Assisted("waitBeforeStarting") final long wait,
|
||||||
|
@Nullable @Assisted("caption") Caption caption);
|
||||||
|
|
||||||
|
}
|
@ -26,6 +26,7 @@
|
|||||||
package com.plotsquared.core.inject.modules;
|
package com.plotsquared.core.inject.modules;
|
||||||
|
|
||||||
import com.google.inject.AbstractModule;
|
import com.google.inject.AbstractModule;
|
||||||
|
import com.google.inject.assistedinject.FactoryModuleBuilder;
|
||||||
import com.intellectualsites.services.ServicePipeline;
|
import com.intellectualsites.services.ServicePipeline;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
import com.plotsquared.core.configuration.file.YamlConfiguration;
|
||||||
@ -34,7 +35,10 @@ import com.plotsquared.core.inject.annotations.ConfigFile;
|
|||||||
import com.plotsquared.core.inject.annotations.ImpromptuPipeline;
|
import com.plotsquared.core.inject.annotations.ImpromptuPipeline;
|
||||||
import com.plotsquared.core.inject.annotations.WorldConfig;
|
import com.plotsquared.core.inject.annotations.WorldConfig;
|
||||||
import com.plotsquared.core.inject.annotations.WorldFile;
|
import com.plotsquared.core.inject.annotations.WorldFile;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.listener.PlotListener;
|
import com.plotsquared.core.listener.PlotListener;
|
||||||
|
import com.plotsquared.core.queue.subscriber.DefaultProgressSubscriber;
|
||||||
|
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
|
||||||
import com.plotsquared.core.util.EventDispatcher;
|
import com.plotsquared.core.util.EventDispatcher;
|
||||||
import com.plotsquared.core.uuid.UUIDPipeline;
|
import com.plotsquared.core.uuid.UUIDPipeline;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
|
@ -575,7 +575,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
|
|||||||
}
|
}
|
||||||
if (Settings.Enabled_Components.BAN_DELETER && isBanned()) {
|
if (Settings.Enabled_Components.BAN_DELETER && isBanned()) {
|
||||||
for (Plot owned : getPlots()) {
|
for (Plot owned : getPlots()) {
|
||||||
owned.getPlotModificationManager().deletePlot(null);
|
owned.getPlotModificationManager().deletePlot(null, null);
|
||||||
if (Settings.DEBUG) {
|
if (Settings.DEBUG) {
|
||||||
logger.info("Plot {} was deleted + cleared due to {} getting banned", owned.getId(), getName());
|
logger.info("Plot {} was deleted + cleared due to {} getting banned", owned.getId(), getName());
|
||||||
}
|
}
|
||||||
|
@ -1624,7 +1624,7 @@ public class Plot {
|
|||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
schematicHandler.paste(sch, this, 0, 1, 0, Settings.Schematics.PASTE_ON_TOP, new RunnableVal<Boolean>() {
|
schematicHandler.paste(sch, this, 0, 1, 0, Settings.Schematics.PASTE_ON_TOP, player, new RunnableVal<Boolean>() {
|
||||||
@Override public void run(Boolean value) {
|
@Override public void run(Boolean value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_success"));
|
player.sendMessage(TranslatableCaption.of("schematics.schematic_paste_success"));
|
||||||
|
@ -28,6 +28,7 @@ package com.plotsquared.core.plot;
|
|||||||
import com.plotsquared.core.command.Template;
|
import com.plotsquared.core.command.Template;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.queue.QueueCoordinator;
|
import com.plotsquared.core.queue.QueueCoordinator;
|
||||||
import com.plotsquared.core.util.FileBytes;
|
import com.plotsquared.core.util.FileBytes;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
@ -61,7 +62,10 @@ public abstract class PlotManager {
|
|||||||
// the same applies here
|
// the same applies here
|
||||||
public abstract Location getPlotTopLocAbs(@Nonnull PlotId plotId);
|
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);
|
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 plotId id of plot to set component to
|
||||||
* @param component FLOOR, WALL, AIR, MAIN, MIDDLE, OUTLINE, BORDER, ALL (floor, air and main).
|
* @param component FLOOR, WALL, AIR, MAIN, MIDDLE, OUTLINE, BORDER, ALL (floor, air and main).
|
||||||
* @param blocks Pattern to set component to
|
* @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,
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return success or not
|
* @return success or not
|
||||||
@ -105,6 +110,7 @@ public abstract class PlotManager {
|
|||||||
public abstract boolean setComponent(@Nonnull PlotId plotId,
|
public abstract boolean setComponent(@Nonnull PlotId plotId,
|
||||||
@Nonnull String component,
|
@Nonnull String component,
|
||||||
@Nonnull Pattern blocks,
|
@Nonnull Pattern blocks,
|
||||||
|
@Nullable PlotPlayer<?> actor,
|
||||||
@Nullable QueueCoordinator queue);
|
@Nullable QueueCoordinator queue);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,8 +25,10 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.plot;
|
package com.plotsquared.core.plot;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.configuration.ConfigurationUtil;
|
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.Caption;
|
||||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
import com.plotsquared.core.database.DBFunc;
|
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.PlotUnlinkEvent;
|
||||||
import com.plotsquared.core.events.Result;
|
import com.plotsquared.core.events.Result;
|
||||||
import com.plotsquared.core.generator.SquarePlotWorld;
|
import com.plotsquared.core.generator.SquarePlotWorld;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.location.Direction;
|
import com.plotsquared.core.location.Direction;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
@ -75,19 +78,21 @@ public final class PlotModificationManager {
|
|||||||
private static final Logger logger = LoggerFactory.getLogger("P2/" + PlotModificationManager.class.getSimpleName());
|
private static final Logger logger = LoggerFactory.getLogger("P2/" + PlotModificationManager.class.getSimpleName());
|
||||||
|
|
||||||
private final Plot plot;
|
private final Plot plot;
|
||||||
|
private final ProgressSubscriberFactory subscriberFactory;
|
||||||
|
|
||||||
PlotModificationManager(@Nonnull final Plot plot) {
|
@Inject PlotModificationManager(@Nonnull final Plot plot) {
|
||||||
this.plot = plot;
|
this.plot = plot;
|
||||||
|
this.subscriberFactory = PlotSquared.platform().getInjector().getInstance(ProgressSubscriberFactory.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy a plot to a location, both physically and the settings
|
* Copy a plot to a location, both physically and the settings
|
||||||
*
|
*
|
||||||
* @param destination destination plot
|
* @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}
|
* @return Future that completes with {@code true} if the copy was successful, else {@code false}
|
||||||
*/
|
*/
|
||||||
public CompletableFuture<Boolean> copy(@Nonnull final Plot destination) {
|
public CompletableFuture<Boolean> copy(@Nonnull final Plot destination, @Nullable PlotPlayer<?> actor) {
|
||||||
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
final CompletableFuture<Boolean> future = new CompletableFuture<>();
|
||||||
final PlotId offset = PlotId.of(destination.getId().getX() - this.plot.getId().getX(), destination.getId().getY() - this.plot.getId().getY());
|
final PlotId offset = PlotId.of(destination.getId().getX() - this.plot.getId().getX(), destination.getId().getY() - this.plot.getId().getY());
|
||||||
final Location db = destination.getBottomAbs();
|
final Location db = destination.getBottomAbs();
|
||||||
@ -169,7 +174,7 @@ public final class PlotModificationManager {
|
|||||||
Location pos1 = corners[0];
|
Location pos1 = corners[0];
|
||||||
Location pos2 = corners[1];
|
Location pos2 = corners[1];
|
||||||
Location newPos = pos1.add(offsetX, 0, offsetZ).withWorld(destination.getWorldName());
|
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();
|
run.run();
|
||||||
@ -180,22 +185,26 @@ public final class PlotModificationManager {
|
|||||||
* Clear the plot
|
* Clear the plot
|
||||||
*
|
*
|
||||||
* @param whenDone A runnable to execute when clearing finishes, or null
|
* @param whenDone A runnable to execute when clearing finishes, or null
|
||||||
* @see #clear(boolean, boolean, Runnable)
|
* @see #clear(boolean, boolean, PlotPlayer, Runnable)
|
||||||
* @see #deletePlot(Runnable) to clear and delete a plot
|
* @see #deletePlot(PlotPlayer, Runnable) to clear and delete a plot
|
||||||
*/
|
*/
|
||||||
public void clear(@Nullable final Runnable whenDone) {
|
public void clear(@Nullable final Runnable whenDone) {
|
||||||
this.clear(false, false, whenDone);
|
this.clear(false, false, null, whenDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear the plot
|
* Clear the plot
|
||||||
*
|
*
|
||||||
* @param checkRunning Whether or not already executing tasks should be checked
|
* @param checkRunning Whether or not already executing tasks should be checked
|
||||||
* @param isDelete Whether or not the plot is being deleted
|
* @param isDelete Whether or not the plot is being deleted
|
||||||
* @param whenDone A runnable to execute when clearing finishes, or null
|
* @param actor The actor clearing the plot
|
||||||
* @see #deletePlot(Runnable) to clear and delete a 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) {
|
if (checkRunning && this.plot.getRunning() != 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -230,9 +239,9 @@ public final class PlotModificationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (queue.size() > 0) {
|
if (queue.size() > 0) {
|
||||||
|
queue.setCompleteTask(run);
|
||||||
queue.enqueue();
|
queue.enqueue();
|
||||||
}
|
}
|
||||||
TaskManager.runTask(run);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Plot current = queue.poll();
|
Plot current = queue.poll();
|
||||||
@ -245,7 +254,7 @@ public final class PlotModificationManager {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
manager.clearPlot(current, this, null);
|
manager.clearPlot(current, this, actor, null);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
run.run();
|
run.run();
|
||||||
@ -352,11 +361,8 @@ public final class PlotModificationManager {
|
|||||||
if (this.plot.getArea().allowSigns()) {
|
if (this.plot.getArea().allowSigns()) {
|
||||||
Location location = manager.getSignLoc(this.plot);
|
Location location = manager.getSignLoc(this.plot);
|
||||||
String id = this.plot.getId().toString();
|
String id = this.plot.getId().toString();
|
||||||
Caption[] lines =
|
Caption[] lines = new Caption[] {TranslatableCaption.of("signs.owner_sign_line_1"), TranslatableCaption.of("signs.owner_sign_line_2"),
|
||||||
new Caption[] {TranslatableCaption.of("signs.owner_sign_line_1"),
|
TranslatableCaption.of("signs.owner_sign_line_3"), TranslatableCaption.of("signs.owner_sign_line_4")};
|
||||||
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));
|
PlotSquared.platform().getWorldUtil().setSign(location, lines, Template.of("id", id), Template.of("owner", name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -387,8 +393,8 @@ public final class PlotModificationManager {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Location location = manager.getSignLoc(this.plot);
|
Location location = manager.getSignLoc(this.plot);
|
||||||
QueueCoordinator queue = PlotSquared.platform().getGlobalBlockQueue()
|
QueueCoordinator queue =
|
||||||
.getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(this.plot.getWorldName()));
|
PlotSquared.platform().getGlobalBlockQueue().getNewQueue(PlotSquared.platform().getWorldUtil().getWeWorld(this.plot.getWorldName()));
|
||||||
queue.setBlock(location.getX(), location.getY(), location.getZ(), BlockTypes.AIR.getDefaultState());
|
queue.setBlock(location.getX(), location.getY(), location.getZ(), BlockTypes.AIR.getDefaultState());
|
||||||
queue.enqueue();
|
queue.enqueue();
|
||||||
}
|
}
|
||||||
@ -450,17 +456,15 @@ public final class PlotModificationManager {
|
|||||||
if (notify && plotworld.isAutoMerge()) {
|
if (notify && plotworld.isAutoMerge()) {
|
||||||
final PlotPlayer<?> player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid);
|
final PlotPlayer<?> player = PlotSquared.platform().getPlayerManager().getPlayerIfExists(uuid);
|
||||||
|
|
||||||
PlotMergeEvent
|
PlotMergeEvent event = PlotSquared.get().getEventDispatcher().callMerge(this.plot, Direction.ALL, Integer.MAX_VALUE, player);
|
||||||
event = PlotSquared.get().getEventDispatcher().callMerge(this.plot, Direction.ALL, Integer.MAX_VALUE, player);
|
|
||||||
|
|
||||||
if (event.getEventResult() == Result.DENY) {
|
if (event.getEventResult() == Result.DENY) {
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.sendMessage(TranslatableCaption.of("events.event_denied"),
|
player.sendMessage(TranslatableCaption.of("events.event_denied"), Template.of("value", "Auto merge on claim"));
|
||||||
Template.of("value", "Auto merge on claim"));
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
plot.getPlotModificationManager().autoMerge(event.getDir(), event.getMax(), uuid, true);
|
plot.getPlotModificationManager().autoMerge(event.getDir(), event.getMax(), uuid, player, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
@ -495,10 +499,15 @@ public final class PlotModificationManager {
|
|||||||
* @param dir the direction to merge
|
* @param dir the direction to merge
|
||||||
* @param max the max number of merges to do
|
* @param max the max number of merges to do
|
||||||
* @param uuid the UUID it is allowed to merge with
|
* @param uuid the UUID it is allowed to merge with
|
||||||
|
* @param actor The actor executing the task
|
||||||
* @param removeRoads whether to remove roads
|
* @param removeRoads whether to remove roads
|
||||||
* @return {@code true} if a merge takes place, else {@code false}
|
* @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
|
//Ignore merging if there is no owner for the plot
|
||||||
if (!this.plot.hasOwner()) {
|
if (!this.plot.hasOwner()) {
|
||||||
return false;
|
return false;
|
||||||
@ -584,6 +593,9 @@ public final class PlotModificationManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
queue.addProgressSubscriber(subscriberFactory.createWithActor(actor));
|
||||||
|
}
|
||||||
if (queue.size() > 0) {
|
if (queue.size() > 0) {
|
||||||
queue.enqueue();
|
queue.enqueue();
|
||||||
}
|
}
|
||||||
@ -595,11 +607,13 @@ public final class PlotModificationManager {
|
|||||||
* Moves a plot physically, as well as the corresponding settings.
|
* Moves a plot physically, as well as the corresponding settings.
|
||||||
*
|
*
|
||||||
* @param destination Plot moved to
|
* @param destination Plot moved to
|
||||||
|
* @param actor The actor executing the task
|
||||||
* @param whenDone task when done
|
* @param whenDone task when done
|
||||||
* @param allowSwap whether to swap plots
|
* @param allowSwap whether to swap plots
|
||||||
* @return {@code true} if the move was successful, else {@code false}
|
* @return {@code true} if the move was successful, else {@code false}
|
||||||
*/
|
*/
|
||||||
@Nonnull public CompletableFuture<Boolean> move(@Nonnull final Plot destination,
|
@Nonnull public CompletableFuture<Boolean> move(@Nonnull final Plot destination,
|
||||||
|
@Nullable final PlotPlayer<?> actor,
|
||||||
@Nonnull final Runnable whenDone,
|
@Nonnull final Runnable whenDone,
|
||||||
final boolean allowSwap) {
|
final boolean allowSwap) {
|
||||||
final PlotId offset = PlotId.of(destination.getId().getX() - this.plot.getId().getX(), destination.getId().getY() - this.plot.getId().getY());
|
final PlotId offset = PlotId.of(destination.getId().getX() - this.plot.getId().getX(), destination.getId().getY() - this.plot.getId().getY());
|
||||||
@ -669,7 +683,7 @@ public final class PlotModificationManager {
|
|||||||
Location pos1 = corners[0];
|
Location pos1 = corners[0];
|
||||||
Location pos2 = corners[1];
|
Location pos2 = corners[1];
|
||||||
Location pos3 = pos1.add(offsetX, 0, offsetZ).withWorld(destination.getWorldName());
|
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();
|
}.run();
|
||||||
@ -678,7 +692,8 @@ public final class PlotModificationManager {
|
|||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
if (regions.isEmpty()) {
|
if (regions.isEmpty()) {
|
||||||
Plot plot = destination.getRelative(0, 0);
|
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 = () -> {
|
final Runnable clearDone = () -> {
|
||||||
QueueCoordinator queue = PlotModificationManager.this.plot.getArea().getQueue();
|
QueueCoordinator queue = PlotModificationManager.this.plot.getArea().getQueue();
|
||||||
for (final Plot current : plot.getConnectedPlots()) {
|
for (final Plot current : plot.getConnectedPlots()) {
|
||||||
@ -691,7 +706,7 @@ public final class PlotModificationManager {
|
|||||||
TaskManager.runTask(whenDone);
|
TaskManager.runTask(whenDone);
|
||||||
};
|
};
|
||||||
if (originPlot != null) {
|
if (originPlot != null) {
|
||||||
originPlot.getPlotModificationManager().clear(false, true, clearDone);
|
originPlot.getPlotModificationManager().clear(false, true, actor, clearDone);
|
||||||
} else {
|
} else {
|
||||||
clearDone.run();
|
clearDone.run();
|
||||||
}
|
}
|
||||||
@ -703,7 +718,7 @@ public final class PlotModificationManager {
|
|||||||
final Location pos1 = corners[0];
|
final Location pos1 = corners[0];
|
||||||
final Location pos2 = corners[1];
|
final Location pos2 = corners[1];
|
||||||
Location newPos = pos1.add(offsetX, 0, offsetZ).withWorld(destination.getWorldName());
|
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();
|
}.run();
|
||||||
}
|
}
|
||||||
@ -726,11 +741,14 @@ public final class PlotModificationManager {
|
|||||||
* - The destination must correspond to a valid plot of equal dimensions
|
* - The destination must correspond to a valid plot of equal dimensions
|
||||||
*
|
*
|
||||||
* @param destination The other plot to swap with
|
* @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
|
* @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}
|
* @return Future that completes with {@code true} if the swap was successful, else {@code false}
|
||||||
*/
|
*/
|
||||||
@Nonnull public CompletableFuture<Boolean> swap(@Nonnull final Plot destination, @Nonnull final Runnable whenDone) {
|
@Nonnull public CompletableFuture<Boolean> swap(@Nonnull final Plot destination,
|
||||||
return this.move(destination, whenDone, true);
|
@Nullable PlotPlayer<?> actor,
|
||||||
|
@Nonnull final Runnable whenDone) {
|
||||||
|
return this.move(destination, actor, whenDone, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -738,11 +756,14 @@ public final class PlotModificationManager {
|
|||||||
* - The location must be empty
|
* - The location must be empty
|
||||||
*
|
*
|
||||||
* @param destination Where to move the plot
|
* @param destination Where to move the plot
|
||||||
|
* @param actor The actor executing the task
|
||||||
* @param whenDone A task to run when done, or null
|
* @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}
|
* @return Future that completes with {@code true} if the move was successful, else {@code false}
|
||||||
*/
|
*/
|
||||||
@Nonnull public CompletableFuture<Boolean> move(@Nonnull final Plot destination, @Nonnull final Runnable whenDone) {
|
@Nonnull public CompletableFuture<Boolean> move(@Nonnull final Plot destination,
|
||||||
return this.move(destination, whenDone, false);
|
@Nullable PlotPlayer<?> actor,
|
||||||
|
@Nonnull final Runnable whenDone) {
|
||||||
|
return this.move(destination, actor, whenDone, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -752,31 +773,34 @@ public final class PlotModificationManager {
|
|||||||
*
|
*
|
||||||
* @param component Component to set
|
* @param component Component to set
|
||||||
* @param blocks Pattern to use the generation
|
* @param blocks Pattern to use the generation
|
||||||
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
* @param actor The actor executing the task
|
||||||
* otherwise writes to the queue but does not enqueue.
|
* @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}
|
* @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);
|
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)
|
* Delete a plot (use null for the runnable if you don't need to be notified on completion)
|
||||||
*
|
*
|
||||||
* @see PlotSquared#removePlot(Plot, boolean)
|
* @param actor The actor executing the task
|
||||||
* @see PlotModificationManager#clear(boolean, boolean, Runnable) to simply clear a plot
|
|
||||||
*
|
|
||||||
* @param whenDone task to run when plot has been deleted. Nullable
|
* @param whenDone task to run when plot has been deleted. Nullable
|
||||||
*
|
|
||||||
* @return {@code true} if the deletion was successful, {@code false} if not
|
* @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()) {
|
if (!this.plot.hasOwner()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
final Set<Plot> plots = this.plot.getConnectedPlots();
|
final Set<Plot> plots = this.plot.getConnectedPlots();
|
||||||
this.clear(false, true, () -> {
|
this.clear(false, true, actor, () -> {
|
||||||
for (Plot current : plots) {
|
for (Plot current : plots) {
|
||||||
current.unclaim();
|
current.unclaim();
|
||||||
}
|
}
|
||||||
@ -785,23 +809,24 @@ public final class PlotModificationManager {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
/**
|
/**
|
||||||
* Sets components such as border, wall, floor.
|
* Sets components such as border, wall, floor.
|
||||||
* (components are generator specific)
|
* (components are generator specific)
|
||||||
*
|
*
|
||||||
* @param component component to set
|
* @param component component to set
|
||||||
* @param blocks string of block(s) to set component to
|
* @param blocks string of block(s) to set component to
|
||||||
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
* @param actor The player executing the task
|
||||||
* otherwise writes to the queue but does not enqueue.
|
* @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
|
* @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);
|
final BlockBucket parsed = ConfigurationUtil.BLOCK_BUCKET.parseString(blocks);
|
||||||
if (parsed != null && parsed.isEmpty()) {
|
if (parsed != null && parsed.isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return this.setComponent(component, parsed.toPattern(), queue);
|
return this.setComponent(component, parsed.toPattern(), actor, queue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -426,7 +426,7 @@ public class ExpireManager {
|
|||||||
Templates.of("plot", plot.toString()));
|
Templates.of("plot", plot.toString()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
plot.getPlotModificationManager().deletePlot(whenDone);
|
plot.getPlotModificationManager().deletePlot(null, whenDone);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getAge(UUID uuid) {
|
public long getAge(UUID uuid) {
|
||||||
|
@ -27,6 +27,7 @@ package com.plotsquared.core.plot.world;
|
|||||||
|
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotId;
|
import com.plotsquared.core.plot.PlotId;
|
||||||
@ -63,7 +64,7 @@ public class SinglePlotManager extends PlotManager {
|
|||||||
return Location.at(plotId.toCommaSeparatedString(), 30000000, 0, 30000000);
|
return Location.at(plotId.toCommaSeparatedString(), 30000000, 0, 30000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean clearPlot(@Nonnull Plot plot, final Runnable whenDone, @Nullable QueueCoordinator queue) {
|
@Override public boolean clearPlot(@Nonnull Plot plot, final Runnable whenDone, @Nullable PlotPlayer<?> actor, @Nullable QueueCoordinator queue) {
|
||||||
PlotSquared.platform().getSetupUtils().unload(plot.getWorldName(), false);
|
PlotSquared.platform().getSetupUtils().unload(plot.getWorldName(), false);
|
||||||
final File worldFolder = new File(PlotSquared.platform().getWorldContainer(), plot.getWorldName());
|
final File worldFolder = new File(PlotSquared.platform().getWorldContainer(), plot.getWorldName());
|
||||||
TaskManager.getPlatformImplementation().taskAsync(() -> {
|
TaskManager.getPlatformImplementation().taskAsync(() -> {
|
||||||
@ -95,8 +96,11 @@ public class SinglePlotManager extends PlotManager {
|
|||||||
return new String[0];
|
return new String[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override public boolean setComponent(@Nonnull PlotId plotId,
|
||||||
public boolean setComponent(@Nonnull PlotId plotId, @Nonnull String component, @Nonnull Pattern blocks, @Nullable QueueCoordinator queue) {
|
@Nonnull String component,
|
||||||
|
@Nonnull Pattern blocks,
|
||||||
|
@Nullable PlotPlayer<?> actor,
|
||||||
|
@Nullable QueueCoordinator queue) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.queue;
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.plotsquared.core.configuration.Settings;
|
||||||
|
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
|
||||||
import com.plotsquared.core.util.PatternUtil;
|
import com.plotsquared.core.util.PatternUtil;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
@ -54,6 +56,7 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
|
|||||||
private final World world;
|
private final World world;
|
||||||
private final ConcurrentHashMap<BlockVector2, LocalChunk> blockChunks = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<BlockVector2, LocalChunk> blockChunks = new ConcurrentHashMap<>();
|
||||||
private final List<BlockVector2> readRegion = new ArrayList<>();
|
private final List<BlockVector2> readRegion = new ArrayList<>();
|
||||||
|
private final List<ProgressSubscriber> progressSubscribers = new ArrayList<>();
|
||||||
private long modified;
|
private long modified;
|
||||||
private LocalChunk lastWrappedChunk;
|
private LocalChunk lastWrappedChunk;
|
||||||
private int lastX = Integer.MIN_VALUE;
|
private int lastX = Integer.MIN_VALUE;
|
||||||
@ -67,6 +70,7 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
|
|||||||
private Consumer<BlockVector2> consumer = null;
|
private Consumer<BlockVector2> consumer = null;
|
||||||
private boolean unloadAfter = true;
|
private boolean unloadAfter = true;
|
||||||
private Runnable whenDone;
|
private Runnable whenDone;
|
||||||
|
@Nullable private LightingMode lightingMode = LightingMode.valueOf(Settings.QUEUE.LIGHTING_MODE);
|
||||||
|
|
||||||
public BasicQueueCoordinator(@Nonnull World world) {
|
public BasicQueueCoordinator(@Nonnull World world) {
|
||||||
super(world);
|
super(world);
|
||||||
@ -252,6 +256,28 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
|
|||||||
this.consumer = consumer;
|
this.consumer = consumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the list of progress subscribers currently added to the queue to be added to the Chunk Coordinator
|
||||||
|
*/
|
||||||
|
public final List<ProgressSubscriber> getProgressSubscribers() {
|
||||||
|
return this.progressSubscribers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public final void addProgressSubscriber(@Nonnull ProgressSubscriber progressSubscriber) {
|
||||||
|
this.progressSubscribers.add(progressSubscriber);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @Nonnull public final LightingMode getLightingMode() {
|
||||||
|
if (lightingMode == null) {
|
||||||
|
return LightingMode.valueOf(Settings.QUEUE.LIGHTING_MODE);
|
||||||
|
}
|
||||||
|
return this.lightingMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public final void setLightingMode(@Nullable LightingMode mode) {
|
||||||
|
this.lightingMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override public Runnable getCompleteTask() {
|
@Override public Runnable getCompleteTask() {
|
||||||
return this.whenDone;
|
return this.whenDone;
|
||||||
}
|
}
|
||||||
|
@ -29,14 +29,16 @@ import com.plotsquared.core.util.task.PlotSquaredTask;
|
|||||||
|
|
||||||
public abstract class ChunkCoordinator implements PlotSquaredTask {
|
public abstract class ChunkCoordinator implements PlotSquaredTask {
|
||||||
|
|
||||||
|
private boolean cancelled = false;
|
||||||
|
|
||||||
@Override public abstract void runTask();
|
@Override public abstract void runTask();
|
||||||
|
|
||||||
@Override public boolean isCancelled() {
|
@Override public boolean isCancelled() {
|
||||||
return false;
|
return cancelled;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void cancel() {
|
@Override public void cancel() {
|
||||||
// Do nothing
|
this.cancelled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -27,8 +27,10 @@ package com.plotsquared.core.queue;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
|
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
|
||||||
import com.sk89q.worldedit.math.BlockVector2;
|
import com.sk89q.worldedit.math.BlockVector2;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
|
|
||||||
@ -46,14 +48,15 @@ import java.util.function.Consumer;
|
|||||||
public class ChunkCoordinatorBuilder {
|
public class ChunkCoordinatorBuilder {
|
||||||
|
|
||||||
private final List<BlockVector2> requestedChunks = new LinkedList<>();
|
private final List<BlockVector2> requestedChunks = new LinkedList<>();
|
||||||
|
private final List<ProgressSubscriber> progressSubscribers = new ArrayList<>();
|
||||||
private final ChunkCoordinatorFactory chunkCoordinatorFactory;
|
private final ChunkCoordinatorFactory chunkCoordinatorFactory;
|
||||||
private Consumer<Throwable> throwableConsumer = Throwable::printStackTrace;
|
private Consumer<Throwable> throwableConsumer = Throwable::printStackTrace;
|
||||||
private World world;
|
private World world;
|
||||||
private Consumer<BlockVector2> chunkConsumer;
|
private Consumer<BlockVector2> chunkConsumer;
|
||||||
private Runnable whenDone = () -> {
|
private Runnable whenDone = () -> {
|
||||||
};
|
};
|
||||||
private long maxIterationTime = 60; // A little over 1 tick;
|
private long maxIterationTime = Settings.QUEUE.MAX_ITERATION_TIME; // A little over 1 tick;
|
||||||
private int initialBatchSize = 4;
|
private int initialBatchSize = Settings.QUEUE.INITIAL_BATCH_SIZE;
|
||||||
private boolean unloadAfter = true;
|
private boolean unloadAfter = true;
|
||||||
|
|
||||||
@Inject public ChunkCoordinatorBuilder(@Nonnull ChunkCoordinatorFactory chunkCoordinatorFactory) {
|
@Inject public ChunkCoordinatorBuilder(@Nonnull ChunkCoordinatorFactory chunkCoordinatorFactory) {
|
||||||
@ -193,6 +196,16 @@ public class ChunkCoordinatorBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withProgressSubscriber(ProgressSubscriber progressSubscriber) {
|
||||||
|
this.progressSubscribers.add(progressSubscriber);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nonnull public ChunkCoordinatorBuilder withProgressSubscribers(Collection<ProgressSubscriber> progressSubscribers) {
|
||||||
|
this.progressSubscribers.addAll(progressSubscribers);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link ChunkCoordinator} instance based on the values in the Builder instance.
|
* Create a new {@link ChunkCoordinator} instance based on the values in the Builder instance.
|
||||||
*
|
*
|
||||||
@ -205,7 +218,7 @@ public class ChunkCoordinatorBuilder {
|
|||||||
Preconditions.checkNotNull(this.throwableConsumer, "No throwable consumer was supplied");
|
Preconditions.checkNotNull(this.throwableConsumer, "No throwable consumer was supplied");
|
||||||
return chunkCoordinatorFactory
|
return chunkCoordinatorFactory
|
||||||
.create(this.maxIterationTime, this.initialBatchSize, this.chunkConsumer, this.world, this.requestedChunks, this.whenDone,
|
.create(this.maxIterationTime, this.initialBatchSize, this.chunkConsumer, this.world, this.requestedChunks, this.whenDone,
|
||||||
this.throwableConsumer, this.unloadAfter);
|
this.throwableConsumer, this.unloadAfter, this.progressSubscribers);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.queue;
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import com.plotsquared.core.configuration.Settings;
|
||||||
|
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
@ -190,7 +192,7 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable @Override public Consumer<BlockVector2> getChunkConsumer() {
|
@Override @Nullable public Consumer<BlockVector2> getChunkConsumer() {
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
return parent.getChunkConsumer();
|
return parent.getChunkConsumer();
|
||||||
}
|
}
|
||||||
@ -203,6 +205,25 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override public void addProgressSubscriber(@Nonnull ProgressSubscriber progressSubscriber) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.addProgressSubscriber(progressSubscriber);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override @Nonnull public LightingMode getLightingMode() {
|
||||||
|
if (parent != null) {
|
||||||
|
return parent.getLightingMode();
|
||||||
|
}
|
||||||
|
return LightingMode.valueOf(Settings.QUEUE.LIGHTING_MODE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void setLightingMode(@Nullable LightingMode mode) {
|
||||||
|
if (parent != null) {
|
||||||
|
parent.setLightingMode(mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override @Nonnull public List<BlockVector2> getReadChunks() {
|
@Override @Nonnull public List<BlockVector2> getReadChunks() {
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
return parent.getReadChunks();
|
return parent.getReadChunks();
|
||||||
@ -246,6 +267,5 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
|
|||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
parent.setRegenRegion(regenRegion);
|
parent.setRegenRegion(regenRegion);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.queue;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public enum LightingMode {
|
||||||
|
|
||||||
|
NONE(0), PLACEMENT(1), REPLACEMENT(2), ALL(3);
|
||||||
|
|
||||||
|
private static final Map<Integer, LightingMode> map = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (LightingMode mode : LightingMode.values()) {
|
||||||
|
map.put(mode.mode, mode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final int mode;
|
||||||
|
|
||||||
|
LightingMode(int mode) {
|
||||||
|
this.mode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LightingMode valueOf(int mode) {
|
||||||
|
return map.get(mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
}
|
@ -28,6 +28,7 @@ package com.plotsquared.core.queue;
|
|||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.queue.subscriber.ProgressSubscriber;
|
||||||
import com.plotsquared.core.util.PatternUtil;
|
import com.plotsquared.core.util.PatternUtil;
|
||||||
import com.sk89q.jnbt.CompoundTag;
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
@ -353,6 +354,23 @@ public abstract class QueueCoordinator {
|
|||||||
*/
|
*/
|
||||||
public abstract void setChunkConsumer(@Nonnull Consumer<BlockVector2> consumer);
|
public abstract void setChunkConsumer(@Nonnull Consumer<BlockVector2> consumer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link ProgressSubscriber} to the Queue to subscribe to the relevant Chunk Processor
|
||||||
|
*/
|
||||||
|
public abstract void addProgressSubscriber(@Nonnull ProgressSubscriber progressSubscriber);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@link LightingMode} to be used when setting blocks
|
||||||
|
*/
|
||||||
|
@Nonnull public abstract LightingMode getLightingMode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the {@link LightingMode} to be used when setting blocks
|
||||||
|
*
|
||||||
|
* @param mode lighting mode. Null to use default.
|
||||||
|
*/
|
||||||
|
public abstract void setLightingMode(@Nullable LightingMode mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fill a cuboid between two positions with a BlockState
|
* Fill a cuboid between two positions with a BlockState
|
||||||
*
|
*
|
||||||
|
@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
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.google.inject.assistedinject.Assisted;
|
||||||
|
import com.google.inject.assistedinject.AssistedInject;
|
||||||
|
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;
|
||||||
|
import com.plotsquared.core.util.task.TaskManager;
|
||||||
|
import com.plotsquared.core.util.task.TaskTime;
|
||||||
|
import net.kyori.adventure.text.minimessage.Template;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default PlotSquared Progress Subscriber. Can be used for both console and player tasks.
|
||||||
|
* It is the {@link ProgressSubscriber} returned by {@link com.plotsquared.core.inject.factory.ProgressSubscriberFactory}.
|
||||||
|
* Runs a repeating synchronous task notifying the given actor about any updates, saving updates notified by the ChunkCoordinator.
|
||||||
|
*/
|
||||||
|
public class DefaultProgressSubscriber implements ProgressSubscriber {
|
||||||
|
|
||||||
|
@Nonnull private final AtomicDouble progress = new AtomicDouble(0);
|
||||||
|
@Nonnull private final AtomicBoolean started = new AtomicBoolean(false);
|
||||||
|
@Nonnull private final AtomicBoolean cancelled = new AtomicBoolean(false);
|
||||||
|
@Nonnull private final TaskTime interval;
|
||||||
|
@Nonnull private final TaskTime wait;
|
||||||
|
@Nonnull private final PlotPlayer<?> actor;
|
||||||
|
@Nonnull private final Caption caption;
|
||||||
|
private PlotSquaredTask task;
|
||||||
|
|
||||||
|
@AssistedInject
|
||||||
|
public DefaultProgressSubscriber() {
|
||||||
|
throw new UnsupportedOperationException("DefaultProgressSubscriber cannot be used without an actor.");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedInject
|
||||||
|
public DefaultProgressSubscriber(@Nullable @Assisted("subscriber") 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.interval = TaskTime.ms(Settings.QUEUE.NOTIFY_INTERVAL);
|
||||||
|
this.wait = TaskTime.ms(Settings.QUEUE.NOTIFY_WAIT);
|
||||||
|
this.caption = TranslatableCaption.of("working.progress");
|
||||||
|
}
|
||||||
|
|
||||||
|
@AssistedInject
|
||||||
|
public DefaultProgressSubscriber(@Nullable @Assisted("subscriber") final PlotPlayer<?> actor,
|
||||||
|
@Assisted("progressInterval") final long interval,
|
||||||
|
@Assisted("waitBeforeStarting") final long wait,
|
||||||
|
@Nullable @Assisted("caption") 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);
|
||||||
|
if (caption == null) {
|
||||||
|
this.caption = TranslatableCaption.of("working.progress");
|
||||||
|
} else {
|
||||||
|
this.caption = caption;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void notifyProgress(@Nonnull ChunkCoordinator coordinator, double progress) {
|
||||||
|
this.progress.set(progress);
|
||||||
|
if (coordinator.isCancelled() || progress >= 1) {
|
||||||
|
if (task != null) {
|
||||||
|
task.cancel();
|
||||||
|
}
|
||||||
|
} else if (started.compareAndSet(false, true)) {
|
||||||
|
TaskManager.getPlatformImplementation().taskLater(() -> task = TaskManager.getPlatformImplementation().taskRepeat(() -> {
|
||||||
|
if (!started.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (cancelled.get()) {
|
||||||
|
task.cancel();
|
||||||
|
}
|
||||||
|
actor.sendMessage(caption, Template.of("progress", String.format("%.2f", this.progress.doubleValue() * 100)));
|
||||||
|
}, interval), wait);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void notifyEnd() {
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void cancel() {
|
||||||
|
this.cancelled.set(true);
|
||||||
|
if (this.task != null) {
|
||||||
|
task.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* _____ _ _ _____ _
|
||||||
|
* | __ \| | | | / ____| | |
|
||||||
|
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
|
||||||
|
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
|
||||||
|
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
|
||||||
|
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
|
||||||
|
* | |
|
||||||
|
* |_|
|
||||||
|
* PlotSquared plot management system for Minecraft
|
||||||
|
* Copyright (C) 2020 IntellectualSites
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU 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 General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package com.plotsquared.core.queue.subscriber;
|
||||||
|
|
||||||
|
import com.plotsquared.core.queue.ChunkCoordinator;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
|
||||||
|
public interface ProgressSubscriber {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify about a progress update in the coordinator
|
||||||
|
*
|
||||||
|
* @param coordinator Coordinator instance that triggered the notification
|
||||||
|
* @param progress Progress in the range [0, 1]
|
||||||
|
*/
|
||||||
|
void notifyProgress(@Nonnull final ChunkCoordinator coordinator, final double progress);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Notify the subscriber that its parent ChunkCoordinator has finished
|
||||||
|
*/
|
||||||
|
void notifyEnd();
|
||||||
|
}
|
@ -27,7 +27,11 @@ package com.plotsquared.core.util;
|
|||||||
|
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.plotsquared.core.configuration.Settings;
|
||||||
|
import com.plotsquared.core.configuration.caption.TranslatableCaption;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.PlotManager;
|
import com.plotsquared.core.plot.PlotManager;
|
||||||
@ -59,10 +63,13 @@ public abstract class RegionManager {
|
|||||||
public static RegionManager manager = null;
|
public static RegionManager manager = null;
|
||||||
private final WorldUtil worldUtil;
|
private final WorldUtil worldUtil;
|
||||||
private final GlobalBlockQueue blockQueue;
|
private final GlobalBlockQueue blockQueue;
|
||||||
|
private final ProgressSubscriberFactory subscriberFactory;
|
||||||
|
|
||||||
@Inject public RegionManager(@Nonnull WorldUtil worldUtil, @Nonnull GlobalBlockQueue blockQueue) {
|
@Inject
|
||||||
|
public RegionManager(@Nonnull WorldUtil worldUtil, @Nonnull GlobalBlockQueue blockQueue, @Nonnull ProgressSubscriberFactory subscriberFactory) {
|
||||||
this.worldUtil = worldUtil;
|
this.worldUtil = worldUtil;
|
||||||
this.blockQueue = blockQueue;
|
this.blockQueue = blockQueue;
|
||||||
|
this.subscriberFactory = subscriberFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockVector2 getRegion(Location location) {
|
public static BlockVector2 getRegion(Location location) {
|
||||||
@ -106,20 +113,25 @@ public abstract class RegionManager {
|
|||||||
* @param blocks pattern
|
* @param blocks pattern
|
||||||
* @param minY y to set from
|
* @param minY y to set from
|
||||||
* @param maxY y to set to
|
* @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,
|
* @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues,
|
||||||
* otherwise writes to the queue but does not enqueue.
|
* otherwise writes to the queue but does not enqueue.
|
||||||
* @return true if not enqueued, otherwise whether the created queue enqueued.
|
* @return true if not enqueued, otherwise whether the created queue enqueued.
|
||||||
*/
|
*/
|
||||||
public boolean setCuboids(final PlotArea area,
|
public boolean setCuboids(@Nonnull final PlotArea area,
|
||||||
final Set<CuboidRegion> regions,
|
@Nonnull final Set<CuboidRegion> regions,
|
||||||
final Pattern blocks,
|
@Nonnull final Pattern blocks,
|
||||||
int minY,
|
int minY,
|
||||||
int maxY,
|
int maxY,
|
||||||
|
@Nullable PlotPlayer<?> actor,
|
||||||
@Nullable QueueCoordinator queue) {
|
@Nullable QueueCoordinator queue) {
|
||||||
boolean enqueue = false;
|
boolean enqueue = false;
|
||||||
if (queue == null) {
|
if (queue == null) {
|
||||||
queue = area.getQueue();
|
queue = area.getQueue();
|
||||||
enqueue = true;
|
enqueue = true;
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
queue.addProgressSubscriber(subscriberFactory.createWithActor(actor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (CuboidRegion region : regions) {
|
for (CuboidRegion region : regions) {
|
||||||
Location pos1 = Location.at(area.getWorldName(), region.getMinimumPoint().getX(), minY, region.getMinimumPoint().getZ());
|
Location pos1 = Location.at(area.getWorldName(), region.getMinimumPoint().getX(), minY, region.getMinimumPoint().getZ());
|
||||||
@ -145,9 +157,13 @@ public abstract class RegionManager {
|
|||||||
* @param plot plot
|
* @param plot plot
|
||||||
* @param whenDone task to run when complete
|
* @param whenDone task to run when complete
|
||||||
* @param manager plot manager
|
* @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
|
* @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)
|
* Copy a region to a new location (in the same world)
|
||||||
@ -155,10 +171,15 @@ public abstract class RegionManager {
|
|||||||
* @param pos1 position 1
|
* @param pos1 position 1
|
||||||
* @param pos2 position 2
|
* @param pos2 position 2
|
||||||
* @param newPos position to move pos1 to
|
* @param newPos position to move pos1 to
|
||||||
|
* @param actor the actor associated with the region copy
|
||||||
* @param whenDone task to run when complete
|
* @param whenDone task to run when complete
|
||||||
* @return success or not
|
* @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 relX = newPos.getX() - pos1.getX();
|
||||||
final int relZ = newPos.getZ() - pos1.getZ();
|
final int relZ = newPos.getZ() - pos1.getZ();
|
||||||
final com.sk89q.worldedit.world.World oldWorld = worldUtil.getWeWorld(pos1.getWorldName());
|
final com.sk89q.worldedit.world.World oldWorld = worldUtil.getWeWorld(pos1.getWorldName());
|
||||||
@ -167,9 +188,17 @@ public abstract class RegionManager {
|
|||||||
final BasicQueueCoordinator copyTo = (BasicQueueCoordinator) blockQueue.getNewQueue(newWorld);
|
final BasicQueueCoordinator copyTo = (BasicQueueCoordinator) blockQueue.getNewQueue(newWorld);
|
||||||
copyFromTo(pos1, pos2, relX, relZ, oldWorld, copyFrom, copyTo, false);
|
copyFromTo(pos1, pos2, relX, relZ, oldWorld, copyFrom, copyTo, false);
|
||||||
copyFrom.setCompleteTask(copyTo::enqueue);
|
copyFrom.setCompleteTask(copyTo::enqueue);
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
copyFrom.addProgressSubscriber(subscriberFactory
|
||||||
|
.createFull(actor, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT, TranslatableCaption.of("swap.progress_region_copy")));
|
||||||
|
}
|
||||||
copyFrom
|
copyFrom
|
||||||
.addReadChunks(new CuboidRegion(BlockVector3.at(pos1.getX(), 0, pos1.getZ()), BlockVector3.at(pos2.getX(), 0, pos2.getZ())).getChunks());
|
.addReadChunks(new CuboidRegion(BlockVector3.at(pos1.getX(), 0, pos1.getZ()), BlockVector3.at(pos2.getX(), 0, pos2.getZ())).getChunks());
|
||||||
copyTo.setCompleteTask(whenDone);
|
copyTo.setCompleteTask(whenDone);
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
copyTo.addProgressSubscriber(subscriberFactory
|
||||||
|
.createFull(actor, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT, TranslatableCaption.of("swap.progress_region_paste")));
|
||||||
|
}
|
||||||
return copyFrom.enqueue();
|
return copyFrom.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +217,16 @@ public abstract class RegionManager {
|
|||||||
|
|
||||||
public abstract void clearAllEntities(Location pos1, Location pos2);
|
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 relX = swapPos.getX() - pos1.getX();
|
||||||
int relZ = swapPos.getZ() - pos1.getZ();
|
int relZ = swapPos.getZ() - pos1.getZ();
|
||||||
|
|
||||||
@ -208,9 +246,26 @@ public abstract class RegionManager {
|
|||||||
copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue1, toQueue2, true);
|
copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue1, toQueue2, true);
|
||||||
copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue2, toQueue1, true);
|
copyFromTo(pos1, pos2, relX, relZ, world1, fromQueue2, toQueue1, true);
|
||||||
fromQueue1.setCompleteTask(fromQueue2::enqueue);
|
fromQueue1.setCompleteTask(fromQueue2::enqueue);
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
fromQueue1.addProgressSubscriber(subscriberFactory
|
||||||
|
.createFull(actor, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT, TranslatableCaption.of("swap.progress_region1_copy")));
|
||||||
|
}
|
||||||
fromQueue2.setCompleteTask(toQueue1::enqueue);
|
fromQueue2.setCompleteTask(toQueue1::enqueue);
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
fromQueue2.addProgressSubscriber(subscriberFactory
|
||||||
|
.createFull(actor, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT, TranslatableCaption.of("swap.progress_region2_copy")));
|
||||||
|
}
|
||||||
toQueue1.setCompleteTask(toQueue2::enqueue);
|
toQueue1.setCompleteTask(toQueue2::enqueue);
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
toQueue1.addProgressSubscriber(subscriberFactory.createFull(actor, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT,
|
||||||
|
TranslatableCaption.of("swap.progress_region1_paste")));
|
||||||
|
}
|
||||||
toQueue2.setCompleteTask(whenDone);
|
toQueue2.setCompleteTask(whenDone);
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
toQueue2.addProgressSubscriber(subscriberFactory.createFull(actor, Settings.QUEUE.NOTIFY_INTERVAL, Settings.QUEUE.NOTIFY_WAIT,
|
||||||
|
TranslatableCaption.of("swap.progress_region2_paste")));
|
||||||
|
}
|
||||||
|
fromQueue1.enqueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyFromTo(Location pos1,
|
private void copyFromTo(Location pos1,
|
||||||
|
@ -25,13 +25,16 @@
|
|||||||
*/
|
*/
|
||||||
package com.plotsquared.core.util;
|
package com.plotsquared.core.util;
|
||||||
|
|
||||||
|
import com.google.inject.Inject;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonParseException;
|
import com.google.gson.JsonParseException;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.generator.ClassicPlotWorld;
|
import com.plotsquared.core.generator.ClassicPlotWorld;
|
||||||
|
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
import com.plotsquared.core.plot.Plot;
|
import com.plotsquared.core.plot.Plot;
|
||||||
import com.plotsquared.core.plot.PlotArea;
|
import com.plotsquared.core.plot.PlotArea;
|
||||||
import com.plotsquared.core.plot.schematic.Schematic;
|
import com.plotsquared.core.plot.schematic.Schematic;
|
||||||
@ -111,9 +114,11 @@ public abstract class SchematicHandler {
|
|||||||
public static SchematicHandler manager;
|
public static SchematicHandler manager;
|
||||||
private final WorldUtil worldUtil;
|
private final WorldUtil worldUtil;
|
||||||
private boolean exportAll = false;
|
private boolean exportAll = false;
|
||||||
|
private final ProgressSubscriberFactory subscriberFactory;
|
||||||
|
|
||||||
public SchematicHandler(@Nonnull final WorldUtil worldUtil) {
|
@Inject public SchematicHandler(@Nonnull final WorldUtil worldUtil, @Nonnull ProgressSubscriberFactory subscriberFactory) {
|
||||||
this.worldUtil = worldUtil;
|
this.worldUtil = worldUtil;
|
||||||
|
this.subscriberFactory = subscriberFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void upload(@Nullable UUID uuid,
|
public static void upload(@Nullable UUID uuid,
|
||||||
@ -259,6 +264,7 @@ public abstract class SchematicHandler {
|
|||||||
* @param yOffset offset y to paste it from plot origin
|
* @param yOffset offset y to paste it from plot origin
|
||||||
* @param zOffset offset z 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 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
|
* @param whenDone task to run when schematic is pasted
|
||||||
*/
|
*/
|
||||||
public void paste(final Schematic schematic,
|
public void paste(final Schematic schematic,
|
||||||
@ -267,6 +273,7 @@ public abstract class SchematicHandler {
|
|||||||
final int yOffset,
|
final int yOffset,
|
||||||
final int zOffset,
|
final int zOffset,
|
||||||
final boolean autoHeight,
|
final boolean autoHeight,
|
||||||
|
final PlotPlayer<?> actor,
|
||||||
final RunnableVal<Boolean> whenDone) {
|
final RunnableVal<Boolean> whenDone) {
|
||||||
|
|
||||||
TaskManager.runTask(() -> {
|
TaskManager.runTask(() -> {
|
||||||
@ -346,6 +353,9 @@ public abstract class SchematicHandler {
|
|||||||
if (whenDone != null) {
|
if (whenDone != null) {
|
||||||
whenDone.value = true;
|
whenDone.value = true;
|
||||||
}
|
}
|
||||||
|
if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) {
|
||||||
|
queue.addProgressSubscriber(subscriberFactory.createWithActor(actor));
|
||||||
|
}
|
||||||
queue.setCompleteTask(whenDone);
|
queue.setCompleteTask(whenDone);
|
||||||
queue.enqueue();
|
queue.enqueue();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -41,13 +41,13 @@ import java.util.concurrent.Callable;
|
|||||||
|
|
||||||
public final class AutoClaimFinishTask implements Callable<Boolean> {
|
public final class AutoClaimFinishTask implements Callable<Boolean> {
|
||||||
|
|
||||||
private final PlotPlayer player;
|
private final PlotPlayer<?> player;
|
||||||
private final Plot plot;
|
private final Plot plot;
|
||||||
private final PlotArea area;
|
private final PlotArea area;
|
||||||
private final String schematic;
|
private final String schematic;
|
||||||
private final EventDispatcher eventDispatcher;
|
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) {
|
final String schematic, final EventDispatcher eventDispatcher) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
this.plot = plot;
|
this.plot = plot;
|
||||||
@ -72,7 +72,7 @@ public final class AutoClaimFinishTask implements Callable<Boolean> {
|
|||||||
player.sendMessage(TranslatableCaption.of("events.event_denied"),
|
player.sendMessage(TranslatableCaption.of("events.event_denied"),
|
||||||
Templates.of("value", "Auto Merge"));
|
Templates.of("value", "Auto Merge"));
|
||||||
} else {
|
} else {
|
||||||
plot.getPlotModificationManager().autoMerge(event.getDir(), event.getMax(), player.getUUID(), true);
|
plot.getPlotModificationManager().autoMerge(event.getDir(), event.getMax(), player.getUUID(), player, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -74,6 +74,12 @@
|
|||||||
"swap.swap_overlap": "<prefix><red>The proposed areas are not allowed to overlap.</red>",
|
"swap.swap_overlap": "<prefix><red>The proposed areas are not allowed to overlap.</red>",
|
||||||
"swap.swap_success": "<prefix><dark_aqua>Successfully swapped plots.</dark_aqua>",
|
"swap.swap_success": "<prefix><dark_aqua>Successfully swapped plots.</dark_aqua>",
|
||||||
"swap.swap_merged": "<prefix><red>Merged plots may not be swapped. Please unmerge the plots before performing the swap.</red>",
|
"swap.swap_merged": "<prefix><red>Merged plots may not be swapped. Please unmerge the plots before performing the swap.</red>",
|
||||||
|
"swap.progress_region1_copy": "<prefix><gray>Current region 1 copy progress: </gray><gold><progress></gold><gray>%</gray>",
|
||||||
|
"swap.progress_region2_copy": "<prefix><gray>Current region 2 copy progress: </gray><gold><progress></gold><gray>%</gray",
|
||||||
|
"swap.progress_region1_paste": "<prefix><gray>Current region 1 paste progress: </gray><gold><progress></gold><gray>%</gray>",
|
||||||
|
"swap.progress_region2_paste": "<prefix><gray>Current region 2 paste progress: </gray><gold><progress></gold><gray>%</gray>",
|
||||||
|
"swap.progress_region_copy": "<prefix><gray>Current copy progress: </gray><gold><progress></gold><gray>%</gray>",
|
||||||
|
"swap.progress_region_paste": "<prefix><gray>Current paste progress: </gray><gold><progress></gold><gray>%</gray>",
|
||||||
|
|
||||||
"comment.inbox_notification": "<prefix><dark_aqua><amount> </dark_aqua><gray>unread messages. Use <command>.</gray>",
|
"comment.inbox_notification": "<prefix><dark_aqua><amount> </dark_aqua><gray>unread messages. Use <command>.</gray>",
|
||||||
"comment.not_valid_inbox_index": "<prefix><gray>No comment at index <number>.</gray>",
|
"comment.not_valid_inbox_index": "<prefix><gray>No comment at index <number>.</gray>",
|
||||||
@ -411,6 +417,8 @@
|
|||||||
"working.plot_not_claimed": "<prefix><gray>Plot not claimed.</gray>",
|
"working.plot_not_claimed": "<prefix><gray>Plot not claimed.</gray>",
|
||||||
"working.plot_is_claimed": "<prefix><gray>This plot is already claimed.</gray>",
|
"working.plot_is_claimed": "<prefix><gray>This plot is already claimed.</gray>",
|
||||||
"working.claimed": "<prefix><dark_aqua>You successfully claimed the plot.</dark_aqua>",
|
"working.claimed": "<prefix><dark_aqua>You successfully claimed the plot.</dark_aqua>",
|
||||||
|
"working.progress": "<prefix><gray>Current progress: </gray><gold><progress></gold><gray>%</gray>",
|
||||||
|
"working.component_complete": "<prefix><gold>Component generation has finished.</gold>",
|
||||||
|
|
||||||
"list.comment_list_header_paged": "<gray>(Page </gray><gold><cur></gold><gray>/</gray><gold><max></gold><gray>) </gray><gold>List of <amount> comments</gold>",
|
"list.comment_list_header_paged": "<gray>(Page </gray><gold><cur></gold><gray>/</gray><gold><max></gold><gray>) </gray><gold>List of <amount> comments</gold>",
|
||||||
"list.comment_list_comment": "<dark_gray>[</dark_gray><gray>#<number></gray><dark_gray>[</dark_gray><gray><world>;<plot_id></gray><dark_gray>][</dark_gray><gold><commenter></gold><dark_gray>]</dark_gray><comment>\n",
|
"list.comment_list_comment": "<dark_gray>[</dark_gray><gray>#<number></gray><dark_gray>[</dark_gray><gray><world>;<plot_id></gray><dark_gray>][</dark_gray><gold><commenter></gold><dark_gray>]</dark_gray><comment>\n",
|
||||||
|
Loading…
Reference in New Issue
Block a user