Compare commits

..

3 Commits

Author SHA1 Message Date
dordsor21
f515ce2cc1 Javadocs 2022-05-10 14:17:16 +01:00
dordsor21
b3c67b55d5 Fix lag caused when generating augmented worlds with roads
- Begin by implementing forceSync to the queue system as we know the chunk will be accessible to edits in some cases (i.e. population).
 - Also implement custom SideEffectSets to override any decided by the default chunk consumer, as we do NOT want to update neighbours in population (this caused infinite generation to be required causing the lag and server death). We also do not want to enqueue the QueueCoordinator in AugmentedUtils as this would write to the world and update neighbours before we might want to (plus it's just used to restrict and offset the blocks being set)
 - Then implement disabling any biomes from being saved/set to the queue to prevent augmented worlds having their biomes overriden in roads
 - Consequently fix ScopedQueueCoordinator, preventing the y value of blocks being set from needlessly being changed, fixing road heights in augmented worlds
 - Finally we do not need a method with chunkObject in the signature in AugmentedUtils as this is no longer used by the method
2022-05-10 01:53:28 +01:00
dordsor21
13d7357c85 Niceties
- Better ordering of augmented information printed to consol on startup
 - Override
2022-05-10 01:43:01 +01:00
23 changed files with 224 additions and 398 deletions

View File

@@ -25,7 +25,11 @@
*/
package com.plotsquared.bukkit.generator;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.generator.AugmentedUtils;
import com.plotsquared.core.queue.QueueCoordinator;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.util.SideEffectSet;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.generator.BlockPopulator;
@@ -52,7 +56,14 @@ public class BukkitAugmentedGenerator extends BlockPopulator {
@Override
public void populate(@NonNull World world, @NonNull Random random, @NonNull Chunk source) {
AugmentedUtils.generate(source, world.getName(), source.getX(), source.getZ(), null);
QueueCoordinator queue = PlotSquared.platform().globalBlockQueue().getNewQueue(BukkitAdapter.adapt(world));
// The chunk is already loaded and we do not want to load the chunk in "fully" by using any PaperLib methods.
queue.setForceSync(true);
queue.setSideEffectSet(SideEffectSet.none());
queue.setBiomesEnabled(false);
queue.setChunkObject(source);
AugmentedUtils.generateChunk(world.getName(), source.getX(), source.getZ(), queue);
queue.enqueue();
}
}

View File

@@ -80,7 +80,8 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator {
result.setBiome(x, z, BukkitAdapter.adapt(biome));
}
//do not annotate with Override until we discontinue support for 1.4.4
//do not annotate with Override until we discontinue support for 1.4.4 (we no longer support 1.4.4)
@Override
public void setBiome(int x, int y, int z, @NonNull Biome biome) {
result.setBiome(x, z, BukkitAdapter.adapt(biome));

View File

@@ -76,10 +76,11 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
private final int totalSize;
private final AtomicInteger expectedSize;
private final AtomicInteger loadingChunks = new AtomicInteger();
private final boolean forceSync;
private int batchSize;
private PlotSquaredTask task;
private boolean shouldCancel;
private volatile boolean shouldCancel;
private boolean finished;
@Inject
@@ -92,7 +93,8 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
@Assisted final @NonNull Runnable whenDone,
@Assisted final @NonNull Consumer<Throwable> throwableConsumer,
@Assisted final boolean unloadAfter,
@Assisted final @NonNull Collection<ProgressSubscriber> progressSubscribers
@Assisted final @NonNull Collection<ProgressSubscriber> progressSubscribers,
@Assisted final boolean forceSync
) {
this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks);
this.availableChunks = new LinkedBlockingQueue<>();
@@ -107,14 +109,27 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class);
this.bukkitWorld = Bukkit.getWorld(world.getName());
this.progressSubscribers.addAll(progressSubscribers);
this.forceSync = forceSync;
}
@Override
public void start() {
// Request initial batch
this.requestBatch();
// Wait until next tick to give the chunks a chance to be loaded
TaskManager.runTaskLater(() -> task = TaskManager.runTaskRepeat(this, TaskTime.ticks(1)), TaskTime.ticks(1));
if (!forceSync) {
// Request initial batch
this.requestBatch();
// Wait until next tick to give the chunks a chance to be loaded
TaskManager.runTaskLater(() -> task = TaskManager.runTaskRepeat(this, TaskTime.ticks(1)), TaskTime.ticks(1));
} else {
try {
while (!shouldCancel && !requestedChunks.isEmpty()) {
chunkConsumer.accept(requestedChunks.poll());
}
} catch (Throwable t) {
throwableConsumer.accept(t);
} finally {
finish();
}
}
}
@Override
@@ -131,7 +146,9 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
for (final ProgressSubscriber subscriber : this.progressSubscribers) {
subscriber.notifyEnd();
}
task.cancel();
if (task != null) {
task.cancel();
}
finished = true;
}
}

