mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-30 14:43:27 +01:00
Major rework of underlying conversion logic
This shouldn't affect plugins utlilizing the API, but will make updates and adding wrappers to PacketWrapper easier. In case you're wondering, major changes include: - Added AutoWrapper - Added Covnerters utility class - Removed generic type parameter from EquivalentConverter
This commit is contained in:
parent
e1ea295600
commit
9e5bdf4124
@ -69,11 +69,7 @@ import com.comphenix.protocol.reflect.instances.DefaultInstances;
|
|||||||
import com.comphenix.protocol.utility.MinecraftMethods;
|
import com.comphenix.protocol.utility.MinecraftMethods;
|
||||||
import com.comphenix.protocol.utility.MinecraftReflection;
|
import com.comphenix.protocol.utility.MinecraftReflection;
|
||||||
import com.comphenix.protocol.utility.StreamSerializer;
|
import com.comphenix.protocol.utility.StreamSerializer;
|
||||||
import com.comphenix.protocol.wrappers.BlockPosition;
|
import com.comphenix.protocol.wrappers.*;
|
||||||
import com.comphenix.protocol.wrappers.BukkitConverters;
|
|
||||||
import com.comphenix.protocol.wrappers.ChunkCoordIntPair;
|
|
||||||
import com.comphenix.protocol.wrappers.ChunkPosition;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers;
|
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.ChatType;
|
import com.comphenix.protocol.wrappers.EnumWrappers.ChatType;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.ChatVisibility;
|
import com.comphenix.protocol.wrappers.EnumWrappers.ChatVisibility;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.ClientCommand;
|
import com.comphenix.protocol.wrappers.EnumWrappers.ClientCommand;
|
||||||
@ -94,16 +90,6 @@ import com.comphenix.protocol.wrappers.EnumWrappers.ScoreboardAction;
|
|||||||
import com.comphenix.protocol.wrappers.EnumWrappers.SoundCategory;
|
import com.comphenix.protocol.wrappers.EnumWrappers.SoundCategory;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
|
import com.comphenix.protocol.wrappers.EnumWrappers.TitleAction;
|
||||||
import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction;
|
import com.comphenix.protocol.wrappers.EnumWrappers.WorldBorderAction;
|
||||||
import com.comphenix.protocol.wrappers.MultiBlockChangeInfo;
|
|
||||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedAttribute;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedBlockData;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedDataWatcher;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedStatistic;
|
|
||||||
import com.comphenix.protocol.wrappers.WrappedWatchableObject;
|
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtBase;
|
import com.comphenix.protocol.wrappers.nbt.NbtBase;
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
import com.comphenix.protocol.wrappers.nbt.NbtCompound;
|
||||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||||
@ -134,30 +120,29 @@ public class PacketContainer implements Serializable {
|
|||||||
private static ConcurrentMap<Class<?>, Method> readMethods = Maps.newConcurrentMap();
|
private static ConcurrentMap<Class<?>, Method> readMethods = Maps.newConcurrentMap();
|
||||||
|
|
||||||
// Used to clone packets
|
// Used to clone packets
|
||||||
private static final AggregateCloner DEEP_CLONER = AggregateCloner.newBuilder().
|
private static final AggregateCloner DEEP_CLONER = AggregateCloner
|
||||||
instanceProvider(DefaultInstances.DEFAULT).
|
.newBuilder()
|
||||||
andThen(BukkitCloner.class).
|
.instanceProvider(DefaultInstances.DEFAULT)
|
||||||
andThen(ImmutableDetector.class).
|
.andThen(BukkitCloner.class)
|
||||||
andThen(OptionalCloner.class).
|
.andThen(ImmutableDetector.class)
|
||||||
andThen(CollectionCloner.class).
|
.andThen(OptionalCloner.class)
|
||||||
andThen(getSpecializedDeepClonerFactory()).
|
.andThen(CollectionCloner.class)
|
||||||
build();
|
.andThen(getSpecializedDeepClonerFactory())
|
||||||
|
.build();
|
||||||
|
|
||||||
private static final AggregateCloner SHALLOW_CLONER = AggregateCloner.newBuilder().
|
private static final AggregateCloner SHALLOW_CLONER = AggregateCloner
|
||||||
instanceProvider(DefaultInstances.DEFAULT).
|
.newBuilder()
|
||||||
andThen(new Function<BuilderParameters, Cloner>() {
|
.instanceProvider(DefaultInstances.DEFAULT)
|
||||||
@Override
|
.andThen(param -> {
|
||||||
public Cloner apply(@Nullable BuilderParameters param) {
|
if (param == null)
|
||||||
if (param == null)
|
throw new IllegalArgumentException("Cannot be NULL.");
|
||||||
throw new IllegalArgumentException("Cannot be NULL.");
|
|
||||||
|
return new FieldCloner(param.getAggregateCloner(), param.getInstanceProvider()) {{
|
||||||
return new FieldCloner(param.getAggregateCloner(), param.getInstanceProvider()) {{
|
// Use a default writer with no concept of cloning
|
||||||
// Use a default writer with no concept of cloning
|
writer = new ObjectWriter();
|
||||||
writer = new ObjectWriter();
|
}};
|
||||||
}};
|
})
|
||||||
}
|
.build();
|
||||||
}).
|
|
||||||
build();
|
|
||||||
|
|
||||||
// Packets that cannot be cloned by our default deep cloner
|
// Packets that cannot be cloned by our default deep cloner
|
||||||
private static final Set<PacketType> CLONING_UNSUPPORTED = Sets.newHashSet(
|
private static final Set<PacketType> CLONING_UNSUPPORTED = Sets.newHashSet(
|
||||||
@ -385,8 +370,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<ItemStack> getItemModifier() {
|
public StructureModifier<ItemStack> getItemModifier() {
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<ItemStack>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getItemStackClass(), BukkitConverters.getItemStackConverter());
|
MinecraftReflection.getItemStackClass(),
|
||||||
|
BukkitConverters.getItemStackConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -398,9 +384,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<ItemStack[]> getItemArrayModifier() {
|
public StructureModifier<ItemStack[]> getItemArrayModifier() {
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<ItemStack[]>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getItemStackArrayClass(),
|
MinecraftReflection.getItemStackArrayClass(),
|
||||||
BukkitConverters.getIgnoreNull(new ItemStackArrayConverter()));
|
Converters.ignoreNull(new ItemStackArrayConverter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -414,10 +400,7 @@ public class PacketContainer implements Serializable {
|
|||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.withType(
|
return structureModifier.withType(
|
||||||
List.class,
|
List.class,
|
||||||
BukkitConverters.getListConverter(
|
BukkitConverters.getListConverter(BukkitConverters.getItemStackConverter())
|
||||||
MinecraftReflection.getItemStackClass(),
|
|
||||||
BukkitConverters.getItemStackConverter()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -428,12 +411,9 @@ public class PacketContainer implements Serializable {
|
|||||||
* @return A modifier for maps of statistics.
|
* @return A modifier for maps of statistics.
|
||||||
*/
|
*/
|
||||||
public StructureModifier<Map<WrappedStatistic, Integer>> getStatisticMaps() {
|
public StructureModifier<Map<WrappedStatistic, Integer>> getStatisticMaps() {
|
||||||
return structureModifier.withType(Map.class,
|
return getMaps(
|
||||||
BukkitConverters.<WrappedStatistic, Integer>getMapConverter(
|
BukkitConverters.getWrappedStatisticConverter(),
|
||||||
MinecraftReflection.getStatisticClass(),
|
Converters.passthrough(Integer.class));
|
||||||
BukkitConverters.getWrappedStatisticConverter()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -445,7 +425,7 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<WorldType> getWorldTypeModifier() {
|
public StructureModifier<WorldType> getWorldTypeModifier() {
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<WorldType>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getWorldTypeClass(),
|
MinecraftReflection.getWorldTypeClass(),
|
||||||
BukkitConverters.getWorldTypeConverter());
|
BukkitConverters.getWorldTypeConverter());
|
||||||
}
|
}
|
||||||
@ -456,7 +436,7 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<WrappedDataWatcher> getDataWatcherModifier() {
|
public StructureModifier<WrappedDataWatcher> getDataWatcherModifier() {
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<WrappedDataWatcher>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getDataWatcherClass(),
|
MinecraftReflection.getDataWatcherClass(),
|
||||||
BukkitConverters.getDataWatcherConverter());
|
BukkitConverters.getDataWatcherConverter());
|
||||||
}
|
}
|
||||||
@ -475,7 +455,7 @@ public class PacketContainer implements Serializable {
|
|||||||
public StructureModifier<Entity> getEntityModifier(@Nonnull World world) {
|
public StructureModifier<Entity> getEntityModifier(@Nonnull World world) {
|
||||||
Preconditions.checkNotNull(world, "world cannot be NULL.");
|
Preconditions.checkNotNull(world, "world cannot be NULL.");
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<Entity>withType(
|
return structureModifier.withType(
|
||||||
int.class, BukkitConverters.getEntityConverter(world));
|
int.class, BukkitConverters.getEntityConverter(world));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -547,10 +527,7 @@ public class PacketContainer implements Serializable {
|
|||||||
// Convert to and from the ProtocolLib wrapper
|
// Convert to and from the ProtocolLib wrapper
|
||||||
return structureModifier.withType(
|
return structureModifier.withType(
|
||||||
Collection.class,
|
Collection.class,
|
||||||
BukkitConverters.getListConverter(
|
BukkitConverters.getListConverter(BukkitConverters.getNbtConverter())
|
||||||
MinecraftReflection.getNBTBaseClass(),
|
|
||||||
BukkitConverters.getNbtConverter()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -576,9 +553,7 @@ public class PacketContainer implements Serializable {
|
|||||||
// Convert to and from the ProtocolLib wrapper
|
// Convert to and from the ProtocolLib wrapper
|
||||||
return structureModifier.withType(
|
return structureModifier.withType(
|
||||||
Collection.class,
|
Collection.class,
|
||||||
BukkitConverters.getListConverter(
|
BukkitConverters.getListConverter(BukkitConverters.getWrappedAttributeConverter())
|
||||||
MinecraftReflection.getAttributeSnapshotClass(),
|
|
||||||
BukkitConverters.getWrappedAttributeConverter())
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,10 +569,7 @@ public class PacketContainer implements Serializable {
|
|||||||
// Convert to and from the ProtocolLib wrapper
|
// Convert to and from the ProtocolLib wrapper
|
||||||
return structureModifier.withType(
|
return structureModifier.withType(
|
||||||
Collection.class,
|
Collection.class,
|
||||||
BukkitConverters.getListConverter(
|
BukkitConverters.getListConverter(ChunkPosition.getConverter()));
|
||||||
MinecraftReflection.getChunkPositionClass(),
|
|
||||||
ChunkPosition.getConverter())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -612,10 +584,7 @@ public class PacketContainer implements Serializable {
|
|||||||
// Convert to and from the ProtocolLib wrapper
|
// Convert to and from the ProtocolLib wrapper
|
||||||
return structureModifier.withType(
|
return structureModifier.withType(
|
||||||
Collection.class,
|
Collection.class,
|
||||||
BukkitConverters.getListConverter(
|
BukkitConverters.getListConverter(BlockPosition.getConverter()));
|
||||||
MinecraftReflection.getBlockPositionClass(),
|
|
||||||
BlockPosition.getConverter())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -629,10 +598,7 @@ public class PacketContainer implements Serializable {
|
|||||||
// Convert to and from the ProtocolLib wrapper
|
// Convert to and from the ProtocolLib wrapper
|
||||||
return structureModifier.withType(
|
return structureModifier.withType(
|
||||||
Collection.class,
|
Collection.class,
|
||||||
BukkitConverters.getListConverter(
|
BukkitConverters.getListConverter(BukkitConverters.getWatchableObjectConverter()));
|
||||||
MinecraftReflection.getDataWatcherItemClass(),
|
|
||||||
BukkitConverters.getWatchableObjectConverter())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -644,7 +610,7 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<Material> getBlocks() {
|
public StructureModifier<Material> getBlocks() {
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<Material>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getBlockClass(), BukkitConverters.getBlockConverter());
|
MinecraftReflection.getBlockClass(), BukkitConverters.getBlockConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -657,7 +623,7 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<WrappedGameProfile> getGameProfiles() {
|
public StructureModifier<WrappedGameProfile> getGameProfiles() {
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<WrappedGameProfile>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getGameProfileClass(), BukkitConverters.getWrappedGameProfileConverter());
|
MinecraftReflection.getGameProfileClass(), BukkitConverters.getWrappedGameProfileConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -670,7 +636,7 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<WrappedBlockData> getBlockData() {
|
public StructureModifier<WrappedBlockData> getBlockData() {
|
||||||
// Convert to and from our wrapper
|
// Convert to and from our wrapper
|
||||||
return structureModifier.<WrappedBlockData>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getIBlockDataClass(), BukkitConverters.getWrappedBlockDataConverter());
|
MinecraftReflection.getIBlockDataClass(), BukkitConverters.getWrappedBlockDataConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -685,7 +651,7 @@ public class PacketContainer implements Serializable {
|
|||||||
ChunkCoordIntPair chunk = getChunkCoordIntPairs().read(0);
|
ChunkCoordIntPair chunk = getChunkCoordIntPairs().read(0);
|
||||||
|
|
||||||
// Convert to and from our wrapper
|
// Convert to and from our wrapper
|
||||||
return structureModifier.<MultiBlockChangeInfo[]>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getMultiBlockChangeInfoArrayClass(), MultiBlockChangeInfo.getArrayConverter(chunk));
|
MinecraftReflection.getMultiBlockChangeInfoArrayClass(), MultiBlockChangeInfo.getArrayConverter(chunk));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -698,7 +664,7 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<WrappedChatComponent> getChatComponents() {
|
public StructureModifier<WrappedChatComponent> getChatComponents() {
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<WrappedChatComponent>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -715,22 +681,23 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<WrappedChatComponent[]> getChatComponentArrays() {
|
public StructureModifier<WrappedChatComponent[]> getChatComponentArrays() {
|
||||||
// Convert to and from the Bukkit wrapper
|
// Convert to and from the Bukkit wrapper
|
||||||
return structureModifier.<WrappedChatComponent[]>withType(
|
return structureModifier.withType(
|
||||||
ComponentArrayConverter.getGenericType(),
|
ComponentArrayConverter.getGenericType(),
|
||||||
BukkitConverters.getIgnoreNull(new ComponentArrayConverter()));
|
Converters.ignoreNull(new ComponentArrayConverter()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a read/write structure for the ServerPing fields in the following packet: <br>
|
* Retrieve a read/write structure for the ServerPing fields in the following packet: <br>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link PacketType.Status.Server#OUT_SERVER_INFO}
|
* <li>{@link PacketType.Status.Server#SERVER_INFO}
|
||||||
* </ul>
|
* </ul>
|
||||||
* @return A modifier for ServerPing fields.
|
* @return A modifier for ServerPing fields.
|
||||||
*/
|
*/
|
||||||
public StructureModifier<WrappedServerPing> getServerPings() {
|
public StructureModifier<WrappedServerPing> getServerPings() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<WrappedServerPing>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getServerPingClass(), BukkitConverters.getWrappedServerPingConverter());
|
MinecraftReflection.getServerPingClass(),
|
||||||
|
BukkitConverters.getWrappedServerPingConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -744,10 +711,7 @@ public class PacketContainer implements Serializable {
|
|||||||
// Convert to and from the ProtocolLib wrapper
|
// Convert to and from the ProtocolLib wrapper
|
||||||
return structureModifier.withType(
|
return structureModifier.withType(
|
||||||
Collection.class,
|
Collection.class,
|
||||||
BukkitConverters.getListConverter(
|
BukkitConverters.getListConverter(PlayerInfoData.getConverter()));
|
||||||
MinecraftReflection.getPlayerInfoDataClass(),
|
|
||||||
PlayerInfoData.getConverter())
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -756,8 +720,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<Protocol> getProtocols() {
|
public StructureModifier<Protocol> getProtocols() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<Protocol>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getProtocolClass(), EnumWrappers.getProtocolConverter());
|
EnumWrappers.getProtocolClass(),
|
||||||
|
EnumWrappers.getProtocolConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -766,8 +731,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<ClientCommand> getClientCommands() {
|
public StructureModifier<ClientCommand> getClientCommands() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<ClientCommand>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getClientCommandClass(), EnumWrappers.getClientCommandConverter());
|
EnumWrappers.getClientCommandClass(),
|
||||||
|
EnumWrappers.getClientCommandConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -776,8 +742,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<ChatVisibility> getChatVisibilities() {
|
public StructureModifier<ChatVisibility> getChatVisibilities() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<ChatVisibility>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getChatVisibilityClass(), EnumWrappers.getChatVisibilityConverter());
|
EnumWrappers.getChatVisibilityClass(),
|
||||||
|
EnumWrappers.getChatVisibilityConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -786,8 +753,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<Difficulty> getDifficulties() {
|
public StructureModifier<Difficulty> getDifficulties() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<Difficulty>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getDifficultyClass(), EnumWrappers.getDifficultyConverter());
|
EnumWrappers.getDifficultyClass(),
|
||||||
|
EnumWrappers.getDifficultyConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -796,8 +764,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<EntityUseAction> getEntityUseActions() {
|
public StructureModifier<EntityUseAction> getEntityUseActions() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<EntityUseAction>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getEntityUseActionClass(), EnumWrappers.getEntityUseActionConverter());
|
EnumWrappers.getEntityUseActionClass(),
|
||||||
|
EnumWrappers.getEntityUseActionConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -806,8 +775,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<NativeGameMode> getGameModes() {
|
public StructureModifier<NativeGameMode> getGameModes() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<NativeGameMode>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getGameModeClass(), EnumWrappers.getGameModeConverter());
|
EnumWrappers.getGameModeClass(),
|
||||||
|
EnumWrappers.getGameModeConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -816,8 +786,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<ResourcePackStatus> getResourcePackStatus() {
|
public StructureModifier<ResourcePackStatus> getResourcePackStatus() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<ResourcePackStatus>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getResourcePackStatusClass(), EnumWrappers.getResourcePackStatusConverter());
|
EnumWrappers.getResourcePackStatusClass(),
|
||||||
|
EnumWrappers.getResourcePackStatusConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -826,8 +797,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<PlayerInfoAction> getPlayerInfoAction() {
|
public StructureModifier<PlayerInfoAction> getPlayerInfoAction() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<PlayerInfoAction>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getPlayerInfoActionClass(), EnumWrappers.getPlayerInfoActionConverter());
|
EnumWrappers.getPlayerInfoActionClass(),
|
||||||
|
EnumWrappers.getPlayerInfoActionConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -836,8 +808,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<TitleAction> getTitleActions() {
|
public StructureModifier<TitleAction> getTitleActions() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<TitleAction>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getTitleActionClass(), EnumWrappers.getTitleActionConverter());
|
EnumWrappers.getTitleActionClass(),
|
||||||
|
EnumWrappers.getTitleActionConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -846,8 +819,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<WorldBorderAction> getWorldBorderActions() {
|
public StructureModifier<WorldBorderAction> getWorldBorderActions() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<WorldBorderAction>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getWorldBorderActionClass(), EnumWrappers.getWorldBorderActionConverter());
|
EnumWrappers.getWorldBorderActionClass(),
|
||||||
|
EnumWrappers.getWorldBorderActionConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -856,8 +830,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<CombatEventType> getCombatEvents() {
|
public StructureModifier<CombatEventType> getCombatEvents() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<CombatEventType>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getCombatEventTypeClass(), EnumWrappers.getCombatEventTypeConverter());
|
EnumWrappers.getCombatEventTypeClass(),
|
||||||
|
EnumWrappers.getCombatEventTypeConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -866,8 +841,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<PlayerDigType> getPlayerDigTypes() {
|
public StructureModifier<PlayerDigType> getPlayerDigTypes() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<PlayerDigType>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getPlayerDigTypeClass(), EnumWrappers.getPlayerDiggingActionConverter());
|
EnumWrappers.getPlayerDigTypeClass(),
|
||||||
|
EnumWrappers.getPlayerDiggingActionConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -876,8 +852,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<PlayerAction> getPlayerActions() {
|
public StructureModifier<PlayerAction> getPlayerActions() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<PlayerAction>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getPlayerActionClass(), EnumWrappers.getEntityActionConverter());
|
EnumWrappers.getPlayerActionClass(),
|
||||||
|
EnumWrappers.getEntityActionConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -886,8 +863,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<ScoreboardAction> getScoreboardActions() {
|
public StructureModifier<ScoreboardAction> getScoreboardActions() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<ScoreboardAction>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getScoreboardActionClass(), EnumWrappers.getUpdateScoreActionConverter());
|
EnumWrappers.getScoreboardActionClass(),
|
||||||
|
EnumWrappers.getUpdateScoreActionConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -896,8 +874,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<Particle> getParticles() {
|
public StructureModifier<Particle> getParticles() {
|
||||||
// Convert to and from the wrapper
|
// Convert to and from the wrapper
|
||||||
return structureModifier.<Particle>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getParticleClass(), EnumWrappers.getParticleConverter());
|
EnumWrappers.getParticleClass(),
|
||||||
|
EnumWrappers.getParticleConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -906,8 +885,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<PotionEffectType> getEffectTypes() {
|
public StructureModifier<PotionEffectType> getEffectTypes() {
|
||||||
// Convert to and from Bukkit
|
// Convert to and from Bukkit
|
||||||
return structureModifier.<PotionEffectType>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getMobEffectListClass(), BukkitConverters.getEffectTypeConverter());
|
MinecraftReflection.getMobEffectListClass(),
|
||||||
|
BukkitConverters.getEffectTypeConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -916,8 +896,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<SoundCategory> getSoundCategories() {
|
public StructureModifier<SoundCategory> getSoundCategories() {
|
||||||
// Convert to and from the enums
|
// Convert to and from the enums
|
||||||
return structureModifier.<SoundCategory>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getSoundCategoryClass(), EnumWrappers.getSoundCategoryConverter());
|
EnumWrappers.getSoundCategoryClass(),
|
||||||
|
EnumWrappers.getSoundCategoryConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -926,8 +907,9 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public StructureModifier<Sound> getSoundEffects() {
|
public StructureModifier<Sound> getSoundEffects() {
|
||||||
// Convert to and from Bukkit
|
// Convert to and from Bukkit
|
||||||
return structureModifier.<Sound>withType(
|
return structureModifier.withType(
|
||||||
MinecraftReflection.getSoundEffectClass(), BukkitConverters.getSoundConverter());
|
MinecraftReflection.getSoundEffectClass(),
|
||||||
|
BukkitConverters.getSoundConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -935,8 +917,9 @@ public class PacketContainer implements Serializable {
|
|||||||
* @return A modifier for ItemSlot enum fields.
|
* @return A modifier for ItemSlot enum fields.
|
||||||
*/
|
*/
|
||||||
public StructureModifier<ItemSlot> getItemSlots() {
|
public StructureModifier<ItemSlot> getItemSlots() {
|
||||||
return structureModifier.<ItemSlot>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getItemSlotClass(), EnumWrappers.getItemSlotConverter());
|
EnumWrappers.getItemSlotClass(),
|
||||||
|
EnumWrappers.getItemSlotConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -944,8 +927,9 @@ public class PacketContainer implements Serializable {
|
|||||||
* @return A modifier for Hand enum fields.
|
* @return A modifier for Hand enum fields.
|
||||||
*/
|
*/
|
||||||
public StructureModifier<Hand> getHands() {
|
public StructureModifier<Hand> getHands() {
|
||||||
return structureModifier.<Hand>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getHandClass(), EnumWrappers.getHandConverter());
|
EnumWrappers.getHandClass(),
|
||||||
|
EnumWrappers.getHandConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -953,8 +937,9 @@ public class PacketContainer implements Serializable {
|
|||||||
* @return A modifier for Direction enum fields.
|
* @return A modifier for Direction enum fields.
|
||||||
*/
|
*/
|
||||||
public StructureModifier<Direction> getDirections() {
|
public StructureModifier<Direction> getDirections() {
|
||||||
return structureModifier.<Direction>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getDirectionClass(), EnumWrappers.getDirectionConverter());
|
EnumWrappers.getDirectionClass(),
|
||||||
|
EnumWrappers.getDirectionConverter());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -962,8 +947,52 @@ public class PacketContainer implements Serializable {
|
|||||||
* @return A modifier for ChatType enum fields.
|
* @return A modifier for ChatType enum fields.
|
||||||
*/
|
*/
|
||||||
public StructureModifier<ChatType> getChatTypes() {
|
public StructureModifier<ChatType> getChatTypes() {
|
||||||
return structureModifier.<ChatType>withType(
|
return structureModifier.withType(
|
||||||
EnumWrappers.getChatTypeClass(), EnumWrappers.getChatTypeConverter());
|
EnumWrappers.getChatTypeClass(),
|
||||||
|
EnumWrappers.getChatTypeConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a read/write structure for the MinecraftKey class.
|
||||||
|
* @return A modifier for MinecraftKey fields.
|
||||||
|
*/
|
||||||
|
public StructureModifier<MinecraftKey> getMinecraftKeys() {
|
||||||
|
return structureModifier.withType(
|
||||||
|
MinecraftReflection.getMinecraftKeyClass(),
|
||||||
|
MinecraftKey.getConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a read/write structure for the Map class.
|
||||||
|
* @param keyConverter Converter for map keys
|
||||||
|
* @param valConverter Converter for map values
|
||||||
|
* @param <K> Key param
|
||||||
|
* @param <V> Value param
|
||||||
|
* @return A modifier for Map fields.
|
||||||
|
*
|
||||||
|
* @see BukkitConverters
|
||||||
|
* @see EquivalentConverter
|
||||||
|
*/
|
||||||
|
public <K, V> StructureModifier<Map<K, V>> getMaps(EquivalentConverter<K> keyConverter,
|
||||||
|
EquivalentConverter<V> valConverter) {
|
||||||
|
return structureModifier.withType(
|
||||||
|
Map.class,
|
||||||
|
BukkitConverters.getMapConverter(keyConverter, valConverter));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a read/write structure for the Set class.
|
||||||
|
* @param converter Converter for elements
|
||||||
|
* @param <E> Element param
|
||||||
|
* @return A modifier for Set fields
|
||||||
|
*
|
||||||
|
* @see BukkitConverters
|
||||||
|
* @see EquivalentConverter
|
||||||
|
*/
|
||||||
|
public <E> StructureModifier<Set<E>> getSets(EquivalentConverter<E> converter) {
|
||||||
|
return structureModifier.withType(
|
||||||
|
Set.class,
|
||||||
|
BukkitConverters.getSetConverter(converter));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -977,7 +1006,9 @@ public class PacketContainer implements Serializable {
|
|||||||
* @return The modifier
|
* @return The modifier
|
||||||
*/
|
*/
|
||||||
public <T extends Enum<T>> StructureModifier<T> getEnumModifier(Class<T> enumClass, Class<?> nmsClass) {
|
public <T extends Enum<T>> StructureModifier<T> getEnumModifier(Class<T> enumClass, Class<?> nmsClass) {
|
||||||
return structureModifier.<T>withType(nmsClass, new EnumConverter<T>(enumClass));
|
return structureModifier.withType(
|
||||||
|
nmsClass,
|
||||||
|
new EnumConverter<>(nmsClass, enumClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -990,7 +1021,9 @@ public class PacketContainer implements Serializable {
|
|||||||
* @see #getEnumModifier(Class, Class)
|
* @see #getEnumModifier(Class, Class)
|
||||||
*/
|
*/
|
||||||
public <T extends Enum<T>> StructureModifier<T> getEnumModifier(Class<T> enumClass, int index) {
|
public <T extends Enum<T>> StructureModifier<T> getEnumModifier(Class<T> enumClass, int index) {
|
||||||
return getEnumModifier(enumClass, structureModifier.getField(index).getType());
|
return getEnumModifier(
|
||||||
|
enumClass,
|
||||||
|
structureModifier.getField(index).getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1036,7 +1069,7 @@ public class PacketContainer implements Serializable {
|
|||||||
* @return A deep copy of the current packet.
|
* @return A deep copy of the current packet.
|
||||||
*/
|
*/
|
||||||
public PacketContainer deepClone() {
|
public PacketContainer deepClone() {
|
||||||
Object clonedPacket = null;
|
Object clonedPacket;
|
||||||
|
|
||||||
// Fall back on the alternative (but slower) method of reading and writing back the packet
|
// Fall back on the alternative (but slower) method of reading and writing back the packet
|
||||||
if (CLONING_UNSUPPORTED.contains(type)) {
|
if (CLONING_UNSUPPORTED.contains(type)) {
|
||||||
@ -1183,7 +1216,7 @@ public class PacketContainer implements Serializable {
|
|||||||
*/
|
*/
|
||||||
public void addMetadata(String key, Object value) {
|
public void addMetadata(String key, Object value) {
|
||||||
if (metadata == null) {
|
if (metadata == null) {
|
||||||
metadata = new HashMap<String, Object>();
|
metadata = new HashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
metadata.put(key, value);
|
metadata.put(key, value);
|
||||||
@ -1259,13 +1292,13 @@ public class PacketContainer implements Serializable {
|
|||||||
final EquivalentConverter<ItemStack> stackConverter = BukkitConverters.getItemStackConverter();
|
final EquivalentConverter<ItemStack> stackConverter = BukkitConverters.getItemStackConverter();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?>genericType, ItemStack[] specific) {
|
public Object getGeneric(ItemStack[] specific) {
|
||||||
Class<?> nmsStack = MinecraftReflection.getItemStackClass();
|
Class<?> nmsStack = MinecraftReflection.getItemStackClass();
|
||||||
Object[] result = (Object[]) Array.newInstance(nmsStack, specific.length);
|
Object[] result = (Object[]) Array.newInstance(nmsStack, specific.length);
|
||||||
|
|
||||||
// Unwrap every item
|
// Unwrap every item
|
||||||
for (int i = 0; i < result.length; i++) {
|
for (int i = 0; i < result.length; i++) {
|
||||||
result[i] = stackConverter.getGeneric(nmsStack, specific[i]);
|
result[i] = stackConverter.getGeneric(specific[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1296,13 +1329,13 @@ public class PacketContainer implements Serializable {
|
|||||||
final EquivalentConverter<WrappedChatComponent> componentConverter = BukkitConverters.getWrappedChatComponentConverter();
|
final EquivalentConverter<WrappedChatComponent> componentConverter = BukkitConverters.getWrappedChatComponentConverter();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
public Object getGeneric(WrappedChatComponent[] specific) {
|
||||||
Class<?> nmsComponent = MinecraftReflection.getIChatBaseComponentClass();
|
Class<?> nmsComponent = MinecraftReflection.getIChatBaseComponentClass();
|
||||||
Object[] result = (Object[]) Array.newInstance(nmsComponent, specific.length);
|
Object[] result = (Object[]) Array.newInstance(nmsComponent, specific.length);
|
||||||
|
|
||||||
// Unwrap every item
|
// Unwrap every item
|
||||||
for (int i = 0; i < result.length; i++) {
|
for (int i = 0; i < result.length; i++) {
|
||||||
result[i] = componentConverter.getGeneric(nmsComponent, specific[i]);
|
result[i] = componentConverter.getGeneric(specific[i]);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1351,7 +1384,7 @@ public class PacketContainer implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
public Object getGeneric(WrappedChatComponent[] specific) {
|
||||||
NbtCompound compound = NbtFactory.ofCompound("");
|
NbtCompound compound = NbtFactory.ofCompound("");
|
||||||
|
|
||||||
for (int i = 0; i < lines; i++) {
|
for (int i = 0; i < lines; i++) {
|
||||||
@ -1365,7 +1398,7 @@ public class PacketContainer implements Serializable {
|
|||||||
compound.put("Text" + (i + 1), component.getJson());
|
compound.put("Text" + (i + 1), component.getJson());
|
||||||
}
|
}
|
||||||
|
|
||||||
return nbtConverter.getGeneric(genericType, compound);
|
return nbtConverter.getGeneric(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1394,8 +1427,8 @@ public class PacketContainer implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
public Object getGeneric(WrappedChatComponent[] specific) {
|
||||||
return DELEGATE.getGeneric(genericType, specific);
|
return DELEGATE.getGeneric(specific);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -21,32 +21,12 @@ package com.comphenix.protocol.reflect;
|
|||||||
* Interface that converts generic objects into types and back.
|
* Interface that converts generic objects into types and back.
|
||||||
*
|
*
|
||||||
* @author Kristian
|
* @author Kristian
|
||||||
* @param <TType> The specific type.
|
* @param <T> The specific type.
|
||||||
*/
|
*/
|
||||||
public interface EquivalentConverter<TType> {
|
public interface EquivalentConverter<T> extends SpecificConverter<T>, GenericConverter<T> {
|
||||||
/**
|
/**
|
||||||
* Retrieve a copy of the specific type using an instance of the generic type.
|
* Due to type erasure, we need to explicitly keep a reference to the specific type.
|
||||||
* <p>
|
|
||||||
* This is usually a wrapper type in the Bukkit API.
|
|
||||||
* @param generic - the generic type.
|
|
||||||
* @return The new specific type.
|
|
||||||
*/
|
|
||||||
public TType getSpecific(Object generic);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieve a copy of the generic type from a specific type.
|
|
||||||
* <p>
|
|
||||||
* This is usually a native net.minecraft.server type in Minecraft.
|
|
||||||
* @param genericType - class or super class of the generic type.
|
|
||||||
* @param specific - the specific type we need to copy.
|
|
||||||
* @return A copy of the specific type.
|
|
||||||
*/
|
|
||||||
public Object getGeneric(Class<?> genericType, TType specific);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Due to type erasion, we need to explicitly keep a reference to the specific type.
|
|
||||||
* @return The specific type.
|
* @return The specific type.
|
||||||
*/
|
*/
|
||||||
public Class<TType> getSpecificType();
|
Class<T> getSpecificType();
|
||||||
}
|
}
|
||||||
|
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||||
|
* Copyright (C) 2017 Dan Mulloy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package com.comphenix.protocol.reflect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts specific objects into generic objects.
|
||||||
|
* @author Dan
|
||||||
|
* @param <T> Specific type
|
||||||
|
*/
|
||||||
|
public interface GenericConverter<T> {
|
||||||
|
/**
|
||||||
|
* Retrieve a copy of the generic type from a specific type.
|
||||||
|
* <p>
|
||||||
|
* This is usually a native net.minecraft.server type in Minecraft.
|
||||||
|
* @param specific - the specific type we need to copy.
|
||||||
|
* @return A copy of the specific type.
|
||||||
|
*/
|
||||||
|
Object getGeneric(T specific);
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||||
|
* Copyright (C) 2017 Dan Mulloy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package com.comphenix.protocol.reflect;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts generic objects into specific objects.
|
||||||
|
* @author Dan
|
||||||
|
* @param <T> The specific type
|
||||||
|
*/
|
||||||
|
public interface SpecificConverter<T> {
|
||||||
|
/**
|
||||||
|
* Retrieve a copy of the specific type using an instance of the generic type.
|
||||||
|
* <p>
|
||||||
|
* This is usually a wrapper type in the Bukkit API or ProtocolLib API.
|
||||||
|
* @param generic - the generic type.
|
||||||
|
* @return The new specific type.
|
||||||
|
*/
|
||||||
|
T getSpecific(Object generic);
|
||||||
|
}
|
@ -352,7 +352,7 @@ public class StructureModifier<TField> {
|
|||||||
throw new FieldAccessException(String.format("Field index out of bounds. (Index: %s, Size: %s)", fieldIndex, data.size()));
|
throw new FieldAccessException(String.format("Field index out of bounds. (Index: %s, Size: %s)", fieldIndex, data.size()));
|
||||||
|
|
||||||
// Use the converter, if it exists
|
// Use the converter, if it exists
|
||||||
Object obj = needConversion() ? converter.getGeneric(getFieldType(fieldIndex), value) : value;
|
Object obj = needConversion() ? converter.getGeneric(value) : value;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
FieldUtils.writeField(data.get(fieldIndex), target, obj, true);
|
FieldUtils.writeField(data.get(fieldIndex), target, obj, true);
|
||||||
|
@ -113,24 +113,24 @@ public class BukkitCloner implements Cloner {
|
|||||||
return MinecraftReflection.getMinecraftItemStack(MinecraftReflection.getBukkitItemStack(source).clone());
|
return MinecraftReflection.getMinecraftItemStack(MinecraftReflection.getBukkitItemStack(source).clone());
|
||||||
case 1:
|
case 1:
|
||||||
EquivalentConverter<WrappedDataWatcher> dataConverter = BukkitConverters.getDataWatcherConverter();
|
EquivalentConverter<WrappedDataWatcher> dataConverter = BukkitConverters.getDataWatcherConverter();
|
||||||
return dataConverter.getGeneric(clonableClasses.get(1), dataConverter.getSpecific(source).deepClone());
|
return dataConverter.getGeneric(dataConverter.getSpecific(source).deepClone());
|
||||||
case 2:
|
case 2:
|
||||||
EquivalentConverter<BlockPosition> blockConverter = BlockPosition.getConverter();
|
EquivalentConverter<BlockPosition> blockConverter = BlockPosition.getConverter();
|
||||||
return blockConverter.getGeneric(clonableClasses.get(2), blockConverter.getSpecific(source));
|
return blockConverter.getGeneric(blockConverter.getSpecific(source));
|
||||||
case 3:
|
case 3:
|
||||||
EquivalentConverter<ChunkPosition> chunkConverter = ChunkPosition.getConverter();
|
EquivalentConverter<ChunkPosition> chunkConverter = ChunkPosition.getConverter();
|
||||||
return chunkConverter.getGeneric(clonableClasses.get(3), chunkConverter.getSpecific(source));
|
return chunkConverter.getGeneric(chunkConverter.getSpecific(source));
|
||||||
case 4:
|
case 4:
|
||||||
EquivalentConverter<WrappedServerPing> serverConverter = BukkitConverters.getWrappedServerPingConverter();
|
EquivalentConverter<WrappedServerPing> serverConverter = BukkitConverters.getWrappedServerPingConverter();
|
||||||
return serverConverter.getGeneric(clonableClasses.get(4), serverConverter.getSpecific(source).deepClone());
|
return serverConverter.getGeneric(serverConverter.getSpecific(source).deepClone());
|
||||||
case 5:
|
case 5:
|
||||||
return source;
|
return source;
|
||||||
case 6:
|
case 6:
|
||||||
EquivalentConverter<MinecraftKey> keyConverter = MinecraftKey.getConverter();
|
EquivalentConverter<MinecraftKey> keyConverter = MinecraftKey.getConverter();
|
||||||
return keyConverter.getGeneric(clonableClasses.get(6), keyConverter.getSpecific(source));
|
return keyConverter.getGeneric(keyConverter.getSpecific(source));
|
||||||
case 7:
|
case 7:
|
||||||
EquivalentConverter<WrappedBlockData> blockDataConverter = BukkitConverters.getWrappedBlockDataConverter();
|
EquivalentConverter<WrappedBlockData> blockDataConverter = BukkitConverters.getWrappedBlockDataConverter();
|
||||||
return blockDataConverter.getGeneric(clonableClasses.get(7), blockDataConverter.getSpecific(source).deepClone());
|
return blockDataConverter.getGeneric(blockDataConverter.getSpecific(source).deepClone());
|
||||||
case 8:
|
case 8:
|
||||||
return nonNullListCloner().clone(source);
|
return nonNullListCloner().clone(source);
|
||||||
default:
|
default:
|
||||||
|
@ -110,7 +110,7 @@ public abstract class CompiledStructureModifier extends StructureModifier<Object
|
|||||||
@Override
|
@Override
|
||||||
public StructureModifier<Object> write(int index, Object value) throws FieldAccessException {
|
public StructureModifier<Object> write(int index, Object value) throws FieldAccessException {
|
||||||
if (converter != null)
|
if (converter != null)
|
||||||
value = converter.getGeneric(getFieldType(index), value);
|
value = converter.getGeneric(value);
|
||||||
return writeGenerated(index, value);
|
return writeGenerated(index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,163 @@
|
|||||||
|
/**
|
||||||
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||||
|
* Copyright (C) 2017 Dan Mulloy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package com.comphenix.protocol.wrappers;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Automatically wraps an internal NMS class to a non-versioned, deofbuscated class.
|
||||||
|
* Requirements:
|
||||||
|
* <ul>
|
||||||
|
* <li>The wrapper must be public</li>
|
||||||
|
* <li>If the wrapper is an internal class, it must be static</li>
|
||||||
|
* <li>The wrapper must have one public constructor with no arguments (the default constructor is acceptable)</li>
|
||||||
|
* <li>The wrapper must have the the same number of fields as the NMS class</li>
|
||||||
|
* <li>Each field should correspond, in order, to its NMS counterpart</li>
|
||||||
|
* <li>Non-generic fields must have a converter</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author dmulloy2
|
||||||
|
*/
|
||||||
|
public class AutoWrapper<T> implements EquivalentConverter<T> {
|
||||||
|
private Map<Integer, Function<Object, Object>> wrappers = new HashMap<>();
|
||||||
|
private Map<Integer, Function<Object, Object>> unwrappers = new HashMap<>();
|
||||||
|
|
||||||
|
private Class<T> wrapperClass;
|
||||||
|
private Class<?> nmsClass;
|
||||||
|
|
||||||
|
private AutoWrapper(Class<T> wrapperClass, Class<?> nmsClass) {
|
||||||
|
this.wrapperClass = wrapperClass;
|
||||||
|
this.nmsClass = nmsClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> AutoWrapper<T> wrap(Class<T> wrapperClass, Class<?> nmsClass) {
|
||||||
|
return new AutoWrapper<>(wrapperClass, nmsClass);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoWrapper<T> field(int index, Function<Object, Object> wrapper, Function<Object, Object> unwrapper) {
|
||||||
|
wrappers.put(index, wrapper);
|
||||||
|
unwrappers.put(index, unwrapper);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AutoWrapper<T> field(int index, EquivalentConverter converter) {
|
||||||
|
return field(index, converter::getSpecific, specific -> converter.getGeneric(specific));
|
||||||
|
}
|
||||||
|
|
||||||
|
public T wrap(Object nmsObject) {
|
||||||
|
T instance;
|
||||||
|
|
||||||
|
try {
|
||||||
|
instance = wrapperClass.newInstance();
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new InvalidWrapperException(wrapperClass.getSimpleName() + " is not accessible!", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Field[] wrapperFields = wrapperClass.getDeclaredFields();
|
||||||
|
Field[] nmsFields = nmsClass.getDeclaredFields();
|
||||||
|
|
||||||
|
for (int i = 0; i < wrapperFields.length; i++) {
|
||||||
|
try {
|
||||||
|
Field wrapperField = wrapperFields[i];
|
||||||
|
|
||||||
|
Field nmsField = nmsFields[i];
|
||||||
|
if (!nmsField.isAccessible())
|
||||||
|
nmsField.setAccessible(true);
|
||||||
|
|
||||||
|
Object value = nmsField.get(nmsObject);
|
||||||
|
if (wrappers.containsKey(i))
|
||||||
|
value = wrappers.get(i).apply(value);
|
||||||
|
|
||||||
|
wrapperField.set(instance, value);
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new InvalidWrapperException("Failed to wrap field", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object unwrap(Object wrapper) {
|
||||||
|
Object instance;
|
||||||
|
|
||||||
|
try {
|
||||||
|
instance = nmsClass.newInstance();
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new InvalidWrapperException("Failed to construct new " + nmsClass.getSimpleName(), ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
Field[] wrapperFields = wrapperClass.getDeclaredFields();
|
||||||
|
Field[] nmsFields = nmsClass.getDeclaredFields();
|
||||||
|
|
||||||
|
for (int i = 0; i < wrapperFields.length; i++) {
|
||||||
|
try {
|
||||||
|
Field wrapperField = wrapperFields[i];
|
||||||
|
|
||||||
|
Field nmsField = nmsFields[i];
|
||||||
|
if (!nmsField.isAccessible())
|
||||||
|
nmsField.setAccessible(true);
|
||||||
|
if (Modifier.isFinal(nmsField.getModifiers()))
|
||||||
|
unsetFinal(nmsField);
|
||||||
|
|
||||||
|
Object value = wrapperField.get(wrapper);
|
||||||
|
if (unwrappers.containsKey(i))
|
||||||
|
value = unwrappers.get(i).apply(value);
|
||||||
|
|
||||||
|
nmsField.set(instance, value);
|
||||||
|
} catch (ReflectiveOperationException ex) {
|
||||||
|
throw new InvalidWrapperException("Failed to unwrap field", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unsetFinal(Field field) throws ReflectiveOperationException {
|
||||||
|
Field modifiers = Field.class.getDeclaredField("modifiers");
|
||||||
|
modifiers.setAccessible(true);
|
||||||
|
modifiers.setInt(field, field.getModifiers() & ~Modifier.FINAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- Equivalent conversion
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getSpecific(Object generic) {
|
||||||
|
return wrap(generic);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGeneric(Object specific) {
|
||||||
|
return unwrap(specific);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getSpecificType() {
|
||||||
|
return wrapperClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class InvalidWrapperException extends RuntimeException {
|
||||||
|
private InvalidWrapperException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -164,7 +164,7 @@ public class BlockPosition {
|
|||||||
public static EquivalentConverter<BlockPosition> getConverter() {
|
public static EquivalentConverter<BlockPosition> getConverter() {
|
||||||
return new EquivalentConverter<BlockPosition>() {
|
return new EquivalentConverter<BlockPosition>() {
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, BlockPosition specific) {
|
public Object getGeneric(BlockPosition specific) {
|
||||||
if (blockPositionConstructor == null) {
|
if (blockPositionConstructor == null) {
|
||||||
try {
|
try {
|
||||||
blockPositionConstructor = MinecraftReflection.getBlockPositionClass().
|
blockPositionConstructor = MinecraftReflection.getBlockPositionClass().
|
||||||
@ -187,7 +187,7 @@ public class BlockPosition {
|
|||||||
public BlockPosition getSpecific(Object generic) {
|
public BlockPosition getSpecific(Object generic) {
|
||||||
if (MinecraftReflection.isBlockPosition(generic)) {
|
if (MinecraftReflection.isBlockPosition(generic)) {
|
||||||
// Use a structure modifier
|
// Use a structure modifier
|
||||||
intModifier = new StructureModifier<Object>(generic.getClass(), null, false).withType(int.class);
|
intModifier = new StructureModifier<>(generic.getClass(), null, false).withType(int.class);
|
||||||
|
|
||||||
// Damn it all
|
// Damn it all
|
||||||
if (intModifier.size() < 3) {
|
if (intModifier.size() < 3) {
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -67,7 +67,7 @@ public class ChunkCoordIntPair {
|
|||||||
public static EquivalentConverter<ChunkCoordIntPair> getConverter() {
|
public static EquivalentConverter<ChunkCoordIntPair> getConverter() {
|
||||||
return new EquivalentConverter<ChunkCoordIntPair>() {
|
return new EquivalentConverter<ChunkCoordIntPair>() {
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, ChunkCoordIntPair specific) {
|
public Object getGeneric(ChunkCoordIntPair specific) {
|
||||||
if (COORD_CONSTRUCTOR == null) {
|
if (COORD_CONSTRUCTOR == null) {
|
||||||
COORD_CONSTRUCTOR = Accessors.getConstructorAccessor(COORD_PAIR_CLASS, int.class, int.class);
|
COORD_CONSTRUCTOR = Accessors.getConstructorAccessor(COORD_PAIR_CLASS, int.class, int.class);
|
||||||
}
|
}
|
||||||
|
@ -154,7 +154,7 @@ public class ChunkPosition {
|
|||||||
public static EquivalentConverter<ChunkPosition> getConverter() {
|
public static EquivalentConverter<ChunkPosition> getConverter() {
|
||||||
return new EquivalentConverter<ChunkPosition>() {
|
return new EquivalentConverter<ChunkPosition>() {
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, ChunkPosition specific) {
|
public Object getGeneric(ChunkPosition specific) {
|
||||||
if (chunkPositionConstructor == null) {
|
if (chunkPositionConstructor == null) {
|
||||||
try {
|
try {
|
||||||
chunkPositionConstructor = MinecraftReflection.getChunkPositionClass().
|
chunkPositionConstructor = MinecraftReflection.getChunkPositionClass().
|
||||||
@ -177,7 +177,7 @@ public class ChunkPosition {
|
|||||||
public ChunkPosition getSpecific(Object generic) {
|
public ChunkPosition getSpecific(Object generic) {
|
||||||
if (MinecraftReflection.isChunkPosition(generic)) {
|
if (MinecraftReflection.isChunkPosition(generic)) {
|
||||||
// Use a structure modifier
|
// Use a structure modifier
|
||||||
intModifier = new StructureModifier<Object>(generic.getClass(), null, false).withType(int.class);
|
intModifier = new StructureModifier<>(generic.getClass(), null, false).withType(int.class);
|
||||||
|
|
||||||
// Damn it all
|
// Damn it all
|
||||||
if (intModifier.size() < 3) {
|
if (intModifier.size() < 3) {
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
/**
|
||||||
|
* ProtocolLib - Bukkit server library that allows access to the Minecraft protocol.
|
||||||
|
* Copyright (C) 2017 Dan Mulloy
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 2 of
|
||||||
|
* the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||||
|
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this program;
|
||||||
|
* if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
* 02111-1307 USA
|
||||||
|
*/
|
||||||
|
package com.comphenix.protocol.wrappers;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import com.comphenix.protocol.reflect.EquivalentConverter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for converters
|
||||||
|
* @author dmulloy2
|
||||||
|
*/
|
||||||
|
public class Converters {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a converter that ignores null elements, so that the underlying converter doesn't have to worry about them.
|
||||||
|
* @param converter Underlying converter
|
||||||
|
* @param <T> Element type
|
||||||
|
* @return An ignore null converter
|
||||||
|
*/
|
||||||
|
public static <T> EquivalentConverter<T> ignoreNull(final EquivalentConverter<T> converter) {
|
||||||
|
return new EquivalentConverter<T>() {
|
||||||
|
@Override
|
||||||
|
public T getSpecific(Object generic) {
|
||||||
|
return generic != null ? converter.getSpecific(generic) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGeneric(T specific) {
|
||||||
|
return specific != null ? converter.getGeneric(specific) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getSpecificType() {
|
||||||
|
return converter.getSpecificType();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a converter that passes generic and specific values through without converting.
|
||||||
|
* @param clazz Element class
|
||||||
|
* @param <T> Element type
|
||||||
|
* @return A passthrough converter
|
||||||
|
*/
|
||||||
|
public static <T> EquivalentConverter<T> passthrough(final Class<T> clazz) {
|
||||||
|
return ignoreNull(new EquivalentConverter<T>() {
|
||||||
|
@Override
|
||||||
|
public T getSpecific(Object generic) {
|
||||||
|
return (T) generic;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGeneric(T specific) {
|
||||||
|
return specific;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getSpecificType() {
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a simple converter for wrappers with {@code getHandle()} and {@code fromHandle(...)} methods. With Java 8,
|
||||||
|
* converters can be reduced to a single line (see {@link BukkitConverters#getWrappedGameProfileConverter()}).
|
||||||
|
* @param toHandle Function from wrapper to handle (i.e. {@code getHandle()})
|
||||||
|
* @param fromHandle Function from handle to wrapper (i.e. {@code fromHandle(Object)})
|
||||||
|
* @param <T> Wrapper type
|
||||||
|
* @return A handle converter
|
||||||
|
*/
|
||||||
|
public static <T> EquivalentConverter<T> handle(final Function<T, Object> toHandle,
|
||||||
|
final Function<Object, T> fromHandle) {
|
||||||
|
return new EquivalentConverter<T>() {
|
||||||
|
@Override
|
||||||
|
public T getSpecific(Object generic) {
|
||||||
|
return fromHandle.apply(generic);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getGeneric(T specific) {
|
||||||
|
return toHandle.apply(specific);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class<T> getSpecificType() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ package com.comphenix.protocol.wrappers;
|
|||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
|
|
||||||
@ -562,117 +563,119 @@ public abstract class EnumWrappers {
|
|||||||
|
|
||||||
// Get the converters
|
// Get the converters
|
||||||
public static EquivalentConverter<Protocol> getProtocolConverter() {
|
public static EquivalentConverter<Protocol> getProtocolConverter() {
|
||||||
return new EnumConverter<Protocol>(Protocol.class);
|
return new EnumConverter<>(getProtocolClass(), Protocol.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<ClientCommand> getClientCommandConverter() {
|
public static EquivalentConverter<ClientCommand> getClientCommandConverter() {
|
||||||
return new EnumConverter<ClientCommand>(ClientCommand.class);
|
return new EnumConverter<>(getClientCommandClass(), ClientCommand.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<ChatVisibility> getChatVisibilityConverter() {
|
public static EquivalentConverter<ChatVisibility> getChatVisibilityConverter() {
|
||||||
return new EnumConverter<ChatVisibility>(ChatVisibility.class);
|
return new EnumConverter<>(getChatVisibilityClass(), ChatVisibility.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<Difficulty> getDifficultyConverter() {
|
public static EquivalentConverter<Difficulty> getDifficultyConverter() {
|
||||||
return new EnumConverter<Difficulty>(Difficulty.class);
|
return new EnumConverter<>(getDifficultyClass(), Difficulty.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<EntityUseAction> getEntityUseActionConverter() {
|
public static EquivalentConverter<EntityUseAction> getEntityUseActionConverter() {
|
||||||
return new EnumConverter<EntityUseAction>(EntityUseAction.class);
|
return new EnumConverter<>(getEntityUseActionClass(), EntityUseAction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<NativeGameMode> getGameModeConverter() {
|
public static EquivalentConverter<NativeGameMode> getGameModeConverter() {
|
||||||
return new EnumConverter<NativeGameMode>(NativeGameMode.class);
|
return new EnumConverter<>(getGameModeClass(), NativeGameMode.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<ResourcePackStatus> getResourcePackStatusConverter() {
|
public static EquivalentConverter<ResourcePackStatus> getResourcePackStatusConverter() {
|
||||||
return new EnumConverter<ResourcePackStatus>(ResourcePackStatus.class);
|
return new EnumConverter<>(getResourcePackStatusClass(), ResourcePackStatus.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<PlayerInfoAction> getPlayerInfoActionConverter() {
|
public static EquivalentConverter<PlayerInfoAction> getPlayerInfoActionConverter() {
|
||||||
return new EnumConverter<PlayerInfoAction>(PlayerInfoAction.class);
|
return new EnumConverter<>(getPlayerInfoActionClass(), PlayerInfoAction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<TitleAction> getTitleActionConverter() {
|
public static EquivalentConverter<TitleAction> getTitleActionConverter() {
|
||||||
return new EnumConverter<TitleAction>(TitleAction.class);
|
return new EnumConverter<>(getTitleActionClass(), TitleAction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<WorldBorderAction> getWorldBorderActionConverter() {
|
public static EquivalentConverter<WorldBorderAction> getWorldBorderActionConverter() {
|
||||||
return new EnumConverter<WorldBorderAction>(WorldBorderAction.class);
|
return new EnumConverter<>(getWorldBorderActionClass(), WorldBorderAction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<CombatEventType> getCombatEventTypeConverter() {
|
public static EquivalentConverter<CombatEventType> getCombatEventTypeConverter() {
|
||||||
return new EnumConverter<CombatEventType>(CombatEventType.class);
|
return new EnumConverter<>(getCombatEventTypeClass(), CombatEventType.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<PlayerDigType> getPlayerDiggingActionConverter() {
|
public static EquivalentConverter<PlayerDigType> getPlayerDiggingActionConverter() {
|
||||||
return new EnumConverter<PlayerDigType>(PlayerDigType.class);
|
return new EnumConverter<>(getPlayerDigTypeClass(), PlayerDigType.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<PlayerAction> getEntityActionConverter() {
|
public static EquivalentConverter<PlayerAction> getEntityActionConverter() {
|
||||||
return new EnumConverter<PlayerAction>(PlayerAction.class);
|
return new EnumConverter<>(getPlayerActionClass(), PlayerAction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<ScoreboardAction> getUpdateScoreActionConverter() {
|
public static EquivalentConverter<ScoreboardAction> getUpdateScoreActionConverter() {
|
||||||
return new EnumConverter<ScoreboardAction>(ScoreboardAction.class);
|
return new EnumConverter<>(getScoreboardActionClass(), ScoreboardAction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<Particle> getParticleConverter() {
|
public static EquivalentConverter<Particle> getParticleConverter() {
|
||||||
return new EnumConverter<Particle>(Particle.class);
|
return new EnumConverter<>(getParticleClass(), Particle.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<SoundCategory> getSoundCategoryConverter() {
|
public static EquivalentConverter<SoundCategory> getSoundCategoryConverter() {
|
||||||
return new EnumConverter<SoundCategory>(SoundCategory.class);
|
return new EnumConverter<>(getSoundCategoryClass(), SoundCategory.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<ItemSlot> getItemSlotConverter() {
|
public static EquivalentConverter<ItemSlot> getItemSlotConverter() {
|
||||||
return new EnumConverter<ItemSlot>(ItemSlot.class);
|
return new EnumConverter<>(getItemSlotClass(), ItemSlot.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<Hand> getHandConverter() {
|
public static EquivalentConverter<Hand> getHandConverter() {
|
||||||
return new EnumConverter<Hand>(Hand.class);
|
return new EnumConverter<>(getHandClass(), Hand.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<Direction> getDirectionConverter() {
|
public static EquivalentConverter<Direction> getDirectionConverter() {
|
||||||
return new EnumConverter<Direction>(Direction.class);
|
return new EnumConverter<>(getDirectionClass(), Direction.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<ChatType> getChatTypeConverter() {
|
public static EquivalentConverter<ChatType> getChatTypeConverter() {
|
||||||
return new EnumConverter<ChatType>(ChatType.class);
|
return new EnumConverter<>(getChatTypeClass(), ChatType.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a generic enum converter for use with StructureModifiers.
|
* Retrieve a generic enum converter for use with StructureModifiers.
|
||||||
* @param enumClass - Enum class
|
* @param genericClass - Generic nms enum class
|
||||||
|
* @param specificType - Specific enum class
|
||||||
* @return A generic enum converter
|
* @return A generic enum converter
|
||||||
*/
|
*/
|
||||||
public static <T extends Enum<T>> EquivalentConverter<T> getGenericConverter(Class<T> enumClass) {
|
public static <T extends Enum<T>> EquivalentConverter<T> getGenericConverter(Class<?> genericClass, Class<T> specificType) {
|
||||||
return new EnumConverter<T>(enumClass);
|
return new EnumConverter<>(genericClass, specificType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The common enum converter
|
// The common enum converter
|
||||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||||
public static class EnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
|
public static class EnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
|
||||||
|
private Class<?> genericType;
|
||||||
private Class<T> specificType;
|
private Class<T> specificType;
|
||||||
|
|
||||||
public EnumConverter(Class<T> specificType) {
|
public EnumConverter(Class<?> genericType, Class<T> specificType) {
|
||||||
|
this.genericType = genericType;
|
||||||
this.specificType = specificType;
|
this.specificType = specificType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T getSpecific(Object generic) {
|
public T getSpecific(Object generic) {
|
||||||
// We know its an enum already!
|
|
||||||
return Enum.valueOf(specificType, ((Enum) generic).name());
|
return Enum.valueOf(specificType, ((Enum) generic).name());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, T specific) {
|
public Object getGeneric(T specific) {
|
||||||
return Enum.valueOf((Class) genericType, specific.name());
|
return Enum.valueOf((Class) genericType, specific.name());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<T> getSpecificType() {
|
public Class<T> getSpecificType() {
|
||||||
return specificType;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ public class MinecraftKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, MinecraftKey specific) {
|
public Object getGeneric(MinecraftKey specific) {
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
try {
|
try {
|
||||||
constructor = MinecraftReflection.getMinecraftKeyClass().getConstructor(String.class, String.class);
|
constructor = MinecraftReflection.getMinecraftKeyClass().getConstructor(String.class, String.class);
|
||||||
|
@ -190,7 +190,7 @@ public class MultiBlockChangeInfo {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MultiBlockChangeInfo getSpecific(Object generic) {
|
public MultiBlockChangeInfo getSpecific(Object generic) {
|
||||||
StructureModifier<Object> modifier = new StructureModifier<Object>(generic.getClass(), null, false).withTarget(generic);
|
StructureModifier<Object> modifier = new StructureModifier<>(generic.getClass(), null, false).withTarget(generic);
|
||||||
|
|
||||||
StructureModifier<Short> shorts = modifier.withType(short.class);
|
StructureModifier<Short> shorts = modifier.withType(short.class);
|
||||||
short location = shorts.read(0);
|
short location = shorts.read(0);
|
||||||
@ -203,7 +203,7 @@ public class MultiBlockChangeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, MultiBlockChangeInfo specific) {
|
public Object getGeneric(MultiBlockChangeInfo specific) {
|
||||||
try {
|
try {
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
constructor = nmsClass.getConstructor(
|
constructor = nmsClass.getConstructor(
|
||||||
@ -216,7 +216,7 @@ public class MultiBlockChangeInfo {
|
|||||||
return constructor.newInstance(
|
return constructor.newInstance(
|
||||||
null,
|
null,
|
||||||
specific.location,
|
specific.location,
|
||||||
BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), specific.data)
|
BukkitConverters.getWrappedBlockDataConverter().getGeneric(specific.data)
|
||||||
);
|
);
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
throw new RuntimeException("Failed to construct MultiBlockChangeInfo instance.", ex);
|
throw new RuntimeException("Failed to construct MultiBlockChangeInfo instance.", ex);
|
||||||
@ -248,12 +248,12 @@ public class MultiBlockChangeInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, MultiBlockChangeInfo[] specific) {
|
public Object getGeneric(MultiBlockChangeInfo[] specific) {
|
||||||
Object[] result = (Object[]) Array.newInstance(nmsClass, specific.length);
|
Object[] result = (Object[]) Array.newInstance(nmsClass, specific.length);
|
||||||
|
|
||||||
// Wrap every item
|
// Wrap every item
|
||||||
for (int i = 0; i < result.length; i++) {
|
for (int i = 0; i < result.length; i++) {
|
||||||
result[i] = converter.getGeneric(nmsClass, specific[i]);
|
result[i] = converter.getGeneric(specific[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -91,7 +91,7 @@ public class PlayerInfoData {
|
|||||||
public static EquivalentConverter<PlayerInfoData> getConverter() {
|
public static EquivalentConverter<PlayerInfoData> getConverter() {
|
||||||
return new EquivalentConverter<PlayerInfoData>() {
|
return new EquivalentConverter<PlayerInfoData>() {
|
||||||
@Override
|
@Override
|
||||||
public Object getGeneric(Class<?> genericType, PlayerInfoData specific) {
|
public Object getGeneric(PlayerInfoData specific) {
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
try {
|
try {
|
||||||
// public PlayerInfoData(Packet, GameProfile, int, GameMode, ChatComponent)
|
// public PlayerInfoData(Packet, GameProfile, int, GameMode, ChatComponent)
|
||||||
@ -116,7 +116,7 @@ public class PlayerInfoData {
|
|||||||
null,
|
null,
|
||||||
specific.profile.handle,
|
specific.profile.handle,
|
||||||
specific.latency,
|
specific.latency,
|
||||||
EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.getGameModeClass(), specific.gameMode),
|
EnumWrappers.getGameModeConverter().getGeneric(specific.gameMode),
|
||||||
specific.displayName != null ? specific.displayName.handle : null
|
specific.displayName != null ? specific.displayName.handle : null
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
@ -128,7 +128,7 @@ public class PlayerInfoData {
|
|||||||
@Override
|
@Override
|
||||||
public PlayerInfoData getSpecific(Object generic) {
|
public PlayerInfoData getSpecific(Object generic) {
|
||||||
if (MinecraftReflection.isPlayerInfoData(generic)) {
|
if (MinecraftReflection.isPlayerInfoData(generic)) {
|
||||||
StructureModifier<Object> modifier = new StructureModifier<Object>(generic.getClass(), null, false)
|
StructureModifier<Object> modifier = new StructureModifier<>(generic.getClass(), null, false)
|
||||||
.withTarget(generic);
|
.withTarget(generic);
|
||||||
|
|
||||||
StructureModifier<WrappedGameProfile> gameProfiles = modifier.withType(
|
StructureModifier<WrappedGameProfile> gameProfiles = modifier.withType(
|
||||||
|
@ -91,15 +91,14 @@ public class Vector3F {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static EquivalentConverter<Vector3F> getConverter() {
|
public static EquivalentConverter<Vector3F> getConverter() {
|
||||||
return new IgnoreNullConverter<Vector3F>() {
|
return Converters.ignoreNull(new EquivalentConverter<Vector3F>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Class<Vector3F> getSpecificType() {
|
public Class<Vector3F> getSpecificType() {
|
||||||
return Vector3F.class;
|
return Vector3F.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object getGenericValue(Class<?> genericType, Vector3F specific) {
|
public Object getGeneric(Vector3F specific) {
|
||||||
if (constructor == null) {
|
if (constructor == null) {
|
||||||
try {
|
try {
|
||||||
constructor = clazz.getConstructor(float.class, float.class, float.class);
|
constructor = clazz.getConstructor(float.class, float.class, float.class);
|
||||||
@ -107,7 +106,7 @@ public class Vector3F {
|
|||||||
throw new RuntimeException("Failed to find constructor for Vector3f", ex);
|
throw new RuntimeException("Failed to find constructor for Vector3f", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return constructor.newInstance(specific.x, specific.y, specific.z);
|
return constructor.newInstance(specific.x, specific.y, specific.z);
|
||||||
} catch (ReflectiveOperationException ex) {
|
} catch (ReflectiveOperationException ex) {
|
||||||
@ -116,7 +115,7 @@ public class Vector3F {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Vector3F getSpecificValue(Object generic) {
|
public Vector3F getSpecific(Object generic) {
|
||||||
StructureModifier<Float> modifier = new StructureModifier<Float>(generic.getClass())
|
StructureModifier<Float> modifier = new StructureModifier<Float>(generic.getClass())
|
||||||
.withTarget(generic).withType(float.class);
|
.withTarget(generic).withType(float.class);
|
||||||
float x = modifier.read(0);
|
float x = modifier.read(0);
|
||||||
@ -124,6 +123,6 @@ public class Vector3F {
|
|||||||
float z = modifier.read(2);
|
float z = modifier.read(2);
|
||||||
return new Vector3F(x, y, z);
|
return new Vector3F(x, y, z);
|
||||||
}
|
}
|
||||||
};
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -280,7 +280,7 @@ public class WrappedServerPing extends AbstractWrapper {
|
|||||||
public void setPlayers(Iterable<? extends WrappedGameProfile> profile) {
|
public void setPlayers(Iterable<? extends WrappedGameProfile> profile) {
|
||||||
if (players == null)
|
if (players == null)
|
||||||
resetPlayers();
|
resetPlayers();
|
||||||
PLAYERS_PROFILES.set(players, (profile != null) ? PROFILE_CONVERT.getGeneric(GAME_PROFILE_ARRAY, profile) : null);
|
PLAYERS_PROFILES.set(players, (profile != null) ? PROFILE_CONVERT.getGeneric(profile) : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -273,22 +273,22 @@ public class WrappedWatchableObject extends AbstractWrapper {
|
|||||||
if (wrapped instanceof WrappedChatComponent) {
|
if (wrapped instanceof WrappedChatComponent) {
|
||||||
return ((WrappedChatComponent) wrapped).getHandle();
|
return ((WrappedChatComponent) wrapped).getHandle();
|
||||||
} else if (wrapped instanceof ItemStack) {
|
} else if (wrapped instanceof ItemStack) {
|
||||||
return BukkitConverters.getItemStackConverter().getGeneric(MinecraftReflection.getItemStackClass(), (ItemStack) wrapped);
|
return BukkitConverters.getItemStackConverter().getGeneric((ItemStack) wrapped);
|
||||||
} else if (wrapped instanceof WrappedBlockData) {
|
} else if (wrapped instanceof WrappedBlockData) {
|
||||||
return BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), (WrappedBlockData) wrapped);
|
return BukkitConverters.getWrappedBlockDataConverter().getGeneric((WrappedBlockData) wrapped);
|
||||||
} else if (wrapped instanceof Vector3F) {
|
} else if (wrapped instanceof Vector3F) {
|
||||||
return Vector3F.getConverter().getGeneric(Vector3F.getMinecraftClass(), (Vector3F) wrapped);
|
return Vector3F.getConverter().getGeneric((Vector3F) wrapped);
|
||||||
} else if (wrapped instanceof BlockPosition) {
|
} else if (wrapped instanceof BlockPosition) {
|
||||||
return BlockPosition.getConverter().getGeneric(MinecraftReflection.getBlockPositionClass(), (BlockPosition) wrapped);
|
return BlockPosition.getConverter().getGeneric((BlockPosition) wrapped);
|
||||||
} else if (wrapped instanceof Direction) {
|
} else if (wrapped instanceof Direction) {
|
||||||
return EnumWrappers.getDirectionConverter().getGeneric(EnumWrappers.getDirectionClass(), (Direction) wrapped);
|
return EnumWrappers.getDirectionConverter().getGeneric((Direction) wrapped);
|
||||||
} else if (wrapped instanceof NbtCompound) {
|
} else if (wrapped instanceof NbtCompound) {
|
||||||
return NbtFactory.fromBase((NbtCompound) wrapped).getHandle();
|
return NbtFactory.fromBase((NbtCompound) wrapped).getHandle();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Legacy classes
|
// Legacy classes
|
||||||
if (wrapped instanceof ChunkPosition) {
|
if (wrapped instanceof ChunkPosition) {
|
||||||
return ChunkPosition.getConverter().getGeneric(MinecraftReflection.getChunkPositionClass(), (ChunkPosition) wrapped);
|
return ChunkPosition.getConverter().getGeneric((ChunkPosition) wrapped);
|
||||||
} else if (wrapped instanceof WrappedChunkCoordinate) {
|
} else if (wrapped instanceof WrappedChunkCoordinate) {
|
||||||
return ((WrappedChunkCoordinate) wrapped).getHandle();
|
return ((WrappedChunkCoordinate) wrapped).getHandle();
|
||||||
}
|
}
|
||||||
|
@ -38,6 +38,7 @@ public class BukkitInitialization {
|
|||||||
try {
|
try {
|
||||||
LogManager.getLogger();
|
LogManager.getLogger();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
|
// Happens only on my Jenkins, but if it errors here it works when it matters
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +70,7 @@ public class BukkitInitialization {
|
|||||||
try {
|
try {
|
||||||
LogManager.getLogger();
|
LogManager.getLogger();
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
|
// Happens only on my Jenkins, but if it errors here it works when it matters
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ public class ChunkCoordIntPairTest {
|
|||||||
|
|
||||||
net.minecraft.server.v1_12_R1.ChunkCoordIntPair roundtrip =
|
net.minecraft.server.v1_12_R1.ChunkCoordIntPair roundtrip =
|
||||||
(net.minecraft.server.v1_12_R1.ChunkCoordIntPair) ChunkCoordIntPair.getConverter().
|
(net.minecraft.server.v1_12_R1.ChunkCoordIntPair) ChunkCoordIntPair.getConverter().
|
||||||
getGeneric(net.minecraft.server.v1_12_R1.ChunkCoordIntPair.class, specific);
|
getGeneric(specific);
|
||||||
|
|
||||||
assertEquals(1, roundtrip.x);
|
assertEquals(1, roundtrip.x);
|
||||||
assertEquals(2, roundtrip.z);
|
assertEquals(2, roundtrip.z);
|
||||||
|
@ -55,7 +55,6 @@ public class EnumWrappersTest {
|
|||||||
FieldAccessor accessor = Accessors.getFieldAccessor(target.getClass(), fieldName, true);
|
FieldAccessor accessor = Accessors.getFieldAccessor(target.getClass(), fieldName, true);
|
||||||
|
|
||||||
return (T) converter.getGeneric(
|
return (T) converter.getGeneric(
|
||||||
accessor.getField().getType(),
|
|
||||||
converter.getSpecific(accessor.get(target))
|
converter.getSpecific(accessor.get(target))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -58,7 +58,7 @@ public class MultiBlockChangeTest {
|
|||||||
MultiBlockChangeInfo[] array = { info, info };
|
MultiBlockChangeInfo[] array = { info, info };
|
||||||
|
|
||||||
EquivalentConverter<MultiBlockChangeInfo[]> converter = MultiBlockChangeInfo.getArrayConverter(chunk);
|
EquivalentConverter<MultiBlockChangeInfo[]> converter = MultiBlockChangeInfo.getArrayConverter(chunk);
|
||||||
Object generic = converter.getGeneric(MinecraftReflection.getMultiBlockChangeInfoArrayClass(), array);
|
Object generic = converter.getGeneric(array);
|
||||||
MultiBlockChangeInfo[] back = converter.getSpecific(generic);
|
MultiBlockChangeInfo[] back = converter.getSpecific(generic);
|
||||||
|
|
||||||
// Make sure our conversions are correct
|
// Make sure our conversions are correct
|
||||||
|
@ -43,7 +43,7 @@ public class PlayerInfoDataTest {
|
|||||||
WrappedChatComponent displayName = WrappedChatComponent.fromText("Name's Name");
|
WrappedChatComponent displayName = WrappedChatComponent.fromText("Name's Name");
|
||||||
|
|
||||||
PlayerInfoData data = new PlayerInfoData(profile, 42, NativeGameMode.CREATIVE, displayName);
|
PlayerInfoData data = new PlayerInfoData(profile, 42, NativeGameMode.CREATIVE, displayName);
|
||||||
Object generic = PlayerInfoData.getConverter().getGeneric(MinecraftReflection.getPlayerInfoDataClass(), data);
|
Object generic = PlayerInfoData.getConverter().getGeneric(data);
|
||||||
PlayerInfoData back = PlayerInfoData.getConverter().getSpecific(generic);
|
PlayerInfoData back = PlayerInfoData.getConverter().getSpecific(generic);
|
||||||
|
|
||||||
assertEquals(data, back);
|
assertEquals(data, back);
|
||||||
|
@ -47,7 +47,7 @@ public class WrappedBlockDataTest {
|
|||||||
assertEquals(wrapper.getType(), type);
|
assertEquals(wrapper.getType(), type);
|
||||||
assertEquals(wrapper.getData(), data);
|
assertEquals(wrapper.getData(), data);
|
||||||
|
|
||||||
Object generic = BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), wrapper);
|
Object generic = BukkitConverters.getWrappedBlockDataConverter().getGeneric(wrapper);
|
||||||
WrappedBlockData back = BukkitConverters.getWrappedBlockDataConverter().getSpecific(generic);
|
WrappedBlockData back = BukkitConverters.getWrappedBlockDataConverter().getSpecific(generic);
|
||||||
|
|
||||||
assertEquals(wrapper.getType(), back.getType());
|
assertEquals(wrapper.getType(), back.getType());
|
||||||
|
4
pom.xml
4
pom.xml
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<minorVersion>4.3.1-SNAPSHOT</minorVersion>
|
<minorVersion>4.4.0-SNAPSHOT</minorVersion>
|
||||||
<spigotVersion>1.12-R0.1-SNAPSHOT</spigotVersion>
|
<spigotVersion>1.12-R0.1-SNAPSHOT</spigotVersion>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@ -45,7 +45,7 @@
|
|||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<!-- Compile with the old version of Netty -->
|
<!-- Compile with the old version of Netty for backwards compat -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.netty</groupId>
|
<groupId>io.netty</groupId>
|
||||||
<artifactId>netty-all</artifactId>
|
<artifactId>netty-all</artifactId>
|
||||||
|
Loading…
Reference in New Issue
Block a user