Add cheat flag to prevent Endermen from teleporting

Fixes #2105
This commit is contained in:
tastybento 2023-03-13 20:17:03 -07:00
parent c31458f8e6
commit 2940d2e492
4 changed files with 200 additions and 0 deletions

View File

@ -0,0 +1,39 @@
package world.bentobox.bentobox.listeners.flags.settings;
import java.util.Optional;
import org.bukkit.World;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityTeleportEvent;
import world.bentobox.bentobox.api.flags.FlagListener;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags;
/**
* Handles natural mob teleporting.
* @author tastybento
*/
public class MobTeleportListener extends FlagListener {
/**
* Check teleport of Endermen
* @param event EntityTeleportEvent
*/
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onEntityTeleportEvent(EntityTeleportEvent event) {
World w = event.getFrom().getWorld();
// If not in the right world exit immediately.
if (!this.getIWM().inWorld(w)) {
return;
}
Optional<Island> island = getIslands().getIslandAt(event.getEntity().getLocation());
if (Boolean.TRUE.equals(island.map(i -> !i.isAllowed(Flags.ENDERMAN_TELEPORT)).orElseGet(
() -> !Flags.ENDERMAN_TELEPORT.isSetForWorld(w)))) {
// Enderman teleport is disabled on island or world. Cancel it.
event.setCancelled(true);
}
}
}

View File

@ -42,6 +42,7 @@ import world.bentobox.bentobox.listeners.flags.protection.TeleportationListener;
import world.bentobox.bentobox.listeners.flags.protection.ThrowingListener;
import world.bentobox.bentobox.listeners.flags.settings.DecayListener;
import world.bentobox.bentobox.listeners.flags.settings.MobSpawnListener;
import world.bentobox.bentobox.listeners.flags.settings.MobTeleportListener;
import world.bentobox.bentobox.listeners.flags.settings.PVPListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.ChestDamageListener;
import world.bentobox.bentobox.listeners.flags.worldsettings.CleanSuperFlatListener;
@ -488,6 +489,13 @@ public final class Flags {
.listener(new EndermanListener())
.build();
/**
* If {@code false}, prevents Endermans from teleporting
* @since 1.22.1
*/
public static final Flag ENDERMAN_TELEPORT = new Flag.Builder("ENDERMAN_TELEPORT", Material.ENDER_PEARL).type(Type.SETTING)
.defaultSetting(true).listener(new MobTeleportListener()).mode(Flag.Mode.ADVANCED).build();
public static final Flag ENTER_EXIT_MESSAGES = new Flag.Builder("ENTER_EXIT_MESSAGES", Material.DIRT).defaultSetting(true).type(Type.WORLD_SETTING)
.listener(new EnterExitListener())
.build();

View File

@ -971,6 +971,11 @@ protection:
&a Endermen can remove
&a blocks from islands
name: "Enderman griefing"
ENDERMAN_TELEPORT:
description: |-
&a Endermen can teleport
&a if active.
name: "Enderman teleport"
ENDER_PEARL:
description: "Toggle use"
name: "EnderPearls"

View File

@ -0,0 +1,148 @@
package world.bentobox.bentobox.listeners.flags.settings;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Optional;
import org.bukkit.Location;
import org.bukkit.World;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.event.entity.EntityTeleportEvent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.lists.Flags;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
/**
* @author tastybento
*
*/
@RunWith(PowerMockRunner.class)
@PrepareForTest({BentoBox.class })
public class MobTeleportListenerTest {
@Mock
private IslandWorldManager iwm;
@Mock
private IslandsManager im;
@Mock
private Island island;
private MobTeleportListener mtl;
@Mock
private Entity enderman;
@Mock
private Entity other;
@Mock
private Location from;
@Mock
private Location to;
@Mock
private World world;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
// Set up plugin
BentoBox plugin = mock(BentoBox.class);
PowerMockito.mockStatic(BentoBox.class, Mockito.RETURNS_MOCKS);
when(BentoBox.getInstance()).thenReturn(plugin);
// Island World Manager
when(plugin.getIWM()).thenReturn(iwm);
when(iwm.inWorld(any(World.class))).thenReturn(true);
// Island Manager
when(plugin.getIslands()).thenReturn(im);
when(im.getIslandAt(any())).thenReturn(Optional.of(island));
when(island.isAllowed(Flags.ENDERMAN_TELEPORT)).thenReturn(true);
when(to.getWorld()).thenReturn(world);
when(from.getWorld()).thenReturn(world);
when(enderman.getType()).thenReturn(EntityType.ENDERMAN);
when(other.getType()).thenReturn(EntityType.AXOLOTL);
mtl = new MobTeleportListener();
}
/**
* @throws java.lang.Exception
*/
@After
public void tearDown() throws Exception {
Mockito.framework().clearInlineMocks();
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.flags.settings.MobTeleportListener#onEntityTeleportEvent(org.bukkit.event.entity.EntityTeleportEvent)}.
*/
@Test
public void testOnEntityTeleportEventEndermanNotAllowed() {
Flags.ENDERMAN_TELEPORT.setSetting(world, false);
when(island.isAllowed(Flags.ENDERMAN_TELEPORT)).thenReturn(false);
EntityTeleportEvent e = new EntityTeleportEvent(enderman, from, to);
mtl.onEntityTeleportEvent(e);
assertTrue(e.isCancelled());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.flags.settings.MobTeleportListener#onEntityTeleportEvent(org.bukkit.event.entity.EntityTeleportEvent)}.
*/
@Test
public void testOnEntityTeleportEventEndermanNotAllowedWrongWorld() {
when(iwm.inWorld(any(World.class))).thenReturn(false);
Flags.ENDERMAN_TELEPORT.setSetting(world, false);
when(island.isAllowed(Flags.ENDERMAN_TELEPORT)).thenReturn(false);
EntityTeleportEvent e = new EntityTeleportEvent(enderman, from, to);
mtl.onEntityTeleportEvent(e);
assertFalse(e.isCancelled());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.flags.settings.MobTeleportListener#onEntityTeleportEvent(org.bukkit.event.entity.EntityTeleportEvent)}.
*/
@Test
public void testOnEntityTeleportEventEndermanNotAllowedNotOnIsland() {
when(im.getIslandAt(any())).thenReturn(Optional.empty());
Flags.ENDERMAN_TELEPORT.setSetting(world, false);
EntityTeleportEvent e = new EntityTeleportEvent(enderman, from, to);
mtl.onEntityTeleportEvent(e);
assertFalse(e.isCancelled());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.flags.settings.MobTeleportListener#onEntityTeleportEvent(org.bukkit.event.entity.EntityTeleportEvent)}.
*/
@Test
public void testOnEntityTeleportEventEndermanAllowedDefault() {
EntityTeleportEvent e = new EntityTeleportEvent(enderman, from, to);
mtl.onEntityTeleportEvent(e);
assertFalse(e.isCancelled());
}
/**
* Test method for {@link world.bentobox.bentobox.listeners.flags.settings.MobTeleportListener#onEntityTeleportEvent(org.bukkit.event.entity.EntityTeleportEvent)}.
*/
@Test
public void testOnEntityTeleportEventOther() {
EntityTeleportEvent e = new EntityTeleportEvent(other, from, to);
mtl.onEntityTeleportEvent(e);
assertFalse(e.isCancelled());
}
}