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.List;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.concurrent.ConcurrentMap;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import org.bukkit.World;
|
import org.bukkit.World;
|
||||||
import org.bukkit.WorldType;
|
import org.bukkit.WorldType;
|
||||||
import org.bukkit.entity.Entity;
|
import org.bukkit.entity.Entity;
|
||||||
@ -38,13 +40,19 @@ import org.bukkit.inventory.ItemStack;
|
|||||||
import com.comphenix.protocol.injector.StructureCache;
|
import com.comphenix.protocol.injector.StructureCache;
|
||||||
import com.comphenix.protocol.reflect.EquivalentConverter;
|
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||||
import com.comphenix.protocol.reflect.FuzzyReflection;
|
import com.comphenix.protocol.reflect.FuzzyReflection;
|
||||||
|
import com.comphenix.protocol.reflect.ObjectWriter;
|
||||||
import com.comphenix.protocol.reflect.StructureModifier;
|
import com.comphenix.protocol.reflect.StructureModifier;
|
||||||
import com.comphenix.protocol.reflect.cloning.AggregateCloner;
|
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.utility.MinecraftReflection;
|
||||||
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.WrappedWatchableObject;
|
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
||||||
|
import com.google.common.base.Function;
|
||||||
import com.google.common.collect.Maps;
|
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> writeMethods = Maps.newConcurrentMap();
|
||||||
private static ConcurrentMap<Class<?>, Method> readMethods = 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.
|
* Creates a packet container for a new packet.
|
||||||
* @param id - ID of the packet to create.
|
* @param id - ID of the packet to create.
|
||||||
@ -364,12 +387,29 @@ public class PacketContainer implements Serializable {
|
|||||||
return id;
|
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.
|
* 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.
|
* @return A deep copy of the current packet.
|
||||||
*/
|
*/
|
||||||
public PacketContainer deepClone() {
|
public PacketContainer deepClone() {
|
||||||
Object clonedPacket = AggregateCloner.DEFAULT.clone(getHandle());
|
Object clonedPacket = DEEP_CLONER.clone(getHandle());
|
||||||
return new PacketContainer(getID(), clonedPacket);
|
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 {
|
public static class Builder {
|
||||||
private List<Function<BuilderParameters, Cloner>> factories = Lists.newArrayList();
|
private List<Function<BuilderParameters, Cloner>> factories = Lists.newArrayList();
|
||||||
private BuilderParameters parameters;
|
private BuilderParameters parameters;
|
||||||
@ -75,7 +80,7 @@ public class AggregateCloner implements Cloner {
|
|||||||
*/
|
*/
|
||||||
public Builder andThen(final Class<? extends Cloner> type) {
|
public Builder andThen(final Class<? extends Cloner> type) {
|
||||||
// Use reflection to generate a factory on the fly
|
// Use reflection to generate a factory on the fly
|
||||||
return orCloner(new Function<BuilderParameters, Cloner>() {
|
return andThen(new Function<BuilderParameters, Cloner>() {
|
||||||
@Override
|
@Override
|
||||||
public Cloner apply(@Nullable BuilderParameters param) {
|
public Cloner apply(@Nullable BuilderParameters param) {
|
||||||
Object result = param.typeConstructor.create(type);
|
Object result = param.typeConstructor.create(type);
|
||||||
@ -97,7 +102,7 @@ public class AggregateCloner implements Cloner {
|
|||||||
* @param factory - factory constructing the next cloner.
|
* @param factory - factory constructing the next cloner.
|
||||||
* @return This builder.
|
* @return This builder.
|
||||||
*/
|
*/
|
||||||
public Builder orCloner(Function<BuilderParameters, Cloner> factory) {
|
public Builder andThen(Function<BuilderParameters, Cloner> factory) {
|
||||||
factories.add(factory);
|
factories.add(factory);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
@ -10,11 +10,11 @@ import com.comphenix.protocol.reflect.instances.InstanceProvider;
|
|||||||
* @author Kristian
|
* @author Kristian
|
||||||
*/
|
*/
|
||||||
public class FieldCloner implements Cloner {
|
public class FieldCloner implements Cloner {
|
||||||
private final Cloner defaultCloner;
|
protected Cloner defaultCloner;
|
||||||
private final InstanceProvider instanceProvider;
|
protected InstanceProvider instanceProvider;
|
||||||
|
|
||||||
// Used to clone objects
|
// 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.
|
* 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