mirror of
https://github.com/IntellectualSites/PlotSquared.git
synced 2024-11-26 07:06:44 +01:00
Merge pull request #2825 from IntellectualSites/tile-entity-cap
Fix chunk processing
This commit is contained in:
commit
dd852801cc
@ -266,7 +266,7 @@ public class ChunkListener implements Listener {
|
|||||||
long start = System.currentTimeMillis();
|
long start = System.currentTimeMillis();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (System.currentTimeMillis() - start < 250) {
|
while (System.currentTimeMillis() - start < 250) {
|
||||||
if (i >= tiles.length) {
|
if (i >= tiles.length - Settings.Chunk_Processor.MAX_TILES) {
|
||||||
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
|
Bukkit.getScheduler().cancelTask(TaskManager.tasks.get(currentIndex));
|
||||||
TaskManager.tasks.remove(currentIndex);
|
TaskManager.tasks.remove(currentIndex);
|
||||||
PlotSquared.debug("Successfully processed and unloaded chunk!");
|
PlotSquared.debug("Successfully processed and unloaded chunk!");
|
||||||
@ -287,11 +287,16 @@ public class ChunkListener implements Listener {
|
|||||||
Entity[] entities = chunk.getEntities();
|
Entity[] entities = chunk.getEntities();
|
||||||
BlockState[] tiles = chunk.getTileEntities();
|
BlockState[] tiles = chunk.getTileEntities();
|
||||||
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
|
if (entities.length > Settings.Chunk_Processor.MAX_ENTITIES) {
|
||||||
for (Entity ent : entities) {
|
int toRemove = entities.length - Settings.Chunk_Processor.MAX_ENTITIES;
|
||||||
if (!(ent instanceof Player)) {
|
int index = 0;
|
||||||
ent.remove();
|
while (toRemove > 0 && index < entities.length) {
|
||||||
|
final Entity entity = entities[index++];
|
||||||
|
if (!(entity instanceof Player)) {
|
||||||
|
entity.remove();
|
||||||
|
toRemove--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PlotSquared.debug(
|
PlotSquared.debug(
|
||||||
"PlotSquared detected unsafe chunk and processed: " + (chunk.getX() << 4) + "," + (
|
"PlotSquared detected unsafe chunk and processed: " + (chunk.getX() << 4) + "," + (
|
||||||
chunk.getX() << 4));
|
chunk.getX() << 4));
|
||||||
@ -304,8 +309,9 @@ public class ChunkListener implements Listener {
|
|||||||
cleanChunk(chunk);
|
cleanChunk(chunk);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for (BlockState tile : tiles) {
|
|
||||||
tile.getBlock().setType(Material.AIR, false);
|
for (int i = 0 ; i < (tiles.length - Settings.Chunk_Processor.MAX_TILES); i++) {
|
||||||
|
tiles[i].getBlock().setType(Material.AIR, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -33,6 +33,7 @@ import com.destroystokyo.paper.event.entity.SlimePathfindEvent;
|
|||||||
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
|
import com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent;
|
||||||
import com.plotsquared.bukkit.util.BukkitUtil;
|
import com.plotsquared.bukkit.util.BukkitUtil;
|
||||||
import com.plotsquared.core.PlotSquared;
|
import com.plotsquared.core.PlotSquared;
|
||||||
|
import com.plotsquared.core.configuration.Captions;
|
||||||
import com.plotsquared.core.configuration.Settings;
|
import com.plotsquared.core.configuration.Settings;
|
||||||
import com.plotsquared.core.location.Location;
|
import com.plotsquared.core.location.Location;
|
||||||
import com.plotsquared.core.player.PlotPlayer;
|
import com.plotsquared.core.player.PlotPlayer;
|
||||||
@ -41,6 +42,7 @@ import com.plotsquared.core.plot.PlotArea;
|
|||||||
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
|
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
|
||||||
import org.bukkit.Chunk;
|
import org.bukkit.Chunk;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.TileState;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
@ -48,7 +50,9 @@ import org.bukkit.entity.Projectile;
|
|||||||
import org.bukkit.entity.Slime;
|
import org.bukkit.entity.Slime;
|
||||||
import org.bukkit.entity.ThrownPotion;
|
import org.bukkit.entity.ThrownPotion;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.event.block.BlockPlaceEvent;
|
||||||
import org.bukkit.event.entity.CreatureSpawnEvent;
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.projectiles.ProjectileSource;
|
import org.bukkit.projectiles.ProjectileSource;
|
||||||
|
|
||||||
@ -252,6 +256,27 @@ public class PaperListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.HIGHEST) public void onBlockPlace(BlockPlaceEvent event) {
|
||||||
|
if (!Settings.Paper_Components.TILE_ENTITY_CHECK || !Settings.Enabled_Components.CHUNK_PROCESSOR) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!(event.getBlock().getState(false) instanceof TileState)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final Location location = BukkitUtil.getLocation(event.getBlock().getLocation());
|
||||||
|
final PlotArea plotArea = location.getPlotArea();
|
||||||
|
if (plotArea == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final int tileEntityCount = event.getBlock().getChunk().getTileEntities(false).length;
|
||||||
|
if (tileEntityCount >= Settings.Chunk_Processor.MAX_TILES) {
|
||||||
|
final PlotPlayer plotPlayer = BukkitUtil.getPlayer(event.getPlayer());
|
||||||
|
Captions.TILE_ENTITY_CAP_REACHED.send(plotPlayer, Settings.Chunk_Processor.MAX_TILES);
|
||||||
|
event.setCancelled(true);
|
||||||
|
event.setBuild(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Unsure if this will be any performance improvement over the spigot version,
|
* Unsure if this will be any performance improvement over the spigot version,
|
||||||
* but here it is anyway :)
|
* but here it is anyway :)
|
||||||
|
@ -42,9 +42,13 @@ import com.plotsquared.core.util.task.TaskManager;
|
|||||||
import com.plotsquared.core.util.uuid.UUIDHandler;
|
import com.plotsquared.core.util.uuid.UUIDHandler;
|
||||||
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.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockCategories;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
import io.papermc.lib.PaperLib;
|
import io.papermc.lib.PaperLib;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
@ -95,10 +99,12 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.IntConsumer;
|
import java.util.function.IntConsumer;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@SuppressWarnings({"unused", "WeakerAccess"})
|
@SuppressWarnings({"unused", "WeakerAccess"})
|
||||||
public class BukkitUtil extends WorldUtil {
|
public class BukkitUtil extends WorldUtil {
|
||||||
@ -638,6 +644,38 @@ public class BukkitUtil extends WorldUtil {
|
|||||||
return types;
|
return types;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final Collection<BlockType> tileEntityTypes = new HashSet<>();
|
||||||
|
@Override public Collection<BlockType> getTileEntityTypes() {
|
||||||
|
if (this.tileEntityTypes.isEmpty()) {
|
||||||
|
// Categories
|
||||||
|
tileEntityTypes.addAll(BlockCategories.BANNERS.getAll());
|
||||||
|
tileEntityTypes.addAll(BlockCategories.SIGNS.getAll());
|
||||||
|
tileEntityTypes.addAll(BlockCategories.BEDS.getAll());
|
||||||
|
tileEntityTypes.addAll(BlockCategories.FLOWER_POTS.getAll());
|
||||||
|
// Individual Types
|
||||||
|
// Add these from strings
|
||||||
|
Stream.of("barrel", "beacon", "beehive", "bee_nest", "bell", "blast_furnace",
|
||||||
|
"brewing_stand", "campfire", "chest", "ender_chest", "trapped_chest",
|
||||||
|
"command_block", "end_gateway", "hopper", "jigsaw", "jubekox",
|
||||||
|
"lectern", "note_block", "black_shulker_box", "blue_shulker_box",
|
||||||
|
"brown_shulker_box", "cyan_shulker_box", "gray_shulker_box", "green_shulker_box",
|
||||||
|
"light_blue_shulker_box", "light_gray_shulker_box", "lime_shulker_box",
|
||||||
|
"magenta_shulker_box", "orange_shulker_box", "pink_shulker_box",
|
||||||
|
"purple_shulker_box", "red_shulker_box", "shulker_box", "white_shulker_box",
|
||||||
|
"yellow_shulker_box", "smoker", "structure_block", "structure_void")
|
||||||
|
.map(BlockTypes::get)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.forEach(tileEntityTypes::add);
|
||||||
|
}
|
||||||
|
return this.tileEntityTypes;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getTileEntityCount(String world, BlockVector2 chunk) {
|
||||||
|
return Bukkit.getWorld(world).getChunkAt(chunk.getBlockX(), chunk.getBlockZ())
|
||||||
|
.getTileEntities().length;
|
||||||
|
}
|
||||||
|
|
||||||
private static void ensureLoaded(final String world, final int x, final int z,
|
private static void ensureLoaded(final String world, final int x, final int z,
|
||||||
final Consumer<Chunk> chunkConsumer) {
|
final Consumer<Chunk> chunkConsumer) {
|
||||||
PaperLib.getChunkAtAsync(getWorld(world), x >> 4, z >> 4, true)
|
PaperLib.getChunkAtAsync(getWorld(world), x >> 4, z >> 4, true)
|
||||||
|
@ -37,8 +37,10 @@ import com.plotsquared.core.util.MainUtil;
|
|||||||
import com.plotsquared.core.util.PatternUtil;
|
import com.plotsquared.core.util.PatternUtil;
|
||||||
import com.plotsquared.core.util.Permissions;
|
import com.plotsquared.core.util.Permissions;
|
||||||
import com.plotsquared.core.util.StringMan;
|
import com.plotsquared.core.util.StringMan;
|
||||||
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
import com.sk89q.worldedit.function.pattern.Pattern;
|
import com.sk89q.worldedit.function.pattern.Pattern;
|
||||||
import com.sk89q.worldedit.world.block.BlockCategory;
|
import com.sk89q.worldedit.world.block.BlockCategory;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import com.sk89q.worldedit.world.block.BlockTypes;
|
import com.sk89q.worldedit.world.block.BlockTypes;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -80,9 +82,15 @@ public class Set extends SubCommand {
|
|||||||
String material =
|
String material =
|
||||||
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 = new ArrayList<>(Settings.General.INVALID_BLOCKS);
|
||||||
if (!Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_ALLOW_UNSAFE)
|
|
||||||
&& !forbiddenTypes.isEmpty()) {
|
if (Settings.Enabled_Components.CHUNK_PROCESSOR) {
|
||||||
|
forbiddenTypes.addAll(WorldUtil.IMP.getTileEntityTypes().stream().map(
|
||||||
|
BlockType::getName).collect(Collectors.toList()));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Permissions.hasPermission(player, Captions.PERMISSION_ADMIN_ALLOW_UNSAFE) &&
|
||||||
|
!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,10 +104,9 @@ public class Set extends SubCommand {
|
|||||||
|
|
||||||
if (blockType.startsWith("##")) {
|
if (blockType.startsWith("##")) {
|
||||||
try {
|
try {
|
||||||
final BlockCategory category = BlockCategory.REGISTRY
|
final BlockCategory category = BlockCategory.REGISTRY.get(blockType.substring(2)
|
||||||
.get(blockType.substring(2).toLowerCase(Locale.ENGLISH));
|
.replaceAll("[*^|]+", "").toLowerCase(Locale.ENGLISH));
|
||||||
if (category == null || !category
|
if (category == null || !category.contains(BlockTypes.get(forbiddenType))) {
|
||||||
.contains(BlockTypes.get(forbiddenType))) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} catch (final Throwable ignored) {
|
} catch (final Throwable ignored) {
|
||||||
|
@ -446,6 +446,7 @@ public enum Captions implements Caption {
|
|||||||
NOT_VALID_PLOT_WORLD("$2That is not a valid plot area (case sensitive)", "Errors"),
|
NOT_VALID_PLOT_WORLD("$2That is not a valid plot area (case sensitive)", "Errors"),
|
||||||
NO_PLOTS("$2You don't have any plots", "Errors"),
|
NO_PLOTS("$2You don't have any plots", "Errors"),
|
||||||
WAIT_FOR_TIMER("$2A set block timer is bound to either the current plot or you. Please wait for it to finish", "Errors"),
|
WAIT_FOR_TIMER("$2A set block timer is bound to either the current plot or you. Please wait for it to finish", "Errors"),
|
||||||
|
TILE_ENTITY_CAP_REACHED("$2The total number of tile entities in this chunk may not exceed $1%s", "Errors"),
|
||||||
//</editor-fold>
|
//</editor-fold>
|
||||||
DEBUG_REPORT_CREATED("$1Uploaded a full debug to: $1%url%", "Paste"),
|
DEBUG_REPORT_CREATED("$1Uploaded a full debug to: $1%url%", "Paste"),
|
||||||
PURGE_SUCCESS("$4Successfully purged %s plots", "Purge"),
|
PURGE_SUCCESS("$4Successfully purged %s plots", "Purge"),
|
||||||
|
@ -485,6 +485,8 @@ public class Settings extends Config {
|
|||||||
public static boolean SPAWNER_SPAWN = true;
|
public static boolean SPAWNER_SPAWN = true;
|
||||||
@Comment("Cancel entity spawns from tick spawn rates before they happen (performance buff)")
|
@Comment("Cancel entity spawns from tick spawn rates before they happen (performance buff)")
|
||||||
public static boolean CREATURE_SPAWN = true;
|
public static boolean CREATURE_SPAWN = true;
|
||||||
|
@Comment("Check the tile entity limit on block placement")
|
||||||
|
public static boolean TILE_ENTITY_CHECK = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,6 +29,7 @@ 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.util.WEManager;
|
import com.plotsquared.core.util.WEManager;
|
||||||
|
import com.plotsquared.core.util.WorldUtil;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.entity.BaseEntity;
|
import com.sk89q.worldedit.entity.BaseEntity;
|
||||||
import com.sk89q.worldedit.entity.Entity;
|
import com.sk89q.worldedit.entity.Entity;
|
||||||
@ -45,6 +46,8 @@ import com.sk89q.worldedit.world.block.BlockState;
|
|||||||
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
import com.sk89q.worldedit.world.block.BlockStateHolder;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
public class ProcessedWEExtent extends AbstractDelegateExtent {
|
public class ProcessedWEExtent extends AbstractDelegateExtent {
|
||||||
@ -52,12 +55,11 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
|
|||||||
private final Set<CuboidRegion> mask;
|
private final Set<CuboidRegion> mask;
|
||||||
private final String world;
|
private final String world;
|
||||||
private final int max;
|
private final int max;
|
||||||
int BScount = 0;
|
|
||||||
int Ecount = 0;
|
int Ecount = 0;
|
||||||
boolean BSblocked = false;
|
|
||||||
boolean Eblocked = false;
|
boolean Eblocked = false;
|
||||||
private int count;
|
private int count;
|
||||||
private Extent parent;
|
private Extent parent;
|
||||||
|
private Map<Long, Integer[]> tileEntityCount = new HashMap<>();
|
||||||
|
|
||||||
public ProcessedWEExtent(String world, Set<CuboidRegion> mask, int max, Extent child,
|
public ProcessedWEExtent(String world, Set<CuboidRegion> mask, int max, Extent child,
|
||||||
Extent parent) {
|
Extent parent) {
|
||||||
@ -89,95 +91,39 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
|
|||||||
@Override
|
@Override
|
||||||
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block)
|
public <T extends BlockStateHolder<T>> boolean setBlock(BlockVector3 location, T block)
|
||||||
throws WorldEditException {
|
throws WorldEditException {
|
||||||
String id = block.getBlockType().getId();
|
|
||||||
switch (id) {
|
|
||||||
case "54":
|
|
||||||
case "130":
|
|
||||||
case "142":
|
|
||||||
case "27":
|
|
||||||
case "137":
|
|
||||||
case "52":
|
|
||||||
case "154":
|
|
||||||
case "84":
|
|
||||||
case "25":
|
|
||||||
case "144":
|
|
||||||
case "138":
|
|
||||||
case "176":
|
|
||||||
case "177":
|
|
||||||
case "63":
|
|
||||||
case "68":
|
|
||||||
case "323":
|
|
||||||
case "117":
|
|
||||||
case "116":
|
|
||||||
case "28":
|
|
||||||
case "66":
|
|
||||||
case "157":
|
|
||||||
case "61":
|
|
||||||
case "62":
|
|
||||||
case "140":
|
|
||||||
case "146":
|
|
||||||
case "149":
|
|
||||||
case "150":
|
|
||||||
case "158":
|
|
||||||
case "23":
|
|
||||||
case "123":
|
|
||||||
case "124":
|
|
||||||
case "29":
|
|
||||||
case "33":
|
|
||||||
case "151":
|
|
||||||
case "178":
|
|
||||||
if (this.BSblocked) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
this.BScount++;
|
|
||||||
if (this.BScount > Settings.Chunk_Processor.MAX_TILES) {
|
|
||||||
this.BSblocked = true;
|
|
||||||
PlotSquared.debug(
|
|
||||||
Captions.PREFIX + "&cDetected unsafe WorldEdit: " + location.getX() + ","
|
|
||||||
+ location.getZ());
|
|
||||||
}
|
|
||||||
if (WEManager
|
|
||||||
.maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
|
|
||||||
if (this.count++ > this.max) {
|
|
||||||
if (this.parent != null) {
|
|
||||||
try {
|
|
||||||
Field field =
|
|
||||||
AbstractDelegateExtent.class.getDeclaredField("extent");
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(this.parent, new NullExtent());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
this.parent = null;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return super.setBlock(location, block);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
if (WEManager
|
|
||||||
.maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
|
|
||||||
if (this.count++ > this.max) {
|
|
||||||
if (this.parent != null) {
|
|
||||||
try {
|
|
||||||
Field field =
|
|
||||||
AbstractDelegateExtent.class.getDeclaredField("extent");
|
|
||||||
field.setAccessible(true);
|
|
||||||
field.set(this.parent, new NullExtent());
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
this.parent = null;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
super.setBlock(location, block);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
|
|
||||||
|
final boolean isTile = WorldUtil.IMP.getTileEntityTypes().contains(block.getBlockType());
|
||||||
|
if (isTile) {
|
||||||
|
final Integer[] tileEntityCount = this.tileEntityCount.computeIfAbsent(getChunkKey(location),
|
||||||
|
key -> new Integer[] {WorldUtil.IMP.getTileEntityCount(world,
|
||||||
|
BlockVector2.at(location.getBlockX() >> 4, location.getBlockZ() >> 4))});
|
||||||
|
if (tileEntityCount[0] >= Settings.Chunk_Processor.MAX_TILES) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
tileEntityCount[0]++;
|
||||||
|
PlotSquared.debug(Captions.PREFIX + "&cDetected unsafe WorldEdit: " + location.getX() + ","
|
||||||
|
+ location.getZ());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
if (WEManager.maskContains(this.mask, location.getX(), location.getY(), location.getZ())) {
|
||||||
|
if (this.count++ > this.max) {
|
||||||
|
if (this.parent != null) {
|
||||||
|
try {
|
||||||
|
Field field =
|
||||||
|
AbstractDelegateExtent.class.getDeclaredField("extent");
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(this.parent, new NullExtent());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
this.parent = null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return super.setBlock(location, block);
|
||||||
|
}
|
||||||
|
|
||||||
|
return !isTile;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public Entity createEntity(Location location, BaseEntity entity) {
|
@Override public Entity createEntity(Location location, BaseEntity entity) {
|
||||||
@ -202,4 +148,10 @@ public class ProcessedWEExtent extends AbstractDelegateExtent {
|
|||||||
return WEManager.maskContains(this.mask, position.getX(), position.getZ()) && super
|
return WEManager.maskContains(this.mask, position.getX(), position.getZ()) && super
|
||||||
.setBiome(position, biome);
|
.setBiome(position, biome);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static long getChunkKey(final BlockVector3 location) {
|
||||||
|
return (long) (location.getBlockX() >> 4) & 4294967295L | ((long) (location.getBlockZ() >> 4) & 4294967295L) << 32;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ import com.sk89q.worldedit.math.BlockVector2;
|
|||||||
import com.sk89q.worldedit.regions.CuboidRegion;
|
import com.sk89q.worldedit.regions.CuboidRegion;
|
||||||
import com.sk89q.worldedit.world.biome.BiomeType;
|
import com.sk89q.worldedit.world.biome.BiomeType;
|
||||||
import com.sk89q.worldedit.world.block.BlockState;
|
import com.sk89q.worldedit.world.block.BlockState;
|
||||||
|
import com.sk89q.worldedit.world.block.BlockType;
|
||||||
import com.sk89q.worldedit.world.entity.EntityType;
|
import com.sk89q.worldedit.world.entity.EntityType;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
@ -48,6 +49,7 @@ import java.io.FileInputStream;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
@ -216,4 +218,8 @@ public abstract class WorldUtil {
|
|||||||
|
|
||||||
public abstract Set<EntityType> getTypesInCategory(final String category);
|
public abstract Set<EntityType> getTypesInCategory(final String category);
|
||||||
|
|
||||||
|
public abstract Collection<BlockType> getTileEntityTypes();
|
||||||
|
|
||||||
|
public abstract int getTileEntityCount(String world, BlockVector2 chunk);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user