Fix invalid serializer for empty optionals, add serializer to MetaIndex and require for all datawatcher objects constructions
This commit is contained in:
		| @@ -112,7 +112,7 @@ public class FlagWatcher { | ||||
|  | ||||
|                 boolean isDirty = watch.getDirtyState(); | ||||
|  | ||||
|                 watch = ReflectionManager.createWatchable(id, value); | ||||
|                 watch = ReflectionManager.createWatchable(MetaIndex.getMetaIndex(this, id), value); | ||||
|  | ||||
|                 if (watch == null) | ||||
|                     continue; | ||||
| @@ -123,7 +123,7 @@ public class FlagWatcher { | ||||
|             } else { | ||||
|                 boolean isDirty = watch.getDirtyState(); | ||||
|  | ||||
|                 watch = ReflectionManager.createWatchable(id, watch.getValue()); | ||||
|                 watch = ReflectionManager.createWatchable(MetaIndex.getMetaIndex(this, id), watch.getValue()); | ||||
|  | ||||
|                 if (watch == null) | ||||
|                     continue; | ||||
| @@ -149,7 +149,8 @@ public class FlagWatcher { | ||||
|                     continue; | ||||
|                 } | ||||
|  | ||||
|                 WrappedWatchableObject watch = ReflectionManager.createWatchable(id, value); | ||||
|                 WrappedWatchableObject watch = ReflectionManager | ||||
|                         .createWatchable(MetaIndex.getMetaIndex(this, id), value); | ||||
|  | ||||
|                 if (watch == null) | ||||
|                     continue; | ||||
| @@ -317,9 +318,10 @@ public class FlagWatcher { | ||||
|             WrappedWatchableObject watchable; | ||||
|  | ||||
|             if (entityValues.containsKey(i) && entityValues.get(i) != null) { | ||||
|                 watchable = ReflectionManager.createWatchable(i, entityValues.get(i)); | ||||
|                 watchable = ReflectionManager.createWatchable(MetaIndex.getMetaIndex(this, i), entityValues.get(i)); | ||||
|             } else if (backupEntityValues.containsKey(i) && backupEntityValues.get(i) != null) { | ||||
|                 watchable = ReflectionManager.createWatchable(i, backupEntityValues.get(i)); | ||||
|                 watchable = ReflectionManager | ||||
|                         .createWatchable(MetaIndex.getMetaIndex(this, i), backupEntityValues.get(i)); | ||||
|             } else { | ||||
|                 continue; | ||||
|             } | ||||
| @@ -354,7 +356,7 @@ public class FlagWatcher { | ||||
|                         WrappedDataWatcher.getEntityWatcher(disguise.getEntity()).getByte(0)); | ||||
|             } | ||||
|  | ||||
|             WrappedWatchableObject watch = ReflectionManager.createWatchable(data.getIndex(), value); | ||||
|             WrappedWatchableObject watch = ReflectionManager.createWatchable(data, value); | ||||
|  | ||||
|             if (watch == null) | ||||
|                 continue; | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import com.comphenix.protocol.wrappers.nbt.NbtFactory; | ||||
| import com.comphenix.protocol.wrappers.nbt.NbtType; | ||||
| import me.libraryaddict.disguise.disguisetypes.watchers.*; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import org.bukkit.Color; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.Particle; | ||||
| @@ -657,6 +658,15 @@ public class MetaIndex<Y> { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param watcher - A FlagWatcher class | ||||
|      * @param flagNo  - The meta index number | ||||
|      * @return The MetaIndex which corresponds to that FlagWatcher at that index | ||||
|      */ | ||||
|     public static MetaIndex getMetaIndex(FlagWatcher watcher, int flagNo) { | ||||
|         return getMetaIndex(watcher.getClass(), flagNo); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * @param watcherClass - A FlagWatcher class | ||||
|      * @param flagNo       - The meta index number | ||||
| @@ -793,6 +803,8 @@ public class MetaIndex<Y> { | ||||
|  | ||||
|                 _values = Arrays.copyOf(_values, _values.length + 1); | ||||
|                 _values[_values.length - 1] = index; | ||||
|  | ||||
|                 index.serializer = DisguiseUtilities.getSerializer(index); | ||||
|             } | ||||
|         } | ||||
|         catch (Exception e) { | ||||
| @@ -823,6 +835,7 @@ public class MetaIndex<Y> { | ||||
|     private Y _defaultValue; | ||||
|     private int _index; | ||||
|     private Class<? extends FlagWatcher> _watcher; | ||||
|     private WrappedDataWatcher.Serializer serializer; | ||||
|  | ||||
|     public MetaIndex(Class<? extends FlagWatcher> watcher, int index, Y defaultValue) { | ||||
|         _index = index; | ||||
| @@ -834,6 +847,13 @@ public class MetaIndex<Y> { | ||||
|         return _defaultValue; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Used for serializing values to a packet stream | ||||
|      */ | ||||
|     public WrappedDataWatcher.Serializer getSerializer() { | ||||
|         return serializer; | ||||
|     } | ||||
|  | ||||
|     public Class<? extends FlagWatcher> getFlagWatcher() { | ||||
|         return _watcher; | ||||
|     } | ||||
|   | ||||
| @@ -28,10 +28,7 @@ import me.libraryaddict.disguise.utilities.reflection.LibsProfileLookup; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| import me.libraryaddict.disguise.utilities.translations.LibsMsg; | ||||
| import org.apache.logging.log4j.util.Strings; | ||||
| import org.bukkit.Bukkit; | ||||
| import org.bukkit.Location; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.World; | ||||
| import org.bukkit.*; | ||||
| import org.bukkit.block.BlockFace; | ||||
| import org.bukkit.craftbukkit.libs.org.apache.commons.io.FileUtils; | ||||
| import org.bukkit.entity.*; | ||||
| @@ -920,8 +917,7 @@ public class DisguiseUtilities { | ||||
|             Field cSection = chunkClass.getDeclaredField("sections"); | ||||
|             cSection.setAccessible(true); | ||||
|  | ||||
|             Object chunkSection = ReflectionManager.getNmsClass("ChunkSection").getConstructor(int.class) | ||||
|                     .newInstance(0); | ||||
|             Object chunkSection = ReflectionManager.getNmsClass("ChunkSection").getConstructor(int.class).newInstance(0); | ||||
|  | ||||
|             Class blockClass = ReflectionManager.getNmsClass("Block"); | ||||
|             Object REGISTRY = ReflectionManager.getNmsField("IRegistry", "BLOCK").get(null); | ||||
| @@ -1036,8 +1032,7 @@ public class DisguiseUtilities { | ||||
|                 Set trackedPlayers = (Set) ReflectionManager.getNmsField("EntityTrackerEntry", "trackedPlayers") | ||||
|                         .get(entityTrackerEntry); | ||||
|  | ||||
|                 Method clear = ReflectionManager | ||||
|                         .getNmsMethod("EntityTrackerEntry", "a", ReflectionManager.getNmsClass("EntityPlayer")); | ||||
|                 Method clear = ReflectionManager.getNmsMethod("EntityTrackerEntry", "a", ReflectionManager.getNmsClass("EntityPlayer")); | ||||
|  | ||||
|                 final Method updatePlayer = ReflectionManager | ||||
|                         .getNmsMethod("EntityTrackerEntry", "b", ReflectionManager.getNmsClass("EntityPlayer")); | ||||
| @@ -1733,6 +1728,44 @@ public class DisguiseUtilities { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public static WrappedDataWatcher.Serializer getSerializer(MetaIndex index) { | ||||
|         if (index.getSerializer() != null) { | ||||
|             return index.getSerializer(); | ||||
|         } | ||||
|  | ||||
|         if (index.getDefault() instanceof Optional) { | ||||
|             for (Field f : MetaIndex.class.getFields()) { | ||||
|                 try { | ||||
|                     if (f.get(null) != index) { | ||||
|                         continue; | ||||
|                     } | ||||
|                 } | ||||
|                 catch (IllegalAccessException e) { | ||||
|                     e.printStackTrace(); | ||||
|                 } | ||||
|  | ||||
|                 Type type = f.getGenericType(); | ||||
|                 Type opt = ((ParameterizedType) type).getActualTypeArguments()[0]; | ||||
|  | ||||
|                 if (opt instanceof ParameterizedType) { | ||||
|                     Type val = ((ParameterizedType) opt).getActualTypeArguments()[0]; | ||||
|  | ||||
|                     return WrappedDataWatcher.Registry.get(ReflectionManager.getNmsClass((Class) val), true); | ||||
|                 } | ||||
|             } | ||||
|         } else { | ||||
|             return WrappedDataWatcher.Registry.get(ReflectionManager.getNmsClass(index.getDefault().getClass())); | ||||
|         } | ||||
|  | ||||
|         Object value = index.getDefault(); | ||||
|  | ||||
|         throw new IllegalArgumentException("Unable to find Serializer for " + value + | ||||
|                 (value instanceof Optional && ((Optional) value).isPresent() ? | ||||
|                         " (" + ((Optional) value).get().getClass().getName() + ")" : | ||||
|                         value instanceof Optional || value == null ? "" : " " + value.getClass().getName()) + | ||||
|                 "! Are you running " + "the latest " + "version of " + "ProtocolLib?"); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Create a new datawatcher but with the 'correct' values | ||||
|      */ | ||||
| @@ -1753,7 +1786,8 @@ public class DisguiseUtilities { | ||||
|                     continue; | ||||
|  | ||||
|                 WrappedDataWatcher.WrappedDataWatcherObject obj = ReflectionManager | ||||
|                         .createDataWatcherObject(watchableObject.getIndex(), watchableObject.getValue()); | ||||
|                         .createDataWatcherObject(MetaIndex.getMetaIndex(disguiseWatcher, watchableObject.getIndex()), | ||||
|                                 watchableObject.getValue()); | ||||
|  | ||||
|                 newWatcher.setObject(obj, watchableObject.getValue()); | ||||
|             } | ||||
|   | ||||
| @@ -6,6 +6,7 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher; | ||||
| import com.comphenix.protocol.wrappers.WrappedWatchableObject; | ||||
| import me.libraryaddict.disguise.DisguiseConfig; | ||||
| import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.MetaIndex; | ||||
| import me.libraryaddict.disguise.utilities.packets.IPacketHandler; | ||||
| import me.libraryaddict.disguise.utilities.packets.LibsPackets; | ||||
| import me.libraryaddict.disguise.utilities.reflection.ReflectionManager; | ||||
| @@ -56,7 +57,7 @@ public class PacketHandlerEquipment implements IPacketHandler { | ||||
|  | ||||
|                 if (DisguiseConfig.isMetadataPacketsEnabled()) { | ||||
|                     WrappedWatchableObject watch = ReflectionManager | ||||
|                             .createWatchable(0, WrappedDataWatcher.getEntityWatcher(entity).getByte(0)); | ||||
|                             .createWatchable(MetaIndex.ENTITY_META, WrappedDataWatcher.getEntityWatcher(entity).getByte(0)); | ||||
|  | ||||
|                     if (watch != null) | ||||
|                         list.add(watch); | ||||
|   | ||||
| @@ -12,6 +12,7 @@ import com.comphenix.protocol.wrappers.WrappedWatchableObject; | ||||
| import me.libraryaddict.disguise.DisguiseAPI; | ||||
| import me.libraryaddict.disguise.LibsDisguises; | ||||
| import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.MetaIndex; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||
| import me.libraryaddict.disguise.utilities.packets.LibsPackets; | ||||
| import me.libraryaddict.disguise.utilities.packets.PacketsManager; | ||||
| @@ -140,7 +141,7 @@ public class PacketListenerViewSelfDisguise extends PacketAdapter { | ||||
|                 if (observer.isSprinting()) | ||||
|                     b = (byte) (b | 1 << 3); | ||||
|  | ||||
|                 WrappedWatchableObject watch = ReflectionManager.createWatchable(0, b); | ||||
|                 WrappedWatchableObject watch = ReflectionManager.createWatchable(MetaIndex.ENTITY_META, b); | ||||
|  | ||||
|                 if (watch != null) | ||||
|                     watchableList.add(watch); | ||||
|   | ||||
| @@ -13,6 +13,7 @@ import com.mojang.datafixers.Dynamic; | ||||
| import me.libraryaddict.disguise.DisguiseConfig; | ||||
| import me.libraryaddict.disguise.disguisetypes.DisguiseType; | ||||
| import me.libraryaddict.disguise.disguisetypes.EntityPose; | ||||
| import me.libraryaddict.disguise.disguisetypes.MetaIndex; | ||||
| import me.libraryaddict.disguise.disguisetypes.VillagerData; | ||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||
| import net.minecraft.server.v1_14_R1.IRegistry; | ||||
| @@ -26,6 +27,7 @@ import org.bukkit.entity.*; | ||||
| import org.bukkit.inventory.EquipmentSlot; | ||||
| import org.bukkit.inventory.ItemStack; | ||||
| import org.bukkit.potion.PotionEffect; | ||||
| import org.bukkit.util.EulerAngle; | ||||
| import org.bukkit.util.Vector; | ||||
|  | ||||
| import java.io.IOException; | ||||
| @@ -836,6 +838,32 @@ public class ReflectionManager { | ||||
|         return null; | ||||
|     } | ||||
|  | ||||
|     public static Class getNmsClass(Class cl) { | ||||
|         if (VillagerData.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("VillagerData"); | ||||
|         } else if (BlockPosition.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("BlockPosition"); | ||||
|         } else if (WrappedBlockData.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("IBlockData"); | ||||
|         } else if (ItemStack.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("ItemStack"); | ||||
|         } else if (WrappedChatComponent.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("IChatBaseComponent"); | ||||
|         } else if (Vector3F.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("Vector3f"); | ||||
|         } else if (Direction.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("EnumDirection"); | ||||
|         } else if (WrappedParticle.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("ParticleParam"); | ||||
|         } else if (EntityPose.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("EntityPose"); | ||||
|         } else if (NbtWrapper.class.isAssignableFrom(cl)) { | ||||
|             return getNmsClass("NBTTagCompound"); | ||||
|         } | ||||
|  | ||||
|         return cl; | ||||
|     } | ||||
|  | ||||
|     public static Object convertInvalidMeta(Object value) { | ||||
|         if (value instanceof Optional) { | ||||
|             Optional opt = (Optional) value; | ||||
| @@ -972,52 +1000,13 @@ public class ReflectionManager { | ||||
|         return version; | ||||
|     } | ||||
|  | ||||
|     public static WrappedDataWatcherObject createDataWatcherObject(int id, Object value) { | ||||
|     public static WrappedDataWatcherObject createDataWatcherObject(MetaIndex index, Object value) { | ||||
|         if (value == null) | ||||
|             return null; | ||||
|  | ||||
|         value = convertInvalidMeta(value); | ||||
|  | ||||
|         Serializer serializer; | ||||
|  | ||||
|         if (value instanceof Optional) { | ||||
|             Optional opt = (Optional) value; | ||||
|  | ||||
|             if (opt.isPresent()) { | ||||
|                 Object val = opt.get(); | ||||
|                 Class cl; | ||||
|                 Class iBlockData = getNmsClass("IBlockData"); | ||||
|                 Class iChat = getNmsClass("IChatBaseComponent"); | ||||
|  | ||||
|                 if (iBlockData.isInstance(val)) { | ||||
|                     cl = iBlockData; | ||||
|                 } else if (iChat.isInstance(val)) { | ||||
|                     cl = iChat; | ||||
|                 } else { | ||||
|                     cl = val.getClass(); | ||||
|                 } | ||||
|  | ||||
|                 serializer = Registry.get(cl, true); | ||||
|             } else { | ||||
|                 serializer = Registry.get(UUID.class, true); | ||||
|             } | ||||
|         } else { | ||||
|             serializer = Registry.get(getNmsClass("ParticleParam").isInstance(value) ? getNmsClass("ParticleParam") : | ||||
|                     value.getClass()); | ||||
|         } | ||||
|  | ||||
|         if (serializer == null) { | ||||
|             if (value.getClass().getSimpleName().equals("NBTTagCompound")) | ||||
|                 return null; // Handle PaperSpigot's bad coding | ||||
|  | ||||
|             throw new IllegalArgumentException("Unable to find Serializer for " + value + | ||||
|                     (value instanceof Optional && ((Optional) value).isPresent() ? | ||||
|                             " (" + ((Optional) value).get().getClass().getName() + ")" : | ||||
|                             value instanceof Optional || value == null ? "" : " " + value.getClass().getName()) + | ||||
|                     "! Are you running " + "the latest " + "version of " + "ProtocolLib?"); | ||||
|         } | ||||
|  | ||||
|         return new WrappedDataWatcherObject(id, serializer); | ||||
|         return new WrappedDataWatcherObject(index.getIndex(), index.getSerializer()); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -1027,7 +1016,7 @@ public class ReflectionManager { | ||||
|      * @param value | ||||
|      * @return | ||||
|      */ | ||||
|     public static Object createDataWatcherItem(int id, Object value) { | ||||
|     public static Object createDataWatcherItem(MetaIndex id, Object value) { | ||||
|         WrappedDataWatcherObject watcherObject = createDataWatcherObject(id, value); | ||||
|  | ||||
|         Constructor construct = getNmsConstructor("DataWatcher$Item", getNmsClass("DataWatcherObject"), Object.class); | ||||
| @@ -1106,7 +1095,7 @@ public class ReflectionManager { | ||||
|         return EntityPose.valueOf(((Enum) nmsEntityPose).name()); | ||||
|     } | ||||
|  | ||||
|     public static WrappedWatchableObject createWatchable(int index, Object obj) { | ||||
|     public static WrappedWatchableObject createWatchable(MetaIndex index, Object obj) { | ||||
|         Object watcherItem = createDataWatcherItem(index, obj); | ||||
|  | ||||
|         if (watcherItem == null) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user