mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-23 02:25:19 +01:00
Basic compatibility with ProtocolSupport, doesn't seem to work with 1.6.4 due to issues with our Login Handler.
This commit is contained in:
parent
91344a0b50
commit
6534a5414e
@ -9,6 +9,7 @@ import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import org.bukkit.plugin.PluginDescriptionFile;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import us.myles.ViaVersion.api.Pair;
|
||||
@ -48,6 +49,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
private boolean compatSpigotBuild = false;
|
||||
private boolean spigot = true;
|
||||
private boolean lateBind = false;
|
||||
private boolean protocolSupport = false;
|
||||
@Getter
|
||||
private ViaConfig conf;
|
||||
|
||||
@ -56,6 +58,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
// Config magic
|
||||
conf = new ViaConfig(this);
|
||||
ViaVersion.setInstance(this);
|
||||
|
||||
// Handle reloads
|
||||
if (System.getProperty("ViaVersion") != null) {
|
||||
if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) {
|
||||
@ -69,19 +72,25 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Spigot detector
|
||||
try {
|
||||
Class.forName("org.spigotmc.SpigotConfig");
|
||||
} catch (ClassNotFoundException e) {
|
||||
spigot = false;
|
||||
}
|
||||
|
||||
// Check if it's a spigot build with a protocol mod
|
||||
try {
|
||||
compatSpigotBuild = ReflectionUtil.nms("PacketEncoder").getDeclaredField("version") != null;
|
||||
} catch (Exception e) {
|
||||
compatSpigotBuild = false;
|
||||
}
|
||||
// Generate classes needed (only works if it's compat)
|
||||
|
||||
// Check if we're using protocol support too
|
||||
protocolSupport = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
|
||||
|
||||
// Generate classes needed (only works if it's compat or ps)
|
||||
ClassGenerator.generate();
|
||||
lateBind = !isBinded();
|
||||
|
||||
@ -435,6 +444,10 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isProtocolSupport() {
|
||||
return protocolSupport;
|
||||
}
|
||||
|
||||
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||
return portedPlayers;
|
||||
}
|
||||
|
@ -125,4 +125,11 @@ public interface ViaVersionAPI {
|
||||
* @return True if spigot
|
||||
*/
|
||||
boolean isSpigot();
|
||||
|
||||
/**
|
||||
* Gets if protocol support is also being used.
|
||||
*
|
||||
* @return True if it is being used.
|
||||
*/
|
||||
boolean isProtocolSupport();
|
||||
}
|
||||
|
@ -3,6 +3,8 @@ package us.myles.ViaVersion.classgenerator;
|
||||
import javassist.*;
|
||||
import javassist.expr.ConstructorCall;
|
||||
import javassist.expr.ExprEditor;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.plugin.Plugin;
|
||||
import us.myles.ViaVersion.api.ViaVersion;
|
||||
import us.myles.ViaVersion.handlers.ViaDecodeHandler;
|
||||
import us.myles.ViaVersion.handlers.ViaEncodeHandler;
|
||||
@ -10,72 +12,93 @@ import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
public class ClassGenerator {
|
||||
private static HandlerConstructor constructor = new BasicHandlerConstructor();
|
||||
private static String psPackage = null;
|
||||
|
||||
public static HandlerConstructor getConstructor() {
|
||||
return constructor;
|
||||
}
|
||||
|
||||
public static void generate() {
|
||||
if(!ViaVersion.getInstance().isCompatSpigotBuild()) return; // Use Basic Handler as not needed.
|
||||
if (ViaVersion.getInstance().isCompatSpigotBuild() || ViaVersion.getInstance().isProtocolSupport()) {
|
||||
try {
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
for (Plugin p : Bukkit.getPluginManager().getPlugins()) {
|
||||
pool.insertClassPath(new LoaderClassPath(p.getClass().getClassLoader()));
|
||||
}
|
||||
|
||||
try {
|
||||
ClassPool pool = ClassPool.getDefault();
|
||||
pool.insertClassPath(new LoaderClassPath(ClassGenerator.class.getClassLoader()));
|
||||
// Generate the classes
|
||||
transformSuperclass(pool, ViaDecodeHandler.class, ReflectionUtil.nms("PacketDecoder"));
|
||||
transformSuperclass(pool, ViaEncodeHandler.class, ReflectionUtil.nms("PacketEncoder"));
|
||||
if (ViaVersion.getInstance().isCompatSpigotBuild()) {
|
||||
Class decodeSuper = ReflectionUtil.nms("PacketDecoder");
|
||||
Class encodeSuper = ReflectionUtil.nms("PacketEncoder");
|
||||
// Generate the classes
|
||||
addSpigotCompatibility(pool, ViaDecodeHandler.class, decodeSuper);
|
||||
addSpigotCompatibility(pool, ViaEncodeHandler.class, encodeSuper);
|
||||
} else {
|
||||
Class decodeSuper = Class.forName(getPSPackage() + ".wrapped.WrappedDecoder");
|
||||
Class encodeSuper = Class.forName(getPSPackage() + ".wrapped.WrappedEncoder");
|
||||
// Generate the classes
|
||||
addPSCompatibility(pool, ViaDecodeHandler.class, decodeSuper);
|
||||
addPSCompatibility(pool, ViaEncodeHandler.class, encodeSuper);
|
||||
}
|
||||
|
||||
// Implement Constructor
|
||||
CtClass generated = pool.makeClass("us.myles.ViaVersion.classgenerator.generated.GeneratedConstructor");
|
||||
CtClass handlerInterface = pool.get(HandlerConstructor.class.getName());
|
||||
|
||||
generated.setInterfaces(new CtClass[]{handlerInterface});
|
||||
// Import required classes
|
||||
pool.importPackage("us.myles.ViaVersion.classgenerator.generated");
|
||||
pool.importPackage("us.myles.ViaVersion.classgenerator");
|
||||
pool.importPackage("us.myles.ViaVersion.api.data");
|
||||
pool.importPackage("io.netty.handler.codec");
|
||||
// Implement Methods
|
||||
generated.addMethod(CtMethod.make("public MessageToByteEncoder newEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {\n" +
|
||||
" return new ViaEncodeHandler(info, minecraftEncoder);\n" +
|
||||
" }", generated));
|
||||
generated.addMethod(CtMethod.make("public ByteToMessageDecoder newDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) {\n" +
|
||||
" return new ViaDecodeHandler(info, minecraftDecoder);\n" +
|
||||
" }", generated));
|
||||
// Implement Constructor
|
||||
CtClass generated = pool.makeClass("us.myles.ViaVersion.classgenerator.generated.GeneratedConstructor");
|
||||
CtClass handlerInterface = pool.get(HandlerConstructor.class.getName());
|
||||
|
||||
constructor = (HandlerConstructor) generated.toClass(HandlerConstructor.class.getClassLoader()).newInstance();
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (CannotCompileException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
generated.setInterfaces(new CtClass[]{handlerInterface});
|
||||
// Import required classes
|
||||
pool.importPackage("us.myles.ViaVersion.classgenerator.generated");
|
||||
pool.importPackage("us.myles.ViaVersion.classgenerator");
|
||||
pool.importPackage("us.myles.ViaVersion.api.data");
|
||||
pool.importPackage("io.netty.handler.codec");
|
||||
// Implement Methods
|
||||
generated.addMethod(CtMethod.make("public MessageToByteEncoder newEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {\n" +
|
||||
" return new ViaEncodeHandler(info, minecraftEncoder);\n" +
|
||||
" }", generated));
|
||||
generated.addMethod(CtMethod.make("public ByteToMessageDecoder newDecodeHandler(UserConnection info, ByteToMessageDecoder minecraftDecoder) {\n" +
|
||||
" return new ViaDecodeHandler(info, minecraftDecoder);\n" +
|
||||
" }", generated));
|
||||
|
||||
constructor = (HandlerConstructor) generated.toClass(HandlerConstructor.class.getClassLoader()).newInstance();
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (CannotCompileException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InstantiationException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Class transformSuperclass(ClassPool pool, Class input, Class superclass) {
|
||||
private static Class addSpigotCompatibility(ClassPool pool, Class input, Class superclass) {
|
||||
String newName = "us.myles.ViaVersion.classgenerator.generated." + input.getSimpleName();
|
||||
|
||||
try {
|
||||
CtClass toExtend = pool.get(superclass.getName());
|
||||
CtClass generated = pool.getAndRename(input.getName(), newName);
|
||||
generated.setSuperclass(toExtend);
|
||||
// Modify constructor to call super
|
||||
if(generated.getConstructors().length != 0) {
|
||||
generated.getConstructors()[0].instrument(new ExprEditor() {
|
||||
@Override
|
||||
public void edit(ConstructorCall c) throws CannotCompileException {
|
||||
if (c.isSuper()) {
|
||||
// Constructor for both has a stats thing.
|
||||
c.replace("super(null);");
|
||||
}
|
||||
super.edit(c);
|
||||
if (superclass != null) {
|
||||
CtClass toExtend = pool.get(superclass.getName());
|
||||
generated.setSuperclass(toExtend);
|
||||
|
||||
// If it's NMS satisfy constructor.
|
||||
if (superclass.getName().startsWith("net.minecraft")) {
|
||||
// Modify constructor to call super
|
||||
if (generated.getConstructors().length != 0) {
|
||||
generated.getConstructors()[0].instrument(new ExprEditor() {
|
||||
@Override
|
||||
public void edit(ConstructorCall c) throws CannotCompileException {
|
||||
if (c.isSuper()) {
|
||||
// Constructor for both has a stats thing.
|
||||
c.replace("super(null);");
|
||||
}
|
||||
super.edit(c);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return generated.toClass(HandlerConstructor.class.getClassLoader());
|
||||
} catch (NotFoundException e) {
|
||||
@ -85,4 +108,58 @@ public class ClassGenerator {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Class addPSCompatibility(ClassPool pool, Class input, Class superclass) {
|
||||
String newName = "us.myles.ViaVersion.classgenerator.generated." + input.getSimpleName();
|
||||
|
||||
try {
|
||||
CtClass generated = pool.getAndRename(input.getName(), newName);
|
||||
if (superclass != null) {
|
||||
CtClass toExtend = pool.get(superclass.getName());
|
||||
generated.setSuperclass(toExtend);
|
||||
|
||||
// Override setRealEncoder / setRealDecoder
|
||||
pool.importPackage(getPSPackage());
|
||||
pool.importPackage(getPSPackage() + ".wrapped");
|
||||
if (superclass.getName().endsWith("Decoder")) {
|
||||
// Decoder
|
||||
generated.addMethod(CtMethod.make("public void setRealDecoder(IPacketDecoder dec) {\n" +
|
||||
" WrappedDecoder decoder = new WrappedDecoder();" +
|
||||
" decoder.setRealDecoder(dec);\n" +
|
||||
" this.minecraftDecoder = decoder;\n" +
|
||||
" }", generated));
|
||||
} else {
|
||||
// Encoder
|
||||
generated.addMethod(CtMethod.make("public void setRealEncoder(IPacketEncoder enc) {\n" +
|
||||
" WrappedEncoder encoder = new WrappedEncoder();" +
|
||||
" encoder.setRealEncoder(enc);\n" +
|
||||
" this.minecraftEncoder = encoder;\n" +
|
||||
" }", generated));
|
||||
}
|
||||
}
|
||||
return generated.toClass(HandlerConstructor.class.getClassLoader());
|
||||
} catch (NotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (CannotCompileException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String getPSPackage() {
|
||||
if (psPackage == null) {
|
||||
try {
|
||||
Class.forName("protocolsupport.protocol.core.IPacketDecoder");
|
||||
psPackage = "protocolsupport.protocol.core";
|
||||
} catch (ClassNotFoundException e) {
|
||||
try {
|
||||
Class.forName("protocolsupport.protocol.pipeline.IPacketDecoder");
|
||||
psPackage = "protocolsupport.protocol.pipeline";
|
||||
} catch (ClassNotFoundException e1) {
|
||||
psPackage = "unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
return psPackage;
|
||||
}
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ author: _MylesC
|
||||
version: ${project.version}
|
||||
load: postworld
|
||||
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, PacketListenerApi, SkinRestorer]
|
||||
softdepend: [ProtocolSupport]
|
||||
commands:
|
||||
viaversion:
|
||||
description: Shows ViaVersion Version and more.
|
||||
|
Loading…
Reference in New Issue
Block a user