Cleans the block change listener

This commit is contained in:
Kristian Knarvik 2022-11-14 16:26:17 +01:00
parent c51b0e9557
commit 6d62a10de3
7 changed files with 449 additions and 314 deletions

View File

@ -12,21 +12,21 @@ public class Arena {
private final World world; private final World world;
private final List<ArenaPlayer> arenaPlayers; private final List<ArenaPlayer> arenaPlayers;
private final ArenaState arenaState; private final ArenaState arenaState;
private final boolean canJoin; private final boolean isJoinAble;
private final boolean open; private final boolean open;
private final int countdownTimer; private final int countdownTimer;
private int maxPlayers; private int maxPlayers;
private int gracePeriod; private int gracePeriod;
private final Map<Integer, Location> locations; private final Map<Integer, Location> locations;
public Arena(int arenaId, World world, List<ArenaPlayer> arenaPlayers, ArenaState arenaState, boolean canJoin, public Arena(int arenaId, World world, List<ArenaPlayer> arenaPlayers, ArenaState arenaState, boolean isJoinAble,
boolean open, int countdownTimer, int maxPlayers, int gracePeriod, boolean open, int countdownTimer, int maxPlayers, int gracePeriod,
Map<Integer, Location> locations) { Map<Integer, Location> locations) {
this.arenaId = arenaId; this.arenaId = arenaId;
this.world = world; this.world = world;
this.arenaPlayers = arenaPlayers; this.arenaPlayers = arenaPlayers;
this.arenaState = arenaState; this.arenaState = arenaState;
this.canJoin = canJoin; this.isJoinAble = isJoinAble;
this.open = open; this.open = open;
this.countdownTimer = countdownTimer; this.countdownTimer = countdownTimer;
this.maxPlayers = maxPlayers; this.maxPlayers = maxPlayers;
@ -55,8 +55,8 @@ public class Arena {
return arenaState; return arenaState;
} }
public boolean isCanJoin() { public boolean isJoinAble() {
return canJoin; return isJoinAble;
} }
public boolean isOpen() { public boolean isOpen() {

View File

@ -21,16 +21,16 @@ public class ArenaPlayer {
/** /**
* Instantiates a new arena player * Instantiates a new arena player
* *
* @param player <p>The player this arena player represents</p> * @param player <p>The player this arena player represents</p>
* @param arena <p>The arena the player is currently in</p> * @param arena <p>The arena the player is currently in</p>
* @param ready <p>Whether the player is currently ready to start the game</p> * @param ready <p>Whether the player is currently ready to start the game</p>
* @param quit <p>Whether the player has quit the game</p> * @param quit <p>Whether the player has quit the game</p>
* @param dead <p>Whether the player has died</p> * @param dead <p>Whether the player has died</p>
* @param isOut <p>Whether the player has left the game</p> * @param isOut <p>Whether the player has left the game</p>
* @param isWatching <p>Whether the player is watching the arena</p> * @param isWatching <p>Whether the player is watching the arena</p>
* @param needConfirmation <p>Whether a conformation is necessary for the player to join the game</p> * @param needConfirmation <p>Whether a conformation is necessary for the player to join the game</p>
* @param inArena <p>Whether the player is currently in an arena</p> * @param inArena <p>Whether the player is currently in an arena</p>
* @param frozen <p>Whether the player is currently frozen, not allowed to move</p> * @param frozen <p>Whether the player is currently frozen, not allowed to move</p>
*/ */
public ArenaPlayer(Player player, Arena arena, boolean ready, boolean quit, boolean dead, boolean isOut, public ArenaPlayer(Player player, Arena arena, boolean ready, boolean quit, boolean dead, boolean isOut,
boolean isWatching, boolean needConfirmation, boolean inArena, boolean frozen) { boolean isWatching, boolean needConfirmation, boolean inArena, boolean frozen) {

View File

@ -1,7 +1,7 @@
package net.knarcraft.hungerarena; package net.knarcraft.hungerarena;
import com.sk89q.worldedit.bukkit.WorldEditPlugin; import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import net.knarcraft.hungerarena.Listeners.BlockStorage; import net.knarcraft.hungerarena.Listeners.BlockChangeListener;
import net.knarcraft.hungerarena.Listeners.Boundaries; import net.knarcraft.hungerarena.Listeners.Boundaries;
import net.knarcraft.hungerarena.Listeners.ChatListener; import net.knarcraft.hungerarena.Listeners.ChatListener;
import net.knarcraft.hungerarena.Listeners.DeathListener; import net.knarcraft.hungerarena.Listeners.DeathListener;
@ -104,7 +104,7 @@ public class HungerArena extends JavaPlugin {
Listener Teleport = new TeleportListener(this); Listener Teleport = new TeleportListener(this);
SignsAndBeds SignsAndBeds = null; SignsAndBeds SignsAndBeds = null;
SignsAndBedsOld SignsAndBedsOld = null; SignsAndBedsOld SignsAndBedsOld = null;
final Listener BlockStorage = new BlockStorage(this); final Listener BlockStorage = new BlockChangeListener(this);
//Listener WinGames = new WinGamesListener(this); //Listener WinGames = new WinGamesListener(this);
final Listener WorldChange = new WorldChange(this); final Listener WorldChange = new WorldChange(this);
final Listener Boundaries = new Boundaries(this); final Listener Boundaries = new Boundaries(this);

View File

@ -0,0 +1,409 @@
package net.knarcraft.hungerarena.Listeners;
import net.knarcraft.hungerarena.Arena;
import net.knarcraft.hungerarena.HungerArena;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.player.PlayerBucketFillEvent;
import java.util.List;
import java.util.UUID;
/**
* A listener for any unwanted placing of or destruction of blocks
*/
public class BlockChangeListener implements Listener {
public final HungerArena plugin;
/**
* Instantiates a new block change listener
*
* @param hungerArena <p>A reference to the hungerArena plugin</p>
*/
public BlockChangeListener(HungerArena hungerArena) {
this.plugin = hungerArena;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onBlockBreak(BlockBreakEvent event) {
//If already cancelled, abort
if (event.isCancelled()) {
return;
}
Block block = event.getBlock();
Player player = event.getPlayer();
UUID playerId = player.getUniqueId();
//If the player has the HungerArena.arena permission, allow bypassing the always protect protection
boolean alwaysProtect = false;
if (!player.hasPermission("HungerArena.arena")) {
alwaysProtect = alwaysProtect();
}
//Find the id of the arena the player is currently in
int arenaId = getArenaId(player, alwaysProtect);
//If the player cannot be found in the arena, abort unless always protect is enabled
if (!plugin.inArena.get(arenaId).contains(playerId) && !alwaysProtect) {
return;
}
if (plugin.config.getBoolean("Protected_Arena")) {
//Prevent any block breakage
event.setCancelled(true);
player.sendMessage(ChatColor.RED + "You can't break blocks while playing!");
} else if ((joinAble(arenaId) || alwaysProtect) && (!plugin.restrictedWorlds ||
plugin.worldNames.containsValue(player.getWorld().getName()))) {
List<String> whitelist = plugin.management.getStringList("blocks.whitelist");
boolean emptyWhitelist = whitelist.isEmpty();
boolean useAsBlacklist = plugin.management.getBoolean("blocks.useWhitelistAsBlacklist");
//If not in whitelist
if ((emptyWhitelist || !whitelist.contains(block.getType().name())) ^ useAsBlacklist) {
//If not in whitelist, or in whitelist, but treated as blacklist, deny breaking the block
event.setCancelled(true);
player.sendMessage(ChatColor.RED + "That is an illegal block!");
} else {
//Store the removed block to restore it later
addDestroyedBlockToList(block, block.getWorld().getName(), arenaId);
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onExplosion(EntityExplodeEvent event) {
//If already cancelled, abort
if (event.isCancelled()) {
return;
}
List<Block> destroyedBlocks = event.blockList();
Entity explosionCause = event.getEntity();
String explosionWorld = explosionCause.getWorld().getName();
for (int arenaId : plugin.arenas.keySet()) {
registerArenaExplosion(arenaId, destroyedBlocks, explosionCause, explosionWorld);
}
}
/**
* Registers an explosion in the given arena
*
* @param arenaId <p>The arena id to register the explosion for</p>
* @param destroyedBlocks <p>The blocks destroyed in the explosion</p>
* @param explosionCause <p>The cause of the explosion</p>
* @param explosionWorld <p>The world in which the explosion happened</p>
*/
private void registerArenaExplosion(int arenaId, List<Block> destroyedBlocks, Entity explosionCause,
String explosionWorld) {
//If not active (join-able) and always protect is disabled, do nothing
if (!joinAble(arenaId) && !alwaysProtect()) {
return;
}
if (isDifferentWorld(arenaId, explosionWorld)) {
return;
}
if (explosionCause.getType() == EntityType.PRIMED_TNT) {
//Put the destroyed TNT back to where it was, save it to destroyed blocks, and remove it again
Location explosionLocation = explosionCause.getLocation();
explosionLocation.getBlock().setType(Material.TNT);
Block tnt = explosionLocation.getBlock();
addDestroyedBlockToList(tnt, explosionWorld, arenaId);
tnt.setType(Material.AIR);
}
//Register all destroyed blocks, except air
for (Block destroyedBlock : destroyedBlocks) {
if (!destroyedBlock.getType().isAir()) {
addDestroyedBlockToList(destroyedBlock, explosionWorld, arenaId);
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onBlockBurn(BlockBurnEvent event) {
//If already cancelled, do nothing
if (event.isCancelled()) {
return;
}
Block burnedBlock = event.getBlock();
String blockWorldName = burnedBlock.getWorld().getName();
for (int arenaId : plugin.arenas.keySet()) {
//If not join-able, and always protect isn't enabled, do nothing
if (!joinAble(arenaId) && !alwaysProtect()) {
continue;
}
//If restricted to HungerArena worlds, and the world is unset, or not the same, do nothing
if (isDifferentWorld(arenaId, blockWorldName)) {
continue;
}
//Register the burned block
addDestroyedBlockToList(burnedBlock, blockWorldName, arenaId);
}
}
/**
* Gets whether the given arena is in a different world than the given world name
*
* @param arenaId <p>The name of the arena to check</p>
* @param worldName <p>The name of the world to check</p>
* @return <p>True if the arena is not in the given world</p>
*/
private boolean isDifferentWorld(int arenaId, String worldName) {
String arenaWorldName = plugin.worldNames.get(arenaId);
//If restricted to HungerArena worlds, and the world is unset, or not the same, do nothing
return plugin.restrictedWorlds && (arenaWorldName == null ||
!arenaWorldName.equalsIgnoreCase(worldName));
}
@EventHandler(priority = EventPriority.MONITOR)
public void blockPlace(BlockPlaceEvent event) {
//If the event is already cancelled, do nothing
if (event.isCancelled()) {
return;
}
Block placedBlock = event.getBlock();
Player player = event.getPlayer();
boolean alwaysProtect = false;
if (!player.hasPermission("HungerArena.arena")) {
alwaysProtect = alwaysProtect();
}
//Find the id of the arena the player is currently in
int arenaId = getArenaId(player, alwaysProtect);
//If the player cannot be found in the arena, abort unless always protect is enabled
if (!plugin.inArena.get(arenaId).contains(player.getUniqueId()) && !alwaysProtect) {
return;
}
//If not join-able, or always protect is disabled, do nothing
if (!joinAble(arenaId) && !alwaysProtect) {
return;
}
//If restricted to HungerArena worlds, and not a registered world, do nothing
if (plugin.restrictedWorlds && !plugin.worldNames.containsValue(placedBlock.getWorld().getName())) {
return;
}
Block blockBeneath = placedBlock.getRelative(BlockFace.DOWN);
World world = placedBlock.getWorld();
if (placedBlock.getType().hasGravity() && !blockBeneath.getType().isSolid()) {
//If affected by gravity, and not placed on a solid surface, find the position the block will fall to
Block finalPosition = findFinalGravityBlockPosition(placedBlock, world, player);
if (finalPosition != null) {
addPlacedBlockToList(finalPosition, world.getName(), arenaId);
}
} else if (!placedBlock.getType().hasGravity()) {
addPlacedBlockToList(placedBlock, world.getName(), arenaId);
}
}
/**
* Finds the final position of a placed block affected by gravity
*
* @param placedBlock <p>The placed block</p>
* @param world <p>The world the block was placed in</p>
* @param player <p>The player that placed the block</p>
* @return <p>The final position the block will end up in</p>
*/
private Block findFinalGravityBlockPosition(Block placedBlock, World world, Player player) {
int x = placedBlock.getX();
int z = placedBlock.getZ();
int y = placedBlock.getY() - 1;
Block blockBeneath = world.getBlockAt(x, y, z);
//TODO: This doesn't really account for sand placed on torches, where the sand would disappear
while (!blockBeneath.getType().isSolid()) {
blockBeneath = world.getBlockAt(x, --y, z);
player.sendMessage(blockBeneath.getType().toString().toLowerCase());
if (blockBeneath.getType().isSolid()) {
return world.getBlockAt(x, y + 1, z);
}
}
return null;
}
@EventHandler(priority = EventPriority.MONITOR)
public void onBucketEmpty(PlayerBucketEmptyEvent event) {
//If already cancelled, do nothing
if (event.isCancelled()) {
return;
}
//If not in an arena, do nothing
if (plugin.getArena(event.getPlayer()) == null) {
return;
}
//TODO: Shouldn't this also follow protect always? And there is no actual prevention of placement
int arenaId = plugin.getArena(event.getPlayer()).getArenaId();
//If not currently join-able, don't do anything
if (!joinAble(arenaId)) {
return;
}
//If in a protected world, register the placed bucket
if (!plugin.restrictedWorlds || plugin.worldNames.containsValue(event.getPlayer().getWorld().getName())) {
Block clickedBlock = event.getBlockClicked().getRelative(event.getBlockFace());
String world = clickedBlock.getWorld().getName();
addPlacedBlockToList(clickedBlock, world, arenaId);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void onBucketFill(PlayerBucketFillEvent event) {
//If already cancelled, do nothing
if (event.isCancelled()) {
return;
}
//If not in an arena, do nothing
if (plugin.getArena(event.getPlayer()) == null) {
return;
}
int arena = plugin.getArena(event.getPlayer()).getArenaId();
boolean isPlaying = plugin.inArena.get(arena).contains(event.getPlayer().getUniqueId());
boolean enabledInWorld = plugin.worldNames.containsValue(event.getPlayer().getWorld().getName());
if (joinAble(arena) && (isPlaying && (!plugin.restrictedWorlds || enabledInWorld))) {
Block block = event.getBlockClicked().getRelative(event.getBlockFace());
String worldName = block.getWorld().getName();
addDestroyedBlockToList(block, worldName, arena);
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void blockMelt(BlockFadeEvent event) {
if (event.isCancelled()) {
return;
}
for (int arena : plugin.canJoin.keySet()) {
boolean isInWorld = plugin.worldNames.get(arena).equalsIgnoreCase(event.getBlock().getWorld().getName());
if (joinAble(arena) || alwaysProtect() &&
(!plugin.restrictedWorlds || plugin.worldNames.get(arena) != null && isInWorld)) {
Block block = event.getBlock();
String worldName = block.getWorld().getName();
Material material = block.getType();
if (material == Material.FIRE || material.isAir()) {
continue;
}
addDestroyedBlockToList(block, worldName, arena);
}
}
}
//SubRoutines:
private boolean alwaysProtect() {
return plugin.config.getBoolean("Protected_Arena_Always");
}
/**
* Adds the given block to the list of destroyed blocks for the given arena
*
* @param block <p>The block removed</p>
* @param worldName <p>The world the block was destroyed in</p>
* @param arena <p>The arena affected</p>
*/
private void addDestroyedBlockToList(Block block, String worldName, int arena) {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
String blockTypeName = block.getType().name();
String blockDataString;
String splitter = ";";
String direction = "";
block.getState().getBlockData();
blockDataString = block.getBlockData().getAsString();
String coordinates = worldName + splitter + x + splitter + y + splitter + z + splitter + blockTypeName +
splitter + blockDataString + splitter + arena + direction;
List<String> blocks = plugin.data.getStringList("Blocks_Destroyed");
if (!plugin.data.getStringList("Blocks_Placed").contains(String.format("%s,%d,%d,%d,%s", worldName, x, y,
z, arena))) {
blocks.add(coordinates);
plugin.data.set("Blocks_Destroyed", blocks);
plugin.saveData();
}
}
/**
* Adds the given block to the list of placed blocks for the given arena
*
* @param block <p>The block placed</p>
* @param worldName <p>The world the block was placed in</p>
* @param arena <p>The arena affected</p>
*/
private void addPlacedBlockToList(Block block, String worldName, int arena) {
String coordinates = String.format("%s,%d,%d,%d,%d", worldName, block.getX(), block.getY(), block.getZ(), arena);
List<String> blocks = plugin.data.getStringList("Blocks_Placed");
if (!blocks.contains(coordinates)) {
blocks.add(coordinates);
plugin.data.set("Blocks_Placed", blocks);
plugin.saveData();
}
}
/**
* Gets whether the given arena can be joined
*
* @param arena <p>The arena to check</p>
* @return <p>True if the arena can be joined</p>
*/
private boolean joinAble(int arena) {
return plugin.arenas.get(arena).isJoinAble();
}
/**
* Gets the id of the given player's current arena
*
* @param player <p>The player to get the id for</p>
* @param alwaysProtect <p>Whether always protect is enabled</p>
* @return <p>The id of the arena the player is in</p>
*/
private int getArenaId(Player player, boolean alwaysProtect) {
int arenaId = 1;
Arena pluginArena = plugin.getArena(player);
if (pluginArena != null) {
arenaId = pluginArena.getArenaId();
} else if (alwaysProtect) {
//If always protect is enabled, choose the first arena in the player's world, as an arena is necessary
String playerWorld = player.getWorld().getName();
for (int worldNameIndex : plugin.worldNames.keySet()) {
String worldName = plugin.worldNames.get(worldNameIndex);
if (worldName != null && worldName.equals(playerWorld)) {
arenaId = worldNameIndex;
}
}
}
return arenaId;
}
}

View File

@ -1,274 +0,0 @@
package net.knarcraft.hungerarena.Listeners;
import net.knarcraft.hungerarena.HungerArena;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockFadeEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.player.PlayerBucketFillEvent;
import java.util.List;
public class BlockStorage implements Listener {
public final HungerArena plugin;
public BlockStorage(HungerArena m) {
this.plugin = m;
}
@EventHandler(priority = EventPriority.MONITOR)
public void BlockBreak(BlockBreakEvent event) {
Block b = event.getBlock();
Player p = event.getPlayer();
String pname = p.getName();
boolean alwaysProtect = false;
if (!p.hasPermission("HungerArena.arena")) {
alwaysProtect = alwaysProtect();
}
if ((plugin.getArena(p) != null) || (alwaysProtect)) {
//Jeppa: get a default arena if always protect is true... (but use getArena if set...)
int a = 1;
if (alwaysProtect) {
String ThisWorld = p.getWorld().getName();
for (int z : plugin.worldNames.keySet()) {
if (plugin.worldNames.get(z) != null) {
if (plugin.worldNames.get(z).equals(ThisWorld)) {
a = z;
}
}
}
}
if (plugin.getArena(p) != null) {
a = plugin.getArena(p).getArenaId();
}
if ((!event.isCancelled()) && (((plugin.Playing.get(a)).contains(pname)) || (alwaysProtect))) {
if (plugin.config.getBoolean("Protected_Arena")) {
event.setCancelled(true);
p.sendMessage(ChatColor.RED + "You can't break blocks while playing!");
} else if ((plugin.canJoin.get(a) || alwaysProtect) && ((!plugin.restrictedWorlds) || ((plugin.restrictedWorlds) && (plugin.worldNames.containsValue(p.getWorld().getName()))))) {
if (((plugin.management.getStringList("blocks.whitelist").isEmpty()) || ((!plugin.management.getStringList("blocks.whitelist").isEmpty()) && (!plugin.management.getStringList("blocks.whitelist").contains(b.getType().name())))) ^ (plugin.management.getBoolean("blocks.useWhitelistAsBlacklist"))) {
event.setCancelled(true);
p.sendMessage(ChatColor.RED + "That is an illegal block!");
} else {
String w = b.getWorld().getName();
addDestroyedBlockToList(b, w, a);
}
}
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void Explosion(EntityExplodeEvent event) {
List<Block> blocksd = event.blockList();
Entity e = event.getEntity();
if (!event.isCancelled()) {
for (int i : plugin.canJoin.keySet()) {
if (plugin.canJoin.get(i) || alwaysProtect()) {
String ThisWorld = e.getWorld().getName();
if ((!plugin.restrictedWorlds) || ((plugin.restrictedWorlds) && plugin.worldNames.get(i) != null && plugin.worldNames.get(i).equalsIgnoreCase(ThisWorld))) {
if (e.getType() == EntityType.PRIMED_TNT) {
e.getLocation().getBlock().setType(Material.TNT);
Block TNT = e.getLocation().getBlock();
addDestroyedBlockToList(TNT, ThisWorld, i);
TNT.setType(Material.AIR);
}
for (Block b : blocksd) {
if (!b.getType().name().equalsIgnoreCase("AIR")) {
addDestroyedBlockToList(b, ThisWorld, i);
}
}
}
}
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void burningBlocks(BlockBurnEvent event) {
Block b = event.getBlock();
if (!event.isCancelled()) {
for (int i : plugin.canJoin.keySet()) {
if (plugin.canJoin.get(i) || alwaysProtect()) {
if ((!plugin.restrictedWorlds) || ((plugin.restrictedWorlds) && (plugin.worldNames.get(i) != null && plugin.worldNames.get(i).equalsIgnoreCase(b.getWorld().getName())))) {
String w = b.getWorld().getName();
addDestroyedBlockToList(b, w, i);
}
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void blockPlace(BlockPlaceEvent event) {
Block b = event.getBlock();
Player p = event.getPlayer();
boolean protall = false;
if (!p.hasPermission("HungerArena.arena")) {
protall = alwaysProtect();
}
if ((plugin.getArena(p) != null) || (protall)) {
int a = 1;
if (protall) {
String ThisWorld = p.getWorld().getName();
for (int z : plugin.worldNames.keySet()) {
if (plugin.worldNames.get(z) != null) {
if (plugin.worldNames.get(z).equals(ThisWorld)) {
a = z;
}
}
}
}
if (plugin.getArena(p) != null) {
a = plugin.getArena(p).getArenaId();
}
if (!event.isCancelled()) {
if (((plugin.Playing.get(a)).contains(p.getName())) || (protall)) {
if ((plugin.canJoin.get(a)) || (protall)) {
if ((!plugin.restrictedWorlds) || ((plugin.restrictedWorlds) && (plugin.worldNames.containsValue(b.getWorld().getName())))) {
if ((b.getType() == Material.SAND || b.getType() == Material.GRAVEL) && (b.getRelative(BlockFace.DOWN).getType() == Material.AIR || b.getRelative(BlockFace.DOWN).getType() == Material.WATER || b.getRelative(BlockFace.DOWN).getType() == Material.LAVA)) {
int n = b.getY() - 1;
while (b.getWorld().getBlockAt(b.getX(), n, b.getZ()).getType() == Material.AIR || b.getWorld().getBlockAt(b.getX(), n, b.getZ()).getType() == Material.WATER || b.getWorld().getBlockAt(b.getX(), n, b.getZ()).getType() == Material.LAVA) {
n = n - 1;
event.getPlayer().sendMessage(b.getWorld().getBlockAt(b.getX(), n, b.getZ()).getType().toString().toLowerCase());
if (b.getWorld().getBlockAt(b.getX(), n, b.getZ()).getType() != Material.AIR || b.getWorld().getBlockAt(b.getX(), n, b.getZ()).getType() != Material.WATER || b.getWorld().getBlockAt(b.getX(), n, b.getZ()).getType() != Material.LAVA) {
int l = n + 1;
Block br = b.getWorld().getBlockAt(b.getX(), l, b.getZ());
String w = br.getWorld().getName();
addPlacedBlockToList(br, w, a);
}
}
} else {
if (b.getType() != Material.SAND && b.getType() != Material.GRAVEL) {
String w = b.getWorld().getName();
addPlacedBlockToList(b, w, a);
}
}
}
}
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void bucketEmpty(PlayerBucketEmptyEvent event) {
if (plugin.getArena(event.getPlayer()) != null) {
int a = plugin.getArena(event.getPlayer()).getArenaId();
if (!event.isCancelled()) {
if (plugin.canJoin.get(a)) {
if (plugin.Playing.get(a).contains(event.getPlayer().getName())) {
if ((!plugin.restrictedWorlds) || ((plugin.restrictedWorlds) && (plugin.worldNames.containsValue(event.getPlayer().getWorld().getName())))) {
Block b = event.getBlockClicked().getRelative(event.getBlockFace());
String w = b.getWorld().getName();
addPlacedBlockToList(b, w, a);
}
}
}
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void bucketFill(PlayerBucketFillEvent event) {
if (plugin.getArena(event.getPlayer()) != null) {
int arena = plugin.getArena(event.getPlayer()).getArenaId();
if (event.isCancelled()) {
return;
}
boolean isPlaying = plugin.Playing.get(arena).contains(event.getPlayer().getName());
boolean enabledInWorld = plugin.worldNames.containsValue(event.getPlayer().getWorld().getName());
if (joinAble(arena) && (isPlaying && (!plugin.restrictedWorlds || enabledInWorld))) {
Block block = event.getBlockClicked().getRelative(event.getBlockFace());
String worldName = block.getWorld().getName();
addDestroyedBlockToList(block, worldName, arena);
}
}
}
@EventHandler(priority = EventPriority.MONITOR)
public void blockMelt(BlockFadeEvent event) {
if (event.isCancelled()) {
return;
}
for (int arena : plugin.canJoin.keySet()) {
boolean isInWorld = plugin.worldNames.get(arena).equalsIgnoreCase(event.getBlock().getWorld().getName());
if (joinAble(arena) || alwaysProtect() &&
(!plugin.restrictedWorlds || plugin.worldNames.get(arena) != null && isInWorld)) {
Block block = event.getBlock();
String worldName = block.getWorld().getName();
Material material = block.getType();
if (material == Material.FIRE || material.isAir()) {
continue;
}
addDestroyedBlockToList(block, worldName, arena);
}
}
}
//SubRoutines:
private boolean alwaysProtect() {
return plugin.config.getBoolean("Protected_Arena_Always");
}
private void addDestroyedBlockToList(Block block, String worldName, int arena) {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
String d = block.getType().name();
String blockDataString;
String splitter = ";";
String direction = "";
block.getState().getBlockData();
blockDataString = block.getBlockData().getAsString();
String coordinates = worldName + splitter + x + splitter + y + splitter + z + splitter + d + splitter +
blockDataString + splitter + arena + direction;
List<String> blocks = plugin.data.getStringList("Blocks_Destroyed");
if (!plugin.data.getStringList("Blocks_Placed").contains(String.format("%s,%d,%d,%d,%s", worldName, x, y, z, arena))) {
blocks.add(coordinates);
plugin.data.set("Blocks_Destroyed", blocks);
plugin.saveData();
}
}
private void addPlacedBlockToList(Block block, String worldName, int arena) {
int x = block.getX();
int y = block.getY();
int z = block.getZ();
String coordinates = String.format("%s,%d,%d,%d,%d", worldName, x, y, z, arena);
List<String> blocks = plugin.data.getStringList("Blocks_Placed");
if (!blocks.contains(coordinates)) {
blocks.add(coordinates);
plugin.data.set("Blocks_Placed", blocks);
plugin.saveData();
}
}
/**
* Gets whether the given arena can be joined
*
* @param arena <p>The arena to check</p>
* @return <p>True if the arena can be joined</p>
*/
private boolean joinAble(int arena) {
return plugin.canJoin.get(arena);
}
}

View File

@ -48,10 +48,10 @@ Countdown_Timer: 15
# How long the grace period should last (seconds) # How long the grace period should last (seconds)
Grace_Period: 60 Grace_Period: 60
# Whether players can break ANY blocks while playing # Whether players are prevented from breaking ANY blocks while playing
Protected_Arena: true Protected_Arena: true
# Whether players (not playing) can break blocks while waiting # Whether players (not playing) are prevented from breaking blocks while waiting
Protected_Arena_Always: true Protected_Arena_Always: true
# Whether new or unknown players on HA-maps should be forced to the spawn or not. # Whether new or unknown players on HA-maps should be forced to the spawn or not.