mirror of
https://github.com/ViaVersion/ViaRewind-Legacy-Support.git
synced 2025-01-26 21:41:32 +01:00
Fixed broken reflection code
This commit is contained in:
parent
491cf1ae99
commit
5fb1033c56
@ -91,7 +91,7 @@ hangarPublish {
|
|||||||
changelog.set(changelogContent)
|
changelog.set(changelogContent)
|
||||||
apiKey.set(System.getenv("HANGAR_TOKEN"))
|
apiKey.set(System.getenv("HANGAR_TOKEN"))
|
||||||
platforms {
|
platforms {
|
||||||
paper {
|
PAPER {
|
||||||
jar.set(tasks.jar.archiveFile)
|
jar.set(tasks.jar.archiveFile)
|
||||||
platformVersions.set([property('mcVersionRange') as String])
|
platformVersions.set([property('mcVersionRange') as String])
|
||||||
dependencies.hangar("ViaVersion") {
|
dependencies.hangar("ViaVersion") {
|
||||||
|
@ -18,13 +18,12 @@
|
|||||||
|
|
||||||
package com.viaversion.viarewind.legacysupport.injector;
|
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 com.viaversion.viaversion.api.Via;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class NMSReflection {
|
public class NMSReflection {
|
||||||
@ -119,22 +118,24 @@ public class NMSReflection {
|
|||||||
return Class.forName("net.minecraft.server." + getVersion() + "." + name);
|
return Class.forName("net.minecraft.server." + getVersion() + "." + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendPacket(Player player, Object packet) {
|
public static void sendPacket(Player player, Object packet) throws ReflectiveOperationException {
|
||||||
try {
|
Object nmsPlayer = player.getClass().getMethod("getHandle").invoke(player);
|
||||||
Object nmsPlayer = player.getClass().getMethod("getHandle").invoke(player);
|
if (playerConnectionField == null) {
|
||||||
if (playerConnectionField == null) {
|
playerConnectionField = Arrays.stream(nmsPlayer.getClass().getFields())
|
||||||
playerConnectionField = Arrays.stream(nmsPlayer.getClass().getFields())
|
.filter(field -> field.getType() == getPlayerConnectionClass()).findFirst()
|
||||||
.filter(field -> field.getType() == getPlayerConnectionClass()).findFirst()
|
.orElseThrow(() -> new ReflectiveOperationException("Failed to find PlayerConnection field in EntityPlayer"));
|
||||||
.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();
|
|
||||||
}
|
}
|
||||||
|
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 org.bukkit.event.player.PlayerPickupItemEvent;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public class SoundListener implements Listener {
|
public class SoundListener implements Listener {
|
||||||
@ -88,7 +89,11 @@ public class SoundListener implements Listener {
|
|||||||
if (Via.getAPI().getServerVersion().lowestSupportedVersion() >= ProtocolVersion.v1_17.getVersion()) {
|
if (Via.getAPI().getServerVersion().lowestSupportedVersion() >= ProtocolVersion.v1_17.getVersion()) {
|
||||||
player.playSound(e.getBlockPlaced().getLocation(), e.getBlock().getBlockData().getSoundGroup().getPlaceSound(), 1.0f, 0.8f);
|
player.playSound(e.getBlockPlaced().getLocation(), e.getBlock().getBlockData().getSoundGroup().getPlaceSound(), 1.0f, 0.8f);
|
||||||
} else {
|
} 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
|
// 1.8.8 -> 1.16.5
|
||||||
private static void playBlockPlaceSoundNMS(Player player, Block block) {
|
private static void playBlockPlaceSoundNMS(Player player, Block block) throws Exception {
|
||||||
try {
|
World world = block.getWorld();
|
||||||
World world = block.getWorld();
|
Object nmsWorld = world.getClass().getMethod("getHandle").invoke(world);
|
||||||
Object nmsWorld = world.getClass().getMethod("getHandle").invoke(world);
|
Class<?> blockPositionClass = NMSReflection.getBlockPositionClass();
|
||||||
Class<?> blockPositionClass = NMSReflection.getBlockPositionClass();
|
Object blockPosition = null;
|
||||||
Object blockPosition = null;
|
|
||||||
|
|
||||||
if (blockPositionClass != null)
|
if (blockPositionClass != null)
|
||||||
blockPosition = blockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(block.getX(), block.getY(), block.getZ());
|
blockPosition = blockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(block.getX(), block.getY(), block.getZ());
|
||||||
|
|
||||||
Method getTypeMethod = nmsWorld.getClass().getMethod("getType", blockPositionClass);
|
Method getTypeMethod = nmsWorld.getClass().getMethod("getType", blockPositionClass);
|
||||||
getTypeMethod.setAccessible(true);
|
getTypeMethod.setAccessible(true);
|
||||||
|
|
||||||
Object blockData = getTypeMethod.invoke(nmsWorld, blockPosition);
|
Object blockData = getTypeMethod.invoke(nmsWorld, blockPosition);
|
||||||
Method getBlock = blockData.getClass().getMethod("getBlock");
|
Method getBlock = blockData.getClass().getMethod("getBlock");
|
||||||
getBlock.setAccessible(true);
|
getBlock.setAccessible(true);
|
||||||
|
|
||||||
Object nmsBlock = getBlock.invoke(blockData);
|
Object nmsBlock = getBlock.invoke(blockData);
|
||||||
Method getStepSound = ReflectionAPI.pickMethod(
|
Method getStepSound;
|
||||||
nmsBlock.getClass(),
|
final int serverProtocol = Via.getAPI().getServerVersion().lowestSupportedVersion();
|
||||||
new MethodSignature("w"), // 1.9 -> 1.10
|
if (serverProtocol > ProtocolVersion.v1_8.getVersion() && serverProtocol < ProtocolVersion.v1_12.getVersion()) {
|
||||||
new MethodSignature("getStepSound", blockData.getClass()), // 1.14 -> 1.16
|
getStepSound = ReflectionAPI.findRecursiveMethodOrNull(nmsBlock.getClass(), "w");
|
||||||
new MethodSignature("getStepSound") // 1.11 -> 1.12
|
} else if (serverProtocol > ProtocolVersion.v1_10.getVersion() && serverProtocol < ProtocolVersion.v1_13.getVersion()) {
|
||||||
);
|
getStepSound = ReflectionAPI.findRecursiveMethodOrNull(nmsBlock.getClass(), "getStepSound");
|
||||||
getStepSound.setAccessible(true);
|
} else { // 1.14 - 1.16.5
|
||||||
|
getStepSound = ReflectionAPI.findRecursiveMethodOrNull(nmsBlock.getClass(), "getStepSound", blockData.getClass());
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
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
|
// 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) {
|
public static Field getField(Class clazz, String fieldname) {
|
||||||
String key = clazz.getName() + ":" + fieldname;
|
String key = clazz.getName() + ":" + fieldname;
|
||||||
Field field = null;
|
Field field = null;
|
||||||
@ -128,4 +100,14 @@ public class ReflectionAPI {
|
|||||||
ex.printStackTrace();
|
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
|
main: com.viaversion.viarewind.legacysupport.BukkitPlugin
|
||||||
api-version: 1.13
|
api-version: 1.13
|
||||||
|
|
||||||
authors: [Gerrygames]
|
authors: [FlorianMichael/EnZaXD, Gerrygames]
|
||||||
website: https://github.com/ViaVersion/ViaRewind-Legacy-Support
|
website: https://github.com/ViaVersion/ViaRewind-Legacy-Support
|
||||||
|
|
||||||
depend: [ViaVersion]
|
depend: [ViaRewind]
|
||||||
|
Loading…
Reference in New Issue
Block a user