View File

@@ -62,10 +62,27 @@ import java.util.function.Consumer;
public class BukkitQueueCoordinator extends BasicQueueCoordinator {
private final SideEffectSet noSideEffectSet;
private final SideEffectSet lightingSideEffectSet;
private final SideEffectSet edgeSideEffectSet;
private final SideEffectSet edgeLightingSideEffectSet;
private static final SideEffectSet NO_SIDE_EFFECT_SET;
private static final SideEffectSet EDGE_SIDE_EFFECT_SET;
private static final SideEffectSet LIGHTING_SIDE_EFFECT_SET;
private static final SideEffectSet EDGE_LIGHTING_SIDE_EFFECT_SET;
static {
NO_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF).with(
SideEffect.NEIGHBORS,
SideEffect.State.OFF
);
EDGE_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.UPDATE, SideEffect.State.ON).with(
SideEffect.NEIGHBORS,
SideEffect.State.ON
);
LIGHTING_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
EDGE_LIGHTING_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.UPDATE, SideEffect.State.ON).with(
SideEffect.NEIGHBORS,
SideEffect.State.ON
);
}
private org.bukkit.World bukkitWorld;
@Inject
private ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory;
@@ -76,19 +93,6 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
@Inject
public BukkitQueueCoordinator(@NonNull World world) {
super(world);
noSideEffectSet = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF).with(
SideEffect.NEIGHBORS,
SideEffect.State.OFF
);
lightingSideEffectSet = SideEffectSet.none().with(SideEffect.NEIGHBORS, SideEffect.State.OFF);
edgeSideEffectSet = noSideEffectSet.with(SideEffect.UPDATE, SideEffect.State.ON).with(
SideEffect.NEIGHBORS,
SideEffect.State.ON
);
edgeLightingSideEffectSet = noSideEffectSet.with(SideEffect.UPDATE, SideEffect.State.ON).with(
SideEffect.NEIGHBORS,
SideEffect.State.ON
);
}
@Override
@@ -201,7 +205,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
localChunk.getTiles().forEach((blockVector3, tag) -> {
try {
BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag);
getWorld().setBlock(blockVector3, block, noSideEffectSet);
getWorld().setBlock(blockVector3, block, getSideEffectSet(SideEffectState.NONE));
} catch (WorldEditException ignored) {
StateWrapper sw = new StateWrapper(tag);
sw.restoreTag(getWorld().getName(), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ());
@@ -258,9 +262,9 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
}
SideEffectSet sideEffectSet;
if (lighting) {
sideEffectSet = edge ? edgeLightingSideEffectSet : lightingSideEffectSet;
sideEffectSet = getSideEffectSet(edge ? SideEffectState.EDGE_LIGHTING : SideEffectState.LIGHTING);
} else {
sideEffectSet = edge ? edgeSideEffectSet : noSideEffectSet;
sideEffectSet = getSideEffectSet(edge ? SideEffectState.EDGE : SideEffectState.NONE);
}
getWorld().setBlock(loc, block, sideEffectSet);
} catch (WorldEditException ignored) {
@@ -375,4 +379,23 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
return false;
}
private SideEffectSet getSideEffectSet(SideEffectState state) {
if (getSideEffectSet() != null) {
return getSideEffectSet();
}
return switch (state) {
case NONE -> NO_SIDE_EFFECT_SET;
case EDGE -> EDGE_SIDE_EFFECT_SET;
case LIGHTING -> LIGHTING_SIDE_EFFECT_SET;
case EDGE_LIGHTING -> EDGE_LIGHTING_SIDE_EFFECT_SET;
};
}
private enum SideEffectState {
NONE,
EDGE,
LIGHTING,
EDGE_LIGHTING
}
}

