Adds optional extensive sign protection which accounts for signs on gravity-affected blocks
This commit is contained in:
parent
1c64e8813d
commit
3bb5970a57
@ -42,6 +42,7 @@ public final class PermissionSigns extends JavaPlugin {
|
|||||||
private static String pluginVersion;
|
private static String pluginVersion;
|
||||||
private static PermissionSigns instance;
|
private static PermissionSigns instance;
|
||||||
private static boolean perWorldPermissions;
|
private static boolean perWorldPermissions;
|
||||||
|
private static boolean enableExtensiveSignProtection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instantiates the permission signs class
|
* Instantiates the permission signs class
|
||||||
@ -120,42 +121,60 @@ public final class PermissionSigns extends JavaPlugin {
|
|||||||
return perWorldPermissions;
|
return perWorldPermissions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether permission signs on falling blocks should be protected
|
||||||
|
*
|
||||||
|
* @return <p>Whether permission signs on falling blocks should be protected</p>
|
||||||
|
*/
|
||||||
|
public static boolean extensiveSignProtectionEnabled() {
|
||||||
|
return enableExtensiveSignProtection;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reloadConfig() {
|
public void reloadConfig() {
|
||||||
super.reloadConfig();
|
super.reloadConfig();
|
||||||
FileConfiguration config = this.getConfig();
|
Translator.loadLanguages(loadConfig());
|
||||||
String language = config.getString("language");
|
|
||||||
perWorldPermissions = config.getBoolean("perWorldPermissions");
|
|
||||||
Translator.loadLanguages(language);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
PluginDescriptionFile pluginDescriptionFile = this.getDescription();
|
|
||||||
pluginVersion = pluginDescriptionFile.getVersion();
|
|
||||||
//TODO: Display a notice in the console if a new version is available
|
|
||||||
|
|
||||||
FileConfiguration config = this.getConfig();
|
|
||||||
config.options().copyDefaults(true);
|
|
||||||
this.saveDefaultConfig();
|
|
||||||
|
|
||||||
String language = config.getString("language");
|
|
||||||
perWorldPermissions = config.getBoolean("perWorldPermissions");
|
|
||||||
|
|
||||||
//Check if vault is loaded
|
//Check if vault is loaded
|
||||||
setupVault();
|
setupVault();
|
||||||
|
|
||||||
|
//Get plugin info
|
||||||
|
PluginDescriptionFile pluginDescriptionFile = this.getDescription();
|
||||||
|
pluginVersion = pluginDescriptionFile.getVersion();
|
||||||
|
|
||||||
|
//TODO: Display a notice in the console if a new version is available (requires Spigot resource first)
|
||||||
|
|
||||||
|
//Load config and write the default config if necessary
|
||||||
|
FileConfiguration config = this.getConfig();
|
||||||
|
config.options().copyDefaults(true);
|
||||||
|
this.saveDefaultConfig();
|
||||||
|
Translator.loadLanguages(loadConfig());
|
||||||
|
|
||||||
registerListeners();
|
registerListeners();
|
||||||
|
|
||||||
Translator.loadLanguages(language);
|
|
||||||
registerCommands();
|
registerCommands();
|
||||||
|
|
||||||
runThreads();
|
runThreads();
|
||||||
|
|
||||||
SignManager.loadSigns();
|
SignManager.loadSigns();
|
||||||
PermissionManager.loadTemporaryPermissions();
|
PermissionManager.loadTemporaryPermissions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the config file
|
||||||
|
*
|
||||||
|
* @return <p>The currently selected language</p>
|
||||||
|
*/
|
||||||
|
private String loadConfig() {
|
||||||
|
FileConfiguration config = this.getConfig();
|
||||||
|
String language = config.getString("language", "en");
|
||||||
|
perWorldPermissions = config.getBoolean("perWorldPermissions", false);
|
||||||
|
enableExtensiveSignProtection = config.getBoolean("enableExtensiveSignProtection", false);
|
||||||
|
saveConfig();
|
||||||
|
return language;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts all separate threads for executing tasks
|
* Starts all separate threads for executing tasks
|
||||||
*/
|
*/
|
||||||
|
@ -12,15 +12,28 @@ import org.bukkit.entity.Player;
|
|||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.block.BlockBreakEvent;
|
import org.bukkit.event.block.BlockBreakEvent;
|
||||||
|
import org.bukkit.event.block.BlockPhysicsEvent;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static net.knarcraft.permissionsigns.PermissionSigns.extensiveSignProtectionEnabled;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A listener for relevant block events such as signs being broken
|
* A listener for relevant block events such as signs being broken
|
||||||
*/
|
*/
|
||||||
public class BlockListener implements Listener {
|
public class BlockListener implements Listener {
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
public void onBlockPhysics(BlockPhysicsEvent event) {
|
||||||
|
//Block any physics events from destroying signs
|
||||||
|
if (SignManager.getSign(event.getBlock().getLocation()) != null) {
|
||||||
|
event.setCancelled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onBlockBreak(BlockBreakEvent event) {
|
public void onBlockBreak(BlockBreakEvent event) {
|
||||||
Block block = event.getBlock();
|
Block block = event.getBlock();
|
||||||
@ -30,14 +43,48 @@ public class BlockListener implements Listener {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (block instanceof FallingBlock) {
|
//Protect the permission sign itself
|
||||||
//TODO: Search recursively upwards (and downwards if pointed dripstone) until a non-falling block is found.
|
protectBlockIfPermissionSign(event, block, player);
|
||||||
// If upwards, check the non-falling block, but not downwards. If player does not have the create permission,
|
|
||||||
// just stop and cancel once a permission sign is found. If it has, all affected signs need to be
|
|
||||||
// de-registered. Must account for stacks of sand and signs on top of each-other. So if a normal sign is
|
|
||||||
// found, the recursion upward must also happen.
|
|
||||||
//}
|
|
||||||
|
|
||||||
|
if (extensiveSignProtectionEnabled()) {
|
||||||
|
protectSignsInDirection(event, block, player, BlockFace.UP);
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
protectSignsInDirection(event, block, player, BlockFace.DOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protects signs on falling blocks in the given direction
|
||||||
|
*
|
||||||
|
* @param event <p>The triggered block break event</p>
|
||||||
|
* @param block <p>The broken block</p>
|
||||||
|
* @param player <p>The player breaking the block</p>
|
||||||
|
* @param direction <p>The direction to check for affected blocks</p>
|
||||||
|
*/
|
||||||
|
private void protectSignsInDirection(BlockBreakEvent event, Block block, Player player, BlockFace direction) {
|
||||||
|
Block directionBlock = block;
|
||||||
|
do {
|
||||||
|
directionBlock = directionBlock.getRelative(direction);
|
||||||
|
protectBlockIfPermissionSign(event, directionBlock, player);
|
||||||
|
if (event.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} while ((direction == BlockFace.DOWN && directionBlock.getBlockData().getMaterial() ==
|
||||||
|
Material.POINTED_DRIPSTONE) || (direction == BlockFace.UP &&
|
||||||
|
isAffectedByGravity(directionBlock.getBlockData().getMaterial())));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protects the given sign
|
||||||
|
*
|
||||||
|
* @param event <p>The triggered block break event</p>
|
||||||
|
* @param block <p>The block to check if it's a sign</p>
|
||||||
|
* @param player <p>The player breaking the block</p>
|
||||||
|
*/
|
||||||
|
private void protectBlockIfPermissionSign(BlockBreakEvent event, Block block, Player player) {
|
||||||
|
//Protect the permission sign itself
|
||||||
Material material = block.getBlockData().getMaterial();
|
Material material = block.getBlockData().getMaterial();
|
||||||
if (Tag.SIGNS.isTagged(material) || Tag.WALL_SIGNS.isTagged(material)) {
|
if (Tag.SIGNS.isTagged(material) || Tag.WALL_SIGNS.isTagged(material)) {
|
||||||
checkIfBlockIsPermissionSign(block, player, event);
|
checkIfBlockIsPermissionSign(block, player, event);
|
||||||
@ -46,34 +93,24 @@ public class BlockListener implements Listener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Block relativeBlock = block.getRelative(BlockFace.UP);
|
Map<Block, Tag<Material>> blocksToCheck = new HashMap<>();
|
||||||
if (Tag.SIGNS.isTagged(relativeBlock.getBlockData().getMaterial())) {
|
|
||||||
checkIfBlockIsPermissionSign(relativeBlock, player, event);
|
|
||||||
if (event.isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (block.getBlockData().getMaterial() == Material.POINTED_DRIPSTONE) {
|
//Protect any block with a permission sign on it
|
||||||
relativeBlock = block.getRelative(BlockFace.DOWN);
|
blocksToCheck.put(block.getRelative(BlockFace.UP), Tag.SIGNS);
|
||||||
if (Tag.WALL_SIGNS.isTagged(relativeBlock.getBlockData().getMaterial())) {
|
|
||||||
checkIfBlockIsPermissionSign(relativeBlock, player, event);
|
//Protect any permission signs attached to the block
|
||||||
if (event.isCancelled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (BlockFace blockFace : getRelevantBlockFaces()) {
|
for (BlockFace blockFace : getRelevantBlockFaces()) {
|
||||||
relativeBlock = block.getRelative(blockFace);
|
blocksToCheck.put(block.getRelative(blockFace), Tag.WALL_SIGNS);
|
||||||
if (Tag.WALL_SIGNS.isTagged(relativeBlock.getBlockData().getMaterial())) {
|
}
|
||||||
checkIfBlockIsPermissionSign(relativeBlock, player, event);
|
|
||||||
|
for (Block blockToCheck : blocksToCheck.keySet()) {
|
||||||
|
if (blocksToCheck.get(blockToCheck).isTagged(blockToCheck.getBlockData().getMaterial())) {
|
||||||
|
checkIfBlockIsPermissionSign(blockToCheck, player, event);
|
||||||
if (event.isCancelled()) {
|
if (event.isCancelled()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Need to protect against other things that might damage the sign, such as explosions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -117,4 +154,23 @@ public class BlockListener implements Listener {
|
|||||||
return relevantBlockFaces;
|
return relevantBlockFaces;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the given material is affected by gravity
|
||||||
|
*
|
||||||
|
* @param material <p>The material to check</p>
|
||||||
|
* @return <p>True if the material is affected by gravity</p>
|
||||||
|
*/
|
||||||
|
private boolean isAffectedByGravity(Material material) {
|
||||||
|
return Tag.SAND.isTagged(material) || Tag.ANVIL.isTagged(material) || material == Material.POINTED_DRIPSTONE ||
|
||||||
|
Tag.SIGNS.isTagged(material) || material == Material.DRAGON_EGG || material == Material.GRAVEL ||
|
||||||
|
material == Material.BLACK_CONCRETE_POWDER || material == Material.BLUE_CONCRETE_POWDER ||
|
||||||
|
material == Material.BROWN_CONCRETE_POWDER || material == Material.CYAN_CONCRETE_POWDER ||
|
||||||
|
material == Material.LIME_CONCRETE_POWDER || material == Material.GRAY_CONCRETE_POWDER ||
|
||||||
|
material == Material.GREEN_CONCRETE_POWDER || material == Material.LIGHT_BLUE_CONCRETE_POWDER ||
|
||||||
|
material == Material.MAGENTA_CONCRETE_POWDER || material == Material.PINK_CONCRETE_POWDER ||
|
||||||
|
material == Material.LIGHT_GRAY_CONCRETE_POWDER || material == Material.ORANGE_CONCRETE_POWDER ||
|
||||||
|
material == Material.RED_CONCRETE_POWDER || material == Material.PURPLE_CONCRETE_POWDER ||
|
||||||
|
material == Material.YELLOW_CONCRETE_POWDER || material == Material.WHITE_CONCRETE_POWDER;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,3 +3,7 @@ language: en
|
|||||||
|
|
||||||
# Whether to only give permissions for a single world, instead of granting permissions for all worlds
|
# Whether to only give permissions for a single world, instead of granting permissions for all worlds
|
||||||
perWorldPermissions: false
|
perWorldPermissions: false
|
||||||
|
|
||||||
|
# Whether to protect permission signs on falling blocks (sand, gravel, anvil, drip-stone, signs) by preventing breakage
|
||||||
|
# of the blocks that would cause a sign to be destroyed.
|
||||||
|
enableExtensiveSignProtection: false
|
Loading…
Reference in New Issue
Block a user