Skip to content

Commit

Permalink
Add view-only mode as default
Browse files Browse the repository at this point in the history
  • Loading branch information
Jikoo committed Aug 10, 2024
1 parent 9f46e2c commit a107cd9
Show file tree
Hide file tree
Showing 15 changed files with 136 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,6 @@ public interface PlayerManager {
*`
* @return the InventoryView opened
*/
@Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory);
@Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory, boolean viewOnly);

}
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ private void injectPlayer(ServerPlayer player) throws IllegalAccessException {
}

@Override
public @Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory) {
public @Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory, boolean viewOnly) {

ServerPlayer nmsPlayer = getHandle(player);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ private void injectPlayer(ServerPlayer player) throws IllegalAccessException {
}

@Override
public @Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory) {
public @Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory, boolean viewOnly) {

ServerPlayer nmsPlayer = getHandle(player);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.ContainerHelper;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.player.StackedContents;
import net.minecraft.world.inventory.AbstractContainerMenu;
Expand All @@ -27,8 +25,8 @@
import java.util.ArrayList;
import java.util.List;

public class OpenEnderChest implements Container, StackedContentsCompatible, MenuProvider,
InternalOwned<ServerPlayer>, ISpecialEnderChest {
public class OpenEnderChest implements Container, StackedContentsCompatible, InternalOwned<ServerPlayer>,
ISpecialEnderChest {

private CraftInventory inventory;
private @NotNull ServerPlayer owner;
Expand Down Expand Up @@ -182,17 +180,15 @@ public void fillStackedContents(StackedContents stackedContents) {
}
}

@Override
public Component getDisplayName() {
public Component getTitle() {
return Component.translatableWithFallback("openinv.container.enderchest.prefix", "", owner.getName())
.append(Component.translatable("container.enderchest"))
.append(Component.translatableWithFallback("openinv.container.enderchest.suffix", " - %s", owner.getName()));
}

@Override
public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
public @Nullable AbstractContainerMenu createMenu(Player player, int i, boolean viewOnly) {
if (player instanceof ServerPlayer serverPlayer) {
return new OpenEnderChestMenu(this, serverPlayer, i);
return new OpenEnderChestMenu(this, serverPlayer, i, viewOnly);
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import com.lishid.openinv.internal.InternalOwned;
import com.lishid.openinv.internal.v1_21_R1.container.bukkit.OpenPlayerInventory;
import com.lishid.openinv.internal.v1_21_R1.container.menu.OpenInventoryMenu;
import com.lishid.openinv.internal.v1_21_R1.player.PlayerManager;
import com.lishid.openinv.internal.v1_21_R1.container.slot.Content;
import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentCrafting;
import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentCraftingResult;
Expand All @@ -15,14 +14,14 @@
import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentOffHand;
import com.lishid.openinv.internal.v1_21_R1.container.slot.ContentViewOnly;
import com.lishid.openinv.internal.v1_21_R1.container.slot.SlotViewOnly;
import com.lishid.openinv.internal.v1_21_R1.player.PlayerManager;
import net.minecraft.ChatFormatting;
import net.minecraft.core.NonNullList;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.MutableComponent;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.Container;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
Expand All @@ -40,7 +39,7 @@
import java.util.ArrayList;
import java.util.List;

public class OpenInventory implements Container, MenuProvider, InternalOwned<ServerPlayer>, ISpecialPlayerInventory {
public class OpenInventory implements Container, InternalOwned<ServerPlayer>, ISpecialPlayerInventory {

private final List<Content> slots;
private final int size;
Expand Down Expand Up @@ -355,15 +354,9 @@ public void clearContent() {
owner.containerMenu.setCarried(ItemStack.EMPTY);
}

@Override
public Component getDisplayName() {
return getTitle(null);
}

@Override
public @Nullable AbstractContainerMenu createMenu(int i, Inventory inventory, Player player) {
public @Nullable AbstractContainerMenu createMenu(Player player, int i, boolean viewOnly) {
if (player instanceof ServerPlayer serverPlayer) {
return new OpenInventoryMenu(this, serverPlayer, i);
return new OpenInventoryMenu(this, serverPlayer, i, viewOnly);
}
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,18 @@ public abstract class OpenChestMenu<T extends Container & ISpecialInventory & In
private ItemStack remoteCarried = ItemStack.EMPTY;
private boolean suppressRemoteUpdates;

protected OpenChestMenu(MenuType<ChestMenu> type, int containerCounter, T container, ServerPlayer viewer) {
protected OpenChestMenu(
@NotNull MenuType<ChestMenu> type,
int containerCounter,
@NotNull T container,
@NotNull ServerPlayer viewer,
boolean viewOnly) {
super(type, containerCounter);
this.container = container;
this.viewer = viewer;
this.viewOnly = viewOnly;
ownContainer = container.getOwnerHandle().equals(viewer);
topSize = getTopSize(viewer);
viewOnly = checkViewOnly();

preSlotSetup();

Expand Down Expand Up @@ -116,8 +121,6 @@ protected OpenChestMenu(MenuType<ChestMenu> type, int containerCounter, T contai
};
}

protected abstract boolean checkViewOnly();

protected void preSlotSetup() {}

protected @NotNull Slot getUpperSlot(int index, int x, int y) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
package com.lishid.openinv.internal.v1_21_R1.container.menu;

import com.lishid.openinv.internal.v1_21_R1.container.OpenEnderChest;
import com.lishid.openinv.util.Permissions;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.Slot;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;

public class OpenEnderChestMenu extends OpenChestMenu<OpenEnderChest> {

public OpenEnderChestMenu(OpenEnderChest enderChest, ServerPlayer viewer, int containerId) {
super(getChestMenuType(enderChest.getContainerSize()), containerId, enderChest, viewer);
}

@Override
protected boolean checkViewOnly() {
return !(ownContainer ? Permissions.ENDERCHEST_EDIT_SELF : Permissions.ENDERCHEST_OPEN_OTHER)
.hasPermission(viewer.getBukkitEntity());
public OpenEnderChestMenu(
@NotNull OpenEnderChest enderChest,
@NotNull ServerPlayer viewer,
int containerId,
boolean viewOnly) {
super(getChestMenuType(enderChest.getContainerSize()), containerId, enderChest, viewer, viewOnly);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ public class OpenInventoryMenu extends OpenChestMenu<OpenInventory> {

private int offset;

public OpenInventoryMenu(OpenInventory inventory, ServerPlayer viewer, int i) {
super(getMenuType(inventory, viewer), i, inventory, viewer);
public OpenInventoryMenu(OpenInventory inventory, ServerPlayer viewer, int i, boolean viewOnly) {
super(getMenuType(inventory, viewer), i, inventory, viewer, viewOnly);
}

private static MenuType<ChestMenu> getMenuType(OpenInventory inventory, ServerPlayer viewer) {
Expand Down Expand Up @@ -97,12 +97,6 @@ protected void preSlotSetup() {
return slot;
}

@Override
protected boolean checkViewOnly() {
return !(ownContainer ? Permissions.INVENTORY_EDIT_SELF : Permissions.INVENTORY_EDIT_OTHER)
.hasPermission(viewer.getBukkitEntity());
}

@Override
protected @NotNull CraftInventoryView<OpenChestMenu<OpenInventory>> createBukkitEntity() {
org.bukkit.inventory.Inventory bukkitInventory;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
import net.minecraft.server.level.ClientInformation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.player.ChatVisiblity;
import net.minecraft.world.inventory.AbstractContainerMenu;
Expand Down Expand Up @@ -219,35 +218,34 @@ private void injectPlayer(ServerPlayer player) throws IllegalAccessException {
}

@Override
public @Nullable InventoryView openInventory(@NotNull Player bukkitPlayer, @NotNull ISpecialInventory inventory) {
public @Nullable InventoryView openInventory(@NotNull Player bukkitPlayer, @NotNull ISpecialInventory inventory, boolean viewOnly) {
ServerPlayer player = getHandle(bukkitPlayer);

if (player.connection == null) {
return null;
}

MenuProvider provider;
// See net.minecraft.server.level.ServerPlayer#openMenu(MenuProvider)
AbstractContainerMenu menu;
Component title;
if (inventory instanceof OpenInventory playerInv) {
provider = playerInv;
menu = playerInv.createMenu(player, player.nextContainerCounter(), viewOnly);
title = playerInv.getTitle(player);
} else if (inventory instanceof OpenEnderChest enderChest) {
provider = enderChest;
title = enderChest.getDisplayName();
menu = enderChest.createMenu(player, player.nextContainerCounter(), viewOnly);
title = enderChest.getTitle();
} else {
return null;
}

// See net.minecraft.server.level.ServerPlayer#openMenu(MenuProvider)
AbstractContainerMenu menu = provider.createMenu(player.nextContainerCounter(), player.getInventory(), player);

// Should never happen, player is a ServerPlayer with an active connection.
if (menu == null) {
return null;
}

// Set up title (the whole reason we're not just using Player#openInventory(Inventory)).
// Title can only be set once for a menu, and is set during the open process.
// Set up title. Title can only be set once for a menu, and is set during the open process.
// Further title changes are a hack where the client is sent a "new" inventory with the same ID,
// resulting in a title change but no other state modifications (like cursor position).
menu.setTitle(title);

menu = CraftEventFactory.callInventoryOpenEvent(player, menu, false);
Expand Down
52 changes: 46 additions & 6 deletions plugin/src/main/java/com/lishid/openinv/OpenInv.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,23 @@
import com.lishid.openinv.listener.ContainerListener;
import com.lishid.openinv.listener.LegacyInventoryListener;
import com.lishid.openinv.listener.ToggleListener;
import com.lishid.openinv.util.config.Config;
import com.lishid.openinv.util.config.ConfigUpdater;
import com.lishid.openinv.util.AccessEqualMode;
import com.lishid.openinv.util.InternalAccessor;
import com.lishid.openinv.util.InventoryManager;
import com.lishid.openinv.util.lang.LangMigrator;
import com.lishid.openinv.util.Permissions;
import com.lishid.openinv.util.PlayerLoader;
import com.lishid.openinv.util.config.Config;
import com.lishid.openinv.util.config.ConfigUpdater;
import com.lishid.openinv.util.lang.LangMigrator;
import com.lishid.openinv.util.lang.LanguageManager;
import com.lishid.openinv.util.setting.PlayerToggle;
import com.lishid.openinv.util.setting.PlayerToggles;
import com.lishid.openinv.util.lang.LanguageManager;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.PluginCommand;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.InventoryView;
import org.bukkit.plugin.PluginManager;
Expand Down Expand Up @@ -143,7 +146,7 @@ private void registerEvents() {
PluginManager pluginManager = this.getServer().getPluginManager();
// Legacy: extra listener for permission handling and self-view issue prevention.
if (BukkitVersions.MINECRAFT.lessThan(Version.of(1, 21))) {
pluginManager.registerEvents(new LegacyInventoryListener(this), this);
pluginManager.registerEvents(new LegacyInventoryListener(this, config), this);
}
pluginManager.registerEvents(playerLoader, this);
pluginManager.registerEvents(inventoryManager, this);
Expand Down Expand Up @@ -248,7 +251,44 @@ public void setSilentContainerStatus(@NotNull final OfflinePlayer offline, final

@Override
public @Nullable InventoryView openInventory(@NotNull Player player, @NotNull ISpecialInventory inventory) {
return this.accessor.openInventory(player, inventory);
Permissions edit = null;
HumanEntity target = inventory.getPlayer();
boolean ownContainer = player.equals(target);
if (inventory instanceof ISpecialPlayerInventory) {
edit = ownContainer ? Permissions.INVENTORY_EDIT_SELF : Permissions.INVENTORY_EDIT_OTHER;
} else if (inventory instanceof ISpecialEnderChest) {
edit = ownContainer ? Permissions.ENDERCHEST_EDIT_SELF : Permissions.ENDERCHEST_OPEN_OTHER;
}

boolean viewOnly = edit != null && !edit.hasPermission(player);

if (!ownContainer && !viewOnly) {
for (int level = 4; level > 0; --level) {
String permission = "openinv.access.level." + level;
// If the target doesn't have this access level...
if (!target.hasPermission(permission)) {
// If the viewer does have the access level, all good.
if (player.hasPermission(permission)) {
break;
}
// Otherwise check next access level.
continue;
}

// If the player doesn't have an equal access level or equal access is a denial, deny.
if (!player.hasPermission(permission) || config.getAccessEqualMode() == AccessEqualMode.DENY) {
return null;
}

// Since this is a tie, setting decides view state.
if (config.getAccessEqualMode() == AccessEqualMode.VIEW) {
viewOnly = true;
}
break;
}
}

return this.accessor.openInventory(player, inventory, viewOnly);
}

@Override
Expand Down
Loading

0 comments on commit a107cd9

Please sign in to comment.