Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-27 08:30:09 +01:00
Fixup docs, remove ConcurrentList
Dieser Commit ist enthalten in:
Ursprung
df495f8131
Commit
aa59ed112a
@ -17,12 +17,18 @@ import us.myles.ViaVersion.api.platform.ViaPlatform;
|
|||||||
import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator;
|
import us.myles.ViaVersion.bukkit.classgenerator.ClassGenerator;
|
||||||
import us.myles.ViaVersion.bukkit.commands.BukkitCommandHandler;
|
import us.myles.ViaVersion.bukkit.commands.BukkitCommandHandler;
|
||||||
import us.myles.ViaVersion.bukkit.commands.BukkitCommandSender;
|
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.bukkit.util.NMSUtil;
|
||||||
import us.myles.ViaVersion.dump.PluginInfo;
|
import us.myles.ViaVersion.dump.PluginInfo;
|
||||||
import us.myles.ViaVersion.util.GsonUtil;
|
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> {
|
public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player> {
|
||||||
private static ViaVersionPlugin instance;
|
private static ViaVersionPlugin instance;
|
||||||
@ -54,15 +60,6 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaPlatform<Player>
|
|||||||
|
|
||||||
// Check if we're using protocol support too
|
// Check if we're using protocol support too
|
||||||
protocolSupport = Bukkit.getPluginManager().getPlugin("ProtocolSupport") != null;
|
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
|
@Override
|
||||||
|
@ -27,15 +27,15 @@ public class BukkitDecodeHandler extends ByteToMessageDecoder {
|
|||||||
throw CancelDecoderException.generate(null);
|
throw CancelDecoderException.generate(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf draft = null;
|
ByteBuf transformedBuf = null;
|
||||||
try {
|
try {
|
||||||
if (info.shouldTransformPacket()) {
|
if (info.shouldTransformPacket()) {
|
||||||
draft = ctx.alloc().buffer().writeBytes(bytebuf);
|
transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||||
info.transformIncoming(draft, CancelDecoderException::generate);
|
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (InvocationTargetException e) {
|
||||||
if (e.getCause() instanceof Exception) {
|
if (e.getCause() instanceof Exception) {
|
||||||
throw (Exception) e.getCause();
|
throw (Exception) e.getCause();
|
||||||
@ -44,8 +44,8 @@ public class BukkitDecodeHandler extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (draft != null) {
|
if (transformedBuf != null) {
|
||||||
draft.release();
|
transformedBuf.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,17 +12,17 @@ import us.myles.ViaVersion.api.Via;
|
|||||||
import us.myles.ViaVersion.api.platform.ViaInjector;
|
import us.myles.ViaVersion.api.platform.ViaInjector;
|
||||||
import us.myles.ViaVersion.bukkit.handlers.BukkitChannelInitializer;
|
import us.myles.ViaVersion.bukkit.handlers.BukkitChannelInitializer;
|
||||||
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
import us.myles.ViaVersion.bukkit.util.NMSUtil;
|
||||||
import us.myles.ViaVersion.util.ConcurrentList;
|
|
||||||
import us.myles.ViaVersion.util.ListWrapper;
|
import us.myles.ViaVersion.util.ListWrapper;
|
||||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class BukkitViaInjector implements ViaInjector {
|
public class BukkitViaInjector implements ViaInjector {
|
||||||
private final List<ChannelFuture> injectedFutures = new ConcurrentList<>();
|
private final List<ChannelFuture> injectedFutures = new ArrayList<>();
|
||||||
private final List<Pair<Field, Object>> injectedLists = new ConcurrentList<>();
|
private final List<Pair<Field, Object>> injectedLists = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void inject() throws Exception {
|
public void inject() throws Exception {
|
||||||
@ -231,25 +231,6 @@ public class BukkitViaInjector implements ViaInjector {
|
|||||||
return connection;
|
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() {
|
public static boolean isBinded() {
|
||||||
try {
|
try {
|
||||||
Object connection = getServerConnection();
|
Object connection = getServerConnection();
|
||||||
|
@ -25,12 +25,12 @@ public class BungeeDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf draft = ctx.alloc().buffer().writeBytes(bytebuf);
|
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||||
try {
|
try {
|
||||||
info.transformIncoming(draft, CancelDecoderException::generate);
|
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||||
out.add(draft.retain());
|
out.add(transformedBuf.retain());
|
||||||
} finally {
|
} finally {
|
||||||
draft.release();
|
transformedBuf.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,29 +27,29 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf draft = ctx.alloc().buffer().writeBytes(bytebuf);
|
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||||
try {
|
try {
|
||||||
boolean needsCompress = handleCompressionOrder(ctx, draft);
|
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
|
||||||
info.transformOutgoing(draft, CancelEncoderException::generate);
|
info.transformOutgoing(transformedBuf, CancelEncoderException::generate);
|
||||||
|
|
||||||
if (needsCompress) {
|
if (needsCompress) {
|
||||||
recompress(ctx, draft);
|
recompress(ctx, transformedBuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
out.add(draft.retain());
|
out.add(transformedBuf.retain());
|
||||||
} finally {
|
} finally {
|
||||||
draft.release();
|
transformedBuf.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf draft) {
|
private boolean handleCompressionOrder(ChannelHandlerContext ctx, ByteBuf buf) {
|
||||||
boolean needsCompress = false;
|
boolean needsCompress = false;
|
||||||
if (!handledCompression) {
|
if (!handledCompression) {
|
||||||
if (ctx.pipeline().names().indexOf("compress") > ctx.pipeline().names().indexOf("via-encoder")) {
|
if (ctx.pipeline().names().indexOf("compress") > ctx.pipeline().names().indexOf("via-encoder")) {
|
||||||
// Need to decompress this packet due to bad order
|
// Need to decompress this packet due to bad order
|
||||||
ByteBuf decompressed = BungeePipelineUtil.decompress(ctx, draft);
|
ByteBuf decompressed = BungeePipelineUtil.decompress(ctx, buf);
|
||||||
try {
|
try {
|
||||||
draft.clear().writeBytes(decompressed);
|
buf.clear().writeBytes(decompressed);
|
||||||
} finally {
|
} finally {
|
||||||
decompressed.release();
|
decompressed.release();
|
||||||
}
|
}
|
||||||
@ -66,10 +66,10 @@ public class BungeeEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
|||||||
return needsCompress;
|
return needsCompress;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void recompress(ChannelHandlerContext ctx, ByteBuf draft) {
|
private void recompress(ChannelHandlerContext ctx, ByteBuf buf) {
|
||||||
ByteBuf compressed = BungeePipelineUtil.compress(ctx, draft);
|
ByteBuf compressed = BungeePipelineUtil.compress(ctx, buf);
|
||||||
try {
|
try {
|
||||||
draft.clear().writeBytes(compressed);
|
buf.clear().writeBytes(compressed);
|
||||||
} finally {
|
} finally {
|
||||||
compressed.release();
|
compressed.release();
|
||||||
}
|
}
|
||||||
|
@ -291,44 +291,44 @@ public class UserConnection {
|
|||||||
/**
|
/**
|
||||||
* Transforms the clientbound packet contained in draft ByteBuf.
|
* 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
|
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
|
||||||
* packet is cancelled
|
* packet is cancelled
|
||||||
* @throws Exception when transforming failed or this packet is cancelled
|
* @throws Exception when transforming failed or this packet is cancelled
|
||||||
*/
|
*/
|
||||||
public void transformOutgoing(ByteBuf draft, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
public void transformOutgoing(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||||
if (!draft.isReadable()) return;
|
if (!buf.isReadable()) return;
|
||||||
transform(draft, Direction.OUTGOING, cancelSupplier);
|
transform(buf, Direction.OUTGOING, cancelSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transforms the serverbound packet contained in draft ByteBuf.
|
* 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
|
* @param cancelSupplier Function called with original CancelException for generating the Exception used when
|
||||||
* packet is cancelled
|
* packet is cancelled
|
||||||
* @throws Exception when transforming failed or this packet is cancelled
|
* @throws Exception when transforming failed or this packet is cancelled
|
||||||
*/
|
*/
|
||||||
public void transformIncoming(ByteBuf draft, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
public void transformIncoming(ByteBuf buf, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||||
if (!draft.isReadable()) return;
|
if (!buf.isReadable()) return;
|
||||||
transform(draft, Direction.INCOMING, cancelSupplier);
|
transform(buf, Direction.INCOMING, cancelSupplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void transform(ByteBuf draft, Direction direction, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
private void transform(ByteBuf buf, Direction direction, Function<Throwable, Exception> cancelSupplier) throws Exception {
|
||||||
int id = Type.VAR_INT.read(draft);
|
int id = Type.VAR_INT.read(buf);
|
||||||
if (id == PacketWrapper.PASSTHROUGH_ID) return;
|
if (id == PacketWrapper.PASSTHROUGH_ID) return;
|
||||||
|
|
||||||
PacketWrapper wrapper = new PacketWrapper(id, draft, this);
|
PacketWrapper wrapper = new PacketWrapper(id, buf, this);
|
||||||
try {
|
try {
|
||||||
protocolInfo.getPipeline().transform(direction, protocolInfo.getState(), wrapper);
|
protocolInfo.getPipeline().transform(direction, protocolInfo.getState(), wrapper);
|
||||||
} catch (CancelException ex) {
|
} catch (CancelException ex) {
|
||||||
throw cancelSupplier.apply(ex);
|
throw cancelSupplier.apply(ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf transformed = draft.alloc().buffer();
|
ByteBuf transformed = buf.alloc().buffer();
|
||||||
try {
|
try {
|
||||||
wrapper.writeToBuffer(transformed);
|
wrapper.writeToBuffer(transformed);
|
||||||
draft.clear().writeBytes(transformed);
|
buf.clear().writeBytes(transformed);
|
||||||
} finally {
|
} finally {
|
||||||
transformed.release();
|
transformed.release();
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@ import io.netty.handler.codec.DecoderException;
|
|||||||
import us.myles.ViaVersion.api.Via;
|
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 class CancelDecoderException extends DecoderException {
|
||||||
public static final CancelDecoderException CACHED = new CancelDecoderException("CACHED") {
|
public static final CancelDecoderException CACHED = new CancelDecoderException("CACHED") {
|
||||||
|
@ -4,7 +4,8 @@ import io.netty.handler.codec.EncoderException;
|
|||||||
import us.myles.ViaVersion.api.Via;
|
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 class CancelEncoderException extends EncoderException {
|
||||||
public static final CancelEncoderException CACHED = new CancelEncoderException("CACHED") {
|
public static final CancelEncoderException CACHED = new CancelEncoderException("CACHED") {
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package us.myles.ViaVersion.exception;
|
package us.myles.ViaVersion.exception;
|
||||||
|
|
||||||
|
import io.netty.handler.codec.CodecException;
|
||||||
import us.myles.ViaVersion.api.Via;
|
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 class CancelException extends Exception {
|
||||||
public static final CancelException CACHED = new CancelException("Cached - Enable /viaver debug to not use cached exception") {
|
public static final CancelException CACHED = new CancelException("Cached - Enable /viaver debug to not use cached exception") {
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,15 +27,15 @@ public class SpongeDecodeHandler extends ByteToMessageDecoder {
|
|||||||
throw CancelDecoderException.generate(null);
|
throw CancelDecoderException.generate(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf draft = null;
|
ByteBuf transformedBuf = null;
|
||||||
try {
|
try {
|
||||||
if (info.shouldTransformPacket()) {
|
if (info.shouldTransformPacket()) {
|
||||||
draft = ctx.alloc().buffer().writeBytes(bytebuf);
|
transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||||
info.transformIncoming(draft, CancelDecoderException::generate);
|
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
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) {
|
} catch (InvocationTargetException e) {
|
||||||
if (e.getCause() instanceof Exception) {
|
if (e.getCause() instanceof Exception) {
|
||||||
throw (Exception) e.getCause();
|
throw (Exception) e.getCause();
|
||||||
@ -44,8 +44,8 @@ public class SpongeDecodeHandler extends ByteToMessageDecoder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
if (draft != null) {
|
if (transformedBuf != null) {
|
||||||
draft.release();
|
transformedBuf.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,12 +25,12 @@ public class VelocityDecodeHandler extends MessageToMessageDecoder<ByteBuf> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf draft = ctx.alloc().buffer().writeBytes(bytebuf);
|
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||||
try {
|
try {
|
||||||
info.transformIncoming(draft, CancelDecoderException::generate);
|
info.transformIncoming(transformedBuf, CancelDecoderException::generate);
|
||||||
out.add(draft.retain());
|
out.add(transformedBuf.retain());
|
||||||
} finally {
|
} finally {
|
||||||
draft.release();
|
transformedBuf.release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,29 +30,29 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ByteBuf draft = ctx.alloc().buffer().writeBytes(bytebuf);
|
ByteBuf transformedBuf = ctx.alloc().buffer().writeBytes(bytebuf);
|
||||||
try {
|
try {
|
||||||
boolean needsCompress = handleCompressionOrder(ctx, draft);
|
boolean needsCompress = handleCompressionOrder(ctx, transformedBuf);
|
||||||
|
|
||||||
info.transformOutgoing(draft, CancelEncoderException::generate);
|
info.transformOutgoing(transformedBuf, CancelEncoderException::generate);
|
||||||
|
|
||||||
if (needsCompress) {
|
if (needsCompress) {
|
||||||
recompress(ctx, draft);
|
recompress(ctx, transformedBuf);
|
||||||
}
|
}
|
||||||
out.add(draft.retain());
|
out.add(transformedBuf.retain());
|
||||||
} finally {
|
} 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;
|
boolean needsCompress = false;
|
||||||
if (!handledCompression
|
if (!handledCompression
|
||||||
&& ctx.pipeline().names().indexOf("compression-encoder") > ctx.pipeline().names().indexOf("via-encoder")) {
|
&& ctx.pipeline().names().indexOf("compression-encoder") > ctx.pipeline().names().indexOf("via-encoder")) {
|
||||||
// Need to decompress this packet due to bad order
|
// 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 {
|
try {
|
||||||
draft.clear().writeBytes(decompressed);
|
buf.clear().writeBytes(decompressed);
|
||||||
} finally {
|
} finally {
|
||||||
decompressed.release();
|
decompressed.release();
|
||||||
}
|
}
|
||||||
@ -68,11 +68,11 @@ public class VelocityEncodeHandler extends MessageToMessageEncoder<ByteBuf> {
|
|||||||
return needsCompress;
|
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();
|
ByteBuf compressed = ctx.alloc().buffer();
|
||||||
try {
|
try {
|
||||||
PipelineUtil.callEncode((MessageToByteEncoder<?>) ctx.pipeline().get("compression-encoder"), ctx, draft, compressed);
|
PipelineUtil.callEncode((MessageToByteEncoder<?>) ctx.pipeline().get("compression-encoder"), ctx, buf, compressed);
|
||||||
draft.clear().writeBytes(compressed);
|
buf.clear().writeBytes(compressed);
|
||||||
} finally {
|
} finally {
|
||||||
compressed.release();
|
compressed.release();
|
||||||
}
|
}
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren