diff --git a/src/me/libraryaddict/disguise/disguisetypes/watchers/VillagerWatcher.java b/src/me/libraryaddict/disguise/disguisetypes/watchers/VillagerWatcher.java index a87235f2..7eaa2866 100644 --- a/src/me/libraryaddict/disguise/disguisetypes/watchers/VillagerWatcher.java +++ b/src/me/libraryaddict/disguise/disguisetypes/watchers/VillagerWatcher.java @@ -17,12 +17,12 @@ public class VillagerWatcher extends AgeableWatcher { return Profession.values()[(Integer) getValue(16, 0)]; } - public void setProfession(Profession newProfession) { - setProfession(newProfession.getId()); - } - public void setProfession(int professionId){ setValue(16, professionId % 6); sendData(16); } + + public void setProfession(Profession newProfession) { + setProfession(newProfession.getId()); + } } diff --git a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java index 072e43c5..3a344ce0 100644 --- a/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java +++ b/src/me/libraryaddict/disguise/utilities/DisguiseUtilities.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.List; import java.util.UUID; import java.util.regex.Pattern; @@ -16,9 +17,12 @@ import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.DisguiseType; +import me.libraryaddict.disguise.disguisetypes.FlagWatcher; import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; +import me.libraryaddict.disguise.disguisetypes.watchers.EndermanWatcher; +import me.libraryaddict.disguise.disguisetypes.watchers.ItemFrameWatcher; import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion; @@ -41,6 +45,7 @@ import com.comphenix.protocol.ProtocolManager; import com.comphenix.protocol.events.PacketContainer; import com.comphenix.protocol.wrappers.WrappedDataWatcher; import com.comphenix.protocol.wrappers.WrappedGameProfile; +import com.comphenix.protocol.wrappers.WrappedWatchableObject; public class DisguiseUtilities { /** @@ -460,6 +465,65 @@ public class DisguiseUtilities { return ReflectionManager.getSkullBlob(gameprofile); } + public static List rebuildForVersion(Player player, FlagWatcher watcher, + List list) { + if (!ReflectionManager.is1_8(player)) + return list; + ArrayList rebuiltList = new ArrayList(); + ArrayList backups = new ArrayList(); + // TODO Player and Minecart + for (WrappedWatchableObject obj : list) { + if (obj.getValue().getClass().getName().startsWith("org.")) { + backups.add(obj); + continue; + } + switch (obj.getIndex()) { + case 2: + case 3: + if (watcher instanceof ItemFrameWatcher) { + rebuiltList.add(new WrappedWatchableObject(obj.getIndex() + 6, obj.getValue())); + } else { + backups.add(obj); + } + break; + case 10: + case 11: + rebuiltList.add(new WrappedWatchableObject(obj.getIndex() - 8, obj.getValue())); + break; + case 12: + if (watcher instanceof AgeableWatcher) { + int i = (Integer) obj.getValue(); + rebuiltList.add(new WrappedWatchableObject(obj.getIndex(), (byte) (i < 0 ? -1 : (i >= 6000 ? 1 : 0)))); + } else { + backups.add(obj); + } + break; + case 16: + if (watcher instanceof EndermanWatcher) { + rebuiltList.add(new WrappedWatchableObject(obj.getIndex(), ((Short) obj.getValue()).byteValue())); + } else { + backups.add(obj); + } + break; + default: + backups.add(obj); + break; + } + } + Iterator itel = backups.iterator(); + while (itel.hasNext()) { + int index = itel.next().getIndex(); + for (WrappedWatchableObject obj2 : rebuiltList) { + if (index == obj2.getIndex()) { + itel.remove(); + break; + } + } + } + rebuiltList.addAll(backups); + return rebuiltList; + } + /** * Resends the entity to this specific player */ @@ -477,7 +541,7 @@ public class DisguiseUtilities { ex.printStackTrace(); } } - }); + }, 2); DisguiseUtilities.sendSelfDisguise((Player) disguise.getEntity(), disguise); } else { final Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity()); @@ -500,7 +564,7 @@ public class DisguiseUtilities { ex.printStackTrace(); } } - }); + }, 2); break; } } @@ -539,7 +603,7 @@ public class DisguiseUtilities { ex.printStackTrace(); } } - }); + }, 2); } } } @@ -565,7 +629,7 @@ public class DisguiseUtilities { ex.printStackTrace(); } } - }); + }, 2); } final Object entityTrackerEntry = ReflectionManager.getEntityTrackerEntry(disguise.getEntity()); if (entityTrackerEntry != null) { @@ -588,7 +652,7 @@ public class DisguiseUtilities { ex.printStackTrace(); } } - }); + }, 2); } } } diff --git a/src/me/libraryaddict/disguise/utilities/PacketsManager.java b/src/me/libraryaddict/disguise/utilities/PacketsManager.java index b40b1afc..fa41fcf4 100644 --- a/src/me/libraryaddict/disguise/utilities/PacketsManager.java +++ b/src/me/libraryaddict/disguise/utilities/PacketsManager.java @@ -113,7 +113,7 @@ public class PacketsManager { /** * Construct the packets I need to spawn in the disguise */ - public static PacketContainer[] constructSpawnPackets(Disguise disguise, Entity disguisedEntity) { + public static PacketContainer[] constructSpawnPackets(Player player, Disguise disguise, Entity disguisedEntity) { if (disguise.getEntity() == null) disguise.setEntity(disguisedEntity); Object nmsEntity = ReflectionManager.getNmsEntity(disguisedEntity); @@ -246,7 +246,7 @@ public class PacketsManager { byteMods.write(0, yaw); byteMods.write(1, pitch); spawnPackets[0].getDataWatcherModifier().write(0, - createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); + createDataWatcher(player, WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); if (((PlayerWatcher) disguise.getWatcher()).isSleeping() && DisguiseConfig.isBedPacketsEnabled()) { spawnPackets[1] = new PacketContainer(PacketType.Play.Server.BED); @@ -290,7 +290,7 @@ public class PacketsManager { mods.write(8, yaw); mods.write(9, pitch); spawnPackets[0].getDataWatcherModifier().write(0, - createDataWatcher(WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); + createDataWatcher(player, WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); } else if (disguise.getType().isMisc()) { @@ -331,11 +331,12 @@ public class PacketsManager { /** * Create a new datawatcher but with the 'correct' values */ - private static WrappedDataWatcher createDataWatcher(WrappedDataWatcher watcher, FlagWatcher flagWatcher) { + private static WrappedDataWatcher createDataWatcher(Player player, WrappedDataWatcher watcher, FlagWatcher flagWatcher) { WrappedDataWatcher newWatcher = new WrappedDataWatcher(); try { List list = DisguiseConfig.isMetadataPacketsEnabled() ? flagWatcher.convert(watcher .getWatchableObjects()) : flagWatcher.getWatchableObjects(); + list = DisguiseUtilities.rebuildForVersion(player, flagWatcher, list); for (WrappedWatchableObject watchableObject : list) { newWatcher.setObject(watchableObject.getIndex(), watchableObject.getValue()); } @@ -1247,6 +1248,7 @@ public class PacketsManager { if (DisguiseConfig.isMetadataPacketsEnabled()) { List watchableObjects = disguise.getWatcher().convert( packets[0].getWatchableCollectionModifier().read(0)); + watchableObjects = DisguiseUtilities.rebuildForVersion(observer, disguise.getWatcher(), watchableObjects); packets[0] = new PacketContainer(sentPacket.getType()); StructureModifier newMods = packets[0].getModifier(); newMods.write(0, entity.getEntityId()); @@ -1262,7 +1264,7 @@ public class PacketsManager { || sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY_EXPERIENCE_ORB || sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY || sentPacket.getType() == PacketType.Play.Server.SPAWN_ENTITY_PAINTING) { - packets = constructSpawnPackets(disguise, entity); + packets = constructSpawnPackets(observer, disguise, entity); } // Else if the disguise is attempting to send players a forbidden packet @@ -1349,6 +1351,7 @@ public class PacketsManager { } } } + list = DisguiseUtilities.rebuildForVersion(observer, disguise.getWatcher(), list); // Construct the packets to return PacketContainer packetBlock = new PacketContainer(PacketType.Play.Server.ENTITY_METADATA); packetBlock.getModifier().write(0, entity.getEntityId()); diff --git a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java index 0e062ddf..ead1a736 100644 --- a/src/me/libraryaddict/disguise/utilities/ReflectionManager.java +++ b/src/me/libraryaddict/disguise/utilities/ReflectionManager.java @@ -29,7 +29,7 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile; public class ReflectionManager { public enum LibVersion { - V1_6, V1_7, V1_7_6; + V1_6, V1_7, V1_7_6, V1_8; private static LibVersion currentVersion = LibVersion.V1_7; static { String mcVersion = Bukkit.getVersion().split("MC: ")[1].replace(")", ""); @@ -37,7 +37,8 @@ public class ReflectionManager { if (mcVersion.compareTo("1.7") < 0) { currentVersion = LibVersion.V1_6; } else { - currentVersion = mcVersion.compareTo("1.7.6") < 0 && !mcVersion.equals("1.7.10") ? LibVersion.V1_7 : LibVersion.V1_7_6; + currentVersion = mcVersion.compareTo("1.7.6") < 0 && !mcVersion.equals("1.7.10") ? LibVersion.V1_7 + : LibVersion.V1_7_6; } } } @@ -541,6 +542,19 @@ public class ReflectionManager { return null; } + public static boolean is1_8(Player player) { + try { + Object cPlayer = getNmsEntity(player); + Field playerConnection = cPlayer.getClass().getField("playerConnection"); + Field networkManager = getNmsClass("PlayerConnection").getField("networkManager"); + Method getVersion = getNmsClass("NetworkManager").getMethod("getVersion"); + return (Integer) getVersion.invoke(networkManager.get(playerConnection.get(cPlayer))) >= 28; + } catch (Exception ex) { + ex.printStackTrace(); + } + return false; + } + public static boolean isForge() { return isForge; }