Split ChunkManager to Chunk and Region Managers

- Having not chunk-specific code in ChunkManager felt wrong.
- Also allow FAWE to replace setbiome code
- Also improve performance (proper usage of chunk loading) for setbiome
This commit is contained in:
dordsor21 2020-05-13 13:13:14 +01:00
parent 98b4ceab7d
commit 617abf89e6
30 changed files with 734 additions and 514 deletions

View File

@ -38,8 +38,10 @@ import com.plotsquared.bukkit.placeholder.Placeholders;
import com.plotsquared.bukkit.queue.BukkitLocalQueue; import com.plotsquared.bukkit.queue.BukkitLocalQueue;
import com.plotsquared.bukkit.schematic.BukkitSchematicHandler; import com.plotsquared.bukkit.schematic.BukkitSchematicHandler;
import com.plotsquared.bukkit.util.BukkitChatManager; import com.plotsquared.bukkit.util.BukkitChatManager;
import com.plotsquared.bukkit.util.BukkitChunkManager;
import com.plotsquared.bukkit.util.BukkitEconHandler; import com.plotsquared.bukkit.util.BukkitEconHandler;
import com.plotsquared.bukkit.util.BukkitInventoryUtil; import com.plotsquared.bukkit.util.BukkitInventoryUtil;
import com.plotsquared.bukkit.util.BukkitRegionManager;
import com.plotsquared.bukkit.util.BukkitSetupUtils; import com.plotsquared.bukkit.util.BukkitSetupUtils;
import com.plotsquared.bukkit.util.BukkitTaskManager; import com.plotsquared.bukkit.util.BukkitTaskManager;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
@ -86,6 +88,7 @@ import com.plotsquared.core.util.InventoryUtil;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.PremiumVerification; import com.plotsquared.core.util.PremiumVerification;
import com.plotsquared.core.util.ReflectionUtils; import com.plotsquared.core.util.ReflectionUtils;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
@ -753,6 +756,10 @@ public final class BukkitMain extends JavaPlugin implements Listener, IPlotMain
return new BukkitChunkManager(); return new BukkitChunkManager();
} }
@Override public RegionManager initRegionManager() {
return new BukkitRegionManager();
}
@Override public void unregister(@NonNull final PlotPlayer player) { @Override public void unregister(@NonNull final PlotPlayer player) {
BukkitUtil.removePlayer(player.getName()); BukkitUtil.removePlayer(player.getName());
} }

View File

@ -0,0 +1,165 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.util;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.listener.WEExtent;
import com.plotsquared.core.queue.GlobalBlockQueue;
import com.plotsquared.core.queue.LocalBlockQueue;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.entity.EntityCategories;
import com.plotsquared.core.util.task.TaskManager;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.block.BaseBlock;
import io.papermc.lib.PaperLib;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import java.util.concurrent.CompletableFuture;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ANIMAL;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ENTITY;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MISC;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MOB;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MONSTER;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
public class BukkitChunkManager extends ChunkManager {
public static boolean isIn(CuboidRegion region, int x, int z) {
return x >= region.getMinimumPoint().getX() && x <= region.getMaximumPoint().getX()
&& z >= region.getMinimumPoint().getZ() && z <= region.getMaximumPoint().getZ();
}
public static ContentMap swapChunk(World world1, World world2, Chunk pos1, Chunk pos2,
CuboidRegion r1, CuboidRegion r2) {
ContentMap map = new ContentMap();
int relX = r2.getMinimumPoint().getX() - r1.getMinimumPoint().getX();
int relZ = r2.getMinimumPoint().getZ() - r1.getMinimumPoint().getZ();
map.saveEntitiesIn(pos1, r1, relX, relZ, true);
map.saveEntitiesIn(pos2, r2, -relX, -relZ, true);
int sx = pos1.getX() << 4;
int sz = pos1.getZ() << 4;
String worldName1 = world1.getName();
String worldName2 = world2.getName();
BukkitWorld bukkitWorld1 = new BukkitWorld(world1);
BukkitWorld bukkitWorld2 = new BukkitWorld(world2);
LocalBlockQueue queue1 = GlobalBlockQueue.IMP.getNewQueue(worldName1, false);
LocalBlockQueue queue2 = GlobalBlockQueue.IMP.getNewQueue(worldName2, false);
for (int x = Math.max(r1.getMinimumPoint().getX(), sx);
x <= Math.min(r1.getMaximumPoint().getX(), sx + 15); x++) {
for (int z = Math.max(r1.getMinimumPoint().getZ(), sz);
z <= Math.min(r1.getMaximumPoint().getZ(), sz + 15); z++) {
for (int y = 0; y < 256; y++) {
Block block1 = world1.getBlockAt(x, y, z);
BaseBlock baseBlock1 = bukkitWorld1.getFullBlock(BlockVector3.at(x, y, z));
BlockData data1 = block1.getBlockData();
int xx = x + relX;
int zz = z + relZ;
Block block2 = world2.getBlockAt(xx, y, zz);
BaseBlock baseBlock2 = bukkitWorld2.getFullBlock(BlockVector3.at(xx, y, zz));
BlockData data2 = block2.getBlockData();
if (block1.isEmpty()) {
if (!block2.isEmpty()) {
queue1.setBlock(x, y, z, baseBlock2);
queue2.setBlock(xx, y, zz, WEExtent.AIRBASE);
}
} else if (block2.isEmpty()) {
queue1.setBlock(x, y, z, WEExtent.AIRBASE);
queue2.setBlock(xx, y, zz, baseBlock1);
} else if (block1.equals(block2)) {
if (!data1.matches(data2)) {
block1.setBlockData(data2);
block2.setBlockData(data1);
}
} else {
queue1.setBlock(x, y, z, baseBlock2);
queue2.setBlock(xx, y, zz, baseBlock1);
}
}
}
}
queue1.enqueue();
queue2.enqueue();
return map;
}
@Override
public CompletableFuture<?> loadChunk(String world, BlockVector2 chunkLoc, boolean force) {
return PaperLib
.getChunkAtAsync(BukkitUtil.getWorld(world), chunkLoc.getX(), chunkLoc.getZ(), force);
}
@Override
public void unloadChunk(final String world, final BlockVector2 chunkLoc, final boolean save) {
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
TaskManager.runTask(() -> BukkitUtil.getWorld(world)
.unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save));
} else {
BukkitUtil.getWorld(world).unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save);
}
}
private void count(int[] count, Entity entity) {
final com.sk89q.worldedit.world.entity.EntityType entityType =
BukkitAdapter.adapt(entity.getType());
if (EntityCategories.PLAYER.contains(entityType)) {
return;
} else if (EntityCategories.PROJECTILE.contains(entityType) || EntityCategories.OTHER
.contains(entityType) || EntityCategories.HANGING.contains(entityType)) {
count[CAP_MISC]++;
} else if (EntityCategories.ANIMAL.contains(entityType) || EntityCategories.VILLAGER
.contains(entityType) || EntityCategories.TAMEABLE.contains(entityType)) {
count[CAP_MOB]++;
count[CAP_ANIMAL]++;
} else if (EntityCategories.VEHICLE.contains(entityType)) {
count[CAP_VEHICLE]++;
} else if (EntityCategories.HOSTILE.contains(entityType)) {
count[CAP_MOB]++;
count[CAP_MONSTER]++;
}
count[CAP_ENTITY]++;
}
}

View File

