Switching to overriding an ArrayList directly.

This makes the injection code compatible with earlier versions of
Minecraft (even 1.0.0).
This commit is contained in:
Kristian S. Stangeland 2012-10-16 07:58:30 +02:00
parent 93468b53b3
commit b52670c4b3
4 changed files with 138 additions and 13 deletions

View File

@ -101,7 +101,7 @@ public class ProtocolLibrary extends JavaPlugin {
private void addDebugListener() { private void addDebugListener() {
// DEBUG DEBUG // DEBUG DEBUG
protocolManager.addPacketListener(new MonitorAdapter(this, ConnectionSide.BOTH) { protocolManager.addPacketListener(new MonitorAdapter(this, ConnectionSide.BOTH, logger) {
@Override @Override
public void onPacketReceiving(PacketEvent event) { public void onPacketReceiving(PacketEvent event) {
System.out.println("RECEIVING " + event.getPacketID() + " from " + event.getPlayer().getName()); System.out.println("RECEIVING " + event.getPacketID() + " from " + event.getPlayer().getName());

View File

@ -25,11 +25,14 @@ public abstract class MonitorAdapter implements PacketListener {
private ListeningWhitelist receiving = ListeningWhitelist.EMPTY_WHITELIST; private ListeningWhitelist receiving = ListeningWhitelist.EMPTY_WHITELIST;
public MonitorAdapter(Plugin plugin, ConnectionSide side) { public MonitorAdapter(Plugin plugin, ConnectionSide side) {
this(plugin, side, plugin.getLogger()); initialize(plugin, side, getLogger(plugin));
} }
public MonitorAdapter(Plugin plugin, ConnectionSide side, Logger logger) { public MonitorAdapter(Plugin plugin, ConnectionSide side, Logger logger) {
super(); initialize(plugin, side, logger);
}
private void initialize(Plugin plugin, ConnectionSide side, Logger logger) {
this.plugin = plugin; this.plugin = plugin;
// Recover in case something goes wrong // Recover in case something goes wrong
@ -47,6 +50,19 @@ public abstract class MonitorAdapter implements PacketListener {
} }
} }
/**
* Retrieve a logger, even if we're running in a CraftBukkit version that doesn't support it.
* @param plugin - the plugin to retrieve.
* @return The logger.
*/
private Logger getLogger(Plugin plugin) {
try {
return plugin.getLogger();
} catch (NoSuchMethodError e) {
return Logger.getLogger("Minecraft");
}
}
@Override @Override
public void onPacketReceiving(PacketEvent event) { public void onPacketReceiving(PacketEvent event) {
// Empty for now // Empty for now

View File

@ -210,6 +210,11 @@ class InjectedServerConnection {
// Hack to avoid the "moved to quickly" error // Hack to avoid the "moved to quickly" error
private ReplacedArrayList<Object> createReplacement(List<Object> list) { private ReplacedArrayList<Object> createReplacement(List<Object> list) {
return new ReplacedArrayList<Object>(list) { return new ReplacedArrayList<Object>(list) {
/**
* Shut up Eclipse!
*/
private static final long serialVersionUID = 2070481080950500367L;
@Override @Override
protected void onReplacing(Object inserting, Object replacement) { protected void onReplacing(Object inserting, Object replacement) {
// Is this a normal Minecraft object? // Is this a normal Minecraft object?

View File

@ -17,12 +17,14 @@
package com.comphenix.protocol.injector.player; package com.comphenix.protocol.injector.player;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.ListIterator;
import com.google.common.base.Objects; import com.google.common.base.Objects;
import com.google.common.collect.BiMap; import com.google.common.collect.BiMap;
import com.google.common.collect.ForwardingList;
import com.google.common.collect.HashBiMap; import com.google.common.collect.HashBiMap;
/** /**
@ -33,7 +35,12 @@ import com.google.common.collect.HashBiMap;
* @author Kristian * @author Kristian
* @param <TKey> - type of the elements we're replacing. * @param <TKey> - type of the elements we're replacing.
*/ */
class ReplacedArrayList<TKey> extends ForwardingList<TKey> { class ReplacedArrayList<TKey> extends ArrayList<TKey> {
/**
* Generated by Eclipse.
*/
private static final long serialVersionUID = 1008492765999744804L;
private BiMap<TKey, TKey> replaceMap = HashBiMap.create(); private BiMap<TKey, TKey> replaceMap = HashBiMap.create();
private List<TKey> underlyingList; private List<TKey> underlyingList;
@ -75,9 +82,9 @@ class ReplacedArrayList<TKey> extends ForwardingList<TKey> {
if (replaceMap.containsKey(element)) { if (replaceMap.containsKey(element)) {
TKey replacement = replaceMap.get(element); TKey replacement = replaceMap.get(element);
onReplacing(element, replacement); onReplacing(element, replacement);
return super.add(replacement); return delegate().add(replacement);
} else { } else {
return super.add(element); return delegate().add(element);
} }
} }
@ -88,9 +95,9 @@ class ReplacedArrayList<TKey> extends ForwardingList<TKey> {
if (replaceMap.containsKey(element)) { if (replaceMap.containsKey(element)) {
TKey replacement = replaceMap.get(element); TKey replacement = replaceMap.get(element);
onReplacing(element, replacement); onReplacing(element, replacement);
super.add(index, replacement); delegate().add(index, replacement);
} else { } else {
super.add(index, element); delegate().add(index, element);
} }
} }
@ -115,7 +122,7 @@ class ReplacedArrayList<TKey> extends ForwardingList<TKey> {
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Override @Override
public boolean remove(Object object) { public boolean remove(Object object) {
boolean success = super.remove(object); boolean success = delegate().remove(object);
if (success) if (success)
onRemoved((TKey) object); onRemoved((TKey) object);
@ -124,7 +131,7 @@ class ReplacedArrayList<TKey> extends ForwardingList<TKey> {
@Override @Override
public TKey remove(int index) { public TKey remove(int index) {
TKey removed = super.remove(index); TKey removed = delegate().remove(index);
if (removed != null) if (removed != null)
onRemoved(removed); onRemoved(removed);
@ -141,11 +148,108 @@ class ReplacedArrayList<TKey> extends ForwardingList<TKey> {
return size() != oldSize; return size() != oldSize;
} }
@Override
protected List<TKey> delegate() { protected List<TKey> delegate() {
return underlyingList; return underlyingList;
} }
@Override
public void clear() {
delegate().clear();
}
@Override
public boolean contains(Object o) {
return delegate().contains(o);
}
@Override
public boolean containsAll(Collection<?> c) {
return delegate().containsAll(c);
}
@Override
public TKey get(int index) {
return delegate().get(index);
}
@Override
public int indexOf(Object o) {
return delegate().indexOf(o);
}
@Override
public boolean isEmpty() {
return delegate().isEmpty();
}
@Override
public Iterator<TKey> iterator() {
return delegate().iterator();
}
@Override
public int lastIndexOf(Object o) {
return delegate().lastIndexOf(o);
}
@Override
public ListIterator<TKey> listIterator() {
return delegate().listIterator();
}
@Override
public ListIterator<TKey> listIterator(int index) {
return delegate().listIterator(index);
}
@Override
public boolean retainAll(Collection<?> c) {
int oldSize = size();
for (Iterator<TKey> it = delegate().iterator(); it.hasNext(); ) {
TKey current = it.next();
// Remove elements that are not in the list
if (!c.contains(current)) {
it.remove();
onRemoved(current);
}
}
return size() != oldSize;
}
@Override
public TKey set(int index, TKey element) {
// Make sure to replace the element
if (replaceMap.containsKey(element)) {
TKey replacement = replaceMap.get(element);
onReplacing(element, replacement);
return delegate().set(index, replacement);
} else {
return delegate().set(index, element);
}
}
@Override
public int size() {
return delegate().size();
}
@Override
public List<TKey> subList(int fromIndex, int toIndex) {
return delegate().subList(fromIndex, toIndex);
}
@Override
public Object[] toArray() {
return delegate().toArray();
}
@Override
public <T> T[] toArray(T[] a) {
return delegate().toArray(a);
}
/** /**
* Add a replace rule. * Add a replace rule.
* <p> * <p>