Merge remote-tracking branch 'origin/master' into dev

This commit is contained in:
FlorianMichael 2024-04-02 12:22:29 +02:00
commit 99cf5cddf9
No known key found for this signature in database
GPG Key ID: C2FB87E71C425126
16 changed files with 146 additions and 156 deletions

View File

@ -1,9 +1,7 @@
import io.papermc.hangarpublishplugin.model.Platforms
plugins {
id "java-library"
id "maven-publish"
id "io.papermc.hangar-publish-plugin" version "0.1.0"
id "io.papermc.hangar-publish-plugin" version "0.1.2"
}
repositories {
@ -25,7 +23,7 @@ version = project.maven_version
group = project.maven_group
dependencies {
compileOnly "com.viaversion:viaversion-api:4.10.0-24w09a-SNAPSHOT"
compileOnly "com.viaversion:viaversion-api:4.9.3"
compileOnly "org.spigotmc:spigot-api:1.16.5-R0.1-SNAPSHOT"
}
@ -104,7 +102,7 @@ hangarPublish {
changelog.set(changelogContent)
apiKey.set(System.getenv("HANGAR_TOKEN"))
platforms {
register(Platforms.PAPER) {
PAPER {
jar.set(tasks.jar.archiveFile)
platformVersions.set([property('mcVersionRange') as String])
dependencies.hangar("ViaVersion") {

Binary file not shown.

View File

@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
zipStorePath=wrapper/dists

18
gradlew vendored
View File

@ -145,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@ -153,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC2039,SC3045
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@ -200,13 +200,13 @@ fi
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"'
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
# Collect all arguments for the java command;
# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
# shell script including quotes and variable substitutions, so put them in
# double quotes to make sure that they get re-expanded; and
# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
@ -246,4 +246,4 @@ eval "set -- $(
tr '\n' ' '
)" '"$@"'
exec "$JAVACMD" "$@"
exec "$JAVACMD" "$@"

22
gradlew.bat vendored
View File

@ -34,7 +34,7 @@ set APP_HOME=%DIRNAME%
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=-Dfile.encoding=UTF-8 "-Xmx64m" "-Xms64m"
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo. 1>&2
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
echo. 1>&2
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
echo location of your Java installation. 1>&2
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail

View File

@ -49,18 +49,18 @@ public class BukkitPlugin extends JavaPlugin {
@Override
public void run() {
final ProtocolVersion serverProtocol = Via.getAPI().getServerVersion().lowestSupportedProtocolVersion();
if (!serverProtocol.isKnown()) return;
final int serverProtocol = Via.getAPI().getServerVersion().lowestSupportedVersion();
if (serverProtocol == -1) return;
cancel();
if (serverProtocol.newerThanOrEqualTo(ProtocolVersion.v1_8)) {
if (serverProtocol >= ProtocolVersion.v1_8.getVersion()) {
if (config.getBoolean("enchanting-gui-fix"))
Bukkit.getPluginManager().registerEvents(new EnchantingListener(), BukkitPlugin.this);
if (config.getBoolean("slime-fix"))
Bukkit.getPluginManager().registerEvents(new BounceListener(), BukkitPlugin.this);
}
if (serverProtocol.newerThanOrEqualTo(ProtocolVersion.v1_9)) {
if (serverProtocol >= ProtocolVersion.v1_9.getVersion()) {
if (config.getBoolean("sound-fix"))
Bukkit.getPluginManager().registerEvents(new SoundListener(BukkitPlugin.this), BukkitPlugin.this);
@ -79,7 +79,7 @@ public class BukkitPlugin extends JavaPlugin {
if (config.getBoolean("lily-pad-fix")) // 15w44b
BoundingBoxFixer.fixLilyPad(getLogger(), serverProtocol);
}
if (serverProtocol.newerThanOrEqualTo(ProtocolVersion.v1_14_4) && config.getBoolean("carpet-fix")) {
if (serverProtocol >= ProtocolVersion.v1_14_4.getVersion() && config.getBoolean("carpet-fix")) {
BoundingBoxFixer.fixCarpet(getLogger(), serverProtocol);
}

View File

@ -30,9 +30,10 @@ import java.util.logging.Logger;
public class BoundingBoxFixer {
public static void fixLilyPad(final Logger logger, final ProtocolVersion serverVersion) {
public static void fixLilyPad(final Logger logger, final int serverVersion) {
try {
final Field boundingBoxField = ReflectionAPI.getFieldAccessible(NMSReflection.getNMSBlock("BlockWaterLily"), serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2) ? "a" : "b");
final Field boundingBoxField = ReflectionAPI.getFieldAccessible(NMSReflection.getNMSBlock("BlockWaterLily"),
serverVersion <= ProtocolVersion.v1_20_2.getVersion() ? "a" : "b");
setBoundingBox(boundingBoxField.get(null), 0.0625, 0.0, 0.0625, 0.9375, 0.015625, 0.9375);
} catch (Exception ex) {
@ -40,23 +41,23 @@ public class BoundingBoxFixer {
}
}
public static void fixCarpet(final Logger logger, final ProtocolVersion serverVersion) {
public static void fixCarpet(final Logger logger, final int serverVersion) {
try {
final Class<?> blockCarpetClass = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_16_4) ? NMSReflection.getNMSBlock("BlockCarpet") : NMSReflection.getNMSBlock("CarpetBlock");
final Class<?> blockCarpetClass = serverVersion <= ProtocolVersion.v1_16_4.getVersion() ? NMSReflection.getNMSBlock("BlockCarpet") : NMSReflection.getNMSBlock("CarpetBlock");
final Field boundingBoxField = ReflectionAPI.getFieldAccessible(blockCarpetClass, serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2) ? "a" : "b");
final Field boundingBoxField = ReflectionAPI.getFieldAccessible(blockCarpetClass, serverVersion <= ProtocolVersion.v1_20_2.getVersion() ? "a" : "b");
setBoundingBox(boundingBoxField.get(0), 0.0D, -0.0000001D, 0.0D, 1.0D, 0.0000001D, 1.0D);
} catch (Exception ex) {
logger.log(Level.SEVERE, "Could not fix carpet bounding box.", ex);
}
}
public static void fixLadder(final Logger logger, final ProtocolVersion serverVersion) {
public static void fixLadder(final Logger logger, final int serverVersion) {
try {
final boolean pre1_12_2 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_12_2);
final boolean pre1_13_2 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_13_2);
final boolean pre1_16_4 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_16_4);
final boolean pre1_20_2 = serverVersion.olderThanOrEqualTo(ProtocolVersion.v1_20_2);
final boolean pre1_12_2 = serverVersion <= ProtocolVersion.v1_12_2.getVersion();
final boolean pre1_13_2 = serverVersion <= ProtocolVersion.v1_13_2.getVersion();
final boolean pre1_16_4 = serverVersion <= ProtocolVersion.v1_16_4.getVersion();
final boolean pre1_20_2 = serverVersion <= ProtocolVersion.v1_20_2.getVersion();
final Class<?> blockLadderClass = NMSReflection.getNMSBlock("BlockLadder");

View File

@ -18,13 +18,12 @@
package com.viaversion.viarewind.legacysupport.injector;
import com.viaversion.viarewind.legacysupport.reflection.MethodSignature;
import com.viaversion.viarewind.legacysupport.reflection.ReflectionAPI;
import com.viaversion.viaversion.api.Via;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
public class NMSReflection {
@ -119,22 +118,24 @@ public class NMSReflection {
return Class.forName("net.minecraft.server." + getVersion() + "." + name);
}
public static void sendPacket(Player player, Object packet) {
try {
Object nmsPlayer = player.getClass().getMethod("getHandle").invoke(player);
if (playerConnectionField == null) {
playerConnectionField = Arrays.stream(nmsPlayer.getClass().getFields())
.filter(field -> field.getType() == getPlayerConnectionClass()).findFirst()
.orElseThrow(() -> new ReflectiveOperationException("Failed to find PlayerConnection field in EntityPlayer"));
}
Object playerConnection = playerConnectionField.get(nmsPlayer);
ReflectionAPI.pickMethod(
playerConnection.getClass(),
new MethodSignature("sendPacket", getPacketClass()),
new MethodSignature("a", getPacketClass())
).invoke(playerConnection, packet);
} catch (Exception ex) {
ex.printStackTrace();
public static void sendPacket(Player player, Object packet) throws ReflectiveOperationException {
Object nmsPlayer = player.getClass().getMethod("getHandle").invoke(player);
if (playerConnectionField == null) {
playerConnectionField = Arrays.stream(nmsPlayer.getClass().getFields())
.filter(field -> field.getType() == getPlayerConnectionClass()).findFirst()
.orElseThrow(() -> new ReflectiveOperationException("Failed to find PlayerConnection field in EntityPlayer"));
}
Object playerConnection = playerConnectionField.get(nmsPlayer);
Method sendPacket;
try { // TODO find better way
sendPacket = playerConnection.getClass().getDeclaredMethod("sendPacket", getPacketClass());
} catch (Exception e) {
try {
sendPacket = playerConnection.getClass().getDeclaredMethod("a", getPacketClass());
} catch (Exception e2) {
throw new ReflectiveOperationException("Failed to find sendPacket method in PlayerConnection");
}
}
sendPacket.invoke(playerConnection, packet);
}
}

View File

@ -41,7 +41,7 @@ public class AreaEffectCloudListener implements Listener {
public AreaEffectCloudListener(final BukkitPlugin plugin) {
Bukkit.getScheduler().runTaskTimer(plugin, () -> {
final Set<Player> affectedPlayers = Bukkit.getOnlinePlayers().stream().filter(p -> Via.getAPI().getPlayerProtocolVersion(p).newerThanOrEqualTo(ProtocolVersion.v1_8)).collect(Collectors.toSet());
final Set<Player> affectedPlayers = Bukkit.getOnlinePlayers().stream().filter(p -> Via.getAPI().getPlayerVersion(p) >= ProtocolVersion.v1_8.getVersion()).collect(Collectors.toSet());
effectClouds.removeIf(e -> !e.isValid());
effectClouds.forEach(cloud -> {
final Location location = cloud.getLocation();

View File

@ -36,7 +36,7 @@ public class BounceListener implements Listener {
if (e.getTo().getY() >= e.getFrom().getY()) return; // Only check upwards motion
final Player player = e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_8)) return; // Only apply for 1.7 and below players
if (Via.getAPI().getPlayerVersion(player) >= ProtocolVersion.v1_8.getVersion()) return; // Only apply for 1.7 and below players
if (Math.floor(e.getTo().getY()) + 0.01 < e.getTo().getY()) return;
if (player.isSneaking()) return;

View File

@ -38,8 +38,8 @@ public class BrewingListener implements Listener {
public void onPlayerInteract(PlayerInteractEvent e) {
if (!e.hasBlock() || e.getClickedBlock().getType() != Material.BREWING_STAND) return;
Player player = e.getPlayer();
ProtocolVersion version = Via.getAPI().getPlayerProtocolVersion(player);
if (version.newerThan(ProtocolVersion.v1_9)) return;
int version = Via.getAPI().getPlayerVersion(player);
if (version > ProtocolVersion.v1_9.getVersion()) return;
ItemStack blazePowder = new ItemStack(Material.BLAZE_POWDER);
ItemStack playerItem = e.getItem();
if (playerItem == null) playerItem = new ItemStack(Material.AIR);

View File

@ -34,7 +34,7 @@ public class ElytraListener implements Listener {
public void onPlayerMove(PlayerMoveEvent e) {
final Player player = e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_9)) return; // Only apply for 1.8 and below players
if (Via.getAPI().getPlayerVersion(player) >= ProtocolVersion.v1_9.getVersion()) return; // Only apply for 1.8 and below players
if (!player.isGliding()) return; // Only apply if the player is gliding
final Vector direction = player.getLocation().getDirection();

View File

@ -54,7 +54,7 @@ public class EnchantingListener implements Listener {
if (!(e.getInventory() instanceof EnchantingInventory)) return;
final Player player = (Player) e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_8)) return;
if (Via.getAPI().getPlayerVersion(player) >= ProtocolVersion.v1_8.getVersion()) return;
final PlayerInventory inv = player.getInventory();
final ItemStack lapis = newMaterialNames ? new ItemStack(lapisMaterial) : new ItemStack(lapisMaterial, 1, (short) 4);
@ -89,7 +89,7 @@ public class EnchantingListener implements Listener {
if (!(e.getInventory() instanceof EnchantingInventory)) return;
final Player player = (Player) e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_8)) return;
if (Via.getAPI().getPlayerVersion(player) >= ProtocolVersion.v1_8.getVersion()) return;
final PlayerInventory inv = player.getInventory();
final EnchantingInventory replacement = (EnchantingInventory) e.getInventory();

View File

@ -40,6 +40,7 @@ import org.bukkit.event.player.PlayerExpChangeEvent;
import org.bukkit.event.player.PlayerPickupItemEvent;
import java.lang.reflect.Method;
import java.util.logging.Level;
@SuppressWarnings("unchecked")
public class SoundListener implements Listener {
@ -83,12 +84,16 @@ public class SoundListener implements Listener {
@EventHandler
public void onBlockPlace(BlockPlaceEvent e) {
final Player player = e.getPlayer();
if (Via.getAPI().getPlayerProtocolVersion(player).newerThanOrEqualTo(ProtocolVersion.v1_9)) return;
if (Via.getAPI().getPlayerVersion(player) >= ProtocolVersion.v1_9.getVersion()) return;
if (Via.getAPI().getServerVersion().lowestSupportedProtocolVersion().newerThanOrEqualTo(ProtocolVersion.v1_17)) {
if (Via.getAPI().getServerVersion().lowestSupportedVersion() >= ProtocolVersion.v1_17.getVersion()) {
player.playSound(e.getBlockPlaced().getLocation(), e.getBlock().getBlockData().getSoundGroup().getPlaceSound(), 1.0f, 0.8f);
} else {
playBlockPlaceSoundNMS(player, e.getBlock());
try {
playBlockPlaceSoundNMS(player, e.getBlock());
} catch (Exception exception) {
Via.getPlatform().getLogger().log(Level.SEVERE, "Could not play block place sound.", exception);
}
}
}
@ -123,67 +128,70 @@ public class SoundListener implements Listener {
// 1.8.8 -> 1.16.5
private static void playBlockPlaceSoundNMS(Player player, Block block) {
try {
World world = block.getWorld();
Object nmsWorld = world.getClass().getMethod("getHandle").invoke(world);
Class<?> blockPositionClass = NMSReflection.getBlockPositionClass();
Object blockPosition = null;
private static void playBlockPlaceSoundNMS(Player player, Block block) throws Exception {
World world = block.getWorld();
Object nmsWorld = world.getClass().getMethod("getHandle").invoke(world);
Class<?> blockPositionClass = NMSReflection.getBlockPositionClass();
Object blockPosition = null;
if (blockPositionClass != null)
blockPosition = blockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(block.getX(), block.getY(), block.getZ());
if (blockPositionClass != null)
blockPosition = blockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(block.getX(), block.getY(), block.getZ());
Method getTypeMethod = nmsWorld.getClass().getMethod("getType", blockPositionClass);
getTypeMethod.setAccessible(true);
Method getTypeMethod = nmsWorld.getClass().getMethod("getType", blockPositionClass);
getTypeMethod.setAccessible(true);
Object blockData = getTypeMethod.invoke(nmsWorld, blockPosition);
Method getBlock = blockData.getClass().getMethod("getBlock");
getBlock.setAccessible(true);
Object blockData = getTypeMethod.invoke(nmsWorld, blockPosition);
Method getBlock = blockData.getClass().getMethod("getBlock");
getBlock.setAccessible(true);
Object nmsBlock = getBlock.invoke(blockData);
Method getStepSound = ReflectionAPI.pickMethod(
nmsBlock.getClass(),
new MethodSignature("w"), // 1.9 -> 1.10
new MethodSignature("getStepSound", blockData.getClass()), // 1.14 -> 1.16
new MethodSignature("getStepSound") // 1.11 -> 1.12
);
getStepSound.setAccessible(true);
Object soundType;
if (getStepSound.getParameterCount() == 0) {
soundType = getStepSound.invoke(nmsBlock); // 1.9 -> 1.13
} else {
soundType = getStepSound.invoke(nmsBlock, blockData); // 1.14 -> 1.16.5
}
Method soundEffectMethod;
Method volumeMethod;
Method pitchMethod;
try {
// 1.16.5
soundEffectMethod = soundType.getClass().getMethod("getPlaceSound");
volumeMethod = soundType.getClass().getMethod("getVolume");
pitchMethod = soundType.getClass().getMethod("getPitch");
} catch (NoSuchMethodException ex) {
// 1.9 -> 1.16.4
soundEffectMethod = soundType.getClass().getMethod("e");
volumeMethod = soundType.getClass().getMethod("a");
pitchMethod = soundType.getClass().getMethod("b");
}
Object soundEffect = soundEffectMethod.invoke(soundType);
float volume = (float) volumeMethod.invoke(soundType);
float pitch = (float) pitchMethod.invoke(soundType);
Object soundCategory = Enum.valueOf(NMSReflection.getSoundCategoryClass(), "BLOCKS");
volume = (volume + 1.0f) / 2.0f;
pitch *= 0.8;
playSound(player, soundEffect, soundCategory, block.getX() + 0.5, block.getY() + 0.5, block.getZ() + 0.5, volume, pitch);
} catch (Exception ex) {
ex.printStackTrace();
Object nmsBlock = getBlock.invoke(blockData);
Method getStepSound;
final int serverProtocol = Via.getAPI().getServerVersion().lowestSupportedVersion();
if (serverProtocol > ProtocolVersion.v1_8.getVersion() && serverProtocol < ProtocolVersion.v1_12.getVersion()) {
getStepSound = ReflectionAPI.findRecursiveMethodOrNull(nmsBlock.getClass(), "w");
} else if (serverProtocol > ProtocolVersion.v1_10.getVersion() && serverProtocol < ProtocolVersion.v1_13.getVersion()) {
getStepSound = ReflectionAPI.findRecursiveMethodOrNull(nmsBlock.getClass(), "getStepSound");
} else { // 1.14 - 1.16.5
getStepSound = ReflectionAPI.findRecursiveMethodOrNull(nmsBlock.getClass(), "getStepSound", blockData.getClass());
}
if (getStepSound == null) {
Via.getPlatform().getLogger().severe("Could not find getStepSound method in " + nmsBlock.getClass().getName());
return;
}
getStepSound.setAccessible(true);
Object soundType;
if (getStepSound.getParameterCount() == 0) {
soundType = getStepSound.invoke(nmsBlock); // 1.9 - 1.13
} else {
soundType = getStepSound.invoke(nmsBlock, blockData); // 1.14 - 1.16.5
}
Method soundEffectMethod;
Method volumeMethod;
Method pitchMethod;
try {
// 1.16.5
soundEffectMethod = soundType.getClass().getMethod("getPlaceSound");
volumeMethod = soundType.getClass().getMethod("getVolume");
pitchMethod = soundType.getClass().getMethod("getPitch");
} catch (NoSuchMethodException ex) {
// 1.9 -> 1.16.4
soundEffectMethod = soundType.getClass().getMethod("e");
volumeMethod = soundType.getClass().getMethod("a");
pitchMethod = soundType.getClass().getMethod("b");
}
Object soundEffect = soundEffectMethod.invoke(soundType);
float volume = (float) volumeMethod.invoke(soundType);
float pitch = (float) pitchMethod.invoke(soundType);
Object soundCategory = Enum.valueOf(NMSReflection.getSoundCategoryClass(), "BLOCKS");
volume = (volume + 1.0f) / 2.0f;
pitch *= 0.8;
playSound(player, soundEffect, soundCategory, block.getX() + 0.5, block.getY() + 0.5, block.getZ() + 0.5, volume, pitch);
}
// 1.8.8 -> 1.16.5

View File

@ -38,34 +38,6 @@ public class ReflectionAPI {
}
}
/**
* Recursively searches for (declared) methods at a specific class and all it's superclasses
*
* @param holder The base class where to start searching
* @param signatures Possible method signatures consisting of method name and parameters
* @return The found {@link Method} or {@code null}
* @throws RuntimeException If no method was found
*/
public static Method pickMethod(Class<?> holder, MethodSignature... signatures) {
Class<?> depth = holder;
do {
for (MethodSignature signature : signatures) {
try {
Method method = depth.getDeclaredMethod(signature.name(), signature.parameterTypes());
if (signature.returnType() != null && !Objects.equals(method.getReturnType(), signature.returnType())) {
continue;
}
if (!method.isAccessible()) {
method.setAccessible(true);
}
return method;
} catch (NoSuchMethodException ignored) {
}
}
} while ((depth = depth.getSuperclass()) != null);
throw new RuntimeException("Failed to resolve method in " + holder + " using " + Arrays.toString(signatures));
}
public static Field getField(Class clazz, String fieldname) {
String key = clazz.getName() + ":" + fieldname;
Field field = null;
@ -128,4 +100,14 @@ public class ReflectionAPI {
ex.printStackTrace();
}
}
public static Method findRecursiveMethodOrNull(Class<?> clazz, String methodName, Class<?>... parameterTypes) {
try {
return clazz.getDeclaredMethod(methodName, parameterTypes);
} catch (NoSuchMethodException ex) {
Class<?> superClass = clazz.getSuperclass();
if (superClass == null) return null;
return findRecursiveMethodOrNull(superClass, methodName, parameterTypes);
}
}
}

View File

@ -3,7 +3,7 @@ version: ${version}
main: com.viaversion.viarewind.legacysupport.BukkitPlugin
api-version: 1.13
authors: [Gerrygames]
authors: [FlorianMichael/EnZaXD, Gerrygames]
website: https://github.com/ViaVersion/ViaRewind-Legacy-Support
depend: [ViaVersion]
depend: [ViaRewind]