Fix Bukkit config NPE, only change the protocol id if ViaVersion can support it and support unsupported Bungee protocol ids (Not working correctly yet)

This commit is contained in:
Matsv 2016-10-01 13:31:14 +02:00
parent b4976bd302
commit f53c8c67e2
No known key found for this signature in database
GPG Key ID: 97CEC2A2EA31350F
8 changed files with 124 additions and 19 deletions

View File

@ -41,8 +41,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
private List<Runnable> asyncQueuedTasks = new ArrayList<>();
public ViaVersionPlugin() {
// Config magic
conf = new BukkitConfigAPI();
// Command handler
commandHandler = new BukkitCommandHandler();
// Init platform
@ -52,6 +50,8 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform {
.injector(new BukkitViaInjector())
.loader(new BukkitViaLoader(this))
.build());
// Config magic
conf = new BukkitConfigAPI();
// For compatibility
ViaVersion.setInstance(this);

View File

@ -9,6 +9,7 @@ import net.md_5.bungee.api.event.ServerConnectEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.api.plugin.Plugin;
import net.md_5.bungee.event.EventHandler;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.ViaAPI;
import us.myles.ViaVersion.api.ViaVersionConfig;
@ -17,6 +18,8 @@ import us.myles.ViaVersion.api.configuration.ConfigurationProvider;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.platform.TaskId;
import us.myles.ViaVersion.api.platform.ViaPlatform;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
import us.myles.ViaVersion.bungee.commands.BungeeCommand;
import us.myles.ViaVersion.bungee.commands.BungeeCommandHandler;
import us.myles.ViaVersion.bungee.commands.BungeeCommandSender;
@ -24,6 +27,7 @@ import us.myles.ViaVersion.bungee.platform.*;
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
import us.myles.ViaVersion.bungee.storage.BungeeStorage;
import us.myles.ViaVersion.dump.PluginInfo;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.util.GsonUtil;
import us.myles.ViaVersion.util.ReflectionUtil;
@ -174,15 +178,19 @@ public class BungeePlugin extends Plugin implements ViaPlatform, Listener {
}
int protocolId = ProtocolDetectorService.getProtocolId(e.getTarget().getName());
try {
Object pendingConnection = ReflectionUtil.invoke(e.getPlayer(), "getPendingConnection");
Object handshake = ReflectionUtil.invoke(pendingConnection, "getHandshake");
Method setProtocol = handshake.getClass().getDeclaredMethod("setProtocolVersion", int.class);
setProtocol.invoke(handshake, protocolId);
} catch (NoSuchMethodException e1) {
e1.printStackTrace();
} catch (InvocationTargetException e1) {
e1.printStackTrace();
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(user.get(ProtocolInfo.class).getProtocolVersion(), protocolId);
// Check if ViaVersion can support that version
if (protocols != null) {
try {
Object pendingConnection = ReflectionUtil.invoke(e.getPlayer(), "getPendingConnection");
Object handshake = ReflectionUtil.invoke(pendingConnection, "getHandshake");
Method setProtocol = handshake.getClass().getDeclaredMethod("setProtocolVersion", int.class);
setProtocol.invoke(handshake, protocolId);
System.out.println("Changed server protocol id " + protocolId + " clientProtocol:" + user.get(ProtocolInfo.class).getProtocolVersion() + " path:" + protocols);
} catch (NoSuchMethodException | InvocationTargetException e1) {
e1.printStackTrace();
}
}
}

View File

@ -98,6 +98,8 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
if (player.getServer() != null) {
if (player.getServer() != null && !player.getServer().getInfo().getName().equals(storage.getCurrentServer())) {
System.out.println("Server change " + player.getServer().getInfo().getName());
String serverName = player.getServer().getInfo().getName();
storage.setCurrentServer(serverName);
@ -110,21 +112,34 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
int protocolId = ProtocolDetectorService.getProtocolId(serverName);
Object wrapper = ReflectionUtil.get(player, "ch", Object.class);
wrapper.getClass().getDeclaredMethod("setVersion", int.class).invoke(wrapper, protocolId);
us.myles.ViaVersion.api.data.UserConnection viaConnection = Via.getManager().getConnection(player.getUniqueId());
UserConnection viaConnection = Via.getManager().getConnection(player.getUniqueId());
ProtocolInfo info = viaConnection.get(ProtocolInfo.class);
// Refresh the pipes
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocolId);
System.out.println(info.getProtocolVersion() + ">" + protocolId + " " + protocols);
ProtocolPipeline pipeline = viaConnection.get(ProtocolInfo.class).getPipeline();
if (protocols != null) {
viaConnection.clearStoredObjects();
pipeline.cleanPipes();
for (Pair<Integer, Protocol> prot : protocols) {
pipeline.add(prot.getValue());
}
viaConnection.put(info);
viaConnection.setActive(true);
// Init all protocols TODO check if this can get moved up to the previous for loop, and doesn't require the pipeline to already exist.
for (Pair<Integer, Protocol> protocol : protocols) {
protocol.getValue().init(viaConnection);
}
Object wrapper = ReflectionUtil.get(player, "ch", Object.class);
wrapper.getClass().getDeclaredMethod("setVersion", int.class).invoke(wrapper, protocolId);
ReflectionUtil.invoke(player, "init");
} else {
viaConnection.setActive(false);
}
ReflectionUtil.invoke(player, "init");
}
}
}

View File

