mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-12-18 07:07:38 +01:00
parent
0abe72d72b
commit
992be51646
@ -1,4 +1,4 @@
|
||||
/*
|
||||
/**
|
||||
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||
* 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
|
||||
* 02111-1307 USA
|
||||
*/
|
||||
|
||||
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.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.BlockPosition;
|
||||
import com.comphenix.protocol.wrappers.BukkitConverters;
|
||||
import com.comphenix.protocol.wrappers.ChunkPosition;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||
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.
|
||||
@ -34,68 +35,75 @@ import com.google.common.collect.Lists;
|
||||
*/
|
||||
public class BukkitCloner implements Cloner {
|
||||
// List of classes we support
|
||||
private Class<?>[] clonableClasses;
|
||||
|
||||
private final Map<Integer, Class<?>> clonableClasses = Maps.newConcurrentMap();
|
||||
|
||||
public BukkitCloner() {
|
||||
List<Class<?>> classes = Lists.newArrayList();
|
||||
|
||||
classes.add(MinecraftReflection.getItemStackClass());
|
||||
classes.add(MinecraftReflection.getDataWatcherClass());
|
||||
addClass(0, MinecraftReflection.getItemStackClass());
|
||||
addClass(1, MinecraftReflection.getDataWatcherClass());
|
||||
|
||||
// Try to add position classes
|
||||
try {
|
||||
classes.add(MinecraftReflection.getBlockPositionClass());
|
||||
} catch (Throwable ex) { }
|
||||
addClass(2, MinecraftReflection.getBlockPositionClass());
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
|
||||
try {
|
||||
classes.add(MinecraftReflection.getChunkPositionClass());
|
||||
} catch (Throwable ex) { }
|
||||
addClass(3, MinecraftReflection.getChunkPositionClass());
|
||||
} catch (Throwable ex) {
|
||||
}
|
||||
|
||||
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) {
|
||||
// See if is a subclass of any of our supported superclasses
|
||||
for (int i = 0; i < clonableClasses.length; i++) {
|
||||
if (clonableClasses[i].isAssignableFrom(type))
|
||||
return i;
|
||||
for (Entry<Integer, Class<?>> entry : clonableClasses.entrySet()) {
|
||||
if (entry.getValue().isAssignableFrom(type)) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean canClone(Object source) {
|
||||
if (source == null)
|
||||
return false;
|
||||
|
||||
|
||||
return findMatchingClass(source.getClass()) >= 0;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public Object clone(Object source) {
|
||||
if (source == null)
|
||||
throw new IllegalArgumentException("source cannot be NULL.");
|
||||
|
||||
|
||||
// Convert to a wrapper
|
||||
switch (findMatchingClass(source.getClass())) {
|
||||
case 0:
|
||||
return MinecraftReflection.getMinecraftItemStack(MinecraftReflection.getBukkitItemStack(source).clone());
|
||||
case 1:
|
||||
EquivalentConverter<ChunkPosition> chunkConverter = ChunkPosition.getConverter();
|
||||
return chunkConverter.getGeneric(clonableClasses[1], chunkConverter.getSpecific(source));
|
||||
case 2:
|
||||
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:
|
||||
EquivalentConverter<ChunkPosition> chunkConverter = ChunkPosition.getConverter();
|
||||
return chunkConverter.getGeneric(clonableClasses.get(3), chunkConverter.getSpecific(source));
|
||||
case 4:
|
||||
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:
|
||||
throw new IllegalArgumentException("Cannot clone objects of type " + source.getClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user