Fixup docs, remove ConcurrentList

This commit is contained in:
KennyTV 2020-06-09 17:53:31 +02:00
parent df495f8131
commit aa59ed112a
No known key found for this signature in database
GPG Key ID: 6BE3B555EBC5982B
13 changed files with 75 additions and 369 deletions

View File

@ -17,12 +17,18 @@ import us.myles.ViaVersion.api.platform.ViaPlatform;
import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator;
import us.myles.ViaVersion.bukkit.commands.BukkitCommandHandler;
import us.myles.ViaVersion.bukkit.commands.BukkitCommandSender;
import us.myles.ViaVersion.bukkit.platform.*;
import us.myles.ViaVersion.bukkit.platform.BukkitTaskId;
import us.myles.ViaVersion.bukkit.platform.BukkitViaAPI;
import us.myles.ViaVersion.bukkit.platform.BukkitViaConfig;
import us.myles.ViaVersion.bukkit.platform.BukkitViaInjector;
import us.myles.ViaVersion.bukkit.platform.BukkitViaLoader;
import us.myles.ViaVersion.bukkit.util.NMSUtil;
import us.myles.ViaVersion.dump.PluginInfo;
import us.myles.ViaVersion.util.GsonUtil;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> {
private static ViaVersionPlugin instance;
@ -54,15 +60,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
// Check if we're using protocol support too
protocolSupport = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
if (protocolSupport) {
getLogger().info("Hooking into ProtocolSupport, to prevent issues!");
try {
BukkitViaInjector.patchLists();
} catch (Exception e) {
e.printStackTrace();
}
}
}
@Override

View File

@ -27,15 +27,15 @@ public class BukkitDecodeHandler extends ByteToMessageDecoder {
throw CancelDecoderException.generate(null);
}
ByteBuf draft = null;
ByteBuf transformedBuf = null;
try {
if (info.shouldTransformPacket()) {
draft = ctx.alloc().buffer().writeBytes(bytebuf);
info.transformIncoming(draft, CancelDecoderException::generate);
transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
}
try {
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, draft == null ? bytebuf : draft));
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, transformedBuf == null ? bytebuf : transformedBuf));
} catch (InvocationTargetException e) {
if (e.getCause() instanceof Exception) {
throw (Exception) e.getCause();
@ -44,8 +44,8 @@ public class BukkitDecodeHandler extends ByteToMessageDecoder {
}
}
} finally {
if (draft != null) {
draft.release();
if (transformedBuf != null) {
transformedBuf.release();
}
}
}

View File

