Merge pull request #1018 from 7kasper/patch-1

ProtocolSupport  <3 ViaVersion
This commit is contained in:
Myles 2018-09-10 20:49:45 +01:00 committed by GitHub
commit 3a4d425a1c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 92 additions and 1 deletions

View File

@ -3,8 +3,18 @@ package us.myles.ViaVersion.bukkit.classgenerator;
import javassist.*;
import javassist.expr.ConstructorCall;
import javassist.expr.ExprEditor;
import java.lang.reflect.Method;
import java.util.Arrays;
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 us.myles.ViaVersion.ViaVersionPlugin;
import us.myles.ViaVersion.api.ViaVersion;
import us.myles.ViaVersion.bukkit.handlers.BukkitDecodeHandler;
import us.myles.ViaVersion.bukkit.handlers.BukkitEncodeHandler;
@ -13,6 +23,7 @@ import us.myles.ViaVersion.bukkit.util.NMSUtil;
public class ClassGenerator {
private static HandlerConstructor constructor = new BasicHandlerConstructor();
private static String psPackage = null;
private static Class psConnectListener;
public static HandlerConstructor getConstructor() {
return constructor;
@ -37,6 +48,7 @@ public class ClassGenerator {
Class encodeSuper;
Class decodeSuper;
if (isMultiplatformPS()) {
psConnectListener = makePSConnectListener(pool);
return;
} else {
String psPackage = getOldPSPackage();
@ -166,6 +178,81 @@ public class ClassGenerator {
return null;
}
private static Class makePSConnectListener(ClassPool pool) {
try {
// Reference classes
CtClass toExtend = pool.get("protocolsupport.api.Connection$PacketListener");
CtClass connectListenerClazz = pool.makeClass("us.myles.ViaVersion.classgenerator.generated.ProtocolSupportConnectListener");
connectListenerClazz.setSuperclass(toExtend);
// Import packages
pool.importPackage("java.util.Arrays");
pool.importPackage("us.myles.ViaVersion.api.protocol.ProtocolRegistry");
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").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.
+ " int protoVersion = ((PacketHandshakingInSetProtocol) event.getPacket()).getProtocolVersion();\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 (protoVersion == us.myles.ViaVersion.api.protocol.ProtocolRegistry.SERVER_PROTOCOL) {\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 connectListenerClazz.toClass(HandlerConstructor.class.getClassLoader());
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void registerPSConnectListener(ViaVersionPlugin plugin) {
if (getPSConnectListener() != 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(Listener listener, Event event) throws EventException {
try {
Object connection = event.getClass().getMethod("getConnection").invoke(event);
Object connectListener = getPSConnectListener().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 String getOldPSPackage() {
if (psPackage == null) {
try {

View File

@ -18,6 +18,7 @@ import us.myles.ViaVersion.bukkit.listeners.protocol1_9to1_8.*;
import us.myles.ViaVersion.bukkit.providers.BukkitInventoryQuickMoveProvider;
import us.myles.ViaVersion.bukkit.providers.BukkitViaBulkChunkTranslator;
import us.myles.ViaVersion.bukkit.providers.BukkitViaMovementTransmitter;
import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.protocol1_12to1_11_1.providers.InventoryQuickMoveProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.BulkChunkTranslatorProvider;
@ -57,6 +58,9 @@ public class BukkitViaLoader implements ViaPlatformLoader {
/* Base Protocol */
final ViaVersionPlugin plugin = (ViaVersionPlugin) Bukkit.getPluginManager().getPlugin("ViaVersion");
// Add ProtocolSupport ConnectListener if necessary.
ClassGenerator.registerPSConnectListener(plugin);
registerListener(new Listener() {
@EventHandler
public void onPlayerQuit(PlayerQuitEvent e) {