Use EnumSet for Material (#1038)

This commit is contained in:
Adam 2020-10-02 20:35:45 -04:00 committed by GitHub
parent dbe4a106bd
commit 1237276823
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 58 additions and 227 deletions

View File

@ -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<Material> playerBlockIDs = RestoreNatureProcessingTask.getPlayerBlocks(this.worldType, biome);
Set<Material> 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<Material> playerBlockIDs = RestoreNatureProcessingTask.getPlayerBlocks(this.worldType, biome);
Set<Material> playerBlockIDs = RestoreNatureProcessingTask.getPlayerBlocks(this.worldType, biome);
boolean ychanged = true;
while (!this.yTooSmall(y) && ychanged)

View File

@ -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<Material> trashBlocks;
private final EnumSet<Material> 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);

View File

@ -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<Material> PLACEABLE_FARMING_BLOCKS = EnumSet.of(
private static final Set<Material> 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<Material> playerBlocks = RestoreNatureProcessingTask.getPlayerBlocks(lesserBoundaryCorner.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome());
Set<Material> playerBlocks = RestoreNatureProcessingTask.getPlayerBlocks(lesserBoundaryCorner.getWorld().getEnvironment(), lesserBoundaryCorner.getBlock().getBiome());
//scan the claim for player placed blocks
double score = 0;

View File

@ -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;
}

View File

@ -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<World> config_siege_enabledWorlds; //whether or not /siege is enabled on this server
public ArrayList<Material> config_siege_blocks; //which blocks will be breakable in siege mode
public Set<Material> 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<String> defaultBreakableBlocksList = new ArrayList<>();
for (Material siegeBlock : this.config_siege_blocks)
{
defaultBreakableBlocksList.add(siegeBlock.name());
}
List<String> breakableBlocksList;
//try to load the list from the config file
List<String> 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<String> stringsToParse, MaterialCollection materialCollection)
private Set<Material> parseMaterialListFromConfig(List<String> stringsToParse)
{
materialCollection.clear();
Set<Material> 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)

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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<MaterialInfo> 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();
}
}

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}
}

View File

@ -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<Material> commonAdjacentBlocks_water = new HashSet<>(Arrays.asList(Material.WATER, Material.FARMLAND, Material.DIRT, Material.STONE));
private final HashSet<Material> commonAdjacentBlocks_lava = new HashSet<>(Arrays.asList(Material.LAVA, Material.DIRT, Material.STONE));
private final Set<Material> commonAdjacentBlocks_water = EnumSet.of(Material.WATER, Material.FARMLAND, Material.DIRT, Material.STONE);
private final Set<Material> 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<Material> exclusionAdjacentTypes;
Set<Material> exclusionAdjacentTypes;
if (bucketEvent.getBucket() == Material.WATER_BUCKET)
exclusionAdjacentTypes = this.commonAdjacentBlocks_water;
else

View File

@ -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<Material> notAllowedToHang; //natural blocks which don't naturally hang in their air
private final ArrayList<Material> playerBlocks; //a "complete" list of player-placed blocks. MUST BE MAINTAINED as patches introduce more
private final Set<Material> notAllowedToHang; //natural blocks which don't naturally hang in their air
private final Set<Material> 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<Material> getPlayerBlocks(Environment environment, Biome biome)
static Set<Material> 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<Material> playerBlocks = new ArrayList<>();
Set<Material> playerBlocks = EnumSet.noneOf(Material.class);
playerBlocks.add(Material.FIRE);
playerBlocks.add(Material.WHITE_BED);
playerBlocks.add(Material.ORANGE_BED);