Added event tests.

Fixed bug with user being retained after a checkIsland.
This commit is contained in:
Tastybento 2018-02-03 19:25:53 -08:00
parent c648409858
commit 6c2078fbec
8 changed files with 146 additions and 58 deletions

View File

@ -278,6 +278,7 @@ public class Island implements DataObject {
* @return rank integer
*/
public int getRank(User user) {
Bukkit.getLogger().info("DEBUG: user UUID = " + user.getUniqueId());
return members.containsKey(user.getUniqueId()) ? members.get(user.getUniqueId()) : RanksManager.VISITOR_RANK;
}

View File

@ -3,14 +3,16 @@
*/
package us.tastybento.bskyblock.listeners.flags;
import java.lang.reflect.Method;
import java.util.Optional;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerEvent;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.commands.User;
@ -36,24 +38,29 @@ public abstract class AbstractFlagListener implements Listener {
* Sets the player associated with this event.
* If the user is a fake player, they are not counted.
* @param e - the event
* @return user or empty
* @return true if found, otherwise false
*/
private Optional<User> createEventUser(Event e) {
// Set the user
if (e instanceof PlayerEvent) {
user = User.getInstance(((PlayerEvent)e).getPlayer());
// Handle fake players
if (plugin.getSettings().getFakePlayers().contains(user.getName())) user = null;
}
return Optional.ofNullable(user);
private boolean createEventUser(Event e) {
try {
// Use reflection to get the getPlayer method if it exists
Method getPlayer = e.getClass().getMethod("getPlayer");
if (getPlayer != null) {
setUser(User.getInstance((Player)getPlayer.invoke(e)));
return true;
}
} catch (Exception e1) {
e1.printStackTrace();
}
return false;
}
/**
* Explicitly set the user
* Explicitly set the user for the next {@link #checkIsland(Event, Location, Flag)} or {@link #checkIsland(Event, Location, Flag, boolean)}
* @param user
*/
public void setUser(User user) {
this.user = user;
public AbstractFlagListener setUser(User user) {
if (!plugin.getSettings().getFakePlayers().contains(user.getName())) this.user = user;
return this;
}
/*
@ -133,22 +140,31 @@ public abstract class AbstractFlagListener implements Listener {
* @return true if the check is okay, false if it was disallowed
*/
public boolean checkIsland(Event e, Location loc, Flag flag, boolean silent) {
// If the user is not set, try to get it from the event
// If the user is not set already, try to get it from the event
if (user == null) {
// Set the user associated with this event
if (!createEventUser(e).isPresent()) return true;
if (!createEventUser(e)) {
// The user is not set, and the event does not hold a getPlayer, so return false
// TODO: is this the correct handling here?
Bukkit.getLogger().severe("Check island had no associated user!");
return false;
}
}
// If this is not an Island World, skip
if (!inWorld(user)) return true;
// Get the island and if present, check the flag, react if required and return
Optional<Island> island = plugin.getIslands().getIslandAt(loc);
if (island.isPresent()) {
if (!island.get().isAllowed(user, flag)) {
noGo(e, silent);
// Clear the user for the next time
user = null;
return false;
} else {
user = null;
return true;
}
}
@ -156,11 +172,12 @@ public abstract class AbstractFlagListener implements Listener {
// The player is in the world, but not on an island, so general world settings apply
if (!flag.isAllowed()) {
noGo(e, silent);
user = null;
return false;
} else {
user = null;
return true;
}
}
}

View File

@ -45,8 +45,7 @@ public class BreakBlocksListener extends AbstractFlagListener {
@EventHandler(priority = EventPriority.LOW)
public void onBreakHanging(final HangingBreakByEntityEvent e) {
if (e.getRemover() instanceof Player) {
setUser(User.getInstance(e.getRemover()));
checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS);
setUser(User.getInstance(e.getRemover())).checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS);
}
}
@ -126,14 +125,12 @@ public class BreakBlocksListener extends AbstractFlagListener {
// Get the attacker
if (e.getDamager() instanceof Player) {
setUser(User.getInstance(e.getDamager()));
checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS);
setUser(User.getInstance(e.getDamager())).checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS);
} else if (e.getDamager() instanceof Projectile) {
// Find out who fired the arrow
Projectile p = (Projectile) e.getDamager();
if (p.getShooter() instanceof Player) {
setUser(User.getInstance((Player)p.getShooter()));
if (!checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS)) {
if (!setUser(User.getInstance((Player)p.getShooter())).checkIsland(e, e.getEntity().getLocation(), Flags.BREAK_BLOCKS)) {
e.getEntity().setFireTicks(0);
e.getDamager().remove();
}

View File

@ -157,8 +157,7 @@ public class FireListener extends AbstractFlagListener {
if (projectile.getShooter() instanceof Player) {
if (projectile.getFireTicks() > 0) {
Player shooter = (Player)projectile.getShooter();
setUser(User.getInstance(shooter));
if (checkIsland(e, e.getBlock().getLocation(), Flags.BREAK_BLOCKS)) {
if (setUser(User.getInstance(shooter)).checkIsland(e, e.getBlock().getLocation(), Flags.BREAK_BLOCKS)) {
// Remove the arrow
projectile.remove();
}

View File

@ -74,14 +74,12 @@ public class HurtingListener extends AbstractFlagListener {
private void respond(Event event, Entity damager, Flag flag) {
// Get the attacker
if (damager instanceof Player) {
setUser(User.getInstance(damager));
checkIsland(event, damager.getLocation(), flag);
setUser(User.getInstance(damager)).checkIsland(event, damager.getLocation(), flag);
} else if (damager instanceof Projectile) {
// Find out who fired the projectile
Projectile p = (Projectile) damager;
if (p.getShooter() instanceof Player) {
setUser(User.getInstance((Player)p.getShooter()));
if (!checkIsland(event, damager.getLocation(), flag)) {
if (!setUser(User.getInstance((Player)p.getShooter())).checkIsland(event, damager.getLocation(), flag)) {
damager.setFireTicks(0);
damager.remove();
}
@ -138,7 +136,6 @@ public class HurtingListener extends AbstractFlagListener {
Projectile projectile = (Projectile) e.getEntity();
if (projectile.getShooter() != null && projectile.getShooter() instanceof Player) {
Player attacker = (Player)projectile.getShooter();
setUser(User.getInstance(attacker));
// Run through all the affected entities
for (LivingEntity entity: e.getAffectedEntities()) {
// Self damage
@ -147,7 +144,7 @@ public class HurtingListener extends AbstractFlagListener {
}
// Monsters being hurt
if (entity instanceof Monster || entity instanceof Slime || entity instanceof Squid) {
if (!checkIsland(e, entity.getLocation(), Flags.HURT_MONSTERS)) {
if (!setUser(User.getInstance(attacker)).checkIsland(e, entity.getLocation(), Flags.HURT_MONSTERS)) {
for (PotionEffect effect : e.getPotion().getEffects()) {
entity.removePotionEffect(effect.getType());
}

View File

@ -37,9 +37,8 @@ public class ItemDropPickUpListener extends AbstractFlagListener {
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onVisitorDrop(EntityPickupItemEvent e) {
if (e.getEntity() instanceof Player) {
setUser(User.getInstance(e.getEntity()));
// Disallow, but don't tell the player an error
checkIsland(e, e.getItem().getLocation(), Flags.ITEM_PICKUP, false);
setUser(User.getInstance(e.getEntity())).checkIsland(e, e.getItem().getLocation(), Flags.ITEM_PICKUP, false);
}
}
}

View File

@ -58,14 +58,13 @@ public class PVPListener extends AbstractFlagListener {
private void respond(Event event, Entity damager, Flag flag) {
// Get the attacker
if (damager instanceof Player) {
setUser(User.getInstance(damager));
checkIsland(event, damager.getLocation(), flag);
setUser(User.getInstance(damager)).checkIsland(event, damager.getLocation(), flag);
} else if (damager instanceof Projectile) {
// Find out who fired the arrow
Projectile p = (Projectile) damager;
if (p.getShooter() instanceof Player) {
setUser(User.getInstance((Player)p.getShooter()));
if (!checkIsland(event, damager.getLocation(), flag)) {
;
if (!setUser(User.getInstance((Player)p.getShooter())).checkIsland(event, damager.getLocation(), flag)) {
damager.setFireTicks(0);
damager.remove();
}
@ -102,7 +101,6 @@ public class PVPListener extends AbstractFlagListener {
Projectile projectile = (Projectile) e.getEntity();
if (projectile.getShooter() != null && projectile.getShooter() instanceof Player) {
Player attacker = (Player)projectile.getShooter();
setUser(User.getInstance(attacker));
// Run through all the affected entities
for (LivingEntity entity: e.getAffectedEntities()) {
// Self damage
@ -111,7 +109,7 @@ public class PVPListener extends AbstractFlagListener {
}
// PVP?
if (entity instanceof Player) {
if (!checkIsland(e, entity.getLocation(), flag)) {
if (!setUser(User.getInstance(attacker)).checkIsland(e, entity.getLocation(), flag)) {
for (PotionEffect effect : e.getPotion().getEffects()) {
entity.removePotionEffect(effect.getType());
}

View File

@ -10,6 +10,8 @@ import static org.mockito.Mockito.mock;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
@ -22,10 +24,14 @@ import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.meta.ItemMeta;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -36,11 +42,15 @@ import org.powermock.modules.junit4.PowerMockRunner;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.Constants;
import us.tastybento.bskyblock.Settings;
import us.tastybento.bskyblock.api.commands.CompositeCommand;
import us.tastybento.bskyblock.api.commands.User;
import us.tastybento.bskyblock.api.events.IslandBaseEvent;
import us.tastybento.bskyblock.api.events.team.TeamEvent;
import us.tastybento.bskyblock.database.managers.island.IslandsManager;
import us.tastybento.bskyblock.database.objects.Island;
import us.tastybento.bskyblock.generators.IslandWorld;
import us.tastybento.bskyblock.listeners.flags.AbstractFlagListener;
import us.tastybento.bskyblock.lists.Flags;
import us.tastybento.bskyblock.managers.FlagsManager;
import us.tastybento.bskyblock.managers.RanksManager;
@ -51,19 +61,26 @@ import us.tastybento.bskyblock.util.Util;
//@PrepareForTest( { Bukkit.class })
@PrepareForTest( { Flags.class })
public class TestBSkyBlock {
private static final UUID MEMBER_UUID = UUID.randomUUID();
private static final UUID OWNER_UUID = UUID.randomUUID();
private static final UUID VISITOR_UUID = UUID.randomUUID();
private final UUID playerUUID = UUID.randomUUID();
private static CommandSender sender;
private static Player player;
private static Location location;
private static BSkyBlock plugin;
private static FlagsManager flagsManager;
private static Block block;
private static World world;
private static Player ownerOfIsland;
private static Player visitorToIsland;
@BeforeClass
public static void setUp() {
//PowerMockito.mockStatic(Bukkit.class);
//Mockito.doReturn(plugin).when(BSkyBlock.getPlugin());
//Mockito.when().thenReturn(plugin);
World world = mock(World.class);
world = mock(World.class);
//Mockito.when(world.getWorldFolder()).thenReturn(worldFile);
@ -76,6 +93,8 @@ public class TestBSkyBlock {
Mockito.when(Bukkit.getLogger()).thenReturn(Logger.getAnonymousLogger());
sender = mock(CommandSender.class);
player = mock(Player.class);
ownerOfIsland = mock(Player.class);
visitorToIsland = mock(Player.class);
Mockito.when(player.hasPermission(Constants.PERMPREFIX + "default.permission")).thenReturn(true);
@ -86,6 +105,14 @@ public class TestBSkyBlock {
Mockito.when(location.getBlockX()).thenReturn(0);
Mockito.when(location.getBlockY()).thenReturn(0);
Mockito.when(location.getBlockZ()).thenReturn(0);
Mockito.when(player.getLocation()).thenReturn(location);
Mockito.when(ownerOfIsland.getLocation()).thenReturn(location);
Mockito.when(visitorToIsland.getLocation()).thenReturn(location);
Mockito.when(player.getUniqueId()).thenReturn(MEMBER_UUID);
Mockito.when(ownerOfIsland.getUniqueId()).thenReturn(OWNER_UUID);
Mockito.when(visitorToIsland.getUniqueId()).thenReturn(VISITOR_UUID);
// Mock itemFactory for ItemStack
ItemFactory itemFactory = PowerMockito.mock(ItemFactory.class);
@ -98,6 +125,40 @@ public class TestBSkyBlock {
plugin = Mockito.mock(BSkyBlock.class);
flagsManager = Mockito.mock(FlagsManager.class);
Mockito.when(plugin.getFlagsManager()).thenReturn(flagsManager);
block = Mockito.mock(Block.class);
// Worlds
IslandWorld iwm = mock(IslandWorld.class);
Mockito.when(plugin.getIslandWorldManager()).thenReturn(iwm);
Mockito.when(iwm.getIslandWorld()).thenReturn(world);
Mockito.when(iwm.getNetherWorld()).thenReturn(world);
Mockito.when(iwm.getEndWorld()).thenReturn(world);
// User
//User user = Mockito.mock(User.class);
//Mockito.when(user.getName()).thenReturn("tastybento");
// Islands
IslandsManager im = mock(IslandsManager.class);
Mockito.when(plugin.getIslands()).thenReturn(im);
Island island = new Island();
island.setOwner(OWNER_UUID);
island.setCenter(location);
island.setProtectionRange(100);
HashMap<UUID, Integer> members = new HashMap<>();
members.put(OWNER_UUID, RanksManager.OWNER_RANK);
members.put(MEMBER_UUID, RanksManager.MEMBER_RANK);
island.setMembers(members);
Bukkit.getLogger().info("SETUP: owner UUID = " + OWNER_UUID);
Bukkit.getLogger().info("SETUP: member UUID = " + MEMBER_UUID);
Bukkit.getLogger().info("SETUP: visitor UUID = " + VISITOR_UUID);
Mockito.when(im.getIslandAt(Mockito.any())).thenReturn(Optional.of(island));
Settings settings = mock(Settings.class);
Mockito.when(plugin.getSettings()).thenReturn(settings);
Mockito.when(settings.getFakePlayers()).thenReturn(new HashSet<String>());
}
@Test
@ -381,16 +442,21 @@ public class TestBSkyBlock {
island.addToBanList(member3);
User mem3 = User.getInstance(member3); // Banned
// Member 1 is a visitor
assertTrue(island.isAllowed(mem1, Flags.PLACE_BLOCKS));
assertFalse(island.isAllowed(mem1, Flags.BREAK_BLOCKS));
// Member 2 is a team member
assertTrue(island.isAllowed(mem2, Flags.PLACE_BLOCKS));
assertTrue(island.isAllowed(mem2, Flags.BREAK_BLOCKS));
// Member 3 is no longer a member and is a visitor
// Member 3 is no longer a member and is banned
assertFalse(island.isAllowed(mem3, Flags.PLACE_BLOCKS));
assertFalse(island.isAllowed(mem3, Flags.BREAK_BLOCKS));
}
@Test
public void TestEventProtection() {
/*
*
@ -430,22 +496,36 @@ public class TestBSkyBlock {
* During the game, the players will never see the rank value. They will only see the ranks.
*
* It will be possible to island owners to promote or demote players up and down the ranks.
*
* This will replace the team system completely.
*
* Pros:
* Very flexible
*
* Cons:
* Too complicated. Are there really ever going to be more than just a few ranks?
* To have generic, unlimited ranks, we lose the concept of hard-coded teams, coops, etc.
* The problem is that team members must lose their islands and so we have special code around that.
* i.e., there's a lot more going on than just ranks.
*
*
* Permissions-based
*
*
*/
// Now test events
FlagListener fl = new FlagListener(plugin);
Bukkit.getLogger().info("SETUP: owner UUID = " + ownerOfIsland.getUniqueId());
Bukkit.getLogger().info("SETUP: member UUID = " + player.getUniqueId());
Bukkit.getLogger().info("SETUP: visitor UUID = " + visitorToIsland.getUniqueId());
Bukkit.getLogger().info("DEBUG: checking events - vistor");
Event e3 = new BlockBreakEvent(block, visitorToIsland);
Assert.assertFalse(fl.checkIsland(e3, location, Flags.BREAK_BLOCKS, true));
Bukkit.getLogger().info("DEBUG: checking events - owner");
Event e = new BlockBreakEvent(block, ownerOfIsland);
Assert.assertTrue(fl.checkIsland(e, location, Flags.BREAK_BLOCKS, true));
// Set up an event with a random player
Bukkit.getLogger().info("DEBUG: checking events - member");
Event e2 = new BlockBreakEvent(block, player);
Assert.assertTrue(fl.checkIsland(e2, location, Flags.BREAK_BLOCKS, true));
}
private class FlagListener extends AbstractFlagListener {
public FlagListener(BSkyBlock plugin) {
super(plugin);
}
}
}