Added a shallow clone method.
Removed the identity cloner, as it's no longer needed.
Dieser Commit ist enthalten in:
Ursprung
dea725e1e3
Commit
695a4f3b0e
@ -30,6 +30,8 @@ import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.WorldType;
|
||||
import org.bukkit.entity.Entity;
|
||||
@ -38,13 +40,19 @@ import org.bukkit.inventory.ItemStack;
|
||||
import com.comphenix.protocol.injector.StructureCache;
|
||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||
import com.comphenix.protocol.reflect.ObjectWriter;
|
||||
import com.comphenix.protocol.reflect.StructureModifier;
|
||||
import com.comphenix.protocol.reflect.cloning.AggregateCloner;
|
||||
import com.comphenix.protocol.reflect.cloning.Cloner;
|
||||
import com.comphenix.protocol.reflect.cloning.FieldCloner;
|
||||
import com.comphenix.protocol.reflect.cloning.AggregateCloner.BuilderParameters;
|
||||
import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||
import com.comphenix.protocol.wrappers.BukkitConverters;
|
||||
import com.comphenix.protocol.wrappers.ChunkPosition;
|
||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
/**
|
||||
@ -69,6 +77,21 @@ public class PacketContainer implements Serializable {
|
||||
private static ConcurrentMap<Class<?>, Method> writeMethods = Maps.newConcurrentMap();
|
||||
private static ConcurrentMap<Class<?>, Method> readMethods = Maps.newConcurrentMap();
|
||||
|
||||
// Used to clone packets
|
||||
private static final AggregateCloner DEEP_CLONER = AggregateCloner.DEFAULT;
|
||||
private static final AggregateCloner SHALLOW_CLONER = AggregateCloner.newBuilder().
|
||||
instanceProvider(DefaultInstances.DEFAULT).
|
||||
andThen(new Function<BuilderParameters, Cloner>() {
|
||||
@Override
|
||||
public Cloner apply(@Nullable BuilderParameters param) {
|
||||
return new FieldCloner(param.getAggregateCloner(), param.getInstanceProvider()) {{
|
||||
// Use a default writer with no concept of cloning
|
||||
writer = new ObjectWriter();
|
||||
}};
|
||||
}
|
||||
}).
|
||||
build();
|
||||
|
||||
/**
|
||||
* Creates a packet container for a new packet.
|
||||
* @param id - ID of the packet to create.
|
||||
@ -364,12 +387,29 @@ public class PacketContainer implements Serializable {
|
||||
return id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a shallow copy of the current packet.
|
||||
* <p>
|
||||
* This merely writes the content of each field to the new class directly,
|
||||
* without performing any expensive copies.
|
||||
*
|
||||
* @return A shallow copy of the current packet.
|
||||
*/
|
||||
public PacketContainer shallowClone() {
|
||||
Object clonedPacket = SHALLOW_CLONER.clone(getHandle());
|
||||
return new PacketContainer(getID(), clonedPacket);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a deep copy of the current packet.
|
||||
* <p>
|
||||
* This will perform a full copy of the entire object tree, only skipping
|
||||
* known immutable objects and primitive types.
|
||||
*
|
||||
* @return A deep copy of the current packet.
|
||||
*/
|
||||
public PacketContainer deepClone() {
|
||||
Object clonedPacket = AggregateCloner.DEFAULT.clone(getHandle());
|
||||
Object clonedPacket = DEEP_CLONER.clone(getHandle());
|
||||
return new PacketContainer(getID(), clonedPacket);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,11 @@ public class AggregateCloner implements Cloner {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a builder for aggregate (combined) cloners.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public static class Builder {
|
||||
private List<Function<BuilderParameters, Cloner>> factories = Lists.newArrayList();
|
||||
private BuilderParameters parameters;
|
||||
@ -75,7 +80,7 @@ public class AggregateCloner implements Cloner {
|
||||
*/
|
||||
public Builder andThen(final Class<? extends Cloner> type) {
|
||||
// Use reflection to generate a factory on the fly
|
||||
return orCloner(new Function<BuilderParameters, Cloner>() {
|
||||
return andThen(new Function<BuilderParameters, Cloner>() {
|
||||
@Override
|
||||
public Cloner apply(@Nullable BuilderParameters param) {
|
||||
Object result = param.typeConstructor.create(type);
|
||||
@ -97,7 +102,7 @@ public class AggregateCloner implements Cloner {
|
||||
* @param factory - factory constructing the next cloner.
|
||||
* @return This builder.
|
||||
*/
|
||||
public Builder orCloner(Function<BuilderParameters, Cloner> factory) {
|
||||
public Builder andThen(Function<BuilderParameters, Cloner> factory) {
|
||||
factories.add(factory);
|
||||
return this;
|
||||
}
|
||||
|
@ -10,11 +10,11 @@ import com.comphenix.protocol.reflect.instances.InstanceProvider;
|
||||
* @author Kristian
|
||||
*/
|
||||
public class FieldCloner implements Cloner {
|
||||
private final Cloner defaultCloner;
|
||||
private final InstanceProvider instanceProvider;
|
||||
protected Cloner defaultCloner;
|
||||
protected InstanceProvider instanceProvider;
|
||||
|
||||
// Used to clone objects
|
||||
private final ObjectWriter writer;
|
||||
protected ObjectWriter writer;
|
||||
|
||||
/**
|
||||
* Constructs a field cloner that copies objects by reading and writing the internal fields directly.
|
||||
|
@ -1,18 +0,0 @@
|
||||
package com.comphenix.protocol.reflect.cloning;
|
||||
|
||||
/**
|
||||
* Represents a cloner that simply returns the given object.
|
||||
*
|
||||
* @author Kristian
|
||||
*/
|
||||
public class IdentityCloner implements Cloner {
|
||||
@Override
|
||||
public boolean canClone(Object source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone(Object source) {
|
||||
return source;
|
||||
}
|
||||
}
|
In neuem Issue referenzieren
Einen Benutzer sperren