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> | ||||
| 			<version>1.7.8-R0.1-SNAPSHOT</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.spigotmc</groupId> | ||||
| 			<artifactId>spigot</artifactId> | ||||
| 			<version>1.7.8-R0.1-SNAPSHOT</version> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>junit</groupId> | ||||
| 			<artifactId>junit</artifactId> | ||||
| 			<version>4.11</version> | ||||
| 			<scope>test</scope> | ||||
| 		</dependency> | ||||
| 		<dependency> | ||||
| 			<groupId>org.spigotmc</groupId> | ||||
| 			<artifactId>spigot</artifactId> | ||||
| 			<version>1.7.10-R0.1-SNAPSHOT</version> | ||||
| 		</dependency> | ||||
| 	</dependencies> | ||||
|  | ||||
| 	<distributionManagement> | ||||
|   | ||||
| @@ -1,5 +1,6 @@ | ||||
| package me.libraryaddict.disguise; | ||||
|  | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| 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.TargetedDisguise; | ||||
| 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.ReflectionManager; | ||||
| import me.libraryaddict.disguise.utilities.UpdateChecker; | ||||
|  | ||||
| import org.bukkit.Bukkit; | ||||
| @@ -24,15 +25,20 @@ import org.bukkit.event.EventPriority; | ||||
| import org.bukkit.event.Listener; | ||||
| import org.bukkit.event.entity.EntityDamageByEntityEvent; | ||||
| import org.bukkit.event.entity.EntityTargetEvent; | ||||
| import org.bukkit.event.player.PlayerChangedWorldEvent; | ||||
| import org.bukkit.event.player.PlayerInteractEntityEvent; | ||||
| import org.bukkit.event.player.PlayerJoinEvent; | ||||
| import org.bukkit.event.player.PlayerMoveEvent; | ||||
| import org.bukkit.event.player.PlayerPortalEvent; | ||||
| import org.bukkit.event.player.PlayerRespawnEvent; | ||||
| import org.bukkit.event.player.PlayerTeleportEvent; | ||||
| import org.bukkit.event.vehicle.VehicleEnterEvent; | ||||
| import org.bukkit.event.vehicle.VehicleExitEvent; | ||||
| import org.bukkit.scheduler.BukkitRunnable; | ||||
|  | ||||
| import com.comphenix.protocol.ProtocolLibrary; | ||||
| import com.comphenix.protocol.events.PacketContainer; | ||||
|  | ||||
| public class DisguiseListener implements Listener { | ||||
|  | ||||
|     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) | ||||
|     public void onAttack(EntityDamageByEntityEvent event) { | ||||
|         if (DisguiseConfig.isDisguiseBlownOnAttack()) { | ||||
| @@ -104,6 +143,33 @@ public class DisguiseListener implements Listener { | ||||
|         if (latestVersion != null && p.hasPermission(updateNotifyPermission)) { | ||||
|             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 | ||||
| @@ -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) | ||||
|     public void onVehicleEnter(VehicleEnterEvent event) { | ||||
|         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) | ||||
|     public void onWorldSwitch(PlayerPortalEvent event) { | ||||
|         if (DisguiseConfig.isUndisguiseOnWorldChange() && event.getFrom().getWorld() != event.getTo().getWorld()) { | ||||
|             for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) { | ||||
|                 disguise.removeDisguise(); | ||||
|             } | ||||
|     public void onWorldSwitch(final PlayerChangedWorldEvent event) { | ||||
|         if (DisguiseConfig.isBedPacketsEnabled()) { | ||||
|             chunkMove(event.getPlayer(), event.getPlayer().getLocation(), null); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| package me.libraryaddict.disguise.disguisetypes.watchers; | ||||
|  | ||||
| import org.bukkit.Location; | ||||
| import org.bukkit.block.BlockFace; | ||||
| import org.bukkit.entity.Player; | ||||
|  | ||||
| import com.comphenix.protocol.PacketType; | ||||
| @@ -8,6 +8,7 @@ import com.comphenix.protocol.ProtocolLibrary; | ||||
| import com.comphenix.protocol.events.PacketContainer; | ||||
| import com.comphenix.protocol.reflect.StructureModifier; | ||||
|  | ||||
| import me.libraryaddict.disguise.DisguiseAPI; | ||||
| import me.libraryaddict.disguise.DisguiseConfig; | ||||
| import me.libraryaddict.disguise.disguisetypes.Disguise; | ||||
| import me.libraryaddict.disguise.disguisetypes.PlayerDisguise; | ||||
| @@ -16,6 +17,7 @@ import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion; | ||||
|  | ||||
| public class PlayerWatcher extends LivingWatcher { | ||||
|     private boolean isInBed; | ||||
|     private BlockFace sleepingDirection; | ||||
|  | ||||
|     public PlayerWatcher(Disguise disguise) { | ||||
|         super(disguise); | ||||
| @@ -31,6 +33,10 @@ public class PlayerWatcher extends LivingWatcher { | ||||
|         return (Byte) getValue(9, (byte) 0); | ||||
|     } | ||||
|  | ||||
|     public BlockFace getSleepingDirection() { | ||||
|         return sleepingDirection; | ||||
|     } | ||||
|  | ||||
|     private boolean getValue16(int i) { | ||||
|         return ((Byte) getValue(16, (byte) 0) & 1 << i) != 0; | ||||
|     } | ||||
| @@ -57,31 +63,57 @@ public class PlayerWatcher extends LivingWatcher { | ||||
|         ((PlayerDisguise) getDisguise()).setSkin(playerName); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * The facing direction for the bed is the block metadata. 0 - 90 degrees. 1 - 0 degrees. 2 - 270 degrees. 3 - 180 degrees. | ||||
|      */ | ||||
|     public void setSleeping(BlockFace sleepingDirection) { | ||||
|         setSleeping(true, sleepingDirection); | ||||
|     } | ||||
|  | ||||
|     public void setSleeping(boolean sleep) { | ||||
|         if (sleep != isSleeping()) { | ||||
|             isInBed = sleep; | ||||
|         setSleeping(sleep, null); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 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())) { | ||||
|                 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 { | ||||
|                     for (Player player : DisguiseUtilities.getPerverts(getDisguise())) { | ||||
|                         ProtocolLibrary.getProtocolManager().sendServerPacket(player, packet); | ||||
|                     if (isSleeping()) { | ||||
|                         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) { | ||||
|                     ex.printStackTrace(); | ||||
|   | ||||
| @@ -1,9 +1,11 @@ | ||||
| package me.libraryaddict.disguise.utilities; | ||||
|  | ||||
| import java.lang.reflect.Array; | ||||
| import java.lang.reflect.Field; | ||||
| import java.lang.reflect.InvocationTargetException; | ||||
| import java.lang.reflect.Method; | ||||
| import java.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.HashSet; | ||||
| 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.EndermanWatcher; | ||||
| 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.TargetedDisguise.TargetType; | ||||
| import me.libraryaddict.disguise.utilities.ReflectionManager.LibVersion; | ||||
| @@ -31,6 +34,7 @@ import org.bukkit.Bukkit; | ||||
| import org.bukkit.Location; | ||||
| import org.bukkit.Material; | ||||
| import org.bukkit.World; | ||||
| import org.bukkit.block.BlockFace; | ||||
| import org.bukkit.entity.Ageable; | ||||
| import org.bukkit.entity.Entity; | ||||
| import org.bukkit.entity.Player; | ||||
| @@ -43,6 +47,7 @@ import com.comphenix.protocol.PacketType; | ||||
| import com.comphenix.protocol.ProtocolLibrary; | ||||
| import com.comphenix.protocol.ProtocolManager; | ||||
| import com.comphenix.protocol.events.PacketContainer; | ||||
| import com.comphenix.protocol.reflect.StructureModifier; | ||||
| import com.comphenix.protocol.wrappers.WrappedDataWatcher; | ||||
| import com.comphenix.protocol.wrappers.WrappedGameProfile; | ||||
| import com.comphenix.protocol.wrappers.WrappedWatchableObject; | ||||
| @@ -53,6 +58,7 @@ public class DisguiseUtilities { | ||||
|      * the plugin to do that. | ||||
|      */ | ||||
|     private static HashSet<String> addedByPlugins = new HashSet<String>(); | ||||
|     private static Object bedChunk; | ||||
|     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 | ||||
| @@ -70,6 +76,43 @@ public class DisguiseUtilities { | ||||
|     private static LibsDisguises libsDisguises; | ||||
|     private static HashMap<String, ArrayList<Object>> runnables = new HashMap<String, ArrayList<Object>>(); | ||||
|     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) { | ||||
|         if (DisguiseConfig.getMaxClonedDisguises() > 0) { | ||||
| @@ -257,6 +300,74 @@ public class DisguiseUtilities { | ||||
|         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) { | ||||
|         if (clonedDisguises.containsKey(key)) { | ||||
|             return clonedDisguises.get(key).clone(); | ||||
| @@ -264,6 +375,12 @@ public class DisguiseUtilities { | ||||
|         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) { | ||||
|         UUID entityId = entity.getUniqueId(); | ||||
|         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) { | ||||
|         UUID entityId = disguise.getEntity().getUniqueId(); | ||||
|         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.util.ArrayList; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
| import java.util.Random; | ||||
|  | ||||
| @@ -250,12 +251,13 @@ public class PacketsManager { | ||||
|                     createDataWatcher(player, WrappedDataWatcher.getEntityWatcher(disguisedEntity), disguise.getWatcher())); | ||||
|  | ||||
|             if (((PlayerWatcher) disguise.getWatcher()).isSleeping() && DisguiseConfig.isBedPacketsEnabled()) { | ||||
|                 spawnPackets[1] = new PacketContainer(PacketType.Play.Server.BED); | ||||
|                 StructureModifier<Integer> mods = spawnPackets[1].getIntegers(); | ||||
|                 mods.write(0, disguisedEntity.getEntityId()); | ||||
|                 mods.write(1, loc.getBlockX()); | ||||
|                 mods.write(2, loc.getBlockY()); | ||||
|                 mods.write(3, loc.getBlockZ()); | ||||
|                 spawnPackets = Arrays.copyOf(spawnPackets, spawnPackets.length); | ||||
|                 PacketContainer[] bedPackets = DisguiseUtilities.getBedPackets(player, | ||||
|                         loc.clone().subtract(0, PacketsManager.getYModifier(disguisedEntity, disguise), 0), player.getLocation(), | ||||
|                         ((PlayerDisguise) disguise)); | ||||
|                 for (int i = 0; i < 2; i++) { | ||||
|                     spawnPackets[i + 1] = bedPackets[i]; | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|         } else if (disguise.getType().isMob()) { | ||||
| @@ -439,7 +441,7 @@ public class PacketsManager { | ||||
|     /** | ||||
|      * 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; | ||||
|         if ((disguise.getType() != DisguiseType.PLAYER || !((PlayerWatcher) disguise.getWatcher()).isSleeping()) | ||||
|                 && entity.getType() == EntityType.DROPPED_ITEM) { | ||||
|   | ||||
| @@ -29,7 +29,7 @@ import com.comphenix.protocol.wrappers.WrappedGameProfile; | ||||
| public class ReflectionManager { | ||||
|  | ||||
|     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; | ||||
|         static { | ||||
|             String mcVersion = Bukkit.getVersion().split("MC: ")[1].replace(")", ""); | ||||
| @@ -58,13 +58,13 @@ public class ReflectionManager { | ||||
|             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() { | ||||
|             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]; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user