Remove javassist dependency, reduces file size by ~1mb

This commit is contained in:
Nassim Jahnke 2022-10-25 17:31:13 +02:00
parent 0355447d53
commit 6095128007
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
19 changed files with 235 additions and 230 deletions

View File

@ -25,7 +25,6 @@ tasks {
publishShadowJar()
fun ShadowJar.configureRelocations() {
relocate("javassist", "com.viaversion.viaversion.libs.javassist")
relocate("com.google.gson", "com.viaversion.viaversion.libs.gson")
relocate("com.github.steveice10.opennbt", "com.viaversion.viaversion.libs.opennbt")
relocate("it.unimi.dsi.fastutil", "com.viaversion.viaversion.libs.fastutil")

View File

@ -1,10 +1,10 @@
dependencies {
implementation(projects.viaversionBukkitLegacy)
implementation(projects.viaversionCommon)
implementation(libs.javassist)
compileOnly(libs.paper) {
exclude("junit", "junit")
exclude("com.google.code.gson", "gson")
exclude("javax.persistence", "persistence-api")
}
compileOnly(projects.compat.protocolsupportCompat)
}

View File

@ -26,7 +26,6 @@ import com.viaversion.viaversion.api.data.MappingDataLoader;
import com.viaversion.viaversion.api.platform.PlatformTask;
import com.viaversion.viaversion.api.platform.UnsupportedSoftware;
import com.viaversion.viaversion.api.platform.ViaPlatform;
import com.viaversion.viaversion.bukkit.classgenerator.ClassGenerator;
import com.viaversion.viaversion.bukkit.commands.BukkitCommandHandler;
import com.viaversion.viaversion.bukkit.commands.BukkitCommandSender;
import com.viaversion.viaversion.bukkit.platform.BukkitViaAPI;
@ -49,7 +48,6 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import java.util.logging.Level;
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> {
private static ViaVersionPlugin instance;
@ -90,12 +88,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
MappingDataLoader.enableMappingsCache();
}
try {
ClassGenerator.generate();
} catch (Exception e) {
getLogger().log(Level.WARNING, "Error generating classes for compatibility layer", e);
}
lateBind = !((BukkitViaInjector) Via.getManager().getInjector()).isBinded();
getLogger().info("ViaVersion " + getDescription().getVersion() + " is now loaded" + (lateBind ? ", waiting for boot. (late-bind)" : ", injecting!"));

View File

@ -1,207 +0,0 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.bukkit.classgenerator;
import com.viaversion.viaversion.ViaVersionPlugin;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.bukkit.util.NMSUtil;
import com.viaversion.viaversion.classgenerator.generated.HandlerSupplier;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtNewConstructor;
import javassist.CtNewMethod;
import javassist.LoaderClassPath;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.plugin.EventExecutor;
import org.bukkit.plugin.Plugin;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.reflect.Method;
//TODO maybe clean this up a bit 👀
public final class ClassGenerator {
private static final boolean useModules = hasModuleMethod();
private static Class psConnectListener;
public static void generate() {
if (ViaVersionPlugin.getInstance().isProtocolSupport() && isMultiplatformPS()) {
ClassPool pool = ClassPool.getDefault();
pool.insertClassPath(new LoaderClassPath(Bukkit.class.getClassLoader()));
for (Plugin p : Bukkit.getPluginManager().getPlugins()) {
pool.insertClassPath(new LoaderClassPath(p.getClass().getClassLoader()));
}
Via.getPlatform().getLogger().info("Generating ProtocolSupport compatibility connect listener...");
psConnectListener = makePSConnectListener(pool);
}
}
private static Class makePSConnectListener(ClassPool pool) {
HandshakeProtocolType type = handshakeVersionMethod();
try {
// Reference classes
CtClass toExtend = pool.get("protocolsupport.api.Connection$PacketListener");
CtClass connectListenerClazz = pool.makeClass("com.viaversion.viaversion.classgenerator.generated.ProtocolSupportConnectListener");
connectListenerClazz.setSuperclass(toExtend);
// Import packages
pool.importPackage("java.util.Arrays");
pool.importPackage("protocolsupport.api.ProtocolVersion");
pool.importPackage("protocolsupport.api.ProtocolType");
pool.importPackage("protocolsupport.api.Connection");
pool.importPackage("protocolsupport.api.Connection.PacketListener");
pool.importPackage("protocolsupport.api.Connection.PacketListener.PacketEvent");
pool.importPackage("protocolsupport.protocol.ConnectionImpl");
pool.importPackage(NMSUtil.nms(
"PacketHandshakingInSetProtocol",
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol"
).getName());
// Add connection reference field
connectListenerClazz.addField(CtField.make("private ConnectionImpl connection;", connectListenerClazz));
// Bake constructor
connectListenerClazz.addConstructor(CtNewConstructor.make(
"public ProtocolSupportConnectListener (ConnectionImpl connection) {\n"
+ " this.connection = connection;\n"
+ "}", connectListenerClazz));
// Add the listening method
connectListenerClazz.addMethod(CtNewMethod.make(
// On packet receive
"public void onPacketReceiving(protocolsupport.api.Connection.PacketListener.PacketEvent event) {\n"
// Check if we are getting handshake packet.
+ " if (event.getPacket() instanceof PacketHandshakingInSetProtocol) {\n"
// Get protocol version.
+ " PacketHandshakingInSetProtocol packet = (PacketHandshakingInSetProtocol) event.getPacket();\n"
+ " int protoVersion = packet." + type.methodName() + "();\n"
// ViaVersion has at this point already spoofed the connectionversion. (Since it is higher up the pipeline)
// If via has put the protoVersion to the server we can spoof ProtocolSupport's version.
+ " if (connection.getVersion() == ProtocolVersion.MINECRAFT_FUTURE && protoVersion == com.viaversion.viaversion.api.Via.getAPI().getServerVersion().lowestSupportedVersion()) {\n"
+ " connection.setVersion(ProtocolVersion.getLatest(ProtocolType.PC));\n"
+ " }\n"
+ " }\n"
// Id version is not serverversion viaversion will not spoof. ProtocolSupport will handle the rest.
// In any case, remove the packet listener and wrap up.
+ " connection.removePacketListener(this);\n"
+ "}", connectListenerClazz));
return toClass(connectListenerClazz);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void registerPSConnectListener(ViaVersionPlugin plugin) {
if (psConnectListener != null) {
try {
Class<? extends Event> connectionOpenEvent = (Class<? extends Event>) Class.forName("protocolsupport.api.events.ConnectionOpenEvent");
Bukkit.getPluginManager().registerEvent(connectionOpenEvent, new Listener() {
}, EventPriority.HIGH, new EventExecutor() {
@Override
public void execute(@NonNull Listener listener, @NonNull Event event) throws EventException {
try {
Object connection = event.getClass().getMethod("getConnection").invoke(event);
Object connectListener = psConnectListener.getConstructor(connection.getClass()).newInstance(connection);
Method addConnectListener = connection.getClass().getMethod("addPacketListener", Class.forName("protocolsupport.api.Connection$PacketListener"));
addConnectListener.invoke(connection, connectListener);
} catch (Exception e) {
e.printStackTrace();
}
}
}, plugin);
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static Class getPSConnectListener() {
return psConnectListener;
}
public static boolean isMultiplatformPS() {
try {
Class.forName("protocolsupport.zplatform.impl.spigot.network.pipeline.SpigotPacketEncoder");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
public static HandshakeProtocolType handshakeVersionMethod() {
Class<?> clazz = null;
// Check for the mapped method
try {
clazz = NMSUtil.nms(
"PacketHandshakingInSetProtocol",
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol"
);
clazz.getMethod("getProtocolVersion");
return HandshakeProtocolType.MAPPED;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException ignored) {
}
// Check for obfusacted b/c methods
try {
if (clazz.getMethod("b").getReturnType() == int.class) {
return HandshakeProtocolType.OBFUSCATED_OLD;
} else if (clazz.getMethod("c").getReturnType() == int.class) {
return HandshakeProtocolType.OBFUSCATED_NEW;
}
throw new UnsupportedOperationException("Protocol version method not found in " + clazz.getSimpleName());
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
@SuppressWarnings("deprecation")
private static Class<?> toClass(CtClass ctClass) throws CannotCompileException {
return useModules ? ctClass.toClass(HandlerSupplier.class) : ctClass.toClass(HandlerSupplier.class.getClassLoader());
}
private static boolean hasModuleMethod() {
try {
Class.class.getDeclaredMethod("getModule");
return true;
} catch (NoSuchMethodException e) {
return false;
}
}
private enum HandshakeProtocolType {
MAPPED("getProtocolVersion"),
OBFUSCATED_OLD("b"),
OBFUSCATED_NEW("c");
private final String methodName;
HandshakeProtocolType(String methodName) {
this.methodName = methodName;
}
public String methodName() {
return methodName;
}
}
}

View File

@ -0,0 +1,107 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.bukkit.compat;
import com.viaversion.viaversion.ViaVersionPlugin;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.bukkit.util.NMSUtil;
import org.bukkit.Bukkit;
import org.bukkit.event.Event;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import java.util.logging.Level;
public final class ProtocolSupportCompat {
public static void registerPSConnectListener(ViaVersionPlugin plugin) {
if (isMultiplatformPS()) {
Via.getPlatform().getLogger().info("Registering ProtocolSupport compat connection listener");
try {
//noinspection unchecked
Class<? extends Event> connectionOpenEvent = (Class<? extends Event>) Class.forName("protocolsupport.api.events.ConnectionOpenEvent");
Bukkit.getPluginManager().registerEvent(connectionOpenEvent, new Listener() {
}, EventPriority.HIGH, (listener, event) -> {
try {
Object connection = event.getClass().getMethod("getConnection").invoke(event);
ProtocolSupportConnectionListener connectListener = new ProtocolSupportConnectionListener(connection);
ProtocolSupportConnectionListener.ADD_PACKET_LISTENER_METHOD.invoke(connection, connectListener);
} catch (Exception e) {
Via.getPlatform().getLogger().log(Level.WARNING, "Error when handling ProtocolSupport event", e);
}
}, plugin);
} catch (Exception e) {
Via.getPlatform().getLogger().log(Level.WARNING, "Unable to register ProtocolSupport listener", e);
}
}
}
public static boolean isMultiplatformPS() {
try {
Class.forName("protocolsupport.zplatform.impl.spigot.network.pipeline.SpigotPacketEncoder");
return true;
} catch (ClassNotFoundException e) {
return false;
}
}
public static HandshakeProtocolType handshakeVersionMethod() {
Class<?> clazz = null;
// Check for the mapped method
try {
clazz = NMSUtil.nms(
"PacketHandshakingInSetProtocol",
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol"
);
clazz.getMethod("getProtocolVersion");
return HandshakeProtocolType.MAPPED;
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
} catch (NoSuchMethodException ignored) {
}
// Check for obfusacted b/c methods
try {
if (clazz.getMethod("b").getReturnType() == int.class) {
return HandshakeProtocolType.OBFUSCATED_B;
} else if (clazz.getMethod("c").getReturnType() == int.class) {
return HandshakeProtocolType.OBFUSCATED_C;
}
throw new UnsupportedOperationException("Protocol version method not found in " + clazz.getSimpleName());
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
public enum HandshakeProtocolType {
MAPPED("getProtocolVersion"),
OBFUSCATED_B("b"),
OBFUSCATED_C("c");
private final String methodName;
HandshakeProtocolType(String methodName) {
this.methodName = methodName;
}
public String methodName() {
return methodName;
}
}
}

View File

@ -0,0 +1,93 @@
/*
* This file is part of ViaVersion - https://github.com/ViaVersion/ViaVersion
* Copyright (C) 2016-2022 ViaVersion and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.viaversion.viaversion.bukkit.compat;
import com.viaversion.viaversion.api.Via;
import com.viaversion.viaversion.bukkit.util.NMSUtil;
import protocolsupport.api.Connection;
import java.lang.reflect.Method;
final class ProtocolSupportConnectionListener extends Connection.PacketListener {
static final Method ADD_PACKET_LISTENER_METHOD;
private static final Class<?> HANDSHAKE_PACKET_CLASS;
private static final Method GET_VERSION_METHOD;
private static final Method SET_VERSION_METHOD;
private static final Method REMOVE_PACKET_LISTENER_METHOD;
private static final Method GET_LATEST_METHOD;
private static final Object PROTOCOL_VERSION_MINECRAFT_FUTURE;
private static final Object PROTOCOL_TYPE_PC;
static {
try {
HANDSHAKE_PACKET_CLASS = NMSUtil.nms(
"PacketHandshakingInSetProtocol",
"net.minecraft.network.protocol.handshake.PacketHandshakingInSetProtocol"
);
final Class<?> connectionImplClass = Class.forName("protocolsupport.protocol.ConnectionImpl");
final Class<?> connectionClass = Class.forName("protocolsupport.api.Connection");
final Class<?> packetListenerClass = Class.forName("protocolsupport.api.Connection$PacketListener");
final Class<?> protocolVersionClass = Class.forName("protocolsupport.api.ProtocolVersion");
final Class<?> protocolTypeClass = Class.forName("protocolsupport.api.ProtocolType");
GET_VERSION_METHOD = connectionClass.getDeclaredMethod("getVersion");
SET_VERSION_METHOD = connectionImplClass.getDeclaredMethod("setVersion", protocolVersionClass);
PROTOCOL_VERSION_MINECRAFT_FUTURE = protocolVersionClass.getDeclaredField("MINECRAFT_FUTURE").get(null);
GET_LATEST_METHOD = protocolVersionClass.getDeclaredMethod("getLatest", protocolTypeClass);
PROTOCOL_TYPE_PC = protocolTypeClass.getDeclaredField("PC").get(null);
ADD_PACKET_LISTENER_METHOD = connectionClass.getDeclaredMethod("addPacketListener", packetListenerClass);
REMOVE_PACKET_LISTENER_METHOD = connectionClass.getDeclaredMethod("removePacketListener", packetListenerClass);
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
private final Object connection;
ProtocolSupportConnectionListener(final Object connection) {
this.connection = connection;
}
@Override
public void onPacketReceiving(final Connection.PacketListener.PacketEvent event) {
try {
// Check if we are getting handshake packet.
if (HANDSHAKE_PACKET_CLASS.isInstance(event.getPacket()) && GET_VERSION_METHOD.invoke(connection) == PROTOCOL_VERSION_MINECRAFT_FUTURE) {
final Object packet = event.getPacket();
final int protocolVersion;
try {
protocolVersion = (int) HANDSHAKE_PACKET_CLASS.getDeclaredMethod(ProtocolSupportCompat.handshakeVersionMethod().methodName()).invoke(packet);
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
// ViaVersion has at this point already spoofed the connectionversion. (Since it is higher up the pipeline)
// If via has put the protoVersion to the server we can spoof ProtocolSupport's version.
if (protocolVersion == Via.getAPI().getServerVersion().lowestSupportedVersion()) {
SET_VERSION_METHOD.invoke(connection, GET_LATEST_METHOD.invoke(null, PROTOCOL_TYPE_PC));
}
}
// Id version is not serverversion viaversion will not spoof. ProtocolSupport will handle the rest.
// In any case, remove the packet listener and wrap up.
REMOVE_PACKET_LISTENER_METHOD.invoke(connection, this);
} catch (final ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
}

View File

@ -23,7 +23,7 @@ import com.viaversion.viaversion.api.connection.UserConnection;
import com.viaversion.viaversion.api.minecraft.item.Item;
import com.viaversion.viaversion.api.platform.ViaPlatformLoader;
import com.viaversion.viaversion.api.protocol.version.ProtocolVersion;
import com.viaversion.viaversion.bukkit.classgenerator.ClassGenerator;
import com.viaversion.viaversion.bukkit.compat.ProtocolSupportCompat;
import com.viaversion.viaversion.bukkit.listeners.JoinListener;
import com.viaversion.viaversion.bukkit.listeners.UpdateListener;
import com.viaversion.viaversion.bukkit.listeners.multiversion.PlayerSneakListener;
@ -88,7 +88,10 @@ public class BukkitViaLoader implements ViaPlatformLoader {
final ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
// Add ProtocolSupport ConnectListener if necessary.
ClassGenerator.registerPSConnectListener(plugin);
if (plugin.isProtocolSupport()) {
ProtocolSupportCompat.registerPSConnectListener(plugin);
}
int serverProtocolVersion = Via.getAPI().getServerVersion().lowestSupportedVersion();
/* 1.9 client to 1.8 server */

View File

@ -1,5 +1,5 @@
dependencies {
implementation(projects.viaversionCommon)
implementation(projects.javaCompat)
implementation(projects.compat)
compileOnly(libs.bungee)
}

4
compat/build.gradle.kts Normal file
View File

@ -0,0 +1,4 @@
dependencies {
api(projects.compat.javaCompatCommon)
api(projects.compat.javaCompatUnsafe)
}

View File

@ -0,0 +1,3 @@
dependencies {
api(projects.compat.javaCompatCommon)
}

View File

@ -0,0 +1,2 @@
dependencies {
}

View File

@ -0,0 +1,18 @@
package protocolsupport.api;
public abstract class Connection {
public abstract static class PacketListener {
public void onPacketReceiving(PacketEvent event) {
throw new UnsupportedOperationException();
}
public static class PacketEvent {
public Object getPacket() {
throw new UnsupportedOperationException();
}
}
}
}

View File

@ -7,7 +7,6 @@ gson = "2.8.8"
fastutil = "8.5.6"
flare = "2.0.0"
openNBT = "2.1"
javassist = "3.28.0-GA"
# Common provided
netty = "4.0.20.Final"
@ -38,7 +37,6 @@ fastutil = { group = "it.unimi.dsi", name = "fastutil", version.ref = "fastutil"
flare = { group = "space.vectrix.flare", name = "flare", version.ref = "flare" }
flareFastutil = { group = "space.vectrix.flare", name = "flare-fastutil", version.ref = "flare" }
openNBT = { group = "com.viaversion", name = "opennbt", version.ref = "openNBT" }
javassist = { group = "org.javassist", name = "javassist", version.ref = "javassist" }
netty = { group = "io.netty", name = "netty-all", version.ref = "netty" }
guava = { group = "com.google.guava", name = "guava", version.ref = "guava" }

View File

@ -1,4 +0,0 @@
dependencies {
api(projects.javaCompat.javaCompatCommon)
api(projects.javaCompat.javaCompatUnsafe)
}

View File

@ -1,3 +0,0 @@
dependencies {
api(projects.javaCompat.javaCompatCommon)
}

View File

@ -27,7 +27,7 @@ rootProject.name = "viaversion-parent"
includeBuild("build-logic")
include("adventure")
include("java-compat", "java-compat:java-compat-common", "java-compat:java-compat-unsafe")
include("compat", "compat:java-compat-common", "compat:java-compat-unsafe", "compat:protocolsupport-compat")
setupViaSubproject("api")
setupViaSubproject("api-legacy")