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() {
@ -82,5 +82,5 @@ public class Arena {
public void setGracePeriod(int gracePeriod) { public void setGracePeriod(int gracePeriod) {
this.gracePeriod = gracePeriod; this.gracePeriod = gracePeriod;
} }
} }

View File

@ -20,17 +20,17 @@ 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) {
@ -48,7 +48,7 @@ public class ArenaPlayer {
/** /**
* Gets the player this arena player corresponds to * Gets the player this arena player corresponds to
* *
* @return <p>The actual player</p> * @return <p>The actual player</p>
*/ */
public Player getPlayer() { public Player getPlayer() {
@ -61,7 +61,7 @@ public class ArenaPlayer {
/** /**
* Gets the arena this arena player is currently in * Gets the arena this arena player is currently in
* *
* @return <p>The arena this player is in, or null if not in an arena</p> * @return <p>The arena this player is in, or null if not in an arena</p>
*/ */
public Arena getArena() { public Arena getArena() {
@ -74,7 +74,7 @@ public class ArenaPlayer {
/** /**
* Gets whether this arena player is ready to start the game * Gets whether this arena player is ready to start the game
* *
* @return <p>True if this player is ready</p> * @return <p>True if this player is ready</p>
*/ */
public boolean isReady() { public boolean isReady() {
@ -87,9 +87,9 @@ public class ArenaPlayer {
/** /**
* Gets whether this arena player has quit * Gets whether this arena player has quit
* *
* <p>If the player has been kicked, has died or has quit the game, this returns true.</p> * <p>If the player has been kicked, has died or has quit the game, this returns true.</p>
* *
* @return <p>True if this arena player has quit</p> * @return <p>True if this arena player has quit</p>
*/ */
public boolean hasQuit() { public boolean hasQuit() {
@ -102,7 +102,7 @@ public class ArenaPlayer {
/** /**
* Gets whether this arena player has died * Gets whether this arena player has died
* *
* @return <p>True if this arena player has died</p> * @return <p>True if this arena player has died</p>
*/ */
public boolean isDead() { public boolean isDead() {
@ -115,7 +115,7 @@ public class ArenaPlayer {
/** /**
* Gets whether this arena player has left the game, and is "out" * Gets whether this arena player has left the game, and is "out"
* *
* @return <p>True if this arena player is currently out</p> * @return <p>True if this arena player is currently out</p>
*/ */
public boolean isOut() { public boolean isOut() {
@ -128,7 +128,7 @@ public class ArenaPlayer {
/** /**
* Gets whether this arena player is currently watching the arena * Gets whether this arena player is currently watching the arena
* *
* @return <p>True if currently watching the arena</p> * @return <p>True if currently watching the arena</p>
*/ */
public boolean isWatching() { public boolean isWatching() {
@ -142,22 +142,22 @@ public class ArenaPlayer {
/** /**
* Gets whether ths arena player needs to confirm that they want to join the game * Gets whether ths arena player needs to confirm that they want to join the game
* *
* <p>As some arenas have entry fees, they might require that a player confirms that they really want to join the * <p>As some arenas have entry fees, they might require that a player confirms that they really want to join the
* arena. If a player hasn't confirmed that they want to join, this will be true.</p> * arena. If a player hasn't confirmed that they want to join, this will be true.</p>
* *
* @return <p>True if this arena player needs to confirm that they are joining</p> * @return <p>True if this arena player needs to confirm that they are joining</p>
*/ */
public boolean needConfirmation() { public boolean needConfirmation() {
return needConfirmation; return needConfirmation;
} }
public void setNeedConfirmation(boolean needConfirmation) { public void setNeedConfirmation(boolean needConfirmation) {
this.needConfirmation = needConfirmation; this.needConfirmation = needConfirmation;
} }
/** /**
* Gets whether this arena player is currently in an arena * Gets whether this arena player is currently in an arena
* *
* @return <p>True if in an arena</p> * @return <p>True if in an arena</p>
*/ */
public boolean isInArena() { public boolean isInArena() {
@ -166,7 +166,7 @@ public class ArenaPlayer {
/** /**
* Sets whether this arena player is currently in an arena * Sets whether this arena player is currently in an arena
* *
* @param inArena <p>True if this arena player is currently in an arena</p> * @param inArena <p>True if this arena player is currently in an arena</p>
*/ */
public void setInArena(boolean inArena) { public void setInArena(boolean inArena) {
@ -175,10 +175,10 @@ public class ArenaPlayer {
/** /**
* Gets whether this arena player is frozen * Gets whether this arena player is frozen
* *
* <p>A frozen player is a player that is currently prevented from moving, such as when players are forced to stay * <p>A frozen player is a player that is currently prevented from moving, such as when players are forced to stay
* on their pedestals until the countdown expires.</p> * on their pedestals until the countdown expires.</p>
* *
* @return <p>True if this arena player is frozen</p> * @return <p>True if this arena player is frozen</p>
*/ */
public boolean isFrozen() { public boolean isFrozen() {
@ -188,5 +188,5 @@ public class ArenaPlayer {
public void setFrozen(boolean frozen) { public void setFrozen(boolean frozen) {
this.frozen = frozen; this.frozen = 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

@ -90,7 +90,7 @@ public class DeathListener implements Listener {
} }
} }
} }
private void doFrozenPlayerStuff(Player p, int players, String leftmsg, String pname, UUID playerId, PlayerDeathEvent event, Server s) { private void doFrozenPlayerStuff(Player p, int players, String leftmsg, String pname, UUID playerId, PlayerDeathEvent event, Server s) {
//Basically, if a frozen player is killed by something which isn't another player, assume the reason the player //Basically, if a frozen player is killed by something which isn't another player, assume the reason the player
// was killed was because they left their pedestal too early // was killed was because they left their pedestal too early
@ -120,7 +120,7 @@ public class DeathListener implements Listener {
plugin.winner(a); plugin.winner(a);
} }
} }
private void doNonFrozenPlayerStuff(Player player, int players, String leftmsg, String pname, UUID playerId, PlayerDeathEvent event, Server s) { private void doNonFrozenPlayerStuff(Player player, int players, String leftmsg, String pname, UUID playerId, PlayerDeathEvent event, Server s) {
leftmsg = ChatColor.BLUE + "There are now " + players + " tributes left!"; leftmsg = ChatColor.BLUE + "There are now " + players + " tributes left!";
fireCannon(player); fireCannon(player);
@ -200,7 +200,7 @@ public class DeathListener implements Listener {
plugin.winner(a); plugin.winner(a);
} }
} }
private void fireCannon(Player player) { private void fireCannon(Player player) {
if (plugin.config.getBoolean("Cannon_Death")) { if (plugin.config.getBoolean("Cannon_Death")) {
double y = player.getLocation().getY(); double y = player.getLocation().getY();

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.