mirror of
https://github.com/ViaVersion/ViaVersion.git
synced 2024-10-31 15:49:32 +01:00
Merge branch 'master' into dev
This commit is contained in:
commit
49205f0361
@ -1,5 +1,7 @@
|
||||
package us.myles.ViaVersion.bukkit.platform;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
@ -16,7 +18,6 @@ import us.myles.ViaVersion.util.ReflectionUtil;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class BukkitViaInjector implements ViaInjector {
|
||||
@ -275,4 +276,65 @@ public class BukkitViaInjector implements ViaInjector {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getDump() {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
// Generate information about current injections
|
||||
JsonArray injectedChannelInitializers = new JsonArray();
|
||||
for (ChannelFuture cf : injectedFutures) {
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty("futureClass", cf.getClass().getName());
|
||||
info.addProperty("channelClass", cf.channel().getClass().getName());
|
||||
|
||||
// Get information about the pipes for this channel future
|
||||
JsonArray pipeline = new JsonArray();
|
||||
for (String pipeName : cf.channel().pipeline().names()) {
|
||||
JsonObject pipe = new JsonObject();
|
||||
pipe.addProperty("name", pipeName);
|
||||
if (cf.channel().pipeline().get(pipeName) != null) {
|
||||
pipe.addProperty("class", cf.channel().pipeline().get(pipeName).getClass().getName());
|
||||
try {
|
||||
Object child = ReflectionUtil.get(cf.channel().pipeline().get(pipeName), "childHandler", ChannelInitializer.class);
|
||||
pipe.addProperty("childClass", child.getClass().getName());
|
||||
if (child instanceof BukkitChannelInitializer) {
|
||||
pipe.addProperty("oldInit", ((BukkitChannelInitializer) child).getOriginal().getClass().getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Don't display
|
||||
}
|
||||
}
|
||||
// Add to the pipeline array
|
||||
pipeline.add(pipe);
|
||||
}
|
||||
info.add("pipeline", pipeline);
|
||||
|
||||
// Add to the list
|
||||
injectedChannelInitializers.add(info);
|
||||
}
|
||||
data.add("injectedChannelInitializers", injectedChannelInitializers);
|
||||
|
||||
// Generate information about lists we've injected into
|
||||
JsonObject wrappedLists = new JsonObject();
|
||||
JsonObject currentLists = new JsonObject();
|
||||
try {
|
||||
for (Pair<Field, Object> pair : injectedLists) {
|
||||
Object list = pair.getKey().get(pair.getValue());
|
||||
// Note down the current value (could be overridden by another plugin)
|
||||
currentLists.addProperty(pair.getKey().getName(), list.getClass().getName());
|
||||
// Also if it's not overridden we can display what's inside our list (possibly another plugin)
|
||||
if (list instanceof ListWrapper) {
|
||||
wrappedLists.addProperty(pair.getKey().getName(), ((ListWrapper) list).getOriginalList().getClass().getName());
|
||||
}
|
||||
}
|
||||
data.add("wrappedLists", wrappedLists);
|
||||
data.add("currentLists", currentLists);
|
||||
} catch (Exception e) {
|
||||
// Ignored, fields won't be present
|
||||
}
|
||||
|
||||
data.addProperty("binded", isBinded());
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -3,13 +3,14 @@ package us.myles.ViaVersion.bungee.handlers;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import lombok.Getter;
|
||||
import us.myles.ViaVersion.api.data.UserConnection;
|
||||
import us.myles.ViaVersion.api.protocol.ProtocolPipeline;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class BungeeChannelInitializer extends ChannelInitializer<SocketChannel> {
|
||||
|
||||
public class BungeeChannelInitializer extends ChannelInitializer<Channel> {
|
||||
@Getter
|
||||
private final ChannelInitializer<Channel> original;
|
||||
private Method method;
|
||||
|
||||
@ -24,7 +25,7 @@ public class BungeeChannelInitializer extends ChannelInitializer<SocketChannel>
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initChannel(SocketChannel socketChannel) throws Exception {
|
||||
protected void initChannel(Channel socketChannel) throws Exception {
|
||||
UserConnection info = new UserConnection(socketChannel);
|
||||
// init protocol
|
||||
new ProtocolPipeline(info);
|
||||
|
@ -1,5 +1,6 @@
|
||||
package us.myles.ViaVersion.bungee.platform;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
@ -56,4 +57,31 @@ public class BungeeViaInjector implements ViaInjector {
|
||||
public String getDecoderName() {
|
||||
return "via-decoder";
|
||||
}
|
||||
|
||||
private ChannelInitializer<Channel> getChannelInitializer() throws Exception {
|
||||
Class<?> pipelineUtils = Class.forName("net.md_5.bungee.netty.PipelineUtils");
|
||||
Field field = pipelineUtils.getDeclaredField("SERVER_CHILD");
|
||||
field.setAccessible(true);
|
||||
// Remove any final stuff
|
||||
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||
modifiersField.setAccessible(true);
|
||||
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||
|
||||
return (ChannelInitializer<Channel>) field.get(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getDump() {
|
||||
JsonObject data = new JsonObject();
|
||||
try {
|
||||
ChannelInitializer<Channel> initializer = getChannelInitializer();
|
||||
data.addProperty("currentInitializer", initializer.getClass().getName());
|
||||
if (initializer instanceof BungeeChannelInitializer) {
|
||||
data.addProperty("originalInitializer", ((BungeeChannelInitializer) initializer).getOriginal().getClass().getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Ignored, not printed in the dump
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package us.myles.ViaVersion.api.platform;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
public interface ViaInjector {
|
||||
/**
|
||||
* Inject into the current Platform
|
||||
@ -36,4 +38,11 @@ public interface ViaInjector {
|
||||
* @return The name
|
||||
*/
|
||||
String getDecoderName();
|
||||
|
||||
/**
|
||||
* Get any relevant data for debugging injection issues.
|
||||
*
|
||||
* @return JSONObject containing the data
|
||||
*/
|
||||
JsonObject getDump();
|
||||
}
|
||||
|
@ -48,7 +48,7 @@ public class DumpSubCmd extends ViaSubCommand {
|
||||
|
||||
Map<String, Object> configuration = Via.getPlatform().getConfigurationProvider().getValues();
|
||||
|
||||
final DumpTemplate template = new DumpTemplate(version, configuration, Via.getPlatform().getDump());
|
||||
final DumpTemplate template = new DumpTemplate(version, configuration, Via.getPlatform().getDump(), Via.getManager().getInjector().getDump());
|
||||
|
||||
Via.getPlatform().runAsync(new Runnable() {
|
||||
@Override
|
||||
|
@ -12,4 +12,5 @@ public class DumpTemplate {
|
||||
private VersionInfo versionInfo;
|
||||
private Map<String, Object> configuration;
|
||||
private JsonObject platformDump;
|
||||
private JsonObject injectionDump;
|
||||
}
|
||||
|
@ -20,39 +20,53 @@ public abstract class ListWrapper implements List {
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return this.list.size();
|
||||
synchronized (this) {
|
||||
return this.list.size();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return this.list.isEmpty();
|
||||
synchronized (this) {
|
||||
return this.list.isEmpty();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean contains(Object o) {
|
||||
return this.list.contains(o);
|
||||
synchronized (this) {
|
||||
return this.list.contains(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator iterator() {
|
||||
return listIterator();
|
||||
synchronized (this) {
|
||||
return listIterator();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray() {
|
||||
return this.list.toArray();
|
||||
synchronized (this) {
|
||||
return this.list.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean add(Object o) {
|
||||
handleAdd(o);
|
||||
return this.list.add(o);
|
||||
synchronized (this) {
|
||||
return this.list.add(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean remove(Object o) {
|
||||
return this.list.remove(o);
|
||||
synchronized (this) {
|
||||
return this.list.remove(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -60,7 +74,9 @@ public abstract class ListWrapper implements List {
|
||||
for (Object o : c) {
|
||||
handleAdd(o);
|
||||
}
|
||||
return this.list.addAll(c);
|
||||
synchronized (this) {
|
||||
return this.list.addAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -68,76 +84,106 @@ public abstract class ListWrapper implements List {
|
||||
for (Object o : c) {
|
||||
handleAdd(o);
|
||||
}
|
||||
return this.list.addAll(index, c);
|
||||
synchronized (this) {
|
||||
return this.list.addAll(index, c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clear() {
|
||||
this.list.clear();
|
||||
synchronized (this) {
|
||||
this.list.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(int index) {
|
||||
return this.list.get(index);
|
||||
synchronized (this) {
|
||||
return this.list.get(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object set(int index, Object element) {
|
||||
return this.list.set(index, element);
|
||||
synchronized (this) {
|
||||
return this.list.set(index, element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void add(int index, Object element) {
|
||||
this.list.add(index, element);
|
||||
synchronized (this) {
|
||||
this.list.add(index, element);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object remove(int index) {
|
||||
return this.list.remove(index);
|
||||
synchronized (this) {
|
||||
return this.list.remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int indexOf(Object o) {
|
||||
return this.list.indexOf(o);
|
||||
synchronized (this) {
|
||||
return this.list.indexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int lastIndexOf(Object o) {
|
||||
return this.list.lastIndexOf(o);
|
||||
synchronized (this) {
|
||||
return this.list.lastIndexOf(o);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator listIterator() {
|
||||
return this.list.listIterator();
|
||||
synchronized (this) {
|
||||
return this.list.listIterator();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public ListIterator listIterator(int index) {
|
||||
return this.list.listIterator(index);
|
||||
synchronized (this) {
|
||||
return this.list.listIterator(index);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List subList(int fromIndex, int toIndex) {
|
||||
return this.list.subList(fromIndex, toIndex);
|
||||
synchronized (this) {
|
||||
return this.list.subList(fromIndex, toIndex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean retainAll(Collection c) {
|
||||
return this.list.retainAll(c);
|
||||
synchronized (this) {
|
||||
return this.list.retainAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeAll(Collection c) {
|
||||
return this.list.removeAll(c);
|
||||
synchronized (this) {
|
||||
return this.list.removeAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection c) {
|
||||
return this.list.containsAll(c);
|
||||
synchronized (this) {
|
||||
return this.list.containsAll(c);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] toArray(Object[] a) {
|
||||
return this.list.toArray(a);
|
||||
synchronized (this) {
|
||||
return this.list.toArray(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package us.myles.ViaVersion.sponge.platform;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelHandler;
|
||||
@ -189,4 +191,63 @@ public class SpongeViaInjector implements ViaInjector {
|
||||
return connection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getDump() {
|
||||
JsonObject data = new JsonObject();
|
||||
|
||||
// Generate information about current injections
|
||||
JsonArray injectedChannelInitializers = new JsonArray();
|
||||
for (ChannelFuture cf : injectedFutures) {
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty("futureClass", cf.getClass().getName());
|
||||
info.addProperty("channelClass", cf.channel().getClass().getName());
|
||||
|
||||
// Get information about the pipes for this channel future
|
||||
JsonArray pipeline = new JsonArray();
|
||||
for (String pipeName : cf.channel().pipeline().names()) {
|
||||
JsonObject pipe = new JsonObject();
|
||||
pipe.addProperty("name", pipeName);
|
||||
if (cf.channel().pipeline().get(pipeName) != null) {
|
||||
pipe.addProperty("class", cf.channel().pipeline().get(pipeName).getClass().getName());
|
||||
try {
|
||||
Object child = ReflectionUtil.get(cf.channel().pipeline().get(pipeName), "childHandler", ChannelInitializer.class);
|
||||
pipe.addProperty("childClass", child.getClass().getName());
|
||||
if (child instanceof SpongeChannelInitializer) {
|
||||
pipe.addProperty("oldInit", ((SpongeChannelInitializer) child).getOriginal().getClass().getName());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Don't display
|
||||
}
|
||||
}
|
||||
// Add to the pipeline array
|
||||
pipeline.add(pipe);
|
||||
}
|
||||
info.add("pipeline", pipeline);
|
||||
|
||||
// Add to the list
|
||||
injectedChannelInitializers.add(info);
|
||||
}
|
||||
data.add("injectedChannelInitializers", injectedChannelInitializers);
|
||||
|
||||
// Generate information about lists we've injected into
|
||||
JsonObject wrappedLists = new JsonObject();
|
||||
JsonObject currentLists = new JsonObject();
|
||||
try {
|
||||
for (Pair<Field, Object> pair : injectedLists) {
|
||||
Object list = pair.getKey().get(pair.getValue());
|
||||
// Note down the current value (could be overridden by another plugin)
|
||||
currentLists.addProperty(pair.getKey().getName(), list.getClass().getName());
|
||||
// Also if it's not overridden we can display what's inside our list (possibly another plugin)
|
||||
if (list instanceof ListWrapper) {
|
||||
wrappedLists.addProperty(pair.getKey().getName(), ((ListWrapper) list).getOriginalList().getClass().getName());
|
||||
}
|
||||
}
|
||||
data.add("wrappedLists", wrappedLists);
|
||||
data.add("currentLists", currentLists);
|
||||
} catch (Exception e) {
|
||||
// Ignored, fields won't be present
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package us.myles.ViaVersion.velocity.platform;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import us.myles.ViaVersion.VelocityPlugin;
|
||||
import us.myles.ViaVersion.api.Via;
|
||||
@ -23,13 +24,19 @@ public class VelocityViaInjector implements ViaInjector {
|
||||
}
|
||||
}
|
||||
|
||||
private ChannelInitializer getInitializer() throws Exception {
|
||||
Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class);
|
||||
Object channelInitializerHolder = ReflectionUtil.invoke(connectionManager, "getServerChannelInitializer");
|
||||
return (ChannelInitializer) ReflectionUtil.invoke(channelInitializerHolder, "get");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void inject() throws Exception {
|
||||
Object connectionManager = ReflectionUtil.get(VelocityPlugin.PROXY, "cm", Object.class);
|
||||
Object channelInitializerHolder = ReflectionUtil.invoke(connectionManager, "getServerChannelInitializer");
|
||||
ChannelInitializer originalIntializer = (ChannelInitializer) ReflectionUtil.invoke(channelInitializerHolder, "get");
|
||||
ChannelInitializer originalInitializer = getInitializer();
|
||||
channelInitializerHolder.getClass().getMethod("set", ChannelInitializer.class)
|
||||
.invoke(channelInitializerHolder, new VelocityChannelInitializer(originalIntializer));
|
||||
.invoke(channelInitializerHolder, new VelocityChannelInitializer(originalInitializer));
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -62,4 +69,15 @@ public class VelocityViaInjector implements ViaInjector {
|
||||
public String getDecoderName() {
|
||||
return "via-decoder";
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonObject getDump() {
|
||||
JsonObject data = new JsonObject();
|
||||
try {
|
||||
data.addProperty("currentInitializer", getInitializer().getClass().getName());
|
||||
} catch (Exception e) {
|
||||
// Ignored
|
||||
}
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user