Fix ItemFactory#getSpawnEgg NoSuchMethodError on older Paper builds (#4582)

This commit is contained in:
EnZaXD authored and GitHub committed 2025-07-13 08:40:09 +02:00
1 parent 81eb3362f3
commit eb51306d82
2 files changed
+45 -8

No files matched your search

@@ -19,11 +19,12 @@ package com.viaversion.viaversion.bukkit.platform;
import com.viaversion.viaversion.bukkit.handlers.BukkitChannelInitializer;
import io.netty.channel.Channel;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import net.kyori.adventure.key.Key;
import org.bukkit.Bukkit;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public final class PaperViaInjector {
public static final boolean PAPER_INJECTION_METHOD = hasPaperInjectionMethod();
public static final boolean PAPER_PROTOCOL_METHOD = hasServerProtocolMethod();
@@ -106,4 +107,12 @@ public final class PaperViaInjector {
return false;
}
}
public static boolean hasMethod(final Class<?> clazz, final Class<?> returnType, final String method, final Class<?>... params) {
try {
return clazz.getDeclaredMethod(method, params).getReturnType().equals(returnType);
} catch (final NoSuchMethodException e) {
return false;
}
}
}
@@ -25,7 +25,6 @@ import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.bukkit.platform.PaperViaInjector;
import com.viaversion.viaversion.bukkit.util.LegacyBlockToItem;
import com.viaversion.viaversion.protocols.v1_21_2to1_21_4.provider.PickItemProvider;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.GameMode;
import org.bukkit.Location;
@@ -40,17 +39,34 @@ import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.PlayerInventory;
import org.bukkit.inventory.meta.BlockStateMeta;
import java.lang.reflect.Method;
import java.util.UUID;
public class BukkitPickItemProvider extends PickItemProvider {
private static final BlockToItem BLOCK_TO_ITEM = BlockToItem.build();
private static final GetStorageContents GET_STORAGE_CONTENT = GetStorageContents.build();
private static final SetInHand SET_IN_HAND = SetInHand.build();
private static final boolean HAS_SPAWN_EGG_METHOD = PaperViaInjector.hasMethod(ItemFactory.class, "getSpawnEgg", EntityType.class);
private static final boolean HAS_SPAWN_EGG_METHOD = PaperViaInjector.hasMethod(ItemFactory.class, Material.class, "getSpawnEgg", EntityType.class);
private static final Method GET_SPAWN_EGG_ITEMSTACK_METHOD;
private static final double BLOCK_RANGE = 4.5 + 1;
private static final double BLOCK_RANGE_SQUARED = BLOCK_RANGE * BLOCK_RANGE;
private static final double ENTITY_RANGE = 3 + 3;
private final ViaVersionPlugin plugin;
static {
if (PaperViaInjector.hasMethod(ItemFactory.class, ItemStack.class, "getSpawnEgg", EntityType.class)) {
try {
GET_SPAWN_EGG_ITEMSTACK_METHOD = ItemFactory.class.getDeclaredMethod("getSpawnEgg", EntityType.class);
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
} else {
GET_SPAWN_EGG_ITEMSTACK_METHOD = null;
}
}
public BukkitPickItemProvider(final ViaVersionPlugin plugin) {
this.plugin = plugin;
}
@@ -83,7 +99,7 @@ public class BukkitPickItemProvider extends PickItemProvider {
@Override
public void pickItemFromEntity(final UserConnection connection, final int entityId, final boolean includeData) {
if (!HAS_SPAWN_EGG_METHOD) {
if (!HAS_SPAWN_EGG_METHOD && GET_SPAWN_EGG_ITEMSTACK_METHOD == null) {
return;
}
@@ -102,9 +118,21 @@ public class BukkitPickItemProvider extends PickItemProvider {
return;
}
final Material spawnEggType = Bukkit.getItemFactory().getSpawnEgg(entity.getType());
if (spawnEggType != null) {
pickItem(player, new ItemStack(spawnEggType, 1));
if (GET_SPAWN_EGG_ITEMSTACK_METHOD == null) {
final Material spawnEggType = Bukkit.getItemFactory().getSpawnEgg(entity.getType());
if (spawnEggType != null) {
pickItem(player, new ItemStack(spawnEggType, 1));
}
return;
}
try {
final ItemStack spawnEggItem = (ItemStack) GET_SPAWN_EGG_ITEMSTACK_METHOD.invoke(Bukkit.getItemFactory(), entity.getType());
if (spawnEggItem != null) {
pickItem(player, spawnEggItem);
}
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}, player);
}