Fix / Compatibility for 1.17 + 1.17.1 (#29)

This commit is contained in:
Pierre Maurice Schwang 2021-07-21 19:53:33 +02:00 committed by GitHub
parent 187e1cbd55
commit ee7bb54894
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 133 additions and 37 deletions

View File

@ -6,7 +6,7 @@
<groupId>de.gerrygames</groupId> <groupId>de.gerrygames</groupId>
<artifactId>viarewind-legacy-support</artifactId> <artifactId>viarewind-legacy-support</artifactId>
<version>1.4.0</version> <version>1.4.1</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties> <properties>

View File

@ -15,7 +15,7 @@ public class BoundingBoxFixer {
public static void fixLilyPad() { public static void fixLilyPad() {
try { try {
Class<?> blockWaterLilyClass = NMSReflection.getNMSClass("BlockWaterLily"); Class<?> blockWaterLilyClass = NMSReflection.getNMSBlock("BlockWaterLily");
Field boundingBoxField = ReflectionAPI.getFieldAccessible(blockWaterLilyClass, "a"); Field boundingBoxField = ReflectionAPI.getFieldAccessible(blockWaterLilyClass, "a");
Object boundingBox = boundingBoxField.get(null); Object boundingBox = boundingBoxField.get(null);
@ -27,7 +27,7 @@ public class BoundingBoxFixer {
public static void fixLadder() { public static void fixLadder() {
try { try {
Class<?> blockLadderClass = NMSReflection.getNMSClass("BlockLadder"); Class<?> blockLadderClass = NMSReflection.getNMSBlock("BlockLadder");
Field boundingBoxNorthField, boundingBoxSouthField, boundingBoxWestField, boundingBoxEastField; Field boundingBoxNorthField, boundingBoxSouthField, boundingBoxWestField, boundingBoxEastField;
@ -42,11 +42,16 @@ public class BoundingBoxFixer {
boundingBoxWestField = ReflectionAPI.getFieldAccessible(blockLadderClass, "o"); boundingBoxWestField = ReflectionAPI.getFieldAccessible(blockLadderClass, "o");
boundingBoxSouthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "p"); boundingBoxSouthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "p");
boundingBoxNorthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "q"); boundingBoxNorthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "q");
} else { } else if (serverProtocol <= 754) {
boundingBoxEastField = ReflectionAPI.getFieldAccessible(blockLadderClass, "c"); boundingBoxEastField = ReflectionAPI.getFieldAccessible(blockLadderClass, "c");
boundingBoxWestField = ReflectionAPI.getFieldAccessible(blockLadderClass, "d"); boundingBoxWestField = ReflectionAPI.getFieldAccessible(blockLadderClass, "d");
boundingBoxSouthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "e"); boundingBoxSouthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "e");
boundingBoxNorthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "f"); boundingBoxNorthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "f");
} else {
boundingBoxEastField = ReflectionAPI.getFieldAccessible(blockLadderClass, "d");
boundingBoxWestField = ReflectionAPI.getFieldAccessible(blockLadderClass, "e");
boundingBoxSouthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "f");
boundingBoxNorthField = ReflectionAPI.getFieldAccessible(blockLadderClass, "g");
} }
setBoundingBox(boundingBoxEastField.get(null), 0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D); setBoundingBox(boundingBoxEastField.get(null), 0.0D, 0.0D, 0.0D, 0.125D, 1.0D, 1.0D);

View File

@ -1,40 +1,128 @@
package de.gerrygames.viarewind.legacysupport.injector; package de.gerrygames.viarewind.legacysupport.injector;
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.util.Arrays;
public class NMSReflection { public class NMSReflection {
private static String version;
public static String getVersion() { private static int protocolVersion = -1;
return version == null ? version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3] : version; private static final int PROTOCOL_1_17 = 755;
}
public static Class getNMSClass(String name) { private static String version;
try { private static Field playerConnectionField;
return Class.forName("net.minecraft.server." + getVersion() + "." + name);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
public static Class getCraftBukkitClass(String name) { public static String getVersion() {
try { return version == null ? version = Bukkit.getServer().getClass().getPackage().getName().split("\\.")[3] : version;
return Class.forName("org.bukkit.craftbukkit." + getVersion() + "." + name); }
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
public static void sendPacket(Player player, Object packet) { public static int getProtocolVersion() {
try { return protocolVersion == -1 ?
Object nmsPlayer = player.getClass().getMethod("getHandle").invoke(player); protocolVersion = Via.getAPI().getServerVersion().lowestSupportedVersion() :
Object playerConnection = nmsPlayer.getClass().getField("playerConnection").get(nmsPlayer); protocolVersion;
playerConnection.getClass().getMethod("sendPacket", getNMSClass("Packet")).invoke(playerConnection, packet); }
} catch (Exception ex) {
ex.printStackTrace(); public static Class<?> getBlockPositionClass() {
} try {
} if (getProtocolVersion() >= PROTOCOL_1_17) {
return Class.forName("net.minecraft.core.BlockPosition");
}
return getLegacyNMSClass("BlockPosition");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
public static Class<?> getNMSBlock(String name) {
try {
if (getProtocolVersion() >= PROTOCOL_1_17) {
return Class.forName("net.minecraft.world.level.block." + name);
}
return getLegacyNMSClass(name);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
@SuppressWarnings("rawtypes")
public static Class getSoundCategoryClass() {
try {
if (getProtocolVersion() >= PROTOCOL_1_17) {
return Class.forName("net.minecraft.sounds.SoundCategory");
}
return getLegacyNMSClass("SoundCategory");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
public static Class<?> getPacketClass() {
try {
if (getProtocolVersion() >= PROTOCOL_1_17) {
return Class.forName("net.minecraft.network.protocol.Packet");
}
return getLegacyNMSClass("Packet");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
public static Class<?> getGamePacketClass(String packetType) {
try {
if (getProtocolVersion() >= PROTOCOL_1_17) {
return Class.forName("net.minecraft.network.protocol.game." + packetType);
}
return getLegacyNMSClass(packetType);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
public static Class<?> getPlayerConnectionClass() {
try {
if (getProtocolVersion() >= PROTOCOL_1_17) {
return Class.forName("net.minecraft.server.network.PlayerConnection");
}
return getLegacyNMSClass("PlayerConnection");
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
public static Class<?> getLegacyNMSClass(String name) throws ClassNotFoundException {
return Class.forName("net.minecraft.server." + getVersion() + "." + name);
}
public static Class<?> getCraftBukkitClass(String name) {
try {
return Class.forName("org.bukkit.craftbukkit." + getVersion() + "." + name);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
}
return null;
}
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);
playerConnection.getClass().getMethod("sendPacket", getPacketClass()).invoke(playerConnection, packet);
} catch (Exception ex) {
ex.printStackTrace();
}
}
} }

View File

@ -93,8 +93,11 @@ public class SoundListener implements Listener {
try { 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.getNMSClass("BlockPosition"); Class<?> blockPositionClass = NMSReflection.getBlockPositionClass();
Object blockPosition = blockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(block.getX(), block.getY(), block.getZ()); Object blockPosition = null;
if (blockPositionClass != null) {
blockPosition = blockPositionClass.getConstructor(int.class, int.class, int.class).newInstance(block.getX(), block.getY(), block.getZ());
}
Object blockData = nmsWorld.getClass().getSuperclass().getMethod("getType", blockPositionClass).invoke(nmsWorld, blockPosition); Object blockData = nmsWorld.getClass().getSuperclass().getMethod("getType", blockPositionClass).invoke(nmsWorld, blockPosition);
Method getBlock = blockData.getClass().getMethod("getBlock"); Method getBlock = blockData.getClass().getMethod("getBlock");
getBlock.setAccessible(true); getBlock.setAccessible(true);
@ -134,7 +137,7 @@ public class SoundListener implements Listener {
Object soundEffect = soundEffectMethod.invoke(soundType); Object soundEffect = soundEffectMethod.invoke(soundType);
float volume = (float) volumeMethod.invoke(soundType); float volume = (float) volumeMethod.invoke(soundType);
float pitch = (float) pitchMethod.invoke(soundType); float pitch = (float) pitchMethod.invoke(soundType);
Object soundCategory = Enum.valueOf(NMSReflection.getNMSClass("SoundCategory"), "BLOCKS"); Object soundCategory = Enum.valueOf(NMSReflection.getSoundCategoryClass(), "BLOCKS");
volume = (volume + 1.0f) / 2.0f; volume = (volume + 1.0f) / 2.0f;
pitch *= 0.8; pitch *= 0.8;
@ -147,7 +150,7 @@ public class SoundListener implements Listener {
private static void playSound(Player player, Object soundEffect, Object soundCategory, double x, double y, double z, float volume, float pitch) { private static void playSound(Player player, Object soundEffect, Object soundCategory, double x, double y, double z, float volume, float pitch) {
try { try {
Object packet = NMSReflection.getNMSClass("PacketPlayOutNamedSoundEffect").getConstructor( Object packet = NMSReflection.getGamePacketClass("PacketPlayOutNamedSoundEffect").getConstructor(
soundEffect.getClass(), soundCategory.getClass(), soundEffect.getClass(), soundCategory.getClass(),
double.class, double.class, double.class, double.class, double.class, double.class,
float.class, float.class float.class, float.class