diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/BootstrapList.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/BootstrapList.java index 11c17037..747cb1bf 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/BootstrapList.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/BootstrapList.java @@ -1,17 +1,18 @@ package com.comphenix.protocol.injector.netty; import java.util.Collection; +import java.util.Iterator; import java.util.List; +import java.util.ListIterator; import java.util.NoSuchElementException; -import com.google.common.collect.ForwardingList; import com.google.common.collect.Lists; // Hopefully, CB won't version these as well import net.minecraft.util.io.netty.channel.ChannelFuture; import net.minecraft.util.io.netty.channel.ChannelHandler; -class BootstrapList extends ForwardingList { +class BootstrapList implements List { private List delegate; private ChannelHandler handler; @@ -33,30 +34,25 @@ class BootstrapList extends ForwardingList { } @Override - protected List delegate() { - return delegate; - } - - @Override - public boolean add(Object element) { + public synchronized boolean add(Object element) { processElement(element); - return super.add(element); + return delegate.add(element); } @Override - public boolean addAll(Collection collection) { + public synchronized boolean addAll(Collection collection) { List copy = Lists.newArrayList(collection); // Process the collection before we pass it on for (Object element : copy) { processElement(element); } - return super.addAll(copy); + return delegate.addAll(copy); } @Override - public Object set(int index, Object element) { - Object old = super.set(index, element); + public synchronized Object set(int index, Object element) { + Object old = delegate.set(index, element); // Handle the old future, and the newly inserted future if (old != element) { @@ -110,8 +106,90 @@ class BootstrapList extends ForwardingList { /** * Close and revert all changes. */ - public void close() { + public synchronized void close() { for (Object element : this) unprocessElement(element); } + + // Boiler plate + public synchronized int size() { + return delegate.size(); + } + + public synchronized boolean isEmpty() { + return delegate.isEmpty(); + } + + public boolean contains(Object o) { + return delegate.contains(o); + } + + public synchronized Iterator iterator() { + return delegate.iterator(); + } + + public synchronized Object[] toArray() { + return delegate.toArray(); + } + + public synchronized T[] toArray(T[] a) { + return delegate.toArray(a); + } + + public synchronized boolean remove(Object o) { + return delegate.remove(o); + } + + public synchronized boolean containsAll(Collection c) { + return delegate.containsAll(c); + } + + public synchronized boolean addAll(int index, Collection c) { + return delegate.addAll(index, c); + } + + public synchronized boolean removeAll(Collection c) { + return delegate.removeAll(c); + } + + public synchronized boolean retainAll(Collection c) { + return delegate.retainAll(c); + } + + public synchronized void clear() { + delegate.clear(); + } + + public synchronized Object get(int index) { + return delegate.get(index); + } + + public synchronized void add(int index, Object element) { + delegate.add(index, element); + } + + public synchronized Object remove(int index) { + return delegate.remove(index); + } + + public synchronized int indexOf(Object o) { + return delegate.indexOf(o); + } + + public synchronized int lastIndexOf(Object o) { + return delegate.lastIndexOf(o); + } + + public synchronized ListIterator listIterator() { + return delegate.listIterator(); + } + + public synchronized ListIterator listIterator(int index) { + return delegate.listIterator(index); + } + + public synchronized List subList(int fromIndex, int toIndex) { + return delegate.subList(fromIndex, toIndex); + } + // End boiler plate } diff --git a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolInjector.java b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolInjector.java index 0089f652..7ad0ee67 100644 --- a/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolInjector.java +++ b/ProtocolLib/src/main/java/com/comphenix/protocol/injector/netty/NettyProtocolInjector.java @@ -5,7 +5,6 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.InetSocketAddress; -import java.util.Collections; import java.util.List; import java.util.Set; import org.bukkit.Bukkit; @@ -112,10 +111,9 @@ public class NettyProtocolInjector implements ChannelListener { final List list = (List) field.getValue(); // Synchronize with each list before we attempt to replace them. - // We also reapply the synchronized list wrapper. - field.setValue(Collections.synchronizedList(new BootstrapList( + field.setValue(new BootstrapList( list, connectionHandler - ))); + )); } injected = true; @@ -174,7 +172,7 @@ public class NettyProtocolInjector implements ChannelListener { for (VolatileField field : bootstrapFields) { Object value = field.getValue(); - + // Undo the processed channels, if any if (value instanceof BootstrapList) { ((BootstrapList) value).close();