@ -23,14 +23,11 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.plotsquared.bukkit; package com.plotsquared.bukkit.util;
import com.plotsquared.bukkit.entity.EntityWrapper; import com.plotsquared.bukkit.BukkitMain;
import com.plotsquared.bukkit.entity.ReplicatingEntityWrapper;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.generator.AugmentedUtils; import com.plotsquared.core.generator.AugmentedUtils;
import com.plotsquared.core.listener.WEExtent;
import com.plotsquared.core.location.Location; import com.plotsquared.core.location.Location;
import com.plotsquared.core.location.PlotLoc; import com.plotsquared.core.location.PlotLoc;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@ -39,6 +36,8 @@ import com.plotsquared.core.queue.GlobalBlockQueue;
import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.queue.LocalBlockQueue;
import com.plotsquared.core.queue.ScopedLocalBlockQueue; import com.plotsquared.core.queue.ScopedLocalBlockQueue;
import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.RegionUtil; import com.plotsquared.core.util.RegionUtil;
import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.entity.EntityCategories;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
@ -46,29 +45,24 @@ import com.plotsquared.core.util.task.TaskManager;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld; import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects; import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
@ -79,75 +73,13 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_MOB;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_MONSTER; import static com.plotsquared.core.util.entity.EntityCategories.CAP_MONSTER;
import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE; import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE;
public class BukkitChunkManager extends ChunkManager { public class BukkitRegionManager extends RegionManager {
public static boolean isIn(CuboidRegion region, int x, int z) { public static boolean isIn(CuboidRegion region, int x, int z) {
return x >= region.getMinimumPoint().getX() && x <= region.getMaximumPoint().getX() return x >= region.getMinimumPoint().getX() && x <= region.getMaximumPoint().getX()
&& z >= region.getMinimumPoint().getZ() && z <= region.getMaximumPoint().getZ(); && z >= region.getMinimumPoint().getZ() && z <= region.getMaximumPoint().getZ();
} }
public static ContentMap swapChunk(World world1, World world2, Chunk pos1, Chunk pos2,
CuboidRegion r1, CuboidRegion r2) {
ContentMap map = new ContentMap();
int relX = r2.getMinimumPoint().getX() - r1.getMinimumPoint().getX();
int relZ = r2.getMinimumPoint().getZ() - r1.getMinimumPoint().getZ();
map.saveEntitiesIn(pos1, r1, relX, relZ, true);
map.saveEntitiesIn(pos2, r2, -relX, -relZ, true);
int sx = pos1.getX() << 4;
int sz = pos1.getZ() << 4;
String worldName1 = world1.getName();
String worldName2 = world2.getName();
BukkitWorld bukkitWorld1 = new BukkitWorld(world1);
BukkitWorld bukkitWorld2 = new BukkitWorld(world2);
LocalBlockQueue queue1 = GlobalBlockQueue.IMP.getNewQueue(worldName1, false);
LocalBlockQueue queue2 = GlobalBlockQueue.IMP.getNewQueue(worldName2, false);
for (int x = Math.max(r1.getMinimumPoint().getX(), sx);
x <= Math.min(r1.getMaximumPoint().getX(), sx + 15); x++) {
for (int z = Math.max(r1.getMinimumPoint().getZ(), sz);
z <= Math.min(r1.getMaximumPoint().getZ(), sz + 15); z++) {
for (int y = 0; y < 256; y++) {
Block block1 = world1.getBlockAt(x, y, z);
BaseBlock baseBlock1 = bukkitWorld1.getFullBlock(BlockVector3.at(x, y, z));
BlockData data1 = block1.getBlockData();
int xx = x + relX;
int zz = z + relZ;
Block block2 = world2.getBlockAt(xx, y, zz);
BaseBlock baseBlock2 = bukkitWorld2.getFullBlock(BlockVector3.at(xx, y, zz));
BlockData data2 = block2.getBlockData();
if (block1.isEmpty()) {
if (!block2.isEmpty()) {
queue1.setBlock(x, y, z, baseBlock2);
queue2.setBlock(xx, y, zz, WEExtent.AIRBASE);
}
} else if (block2.isEmpty()) {
queue1.setBlock(x, y, z, WEExtent.AIRBASE);
queue2.setBlock(xx, y, zz, baseBlock1);
} else if (block1.equals(block2)) {
if (!data1.matches(data2)) {
block1.setBlockData(data2);
block2.setBlockData(data1);
}
} else {
queue1.setBlock(x, y, z, baseBlock2);
queue2.setBlock(xx, y, zz, baseBlock1);
}
}
}
}
queue1.enqueue();
queue2.enqueue();
return map;
}
@Override public Set<BlockVector2> getChunkChunks(String world) { @Override public Set<BlockVector2> getChunkChunks(String world) {
Set<BlockVector2> chunks = super.getChunkChunks(world); Set<BlockVector2> chunks = super.getChunkChunks(world);
if (Bukkit.isPrimaryThread()) { if (Bukkit.isPrimaryThread()) {
@ -416,8 +348,8 @@ public class BukkitChunkManager extends ChunkManager {
CuboidRegion currentPlotClear = RegionUtil CuboidRegion currentPlotClear = RegionUtil
.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ()); .createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ());
map.saveEntitiesOut(chunkObj, currentPlotClear); map.saveEntitiesOut(chunkObj, currentPlotClear);
AugmentedUtils.bypass(ignoreAugment, () -> setChunkInPlotArea(null, AugmentedUtils.bypass(ignoreAugment, () -> ChunkManager.manager
new RunnableVal<ScopedLocalBlockQueue>() { .setChunkInPlotArea(null, new RunnableVal<ScopedLocalBlockQueue>() {
@Override public void run(ScopedLocalBlockQueue value) { @Override public void run(ScopedLocalBlockQueue value) {
Location min = value.getMin(); Location min = value.getMin();
int bx = min.getX(); int bx = min.getX();
@ -463,22 +395,6 @@ public class BukkitChunkManager extends ChunkManager {
return true; return true;
} }
@Override
public CompletableFuture<?> loadChunk(String world, BlockVector2 chunkLoc, boolean force) {
return PaperLib
.getChunkAtAsync(BukkitUtil.getWorld(world), chunkLoc.getX(), chunkLoc.getZ(), force);
}
@Override
public void unloadChunk(final String world, final BlockVector2 chunkLoc, final boolean save) {
if (!PlotSquared.get().isMainThread(Thread.currentThread())) {
TaskManager.runTask(() -> BukkitUtil.getWorld(world)
.unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save));
} else {
BukkitUtil.getWorld(world).unloadChunk(chunkLoc.getX(), chunkLoc.getZ(), save);
}
}
@Override public void clearAllEntities(Location pos1, Location pos2) { @Override public void clearAllEntities(Location pos1, Location pos2) {
String world = pos1.getWorld(); String world = pos1.getWorld();
List<Entity> entities = BukkitUtil.getEntities(world); List<Entity> entities = BukkitUtil.getEntities(world);
@ -520,7 +436,8 @@ public class BukkitChunkManager extends ChunkManager {
for (int z = bot1.getZ() >> 4; z <= top1.getZ() >> 4; z++) { for (int z = bot1.getZ() >> 4; z <= top1.getZ() >> 4; z++) {
Chunk chunk1 = world1.getChunkAt(x, z); Chunk chunk1 = world1.getChunkAt(x, z);
Chunk chunk2 = world2.getChunkAt(x + (relX >> 4), z + (relZ >> 4)); Chunk chunk2 = world2.getChunkAt(x + (relX >> 4), z + (relZ >> 4));
maps.add(swapChunk(world1, world2, chunk1, chunk2, region1, region2)); maps.add(
BukkitChunkManager.swapChunk(world1, world2, chunk1, chunk2, region1, region2));
} }
} }
GlobalBlockQueue.IMP.addEmptyTask(() -> { GlobalBlockQueue.IMP.addEmptyTask(() -> {
@ -531,6 +448,26 @@ public class BukkitChunkManager extends ChunkManager {
}); });
} }
@Override
public void setBiome(final CuboidRegion region, final int extendBiome, final BiomeType biome,
final String world, final Runnable whenDone) {
Location pos1 = new Location(world, region.getMinimumPoint().getX() - extendBiome,
region.getMinimumPoint().getY(), region.getMinimumPoint().getZ() - extendBiome);
Location pos2 = new Location(world, region.getMaximumPoint().getX() + extendBiome,
region.getMaximumPoint().getY(), region.getMaximumPoint().getZ() + extendBiome);
final LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
@Override public void run(int[] value) {
BlockVector2 loc = BlockVector2.at(value[0], value[1]);
ChunkManager.manager.loadChunk(world, loc, false).thenRun(() -> {
MainUtil.setBiome(world, value[2], value[3], value[4], value[5], biome);
queue.refreshChunk(value[0], value[1]);
});
}
}, whenDone, 5);
}
private void count(int[] count, Entity entity) { private void count(int[] count, Entity entity) {
final com.sk89q.worldedit.world.entity.EntityType entityType = final com.sk89q.worldedit.world.entity.EntityType entityType =
BukkitAdapter.adapt(entity.getType()); BukkitAdapter.adapt(entity.getType());
@ -552,104 +489,4 @@ public class BukkitChunkManager extends ChunkManager {
} }
count[CAP_ENTITY]++; count[CAP_ENTITY]++;
} }
public static class ContentMap {
final Set<EntityWrapper> entities;
final Map<PlotLoc, BaseBlock[]> allBlocks;
ContentMap() {
this.entities = new HashSet<>();
this.allBlocks = new HashMap<>();
}
public void saveRegion(BukkitWorld world, int x1, int x2, int z1, int z2) {
if (z1 > z2) {
int tmp = z1;
z1 = z2;
z2 = tmp;
}
if (x1 > x2) {
int tmp = x1;
x1 = x2;
x2 = tmp;
}
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
saveBlocks(world, 256, x, z, 0, 0);
}
}
}
void saveEntitiesOut(Chunk chunk, CuboidRegion region) {
for (Entity entity : chunk.getEntities()) {
Location location = BukkitUtil.getLocation(entity);
int x = location.getX();
int z = location.getZ();
if (isIn(region, x, z)) {
continue;
}
if (entity.getVehicle() != null) {
continue;
}
EntityWrapper wrap = new ReplicatingEntityWrapper(entity, (short) 2);
wrap.saveEntity();
this.entities.add(wrap);
}
}
void saveEntitiesIn(Chunk chunk, CuboidRegion region) {
saveEntitiesIn(chunk, region, 0, 0, false);
}
void saveEntitiesIn(Chunk chunk, CuboidRegion region, int offsetX, int offsetZ,
boolean delete) {
for (Entity entity : chunk.getEntities()) {
Location location = BukkitUtil.getLocation(entity);
int x = location.getX();
int z = location.getZ();
if (!isIn(region, x, z)) {
continue;
}
if (entity.getVehicle() != null) {
continue;
}
EntityWrapper wrap = new ReplicatingEntityWrapper(entity, (short) 2);
wrap.x += offsetX;
wrap.z += offsetZ;
wrap.saveEntity();
this.entities.add(wrap);
if (delete) {
if (!(entity instanceof Player)) {
entity.remove();
}
}
}
}
void restoreEntities(World world, int xOffset, int zOffset) {
for (EntityWrapper entity : this.entities) {
try {
entity.spawn(world, xOffset, zOffset);
} catch (Exception e) {
PlotSquared.debug("Failed to restore entity (e): " + e.toString());
e.printStackTrace();
}
}
this.entities.clear();
}
//todo optimize maxY
void saveBlocks(BukkitWorld world, int maxY, int x, int z, int offsetX, int offsetZ) {
maxY = Math.min(255, maxY);
BaseBlock[] ids = new BaseBlock[maxY + 1];
for (short y = 0; y <= maxY; y++) {
BaseBlock block = world.getFullBlock(BlockVector3.at(x, y, z));
ids[y] = block;
}
PlotLoc loc = new PlotLoc(x + offsetX, z + offsetZ);
this.allBlocks.put(loc, ids);
}
}
} }

View File

@ -0,0 +1,144 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.util;
import com.plotsquared.bukkit.entity.EntityWrapper;
import com.plotsquared.bukkit.entity.ReplicatingEntityWrapper;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.location.PlotLoc;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.block.BaseBlock;
import org.bukkit.Chunk;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class ContentMap {
final Set<EntityWrapper> entities;
final Map<PlotLoc, BaseBlock[]> allBlocks;
ContentMap() {
this.entities = new HashSet<>();
this.allBlocks = new HashMap<>();
}
public void saveRegion(BukkitWorld world, int x1, int x2, int z1, int z2) {
if (z1 > z2) {
int tmp = z1;
z1 = z2;
z2 = tmp;
}
if (x1 > x2) {
int tmp = x1;
x1 = x2;
x2 = tmp;
}
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
saveBlocks(world, 256, x, z, 0, 0);
}
}
}
void saveEntitiesOut(Chunk chunk, CuboidRegion region) {
for (Entity entity : chunk.getEntities()) {
Location location = BukkitUtil.getLocation(entity);
int x = location.getX();
int z = location.getZ();
if (BukkitChunkManager.isIn(region, x, z)) {
continue;
}
if (entity.getVehicle() != null) {
continue;
}
EntityWrapper wrap = new ReplicatingEntityWrapper(entity, (short) 2);
wrap.saveEntity();
this.entities.add(wrap);
}
}
void saveEntitiesIn(Chunk chunk, CuboidRegion region) {
saveEntitiesIn(chunk, region, 0, 0, false);
}
void saveEntitiesIn(Chunk chunk, CuboidRegion region, int offsetX, int offsetZ,
boolean delete) {
for (Entity entity : chunk.getEntities()) {
Location location = BukkitUtil.getLocation(entity);
int x = location.getX();
int z = location.getZ();
if (!BukkitChunkManager.isIn(region, x, z)) {
continue;
}
if (entity.getVehicle() != null) {
continue;
}
EntityWrapper wrap = new ReplicatingEntityWrapper(entity, (short) 2);
wrap.x += offsetX;
wrap.z += offsetZ;
wrap.saveEntity();
this.entities.add(wrap);
if (delete) {
if (!(entity instanceof Player)) {
entity.remove();
}
}
}
}
void restoreEntities(World world, int xOffset, int zOffset) {
for (EntityWrapper entity : this.entities) {
try {
entity.spawn(world, xOffset, zOffset);
} catch (Exception e) {
PlotSquared.debug("Failed to restore entity (e): " + e.toString());
e.printStackTrace();
}
}
this.entities.clear();
}
//todo optimize maxY
void saveBlocks(BukkitWorld world, int maxY, int x, int z, int offsetX, int offsetZ) {
maxY = Math.min(255, maxY);
BaseBlock[] ids = new BaseBlock[maxY + 1];
for (short y = 0; y <= maxY; y++) {
BaseBlock block = world.getFullBlock(BlockVector3.at(x, y, z));
ids[y] = block;
}
PlotLoc loc = new PlotLoc(x + offsetX, z + offsetZ);
this.allBlocks.put(loc, ids);
}
}

View File

@ -35,6 +35,7 @@ import com.plotsquared.core.util.ChatManager;
import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.InventoryUtil; import com.plotsquared.core.util.InventoryUtil;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
@ -189,6 +190,13 @@ public interface IPlotMain extends ILogger {
*/ */
ChunkManager initChunkManager(); ChunkManager initChunkManager();
/**
* Gets the region manager.
*
* @return the PlotSquared region manager
*/
RegionManager initRegionManager();
/** /**
* Gets the {@link SetupUtils} class. * Gets the {@link SetupUtils} class.
*/ */

View File

@ -74,6 +74,7 @@ import com.plotsquared.core.util.LegacyConverter;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.ReflectionUtils; import com.plotsquared.core.util.ReflectionUtils;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
@ -273,6 +274,7 @@ public class PlotSquared {
GlobalBlockQueue.IMP.runTask(); GlobalBlockQueue.IMP.runTask();
// Set chunk // Set chunk
ChunkManager.manager = this.IMP.initChunkManager(); ChunkManager.manager = this.IMP.initChunkManager();
RegionManager.manager = this.IMP.initRegionManager();
// Schematic handler // Schematic handler
SchematicHandler.manager = this.IMP.initSchematicHandler(); SchematicHandler.manager = this.IMP.initSchematicHandler();
// Chat // Chat

View File

@ -40,10 +40,10 @@ import com.plotsquared.core.plot.PlotAreaType;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.plot.SetupObject; import com.plotsquared.core.plot.SetupObject;
import com.plotsquared.core.plot.message.PlotMessage; import com.plotsquared.core.plot.message.PlotMessage;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.RegionUtil; import com.plotsquared.core.util.RegionUtil;
import com.plotsquared.core.util.SetupUtils; import com.plotsquared.core.util.SetupUtils;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
@ -167,7 +167,7 @@ public class Area extends SubCommand {
player.teleport(WorldUtil.IMP.getSpawn(world), player.teleport(WorldUtil.IMP.getSpawn(world),
TeleportCause.COMMAND); TeleportCause.COMMAND);
if (area.getTerrain() != PlotAreaTerrainType.ALL) { if (area.getTerrain() != PlotAreaTerrainType.ALL) {
ChunkManager.largeRegionTask(world, region, RegionManager.largeRegionTask(world, region,
new RunnableVal<BlockVector2>() { new RunnableVal<BlockVector2>() {
@Override public void run(BlockVector2 value) { @Override public void run(BlockVector2 value) {
AugmentedUtils AugmentedUtils
@ -474,7 +474,7 @@ public class Area extends SubCommand {
"$4Stop the server and delete: " + area.getWorldName() + "/region"); "$4Stop the server and delete: " + area.getWorldName() + "/region");
return false; return false;
} }
ChunkManager.largeRegionTask(area.getWorldName(), area.getRegion(), RegionManager.largeRegionTask(area.getWorldName(), area.getRegion(),
new RunnableVal<BlockVector2>() { new RunnableVal<BlockVector2>() {
@Override public void run(BlockVector2 value) { @Override public void run(BlockVector2 value) {
AugmentedUtils AugmentedUtils

View File

@ -53,11 +53,11 @@ import java.util.stream.IntStream;
import java.util.stream.Stream; import java.util.stream.Stream;
@CommandDeclaration(command = "backup", @CommandDeclaration(command = "backup",
usage = "/plot backup <save|list|load>", usage = "/plot backup <save|list|load>",
description = "Manage plot backups", description = "Manage plot backups",
category = CommandCategory.SETTINGS, category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER, requiredType = RequiredType.PLAYER,
permission = "plots.backup") permission = "plots.backup")
public final class Backup extends Command { public final class Backup extends Command {
public Backup() { public Backup() {
@ -69,7 +69,8 @@ public final class Backup extends Command {
return true; return true;
} }
@Override public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args, @Override
public CompletableFuture<Boolean> execute(PlotPlayer player, String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone) throws CommandException { RunnableVal2<Command, CommandResult> whenDone) throws CommandException {
if (args.length == 0 || !Arrays.asList("save", "list", "load") if (args.length == 0 || !Arrays.asList("save", "list", "load")
@ -82,23 +83,28 @@ public final class Backup extends Command {
@Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) { @Override public Collection<Command> tab(PlotPlayer player, String[] args, boolean space) {
if (args.length == 1) { if (args.length == 1) {
return Stream.of("save", "list", "load") return Stream.of("save", "list", "load")
.filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH)))
.map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {}) .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {
.collect(Collectors.toList()); }).collect(Collectors.toList());
} else if (args[0].equalsIgnoreCase("load")) { } else if (args[0].equalsIgnoreCase("load")) {
final Plot plot = player.getCurrentPlot(); final Plot plot = player.getCurrentPlot();
if (plot != null) { if (plot != null) {
final BackupProfile backupProfile = Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot); final BackupProfile backupProfile =
Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot);
if (backupProfile instanceof PlayerBackupProfile) { if (backupProfile instanceof PlayerBackupProfile) {
final CompletableFuture<List<com.plotsquared.core.backup.Backup>> backupList = backupProfile.listBackups(); final CompletableFuture<List<com.plotsquared.core.backup.Backup>> backupList =
backupProfile.listBackups();
if (backupList.isDone()) { if (backupList.isDone()) {
final List<com.plotsquared.core.backup.Backup> backups = backupList.getNow(new ArrayList<>()); final List<com.plotsquared.core.backup.Backup> backups =
backupList.getNow(new ArrayList<>());
if (backups.isEmpty()) { if (backups.isEmpty()) {
return new ArrayList<>(); return new ArrayList<>();
} }
return IntStream.range(1, 1 + backups.size()).mapToObj(i -> new Command(null, false, Integer.toString(i), return IntStream.range(1, 1 + backups.size()).mapToObj(
"", RequiredType.NONE, null) {}).collect(Collectors.toList()); i -> new Command(null, false, Integer.toString(i), "",
RequiredType.NONE, null) {
}).collect(Collectors.toList());
} }
} }
@ -108,11 +114,11 @@ public final class Backup extends Command {
} }
@CommandDeclaration(command = "save", @CommandDeclaration(command = "save",
usage = "/plot backup save", usage = "/plot backup save",
description = "Create a plot backup", description = "Create a plot backup",
category = CommandCategory.SETTINGS, category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER, requiredType = RequiredType.PLAYER,
permission = "plots.backup.save") permission = "plots.backup.save")
public void save(final Command command, final PlotPlayer player, final String[] args, public void save(final Command command, final PlotPlayer player, final String[] args,
final RunnableVal3<Command, Runnable, Runnable> confirm, final RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone) { final RunnableVal2<Command, CommandResult> whenDone) {
@ -120,15 +126,20 @@ public final class Backup extends Command {
if (plot == null) { if (plot == null) {
sendMessage(player, Captions.NOT_IN_PLOT); sendMessage(player, Captions.NOT_IN_PLOT);
} else if (!plot.hasOwner()) { } else if (!plot.hasOwner()) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_UNOWNED.getTranslated()); sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
Captions.GENERIC_UNOWNED.getTranslated());
} else if (plot.isMerged()) { } else if (plot.isMerged()) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_MERGED.getTranslated()); sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
} else if (!plot.isOwner(player.getUUID()) && !Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_BACKUP_OTHER)) { Captions.GENERIC_MERGED.getTranslated());
} else if (!plot.isOwner(player.getUUID()) && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_BACKUP_OTHER)) {
sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_ADMIN_BACKUP_OTHER); sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_ADMIN_BACKUP_OTHER);
} else { } else {
final BackupProfile backupProfile = Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot); final BackupProfile backupProfile =
Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot);
if (backupProfile instanceof NullBackupProfile) { if (backupProfile instanceof NullBackupProfile) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_OTHER.getTranslated()); sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
Captions.GENERIC_OTHER.getTranslated());
} else { } else {
backupProfile.createBackup().whenComplete((backup, throwable) -> { backupProfile.createBackup().whenComplete((backup, throwable) -> {
if (throwable != null) { if (throwable != null) {
@ -151,40 +162,47 @@ public final class Backup extends Command {
public void list(final Command command, final PlotPlayer player, final String[] args, public void list(final Command command, final PlotPlayer player, final String[] args,
final RunnableVal3<Command, Runnable, Runnable> confirm, final RunnableVal3<Command, Runnable, Runnable> confirm,
final RunnableVal2<Command, CommandResult> whenDone) { final RunnableVal2<Command, CommandResult> whenDone) {
final Plot plot = player.getCurrentPlot(); final Plot plot = player.getCurrentPlot();
if (plot == null) { if (plot == null) {
sendMessage(player, Captions.NOT_IN_PLOT); sendMessage(player, Captions.NOT_IN_PLOT);
} else if (!plot.hasOwner()) { } else if (!plot.hasOwner()) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_UNOWNED.getTranslated()); sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
} else if (plot.isMerged()) { Captions.GENERIC_UNOWNED.getTranslated());
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_MERGED.getTranslated()); } else if (plot.isMerged()) {
} else if (!plot.isOwner(player.getUUID()) && !Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_BACKUP_OTHER)) { sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_ADMIN_BACKUP_OTHER); Captions.GENERIC_MERGED.getTranslated());
} else if (!plot.isOwner(player.getUUID()) && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_BACKUP_OTHER)) {
sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_ADMIN_BACKUP_OTHER);
} else {
final BackupProfile backupProfile =
Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot);
if (backupProfile instanceof NullBackupProfile) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
Captions.GENERIC_OTHER.getTranslated());
} else { } else {
final BackupProfile backupProfile = Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot); backupProfile.listBackups().whenComplete((backups, throwable) -> {
if (backupProfile instanceof NullBackupProfile) { if (throwable != null) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_OTHER.getTranslated()); sendMessage(player, Captions.BACKUP_LIST_FAILED, throwable.getMessage());
} else { throwable.printStackTrace();
backupProfile.listBackups().whenComplete((backups, throwable) -> { } else {
if (throwable != null) { sendMessage(player, Captions.BACKUP_LIST_HEADER,
sendMessage(player, Captions.BACKUP_LIST_FAILED, throwable.getMessage()); plot.getId().toCommaSeparatedString());
throwable.printStackTrace(); try {
} else { for (int i = 0; i < backups.size(); i++) {
sendMessage(player, Captions.BACKUP_LIST_HEADER, plot.getId().toCommaSeparatedString()); sendMessage(player, Captions.BACKUP_LIST_ENTRY,
try { Integer.toString(i + 1), DateTimeFormatter.RFC_1123_DATE_TIME
for (int i = 0; i < backups.size(); i++) { .format(ZonedDateTime.ofInstant(
sendMessage(player, Captions.BACKUP_LIST_ENTRY, Integer.toString(i + 1), Instant.ofEpochMilli(backups.get(i).getCreationTime()),
DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime ZoneId.systemDefault())));
.ofInstant(Instant.ofEpochMilli(backups.get(i).getCreationTime()), ZoneId
.systemDefault())));
}
} catch (final Exception e) {
e.printStackTrace();
} }
} catch (final Exception e) {
e.printStackTrace();
} }
}); }
} });
} }
}
} }
@CommandDeclaration(command = "load", @CommandDeclaration(command = "load",
@ -200,11 +218,14 @@ public final class Backup extends Command {
if (plot == null) { if (plot == null) {
sendMessage(player, Captions.NOT_IN_PLOT); sendMessage(player, Captions.NOT_IN_PLOT);
} else if (!plot.hasOwner()) { } else if (!plot.hasOwner()) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_UNOWNED.getTranslated()); sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
Captions.GENERIC_UNOWNED.getTranslated());
} else if (plot.isMerged()) { } else if (plot.isMerged()) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_MERGED.getTranslated()); sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
Captions.GENERIC_MERGED.getTranslated());
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, "merged"); sendMessage(player, Captions.BACKUP_IMPOSSIBLE, "merged");
} else if (!plot.isOwner(player.getUUID()) && !Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_BACKUP_OTHER)) { } else if (!plot.isOwner(player.getUUID()) && !Permissions
.hasPermission(player, Captions.PERMISSION_ADMIN_BACKUP_OTHER)) {
sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_ADMIN_BACKUP_OTHER); sendMessage(player, Captions.NO_PERMISSION, Captions.PERMISSION_ADMIN_BACKUP_OTHER);
} else if (args.length == 0) { } else if (args.length == 0) {
sendMessage(player, Captions.BACKUP_LOAD_USAGE); sendMessage(player, Captions.BACKUP_LOAD_USAGE);
@ -216,9 +237,11 @@ public final class Backup extends Command {
sendMessage(player, Captions.NOT_A_NUMBER, args[0]); sendMessage(player, Captions.NOT_A_NUMBER, args[0]);
return; return;
} }
final BackupProfile backupProfile = Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot); final BackupProfile backupProfile =
Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(plot);
if (backupProfile instanceof NullBackupProfile) { if (backupProfile instanceof NullBackupProfile) {
sendMessage(player, Captions.BACKUP_IMPOSSIBLE, Captions.GENERIC_OTHER.getTranslated()); sendMessage(player, Captions.BACKUP_IMPOSSIBLE,
Captions.GENERIC_OTHER.getTranslated());
} else { } else {
backupProfile.listBackups().whenComplete((backups, throwable) -> { backupProfile.listBackups().whenComplete((backups, throwable) -> {
if (throwable != null) { if (throwable != null) {
@ -226,20 +249,26 @@ public final class Backup extends Command {
throwable.printStackTrace(); throwable.printStackTrace();
} else { } else {
if (number < 1 || number > backups.size()) { if (number < 1 || number > backups.size()) {
sendMessage(player, Captions.BACKUP_LOAD_FAILURE, Captions.GENERIC_INVALID_CHOICE.getTranslated()); sendMessage(player, Captions.BACKUP_LOAD_FAILURE,
Captions.GENERIC_INVALID_CHOICE.getTranslated());
} else { } else {
final com.plotsquared.core.backup.Backup backup = backups.get(number - 1); final com.plotsquared.core.backup.Backup backup =
if (backup == null || backup.getFile() == null || !Files.exists(backup.getFile())) { backups.get(number - 1);
sendMessage(player, Captions.BACKUP_LOAD_FAILURE, Captions.GENERIC_INVALID_CHOICE.getTranslated()); if (backup == null || backup.getFile() == null || !Files
.exists(backup.getFile())) {
sendMessage(player, Captions.BACKUP_LOAD_FAILURE,
Captions.GENERIC_INVALID_CHOICE.getTranslated());
} else { } else {
CmdConfirm.addPending(player, "/plot backup load " + number, () -> CmdConfirm.addPending(player, "/plot backup load " + number,
backupProfile.restoreBackup(backup).whenComplete((n, error) -> { () -> backupProfile.restoreBackup(backup)
if (error != null) { .whenComplete((n, error) -> {
sendMessage(player, Captions.BACKUP_LOAD_FAILURE, error.getMessage()); if (error != null) {
} else { sendMessage(player, Captions.BACKUP_LOAD_FAILURE,
sendMessage(player, Captions.BACKUP_LOAD_SUCCESS); error.getMessage());
} } else {
})); sendMessage(player, Captions.BACKUP_LOAD_SUCCESS);
}
}));
} }
} }
} }

View File

@ -74,12 +74,14 @@ public class Biome extends SetCommand {
return true; return true;
} }
@Override public Collection<Command> tab(final PlotPlayer player, final String[] args, final boolean space) { @Override
public Collection<Command> tab(final PlotPlayer player, final String[] args,
final boolean space) {
return SuggestionHelper.getNamespacedRegistrySuggestions(BiomeType.REGISTRY, args[0]) return SuggestionHelper.getNamespacedRegistrySuggestions(BiomeType.REGISTRY, args[0])
.map(value -> value.toLowerCase(Locale.ENGLISH).replace("minecraft:", "")) .map(value -> value.toLowerCase(Locale.ENGLISH).replace("minecraft:", ""))
.filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH)))
.map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {}) .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {
.collect(Collectors.toList()); }).collect(Collectors.toList());
} }
} }