View File

@@ -37,10 +37,6 @@ dependencies {
// Logging
compileOnlyApi(libs.log4j)
// Records are cool. Builders are cooler
compileOnly(libs.recordBuilderProcessor)
annotationProcessor(libs.recordBuilderProcessor)
// Other libraries
api(libs.prtree)
api(libs.aopalliance)

View File

@@ -889,8 +889,8 @@ public class PlotSquared {
e.printStackTrace();
}
LOGGER.info("| generator: {}>{}", baseGenerator, areaGen);
LOGGER.info("| plot world: {}", pa);
LOGGER.info("| manager: {}", pa);
LOGGER.info("| plot world: {}", pa.getClass().getCanonicalName());
LOGGER.info("| manager: {}", pa.getPlotManager().getClass().getCanonicalName());
LOGGER.info("Note: Area created for cluster '{}' (invalid or old configuration?)", name);
areaGen.getPlotGenerator().initialize(pa);
areaGen.augment(pa);
@@ -906,6 +906,13 @@ public class PlotSquared {
throw new IllegalArgumentException("Invalid Generator: " + gen_string);
}
PlotArea pa = areaGen.getPlotGenerator().getNewPlotArea(world, null, null, null);
LOGGER.info("- generator: {}>{}", baseGenerator, areaGen);
LOGGER.info("- plot world: {}", pa.getClass().getCanonicalName());
LOGGER.info("- plot area manager: {}", pa.getPlotManager().getClass().getCanonicalName());
if (!this.worldConfiguration.contains(path)) {
this.worldConfiguration.createSection(path);
worldSection = this.worldConfiguration.getConfigurationSection(path);
}
pa.saveConfiguration(worldSection);
pa.loadDefaultConfiguration(worldSection);
try {
@@ -913,9 +920,6 @@ public class PlotSquared {
} catch (IOException e) {
e.printStackTrace();
}
LOGGER.info("- generator: {}>{}", baseGenerator, areaGen);
LOGGER.info("- plot world: {}", pa);
LOGGER.info("- plot area manager: {}", pa.getPlotManager());
areaGen.getPlotGenerator().initialize(pa);
areaGen.augment(pa);
addPlotArea(pa);

View File

@@ -54,12 +54,23 @@ public class AugmentedUtils {
enabled = true;
}
public static boolean generate(
@Nullable Object chunkObject,
/**
* Generate an augmented world chunk at the given location. If a queue is given, the data will be written to it, else a new
* queue will be created and written to world. Returns true if generation occurred.
*
* @param world World name to generate data for. Must be a PlotSquared world containing one or more areas else nothing will
* happen.
* @param chunkX Chunk X position
* @param chunkZ Chunk Z position
* @param queue Queue to write to, if desired.
* @return true if generation occurred.
* @since TODO
*/
public static boolean generateChunk(
final @NonNull String world,
final int chunkX,
final int chunkZ,
QueueCoordinator queue
@Nullable QueueCoordinator queue
) {
if (!enabled) {
return false;
@@ -97,9 +108,6 @@ public class AugmentedUtils {
.platform()
.worldUtil()
.getWeWorld(world));
if (chunkObject != null) {
queue.setChunkObject(chunkObject);
}
}
QueueCoordinator primaryMask;
// coordinates
@@ -157,13 +165,9 @@ public class AugmentedUtils {
}
generationResult = true;
}
if (chunkObject != null) {
primaryMask.setChunkObject(chunkObject);
}
if (chunkObject != null) {
secondaryMask.setChunkObject(chunkObject);
}
// This queue should not be enqueued as it is simply used to restrict block setting, and then delegate to the
// actual queue
ScopedQueueCoordinator scoped =
new ScopedQueueCoordinator(
secondaryMask,
@@ -172,8 +176,6 @@ public class AugmentedUtils {
);
generator.generateChunk(scoped, area);
generator.populateChunk(scoped, area);
scoped.setForceSync(true);
scoped.enqueue();
}
if (enqueue) {
queue.enqueue();
@@ -181,4 +183,19 @@ public class AugmentedUtils {
return generationResult;
}
/**
* @deprecated Use {@link AugmentedUtils#generateChunk(String, int, int, QueueCoordinator)} as chunkObject is not required
* in the above method
*/
@Deprecated(forRemoval = true, since = "TODO")
public static boolean generate(
@Nullable Object chunkObject,
final @NonNull String world,
final int chunkX,
final int chunkZ,
QueueCoordinator queue
) {
return generateChunk(world, chunkX, chunkZ, queue);
}
}

View File

@@ -1,8 +0,0 @@
package com.plotsquared.core.player;
public enum PlotRole {
OWNER,
HELPER,
TRUSTED,
DENIED,
}

View File

@@ -290,14 +290,14 @@ public class Plot {
* @param area the plot's PlotArea
* @param merged an array giving merged plots
* @param timestamp when the plot was created
* @param temp value representing whatever DBManager needs it to. Do not touch tbh.
* @param temp value representing whatever DBManager needs to to. Do not touch tbh.
*/
public Plot(
@NonNull PlotId id,
UUID owner,
Set<UUID> trusted,
Set<UUID> members,
Set<UUID> denied,
HashSet<UUID> trusted,
HashSet<UUID> members,
HashSet<UUID> denied,
String alias,
BlockLoc position,
Collection<PlotFlag<?, ?>> flags,
@@ -310,9 +310,9 @@ public class Plot {
this.area = area;
this.owner = owner;
this.settings = new PlotSettings();
this.members = new HashSet<>(members);
this.trusted = new HashSet<>(trusted);
this.denied = new HashSet<>(denied);
this.members = members;
this.trusted = trusted;
this.denied = denied;
this.settings.setAlias(alias);
this.settings.setPosition(position);
this.settings.setMerged(merged);
@@ -321,7 +321,9 @@ public class Plot {
if (area != null) {
this.flagContainer.setParentContainer(area.getFlagContainer());
if (flags != null) {
flags.forEach(this.flagContainer::addFlag);
for (PlotFlag<?, ?> flag : flags) {
this.flagContainer.addFlag(flag);
}
}
}
PlotSquared.platform().injector().injectMembers(this);

View File

@@ -1,56 +0,0 @@
package com.plotsquared.core.plot;
import com.plotsquared.core.repository.PlotRepository;
import com.plotsquared.core.repository.PlotRoleRepository;
import com.plotsquared.core.repository.PlotSettingsRepository;
import com.plotsquared.core.repository.dbo.PlotSettingsDBOBuilder;
import org.checkerframework.checker.nullness.qual.NonNull;
import javax.inject.Inject;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
public final class PlotService {
private static final String PLOT_SETTINGS_DEFAULT_POSITION = "default";
private final PlotRepository plotRepository;
private final PlotSettingsRepository plotSettingsRepository;
private final PlotRoleRepository plotRoleRepository;
@Inject
public PlotService(
final @NonNull PlotRepository plotRepository,
final @NonNull PlotSettingsRepository plotSettingsRepository,
final @NonNull PlotRoleRepository plotRoleRepository
) {
this.plotRepository = plotRepository;
this.plotSettingsRepository = plotSettingsRepository;
this.plotRoleRepository = plotRoleRepository;
}
/**
* Returns a list containing all the plots in the given {@code plotArea}.
*
* @param plotArea the area
* @return all plots in the area
*/
public @NonNull Collection<Plot> getPlotsInArea(final @NonNull PlotArea plotArea) {
return this.plotRepository.getPlotsInArea(plotArea.getId())
.map(plotDBO -> {
final var settings = this.plotSettingsRepository.findById(plotDBO)
.orElseGet(() -> PlotSettingsDBOBuilder.builder()
.plot(plotDBO)
.position(PLOT_SETTINGS_DEFAULT_POSITION)
.build()
);
return plotDBO.toPlot(
plotArea,
settings,
this.plotRoleRepository.findAllFor(plotDBO),
List.of()
);
}).collect(Collectors.toList());
}
}

View File

@@ -34,6 +34,7 @@ import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
@@ -61,6 +62,7 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
private int lastX = Integer.MIN_VALUE;
private int lastZ = Integer.MIN_VALUE;
private boolean settingBiomes = false;
private boolean disableBiomes = false;
private boolean settingTiles = false;
private boolean regen = false;
private int[] regenStart;
@@ -68,7 +70,8 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
private CuboidRegion regenRegion = null;
private Consumer<BlockVector2> consumer = null;
private boolean unloadAfter = true;
private Runnable whenDone;
private Runnable whenDone = null;
private SideEffectSet sideEffectSet = null;
@Nullable
private LightingMode lightingMode = LightingMode.valueOf(Settings.QUEUE.LIGHTING_MODE);
@@ -120,6 +123,9 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
@SuppressWarnings("removal")
@Override
public boolean setBiome(int x, int z, @NonNull BiomeType biomeType) {
if (disableBiomes) {
return false;
}
LocalChunk chunk = getChunk(x >> 4, z >> 4);
for (int y = world.getMinY(); y <= world.getMaxY(); y++) {
chunk.setBiome(x & 15, y, z & 15, biomeType);
@@ -130,6 +136,9 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
@Override
public final boolean setBiome(int x, int y, int z, @NonNull BiomeType biomeType) {
if (disableBiomes) {
return false;
}
LocalChunk chunk = getChunk(x >> 4, z >> 4);
chunk.setBiome(x & 15, y, z & 15, biomeType);
settingBiomes = true;
@@ -141,6 +150,12 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
return this.settingBiomes;
}
@Override
public void setBiomesEnabled(boolean settingBiomes) {
this.settingBiomes = settingBiomes;
this.disableBiomes = true;
}
@Override
public boolean setTile(int x, int y, int z, @NonNull CompoundTag tag) {
LocalChunk chunk = getChunk(x >> 4, z >> 4);
@@ -315,6 +330,29 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator {
this.whenDone = whenDone;
}
@Override
public SideEffectSet getSideEffectSet() {
return sideEffectSet;
}
@Override
public void setSideEffectSet(SideEffectSet sideEffectSet) {
this.sideEffectSet = sideEffectSet;
}
// Don't ask about the @NonNull placement. That's how it needs to be else it errors.
@Override
public void setBiomeCuboid(
final com.plotsquared.core.location.@NonNull Location pos1,
final com.plotsquared.core.location.@NonNull Location pos2,
@NonNull final BiomeType biome
) {
if (disableBiomes) {
return;
}
super.setBiomeCuboid(pos1, pos2, biome);
}
/**
* Get the {@link LocalChunk} from the queue at the given chunk coordinates. Returns a new instance if one doesn't exist
*/

View File

@@ -32,6 +32,7 @@ import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
@@ -135,6 +136,13 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
return false;
}
@Override
public void setBiomesEnabled(final boolean enabled) {
if (parent != null) {
parent.setBiomesEnabled(enabled);
}
}
@Override
public boolean setEntity(@NonNull Entity entity) {
if (parent != null) {
@@ -248,6 +256,21 @@ public class DelegateQueueCoordinator extends QueueCoordinator {
}
}
@Override
public SideEffectSet getSideEffectSet() {
if (parent != null) {
return parent.getSideEffectSet();
}
return null;
}
@Override
public void setSideEffectSet(final SideEffectSet sideEffectSet) {
if (parent != null) {
parent.setSideEffectSet(sideEffectSet);
}
}
@Override
public @NonNull List<BlockVector2> getReadChunks() {
if (parent != null) {

View File

@@ -35,6 +35,7 @@ import com.sk89q.worldedit.entity.Entity;
import com.sk89q.worldedit.function.pattern.Pattern;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.util.SideEffectSet;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
@@ -247,6 +248,14 @@ public abstract class QueueCoordinator {
*/
public abstract boolean isSettingBiomes();
/**
* If the queue should accept biome placement
*
* @param enabled If biomes should be enabled
* @since TODO
*/
public abstract void setBiomesEnabled(boolean enabled);
/**
* Add entities to be created
*
@@ -412,6 +421,20 @@ public abstract class QueueCoordinator {
*/
public abstract void setLightingMode(@Nullable LightingMode mode);
/**
* Get the overriding {@link SideEffectSet} to be used by the queue if it exists, else null
*
* @return Overriding {@link SideEffectSet} or null
*/
public abstract @Nullable SideEffectSet getSideEffectSet();
/**
* Set the overriding {@link SideEffectSet} to be used by the queue. Null to use default side effects.
*
* @param sideEffectSet side effects to override with, or null to use default
*/
public abstract void setSideEffectSet(@Nullable SideEffectSet sideEffectSet);
/**
* Fill a cuboid between two positions with a BlockState
*

View File

@@ -35,22 +35,20 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* Queue that only sets blocks with a designated area
* Queue that only sets blocks with a designated X-Z area, will accept any Y values. Requires all blocks be set normalized in
* the x and z directions, i.e. starting from 0,0. An offset of the minimum point of the region will then be applied to x and z.
*/
public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
private final Location min;
private final Location max;
private final int minX;
private final int minY;
private final int minZ;
private final int maxX;
private final int maxY;
private final int maxZ;
private final int dx;
private final int dy;
private final int dz;
/**
@@ -61,15 +59,12 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
this.min = min;
this.max = max;
this.minX = min.getX();
this.minY = min.getY();
this.minZ = min.getZ();
this.maxX = max.getX();
this.maxY = max.getY();
this.maxZ = max.getZ();
this.dx = maxX - minX;
this.dy = maxY - minY;
this.dz = maxZ - minZ;
}
@@ -80,11 +75,11 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
@Override
public boolean setBiome(int x, int y, int z, @NonNull BiomeType biome) {
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBiome(x + minX, y + minY, z + minZ, biome);
return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBiome(x + minX, y, z + minZ, biome);
}
public void fillBiome(BiomeType biome) {
for (int y = 0; y <= dy; y++) {
for (int y = min.getY(); y <= max.getY(); y++) {
for (int x = 0; x <= dx; x++) {
for (int z = 0; z < dz; z++) {
setBiome(x, y, z, biome);
@@ -95,27 +90,22 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator {
@Override
public boolean setBlock(int x, int y, int z, @NonNull BaseBlock id) {
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock(x + minX, y + minY, z + minZ, id);
return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBlock(x + minX, y, z + minZ, id);
}
@Override
public boolean setBlock(int x, int y, int z, @NonNull BlockState id) {
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock(x + minX, y + minY, z + minZ, id);
return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBlock(x + minX, y, z + minZ, id);
}
@Override
public boolean setBlock(int x, int y, int z, @NonNull Pattern pattern) {
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock(
x + minX,
y + minY,
z + minZ,
pattern
);
return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBlock(x + minX, y, z + minZ, pattern);
}
@Override
public boolean setTile(int x, int y, int z, @NonNull CompoundTag tag) {
return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setTile(x + minX, y + minY, z + minZ, tag);
return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setTile(x + minX, y, z + minZ, tag);
}
public @NonNull Location getMin() {

View File

@@ -1,21 +0,0 @@
package com.plotsquared.core.repository;
import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.repository.dbo.PlotDBO;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.stream.Stream;
/**
* {@link Repository} storing {@link PlotDBO plots} identified by their respective {@link PlotId}.
*/
public interface PlotRepository extends Repository<PlotDBO, Integer> {
/**
* Returns all plots in the given {@code area}.
*
* @param area the plot area
* @return a stream with all plots in the given area.
*/
@NonNull Stream<PlotDBO> getPlotsInArea(@NonNull String area);
}

View File

@@ -1,12 +0,0 @@
package com.plotsquared.core.repository;
import com.plotsquared.core.repository.dbo.PlotDBO;
import com.plotsquared.core.repository.dbo.PlotRoleDBO;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List;
public interface PlotRoleRepository extends Repository<PlotRoleDBO, PlotRoleDBO.Key> {
List<PlotRoleDBO> findAllFor(@NonNull PlotDBO plotDBO);
}

View File

@@ -1,8 +0,0 @@
package com.plotsquared.core.repository;
import com.plotsquared.core.repository.dbo.PlotDBO;
import com.plotsquared.core.repository.dbo.PlotSettingsDBO;
public interface PlotSettingsRepository extends Repository<PlotSettingsDBO, PlotDBO> {
}

View File

@@ -1,28 +0,0 @@
package com.plotsquared.core.repository;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Optional;
/**
* Generic object repository.
*
* @param <T> the type of object stored in the repository.
* @param <U> the type used to identify objects stored in the repository.
*/
public interface Repository<@NonNull T, @NonNull U> {
/**
* Saves the given object.
*
* @param object {@code the object}.
*/
void save(T object);
/**
* Finds the object by its {@code id}.
*
* @param id the id
*/
@NonNull Optional<T> findById(U id);
}

View File

@@ -1,65 +0,0 @@
package com.plotsquared.core.repository.dbo;
import com.plotsquared.core.location.BlockLoc;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.flag.PlotFlag;
import io.soabase.recordbuilder.core.RecordBuilder;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.time.Instant;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
@RecordBuilder
public record PlotDBO(
@Nullable Integer id,
int plotIdX,
int plotIdZ,
@NonNull String world,
@NonNull UUID owner,
@NonNull Instant timestamp
) {
public @NonNull Plot toPlot(
final @NonNull PlotArea plotArea,
final @NonNull PlotSettingsDBO plotSettingsDBO,
final @NonNull Collection<PlotRoleDBO> plotRoles,
final @NonNull Collection<PlotFlag<?, ?>> flags
) {
final PlotId plotId = PlotId.of(this.plotIdX(), this.plotIdZ());
final int id = Objects.requireNonNull(id(), "id may not be null");
final Set<UUID> trusted = new HashSet<>();
final Set<UUID> members = new HashSet<>();
final Set<UUID> denied = new HashSet<>();
for (final PlotRoleDBO plotRole : plotRoles) {
switch (plotRole.plotRole()) {
case TRUSTED -> trusted.add(plotRole.userId());
case HELPER -> members.add(plotRole.userId());
case DENIED -> denied.add(plotRole.userId());
}
}
return new Plot(
plotId,
this.owner(),
Collections.unmodifiableSet(trusted),
Collections.unmodifiableSet(members),
Collections.unmodifiableSet(denied),
plotSettingsDBO.alias(),
BlockLoc.fromString(plotSettingsDBO.position()),
flags,
plotArea,
plotSettingsDBO.unwrapMerged(),
this.timestamp().toEpochMilli(),
id
);
}
}

View File

@@ -1,22 +0,0 @@
package com.plotsquared.core.repository.dbo;
import com.plotsquared.core.player.PlotRole;
import io.soabase.recordbuilder.core.RecordBuilder;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.UUID;
@RecordBuilder
public record PlotRoleDBO(
@NonNull PlotDBO plot,
@NonNull UUID userId,
@NonNull PlotRole plotRole
) {
public @NonNull Key key() {
return new Key(this.plot(), this.userId());
}
public record Key(@NonNull PlotDBO plot, @NonNull UUID userId) {
}
}

View File

@@ -1,29 +0,0 @@
package com.plotsquared.core.repository.dbo;
import io.soabase.recordbuilder.core.RecordBuilder;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@RecordBuilder
public record PlotSettingsDBO(
@NonNull PlotDBO plot,
@Nullable String alias,
Integer merged,
@NonNull String position
) {
/**
* Unwraps {@link #merged()} into an array indicating whether the plot is merged in
* any given cardinal direction. The indices of the array correspond to the ordinals of
* {@link com.plotsquared.core.location.Direction}.
*
* @return unwrapped merged status
*/
public boolean@NonNull [] unwrapMerged() {
final boolean[] merged = new boolean[4];
for (int i = 0; i < 4; i++) {
merged[3 - i] = (this.merged() & 1 << i) != 0;
}
return merged;
}
}

View File

@@ -1,68 +0,0 @@
create table if not exists ${prefix}plot(
id int(11) not null auto_increment,
plot_id_x int(11) not null,
plot_id_z int(11) not null,
world varchar(45) not null,
owner varchar(40) not null,
timestamp timestamp not null default current_timestamp,
primary key (id)
) engine=InnoDB default charset=utf8 auto_increment=0;
-- TODO: Migrating existing data to this table.
create table if not exists ${prefix}plot_role(
plot_id int(11) not null,
user_id varchar(45) not null,
role enum('helper', 'trusted', 'denied') not null,
foreign key (plot_id) references ${prefix}plot(id) on delete cascade,
primary key (plot_id, user_id)
) engine=InnoDB default charset=utf8 auto_increment=0;
create table if not exists ${prefix}plot_comments(
world varchar(45) not null,
comment varchar(45) not null,
inbox varchar(45) not null,
timestamp int(11) not null,
sender varchar(45) not null
) engine=InnoDB default charset=utf8 auto_increment=0;
-- TODO: Look into what to do with this one...
-- Most data is now found in flags.
create table if not exists ${prefix}plot_settings(
plot_plot_id int(11) not null,
biome varchar(45) default 'FOREST', -- Unused. Moved to flags.
rain int(1) default 0, -- Unused. Moved to flags.
custom_time tinyint(1) default 0, -- Unused. Moved to flags.
time int(11) default 8000, -- Unused. Moved to flags.
deny_entry tinyint(1) default 0, -- Unused. Moved to flags.
alias varchar(50) default null,
merged int(11) default null,
position varchar(50) not null default 'default',
foreign key (plot_plot_id) references ${prefix}plot(id) on delete cascade,
primary key (plot_plot_id)
) engine=InnoDB default charset=utf8;
-- TODO: Look into adding foreign keys to this.
create table if not exists ${prefix}plot_rating(
plot_plot_id int(11) not null,
rating int(2) not null,
player varchar(45) not null
) engine=InnoDB default charset=utf8;
-- TODO: Drop the key and make the player ID the key instead.
create table if not exists ${prefix}player_meta(
meta_id int(11) not null auto_increment,
uuid varchar(45) not null,
key varchar(32) not null,
value blob not null,
primary key (meta_id)
) engine=InnoDB default charset=utf8 auto_increment=0;
-- TODO: Drop the ID and make (plot_id, flag) the new primary key.
create table if not exists ${prefix}plot_flags(
id int(11) not null auto_increment primary key,
plot_id int(11) not null,
flag varchar(64),
value varchar(512),
foreign key (plot_id) references ${prefix}plot(id) on delete cascade,
unique (plot_id, flag)
) engine=InnoDB default charset=utf8 auto_increment=0;

View File

@@ -36,7 +36,6 @@ paperlib = "1.0.7"
squirrelid = "0.3.1"
serverlib = "2.3.1"
http4j = "1.3"
record-builder-processor = "33"
# Gradle plugins
shadow = "7.1.2"
@@ -87,7 +86,6 @@ arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitek
http4j = { group = "com.intellectualsites.http", name = "HTTP4J", version.ref = "http4j" }
paster = { group = "com.intellectualsites.paster", name = "Paster", version.ref = "paster" }
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }
recordBuilderProcessor = { group = "io.soabase.record-builder", name = "record-builder-processor", version.ref = "record-builder-processor" }
[plugins]
shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" }