mirror of
https://github.com/dmulloy2/ProtocolLib.git
synced 2024-11-27 13:15:52 +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.MinecraftReflection;
|
||||
import com.comphenix.protocol.utility.StreamSerializer;
|
||||
import com.comphenix.protocol.wrappers.BlockPosition;
|
||||
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.*;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ChatType;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.ChatVisibility;
|
||||
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.TitleAction;
|
||||
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.NbtCompound;
|
||||
import com.comphenix.protocol.wrappers.nbt.NbtFactory;
|
||||
@ -134,30 +120,29 @@ public class PacketContainer implements Serializable {
|
||||
private static ConcurrentMap<Class<?>, Method> readMethods = Maps.newConcurrentMap();
|
||||
|
||||
// Used to clone packets
|
||||
private static final AggregateCloner DEEP_CLONER = AggregateCloner.newBuilder().
|
||||
instanceProvider(DefaultInstances.DEFAULT).
|
||||
andThen(BukkitCloner.class).
|
||||
andThen(ImmutableDetector.class).
|
||||
andThen(OptionalCloner.class).
|
||||
andThen(CollectionCloner.class).
|
||||
andThen(getSpecializedDeepClonerFactory()).
|
||||
build();
|
||||
private static final AggregateCloner DEEP_CLONER = AggregateCloner
|
||||
.newBuilder()
|
||||
.instanceProvider(DefaultInstances.DEFAULT)
|
||||
.andThen(BukkitCloner.class)
|
||||
.andThen(ImmutableDetector.class)
|
||||
.andThen(OptionalCloner.class)
|
||||
.andThen(CollectionCloner.class)
|
||||
.andThen(getSpecializedDeepClonerFactory())
|
||||
.build();
|
||||
|
||||
private static final AggregateCloner SHALLOW_CLONER = AggregateCloner.newBuilder().
|
||||
instanceProvider(DefaultInstances.DEFAULT).
|
||||
andThen(new Function<BuilderParameters, Cloner>() {
|
||||
@Override
|
||||
public Cloner apply(@Nullable BuilderParameters param) {
|
||||
if (param == null)
|
||||
throw new IllegalArgumentException("Cannot be NULL.");
|
||||
|
||||
return new FieldCloner(param.getAggregateCloner(), param.getInstanceProvider()) {{
|
||||
// Use a default writer with no concept of cloning
|
||||
writer = new ObjectWriter();
|
||||
}};
|
||||
}
|
||||
}).
|
||||
build();
|
||||
private static final AggregateCloner SHALLOW_CLONER = AggregateCloner
|
||||
.newBuilder()
|
||||
.instanceProvider(DefaultInstances.DEFAULT)
|
||||
.andThen(param -> {
|
||||
if (param == null)
|
||||
throw new IllegalArgumentException("Cannot be NULL.");
|
||||
|
||||
return new FieldCloner(param.getAggregateCloner(), param.getInstanceProvider()) {{
|
||||
// Use a default writer with no concept of cloning
|
||||
writer = new ObjectWriter();
|
||||
}};
|
||||
})
|
||||
.build();
|
||||
|
||||
// Packets that cannot be cloned by our default deep cloner
|
||||
private static final Set<PacketType> CLONING_UNSUPPORTED = Sets.newHashSet(
|
||||
@ -385,8 +370,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<ItemStack> getItemModifier() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<ItemStack>withType(
|
||||
MinecraftReflection.getItemStackClass(), BukkitConverters.getItemStackConverter());
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getItemStackClass(),
|
||||
BukkitConverters.getItemStackConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -398,9 +384,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<ItemStack[]> getItemArrayModifier() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<ItemStack[]>withType(
|
||||
return structureModifier.withType(
|
||||
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
|
||||
return structureModifier.withType(
|
||||
List.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getItemStackClass(),
|
||||
BukkitConverters.getItemStackConverter()
|
||||
)
|
||||
BukkitConverters.getListConverter(BukkitConverters.getItemStackConverter())
|
||||
);
|
||||
}
|
||||
|
||||
@ -428,12 +411,9 @@ public class PacketContainer implements Serializable {
|
||||
* @return A modifier for maps of statistics.
|
||||
*/
|
||||
public StructureModifier<Map<WrappedStatistic, Integer>> getStatisticMaps() {
|
||||
return structureModifier.withType(Map.class,
|
||||
BukkitConverters.<WrappedStatistic, Integer>getMapConverter(
|
||||
MinecraftReflection.getStatisticClass(),
|
||||
BukkitConverters.getWrappedStatisticConverter()
|
||||
)
|
||||
);
|
||||
return getMaps(
|
||||
BukkitConverters.getWrappedStatisticConverter(),
|
||||
Converters.passthrough(Integer.class));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -445,7 +425,7 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<WorldType> getWorldTypeModifier() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<WorldType>withType(
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getWorldTypeClass(),
|
||||
BukkitConverters.getWorldTypeConverter());
|
||||
}
|
||||
@ -456,7 +436,7 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<WrappedDataWatcher> getDataWatcherModifier() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<WrappedDataWatcher>withType(
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getDataWatcherClass(),
|
||||
BukkitConverters.getDataWatcherConverter());
|
||||
}
|
||||
@ -475,7 +455,7 @@ public class PacketContainer implements Serializable {
|
||||
public StructureModifier<Entity> getEntityModifier(@Nonnull World world) {
|
||||
Preconditions.checkNotNull(world, "world cannot be NULL.");
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<Entity>withType(
|
||||
return structureModifier.withType(
|
||||
int.class, BukkitConverters.getEntityConverter(world));
|
||||
}
|
||||
|
||||
@ -547,10 +527,7 @@ public class PacketContainer implements Serializable {
|
||||
// Convert to and from the ProtocolLib wrapper
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getNBTBaseClass(),
|
||||
BukkitConverters.getNbtConverter()
|
||||
)
|
||||
BukkitConverters.getListConverter(BukkitConverters.getNbtConverter())
|
||||
);
|
||||
}
|
||||
|
||||
@ -576,9 +553,7 @@ public class PacketContainer implements Serializable {
|
||||
// Convert to and from the ProtocolLib wrapper
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getAttributeSnapshotClass(),
|
||||
BukkitConverters.getWrappedAttributeConverter())
|
||||
BukkitConverters.getListConverter(BukkitConverters.getWrappedAttributeConverter())
|
||||
);
|
||||
}
|
||||
|
||||
@ -594,10 +569,7 @@ public class PacketContainer implements Serializable {
|
||||
// Convert to and from the ProtocolLib wrapper
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getChunkPositionClass(),
|
||||
ChunkPosition.getConverter())
|
||||
);
|
||||
BukkitConverters.getListConverter(ChunkPosition.getConverter()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -612,10 +584,7 @@ public class PacketContainer implements Serializable {
|
||||
// Convert to and from the ProtocolLib wrapper
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getBlockPositionClass(),
|
||||
BlockPosition.getConverter())
|
||||
);
|
||||
BukkitConverters.getListConverter(BlockPosition.getConverter()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -629,10 +598,7 @@ public class PacketContainer implements Serializable {
|
||||
// Convert to and from the ProtocolLib wrapper
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getDataWatcherItemClass(),
|
||||
BukkitConverters.getWatchableObjectConverter())
|
||||
);
|
||||
BukkitConverters.getListConverter(BukkitConverters.getWatchableObjectConverter()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -644,7 +610,7 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<Material> getBlocks() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<Material>withType(
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getBlockClass(), BukkitConverters.getBlockConverter());
|
||||
}
|
||||
|
||||
@ -657,7 +623,7 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<WrappedGameProfile> getGameProfiles() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<WrappedGameProfile>withType(
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getGameProfileClass(), BukkitConverters.getWrappedGameProfileConverter());
|
||||
}
|
||||
|
||||
@ -670,7 +636,7 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<WrappedBlockData> getBlockData() {
|
||||
// Convert to and from our wrapper
|
||||
return structureModifier.<WrappedBlockData>withType(
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getIBlockDataClass(), BukkitConverters.getWrappedBlockDataConverter());
|
||||
}
|
||||
|
||||
@ -685,7 +651,7 @@ public class PacketContainer implements Serializable {
|
||||
ChunkCoordIntPair chunk = getChunkCoordIntPairs().read(0);
|
||||
|
||||
// Convert to and from our wrapper
|
||||
return structureModifier.<MultiBlockChangeInfo[]>withType(
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getMultiBlockChangeInfoArrayClass(), MultiBlockChangeInfo.getArrayConverter(chunk));
|
||||
}
|
||||
|
||||
@ -698,7 +664,7 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<WrappedChatComponent> getChatComponents() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<WrappedChatComponent>withType(
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getIChatBaseComponentClass(), BukkitConverters.getWrappedChatComponentConverter());
|
||||
}
|
||||
|
||||
@ -715,22 +681,23 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<WrappedChatComponent[]> getChatComponentArrays() {
|
||||
// Convert to and from the Bukkit wrapper
|
||||
return structureModifier.<WrappedChatComponent[]>withType(
|
||||
return structureModifier.withType(
|
||||
ComponentArrayConverter.getGenericType(),
|
||||
BukkitConverters.getIgnoreNull(new ComponentArrayConverter()));
|
||||
Converters.ignoreNull(new ComponentArrayConverter()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a read/write structure for the ServerPing fields in the following packet: <br>
|
||||
* <ul>
|
||||
* <li>{@link PacketType.Status.Server#OUT_SERVER_INFO}
|
||||
* <li>{@link PacketType.Status.Server#SERVER_INFO}
|
||||
* </ul>
|
||||
* @return A modifier for ServerPing fields.
|
||||
*/
|
||||
public StructureModifier<WrappedServerPing> getServerPings() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<WrappedServerPing>withType(
|
||||
MinecraftReflection.getServerPingClass(), BukkitConverters.getWrappedServerPingConverter());
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getServerPingClass(),
|
||||
BukkitConverters.getWrappedServerPingConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -744,10 +711,7 @@ public class PacketContainer implements Serializable {
|
||||
// Convert to and from the ProtocolLib wrapper
|
||||
return structureModifier.withType(
|
||||
Collection.class,
|
||||
BukkitConverters.getListConverter(
|
||||
MinecraftReflection.getPlayerInfoDataClass(),
|
||||
PlayerInfoData.getConverter())
|
||||
);
|
||||
BukkitConverters.getListConverter(PlayerInfoData.getConverter()));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -756,8 +720,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<Protocol> getProtocols() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<Protocol>withType(
|
||||
EnumWrappers.getProtocolClass(), EnumWrappers.getProtocolConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getProtocolClass(),
|
||||
EnumWrappers.getProtocolConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -766,8 +731,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<ClientCommand> getClientCommands() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<ClientCommand>withType(
|
||||
EnumWrappers.getClientCommandClass(), EnumWrappers.getClientCommandConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getClientCommandClass(),
|
||||
EnumWrappers.getClientCommandConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -776,8 +742,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<ChatVisibility> getChatVisibilities() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<ChatVisibility>withType(
|
||||
EnumWrappers.getChatVisibilityClass(), EnumWrappers.getChatVisibilityConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getChatVisibilityClass(),
|
||||
EnumWrappers.getChatVisibilityConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -786,8 +753,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<Difficulty> getDifficulties() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<Difficulty>withType(
|
||||
EnumWrappers.getDifficultyClass(), EnumWrappers.getDifficultyConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getDifficultyClass(),
|
||||
EnumWrappers.getDifficultyConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -796,8 +764,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<EntityUseAction> getEntityUseActions() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<EntityUseAction>withType(
|
||||
EnumWrappers.getEntityUseActionClass(), EnumWrappers.getEntityUseActionConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getEntityUseActionClass(),
|
||||
EnumWrappers.getEntityUseActionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -806,8 +775,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<NativeGameMode> getGameModes() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<NativeGameMode>withType(
|
||||
EnumWrappers.getGameModeClass(), EnumWrappers.getGameModeConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getGameModeClass(),
|
||||
EnumWrappers.getGameModeConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -816,8 +786,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<ResourcePackStatus> getResourcePackStatus() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<ResourcePackStatus>withType(
|
||||
EnumWrappers.getResourcePackStatusClass(), EnumWrappers.getResourcePackStatusConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getResourcePackStatusClass(),
|
||||
EnumWrappers.getResourcePackStatusConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -826,8 +797,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<PlayerInfoAction> getPlayerInfoAction() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<PlayerInfoAction>withType(
|
||||
EnumWrappers.getPlayerInfoActionClass(), EnumWrappers.getPlayerInfoActionConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getPlayerInfoActionClass(),
|
||||
EnumWrappers.getPlayerInfoActionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -836,8 +808,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<TitleAction> getTitleActions() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<TitleAction>withType(
|
||||
EnumWrappers.getTitleActionClass(), EnumWrappers.getTitleActionConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getTitleActionClass(),
|
||||
EnumWrappers.getTitleActionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -846,8 +819,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<WorldBorderAction> getWorldBorderActions() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<WorldBorderAction>withType(
|
||||
EnumWrappers.getWorldBorderActionClass(), EnumWrappers.getWorldBorderActionConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getWorldBorderActionClass(),
|
||||
EnumWrappers.getWorldBorderActionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -856,8 +830,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<CombatEventType> getCombatEvents() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<CombatEventType>withType(
|
||||
EnumWrappers.getCombatEventTypeClass(), EnumWrappers.getCombatEventTypeConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getCombatEventTypeClass(),
|
||||
EnumWrappers.getCombatEventTypeConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -866,8 +841,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<PlayerDigType> getPlayerDigTypes() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<PlayerDigType>withType(
|
||||
EnumWrappers.getPlayerDigTypeClass(), EnumWrappers.getPlayerDiggingActionConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getPlayerDigTypeClass(),
|
||||
EnumWrappers.getPlayerDiggingActionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -876,8 +852,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<PlayerAction> getPlayerActions() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<PlayerAction>withType(
|
||||
EnumWrappers.getPlayerActionClass(), EnumWrappers.getEntityActionConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getPlayerActionClass(),
|
||||
EnumWrappers.getEntityActionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -886,8 +863,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<ScoreboardAction> getScoreboardActions() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<ScoreboardAction>withType(
|
||||
EnumWrappers.getScoreboardActionClass(), EnumWrappers.getUpdateScoreActionConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getScoreboardActionClass(),
|
||||
EnumWrappers.getUpdateScoreActionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -896,8 +874,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<Particle> getParticles() {
|
||||
// Convert to and from the wrapper
|
||||
return structureModifier.<Particle>withType(
|
||||
EnumWrappers.getParticleClass(), EnumWrappers.getParticleConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getParticleClass(),
|
||||
EnumWrappers.getParticleConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -906,8 +885,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<PotionEffectType> getEffectTypes() {
|
||||
// Convert to and from Bukkit
|
||||
return structureModifier.<PotionEffectType>withType(
|
||||
MinecraftReflection.getMobEffectListClass(), BukkitConverters.getEffectTypeConverter());
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getMobEffectListClass(),
|
||||
BukkitConverters.getEffectTypeConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -916,8 +896,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<SoundCategory> getSoundCategories() {
|
||||
// Convert to and from the enums
|
||||
return structureModifier.<SoundCategory>withType(
|
||||
EnumWrappers.getSoundCategoryClass(), EnumWrappers.getSoundCategoryConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getSoundCategoryClass(),
|
||||
EnumWrappers.getSoundCategoryConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -926,8 +907,9 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public StructureModifier<Sound> getSoundEffects() {
|
||||
// Convert to and from Bukkit
|
||||
return structureModifier.<Sound>withType(
|
||||
MinecraftReflection.getSoundEffectClass(), BukkitConverters.getSoundConverter());
|
||||
return structureModifier.withType(
|
||||
MinecraftReflection.getSoundEffectClass(),
|
||||
BukkitConverters.getSoundConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -935,8 +917,9 @@ public class PacketContainer implements Serializable {
|
||||
* @return A modifier for ItemSlot enum fields.
|
||||
*/
|
||||
public StructureModifier<ItemSlot> getItemSlots() {
|
||||
return structureModifier.<ItemSlot>withType(
|
||||
EnumWrappers.getItemSlotClass(), EnumWrappers.getItemSlotConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getItemSlotClass(),
|
||||
EnumWrappers.getItemSlotConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -944,8 +927,9 @@ public class PacketContainer implements Serializable {
|
||||
* @return A modifier for Hand enum fields.
|
||||
*/
|
||||
public StructureModifier<Hand> getHands() {
|
||||
return structureModifier.<Hand>withType(
|
||||
EnumWrappers.getHandClass(), EnumWrappers.getHandConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getHandClass(),
|
||||
EnumWrappers.getHandConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -953,8 +937,9 @@ public class PacketContainer implements Serializable {
|
||||
* @return A modifier for Direction enum fields.
|
||||
*/
|
||||
public StructureModifier<Direction> getDirections() {
|
||||
return structureModifier.<Direction>withType(
|
||||
EnumWrappers.getDirectionClass(), EnumWrappers.getDirectionConverter());
|
||||
return structureModifier.withType(
|
||||
EnumWrappers.getDirectionClass(),
|
||||
EnumWrappers.getDirectionConverter());
|
||||
}
|
||||
|
||||
/**
|
||||
@ -962,8 +947,52 @@ public class PacketContainer implements Serializable {
|
||||
* @return A modifier for ChatType enum fields.
|
||||
*/
|
||||
public StructureModifier<ChatType> getChatTypes() {
|
||||
return structureModifier.<ChatType>withType(
|
||||
EnumWrappers.getChatTypeClass(), EnumWrappers.getChatTypeConverter());
|
||||
return structureModifier.withType(
|
||||
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
|
||||
*/
|
||||
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)
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
public PacketContainer deepClone() {
|
||||
Object clonedPacket = null;
|
||||
Object clonedPacket;
|
||||
|
||||
// Fall back on the alternative (but slower) method of reading and writing back the packet
|
||||
if (CLONING_UNSUPPORTED.contains(type)) {
|
||||
@ -1183,7 +1216,7 @@ public class PacketContainer implements Serializable {
|
||||
*/
|
||||
public void addMetadata(String key, Object value) {
|
||||
if (metadata == null) {
|
||||
metadata = new HashMap<String, Object>();
|
||||
metadata = new HashMap<>();
|
||||
}
|
||||
|
||||
metadata.put(key, value);
|
||||
@ -1259,13 +1292,13 @@ public class PacketContainer implements Serializable {
|
||||
final EquivalentConverter<ItemStack> stackConverter = BukkitConverters.getItemStackConverter();
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?>genericType, ItemStack[] specific) {
|
||||
public Object getGeneric(ItemStack[] specific) {
|
||||
Class<?> nmsStack = MinecraftReflection.getItemStackClass();
|
||||
Object[] result = (Object[]) Array.newInstance(nmsStack, specific.length);
|
||||
|
||||
// Unwrap every item
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = stackConverter.getGeneric(nmsStack, specific[i]);
|
||||
result[i] = stackConverter.getGeneric(specific[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1296,13 +1329,13 @@ public class PacketContainer implements Serializable {
|
||||
final EquivalentConverter<WrappedChatComponent> componentConverter = BukkitConverters.getWrappedChatComponentConverter();
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
||||
public Object getGeneric(WrappedChatComponent[] specific) {
|
||||
Class<?> nmsComponent = MinecraftReflection.getIChatBaseComponentClass();
|
||||
Object[] result = (Object[]) Array.newInstance(nmsComponent, specific.length);
|
||||
|
||||
// Unwrap every item
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = componentConverter.getGeneric(nmsComponent, specific[i]);
|
||||
result[i] = componentConverter.getGeneric(specific[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -1351,7 +1384,7 @@ public class PacketContainer implements Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
||||
public Object getGeneric(WrappedChatComponent[] specific) {
|
||||
NbtCompound compound = NbtFactory.ofCompound("");
|
||||
|
||||
for (int i = 0; i < lines; i++) {
|
||||
@ -1365,7 +1398,7 @@ public class PacketContainer implements Serializable {
|
||||
compound.put("Text" + (i + 1), component.getJson());
|
||||
}
|
||||
|
||||
return nbtConverter.getGeneric(genericType, compound);
|
||||
return nbtConverter.getGeneric(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1394,8 +1427,8 @@ public class PacketContainer implements Serializable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, WrappedChatComponent[] specific) {
|
||||
return DELEGATE.getGeneric(genericType, specific);
|
||||
public Object getGeneric(WrappedChatComponent[] specific) {
|
||||
return DELEGATE.getGeneric(specific);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -21,32 +21,12 @@ package com.comphenix.protocol.reflect;
|
||||
* Interface that converts generic objects into types and back.
|
||||
*
|
||||
* @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.
|
||||
* <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.
|
||||
* Due to type erasure, we need to explicitly keep a reference to 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()));
|
||||
|
||||
// Use the converter, if it exists
|
||||
Object obj = needConversion() ? converter.getGeneric(getFieldType(fieldIndex), value) : value;
|
||||
Object obj = needConversion() ? converter.getGeneric(value) : value;
|
||||
|
||||
try {
|
||||
FieldUtils.writeField(data.get(fieldIndex), target, obj, true);
|
||||
|
@ -113,24 +113,24 @@ public class BukkitCloner implements Cloner {
|
||||
return MinecraftReflection.getMinecraftItemStack(MinecraftReflection.getBukkitItemStack(source).clone());
|
||||
case 1:
|
||||
EquivalentConverter<WrappedDataWatcher> dataConverter = BukkitConverters.getDataWatcherConverter();
|
||||
return dataConverter.getGeneric(clonableClasses.get(1), dataConverter.getSpecific(source).deepClone());
|
||||
return dataConverter.getGeneric(dataConverter.getSpecific(source).deepClone());
|
||||
case 2:
|
||||
EquivalentConverter<BlockPosition> blockConverter = BlockPosition.getConverter();
|
||||
return blockConverter.getGeneric(clonableClasses.get(2), blockConverter.getSpecific(source));
|
||||
return blockConverter.getGeneric(blockConverter.getSpecific(source));
|
||||
case 3:
|
||||
EquivalentConverter<ChunkPosition> chunkConverter = ChunkPosition.getConverter();
|
||||
return chunkConverter.getGeneric(clonableClasses.get(3), chunkConverter.getSpecific(source));
|
||||
return chunkConverter.getGeneric(chunkConverter.getSpecific(source));
|
||||
case 4:
|
||||
EquivalentConverter<WrappedServerPing> serverConverter = BukkitConverters.getWrappedServerPingConverter();
|
||||
return serverConverter.getGeneric(clonableClasses.get(4), serverConverter.getSpecific(source).deepClone());
|
||||
return serverConverter.getGeneric(serverConverter.getSpecific(source).deepClone());
|
||||
case 5:
|
||||
return source;
|
||||
case 6:
|
||||
EquivalentConverter<MinecraftKey> keyConverter = MinecraftKey.getConverter();
|
||||
return keyConverter.getGeneric(clonableClasses.get(6), keyConverter.getSpecific(source));
|
||||
return keyConverter.getGeneric(keyConverter.getSpecific(source));
|
||||
case 7:
|
||||
EquivalentConverter<WrappedBlockData> blockDataConverter = BukkitConverters.getWrappedBlockDataConverter();
|
||||
return blockDataConverter.getGeneric(clonableClasses.get(7), blockDataConverter.getSpecific(source).deepClone());
|
||||
return blockDataConverter.getGeneric(blockDataConverter.getSpecific(source).deepClone());
|
||||
case 8:
|
||||
return nonNullListCloner().clone(source);
|
||||
default:
|
||||
|
@ -110,7 +110,7 @@ public abstract class CompiledStructureModifier extends StructureModifier<Object
|
||||
@Override
|
||||
public StructureModifier<Object> write(int index, Object value) throws FieldAccessException {
|
||||
if (converter != null)
|
||||
value = converter.getGeneric(getFieldType(index), value);
|
||||
value = converter.getGeneric(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() {
|
||||
return new EquivalentConverter<BlockPosition>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, BlockPosition specific) {
|
||||
public Object getGeneric(BlockPosition specific) {
|
||||
if (blockPositionConstructor == null) {
|
||||
try {
|
||||
blockPositionConstructor = MinecraftReflection.getBlockPositionClass().
|
||||
@ -187,7 +187,7 @@ public class BlockPosition {
|
||||
public BlockPosition getSpecific(Object generic) {
|
||||
if (MinecraftReflection.isBlockPosition(generic)) {
|
||||
// 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
|
||||
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() {
|
||||
return new EquivalentConverter<ChunkCoordIntPair>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, ChunkCoordIntPair specific) {
|
||||
public Object getGeneric(ChunkCoordIntPair specific) {
|
||||
if (COORD_CONSTRUCTOR == null) {
|
||||
COORD_CONSTRUCTOR = Accessors.getConstructorAccessor(COORD_PAIR_CLASS, int.class, int.class);
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ public class ChunkPosition {
|
||||
public static EquivalentConverter<ChunkPosition> getConverter() {
|
||||
return new EquivalentConverter<ChunkPosition>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, ChunkPosition specific) {
|
||||
public Object getGeneric(ChunkPosition specific) {
|
||||
if (chunkPositionConstructor == null) {
|
||||
try {
|
||||
chunkPositionConstructor = MinecraftReflection.getChunkPositionClass().
|
||||
@ -177,7 +177,7 @@ public class ChunkPosition {
|
||||
public ChunkPosition getSpecific(Object generic) {
|
||||
if (MinecraftReflection.isChunkPosition(generic)) {
|
||||
// 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
|
||||
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.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import org.bukkit.GameMode;
|
||||
|
||||
@ -562,117 +563,119 @@ public abstract class EnumWrappers {
|
||||
|
||||
// Get the converters
|
||||
public static EquivalentConverter<Protocol> getProtocolConverter() {
|
||||
return new EnumConverter<Protocol>(Protocol.class);
|
||||
return new EnumConverter<>(getProtocolClass(), Protocol.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<ClientCommand> getClientCommandConverter() {
|
||||
return new EnumConverter<ClientCommand>(ClientCommand.class);
|
||||
return new EnumConverter<>(getClientCommandClass(), ClientCommand.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<ChatVisibility> getChatVisibilityConverter() {
|
||||
return new EnumConverter<ChatVisibility>(ChatVisibility.class);
|
||||
return new EnumConverter<>(getChatVisibilityClass(), ChatVisibility.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<Difficulty> getDifficultyConverter() {
|
||||
return new EnumConverter<Difficulty>(Difficulty.class);
|
||||
return new EnumConverter<>(getDifficultyClass(), Difficulty.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<EntityUseAction> getEntityUseActionConverter() {
|
||||
return new EnumConverter<EntityUseAction>(EntityUseAction.class);
|
||||
return new EnumConverter<>(getEntityUseActionClass(), EntityUseAction.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<NativeGameMode> getGameModeConverter() {
|
||||
return new EnumConverter<NativeGameMode>(NativeGameMode.class);
|
||||
return new EnumConverter<>(getGameModeClass(), NativeGameMode.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<ResourcePackStatus> getResourcePackStatusConverter() {
|
||||
return new EnumConverter<ResourcePackStatus>(ResourcePackStatus.class);
|
||||
return new EnumConverter<>(getResourcePackStatusClass(), ResourcePackStatus.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<PlayerInfoAction> getPlayerInfoActionConverter() {
|
||||
return new EnumConverter<PlayerInfoAction>(PlayerInfoAction.class);
|
||||
return new EnumConverter<>(getPlayerInfoActionClass(), PlayerInfoAction.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<TitleAction> getTitleActionConverter() {
|
||||
return new EnumConverter<TitleAction>(TitleAction.class);
|
||||
return new EnumConverter<>(getTitleActionClass(), TitleAction.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<WorldBorderAction> getWorldBorderActionConverter() {
|
||||
return new EnumConverter<WorldBorderAction>(WorldBorderAction.class);
|
||||
return new EnumConverter<>(getWorldBorderActionClass(), WorldBorderAction.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<CombatEventType> getCombatEventTypeConverter() {
|
||||
return new EnumConverter<CombatEventType>(CombatEventType.class);
|
||||
return new EnumConverter<>(getCombatEventTypeClass(), CombatEventType.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<PlayerDigType> getPlayerDiggingActionConverter() {
|
||||
return new EnumConverter<PlayerDigType>(PlayerDigType.class);
|
||||
return new EnumConverter<>(getPlayerDigTypeClass(), PlayerDigType.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<PlayerAction> getEntityActionConverter() {
|
||||
return new EnumConverter<PlayerAction>(PlayerAction.class);
|
||||
return new EnumConverter<>(getPlayerActionClass(), PlayerAction.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<ScoreboardAction> getUpdateScoreActionConverter() {
|
||||
return new EnumConverter<ScoreboardAction>(ScoreboardAction.class);
|
||||
return new EnumConverter<>(getScoreboardActionClass(), ScoreboardAction.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<Particle> getParticleConverter() {
|
||||
return new EnumConverter<Particle>(Particle.class);
|
||||
return new EnumConverter<>(getParticleClass(), Particle.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<SoundCategory> getSoundCategoryConverter() {
|
||||
return new EnumConverter<SoundCategory>(SoundCategory.class);
|
||||
return new EnumConverter<>(getSoundCategoryClass(), SoundCategory.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<ItemSlot> getItemSlotConverter() {
|
||||
return new EnumConverter<ItemSlot>(ItemSlot.class);
|
||||
return new EnumConverter<>(getItemSlotClass(), ItemSlot.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<Hand> getHandConverter() {
|
||||
return new EnumConverter<Hand>(Hand.class);
|
||||
return new EnumConverter<>(getHandClass(), Hand.class);
|
||||
}
|
||||
|
||||
public static EquivalentConverter<Direction> getDirectionConverter() {
|
||||
return new EnumConverter<Direction>(Direction.class);
|
||||
return new EnumConverter<>(getDirectionClass(), Direction.class);
|
||||
}
|
||||
|
||||
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.
|
||||
* @param enumClass - Enum class
|
||||
* @param genericClass - Generic nms enum class
|
||||
* @param specificType - Specific enum class
|
||||
* @return A generic enum converter
|
||||
*/
|
||||
public static <T extends Enum<T>> EquivalentConverter<T> getGenericConverter(Class<T> enumClass) {
|
||||
return new EnumConverter<T>(enumClass);
|
||||
public static <T extends Enum<T>> EquivalentConverter<T> getGenericConverter(Class<?> genericClass, Class<T> specificType) {
|
||||
return new EnumConverter<>(genericClass, specificType);
|
||||
}
|
||||
|
||||
// The common enum converter
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public static class EnumConverter<T extends Enum<T>> implements EquivalentConverter<T> {
|
||||
private Class<?> genericType;
|
||||
private Class<T> specificType;
|
||||
|
||||
public EnumConverter(Class<T> specificType) {
|
||||
public EnumConverter(Class<?> genericType, Class<T> specificType) {
|
||||
this.genericType = genericType;
|
||||
this.specificType = specificType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getSpecific(Object generic) {
|
||||
// We know its an enum already!
|
||||
return Enum.valueOf(specificType, ((Enum) generic).name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, T specific) {
|
||||
public Object getGeneric(T specific) {
|
||||
return Enum.valueOf((Class) genericType, specific.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<T> getSpecificType() {
|
||||
return specificType;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ public class MinecraftKey {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MinecraftKey specific) {
|
||||
public Object getGeneric(MinecraftKey specific) {
|
||||
if (constructor == null) {
|
||||
try {
|
||||
constructor = MinecraftReflection.getMinecraftKeyClass().getConstructor(String.class, String.class);
|
||||
|
@ -190,7 +190,7 @@ public class MultiBlockChangeInfo {
|
||||
|
||||
@Override
|
||||
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);
|
||||
short location = shorts.read(0);
|
||||
@ -203,7 +203,7 @@ public class MultiBlockChangeInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MultiBlockChangeInfo specific) {
|
||||
public Object getGeneric(MultiBlockChangeInfo specific) {
|
||||
try {
|
||||
if (constructor == null) {
|
||||
constructor = nmsClass.getConstructor(
|
||||
@ -216,7 +216,7 @@ public class MultiBlockChangeInfo {
|
||||
return constructor.newInstance(
|
||||
null,
|
||||
specific.location,
|
||||
BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), specific.data)
|
||||
BukkitConverters.getWrappedBlockDataConverter().getGeneric(specific.data)
|
||||
);
|
||||
} catch (Throwable ex) {
|
||||
throw new RuntimeException("Failed to construct MultiBlockChangeInfo instance.", ex);
|
||||
@ -248,12 +248,12 @@ public class MultiBlockChangeInfo {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, MultiBlockChangeInfo[] specific) {
|
||||
public Object getGeneric(MultiBlockChangeInfo[] specific) {
|
||||
Object[] result = (Object[]) Array.newInstance(nmsClass, specific.length);
|
||||
|
||||
// Wrap every item
|
||||
for (int i = 0; i < result.length; i++) {
|
||||
result[i] = converter.getGeneric(nmsClass, specific[i]);
|
||||
result[i] = converter.getGeneric(specific[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -91,7 +91,7 @@ public class PlayerInfoData {
|
||||
public static EquivalentConverter<PlayerInfoData> getConverter() {
|
||||
return new EquivalentConverter<PlayerInfoData>() {
|
||||
@Override
|
||||
public Object getGeneric(Class<?> genericType, PlayerInfoData specific) {
|
||||
public Object getGeneric(PlayerInfoData specific) {
|
||||
if (constructor == null) {
|
||||
try {
|
||||
// public PlayerInfoData(Packet, GameProfile, int, GameMode, ChatComponent)
|
||||
@ -116,7 +116,7 @@ public class PlayerInfoData {
|
||||
null,
|
||||
specific.profile.handle,
|
||||
specific.latency,
|
||||
EnumWrappers.getGameModeConverter().getGeneric(EnumWrappers.getGameModeClass(), specific.gameMode),
|
||||
EnumWrappers.getGameModeConverter().getGeneric(specific.gameMode),
|
||||
specific.displayName != null ? specific.displayName.handle : null
|
||||
);
|
||||
return result;
|
||||
@ -128,7 +128,7 @@ public class PlayerInfoData {
|
||||
@Override
|
||||
public PlayerInfoData getSpecific(Object 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);
|
||||
|
||||
StructureModifier<WrappedGameProfile> gameProfiles = modifier.withType(
|
||||
|
@ -91,15 +91,14 @@ public class Vector3F {
|
||||
}
|
||||
|
||||
public static EquivalentConverter<Vector3F> getConverter() {
|
||||
return new IgnoreNullConverter<Vector3F>() {
|
||||
|
||||
return Converters.ignoreNull(new EquivalentConverter<Vector3F>() {
|
||||
@Override
|
||||
public Class<Vector3F> getSpecificType() {
|
||||
return Vector3F.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object getGenericValue(Class<?> genericType, Vector3F specific) {
|
||||
public Object getGeneric(Vector3F specific) {
|
||||
if (constructor == null) {
|
||||
try {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
return constructor.newInstance(specific.x, specific.y, specific.z);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
@ -116,7 +115,7 @@ public class Vector3F {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Vector3F getSpecificValue(Object generic) {
|
||||
public Vector3F getSpecific(Object generic) {
|
||||
StructureModifier<Float> modifier = new StructureModifier<Float>(generic.getClass())
|
||||
.withTarget(generic).withType(float.class);
|
||||
float x = modifier.read(0);
|
||||
@ -124,6 +123,6 @@ public class Vector3F {
|
||||
float z = modifier.read(2);
|
||||
return new Vector3F(x, y, z);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
@ -280,7 +280,7 @@ public class WrappedServerPing extends AbstractWrapper {
|
||||
public void setPlayers(Iterable<? extends WrappedGameProfile> profile) {
|
||||
if (players == null)
|
||||
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) {
|
||||
return ((WrappedChatComponent) wrapped).getHandle();
|
||||
} else if (wrapped instanceof ItemStack) {
|
||||
return BukkitConverters.getItemStackConverter().getGeneric(MinecraftReflection.getItemStackClass(), (ItemStack) wrapped);
|
||||
return BukkitConverters.getItemStackConverter().getGeneric((ItemStack) wrapped);
|
||||
} else if (wrapped instanceof WrappedBlockData) {
|
||||
return BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), (WrappedBlockData) wrapped);
|
||||
return BukkitConverters.getWrappedBlockDataConverter().getGeneric((WrappedBlockData) wrapped);
|
||||
} else if (wrapped instanceof Vector3F) {
|
||||
return Vector3F.getConverter().getGeneric(Vector3F.getMinecraftClass(), (Vector3F) wrapped);
|
||||
return Vector3F.getConverter().getGeneric((Vector3F) wrapped);
|
||||
} else if (wrapped instanceof BlockPosition) {
|
||||
return BlockPosition.getConverter().getGeneric(MinecraftReflection.getBlockPositionClass(), (BlockPosition) wrapped);
|
||||
return BlockPosition.getConverter().getGeneric((BlockPosition) wrapped);
|
||||
} else if (wrapped instanceof Direction) {
|
||||
return EnumWrappers.getDirectionConverter().getGeneric(EnumWrappers.getDirectionClass(), (Direction) wrapped);
|
||||
return EnumWrappers.getDirectionConverter().getGeneric((Direction) wrapped);
|
||||
} else if (wrapped instanceof NbtCompound) {
|
||||
return NbtFactory.fromBase((NbtCompound) wrapped).getHandle();
|
||||
}
|
||||
|
||||
// Legacy classes
|
||||
if (wrapped instanceof ChunkPosition) {
|
||||
return ChunkPosition.getConverter().getGeneric(MinecraftReflection.getChunkPositionClass(), (ChunkPosition) wrapped);
|
||||
return ChunkPosition.getConverter().getGeneric((ChunkPosition) wrapped);
|
||||
} else if (wrapped instanceof WrappedChunkCoordinate) {
|
||||
return ((WrappedChunkCoordinate) wrapped).getHandle();
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ public class BukkitInitialization {
|
||||
try {
|
||||
LogManager.getLogger();
|
||||
} catch (Throwable ex) {
|
||||
// Happens only on my Jenkins, but if it errors here it works when it matters
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
@ -69,6 +70,7 @@ public class BukkitInitialization {
|
||||
try {
|
||||
LogManager.getLogger();
|
||||
} catch (Throwable ex) {
|
||||
// Happens only on my Jenkins, but if it errors here it works when it matters
|
||||
ex.printStackTrace();
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@ public class ChunkCoordIntPairTest {
|
||||
|
||||
net.minecraft.server.v1_12_R1.ChunkCoordIntPair roundtrip =
|
||||
(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(2, roundtrip.z);
|
||||
|
@ -55,7 +55,6 @@ public class EnumWrappersTest {
|
||||
FieldAccessor accessor = Accessors.getFieldAccessor(target.getClass(), fieldName, true);
|
||||
|
||||
return (T) converter.getGeneric(
|
||||
accessor.getField().getType(),
|
||||
converter.getSpecific(accessor.get(target))
|
||||
);
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ public class MultiBlockChangeTest {
|
||||
MultiBlockChangeInfo[] array = { info, info };
|
||||
|
||||
EquivalentConverter<MultiBlockChangeInfo[]> converter = MultiBlockChangeInfo.getArrayConverter(chunk);
|
||||
Object generic = converter.getGeneric(MinecraftReflection.getMultiBlockChangeInfoArrayClass(), array);
|
||||
Object generic = converter.getGeneric(array);
|
||||
MultiBlockChangeInfo[] back = converter.getSpecific(generic);
|
||||
|
||||
// Make sure our conversions are correct
|
||||
|
@ -43,7 +43,7 @@ public class PlayerInfoDataTest {
|
||||
WrappedChatComponent displayName = WrappedChatComponent.fromText("Name's Name");
|
||||
|
||||
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);
|
||||
|
||||
assertEquals(data, back);
|
||||
|
@ -47,7 +47,7 @@ public class WrappedBlockDataTest {
|
||||
assertEquals(wrapper.getType(), type);
|
||||
assertEquals(wrapper.getData(), data);
|
||||
|
||||
Object generic = BukkitConverters.getWrappedBlockDataConverter().getGeneric(MinecraftReflection.getIBlockDataClass(), wrapper);
|
||||
Object generic = BukkitConverters.getWrappedBlockDataConverter().getGeneric(wrapper);
|
||||
WrappedBlockData back = BukkitConverters.getWrappedBlockDataConverter().getSpecific(generic);
|
||||
|
||||
assertEquals(wrapper.getType(), back.getType());
|
||||
|
4
pom.xml
4
pom.xml
@ -8,7 +8,7 @@
|
||||
|
||||
<properties>
|
||||
<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>
|
||||
</properties>
|
||||
|
||||
@ -45,7 +45,7 @@
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<!-- Compile with the old version of Netty -->
|
||||
<!-- Compile with the old version of Netty for backwards compat -->
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-all</artifactId>
|
||||
|
Loading…
Reference in New Issue
Block a user