View File

@ -91,9 +91,10 @@ public class Clear extends Command {
plot.removeRunning(); plot.removeRunning();
// If the state changes, then mark it as no longer done // If the state changes, then mark it as no longer done
if (DoneFlag.isDone(plot)) { if (DoneFlag.isDone(plot)) {
PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(DoneFlag.class); PlotFlag<?, ?> plotFlag =
PlotFlagRemoveEvent event = plot.getFlagContainer().getFlag(DoneFlag.class);
PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot); PlotFlagRemoveEvent event = PlotSquared.get().getEventDispatcher()
.callFlagRemove(plotFlag, plot);
if (event.getEventResult() != Result.DENY) { if (event.getEventResult() != Result.DENY) {
plot.removeFlag(event.getFlag()); plot.removeFlag(event.getFlag());
} }
@ -101,8 +102,8 @@ public class Clear extends Command {
if (!plot.getFlag(AnalysisFlag.class).isEmpty()) { if (!plot.getFlag(AnalysisFlag.class).isEmpty()) {
PlotFlag<?, ?> plotFlag = PlotFlag<?, ?> plotFlag =
plot.getFlagContainer().getFlag(AnalysisFlag.class); plot.getFlagContainer().getFlag(AnalysisFlag.class);
PlotFlagRemoveEvent event = PlotFlagRemoveEvent event = PlotSquared.get().getEventDispatcher()
PlotSquared.get().getEventDispatcher().callFlagRemove(plotFlag, plot); .callFlagRemove(plotFlag, plot);
if (event.getEventResult() != Result.DENY) { if (event.getEventResult() != Result.DENY) {
plot.removeFlag(event.getFlag()); plot.removeFlag(event.getFlag());
} }

View File

@ -28,8 +28,8 @@ package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.entity.EntityCategories; import com.plotsquared.core.util.entity.EntityCategories;
import com.plotsquared.core.util.entity.EntityCategory; import com.plotsquared.core.util.entity.EntityCategory;
@ -59,7 +59,7 @@ public class Debug extends SubCommand {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
MainUtil.sendMessage(player, "Fetching loaded chunks..."); MainUtil.sendMessage(player, "Fetching loaded chunks...");
TaskManager.runTaskAsync(() -> MainUtil.sendMessage(player, TaskManager.runTaskAsync(() -> MainUtil.sendMessage(player,
"Loaded chunks: " + ChunkManager.manager "Loaded chunks: " + RegionManager.manager
.getChunkChunks(player.getLocation().getWorld()).size() + "(" + ( .getChunkChunks(player.getLocation().getWorld()).size() + "(" + (
System.currentTimeMillis() - start) + "ms) using thread: " + Thread System.currentTimeMillis() - start) + "ms) using thread: " + Thread
.currentThread().getName())); .currentThread().getName()));

View File

@ -31,7 +31,6 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.PremiumVerification; import com.plotsquared.core.util.PremiumVerification;
import com.plotsquared.core.util.net.IncendoPaster; import com.plotsquared.core.util.net.IncendoPaster;
@ -82,7 +81,8 @@ public class DebugPaste extends SubCommand {
"# Welcome to this paste\n# It is meant to provide us at IntellectualSites with better information about your " "# Welcome to this paste\n# It is meant to provide us at IntellectualSites with better information about your "
+ "problem\n\n"); + "problem\n\n");
b.append("# PlotSquared Information\n"); b.append("# PlotSquared Information\n");
b.append("PlotSquared Version: ").append(PlotSquared.get().getVersion()).append("\n"); b.append("PlotSquared Version: ").append(PlotSquared.get().getVersion())
.append("\n");
b.append("Resource ID: ").append(PremiumVerification.getResourceID()).append("\n"); b.append("Resource ID: ").append(PremiumVerification.getResourceID()).append("\n");
b.append("Download ID: ").append(PremiumVerification.getDownloadID()).append("\n"); b.append("Download ID: ").append(PremiumVerification.getDownloadID()).append("\n");
b.append("This PlotSquared version is licensed to the spigot user ") b.append("This PlotSquared version is licensed to the spigot user ")

View File

@ -81,8 +81,8 @@ public class Set extends SubCommand {
StringMan.join(Arrays.copyOfRange(args, 1, args.length), ",").trim(); StringMan.join(Arrays.copyOfRange(args, 1, args.length), ",").trim();
final List<String> forbiddenTypes = Settings.General.INVALID_BLOCKS; final List<String> forbiddenTypes = Settings.General.INVALID_BLOCKS;
if (!Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_ALLOW_UNSAFE) && if (!Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_ALLOW_UNSAFE)
!forbiddenTypes.isEmpty()) { && !forbiddenTypes.isEmpty()) {
for (String forbiddenType : forbiddenTypes) { for (String forbiddenType : forbiddenTypes) {
forbiddenType = forbiddenType.toLowerCase(Locale.ENGLISH); forbiddenType = forbiddenType.toLowerCase(Locale.ENGLISH);
if (forbiddenType.startsWith("minecraft:")) { if (forbiddenType.startsWith("minecraft:")) {
@ -96,11 +96,14 @@ public class Set extends SubCommand {
if (blockType.startsWith("##")) { if (blockType.startsWith("##")) {
try { try {
final BlockCategory category = BlockCategory.REGISTRY.get(blockType.substring(2).toLowerCase(Locale.ENGLISH)); final BlockCategory category = BlockCategory.REGISTRY
if (category == null || !category.contains(BlockTypes.get(forbiddenType))) { .get(blockType.substring(2).toLowerCase(Locale.ENGLISH));
if (category == null || !category
.contains(BlockTypes.get(forbiddenType))) {
continue; continue;
} }
} catch (final Throwable ignored) {} } catch (final Throwable ignored) {
}
} else if (!blockType.contains(forbiddenType)) { } else if (!blockType.contains(forbiddenType)) {
continue; continue;
} }
@ -147,13 +150,13 @@ public class Set extends SubCommand {
} }
@Override @Override
public Collection<Command> tab(final PlotPlayer player, final String[] args, final boolean space) { public Collection<Command> tab(final PlotPlayer player, final String[] args,
return PatternUtil.getSuggestions(player, StringMan.join(args, ",").trim()) final boolean space) {
.stream() return PatternUtil.getSuggestions(player, StringMan.join(args, ",").trim()).stream()
.map(value -> value.toLowerCase(Locale.ENGLISH).replace("minecraft:", "")) .map(value -> value.toLowerCase(Locale.ENGLISH).replace("minecraft:", ""))
.filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH)))
.map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {}) .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {
.collect(Collectors.toList()); }).collect(Collectors.toList());
} }
}; };
} }
@ -197,13 +200,16 @@ public class Set extends SubCommand {
return noArgs(player); return noArgs(player);
} }
@Override public Collection<Command> tab(final PlotPlayer player, final String[] args, final boolean space) { @Override
public Collection<Command> tab(final PlotPlayer player, final String[] args,
final boolean space) {
if (args.length == 1) { if (args.length == 1) {
return Stream return Stream
.of("biome", "alias", "home", "main", "floor", "air", "all", "border", "wall", "outline", "middle") .of("biome", "alias", "home", "main", "floor", "air", "all", "border", "wall",
"outline", "middle")
.filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH)))
.map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {}) .map(value -> new Command(null, false, value, "", RequiredType.NONE, null) {
.collect(Collectors.toList()); }).collect(Collectors.toList());
} else if (args.length > 1) { } else if (args.length > 1) {
// Additional checks // Additional checks
Plot plot = player.getCurrentPlot(); Plot plot = player.getCurrentPlot();
@ -223,7 +229,8 @@ public class Set extends SubCommand {
} }
// components // components
HashSet<String> components = new HashSet<>(Arrays.asList(plot.getManager().getPlotComponents(plot.getId()))); HashSet<String> components =
new HashSet<>(Arrays.asList(plot.getManager().getPlotComponents(plot.getId())));
if (components.contains(args[0].toLowerCase())) { if (components.contains(args[0].toLowerCase())) {
return this.component.tab(player, newArgs, space); return this.component.tab(player, newArgs, space);
} }

