Hack for WrappedSignedProperty on Cauldron 1.7.10. FIXES #54
Dieser Commit ist enthalten in:
Ursprung
4ccd8853c4
Commit
d717ff1586
@ -0,0 +1,316 @@
|
||||
package com.comphenix.protocol.wrappers;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
|
||||
import com.comphenix.protocol.reflect.accessors.Accessors;
|
||||
import com.comphenix.protocol.reflect.accessors.MethodAccessor;
|
||||
import com.comphenix.protocol.wrappers.collection.ConvertedSet;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multiset;
|
||||
|
||||
/**
|
||||
* Wrap multimap and multiset from another version of Guava by using reflection.
|
||||
* <p>
|
||||
* This is often the last resort, if we can't remap manually.
|
||||
* @author Kristian
|
||||
*/
|
||||
class GuavaReflection {
|
||||
/**
|
||||
* Wrap a Bukkit multimap around Minecraft's internal multimap.
|
||||
* @param multimap - the multimap to wrap.
|
||||
* @return The Bukkit multimap.
|
||||
*/
|
||||
public static <TKey, TValue> Multimap<TKey, TValue> getBukkitMultimap(
|
||||
final Object multimap) {
|
||||
return new Multimap<TKey, TValue>() {
|
||||
private Class<?> multimapClass = multimap.getClass();
|
||||
private MethodAccessor methodAsMap = Accessors.getMethodAccessor(multimapClass, "asMap");
|
||||
private MethodAccessor methodClear = Accessors.getMethodAccessor(multimapClass, "clear");
|
||||
private MethodAccessor methodContainsEntry = Accessors.getMethodAccessor(multimapClass, "containsEntry",Object.class, Object.class);
|
||||
private MethodAccessor methodContainsKey = Accessors.getMethodAccessor(multimapClass, "containsKey", Object.class);
|
||||
private MethodAccessor methodContainsValue = Accessors.getMethodAccessor(multimapClass, "containsValue", Object.class);
|
||||
private MethodAccessor methodEntries = Accessors.getMethodAccessor(multimapClass, "entries");
|
||||
private MethodAccessor methodGet = Accessors.getMethodAccessor(multimapClass, "get", Object.class);
|
||||
private MethodAccessor methodIsEmpty = Accessors.getMethodAccessor(multimapClass, "isEmpty");
|
||||
private MethodAccessor methodKeySet = Accessors.getMethodAccessor(multimapClass, "keySet");
|
||||
private MethodAccessor methodKeys = Accessors.getMethodAccessor(multimapClass, "keys");
|
||||
private MethodAccessor methodPut = Accessors.getMethodAccessor(multimapClass, "put", Object.class, Object.class);
|
||||
private MethodAccessor methodPutAll = Accessors.getMethodAccessor(multimapClass, "putAll", Object.class, Iterable.class);
|
||||
private MethodAccessor methodRemove = Accessors.getMethodAccessor(multimapClass, "remove", Object.class, Object.class);
|
||||
private MethodAccessor methodRemoveAll = Accessors.getMethodAccessor(multimapClass, "removeAll", Object.class);
|
||||
private MethodAccessor methodReplaceValues = Accessors.getMethodAccessor(multimapClass, "replaceValues", Object.class, Iterable.class);
|
||||
private MethodAccessor methodSize = Accessors.getMethodAccessor(multimapClass, "size");
|
||||
private MethodAccessor methodValues = Accessors.getMethodAccessor(multimapClass, "values");
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Map<TKey, Collection<TValue>> asMap() {
|
||||
return (Map<TKey, Collection<TValue>>) methodAsMap.invoke(multimap);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
methodClear.invoke(multimap);
|
||||
}
|
||||
|
||||
public boolean containsEntry(Object arg0, Object arg1) {
|
||||
return (Boolean) methodContainsEntry.invoke(multimap, arg0, arg1);
|
||||
}
|
||||
|
||||
public boolean containsKey(Object arg0) {
|
||||
return (Boolean) methodContainsKey.invoke(multimap, arg0);
|
||||
}
|
||||
|
||||
public boolean containsValue(Object arg0) {
|
||||
return (Boolean) methodContainsValue.invoke(multimap, arg0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<Entry<TKey, TValue>> entries() {
|
||||
return (Collection<Entry<TKey, TValue>>) methodEntries.invoke(multimap);
|
||||
}
|
||||
|
||||
public boolean equals(Object arg0) {
|
||||
return multimap.equals(arg0);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return multimap.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return multimap.toString();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<TValue> get(TKey arg0) {
|
||||
return (Collection<TValue>) methodGet.invoke(multimap, arg0);
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (Boolean) methodIsEmpty.invoke(multimap);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<TKey> keySet() {
|
||||
return (Set<TKey>) methodKeySet.invoke(multimap);
|
||||
}
|
||||
|
||||
public Multiset<TKey> keys() {
|
||||
return getBukkitMultiset(methodKeys.invoke(multimap));
|
||||
}
|
||||
|
||||
public boolean put(TKey arg0, TValue arg1) {
|
||||
return (Boolean) methodPut.invoke(multimap, arg0, arg1);
|
||||
}
|
||||
|
||||
public boolean putAll(com.google.common.collect.Multimap<? extends TKey, ? extends TValue> arg0) {
|
||||
boolean result = false;
|
||||
|
||||
// Add each entry
|
||||
for (Entry<? extends TKey, ? extends TValue> entry : arg0.entries()) {
|
||||
result |= (Boolean) methodPut.invoke(multimap, entry.getKey(), entry.getValue());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public boolean putAll(TKey arg0, Iterable<? extends TValue> arg1) {
|
||||
return (Boolean) methodPutAll.invoke(arg0, arg1);
|
||||
}
|
||||
|
||||
public boolean remove(Object arg0, Object arg1) {
|
||||
return (Boolean) methodRemove.invoke(multimap, arg0, arg1);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<TValue> removeAll(Object arg0) {
|
||||
return (Collection<TValue>) methodRemoveAll.invoke(multimap, arg0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<TValue> replaceValues(TKey arg0, Iterable<? extends TValue> arg1) {
|
||||
return (Collection<TValue>) methodReplaceValues.invoke(multimap, arg0, arg1);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return (Integer) methodSize.invoke(multimap);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<TValue> values() {
|
||||
return (Collection<TValue>) methodValues.invoke(multimap);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static <TValue> Multiset<TValue> getBukkitMultiset(final Object multiset) {
|
||||
return new Multiset<TValue>() {
|
||||
private Class<?> multisetClass = multiset.getClass();
|
||||
private MethodAccessor methodAddMany = Accessors.getMethodAccessor(multisetClass, "add", Object.class, int.class);
|
||||
private MethodAccessor methodAddOne = Accessors.getMethodAccessor(multisetClass, "add", Object.class);
|
||||
private MethodAccessor methodAddAll = Accessors.getMethodAccessor(multisetClass, "addAll", Collection.class);
|
||||
private MethodAccessor methodClear = Accessors.getMethodAccessor(multisetClass, "clear");
|
||||
private MethodAccessor methodContains = Accessors.getMethodAccessor(multisetClass, "contains", Object.class);
|
||||
private MethodAccessor methodContainsAll = Accessors.getMethodAccessor(multisetClass, "containsAll", Collection.class);
|
||||
private MethodAccessor methodCount = Accessors.getMethodAccessor(multisetClass, "count", Object.class);
|
||||
private MethodAccessor methodElementSet = Accessors.getMethodAccessor(multisetClass, "elementSet");
|
||||
private MethodAccessor methodEntrySet = Accessors.getMethodAccessor(multisetClass, "entrySet");
|
||||
private MethodAccessor methodIsEmpty = Accessors.getMethodAccessor(multisetClass, "isEmpty");
|
||||
private MethodAccessor methodIterator = Accessors.getMethodAccessor(multisetClass, "iterator");
|
||||
private MethodAccessor methodRemoveCount = Accessors.getMethodAccessor(multisetClass, "remove", Object.class, int.class);
|
||||
private MethodAccessor methodRemoveOne = Accessors.getMethodAccessor(multisetClass, "remove", Object.class);
|
||||
private MethodAccessor methodRemoveAll = Accessors.getMethodAccessor(multisetClass, "removeAll", Collection.class);
|
||||
private MethodAccessor methodRetainAll = Accessors.getMethodAccessor(multisetClass, "retainAll", Collection.class);
|
||||
private MethodAccessor methodSetCountOldNew = Accessors.getMethodAccessor(multisetClass, "setCount", Object.class, int.class, int.class);
|
||||
private MethodAccessor methodSetCountNew = Accessors.getMethodAccessor(multisetClass, "setCount", Object.class, int.class);
|
||||
private MethodAccessor methodSize = Accessors.getMethodAccessor(multisetClass, "size");
|
||||
private MethodAccessor methodToArray = Accessors.getMethodAccessor(multisetClass, "toArray");
|
||||
private MethodAccessor methodToArrayBuffer = Accessors.getMethodAccessor(multisetClass, "toArray", Object[].class);
|
||||
|
||||
public int add(TValue arg0, int arg1) {
|
||||
return (Integer) methodAddMany.invoke(multiset, arg0, arg1);
|
||||
}
|
||||
|
||||
public boolean add(TValue arg0) {
|
||||
return (Boolean) methodAddOne.invoke(multiset, arg0);
|
||||
}
|
||||
|
||||
public boolean addAll(Collection<? extends TValue> c) {
|
||||
return (Boolean) methodAddAll.invoke(multiset, c);
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
methodClear.invoke(multiset);
|
||||
}
|
||||
|
||||
public boolean contains(Object arg0) {
|
||||
return (Boolean) methodContains.invoke(multiset, arg0);
|
||||
}
|
||||
|
||||
public boolean containsAll(Collection<?> arg0) {
|
||||
return (Boolean) methodContainsAll.invoke(multiset, arg0);
|
||||
}
|
||||
|
||||
public int count(Object arg0) {
|
||||
return (Integer) methodCount.invoke(multiset, arg0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Set<TValue> elementSet() {
|
||||
return (Set<TValue>) methodElementSet.invoke(multiset);
|
||||
}
|
||||
|
||||
@SuppressWarnings({"unchecked", "rawtypes"})
|
||||
public Set<Multiset.Entry<TValue>> entrySet() {
|
||||
return new ConvertedSet<
|
||||
Object,
|
||||
Multiset.Entry<TValue>>
|
||||
((Set) methodEntrySet.invoke(multiset)) {
|
||||
|
||||
@Override
|
||||
protected com.google.common.collect.Multiset.Entry<TValue> toOuter(
|
||||
Object inner) {
|
||||
return getBukkitEntry(inner);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object toInner(
|
||||
com.google.common.collect.Multiset.Entry<TValue> outer) {
|
||||
throw new UnsupportedOperationException("Cannot convert " + outer);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean equals(Object arg0) {
|
||||
return multiset.equals(arg0);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return multiset.hashCode();
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return (Boolean) methodIsEmpty.invoke(multiset);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<TValue> iterator() {
|
||||
return (Iterator<TValue>) methodIterator.invoke(multiset);
|
||||
}
|
||||
|
||||
public int remove(Object arg0, int arg1) {
|
||||
return (Integer) methodRemoveCount.invoke(multiset, arg0, arg1);
|
||||
}
|
||||
|
||||
public boolean remove(Object arg0) {
|
||||
return (Boolean) methodRemoveOne.invoke(multiset, arg0);
|
||||
}
|
||||
|
||||
public boolean removeAll(Collection<?> arg0) {
|
||||
return (Boolean) methodRemoveAll.invoke(multiset, arg0);
|
||||
}
|
||||
|
||||
public boolean retainAll(Collection<?> arg0) {
|
||||
return (Boolean) methodRetainAll.invoke(multiset, arg0);
|
||||
}
|
||||
|
||||
public boolean setCount(TValue arg0, int arg1, int arg2) {
|
||||
return (Boolean) methodSetCountOldNew.invoke(multiset, arg0, arg1, arg2);
|
||||
}
|
||||
|
||||
public int setCount(TValue arg0, int arg1) {
|
||||
return (Integer) methodSetCountNew.invoke(multiset, arg0, arg1);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return (Integer) methodSize.invoke(multiset);
|
||||
}
|
||||
|
||||
public Object[] toArray() {
|
||||
return (Object[]) methodToArray.invoke(multiset);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <T> T[] toArray(T[] a) {
|
||||
return (T[]) methodToArrayBuffer.invoke(multiset, a);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return multiset.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private static <TValue> Multiset.Entry<TValue> getBukkitEntry(final Object entry) {
|
||||
return new Multiset.Entry<TValue>() {
|
||||
private Class<?> entryClass = entry.getClass();
|
||||
private MethodAccessor methodEquals = Accessors.getMethodAccessor(entryClass, "equals", Object.class);
|
||||
private MethodAccessor methodGetCount = Accessors.getMethodAccessor(entryClass, "getCount");
|
||||
private MethodAccessor methodGetElement = Accessors.getMethodAccessor(entryClass, "getElement");
|
||||
|
||||
public boolean equals(Object arg0) {
|
||||
return (Boolean) methodEquals.invoke(entry, arg0);
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return (Integer) methodGetCount.invoke(entry);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public TValue getElement() {
|
||||
return (TValue) methodGetElement.invoke(entry);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return entry.hashCode();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return entry.toString();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
@ -15,6 +15,8 @@ import com.google.common.collect.Multiset;
|
||||
* @author Kristian
|
||||
*/
|
||||
class GuavaWrappers {
|
||||
private static volatile boolean USE_REFLECTION_FALLBACK = false;
|
||||
|
||||
/**
|
||||
* Wrap a Bukkit multimap around Minecraft's internal multimap.
|
||||
* @param multimap - the multimap to wrap.
|
||||
@ -22,7 +24,12 @@ class GuavaWrappers {
|
||||
*/
|
||||
public static <TKey, TValue> Multimap<TKey, TValue> getBukkitMultimap(
|
||||
final net.minecraft.util.com.google.common.collect.Multimap<TKey, TValue> multimap) {
|
||||
return new Multimap<TKey, TValue>() {
|
||||
|
||||
if (USE_REFLECTION_FALLBACK) {
|
||||
return GuavaReflection.getBukkitMultimap(multimap);
|
||||
}
|
||||
|
||||
Multimap<TKey, TValue> result = new Multimap<TKey, TValue>() {
|
||||
public Map<TKey, Collection<TValue>> asMap() {
|
||||
return multimap.asMap();
|
||||
}
|
||||
@ -109,12 +116,23 @@ class GuavaWrappers {
|
||||
return multimap.values();
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
result.size(); // Test
|
||||
return result;
|
||||
} catch (LinkageError e) {
|
||||
// Occurs on Cauldron 1.7.10
|
||||
USE_REFLECTION_FALLBACK = true;
|
||||
return GuavaReflection.getBukkitMultimap(multimap);
|
||||
}
|
||||
}
|
||||
|
||||
public static <TValue> Multiset<TValue> getBukkitMultiset(net.minecraft.util.com.google.common.collect.Multiset<TValue> multiset2) {
|
||||
return new Multiset<TValue>() {
|
||||
private net.minecraft.util.com.google.common.collect.Multiset<TValue> multiset;
|
||||
|
||||
public static <TValue> Multiset<TValue> getBukkitMultiset(final net.minecraft.util.com.google.common.collect.Multiset<TValue> multiset) {
|
||||
if (USE_REFLECTION_FALLBACK) {
|
||||
return GuavaReflection.getBukkitMultiset(multiset);
|
||||
}
|
||||
|
||||
Multiset<TValue> result = new Multiset<TValue>() {
|
||||
public int add(TValue arg0, int arg1) {
|
||||
return multiset.add(arg0, arg1);
|
||||
}
|
||||
@ -223,6 +241,14 @@ class GuavaWrappers {
|
||||
return multiset.toString();
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
result.size(); // Test
|
||||
return result;
|
||||
} catch (LinkageError e) {
|
||||
USE_REFLECTION_FALLBACK = true;
|
||||
return GuavaReflection.getBukkitMultiset(multiset);
|
||||
}
|
||||
}
|
||||
|
||||
private static <TValue> Multiset.Entry<TValue> getBukkitEntry(final net.minecraft.util.com.google.common.collect.Multiset.Entry<TValue> entry) {
|
||||
|
In neuem Issue referenzieren
Einen Benutzer sperren