/** * Retrieves a read/write structure for collections of chunk positions. * * <p>This modifier will automatically marshall between the visible ProtocolLib ChunkPosition and * the internal Minecraft ChunkPosition. * * @return A modifier for ChunkPosition list fields. */ public StructureModifier<List<ChunkPosition>> getPositionCollectionModifier() { // Convert to and from the ProtocolLib wrapper return structureModifier.withType( Collection.class, BukkitConverters.getListConverter( MinecraftReflection.getChunkPositionClass(), ChunkPosition.getConverter())); }
private void readObject(ObjectInputStream input) throws ClassNotFoundException, IOException { // Default deserialization input.defaultReadObject(); // Get structure modifier structureModifier = StructureCache.getStructure(id); // Don't read NULL packets if (input.readBoolean()) { // Create a default instance of the packet handle = StructureCache.newPacket(id); // Call the read method try { getMethodLazily(readMethods, handle.getClass(), "read", DataInputStream.class) .invoke(handle, new DataInputStream(input)); } catch (IllegalArgumentException e) { throw new IOException("Minecraft packet doesn't support DataInputStream", e); } catch (IllegalAccessException e) { throw new RuntimeException("Insufficient security privileges.", e); } catch (InvocationTargetException e) { throw new IOException("Could not deserialize Minecraft packet.", e); } // And we're done structureModifier = structureModifier.withTarget(handle); } }
/** * Retrieves a read/write structure for collections of watchable objects. * * <p>This modifier will automatically marshall between the visible WrappedWatchableObject and the * internal Minecraft WatchableObject. * * @return A modifier for watchable object list fields. */ public StructureModifier<List<WrappedWatchableObject>> getWatchableCollectionModifier() { // Convert to and from the ProtocolLib wrapper return structureModifier.withType( Collection.class, BukkitConverters.getListConverter( MinecraftReflection.getWatchableObjectClass(), BukkitConverters.getWatchableObjectConverter())); }
/** * Retrieve a structure modifier that automatically marshalls between NBT wrappers and their NMS * counterpart. * * @param stack - the stack that will store the NBT compound. * @return The structure modifier. */ private static StructureModifier<NbtBase<?>> getStackModifier(ItemStack stack) { Object nmsStack = MinecraftReflection.getMinecraftItemStack(stack); if (itemStackModifier == null) { itemStackModifier = new StructureModifier<Object>(nmsStack.getClass(), Object.class, false); } // Use the first and best NBT tag return itemStackModifier .withTarget(nmsStack) .withType(MinecraftReflection.getNBTBaseClass(), BukkitConverters.getNbtConverter()); }
@Override public void onPacketSending(PacketEvent event) { if (!event.isCancelled() && event.getPacketID() == Packets.Server.NAMED_ENTITY_SPAWN) { PacketContainer packet = event.getPacket(); StructureModifier<String> text = packet.getSpecificModifier(String.class); try { String tag = text.read(0); Player observer = event.getPlayer(); Entity watched = packet.getEntityModifier(observer.getWorld()).read(0); if (watched instanceof Player) { ReceiveNameTagEvent nameTagEvent = new ReceiveNameTagEvent(event.getPlayer(), (Player) watched, tag); pluginManager.callEvent(nameTagEvent); if (nameTagEvent.isModified()) { // Trim excess tag = nameTagEvent.getTrimmedTag(); // Uh, ok. if (tag == null) tag = ""; text.write(0, tag); } } else { // Might as well notify about this logger.log( Level.WARNING, "Cannot find entity id " + packet.getSpecificModifier(int.class).read(0)); } } catch (FieldAccessException e) { logger.log(Level.SEVERE, "Cannot read field.", e); } } }
/** * Retrieves a read/write structure for arrays of ItemStacks. * * <p>This modifier will automatically marshall between the Bukkit ItemStack and the internal * Minecraft ItemStack. * * @return A modifier for ItemStack array fields. */ public StructureModifier<ItemStack[]> getItemArrayModifier() { final EquivalentConverter<ItemStack> stackConverter = BukkitConverters.getItemStackConverter(); // Convert to and from the Bukkit wrapper return structureModifier.<ItemStack[]>withType( MinecraftReflection.getItemStackArrayClass(), BukkitConverters.getIgnoreNull( new EquivalentConverter<ItemStack[]>() { public Object getGeneric(Class<?> genericType, 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]); } return result; } @Override public ItemStack[] getSpecific(Object generic) { Object[] input = (Object[]) generic; ItemStack[] result = new ItemStack[input.length]; // Add the wrapper for (int i = 0; i < result.length; i++) { result[i] = stackConverter.getSpecific(input[i]); } return result; } @Override public Class<ItemStack[]> getSpecificType() { return ItemStack[].class; } })); }
/** * Retrieves a read/write structure for every short field. * * @return A modifier for every short field. */ public StructureModifier<Short> getShorts() { return structureModifier.withType(short.class); }
/** * Retrieves a read/write structure for every integer field. * * @return A modifier for every integer field. */ public StructureModifier<Integer> getIntegers() { return structureModifier.withType(int.class); }
/** * Retrieves a read/write structure for NBT classes. * * @return A modifier for NBT classes. */ public StructureModifier<NbtBase<?>> getNbtModifier() { // Allow access to the NBT class in packet 130 return structureModifier.withType( MinecraftReflection.getNBTBaseClass(), BukkitConverters.getNbtConverter()); }
/** * Retrieves a read/write structure for chunk positions. * * @return A modifier for a ChunkPosition. */ public StructureModifier<ChunkPosition> getPositionModifier() { // Convert to and from the Bukkit wrapper return structureModifier.withType( MinecraftReflection.getChunkPositionClass(), ChunkPosition.getConverter()); }
/** * Retrieves a read/write structure for entity objects. * * <p>Note that entities are transmitted by integer ID, and the type may not be enough to * distinguish between entities and other values. Thus, this structure modifier MAY return null or * invalid entities for certain fields. Using the correct index is essential. * * @return A modifier entity types. */ public StructureModifier<Entity> getEntityModifier(World world) { // Convert to and from the Bukkit wrapper return structureModifier.<Entity>withType( int.class, BukkitConverters.getEntityConverter(world)); }
/** * Retrieves a read/write structure for data watchers. * * @return A modifier for data watchers. */ public StructureModifier<WrappedDataWatcher> getDataWatcherModifier() { // Convert to and from the Bukkit wrapper return structureModifier.<WrappedDataWatcher>withType( MinecraftReflection.getDataWatcherClass(), BukkitConverters.getDataWatcherConverter()); }
/** * Retrieves a read/write structure for every float field. * * @return A modifier for every float field. */ public StructureModifier<Float> getFloat() { return structureModifier.withType(float.class); }
/** * Retrieves a read/write structure for ItemStack. * * <p>This modifier will automatically marshall between the Bukkit ItemStack and the internal * Minecraft ItemStack. * * @return A modifier for ItemStack fields. */ public StructureModifier<ItemStack> getItemModifier() { // Convert to and from the Bukkit wrapper return structureModifier.<ItemStack>withType( MinecraftReflection.getItemStackClass(), BukkitConverters.getItemStackConverter()); }
/** * Retrieves a read/write structure for every byte array field. * * @return A modifier for every byte array field. */ public StructureModifier<byte[]> getByteArrays() { return structureModifier.withType(byte[].class); }
/** * Retrieves a read/write structure for every field with the given type. * * @param primitiveType - the type to find. * @return A modifier for this specific type. */ public <T> StructureModifier<T> getSpecificModifier(Class<T> primitiveType) { return structureModifier.withType(primitiveType); }
/** * Retrieves a read/write structure for every String array field. * * @return A modifier for every String array field. */ public StructureModifier<String[]> getStringArrays() { return structureModifier.withType(String[].class); }
/** * Retrieves a read/write structure for every String field. * * @return A modifier for every String field. */ public StructureModifier<String> getStrings() { return structureModifier.withType(String.class); }
/** * Retrieves a read/write structure for every double field. * * @return A modifier for every double field. */ public StructureModifier<Double> getDoubles() { return structureModifier.withType(double.class); }
/** * Retrieves a read/write structure for every byte field. * * @return A modifier for every byte field. */ public StructureModifier<Byte> getBytes() { return structureModifier.withType(byte.class); }
/** * Retrieves a read/write structure for the world type enum. * * <p>This modifier will automatically marshall between the Bukkit world type and the internal * Minecraft world type. * * @return A modifier for world type fields. */ public StructureModifier<WorldType> getWorldTypeModifier() { // Convert to and from the Bukkit wrapper return structureModifier.<WorldType>withType( MinecraftReflection.getWorldTypeClass(), BukkitConverters.getWorldTypeConverter()); }
/** * Retrieves a read/write structure for every int array field. * * @return A modifier for every int array field. */ public StructureModifier<int[]> getIntegerArrays() { return structureModifier.withType(int[].class); }
/** * Retrieves a read/write structure for every long field. * * @return A modifier for every long field. */ public StructureModifier<Long> getLongs() { return structureModifier.withType(long.class); }