@ -12,17 +12,17 @@ import us.myles.ViaVersion.api.Via;
import us.myles.ViaVersion.api.platform.ViaInjector;
import us.myles.ViaVersion.bukkit.handlers.BukkitChannelInitializer;
import us.myles.ViaVersion.bukkit.util.NMSUtil;
import us.myles.ViaVersion.util.ConcurrentList;
import us.myles.ViaVersion.util.ListWrapper;
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 {
private final List<ChannelFuture> injectedFutures = new ConcurrentList<>();
private final List<Pair<Field, Object>> injectedLists = new ConcurrentList<>();
private final List<ChannelFuture> injectedFutures = new ArrayList<>();
private final List<Pair<Field, Object>> injectedLists = new ArrayList<>();
@Override
public void inject() throws Exception {
@ -231,25 +231,6 @@ public class BukkitViaInjector implements ViaInjector {
return connection;
}
public static void patchLists() throws Exception {
Object connection = getServerConnection();
if (connection == null) {
Via.getPlatform().getLogger().warning("We failed to find the core component 'ServerConnection', please file an issue on our GitHub.");
return;
}
for (Field field : connection.getClass().getDeclaredFields()) {
field.setAccessible(true);
final Object value = field.get(connection);
if (value instanceof List) {
if (!(value instanceof ConcurrentList)) {
ConcurrentList list = new ConcurrentList();
list.addAll((List) value);
field.set(connection, list);
}
}
}
}
public static boolean isBinded() {
try {
Object connection = getServerConnection();

View File

@ -25,12 +25,12 @@ public class BungeeDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
return;
}
ByteBuf draft = ctx.alloc().buffer().writeBytes(bytebuf);
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
try {
info.transformIncoming(draft, CancelDecoderException::generate);
out.add(draft.retain());
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
out.add(transformedBuf.retain());
} finally {
draft.release();
transformedBuf.release();
}
}

View File

@ -27,29 +27,29 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
return;
}
ByteBuf draft = ctx.alloc().buffer().writeBytes(bytebuf);
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
try {
boolean needsCompress = handleCompressionOrder(ctx, draft);
info.transformOutgoing(draft, CancelEncoderException::generate);
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
info.transformOutgoing(transformedBuf, CancelEncoderException::generate);
if (needsCompress) {
recompress(ctx, draft);
recompress(ctx, transformedBuf);
}
out.add(draft.retain());
out.add(transformedBuf.retain());
} finally {
draft.release();
transformedBuf.release();
}
}
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf draft) {
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buf) {
boolean needsCompress = false;
if (!handledCompression) {
if (ctx.pipeline().names().indexOf("compress") > ctx.pipeline().names().indexOf("via-encoder")) {
// Need to decompress this packet due to bad order
ByteBuf decompressed = BungeePipelineUtil.decompress(ctx, draft);
ByteBuf decompressed = BungeePipelineUtil.decompress(ctx, buf);
try {
draft.clear().writeBytes(decompressed);
buf.clear().writeBytes(decompressed);
} finally {
decompressed.release();
}
@ -66,10 +66,10 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
return needsCompress;
}
private void recompress(ChannelHandlerContext ctx, ByteBuf draft) {
ByteBuf compressed = BungeePipelineUtil.compress(ctx, draft);
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) {
ByteBuf compressed = BungeePipelineUtil.compress(ctx, buf);
try {
draft.clear().writeBytes(compressed);
buf.clear().writeBytes(compressed);
} finally {
compressed.release();
}

View File

@ -291,44 +291,44 @@ public class UserConnection {
/**
* Transforms the clientbound packet contained in draft ByteBuf.
*
* @param draft ByteBuf with packet id and packet contents
* @param buf ByteBuf with packet id and packet contents
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
* packet is cancelled
* @throws Exception when transforming failed or this packet is cancelled
*/
public void transformOutgoing(ByteBuf draft, Function<Throwable, Exception> cancelSupplier) throws Exception {
if (!draft.isReadable()) return;
transform(draft, Direction.OUTGOING, cancelSupplier);
public void transformOutgoing(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
if (!buf.isReadable()) return;
transform(buf, Direction.OUTGOING, cancelSupplier);
}
/**
* Transforms the serverbound packet contained in draft ByteBuf.
*
* @param draft ByteBuf with packet id and packet contents
* @param buf ByteBuf with packet id and packet contents
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
* packet is cancelled
* @throws Exception when transforming failed or this packet is cancelled
*/
public void transformIncoming(ByteBuf draft, Function<Throwable, Exception> cancelSupplier) throws Exception {
if (!draft.isReadable()) return;
transform(draft, Direction.INCOMING, cancelSupplier);
public void transformIncoming(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
if (!buf.isReadable()) return;
transform(buf, Direction.INCOMING, cancelSupplier);
}
private void transform(ByteBuf draft, Direction direction, Function<Throwable, Exception> cancelSupplier) throws Exception {
int id = Type.VAR_INT.read(draft);
private void transform(ByteBuf buf, Direction direction, Function<Throwable, Exception> cancelSupplier) throws Exception {
int id = Type.VAR_INT.read(buf);
if (id == PacketWrapper.PASSTHROUGH_ID) return;
PacketWrapper wrapper = new PacketWrapper(id, draft, this);
PacketWrapper wrapper = new PacketWrapper(id, buf, this);
try {
protocolInfo.getPipeline().transform(direction, protocolInfo.getState(), wrapper);
} catch (CancelException ex) {
throw cancelSupplier.apply(ex);
}
ByteBuf transformed = draft.alloc().buffer();
ByteBuf transformed = buf.alloc().buffer();
try {
wrapper.writeToBuffer(transformed);
draft.clear().writeBytes(transformed);
buf.clear().writeBytes(transformed);
} finally {
transformed.release();
}

View File

@ -4,7 +4,8 @@ import io.netty.handler.codec.DecoderException;
import us.myles.ViaVersion.api.Via;
/**
* Used for cancelling packets in decode handlers.
* Thrown during packet decoding when an incoming packet should be cancelled.
* Specifically extends {@link DecoderException} to prevent netty from wrapping the exception.
*/
public class CancelDecoderException extends DecoderException {
public static final CancelDecoderException CACHED = new CancelDecoderException("CACHED") {

View File

@ -4,7 +4,8 @@ import io.netty.handler.codec.EncoderException;
import us.myles.ViaVersion.api.Via;
/**
* Used for cancelling packets in encode handlers.
* Thrown during packet encoding when an outgoing packet should be cancelled.
* Specifically extends {@link EncoderException} to prevent netty from wrapping the exception.
*/
public class CancelEncoderException extends EncoderException {
public static final CancelEncoderException CACHED = new CancelEncoderException("CACHED") {

View File

@ -1,9 +1,11 @@
package us.myles.ViaVersion.exception;
import io.netty.handler.codec.CodecException;
import us.myles.ViaVersion.api.Via;
/**
* Used for cancelling packets.
* Thrown during packet transformation to cancel the packet.
* Internally catched to then throw the appropriate {@link CodecException} for Netty's handler.
*/
public class CancelException extends Exception {
public static final CancelException CACHED = new CancelException("Cached - Enable /viaver debug to not use cached exception") {

View File

@ -1,276 +0,0 @@
package us.myles.ViaVersion.util;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.NoSuchElementException;
/**
* Created by wea_ondara licensed under MIT
* Same license as in LICENSE
* <p>
* Taken from:
* https://github.com/weaondara/BungeePerms/blob/master/src/main/java/net/alpenblock/bungeeperms/util/ConcurrentList.java
*
* @param <E> List Type
*/
public class ConcurrentList<E> extends ArrayList<E> {
private final Object lock = new Object();
@Override
public boolean add(E e) {
synchronized (lock) {
return super.add(e);
}
}
@Override
public void add(int index, E element) {
synchronized (lock) {
super.add(index, element);
}
}
@Override
public boolean addAll(Collection<? extends E> c) {
synchronized (lock) {
return super.addAll(c);
}
}
@Override
public boolean addAll(int index, Collection<? extends E> c) {
synchronized (lock) {
return super.addAll(index, c);
}
}
@Override
public void clear() {
synchronized (lock) {
super.clear();
}
}
@Override
public Object clone() {
synchronized (lock) {
try {
ConcurrentList<E> clist = (ConcurrentList<E>) super.clone();
clist.modCount = 0;
Field f = ArrayList.class.getDeclaredField("elementData");
f.setAccessible(true);
f.set(clist, Arrays.copyOf((Object[]) f.get(this), this.size()));
return clist;
} catch (ReflectiveOperationException e) {
throw new RuntimeException(e);
}
}
}
@Override
public boolean contains(Object o) {
synchronized (lock) {
return super.contains(o);
}
}
@Override
public void ensureCapacity(int minCapacity) {
synchronized (lock) {
super.ensureCapacity(minCapacity);
}
}
@Override
public E get(int index) {
synchronized (lock) {
return super.get(index);
}
}
@Override
public int indexOf(Object o) {
synchronized (lock) {
return super.indexOf(o);
}
}
@Override
public int lastIndexOf(Object o) {
synchronized (lock) {
return super.lastIndexOf(o);
}
}
@Override
public E remove(int index) {
synchronized (lock) {
return super.remove(index);
}
}
@Override
public boolean remove(Object o) {
synchronized (lock) {
return super.remove(o);
}
}
@Override
public boolean removeAll(Collection<?> c) {
synchronized (lock) {
return super.removeAll(c);
}
}
@Override
public boolean retainAll(Collection<?> c) {
synchronized (lock) {
return super.retainAll(c);
}
}
@Override
public E set(int index, E element) {
synchronized (lock) {
return super.set(index, element);
}
}
@Override
public List<E> subList(int fromIndex, int toIndex) {
synchronized (lock) {
return super.subList(fromIndex, toIndex);
}
}
@Override
public Object[] toArray() {
synchronized (lock) {
return super.toArray();
}
}
@Override
public <T> T[] toArray(T[] a) {
synchronized (lock) {
return super.toArray(a);
}
}
@Override
public void trimToSize() {
synchronized (lock) {
super.trimToSize();
}
}
@Override
public ListIterator<E> listIterator() {
return new ListItr(0);
}
@Override
public Iterator<E> iterator() {
return new Itr();
}
private class Itr implements Iterator<E> {
protected int cursor;
protected int lastRet;
final ConcurrentList l;
public Itr() {
cursor = 0;
lastRet = -1;
l = (ConcurrentList) ConcurrentList.this.clone();
}
@Override
public boolean hasNext() {
return cursor < l.size();
}
@Override
public E next() {
int i = cursor;
if (i >= l.size()) {
throw new NoSuchElementException();
}
cursor = i + 1;
return (E) l.get(lastRet = i);
}
@Override
public void remove() {
if (lastRet < 0) {
throw new IllegalStateException();
}
l.remove(lastRet);
ConcurrentList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
}
}
public class ListItr extends Itr implements ListIterator<E> {
ListItr(int index) {
super();
cursor = index;
}
@Override
public boolean hasPrevious() {
return cursor > 0;
}
@Override
public int nextIndex() {
return cursor;
}
@Override
public int previousIndex() {
return cursor - 1;
}
@Override
public E previous() {
int i = cursor - 1;
if (i < 0) {
throw new NoSuchElementException();
}
cursor = i;
return (E) l.get(lastRet = i);
}
@Override
public void set(E e) {
if (lastRet < 0) {
throw new IllegalStateException();
}
l.set(lastRet, e);
ConcurrentList.this.set(lastRet, e);
}
@Override
public void add(E e) {
int i = cursor;
l.add(i, e);
ConcurrentList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
}
}
}

View File

@ -27,15 +27,15 @@ public class SpongeDecodeHandler extends ByteToMessageDecoder {
throw CancelDecoderException.generate(null);
}
ByteBuf draft = null;
ByteBuf transformedBuf = null;
try {
if (info.shouldTransformPacket()) {
draft = ctx.alloc().buffer().writeBytes(bytebuf);
info.transformIncoming(draft, CancelDecoderException::generate);
transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
}
try {
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, draft == null ? bytebuf : draft));
list.addAll(PipelineUtil.callDecode(this.minecraftDecoder, ctx, transformedBuf == null ? bytebuf : transformedBuf));
} catch (InvocationTargetException e) {
if (e.getCause() instanceof Exception) {
throw (Exception) e.getCause();
@ -44,8 +44,8 @@ public class SpongeDecodeHandler extends ByteToMessageDecoder {
}
}
} finally {
if (draft != null) {
draft.release();
if (transformedBuf != null) {
transformedBuf.release();
}
}
}

View File

@ -25,12 +25,12 @@ public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
return;
}
ByteBuf draft = ctx.alloc().buffer().writeBytes(bytebuf);
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
try {
info.transformIncoming(draft, CancelDecoderException::generate);
out.add(draft.retain());
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
out.add(transformedBuf.retain());
} finally {
draft.release();
transformedBuf.release();
}
}

View File

@ -30,29 +30,29 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
return;
}
ByteBuf draft = ctx.alloc().buffer().writeBytes(bytebuf);
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
try {
boolean needsCompress = handleCompressionOrder(ctx, draft);
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
info.transformOutgoing(draft, CancelEncoderException::generate);
info.transformOutgoing(transformedBuf, CancelEncoderException::generate);
if (needsCompress) {
recompress(ctx, draft);
recompress(ctx, transformedBuf);
}
out.add(draft.retain());
out.add(transformedBuf.retain());
} finally {
draft.release();
transformedBuf.release();
}
}
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf draft) throws InvocationTargetException {
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buf) throws InvocationTargetException {
boolean needsCompress = false;
if (!handledCompression
&& ctx.pipeline().names().indexOf("compression-encoder") > ctx.pipeline().names().indexOf("via-encoder")) {
// Need to decompress this packet due to bad order
ByteBuf decompressed = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder<?>) ctx.pipeline().get("compression-decoder"), ctx, draft).get(0);
ByteBuf decompressed = (ByteBuf) PipelineUtil.callDecode((MessageToMessageDecoder<?>) ctx.pipeline().get("compression-decoder"), ctx, buf).get(0);
try {
draft.clear().writeBytes(decompressed);
buf.clear().writeBytes(decompressed);
} finally {
decompressed.release();
}
@ -68,11 +68,11 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
return needsCompress;
}
private void recompress(ChannelHandlerContext ctx, ByteBuf draft) throws InvocationTargetException {
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) throws InvocationTargetException {
ByteBuf compressed = ctx.alloc().buffer();
try {
PipelineUtil.callEncode((MessageToByteEncoder<?>) ctx.pipeline().get("compression-encoder"), ctx, draft, compressed);
draft.clear().writeBytes(compressed);
PipelineUtil.callEncode((MessageToByteEncoder<?>) ctx.pipeline().get("compression-encoder"), ctx, buf, compressed);
buf.clear().writeBytes(compressed);
} finally {
compressed.release();
}