View File

@ -125,7 +125,8 @@ public class Setup extends SubCommand {
case 0: // choose generator case 0: // choose generator
if (args.length != 1 || !SetupUtils.generators.containsKey(args[0])) { if (args.length != 1 || !SetupUtils.generators.containsKey(args[0])) {
String prefix = "\n&8 - &7"; String prefix = "\n&8 - &7";
MainUtil.sendMessage(player, Captions.SETUP_WORLD_GENERATOR_ERROR + prefix + StringMan MainUtil.sendMessage(player,
Captions.SETUP_WORLD_GENERATOR_ERROR + prefix + StringMan
.join(SetupUtils.generators.keySet(), prefix) .join(SetupUtils.generators.keySet(), prefix)
.replaceAll(PlotSquared.imp().getPluginName(), .replaceAll(PlotSquared.imp().getPluginName(),
"&2" + PlotSquared.imp().getPluginName())); "&2" + PlotSquared.imp().getPluginName()));
@ -247,8 +248,7 @@ public class Setup extends SubCommand {
return false; return false;
} }
if (id.x <= object.min.x || id.y <= object.min.y) { if (id.x <= object.min.x || id.y <= object.min.y) {
MainUtil MainUtil.sendMessage(player, Captions.SETUP_AREA_PLOT_ID_GREATER_THAN_MINIMUM);
.sendMessage(player, Captions.SETUP_AREA_PLOT_ID_GREATER_THAN_MINIMUM);
return false; return false;
} }
object.max = id; object.max = id;
@ -259,7 +259,8 @@ public class Setup extends SubCommand {
Optional<PlotAreaTerrainType> optTerrain; Optional<PlotAreaTerrainType> optTerrain;
if (args.length != 1 || !(optTerrain = PlotAreaTerrainType.fromString(args[0])) if (args.length != 1 || !(optTerrain = PlotAreaTerrainType.fromString(args[0]))
.isPresent()) { .isPresent()) {
MainUtil.sendMessage(player, Captions.SETUP_PARTIAL_AREA_ERROR, Captions.SETUP_PARTIAL_AREA); MainUtil.sendMessage(player, Captions.SETUP_PARTIAL_AREA_ERROR,
Captions.SETUP_PARTIAL_AREA);
return false; return false;
} }
object.terrain = optTerrain.get(); object.terrain = optTerrain.get();

View File

@ -33,8 +33,8 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.expiration.ExpireManager; import com.plotsquared.core.plot.expiration.ExpireManager;
import com.plotsquared.core.queue.GlobalBlockQueue; import com.plotsquared.core.queue.GlobalBlockQueue;
import com.plotsquared.core.queue.LocalBlockQueue; import com.plotsquared.core.queue.LocalBlockQueue;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.RegionUtil; import com.plotsquared.core.util.RegionUtil;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
@ -133,7 +133,7 @@ public class Trim extends SubCommand {
if (ExpireManager.IMP != null) { if (ExpireManager.IMP != null) {
plots.removeAll(ExpireManager.IMP.getPendingExpired()); plots.removeAll(ExpireManager.IMP.getPendingExpired());
} }
result.value1 = new HashSet<>(ChunkManager.manager.getChunkChunks(world)); result.value1 = new HashSet<>(RegionManager.manager.getChunkChunks(world));
result.value2 = new HashSet<>(); result.value2 = new HashSet<>();
MainUtil.sendMessage(null, " - MCA #: " + result.value1.size()); MainUtil.sendMessage(null, " - MCA #: " + result.value1.size());
MainUtil.sendMessage(null, " - CHUNKS: " + (result.value1.size() * 1024) + " (max)"); MainUtil.sendMessage(null, " - CHUNKS: " + (result.value1.size() * 1024) + " (max)");
@ -238,7 +238,7 @@ public class Trim extends SubCommand {
player.sendMessage("Trim done!"); player.sendMessage("Trim done!");
}; };
} }
ChunkManager.manager.deleteRegionFiles(world, viable, regenTask); RegionManager.manager.deleteRegionFiles(world, viable, regenTask);
} }
}); });

