Fix setSleeping for player disguise in 1.8
This commit is contained in:
		
							
								
								
									
										10
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								pom.xml
									
									
									
									
									
								
							| @@ -86,17 +86,17 @@ | |||||||
| 			<artifactId>spigot-api</artifactId> | 			<artifactId>spigot-api</artifactId> | ||||||
| 			<version>1.7.8-R0.1-SNAPSHOT</version> | 			<version>1.7.8-R0.1-SNAPSHOT</version> | ||||||
| 		</dependency> | 		</dependency> | ||||||
| 		<dependency> |  | ||||||
| 			<groupId>org.spigotmc</groupId> |  | ||||||
| 			<artifactId>spigot</artifactId> |  | ||||||
| 			<version>1.7.8-R0.1-SNAPSHOT</version> |  | ||||||
| 		</dependency> |  | ||||||
| 		<dependency> | 		<dependency> | ||||||
| 			<groupId>junit</groupId> | 			<groupId>junit</groupId> | ||||||
| 			<artifactId>junit</artifactId> | 			<artifactId>junit</artifactId> | ||||||
| 			<version>4.11</version> | 			<version>4.11</version> | ||||||
| 			<scope>test</scope> | 			<scope>test</scope> | ||||||
| 		</dependency> | 		</dependency> | ||||||
|  | 		<dependency> | ||||||
|  | 			<groupId>org.spigotmc</groupId> | ||||||
|  | 			<artifactId>spigot</artifactId> | ||||||
|  | 			<version>1.7.10-R0.1-SNAPSHOT</version> | ||||||
|  | 		</dependency> | ||||||
| 	</dependencies> | 	</dependencies> | ||||||
|  |  | ||||||
| 	<distributionManagement> | 	<distributionManagement> | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| package me.libraryaddict.disguise; | package me.libraryaddict.disguise; | ||||||
|  |  | ||||||
|  | import java.lang.reflect.InvocationTargetException; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
| @@ -9,8 +10,8 @@ import me.libraryaddict.disguise.disguisetypes.DisguiseType; | |||||||
| import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | ||||||
| import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; | import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; | ||||||
| import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; | import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher; | ||||||
| import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; |  | ||||||
| import me.libraryaddict.disguise.utilities.DisguiseUtilities; | import me.libraryaddict.disguise.utilities.DisguiseUtilities; | ||||||
|  | import me.libraryaddict.disguise.utilities.ReflectionManager; | ||||||
| import me.libraryaddict.disguise.utilities.UpdateChecker; | import me.libraryaddict.disguise.utilities.UpdateChecker; | ||||||
|  |  | ||||||
| import org.bukkit.Bukkit; | import org.bukkit.Bukkit; | ||||||
| @@ -24,15 +25,20 @@ import org.bukkit.event.EventPriority; | |||||||
| import org.bukkit.event.Listener; | import org.bukkit.event.Listener; | ||||||
| import org.bukkit.event.entity.EntityDamageByEntityEvent; | import org.bukkit.event.entity.EntityDamageByEntityEvent; | ||||||
| import org.bukkit.event.entity.EntityTargetEvent; | import org.bukkit.event.entity.EntityTargetEvent; | ||||||
|  | import org.bukkit.event.player.PlayerChangedWorldEvent; | ||||||
| import org.bukkit.event.player.PlayerInteractEntityEvent; | import org.bukkit.event.player.PlayerInteractEntityEvent; | ||||||
| import org.bukkit.event.player.PlayerJoinEvent; | import org.bukkit.event.player.PlayerJoinEvent; | ||||||
| import org.bukkit.event.player.PlayerMoveEvent; | import org.bukkit.event.player.PlayerMoveEvent; | ||||||
| import org.bukkit.event.player.PlayerPortalEvent; | import org.bukkit.event.player.PlayerPortalEvent; | ||||||
| import org.bukkit.event.player.PlayerRespawnEvent; | import org.bukkit.event.player.PlayerRespawnEvent; | ||||||
|  | import org.bukkit.event.player.PlayerTeleportEvent; | ||||||
| import org.bukkit.event.vehicle.VehicleEnterEvent; | import org.bukkit.event.vehicle.VehicleEnterEvent; | ||||||
| import org.bukkit.event.vehicle.VehicleExitEvent; | import org.bukkit.event.vehicle.VehicleExitEvent; | ||||||
| import org.bukkit.scheduler.BukkitRunnable; | import org.bukkit.scheduler.BukkitRunnable; | ||||||
|  |  | ||||||
|  | import com.comphenix.protocol.ProtocolLibrary; | ||||||
|  | import com.comphenix.protocol.events.PacketContainer; | ||||||
|  |  | ||||||
| public class DisguiseListener implements Listener { | public class DisguiseListener implements Listener { | ||||||
|  |  | ||||||
|     private String currentVersion; |     private String currentVersion; | ||||||
| @@ -86,6 +92,39 @@ public class DisguiseListener implements Listener { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private void chunkMove(Player player, Location newLoc, Location oldLoc) { | ||||||
|  |         try { | ||||||
|  |             if (ReflectionManager.is1_8(player)) { | ||||||
|  |                 for (PacketContainer packet : DisguiseUtilities.getBedChunkPacket(player, newLoc, oldLoc)) { | ||||||
|  |                     ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet, false); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             if (newLoc != null) { | ||||||
|  |                 for (HashSet<TargetedDisguise> list : DisguiseUtilities.getDisguises().values()) { | ||||||
|  |                     for (TargetedDisguise disguise : list) { | ||||||
|  |                         if (disguise.getType() == DisguiseType.PLAYER && disguise.canSee(player) | ||||||
|  |                                 && ((PlayerDisguise) disguise).getWatcher().isSleeping() | ||||||
|  |                                 && DisguiseUtilities.getPerverts(disguise).contains(player)) { | ||||||
|  |                             PacketContainer[] packets = DisguiseUtilities.getBedPackets(player, | ||||||
|  |                                     disguise.getEntity() == player ? newLoc : disguise.getEntity().getLocation(), newLoc, | ||||||
|  |                                     (PlayerDisguise) disguise); | ||||||
|  |                             if (disguise.getEntity() == player) { | ||||||
|  |                                 for (PacketContainer packet : packets) { | ||||||
|  |                                     packet.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId()); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                             for (PacketContainer packet : packets) { | ||||||
|  |                                 ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } catch (InvocationTargetException e) { | ||||||
|  |             e.printStackTrace(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) |     @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) | ||||||
|     public void onAttack(EntityDamageByEntityEvent event) { |     public void onAttack(EntityDamageByEntityEvent event) { | ||||||
|         if (DisguiseConfig.isDisguiseBlownOnAttack()) { |         if (DisguiseConfig.isDisguiseBlownOnAttack()) { | ||||||
| @@ -104,6 +143,33 @@ public class DisguiseListener implements Listener { | |||||||
|         if (latestVersion != null && p.hasPermission(updateNotifyPermission)) { |         if (latestVersion != null && p.hasPermission(updateNotifyPermission)) { | ||||||
|             p.sendMessage(String.format(updateMessage, currentVersion, latestVersion)); |             p.sendMessage(String.format(updateMessage, currentVersion, latestVersion)); | ||||||
|         } |         } | ||||||
|  |         if (DisguiseConfig.isBedPacketsEnabled()) { | ||||||
|  |             chunkMove(p, p.getLocation(), null); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Most likely faster if we don't bother doing checks if he sees a player disguise | ||||||
|  |      */ | ||||||
|  |     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) | ||||||
|  |     public void onMove(PlayerMoveEvent event) { | ||||||
|  |         if (DisguiseConfig.isBedPacketsEnabled()) { | ||||||
|  |             Location to = event.getTo(); | ||||||
|  |             Location from = event.getFrom(); | ||||||
|  |             if (Math.floor(to.getBlockX() / 160D) != Math.floor(from.getBlockX() / 160D) | ||||||
|  |                     || Math.floor(to.getBlockZ() / 160D) != Math.floor(from.getBlockZ() / 160D)) { | ||||||
|  |                 chunkMove(event.getPlayer(), to, from); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) | ||||||
|  |     public void onPortalEnter(PlayerPortalEvent event) { | ||||||
|  |         if (DisguiseConfig.isUndisguiseOnWorldChange() && event.getFrom().getWorld() != event.getTo().getWorld()) { | ||||||
|  |             for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) { | ||||||
|  |                 disguise.removeDisguise(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler |     @EventHandler | ||||||
| @@ -216,6 +282,27 @@ public class DisguiseListener implements Listener { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) | ||||||
|  |     public void onTeleport(final PlayerTeleportEvent event) { | ||||||
|  |         if (DisguiseConfig.isBedPacketsEnabled()) { | ||||||
|  |             Location to = event.getTo(); | ||||||
|  |             Location from = event.getFrom(); | ||||||
|  |             if (Math.floor(to.getBlockX() / 160D) != Math.floor(from.getBlockX() / 160D) | ||||||
|  |                     || Math.floor(to.getBlockZ() / 160D) != Math.floor(from.getBlockZ() / 160D)) { | ||||||
|  |                 chunkMove(event.getPlayer(), null, from); | ||||||
|  |                 Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { | ||||||
|  |                     public void run() { | ||||||
|  |                         if (!event.isCancelled()) { | ||||||
|  |                             chunkMove(event.getPlayer(), event.getTo(), null); | ||||||
|  |                         } else { | ||||||
|  |                             chunkMove(event.getPlayer(), event.getPlayer().getLocation(), null); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) | ||||||
|     public void onVehicleEnter(VehicleEnterEvent event) { |     public void onVehicleEnter(VehicleEnterEvent event) { | ||||||
|         if (event.getEntered() instanceof Player && DisguiseAPI.isDisguised((Player) event.getEntered(), event.getEntered())) { |         if (event.getEntered() instanceof Player && DisguiseAPI.isDisguised((Player) event.getEntered(), event.getEntered())) { | ||||||
| @@ -240,11 +327,9 @@ public class DisguiseListener implements Listener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) |     @EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true) | ||||||
|     public void onWorldSwitch(PlayerPortalEvent event) { |     public void onWorldSwitch(final PlayerChangedWorldEvent event) { | ||||||
|         if (DisguiseConfig.isUndisguiseOnWorldChange() && event.getFrom().getWorld() != event.getTo().getWorld()) { |         if (DisguiseConfig.isBedPacketsEnabled()) { | ||||||
|             for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) { |             chunkMove(event.getPlayer(), event.getPlayer().getLocation(), null); | ||||||
|                 disguise.removeDisguise(); |  | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| package me.libraryaddict.disguise.disguisetypes.watchers; | package me.libraryaddict.disguise.disguisetypes.watchers; | ||||||
|  |  | ||||||
| import org.bukkit.Location; | import org.bukkit.block.BlockFace; | ||||||
| import org.bukkit.entity.Player; | import org.bukkit.entity.Player; | ||||||
|  |  | ||||||
| import com.comphenix.protocol.PacketType; | import com.comphenix.protocol.PacketType; | ||||||
| @@ -8,6 +8,7 @@ import com.comphenix.protocol.ProtocolLibrary; | |||||||
| import com.comphenix.protocol.events.PacketContainer; | import com.comphenix.protocol.events.PacketContainer; | ||||||
| import com.comphenix.protocol.reflect.StructureModifier; | import com.comphenix.protocol.reflect.StructureModifier; | ||||||
|  |  | ||||||
|  | import me.libraryaddict.disguise.DisguiseAPI; | ||||||
| import me.libraryaddict.disguise.DisguiseConfig; | import me.libraryaddict.disguise.DisguiseConfig; | ||||||
| import me.libraryaddict.disguise.disguisetypes.Disguise; | import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||||
| import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | ||||||
| @@ -16,6 +17,7 @@ import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion; | |||||||
|  |  | ||||||
| public class PlayerWatcher extends LivingWatcher { | public class PlayerWatcher extends LivingWatcher { | ||||||
|     private boolean isInBed; |     private boolean isInBed; | ||||||
|  |     private BlockFace sleepingDirection; | ||||||
|  |  | ||||||
|     public PlayerWatcher(Disguise disguise) { |     public PlayerWatcher(Disguise disguise) { | ||||||
|         super(disguise); |         super(disguise); | ||||||
| @@ -31,6 +33,10 @@ public class PlayerWatcher extends LivingWatcher { | |||||||
|         return (Byte) getValue(9, (byte) 0); |         return (Byte) getValue(9, (byte) 0); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public BlockFace getSleepingDirection() { | ||||||
|  |         return sleepingDirection; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private boolean getValue16(int i) { |     private boolean getValue16(int i) { | ||||||
|         return ((Byte) getValue(16, (byte) 0) & 1 << i) != 0; |         return ((Byte) getValue(16, (byte) 0) & 1 << i) != 0; | ||||||
|     } |     } | ||||||
| @@ -57,31 +63,57 @@ public class PlayerWatcher extends LivingWatcher { | |||||||
|         ((PlayerDisguise) getDisguise()).setSkin(playerName); |         ((PlayerDisguise) getDisguise()).setSkin(playerName); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     public void setSleeping(BlockFace sleepingDirection) { | ||||||
|      * The facing direction for the bed is the block metadata. 0 - 90 degrees. 1 - 0 degrees. 2 - 270 degrees. 3 - 180 degrees. |         setSleeping(true, sleepingDirection); | ||||||
|      */ |     } | ||||||
|  |  | ||||||
|     public void setSleeping(boolean sleep) { |     public void setSleeping(boolean sleep) { | ||||||
|         if (sleep != isSleeping()) { |         setSleeping(sleep, null); | ||||||
|             isInBed = sleep; |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * If no BlockFace is supplied. It grabs it from the entities facing direction if applicable. | ||||||
|  |      */ | ||||||
|  |     public void setSleeping(boolean sleeping, BlockFace sleepingDirection) { | ||||||
|  |         if (sleepingDirection != null) { | ||||||
|  |             this.sleepingDirection = BlockFace.values()[sleepingDirection.ordinal() % 4]; | ||||||
|  |         } else if (sleeping) { | ||||||
|  |             if (this.getDisguise().getEntity() != null) { | ||||||
|  |                 this.sleepingDirection = BlockFace.values()[Math | ||||||
|  |                         .round(this.getDisguise().getEntity().getLocation().getYaw() / 90F) & 0x3]; | ||||||
|  |             } else { | ||||||
|  |                 this.sleepingDirection = BlockFace.EAST; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (sleeping != isSleeping()) { | ||||||
|  |             isInBed = sleeping; | ||||||
|             if (DisguiseConfig.isBedPacketsEnabled() && DisguiseUtilities.isDisguiseInUse(getDisguise())) { |             if (DisguiseConfig.isBedPacketsEnabled() && DisguiseUtilities.isDisguiseInUse(getDisguise())) { | ||||||
|                 PacketContainer packet; |  | ||||||
|                 if (isSleeping()) { |  | ||||||
|                     packet = new PacketContainer(PacketType.Play.Server.BED); |  | ||||||
|                     StructureModifier<Integer> mods = packet.getIntegers(); |  | ||||||
|                     mods.write(0, getDisguise().getEntity().getEntityId()); |  | ||||||
|                     Location loc = getDisguise().getEntity().getLocation(); |  | ||||||
|                     mods.write(1, loc.getBlockX()); |  | ||||||
|                     mods.write(2, loc.getBlockY()); |  | ||||||
|                     mods.write(3, loc.getBlockZ()); |  | ||||||
|                 } else { |  | ||||||
|                     packet = new PacketContainer(PacketType.Play.Server.ANIMATION); |  | ||||||
|                     StructureModifier<Integer> mods = packet.getIntegers(); |  | ||||||
|                     mods.write(0, getDisguise().getEntity().getEntityId()); |  | ||||||
|                     mods.write(1, LibVersion.is1_7() ? 3 : 2); |  | ||||||
|                 } |  | ||||||
|                 try { |                 try { | ||||||
|                     for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { |                     if (isSleeping()) { | ||||||
|                         ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); |                         for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { | ||||||
|  |                             PacketContainer[] packets = DisguiseUtilities.getBedPackets(player, this.getDisguise().getEntity() | ||||||
|  |                                     .getLocation(), player.getLocation(), (PlayerDisguise) this.getDisguise()); | ||||||
|  |                             if (getDisguise().getEntity() == player) { | ||||||
|  |                                 for (PacketContainer packet : packets) { | ||||||
|  |                                     packet = packet.shallowClone(); | ||||||
|  |                                     packet.getIntegers().write(0, DisguiseAPI.getSelfDisguiseId()); | ||||||
|  |                                     ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); | ||||||
|  |                                 } | ||||||
|  |                             } else { | ||||||
|  |                                 for (PacketContainer packet : packets) { | ||||||
|  |                                     ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); | ||||||
|  |                                 } | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     } else { | ||||||
|  |                         PacketContainer packet = new PacketContainer(PacketType.Play.Server.ANIMATION); | ||||||
|  |                         StructureModifier<Integer> mods = packet.getIntegers(); | ||||||
|  |                         mods.write(0, getDisguise().getEntity().getEntityId()); | ||||||
|  |                         mods.write(1, LibVersion.is1_7() ? 3 : 2); | ||||||
|  |                         for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { | ||||||
|  |                             ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); | ||||||
|  |  | ||||||
|  |                         } | ||||||
|                     } |                     } | ||||||
|                 } catch (Exception ex) { |                 } catch (Exception ex) { | ||||||
|                     ex.printStackTrace(); |                     ex.printStackTrace(); | ||||||
|   | |||||||
| @@ -1,9 +1,11 @@ | |||||||
| package me.libraryaddict.disguise.utilities; | package me.libraryaddict.disguise.utilities; | ||||||
|  |  | ||||||
|  | import java.lang.reflect.Array; | ||||||
| import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||||
| import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
| @@ -23,6 +25,7 @@ import me.libraryaddict.disguise.disguisetypes.TargetedDisguise; | |||||||
| import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; | import me.libraryaddict.disguise.disguisetypes.watchers.AgeableWatcher; | ||||||
| import me.libraryaddict.disguise.disguisetypes.watchers.EndermanWatcher; | import me.libraryaddict.disguise.disguisetypes.watchers.EndermanWatcher; | ||||||
| import me.libraryaddict.disguise.disguisetypes.watchers.ItemFrameWatcher; | import me.libraryaddict.disguise.disguisetypes.watchers.ItemFrameWatcher; | ||||||
|  | import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher; | ||||||
| import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; | import me.libraryaddict.disguise.disguisetypes.watchers.ZombieWatcher; | ||||||
| import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; | import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType; | ||||||
| import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion; | import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion; | ||||||
| @@ -31,6 +34,7 @@ import org.bukkit.Bukkit; | |||||||
| import org.bukkit.Location; | import org.bukkit.Location; | ||||||
| import org.bukkit.Material; | import org.bukkit.Material; | ||||||
| import org.bukkit.World; | import org.bukkit.World; | ||||||
|  | import org.bukkit.block.BlockFace; | ||||||
| import org.bukkit.entity.Ageable; | import org.bukkit.entity.Ageable; | ||||||
| import org.bukkit.entity.Entity; | import org.bukkit.entity.Entity; | ||||||
| import org.bukkit.entity.Player; | import org.bukkit.entity.Player; | ||||||
| @@ -43,6 +47,7 @@ import com.comphenix.protocol.PacketType; | |||||||
| import com.comphenix.protocol.ProtocolLibrary; | import com.comphenix.protocol.ProtocolLibrary; | ||||||
| import com.comphenix.protocol.ProtocolManager; | import com.comphenix.protocol.ProtocolManager; | ||||||
| import com.comphenix.protocol.events.PacketContainer; | import com.comphenix.protocol.events.PacketContainer; | ||||||
|  | import com.comphenix.protocol.reflect.StructureModifier; | ||||||
| import com.comphenix.protocol.wrappers.WrappedDataWatcher; | import com.comphenix.protocol.wrappers.WrappedDataWatcher; | ||||||
| import com.comphenix.protocol.wrappers.WrappedGameProfile; | import com.comphenix.protocol.wrappers.WrappedGameProfile; | ||||||
| import com.comphenix.protocol.wrappers.WrappedWatchableObject; | import com.comphenix.protocol.wrappers.WrappedWatchableObject; | ||||||
| @@ -53,6 +58,7 @@ public class DisguiseUtilities { | |||||||
|      * the plugin to do that. |      * the plugin to do that. | ||||||
|      */ |      */ | ||||||
|     private static HashSet<String> addedByPlugins = new HashSet<String>(); |     private static HashSet<String> addedByPlugins = new HashSet<String>(); | ||||||
|  |     private static Object bedChunk; | ||||||
|     private static LinkedHashMap<String, Disguise> clonedDisguises = new LinkedHashMap<String, Disguise>(); |     private static LinkedHashMap<String, Disguise> clonedDisguises = new LinkedHashMap<String, Disguise>(); | ||||||
|     /** |     /** | ||||||
|      * A hashmap of the uuid's of entitys, alive and dead. And their disguises in use |      * A hashmap of the uuid's of entitys, alive and dead. And their disguises in use | ||||||
| @@ -70,6 +76,43 @@ public class DisguiseUtilities { | |||||||
|     private static LibsDisguises libsDisguises; |     private static LibsDisguises libsDisguises; | ||||||
|     private static HashMap<String, ArrayList<Object>> runnables = new HashMap<String, ArrayList<Object>>(); |     private static HashMap<String, ArrayList<Object>> runnables = new HashMap<String, ArrayList<Object>>(); | ||||||
|     private static HashSet<UUID> selfDisguised = new HashSet<UUID>(); |     private static HashSet<UUID> selfDisguised = new HashSet<UUID>(); | ||||||
|  |     private static Field xChunk, zChunk; | ||||||
|  |  | ||||||
|  |     static { | ||||||
|  |         try { | ||||||
|  |             bedChunk = ReflectionManager.getNmsClass("Chunk") | ||||||
|  |                     .getConstructor(ReflectionManager.getNmsClass("World"), int.class, int.class).newInstance(null, 0, 0); | ||||||
|  |             Field cSection = bedChunk.getClass().getDeclaredField("sections"); | ||||||
|  |             cSection.setAccessible(true); | ||||||
|  |             Object chunkSection = ReflectionManager.getNmsClass("ChunkSection").getConstructor(int.class, boolean.class) | ||||||
|  |                     .newInstance(0, false); | ||||||
|  |             Object block = ReflectionManager.getNmsClass("Block").getMethod("getById", int.class) | ||||||
|  |                     .invoke(null, Material.BED_BLOCK.getId()); // TODO Method name exists in older versions? | ||||||
|  |             Method setId = chunkSection.getClass().getMethod("setTypeId", int.class, int.class, int.class, | ||||||
|  |                     ReflectionManager.getNmsClass("Block")); | ||||||
|  |             Method setData = chunkSection.getClass().getMethod("setData", int.class, int.class, int.class, int.class); | ||||||
|  |             Method setSky = chunkSection.getClass().getMethod("setSkyLight", int.class, int.class, int.class, int.class); | ||||||
|  |             Method setEmitted = chunkSection.getClass().getMethod("setEmittedLight", int.class, int.class, int.class, int.class); | ||||||
|  |             for (BlockFace face : new BlockFace[] { BlockFace.EAST, BlockFace.WEST, BlockFace.NORTH, BlockFace.SOUTH }) { | ||||||
|  |                 setId.invoke(chunkSection, 1 + face.getModX(), 0, 1 + face.getModZ(), block); | ||||||
|  |                 setData.invoke(chunkSection, 1 + face.getModX(), 0, 1 + face.getModZ(), face.ordinal()); | ||||||
|  |                 setSky.invoke(chunkSection, 1 + face.getModX(), 0, 1 + face.getModZ(), 0); | ||||||
|  |                 setEmitted.invoke(chunkSection, 1 + face.getModX(), 0, 1 + face.getModZ(), 0); | ||||||
|  |             } | ||||||
|  |             Object[] array = (Object[]) Array.newInstance(chunkSection.getClass(), 16); | ||||||
|  |             array[0] = chunkSection; | ||||||
|  |             cSection.set(bedChunk, array); | ||||||
|  |             Object server = ReflectionManager.getNmsMethod("MinecraftServer", "getServer").invoke(null); | ||||||
|  |             Object world = ((List) server.getClass().getField("worlds").get(server)).get(0); | ||||||
|  |             bedChunk.getClass().getField("world").set(bedChunk, world); | ||||||
|  |             xChunk = bedChunk.getClass().getField("locX"); | ||||||
|  |             xChunk.setAccessible(true); | ||||||
|  |             zChunk = bedChunk.getClass().getField("locZ"); | ||||||
|  |             zChunk.setAccessible(true); | ||||||
|  |         } catch (Exception ex) { | ||||||
|  |             ex.printStackTrace(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public static boolean addClonedDisguise(String key, Disguise disguise) { |     public static boolean addClonedDisguise(String key, Disguise disguise) { | ||||||
|         if (DisguiseConfig.getMaxClonedDisguises() > 0) { |         if (DisguiseConfig.getMaxClonedDisguises() > 0) { | ||||||
| @@ -257,6 +300,74 @@ public class DisguiseUtilities { | |||||||
|         return addedByPlugins; |         return addedByPlugins; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static PacketContainer[] getBedChunkPacket(Player player, Location newLoc, Location oldLoc) { | ||||||
|  |         int i = 0; | ||||||
|  |         PacketContainer[] packets = new PacketContainer[newLoc != null ? 2 + (oldLoc != null ? 1 : 0) : 1]; | ||||||
|  |         for (Location loc : new Location[] { oldLoc, newLoc }) { | ||||||
|  |             if (loc == null) { | ||||||
|  |                 continue; | ||||||
|  |             } | ||||||
|  |             try { | ||||||
|  |                 int chunkX = (int) Math.floor(loc.getBlockX() / 16D) + 20, chunkZ = (int) Math.floor(loc.getBlockZ() / 16D) + 20; | ||||||
|  |                 chunkX -= chunkX % 10; | ||||||
|  |                 chunkZ -= chunkZ % 10; | ||||||
|  |                 xChunk.set(bedChunk, chunkX); | ||||||
|  |                 zChunk.set(bedChunk, chunkZ); | ||||||
|  |             } catch (Exception ex) { | ||||||
|  |                 ex.printStackTrace(); | ||||||
|  |             } | ||||||
|  |             try { | ||||||
|  |                 packets[i++] = ProtocolLibrary.getProtocolManager() | ||||||
|  |                         .createPacketConstructor(PacketType.Play.Server.MAP_CHUNK, bedChunk, true, 0, 40) | ||||||
|  |                         .createPacket(bedChunk, true, 0, ReflectionManager.is1_8(player) ? 48 : 0); | ||||||
|  |             } catch (IllegalArgumentException ex) { | ||||||
|  |                 packets[i++] = ProtocolLibrary.getProtocolManager() | ||||||
|  |                         .createPacketConstructor(PacketType.Play.Server.MAP_CHUNK, bedChunk, true, 0) | ||||||
|  |                         .createPacket(bedChunk, true, 0); | ||||||
|  |             } | ||||||
|  |             if (oldLoc == null || i > 1) { | ||||||
|  |                 try { | ||||||
|  |                     packets[i++] = ProtocolLibrary.getProtocolManager() | ||||||
|  |                             .createPacketConstructor(PacketType.Play.Server.MAP_CHUNK_BULK, Arrays.asList(bedChunk), 40) | ||||||
|  |                             .createPacket(Arrays.asList(bedChunk), ReflectionManager.is1_8(player) ? 48 : 0); | ||||||
|  |                 } catch (IllegalArgumentException ex) { | ||||||
|  |                     packets[i++] = ProtocolLibrary.getProtocolManager() | ||||||
|  |                             .createPacketConstructor(PacketType.Play.Server.MAP_CHUNK_BULK, Arrays.asList(bedChunk)) | ||||||
|  |                             .createPacket(Arrays.asList(bedChunk)); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return packets; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public static PacketContainer[] getBedPackets(Player player, Location loc, Location playerLocation, PlayerDisguise disguise) { | ||||||
|  |         Entity entity = disguise.getEntity(); | ||||||
|  |         PacketContainer setBed = new PacketContainer(PacketType.Play.Server.BED); | ||||||
|  |         StructureModifier<Integer> bedInts = setBed.getIntegers(); | ||||||
|  |         bedInts.write(0, entity.getEntityId()); | ||||||
|  |         if (ReflectionManager.is1_8(player)) { | ||||||
|  |             PlayerWatcher watcher = disguise.getWatcher(); | ||||||
|  |             int chunkX = (int) Math.floor(playerLocation.getBlockX() / 16D) + 20, chunkZ = (int) Math.floor(playerLocation | ||||||
|  |                     .getBlockZ() / 16D) + 20; | ||||||
|  |             chunkX -= chunkX % 10; | ||||||
|  |             chunkZ -= chunkZ % 10; | ||||||
|  |             bedInts.write(1, (chunkX * 16) + 1 + watcher.getSleepingDirection().getModX()); | ||||||
|  |             bedInts.write(3, (chunkZ * 16) + 1 + watcher.getSleepingDirection().getModZ()); | ||||||
|  |         } else { | ||||||
|  |             bedInts.write(1, loc.getBlockX()); | ||||||
|  |             bedInts.write(2, loc.getBlockY()); | ||||||
|  |             bedInts.write(3, loc.getBlockZ()); | ||||||
|  |         } | ||||||
|  |         PacketContainer teleport = new PacketContainer(PacketType.Play.Server.ENTITY_TELEPORT); | ||||||
|  |         StructureModifier<Integer> ints = teleport.getIntegers(); | ||||||
|  |         ints.write(0, entity.getEntityId()); | ||||||
|  |         ints.write(1, (int) Math.floor(loc.getX() * 32)); | ||||||
|  |         ints.write(2, (int) Math.floor((PacketsManager.getYModifier(disguise.getEntity(), disguise) + loc.getY()) * 32)); | ||||||
|  |         ints.write(3, (int) Math.floor(loc.getZ() * 32)); | ||||||
|  |         return new PacketContainer[] { setBed, teleport }; | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public static Disguise getClonedDisguise(String key) { |     public static Disguise getClonedDisguise(String key) { | ||||||
|         if (clonedDisguises.containsKey(key)) { |         if (clonedDisguises.containsKey(key)) { | ||||||
|             return clonedDisguises.get(key).clone(); |             return clonedDisguises.get(key).clone(); | ||||||
| @@ -264,6 +375,12 @@ public class DisguiseUtilities { | |||||||
|         return null; |         return null; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public static PacketContainer getDestroyPacket(int... ids) { | ||||||
|  |         PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); | ||||||
|  |         destroyPacket.getIntegerArrays().write(0, ids); | ||||||
|  |         return destroyPacket; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public static TargetedDisguise getDisguise(Player observer, Entity entity) { |     public static TargetedDisguise getDisguise(Player observer, Entity entity) { | ||||||
|         UUID entityId = entity.getUniqueId(); |         UUID entityId = entity.getUniqueId(); | ||||||
|         if (futureDisguises.containsKey(entity.getEntityId())) { |         if (futureDisguises.containsKey(entity.getEntityId())) { | ||||||
| @@ -671,12 +788,6 @@ public class DisguiseUtilities { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static PacketContainer getDestroyPacket(int... ids) { |  | ||||||
|         PacketContainer destroyPacket = new PacketContainer(PacketType.Play.Server.ENTITY_DESTROY); |  | ||||||
|         destroyPacket.getIntegerArrays().write(0, ids); |  | ||||||
|         return destroyPacket; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public static boolean removeDisguise(TargetedDisguise disguise) { |     public static boolean removeDisguise(TargetedDisguise disguise) { | ||||||
|         UUID entityId = disguise.getEntity().getUniqueId(); |         UUID entityId = disguise.getEntity().getUniqueId(); | ||||||
|         if (getDisguises().containsKey(entityId) && getDisguises().get(entityId).remove(disguise)) { |         if (getDisguises().containsKey(entityId) && getDisguises().get(entityId).remove(disguise)) { | ||||||
|   | |||||||
| @@ -2,6 +2,7 @@ package me.libraryaddict.disguise.utilities; | |||||||
|  |  | ||||||
| import java.lang.reflect.InvocationTargetException; | import java.lang.reflect.InvocationTargetException; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
|  | import java.util.Arrays; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
|  |  | ||||||
| @@ -250,12 +251,13 @@ public class PacketsManager { | |||||||
|                     createDataWatcher(player, WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); |                     createDataWatcher(player, WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); | ||||||
|  |  | ||||||
|             if (((PlayerWatcher) disguise.getWatcher()).isSleeping() && DisguiseConfig.isBedPacketsEnabled()) { |             if (((PlayerWatcher) disguise.getWatcher()).isSleeping() && DisguiseConfig.isBedPacketsEnabled()) { | ||||||
|                 spawnPackets[1] = new PacketContainer(PacketType.Play.Server.BED); |                 spawnPackets = Arrays.copyOf(spawnPackets, spawnPackets.length); | ||||||
|                 StructureModifier<Integer> mods = spawnPackets[1].getIntegers(); |                 PacketContainer[] bedPackets = DisguiseUtilities.getBedPackets(player, | ||||||
|                 mods.write(0, disguisedEntity.getEntityId()); |                         loc.clone().subtract(0, PacketsManager.getYModifier(disguisedEntity, disguise), 0), player.getLocation(), | ||||||
|                 mods.write(1, loc.getBlockX()); |                         ((PlayerDisguise) disguise)); | ||||||
|                 mods.write(2, loc.getBlockY()); |                 for (int i = 0; i < 2; i++) { | ||||||
|                 mods.write(3, loc.getBlockZ()); |                     spawnPackets[i + 1] = bedPackets[i]; | ||||||
|  |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
|         } else if (disguise.getType().isMob()) { |         } else if (disguise.getType().isMob()) { | ||||||
| @@ -439,7 +441,7 @@ public class PacketsManager { | |||||||
|     /** |     /** | ||||||
|      * Get the Y level to add to the disguise for realism. |      * Get the Y level to add to the disguise for realism. | ||||||
|      */ |      */ | ||||||
|     private static double getYModifier(Entity entity, Disguise disguise) { |     public static double getYModifier(Entity entity, Disguise disguise) { | ||||||
|         double yMod = 0; |         double yMod = 0; | ||||||
|         if ((disguise.getType() != DisguiseType.PLAYER || !((PlayerWatcher) disguise.getWatcher()).isSleeping()) |         if ((disguise.getType() != DisguiseType.PLAYER || !((PlayerWatcher) disguise.getWatcher()).isSleeping()) | ||||||
|                 && entity.getType() == EntityType.DROPPED_ITEM) { |                 && entity.getType() == EntityType.DROPPED_ITEM) { | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile; | |||||||
| public class ReflectionManager { | public class ReflectionManager { | ||||||
|  |  | ||||||
|     public enum LibVersion { |     public enum LibVersion { | ||||||
|         V1_6, V1_7, V1_7_6, V1_7_10, V1_8; |         V1_6, V1_7, V1_7_10, V1_7_6, V1_8; | ||||||
|         private static LibVersion currentVersion = LibVersion.V1_7; |         private static LibVersion currentVersion = LibVersion.V1_7; | ||||||
|         static { |         static { | ||||||
|             String mcVersion = Bukkit.getVersion().split("MC: ")[1].replace(")", ""); |             String mcVersion = Bukkit.getVersion().split("MC: ")[1].replace(")", ""); | ||||||
| @@ -58,13 +58,13 @@ public class ReflectionManager { | |||||||
|             return getGameVersion() == V1_7 || is1_7_6(); |             return getGameVersion() == V1_7 || is1_7_6(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public static boolean is1_7_6() { |  | ||||||
|             return getGameVersion() == V1_7_6 || is1_7_10(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public static boolean is1_7_10() { |         public static boolean is1_7_10() { | ||||||
|             return getGameVersion() == V1_7_10; |             return getGameVersion() == V1_7_10; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         public static boolean is1_7_6() { | ||||||
|  |             return getGameVersion() == V1_7_6 || is1_7_10(); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static final String bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3]; |     private static final String bukkitVersion = Bukkit.getServer().getClass().getName().split("\\.")[3]; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user