2018-07-31 18:03:32 +02:00
|
|
|
package world.bentobox.bentobox.api.flags;
|
2018-02-20 23:06:09 +01:00
|
|
|
|
2019-01-15 20:45:49 +01:00
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
2018-02-20 23:06:09 +01:00
|
|
|
import java.util.Optional;
|
|
|
|
|
2018-02-25 17:09:46 +01:00
|
|
|
import org.bukkit.Material;
|
2018-06-04 05:54:37 +02:00
|
|
|
import org.bukkit.World;
|
2018-02-20 23:06:09 +01:00
|
|
|
import org.bukkit.event.Listener;
|
2018-02-25 17:09:46 +01:00
|
|
|
import org.bukkit.inventory.ItemStack;
|
2018-02-26 03:21:42 +01:00
|
|
|
|
2019-01-23 19:58:31 +01:00
|
|
|
import org.eclipse.jdt.annotation.NonNull;
|
2018-07-31 18:03:32 +02:00
|
|
|
import world.bentobox.bentobox.BentoBox;
|
|
|
|
import world.bentobox.bentobox.api.configuration.WorldSettings;
|
2018-12-23 16:33:10 +01:00
|
|
|
import world.bentobox.bentobox.api.flags.clicklisteners.CycleClick;
|
|
|
|
import world.bentobox.bentobox.api.flags.clicklisteners.IslandToggleClick;
|
|
|
|
import world.bentobox.bentobox.api.flags.clicklisteners.WorldToggleClick;
|
2018-07-31 18:03:32 +02:00
|
|
|
import world.bentobox.bentobox.api.localization.TextVariables;
|
|
|
|
import world.bentobox.bentobox.api.panels.PanelItem;
|
|
|
|
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
|
|
|
import world.bentobox.bentobox.api.user.User;
|
|
|
|
import world.bentobox.bentobox.database.objects.Island;
|
|
|
|
import world.bentobox.bentobox.managers.RanksManager;
|
2019-01-15 20:45:49 +01:00
|
|
|
import world.bentobox.bentobox.util.Util;
|
2018-02-20 23:06:09 +01:00
|
|
|
|
2018-02-26 04:48:01 +01:00
|
|
|
public class Flag implements Comparable<Flag> {
|
2018-02-20 23:06:09 +01:00
|
|
|
|
2019-01-23 19:58:31 +01:00
|
|
|
/**
|
|
|
|
* Defines the behavior and operation of the flag, as well as its category in the {@link world.bentobox.bentobox.panels.SettingsPanel}.
|
|
|
|
*/
|
2018-02-20 23:06:09 +01:00
|
|
|
public enum Type {
|
2019-01-23 19:58:31 +01:00
|
|
|
/**
|
|
|
|
* Flag protecting an island.
|
|
|
|
* It can be modified by the players (island owner).
|
|
|
|
* It applies differently depending on the rank of the player who performs the action protected by the flag.
|
|
|
|
*/
|
2018-06-16 17:10:00 +02:00
|
|
|
PROTECTION(Material.SHIELD),
|
2019-01-23 19:58:31 +01:00
|
|
|
/**
|
|
|
|
* Flag modifying parameters of the island.
|
|
|
|
* It can be modified by the players (island owner).
|
|
|
|
* This is usually an on/off setting.
|
|
|
|
*/
|
2018-08-01 10:18:37 +02:00
|
|
|
SETTING(Material.COMMAND_BLOCK),
|
2019-01-23 19:58:31 +01:00
|
|
|
/**
|
|
|
|
* Flag applying to the world.
|
|
|
|
* It can only be modified by administrators (permission or operator).
|
|
|
|
* This is usually an on/off setting.
|
|
|
|
*/
|
2018-08-31 21:04:24 +02:00
|
|
|
WORLD_SETTING(Material.GRASS_BLOCK);
|
2018-06-16 17:10:00 +02:00
|
|
|
|
2019-01-23 19:58:31 +01:00
|
|
|
private @NonNull Material icon;
|
2018-06-16 17:10:00 +02:00
|
|
|
|
2019-01-23 19:58:31 +01:00
|
|
|
Type(@NonNull Material icon) {
|
2018-06-16 17:10:00 +02:00
|
|
|
this.icon = icon;
|
|
|
|
}
|
|
|
|
|
2019-01-23 19:58:31 +01:00
|
|
|
@NonNull
|
2018-06-16 17:10:00 +02:00
|
|
|
public Material getIcon() {
|
|
|
|
return icon;
|
|
|
|
}
|
2018-02-20 23:06:09 +01:00
|
|
|
}
|
|
|
|
|
2018-06-24 02:06:17 +02:00
|
|
|
private static final String PROTECTION_FLAGS = "protection.flags.";
|
|
|
|
|
2018-02-20 23:06:09 +01:00
|
|
|
private final String id;
|
2018-02-25 17:09:46 +01:00
|
|
|
private final Material icon;
|
2018-02-20 23:06:09 +01:00
|
|
|
private final Listener listener;
|
|
|
|
private final Type type;
|
2018-06-04 05:54:37 +02:00
|
|
|
private boolean setting;
|
2019-01-15 20:45:49 +01:00
|
|
|
private Map<World, Boolean> defaultWorldSettings = new HashMap<>();
|
2018-04-30 10:12:32 +02:00
|
|
|
private final int defaultRank;
|
2018-05-02 07:56:10 +02:00
|
|
|
private final PanelItem.ClickHandler clickHandler;
|
2018-06-16 17:10:00 +02:00
|
|
|
private final boolean subPanel;
|
2018-02-20 23:06:09 +01:00
|
|
|
|
2018-12-23 16:33:10 +01:00
|
|
|
/**
|
2018-12-24 07:15:37 +01:00
|
|
|
* {@link Flag.Builder} should be used instead. This is only used for testing.
|
2018-12-23 16:33:10 +01:00
|
|
|
*/
|
2018-06-24 02:06:17 +02:00
|
|
|
Flag(String id, Material icon, Listener listener, Type type, int defaultRank, PanelItem.ClickHandler clickListener, boolean subPanel) {
|
2018-02-25 17:09:46 +01:00
|
|
|
this.id = id;
|
2018-02-20 23:06:09 +01:00
|
|
|
this.icon = icon;
|
|
|
|
this.listener = listener;
|
|
|
|
this.type = type;
|
2018-04-30 10:12:32 +02:00
|
|
|
this.defaultRank = defaultRank;
|
2018-05-02 07:56:10 +02:00
|
|
|
this.clickHandler = clickListener;
|
2018-06-16 17:10:00 +02:00
|
|
|
this.subPanel = subPanel;
|
2018-02-20 23:06:09 +01:00
|
|
|
}
|
|
|
|
|
2018-12-23 16:33:10 +01:00
|
|
|
private Flag(Builder builder) {
|
|
|
|
this.id = builder.id;
|
|
|
|
this.icon = builder.icon;
|
|
|
|
this.listener = builder.listener;
|
|
|
|
this.type = builder.type;
|
|
|
|
this.setting = builder.defaultSetting;
|
|
|
|
this.defaultRank = builder.defaultRank;
|
|
|
|
this.clickHandler = builder.clickHandler;
|
|
|
|
this.subPanel = builder.usePanel;
|
|
|
|
}
|
|
|
|
|
2018-02-20 23:06:09 +01:00
|
|
|
public String getID() {
|
|
|
|
return id;
|
|
|
|
}
|
|
|
|
|
2018-02-25 17:09:46 +01:00
|
|
|
public Material getIcon() {
|
2018-02-20 23:06:09 +01:00
|
|
|
return icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Optional<Listener> getListener() {
|
|
|
|
return Optional.ofNullable(listener);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-06-04 05:54:37 +02:00
|
|
|
* Check if a setting is set in this world
|
|
|
|
* @param world - world
|
2018-06-11 07:34:01 +02:00
|
|
|
* @return world setting or default flag setting if a specific world setting is not set.
|
|
|
|
* If world is not a game world, then the result will always be false!
|
2018-02-20 23:06:09 +01:00
|
|
|
*/
|
2018-06-08 17:20:16 +02:00
|
|
|
public boolean isSetForWorld(World world) {
|
2018-06-18 06:37:50 +02:00
|
|
|
if (type.equals(Type.WORLD_SETTING)) {
|
2018-07-29 22:21:46 +02:00
|
|
|
WorldSettings ws = BentoBox.getInstance().getIWM().getWorldSettings(world);
|
2018-06-18 06:37:50 +02:00
|
|
|
if (ws != null) {
|
|
|
|
ws.getWorldFlags().putIfAbsent(getID(), setting);
|
|
|
|
return ws.getWorldFlags().get(getID());
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
// Setting
|
2019-01-15 20:45:49 +01:00
|
|
|
return defaultWorldSettings.getOrDefault(Util.getWorld(world), setting);
|
2018-06-18 06:37:50 +02:00
|
|
|
}
|
2018-06-04 05:54:37 +02:00
|
|
|
}
|
2018-06-08 17:20:16 +02:00
|
|
|
|
2018-06-04 05:54:37 +02:00
|
|
|
/**
|
2018-06-10 07:09:20 +02:00
|
|
|
* Set a world setting
|
2018-06-04 05:54:37 +02:00
|
|
|
* @param world - world
|
|
|
|
* @param setting - true or false
|
|
|
|
*/
|
|
|
|
public void setSetting(World world, boolean setting) {
|
2018-06-10 07:09:20 +02:00
|
|
|
if (getType().equals(Type.WORLD_SETTING)) {
|
2018-07-29 22:21:46 +02:00
|
|
|
BentoBox.getInstance().getIWM().getWorldSettings(world).getWorldFlags().put(getID(), setting);
|
2018-06-10 07:09:20 +02:00
|
|
|
}
|
2018-02-20 23:06:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the status of this flag for locations outside of island spaces
|
|
|
|
* @param defaultSetting - true means it is allowed. false means it is not allowed
|
|
|
|
*/
|
|
|
|
public void setDefaultSetting(boolean defaultSetting) {
|
2018-06-04 05:54:37 +02:00
|
|
|
this.setting = defaultSetting;
|
2018-02-20 23:06:09 +01:00
|
|
|
}
|
|
|
|
|
2019-01-15 20:45:49 +01:00
|
|
|
/**
|
|
|
|
* Set the status of this flag for locations outside of island spaces for a specific world
|
|
|
|
* @param defaultSetting - true means it is allowed. false means it is not allowed
|
|
|
|
*/
|
|
|
|
public void setDefaultSetting(World world, boolean defaultSetting) {
|
|
|
|
this.defaultWorldSettings.put(world, defaultSetting);
|
|
|
|
}
|
|
|
|
|
2018-02-20 23:06:09 +01:00
|
|
|
/**
|
|
|
|
* @return the type
|
|
|
|
*/
|
|
|
|
public Type getType() {
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2018-04-30 10:12:32 +02:00
|
|
|
/**
|
|
|
|
* @return the defaultRank
|
|
|
|
*/
|
|
|
|
public int getDefaultRank() {
|
|
|
|
return defaultRank;
|
|
|
|
}
|
|
|
|
|
2018-06-16 17:10:00 +02:00
|
|
|
/**
|
|
|
|
* @return whether the flag uses a subpanel or not
|
|
|
|
*/
|
|
|
|
public boolean hasSubPanel() {
|
|
|
|
return subPanel;
|
|
|
|
}
|
|
|
|
|
2018-02-20 23:06:09 +01:00
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see java.lang.Object#hashCode()
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public int hashCode() {
|
|
|
|
final int prime = 31;
|
|
|
|
int result = 1;
|
|
|
|
result = prime * result + ((id == null) ? 0 : id.hashCode());
|
|
|
|
result = prime * result + ((type == null) ? 0 : type.hashCode());
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see java.lang.Object#equals(java.lang.Object)
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public boolean equals(Object obj) {
|
|
|
|
if (this == obj) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
if (obj == null) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-02-25 16:01:30 +01:00
|
|
|
if (!(obj instanceof Flag)) {
|
2018-02-20 23:06:09 +01:00
|
|
|
return false;
|
|
|
|
}
|
2018-02-25 16:01:30 +01:00
|
|
|
Flag other = (Flag) obj;
|
2018-02-20 23:06:09 +01:00
|
|
|
if (id == null) {
|
|
|
|
if (other.id != null) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
} else if (!id.equals(other.id)) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-04-25 13:48:58 +02:00
|
|
|
|
|
|
|
return type == other.type;
|
2018-02-20 23:06:09 +01:00
|
|
|
}
|
|
|
|
|
2018-06-11 15:55:01 +02:00
|
|
|
public String getNameReference() {
|
2018-06-24 02:06:17 +02:00
|
|
|
return PROTECTION_FLAGS + this.id + ".name";
|
2018-06-11 15:55:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public String getDescriptionReference() {
|
2018-06-24 02:06:17 +02:00
|
|
|
return PROTECTION_FLAGS + this.id + ".description";
|
2018-06-11 15:55:01 +02:00
|
|
|
}
|
|
|
|
|
2018-06-16 17:15:51 +02:00
|
|
|
public String getHintReference() {
|
2018-06-24 02:06:17 +02:00
|
|
|
return PROTECTION_FLAGS + this.id + ".hint";
|
2018-06-16 17:15:51 +02:00
|
|
|
}
|
|
|
|
|
2018-05-02 07:56:10 +02:00
|
|
|
/**
|
|
|
|
* Converts a flag to a panel item. The content of the flag will change depending on who the user is and where they are.
|
2018-06-11 02:23:48 +02:00
|
|
|
* @param plugin - plugin
|
2018-05-02 07:56:10 +02:00
|
|
|
* @param user - user that will see this flag
|
|
|
|
* @return - PanelItem for this flag
|
|
|
|
*/
|
2018-07-29 22:21:46 +02:00
|
|
|
public PanelItem toPanelItem(BentoBox plugin, User user) {
|
2018-06-02 20:27:51 +02:00
|
|
|
// Start the flag conversion
|
|
|
|
PanelItemBuilder pib = new PanelItemBuilder()
|
|
|
|
.icon(new ItemStack(icon))
|
2018-06-11 15:55:01 +02:00
|
|
|
.name(user.getTranslation("protection.panel.flag-item.name-layout", TextVariables.NAME, user.getTranslation(getNameReference())))
|
2018-06-02 20:27:51 +02:00
|
|
|
.clickHandler(clickHandler);
|
2018-06-16 17:10:00 +02:00
|
|
|
if (hasSubPanel()) {
|
2018-06-11 15:55:01 +02:00
|
|
|
pib.description(user.getTranslation("protection.panel.flag-item.menu-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference())));
|
2018-06-10 02:22:38 +02:00
|
|
|
return pib.build();
|
|
|
|
}
|
2018-06-08 17:20:16 +02:00
|
|
|
// Check if this is a setting or world setting
|
2018-06-10 02:22:38 +02:00
|
|
|
if (getType().equals(Type.WORLD_SETTING)) {
|
2018-06-11 00:42:21 +02:00
|
|
|
String worldDetting = this.isSetForWorld(user.getWorld()) ? user.getTranslation("protection.panel.flag-item.setting-active")
|
2018-06-04 05:54:37 +02:00
|
|
|
: user.getTranslation("protection.panel.flag-item.setting-disabled");
|
2018-06-11 15:55:01 +02:00
|
|
|
pib.description(user.getTranslation("protection.panel.flag-item.setting-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference())
|
2018-06-11 00:42:21 +02:00
|
|
|
, "[setting]", worldDetting));
|
2018-06-04 05:54:37 +02:00
|
|
|
return pib.build();
|
2018-07-29 22:21:46 +02:00
|
|
|
}
|
2018-06-02 20:27:51 +02:00
|
|
|
|
2018-05-02 07:56:10 +02:00
|
|
|
// Get the island this user is on or their own
|
2018-05-18 06:25:12 +02:00
|
|
|
Island island = plugin.getIslands().getIslandAt(user.getLocation()).orElse(plugin.getIslands().getIsland(user.getWorld(), user.getUniqueId()));
|
2018-05-02 07:56:10 +02:00
|
|
|
if (island != null) {
|
2018-06-10 02:22:38 +02:00
|
|
|
if (getType().equals(Type.SETTING)) {
|
2018-06-11 00:42:21 +02:00
|
|
|
String islandSetting = island.isAllowed(this) ? user.getTranslation("protection.panel.flag-item.setting-active")
|
2018-06-08 17:20:16 +02:00
|
|
|
: user.getTranslation("protection.panel.flag-item.setting-disabled");
|
2018-06-11 15:55:01 +02:00
|
|
|
pib.description(user.getTranslation("protection.panel.flag-item.setting-layout", TextVariables.DESCRIPTION, user.getTranslation(getDescriptionReference())
|
2018-06-11 00:42:21 +02:00
|
|
|
, "[setting]", islandSetting));
|
2018-06-08 17:20:16 +02:00
|
|
|
return pib.build();
|
|
|
|
}
|
2018-05-02 07:56:10 +02:00
|
|
|
// TODO: Get the world settings - the player has no island and is not in an island location
|
2018-06-02 20:27:51 +02:00
|
|
|
// Dynamic rank list
|
2018-06-10 02:22:38 +02:00
|
|
|
if (getType().equals(Type.PROTECTION)) {
|
2018-06-08 17:20:16 +02:00
|
|
|
// Protection flag
|
2018-06-11 15:55:01 +02:00
|
|
|
String d = user.getTranslation(getDescriptionReference());
|
|
|
|
d = user.getTranslation("protection.panel.flag-item.description-layout", TextVariables.DESCRIPTION, d);
|
2018-06-10 07:09:20 +02:00
|
|
|
pib.description(d);
|
2018-06-08 17:20:16 +02:00
|
|
|
plugin.getRanksManager().getRanks().forEach((reference, score) -> {
|
|
|
|
if (score > RanksManager.BANNED_RANK && score < island.getFlag(this)) {
|
2018-08-12 18:47:31 +02:00
|
|
|
pib.description(user.getTranslation("protection.panel.flag-item.blocked-rank") + user.getTranslation(reference));
|
2018-06-08 17:20:16 +02:00
|
|
|
} else if (score <= RanksManager.OWNER_RANK && score > island.getFlag(this)) {
|
2018-08-12 18:47:31 +02:00
|
|
|
pib.description(user.getTranslation("protection.panel.flag-item.allowed-rank") + user.getTranslation(reference));
|
2018-06-08 17:20:16 +02:00
|
|
|
} else if (score == island.getFlag(this)) {
|
2018-08-12 18:47:31 +02:00
|
|
|
pib.description(user.getTranslation("protection.panel.flag-item.minimal-rank") + user.getTranslation(reference));
|
2018-06-08 17:20:16 +02:00
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
2018-05-02 07:56:10 +02:00
|
|
|
}
|
2018-06-02 20:27:51 +02:00
|
|
|
return pib.build();
|
2018-02-25 17:09:46 +01:00
|
|
|
}
|
2018-06-02 20:27:51 +02:00
|
|
|
|
2018-02-26 04:48:01 +01:00
|
|
|
|
|
|
|
/* (non-Javadoc)
|
|
|
|
* @see java.lang.Object#toString()
|
|
|
|
*/
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
2018-05-02 07:56:10 +02:00
|
|
|
return "Flag [id=" + id + ", icon=" + icon + ", listener=" + listener + ", type=" + type + ", defaultSetting="
|
2018-06-16 17:10:00 +02:00
|
|
|
+ setting + ", defaultRank=" + defaultRank + ", clickHandler=" + clickHandler + ", subPanel=" + subPanel + "]";
|
2018-02-26 04:48:01 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public int compareTo(Flag o) {
|
|
|
|
return getID().compareTo(o.getID());
|
|
|
|
}
|
2018-12-23 16:33:10 +01:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @author tastybento, Poslovitch
|
|
|
|
*/
|
|
|
|
public static class Builder {
|
|
|
|
// Mandatory fields
|
|
|
|
private String id;
|
|
|
|
private Material icon;
|
|
|
|
|
|
|
|
// Listener
|
|
|
|
private Listener listener;
|
|
|
|
|
|
|
|
// Type - is defaulted to PROTECTION
|
|
|
|
private Type type = Type.PROTECTION;
|
|
|
|
|
|
|
|
// Default settings
|
2018-12-27 11:24:53 +01:00
|
|
|
private boolean defaultSetting = false;
|
2018-12-24 07:15:37 +01:00
|
|
|
private int defaultRank = RanksManager.MEMBER_RANK;
|
2018-12-23 16:33:10 +01:00
|
|
|
|
|
|
|
// ClickHandler - default depends on the type
|
|
|
|
private PanelItem.ClickHandler clickHandler;
|
|
|
|
|
|
|
|
// Whether there is a sub-panel or not
|
|
|
|
private boolean usePanel = false;
|
|
|
|
|
|
|
|
public Builder(String id, Material icon) {
|
|
|
|
this.id = id;
|
|
|
|
this.icon = icon;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Builder listener(Listener listener) {
|
|
|
|
this.listener = listener;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Builder type(Type type) {
|
|
|
|
this.type = type;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Builder clickHandler(PanelItem.ClickHandler clickHandler) {
|
|
|
|
this.clickHandler = clickHandler;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Builder defaultSetting(boolean defaultSetting) {
|
|
|
|
this.defaultSetting = defaultSetting;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Builder defaultRank(int defaultRank) {
|
|
|
|
this.defaultRank = defaultRank;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
2018-12-23 16:39:31 +01:00
|
|
|
public Builder usePanel(boolean usePanel) {
|
2018-12-23 16:33:10 +01:00
|
|
|
this.usePanel = usePanel;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public Flag build() {
|
|
|
|
// If no clickHandler has been set, then apply default ones
|
|
|
|
if (clickHandler == null) {
|
|
|
|
switch (type){
|
2018-12-24 07:15:37 +01:00
|
|
|
case PROTECTION:
|
|
|
|
clickHandler = new CycleClick(id);
|
|
|
|
break;
|
|
|
|
case SETTING:
|
|
|
|
clickHandler = new IslandToggleClick(id);
|
|
|
|
break;
|
|
|
|
case WORLD_SETTING:
|
|
|
|
clickHandler = new WorldToggleClick(id);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
clickHandler = new CycleClick(id);
|
|
|
|
break;
|
2018-12-23 16:33:10 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return new Flag(this);
|
|
|
|
}
|
|
|
|
}
|
2018-02-20 23:06:09 +01:00
|
|
|
}
|