Enabled settings flag clicks to work.

A listener can be added to a flag. This listener is the same as a panel
item listener. When the settings flag is clicked, it'll call the
listener. There is a default listener. Right now the default is called
UpDownClick.java. This makes the rank go up when you left click and down
when you right click. Another implementation may be to just have the
rank loop around with left clicks.

I added two more ranks - Admin and Mod. These are special ranks that
have a value above owner. If a player is given this rank, they can
bypass protections. This will avoid the need to use permissions and also
enable islands to be set up that for example, only Admins can edit, but
Mods cannot.

So, it's now possible for an owner to lock out team members from the
island as well as visitors. This is a bit weird and so more click
classes should be created. For example, one that just toggles between
Owner and Visitor.

Currently, only an island owner can change settings, but this could be
expanded to allow members. Also, it will need to be expanded to allow
Admins.
This commit is contained in:
Tastybento 2018-05-01 22:56:10 -07:00
parent 6e810747f4
commit de85f85bbe
18 changed files with 603 additions and 59 deletions

View File

@ -6,9 +6,12 @@ import org.bukkit.Material;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder; import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.database.objects.Island;
import us.tastybento.bskyblock.managers.RanksManager;
public class Flag implements Comparable<Flag> { public class Flag implements Comparable<Flag> {
@ -23,14 +26,16 @@ public class Flag implements Comparable<Flag> {
private final Type type; private final Type type;
private boolean defaultSetting; private boolean defaultSetting;
private final int defaultRank; private final int defaultRank;
private final PanelItem.ClickHandler clickHandler;
Flag(String id, Material icon, Listener listener, boolean defaultSetting, Type type, int defaultRank) { Flag(String id, Material icon, Listener listener, boolean defaultSetting, Type type, int defaultRank, PanelItem.ClickHandler clickListener) {
this.id = id; this.id = id;
this.icon = icon; this.icon = icon;
this.listener = listener; this.listener = listener;
this.defaultSetting = defaultSetting; this.defaultSetting = defaultSetting;
this.type = type; this.type = type;
this.defaultRank = defaultRank; this.defaultRank = defaultRank;
this.clickHandler = clickListener;
} }
public String getID() { public String getID() {
@ -112,26 +117,38 @@ public class Flag implements Comparable<Flag> {
return type == other.type; return type == other.type;
} }
public PanelItem toPanelItem(User user) { /**
* Converts a flag to a panel item. The content of the flag will change depending on who the user is and where they are.
* The panel item may reflect their island settings, the island they are on, or the world in general.
* @param user - user that will see this flag
* @return - PanelItem for this flag
*/
public PanelItem toPanelItem(BSkyBlock plugin, User user) {
// Get the island this user is on or their own
Island island = plugin.getIslands().getIslandAt(user.getLocation()).orElse(plugin.getIslands().getIsland(user.getUniqueId()));
String rank = RanksManager.OWNER_RANK_REF;
if (island != null) {
// TODO: Get the world settings - the player has no island and is not in an island location
rank = plugin.getRanksManager().getRank(island.getFlag(this));
}
return new PanelItemBuilder() return new PanelItemBuilder()
.icon(new ItemStack(icon)) .icon(new ItemStack(icon))
.name(user.getTranslation("protection.panel.flag-item.name-layout", "[name]", user.getTranslation("protection.flags." + id + ".name"))) .name(user.getTranslation("protection.panel.flag-item.name-layout", "[name]", user.getTranslation("protection.flags." + id + ".name")))
.description(user.getTranslation("protection.panel.flag-item.description-layout", .description(user.getTranslation("protection.panel.flag-item.description-layout",
"[description]", user.getTranslation("protection.flags." + id + ".description"), "[description]", user.getTranslation("protection.flags." + id + ".description"),
"[rank]", "Owner")) "[rank]", user.getTranslation(rank)))
.clickHandler((clicker, click) -> { .clickHandler(clickHandler)
clicker.sendRawMessage("You clicked on : " + id);
return true;
})
.build(); .build();
} }
/* (non-Javadoc) /* (non-Javadoc)
* @see java.lang.Object#toString() * @see java.lang.Object#toString()
*/ */
@Override @Override
public String toString() { public String toString() {
return "Flag [id=" + id + ", icon=" + icon + ", type=" + type + ", defaultSetting=" + defaultSetting + "]"; return "Flag [id=" + id + ", icon=" + icon + ", listener=" + listener + ", type=" + type + ", defaultSetting="
+ defaultSetting + ", defaultRank=" + defaultRank + ", clickHandler=" + clickHandler + "]";
} }
@Override @Override

View File

@ -4,6 +4,8 @@ import org.bukkit.Material;
import org.bukkit.event.Listener; import org.bukkit.event.Listener;
import us.tastybento.bskyblock.api.flags.Flag.Type; import us.tastybento.bskyblock.api.flags.Flag.Type;
import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.listeners.flags.UpDownClick;
import us.tastybento.bskyblock.managers.RanksManager; import us.tastybento.bskyblock.managers.RanksManager;
public class FlagBuilder { public class FlagBuilder {
@ -14,9 +16,12 @@ public class FlagBuilder {
private boolean defaultSetting; private boolean defaultSetting;
private Type type = Type.PROTECTION; private Type type = Type.PROTECTION;
private int defaultRank = RanksManager.MEMBER_RANK; private int defaultRank = RanksManager.MEMBER_RANK;
private PanelItem.ClickHandler onClick;
public FlagBuilder id(String string) { public FlagBuilder id(String string) {
id = string; id = string;
// Set the default click operation to UpDownClick
onClick = new UpDownClick(id);
return this; return this;
} }
@ -31,7 +36,7 @@ public class FlagBuilder {
} }
public Flag build() { public Flag build() {
return new Flag(id, icon, listener, defaultSetting, type, defaultRank); return new Flag(id, icon, listener, defaultSetting, type, defaultRank, onClick);
} }
/** /**
@ -73,4 +78,15 @@ public class FlagBuilder {
this.defaultRank = rank; this.defaultRank = rank;
return this; return this;
} }
/**
* Adds a listener for clicks on this flag when it is a panel item. Default is
* {@link us.tastybento.bskyblock.listeners.flags.UpDownClick.UpDownClick}
* @param onClickListener - the listener for clicks. Must use the ClickOn interface
* @return FlagBuilder
*/
public FlagBuilder onClick(PanelItem.ClickHandler onClickListener) {
this.onClick = onClickListener;
return this;
}
} }

View File

@ -1,6 +0,0 @@
package us.tastybento.bskyblock.api.panels;
public enum ClickType {
RIGHT,
LEFT
}

View File

@ -4,6 +4,7 @@ import java.util.List;
import java.util.Optional; import java.util.Optional;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
@ -102,11 +103,13 @@ public class PanelItem {
public interface ClickHandler { public interface ClickHandler {
/** /**
* This is executed when the icon is clicked * This is executed when the icon is clicked
* @param panel - the panel that is being clicked
* @param user - the User * @param user - the User
* @param click * @param clickType - the click type
* @param slot - the slot that was clicked
* @return true if the click event should be cancelled * @return true if the click event should be cancelled
*/ */
boolean onClick(User user, ClickType click); boolean onClick(Panel panel, User user, ClickType clickType, int slot);
} }
public void setHead(ItemStack itemStack) { public void setHead(ItemStack itemStack) {

View File

@ -32,7 +32,7 @@ public class IslandSettingsCommand extends CompositeCommand {
*/ */
@Override @Override
public boolean execute(User user, List<String> args) { public boolean execute(User user, List<String> args) {
SettingsPanel.openPanel(user); SettingsPanel.openPanel(getPlugin(), user);
return true; return true;
} }
} }

View File

@ -56,7 +56,7 @@ public class IslandTeamPromoteCommand extends AbstractIslandTeamCommand {
private boolean change(User user, User target) { private boolean change(User user, User target) {
int currentRank = getIslands().getIsland(user.getUniqueId()).getRank(target); int currentRank = getIslands().getIsland(user.getUniqueId()).getRank(target);
if (this.getLabel().equals("promote")) { if (this.getLabel().equals("promote")) {
int nextRank = getPlugin().getRanksManager().getNextRankValue(currentRank); int nextRank = getPlugin().getRanksManager().getRankUpValue(currentRank);
if (nextRank > currentRank) { if (nextRank > currentRank) {
getIslands().getIsland(user.getUniqueId()).setRank(target, nextRank); getIslands().getIsland(user.getUniqueId()).setRank(target, nextRank);
String rankName = user.getTranslation(getPlugin().getRanksManager().getRank(nextRank)); String rankName = user.getTranslation(getPlugin().getRanksManager().getRank(nextRank));
@ -68,7 +68,7 @@ public class IslandTeamPromoteCommand extends AbstractIslandTeamCommand {
} }
} else { } else {
// Demote // Demote
int prevRank = getPlugin().getRanksManager().getPreviousRankValue(currentRank); int prevRank = getPlugin().getRanksManager().getRankDownValue(currentRank);
if (prevRank < currentRank) { if (prevRank < currentRank) {
getIslands().getIsland(user.getUniqueId()).setRank(target, prevRank); getIslands().getIsland(user.getUniqueId()).setRank(target, prevRank);
String rankName = user.getTranslation(getPlugin().getRanksManager().getRank(prevRank)); String rankName = user.getTranslation(getPlugin().getRanksManager().getRank(prevRank));

View File

@ -12,7 +12,6 @@ import org.bukkit.event.inventory.InventoryCloseEvent;
import org.bukkit.event.player.PlayerQuitEvent; import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import us.tastybento.bskyblock.api.panels.ClickType;
import us.tastybento.bskyblock.api.panels.Panel; import us.tastybento.bskyblock.api.panels.Panel;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
@ -36,11 +35,9 @@ public class PanelListenerManager implements Listener {
// Check that they clicked on a specific item // Check that they clicked on a specific item
for (int slot : panel.getItems().keySet()) { for (int slot : panel.getItems().keySet()) {
if (slot == event.getRawSlot()) { if (slot == event.getRawSlot()) {
// Check that they left clicked on it
// TODO: in the future, we may want to support right clicking
panel.getItems().get(slot).getClickHandler().ifPresent(handler -> panel.getItems().get(slot).getClickHandler().ifPresent(handler ->
// Execute the handler's onClick method and optionally cancel the event if the handler returns true // Execute the handler's onClick method and optionally cancel the event if the handler returns true
event.setCancelled(handler.onClick(user, ClickType.LEFT)) event.setCancelled(handler.onClick(panel, user, event.getClick(), event.getSlot()))
); );
} }
} }

View File

@ -4,6 +4,7 @@
package us.tastybento.bskyblock.listeners.flags; package us.tastybento.bskyblock.listeners.flags;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Sound; import org.bukkit.Sound;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -14,6 +15,7 @@ import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.event.player.PlayerMoveEvent; import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent; import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.vehicle.VehicleMoveEvent; import org.bukkit.event.vehicle.VehicleMoveEvent;
import org.bukkit.util.Vector;
import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
@ -57,9 +59,11 @@ public class LockAndBanListener implements Listener {
if (e.getFrom().getBlockX() - e.getTo().getBlockX() == 0 && e.getFrom().getBlockZ() - e.getTo().getBlockZ() == 0) { if (e.getFrom().getBlockX() - e.getTo().getBlockX() == 0 && e.getFrom().getBlockZ() - e.getTo().getBlockZ() == 0) {
return; return;
} }
e.setCancelled(checkAndNotify(e.getPlayer(), e.getTo()).equals(CheckResult.OPEN) ? false : true); if (checkAndNotify(e.getPlayer(), e.getTo()).equals(CheckResult.OPEN) ? false : true) {
if (e.isCancelled()) { e.setCancelled(true);
e.getFrom().getWorld().playSound(e.getFrom(), Sound.BLOCK_ANVIL_HIT, 1F, 1F); e.getFrom().getWorld().playSound(e.getFrom(), Sound.BLOCK_ANVIL_HIT, 1F, 1F);
e.getPlayer().setVelocity(new Vector(0,0,0));
e.getPlayer().setGliding(false);
} }
// Check from - just in case the player is inside the island // Check from - just in case the player is inside the island
if (!check(e.getPlayer(), e.getFrom()).equals(CheckResult.OPEN)) { if (!check(e.getPlayer(), e.getFrom()).equals(CheckResult.OPEN)) {
@ -101,6 +105,7 @@ public class LockAndBanListener implements Listener {
* @return CheckResult LOCKED, BANNED or OPEN. If an island is locked, that will take priority over banned * @return CheckResult LOCKED, BANNED or OPEN. If an island is locked, that will take priority over banned
*/ */
private CheckResult check(Player player, Location loc) { private CheckResult check(Player player, Location loc) {
// See if the island is locked to non-members or player is banned // See if the island is locked to non-members or player is banned
return im.getProtectedIslandAt(loc) return im.getProtectedIslandAt(loc)
.map(is -> !is.isAllowed(User.getInstance(player), Flags.LOCK) ? CheckResult.LOCKED .map(is -> !is.isAllowed(User.getInstance(player), Flags.LOCK) ? CheckResult.LOCKED
@ -135,6 +140,7 @@ public class LockAndBanListener implements Listener {
* @param player * @param player
*/ */
private void eject(Player player) { private void eject(Player player) {
player.setGameMode(GameMode.SPECTATOR);
// Teleport player to their home // Teleport player to their home
if (im.hasIsland(player.getUniqueId())) { if (im.hasIsland(player.getUniqueId())) {
im.homeTeleport(player); im.homeTeleport(player);

View File

@ -0,0 +1,60 @@
/**
*
*/
package us.tastybento.bskyblock.listeners.flags;
import org.bukkit.Sound;
import org.bukkit.event.inventory.ClickType;
import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.flags.Flag;
import us.tastybento.bskyblock.api.panels.Panel;
import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.database.objects.Island;
import us.tastybento.bskyblock.managers.RanksManager;
/**
* Left Clicks increase rank, right clicks lower rank
* @author tastybento
*
*/
public class UpDownClick implements PanelItem.ClickHandler {
private BSkyBlock plugin = BSkyBlock.getInstance();
private final String id;
/**
* @param id - the flag id that will be adjusted by this click
*/
public UpDownClick(String id) {
this.id = id;
}
@Override
public boolean onClick(Panel panel, User user, ClickType click, int slot) {
// Left clicking increases the rank required
// Right clicking decreases the rank required
// Get the user's island
Island island = plugin.getIslands().getIsland(user.getUniqueId());
if (island != null && island.getOwner().equals(user.getUniqueId())) {
RanksManager rm = plugin.getRanksManager();
Flag flag = plugin.getFlagsManager().getFlagByID(id);
int currentRank = island.getFlag(flag);
if (click.equals(ClickType.LEFT)) {
int nextRank = rm.getRankUpValue(currentRank);
island.setFlag(flag, nextRank);
user.getWorld().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_ON, 1F, 1F);
} else if (click.equals(ClickType.RIGHT)) {
int nextRank = rm.getRankDownValue(currentRank);
island.setFlag(flag, nextRank);
user.getWorld().playSound(user.getLocation(), Sound.BLOCK_STONE_BUTTON_CLICK_OFF, 1F, 1F);
}
// Apply change to panel
panel.getInventory().setItem(slot, flag.toPanelItem(plugin, user).getItem());
}
return true;
}
}

View File

@ -119,7 +119,10 @@ public class Flags {
public static final Flag ITEM_PICKUP = new FlagBuilder().id("ITEM_PICKUP").icon(Material.BEETROOT_SEEDS).build(); public static final Flag ITEM_PICKUP = new FlagBuilder().id("ITEM_PICKUP").icon(Material.BEETROOT_SEEDS).build();
// Island lock // Island lock
public static final Flag LOCK = new FlagBuilder().id("LOCK").icon(Material.TRIPWIRE_HOOK).type(Type.PROTECTION).allowedByDefault(true).defaultRank(RanksManager.VISITOR_RANK).listener(new LockAndBanListener()).build(); public static final Flag LOCK = new FlagBuilder().id("LOCK")
.icon(Material.TRIPWIRE_HOOK).type(Type.PROTECTION).allowedByDefault(true)
.defaultRank(RanksManager.VISITOR_RANK).listener(new LockAndBanListener())
.build();
/* /*
* Settings flags (not protection flags) * Settings flags (not protection flags)

View File

@ -520,6 +520,8 @@ public class IslandsManager {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
public void homeTeleport(final Player player, int number) { public void homeTeleport(final Player player, int number) {
Location home = getSafeHomeLocation(player.getUniqueId(), number); Location home = getSafeHomeLocation(player.getUniqueId(), number);
// Stop any gliding
player.setGliding(false);
// Check if the player is a passenger in a boat // Check if the player is a passenger in a boat
if (player.isInsideVehicle()) { if (player.isInsideVehicle()) {
Entity boat = player.getVehicle(); Entity boat = player.getVehicle();

View File

@ -10,10 +10,14 @@ import us.tastybento.bskyblock.BSkyBlock;
public class RanksManager { public class RanksManager {
// Constants that define the hard coded rank values // Constants that define the hard coded rank values
public static final String ADMIN_RANK_REF = "ranks.admin";
public static final String MOD_RANK_REF = "ranks.mod";
public static final String OWNER_RANK_REF = "ranks.owner"; public static final String OWNER_RANK_REF = "ranks.owner";
public static final String MEMBER_RANK_REF = "ranks.member"; public static final String MEMBER_RANK_REF = "ranks.member";
public static final String VISITOR_RANK_REF = "ranks.visitor"; public static final String VISITOR_RANK_REF = "ranks.visitor";
public static final String BANNED_RANK_REF = "ranks.banned"; public static final String BANNED_RANK_REF = "ranks.banned";
public static final int ADMIN_RANK = 10000;
public static final int MOD_RANK = 5000;
public static final int OWNER_RANK = 1000; public static final int OWNER_RANK = 1000;
public static final int MEMBER_RANK = 900; public static final int MEMBER_RANK = 900;
public static final int VISITOR_RANK = 0; public static final int VISITOR_RANK = 0;
@ -31,6 +35,8 @@ public class RanksManager {
super(); super();
this.plugin = plugin; this.plugin = plugin;
// Hard coded ranks // Hard coded ranks
ranksPut(ADMIN_RANK_REF, ADMIN_RANK);
ranksPut(MOD_RANK_REF, MOD_RANK);
ranksPut(OWNER_RANK_REF, OWNER_RANK); ranksPut(OWNER_RANK_REF, OWNER_RANK);
ranksPut(MEMBER_RANK_REF, MEMBER_RANK); ranksPut(MEMBER_RANK_REF, MEMBER_RANK);
ranksPut(VISITOR_RANK_REF, VISITOR_RANK); ranksPut(VISITOR_RANK_REF, VISITOR_RANK);
@ -59,7 +65,9 @@ public class RanksManager {
if (reference.equalsIgnoreCase(OWNER_RANK_REF) if (reference.equalsIgnoreCase(OWNER_RANK_REF)
|| reference.equalsIgnoreCase(MEMBER_RANK_REF) || reference.equalsIgnoreCase(MEMBER_RANK_REF)
|| reference.equalsIgnoreCase(VISITOR_RANK_REF) || reference.equalsIgnoreCase(VISITOR_RANK_REF)
|| reference.equalsIgnoreCase(BANNED_RANK_REF)) { || reference.equalsIgnoreCase(BANNED_RANK_REF)
|| reference.equalsIgnoreCase(ADMIN_RANK_REF)
|| reference.equalsIgnoreCase(MOD_RANK_REF)) {
return false; return false;
} }
ranksPut(reference, value); ranksPut(reference, value);
@ -85,7 +93,9 @@ public class RanksManager {
if (reference.equalsIgnoreCase(OWNER_RANK_REF) if (reference.equalsIgnoreCase(OWNER_RANK_REF)
|| reference.equalsIgnoreCase(MEMBER_RANK_REF) || reference.equalsIgnoreCase(MEMBER_RANK_REF)
|| reference.equalsIgnoreCase(VISITOR_RANK_REF) || reference.equalsIgnoreCase(VISITOR_RANK_REF)
|| reference.equalsIgnoreCase(BANNED_RANK_REF)) { || reference.equalsIgnoreCase(BANNED_RANK_REF)
|| reference.equalsIgnoreCase(ADMIN_RANK_REF)
|| reference.equalsIgnoreCase(MOD_RANK_REF)) {
return false; return false;
} }
@ -111,11 +121,11 @@ public class RanksManager {
/** /**
* Gets the next rank value above the current rank, excluding the owner rank * Gets the next rank value above the current rank. Highest is {@link RanksManager.OWNER_RANK}
* @param currentRank * @param currentRank
* @return Optional rank value * @return Optional rank value
*/ */
public int getNextRankValue(int currentRank) { public int getRankUpValue(int currentRank) {
return getRanks().values().stream().mapToInt(x -> { return getRanks().values().stream().mapToInt(x -> {
if (x > currentRank) { if (x > currentRank) {
return x; return x;
@ -125,16 +135,16 @@ public class RanksManager {
} }
/** /**
* Gets the previous rank value below the current rank * Gets the previous rank value below the current rank. Lowest is {@link RanksManager.VISITOR_RANK}
* @param currentRank * @param currentRank
* @return Optional rank value * @return Optional rank value
*/ */
public int getPreviousRankValue(int currentRank) { public int getRankDownValue(int currentRank) {
return getRanks().values().stream().mapToInt(x -> { return getRanks().values().stream().mapToInt(x -> {
if (x < currentRank) { if (x < currentRank) {
return x; return x;
} }
return BANNED_RANK; return VISITOR_RANK;
}).max().orElse(currentRank); }).max().orElse(currentRank);
} }

View File

@ -23,7 +23,7 @@ public class LanguagePanel {
for (Locale locale : BSkyBlock.getInstance().getLocalesManager().getAvailableLocales()) { for (Locale locale : BSkyBlock.getInstance().getLocalesManager().getAvailableLocales()) {
PanelItemBuilder localeIcon = new PanelItemBuilder().icon(BSkyBlock.getInstance().getLocalesManager().getLanguages().get(locale).getBanner()) PanelItemBuilder localeIcon = new PanelItemBuilder().icon(BSkyBlock.getInstance().getLocalesManager().getLanguages().get(locale).getBanner())
.name(fancyLocaleDisplayName(user, locale)) .name(fancyLocaleDisplayName(user, locale))
.clickHandler((u, click) -> { .clickHandler((panel, u, click, slot) -> {
BSkyBlock.getInstance().getPlayers().setLocale(u.getUniqueId(), locale.toLanguageTag()); BSkyBlock.getInstance().getPlayers().setLocale(u.getUniqueId(), locale.toLanguageTag());
u.sendMessage("language.edited", "[lang]", fancyLocaleDisplayName(u, locale)); u.sendMessage("language.edited", "[lang]", fancyLocaleDisplayName(u, locale));
openPanel(u); openPanel(u);

View File

@ -1,7 +1,6 @@
package us.tastybento.bskyblock.panels; package us.tastybento.bskyblock.panels;
import us.tastybento.bskyblock.BSkyBlock; import us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.flags.Flag;
import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.panels.builders.PanelBuilder; import us.tastybento.bskyblock.api.panels.builders.PanelBuilder;
import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder; import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder;
@ -16,22 +15,23 @@ public class SettingsPanel {
* Dynamically creates the panel. * Dynamically creates the panel.
* @param user the User to show the panel to * @param user the User to show the panel to
*/ */
public static void openPanel(User user) { public static void openPanel(BSkyBlock plugin, User user) {
// Make a panel for settings
PanelBuilder panelBuilder = new PanelBuilder() PanelBuilder panelBuilder = new PanelBuilder()
.name(user.getTranslation("protection.panel.title")); .name(user.getTranslation("protection.panel.title"));
// Make the help item
PanelItem help = new PanelItemBuilder() PanelItem help = new PanelItemBuilder()
.name(user.getTranslation("protection.panel.help-item.name")) .name(user.getTranslation("protection.panel.help-item.name"))
.icon("MHF_Question") // Question marks .icon("MHF_Question") // Question marks
.build(); .build();
// Place it at position 8 (end of first row)
panelBuilder.item(8, help); panelBuilder.item(8, help);
for (Flag flag : BSkyBlock.getInstance().getFlagsManager().getFlags()) { // Add flags after position 8, i.e., from second row
PanelItem flagIcon = flag.toPanelItem(user); plugin.getFlagsManager().getFlags().forEach((f -> panelBuilder.item(f.toPanelItem(plugin, user))));
panelBuilder.item(flagIcon);
}
// Make the panel
panelBuilder.build().open(user); panelBuilder.build().open(user);
} }
} }

View File

@ -0,0 +1,192 @@
package us.tastybento.bskyblock.api.flags;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;
import org.junit.Before;
import org.junit.BeforeClass;
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 us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.panels.builders.PanelItemBuilder;
import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.database.objects.Island;
import us.tastybento.bskyblock.managers.IslandsManager;
import us.tastybento.bskyblock.managers.RanksManager;
@RunWith(PowerMockRunner.class)
@PrepareForTest({ Flag.class })
public class FlagTest {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@Before
public void setUp() throws Exception {
}
@Test
public void testHashCode() {
Flag flag1 = new Flag(null, null, null, false, null, 0, null);
Flag flag2 = new Flag(null, null, null, false, null, 0, null);
assertTrue(flag1.hashCode() == flag2.hashCode());
}
@Test
public void testFlag() {
assertNotNull(new Flag(null, null, null, false, null, 0, null));
}
@Test
public void testGetID() {
Flag id = new Flag("id", null, null, false, null, 0, null);
assertEquals("id", id.getID());
}
@Test
public void testGetIcon() {
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, null, 0, null);
assertEquals(Material.ACACIA_DOOR, id.getIcon());
}
@Test
public void testGetListener() {
Listener l = mock(Listener.class);
Flag id = new Flag("id", Material.ACACIA_DOOR, l, false, null, 0, null);
Optional<Listener> ol = Optional.ofNullable(l);
assertEquals(ol, id.getListener());
id = new Flag("id", Material.ACACIA_DOOR, null, false, null, 0, null);
assertEquals(Optional.empty(), id.getListener());
}
@Test
public void testIsDefaultSetting() {
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, null, 0, null);
assertFalse(id.isDefaultSetting());
id = new Flag("id", Material.ACACIA_DOOR, null, true, null, 0, null);
assertTrue(id.isDefaultSetting());
}
@Test
public void testSetDefaultSetting() {
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, null, 0, null);
assertFalse(id.isDefaultSetting());
id.setDefaultSetting(true);
assertTrue(id.isDefaultSetting());
id.setDefaultSetting(false);
assertFalse(id.isDefaultSetting());
}
@Test
public void testGetType() {
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, Flag.Type.PROTECTION, 0, null);
assertEquals(Flag.Type.PROTECTION,id.getType());
id = new Flag("id", Material.ACACIA_DOOR, null, false, Flag.Type.SETTING, 0, null);
assertEquals(Flag.Type.SETTING,id.getType());
}
@Test
public void testGetDefaultRank() {
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, Flag.Type.PROTECTION, 100, null);
assertEquals(100, id.getDefaultRank());
}
@Test
public void testEqualsObject() {
Flag flag1 = null;
Flag flag2 = new Flag(null, null, null, false, null, 0, null);
assertFalse(flag2.equals(null));
int i = 45;
assertFalse(flag2.equals(i));
flag1 = new Flag(null, null, null, false, null, 0, null);
flag2 = flag1;
assertTrue(flag1.equals(flag2));
assertTrue(flag2.equals(flag1));
flag2 = new Flag("id", Material.ACACIA_DOOR, null, false, Flag.Type.PROTECTION, 0, null);
assertFalse(flag1.equals(flag2));
assertFalse(flag2.equals(flag1));
}
@Test
public void testToPanelItem() throws Exception {
BSkyBlock plugin = mock(BSkyBlock.class);
IslandsManager im = mock(IslandsManager.class);
Island island = mock(Island.class);
when(island.getFlag(Mockito.any())).thenReturn(RanksManager.VISITOR_RANK);
User user = mock(User.class);
when(user.getUniqueId()).thenReturn(UUID.randomUUID());
when(user.getTranslation(Mockito.anyString())).thenReturn("translation");
when(user.getTranslation(Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString())).thenReturn("long translation");
when(im.getIsland(Mockito.any())).thenReturn(island);
Optional<Island> oL = Optional.ofNullable(island);
when(im.getIslandAt(Mockito.any(Location.class))).thenReturn(oL);
when(plugin.getIslands()).thenReturn(im);
RanksManager rm = mock(RanksManager.class);
when(plugin.getRanksManager()).thenReturn(rm);
when(rm.getRank(Mockito.eq(RanksManager.VISITOR_RANK))).thenReturn("Visitor");
when(rm.getRank(Mockito.eq(RanksManager.OWNER_RANK))).thenReturn("Owner");
PowerMockito.whenNew(ItemStack.class).withAnyArguments().thenReturn(mock(ItemStack.class));
PanelItemBuilder pib = mock(PanelItemBuilder.class);
when(pib.description(Mockito.anyString())).thenReturn(pib);
when(pib.name(Mockito.anyString())).thenReturn(pib);
when(pib.icon(Mockito.any(ItemStack.class))).thenReturn(pib);
when(pib.clickHandler(Mockito.any())).thenReturn(pib);
when(pib.build()).thenReturn(mock(PanelItem.class));
// Remember to prepare the calling class, not the subject class!
PowerMockito.whenNew(PanelItemBuilder.class).withAnyArguments().thenReturn(pib);
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, Flag.Type.PROTECTION, 0, null);
id.toPanelItem(plugin, user);
verify(user).getTranslation(Mockito.eq("protection.flags.id.name"));
verify(user).getTranslation(Mockito.eq("protection.panel.flag-item.name-layout"), Mockito.anyVararg());
}
@Test
public void testToString() {
Flag id = new Flag("id", Material.ACACIA_DOOR, null, false, Flag.Type.PROTECTION, 0, null);
assertEquals("Flag [id=id, icon=ACACIA_DOOR, listener=null, type=PROTECTION, defaultSetting=false, defaultRank=0, clickHandler=null]", id.toString());
}
@Test
public void testCompareTo() {
Flag aaa = new Flag("AAA", Material.ACACIA_DOOR, null, false, Flag.Type.PROTECTION, 0, null);
Flag bbb = new Flag("BBB", Material.ACACIA_DOOR, null, false, Flag.Type.PROTECTION, 0, null);
assertTrue(aaa.compareTo(bbb) < bbb.compareTo(aaa));
assertTrue(aaa.compareTo(aaa) == 0);
}
}

View File

@ -18,6 +18,7 @@ import org.bukkit.Material;
import org.bukkit.OfflinePlayer; import org.bukkit.OfflinePlayer;
import org.bukkit.Server; import org.bukkit.Server;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.event.inventory.ClickType;
import org.bukkit.inventory.ItemFactory; import org.bukkit.inventory.ItemFactory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.SkullMeta; import org.bukkit.inventory.meta.SkullMeta;
@ -28,7 +29,7 @@ import org.junit.runner.RunWith;
import org.mockito.Mockito; import org.mockito.Mockito;
import org.powermock.modules.junit4.PowerMockRunner; import org.powermock.modules.junit4.PowerMockRunner;
import us.tastybento.bskyblock.api.panels.ClickType; import us.tastybento.bskyblock.api.panels.Panel;
import us.tastybento.bskyblock.api.panels.PanelItem; import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.user.User; import us.tastybento.bskyblock.api.user.User;
@ -141,7 +142,7 @@ public class PanelItemBuilderTest {
item = builder.clickHandler(new Clicker()).build(); item = builder.clickHandler(new Clicker()).build();
assertTrue(item.getClickHandler().isPresent()); assertTrue(item.getClickHandler().isPresent());
assertTrue(item.getClickHandler().map(x -> x.onClick(null, ClickType.LEFT)).orElse(false)); assertTrue(item.getClickHandler().map(x -> x.onClick(null, null, ClickType.LEFT, 0)).orElse(false));
} }
@Test @Test
@ -159,7 +160,7 @@ public class PanelItemBuilderTest {
public class Clicker implements PanelItem.ClickHandler { public class Clicker implements PanelItem.ClickHandler {
@Override @Override
public boolean onClick(User user, ClickType click) { public boolean onClick(Panel panel, User user, ClickType click, int slot) {
return true; return true;
} }

View File

@ -0,0 +1,242 @@
package us.tastybento.bskyblock.listeners.flags;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.Location;
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.scheduler.BukkitScheduler;
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 us.tastybento.bskyblock.BSkyBlock;
import us.tastybento.bskyblock.Settings;
import us.tastybento.bskyblock.api.flags.Flag;
import us.tastybento.bskyblock.api.panels.Panel;
import us.tastybento.bskyblock.api.panels.PanelItem;
import us.tastybento.bskyblock.api.user.Notifier;
import us.tastybento.bskyblock.api.user.User;
import us.tastybento.bskyblock.database.objects.Island;
import us.tastybento.bskyblock.managers.FlagsManager;
import us.tastybento.bskyblock.managers.IslandsManager;
import us.tastybento.bskyblock.managers.LocalesManager;
import us.tastybento.bskyblock.managers.PlayersManager;
import us.tastybento.bskyblock.managers.RanksManager;
@RunWith(PowerMockRunner.class)
@PrepareForTest({Bukkit.class, BSkyBlock.class, User.class })
public class UpDownClickTest {
private static final Integer PROTECTION_RANGE = 200;
private static final Integer X = 600;
private static final Integer Y = 120;
private static final Integer Z = 10000;
private BSkyBlock plugin;
private UUID uuid;
private User user;
private Settings s;
private IslandsManager im;
private PlayersManager pm;
private Island island;
private World world;
private Location loc;
private Location outside;
private Location inside;
private Notifier notifier;
private Location inside2;
private BukkitScheduler sch;
private Flag flag;
private PanelItem panelItem;
private Panel panel;
private Inventory inv;
/**
* @throws java.lang.Exception
*/
@Before
public void setUp() throws Exception {
// Set up plugin
plugin = mock(BSkyBlock.class);
Whitebox.setInternalState(BSkyBlock.class, "instance", plugin);
// World
world = mock(World.class);
// Settings
s = mock(Settings.class);
when(s.getResetWait()).thenReturn(0L);
when(s.getResetLimit()).thenReturn(3);
when(plugin.getSettings()).thenReturn(s);
// Player
Player p = mock(Player.class);
// Sometimes use Mockito.withSettings().verboseLogging()
user = mock(User.class);
User.setPlugin(plugin);
when(user.isOp()).thenReturn(false);
uuid = UUID.randomUUID();
when(user.getUniqueId()).thenReturn(uuid);
when(user.getPlayer()).thenReturn(p);
when(user.getName()).thenReturn("tastybento");
when(user.getWorld()).thenReturn(world);
// No island for player to begin with (set it later in the tests)
im = mock(IslandsManager.class);
when(im.hasIsland(Mockito.eq(uuid))).thenReturn(false);
when(im.isOwner(Mockito.eq(uuid))).thenReturn(false);
when(plugin.getIslands()).thenReturn(im);
// Has team
pm = mock(PlayersManager.class);
when(pm.inTeam(Mockito.eq(uuid))).thenReturn(true);
when(plugin.getPlayers()).thenReturn(pm);
// Server & Scheduler
sch = mock(BukkitScheduler.class);
PowerMockito.mockStatic(Bukkit.class);
when(Bukkit.getScheduler()).thenReturn(sch);
// Locales
LocalesManager lm = mock(LocalesManager.class);
when(plugin.getLocalesManager()).thenReturn(lm);
when(lm.get(any(), any())).thenReturn("mock translation");
// Notifier
notifier = mock(Notifier.class);
when(plugin.getNotifier()).thenReturn(notifier);
// Island Banned list initialization
island = mock(Island.class);
when(island.getBanned()).thenReturn(new HashSet<>());
when(island.isBanned(Mockito.any())).thenReturn(false);
loc = mock(Location.class);
when(loc.getWorld()).thenReturn(world);
when(loc.getBlockX()).thenReturn(X);
when(loc.getBlockY()).thenReturn(Y);
when(loc.getBlockZ()).thenReturn(Z);
when(island.getCenter()).thenReturn(loc);
when(island.getProtectionRange()).thenReturn(PROTECTION_RANGE);
// Island is not locked by default
when(island.isAllowed(Mockito.any(), Mockito.any())).thenReturn(true);
// Island owner is user by default
when(island.getOwner()).thenReturn(uuid);
when(im.getIsland(Mockito.any(UUID.class))).thenReturn(island);
// Common from to's
outside = mock(Location.class);
when(outside.getWorld()).thenReturn(world);
when(outside.getBlockX()).thenReturn(X + PROTECTION_RANGE + 1);
when(outside.getBlockY()).thenReturn(Y);
when(outside.getBlockZ()).thenReturn(Z);
inside = mock(Location.class);
when(inside.getWorld()).thenReturn(world);
when(inside.getBlockX()).thenReturn(X + PROTECTION_RANGE - 1);
when(inside.getBlockY()).thenReturn(Y);
when(inside.getBlockZ()).thenReturn(Z);
inside2 = mock(Location.class);
when(inside.getWorld()).thenReturn(world);
when(inside.getBlockX()).thenReturn(X + PROTECTION_RANGE - 2);
when(inside.getBlockY()).thenReturn(Y);
when(inside.getBlockZ()).thenReturn(Z);
Optional<Island> opIsland = Optional.ofNullable(island);
when(im.getProtectedIslandAt(Mockito.eq(inside))).thenReturn(opIsland);
when(im.getProtectedIslandAt(Mockito.eq(inside2))).thenReturn(opIsland);
when(im.getProtectedIslandAt(Mockito.eq(outside))).thenReturn(Optional.empty());
panelItem = mock(PanelItem.class);
flag = mock(Flag.class);
when(flag.toPanelItem(Mockito.any(), Mockito.any())).thenReturn(panelItem);
when(panelItem.getItem()).thenReturn(mock(ItemStack.class));
FlagsManager fm = mock(FlagsManager.class);
when(fm.getFlagByID(Mockito.anyString())).thenReturn(flag);
when(plugin.getFlagsManager()).thenReturn(fm);
RanksManager rm = mock(RanksManager.class);
when(plugin.getRanksManager()).thenReturn(rm);
// Provide a current rank value - member
when(island.getFlag(Mockito.any())).thenReturn(RanksManager.MEMBER_RANK);
// Set up up and down ranks
when(rm.getRankUpValue(Mockito.eq(RanksManager.MEMBER_RANK))).thenReturn(RanksManager.OWNER_RANK);
when(rm.getRankDownValue(Mockito.eq(RanksManager.MEMBER_RANK))).thenReturn(RanksManager.VISITOR_RANK);
panel = mock(Panel.class);
inv = mock(Inventory.class);
when(panel.getInventory()).thenReturn(inv);
}
@Test
public void testUpDownClick() {
UpDownClick udc = new UpDownClick("LOCK");
assertNotNull(udc);
}
@Test
public void testOnLeftClick() {
UpDownClick udc = new UpDownClick("LOCK");
// Click left
assertTrue(udc.onClick(panel, user, ClickType.LEFT, 5));
Mockito.verify(island).setFlag(Mockito.eq(flag), Mockito.eq(RanksManager.OWNER_RANK));
Mockito.verify(flag).toPanelItem(Mockito.any(), Mockito.any());
Mockito.verify(inv).setItem(Mockito.eq(5), Mockito.any());
}
@Test
public void testOnRightClick() {
UpDownClick udc = new UpDownClick("LOCK");
// Right click
assertTrue(udc.onClick(panel, user, ClickType.RIGHT, 0));
Mockito.verify(island).setFlag(Mockito.eq(flag), Mockito.eq(RanksManager.VISITOR_RANK));
}
@Test
public void testAllClicks() {
// Test all possible click types
UpDownClick udc = new UpDownClick("LOCK");
Arrays.asList(ClickType.values()).forEach(c -> assertTrue(udc.onClick(panel, user, c, 0)));
}
@Test
public void testNotOwner() {
UUID u;
do {
u = UUID.randomUUID();
} while(u.equals(uuid));
when(island.getOwner()).thenReturn(u);
Mockito.verify(plugin, Mockito.never()).getRanksManager();
}
@Test
public void testNullIsland() {
when(im.getIsland(Mockito.any(UUID.class))).thenReturn(null);
Mockito.verify(plugin, Mockito.never()).getRanksManager();
}
}

View File

@ -83,27 +83,28 @@ public class RanksManagerTest {
} }
/** /**
* Test method for {@link us.tastybento.bskyblock.managers.RanksManager#getNextRankValue(int)}. * Test method for {@link us.tastybento.bskyblock.managers.RanksManager#getRankUpValue(int)}.
*/ */
@Test @Test
public void testGetNextRankValue() { public void testGetNextRankValue() {
assertEquals(RanksManager.BANNED_RANK, ranksManager.getNextRankValue(-20)); assertEquals(RanksManager.BANNED_RANK, ranksManager.getRankUpValue(-20));
assertEquals(RanksManager.VISITOR_RANK, ranksManager.getNextRankValue(RanksManager.BANNED_RANK)); assertEquals(RanksManager.VISITOR_RANK, ranksManager.getRankUpValue(RanksManager.BANNED_RANK));
assertEquals(RanksManager.MEMBER_RANK, ranksManager.getNextRankValue(RanksManager.VISITOR_RANK)); assertEquals(RanksManager.MEMBER_RANK, ranksManager.getRankUpValue(RanksManager.VISITOR_RANK));
assertEquals(RanksManager.OWNER_RANK, ranksManager.getNextRankValue(RanksManager.MEMBER_RANK)); assertEquals(RanksManager.OWNER_RANK, ranksManager.getRankUpValue(RanksManager.MEMBER_RANK));
assertEquals(RanksManager.OWNER_RANK, ranksManager.getNextRankValue(RanksManager.OWNER_RANK)); assertEquals(RanksManager.OWNER_RANK, ranksManager.getRankUpValue(RanksManager.OWNER_RANK));
assertEquals(RanksManager.OWNER_RANK, ranksManager.getNextRankValue(2000)); assertEquals(RanksManager.OWNER_RANK, ranksManager.getRankUpValue(2000));
} }
/** /**
* Test method for {@link us.tastybento.bskyblock.managers.RanksManager#getPreviousRankValue(int)}. * Test method for {@link us.tastybento.bskyblock.managers.RanksManager#getRankDownValue(int)}.
*/ */
@Test @Test
public void testGetPreviousRankValue() { public void testGetPreviousRankValue() {
assertEquals(RanksManager.BANNED_RANK, ranksManager.getPreviousRankValue(-20)); // Lowest rank is Visitor
assertEquals(RanksManager.BANNED_RANK, ranksManager.getPreviousRankValue(RanksManager.VISITOR_RANK)); assertEquals(RanksManager.VISITOR_RANK, ranksManager.getRankDownValue(-20));
assertEquals(RanksManager.VISITOR_RANK, ranksManager.getPreviousRankValue(RanksManager.MEMBER_RANK)); assertEquals(RanksManager.VISITOR_RANK, ranksManager.getRankDownValue(RanksManager.VISITOR_RANK));
assertEquals(RanksManager.MEMBER_RANK, ranksManager.getPreviousRankValue(RanksManager.OWNER_RANK)); assertEquals(RanksManager.VISITOR_RANK, ranksManager.getRankDownValue(RanksManager.MEMBER_RANK));
assertEquals(RanksManager.MEMBER_RANK, ranksManager.getRankDownValue(RanksManager.OWNER_RANK));
} }
/** /**