@ -5,7 +5,9 @@ import us.myles.ViaVersion.BungeePlugin;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.platform.ViaPlatformLoader;
import us.myles.ViaVersion.bungee.providers.BungeeMovementTransmitter;
import us.myles.ViaVersion.bungee.providers.BungeeVersionProvider;
import us.myles.ViaVersion.bungee.service.ProtocolDetectorService;
import us.myles.ViaVersion.protocols.base.VersionProvider;
import us.myles.ViaVersion.protocols.protocol1_9to1_8.providers.MovementTransmitterProvider;
import java.util.concurrent.TimeUnit;
@ -17,6 +19,7 @@ public class BungeeViaLoader implements ViaPlatformLoader {
@Override
public void load() {
Via.getManager().getProviders().use(MovementTransmitterProvider.class, new BungeeMovementTransmitter());
Via.getManager().getProviders().use(VersionProvider.class, new BungeeVersionProvider());
plugin.getProxy().getScheduler().schedule(plugin, new ProtocolDetectorService(plugin), 0, 1, TimeUnit.MINUTES);
}

View File

@ -0,0 +1,50 @@
package us.myles.ViaVersion.bungee.providers;
import com.google.common.collect.Lists;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.protocols.base.ProtocolInfo;
import us.myles.ViaVersion.protocols.base.VersionProvider;
import us.myles.ViaVersion.util.ReflectionUtil;
import java.util.List;
public class BungeeVersionProvider extends VersionProvider {
private static Class<?> ref;
public BungeeVersionProvider() {
try {
ref = Class.forName("net.md_5.bungee.protocol.ProtocolConstants");
} catch (Exception e) {
System.out.println("Could not detect the ProtocolConstants class");
e.printStackTrace();
}
}
@Override
public int getServerProtocol(UserConnection user) throws Exception {
if (ref == null)
return super.getServerProtocol(user);
// TODO Have one constant list forever until restart? (Might limit plugins if they change this)
List<Integer> list = ReflectionUtil.getStatic(ref, "SUPPORTED_VERSION_IDS", List.class);
ProtocolInfo info = user.get(ProtocolInfo.class);
// Bungee supports it
if (list.contains(info.getProtocolVersion()))
return info.getProtocolVersion();
// Older than bungee supports, get the lowest version
if (info.getProtocolVersion() < list.get(0)) {
return list.get(0);
}
// Loop through all protocols to get the closest protocol id that bungee supports
for (Integer protocol : Lists.reverse(list)) {
if (info.getProtocolVersion() > protocol)
return protocol;
}
System.out.println("Panic, no protocol id found for " + info.getProtocolVersion());
return info.getProtocolVersion();
}
}

View File

@ -66,6 +66,14 @@ public class UserConnection {
storedObjects.put(object.getClass(), object);
}
/**
* Clear all the stored objects
* Used for bungee when switching servers.
*/
public void clearStoredObjects() {
storedObjects.clear();
}
/**
* Send a raw packet to the player
*

View File

@ -11,6 +11,7 @@ import us.myles.ViaVersion.api.PacketWrapper;
import us.myles.ViaVersion.api.Pair;
import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.platform.providers.ViaProviders;
import us.myles.ViaVersion.api.protocol.Protocol;
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
@ -53,7 +54,9 @@ public class BaseProtocol extends Protocol {
if (ProtocolRegistry.SERVER_PROTOCOL == -1) // Set the Server protocol if the detection on startup failed
ProtocolRegistry.SERVER_PROTOCOL = protocolVersion;
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), ProtocolRegistry.SERVER_PROTOCOL);
int protocol = Via.getManager().getProviders().get(VersionProvider.class).getServerProtocol(wrapper.user());
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocol);
if (protocols != null) {
if (protocolVersion != 9999) {
//Fix ServerListPlus
@ -137,13 +140,14 @@ public class BaseProtocol extends Protocol {
ProtocolInfo info = wrapper.user().get(ProtocolInfo.class);
info.setProtocolVersion(protVer);
// Choose the pipe
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), ProtocolRegistry.SERVER_PROTOCOL);
int protocol = Via.getManager().getProviders().get(VersionProvider.class).getServerProtocol(wrapper.user());
List<Pair<Integer, Protocol>> protocols = ProtocolRegistry.getProtocolPath(info.getProtocolVersion(), protocol);
ProtocolPipeline pipeline = wrapper.user().get(ProtocolInfo.class).getPipeline();
if (protocols != null) {
for (Pair<Integer, Protocol> prot : protocols) {
pipeline.add(prot.getValue());
}
wrapper.set(Type.VAR_INT, 0, ProtocolRegistry.SERVER_PROTOCOL);
wrapper.set(Type.VAR_INT, 0, protocol);
}
// Change state
@ -196,6 +200,11 @@ public class BaseProtocol extends Protocol {
// Nothing gets added, ProtocolPipeline handles ProtocolInfo
}
@Override
protected void register(ViaProviders providers) {
providers.register(VersionProvider.class, new VersionProvider());
}
@Override
public void transform(Direction direction, State state, PacketWrapper packetWrapper) throws Exception {
super.transform(direction, state, packetWrapper);

View File

@ -0,0 +1,12 @@
package us.myles.ViaVersion.protocols.base;
import us.myles.ViaVersion.api.data.UserConnection;
import us.myles.ViaVersion.api.platform.providers.Provider;
import us.myles.ViaVersion.api.protocol.ProtocolRegistry;
public class VersionProvider implements Provider {
public int getServerProtocol(UserConnection connection) throws Exception {
return ProtocolRegistry.SERVER_PROTOCOL;
}
}