Limits/src/main/java/bentobox/addon/limits/listeners/JoinListener.java

175 lines
6.8 KiB
Java

package bentobox.addon.limits.listeners;
import java.util.Locale;
import java.util.UUID;
import org.apache.commons.lang.math.NumberUtils;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.World;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.permissions.PermissionAttachmentInfo;
import bentobox.addon.limits.Limits;
import bentobox.addon.limits.Settings;
import bentobox.addon.limits.commands.LimitPanel;
import bentobox.addon.limits.objects.IslandBlockCount;
import world.bentobox.bentobox.api.events.island.IslandEvent;
import world.bentobox.bentobox.api.events.island.IslandEvent.Reason;
import world.bentobox.bentobox.api.events.team.TeamEvent.TeamSetownerEvent;
import world.bentobox.bentobox.database.objects.Island;
/**
* Sets block limits based on player permission
* @author tastybento
*
*/
public class JoinListener implements Listener {
private final Limits addon;
public JoinListener(Limits addon) {
this.addon = addon;
}
private void checkPerms(Player player, String permissionPrefix, String islandId, String gameMode) {
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
if (ibc == null) {
ibc = new IslandBlockCount(islandId, gameMode);
}
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
if (perms.getPermission().startsWith(permissionPrefix)) {
// No wildcards
if (perms.getPermission().contains(permissionPrefix + "*")) {
logError(player.getName(), perms.getPermission(), "Wildcards are not allowed.");
return;
}
// Get the Material
String[] split = perms.getPermission().split("\\.");
if (split.length != 5) {
logError(player.getName(), perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL/ENTITY-TYPE.NUMBER'");
return;
}
// Get the value
if (!NumberUtils.isDigits(split[4])) {
logError(player.getName(), perms.getPermission(), "the last part MUST be a number!");
return;
}
try {
int limit = Integer.valueOf(split[4]);
String key = split[3].toUpperCase(Locale.ENGLISH);
Material m = Material.getMaterial(key);
if (m == null) {
EntityType type = Settings.getType(key);
if (type != null) {
if (!type.equals(EntityType.PAINTING) &&
!type.equals(EntityType.ITEM_FRAME) &&
(!type.isSpawnable() || (LimitPanel.E2M.containsKey(type) && LimitPanel.E2M.get(type) == null))) {
addon.logError("Entity type: " + key + " is not supported - skipping...");
} else {
ibc.setEntityLimit(type, Math.max(ibc.getEntityLimit(type), limit));
return;
}
} else {
logError(player.getName(), perms.getPermission(), split[3].toUpperCase(Locale.ENGLISH) + " is not a valid material or entity type.");
return;
}
}
// Set the limit
ibc.setBlockLimit(m, Math.max(ibc.getBlockLimit(m), limit));
} catch (Exception e) {
logError(player.getName(), perms.getPermission(), "the last part MUST be a number!");
return;
}
}
}
// If any changes have been made then store it
if (ibc != null) {
addon.getBlockLimitListener().setIsland(islandId, ibc);
}
}
private void logError(String name, String perm, String error) {
addon.logError("Player " + name + " has permission: '" + perm + "' but " + error + " Ignoring...");
}
/*
* Event handling
*/
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onNewIsland(IslandEvent e) {
if (!e.getReason().equals(Reason.CREATED)
&& !e.getReason().equals(Reason.RESETTED)
&& !e.getReason().equals(Reason.REGISTERED)) {
return;
}
setOwnerPerms(e.getIsland(), e.getOwner());
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onOwnerChange(TeamSetownerEvent e) {
removeOwnerPerms(e.getIsland());
setOwnerPerms(e.getIsland(), e.getNewOwner());
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onPlayerJoin(PlayerJoinEvent e) {
// Check if player has any islands in the game modes
addon.getGameModes().forEach(gm -> {
if (addon.getIslands().hasIsland(gm.getOverWorld(), e.getPlayer().getUniqueId())) {
String islandId = addon.getIslands().getIsland(gm.getOverWorld(), e.getPlayer().getUniqueId()).getUniqueId();
checkPerms(e.getPlayer(), gm.getPermissionPrefix() + "island.limit.", islandId, gm.getDescription().getName());
}
});
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onUnregisterIsland(IslandEvent e) {
if (!e.getReason().equals(Reason.UNREGISTERED)) {
return;
}
removeOwnerPerms(e.getIsland());
}
/*
* Utility methods
*/
private void removeOwnerPerms(Island island) {
World world = island.getWorld();
if (addon.inGameModeWorld(world)) {
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(island.getUniqueId());
if (ibc != null) {
ibc.getBlockLimits().clear();
}
}
}
private void setOwnerPerms(Island island, UUID ownerUUID) {
World world = island.getWorld();
if (addon.inGameModeWorld(world)) {
// Check if owner is online
OfflinePlayer owner = Bukkit.getOfflinePlayer(ownerUUID);
if (owner.isOnline()) {
// Set perm-based limits
String prefix = addon.getGameModePermPrefix(world);
String name = addon.getGameModeName(world);
if (!prefix.isEmpty() && !name.isEmpty()) {
checkPerms(owner.getPlayer(), prefix + "island.limit.", island.getUniqueId(), name);
}
}
}
}
}