From 1237276823294a74ddb3287636ae988576a0300e Mon Sep 17 00:00:00 2001 From: Adam Date: Fri, 2 Oct 2020 20:35:45 -0400 Subject: [PATCH] Use EnumSet for Material (#1038) --- .../GriefPrevention/AutoExtendClaimTask.java | 5 +- .../GriefPrevention/BlockEventHandler.java | 5 +- .../ryanhamshire/GriefPrevention/Claim.java | 17 +--- .../GriefPrevention/EntityEventHandler.java | 12 +-- .../GriefPrevention/GriefPrevention.java | 74 +++++++------- .../GriefPrevention/MaterialCollection.java | 54 ----------- .../GriefPrevention/MaterialInfo.java | 96 ------------------- .../GriefPrevention/PlayerEventHandler.java | 8 +- .../RestoreNatureProcessingTask.java | 14 +-- 9 files changed, 58 insertions(+), 227 deletions(-) delete mode 100644 src/main/java/me/ryanhamshire/GriefPrevention/MaterialCollection.java delete mode 100644 src/main/java/me/ryanhamshire/GriefPrevention/MaterialInfo.java diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java index 6bbef1b..3427dcd 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/AutoExtendClaimTask.java @@ -7,6 +7,7 @@ import org.bukkit.World.Environment; import org.bukkit.block.Biome; import java.util.ArrayList; +import java.util.Set; //automatically extends a claim downward based on block types detected class AutoExtendClaimTask implements Runnable @@ -43,7 +44,7 @@ class AutoExtendClaimTask implements Runnable for (ChunkSnapshot chunk : this.chunks) { Biome biome = chunk.getBiome(0, 0); - ArrayList playerBlockIDs = RestoreNatureProcessingTask.getPlayerBlocks(this.worldType, biome); + Set playerBlockIDs = RestoreNatureProcessingTask.getPlayerBlocks(this.worldType, biome); boolean ychanged = true; while (!this.yTooSmall(y) && ychanged) @@ -74,7 +75,7 @@ class AutoExtendClaimTask implements Runnable for (ChunkSnapshot chunk : this.chunks) { Biome biome = chunk.getBiome(0, 0); - ArrayList playerBlockIDs = RestoreNatureProcessingTask.getPlayerBlocks(this.worldType, biome); + Set playerBlockIDs = RestoreNatureProcessingTask.getPlayerBlocks(this.worldType, biome); boolean ychanged = true; while (!this.yTooSmall(y) && ychanged) diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java b/src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java index f64b313..9415f9d 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/BlockEventHandler.java @@ -68,6 +68,7 @@ import org.bukkit.projectiles.ProjectileSource; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumSet; import java.util.HashSet; import java.util.List; import java.util.Objects; @@ -79,7 +80,7 @@ public class BlockEventHandler implements Listener //convenience reference to singleton datastore private final DataStore dataStore; - private final ArrayList trashBlocks; + private final EnumSet trashBlocks; //constructor public BlockEventHandler(DataStore dataStore) @@ -87,7 +88,7 @@ public class BlockEventHandler implements Listener this.dataStore = dataStore; //create the list of blocks which will not trigger a warning when they're placed outside of land claims - this.trashBlocks = new ArrayList<>(); + this.trashBlocks = EnumSet.noneOf(Material.class); this.trashBlocks.add(Material.COBBLESTONE); this.trashBlocks.add(Material.TORCH); this.trashBlocks.add(Material.DIRT); diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java b/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java index 40ea03c..ad154ae 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/Claim.java @@ -35,6 +35,7 @@ import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.UUID; //represents a player claim @@ -353,7 +354,7 @@ public class Claim return GriefPrevention.instance.dataStore.getMessage(Messages.OnlyOwnersModifyClaims, this.getOwnerName()); } - private static final EnumSet PLACEABLE_FARMING_BLOCKS = EnumSet.of( + private static final Set PLACEABLE_FARMING_BLOCKS = EnumSet.of( Material.PUMPKIN_STEM, Material.WHEAT, Material.MELON_STEM, @@ -469,18 +470,8 @@ public class Claim //if under siege, some blocks will be breakable if (this.siegeData != null || this.doorsOpen) { - boolean breakable = false; - //search for block type in list of breakable blocks - for (int i = 0; i < GriefPrevention.instance.config_siege_blocks.size(); i++) - { - Material breakableMaterial = GriefPrevention.instance.config_siege_blocks.get(i); - if (breakableMaterial == material) - { - breakable = true; - break; - } - } + boolean breakable = GriefPrevention.instance.config_siege_blocks.contains(material); //custom error messages for siege mode if (!breakable) @@ -878,7 +869,7 @@ public class Claim { //decide which blocks will be considered player placed Location lesserBoundaryCorner = this.getLesserBoundaryCorner(); - ArrayList playerBlocks = RestoreNatureProcessingTask.getPlayerBlocks(lesserBoundaryCorner.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome()); + Set playerBlocks = RestoreNatureProcessingTask.getPlayerBlocks(lesserBoundaryCorner.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome()); //scan the claim for player placed blocks double score = 0; diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java b/src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java index 48f5d2f..7f1c93e 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/EntityEventHandler.java @@ -367,17 +367,7 @@ public class EntityEventHandler implements Listener if (claim != null && claim.siegeData != null) { Material material = block.getType(); - boolean breakable = false; - for (int j = 0; j < GriefPrevention.instance.config_siege_blocks.size(); j++) - { - Material breakableMaterial = GriefPrevention.instance.config_siege_blocks.get(j); - if (breakableMaterial == material) - { - breakable = true; - explodedBlocks.add(block); - break; - } - } + boolean breakable = GriefPrevention.instance.config_siege_blocks.contains(material); if (breakable) continue; } diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java b/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java index 1d127b1..5c30139 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/GriefPrevention.java @@ -58,15 +58,18 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map.Entry; +import java.util.Set; import java.util.UUID; import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.logging.Logger; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class GriefPrevention extends JavaPlugin { @@ -142,7 +145,7 @@ public class GriefPrevention extends JavaPlugin public boolean config_claims_lecternReadingRequiresAccessTrust; //reading lecterns requires access trust public ArrayList config_siege_enabledWorlds; //whether or not /siege is enabled on this server - public ArrayList config_siege_blocks; //which blocks will be breakable in siege mode + public Set config_siege_blocks; //which blocks will be breakable in siege mode public int config_siege_doorsOpenSeconds; // how before claim is re-secured after siege win public int config_siege_cooldownEndInMinutes; public boolean config_spam_enabled; //whether or not to monitor for spam @@ -707,7 +710,7 @@ public class GriefPrevention extends JavaPlugin } //default siege blocks - this.config_siege_blocks = new ArrayList<>(); + this.config_siege_blocks = EnumSet.noneOf(Material.class); this.config_siege_blocks.add(Material.DIRT); this.config_siege_blocks.add(Material.GRASS_BLOCK); this.config_siege_blocks.add(Material.GRASS); @@ -742,35 +745,20 @@ public class GriefPrevention extends JavaPlugin this.config_siege_blocks.add(Material.BLACK_WOOL); this.config_siege_blocks.add(Material.SNOW); - //build a default config entry - ArrayList defaultBreakableBlocksList = new ArrayList<>(); - for (Material siegeBlock : this.config_siege_blocks) - { - defaultBreakableBlocksList.add(siegeBlock.name()); - } + List breakableBlocksList; //try to load the list from the config file - List breakableBlocksList = config.getStringList("GriefPrevention.Siege.BreakableBlocks"); - - //if it fails, use default list instead - if (breakableBlocksList == null || breakableBlocksList.size() == 0) + if (config.isList("GriefPrevention.Siege.BreakableBlocks")) { - breakableBlocksList = defaultBreakableBlocksList; + breakableBlocksList = config.getStringList("GriefPrevention.Siege.BreakableBlocks"); + + //load materials + this.config_siege_blocks = parseMaterialListFromConfig(breakableBlocksList); } - - //parse the list of siege-breakable blocks - this.config_siege_blocks = new ArrayList<>(); - for (String blockName : breakableBlocksList) + //if it fails, use default siege block list instead + else { - Material material = Material.getMaterial(blockName); - if (material == null) - { - GriefPrevention.AddLogEntry("Siege Configuration: Material not found: " + blockName + "."); - } - else - { - this.config_siege_blocks.add(material); - } + breakableBlocksList = this.config_siege_blocks.stream().map(Material::name).collect(Collectors.toList()); } this.config_siege_doorsOpenSeconds = config.getInt("GriefPrevention.Siege.DoorsOpenDelayInSeconds", 5 * 60); @@ -3578,35 +3566,43 @@ public class GriefPrevention extends JavaPlugin GriefPrevention.instance.getServer().getScheduler().runTaskLaterAsynchronously(GriefPrevention.instance, task, delayInTicks); } - private void parseMaterialListFromConfig(List stringsToParse, MaterialCollection materialCollection) + private Set parseMaterialListFromConfig(List stringsToParse) { - materialCollection.clear(); + Set materials = EnumSet.noneOf(Material.class); //for each string in the list for (int i = 0; i < stringsToParse.size(); i++) { - //try to parse the string value into a material info - MaterialInfo materialInfo = MaterialInfo.fromString(stringsToParse.get(i)); + String string = stringsToParse.get(i); + + //defensive coding + if (string == null) continue; + + //try to parse the string value into a material + Material material = Material.getMaterial(string.toUpperCase()); //null value returned indicates an error parsing the string from the config file - if (materialInfo == null) + if (material == null) { - //show error in log - GriefPrevention.AddLogEntry("ERROR: Unable to read a material entry from the config file. Please update your config.yml."); - - //update string, which will go out to config file to help user find the error entry - if (!stringsToParse.get(i).contains("can't")) + //check if string has failed validity before + if (!string.contains("can't")) { - stringsToParse.set(i, stringsToParse.get(i) + " <-- can't understand this entry, see BukkitDev documentation"); + //update string, which will go out to config file to help user find the error entry + stringsToParse.set(i, string + " <-- can't understand this entry, see BukkitDev documentation"); + + //warn about invalid material in log + GriefPrevention.AddLogEntry(String.format("ERROR: Invalid material %s. Please update your config.yml.", string)); } } - //otherwise store the valid entry in config data + //otherwise material is valid, add it else { - materialCollection.Add(materialInfo); + materials.add(material); } } + + return materials; } public int getSeaLevel(World world) diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/MaterialCollection.java b/src/main/java/me/ryanhamshire/GriefPrevention/MaterialCollection.java deleted file mode 100644 index 0459054..0000000 --- a/src/main/java/me/ryanhamshire/GriefPrevention/MaterialCollection.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - GriefPrevention Server Plugin for Minecraft - Copyright (C) 2012 Ryan Hamshire - - 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 . - */ - -package me.ryanhamshire.GriefPrevention; - -import java.util.HashSet; -import java.util.Set; - -//ordered list of material info objects, for fast searching -public class MaterialCollection -{ - Set materials = new HashSet<>(); - - void Add(MaterialInfo material) - { - this.materials.add(material); - } - - boolean Contains(MaterialInfo material) - { - return this.materials.contains(material); - } - - @Override - public String toString() - { - return materials.toString(); - } - - public int size() - { - return this.materials.size(); - } - - public void clear() - { - this.materials.clear(); - } -} diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/MaterialInfo.java b/src/main/java/me/ryanhamshire/GriefPrevention/MaterialInfo.java deleted file mode 100644 index 16da4ce..0000000 --- a/src/main/java/me/ryanhamshire/GriefPrevention/MaterialInfo.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - GriefPrevention Server Plugin for Minecraft - Copyright (C) 2012 Ryan Hamshire - - 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 . - */ - -package me.ryanhamshire.GriefPrevention; - -//represents a material or collection of materials - -import org.bukkit.Material; - -public class MaterialInfo -{ - Material typeID; - byte data; - boolean allDataValues; - String description; - - public MaterialInfo(Material typeID, byte data, String description) - { - this.typeID = typeID; - this.data = data; - this.allDataValues = false; - this.description = description; - } - - public MaterialInfo(Material typeID, String description) - { - this.typeID = typeID; - this.data = 0; - this.allDataValues = true; - this.description = description; - } - - private MaterialInfo(Material typeID, byte data, boolean allDataValues, String description) - { - this.typeID = typeID; - this.data = data; - this.allDataValues = allDataValues; - this.description = description; - } - - @Override - public String toString() - { - String returnValue = String.valueOf(this.typeID) + ":" + (this.allDataValues ? "*" : String.valueOf(this.data)); - if (this.description != null) returnValue += ":" + this.description; - - return returnValue; - } - - public static MaterialInfo fromString(String string) - { - if (string == null || string.isEmpty()) return null; - - String[] parts = string.split(":"); - if (parts.length < 3) return null; - - try - { - Material typeID = Material.matchMaterial(parts[0]); - - byte data; - boolean allDataValues; - if (parts[1].equals("*")) - { - allDataValues = true; - data = 0; - } - else - { - allDataValues = false; - data = Byte.parseByte(parts[1]); - } - - return new MaterialInfo(typeID, data, allDataValues, parts[2]); - } - catch (NumberFormatException exception) - { - return null; - } - } -} diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java b/src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java index c361ba7..8013bad 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/PlayerEventHandler.java @@ -92,11 +92,11 @@ import org.bukkit.util.BlockIterator; import java.net.InetAddress; import java.util.ArrayList; -import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.EnumSet; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -1449,8 +1449,8 @@ class PlayerEventHandler implements Listener } //block use of buckets within other players' claims - private final HashSet commonAdjacentBlocks_water = new HashSet<>(Arrays.asList(Material.WATER, Material.FARMLAND, Material.DIRT, Material.STONE)); - private final HashSet commonAdjacentBlocks_lava = new HashSet<>(Arrays.asList(Material.LAVA, Material.DIRT, Material.STONE)); + private final Set commonAdjacentBlocks_water = EnumSet.of(Material.WATER, Material.FARMLAND, Material.DIRT, Material.STONE); + private final Set commonAdjacentBlocks_lava = EnumSet.of(Material.LAVA, Material.DIRT, Material.STONE); @EventHandler(ignoreCancelled = true, priority = EventPriority.LOWEST) public void onPlayerBucketEmpty(PlayerBucketEmptyEvent bucketEvent) @@ -1515,7 +1515,7 @@ class PlayerEventHandler implements Listener if (block.getY() >= instance.getSeaLevel(block.getWorld()) - 5 && !player.hasPermission("griefprevention.lava") && block.getWorld().getEnvironment() != Environment.NETHER) { //if certain blocks are nearby, it's less suspicious and not worth logging - HashSet exclusionAdjacentTypes; + Set exclusionAdjacentTypes; if (bucketEvent.getBucket() == Material.WATER_BUCKET) exclusionAdjacentTypes = this.commonAdjacentBlocks_water; else diff --git a/src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureProcessingTask.java b/src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureProcessingTask.java index 3008f07..bec9d8a 100644 --- a/src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureProcessingTask.java +++ b/src/main/java/me/ryanhamshire/GriefPrevention/RestoreNatureProcessingTask.java @@ -29,6 +29,8 @@ import org.bukkit.entity.Player; import java.util.ArrayList; import java.util.Arrays; +import java.util.EnumSet; +import java.util.Set; //non-main-thread task which processes world data to repair the unnatural //after processing is complete, creates a main thread task to make the necessary changes to the world @@ -51,8 +53,8 @@ class RestoreNatureProcessingTask implements Runnable private final boolean aggressiveMode; //two lists of materials - private final ArrayList notAllowedToHang; //natural blocks which don't naturally hang in their air - private final ArrayList playerBlocks; //a "complete" list of player-placed blocks. MUST BE MAINTAINED as patches introduce more + private final Set notAllowedToHang; //natural blocks which don't naturally hang in their air + private final Set playerBlocks; //a "complete" list of player-placed blocks. MUST BE MAINTAINED as patches introduce more public RestoreNatureProcessingTask(BlockSnapshot[][][] snapshots, int miny, Environment environment, Biome biome, Location lesserBoundaryCorner, Location greaterBoundaryCorner, int seaLevel, boolean aggressiveMode, boolean creativeMode, Player player) @@ -69,7 +71,7 @@ class RestoreNatureProcessingTask implements Runnable this.player = player; this.creativeMode = creativeMode; - this.notAllowedToHang = new ArrayList<>(); + this.notAllowedToHang = EnumSet.noneOf(Material.class); this.notAllowedToHang.add(Material.DIRT); this.notAllowedToHang.add(Material.GRASS); this.notAllowedToHang.add(Material.SNOW); @@ -86,7 +88,7 @@ class RestoreNatureProcessingTask implements Runnable this.notAllowedToHang.add(Material.STONE); } - this.playerBlocks = new ArrayList<>(); + this.playerBlocks = EnumSet.noneOf(Material.class); this.playerBlocks.addAll(RestoreNatureProcessingTask.getPlayerBlocks(this.environment, this.biome)); //in aggressive or creative world mode, also treat these blocks as user placed, to be removed @@ -642,12 +644,12 @@ class RestoreNatureProcessingTask implements Runnable } - static ArrayList getPlayerBlocks(Environment environment, Biome biome) + static Set getPlayerBlocks(Environment environment, Biome biome) { //NOTE on this list. why not make a list of natural blocks? //answer: better to leave a few player blocks than to remove too many natural blocks. remember we're "restoring nature" //a few extra player blocks can be manually removed, but it will be impossible to guess exactly which natural materials to use in manual repair of an overzealous block removal - ArrayList playerBlocks = new ArrayList<>(); + Set playerBlocks = EnumSet.noneOf(Material.class); playerBlocks.add(Material.FIRE); playerBlocks.add(Material.WHITE_BED); playerBlocks.add(Material.ORANGE_BED);