203 lines
6.4 KiB
Java
203 lines
6.4 KiB
Java
package us.tastybento.bskyblock.api.flags;
|
|
|
|
import java.lang.reflect.Method;
|
|
import java.util.Optional;
|
|
|
|
import org.bukkit.Location;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.event.Cancellable;
|
|
import org.bukkit.event.Event;
|
|
import org.bukkit.event.Listener;
|
|
|
|
import us.tastybento.bskyblock.BSkyBlock;
|
|
import us.tastybento.bskyblock.api.localization.TextVariables;
|
|
import us.tastybento.bskyblock.api.user.User;
|
|
import us.tastybento.bskyblock.database.objects.Island;
|
|
import us.tastybento.bskyblock.managers.IslandWorldManager;
|
|
import us.tastybento.bskyblock.managers.IslandsManager;
|
|
|
|
/**
|
|
* Abstract class for flag listeners. Provides common code.
|
|
* @author tastybento
|
|
*
|
|
*/
|
|
public abstract class AbstractFlagListener implements Listener {
|
|
|
|
private BSkyBlock plugin = BSkyBlock.getInstance();
|
|
private User user = null;
|
|
|
|
/**
|
|
* @return the plugin
|
|
*/
|
|
public BSkyBlock getPlugin() {
|
|
return plugin;
|
|
}
|
|
|
|
/**
|
|
* Used for unit testing only to set the plugin
|
|
* @param plugin - BSkyBlock plugin object
|
|
*/
|
|
public void setPlugin(BSkyBlock plugin) {
|
|
this.plugin = plugin;
|
|
}
|
|
|
|
/**
|
|
* Sets the player associated with this event.
|
|
* If the user is a fake player, they are not counted.
|
|
* @param e - event
|
|
* @return true if found, otherwise false
|
|
*/
|
|
private boolean createEventUser(Event e) {
|
|
try {
|
|
// Use reflection to get the getPlayer method if it exists
|
|
Method getPlayer = e.getClass().getMethod("getPlayer");
|
|
if (getPlayer != null) {
|
|
setUser(User.getInstance((Player)getPlayer.invoke(e)));
|
|
return true;
|
|
}
|
|
} catch (Exception e1) { // Do nothing
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Explicitly set the user for the next {@link #checkIsland(Event, Location, Flag)} or {@link #checkIsland(Event, Location, Flag, boolean)}
|
|
* @param user - the User
|
|
*/
|
|
public AbstractFlagListener setUser(User user) {
|
|
if (!plugin.getSettings().getFakePlayers().contains(user.getName())) {
|
|
this.user = user;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
/*
|
|
* The following methods cover the cancellable events and enable a simple noGo(e) to be used to cancel and send the error message
|
|
*/
|
|
|
|
/**
|
|
* Cancels the event and sends the island public message to user
|
|
* @param e - event
|
|
* @param flag - the flag that has been checked
|
|
*/
|
|
public void noGo(Event e, Flag flag) {
|
|
noGo(e, flag, false);
|
|
}
|
|
|
|
/**
|
|
* Cancels the event and sends the island protected message to user unless silent is true
|
|
* @param e - event
|
|
* @param flag - the flag that has been checked
|
|
* @param silent - if true, message is not sent
|
|
*/
|
|
public void noGo(Event e, Flag flag, boolean silent) {
|
|
if (e instanceof Cancellable) {
|
|
((Cancellable)e).setCancelled(true);
|
|
}
|
|
if (user != null) {
|
|
if (!silent) {
|
|
user.notify("protection.protected", TextVariables.DESCRIPTION, user.getTranslation(flag.getHintReference()));
|
|
}
|
|
user.updateInventory();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check if flag is allowed at location
|
|
* @param e - event
|
|
* @param loc - location
|
|
* @param flag - flag {@link us.tastybento.bskyblock.lists.Flags}
|
|
* @return true if allowed, false if not
|
|
*/
|
|
public boolean checkIsland(Event e, Location loc, Flag flag) {
|
|
return checkIsland(e, loc, flag, false);
|
|
}
|
|
|
|
/**
|
|
* Check if flag is allowed at location
|
|
* @param e - event
|
|
* @param loc - location
|
|
* @param flag - flag {@link us.tastybento.bskyblock.lists.Flags}
|
|
* @param silent - if true, no attempt is made to tell the user
|
|
* @return true if the check is okay, false if it was disallowed
|
|
*/
|
|
public boolean checkIsland(Event e, Location loc, Flag flag, boolean silent) {
|
|
// If this is not an Island World, skip
|
|
if (!plugin.getIWM().inWorld(loc)) {
|
|
return true;
|
|
}
|
|
// Get the island and if present
|
|
Optional<Island> island = getIslands().getProtectedIslandAt(loc);
|
|
// Handle Settings Flag
|
|
if (flag.getType().equals(Flag.Type.SETTING)) {
|
|
// If the island exists, return the setting, otherwise return the default setting for this flag
|
|
return island.map(x -> x.isAllowed(flag)).orElse(flag.isSetForWorld(loc.getWorld()));
|
|
}
|
|
|
|
// Protection flag
|
|
// If the user is not set already, try to get it from the event
|
|
// Set the user associated with this event
|
|
// The user is not set, and the event does not hold a getPlayer, so return false
|
|
// TODO: is this the correct handling here?
|
|
if (user == null && !createEventUser(e)) {
|
|
plugin.logError("Check island had no associated user! " + e.getEventName());
|
|
return false;
|
|
}
|
|
|
|
// Ops or bypass mods can do anything
|
|
if (user.isOp() || user.hasPermission(getIWM().getPermissionPrefix(loc.getWorld()) + ".mod.bypassprotect")) {
|
|
user = null;
|
|
return true;
|
|
}
|
|
|
|
// Check if the plugin is set in User (required for testing)
|
|
User.setPlugin(plugin);
|
|
|
|
if (island.isPresent()) {
|
|
if (!island.get().isAllowed(user, flag)) {
|
|
noGo(e, flag, silent);
|
|
// Clear the user for the next time
|
|
user = null;
|
|
return false;
|
|
} else {
|
|
user = null;
|
|
return true;
|
|
}
|
|
}
|
|
// The player is in the world, but not on an island, so general world settings apply
|
|
if (!flag.isSetForWorld(loc.getWorld())) {
|
|
noGo(e, flag, silent);
|
|
user = null;
|
|
return false;
|
|
} else {
|
|
user = null;
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Get the flag for this ID
|
|
* @param id - the flag ID
|
|
* @return Flag denoted by the id
|
|
*/
|
|
protected Flag id(String id) {
|
|
return plugin.getFlagsManager().getFlagByID(id);
|
|
}
|
|
|
|
/**
|
|
* Get the island database manager
|
|
* @return the island database manager
|
|
*/
|
|
protected IslandsManager getIslands() {
|
|
return plugin.getIslands();
|
|
}
|
|
|
|
/**
|
|
* Get the island world manager
|
|
* @return Island World Manager
|
|
*/
|
|
protected IslandWorldManager getIWM() {
|
|
return plugin.getIWM();
|
|
}
|
|
}
|