mirror of
https://github.com/ViaVersion/ViaRewind-Legacy-Support.git
synced 2025-01-24 21:21:50 +01:00
Fixed broken reflection code
This commit is contained in:
parent
491cf1ae99
commit
5fb1033c56
@ -91,7 +91,7 @@ hangarPublish {
|
||||
changelog.set(changelogContent)
|
||||
apiKey.set(System.getenv("HANGAR_TOKEN"))
|
||||
platforms {
|
||||
paper {
|
||||
PAPER {
|
||||
jar.set(tasks.jar.archiveFile)
|
||||
platformVersions.set([property('mcVersionRange') as String])
|
||||
dependencies.hangar("ViaVersion") {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
@ -88,7 +89,11 @@ public class SoundListener implements Listener {
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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]
|
||||
|
Loading…
Reference in New Issue
Block a user