Tab panels (#857)

TabbedPanel extends Panel so that when an icon is
clicked, the context can be gathered by the click listener via the
getActiveTab method. In this case, the CycleClick and IslandToggleClick
classes cast the tab to the SettingsTab so they can retrieve the island
that the panel is referring too. This is required in the case where an
admin is setting a user's island settings. Previously the context of a
panel was only every about the user who opened the panel.

* Adds a tabbed panel API

* Added permission for tab

* Adds default world protection settings GUI

This switches the settings panel to use the new TabbedPanel API.

https://github.com/BentoBoxWorld/BentoBox/issues/384

* Adds admin command to change a player's settings.

Requires addon to add the admin settings command.

https://github.com/BentoBoxWorld/BentoBox/issues/59

* Locale for AdminSettingsCommand
This commit is contained in:
tastybento 2019-08-03 16:45:41 -07:00 committed by GitHub
parent d622c12425
commit 13ee55a173
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
37 changed files with 925 additions and 333 deletions

View File

@ -123,9 +123,9 @@ public abstract class DelayedTeleportCommand extends CompositeCommand implements
private final Location location;
/**
* @param label - command label
* @param runnable - runnable to run when confirmed
* @param task - task ID to cancel when confirmed
* @param location - location
*/
DelayedCommand(Runnable runnable, BukkitTask task, Location location) {
this.runnable = runnable;

View File

@ -0,0 +1,69 @@
package world.bentobox.bentobox.api.commands.admin;
import java.util.List;
import java.util.UUID;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.builders.TabbedPanelBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.panels.settings.SettingsTab;
/**
* @author tastybento
* @since 1.6.0
*/
public class AdminSettingsCommand extends CompositeCommand {
private @Nullable UUID targetUUID;
private Island island;
public AdminSettingsCommand(CompositeCommand islandCommand) {
super(islandCommand, "settings", "flags", "options");
}
@Override
public void setup() {
setPermission("admin.settings");
setOnlyPlayer(true);
setParametersHelp("commands.admin.settings.parameters");
setDescription("commands.admin.settings.description");
}
@Override
public boolean canExecute(User user, String label, List<String> args) {
if (args.size() != 1) {
// Show help
showHelp(this, user);
return false;
}
// Get target player
targetUUID = getPlayers().getUUID(args.get(0));
if (targetUUID == null) {
user.sendMessage("general.errors.unknown-player", TextVariables.NAME, args.get(0));
return false;
}
island = getIslands().getIsland(getWorld(), targetUUID);
if (island == null || !getPlugin().getIslands().hasIsland(getWorld(), targetUUID)) {
user.sendMessage("general.errors.player-has-no-island");
return false;
}
return true;
}
@Override
public boolean execute(User user, String label, List<String> args) {
new TabbedPanelBuilder()
.user(user)
.world(getWorld())
.tab(2, new SettingsTab(getWorld(), user, island, Flag.Type.PROTECTION))
.tab(6, new SettingsTab(getWorld(), user, island, Flag.Type.SETTING))
.startingSlot(1)
.build().openPanel();
return true;
}
}

View File

@ -4,12 +4,15 @@ import java.util.List;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.panels.builders.TabbedPanelBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.panels.SettingsPanel;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.panels.settings.SettingsTab;
import world.bentobox.bentobox.panels.settings.WorldDefaultSettingsTab;
import world.bentobox.bentobox.util.Util;
/**
* @author Poslovitch
* @author tastybento
*/
public class IslandSettingsCommand extends CompositeCommand {
@ -37,7 +40,16 @@ public class IslandSettingsCommand extends CompositeCommand {
@Override
public boolean execute(User user, String label, List<String> args) {
SettingsPanel.openPanel(getPlugin(), user, Flag.Type.PROTECTION, getWorld(), 0);
Island island = getIslands().getIslandAt(user.getLocation()).orElse(getIslands().getIsland(user.getWorld(), user.getUniqueId()));
new TabbedPanelBuilder()
.user(user)
.world(getWorld())
.tab(1, new SettingsTab(getWorld(), user, island, Flag.Type.PROTECTION))
.tab(3, new SettingsTab(getWorld(), user, island, Flag.Type.SETTING))
.tab(5, new SettingsTab(getWorld(), user, Flag.Type.WORLD_SETTING))
.tab(7, new WorldDefaultSettingsTab(getWorld(), user))
.startingSlot(1)
.build().openPanel();
return true;
}
}

View File

@ -9,6 +9,7 @@ import org.bukkit.World;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.addons.Addon;
@ -27,7 +28,7 @@ import world.bentobox.bentobox.managers.RanksManager;
public class Flag implements Comparable<Flag> {
/**
* Defines the behavior and operation of the flag, as well as its category in the {@link world.bentobox.bentobox.panels.SettingsPanel}.
* Defines the behavior and operation of the flag.
*/
public enum Type {
/**
@ -136,12 +137,14 @@ public class Flag implements Comparable<Flag> {
* @param setting - true or false
*/
public void setSetting(World world, boolean setting) {
if (getType().equals(Type.WORLD_SETTING)) {
if (getType().equals(Type.WORLD_SETTING) || type.equals(Type.PROTECTION)) {
BentoBox.getInstance()
.getIWM()
.getWorldSettings(world)
.getWorldFlags()
.put(getID(), setting);
// Save config file
BentoBox.getInstance().getIWM().getAddon(world).ifPresent(GameModeAddon::saveWorldSettings);
}
}
@ -295,10 +298,11 @@ public class Flag implements Comparable<Flag> {
* Converts a flag to a panel item. The content of the flag will change depending on who the user is and where they are.
* @param plugin - plugin
* @param user - user that will see this flag
* @param island - target island, if any
* @param invisible - true if this flag is not visible to players
* @return - PanelItem for this flag or null if item is inivisible to user
* @return - PanelItem for this flag or null if item is invisible to user
*/
public PanelItem toPanelItem(BentoBox plugin, User user, boolean invisible) {
public PanelItem toPanelItem(BentoBox plugin, User user, @Nullable Island island, boolean invisible) {
// Invisibility
if (!user.isOp() && invisible) {
return null;
@ -313,7 +317,6 @@ public class Flag implements Comparable<Flag> {
pib.description(user.getTranslation("protection.panel.flag-item.menu-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference())));
return pib.build();
}
Island island = plugin.getIslands().getIslandAt(user.getLocation()).orElse(plugin.getIslands().getIsland(user.getWorld(), user.getUniqueId()));
switch(getType()) {
case PROTECTION:
return createProtectionFlag(plugin, user, island, pib).build();

View File

@ -87,7 +87,7 @@ public abstract class FlagListener implements Listener {
* @param e - event
* @param flag - the flag that has been checked
* @param silent - if true, message is not sent
* @param string
* @param string - translation reference
*/
public void noGo(@NonNull Event e, @NonNull Flag flag, boolean silent, String string) {
if (e instanceof Cancellable) {

View File

@ -10,9 +10,11 @@ import world.bentobox.bentobox.api.events.island.FlagProtectionChangeEvent;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.TabbedPanel;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.panels.settings.SettingsTab;
import world.bentobox.bentobox.util.Util;
/**
@ -53,16 +55,19 @@ public class CycleClick implements PanelItem.ClickHandler {
@Override
public boolean onClick(Panel panel, User user, ClickType click, int slot) {
// This click listener is used with TabbedPanel and SettingsTabs only
TabbedPanel tp = (TabbedPanel)panel;
SettingsTab st = (SettingsTab)tp.getActiveTab();
// Get the island for this tab
island = st.getIsland();
this.user = user;
changeOccurred = false;
// Get the world
if (!plugin.getIWM().inWorld(user.getLocation())) {
user.sendMessage("general.errors.wrong-world");
return true;
}
String reqPerm = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + "settings." + id;
String allPerms = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + "settings.*";
if (!user.hasPermission(reqPerm) && !user.hasPermission(allPerms)) {
// Permission prefix
String prefix = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld()));
String reqPerm = prefix + "settings." + id;
String allPerms = prefix + "settings.*";
if (!user.hasPermission(reqPerm) && !user.hasPermission(allPerms)
&& !user.isOp() && !user.hasPermission(prefix + "admin.settings")) {
user.sendMessage("general.errors.no-permission", TextVariables.PERMISSION, reqPerm);
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F);
return true;
@ -70,15 +75,10 @@ public class CycleClick implements PanelItem.ClickHandler {
// Left clicking increases the rank required
// Right clicking decreases the rank required
// Shift Left Click toggles player visibility
// Get the user's island
island = plugin.getIslands().getIslandAt(user.getLocation()).orElse(plugin.getIslands().getIsland(user.getWorld(), user.getUniqueId()));
if (island != null && (user.isOp() || user.getUniqueId().equals(island.getOwner()))) {
if (island != null && (user.isOp() || user.getUniqueId().equals(island.getOwner()) || user.hasPermission(prefix + "admin.settings"))) {
changeOccurred = true;
RanksManager rm = plugin.getRanksManager();
plugin.getFlagsManager().getFlag(id).ifPresent(flag -> {
// Flag visibility
boolean invisible = false;
// Rank
int currentRank = island.getFlag(flag);
if (click.equals(ClickType.LEFT)) {
@ -101,7 +101,6 @@ public class CycleClick implements PanelItem.ClickHandler {
Bukkit.getPluginManager().callEvent(new FlagProtectionChangeEvent(island, user.getUniqueId(), flag, island.getFlag(flag)));
} else if (click.equals(ClickType.SHIFT_LEFT) && user.isOp()) {
if (!plugin.getIWM().getHiddenFlags(user.getWorld()).contains(flag.getID())) {
invisible = true;
plugin.getIWM().getHiddenFlags(user.getWorld()).add(flag.getID());
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_GLASS_BREAK, 1F, 1F);
} else {
@ -109,9 +108,8 @@ public class CycleClick implements PanelItem.ClickHandler {
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_NOTE_BLOCK_CHIME, 1F, 1F);
}
// Save changes
plugin.getIWM().getAddon(user.getWorld()).ifPresent(GameModeAddon::saveWorldSettings); }
// Apply change to panel
panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user, invisible).getItem());
plugin.getIWM().getAddon(user.getWorld()).ifPresent(GameModeAddon::saveWorldSettings);
}
});
} else {
// Player is not the owner of the island.

View File

@ -9,9 +9,11 @@ import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.events.island.FlagSettingChangeEvent;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.TabbedPanel;
import world.bentobox.bentobox.api.panels.PanelItem.ClickHandler;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.panels.settings.SettingsTab;
import world.bentobox.bentobox.util.Util;
/**
@ -33,27 +35,26 @@ public class IslandToggleClick implements ClickHandler {
@Override
public boolean onClick(Panel panel, User user, ClickType click, int slot) {
// Get the world
if (!plugin.getIWM().inWorld(user.getLocation())) {
user.sendMessage("general.errors.wrong-world");
return true;
}
String reqPerm = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld())) + "settings." + id;
if (!user.hasPermission(reqPerm)) {
// This click listener is used with TabbedPanel and SettingsTabs only
TabbedPanel tp = (TabbedPanel)panel;
SettingsTab st = (SettingsTab)tp.getActiveTab();
// Permission prefix
String prefix = plugin.getIWM().getPermissionPrefix(Util.getWorld(user.getWorld()));
String reqPerm = prefix + "settings." + id;
String allPerms = prefix + "settings.*";
if (!user.hasPermission(reqPerm) && !user.hasPermission(allPerms)
&& !user.isOp() && !user.hasPermission(prefix + "admin.settings")) {
user.sendMessage("general.errors.no-permission", TextVariables.PERMISSION, reqPerm);
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_METAL_HIT, 1F, 1F);
return true;
}
// Get the user's island or where they are standing
Island island = plugin.getIslands().getIslandAt(user.getLocation()).orElse(plugin.getIslands().getIsland(user.getWorld(), user.getUniqueId()));
if (island != null && (user.isOp() || user.getUniqueId().equals(island.getOwner()))) {
// Get the island for this tab
Island island = st.getIsland();
if (island != null && (user.isOp() || user.getUniqueId().equals(island.getOwner()) || user.hasPermission(prefix + "admin.settings"))) {
plugin.getFlagsManager().getFlag(id).ifPresent(flag -> {
// Visibility
boolean invisible = false;
if (click.equals(ClickType.SHIFT_LEFT) && user.isOp()) {
if (!plugin.getIWM().getHiddenFlags(user.getWorld()).contains(flag.getID())) {
invisible = true;
plugin.getIWM().getHiddenFlags(user.getWorld()).add(flag.getID());
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_GLASS_BREAK, 1F, 1F);
} else {
@ -77,8 +78,6 @@ public class IslandToggleClick implements ClickHandler {
// Fire event
Bukkit.getPluginManager().callEvent(new FlagSettingChangeEvent(island, user.getUniqueId(), flag, island.isAllowed(flag)));
}
// Apply change to panel
panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user, invisible).getItem());
});
} else {
// Player is not the owner of the island.

View File

@ -20,8 +20,8 @@ import world.bentobox.bentobox.util.Util;
*/
public class WorldToggleClick implements ClickHandler {
private BentoBox plugin = BentoBox.getInstance();
private String id;
private final BentoBox plugin = BentoBox.getInstance();
private final String id;
/**
* @param id - the flag ID that this click listener is associated with
@ -45,11 +45,8 @@ public class WorldToggleClick implements ClickHandler {
}
// Get flag
plugin.getFlagsManager().getFlag(id).ifPresent(flag -> {
// Visibility
boolean invisible = false;
if (click.equals(ClickType.SHIFT_LEFT) && user.isOp()) {
if (!plugin.getIWM().getHiddenFlags(user.getWorld()).contains(flag.getID())) {
invisible = true;
plugin.getIWM().getHiddenFlags(user.getWorld()).add(flag.getID());
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_GLASS_BREAK, 1F, 1F);
} else {
@ -65,8 +62,6 @@ public class WorldToggleClick implements ClickHandler {
// Fire event
Bukkit.getPluginManager().callEvent(new FlagWorldSettingChangeEvent(user.getWorld(), user.getUniqueId(), flag, flag.isSetForWorld(user.getWorld())));
}
// Apply change to panel
panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user, invisible).getItem());
// Save world settings
plugin.getIWM().getAddon(Util.getWorld(user.getWorld())).ifPresent(GameModeAddon::saveWorldSettings);

View File

@ -18,15 +18,27 @@ import world.bentobox.bentobox.listeners.PanelListenerManager;
import world.bentobox.bentobox.util.heads.HeadGetter;
import world.bentobox.bentobox.util.heads.HeadRequester;
/**
* A GUI panel that uses the Bukkit inventory API
* @author tastybento
*
*/
public class Panel implements HeadRequester, InventoryHolder {
private Inventory inventory;
private Map<Integer, PanelItem> items;
private PanelListener listener;
private User user;
private final String name;
private String name;
public Panel(String name, Map<Integer, PanelItem> items, int size, User user, PanelListener listener) {
makePanel(name, items, size, user, listener);
}
public Panel() {}
protected void makePanel(String name, Map<Integer, PanelItem> items, int size, User user,
PanelListener listener) {
this.name = name;
this.items = items;
// If size is undefined (0) then use the number of items
@ -43,7 +55,6 @@ public class Panel implements HeadRequester, InventoryHolder {
inventory = Bukkit.createInventory(null, size, name);
// Fill the inventory and return
for (Map.Entry<Integer, PanelItem> en: items.entrySet()) {
//TODO allow multi-paging
if (en.getKey() < 54) {
inventory.setItem(en.getKey(), en.getValue().getItem());
// Get player head async

View File

@ -12,6 +12,11 @@ import org.bukkit.inventory.meta.ItemMeta;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* Represents an item in a {@link Panel}
* @author tastybento
*
*/
public class PanelItem {
public static PanelItem empty() {
@ -24,7 +29,7 @@ public class PanelItem {
private String name;
private boolean glow;
private ItemMeta meta;
private boolean playerHead;
private final boolean playerHead;
private boolean invisible;
public PanelItem(PanelItemBuilder builtItem) {
@ -104,6 +109,14 @@ public class PanelItem {
return Optional.ofNullable(clickHandler);
}
/**
* @param clickHandler the clickHandler to set
* @since 1.6.0
*/
public void setClickHandler(ClickHandler clickHandler) {
this.clickHandler = clickHandler;
}
public boolean isGlow() {
return glow;
}

View File

@ -5,6 +5,11 @@ import org.bukkit.event.inventory.InventoryCloseEvent;
import world.bentobox.bentobox.api.user.User;
/**
* This will be called if registered and if a player clicks on a panel
* @author tastybento
*
*/
public interface PanelListener {
/**
@ -16,4 +21,10 @@ public interface PanelListener {
void onInventoryClick(User user, InventoryClickEvent event);
/**
* Called after a user has clicked on a panel item.
* Used to refresh the panel in its entirety
* @since 1.6.0
*/
default void refreshPanel() {}
}

View File

@ -0,0 +1,33 @@
package world.bentobox.bentobox.api.panels;
import java.util.List;
/**
* Represents a tab in a {@link TabbedPanel}. Contains {@link PanelItem}'s.
*
* @author tastybento
* @since 1.6.0
*
*/
public interface Tab {
// The icon that should be shown at the top of the tabbed panel
PanelItem getIcon();
/**
* @return the name of this tab
*/
String getName();
/**
* Return the panel items for this tab
* @return a list of items in slot order
*/
List<PanelItem> getPanelItems();
/**
* @return the permission required to view this tab or empty if no permission required
*/
String getPermission();
}

View File

@ -0,0 +1,166 @@
package world.bentobox.bentobox.api.panels;
import java.security.InvalidParameterException;
import java.util.List;
import java.util.Map.Entry;
import java.util.TreeMap;
import org.bukkit.Material;
import org.bukkit.Sound;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.event.inventory.InventoryCloseEvent;
import org.eclipse.jdt.annotation.NonNull;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.panels.builders.TabbedPanelBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* Represents a panel with tabs. The top row of the panel is made up of up to 9 icons that are made of {@link world.bentobox.bentobox.api.panels.Tab}s.
* Only the active tab is shown. The panel will auto-refresh when a panel item is clicked, so panel item
* click listeners do not have to actively update the panel. Viewers of the panel who do not have permission
* to see a {@link world.bentobox.bentobox.api.panels.Tab} will not be shown it.
*
* @author tastybento
* @since 1.6.0
*/
public class TabbedPanel extends Panel implements PanelListener {
private final TabbedPanelBuilder tpb;
private @NonNull BentoBox plugin = BentoBox.getInstance();
private int activeTab;
private int activePage;
private boolean closed;
/**
* Construct the tabbed panel
* @param tpb - tabbed panel builder
*/
public TabbedPanel(TabbedPanelBuilder tpb) {
this.tpb = tpb;
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.api.panels.PanelListener#refreshPanel()
*/
@Override
public void refreshPanel() {
if (closed) return;
// Called when a player clicks on the panel
openPanel(activeTab, activePage);
// Reset the closed flag
closed = false;
}
/**
* Open the tabbed panel at the starting slot
*/
public void openPanel() {
openPanel(tpb.getStartingSlot(), 0);
}
/**
* Open the tabbed panel
* @param activeTab - the tab to show referenced by the slot (0 through 8)
* @param page - the page of the tab to show (if multi paged)
*/
public void openPanel(int activeTab, int page) {
if (!tpb.getTabs().containsKey(activeTab)) {
// Request to open a non-existent tab
throw new InvalidParameterException("Attemot to open a non-existent tab in a tabbed panel. Missing tab #" + activeTab);
}
if (page < 0) {
// Request to open a non-existent tab
throw new InvalidParameterException("Attemot to open a tab in a tabbed panel to a negative page! " + page);
}
this.activeTab = activeTab;
this.activePage = page;
// The items in the panel
TreeMap<Integer, PanelItem> items = new TreeMap<>();
// Get the tab
Tab tab = tpb.getTabs().get(activeTab);
// Set up the tabbed header
setupHeader(items);
// Show the active tab
if (tpb.getTabs().containsKey(activeTab)) {
List<PanelItem> panelItems = tab.getPanelItems();
panelItems.stream().skip(page * 43L).limit(page * 43L + 43L).forEach(i -> items.put(items.lastKey() + 1, i));
// Add forward and backward icons
if (page > 0) {
// Previous page icon
items.put(items.lastKey() + 1, new PanelItemBuilder().icon(Material.ARROW).name(tpb.getUser().getTranslation("previous")).clickHandler((panel, user1, clickType, slot1) -> {
openPanel(activeTab, page - 1);
return true;
}).build());
}
if ((page + 1) * 44 < items.size()) {
// Next page icon
items.put(items.lastKey() + 1, new PanelItemBuilder().icon(Material.ARROW).name(tpb.getUser().getTranslation("next")).clickHandler((panel, user1, clickType, slot1) -> {
openPanel(activeTab, page + 1);
return true;
}).build());
}
} else {
throw new InvalidParameterException("Unknown tab slot number " + activeTab);
}
// Show it to the player
this.makePanel(tab.getName(), items, tpb.getSize(), tpb.getUser(), this);
}
/**
* Shows the top row of icons
* @param items - panel builder
*/
private void setupHeader(TreeMap<Integer, PanelItem> items) {
// Set up top
for (int i = 0; i < 9; i++) {
items.put(i, new PanelItemBuilder().icon(Material.BLACK_STAINED_GLASS_PANE).name("").build());
}
// Add icons
for (Entry<Integer, Tab> tabPanel : tpb.getTabs().entrySet()) {
// Set the glow of the active tab
tabPanel.getValue().getIcon().setGlow(tabPanel.getKey() == activeTab);
// Add the icon to the top row
if (tabPanel.getValue().getPermission().isEmpty() || tpb.getUser().hasPermission(tabPanel.getValue().getPermission()) || tpb.getUser().isOp()) {
items.put(tabPanel.getKey(), tabPanel.getValue().getIcon());
}
}
}
@Override
public void setup() {
// Not used
}
@Override
public void onInventoryClose(InventoryCloseEvent event) {
// This flag is set every time the inventory is closed or refreshed (closed and opened)
closed = true;
}
@Override
public void onInventoryClick(User user, InventoryClickEvent event) {
// Trap top row tab clicks
if (event.isLeftClick() && tpb.getTabs().containsKey(event.getRawSlot())
&& (tpb.getTabs().get(event.getRawSlot()).getPermission().isEmpty()
|| tpb.getUser().hasPermission(tpb.getTabs().get(event.getRawSlot()).getPermission()) || tpb.getUser().isOp())) {
event.setCancelled(true);
this.openPanel(event.getRawSlot(), 0);
user.getPlayer().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_OFF, 1F, 1F);
// Reset the closed flag
closed = false;
}
}
/**
* @return the active tab being shown to the user
*/
public Tab getActiveTab() {
return tpb.getTabs().get(activeTab);
}
}

View File

@ -16,7 +16,7 @@ import world.bentobox.bentobox.api.user.User;
*/
public class PanelBuilder {
private String name;
private TreeMap<Integer, PanelItem> items = new TreeMap<>();
private final TreeMap<Integer, PanelItem> items = new TreeMap<>();
private int size;
private User user;
private PanelListener listener;
@ -109,4 +109,39 @@ public class PanelBuilder {
// items.lastKey() is a slot position, so the panel size is this value + 1
return new Panel(name, items, Math.max(size, items.isEmpty() ? size : items.lastKey() + 1), user, listener);
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @return the items
*/
public TreeMap<Integer, PanelItem> getItems() {
return items;
}
/**
* @return the size
*/
public int getSize() {
return size;
}
/**
* @return the user
*/
public User getUser() {
return user;
}
/**
* @return the listener
*/
public PanelListener getListener() {
return listener;
}
}

View File

@ -0,0 +1,131 @@
package world.bentobox.bentobox.api.panels.builders;
import java.security.InvalidParameterException;
import java.util.Map;
import java.util.TreeMap;
import org.bukkit.World;
import world.bentobox.bentobox.api.panels.Tab;
import world.bentobox.bentobox.api.panels.TabbedPanel;
import world.bentobox.bentobox.api.user.User;
/**
* Builds {@link TabbedPanel}'s
* @author tastybento
* @since 1.6.0
*/
public class TabbedPanelBuilder {
private int size;
private final Map<Integer, Tab> tabs = new TreeMap<>();
private int startingSlot;
private World world;
private User user;
/**
* Forces panel to be a specific number of slots.
* @param size - size to be
* @return PanelBuilder - PanelBuilder
*/
public TabbedPanelBuilder size(int size) {
this.size = size;
return this;
}
/**
* Sets the user who will get this panel. This will open it immediately when it is built
* @param user - the User
* @return PanelBuilder
*/
public TabbedPanelBuilder user(User user) {
this.user = user;
return this;
}
/**
* @param world - world that applies to this tab
* @return TabbedPanelBuilder
*/
public TabbedPanelBuilder world(World world) {
this.world = world;
return this;
}
/**
* Add a tab to the panel
* @param slot - slot of panel (0 to 9)
* @param tab - tab to show
* @return TabbedPanelBuilder
*/
public TabbedPanelBuilder tab(int slot, Tab tab) {
if (slot < 0 || slot > 9) {
throw new InvalidParameterException("Slot must be between 0 and 9");
}
tabs.put(slot, tab);
return this;
}
/**
* The default tab to show
* @param slot - slot value between 0 and 9
* @return TabbedPanelBuilder
*/
public TabbedPanelBuilder startingSlot(int slot) {
if (slot < 0 || slot > 9) {
throw new InvalidParameterException("Slot must be between 0 and 9");
}
startingSlot = slot;
return this;
}
/**
* Build the panel
* @return Panel
*/
public TabbedPanel build() {
// Set starting slot
if (!tabs.isEmpty() && !tabs.containsKey(startingSlot)) {
startingSlot = ((TreeMap<Integer, Tab>)tabs).firstKey();
}
return new TabbedPanel(this);
}
/**
* @return the tabs
*/
public Map<Integer, Tab> getTabs() {
return tabs;
}
/**
* @return the startingSlot
*/
public int getStartingSlot() {
return startingSlot;
}
/**
* @return the world
*/
public World getWorld() {
return world;
}
/**
* @return the size
*/
public int getSize() {
return size;
}
/**
* @return the user
*/
public User getUser() {
return user;
}
}

View File

@ -54,9 +54,12 @@ public class PanelListenerManager implements Listener {
// Execute the handler's onClick method and optionally cancel the event if the handler returns true
event.setCancelled(handler.onClick(panel, user, event.getClick(), event.getSlot())));
}
// If there is a listener, then run it.
panel.getListener().ifPresent(l -> l.onInventoryClick(user, event));
// If there is a listener, then run it and refresh the panel
panel.getListener().ifPresent(l -> {
l.onInventoryClick(user, event);
// Refresh
l.refreshPanel();
});
} else {
// Wrong name - delete this panel
openPanels.remove(user.getUniqueId());

View File

@ -106,7 +106,6 @@ public class CleanSuperFlatListener extends FlagListener {
/**
* Check if chunk should be cleaned or not
* @param world - world
* @param plugin - plugin
* @param e chunk load event
* @return true if the chunk should not be cleaned
*/
@ -114,17 +113,14 @@ public class CleanSuperFlatListener extends FlagListener {
if (!ready) {
return true;
}
if (!getIWM().inWorld(world) || !Flags.CLEAN_SUPER_FLAT.isSetForWorld(world) ||
return !getIWM().inWorld(world) || !Flags.CLEAN_SUPER_FLAT.isSetForWorld(world) ||
(!(e.getChunk().getBlock(0, 0, 0).getType().equals(Material.BEDROCK)
&& e.getChunk().getBlock(0, 1, 0).getType().equals(Material.DIRT)
&& e.getChunk().getBlock(0, 2, 0).getType().equals(Material.DIRT)
&& e.getChunk().getBlock(0, 3, 0).getType().equals(Material.GRASS_BLOCK))
|| (world.getEnvironment().equals(Environment.NETHER) && (!plugin.getIWM().isNetherGenerate(world)
|| !plugin.getIWM().isNetherIslands(world)))
|| !plugin.getIWM().isNetherIslands(world)))
|| (world.getEnvironment().equals(Environment.THE_END) && (!plugin.getIWM().isEndGenerate(world)
|| !plugin.getIWM().isEndIslands(world))))) {
return true;
}
return false;
|| !plugin.getIWM().isEndIslands(world))));
}
}

View File

@ -1,98 +0,0 @@
package world.bentobox.bentobox.panels;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.Material;
import org.bukkit.World;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* Creates settings panels
* @author Poslovitch, tastybento
*/
public class SettingsPanel {
private static final String PROTECTION_PANEL = "protection.panel.";
private SettingsPanel() {}
/**
* Dynamically creates the panel.
* @param plugin - plugin
* @param user - user to show panel to
* @param flagType - initial view
* @param world - world
*/
public static void openPanel(BentoBox plugin, User user, Flag.Type flagType, World world, int page) {
String friendlyWorldName = plugin.getIWM().getFriendlyName(world);
// Create the panel
PanelBuilder panelBuilder = new PanelBuilder()
.name(user.getTranslation(PROTECTION_PANEL + flagType.toString() + ".title", "[world_name]", friendlyWorldName))
.size(54);
setupHeader(user, panelBuilder, flagType, world, friendlyWorldName);
// Get a list of flags of the correct type and sort by the translated names
List<Flag> flags = plugin.getFlagsManager().getFlags().stream().filter(f -> f.getType().equals(flagType))
.sorted(Comparator.comparing(flag -> user.getTranslation(flag.getNameReference())))
.collect(Collectors.toList());
// Remove any that are not for this game mode
plugin.getIWM().getAddon(world).ifPresent(gm -> flags.removeIf(f -> !f.getGameModes().isEmpty() && !f.getGameModes().contains(gm)));
// Use paging
flags.stream().skip(page * 43L).limit(page * 43L + 43L)
.forEach((f -> panelBuilder.item(f.toPanelItem(plugin, user, plugin.getIWM().getHiddenFlags(world).contains(f.getID())))));
// Add forward and backward icons
if (page > 0) {
// Previous page icon
panelBuilder.item(new PanelItemBuilder().icon(Material.ARROW).name(user.getTranslation(PROTECTION_PANEL + "previous")).clickHandler((panel, user1, clickType, slot1) -> {
openPanel(BentoBox.getInstance(), user, flagType, world, page - 1);
return true;
}).build());
}
if ((page + 1) * 44 < flags.size()) {
// Next page icon
panelBuilder.item(new PanelItemBuilder().icon(Material.ARROW).name(user.getTranslation(PROTECTION_PANEL + "next")).clickHandler((panel, user1, clickType, slot1) -> {
openPanel(BentoBox.getInstance(), user, flagType, world, page + 1);
return true;
}).build());
}
// Show it to the player
panelBuilder.build().open(user);
}
private static void setupHeader(User user, PanelBuilder panelBuilder, Flag.Type currentFlagType, World world, String friendlyWorldName) {
int slot = 2;
for (Flag.Type flagType : Flag.Type.values()) {
PanelItem panelItem = new PanelItemBuilder()
.icon(flagType.getIcon())
.name(user.getTranslation(PROTECTION_PANEL + flagType.toString() + ".title", "[world_name]", friendlyWorldName))
.description(user.getTranslation(PROTECTION_PANEL + flagType.toString() + ".description"))
.glow(flagType.equals(currentFlagType))
.clickHandler((panel, user1, clickType, slot1) -> {
if (!flagType.equals(currentFlagType)) {
openPanel(BentoBox.getInstance(), user, flagType, world, 0);
}
return true;
})
.build();
panelBuilder.item(slot, panelItem);
slot += 2;
}
for (int i = 0; i < 9; i++) {
if (!panelBuilder.slotOccupied(i)) {
panelBuilder.item(i, new PanelItemBuilder().icon(Material.LIGHT_GRAY_STAINED_GLASS_PANE).name(" ").build());
}
}
}
}

View File

@ -0,0 +1,141 @@
package world.bentobox.bentobox.panels.settings;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.World;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.flags.Flag.Type;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.Tab;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
/**
* Implements a {@link Tab} that shows settings for
* {@link world.bentobox.bentobox.api.flags.Flag.Type#PROTECTION}, {@link world.bentobox.bentobox.api.flags.Flag.Type#SETTING}, {@link world.bentobox.bentobox.api.flags.Flag.Type#WORLD_SETTING}
* @author tastybento
* @since 1.6.0
*
*/
public class SettingsTab implements Tab {
protected static final String PROTECTION_PANEL = "protection.panel.";
protected BentoBox plugin = BentoBox.getInstance();
protected Flag.Type type;
protected User user;
protected World world;
protected Island island;
/**
* Show a tab of settings for the island owned by targetUUID to user
* @param world - world
* @param user - user who is viewing the tab
* @param island - the island
* @param type - flag type
*/
public SettingsTab(World world, User user, Island island, Type type) {
this.world = world;
this.user = user;
this.island = island;
this.type = type;
}
/**
* Show a tab of settings for the island owned by targetUUID to user
* @param world - world
* @param user - user who is viewing the tab
* @param type - flag type
*/
public SettingsTab(World world, User user, Type type) {
this.world = world;
this.user = user;
this.type = type;
}
/**
* @return list of flags that will be shown in this panel
*/
protected List<Flag> getFlags() {
// Get a list of flags of the correct type and sort by the translated names
List<Flag> flags = plugin.getFlagsManager().getFlags().stream().filter(f -> f.getType().equals(type))
.sorted(Comparator.comparing(flag -> user.getTranslation(flag.getNameReference())))
.collect(Collectors.toList());
// Remove any that are not for this game mode
plugin.getIWM().getAddon(world).ifPresent(gm -> flags.removeIf(f -> !f.getGameModes().isEmpty() && !f.getGameModes().contains(gm)));
return flags;
}
/**
* Get the icon for this tab
* @return panel item
*/
@Override
public PanelItem getIcon() {
PanelItemBuilder pib = new PanelItemBuilder();
// Set the icon
pib.icon(type.getIcon());
pib.name(getName());
pib.description(user.getTranslation(PROTECTION_PANEL + type.toString() + ".description"));
return pib.build();
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.api.panels.Tab#getName()
*/
@Override
public String getName() {
return user.getTranslation(PROTECTION_PANEL + type.toString() + ".title", "[world_name]", plugin.getIWM().getFriendlyName(world));
}
/**
* Get all the flags as panel items
* @return list of all the panel items for this flag type
*/
@Override
public List<PanelItem> getPanelItems() {
return getFlags().stream().map((f -> f.toPanelItem(plugin, user, island, plugin.getIWM().getHiddenFlags(world).contains(f.getID())))).collect(Collectors.toList());
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.api.panels.Tab#getPermission()
*/
@Override
public String getPermission() {
// All of these tabs can be seen by anyone
return "";
}
/**
* @return the type
*/
public Flag.Type getType() {
return type;
}
/**
* @return the user
*/
public User getUser() {
return user;
}
/**
* @return the world
*/
public World getWorld() {
return world;
}
/**
* @return the island
*/
public Island getIsland() {
return island;
}
}

View File

@ -0,0 +1,87 @@
package world.bentobox.bentobox.panels.settings;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import org.bukkit.Material;
import org.bukkit.World;
import world.bentobox.bentobox.api.flags.Flag.Type;
import world.bentobox.bentobox.api.flags.clicklisteners.WorldToggleClick;
import world.bentobox.bentobox.api.localization.TextVariables;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.Tab;
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
import world.bentobox.bentobox.api.user.User;
/**
* Implements a {@link Tab} that enables the default world protection settings to be set
* @author tastybento
* @since 1.6.0
*
*/
public class WorldDefaultSettingsTab extends SettingsTab implements Tab {
/**
* @param world - world
* @param user - user
*/
public WorldDefaultSettingsTab(World world, User user) {
super(world, user, Type.PROTECTION);
}
/**
* Get the icon for this tab
* @return panel item
*/
@Override
public PanelItem getIcon() {
PanelItemBuilder pib = new PanelItemBuilder();
pib.icon(Material.STONE_BRICKS);
pib.name(getName());
// Different description
pib.description(user.getTranslation(PROTECTION_PANEL + "WORLD_DEFAULTS.description"));
return pib.build();
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.panels.settings.SettingsTab#getName()
*/
@Override
public String getName() {
// Different name
return user.getTranslation(PROTECTION_PANEL + "WORLD_DEFAULTS.title", "[world_name]", plugin.getIWM().getFriendlyName(world));
}
/* (non-Javadoc)
* @see world.bentobox.bentobox.panels.settings.SettingsTab#getPermission()
*/
@Override
public String getPermission() {
// This permission should be in the Game Mode Addon's permissions list
return plugin.getIWM().getPermissionPrefix(world) + "admin.set-world-defaults";
}
/**
* Get all the flags as panel items
* @return list of all the panel items for this flag type
*/
@Override
public List<PanelItem> getPanelItems() {
// Different description and click handlers
return getFlags().stream().map(f -> {
PanelItem i = f.toPanelItem(plugin, user, null, false);
// Replace the click handler with WorldToggleClick
i.setClickHandler(new WorldToggleClick(f.getID()));
// Replace the description
String worldSetting = f.isSetForWorld(user.getWorld()) ? user.getTranslation("protection.panel.flag-item.setting-active")
: user.getTranslation("protection.panel.flag-item.setting-disabled");
i.setDescription(Arrays.asList(user.getTranslation("protection.panel.flag-item.setting-layout",
TextVariables.DESCRIPTION, user.getTranslation(f.getDescriptionReference()),
"[setting]", worldSetting).split("\n")));
return i;
}).collect(Collectors.toList());
}
}

View File

@ -219,6 +219,9 @@ commands:
no-island-here: "&cThere is no island here."
confirmation: "&cAre you sure you want to set this island as the spawn for this world?"
success: "&aSuccessfully set this island as the spawn for this world."
settings:
parameters: "<player>"
description: "open island settings for player"
blueprint:
parameters: "<load/copy/paste/pos1/pos2/save>"
description: "manipulate blueprints"
@ -1072,6 +1075,11 @@ protection:
WORLD_SETTING:
title: "&b[world_name] &6Settings"
description: "&aSettings for this game world"
WORLD_DEFAULTS:
title: "&b[world_name] &6World Protections"
description: |
&aProtection settings when
&aplayer is outside their island
flag-item:
name-layout: "&a[name]"
description-layout: |

View File

@ -363,7 +363,7 @@ public class FlagTest {
when(rm.getRank(Mockito.eq(RanksManager.OWNER_RANK))).thenReturn("Owner");
PanelItem pi = f.toPanelItem(plugin, user, false);
PanelItem pi = f.toPanelItem(plugin, user, island, false);
verify(user).getTranslation(Mockito.eq("protection.flags.flagID.name"));
verify(user).getTranslation(Mockito.eq("protection.panel.flag-item.name-layout"), Mockito.anyVararg());

View File

@ -2,13 +2,13 @@ package world.bentobox.bentobox.api.flags.clicklisteners;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.HashSet;
@ -21,7 +21,6 @@ import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
import org.bukkit.scheduler.BukkitScheduler;
import org.junit.Before;
@ -38,8 +37,7 @@ import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.Settings;
import world.bentobox.bentobox.api.events.island.FlagProtectionChangeEvent;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.TabbedPanel;
import world.bentobox.bentobox.api.user.Notifier;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
@ -49,6 +47,7 @@ import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.managers.LocalesManager;
import world.bentobox.bentobox.managers.PlayersManager;
import world.bentobox.bentobox.managers.RanksManager;
import world.bentobox.bentobox.panels.settings.SettingsTab;
import world.bentobox.bentobox.util.Util;
@RunWith(PowerMockRunner.class)
@ -71,7 +70,7 @@ public class CycleClickTest {
@Mock
private Flag flag;
@Mock
private Panel panel;
private TabbedPanel panel;
@Mock
private Inventory inv;
@Mock
@ -80,6 +79,8 @@ public class CycleClickTest {
private RanksManager rm;
@Mock
private PluginManager pim;
@Mock
private SettingsTab settingsTab;
/**
* @throws java.lang.Exception - exception
@ -175,9 +176,6 @@ public class CycleClickTest {
when(im.getProtectedIslandAt(eq(outside))).thenReturn(Optional.empty());
when(im.getIslandAt(any())).thenReturn(opIsland);
PanelItem panelItem = mock(PanelItem.class);
when(flag.toPanelItem(any(), any(), eq(false))).thenReturn(panelItem);
when(panelItem.getItem()).thenReturn(mock(ItemStack.class));
FlagsManager fm = mock(FlagsManager.class);
when(fm.getFlag(anyString())).thenReturn(Optional.of(flag));
when(plugin.getFlagsManager()).thenReturn(fm);
@ -197,9 +195,6 @@ public class CycleClickTest {
when(rm.getRankDownValue(eq(RanksManager.TRUSTED_RANK))).thenReturn(RanksManager.COOP_RANK);
when(rm.getRankDownValue(eq(RanksManager.COOP_RANK))).thenReturn(RanksManager.VISITOR_RANK);
// Panel
when(panel.getInventory()).thenReturn(inv);
// IslandWorldManager
when(plugin.getIWM()).thenReturn(iwm);
when(iwm.inWorld(any(World.class))).thenReturn(true);
@ -213,15 +208,11 @@ public class CycleClickTest {
// Event
when(Bukkit.getPluginManager()).thenReturn(pim);
}
// Active tab
when(panel.getActiveTab()).thenReturn(settingsTab);
when(settingsTab.getIsland()).thenReturn(island);
@Test
public void testNotInWorld() {
when(iwm.inWorld(any(World.class))).thenReturn(false);
when(iwm.inWorld(any(Location.class))).thenReturn(false);
CycleClick udc = new CycleClick("LOCK");
assertTrue(udc.onClick(panel, user, ClickType.LEFT, 5));
verify(user).sendMessage(eq("general.errors.wrong-world"));
}
@Test
@ -246,15 +237,11 @@ public class CycleClickTest {
// Click left
assertTrue(udc.onClick(panel, user, ClickType.LEFT, SLOT));
verify(island).setFlag(eq(flag), eq(RanksManager.OWNER_RANK));
verify(flag).toPanelItem(any(), any(), eq(false));
verify(inv).setItem(eq(SLOT), any());
// Check rollover
// Clicking when Owner should go to Visitor
when(island.getFlag(any())).thenReturn(RanksManager.OWNER_RANK);
assertTrue(udc.onClick(panel, user, ClickType.LEFT, SLOT));
verify(island).setFlag(eq(flag), eq(RanksManager.VISITOR_RANK));
verify(flag, times(2)).toPanelItem(any(), any(), eq(false));
verify(inv, times(2)).setItem(eq(SLOT), any());
verify(pim, times(2)).callEvent(any(FlagProtectionChangeEvent.class));
}
@ -268,15 +255,11 @@ public class CycleClickTest {
// Click left
assertTrue(udc.onClick(panel, user, ClickType.LEFT, SLOT));
verify(island).setFlag(eq(flag), eq(RanksManager.TRUSTED_RANK));
verify(flag).toPanelItem(any(), any(), eq(false));
verify(inv).setItem(eq(SLOT), any());
// Check rollover
// Clicking when Member should go to Coop
when(island.getFlag(any())).thenReturn(RanksManager.MEMBER_RANK);
assertTrue(udc.onClick(panel, user, ClickType.LEFT, SLOT));
verify(island).setFlag(eq(flag), eq(RanksManager.COOP_RANK));
verify(flag, times(2)).toPanelItem(any(), any(), eq(false));
verify(inv, times(2)).setItem(eq(SLOT), any());
verify(pim, times(2)).callEvent(any(FlagProtectionChangeEvent.class));
}
@ -288,15 +271,11 @@ public class CycleClickTest {
// Right click - down rank to Trusted
assertTrue(udc.onClick(panel, user, ClickType.RIGHT, SLOT));
verify(island).setFlag(eq(flag), eq(RanksManager.TRUSTED_RANK));
verify(flag).toPanelItem(any(), any(), eq(false));
verify(inv).setItem(eq(SLOT), any());
// Check rollover
// Clicking when Visitor should go to Owner
when(island.getFlag(any())).thenReturn(RanksManager.VISITOR_RANK);
assertTrue(udc.onClick(panel, user, ClickType.RIGHT, SLOT));
verify(island).setFlag(eq(flag), eq(RanksManager.OWNER_RANK));
verify(flag, times(2)).toPanelItem(any(), any(), eq(false));
verify(inv, times(2)).setItem(eq(SLOT), any());
verify(pim, times(2)).callEvent(any(FlagProtectionChangeEvent.class));
}
@ -310,15 +289,11 @@ public class CycleClickTest {
// Right click
assertTrue(udc.onClick(panel, user, ClickType.RIGHT, SLOT));
verify(island).setFlag(eq(flag), eq(RanksManager.COOP_RANK));
verify(flag).toPanelItem(any(), any(), eq(false));
verify(inv).setItem(eq(SLOT), any());
// Check rollover
// Clicking when Coop should go to Member
when(island.getFlag(any())).thenReturn(RanksManager.COOP_RANK);
assertTrue(udc.onClick(panel, user, ClickType.RIGHT, SLOT));
verify(island).setFlag(eq(flag), eq(RanksManager.MEMBER_RANK));
verify(flag, times(2)).toPanelItem(any(), any(), eq(false));
verify(inv, times(2)).setItem(eq(SLOT), any());
verify(pim, times(2)).callEvent(any(FlagProtectionChangeEvent.class));
}
@ -333,7 +308,6 @@ public class CycleClickTest {
@Test
public void testNotOwner() {
UUID u = UUID.randomUUID();
when(island.getOwner()).thenReturn(u);
verify(plugin, Mockito.never()).getRanksManager();

View File

@ -1,6 +1,7 @@
package world.bentobox.bentobox.api.flags.clicklisteners;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@ -15,7 +16,6 @@ import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
import org.junit.Before;
import org.junit.Test;
@ -30,13 +30,13 @@ import org.powermock.reflect.Whitebox;
import world.bentobox.bentobox.BentoBox;
import world.bentobox.bentobox.api.events.island.FlagSettingChangeEvent;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.panels.TabbedPanel;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
import world.bentobox.bentobox.managers.IslandsManager;
import world.bentobox.bentobox.panels.settings.SettingsTab;
import world.bentobox.bentobox.util.Util;
@RunWith(PowerMockRunner.class)
@ -47,7 +47,7 @@ public class IslandToggleClickTest {
private IslandWorldManager iwm;
private IslandToggleClick listener;
@Mock
private Panel panel;
private TabbedPanel panel;
@Mock
private User user;
@Mock
@ -59,6 +59,8 @@ public class IslandToggleClickTest {
private UUID uuid;
@Mock
private PluginManager pim;
@Mock
private SettingsTab settingsTab;
/**
* @throws java.lang.Exception
@ -93,9 +95,6 @@ public class IslandToggleClickTest {
FlagsManager fm = mock(FlagsManager.class);
when(flag.isSetForWorld(any())).thenReturn(false);
PanelItem item = mock(PanelItem.class);
when(item.getItem()).thenReturn(mock(ItemStack.class));
when(flag.toPanelItem(any(), Mockito.eq(user), Mockito.eq(false))).thenReturn(item);
when(fm.getFlag(Mockito.anyString())).thenReturn(Optional.of(flag));
when(plugin.getFlagsManager()).thenReturn(fm);
@ -111,14 +110,10 @@ public class IslandToggleClickTest {
// Event
PowerMockito.mockStatic(Bukkit.class);
when(Bukkit.getPluginManager()).thenReturn(pim);
}
@Test
public void testOnClickWrongWorld() {
when(iwm.inWorld(any(World.class))).thenReturn(false);
when(iwm.inWorld(any(Location.class))).thenReturn(false);
listener.onClick(panel, user, ClickType.LEFT, 0);
verify(user).sendMessage("general.errors.wrong-world");
// Active tab
when(panel.getActiveTab()).thenReturn(settingsTab);
when(settingsTab.getIsland()).thenReturn(island);
}
@Test
@ -137,14 +132,15 @@ public class IslandToggleClickTest {
@Test
public void testOnClickNoIsland() {
when(im.getIslandAt(any())).thenReturn(Optional.empty());
when(im.getIsland(any(), any(User.class))).thenReturn(null);
when(settingsTab.getIsland()).thenReturn(null);
listener.onClick(panel, user, ClickType.LEFT, 0);
verify(island, never()).toggleFlag(flag);
}
@Test
public void testOnClickNotOwner() {
// No permission
when(user.hasPermission(anyString())).thenReturn(false);
// Pick a different UUID from owner
UUID u = UUID.randomUUID();
while(u.equals(uuid)) {

View File

@ -2,8 +2,8 @@ package world.bentobox.bentobox.api.flags.clicklisteners;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Optional;
@ -13,7 +13,6 @@ import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.PluginManager;
import org.junit.Before;
import org.junit.Test;
@ -30,7 +29,6 @@ import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.events.island.FlagWorldSettingChangeEvent;
import world.bentobox.bentobox.api.flags.Flag;
import world.bentobox.bentobox.api.panels.Panel;
import world.bentobox.bentobox.api.panels.PanelItem;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.managers.FlagsManager;
import world.bentobox.bentobox.managers.IslandWorldManager;
@ -90,9 +88,6 @@ public class WorldToggleClickTest {
flag = mock(Flag.class);
when(flag.isSetForWorld(Mockito.any())).thenReturn(false);
PanelItem item = mock(PanelItem.class);
when(item.getItem()).thenReturn(mock(ItemStack.class));
when(flag.toPanelItem(Mockito.any(), Mockito.eq(user), Mockito.eq(false))).thenReturn(item);
when(fm.getFlag(Mockito.anyString())).thenReturn(Optional.of(flag));
when(plugin.getFlagsManager()).thenReturn(fm);
@ -123,7 +118,6 @@ public class WorldToggleClickTest {
when(user.hasPermission(Mockito.anyString())).thenReturn(true);
listener.onClick(panel, user, ClickType.LEFT, 0);
verify(flag).setSetting(Mockito.any(), Mockito.eq(true));
verify(panel).getInventory();
verify(addon).saveWorldSettings();
verify(pim).callEvent(any(FlagWorldSettingChangeEvent.class));
}

View File

@ -1,13 +1,13 @@
/**
*
*/
package world.bentobox.bentobox.listeners.flags.settings;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
@ -112,7 +112,7 @@ public class PVPListenerTest {
when(iwm.inWorld(any(Location.class))).thenReturn(true);
when(iwm.getPermissionPrefix(Mockito.any())).thenReturn("bskyblock.");
// No visitor protection right now
when(iwm.getIvSettings(Mockito.any())).thenReturn(new ArrayList<>());
when(iwm.getIvSettings(any())).thenReturn(new ArrayList<>());
when(plugin.getIWM()).thenReturn(iwm);
Panel panel = mock(Panel.class);
@ -143,25 +143,25 @@ public class PVPListenerTest {
User.getInstance(player2);
PowerMockito.mockStatic(Util.class);
when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class));
when(Util.getWorld(any())).thenReturn(mock(World.class));
FlagsManager fm = mock(FlagsManager.class);
Flag flag = mock(Flag.class);
when(flag.isSetForWorld(Mockito.any())).thenReturn(false);
when(flag.isSetForWorld(any())).thenReturn(false);
PanelItem item = mock(PanelItem.class);
when(item.getItem()).thenReturn(mock(ItemStack.class));
when(flag.toPanelItem(Mockito.any(), Mockito.any(), Mockito.eq(false))).thenReturn(item);
when(flag.toPanelItem(any(), any(), any(), eq(false))).thenReturn(item);
when(fm.getFlag(Mockito.anyString())).thenReturn(Optional.of(flag));
when(plugin.getFlagsManager()).thenReturn(fm);
im = mock(IslandsManager.class);
// Default is that player in on their island
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(true);
when(im.userIsOnIsland(any(), any())).thenReturn(true);
island = mock(Island.class);
when(im.getIslandAt(Mockito.any())).thenReturn(Optional.of(island));
when(im.getProtectedIslandAt(Mockito.any())).thenReturn(Optional.of(island));
when(im.getIslandAt(any())).thenReturn(Optional.of(island));
when(im.getProtectedIslandAt(any())).thenReturn(Optional.of(island));
// All flags are disallowed by default.
when(island.isAllowed(Mockito.any())).thenReturn(false);
when(island.isAllowed(any())).thenReturn(false);
when(plugin.getIslands()).thenReturn(im);
// Settings
@ -194,7 +194,7 @@ public class PVPListenerTest {
// World Settings
WorldSettings ws = mock(WorldSettings.class);
when(iwm.getWorldSettings(Mockito.any())).thenReturn(ws);
when(iwm.getWorldSettings(any())).thenReturn(ws);
Map<String, Boolean> worldFlags = new HashMap<>();
when(ws.getWorldFlags()).thenReturn(worldFlags);
GameModeAddon gma = mock(GameModeAddon.class);
@ -206,7 +206,7 @@ public class PVPListenerTest {
when(plugin.getNotifier()).thenReturn(notifier);
// Addon
when(iwm.getAddon(Mockito.any())).thenReturn(Optional.empty());
when(iwm.getAddon(any())).thenReturn(Optional.empty());
}
@ -326,7 +326,7 @@ public class PVPListenerTest {
visitorProtectionList.add("ENTITY_ATTACK");
when(iwm.getIvSettings(world)).thenReturn(visitorProtectionList);
// This player is a visitor
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(im.userIsOnIsland(any(), any())).thenReturn(false);
EntityDamageByEntityEvent e = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK,
new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, 0D)),
@ -360,7 +360,7 @@ public class PVPListenerTest {
visitorProtectionList.add("ENTITY_ATTACK");
when(iwm.getIvSettings(world)).thenReturn(visitorProtectionList);
// This player is a visitor
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(im.userIsOnIsland(any(), any())).thenReturn(false);
// Damage is not entity attack
EntityDamageByEntityEvent e = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.THORNS,
new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, 0D)),
@ -386,7 +386,7 @@ public class PVPListenerTest {
when(damagee.getWorld()).thenReturn(world);
// This player is a visitor
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(im.userIsOnIsland(any(), any())).thenReturn(false);
EntityDamageByEntityEvent e = new EntityDamageByEntityEvent(damager, damagee, EntityDamageEvent.DamageCause.ENTITY_ATTACK,
new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, 0D)),
@ -425,7 +425,7 @@ public class PVPListenerTest {
new PVPListener().onEntityDamage(e);
// PVP should be banned
assertTrue(e.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.PVP_OVERWORLD.getHintReference()));
verify(notifier).notify(any(), eq(Flags.PVP_OVERWORLD.getHintReference()));
}
@ -440,12 +440,12 @@ public class PVPListenerTest {
// Enable visitor protection
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
new PVPListener().onEntityDamage(e);
// visitor should be protected
assertTrue(e.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
}
/**
@ -454,23 +454,23 @@ public class PVPListenerTest {
@Test
public void testOnEntityDamageOnPVPAllowed() {
// PVP is allowed
when(island.isAllowed(Mockito.any())).thenReturn(true);
when(island.isAllowed(any())).thenReturn(true);
EntityDamageByEntityEvent e = new EntityDamageByEntityEvent(player, player2, EntityDamageEvent.DamageCause.ENTITY_ATTACK,
new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, 0D)),
new EnumMap<DamageModifier, Function<? super Double, Double>>(ImmutableMap.of(DamageModifier.BASE, Functions.constant(-0.0))));
new PVPListener().onEntityDamage(e);
// PVP should be allowed
assertFalse(e.isCancelled());
Mockito.verify(player, Mockito.never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
verify(player, never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
// Enable visitor protection
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
new PVPListener().onEntityDamage(e);
// visitor should be protected
assertTrue(e.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
}
@ -488,17 +488,17 @@ public class PVPListenerTest {
new PVPListener().onEntityDamage(e);
// PVP should be banned
assertTrue(e.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.PVP_OVERWORLD.getHintReference()));
verify(notifier).notify(any(), eq(Flags.PVP_OVERWORLD.getHintReference()));
// Visitor protection
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
new PVPListener().onEntityDamage(e);
// visitor should be protected
assertTrue(e.isCancelled());
// PVP trumps visitor protection
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.PVP_OVERWORLD.getHintReference()));
verify(notifier).notify(any(), eq(Flags.PVP_OVERWORLD.getHintReference()));
}
@ -527,23 +527,23 @@ public class PVPListenerTest {
when(p.getShooter()).thenReturn(player);
when(p.getLocation()).thenReturn(loc);
// PVP is allowed
when(island.isAllowed(Mockito.any())).thenReturn(true);
when(island.isAllowed(any())).thenReturn(true);
EntityDamageByEntityEvent e = new EntityDamageByEntityEvent(p, player2, EntityDamageEvent.DamageCause.ENTITY_ATTACK,
new EnumMap<>(ImmutableMap.of(DamageModifier.BASE, 0D)),
new EnumMap<DamageModifier, Function<? super Double, Double>>(ImmutableMap.of(DamageModifier.BASE, Functions.constant(-0.0))));
new PVPListener().onEntityDamage(e);
// PVP should be allowed
assertFalse(e.isCancelled());
Mockito.verify(player, Mockito.never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
verify(player, never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
// Enable visitor protection
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
new PVPListener().onEntityDamage(e);
// visitor should be protected
assertTrue(e.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
}
@ -566,9 +566,9 @@ public class PVPListenerTest {
// PVP should be banned
assertTrue(pfe.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.PVP_OVERWORLD.getHintReference()));
verify(notifier).notify(any(), eq(Flags.PVP_OVERWORLD.getHintReference()));
// Hook should be removed
Mockito.verify(hook).remove();
verify(hook).remove();
// Wrong world
wrongWorld();
@ -581,7 +581,7 @@ public class PVPListenerTest {
when(iwm.inWorld(any(Location.class))).thenReturn(true);
// Allow PVP
when(island.isAllowed(Mockito.any())).thenReturn(true);
when(island.isAllowed(any())).thenReturn(true);
pfe = new PlayerFishEvent(player, player2, hook, null);
new PVPListener().onFishing(pfe);
assertFalse(pfe.isCancelled());
@ -604,16 +604,16 @@ public class PVPListenerTest {
PlayerFishEvent pfe = new PlayerFishEvent(player, player2, hook, null);
// Allow PVP
when(island.isAllowed(Mockito.any())).thenReturn(true);
when(island.isAllowed(any())).thenReturn(true);
// Protect visitors
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
new PVPListener().onFishing(pfe);
// visitor should be protected
assertTrue(pfe.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
}
/**
@ -626,7 +626,7 @@ public class PVPListenerTest {
// Catch a player
PlayerFishEvent pfe = new PlayerFishEvent(player, player, hook, null);
assertFalse(pfe.isCancelled());
Mockito.verify(player, Mockito.never()).sendMessage(Mockito.anyString());
verify(player, never()).sendMessage(Mockito.anyString());
}
/**
@ -640,16 +640,16 @@ public class PVPListenerTest {
PlayerFishEvent pfe = new PlayerFishEvent(player, player2, hook, null);
// Disallow PVP
when(island.isAllowed(Mockito.any())).thenReturn(false);
when(island.isAllowed(any())).thenReturn(false);
// Protect visitors
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
new PVPListener().onFishing(pfe);
// visitor should be protected
assertTrue(pfe.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
}
/**
@ -688,7 +688,7 @@ public class PVPListenerTest {
@Test
public void testOnSplashPotionSplash() {
// Disallow PVP
when(island.isAllowed(Mockito.any())).thenReturn(false);
when(island.isAllowed(any())).thenReturn(false);
ThrownPotion tp = mock(ThrownPotion.class);
when(tp.getShooter()).thenReturn(player);
@ -701,7 +701,7 @@ public class PVPListenerTest {
PotionSplashEvent e = new PotionSplashEvent(tp, map);
new PVPListener().onSplashPotionSplash(e);
assertTrue(e.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.PVP_OVERWORLD.getHintReference()));
verify(notifier).notify(any(), eq(Flags.PVP_OVERWORLD.getHintReference()));
// Wrong world
wrongWorld();
@ -716,7 +716,7 @@ public class PVPListenerTest {
@Test
public void testOnSplashPotionSplashSelfInflicted() {
// Disallow PVP
when(island.isAllowed(Mockito.any())).thenReturn(false);
when(island.isAllowed(any())).thenReturn(false);
ThrownPotion tp = mock(ThrownPotion.class);
when(tp.getShooter()).thenReturn(player);
@ -743,7 +743,7 @@ public class PVPListenerTest {
@Test
public void testOnSplashPotionSplashAllowPVP() {
// Disallow PVP
when(island.isAllowed(Mockito.any())).thenReturn(true);
when(island.isAllowed(any())).thenReturn(true);
ThrownPotion tp = mock(ThrownPotion.class);
when(tp.getShooter()).thenReturn(player);
@ -756,7 +756,7 @@ public class PVPListenerTest {
PotionSplashEvent e = new PotionSplashEvent(tp, map);
new PVPListener().onSplashPotionSplash(e);
assertFalse(e.isCancelled());
Mockito.verify(player, Mockito.never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
verify(player, never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
}
@ -766,7 +766,7 @@ public class PVPListenerTest {
@Test
public void testOnSplashPotionSplashAllowPVPProtectVisitors() {
// Allow PVP
when(island.isAllowed(Mockito.any())).thenReturn(true);
when(island.isAllowed(any())).thenReturn(true);
ThrownPotion tp = mock(ThrownPotion.class);
when(tp.getShooter()).thenReturn(player);
@ -779,12 +779,12 @@ public class PVPListenerTest {
PotionSplashEvent e = new PotionSplashEvent(tp, map);
// Protect visitors
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
new PVPListener().onSplashPotionSplash(e);
// visitor should be protected
assertTrue(e.isCancelled());
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
// Wrong world
wrongWorld();
@ -805,9 +805,9 @@ public class PVPListenerTest {
LingeringPotionSplashEvent e = new LingeringPotionSplashEvent(tp, cloud);
new PVPListener().onLingeringPotionSplash(e);
// Verify
Mockito.verify(player, Mockito.times(3)).getUniqueId();
Mockito.verify(cloud).getEntityId();
Mockito.verify(tp, Mockito.times(2)).getShooter();
verify(player, Mockito.times(3)).getUniqueId();
verify(cloud).getEntityId();
verify(tp, Mockito.times(2)).getShooter();
PowerMockito.verifyStatic(Bukkit.class);
}
@ -823,9 +823,9 @@ public class PVPListenerTest {
LingeringPotionSplashEvent e = new LingeringPotionSplashEvent(tp, cloud);
new PVPListener().onLingeringPotionSplash(e);
// Verify
Mockito.verify(cloud, Mockito.never()).getEntityId();
Mockito.verify(tp).getShooter();
PowerMockito.verifyStatic(Bukkit.class, Mockito.never());
verify(cloud, never()).getEntityId();
verify(tp).getShooter();
PowerMockito.verifyStatic(Bukkit.class, never());
}
/**
@ -834,7 +834,7 @@ public class PVPListenerTest {
@Test
public void testOnLingeringPotionDamageNoPVP() {
// Disallow PVP
when(island.isAllowed(Mockito.any())).thenReturn(false);
when(island.isAllowed(any())).thenReturn(false);
// Throw a potion
LingeringPotion tp = mock(LingeringPotion.class);
when(tp.getShooter()).thenReturn(player);
@ -854,14 +854,14 @@ public class PVPListenerTest {
listener.onLingeringPotionDamage(ae);
assertEquals(3, ae.getAffectedEntities().size());
assertFalse(ae.getAffectedEntities().contains(player2));
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.PVP_OVERWORLD.getHintReference()));
verify(notifier).notify(any(), eq(Flags.PVP_OVERWORLD.getHintReference()));
// Wrong world
wrongWorld();
listener.onLingeringPotionSplash(e);
// No change to results
assertEquals(3, ae.getAffectedEntities().size());
assertFalse(ae.getAffectedEntities().contains(player2));
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.PVP_OVERWORLD.getHintReference()));
verify(notifier).notify(any(), eq(Flags.PVP_OVERWORLD.getHintReference()));
}
/**
@ -870,7 +870,7 @@ public class PVPListenerTest {
@Test
public void testOnLingeringPotionDamagePVP() {
// Allow PVP
when(island.isAllowed(Mockito.any())).thenReturn(true);
when(island.isAllowed(any())).thenReturn(true);
// Throw a potion
LingeringPotion tp = mock(LingeringPotion.class);
when(tp.getShooter()).thenReturn(player);
@ -889,12 +889,12 @@ public class PVPListenerTest {
AreaEffectCloudApplyEvent ae = new AreaEffectCloudApplyEvent(cloud, list);
listener.onLingeringPotionDamage(ae);
assertEquals(4, ae.getAffectedEntities().size());
Mockito.verify(player, Mockito.never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
verify(player, never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
// Wrong world
wrongWorld();
listener.onLingeringPotionSplash(e);
assertEquals(4, ae.getAffectedEntities().size());
Mockito.verify(player, Mockito.never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
verify(player, never()).sendMessage(Flags.PVP_OVERWORLD.getHintReference());
}
@ -904,7 +904,7 @@ public class PVPListenerTest {
@Test
public void testOnLingeringPotionDamageNoPVPVisitor() {
// Disallow PVP
when(island.isAllowed(Mockito.any())).thenReturn(false);
when(island.isAllowed(any())).thenReturn(false);
// Throw a potion
LingeringPotion tp = mock(LingeringPotion.class);
when(tp.getShooter()).thenReturn(player);
@ -921,21 +921,21 @@ public class PVPListenerTest {
list.add(zombie);
// Protect visitor
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
// See who it affects
AreaEffectCloudApplyEvent ae = new AreaEffectCloudApplyEvent(cloud, list);
listener.onLingeringPotionDamage(ae);
assertEquals(3, ae.getAffectedEntities().size());
assertFalse(ae.getAffectedEntities().contains(player2));
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
// Wrong world
wrongWorld();
listener.onLingeringPotionSplash(e);
assertEquals(3, ae.getAffectedEntities().size());
assertFalse(ae.getAffectedEntities().contains(player2));
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
}
/**
@ -944,7 +944,7 @@ public class PVPListenerTest {
@Test
public void testOnLingeringPotionDamagePVPVisitor() {
// Allow PVP
when(island.isAllowed(Mockito.any())).thenReturn(true);
when(island.isAllowed(any())).thenReturn(true);
// Throw a potion
LingeringPotion tp = mock(LingeringPotion.class);
when(tp.getShooter()).thenReturn(player);
@ -961,20 +961,20 @@ public class PVPListenerTest {
list.add(zombie);
// Protect visitor
// This player is a visitor and any damage is not allowed
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(iwm.getIvSettings(Mockito.any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(iwm.getIvSettings(any())).thenReturn(Collections.singletonList("ENTITY_ATTACK"));
// See who it affects
AreaEffectCloudApplyEvent ae = new AreaEffectCloudApplyEvent(cloud, list);
listener.onLingeringPotionDamage(ae);
assertEquals(3, ae.getAffectedEntities().size());
assertFalse(ae.getAffectedEntities().contains(player2));
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
// Wrong world
wrongWorld();
listener.onLingeringPotionSplash(e);
assertEquals(3, ae.getAffectedEntities().size());
assertFalse(ae.getAffectedEntities().contains(player2));
Mockito.verify(notifier).notify(Mockito.any(), Mockito.eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
verify(notifier).notify(any(), eq(Flags.INVINCIBLE_VISITORS.getHintReference()));
}
}

View File

@ -110,6 +110,7 @@ public class ChestDamageListenerTest {
IslandWorldManager iwm = mock(IslandWorldManager.class);
when(iwm.inWorld(any(World.class))).thenReturn(true);
when(iwm.inWorld(any(Location.class))).thenReturn(true);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
when(plugin.getIWM()).thenReturn(iwm);
// Monsters and animals

View File

@ -1,13 +1,14 @@
package world.bentobox.bentobox.listeners.flags.worldsettings;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.anyInt;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Random;
import org.bukkit.Bukkit;
@ -88,6 +89,7 @@ public class CleanSuperFlatListenerTest {
when(iwm.isNetherIslands(Mockito.any())).thenReturn(true);
when(iwm.isEndIslands(Mockito.any())).thenReturn(true);
when(iwm.isUseOwnGenerator(any())).thenReturn(false);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
PowerMockito.mockStatic(Bukkit.class);

View File

@ -105,6 +105,7 @@ public class EnderChestListenerTest {
// By default everything is in world
when(iwm.inWorld(any(World.class))).thenReturn(true);
when(iwm.inWorld(any(Location.class))).thenReturn(true);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
// Ender chest use is not allowed by default
Flags.ENDER_CHEST.setSetting(world, false);

View File

@ -102,6 +102,7 @@ public class EndermanListenerTest {
iwm = mock(IslandWorldManager.class);
when(iwm.inWorld(any(World.class))).thenReturn(true);
when(iwm.inWorld(any(Location.class))).thenReturn(true);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
when(plugin.getIWM()).thenReturn(iwm);
// Monsters and animals

View File

@ -2,9 +2,13 @@ package world.bentobox.bentobox.listeners.flags.worldsettings;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import java.util.ArrayList;
import java.util.Arrays;
@ -85,7 +89,7 @@ public class InvincibleVisitorsListenerTest {
when(iwm.inWorld(any(Location.class))).thenReturn(true);
when(iwm.getPermissionPrefix(Mockito.any())).thenReturn("bskyblock.");
Optional<GameModeAddon> optionalAddon = Optional.of(addon);
when(iwm.getAddon(Mockito.any())).thenReturn(optionalAddon);
when(iwm.getAddon(any())).thenReturn(optionalAddon);
when(plugin.getIWM()).thenReturn(iwm);
listener = new InvincibleVisitorsListener();
@ -102,14 +106,14 @@ public class InvincibleVisitorsListenerTest {
UUID uuid = UUID.randomUUID();
when(user.getUniqueId()).thenReturn(uuid);
PowerMockito.mockStatic(Util.class);
when(Util.getWorld(Mockito.any())).thenReturn(mock(World.class));
when(Util.getWorld(any())).thenReturn(mock(World.class));
FlagsManager fm = mock(FlagsManager.class);
Flag flag = mock(Flag.class);
when(flag.isSetForWorld(Mockito.any())).thenReturn(false);
when(flag.isSetForWorld(any())).thenReturn(false);
PanelItem item = mock(PanelItem.class);
when(item.getItem()).thenReturn(mock(ItemStack.class));
when(flag.toPanelItem(Mockito.any(), Mockito.eq(user), Mockito.eq(false))).thenReturn(item);
when(flag.toPanelItem(any(), eq(user), any(), eq(false))).thenReturn(item);
when(fm.getFlag(Mockito.anyString())).thenReturn(Optional.of(flag));
when(plugin.getFlagsManager()).thenReturn(fm);
@ -121,43 +125,43 @@ public class InvincibleVisitorsListenerTest {
Vector vector = mock(Vector.class);
when(location.toVector()).thenReturn(vector);
when(island.getCenter()).thenReturn(location);
when(im.getIsland(Mockito.any(World.class), Mockito.any(User.class))).thenReturn(island);
when(im.getIsland(any(World.class), any(User.class))).thenReturn(island);
optionalIsland = Optional.of(island);
// Visitor
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(false);
when(im.userIsOnIsland(any(), any())).thenReturn(false);
when(plugin.getIslands()).thenReturn(im);
// IV Settings
ivSettings = new ArrayList<>();
ivSettings.add(EntityDamageEvent.DamageCause.CRAMMING.name());
ivSettings.add(EntityDamageEvent.DamageCause.VOID.name());
when(iwm.getIvSettings(Mockito.any())).thenReturn(ivSettings);
when(iwm.getIvSettings(any())).thenReturn(ivSettings);
PowerMockito.mockStatic(Bukkit.class);
ItemFactory itemF = mock(ItemFactory.class);
ItemMeta imeta = mock(ItemMeta.class);
when(itemF.getItemMeta(Mockito.any())).thenReturn(imeta);
when(itemF.getItemMeta(any())).thenReturn(imeta);
when(Bukkit.getItemFactory()).thenReturn(itemF);
Inventory top = mock(Inventory.class);
when(top.getSize()).thenReturn(9);
when(panel.getInventory()).thenReturn(top);
when(Bukkit.createInventory(Mockito.any(), Mockito.anyInt(), Mockito.any())).thenReturn(top);
when(Bukkit.createInventory(any(), Mockito.anyInt(), any())).thenReturn(top);
}
@Test
public void testOnClickWrongWorld() {
when(user.inWorld()).thenReturn(false);
listener.onClick(panel, user, ClickType.LEFT, 0);
Mockito.verify(user).sendMessage("general.errors.wrong-world");
verify(user).sendMessage("general.errors.wrong-world");
}
@Test
public void testOnClickNoPermission() {
when(user.hasPermission(Mockito.anyString())).thenReturn(false);
listener.onClick(panel, user, ClickType.LEFT, 0);
Mockito.verify(user).sendMessage("general.errors.no-permission", "[permission]", "bskyblock.admin.settings.INVINCIBLE_VISITORS");
verify(user).sendMessage("general.errors.no-permission", "[permission]", "bskyblock.admin.settings.INVINCIBLE_VISITORS");
}
@Test
@ -167,8 +171,8 @@ public class InvincibleVisitorsListenerTest {
when(panel.getName()).thenReturn("not_panel");
listener.onClick(panel, user, clickType, slot );
// Should open inv visitors
Mockito.verify(user).closeInventory();
Mockito.verify(player).openInventory(Mockito.any(Inventory.class));
verify(user).closeInventory();
verify(player).openInventory(any(Inventory.class));
}
@Test
@ -185,19 +189,19 @@ public class InvincibleVisitorsListenerTest {
// Click on the icon
listener.onClick(panel, user, clickType, slot);
// Should keep panel open
Mockito.verify(user, Mockito.never()).closeInventory();
verify(user, never()).closeInventory();
// IV settings should now have the damage cause in it
assertTrue(ivSettings.contains(dc.name()));
// Click on it again
listener.onClick(panel, user, clickType, slot );
// Should keep panel open
Mockito.verify(user, Mockito.never()).closeInventory();
verify(user, never()).closeInventory();
// IV settings should not have the damage cause in it anymore
assertFalse(ivSettings.contains(dc.name()));
}
// The values should be saved twice because there are two clicks
Mockito.verify(addon, Mockito.times(DamageCause.values().length * 2)).saveWorldSettings();
verify(addon, times(DamageCause.values().length * 2)).saveWorldSettings();
}
@Test
@ -229,7 +233,7 @@ public class InvincibleVisitorsListenerTest {
@Test
public void testOnVisitorGetDamageNotVisitor() {
EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.CRAMMING, 0D);
when(im.userIsOnIsland(Mockito.any(), Mockito.any())).thenReturn(true);
when(im.userIsOnIsland(any(), any())).thenReturn(true);
listener.onVisitorGetDamage(e);
assertFalse(e.isCancelled());
}
@ -239,13 +243,13 @@ public class InvincibleVisitorsListenerTest {
EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.CRAMMING, 0D);
listener.onVisitorGetDamage(e);
assertTrue(e.isCancelled());
Mockito.verify(player, Mockito.never()).setGameMode(Mockito.eq(GameMode.SPECTATOR));
verify(player, never()).setGameMode(eq(GameMode.SPECTATOR));
}
@Test
public void testOnVisitorGetDamageVoidIslandHere() {
when(im.getIslandAt(Mockito.any())).thenReturn(optionalIsland);
when(im.getIslandAt(any())).thenReturn(optionalIsland);
EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.VOID, 0D);
// Player should be teleported to this island
listener.onVisitorGetDamage(e);
@ -254,8 +258,8 @@ public class InvincibleVisitorsListenerTest {
@Test
public void testOnVisitorGetDamageVoidNoIslandHerePlayerHasNoIsland() {
when(im.getIslandAt(Mockito.any())).thenReturn(Optional.empty());
when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(false);
when(im.getIslandAt(any())).thenReturn(Optional.empty());
when(im.hasIsland(any(), any(UUID.class))).thenReturn(false);
EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.VOID, 0D);
// Player should die
listener.onVisitorGetDamage(e);
@ -264,12 +268,12 @@ public class InvincibleVisitorsListenerTest {
@Test
public void testOnVisitorGetDamageVoidPlayerHasIsland() {
when(im.getIslandAt(Mockito.any())).thenReturn(Optional.empty());
when(im.hasIsland(Mockito.any(), Mockito.any(UUID.class))).thenReturn(true);
when(im.getIslandAt(any())).thenReturn(Optional.empty());
when(im.hasIsland(any(), any(UUID.class))).thenReturn(true);
EntityDamageEvent e = new EntityDamageEvent(player, EntityDamageEvent.DamageCause.VOID, 0D);
// Player should be teleported to their island
listener.onVisitorGetDamage(e);
assertTrue(e.isCancelled());
Mockito.verify(im).homeTeleport(Mockito.any(), Mockito.eq(player));
verify(im).homeTeleport(any(), eq(player));
}
}

View File

@ -103,6 +103,7 @@ public class ItemFrameListenerTest {
when(iwm.inWorld(any(World.class))).thenReturn(true);
when(iwm.inWorld(any(Location.class))).thenReturn(true);
when(plugin.getIWM()).thenReturn(iwm);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
// Monsters and animals
enderman = mock(Enderman.class);

View File

@ -88,6 +88,7 @@ public class LiquidsFlowingOutListenerTest {
when(iwm.getWorldSettings(Mockito.any())).thenReturn(ws);
Map<String, Boolean> worldFlags = new HashMap<>();
when(ws.getWorldFlags()).thenReturn(worldFlags);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
// By default everything is in world
when(iwm.inWorld(any(World.class))).thenReturn(true);

View File

@ -97,6 +97,7 @@ public class OfflineGrowthListenerTest {
when(iwm.getWorldSettings(any())).thenReturn(ws);
Map<String, Boolean> worldFlags = new HashMap<>();
when(ws.getWorldFlags()).thenReturn(worldFlags);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
PowerMockito.mockStatic(Bukkit.class);
}

View File

@ -94,6 +94,7 @@ public class OfflineRedstoneListenerTest {
when(iwm.getWorldSettings(any())).thenReturn(ws);
Map<String, Boolean> worldFlags = new HashMap<>();
when(ws.getWorldFlags()).thenReturn(worldFlags);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
PowerMockito.mockStatic(Bukkit.class);
}

View File

@ -3,9 +3,9 @@
*/
package world.bentobox.bentobox.listeners.flags.worldsettings;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.any;
import java.util.HashMap;
import java.util.Map;
@ -87,6 +87,7 @@ public class RemoveMobsListenerTest {
// World Settings
IslandWorldManager iwm = mock(IslandWorldManager.class);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
when(plugin.getIWM()).thenReturn(iwm);
WorldSettings ws = mock(WorldSettings.class);
when(iwm.getWorldSettings(Mockito.any())).thenReturn(ws);

View File

@ -94,6 +94,7 @@ public class TreesGrowingOutsideRangeListenerTest {
// By default everything is in world
when(iwm.inWorld(any(World.class))).thenReturn(true);
when(iwm.inWorld(any(Location.class))).thenReturn(true);
when(iwm.getAddon(any())).thenReturn(Optional.empty());
/* Flags */
// By default, it is not allowed