diff --git a/api/src/main/java/com/lishid/openinv/util/Permissions.java b/api/src/main/java/com/lishid/openinv/util/Permissions.java new file mode 100644 index 00000000..e8940332 --- /dev/null +++ b/api/src/main/java/com/lishid/openinv/util/Permissions.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2011-2022 lishid. All rights reserved. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.lishid.openinv.util; + +import org.bukkit.permissions.Permissible; +import org.jetbrains.annotations.NotNull; + +/** + * An enum containing all permissions directly checked by OpenInv. + * + *

Note that this is not an exhaustive list! This does not contain + * all permissions managed by Bukkit, largely parent nodes.

+ */ +public enum Permissions { + + /// Permission to open one's own inventory. + INVENTORY_OPEN_SELF("inventory.open.self"), + /// Permission to open someone else's inventory. + INVENTORY_OPEN_OTHER("inventory.open.other"), + /** + * Permission to edit one's own inventory. + * + *

Note that this does not guarantee that the user has access to open the inventory! + * Be sure to check {@link #INVENTORY_OPEN_SELF} first.

+ */ + INVENTORY_EDIT_SELF("inventory.edit.self"), + /** + * Permission to edit someone else's inventory. + * + *

Note that this does not guarantee that the user has access to open the inventory! + * Be sure to check {@link #INVENTORY_OPEN_OTHER} first.

+ */ + INVENTORY_EDIT_OTHER("inventory.edit.other"), + /// Permission to insert any item into the head slot. + INVENTORY_SLOT_HEAD_ANY("inventory.slot.head.any"), + /// Permission to insert any item into the chest slot. + INVENTORY_SLOT_CHEST_ANY("inventory.slot.chest.any"), + /// Permission to insert any item into the legs slot. + INVENTORY_SLOT_LEGS_ANY("inventory.slot.legs.any"), + /// Permission to insert any item into the feet slot. + INVENTORY_SLOT_FEET_ANY("inventory.slot.feet.any"), + /// Permission to drop items as the player via the drop slot. + INVENTORY_SLOT_DROP("inventory.slot.drop"), + + /// Permission to open one's own ender chest. + ENDERCHEST_OPEN_SELF("enderchest.open.self"), + /// Permission to open someone else's ender chest. + ENDERCHEST_OPEN_OTHER("enderchest.open.other"), + /** + * Permission to edit one's own ender chest. + * + *

Note that this does not guarantee that the user has access to open the inventory! + * Be sure to check {@link #ENDERCHEST_OPEN_SELF} first.

+ */ + ENDERCHEST_EDIT_SELF("enderchest.edit.self"), + /** + * Permission to edit someone else's ender chest. + * + *

Note that this does not guarantee that the user has access to open the inventory! + * Be sure to check {@link #ENDERCHEST_OPEN_OTHER} first.

+ */ + ENDERCHEST_EDIT_OTHER("enderchest.edit.other"), + + /// Permission to clear one's own inventory. + CLEAR_SELF("clear.self"), + /// Permission to clear someone else's inventory. + CLEAR_OTHER("clear.other"), + + /// Permission to view inventories and ender chests from other worlds. + ACCESS_CROSSWORLD("access.crossworld"), + /// Permission to access offline players' inventories and ender chests. + ACCESS_OFFLINE("access.offline"), + /// Permission to access online players' inventories and ender chests. + ACCESS_ONLINE("access.online"), + /// Permission granting the ability to edit players with the same access level. + ACCESS_EQUAL_EDIT("access.equal.edit"), + /// Permission to view, but not edit, players with the same access level. + ACCESS_EQUAL_VIEW("access.equal.view"), + /// Permission to deny access to players with the same access level. + ACCESS_EQUAL_DENY("access.equal.deny"), + + /// Permission to perform inventory interaction while in spectator mode. + SPECTATE_CLICK("spectate.click"), + + /// Permission to use the AnyContainer feature. + CONTAINER_ANY("container.any"), + /// Permission to use the AnyContainer feature but not the command to toggle it. + CONTAINER_ANY_USE("container.any.use"), + /// Permission to use the SilentContainer feature. + CONTAINER_SILENT("container.silent"), + /// Permission to use the SilentContainer feature but not the command to toggle it. + CONTAINER_SILENT_USE("container.silent.use"), + /// Permission to search inventories and ender chests. + SEARCH_INVENTORY("search.inventory"), + /// Permission to search containers. + SEARCH_CONTAINER("search.container"); + + private final String permission; + + Permissions(String permission) { + this.permission = "openinv." + permission; + } + + /** + * Check if a {@link Permissible} has this permission. + * + * @param permissible the Permissible + * @return true if the permission is granted + */ + public boolean hasPermission(@NotNull Permissible permissible) { + return permissible.hasPermission(permission); + } + +} diff --git a/api/src/main/java/com/lishid/openinv/util/setting/PlayerToggle.java b/api/src/main/java/com/lishid/openinv/util/setting/PlayerToggle.java index 6e8dc880..b4976eea 100644 --- a/api/src/main/java/com/lishid/openinv/util/setting/PlayerToggle.java +++ b/api/src/main/java/com/lishid/openinv/util/setting/PlayerToggle.java @@ -1,5 +1,6 @@ package com.lishid.openinv.util.setting; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import java.util.UUID; @@ -24,6 +25,15 @@ public interface PlayerToggle { */ boolean is(@NotNull UUID uuid); + /** + * Get the state of the toggle for a particular {@link Player}, + * accounting for permissions required to use the feature. + * + * @param player the player + * @return true if the setting is enabled and the player has the required permissions + */ + boolean is(@NotNull Player player); + /** * Set the state of the toggle for a particular player ID. * diff --git a/api/src/main/java/com/lishid/openinv/util/setting/PlayerToggles.java b/api/src/main/java/com/lishid/openinv/util/setting/PlayerToggles.java index d61cd115..e6d2f5fa 100644 --- a/api/src/main/java/com/lishid/openinv/util/setting/PlayerToggles.java +++ b/api/src/main/java/com/lishid/openinv/util/setting/PlayerToggles.java @@ -1,5 +1,7 @@ package com.lishid.openinv.util.setting; +import com.lishid.openinv.util.Permissions; +import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.UnmodifiableView; @@ -19,8 +21,20 @@ public final class PlayerToggles { private static final Map TOGGLES = new HashMap<>(); - private static final PlayerToggle ANY = add(new MemoryToggle("AnyContainer")); - private static final PlayerToggle SILENT = add(new MemoryToggle("SilentContainer")); + private static final PlayerToggle ANY = add(new MemoryToggle("AnyContainer") { + @Override + public boolean is(@NotNull Player player) { + return is(player.getUniqueId()) + && (Permissions.CONTAINER_ANY.hasPermission(player) || Permissions.CONTAINER_ANY_USE.hasPermission(player)); + } + }); + private static final PlayerToggle SILENT = add(new MemoryToggle("SilentContainer") { + @Override + public boolean is(@NotNull Player player) { + return is(player.getUniqueId()) + && (Permissions.CONTAINER_SILENT.hasPermission(player) || Permissions.CONTAINER_SILENT_USE.hasPermission(player)); + } + }); /** * Get the AnyContainer toggle. @@ -72,7 +86,7 @@ private PlayerToggles() { throw new IllegalStateException("Cannot create instance of utility class."); } - private static class MemoryToggle implements PlayerToggle { + private static abstract class MemoryToggle implements PlayerToggle { private final @NotNull Set enabled; private final @NotNull String name; diff --git a/common/src/main/java/com/lishid/openinv/util/Permissions.java b/common/src/main/java/com/lishid/openinv/util/Permissions.java deleted file mode 100644 index 911dcb5e..00000000 --- a/common/src/main/java/com/lishid/openinv/util/Permissions.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2011-2022 lishid. All rights reserved. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, version 3. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.lishid.openinv.util; - -import org.bukkit.permissions.Permissible; -import org.jetbrains.annotations.NotNull; - -public enum Permissions { - - INVENTORY_OPEN_SELF("inventory.open.self"), - INVENTORY_OPEN_OTHER("inventory.open.other"), - INVENTORY_EDIT_SELF("inventory.edit.self"), - INVENTORY_EDIT_OTHER("inventory.edit.other"), - INVENTORY_SLOT_HEAD_ANY("inventory.slot.head.any"), - INVENTORY_SLOT_CHEST_ANY("inventory.slot.chest.any"), - INVENTORY_SLOT_LEGS_ANY("inventory.slot.legs.any"), - INVENTORY_SLOT_FEET_ANY("inventory.slot.feet.any"), - INVENTORY_SLOT_DROP("inventory.slot.drop"), - - ENDERCHEST_OPEN_SELF("enderchest.open.self"), - ENDERCHEST_OPEN_OTHER("enderchest.open.other"), - ENDERCHEST_EDIT_SELF("enderchest.edit.self"), - ENDERCHEST_EDIT_OTHER("enderchest.edit.other"), - - CLEAR_SELF("clear.self"), - CLEAR_OTHER("clear.other"), - - ACCESS_CROSSWORLD("access.crossworld"), - ACCESS_OFFLINE("access.offline"), - ACCESS_ONLINE("access.online"), - ACCESS_EQUAL_EDIT("access.equal.edit"), - ACCESS_EQUAL_VIEW("access.equal.view"), - ACCESS_EQUAL_DENY("access.equal.deny"), - - SPECTATE_CLICK("spectate.click"), - - CONTAINER_ANY("container.any"), - CONTAINER_ANY_USE("container.any.use"), - CONTAINER_SILENT("container.silent"), - CONTAINER_SILENT_USE("container.silent.use"), - SEARCH_INVENTORY("search.inventory"), - SEARCH_CONTAINER("search.container"); - - private final String permission; - - Permissions(String permission) { - this.permission = "openinv." + permission; - } - - public boolean hasPermission(@NotNull Permissible permissible) { - return permissible.hasPermission(permission); - } - - public boolean hasPermission(@NotNull Permissible permissible, @NotNull Permissions parent) { - if (permissible.hasPermission(permission)) return true; - if (permissible.isPermissionSet(permission) && !permissible.hasPermission(permission)) return false; - return permissible.hasPermission(parent.permission); - } -} diff --git a/gradle.properties b/gradle.properties index 79c27754..989e09b9 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,6 +1,6 @@ # Project meta group=com.lishid.openinv -version=5.2.1-SNAPSHOT +version=5.3.0-SNAPSHOT description=A Bukkit plugin for opening normally-inaccessible inventories. # Gradle configuration diff --git a/plugin/src/main/java/com/lishid/openinv/listener/ContainerListener.java b/plugin/src/main/java/com/lishid/openinv/listener/ContainerListener.java index ffcba7d4..87fbb941 100644 --- a/plugin/src/main/java/com/lishid/openinv/listener/ContainerListener.java +++ b/plugin/src/main/java/com/lishid/openinv/listener/ContainerListener.java @@ -39,8 +39,6 @@ import org.bukkit.inventory.InventoryHolder; import org.jetbrains.annotations.NotNull; -import java.util.UUID; - /** * A listener managing AnyContainer, SilentContainer, and more. */ @@ -71,15 +69,14 @@ private void onPlayerInteract(@NotNull PlayerInteractEvent event) { } Player player = event.getPlayer(); - UUID playerId = player.getUniqueId(); - boolean any = Permissions.CONTAINER_ANY_USE.hasPermission(player, Permissions.CONTAINER_ANY) && PlayerToggles.any().is(playerId); + boolean any = PlayerToggles.any().is(player); boolean needsAny = accessor.getAnySilentContainer().isAnyContainerNeeded(event.getClickedBlock()); if (!any && needsAny) { return; } - boolean silent = Permissions.CONTAINER_SILENT_USE.hasPermission(player, Permissions.CONTAINER_SILENT) && PlayerToggles.silent().is(playerId); + boolean silent = PlayerToggles.silent().is(player); // If anycontainer or silentcontainer is active if (any || silent) { @@ -104,7 +101,7 @@ private void onInventoryClose(@NotNull final InventoryCloseEvent event) { } InventoryHolder holder = event.getInventory().getHolder(); - if (PlayerToggles.silent().is(player.getUniqueId()) + if (PlayerToggles.silent().is(player) && holder != null && this.accessor.getAnySilentContainer().isAnySilentContainer(holder)) { this.accessor.getAnySilentContainer().deactivateContainer(player);