mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-31 09:33:43 +01:00 
			
		
		
		
	Compare commits
	
		
			15 Commits
		
	
	
		
			chore/v7/q
			...
			feature/v6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 70baca7145 | ||
|   | 2a90015037 | ||
|   | f17aa377b7 | ||
|   | e159fa054d | ||
|   | 058c65e34c | ||
|   | 8608604306 | ||
|   | 8d0cc68721 | ||
|   | 2a79c0a419 | ||
|   | 90d42b8b9f | ||
|   | a79c474957 | ||
|   | 4bb480a238 | ||
|   | 9ffa935c0c | ||
|   | 0a32268784 | ||
|   | ae3b8c06f6 | ||
|   | 713c4ad0d2 | 
| @@ -21,20 +21,20 @@ dependencies { | ||||
|     api(projects.plotSquaredCore) | ||||
|  | ||||
|     // Metrics | ||||
|     implementation(libs.bstats) | ||||
|     implementation("org.bstats:bstats-bukkit") | ||||
|  | ||||
|     // Paper | ||||
|     compileOnly(libs.paper) | ||||
|     implementation(libs.paperlib) | ||||
|     implementation("io.papermc:paperlib") | ||||
|  | ||||
|     // Plugins | ||||
|     compileOnly(libs.worldeditBukkit) { | ||||
|         exclude(group = "org.bukkit") | ||||
|         exclude(group = "org.spigotmc") | ||||
|     } | ||||
|     compileOnly(libs.fastasyncworldeditBukkit) { isTransitive = false } | ||||
|     testImplementation(libs.fastasyncworldeditBukkit) { isTransitive = false } | ||||
|     compileOnly(libs.vault) { | ||||
|     compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } | ||||
|     testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } | ||||
|     compileOnly("com.github.MilkBowl:VaultAPI") { | ||||
|         exclude(group = "org.bukkit") | ||||
|     } | ||||
|     compileOnly(libs.placeholderapi) | ||||
| @@ -44,15 +44,15 @@ dependencies { | ||||
|  | ||||
|     // Other libraries | ||||
|     implementation(libs.squirrelid) { isTransitive = false } | ||||
|     implementation(libs.serverlib) | ||||
|     implementation("dev.notmyfault.serverlib:ServerLib") | ||||
|  | ||||
|     // Our libraries | ||||
|     implementation(libs.arkitektonika) | ||||
|     implementation(libs.http4j) | ||||
|     implementation(libs.paster) | ||||
|     implementation("com.intellectualsites.paster:Paster") | ||||
|  | ||||
|     // Adventure | ||||
|     implementation(libs.adventurePlatformBukkit) | ||||
|     implementation("net.kyori:adventure-platform-bukkit") | ||||
| } | ||||
|  | ||||
| tasks.processResources { | ||||
| @@ -97,7 +97,7 @@ tasks.named<ShadowJar>("shadowJar") { | ||||
| tasks { | ||||
|     withType<Javadoc> { | ||||
|         val opt = options as StandardJavadocDocletOptions | ||||
|         opt.links("https://papermc.io/javadocs/paper/1.18/") | ||||
|         opt.links("https://jd.papermc.io/paper/1.18/") | ||||
|         opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString()) | ||||
|         opt.links("https://javadoc.io/doc/com.plotsquared/PlotSquared-Core/latest/") | ||||
|         opt.links("https://jd.adventure.kyori.net/api/" + libs.adventure.get().versionConstraint.toString()) | ||||
|   | ||||
| @@ -25,17 +25,18 @@ | ||||
|  */ | ||||
| package com.plotsquared.bukkit.generator; | ||||
|  | ||||
| import com.plotsquared.core.PlotSquared; | ||||
| import com.plotsquared.bukkit.queue.LimitedRegionWrapperQueue; | ||||
| import com.plotsquared.core.generator.HybridPlotWorld; | ||||
| import com.plotsquared.core.generator.IndependentPlotGenerator; | ||||
| import com.plotsquared.core.location.ChunkWrapper; | ||||
| import com.plotsquared.core.location.Location; | ||||
| import com.plotsquared.core.location.UncheckedWorldLocation; | ||||
| import com.plotsquared.core.plot.PlotArea; | ||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | ||||
| import com.plotsquared.core.queue.QueueCoordinator; | ||||
| import com.plotsquared.core.plot.world.SinglePlotArea; | ||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||
| import com.sk89q.worldedit.bukkit.BukkitWorld; | ||||
| import org.bukkit.Chunk; | ||||
| import org.bukkit.World; | ||||
| import org.bukkit.generator.BlockPopulator; | ||||
| import org.bukkit.generator.LimitedRegion; | ||||
| import org.bukkit.generator.WorldInfo; | ||||
| import org.checkerframework.checker.nullness.qual.NonNull; | ||||
|  | ||||
| import java.util.Random; | ||||
| @@ -43,35 +44,51 @@ import java.util.Random; | ||||
| final class BlockStatePopulator extends BlockPopulator { | ||||
|  | ||||
|     private final IndependentPlotGenerator plotGenerator; | ||||
|     private final PlotAreaManager plotAreaManager; | ||||
|  | ||||
|     private QueueCoordinator queue; | ||||
|     /** | ||||
|      * @since TODO | ||||
|      */ | ||||
|     public BlockStatePopulator( | ||||
|             final @NonNull IndependentPlotGenerator plotGenerator | ||||
|     ) { | ||||
|         this.plotGenerator = plotGenerator; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @deprecated Use {@link BlockStatePopulator#BlockStatePopulator(IndependentPlotGenerator)} as plotAreManager is unused | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public BlockStatePopulator( | ||||
|             final @NonNull IndependentPlotGenerator plotGenerator, | ||||
|             final @NonNull PlotAreaManager plotAreaManager | ||||
|     ) { | ||||
|         this.plotGenerator = plotGenerator; | ||||
|         this.plotAreaManager = plotAreaManager; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void populate(final @NonNull World world, final @NonNull Random random, final @NonNull Chunk source) { | ||||
|         if (this.queue == null) { | ||||
|             this.queue = PlotSquared.platform().globalBlockQueue().getNewQueue(new BukkitWorld(world)); | ||||
|         } | ||||
|         final PlotArea area = this.plotAreaManager.getPlotArea(world.getName(), null); | ||||
|         if (area == null) { | ||||
|     public void populate( | ||||
|             @NonNull final WorldInfo worldInfo, | ||||
|             @NonNull final Random random, | ||||
|             final int chunkX, | ||||
|             final int chunkZ, | ||||
|             @NonNull final LimitedRegion limitedRegion | ||||
|     ) { | ||||
|         PlotArea area = UncheckedWorldLocation.at(worldInfo.getName(), chunkX << 4, 0, chunkZ << 4).getPlotArea(); | ||||
|         if (area == null || (area instanceof HybridPlotWorld hpw && !hpw.populationNeeded()) || area instanceof SinglePlotArea) { | ||||
|             return; | ||||
|         } | ||||
|         final ChunkWrapper wrap = new ChunkWrapper(area.getWorldName(), source.getX(), source.getZ()); | ||||
|         final ScopedQueueCoordinator chunk = this.queue.getForChunk(wrap.x, wrap.z, | ||||
|                 com.plotsquared.bukkit.util.BukkitWorld.getMinWorldHeight(world), | ||||
|                 com.plotsquared.bukkit.util.BukkitWorld.getMaxWorldHeight(world) - 1 | ||||
|         LimitedRegionWrapperQueue wrapped = new LimitedRegionWrapperQueue(limitedRegion); | ||||
|         // It is possible for the region to be larger than the chunk, but there is no reason for P2 to need to populate | ||||
|         // outside of the actual chunk area. | ||||
|         Location min = UncheckedWorldLocation.at(worldInfo.getName(), chunkX << 4, worldInfo.getMinHeight(), chunkZ << 4); | ||||
|         Location max = UncheckedWorldLocation.at( | ||||
|                 worldInfo.getName(), | ||||
|                 (chunkX << 4) + 15, | ||||
|                 worldInfo.getMaxHeight(), | ||||
|                 (chunkZ << 4) + 15 | ||||
|         ); | ||||
|         if (this.plotGenerator.populateChunk(chunk, area)) { | ||||
|             this.queue.enqueue(); | ||||
|         } | ||||
|         ScopedQueueCoordinator offsetChunkQueue = new ScopedQueueCoordinator(wrapped, min, max); | ||||
|         this.plotGenerator.populateChunk(offsetChunkQueue, area); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -49,8 +49,7 @@ import java.util.List; | ||||
| import java.util.Random; | ||||
| import java.util.Set; | ||||
|  | ||||
| public class BukkitPlotGenerator extends ChunkGenerator | ||||
|         implements GeneratorWrapper<ChunkGenerator> { | ||||
| public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> { | ||||
|  | ||||
|     @SuppressWarnings("unused") | ||||
|     public final boolean PAPER_ASYNC_SAFE = true; | ||||
| @@ -73,7 +72,12 @@ public class BukkitPlotGenerator extends ChunkGenerator | ||||
|         this.plotGenerator = generator; | ||||
|         this.platformGenerator = this; | ||||
|         this.populators = new ArrayList<>(); | ||||
|         this.populators.add(new BlockStatePopulator(this.plotGenerator, this.plotAreaManager)); | ||||
|         int minecraftMinorVersion = PlotSquared.platform().serverVersion()[1]; | ||||
|         if (minecraftMinorVersion >= 17) { | ||||
|             this.populators.add(new BlockStatePopulator(this.plotGenerator)); | ||||
|         } else { | ||||
|             this.populators.add(new LegacyBlockStatePopulator(this.plotGenerator)); | ||||
|         } | ||||
|         this.full = true; | ||||
|     } | ||||
|  | ||||
| @@ -159,7 +163,6 @@ public class BukkitPlotGenerator extends ChunkGenerator | ||||
|             @NonNull World world, @NonNull Random random, int x, int z, | ||||
|             @NonNull BiomeGrid biome | ||||
|     ) { | ||||
|  | ||||
|         int minY = BukkitWorld.getMinWorldHeight(world); | ||||
|         int maxY = BukkitWorld.getMaxWorldHeight(world); | ||||
|         GenChunk result = new GenChunk(minY, maxY); | ||||
|   | ||||
| @@ -0,0 +1,81 @@ | ||||
| /* | ||||
|  *       _____  _       _    _____                                _ | ||||
|  *      |  __ \| |     | |  / ____|                              | | | ||||
|  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||
|  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||
|  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||
|  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||
|  *                                    | | | ||||
|  *                                    |_| | ||||
|  *            PlotSquared plot management system for Minecraft | ||||
|  *               Copyright (C) 2014 - 2022 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.generator; | ||||
|  | ||||
| import com.plotsquared.core.PlotSquared; | ||||
| import com.plotsquared.core.generator.HybridPlotWorld; | ||||
| import com.plotsquared.core.generator.IndependentPlotGenerator; | ||||
| import com.plotsquared.core.location.Location; | ||||
| import com.plotsquared.core.location.UncheckedWorldLocation; | ||||
| import com.plotsquared.core.plot.PlotArea; | ||||
| import com.plotsquared.core.plot.world.SinglePlotArea; | ||||
| import com.plotsquared.core.queue.QueueCoordinator; | ||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||
| import com.sk89q.worldedit.bukkit.BukkitWorld; | ||||
| import com.sk89q.worldedit.util.SideEffectSet; | ||||
| import org.bukkit.Chunk; | ||||
| import org.bukkit.World; | ||||
| import org.bukkit.generator.BlockPopulator; | ||||
| import org.checkerframework.checker.nullness.qual.NonNull; | ||||
| import org.jetbrains.annotations.NotNull; | ||||
|  | ||||
| import java.util.Random; | ||||
|  | ||||
| final class LegacyBlockStatePopulator extends BlockPopulator { | ||||
|  | ||||
|     private final IndependentPlotGenerator plotGenerator; | ||||
|  | ||||
|     /** | ||||
|      * @since TODO | ||||
|      */ | ||||
|     public LegacyBlockStatePopulator( | ||||
|             final @NonNull IndependentPlotGenerator plotGenerator | ||||
|     ) { | ||||
|         this.plotGenerator = plotGenerator; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void populate(@NotNull final World world, @NotNull final Random random, @NotNull final Chunk source) { | ||||
|         int chunkMinX = source.getX() << 4; | ||||
|         int chunkMinZ = source.getZ() << 4; | ||||
|         PlotArea area = Location.at(world.getName(), chunkMinX, 0, chunkMinZ).getPlotArea(); | ||||
|         if (area == null || (area instanceof HybridPlotWorld hpw && !hpw.populationNeeded()) || area instanceof SinglePlotArea) { | ||||
|             return; | ||||
|         } | ||||
|  | ||||
|         QueueCoordinator queue = PlotSquared.platform().globalBlockQueue().getNewQueue(new BukkitWorld(world)); | ||||
|         queue.setForceSync(true); | ||||
|         queue.setSideEffectSet(SideEffectSet.none()); | ||||
|         queue.setBiomesEnabled(false); | ||||
|         queue.setChunkObject(source); | ||||
|         Location min = UncheckedWorldLocation.at(world.getName(), chunkMinX, world.getMinHeight(), chunkMinZ); | ||||
|         Location max = UncheckedWorldLocation.at(world.getName(), chunkMinX + 15, world.getMaxHeight(), chunkMinZ + 15); | ||||
|         ScopedQueueCoordinator offsetChunkQueue = new ScopedQueueCoordinator(queue, min, max); | ||||
|         this.plotGenerator.populateChunk(offsetChunkQueue, area); | ||||
|         queue.enqueue(); | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -551,6 +551,10 @@ public class BlockEventListener implements Listener { | ||||
|         if (plot == null) { | ||||
|             return; | ||||
|         } | ||||
|         if (location.getY() >= area.getMaxBuildHeight() || location.getY() < area.getMinBuildHeight()) { | ||||
|             event.setCancelled(true); | ||||
|             return; | ||||
|         } | ||||
|         switch (event.getNewState().getType()) { | ||||
|             case SNOW: | ||||
|             case SNOW_BLOCK: | ||||
| @@ -750,62 +754,66 @@ public class BlockEventListener implements Listener { | ||||
|  | ||||
|     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) | ||||
|     public void onChange(BlockFromToEvent event) { | ||||
|         Block from = event.getBlock(); | ||||
|         Block fromBlock = event.getBlock(); | ||||
|  | ||||
|         // Check liquid flow flag inside of origin plot too | ||||
|         final Location fLocation = BukkitUtil.adapt(from.getLocation()); | ||||
|         final PlotArea fromArea = fLocation.getPlotArea(); | ||||
|         final Location fromLocation = BukkitUtil.adapt(fromBlock.getLocation()); | ||||
|         final PlotArea fromArea = fromLocation.getPlotArea(); | ||||
|         if (fromArea != null) { | ||||
|             final Plot plot = fromArea.getOwnedPlot(fLocation); | ||||
|             if (plot != null && plot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.DISABLED && event | ||||
|             final Plot fromPlot = fromArea.getOwnedPlot(fromLocation); | ||||
|             if (fromPlot != null && fromPlot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.DISABLED && event | ||||
|                     .getBlock() | ||||
|                     .isLiquid()) { | ||||
|                 plot.debug("Liquid could not flow because liquid-flow = disabled"); | ||||
|                 fromPlot.debug("Liquid could not flow because liquid-flow = disabled"); | ||||
|                 event.setCancelled(true); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Block to = event.getToBlock(); | ||||
|         Location tLocation = BukkitUtil.adapt(to.getLocation()); | ||||
|         PlotArea area = tLocation.getPlotArea(); | ||||
|         if (area == null) { | ||||
|             if (from.getType() == Material.DRAGON_EGG && fromArea != null) { | ||||
|         Block toBlock = event.getToBlock(); | ||||
|         Location toLocation = BukkitUtil.adapt(toBlock.getLocation()); | ||||
|         PlotArea toArea = toLocation.getPlotArea(); | ||||
|         if (toArea == null) { | ||||
|             if (fromBlock.getType() == Material.DRAGON_EGG && fromArea != null) { | ||||
|                 event.setCancelled(true); | ||||
|             } | ||||
|             return; | ||||
|         } | ||||
|         Plot plot = area.getOwnedPlot(tLocation); | ||||
|         if (toLocation.getY() >= toArea.getMaxBuildHeight() || toLocation.getY() < toArea.getMinBuildHeight()) { | ||||
|             event.setCancelled(true); | ||||
|             return; | ||||
|         } | ||||
|         Plot toPlot = toArea.getOwnedPlot(toLocation); | ||||
|  | ||||
|         if (from.getType() == Material.DRAGON_EGG && fromArea != null) { | ||||
|             final Plot fromPlot = fromArea.getOwnedPlot(fLocation); | ||||
|         if (fromBlock.getType() == Material.DRAGON_EGG && fromArea != null) { | ||||
|             final Plot fromPlot = fromArea.getOwnedPlot(fromLocation); | ||||
|  | ||||
|             if (fromPlot != null || plot != null) { | ||||
|                 if ((fromPlot == null || !fromPlot.equals(plot)) && (plot == null || !plot.equals(fromPlot))) { | ||||
|             if (fromPlot != null || toPlot != null) { | ||||
|                 if ((fromPlot == null || !fromPlot.equals(toPlot)) && (toPlot == null || !toPlot.equals(fromPlot))) { | ||||
|                     event.setCancelled(true); | ||||
|                     return; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if (plot != null) { | ||||
|             if (!area.contains(fLocation.getX(), fLocation.getZ()) || !Objects.equals(plot, area.getOwnedPlot(fLocation))) { | ||||
|         if (toPlot != null) { | ||||
|             if (!toArea.contains(fromLocation.getX(), fromLocation.getZ()) || !Objects.equals(toPlot, toArea.getOwnedPlot(fromLocation))) { | ||||
|                 event.setCancelled(true); | ||||
|                 return; | ||||
|             } | ||||
|             if (plot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.ENABLED && event.getBlock().isLiquid()) { | ||||
|             if (toPlot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.ENABLED && event.getBlock().isLiquid()) { | ||||
|                 return; | ||||
|             } | ||||
|             if (plot.getFlag(DisablePhysicsFlag.class)) { | ||||
|                 plot.debug(event.getBlock().getType() + " could not update because disable-physics = true"); | ||||
|             if (toPlot.getFlag(DisablePhysicsFlag.class)) { | ||||
|                 toPlot.debug(event.getBlock().getType() + " could not update because disable-physics = true"); | ||||
|                 event.setCancelled(true); | ||||
|                 return; | ||||
|             } | ||||
|             if (plot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.DISABLED && event.getBlock().isLiquid()) { | ||||
|                 plot.debug("Liquid could not flow because liquid-flow = disabled"); | ||||
|             if (toPlot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.DISABLED && event.getBlock().isLiquid()) { | ||||
|                 toPlot.debug("Liquid could not flow because liquid-flow = disabled"); | ||||
|                 event.setCancelled(true); | ||||
|             } | ||||
|         } else if (!area.contains(fLocation.getX(), fLocation.getZ()) || !Objects.equals(null, area.getOwnedPlot(fLocation))) { | ||||
|         } else if (!toArea.contains(fromLocation.getX(), fromLocation.getZ()) || !Objects.equals(null, toArea.getOwnedPlot(fromLocation))) { | ||||
|             event.setCancelled(true); | ||||
|         } else if (event.getBlock().isLiquid()) { | ||||
|             final org.bukkit.Location location = event.getBlock().getLocation(); | ||||
|   | ||||
| @@ -0,0 +1,128 @@ | ||||
| /* | ||||
|  *       _____  _       _    _____                                _ | ||||
|  *      |  __ \| |     | |  / ____|                              | | | ||||
|  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||
|  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||
|  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||
|  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||
|  *                                    | | | ||||
|  *                                    |_| | ||||
|  *            PlotSquared plot management system for Minecraft | ||||
|  *               Copyright (C) 2014 - 2022 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.plotsquared.bukkit.schematic.StateWrapper; | ||||
| import com.plotsquared.core.queue.DelegateQueueCoordinator; | ||||
| import com.sk89q.jnbt.CompoundTag; | ||||
| import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||
| import com.sk89q.worldedit.entity.Entity; | ||||
| import com.sk89q.worldedit.function.pattern.Pattern; | ||||
| import com.sk89q.worldedit.math.BlockVector3; | ||||
| import com.sk89q.worldedit.world.block.BaseBlock; | ||||
| import com.sk89q.worldedit.world.block.BlockState; | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.bukkit.Location; | ||||
| import org.bukkit.entity.EntityType; | ||||
| import org.bukkit.generator.LimitedRegion; | ||||
| import org.checkerframework.checker.nullness.qual.NonNull; | ||||
|  | ||||
| /** | ||||
|  * Wraps a {@link LimitedRegion} inside a {@link com.plotsquared.core.queue.QueueCoordinator} so it can be written to. | ||||
|  * | ||||
|  * @since TODO | ||||
|  */ | ||||
| public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator { | ||||
|  | ||||
|     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + LimitedRegionWrapperQueue.class.getSimpleName()); | ||||
|  | ||||
|     private final LimitedRegion limitedRegion; | ||||
|  | ||||
|     /** | ||||
|      * @since TODO | ||||
|      */ | ||||
|     public LimitedRegionWrapperQueue(LimitedRegion limitedRegion) { | ||||
|         super(null); | ||||
|         this.limitedRegion = limitedRegion; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean setBlock(final int x, final int y, final int z, @NonNull final Pattern pattern) { | ||||
|         return setBlock(x, y, z, pattern.applyBlock(BlockVector3.at(x, y, z))); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean setBlock(final int x, final int y, final int z, @NonNull final BaseBlock id) { | ||||
|         boolean result = setBlock(x, y, z, id.toImmutableState()); | ||||
|         if (result && id.hasNbtData()) { | ||||
|             CompoundTag tag = id.getNbtData(); | ||||
|             StateWrapper sw = new StateWrapper(tag); | ||||
|             try { | ||||
|                 sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); | ||||
|             } catch (IllegalArgumentException e) { | ||||
|                 LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         return result; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean setBlock(final int x, final int y, final int z, @NonNull final BlockState id) { | ||||
|         try { | ||||
|             limitedRegion.setType(x, y, z, BukkitAdapter.adapt(id.getBlockType())); | ||||
|             limitedRegion.setBlockData(x, y, z, BukkitAdapter.adapt(id)); | ||||
|         } catch (IllegalArgumentException e) { | ||||
|             LOGGER.error("Error attempting to populate block into the world at location {},{},{}", x, y, z, e); | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean setEntity(@NonNull final Entity entity) { | ||||
|         EntityType type = BukkitAdapter.adapt(entity.getState().getType()); | ||||
|         double x = entity.getLocation().getX(); | ||||
|         double y = entity.getLocation().getY(); | ||||
|         double z = entity.getLocation().getZ(); | ||||
|         Location location = new Location(limitedRegion.getWorld(), x, y, z); | ||||
|         try { | ||||
|             limitedRegion.spawnEntity(location, type); | ||||
|         } catch (IllegalArgumentException e) { | ||||
|             LOGGER.error("Error attempting to populate entity into the world at location {},{},{}", (int) x, (int) y, (int) z, e); | ||||
|             return false; | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean setTile(final int x, final int y, final int z, @NonNull final CompoundTag tag) { | ||||
|         StateWrapper sw = new StateWrapper(tag); | ||||
|         try { | ||||
|             return sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); | ||||
|         } catch (IllegalArgumentException e) { | ||||
|             LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); | ||||
|             return false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean isSettingTiles() { | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -35,11 +35,13 @@ import com.sk89q.jnbt.Tag; | ||||
| import com.sk89q.worldedit.blocks.BaseItemStack; | ||||
| import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||
| import com.sk89q.worldedit.world.item.ItemType; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.ChatColor; | ||||
| import org.bukkit.World; | ||||
| import org.bukkit.block.Block; | ||||
| import org.bukkit.block.Container; | ||||
| import org.bukkit.block.Sign; | ||||
| import org.bukkit.block.Skull; | ||||
| import org.bukkit.enchantments.Enchantment; | ||||
| import org.bukkit.inventory.Inventory; | ||||
| import org.bukkit.inventory.InventoryHolder; | ||||
| @@ -57,6 +59,11 @@ public class StateWrapper { | ||||
|     public org.bukkit.block.BlockState state = null; | ||||
|     public CompoundTag tag = null; | ||||
|  | ||||
|     /** | ||||
|      * @deprecated in favour of using WE methods for obtaining NBT, specifically by obtaining a | ||||
|      *         {@link com.sk89q.worldedit.world.block.BaseBlock} and then using {@link com.sk89q.worldedit.world.block.BaseBlock#getNbtData()} | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public StateWrapper(org.bukkit.block.BlockState state) { | ||||
|         this.state = state; | ||||
|     } | ||||
| @@ -230,10 +237,37 @@ public class StateWrapper { | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|             case "skull" -> { | ||||
|                 if (state instanceof Skull skull) { | ||||
|                     CompoundTag skullOwner = ((CompoundTag) this.tag.getValue().get("SkullOwner")); | ||||
|                     if (skullOwner == null) { | ||||
|                         return true; | ||||
|                     } | ||||
|                     String player = skullOwner.getString("Name"); | ||||
|                     if (player == null || player.isEmpty()) { | ||||
|                         return false; | ||||
|                     } | ||||
|                     try { | ||||
|                         skull.setOwningPlayer(Bukkit.getOfflinePlayer(player)); | ||||
|                         skull.update(true); | ||||
|                     } catch (Exception e) { | ||||
|                         e.printStackTrace(); | ||||
|                     } | ||||
|                     return true; | ||||
|                 } | ||||
|                 return false; | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get a CompoundTag of the contents of a block's inventory (chest, furnace, etc.). | ||||
|      * | ||||
|      * @deprecated in favour of using WorldEdit methods for obtaining NBT, specifically by obtaining a | ||||
|      *         {@link com.sk89q.worldedit.world.block.BaseBlock} and then using {@link com.sk89q.worldedit.world.block.BaseBlock#getNbtData()} | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public CompoundTag getTag() { | ||||
|         if (this.tag != null) { | ||||
|             return this.tag; | ||||
|   | ||||
| @@ -55,7 +55,7 @@ further defined and clarified by project maintainers. | ||||
| ## Enforcement | ||||
|  | ||||
| Instances of abusive, harassing, or otherwise unacceptable behavior may be | ||||
| reported by contacting the project team at contact@alexander-soderberg.com. All | ||||
| reported by contacting the project team at contact@intellectualsites.com. All | ||||
| complaints will be reviewed and investigated and will result in a response that | ||||
| is deemed necessary and appropriate to the circumstances. The project team is | ||||
| obligated to maintain confidentiality with regard to the reporter of an incident. | ||||
|   | ||||
| @@ -2,18 +2,18 @@ import java.time.format.DateTimeFormatter | ||||
|  | ||||
| dependencies { | ||||
|     // Expected everywhere. | ||||
|     compileOnlyApi(libs.checkerqual) | ||||
|     compileOnlyApi("org.checkerframework:checker-qual") | ||||
|  | ||||
|     // Minecraft expectations | ||||
|     compileOnlyApi(libs.gson) | ||||
|     compileOnly(libs.guava) | ||||
|     compileOnlyApi("com.google.code.gson:gson") | ||||
|     compileOnly("com.google.guava:guava") | ||||
|  | ||||
|     // Platform expectations | ||||
|     compileOnlyApi(libs.snakeyaml) | ||||
|     compileOnlyApi("org.yaml:snakeyaml") | ||||
|  | ||||
|     // Adventure | ||||
|     api(libs.adventure) | ||||
|     api(libs.minimessage) | ||||
|     api("net.kyori:adventure-api") | ||||
|     api("net.kyori:adventure-text-minimessage") | ||||
|  | ||||
|     // Guice | ||||
|     api(libs.guice) { | ||||
| @@ -31,18 +31,18 @@ dependencies { | ||||
|         exclude(group = "dummypermscompat") | ||||
|     } | ||||
|     testImplementation(libs.worldeditCore) | ||||
|     compileOnly(libs.fastasyncworldeditCore) { isTransitive = false } | ||||
|     testImplementation(libs.fastasyncworldeditCore) { isTransitive = false } | ||||
|     compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core") { isTransitive = false } | ||||
|     testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Core") { isTransitive = false } | ||||
|  | ||||
|     // Logging | ||||
|     compileOnlyApi(libs.log4j) | ||||
|     compileOnlyApi("org.apache.logging.log4j:log4j-api") | ||||
|  | ||||
|     // Other libraries | ||||
|     api(libs.prtree) | ||||
|     api(libs.aopalliance) | ||||
|     api(libs.cloudServices) | ||||
|     api(libs.arkitektonika) | ||||
|     api(libs.paster) | ||||
|     api("com.intellectualsites.paster:Paster") | ||||
| } | ||||
|  | ||||
| tasks.processResources { | ||||
|   | ||||
| @@ -35,13 +35,23 @@ import com.plotsquared.core.plot.PlotArea; | ||||
| import com.plotsquared.core.plot.PlotId; | ||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||
| import com.plotsquared.core.util.MathMan; | ||||
| import com.sk89q.worldedit.entity.BaseEntity; | ||||
| import com.sk89q.worldedit.entity.Entity; | ||||
| import com.sk89q.worldedit.extent.Extent; | ||||
| import com.sk89q.worldedit.math.BlockVector3; | ||||
| import com.sk89q.worldedit.math.Vector3; | ||||
| import com.sk89q.worldedit.regions.CuboidRegion; | ||||
| import com.sk89q.worldedit.regions.RegionOperationException; | ||||
| import com.sk89q.worldedit.world.NullWorld; | ||||
| import com.sk89q.worldedit.world.biome.BiomeType; | ||||
| import com.sk89q.worldedit.world.block.BaseBlock; | ||||
| import com.sk89q.worldedit.world.block.BlockTypes; | ||||
| import org.checkerframework.checker.nullness.qual.NonNull; | ||||
| import org.checkerframework.checker.nullness.qual.Nullable; | ||||
|  | ||||
| public class HybridGen extends IndependentPlotGenerator { | ||||
|  | ||||
|     private static final CuboidRegion CHUNK = new CuboidRegion(BlockVector3.ZERO, BlockVector3.at(15, 396, 15)); | ||||
|     private final HybridPlotWorldFactory hybridPlotWorldFactory; | ||||
|  | ||||
|     @Inject | ||||
| @@ -55,12 +65,17 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|     } | ||||
|  | ||||
|     private void placeSchem( | ||||
|             HybridPlotWorld world, ScopedQueueCoordinator result, short relativeX, | ||||
|             short relativeZ, int x, int z, boolean isRoad | ||||
|             HybridPlotWorld world, | ||||
|             ScopedQueueCoordinator result, | ||||
|             short relativeX, | ||||
|             short relativeZ, | ||||
|             int x, | ||||
|             int z, | ||||
|             boolean isRoad, | ||||
|             boolean isPopulating | ||||
|     ) { | ||||
|         int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); | ||||
|         if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad | ||||
|                 && Settings.Schematics.PASTE_ON_TOP)) { | ||||
|         if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad && Settings.Schematics.PASTE_ON_TOP)) { | ||||
|             minY = world.SCHEM_Y; | ||||
|         } else { | ||||
|             minY = world.getMinBuildHeight(); | ||||
| @@ -69,10 +84,12 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|         if (blocks != null) { | ||||
|             for (int y = 0; y < blocks.length; y++) { | ||||
|                 if (blocks[y] != null) { | ||||
|                     if (!isPopulating || blocks[y].hasNbtData()) { | ||||
|                         result.setBlock(x, minY + y, z, blocks[y]); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         BiomeType biome = world.G_SCH_B.get(MathMan.pair(relativeX, relativeZ)); | ||||
|         if (biome != null) { | ||||
|             result.setBiome(x, z, biome); | ||||
| @@ -121,42 +138,38 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|         short[] relativeX = new short[16]; | ||||
|         boolean[] insideRoadX = new boolean[16]; | ||||
|         boolean[] insideWallX = new boolean[16]; | ||||
|         short offsetX = relativeOffsetX; | ||||
|         for (short i = 0; i < 16; i++) { | ||||
|             short v = (short) (relativeOffsetX + i); | ||||
|             while (v >= hybridPlotWorld.SIZE) { | ||||
|                 v -= hybridPlotWorld.SIZE; | ||||
|             if (offsetX >= hybridPlotWorld.SIZE) { | ||||
|                 offsetX -= hybridPlotWorld.SIZE; | ||||
|             } | ||||
|             relativeX[i] = v; | ||||
|             relativeX[i] = offsetX; | ||||
|             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||
|                 insideRoadX[i] = | ||||
|                         v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 insideWallX[i] = | ||||
|                         v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 insideRoadX[i] = offsetX < hybridPlotWorld.PATH_WIDTH_LOWER || offsetX > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 insideWallX[i] = offsetX == hybridPlotWorld.PATH_WIDTH_LOWER || offsetX == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|             } | ||||
|             offsetX++; | ||||
|         } | ||||
|         // The Z-coordinate of a given Z coordinate, relative to the | ||||
|         // plot (Counting from the corner with the least positive | ||||
|         // coordinates) | ||||
|         short[] relativeZ = new short[16]; | ||||
|         // Whether or not the given Z coordinate belongs to the road | ||||
|         boolean[] insideRoadZ = new boolean[16]; | ||||
|         // Whether or not the given Z coordinate belongs to the wall | ||||
|         boolean[] insideWallZ = new boolean[16]; | ||||
|         short offsetZ = relativeOffsetZ; | ||||
|         for (short i = 0; i < 16; i++) { | ||||
|             short v = (short) (relativeOffsetZ + i); | ||||
|             while (v >= hybridPlotWorld.SIZE) { | ||||
|                 v -= hybridPlotWorld.SIZE; | ||||
|             if (offsetZ >= hybridPlotWorld.SIZE) { | ||||
|                 offsetZ -= hybridPlotWorld.SIZE; | ||||
|             } | ||||
|             relativeZ[i] = v; | ||||
|             relativeZ[i] = offsetZ; | ||||
|             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||
|                 insideRoadZ[i] = | ||||
|                         v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 insideWallZ[i] = | ||||
|                         v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 insideRoadZ[i] = offsetZ < hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 insideWallZ[i] = offsetZ == hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|             } | ||||
|             offsetZ++; | ||||
|         } | ||||
|         // generation | ||||
|         int startY = hybridPlotWorld.getMinGenHeight() + (hybridPlotWorld.PLOT_BEDROCK ? 1: 0); | ||||
|         int startY = hybridPlotWorld.getMinGenHeight() + (hybridPlotWorld.PLOT_BEDROCK ? 1 : 0); | ||||
|         for (short x = 0; x < 16; x++) { | ||||
|             if (insideRoadX[x]) { | ||||
|                 for (short z = 0; z < 16; z++) { | ||||
| @@ -165,7 +178,7 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|                         result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||
|                     } | ||||
|                     if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true); | ||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||
|                     } | ||||
|                 } | ||||
|             } else if (insideWallX[x]) { | ||||
| @@ -176,9 +189,7 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||
|                         } | ||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, | ||||
|                                     true | ||||
|                             ); | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||
|                         } | ||||
|                     } else { | ||||
|                         // wall | ||||
| @@ -187,14 +198,10 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|                         } | ||||
|                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||
|                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { | ||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, | ||||
|                                         hybridPlotWorld.WALL_BLOCK.toPattern() | ||||
|                                 ); | ||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); | ||||
|                             } | ||||
|                         } else { | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, | ||||
|                                     true | ||||
|                             ); | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @@ -206,9 +213,7 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||
|                         } | ||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, | ||||
|                                     true | ||||
|                             ); | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||
|                         } | ||||
|                     } else if (insideWallZ[z]) { | ||||
|                         // wall | ||||
| @@ -217,27 +222,19 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|                         } | ||||
|                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||
|                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { | ||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, | ||||
|                                         hybridPlotWorld.WALL_BLOCK.toPattern() | ||||
|                                 ); | ||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); | ||||
|                             } | ||||
|                         } else { | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, | ||||
|                                     true | ||||
|                             ); | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||
|                         } | ||||
|                     } else { | ||||
|                         // plot | ||||
|                         for (int y = startY; y < hybridPlotWorld.PLOT_HEIGHT; y++) { | ||||
|                             result.setBlock(x, y, z, hybridPlotWorld.MAIN_BLOCK.toPattern()); | ||||
|                         } | ||||
|                         result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, | ||||
|                                 hybridPlotWorld.TOP_BLOCK.toPattern() | ||||
|                         ); | ||||
|                         result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, hybridPlotWorld.TOP_BLOCK.toPattern()); | ||||
|                         if (hybridPlotWorld.PLOT_SCHEMATIC) { | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, | ||||
|                                     false | ||||
|                             ); | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, false); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
| @@ -245,6 +242,138 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public boolean populateChunk(final ScopedQueueCoordinator result, final PlotArea settings) { | ||||
|         HybridPlotWorld hybridPlotWorld = (HybridPlotWorld) settings; | ||||
|         if (!hybridPlotWorld.populationNeeded()) { | ||||
|             return false; | ||||
|         } | ||||
|         // Coords | ||||
|         Location min = result.getMin(); | ||||
|         int bx = min.getX() - hybridPlotWorld.ROAD_OFFSET_X; | ||||
|         int bz = min.getZ() - hybridPlotWorld.ROAD_OFFSET_Z; | ||||
|         // The relative X-coordinate (within the plot) of the minimum X coordinate | ||||
|         // contained in the scoped queue | ||||
|         short relativeOffsetX; | ||||
|         if (bx < 0) { | ||||
|             relativeOffsetX = (short) (hybridPlotWorld.SIZE + (bx % hybridPlotWorld.SIZE)); | ||||
|         } else { | ||||
|             relativeOffsetX = (short) (bx % hybridPlotWorld.SIZE); | ||||
|         } | ||||
|         // The relative Z-coordinate (within the plot) of the minimum Z coordinate | ||||
|         // contained in the scoped queue | ||||
|         short relativeOffsetZ; | ||||
|         if (bz < 0) { | ||||
|             relativeOffsetZ = (short) (hybridPlotWorld.SIZE + (bz % hybridPlotWorld.SIZE)); | ||||
|         } else { | ||||
|             relativeOffsetZ = (short) (bz % hybridPlotWorld.SIZE); | ||||
|         } | ||||
|         boolean allRoad = true; | ||||
|         boolean overlap = false; | ||||
|  | ||||
|         // The X-coordinate of a given X coordinate, relative to the | ||||
|         // plot (Counting from the corner with the least positive | ||||
|         // coordinates) | ||||
|         short[] relativeX = new short[16]; | ||||
|         boolean[] insideRoadX = new boolean[16]; | ||||
|         boolean[] insideWallX = new boolean[16]; | ||||
|         short offsetX = relativeOffsetX; | ||||
|         for (short i = 0; i < 16; i++) { | ||||
|             if (offsetX >= hybridPlotWorld.SIZE) { | ||||
|                 offsetX -= hybridPlotWorld.SIZE; | ||||
|                 overlap = true; | ||||
|             } | ||||
|             relativeX[i] = offsetX; | ||||
|             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||
|                 boolean insideRoad = offsetX < hybridPlotWorld.PATH_WIDTH_LOWER || offsetX > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 boolean insideWall = offsetX == hybridPlotWorld.PATH_WIDTH_LOWER || offsetX == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 insideRoadX[i] = insideRoad; | ||||
|                 insideWallX[i] = insideWall; | ||||
|                 allRoad &= insideRoad && insideWall; | ||||
|             } | ||||
|             offsetX++; | ||||
|         } | ||||
|  | ||||
|         // The Z-coordinate of a given Z coordinate, relative to the | ||||
|         // plot (Counting from the corner with the least positive | ||||
|         // coordinates) | ||||
|         short[] relativeZ = new short[16]; | ||||
|         boolean[] insideRoadZ = new boolean[16]; | ||||
|         boolean[] insideWallZ = new boolean[16]; | ||||
|         short offsetZ = relativeOffsetZ; | ||||
|         for (short i = 0; i < 16; i++) { | ||||
|             if (offsetZ >= hybridPlotWorld.SIZE) { | ||||
|                 offsetZ -= hybridPlotWorld.SIZE; | ||||
|                 overlap = true; | ||||
|             } | ||||
|             relativeZ[i] = offsetZ; | ||||
|             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||
|                 boolean insideRoad = offsetZ < hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 boolean insideWall = offsetZ == hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||
|                 insideRoadZ[i] = insideRoad; | ||||
|                 insideWallZ[i] = insideWall; | ||||
|                 allRoad &= insideRoad && insideWall; | ||||
|             } | ||||
|             offsetZ++; | ||||
|         } | ||||
|         for (short x = 0; x < 16; x++) { | ||||
|             if (insideRoadX[x] || insideWallX[x]) { | ||||
|                 if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||
|                     for (short z = 0; z < 16; z++) { | ||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, true); | ||||
|                     } | ||||
|                 } | ||||
|             } else { | ||||
|                 for (short z = 0; z < 16; z++) { | ||||
|                     if (insideRoadZ[z] || insideWallZ[z]) { | ||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, true); | ||||
|                         } | ||||
|                     } else if (hybridPlotWorld.PLOT_SCHEMATIC) { | ||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, true); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         if (!allRoad && hybridPlotWorld.getPlotSchematicEntities() != null && !hybridPlotWorld | ||||
|                 .getPlotSchematicEntities() | ||||
|                 .isEmpty()) { | ||||
|             CuboidRegion region = CHUNK.clone(); | ||||
|             try { | ||||
|                 region.shift(hybridPlotWorld | ||||
|                         .getPlotSchematicMinPoint() | ||||
|                         .add(relativeOffsetX, 0, relativeOffsetZ) | ||||
|                         .subtract(hybridPlotWorld.PATH_WIDTH_LOWER + 1, 0, hybridPlotWorld.PATH_WIDTH_LOWER + 1)); | ||||
|                 for (Entity entity : hybridPlotWorld.getPlotSchematicEntities()) { | ||||
|                     if (region.contains(entity.getLocation().toVector().toBlockPoint())) { | ||||
|                         Vector3 pos = (entity.getLocation().toVector() | ||||
|                                 .subtract(region.getMinimumPoint().withY(hybridPlotWorld.getPlotSchematicMinPoint().getY()).toVector3())) | ||||
|                                 .add(min.getBlockVector3().withY(hybridPlotWorld.SCHEM_Y).toVector3()); | ||||
|                         result.setEntity(new PopulatingEntity( | ||||
|                                 entity, | ||||
|                                 new com.sk89q.worldedit.util.Location(NullWorld.getInstance(), pos) | ||||
|                         )); | ||||
|                     } | ||||
|                 } | ||||
|             } catch (RegionOperationException e) { | ||||
|                 throw new RuntimeException(e); | ||||
|             } | ||||
|             if (overlap) { | ||||
|                 try { | ||||
|                     region.shift(BlockVector3.at(-hybridPlotWorld.SIZE, 0, -hybridPlotWorld.SIZE)); | ||||
|                     for (Entity entity : hybridPlotWorld.getPlotSchematicEntities()) { | ||||
|                         if (region.contains(entity.getLocation().toVector().toBlockPoint())) { | ||||
|                             result.setEntity(entity); | ||||
|                         } | ||||
|                     } | ||||
|                 } catch (RegionOperationException e) { | ||||
|                     throw new RuntimeException(e); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) { | ||||
|         return this.hybridPlotWorldFactory.create(world, id, this, min, max); | ||||
| @@ -255,4 +384,58 @@ public class HybridGen extends IndependentPlotGenerator { | ||||
|         // All initialization is done in the PlotArea class | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Wrapper to allow a WorldEdit {@link Entity} to effectively have a mutable location as the location in its NBT should be changed | ||||
|      * when set to the world. | ||||
|      * | ||||
|      * @since TODO | ||||
|      */ | ||||
|     private static final class PopulatingEntity implements Entity { | ||||
|  | ||||
|         private final Entity parent; | ||||
|         private com.sk89q.worldedit.util.Location location; | ||||
|  | ||||
|         /** | ||||
|          * @since TODO | ||||
|          */ | ||||
|         private PopulatingEntity(Entity parent, com.sk89q.worldedit.util.Location location) { | ||||
|             this.parent = parent; | ||||
|             this.location = location; | ||||
|         } | ||||
|  | ||||
|         @Nullable | ||||
|         @Override | ||||
|         public BaseEntity getState() { | ||||
|             return parent.getState(); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public boolean remove() { | ||||
|             return parent.remove(); | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public com.sk89q.worldedit.util.Location getLocation() { | ||||
|             return location; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public boolean setLocation(final com.sk89q.worldedit.util.Location location) { | ||||
|             this.location = location; | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|         @Override | ||||
|         public Extent getExtent() { | ||||
|             return parent.getExtent(); | ||||
|         } | ||||
|  | ||||
|         @Nullable | ||||
|         @Override | ||||
|         public <T> T getFacet(final Class<? extends T> cls) { | ||||
|             return parent.getFacet(cls); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -40,11 +40,13 @@ import com.plotsquared.core.plot.PlotId; | ||||
| import com.plotsquared.core.plot.PlotManager; | ||||
| import com.plotsquared.core.plot.schematic.Schematic; | ||||
| import com.plotsquared.core.queue.GlobalBlockQueue; | ||||
| import com.plotsquared.core.util.AnnotationHelper; | ||||
| import com.plotsquared.core.util.FileUtils; | ||||
| import com.plotsquared.core.util.MathMan; | ||||
| import com.plotsquared.core.util.SchematicHandler; | ||||
| import com.sk89q.jnbt.CompoundTag; | ||||
| import com.sk89q.jnbt.CompoundTagBuilder; | ||||
| import com.sk89q.worldedit.entity.Entity; | ||||
| import com.sk89q.worldedit.extent.clipboard.Clipboard; | ||||
| import com.sk89q.worldedit.extent.transform.BlockTransformExtent; | ||||
| import com.sk89q.worldedit.internal.helper.MCDirections; | ||||
| @@ -58,11 +60,13 @@ import com.sk89q.worldedit.world.block.BaseBlock; | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.checkerframework.checker.nullness.qual.NonNull; | ||||
| import org.checkerframework.checker.nullness.qual.Nullable; | ||||
|  | ||||
| import javax.annotation.Nullable; | ||||
| import java.io.File; | ||||
| import java.lang.reflect.Field; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Locale; | ||||
|  | ||||
| public class HybridPlotWorld extends ClassicPlotWorld { | ||||
| @@ -71,6 +75,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|     private static final AffineTransform transform = new AffineTransform().rotateY(90); | ||||
|     public boolean ROAD_SCHEMATIC_ENABLED; | ||||
|     public boolean PLOT_SCHEMATIC = false; | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public int PLOT_SCHEMATIC_HEIGHT = -1; | ||||
|     public short PATH_WIDTH_LOWER; | ||||
|     public short PATH_WIDTH_UPPER; | ||||
| @@ -80,6 +85,11 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|     private Location SIGN_LOCATION; | ||||
|     private File root = null; | ||||
|     private int lastOverlayHeightError = Integer.MIN_VALUE; | ||||
|     private List<Entity> schem3Entities = null; | ||||
|     private BlockVector3 schem3MinPoint = null; | ||||
|     private boolean schem1PopulationNeeded = false; | ||||
|     private boolean schem2PopulationNeeded = false; | ||||
|     private boolean schem3PopulationNeeded = false; | ||||
|  | ||||
|     @Inject | ||||
|     private SchematicHandler schematicHandler; | ||||
| @@ -98,6 +108,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|         PlotSquared.platform().injector().injectMembers(this); | ||||
|     } | ||||
|  | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public static byte wrap(byte data, int start) { | ||||
|         if ((data >= start) && (data < (start + 4))) { | ||||
|             data = (byte) ((((data - start) + 2) & 3) + start); | ||||
| @@ -105,6 +116,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|         return data; | ||||
|     } | ||||
|  | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public static byte wrap2(byte data, int start) { | ||||
|         if ((data >= start) && (data < (start + 2))) { | ||||
|             data = (byte) ((((data - start) + 1) & 1) + start); | ||||
| @@ -112,8 +124,6 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|         return data; | ||||
|     } | ||||
|  | ||||
|     // FIXME depends on block ids | ||||
|     // Possibly make abstract? | ||||
|     public static BaseBlock rotate(BaseBlock id) { | ||||
|  | ||||
|         CompoundTag tag = id.getNbtData(); | ||||
| @@ -251,6 +261,14 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|         Schematic schematic1 = this.schematicHandler.getSchematic(schematic1File); | ||||
|         Schematic schematic2 = this.schematicHandler.getSchematic(schematic2File); | ||||
|         Schematic schematic3 = this.schematicHandler.getSchematic(schematic3File); | ||||
|  | ||||
|         // If the plot schematic contains entities, then they need to be populated upon generation. | ||||
|         if (schematic3 != null && !schematic3.getClipboard().getEntities().isEmpty()) { | ||||
|             this.schem3Entities = new ArrayList<>(schematic3.getClipboard().getEntities()); | ||||
|             this.schem3MinPoint = schematic3.getClipboard().getMinimumPoint(); | ||||
|             this.schem3PopulationNeeded = true; | ||||
|         } | ||||
|  | ||||
|         int shift = this.ROAD_WIDTH / 2; | ||||
|         int oddshift = (this.ROAD_WIDTH & 1); | ||||
|  | ||||
| @@ -314,19 +332,28 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|             for (short x = 0; x < w3; x++) { | ||||
|                 for (short z = 0; z < l3; z++) { | ||||
|                     for (short y = 0; y < h3; y++) { | ||||
|                         BaseBlock id = | ||||
|                                 blockArrayClipboard3.getFullBlock(BlockVector3.at( | ||||
|                         BaseBlock id = blockArrayClipboard3.getFullBlock(BlockVector3.at( | ||||
|                                 x + min.getBlockX(), | ||||
|                                 y + min.getBlockY(), | ||||
|                                 z + min.getBlockZ() | ||||
|                         )); | ||||
|                         if (!id.getBlockType().getMaterial().isAir()) { | ||||
|                             addOverlayBlock((short) (x + shift + oddshift + centerShiftX), (short) (y + plotY), | ||||
|                                     (short) (z + shift + oddshift + centerShiftZ), id, false, h3 | ||||
|                             schem3PopulationNeeded |= id.hasNbtData(); | ||||
|                             addOverlayBlock( | ||||
|                                     (short) (x + shift + oddshift + centerShiftX), | ||||
|                                     (short) (y + plotY), | ||||
|                                     (short) (z + shift + oddshift + centerShiftZ), | ||||
|                                     id, | ||||
|                                     false, | ||||
|                                     h3 | ||||
|                             ); | ||||
|                         } | ||||
|                     } | ||||
|                     BiomeType biome = blockArrayClipboard3.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); | ||||
|                     if (blockArrayClipboard3.hasBiomes()) { | ||||
|                         BiomeType biome = blockArrayClipboard3.getBiome(BlockVector2.at( | ||||
|                                 x + min.getBlockX(), | ||||
|                                 z + min.getBlockZ() | ||||
|                         )); | ||||
|                         addOverlayBiome( | ||||
|                                 (short) (x + shift + oddshift + centerShiftX), | ||||
|                                 (short) (z + shift + oddshift + centerShiftZ), | ||||
| @@ -334,12 +361,13 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|                         ); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (Settings.DEBUG) { | ||||
|                 LOGGER.info("- plot schematic: {}", schematic3File.getPath()); | ||||
|             } | ||||
|         } | ||||
|         if ((schematic1 == null&& schematic2 == null) || this.ROAD_WIDTH == 0) { | ||||
|         if ((schematic1 == null && schematic2 == null) || this.ROAD_WIDTH == 0) { | ||||
|             if (Settings.DEBUG) { | ||||
|                 LOGGER.info("- schematic: false"); | ||||
|             } | ||||
| @@ -370,6 +398,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|                             z + min.getBlockZ() | ||||
|                     )); | ||||
|                     if (!id.getBlockType().getMaterial().isAir()) { | ||||
|                         schem1PopulationNeeded |= id.hasNbtData(); | ||||
|                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z + shift + oddshift), id, false, h1); | ||||
|                         addOverlayBlock( | ||||
|                                 (short) (z + shift + oddshift), | ||||
| @@ -381,11 +410,13 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|                         ); | ||||
|                     } | ||||
|                 } | ||||
|                 if (blockArrayClipboard1.hasBiomes()) { | ||||
|                     BiomeType biome = blockArrayClipboard1.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); | ||||
|                     addOverlayBiome((short) (x - shift), (short) (z + shift + oddshift), biome); | ||||
|                     addOverlayBiome((short) (z + shift + oddshift), (short) (shift - x + (oddshift - 1)), biome); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Clipboard blockArrayClipboard2 = schematic2.getClipboard(); | ||||
|         BlockVector3 d2 = blockArrayClipboard2.getDimensions(); | ||||
| @@ -406,14 +437,17 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|                             z + min.getBlockZ() | ||||
|                     )); | ||||
|                     if (!id.getBlockType().getMaterial().isAir()) { | ||||
|                         schem2PopulationNeeded |= id.hasNbtData(); | ||||
|                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z - shift), id, false, h2); | ||||
|                     } | ||||
|                 } | ||||
|                 if (blockArrayClipboard2.hasBiomes()) { | ||||
|                     BiomeType biome = blockArrayClipboard2.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); | ||||
|                     addOverlayBiome((short) (x - shift), (short) (z - shift), biome); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public void addOverlayBlock(short x, short y, short z, BaseBlock id, boolean rotate, int height) { | ||||
|         if (z < 0) { | ||||
| @@ -456,8 +490,52 @@ public class HybridPlotWorld extends ClassicPlotWorld { | ||||
|         this.G_SCH_B.put(pair, id); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the entities contained within the plot schematic for generation. Intended for internal use only. | ||||
|      * | ||||
|      * @since TODO | ||||
|      */ | ||||
|     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||
|     public @Nullable List<Entity> getPlotSchematicEntities() { | ||||
|         return schem3Entities; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the minimum point of the plot schematic for generation. Intended for internal use only. | ||||
|      * | ||||
|      * @since TODO | ||||
|      */ | ||||
|     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||
|     public @Nullable BlockVector3 getPlotSchematicMinPoint() { | ||||
|         return schem3MinPoint; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get if post-generation population of chunks with tiles/entities is needed for this world. Not for public API use. | ||||
|      * | ||||
|      * @since TODO | ||||
|      */ | ||||
|     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||
|     public boolean populationNeeded() { | ||||
|         return schem1PopulationNeeded || schem2PopulationNeeded || schem3PopulationNeeded; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @deprecated in favour of {@link HybridPlotWorld#getSchematicRoot()} | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public File getRoot() { | ||||
|         return this.root; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Get the root folder for this world's generation schematics. May be null if schematics not initialised via | ||||
|      * {@link HybridPlotWorld#setupSchematics()} | ||||
|      * | ||||
|      * @since TODO | ||||
|      */ | ||||
|     public @Nullable File getSchematicRoot() { | ||||
|         return this.root; | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -47,16 +47,25 @@ public abstract class IndependentPlotGenerator { | ||||
|     public abstract String getName(); | ||||
|  | ||||
|     /** | ||||
|      * Use the setBlock or setBiome method of the PlotChunk result parameter to make changes. | ||||
|      * The PlotArea settings is the same one this was initialized with. | ||||
|      * The PseudoRandom random is a fast random object. | ||||
|      * Generate chunk block data | ||||
|      * | ||||
|      * @param result   queue | ||||
|      * @param settings PlotArea (settings) | ||||
|      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public abstract void generateChunk(ScopedQueueCoordinator result, PlotArea settings); | ||||
|  | ||||
|     public boolean populateChunk(ScopedQueueCoordinator result, PlotArea setting) { | ||||
|     /** | ||||
|      * Populates the queue representing a chunk area with tile entities and entities | ||||
|      * | ||||
|      * @param result   Queue to write to | ||||
|      * @param settings PlotArea (settings) | ||||
|      * @return True if any population occurred | ||||
|      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public boolean populateChunk(ScopedQueueCoordinator result, PlotArea settings) { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -41,14 +41,17 @@ import org.khelekore.prtree.SimpleMBR; | ||||
|  * An unmodifiable 6-tuple (world,x,y,z,yaw,pitch) | ||||
|  */ | ||||
| @SuppressWarnings("unused") | ||||
| public final class Location extends BlockLoc implements Comparable<Location> { | ||||
| public sealed class Location extends BlockLoc implements Comparable<Location> permits UncheckedWorldLocation { | ||||
|  | ||||
|     private final float yaw; | ||||
|     private final float pitch; | ||||
|     private final BlockVector3 blockVector3; | ||||
|     private final World<?> world; | ||||
|  | ||||
|     private Location( | ||||
|     /** | ||||
|      * @since TODO | ||||
|      */ | ||||
|     protected Location( | ||||
|             final @NonNull World<?> world, final @NonNull BlockVector3 blockVector3, | ||||
|             final float yaw, final float pitch | ||||
|     ) { | ||||
|   | ||||
| @@ -0,0 +1,77 @@ | ||||
| /* | ||||
|  *       _____  _       _    _____                                _ | ||||
|  *      |  __ \| |     | |  / ____|                              | | | ||||
|  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||
|  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||
|  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||
|  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||
|  *                                    | | | ||||
|  *                                    |_| | ||||
|  *            PlotSquared plot management system for Minecraft | ||||
|  *               Copyright (C) 2014 - 2022 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.location; | ||||
|  | ||||
| import com.plotsquared.core.util.AnnotationHelper; | ||||
| import com.sk89q.worldedit.math.BlockVector3; | ||||
| import org.checkerframework.checker.nullness.qual.NonNull; | ||||
|  | ||||
| /** | ||||
|  * Used internally for generation to reference locations in worlds that "don't exist yet". There is no guarantee that the world | ||||
|  * name provided by {@link UncheckedWorldLocation#getWorldName()} exists on the server. | ||||
|  * | ||||
|  * @since TODO | ||||
|  */ | ||||
| @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||
| public final class UncheckedWorldLocation extends Location { | ||||
|  | ||||
|     private final String worldName; | ||||
|  | ||||
|     /** | ||||
|      * @since TODO | ||||
|      */ | ||||
|     private UncheckedWorldLocation( | ||||
|             final @NonNull String worldName, final int x, final int y, final int z | ||||
|     ) { | ||||
|         super(World.nullWorld(), BlockVector3.at(x, y, z), 0f, 0f); | ||||
|         this.worldName = worldName; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Construct a new location with yaw and pitch equal to 0 | ||||
|      * | ||||
|      * @param world World | ||||
|      * @param x     X coordinate | ||||
|      * @param y     Y coordinate | ||||
|      * @param z     Z coordinate | ||||
|      * @return New location | ||||
|      * | ||||
|      * @since TODO | ||||
|      */ | ||||
|     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||
|     public static @NonNull UncheckedWorldLocation at( | ||||
|             final @NonNull String world, final int x, final int y, final int z | ||||
|     ) { | ||||
|         return new UncheckedWorldLocation(world, x, y, z); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||
|     public @NonNull String getWorldName() { | ||||
|         return this.worldName; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @@ -93,7 +93,9 @@ public abstract class QueueCoordinator { | ||||
|      * @param z chunk z coordinate | ||||
|      * @return a new {@link ScopedQueueCoordinator} | ||||
|      * @since 6.6.0 | ||||
|      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public ScopedQueueCoordinator getForChunk(int x, int z, int minY, int maxY) { | ||||
|         int bx = x << 4; | ||||
|         int bz = z << 4; | ||||
|   | ||||
| @@ -42,6 +42,10 @@ public abstract class ChunkManager { | ||||
|     private static final Map<BlockVector2, RunnableVal<ScopedQueueCoordinator>> forceChunks = new ConcurrentHashMap<>(); | ||||
|     private static final Map<BlockVector2, RunnableVal<ScopedQueueCoordinator>> addChunks = new ConcurrentHashMap<>(); | ||||
|  | ||||
|     /** | ||||
|      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public static void setChunkInPlotArea( | ||||
|             RunnableVal<ScopedQueueCoordinator> force, | ||||
|             RunnableVal<ScopedQueueCoordinator> add, | ||||
| @@ -79,6 +83,10 @@ public abstract class ChunkManager { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public static boolean preProcessChunk(BlockVector2 loc, ScopedQueueCoordinator queue) { | ||||
|         final RunnableVal<ScopedQueueCoordinator> forceChunk = forceChunks.get(loc); | ||||
|         if (forceChunk != null) { | ||||
| @@ -89,6 +97,10 @@ public abstract class ChunkManager { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||
|      */ | ||||
|     @Deprecated(forRemoval = true, since = "TODO") | ||||
|     public static boolean postProcessChunk(BlockVector2 loc, ScopedQueueCoordinator queue) { | ||||
|         final RunnableVal<ScopedQueueCoordinator> addChunk = forceChunks.get(loc); | ||||
|         if (addChunk != null) { | ||||
|   | ||||
| @@ -34,7 +34,7 @@ allprojects { | ||||
|  | ||||
|         maven { | ||||
|             name = "Sonatype OSS (S01)" | ||||
|             url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots") | ||||
|             url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") | ||||
|         } | ||||
|  | ||||
|         maven { | ||||
| @@ -64,9 +64,12 @@ subprojects { | ||||
|         plugin<EclipsePlugin>() | ||||
|         plugin<IdeaPlugin>() | ||||
|     } | ||||
|  | ||||
|     dependencies { | ||||
|         implementation(platform("com.intellectualsites.bom:bom-1.18.x:1.2")) | ||||
|     } | ||||
| } | ||||
|  | ||||
| val javadocDir = rootDir.resolve("docs").resolve("javadoc").resolve(project.name) | ||||
| allprojects { | ||||
|     dependencies { | ||||
|         // Tests | ||||
| @@ -172,11 +175,6 @@ allprojects { | ||||
|     } | ||||
|  | ||||
|     tasks { | ||||
|         named<Delete>("clean") { | ||||
|             doFirst { | ||||
|                 javadocDir.deleteRecursively() | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         compileJava { | ||||
|             options.compilerArgs.addAll(arrayOf("-Xmaxerrs", "1000")) | ||||
| @@ -187,16 +185,6 @@ allprojects { | ||||
|             options.encoding = "UTF-8" | ||||
|         } | ||||
|  | ||||
|         javadoc { | ||||
|             val opt = options as StandardJavadocDocletOptions | ||||
|             opt.addStringOption("Xdoclint:none", "-quiet") | ||||
|             opt.tags( | ||||
|                     "apiNote:a:API Note:", | ||||
|                     "implSpec:a:Implementation Requirements:", | ||||
|                     "implNote:a:Implementation Note:" | ||||
|             ) | ||||
|         } | ||||
|  | ||||
|         shadowJar { | ||||
|             this.archiveClassifier.set(null as String?) | ||||
|             this.archiveFileName.set("${project.name}-${project.version}.${this.archiveExtension.getOrElse("jar")}") | ||||
| @@ -221,37 +209,3 @@ nexusPublishing { | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| tasks { | ||||
|     val aggregatedJavadocs = create<Javadoc>("aggregatedJavadocs") { | ||||
|         title = "${project.name} ${project.version} API" | ||||
|         setDestinationDir(javadocDir) | ||||
|         options.destinationDirectory = javadocDir | ||||
|  | ||||
|         doFirst { | ||||
|             javadocDir.deleteRecursively() | ||||
|         } | ||||
|     }.also { | ||||
|         it.group = "Documentation" | ||||
|         it.description = "Generate javadocs from all child projects as if it was a single project" | ||||
|     } | ||||
|  | ||||
|     subprojects.forEach { subProject -> | ||||
|         subProject.afterEvaluate { | ||||
|             subProject.tasks.withType<Javadoc>().forEach { task -> | ||||
|                 aggregatedJavadocs.source += task.source | ||||
|                 aggregatedJavadocs.classpath += task.classpath | ||||
|                 aggregatedJavadocs.excludes += task.excludes | ||||
|                 aggregatedJavadocs.includes += task.includes | ||||
|  | ||||
|                 val rootOptions = aggregatedJavadocs.options as StandardJavadocDocletOptions | ||||
|                 val subOptions = task.options as StandardJavadocDocletOptions | ||||
|                 rootOptions.links(*subOptions.links.orEmpty().minus(rootOptions.links.orEmpty().toSet()).toTypedArray()) | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     build { | ||||
|         dependsOn(aggregatedJavadocs) | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -1,15 +1,9 @@ | ||||
| [versions] | ||||
| # Minecraft expectations | ||||
| gson = "2.8.8" # Version set by Minecraft | ||||
| log4j-api = "2.17.1" # Version set by Minecraft | ||||
| guava = "31.0.1-jre" # Version set by Minecraft | ||||
|  | ||||
| # Platform expectations | ||||
| paper = "1.18.1-R0.1-SNAPSHOT" | ||||
| checker-qual = "3.22.0" | ||||
| guice = "5.1.0" | ||||
| spotbugs = "4.7.0" | ||||
| snakeyaml = "1.30" # Version set by Bukkit | ||||
|  | ||||
| # Adventure & MiniMessage | ||||
| adventure-api = "4.9.3" | ||||
| @@ -18,8 +12,6 @@ adventure-platform-bukkit = "4.0.1" | ||||
|  | ||||
| # Plugins | ||||
| worldedit = "7.2.10" | ||||
| fawe = "2.2.0" | ||||
| vault = "1.7.1" | ||||
| placeholderapi = "2.11.1" | ||||
| luckperms = "5.4" | ||||
| essentialsx = "2.19.4" | ||||
| @@ -30,11 +22,7 @@ prtree = "2.0.0" | ||||
| aopalliance = "1.0" | ||||
| cloud-services = "1.6.2" | ||||
| arkitektonika = "2.1.1" | ||||
| paster = "1.1.4" | ||||
| bstats = "3.0.0" | ||||
| paperlib = "1.0.7" | ||||
| squirrelid = "0.3.1" | ||||
| serverlib = "2.3.1" | ||||
| http4j = "1.3" | ||||
|  | ||||
| # Gradle plugins | ||||
| @@ -48,12 +36,7 @@ nexus = "1.1.0" | ||||
| paper = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper" } | ||||
| checkerqual = { group = "org.checkerframework", name = "checker-qual", version.ref = "checker-qual" } | ||||
|  | ||||
| # Minecraft expectations | ||||
| gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } | ||||
| log4j = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j-api" } | ||||
|  | ||||
| # Platform expectations | ||||
| snakeyaml = { group = "org.yaml", name = "snakeyaml", version.ref = "snakeyaml" } | ||||
| guice = { group = "com.google.inject", name = "guice", version.ref = "guice" } | ||||
| guiceassistedinject = { group = "com.google.inject.extensions", name = "guice-assistedinject", version.ref = "guice" } | ||||
| spotbugs = { group = "com.github.spotbugs", name = "spotbugs-annotations", version.ref = "spotbugs" } | ||||
| @@ -66,9 +49,6 @@ adventurePlatformBukkit = { group = "net.kyori", name = "adventure-platform-bukk | ||||
| # Plugins | ||||
| worldeditCore = { group = "com.sk89q.worldedit", name = "worldedit-core", version.ref = "worldedit" } | ||||
| worldeditBukkit = { group = "com.sk89q.worldedit", name = "worldedit-bukkit", version.ref = "worldedit" } | ||||
| fastasyncworldeditBukkit = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Bukkit", version.ref = "fawe" } | ||||
| fastasyncworldeditCore = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Core", version.ref = "fawe" } | ||||
| vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" } | ||||
| placeholderapi = { group = "me.clip", name = "placeholderapi", version.ref = "placeholderapi" } | ||||
| luckperms = { group = "net.luckperms", name = "api", version.ref = "luckperms" } | ||||
| essentialsx = { group = "net.essentialsx", name = "EssentialsX", version.ref = "essentialsx" } | ||||
| @@ -79,13 +59,8 @@ aopalliance = { group = "aopalliance", name = "aopalliance", version.ref = "aopa | ||||
| cloudServices = { group = "cloud.commandframework", name = "cloud-services", version.ref = "cloud-services" } | ||||
| mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } | ||||
| squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" } | ||||
| serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" } | ||||
| bstats = { group = "org.bstats", name = "bstats-bukkit", version.ref = "bstats" } | ||||
| paperlib = { group = "io.papermc", name = "paperlib", version.ref = "paperlib" } | ||||
| arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } | ||||
| 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" } | ||||
|  | ||||
| [plugins] | ||||
| shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user