View File

@ -256,7 +256,8 @@ public class Settings extends Config {
"birch_trapdoor", "birch_sapling", "birch_sign", "birch_wall_sign", "birch_leaves", "birch_trapdoor", "birch_sapling", "birch_sign", "birch_wall_sign", "birch_leaves",
// Dark Oak Stuff // Dark Oak Stuff
"dark_oak_button", "dark_oak_fence_gate", "dark_oak_door", "dark_oak_pressure_plate", "dark_oak_button", "dark_oak_fence_gate", "dark_oak_door", "dark_oak_pressure_plate",
"dark_oak_trapdoor", "dark_oak_sapling", "dark_oak_sign", "dark_oak_wall_sign", "dark_oak_leaves", "dark_oak_trapdoor", "dark_oak_sapling", "dark_oak_sign", "dark_oak_wall_sign",
"dark_oak_leaves",
// Jungle Stuff // Jungle Stuff
"jungle_button", "jungle_fence_gate", "jungle_door", "jungle_pressure_plate", "jungle_button", "jungle_fence_gate", "jungle_door", "jungle_pressure_plate",
"jungle_trapdoor", "jungle_sapling", "jungle_sign", "jungle_wall_sign", "jungle_leaves", "jungle_trapdoor", "jungle_sapling", "jungle_sign", "jungle_wall_sign", "jungle_leaves",
@ -430,8 +431,8 @@ public class Settings extends Config {
public static final class Confirmation { public static final class Confirmation {
@Comment("Timeout before a confirmation prompt expires") public static int CONFIRMATION_TIMEOUT_SECONDS = @Comment("Timeout before a confirmation prompt expires") public static int
20; CONFIRMATION_TIMEOUT_SECONDS = 20;
} }

View File

@ -1963,7 +1963,8 @@ public class SQLManager implements AbstractDB {
try (final ResultSet resultSet = statement try (final ResultSet resultSet = statement
.executeQuery("SELECT * FROM `" + this.prefix + "plot_flags`")) { .executeQuery("SELECT * FROM `" + this.prefix + "plot_flags`")) {
BlockTypeListFlag.skipCategoryVerification = true; // allow invalid tags, as initialized lazily BlockTypeListFlag.skipCategoryVerification =
true; // allow invalid tags, as initialized lazily
final ArrayList<Integer> toDelete = new ArrayList<>(); final ArrayList<Integer> toDelete = new ArrayList<>();
final Map<Plot, Collection<PlotFlag<?, ?>>> invalidFlags = new HashMap<>(); final Map<Plot, Collection<PlotFlag<?, ?>>> invalidFlags = new HashMap<>();
while (resultSet.next()) { while (resultSet.next()) {
@ -2001,7 +2002,8 @@ public class SQLManager implements AbstractDB {
+ " in `plot_flags` does not exist. Create this plot or set `database-purger: true` in the settings.yml."); + " in `plot_flags` does not exist. Create this plot or set `database-purger: true` in the settings.yml.");
} }
} }
BlockTypeListFlag.skipCategoryVerification = false; // don't allow invalid tags anymore BlockTypeListFlag.skipCategoryVerification =
false; // don't allow invalid tags anymore
if (Settings.Enabled_Components.DATABASE_PURGER) { if (Settings.Enabled_Components.DATABASE_PURGER) {
for (final Map.Entry<Plot, Collection<PlotFlag<?, ?>>> plotFlagEntry : invalidFlags for (final Map.Entry<Plot, Collection<PlotFlag<?, ?>>> plotFlagEntry : invalidFlags
.entrySet()) { .entrySet()) {

View File

@ -25,19 +25,14 @@
*/ */
package com.plotsquared.core.generator; package com.plotsquared.core.generator;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.ConfigurationNode; import com.plotsquared.core.configuration.ConfigurationNode;
import com.plotsquared.core.configuration.ConfigurationSection; import com.plotsquared.core.configuration.ConfigurationSection;
import com.plotsquared.core.configuration.ConfigurationUtil; import com.plotsquared.core.configuration.ConfigurationUtil;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.plot.BlockBucket; import com.plotsquared.core.plot.BlockBucket;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.block.BlockTypes;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Field;
import java.util.Locale;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public abstract class ClassicPlotWorld extends SquarePlotWorld { public abstract class ClassicPlotWorld extends SquarePlotWorld {

View File

@ -46,6 +46,7 @@ import com.plotsquared.core.queue.LocalBlockQueue;
import com.plotsquared.core.util.ChunkManager; import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.RegionUtil; import com.plotsquared.core.util.RegionUtil;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
@ -378,7 +379,7 @@ public abstract class HybridUtils {
return false; return false;
} }
HybridUtils.UPDATE = true; HybridUtils.UPDATE = true;
Set<BlockVector2> regions = ChunkManager.manager.getChunkChunks(area.getWorldName()); Set<BlockVector2> regions = RegionManager.manager.getChunkChunks(area.getWorldName());
return scheduleRoadUpdate(area, regions, extend, new HashSet<>()); return scheduleRoadUpdate(area, regions, extend, new HashSet<>());
} }
@ -388,7 +389,7 @@ public abstract class HybridUtils {
} }
HybridUtils.UPDATE = true; HybridUtils.UPDATE = true;
Set<BlockVector2> regions = new HashSet<>(); Set<BlockVector2> regions = new HashSet<>();
regions.add(ChunkManager.getRegion(plot.getCenterSynchronous())); regions.add(RegionManager.getRegion(plot.getCenterSynchronous()));
return scheduleRoadUpdate(plot.getArea(), regions, extend, new HashSet<>()); return scheduleRoadUpdate(plot.getArea(), regions, extend, new HashSet<>());
} }

View File

@ -31,8 +31,8 @@ import com.plotsquared.core.location.Location;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.RegionManager;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import java.util.Arrays; import java.util.Arrays;
@ -66,7 +66,7 @@ public abstract class SquarePlotManager extends GridPlotManager {
region.getMinimumPoint().getY(), region.getMinimumPoint().getZ()); region.getMinimumPoint().getY(), region.getMinimumPoint().getZ());
Location pos2 = new Location(plot.getWorldName(), region.getMaximumPoint().getX(), Location pos2 = new Location(plot.getWorldName(), region.getMaximumPoint().getX(),
region.getMaximumPoint().getY(), region.getMaximumPoint().getZ()); region.getMaximumPoint().getY(), region.getMaximumPoint().getZ());
ChunkManager.manager.regenerateRegion(pos1, pos2, false, this); RegionManager.manager.regenerateRegion(pos1, pos2, false, this);
} }
}; };
run.run(); run.run();

