Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@
<version>5.14.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<version>1.14.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockbukkit.mockbukkit</groupId>
<artifactId>mockbukkit-v1.21</artifactId>
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/net/tfminecraft/companionpets/PetsPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,8 @@ private void reloadSettings(CommandSender sender) {
return;
}
for (var player : Bukkit.getOnlinePlayers()) {
if (player.getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder || player.getOpenInventory().getTopInventory().getHolder() instanceof net.tfminecraft.companionpets.staff.StaffMenuHolder) player.closeInventory();
var holder = player.getOpenInventory().getTopInventory().getHolder(false);
if (holder instanceof MenuHolder || holder instanceof net.tfminecraft.companionpets.staff.StaffMenuHolder) player.closeInventory();
}
actions.clearInteractions();
actions.holograms().clear();
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/net/tfminecraft/companionpets/gui/PetMenus.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public void openCare(org.bukkit.entity.Player player, Pet pet, boolean petHouseB
}

public void refreshCare(org.bukkit.entity.Player player, Pet pet) {
if (!(player.getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder holder)
if (!(player.getOpenInventory().getTopInventory().getHolder(false) instanceof MenuHolder holder)
|| holder.kind() != MenuHolder.Kind.CARE
|| !pet.id().equals(holder.petId())) {
return;
Expand All @@ -87,7 +87,7 @@ public void refreshCare(org.bukkit.entity.Player player, Pet pet) {

private void fillCare(org.bukkit.entity.Player player, Inventory inventory, Pet pet) {
fillProfile(inventory, pet, runtime.owns(pet, player),
inventory.getHolder() instanceof MenuHolder holder && holder.petHouseBack());
inventory.getHolder(false) instanceof MenuHolder holder && holder.petHouseBack());
}

public void fillInformation(Inventory inventory, Pet pet) {
Expand Down Expand Up @@ -334,7 +334,7 @@ public void openTricks(org.bukkit.entity.Player player, Pet pet, String word, in

private void inheritPetHouseNavigation(org.bukkit.entity.Player player, MenuHolder holder) {
Inventory previousInventory = player.getOpenInventory().getTopInventory();
if (previousInventory != null && previousInventory.getHolder() instanceof MenuHolder previous
if (previousInventory != null && previousInventory.getHolder(false) instanceof MenuHolder previous
&& holder.petId().equals(previous.petId())) {
holder.petHouseBack(previous.petHouseBack());
holder.petHousePage(previous.petHousePage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ public void onChat(AsyncPlayerChatEvent event) {

@EventHandler
public void onClick(InventoryClickEvent event) {
InventoryHolder holder = event.getView().getTopInventory().getHolder();
InventoryHolder holder = event.getView().getTopInventory().getHolder(false);
if (!(holder instanceof MenuHolder menu) || !(event.getWhoClicked() instanceof Player player)) {
return;
}
Expand All @@ -152,14 +152,14 @@ public void onClick(InventoryClickEvent event) {

@EventHandler
public void onDrag(InventoryDragEvent event) {
if (event.getView().getTopInventory().getHolder() instanceof MenuHolder) {
if (event.getView().getTopInventory().getHolder(false) instanceof MenuHolder) {
event.setCancelled(true);
}
}

@EventHandler
public void onClose(InventoryCloseEvent event) {
if (event.getInventory().getHolder() instanceof MenuHolder menu
if (event.getInventory().getHolder(false) instanceof MenuHolder menu
&& menu.kind() == MenuHolder.Kind.TRICK
&& !menu.navigating()
&& event.getPlayer() instanceof Player player) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public void end(CharacterSessionEndEvent event) {
Player player = Bukkit.getPlayer(event.getSession().ref().ownerId());
if (player != null) {
actions.ownerSessionChanged(player);
if (player.getOpenInventory().getTopInventory().getHolder() instanceof MenuHolder) player.closeInventory();
if (player.getOpenInventory().getTopInventory().getHolder(false) instanceof MenuHolder) player.closeInventory();
}
runtime.sessions().clearPlayer(event.getSession().ref().ownerId());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,14 @@ private static ItemStack named(ItemStack source, String title, String... lore) {
}

@EventHandler public void onClick(InventoryClickEvent event) {
if (!(event.getView().getTopInventory().getHolder() instanceof StaffMenuHolder holder)) return;
if (!(event.getView().getTopInventory().getHolder(false) instanceof StaffMenuHolder holder)) return;
event.setCancelled(true);
if (!(event.getWhoClicked() instanceof Player player) || !holder.viewer().equals(player.getUniqueId())) return;
if (event.getClickedInventory() != event.getView().getTopInventory() || !(event.getClick().isLeftClick() || event.getClick().isRightClick())
|| event.isShiftClick()) return;
if (allowed(player, "list")) holder.click(event.getSlot(), event.getClick().isRightClick());
}
@EventHandler public void onDrag(InventoryDragEvent event) {
if (event.getView().getTopInventory().getHolder() instanceof StaffMenuHolder) event.setCancelled(true);
if (event.getView().getTopInventory().getHolder(false) instanceof StaffMenuHolder) event.setCancelled(true);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
package net.tfminecraft.companionpets.testutil;

import static net.bytebuddy.matcher.ElementMatchers.is;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;

import java.util.concurrent.atomic.AtomicBoolean;

import net.bytebuddy.agent.ByteBuddyAgent;
import net.bytebuddy.agent.builder.AgentBuilder;
import net.bytebuddy.asm.Advice;
import net.bytebuddy.description.type.TypeDescription;
import net.bytebuddy.dynamic.DynamicType;
import net.bytebuddy.utility.JavaModule;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryHolder;
import org.junit.platform.launcher.LauncherSession;
import org.junit.platform.launcher.LauncherSessionListener;
import org.mockbukkit.mockbukkit.inventory.InventoryMock;

/**
* MockBukkit throws on Paper's {@code getHolder(false)}. Its inventories hold no block snapshot,
* so the patch answers with the plain holder, which is what Paper returns for plugin GUIs.
*/
public final class HolderLookupPatch implements LauncherSessionListener {
private static boolean installed;

@Override
public void launcherSessionOpened(LauncherSession session) {
install();
}

/** Patches {@link InventoryMock#getHolder(boolean)} once per test JVM. */
public static synchronized void install() {
if (installed) {
return;
}
AtomicBoolean patched = new AtomicBoolean();
AtomicBoolean rejected = new AtomicBoolean();
new AgentBuilder.Default()
.disableClassFormatChanges()
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
.with(AgentBuilder.InitializationStrategy.NoOp.INSTANCE)
.with(AgentBuilder.TypeStrategy.Default.REDEFINE)
.with(AgentBuilder.Listener.StreamWriting.toSystemError().withErrorsOnly())
.with(new AgentBuilder.Listener.Adapter() {
@Override
public void onTransformation(TypeDescription type, ClassLoader loader, JavaModule module,
boolean loaded, DynamicType dynamicType) {
if (type.getName().equals(InventoryMock.class.getName())) {
patched.set(true);
}
}

// The JVM can still reject the new bytes after onTransformation.
@Override
public void onError(String typeName, ClassLoader loader, JavaModule module, boolean loaded,
Throwable throwable) {
if (typeName.equals(InventoryMock.class.getName())) {
rejected.set(true);
}
}
})
.type(is(InventoryMock.class))
.transform((builder, type, loader, module, domain) -> builder.visit(Advice.to(PlainHolder.class)
.on(named("getHolder").and(takesArguments(boolean.class)))))
.installOn(ByteBuddyAgent.install());
// A failed retransformation only reaches the listeners, so check it took before marking it done.
if (!patched.get() || rejected.get()) {
throw new IllegalStateException("Could not patch InventoryMock#getHolder(boolean)");
}
installed = true;
}

/** Skips the throwing body and returns {@code getHolder()} instead. */
static final class PlainHolder {
private PlainHolder() {
}

@Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
static boolean skip() {
return true;
}

@Advice.OnMethodExit
static void exit(@Advice.This Inventory inventory,
@Advice.Return(readOnly = false) InventoryHolder holder) {
holder = inventory.getHolder();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
net.tfminecraft.companionpets.testutil.HolderLookupPatch
Loading