mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-11-23 10:35:12 +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 lombok.NonNull;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.PluginDescriptionFile;
|
import org.bukkit.plugin.PluginDescriptionFile;
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import us.myles.ViaVersion.api.Pair;
|
import us.myles.ViaVersion.api.Pair;
|
||||||
@ -48,6 +49,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
|||||||
private boolean compatSpigotBuild = false;
|
private boolean compatSpigotBuild = false;
|
||||||
private boolean spigot = true;
|
private boolean spigot = true;
|
||||||
private boolean lateBind = false;
|
private boolean lateBind = false;
|
||||||
|
private boolean protocolSupport = false;
|
||||||
@Getter
|
@Getter
|
||||||
private ViaConfig conf;
|
private ViaConfig conf;
|
||||||
|
|
||||||
@ -56,6 +58,7 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
|||||||
// Config magic
|
// Config magic
|
||||||
conf = new ViaConfig(this);
|
conf = new ViaConfig(this);
|
||||||
ViaVersion.setInstance(this);
|
ViaVersion.setInstance(this);
|
||||||
|
|
||||||
// Handle reloads
|
// Handle reloads
|
||||||
if (System.getProperty("ViaVersion") != null) {
|
if (System.getProperty("ViaVersion") != null) {
|
||||||
if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) {
|
if (Bukkit.getPluginManager().getPlugin("ProtocolLib") != null) {
|
||||||
@ -69,19 +72,25 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
|||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Spigot detector
|
// Spigot detector
|
||||||
try {
|
try {
|
||||||
Class.forName("org.spigotmc.SpigotConfig");
|
Class.forName("org.spigotmc.SpigotConfig");
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
spigot = false;
|
spigot = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if it's a spigot build with a protocol mod
|
// Check if it's a spigot build with a protocol mod
|
||||||
try {
|
try {
|
||||||
compatSpigotBuild = ReflectionUtil.nms("PacketEncoder").getDeclaredField("version") != null;
|
compatSpigotBuild = ReflectionUtil.nms("PacketEncoder").getDeclaredField("version") != null;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
compatSpigotBuild = false;
|
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();
|
ClassGenerator.generate();
|
||||||
lateBind = !isBinded();
|
lateBind = !isBinded();
|
||||||
|
|
||||||
@ -435,6 +444,10 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isProtocolSupport() {
|
||||||
|
return protocolSupport;
|
||||||
|
}
|
||||||
|
|
||||||
public Map<UUID, UserConnection> getPortedPlayers() {
|
public Map<UUID, UserConnection> getPortedPlayers() {
|
||||||
return portedPlayers;
|
return portedPlayers;
|
||||||
}
|
}
|
||||||
|
@ -125,4 +125,11 @@ public interface ViaVersionAPI {
|
|||||||
* @return True if spigot
|
* @return True if spigot
|
||||||
*/
|
*/
|
||||||
boolean isSpigot();
|
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.*;
|
||||||
import javassist.expr.ConstructorCall;
|
import javassist.expr.ConstructorCall;
|
||||||
import javassist.expr.ExprEditor;
|
import javassist.expr.ExprEditor;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.plugin.Plugin;
|
||||||
import us.myles.ViaVersion.api.ViaVersion;
|
import us.myles.ViaVersion.api.ViaVersion;
|
||||||
import us.myles.ViaVersion.handlers.ViaDecodeHandler;
|
import us.myles.ViaVersion.handlers.ViaDecodeHandler;
|
||||||
import us.myles.ViaVersion.handlers.ViaEncodeHandler;
|
import us.myles.ViaVersion.handlers.ViaEncodeHandler;
|
||||||
@ -10,72 +12,93 @@ import us.myles.ViaVersion.util.ReflectionUtil;
|
|||||||
|
|
||||||
public class ClassGenerator {
|
public class ClassGenerator {
|
||||||
private static HandlerConstructor constructor = new BasicHandlerConstructor();
|
private static HandlerConstructor constructor = new BasicHandlerConstructor();
|
||||||
|
private static String psPackage = null;
|
||||||
|
|
||||||
public static HandlerConstructor getConstructor() {
|
public static HandlerConstructor getConstructor() {
|
||||||
return constructor;
|
return constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void generate() {
|
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 {
|
if (ViaVersion.getInstance().isCompatSpigotBuild()) {
|
||||||
ClassPool pool = ClassPool.getDefault();
|
Class decodeSuper = ReflectionUtil.nms("PacketDecoder");
|
||||||
pool.insertClassPath(new LoaderClassPath(ClassGenerator.class.getClassLoader()));
|
Class encodeSuper = ReflectionUtil.nms("PacketEncoder");
|
||||||
// Generate the classes
|
// Generate the classes
|
||||||
transformSuperclass(pool, ViaDecodeHandler.class, ReflectionUtil.nms("PacketDecoder"));
|
addSpigotCompatibility(pool, ViaDecodeHandler.class, decodeSuper);
|
||||||
transformSuperclass(pool, ViaEncodeHandler.class, ReflectionUtil.nms("PacketEncoder"));
|
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});
|
// Implement Constructor
|
||||||
// Import required classes
|
CtClass generated = pool.makeClass("us.myles.ViaVersion.classgenerator.generated.GeneratedConstructor");
|
||||||
pool.importPackage("us.myles.ViaVersion.classgenerator.generated");
|
CtClass handlerInterface = pool.get(HandlerConstructor.class.getName());
|
||||||
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();
|
generated.setInterfaces(new CtClass[]{handlerInterface});
|
||||||
} catch (ClassNotFoundException e) {
|
// Import required classes
|
||||||
e.printStackTrace();
|
pool.importPackage("us.myles.ViaVersion.classgenerator.generated");
|
||||||
} catch (CannotCompileException e) {
|
pool.importPackage("us.myles.ViaVersion.classgenerator");
|
||||||
e.printStackTrace();
|
pool.importPackage("us.myles.ViaVersion.api.data");
|
||||||
} catch (NotFoundException e) {
|
pool.importPackage("io.netty.handler.codec");
|
||||||
e.printStackTrace();
|
// Implement Methods
|
||||||
} catch (InstantiationException e) {
|
generated.addMethod(CtMethod.make("public MessageToByteEncoder newEncodeHandler(UserConnection info, MessageToByteEncoder minecraftEncoder) {\n" +
|
||||||
e.printStackTrace();
|
" return new ViaEncodeHandler(info, minecraftEncoder);\n" +
|
||||||
} catch (IllegalAccessException e) {
|
" }", generated));
|
||||||
e.printStackTrace();
|
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();
|
String newName = "us.myles.ViaVersion.classgenerator.generated." + input.getSimpleName();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
CtClass toExtend = pool.get(superclass.getName());
|
|
||||||
CtClass generated = pool.getAndRename(input.getName(), newName);
|
CtClass generated = pool.getAndRename(input.getName(), newName);
|
||||||
generated.setSuperclass(toExtend);
|
if (superclass != null) {
|
||||||
// Modify constructor to call super
|
CtClass toExtend = pool.get(superclass.getName());
|
||||||
if(generated.getConstructors().length != 0) {
|
generated.setSuperclass(toExtend);
|
||||||
generated.getConstructors()[0].instrument(new ExprEditor() {
|
|
||||||
@Override
|
// If it's NMS satisfy constructor.
|
||||||
public void edit(ConstructorCall c) throws CannotCompileException {
|
if (superclass.getName().startsWith("net.minecraft")) {
|
||||||
if (c.isSuper()) {
|
// Modify constructor to call super
|
||||||
// Constructor for both has a stats thing.
|
if (generated.getConstructors().length != 0) {
|
||||||
c.replace("super(null);");
|
generated.getConstructors()[0].instrument(new ExprEditor() {
|
||||||
}
|
@Override
|
||||||
super.edit(c);
|
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());
|
return generated.toClass(HandlerConstructor.class.getClassLoader());
|
||||||
} catch (NotFoundException e) {
|
} catch (NotFoundException e) {
|
||||||
@ -85,4 +108,58 @@ public class ClassGenerator {
|
|||||||
}
|
}
|
||||||
return null;
|
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}
|
version: ${project.version}
|
||||||
load: postworld
|
load: postworld
|
||||||
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, PacketListenerApi, SkinRestorer]
|
loadbefore: [ProtocolLib, ProxyPipe, SpigotLib, PacketListenerApi, SkinRestorer]
|
||||||
|
softdepend: [ProtocolSupport]
|
||||||
commands:
|
commands:
|
||||||
viaversion:
|
viaversion:
|
||||||
description: Shows ViaVersion Version and more.
|
description: Shows ViaVersion Version and more.
|
||||||
|
Loading…
Reference in New Issue
Block a user