View File

@ -60,6 +60,7 @@ import com.plotsquared.core.util.ChunkManager;
import com.plotsquared.core.util.MainUtil; import com.plotsquared.core.util.MainUtil;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.Permissions; import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.RegionManager;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.StringWrapper; import com.plotsquared.core.util.StringWrapper;
import com.plotsquared.core.util.WorldUtil; import com.plotsquared.core.util.WorldUtil;
@ -98,7 +99,6 @@ import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -944,7 +944,7 @@ public class Plot {
Runnable run = () -> { Runnable run = () -> {
for (CuboidRegion region : regions) { for (CuboidRegion region : regions) {
Location[] corners = MainUtil.getCorners(getWorldName(), region); Location[] corners = MainUtil.getCorners(getWorldName(), region);
ChunkManager.manager.clearAllEntities(corners[0], corners[1]); RegionManager.manager.clearAllEntities(corners[0], corners[1]);
} }
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
}; };
@ -961,7 +961,7 @@ public class Plot {
Plot current = queue.poll(); Plot current = queue.poll();
if (Plot.this.area.getTerrain() != PlotAreaTerrainType.NONE) { if (Plot.this.area.getTerrain() != PlotAreaTerrainType.NONE) {
try { try {
ChunkManager.manager RegionManager.manager
.regenerateRegion(current.getBottomAbs(), current.getTopAbs(), false, .regenerateRegion(current.getBottomAbs(), current.getTopAbs(), false,
this); this);
} catch (UnsupportedOperationException exception) { } catch (UnsupportedOperationException exception) {
@ -995,39 +995,10 @@ public class Plot {
Runnable run = new Runnable() { Runnable run = new Runnable() {
@Override public void run() { @Override public void run() {
if (regions.isEmpty()) { if (regions.isEmpty()) {
Plot.this.refreshChunks();
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
return;
} }
CuboidRegion region = regions.poll(); CuboidRegion region = regions.poll();
Location pos1 = RegionManager.manager.setBiome(region, extendBiome, biome, getWorldName(), this);
new Location(getWorldName(), region.getMinimumPoint().getX() - extendBiome,
region.getMinimumPoint().getY(),
region.getMinimumPoint().getZ() - extendBiome);
Location pos2 =
new Location(getWorldName(), region.getMaximumPoint().getX() + extendBiome,
region.getMaximumPoint().getY(),
region.getMaximumPoint().getZ() + extendBiome);
ChunkManager.chunkTask(pos1, pos2, new RunnableVal<int[]>() {
@Override public void run(int[] value) {
BlockVector2 loc = BlockVector2.at(value[0], value[1]);
long start = System.currentTimeMillis();
ChunkManager.manager.loadChunk(getWorldName(), loc, false);
long end = System.currentTimeMillis();
PlotSquared.debug(
"[Biome Operation] Loading chunk took: " + TimeUnit.MILLISECONDS
.toSeconds(end - start));
MainUtil.setBiome(getWorldName(), value[2], value[3], value[4], value[5],
biome);
start = System.currentTimeMillis();
ChunkManager.manager.unloadChunk(getWorldName(), loc, true);
end = System.currentTimeMillis();
PlotSquared.debug(
"[Biome Operation] Unloading chunk took: " + TimeUnit.MILLISECONDS
.toSeconds(end - start));
}
}, this, 5);
} }
}; };
run.run(); run.run();
@ -1279,7 +1250,7 @@ public class Plot {
* Count the entities in a plot * Count the entities in a plot
* *
* @return array of entity counts * @return array of entity counts
* @see ChunkManager#countEntities(Plot) * @see RegionManager#countEntities(Plot)
* 0 = Entity * 0 = Entity
* 1 = Animal * 1 = Animal
* 2 = Monster * 2 = Monster
@ -1290,7 +1261,7 @@ public class Plot {
public int[] countEntities() { public int[] countEntities() {
int[] count = new int[6]; int[] count = new int[6];
for (Plot current : this.getConnectedPlots()) { for (Plot current : this.getConnectedPlots()) {
int[] result = ChunkManager.manager.countEntities(current); int[] result = RegionManager.manager.countEntities(current);
count[CAP_ENTITY] += result[CAP_ENTITY]; count[CAP_ENTITY] += result[CAP_ENTITY];
count[CAP_ANIMAL] += result[CAP_ANIMAL]; count[CAP_ANIMAL] += result[CAP_ANIMAL];
count[CAP_MONSTER] += result[CAP_MONSTER]; count[CAP_MONSTER] += result[CAP_MONSTER];
@ -1362,7 +1333,8 @@ public class Plot {
if (Settings.Backup.DELETE_ON_UNCLAIM) { if (Settings.Backup.DELETE_ON_UNCLAIM) {
// Destroy all backups when the plot is unclaimed // Destroy all backups when the plot is unclaimed
Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(current).destroy(); Objects.requireNonNull(PlotSquared.imp()).getBackupManager().getProfile(current)
.destroy();
} }
getArea().removePlot(getId()); getArea().removePlot(getId());
@ -2055,7 +2027,7 @@ public class Plot {
Location top = this.getTopAbs(); Location top = this.getTopAbs();
Location pos1 = new Location(this.getWorldName(), top.getX(), 0, bot.getZ()); Location pos1 = new Location(this.getWorldName(), top.getX(), 0, bot.getZ());
Location pos2 = new Location(this.getWorldName(), bot.getX(), MAX_HEIGHT, top.getZ()); Location pos2 = new Location(this.getWorldName(), bot.getX(), MAX_HEIGHT, top.getZ());
ChunkManager.manager.regenerateRegion(pos1, pos2, true, null); RegionManager.manager.regenerateRegion(pos1, pos2, true, null);
} else if (this.area.getTerrain() } else if (this.area.getTerrain()
!= PlotAreaTerrainType.ALL) { // no road generated => no road to remove != PlotAreaTerrainType.ALL) { // no road generated => no road to remove
this.area.getPlotManager().removeRoadEast(this); this.area.getPlotManager().removeRoadEast(this);
@ -2497,7 +2469,7 @@ public class Plot {
Location top = this.getTopAbs(); Location top = this.getTopAbs();
Location pos1 = new Location(this.getWorldName(), bot.getX(), 0, top.getZ()); Location pos1 = new Location(this.getWorldName(), bot.getX(), 0, top.getZ());
Location pos2 = new Location(this.getWorldName(), top.getX(), MAX_HEIGHT, bot.getZ()); Location pos2 = new Location(this.getWorldName(), top.getX(), MAX_HEIGHT, bot.getZ());
ChunkManager.manager.regenerateRegion(pos1, pos2, true, null); RegionManager.manager.regenerateRegion(pos1, pos2, true, null);
} else if (this.area.getTerrain() } else if (this.area.getTerrain()
!= PlotAreaTerrainType.ALL) { // no road generated => no road to remove != PlotAreaTerrainType.ALL) { // no road generated => no road to remove
this.getManager().removeRoadSouth(this); this.getManager().removeRoadSouth(this);
@ -2675,7 +2647,7 @@ public class Plot {
Location pos2 = other.getBottomAbs().subtract(1, 0, 1); Location pos2 = other.getBottomAbs().subtract(1, 0, 1);
pos1.setY(0); pos1.setY(0);
pos2.setY(MAX_HEIGHT); pos2.setY(MAX_HEIGHT);
ChunkManager.manager.regenerateRegion(pos1, pos2, true, null); RegionManager.manager.regenerateRegion(pos1, pos2, true, null);
} else if (this.area.getTerrain() } else if (this.area.getTerrain()
!= PlotAreaTerrainType.ALL) { // no road generated => no road to remove != PlotAreaTerrainType.ALL) { // no road generated => no road to remove
this.area.getPlotManager().removeRoadSouthEast(this); this.area.getPlotManager().removeRoadSouthEast(this);
@ -3319,7 +3291,7 @@ public class Plot {
Location pos4 = pos2.clone().add(offsetX, 0, offsetZ); Location pos4 = pos2.clone().add(offsetX, 0, offsetZ);
pos3.setWorld(destination.getWorldName()); pos3.setWorld(destination.getWorldName());
pos4.setWorld(destination.getWorldName()); pos4.setWorld(destination.getWorldName());
ChunkManager.manager.swap(pos1, pos2, pos3, pos4, this); RegionManager.manager.swap(pos1, pos2, pos3, pos4, this);
} }
} }
}.run(); }.run();
@ -3351,7 +3323,7 @@ public class Plot {
final Location pos2 = corners[1]; final Location pos2 = corners[1];
Location newPos = pos1.clone().add(offsetX, 0, offsetZ); Location newPos = pos1.clone().add(offsetX, 0, offsetZ);
newPos.setWorld(destination.getWorldName()); newPos.setWorld(destination.getWorldName());
ChunkManager.manager.copyRegion(pos1, pos2, newPos, task); RegionManager.manager.copyRegion(pos1, pos2, newPos, task);
} }
}.run(); }.run();
} }
@ -3446,7 +3418,7 @@ public class Plot {
Location pos2 = corners[1]; Location pos2 = corners[1];
Location newPos = pos1.clone().add(offsetX, 0, offsetZ); Location newPos = pos1.clone().add(offsetX, 0, offsetZ);
newPos.setWorld(destination.getWorldName()); newPos.setWorld(destination.getWorldName());
ChunkManager.manager.copyRegion(pos1, pos2, newPos, this); RegionManager.manager.copyRegion(pos1, pos2, newPos, this);
} }
}; };
run.run(); run.run();

View File

@ -146,9 +146,11 @@ public class FlagContainer {
this.updateSubscribers this.updateSubscribers
.forEach(subscriber -> subscriber.handle(flag, plotFlagUpdateType)); .forEach(subscriber -> subscriber.handle(flag, plotFlagUpdateType));
} catch (IllegalStateException e) { } catch (IllegalStateException e) {
PlotSquared.log(String.format("Flag '%s' (class: '%s') could not be added to the container" PlotSquared.log(String.format(
+ " because the flag name exceeded the allowed limit of 64 characters." "Flag '%s' (class: '%s') could not be added to the container"
+ " Please tell the developer of that flag to fix this.", flag.getName(), flag.getClass().getName())); + " because the flag name exceeded the allowed limit of 64 characters."
+ " Please tell the developer of that flag to fix this.", flag.getName(),
flag.getClass().getName()));
e.printStackTrace(); e.printStackTrace();
} }
} }

View File

@ -31,7 +31,7 @@ import org.jetbrains.annotations.NotNull;
public class KeepInventoryFlag extends BooleanFlag<KeepInventoryFlag> { public class KeepInventoryFlag extends BooleanFlag<KeepInventoryFlag> {
public static final KeepInventoryFlag KEEP_INVENTORY_TRUE = new KeepInventoryFlag(true); public static final KeepInventoryFlag KEEP_INVENTORY_TRUE = new KeepInventoryFlag(true);
public static final KeepInventoryFlag KEEP_INVENTORY_FALSE = new KeepInventoryFlag(false); public static final KeepInventoryFlag KEEP_INVENTORY_FALSE = new KeepInventoryFlag(false);
private KeepInventoryFlag(final boolean value) { private KeepInventoryFlag(final boolean value) {

View File

@ -31,8 +31,10 @@ import org.jetbrains.annotations.NotNull;
public class PreventCreativeCopyFlag extends BooleanFlag<PreventCreativeCopyFlag> { public class PreventCreativeCopyFlag extends BooleanFlag<PreventCreativeCopyFlag> {
public static final PreventCreativeCopyFlag PREVENT_CREATIVE_COPY_TRUE = new PreventCreativeCopyFlag(true); public static final PreventCreativeCopyFlag PREVENT_CREATIVE_COPY_TRUE =
public static final PreventCreativeCopyFlag PREVENT_CREATIVE_COPY_FALSE = new PreventCreativeCopyFlag(false); new PreventCreativeCopyFlag(true);
public static final PreventCreativeCopyFlag PREVENT_CREATIVE_COPY_FALSE =
new PreventCreativeCopyFlag(false);
private PreventCreativeCopyFlag(@NotNull final Boolean value) { private PreventCreativeCopyFlag(@NotNull final Boolean value) {
super(value, Captions.FLAG_DESCRIPTION_PREVENT_CREATIVE_COPY); super(value, Captions.FLAG_DESCRIPTION_PREVENT_CREATIVE_COPY);

View File

@ -87,8 +87,7 @@ public abstract class BlockTypeListFlag<F extends ListFlag<BlockTypeWrapper, F>>
private BlockTypeWrapper getCategory(final String blockString) throws FlagParseException { private BlockTypeWrapper getCategory(final String blockString) throws FlagParseException {
if (!blockString.startsWith("#")) { if (!blockString.startsWith("#")) {
throw new FlagParseException(this, blockString, throw new FlagParseException(this, blockString, Captions.FLAG_ERROR_INVALID_BLOCK);
Captions.FLAG_ERROR_INVALID_BLOCK);
} }
String categoryId = blockString.substring(1); String categoryId = blockString.substring(1);
BlockTypeWrapper blockTypeWrapper; BlockTypeWrapper blockTypeWrapper;
@ -97,8 +96,7 @@ public abstract class BlockTypeListFlag<F extends ListFlag<BlockTypeWrapper, F>>
} else { } else {
BlockCategory blockCategory = BlockCategory.REGISTRY.get(categoryId); BlockCategory blockCategory = BlockCategory.REGISTRY.get(categoryId);
if (blockCategory == null) { if (blockCategory == null) {
throw new FlagParseException(this, blockString, throw new FlagParseException(this, blockString, Captions.FLAG_ERROR_INVALID_BLOCK);
Captions.FLAG_ERROR_INVALID_BLOCK);
} }
blockTypeWrapper = BlockTypeWrapper.get(blockCategory); blockTypeWrapper = BlockTypeWrapper.get(blockCategory);
} }

View File

@ -109,9 +109,9 @@ public class BlockTypeWrapper {
* *
* @return the block category represented by this wrapper. * @return the block category represented by this wrapper.
*/ */
@Nullable @Nullable public BlockCategory getBlockCategory() {
public BlockCategory getBlockCategory() { if (this.blockCategory == null
if (this.blockCategory == null && this.blockCategoryId != null) { // only if name is available && this.blockCategoryId != null) { // only if name is available
this.blockCategory = BlockCategory.REGISTRY.get(this.blockCategoryId); this.blockCategory = BlockCategory.REGISTRY.get(this.blockCategoryId);
if (this.blockCategory == null && !BlockCategory.REGISTRY.values().isEmpty()) { if (this.blockCategory == null && !BlockCategory.REGISTRY.values().isEmpty()) {
PlotSquared.debug("- Block category #" + this.blockCategoryId + " does not exist"); PlotSquared.debug("- Block category #" + this.blockCategoryId + " does not exist");
@ -121,17 +121,17 @@ public class BlockTypeWrapper {
return this.blockCategory; return this.blockCategory;
} }
@Override @Override public boolean equals(final Object o) {
public boolean equals(final Object o) { if (this == o)
if (this == o) return true; return true;
if (o == null || getClass() != o.getClass()) return false; if (o == null || getClass() != o.getClass())
return false;
BlockTypeWrapper that = (BlockTypeWrapper) o; BlockTypeWrapper that = (BlockTypeWrapper) o;
return Objects.equal(this.blockType, that.blockType) && return Objects.equal(this.blockType, that.blockType) && Objects
Objects.equal(this.blockCategoryId, that.blockCategoryId); .equal(this.blockCategoryId, that.blockCategoryId);
} }
@Override @Override public int hashCode() {
public int hashCode() {
return Objects.hashCode(this.blockType, this.blockCategoryId); return Objects.hashCode(this.blockType, this.blockCategoryId);
} }
@ -143,7 +143,8 @@ public class BlockTypeWrapper {
} }
public static BlockTypeWrapper get(final BlockCategory blockCategory) { public static BlockTypeWrapper get(final BlockCategory blockCategory) {
return blockCategories.computeIfAbsent(blockCategory.getId(), id -> new BlockTypeWrapper(blockCategory)); return blockCategories
.computeIfAbsent(blockCategory.getId(), id -> new BlockTypeWrapper(blockCategory));
} }
public static BlockTypeWrapper get(final String blockCategoryId) { public static BlockTypeWrapper get(final String blockCategoryId) {
@ -159,8 +160,7 @@ public class BlockTypeWrapper {
super(id); super(id);
} }
@Override @Override public <B extends BlockStateHolder<B>> boolean contains(B blockStateHolder) {
public <B extends BlockStateHolder<B>> boolean contains(B blockStateHolder) {
return false; return false;
} }
} }

View File

@ -36,12 +36,8 @@ import com.plotsquared.core.util.task.TaskManager;
import com.sk89q.worldedit.math.BlockVector2; import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion; import com.sk89q.worldedit.regions.CuboidRegion;
import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@ -53,12 +49,6 @@ public abstract class ChunkManager {
new ConcurrentHashMap<>(); new ConcurrentHashMap<>();
public static ChunkManager manager = null; public static ChunkManager manager = null;
public static BlockVector2 getRegion(Location location) {
int x = location.getX() >> 9;
int z = location.getZ() >> 9;
return BlockVector2.at(x, z);
}
public static void setChunkInPlotArea(RunnableVal<ScopedLocalBlockQueue> force, public static void setChunkInPlotArea(RunnableVal<ScopedLocalBlockQueue> force,
RunnableVal<ScopedLocalBlockQueue> add, String world, BlockVector2 loc) { RunnableVal<ScopedLocalBlockQueue> add, String world, BlockVector2 loc) {
LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false); LocalBlockQueue queue = GlobalBlockQueue.IMP.getNewQueue(world, false);
@ -108,45 +98,6 @@ public abstract class ChunkManager {
return false; return false;
} }
public static void largeRegionTask(final String world, final CuboidRegion region,
final RunnableVal<BlockVector2> task, final Runnable whenDone) {
TaskManager.runTaskAsync(() -> {
HashSet<BlockVector2> chunks = new HashSet<>();
Set<BlockVector2> mcrs = manager.getChunkChunks(world);
for (BlockVector2 mcr : mcrs) {
int bx = mcr.getX() << 9;
int bz = mcr.getZ() << 9;
int tx = bx + 511;
int tz = bz + 511;
if (bx <= region.getMaximumPoint().getX() && tx >= region.getMinimumPoint().getX()
&& bz <= region.getMaximumPoint().getZ() && tz >= region.getMinimumPoint()
.getZ()) {
for (int x = bx >> 4; x <= (tx >> 4); x++) {
int cbx = x << 4;
int ctx = cbx + 15;
if (cbx <= region.getMaximumPoint().getX() && ctx >= region
.getMinimumPoint().getX()) {
for (int z = bz >> 4; z <= (tz >> 4); z++) {
int cbz = z << 4;
int ctz = cbz + 15;
if (cbz <= region.getMaximumPoint().getZ() && ctz >= region
.getMinimumPoint().getZ()) {
chunks.add(BlockVector2.at(x, z));
}
}
}
}
}
}
TaskManager.objectTask(chunks, new RunnableVal<BlockVector2>() {
@Override public void run(BlockVector2 value) {
manager.loadChunk(world, value, false).thenRun(() -> task.run(value));
}
}, whenDone);
});
}
public static void chunkTask(final Plot plot, final RunnableVal<int[]> task, public static void chunkTask(final Plot plot, final RunnableVal<int[]> task,
final Runnable whenDone, final int allocate) { final Runnable whenDone, final int allocate) {
final ArrayList<CuboidRegion> regions = new ArrayList<>(plot.getRegions()); final ArrayList<CuboidRegion> regions = new ArrayList<>(plot.getRegions());
@ -231,69 +182,10 @@ public abstract class ChunkManager {
}); });
} }
/**
* 0 = Entity
* 1 = Animal
* 2 = Monster
* 3 = Mob
* 4 = Boat
* 5 = Misc
*
* @param plot
* @return
*/
public abstract int[] countEntities(Plot plot);
public abstract CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force); public abstract CompletableFuture loadChunk(String world, BlockVector2 loc, boolean force);
public abstract void unloadChunk(String world, BlockVector2 loc, boolean save); public abstract void unloadChunk(String world, BlockVector2 loc, boolean save);
public Set<BlockVector2> getChunkChunks(String world) {
File folder =
new File(PlotSquared.get().IMP.getWorldContainer(), world + File.separator + "region");
File[] regionFiles = folder.listFiles();
if (regionFiles == null) {
throw new RuntimeException(
"Could not find worlds folder: " + folder + " ? (no read access?)");
}
HashSet<BlockVector2> chunks = new HashSet<>();
for (File file : regionFiles) {
String name = file.getName();
if (name.endsWith("mca")) {
String[] split = name.split("\\.");
try {
int x = Integer.parseInt(split[1]);
int z = Integer.parseInt(split[2]);
BlockVector2 loc = BlockVector2.at(x, z);
chunks.add(loc);
} catch (NumberFormatException ignored) {
}
}
}
return chunks;
}
public void deleteRegionFiles(String world, Collection<BlockVector2> chunks) {
deleteRegionFiles(world, chunks, null);
}
public void deleteRegionFiles(final String world, final Collection<BlockVector2> chunks,
final Runnable whenDone) {
TaskManager.runTaskAsync(() -> {
for (BlockVector2 loc : chunks) {
String directory =
world + File.separator + "region" + File.separator + "r." + loc.getX() + "."
+ loc.getZ() + ".mca";
File file = new File(PlotSquared.get().IMP.getWorldContainer(), directory);
PlotSquared.log("&6 - Deleting file: " + file.getName() + " (max 1024 chunks)");
if (file.exists()) {
file.delete();
}
}
TaskManager.runTask(whenDone);
});
}
public Plot hasPlot(String world, BlockVector2 chunk) { public Plot hasPlot(String world, BlockVector2 chunk) {
int x1 = chunk.getX() << 4; int x1 = chunk.getX() << 4;
int z1 = chunk.getZ() << 4; int z1 = chunk.getZ() << 4;
@ -309,27 +201,4 @@ public abstract class ChunkManager {
return plot; return plot;
} }
/**
* Copy a region to a new location (in the same world)
*/
public abstract boolean copyRegion(Location pos1, Location pos2, Location newPos,
Runnable whenDone);
/**
* Assumptions:<br>
* - pos1 and pos2 are in the same plot<br>
* It can be harmful to the world if parameters outside this scope are provided
*
* @param pos1
* @param pos2
* @param whenDone
* @return
*/
public abstract boolean regenerateRegion(Location pos1, Location pos2, boolean ignoreAugment,
Runnable whenDone);
public abstract void clearAllEntities(Location pos1, Location pos2);
public abstract void swap(Location bot1, Location top1, Location bot2, Location top2,
Runnable whenDone);
} }

View File

@ -0,0 +1,176 @@
/*
* _____ _ _ _____ _
* | __ \| | | | / ____| | |
* | |__) | | ___ | |_| (___ __ _ _ _ __ _ _ __ ___ __| |
* | ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` |
* | | | | (_) | |_ ____) | (_| | |_| | (_| | | | __/ (_| |
* |_| |_|\___/ \__|_____/ \__, |\__,_|\__,_|_| \___|\__,_|
* | |
* |_|
* PlotSquared plot management system for Minecraft
* Copyright (C) 2020 IntellectualSites
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.util;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.world.biome.BiomeType;
import java.io.File;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public abstract class RegionManager {
public static RegionManager manager = null;
public static BlockVector2 getRegion(Location location) {
int x = location.getX() >> 9;
int z = location.getZ() >> 9;
return BlockVector2.at(x, z);
}
public static void largeRegionTask(final String world, final CuboidRegion region,
final RunnableVal<BlockVector2> task, final Runnable whenDone) {
TaskManager.runTaskAsync(() -> {
HashSet<BlockVector2> chunks = new HashSet<>();
Set<BlockVector2> mcrs = manager.getChunkChunks(world);
for (BlockVector2 mcr : mcrs) {
int bx = mcr.getX() << 9;
int bz = mcr.getZ() << 9;
int tx = bx + 511;
int tz = bz + 511;
if (bx <= region.getMaximumPoint().getX() && tx >= region.getMinimumPoint().getX()
&& bz <= region.getMaximumPoint().getZ() && tz >= region.getMinimumPoint()
.getZ()) {
for (int x = bx >> 4; x <= (tx >> 4); x++) {
int cbx = x << 4;
int ctx = cbx + 15;
if (cbx <= region.getMaximumPoint().getX() && ctx >= region
.getMinimumPoint().getX()) {
for (int z = bz >> 4; z <= (tz >> 4); z++) {
int cbz = z << 4;
int ctz = cbz + 15;
if (cbz <= region.getMaximumPoint().getZ() && ctz >= region
.getMinimumPoint().getZ()) {
chunks.add(BlockVector2.at(x, z));
}
}
}
}
}
}
TaskManager.objectTask(chunks, new RunnableVal<BlockVector2>() {
@Override public void run(BlockVector2 value) {
ChunkManager.manager.loadChunk(world, value, false)
.thenRun(() -> task.run(value));
}
}, whenDone);
});
}
/**
* 0 = Entity
* 1 = Animal
* 2 = Monster
* 3 = Mob
* 4 = Boat
* 5 = Misc
*
* @param plot
* @return
*/
public abstract int[] countEntities(Plot plot);
public Set<BlockVector2> getChunkChunks(String world) {
File folder =
new File(PlotSquared.get().IMP.getWorldContainer(), world + File.separator + "region");
File[] regionFiles = folder.listFiles();
if (regionFiles == null) {
throw new RuntimeException(
"Could not find worlds folder: " + folder + " ? (no read access?)");
}
HashSet<BlockVector2> chunks = new HashSet<>();
for (File file : regionFiles) {
String name = file.getName();
if (name.endsWith("mca")) {
String[] split = name.split("\\.");
try {
int x = Integer.parseInt(split[1]);
int z = Integer.parseInt(split[2]);
BlockVector2 loc = BlockVector2.at(x, z);
chunks.add(loc);
} catch (NumberFormatException ignored) {
}
}
}
return chunks;
}
public void deleteRegionFiles(String world, Collection<BlockVector2> chunks) {
deleteRegionFiles(world, chunks, null);
}
public void deleteRegionFiles(final String world, final Collection<BlockVector2> chunks,
final Runnable whenDone) {
TaskManager.runTaskAsync(() -> {
for (BlockVector2 loc : chunks) {
String directory =
world + File.separator + "region" + File.separator + "r." + loc.getX() + "."
+ loc.getZ() + ".mca";
File file = new File(PlotSquared.get().IMP.getWorldContainer(), directory);
PlotSquared.log("&6 - Deleting file: " + file.getName() + " (max 1024 chunks)");
if (file.exists()) {
file.delete();
}
}
TaskManager.runTask(whenDone);
});
}
/**
* Copy a region to a new location (in the same world)
*/
public abstract boolean copyRegion(Location pos1, Location pos2, Location newPos,
Runnable whenDone);
/**
* Assumptions:<br>
* - pos1 and pos2 are in the same plot<br>
* It can be harmful to the world if parameters outside this scope are provided
*
* @param pos1
* @param pos2
* @param whenDone
* @return
*/
public abstract boolean regenerateRegion(Location pos1, Location pos2, boolean ignoreAugment,
Runnable whenDone);
public abstract void clearAllEntities(Location pos1, Location pos2);
public abstract void swap(Location bot1, Location top1, Location bot2, Location top2,
Runnable whenDone);
public abstract void setBiome(CuboidRegion region, int extendBiome, BiomeType biome,
String world, Runnable whenDone);
}

View File

@ -149,7 +149,7 @@ public abstract class WorldUtil {
int trx = top.getX() >> 9; int trx = top.getX() >> 9;
int trz = top.getZ() >> 9; int trz = top.getZ() >> 9;
Set<BlockVector2> files = Set<BlockVector2> files =
ChunkManager.manager.getChunkChunks(bot.getWorld()); RegionManager.manager.getChunkChunks(bot.getWorld());
for (BlockVector2 mca : files) { for (BlockVector2 mca : files) {
if (mca.getX() >= brx && mca.getX() <= trx && mca.getZ() >= brz if (mca.getX() >= brx && mca.getX() <= trx && mca.getZ() >= brz
&& mca.getZ() <= trz) { && mca.getZ() <= trz) {

View File

@ -28,7 +28,6 @@ package com.plotsquared.core.util.task;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.command.Auto; import com.plotsquared.core.command.Auto;
import com.plotsquared.core.configuration.Captions; import com.plotsquared.core.configuration.Captions;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.PlotMergeEvent; import com.plotsquared.core.events.PlotMergeEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Direction; import com.plotsquared.core.location.Direction;