diff --git a/favs/src/main/java/com/thevoxelbox/voxelsniper/SnipeData.java b/favs/src/main/java/com/thevoxelbox/voxelsniper/SnipeData.java index 9e606daff..0c7bbe9e9 100644 --- a/favs/src/main/java/com/thevoxelbox/voxelsniper/SnipeData.java +++ b/favs/src/main/java/com/thevoxelbox/voxelsniper/SnipeData.java @@ -272,7 +272,7 @@ public class SnipeData { * @param voxelId the voxelId to set */ public final void setVoxelId(final int voxelId) { - if (WorldEdit.getInstance().getConfiguration().disallowedBlocks.contains(BlockTypes.getFromStateId(voxelId).getId())) { + if (WorldEdit.getInstance().getConfiguration().checkDisallowedBlocks(BlockTypes.getFromStateId(voxelId).getDefaultState())) { if (owner != null) { Player plr = owner.getPlayer(); if (plr != null) { diff --git a/favs/src/main/java/com/thevoxelbox/voxelsniper/command/VoxelVoxelCommand.java b/favs/src/main/java/com/thevoxelbox/voxelsniper/command/VoxelVoxelCommand.java index 743b027c7..b574ced6c 100644 --- a/favs/src/main/java/com/thevoxelbox/voxelsniper/command/VoxelVoxelCommand.java +++ b/favs/src/main/java/com/thevoxelbox/voxelsniper/command/VoxelVoxelCommand.java @@ -55,7 +55,7 @@ public class VoxelVoxelCommand extends VoxelCommand { Material blockType = block.getType(); BlockType weType = BukkitAdapter.adapt(blockType); - if(!player.hasPermission("voxelsniper.ignorelimitations") && WorldEdit.getInstance().getConfiguration().disallowedBlocks.contains(weType.getId())) { + if(!player.hasPermission("voxelsniper.ignorelimitations") && WorldEdit.getInstance().getConfiguration().checkDisallowedBlocks(weType.getDefaultState())) { player.sendMessage("You are not allowed to use " + blockType.name() + ". (WorldEdit config.yml)"); return true; } @@ -68,7 +68,7 @@ public class VoxelVoxelCommand extends VoxelCommand { } else { BlockType weType = BlockTypes.parse(args[0]); if(weType != null) { - if(!player.hasPermission("voxelsniper.ignorelimitations") && WorldEdit.getInstance().getConfiguration().disallowedBlocks.contains(weType.getId())) { + if(!player.hasPermission("voxelsniper.ignorelimitations") && WorldEdit.getInstance().getConfiguration().checkDisallowedBlocks(weType.getDefaultState())) { player.sendMessage("You are not allowed to use " + weType + "."); return true; } else { diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java index d88f23e4b..007290e7a 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/LocalConfiguration.java @@ -20,7 +20,11 @@ package com.sk89q.worldedit; import com.google.common.collect.Lists; +import com.sk89q.worldedit.extent.NullExtent; +import com.sk89q.worldedit.function.mask.BlockMask; +import com.sk89q.worldedit.function.mask.BlockMaskBuilder; import com.sk89q.worldedit.util.logging.LogFormat; +import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; @@ -40,6 +44,7 @@ public abstract class LocalConfiguration { public boolean profile = false; public boolean traceUnflushedSessions = false; public Set disallowedBlocks = new HashSet<>(); + protected BlockMask disallowedBlocksMask; public int defaultChangeLimit = -1; public int maxChangeLimit = -1; public int defaultMaxPolygonalPoints = -1; @@ -149,6 +154,17 @@ public abstract class LocalConfiguration { */ public abstract void load(); + public boolean checkDisallowedBlocks(BlockStateHolder holder) { + if (disallowedBlocksMask == null) { + BlockMaskBuilder builder = new BlockMaskBuilder(); + for (String blockRegex : disallowedBlocks) { + builder.addRegex(blockRegex); + } + disallowedBlocksMask = builder.build(new NullExtent()); + } + return disallowedBlocksMask.test(holder.toImmutableState()); + } + /** * Get the working directory to work from. * diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java index 03d62887e..c06b04fb5 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extension/factory/parser/DefaultBlockParser.java @@ -50,6 +50,7 @@ import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.world.World; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockState; +import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockTypes; import com.sk89q.worldedit.world.registry.LegacyMapper; @@ -257,21 +258,7 @@ public class DefaultBlockParser extends InputParser { // Check if the item is allowed BlockType blockType = state.getBlockType(); - if (context.isRestricted()) { - Actor actor = context.requireActor(); - if (actor != null) { - if (!actor.hasPermission("worldedit.anyblock") && worldEdit.getConfiguration().disallowedBlocks.contains(blockType.getId())) { - throw new DisallowedUsageException("You are not allowed to use '" + input + "'"); - } - if (nbt != null) { - if (!actor.hasPermission("worldedit.anyblock")) { - throw new DisallowedUsageException("You are not allowed to nbt'"); - } - } - } - } - - if (nbt != null) return state.toBaseBlock(nbt); + if (nbt != null) return validate(context, state.toBaseBlock(nbt)); if (blockType == BlockTypes.SIGN || blockType == BlockTypes.WALL_SIGN) { // Allow special sign text syntax @@ -280,7 +267,7 @@ public class DefaultBlockParser extends InputParser { text[1] = blockAndExtraData.length > 2 ? blockAndExtraData[2] : ""; text[2] = blockAndExtraData.length > 3 ? blockAndExtraData[3] : ""; text[3] = blockAndExtraData.length > 4 ? blockAndExtraData[4] : ""; - return new SignBlock(state, text); + return validate(context, new SignBlock(state, text)); } else if (blockType == BlockTypes.SPAWNER) { // Allow setting mob spawn type if (blockAndExtraData.length > 1) { @@ -299,21 +286,37 @@ public class DefaultBlockParser extends InputParser { .filter(s -> s.startsWith(finalMobName)) .collect(Collectors.toList())); } - return new MobSpawnerBlock(state, mobName); + return validate(context, new MobSpawnerBlock(state, mobName)); } else { - return new MobSpawnerBlock(state, MobType.PIG.getName()); + return validate(context, new MobSpawnerBlock(state, MobType.PIG.getName())); } } else if (blockType == BlockTypes.PLAYER_HEAD || blockType == BlockTypes.PLAYER_WALL_HEAD) { // allow setting type/player/rotation if (blockAndExtraData.length <= 1) { - return new SkullBlock(state); + return validate(context, new SkullBlock(state)); } String type = blockAndExtraData[1]; - return new SkullBlock(state, type.replace(" ", "_")); // valid MC usernames + return validate(context, new SkullBlock(state, type.replace(" ", "_"))); // valid MC usernames } else { - return state.toBaseBlock(); + return validate(context, state.toBaseBlock()); } } + + private T validate(ParserContext context, T holder) { + if (context.isRestricted()) { + Actor actor = context.requireActor(); + if (!actor.hasPermission("worldedit.anyblock") && worldEdit.getConfiguration().checkDisallowedBlocks(holder)) { + throw new DisallowedUsageException("You are not allowed to use '" + holder + "'"); + } + CompoundTag nbt = holder.getNbtData(); + if (nbt != null) { + if (!actor.hasPermission("worldedit.anyblock")) { + throw new DisallowedUsageException("You are not allowed to nbt'"); + } + } + } + return holder; + } } \ No newline at end of file diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java index b4620b293..20195fcbf 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/PropertiesConfiguration.java @@ -80,6 +80,7 @@ public class PropertiesConfiguration extends LocalConfiguration { profile = getBool("profile", profile); traceUnflushedSessions = getBool("trace-unflushed-sessions", traceUnflushedSessions); disallowedBlocks = getStringSet("disallowed-blocks", getDefaultDisallowedBlocks()); + disallowedBlocksMask = null; allowedDataCycleBlocks = new HashSet<>(getStringSet("limits.allowed-data-cycle-blocks", null)); defaultChangeLimit = getInt("default-max-changed-blocks", defaultChangeLimit); diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java b/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java index 5a657584d..3542f0263 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/util/YAMLConfiguration.java @@ -79,6 +79,7 @@ public class YAMLConfiguration extends LocalConfiguration { butcherMaxRadius = Math.max(-1, config.getInt("limits.butcher-radius.maximum", butcherMaxRadius)); disallowedBlocks = new HashSet<>(config.getStringList("limits.disallowed-blocks", Lists.newArrayList(getDefaultDisallowedBlocks()))); + disallowedBlocksMask = null; allowedDataCycleBlocks = new HashSet<>(config.getStringList("limits.allowed-data-cycle-blocks", null)); registerHelp = config.getBoolean("register-help", true);