Make island owner the setter of limits

This commit is contained in:
tastybento 2024-10-05 01:10:08 -07:00
parent 923ce3ad17
commit e317f27869
3 changed files with 190 additions and 169 deletions

View File

@ -1,10 +1,12 @@
package world.bentobox.limits.commands.player;
import java.util.List;
import java.util.Optional;
import world.bentobox.bentobox.api.addons.GameModeAddon;
import world.bentobox.bentobox.api.commands.CompositeCommand;
import world.bentobox.bentobox.api.user.User;
import world.bentobox.bentobox.database.objects.Island;
import world.bentobox.limits.Limits;
/**
@ -46,7 +48,22 @@ public class PlayerCommand extends CompositeCommand {
showHelp(this, user);
return false;
} else {
new LimitPanel(addon).showLimits((GameModeAddon)getAddon(), user, user.getUniqueId());
// Report the limit for the island, which is governed by the owner of the island
Optional<Island> opIsland = getIslands().getIslandAt(user.getLocation());
if (opIsland.isEmpty()) {
user.sendMessage("general.errors.no-island");
return false;
}
Island island = opIsland.get();
if (!island.getWorld().equals(getWorld())) {
user.sendMessage("general.errors.wrong-world");
return false;
}
if (island.getOwner() == null) {
user.sendMessage("general.errors.no-owner");
return false;
}
new LimitPanel(addon).showLimits((GameModeAddon) getAddon(), user, island.getOwner());
return true;
}
}

View File

@ -39,7 +39,7 @@ public class JoinListener implements Listener {
private final Limits addon;
public JoinListener(Limits addon) {
this.addon = addon;
this.addon = addon;
}
/**
@ -52,126 +52,126 @@ public class JoinListener implements Listener {
* @param gameMode - game mode string doing the checking
*/
public void checkPerms(Player player, String permissionPrefix, String islandId, String gameMode) {
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
// Check permissions
if (ibc != null) {
// Clear permission limits
ibc.getEntityLimits().clear();
ibc.getEntityGroupLimits().clear();
ibc.getBlockLimits().clear();
}
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
if (!perms.getValue() || !perms.getPermission().startsWith(permissionPrefix)
|| badSyntaxCheck(perms, player.getName(), permissionPrefix)) {
continue;
}
// Check formatting
String[] split = perms.getPermission().split("\\.");
// Entities & materials
EntityType et = Arrays.stream(EntityType.values()).filter(t -> t.name().equalsIgnoreCase(split[3]))
.findFirst().orElse(null);
Material m = Arrays.stream(Material.values()).filter(t -> t.name().equalsIgnoreCase(split[3])).findFirst()
.orElse(null);
EntityGroup entgroup = addon.getSettings().getGroupLimitDefinitions().stream()
.filter(t -> t.getName().equalsIgnoreCase(split[3])).findFirst().orElse(null);
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
// Check permissions
if (ibc != null) {
// Clear permission limits
ibc.getEntityLimits().clear();
ibc.getEntityGroupLimits().clear();
ibc.getBlockLimits().clear();
}
for (PermissionAttachmentInfo perms : player.getEffectivePermissions()) {
if (!perms.getValue() || !perms.getPermission().startsWith(permissionPrefix)
|| badSyntaxCheck(perms, player.getName(), permissionPrefix)) {
continue;
}
// Check formatting
String[] split = perms.getPermission().split("\\.");
// Entities & materials
EntityType et = Arrays.stream(EntityType.values()).filter(t -> t.name().equalsIgnoreCase(split[3]))
.findFirst().orElse(null);
Material m = Arrays.stream(Material.values()).filter(t -> t.name().equalsIgnoreCase(split[3])).findFirst()
.orElse(null);
EntityGroup entgroup = addon.getSettings().getGroupLimitDefinitions().stream()
.filter(t -> t.getName().equalsIgnoreCase(split[3])).findFirst().orElse(null);
if (entgroup == null && et == null && m == null) {
logError(player.getName(), perms.getPermission(),
split[3].toUpperCase(Locale.ENGLISH) + " is not a valid material or entity type/group.");
break;
}
// Make an ibc if required
if (ibc == null) {
ibc = new IslandBlockCount(islandId, gameMode);
}
// Get the value
int value = Integer.parseInt(split[4]);
addon.log("Setting login limit via perm for " + player.getName() + "...");
if (entgroup == null && et == null && m == null) {
logError(player.getName(), perms.getPermission(),
split[3].toUpperCase(Locale.ENGLISH) + " is not a valid material or entity type/group.");
break;
}
// Make an ibc if required
if (ibc == null) {
ibc = new IslandBlockCount(islandId, gameMode);
}
// Get the value
int value = Integer.parseInt(split[4]);
addon.log("Setting login limit via perm for " + player.getName() + "...");
// Fire perm check event
LimitsPermCheckEvent l = new LimitsPermCheckEvent(player, islandId, ibc, entgroup, et, m, value);
Bukkit.getPluginManager().callEvent(l);
if (l.isCancelled()) {
addon.log("Permissions not set because another addon/plugin canceled setting.");
continue;
}
// Use event values
ibc = l.getIbc();
// Make an ibc if required
if (ibc == null) {
ibc = new IslandBlockCount(islandId, gameMode);
}
// Run null checks and set ibc
runNullCheckAndSet(ibc, l);
}
// Check removed permissions
// If any changes have been made then store it - don't make files unless they
// are needed
if (ibc != null)
addon.getBlockLimitListener().setIsland(islandId, ibc);
// Fire perm check event
LimitsPermCheckEvent l = new LimitsPermCheckEvent(player, islandId, ibc, entgroup, et, m, value);
Bukkit.getPluginManager().callEvent(l);
if (l.isCancelled()) {
addon.log("Permissions not set because another addon/plugin canceled setting.");
continue;
}
// Use event values
ibc = l.getIbc();
// Make an ibc if required
if (ibc == null) {
ibc = new IslandBlockCount(islandId, gameMode);
}
// Run null checks and set ibc
runNullCheckAndSet(ibc, l);
}
// Check removed permissions
// If any changes have been made then store it - don't make files unless they
// are needed
if (ibc != null)
addon.getBlockLimitListener().setIsland(islandId, ibc);
}
private boolean badSyntaxCheck(PermissionAttachmentInfo perms, String name, String permissionPrefix) {
// No wildcards
if (perms.getPermission().contains(permissionPrefix + "*")) {
logError(name, perms.getPermission(), "wildcards are not allowed.");
return true;
}
// Check formatting
String[] split = perms.getPermission().split("\\.");
if (split.length != 5) {
logError(name, perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL.NUMBER', '"
+ permissionPrefix + "ENTITY-TYPE.NUMBER', or '" + permissionPrefix + "ENTITY-GROUP.NUMBER'");
return true;
}
// Check value
try {
Integer.parseInt(split[4]);
} catch (Exception e) {
logError(name, perms.getPermission(), "the last part MUST be an integer!");
return true;
}
return false;
// No wildcards
if (perms.getPermission().contains(permissionPrefix + "*")) {
logError(name, perms.getPermission(), "wildcards are not allowed.");
return true;
}
// Check formatting
String[] split = perms.getPermission().split("\\.");
if (split.length != 5) {
logError(name, perms.getPermission(), "format must be '" + permissionPrefix + "MATERIAL.NUMBER', '"
+ permissionPrefix + "ENTITY-TYPE.NUMBER', or '" + permissionPrefix + "ENTITY-GROUP.NUMBER'");
return true;
}
// Check value
try {
Integer.parseInt(split[4]);
} catch (Exception e) {
logError(name, perms.getPermission(), "the last part MUST be an integer!");
return true;
}
return false;
}
private void runNullCheckAndSet(@NonNull IslandBlockCount ibc, @NonNull LimitsPermCheckEvent l) {
EntityGroup entgroup = l.getEntityGroup();
EntityType et = l.getEntityType();
Material m = l.getMaterial();
int value = l.getValue();
if (entgroup != null) {
// Entity group limit
int v = Math.max(ibc.getEntityGroupLimit(entgroup.getName()), value);
ibc.setEntityGroupLimit(entgroup.getName(), v);
addon.log("Setting group limit " + entgroup.getName() + " " + v);
} else if (et != null && m == null) {
// Entity limit
int v = Math.max(ibc.getEntityLimit(et), value);
ibc.setEntityLimit(et, v);
addon.log("Setting entity limit " + et + " " + v);
} else if (m != null && et == null) {
// Block limit
int v = Math.max(ibc.getBlockLimit(m), value);
addon.log("Setting block limit " + m + " " + v);
ibc.setBlockLimit(m, v);
} else {
if (m != null && m.isBlock()) {
int v = Math.max(ibc.getBlockLimit(m), value);
addon.log("Setting block limit " + m + " " + v);
// Material limit
ibc.setBlockLimit(m, v);
} else if (et != null) {
int v = Math.max(ibc.getEntityLimit(et), value);
addon.log("Setting entity limit " + et + " " + v);
// This is an entity setting
ibc.setEntityLimit(et, v);
}
}
EntityGroup entgroup = l.getEntityGroup();
EntityType et = l.getEntityType();
Material m = l.getMaterial();
int value = l.getValue();
if (entgroup != null) {
// Entity group limit
int v = Math.max(ibc.getEntityGroupLimit(entgroup.getName()), value);
ibc.setEntityGroupLimit(entgroup.getName(), v);
addon.log("Setting group limit " + entgroup.getName() + " " + v);
} else if (et != null && m == null) {
// Entity limit
int v = Math.max(ibc.getEntityLimit(et), value);
ibc.setEntityLimit(et, v);
addon.log("Setting entity limit " + et + " " + v);
} else if (m != null && et == null) {
// Block limit
int v = Math.max(ibc.getBlockLimit(m), value);
addon.log("Setting block limit " + m + " " + v);
ibc.setBlockLimit(m, v);
} else {
if (m != null && m.isBlock()) {
int v = Math.max(ibc.getBlockLimit(m), value);
addon.log("Setting block limit " + m + " " + v);
// Material limit
ibc.setBlockLimit(m, v);
} else if (et != null) {
int v = Math.max(ibc.getEntityLimit(et), value);
addon.log("Setting entity limit " + et + " " + v);
// This is an entity setting
ibc.setEntityLimit(et, v);
}
}
}
private void logError(String name, String perm, String error) {
addon.logError("Player " + name + " has permission: '" + perm + "' but " + error + " Ignoring...");
addon.logError("Player " + name + " has permission: '" + perm + "' but " + error + " Ignoring...");
}
/*
@ -180,32 +180,33 @@ public class JoinListener implements Listener {
@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());
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());
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 -> {
addon.getIslands().getIslands(gm.getOverWorld(), e.getPlayer().getUniqueId()).stream()
.map(Island::getUniqueId).forEach(islandId -> {
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
if (!joinEventCheck(e.getPlayer(), islandId, ibc)) {
checkPerms(e.getPlayer(), gm.getPermissionPrefix() + "island.limit.", islandId,
gm.getDescription().getName());
}
});
});
// Check if player has any islands in the game modes
addon.getGameModes().forEach(gm -> {
addon.getIslands().getIslands(gm.getOverWorld(), e.getPlayer().getUniqueId()).stream()
.filter(island -> e.getPlayer().getUniqueId().equals(island.getOwner()))
.map(Island::getUniqueId).forEach(islandId -> {
IslandBlockCount ibc = addon.getBlockLimitListener().getIsland(islandId);
if (!joinEventCheck(e.getPlayer(), islandId, ibc)) {
checkPerms(e.getPlayer(), gm.getPermissionPrefix() + "island.limit.", islandId,
gm.getDescription().getName());
}
});
});
}
/**
@ -217,29 +218,29 @@ public class JoinListener implements Listener {
* @return true if canceled
*/
private boolean joinEventCheck(Player player, String islandId, IslandBlockCount ibc) {
// Fire event, so other addons can cancel this permissions change
LimitsJoinPermCheckEvent e = new LimitsJoinPermCheckEvent(player, islandId, ibc);
Bukkit.getPluginManager().callEvent(e);
if (e.isCancelled()) {
return true;
}
// Get ibc from event if it has changed
ibc = e.getIbc();
// If perms should be ignored, but the IBC given in the event used, then set it
// and return
if (e.isIgnorePerms() && ibc != null) {
addon.getBlockLimitListener().setIsland(islandId, ibc);
return true;
}
return false;
// Fire event, so other addons can cancel this permissions change
LimitsJoinPermCheckEvent e = new LimitsJoinPermCheckEvent(player, islandId, ibc);
Bukkit.getPluginManager().callEvent(e);
if (e.isCancelled()) {
return true;
}
// Get ibc from event if it has changed
ibc = e.getIbc();
// If perms should be ignored, but the IBC given in the event used, then set it
// and return
if (e.isIgnorePerms() && ibc != null) {
addon.getBlockLimitListener().setIsland(islandId, ibc);
return true;
}
return false;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onUnregisterIsland(IslandEvent e) {
if (!e.getReason().equals(Reason.UNREGISTERED)) {
return;
}
removeOwnerPerms(e.getIsland());
if (!e.getReason().equals(Reason.UNREGISTERED)) {
return;
}
removeOwnerPerms(e.getIsland());
}
/*
@ -247,30 +248,30 @@ public class JoinListener implements Listener {
*/
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();
}
}
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() && owner.getPlayer() != null) {
checkPerms(Objects.requireNonNull(owner.getPlayer()), prefix + "island.limit.",
island.getUniqueId(), name);
}
}
}
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() && owner.getPlayer() != null) {
checkPerms(Objects.requireNonNull(owner.getPlayer()), prefix + "island.limit.",
island.getUniqueId(), name);
}
}
}
}
}

View File

@ -25,6 +25,7 @@ import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerJoinEvent;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.PluginManager;
import org.eclipse.jdt.annotation.Nullable;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -76,6 +77,7 @@ public class JoinListenerTest {
private Island island;
@Mock
private PluginManager pim;
private @Nullable UUID uuid = UUID.randomUUID();
@Before
public void setUp() {
@ -90,12 +92,13 @@ public class JoinListenerTest {
.thenReturn(new ArrayList<>(List.of(new Settings.EntityGroup("friendly", new HashSet<>(), -1))));
// Island Manager
when(island.getUniqueId()).thenReturn("unique_id");
when(island.getOwner()).thenReturn(uuid);
when(im.getIsland(any(), any(UUID.class))).thenReturn(island);
when(im.getIslands(any(), any(UUID.class))).thenReturn(List.of(island));
// Default is that player has island
when(addon.getIslands()).thenReturn(im);
// Player
when(player.getUniqueId()).thenReturn(UUID.randomUUID());
when(player.getUniqueId()).thenReturn(uuid);
when(player.getName()).thenReturn("tastybento");
// No permissions by default
when(player.getEffectivePermissions()).thenReturn(Collections.emptySet());