mirror of
https://github.com/BentoBoxWorld/BentoBox.git
synced 2024-12-21 16:47:39 +01:00
Added offline redstone world flag
Removed constructor from LockAndBanListener. Due to loading order, some manager objects are null. Flags load very early so must assume everything is null.
This commit is contained in:
parent
a60bcc8a22
commit
4963ea573c
@ -447,6 +447,13 @@ protection:
|
||||
description: "Toggle access"
|
||||
name: Music
|
||||
hint: "No jukebox use"
|
||||
OFFLINE_REDSTONE:
|
||||
description: |
|
||||
&aWhen disabled, redstone
|
||||
&awill not operate on islands
|
||||
&awhere all members are offline.
|
||||
&aMay help reduce lag.
|
||||
name: "Offline Redstone"
|
||||
PISTON_PUSH:
|
||||
description: |
|
||||
&aAllow pistons to push
|
||||
|
@ -239,12 +239,6 @@ public class Settings implements DataObject, WorldSettings {
|
||||
@ConfigEntry(path = "world.end.dragon-spawn")
|
||||
private boolean dragonSpawn = false;
|
||||
|
||||
@ConfigComment("Disable redstone operation on islands unless a team member is online.")
|
||||
@ConfigComment("This may reduce lag but it can cause problems with visitors needing to use a redstone system.")
|
||||
@ConfigComment("Default is false, because it is an experimental feature that can break a lot of redstone systems.")
|
||||
@ConfigEntry(path = "world.disable-offline-redstone")
|
||||
private boolean disableOfflineRedstone = false;
|
||||
|
||||
@ConfigComment("Removing mobs - this kills all monsters in the vicinity. Benefit is that it helps")
|
||||
@ConfigComment("players return to their island if the island has been overrun by monsters.")
|
||||
@ConfigComment("This setting is toggled in world flags and set by the settings GUI.")
|
||||
@ -503,18 +497,6 @@ public class Settings implements DataObject, WorldSettings {
|
||||
public void setMuteDeathMessages(boolean muteDeathMessages) {
|
||||
this.muteDeathMessages = muteDeathMessages;
|
||||
}
|
||||
/**
|
||||
* @return the disableOfflineRedstone
|
||||
*/
|
||||
public boolean isDisableOfflineRedstone() {
|
||||
return disableOfflineRedstone;
|
||||
}
|
||||
/**
|
||||
* @param disableOfflineRedstone the disableOfflineRedstone to set
|
||||
*/
|
||||
public void setDisableOfflineRedstone(boolean disableOfflineRedstone) {
|
||||
this.disableOfflineRedstone = disableOfflineRedstone;
|
||||
}
|
||||
/**
|
||||
* @return the chestItems
|
||||
*/
|
||||
|
@ -17,30 +17,22 @@ import org.bukkit.util.Vector;
|
||||
import us.tastybento.bskyblock.BSkyBlock;
|
||||
import us.tastybento.bskyblock.api.user.User;
|
||||
import us.tastybento.bskyblock.lists.Flags;
|
||||
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||
|
||||
/**
|
||||
* Listener for the lock flag
|
||||
* Also handles ban protection
|
||||
*
|
||||
*
|
||||
* @author tastybento
|
||||
*
|
||||
*/
|
||||
public class LockAndBanListener implements Listener {
|
||||
|
||||
private IslandsManager im;
|
||||
private enum CheckResult {
|
||||
BANNED,
|
||||
LOCKED,
|
||||
OPEN
|
||||
}
|
||||
|
||||
/**
|
||||
* Enforces island bans and locks
|
||||
*/
|
||||
public LockAndBanListener() {
|
||||
this.im = BSkyBlock.getInstance().getIslands();
|
||||
}
|
||||
|
||||
// Teleport check
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
@ -79,12 +71,12 @@ public class LockAndBanListener implements Listener {
|
||||
e.getVehicle().getPassengers().stream().filter(en -> en instanceof Player).map(en -> (Player)en).forEach(p -> {
|
||||
if (!checkAndNotify(p, e.getTo()).equals(CheckResult.OPEN)) {
|
||||
p.leaveVehicle();
|
||||
p.teleport(e.getFrom());
|
||||
p.teleport(e.getFrom());
|
||||
e.getFrom().getWorld().playSound(e.getFrom(), Sound.BLOCK_ANVIL_HIT, 1F, 1F);
|
||||
eject(p);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Login check
|
||||
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||
@ -103,7 +95,7 @@ public class LockAndBanListener implements Listener {
|
||||
private CheckResult check(Player player, Location loc) {
|
||||
|
||||
// See if the island is locked to non-members or player is banned
|
||||
return im.getProtectedIslandAt(loc)
|
||||
return BSkyBlock.getInstance().getIslands().getProtectedIslandAt(loc)
|
||||
.map(is -> {
|
||||
if (is.isBanned(player.getUniqueId())) {
|
||||
return CheckResult.BANNED;
|
||||
@ -143,9 +135,9 @@ public class LockAndBanListener implements Listener {
|
||||
private void eject(Player player) {
|
||||
player.setGameMode(GameMode.SPECTATOR);
|
||||
// Teleport player to their home
|
||||
if (im.hasIsland(player.getWorld(), player.getUniqueId())) {
|
||||
im.homeTeleport(player.getWorld(), player);
|
||||
} // else, TODO: teleport somewhere else?
|
||||
if (BSkyBlock.getInstance().getIslands().hasIsland(player.getWorld(), player.getUniqueId())) {
|
||||
BSkyBlock.getInstance().getIslands().homeTeleport(player.getWorld(), player);
|
||||
} // else, TODO: teleport somewhere else?
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,29 @@
|
||||
package us.tastybento.bskyblock.listeners.flags;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.EventPriority;
|
||||
import org.bukkit.event.block.BlockRedstoneEvent;
|
||||
|
||||
import us.tastybento.bskyblock.api.flags.AbstractFlagListener;
|
||||
import us.tastybento.bskyblock.lists.Flags;
|
||||
|
||||
public class OfflineRedstoneListener extends AbstractFlagListener {
|
||||
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
|
||||
public void onBlockRedstone(BlockRedstoneEvent e) {
|
||||
// If offline redstone is allowed then return
|
||||
if (!Flags.OFFLINE_REDSTONE.isSetForWorld(e.getBlock().getWorld())) {
|
||||
// Check if island exists and members are online
|
||||
getIslands().getProtectedIslandAt(e.getBlock().getLocation()).ifPresent(i -> {
|
||||
for (UUID uuid : i.getMemberSet()) {
|
||||
if (Bukkit.getPlayer(uuid) != null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
e.setNewCurrent(0);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ import us.tastybento.bskyblock.listeners.flags.IslandRespawnListener;
|
||||
import us.tastybento.bskyblock.listeners.flags.ItemDropPickUpListener;
|
||||
import us.tastybento.bskyblock.listeners.flags.LeashListener;
|
||||
import us.tastybento.bskyblock.listeners.flags.LockAndBanListener;
|
||||
import us.tastybento.bskyblock.listeners.flags.OfflineRedstoneListener;
|
||||
import us.tastybento.bskyblock.listeners.flags.PVPListener;
|
||||
import us.tastybento.bskyblock.listeners.flags.PhysicalInteractionListener;
|
||||
import us.tastybento.bskyblock.listeners.flags.PistonPushListener;
|
||||
@ -173,6 +174,8 @@ public class Flags {
|
||||
.listener(new RemoveMobsListener()).allowedByDefault(true).onClick(new WorldToggleClickListener("REMOVE_MOBS")).build();
|
||||
public static final Flag ISLAND_RESPAWN = new FlagBuilder().id("ISLAND_RESPAWN").icon(Material.TORCH).type(Type.WORLD_SETTING)
|
||||
.listener(new IslandRespawnListener()).allowedByDefault(true).onClick(new WorldToggleClickListener("ISLAND_RESPAWN")).build();
|
||||
public static final Flag OFFLINE_REDSTONE = new FlagBuilder().id("OFFLINE_REDSTONE").icon(Material.REDSTONE_COMPARATOR).type(Type.WORLD_SETTING)
|
||||
.listener(new OfflineRedstoneListener()).allowedByDefault(true).onClick(new WorldToggleClickListener("OFFLINE_REDSTONE")).build();
|
||||
|
||||
/**
|
||||
* @return List of all the flags in this class
|
||||
|
@ -0,0 +1,152 @@
|
||||
package us.tastybento.bskyblock.listeners.flags;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.block.BlockRedstoneEvent;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mockito;
|
||||
import org.powermock.api.mockito.PowerMockito;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import org.powermock.reflect.Whitebox;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.collect.ImmutableSet.Builder;
|
||||
|
||||
import us.tastybento.bskyblock.BSkyBlock;
|
||||
import us.tastybento.bskyblock.api.configuration.WorldSettings;
|
||||
import us.tastybento.bskyblock.database.objects.Island;
|
||||
import us.tastybento.bskyblock.lists.Flags;
|
||||
import us.tastybento.bskyblock.managers.IslandWorldManager;
|
||||
import us.tastybento.bskyblock.managers.IslandsManager;
|
||||
import us.tastybento.bskyblock.util.Util;
|
||||
@RunWith(PowerMockRunner.class)
|
||||
@PrepareForTest({BSkyBlock.class, Util.class, Bukkit.class })
|
||||
public class OfflineRedstoneListenerTest {
|
||||
|
||||
private World world;
|
||||
private UUID uuid;
|
||||
private Island island;
|
||||
private IslandsManager im;
|
||||
private Location inside;
|
||||
private Block block;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
// Set up plugin
|
||||
BSkyBlock plugin = mock(BSkyBlock.class);
|
||||
Whitebox.setInternalState(BSkyBlock.class, "instance", plugin);
|
||||
|
||||
// World
|
||||
world = mock(World.class);
|
||||
// Owner
|
||||
uuid = UUID.randomUUID();
|
||||
|
||||
// Island initialization
|
||||
island = mock(Island.class);
|
||||
when(island.getOwner()).thenReturn(uuid);
|
||||
// Add members
|
||||
Builder<UUID> set = new ImmutableSet.Builder<>();
|
||||
set.add(UUID.randomUUID());
|
||||
set.add(UUID.randomUUID());
|
||||
set.add(UUID.randomUUID());
|
||||
set.add(UUID.randomUUID());
|
||||
when(island.getMemberSet()).thenReturn(set.build());
|
||||
|
||||
|
||||
im = mock(IslandsManager.class);
|
||||
when(plugin.getIslands()).thenReturn(im);
|
||||
when(im.getIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(island);
|
||||
|
||||
inside = mock(Location.class);
|
||||
|
||||
Optional<Island> opIsland = Optional.ofNullable(island);
|
||||
when(im.getProtectedIslandAt(Mockito.eq(inside))).thenReturn(opIsland);
|
||||
|
||||
// Blocks
|
||||
block = mock(Block.class);
|
||||
when(block.getWorld()).thenReturn(world);
|
||||
when(block.getLocation()).thenReturn(inside);
|
||||
|
||||
PowerMockito.mockStatic(Util.class);
|
||||
when(Util.getWorld(Mockito.any())).thenReturn(world);
|
||||
|
||||
// World Settings
|
||||
IslandWorldManager iwm = mock(IslandWorldManager.class);
|
||||
when(plugin.getIWM()).thenReturn(iwm);
|
||||
WorldSettings ws = mock(WorldSettings.class);
|
||||
when(iwm.getWorldSettings(Mockito.any())).thenReturn(ws);
|
||||
Map<String, Boolean> worldFlags = new HashMap<>();
|
||||
when(ws.getWorldFlags()).thenReturn(worldFlags);
|
||||
|
||||
PowerMockito.mockStatic(Bukkit.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBlockRedstoneDoNothing() {
|
||||
// Make an event to give some current to block
|
||||
BlockRedstoneEvent e = new BlockRedstoneEvent(block, 0, 10);
|
||||
OfflineRedstoneListener orl = new OfflineRedstoneListener();
|
||||
Flags.OFFLINE_REDSTONE.setSetting(world, true);
|
||||
orl.onBlockRedstone(e);
|
||||
// Current remains 10
|
||||
assertEquals(10, e.getNewCurrent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBlockRedstoneMembersOnline() {
|
||||
// Make an event to give some current to block
|
||||
BlockRedstoneEvent e = new BlockRedstoneEvent(block, 0, 10);
|
||||
OfflineRedstoneListener orl = new OfflineRedstoneListener();
|
||||
// Offline redstone not allowed
|
||||
Flags.OFFLINE_REDSTONE.setSetting(world, false);
|
||||
// Members are online
|
||||
when(Bukkit.getPlayer(Mockito.any(UUID.class))).thenReturn(mock(Player.class));
|
||||
|
||||
orl.onBlockRedstone(e);
|
||||
// Current remains 10
|
||||
assertEquals(10, e.getNewCurrent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBlockRedstoneMembersOffline() {
|
||||
// Make an event to give some current to block
|
||||
BlockRedstoneEvent e = new BlockRedstoneEvent(block, 0, 10);
|
||||
OfflineRedstoneListener orl = new OfflineRedstoneListener();
|
||||
// Offline redstone not allowed
|
||||
Flags.OFFLINE_REDSTONE.setSetting(world, false);
|
||||
// Members are online
|
||||
when(Bukkit.getPlayer(Mockito.any(UUID.class))).thenReturn(null);
|
||||
|
||||
orl.onBlockRedstone(e);
|
||||
// Current will be 0
|
||||
assertEquals(0, e.getNewCurrent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnBlockRedstoneNonIsland() {
|
||||
// Make an event to give some current to block
|
||||
BlockRedstoneEvent e = new BlockRedstoneEvent(block, 0, 10);
|
||||
OfflineRedstoneListener orl = new OfflineRedstoneListener();
|
||||
Flags.OFFLINE_REDSTONE.setSetting(world, false);
|
||||
when(im.getProtectedIslandAt(Mockito.eq(inside))).thenReturn(Optional.empty());
|
||||
orl.onBlockRedstone(e);
|
||||
// Current remains 10
|
||||
assertEquals(10, e.getNewCurrent());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user