Ursprung
0abe72d72b
Commit
992be51646
@ -1,4 +1,4 @@
|
|||||||
/*
|
/**
|
||||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||||
* Copyright (C) 2012 Kristian S. Stangeland
|
* Copyright (C) 2012 Kristian S. Stangeland
|
||||||
*
|
*
|
||||||
@ -14,18 +14,19 @@
|
|||||||
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
* 02111-1307 USA
|
* 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.comphenix.protocol.reflect.cloning;
|
package com.comphenix.protocol.reflect.cloning;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
|
import com.comphenix.protocol.wrappers.BlockPosition;
|
||||||
import com.comphenix.protocol.wrappers.BukkitConverters;
|
import com.comphenix.protocol.wrappers.BukkitConverters;
|
||||||
import com.comphenix.protocol.wrappers.ChunkPosition;
|
import com.comphenix.protocol.wrappers.ChunkPosition;
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||||
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Maps;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an object that can clone a specific list of Bukkit- and Minecraft-related objects.
|
* Represents an object that can clone a specific list of Bukkit- and Minecraft-related objects.
|
||||||
@ -34,68 +35,75 @@ import com.google.common.collect.Lists;
|
|||||||
*/
|
*/
|
||||||
public class BukkitCloner implements Cloner {
|
public class BukkitCloner implements Cloner {
|
||||||
// List of classes we support
|
// List of classes we support
|
||||||
private Class<?>[] clonableClasses;
|
private final Map<Integer, Class<?>> clonableClasses = Maps.newConcurrentMap();
|
||||||
|
|
||||||
public BukkitCloner() {
|
public BukkitCloner() {
|
||||||
List<Class<?>> classes = Lists.newArrayList();
|
addClass(0, MinecraftReflection.getItemStackClass());
|
||||||
|
addClass(1, MinecraftReflection.getDataWatcherClass());
|
||||||
classes.add(MinecraftReflection.getItemStackClass());
|
|
||||||
classes.add(MinecraftReflection.getDataWatcherClass());
|
|
||||||
|
|
||||||
// Try to add position classes
|
// Try to add position classes
|
||||||
try {
|
try {
|
||||||
classes.add(MinecraftReflection.getBlockPositionClass());
|
addClass(2, MinecraftReflection.getBlockPositionClass());
|
||||||
} catch (Throwable ex) { }
|
} catch (Throwable ex) {
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
classes.add(MinecraftReflection.getChunkPositionClass());
|
addClass(3, MinecraftReflection.getChunkPositionClass());
|
||||||
} catch (Throwable ex) { }
|
} catch (Throwable ex) {
|
||||||
|
}
|
||||||
|
|
||||||
if (MinecraftReflection.isUsingNetty()) {
|
if (MinecraftReflection.isUsingNetty()) {
|
||||||
classes.add(MinecraftReflection.getServerPingClass());
|
addClass(4, MinecraftReflection.getServerPingClass());
|
||||||
}
|
}
|
||||||
|
|
||||||
this.clonableClasses = classes.toArray(new Class<?>[0]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addClass(int id, Class<?> clazz) {
|
||||||
|
if (clazz != null)
|
||||||
|
clonableClasses.put(id, clazz);
|
||||||
|
}
|
||||||
|
|
||||||
private int findMatchingClass(Class<?> type) {
|
private int findMatchingClass(Class<?> type) {
|
||||||
// See if is a subclass of any of our supported superclasses
|
// See if is a subclass of any of our supported superclasses
|
||||||
for (int i = 0; i < clonableClasses.length; i++) {
|
for (Entry<Integer, Class<?>> entry : clonableClasses.entrySet()) {
|
||||||
if (clonableClasses[i].isAssignableFrom(type))
|
if (entry.getValue().isAssignableFrom(type)) {
|
||||||
return i;
|
return entry.getKey();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean canClone(Object source) {
|
public boolean canClone(Object source) {
|
||||||
if (source == null)
|
if (source == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return findMatchingClass(source.getClass()) >= 0;
|
return findMatchingClass(source.getClass()) >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object clone(Object source) {
|
public Object clone(Object source) {
|
||||||
if (source == null)
|
if (source == null)
|
||||||
throw new IllegalArgumentException("source cannot be NULL.");
|
throw new IllegalArgumentException("source cannot be NULL.");
|
||||||
|
|
||||||
// Convert to a wrapper
|
// Convert to a wrapper
|
||||||
switch (findMatchingClass(source.getClass())) {
|
switch (findMatchingClass(source.getClass())) {
|
||||||
case 0:
|
case 0:
|
||||||
return MinecraftReflection.getMinecraftItemStack(MinecraftReflection.getBukkitItemStack(source).clone());
|
return MinecraftReflection.getMinecraftItemStack(MinecraftReflection.getBukkitItemStack(source).clone());
|
||||||
case 1:
|
case 1:
|
||||||
EquivalentConverter<ChunkPosition> chunkConverter = ChunkPosition.getConverter();
|
|
||||||
return chunkConverter.getGeneric(clonableClasses[1], chunkConverter.getSpecific(source));
|
|
||||||
case 2:
|
|
||||||
EquivalentConverter<WrappedDataWatcher> dataConverter = BukkitConverters.getDataWatcherConverter();
|
EquivalentConverter<WrappedDataWatcher> dataConverter = BukkitConverters.getDataWatcherConverter();
|
||||||
return dataConverter.getGeneric(clonableClasses[2], dataConverter.getSpecific(source).deepClone());
|
return dataConverter.getGeneric(clonableClasses.get(1), dataConverter.getSpecific(source).deepClone());
|
||||||
|
case 2:
|
||||||
|
EquivalentConverter<BlockPosition> blockConverter = BlockPosition.getConverter();
|
||||||
|
return blockConverter.getGeneric(clonableClasses.get(2), blockConverter.getSpecific(source));
|
||||||
case 3:
|
case 3:
|
||||||
|
EquivalentConverter<ChunkPosition> chunkConverter = ChunkPosition.getConverter();
|
||||||
|
return chunkConverter.getGeneric(clonableClasses.get(3), chunkConverter.getSpecific(source));
|
||||||
|
case 4:
|
||||||
EquivalentConverter<WrappedServerPing> serverConverter = BukkitConverters.getWrappedServerPingConverter();
|
EquivalentConverter<WrappedServerPing> serverConverter = BukkitConverters.getWrappedServerPingConverter();
|
||||||
return serverConverter.getGeneric(clonableClasses[3], serverConverter.getSpecific(source).deepClone());
|
return serverConverter.getGeneric(clonableClasses.get(4), serverConverter.getSpecific(source).deepClone());
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Cannot clone objects of type " + source.getClass());
|
throw new IllegalArgumentException("Cannot clone objects of type " + source.getClass());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
In neuem Issue referenzieren
Einen Benutzer sperren