Improve tablist handling

This commit is contained in:
libraryaddict 2018-02-14 20:15:56 +13:00
parent e6c904be6a
commit 88bc7f5784
3 changed files with 133 additions and 138 deletions

View File

@ -43,7 +43,7 @@ import org.bukkit.scoreboard.Team;
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.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
@ -291,8 +291,8 @@ public class DisguiseListener implements Listener {
chunkMove(p, p.getLocation(), null); chunkMove(p, p.getLocation(), null);
} }
if (DisguiseConfig.isSaveGameProfiles() && DisguiseConfig.isUpdateGameProfiles() && DisguiseUtilities if (DisguiseConfig.isSaveGameProfiles() && DisguiseConfig.isUpdateGameProfiles() &&
.hasGameProfile(p.getName())) { DisguiseUtilities.hasGameProfile(p.getName())) {
WrappedGameProfile profile = WrappedGameProfile.fromPlayer(p); WrappedGameProfile profile = WrappedGameProfile.fromPlayer(p);
if (!profile.getProperties().isEmpty()) { if (!profile.getProperties().isEmpty()) {
@ -331,7 +331,7 @@ public class DisguiseListener implements Listener {
PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
addTab.getPlayerInfoDataLists().write(0, Arrays.asList( addTab.getPlayerInfoDataLists().write(0, Collections.singletonList(
new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL, new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(disguise.getGameProfile().getName())))); WrappedChatComponent.fromText(disguise.getGameProfile().getName()))));
@ -354,9 +354,9 @@ public class DisguiseListener implements Listener {
Location to = event.getTo(); Location to = event.getTo();
Location from = event.getFrom(); Location from = event.getFrom();
if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities.getChunkCord(from.getBlockX()) ||
.getChunkCord(from.getBlockX()) || DisguiseUtilities DisguiseUtilities.getChunkCord(to.getBlockZ()) !=
.getChunkCord(to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) { DisguiseUtilities.getChunkCord(from.getBlockZ())) {
chunkMove(event.getPlayer(), to, from); chunkMove(event.getPlayer(), to, from);
} }
} }
@ -365,8 +365,8 @@ public class DisguiseListener implements Listener {
Disguise disguise; Disguise disguise;
if ((disguise = DisguiseAPI.getDisguise(event.getPlayer())) != null) { if ((disguise = DisguiseAPI.getDisguise(event.getPlayer())) != null) {
if (disguise if (disguise.getType() ==
.getType() == DisguiseType.SHULKER) { // Stop Shulker disguises from moving their coordinates DisguiseType.SHULKER) { // Stop Shulker disguises from moving their coordinates
Location from = event.getFrom(); Location from = event.getFrom();
Location to = event.getTo(); Location to = event.getTo();
@ -422,8 +422,8 @@ public class DisguiseListener implements Listener {
public void onRightClick(PlayerInteractEntityEvent event) { public void onRightClick(PlayerInteractEntityEvent event) {
Player p = event.getPlayer(); Player p = event.getPlayer();
if (!disguiseEntity.containsKey(p.getName()) && !disguiseClone.containsKey(p.getName()) && !disguiseModify if (!disguiseEntity.containsKey(p.getName()) && !disguiseClone.containsKey(p.getName()) &&
.containsKey(p.getName())) { !disguiseModify.containsKey(p.getName())) {
return; return;
} }
@ -447,8 +447,8 @@ public class DisguiseListener implements Listener {
Disguise disguise = disguiseEntity.remove(p.getName()); Disguise disguise = disguiseEntity.remove(p.getName());
if (disguise != null) { if (disguise != null) {
if (disguise.isMiscDisguise() && !DisguiseConfig if (disguise.isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() &&
.isMiscDisguisesForLivingEnabled() && entity instanceof LivingEntity) { entity instanceof LivingEntity) {
p.sendMessage(LibsMsg.DISABLED_LIVING_TO_MISC.get()); p.sendMessage(LibsMsg.DISABLED_LIVING_TO_MISC.get());
} else { } else {
if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) { if (entity instanceof Player && DisguiseConfig.isNameOfPlayerShownAboveDisguise()) {
@ -456,8 +456,8 @@ public class DisguiseListener implements Listener {
Team team = ((Player) entity).getScoreboard().getEntryTeam(entity.getName()); Team team = ((Player) entity).getScoreboard().getEntryTeam(entity.getName());
disguise.getWatcher().setCustomName( disguise.getWatcher().setCustomName(
(team == null ? "" : team.getPrefix()) + entity.getName() + (team == null ? "" : (team == null ? "" : team.getPrefix()) + entity.getName() +
team.getSuffix())); (team == null ? "" : team.getSuffix()));
if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) { if (DisguiseConfig.isNameAboveHeadAlwaysVisible()) {
disguise.getWatcher().setCustomNameVisible(true); disguise.getWatcher().setCustomNameVisible(true);
@ -561,8 +561,8 @@ public class DisguiseListener implements Listener {
@EventHandler @EventHandler
public void onTarget(EntityTargetEvent event) { public void onTarget(EntityTargetEvent event) {
if (DisguiseConfig.isMonstersIgnoreDisguises() && event.getTarget() != null && event if (DisguiseConfig.isMonstersIgnoreDisguises() && event.getTarget() != null &&
.getTarget() instanceof Player && DisguiseAPI.isDisguised(event.getTarget())) { event.getTarget() instanceof Player && DisguiseAPI.isDisguised(event.getTarget())) {
switch (event.getReason()) { switch (event.getReason()) {
case TARGET_ATTACKED_ENTITY: case TARGET_ATTACKED_ENTITY:
case TARGET_ATTACKED_OWNER: case TARGET_ATTACKED_OWNER:
@ -583,9 +583,9 @@ public class DisguiseListener implements Listener {
Location from = event.getFrom(); Location from = event.getFrom();
if (DisguiseConfig.isBedPacketsEnabled()) { if (DisguiseConfig.isBedPacketsEnabled()) {
if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities if (DisguiseUtilities.getChunkCord(to.getBlockX()) != DisguiseUtilities.getChunkCord(from.getBlockX()) ||
.getChunkCord(from.getBlockX()) || DisguiseUtilities DisguiseUtilities.getChunkCord(to.getBlockZ()) !=
.getChunkCord(to.getBlockZ()) != DisguiseUtilities.getChunkCord(from.getBlockZ())) { DisguiseUtilities.getChunkCord(from.getBlockZ())) {
chunkMove(player, null, from); chunkMove(player, null, from);
Bukkit.getScheduler().runTask(plugin, new Runnable() { Bukkit.getScheduler().runTask(plugin, new Runnable() {
@ -601,8 +601,8 @@ public class DisguiseListener implements Listener {
return; return;
} }
if (DisguiseConfig.isUndisguiseOnWorldChange() && to.getWorld() != null && from.getWorld() != null && to if (DisguiseConfig.isUndisguiseOnWorldChange() && to.getWorld() != null && from.getWorld() != null &&
.getWorld() != from.getWorld()) { to.getWorld() != from.getWorld()) {
for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) { for (Disguise disguise : DisguiseAPI.getDisguises(event.getPlayer())) {
disguise.removeDisguise(); disguise.removeDisguise();
} }
@ -611,8 +611,8 @@ public class DisguiseListener implements Listener {
@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 if (event.getEntered() instanceof Player &&
.isDisguised((Player) event.getEntered(), event.getEntered())) { DisguiseAPI.isDisguised((Player) event.getEntered(), event.getEntered())) {
DisguiseUtilities.removeSelfDisguise((Player) event.getEntered()); DisguiseUtilities.removeSelfDisguise((Player) event.getEntered());
((Player) event.getEntered()).updateInventory(); ((Player) event.getEntered()).updateInventory();

View File

@ -29,7 +29,6 @@ import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitTask; import org.bukkit.scheduler.BukkitTask;
import org.bukkit.util.Vector; import org.bukkit.util.Vector;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.util.*; import java.util.*;
@ -74,8 +73,9 @@ public abstract class Disguise {
*/ */
protected void createDisguise() { protected void createDisguise() {
if (getType().getEntityType() == null) { if (getType().getEntityType() == null) {
throw new RuntimeException( throw new RuntimeException("DisguiseType " + getType() +
"DisguiseType " + getType() + " was used in a futile attempt to construct a disguise, but this Minecraft version does not have that entity"); " was used in a futile attempt to construct a disguise, but this Minecraft version does not have " +
"that entity");
} }
// Get if they are a adult now.. // Get if they are a adult now..
@ -193,7 +193,8 @@ public abstract class Disguise {
if (!getEntity().isValid()) { if (!getEntity().isValid()) {
// If it has been dead for 30+ ticks // If it has been dead for 30+ ticks
// This is to ensure that this disguise isn't removed while clients think its the real entity // This is to ensure that this disguise isn't removed while clients think its the real entity
// The delay is because if it sends the destroy entity packets straight away, then it means no death animation // The delay is because if it sends the destroy entity packets straight away, then it means no
// death animation
// This is probably still a problem for wither and enderdragon deaths. // This is probably still a problem for wither and enderdragon deaths.
if (deadTicks++ > (getType() == DisguiseType.ENDER_DRAGON ? 200 : 20)) { if (deadTicks++ > (getType() == DisguiseType.ENDER_DRAGON ? 200 : 20)) {
deadTicks = 0; deadTicks = 0;
@ -232,8 +233,8 @@ public abstract class Disguise {
int newFacing = (((int) loc.getYaw() + 720 + 45) / 90) % 4; int newFacing = (((int) loc.getYaw() + 720 + 45) / 90) % 4;
if (loc.getBlockX() != blockX || loc.getBlockY() != blockY || loc if (loc.getBlockX() != blockX || loc.getBlockY() != blockY || loc.getBlockZ() != blockZ ||
.getBlockZ() != blockZ || newFacing != facing) { newFacing != facing) {
blockX = loc.getBlockX(); blockX = loc.getBlockX();
blockY = loc.getBlockY(); blockY = loc.getBlockY();
blockZ = loc.getBlockZ(); blockZ = loc.getBlockZ();
@ -256,11 +257,12 @@ public abstract class Disguise {
if (isVelocitySent() && vectorY != 0 && (alwaysSendVelocity || !getEntity().isOnGround())) { if (isVelocitySent() && vectorY != 0 && (alwaysSendVelocity || !getEntity().isOnGround())) {
Vector vector = getEntity().getVelocity(); Vector vector = getEntity().getVelocity();
// If the entity doesn't have velocity changes already - You know. I really can't wrap my head about the // If the entity doesn't have velocity changes already - You know. I really can't wrap my
// head about the
// if statement. // if statement.
// But it doesn't seem to do anything wrong.. // But it doesn't seem to do anything wrong..
if (vector.getY() != 0 && !(vector.getY() < 0 && alwaysSendVelocity && getEntity() if (vector.getY() != 0 &&
.isOnGround())) { !(vector.getY() < 0 && alwaysSendVelocity && getEntity().isOnGround())) {
return; return;
} }
@ -268,8 +270,8 @@ public abstract class Disguise {
if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) { if (getType() != DisguiseType.EXPERIENCE_ORB || !getEntity().isOnGround()) {
PacketContainer lookPacket = null; PacketContainer lookPacket = null;
if (getType() == DisguiseType.WITHER_SKULL && DisguiseConfig if (getType() == DisguiseType.WITHER_SKULL &&
.isWitherSkullPacketsEnabled()) { DisguiseConfig.isWitherSkullPacketsEnabled()) {
lookPacket = new PacketContainer(Server.ENTITY_LOOK); lookPacket = new PacketContainer(Server.ENTITY_LOOK);
StructureModifier<Object> mods = lookPacket.getModifier(); StructureModifier<Object> mods = lookPacket.getModifier();
@ -332,7 +334,8 @@ public abstract class Disguise {
e.printStackTrace(); e.printStackTrace();
} }
} }
// If we need to send a packet to update the exp position as it likes to gravitate client sided to // If we need to send a packet to update the exp position as it likes to gravitate client
// sided to
// players. // players.
} }
if (getType() == DisguiseType.EXPERIENCE_ORB) { if (getType() == DisguiseType.EXPERIENCE_ORB) {
@ -395,7 +398,8 @@ public abstract class Disguise {
} }
/** /**
* In use doesn't mean that this disguise is active. It means that Lib's Disguises still stores a reference to the disguise. * In use doesn't mean that this disguise is active. It means that Lib's Disguises still stores a reference to
* the disguise.
* getEntity() can still return null if this disguise is active after despawn, logout, etc. * getEntity() can still return null if this disguise is active after despawn, logout, etc.
* *
* @return isDisguiseInUse * @return isDisguiseInUse
@ -443,8 +447,8 @@ public abstract class Disguise {
* Internal use * Internal use
*/ */
public boolean isRemoveDisguiseOnDeath() { public boolean isRemoveDisguiseOnDeath() {
return getEntity() == null || (getEntity() instanceof Player ? !isKeepDisguiseOnPlayerDeath() : return getEntity() == null ||
getEntity().isDead()); (getEntity() instanceof Player ? !isKeepDisguiseOnPlayerDeath() : getEntity().isDead());
} }
public boolean isSelfDisguiseSoundsReplaced() { public boolean isSelfDisguiseSoundsReplaced() {
@ -488,7 +492,7 @@ public abstract class Disguise {
Bukkit.getPluginManager().callEvent(event); Bukkit.getPluginManager().callEvent(event);
if (!event.isCancelled()) { if (!event.isCancelled() || (getEntity() instanceof Player && !((Player) getEntity()).isOnline())) {
disguiseInUse = false; disguiseInUse = false;
if (task != null) { if (task != null) {
@ -506,7 +510,7 @@ public abstract class Disguise {
if (disguise.isDisplayedInTab()) { if (disguise.isDisplayedInTab()) {
PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER); deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER);
deleteTab.getPlayerInfoDataLists().write(0, Arrays.asList( deleteTab.getPlayerInfoDataLists().write(0, Collections.singletonList(
new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL, new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(disguise.getName())))); WrappedChatComponent.fromText(disguise.getName()))));
@ -524,20 +528,23 @@ public abstract class Disguise {
} }
} }
if (isHidePlayer() && getEntity() instanceof Player) { if (isHidePlayer() && getEntity() instanceof Player && ((Player) getEntity()).isOnline()) {
PacketContainer deleteTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PlayerInfoData playerInfo = new PlayerInfoData(
deleteTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); ReflectionManager.getGameProfile((Player) getEntity()), 0,
deleteTab.getPlayerInfoDataLists().write(0, Arrays.asList( NativeGameMode.SURVIVAL, WrappedChatComponent
new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, .fromText(DisguiseUtilities.getPlayerListName((Player) getEntity())));
NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(DisguiseUtilities.getPlayerListName((Player) getEntity()))))); PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
addTab.getPlayerInfoDataLists().write(0, Collections.singletonList(playerInfo));
try { try {
for (Player player : Bukkit.getOnlinePlayers()) { for (Player player : Bukkit.getOnlinePlayers()) {
if (!((TargetedDisguise) this).canSee(player)) if (!((TargetedDisguise) this).canSee(player))
continue; continue;
ProtocolLibrary.getProtocolManager().sendServerPacket(player, deleteTab); ProtocolLibrary.getProtocolManager().sendServerPacket(player, addTab);
} }
} }
catch (InvocationTargetException e) { catch (InvocationTargetException e) {
@ -598,7 +605,8 @@ public abstract class Disguise {
if (isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && entity instanceof LivingEntity) { if (isMiscDisguise() && !DisguiseConfig.isMiscDisguisesForLivingEnabled() && entity instanceof LivingEntity) {
throw new RuntimeException( throw new RuntimeException(
"Cannot disguise a living entity with a misc disguise. Reenable MiscDisguisesForLiving in the config to do this"); "Cannot disguise a living entity with a misc disguise. Reenable MiscDisguisesForLiving in the " +
"config to do this");
} }
this.entity = entity; this.entity = entity;
@ -651,8 +659,8 @@ public abstract class Disguise {
public Disguise setModifyBoundingBox(boolean modifyBox) { public Disguise setModifyBoundingBox(boolean modifyBox) {
if (((TargetedDisguise) this).getDisguiseTarget() != TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) { if (((TargetedDisguise) this).getDisguiseTarget() != TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS) {
throw new RuntimeException( throw new RuntimeException("Cannot modify the bounding box of a disguise which is not TargetType" +
"Cannot modify the bounding box of a disguise which is not TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS"); ".SHOW_TO_EVERYONE_BUT_THESE_PLAYERS");
} }
if (isModifyBoundingBox() != modifyBox) { if (isModifyBoundingBox() != modifyBox) {
@ -679,7 +687,8 @@ public abstract class Disguise {
} }
/** /**
* Sets up the FlagWatcher with the entityclass, it creates all the data it needs to prevent conflicts when sending the * Sets up the FlagWatcher with the entityclass, it creates all the data it needs to prevent conflicts when
* sending the
* datawatcher. * datawatcher.
*/ */
private void setupWatcher() { private void setupWatcher() {
@ -736,9 +745,8 @@ public abstract class Disguise {
public Disguise setWatcher(FlagWatcher newWatcher) { public Disguise setWatcher(FlagWatcher newWatcher) {
if (!getType().getWatcherClass().isInstance(newWatcher)) { if (!getType().getWatcherClass().isInstance(newWatcher)) {
throw new IllegalArgumentException( throw new IllegalArgumentException(newWatcher.getClass().getSimpleName() + " is not a instance of " +
newWatcher.getClass().getSimpleName() + " is not a instance of " + getType().getWatcherClass() getType().getWatcherClass().getSimpleName() + " for DisguiseType " + getType().name());
.getSimpleName() + " for DisguiseType " + getType().name());
} }
watcher = newWatcher; watcher = newWatcher;
@ -788,7 +796,7 @@ public abstract class Disguise {
if (disguise.isDisplayedInTab()) { if (disguise.isDisplayedInTab()) {
PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER); addTab.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
addTab.getPlayerInfoDataLists().write(0, Arrays.asList( addTab.getPlayerInfoDataLists().write(0, Collections.singletonList(
new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL, new PlayerInfoData(disguise.getGameProfile(), 0, NativeGameMode.SURVIVAL,
WrappedChatComponent.fromText(disguise.getName())))); WrappedChatComponent.fromText(disguise.getName()))));
@ -828,7 +836,7 @@ public abstract class Disguise {
if (isHidePlayer() && getEntity() instanceof Player) { if (isHidePlayer() && getEntity() instanceof Player) {
PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO); PacketContainer addTab = new PacketContainer(PacketType.Play.Server.PLAYER_INFO);
addTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER); addTab.getPlayerInfoAction().write(0, PlayerInfoAction.REMOVE_PLAYER);
addTab.getPlayerInfoDataLists().write(0, Arrays.asList( addTab.getPlayerInfoDataLists().write(0, Collections.singletonList(
new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0, new PlayerInfoData(ReflectionManager.getGameProfile((Player) getEntity()), 0,
NativeGameMode.SURVIVAL, WrappedChatComponent.fromText("")))); NativeGameMode.SURVIVAL, WrappedChatComponent.fromText(""))));

View File

@ -1,27 +1,5 @@
package me.libraryaddict.disguise.utilities; package me.libraryaddict.disguise.utilities;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map.Entry;
import java.util.UUID;
import org.bukkit.Art;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import com.comphenix.protocol.PacketType; import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.PacketType.Play; import com.comphenix.protocol.PacketType.Play;
import com.comphenix.protocol.PacketType.Play.Server; import com.comphenix.protocol.PacketType.Play.Server;
@ -36,24 +14,26 @@ import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject; import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
import com.comphenix.protocol.wrappers.WrappedGameProfile; import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedWatchableObject; import com.comphenix.protocol.wrappers.WrappedWatchableObject;
import me.libraryaddict.disguise.DisguiseAPI; import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseConfig; import me.libraryaddict.disguise.DisguiseConfig;
import me.libraryaddict.disguise.LibsDisguises; import me.libraryaddict.disguise.LibsDisguises;
import me.libraryaddict.disguise.disguisetypes.Disguise; import me.libraryaddict.disguise.disguisetypes.*;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.MetaIndex;
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
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.disguisetypes.watchers.PlayerWatcher;
import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerClientInteract; import me.libraryaddict.disguise.utilities.packetlisteners.*;
import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerInventory; import org.bukkit.Art;
import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerMain; import org.bukkit.Bukkit;
import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerSounds; import org.bukkit.Location;
import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerTabList; import org.bukkit.Material;
import me.libraryaddict.disguise.utilities.packetlisteners.PacketListenerViewDisguises; import org.bukkit.entity.*;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.util.Vector;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.Map.Entry;
public class PacketsManager { public class PacketsManager {
public static class LibsPackets { public static class LibsPackets {
@ -222,8 +202,8 @@ public class PacketsManager {
if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) { if (((LivingWatcher) disguise.getWatcher()).isMaxHealthSet()) {
builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth()); builder.baseValue(((LivingWatcher) disguise.getWatcher()).getMaxHealth());
} else if (DisguiseConfig } else if (DisguiseConfig.isMaxHealthDeterminedByDisguisedEntity() &&
.isMaxHealthDeterminedByDisguisedEntity() && disguisedEntity instanceof Damageable) { disguisedEntity instanceof Damageable) {
builder.baseValue(((Damageable) disguisedEntity).getMaxHealth()); builder.baseValue(((Damageable) disguisedEntity).getMaxHealth());
} else { } else {
builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth()); builder.baseValue(DisguiseValues.getDisguiseValues(disguise.getType()).getMaxHealth());
@ -294,22 +274,23 @@ public class PacketsManager {
PlayerDisguise playerDisguise = (PlayerDisguise) disguise; PlayerDisguise playerDisguise = (PlayerDisguise) disguise;
String name = playerDisguise.getName(); String name = playerDisguise.getName();
WrappedGameProfile gameProfile = playerDisguise.getGameProfile();
int entityId = disguisedEntity.getEntityId(); int entityId = disguisedEntity.getEntityId();
// Send player info along with the disguise // Send player info along with the disguise
PacketContainer sendTab = new PacketContainer(Server.PLAYER_INFO); PacketContainer sendTab = new PacketContainer(Server.PLAYER_INFO);
if (!((PlayerDisguise) disguise).isDisplayedInTab()) if (!((PlayerDisguise) disguise).isDisplayedInTab()) {
// Add player to the list, necessary to spawn them
sendTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0));
List playerList = Collections
.singletonList(ReflectionManager.getPlayerInfoData(sendTab.getHandle(), gameProfile));
sendTab.getModifier().write(1, playerList);
packets.addPacket(sendTab); packets.addPacket(sendTab);
}
// Add player to the list, necessary to spawn them
sendTab.getModifier().write(0, ReflectionManager.getEnumPlayerInfoAction(0));
WrappedGameProfile gameProfile = playerDisguise.getGameProfile();
List playerList = new ArrayList();
playerList.add(ReflectionManager.getPlayerInfoData(sendTab.getHandle(), gameProfile));
sendTab.getModifier().write(1, playerList);
// Spawn the player // Spawn the player
PacketContainer spawnPlayer = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN); PacketContainer spawnPlayer = new PacketContainer(PacketType.Play.Server.NAMED_ENTITY_SPAWN);
@ -453,7 +434,8 @@ public class PacketsManager {
if (disguise.getType() == DisguiseType.FALLING_BLOCK) { if (disguise.getType() == DisguiseType.FALLING_BLOCK) {
data = ReflectionManager.getCombinedId(((MiscDisguise) disguise).getId(), data); data = ReflectionManager.getCombinedId(((MiscDisguise) disguise).getId(), data);
} else if (disguise.getType() == DisguiseType.FISHING_HOOK && data == -1) { } else if (disguise.getType() == DisguiseType.FISHING_HOOK && data == -1) {
// If the MiscDisguise data isn't set. Then no entity id was provided, so default to the owners entity id // If the MiscDisguise data isn't set. Then no entity id was provided, so default to the owners
// entity id
data = observer.getEntityId(); data = observer.getEntityId();
} else if (disguise.getType() == DisguiseType.ITEM_FRAME) { } else if (disguise.getType() == DisguiseType.ITEM_FRAME) {
data = ((((int) loc.getYaw() % 360) + 720 + 45) / 90) % 4; data = ((((int) loc.getYaw() % 360) + 720 + 45) / 90) % 4;
@ -637,8 +619,8 @@ public class PacketsManager {
public 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()) if ((disguise.getType() != DisguiseType.PLAYER || !((PlayerWatcher) disguise.getWatcher()).isSleeping()) &&
.isSleeping()) && entity.getType() == EntityType.DROPPED_ITEM) { entity.getType() == EntityType.DROPPED_ITEM) {
yMod -= 0.13; yMod -= 0.13;
} }
@ -743,8 +725,8 @@ public class PacketsManager {
Disguise disguise = DisguiseAPI.getDisguise(player, player); Disguise disguise = DisguiseAPI.getDisguise(player, player);
if (disguise != null) { if (disguise != null) {
if (viewDisguisesListenerEnabled && disguise.isSelfDisguiseVisible() && (disguise if (viewDisguisesListenerEnabled && disguise.isSelfDisguiseVisible() &&
.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) { (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) {
player.updateInventory(); player.updateInventory();
} }
} }
@ -838,8 +820,8 @@ public class PacketsManager {
DisguiseUtilities.removeSelfDisguise(player); DisguiseUtilities.removeSelfDisguise(player);
} }
if (inventoryModifierEnabled && (disguise.isHidingArmorFromSelf() || disguise if (inventoryModifierEnabled &&
.isHidingHeldItemFromSelf())) { (disguise.isHidingArmorFromSelf() || disguise.isHidingHeldItemFromSelf())) {
player.updateInventory(); player.updateInventory();
} }
} }
@ -849,7 +831,8 @@ public class PacketsManager {
} }
/** /**
* Transform the packet magically into the one I have always dreamed off. My true luv!!! This will return null if its not * Transform the packet magically into the one I have always dreamed off. My true luv!!! This will return null if
* its not
* transformed * transformed
*/ */
public static LibsPackets transformPacket(PacketContainer sentPacket, Disguise disguise, Player observer, public static LibsPackets transformPacket(PacketContainer sentPacket, Disguise disguise, Player observer,
@ -907,8 +890,8 @@ public class PacketsManager {
else if (sentPacket.getType() == Server.ENTITY_METADATA) { else if (sentPacket.getType() == Server.ENTITY_METADATA) {
packets.clear(); packets.clear();
if (DisguiseConfig.isMetadataPacketsEnabled() && (!cancelMeta.containsKey(disguise) || !cancelMeta if (DisguiseConfig.isMetadataPacketsEnabled() && (!cancelMeta.containsKey(disguise) ||
.get(disguise).contains(observer.getUniqueId()))) { !cancelMeta.get(disguise).contains(observer.getUniqueId()))) {
List<WrappedWatchableObject> watchableObjects = disguise.getWatcher() List<WrappedWatchableObject> watchableObjects = disguise.getWatcher()
.convert(sentPacket.getWatchableCollectionModifier().read(0)); .convert(sentPacket.getWatchableCollectionModifier().read(0));
@ -925,10 +908,11 @@ public class PacketsManager {
} }
// Else if the packet is spawning.. // Else if the packet is spawning..
else if (sentPacket.getType() == Server.NAMED_ENTITY_SPAWN || sentPacket else if (sentPacket.getType() == Server.NAMED_ENTITY_SPAWN ||
.getType() == Server.SPAWN_ENTITY_LIVING || sentPacket sentPacket.getType() == Server.SPAWN_ENTITY_LIVING ||
.getType() == Server.SPAWN_ENTITY_EXPERIENCE_ORB || sentPacket sentPacket.getType() == Server.SPAWN_ENTITY_EXPERIENCE_ORB ||
.getType() == Server.SPAWN_ENTITY || sentPacket.getType() == Server.SPAWN_ENTITY_PAINTING) { sentPacket.getType() == Server.SPAWN_ENTITY ||
sentPacket.getType() == Server.SPAWN_ENTITY_PAINTING) {
packets.clear(); packets.clear();
constructSpawnPackets(observer, packets, entity); constructSpawnPackets(observer, packets, entity);
@ -936,9 +920,9 @@ public class PacketsManager {
// Else if the disguise is attempting to send players a forbidden packet // Else if the disguise is attempting to send players a forbidden packet
else if (sentPacket.getType() == Server.ANIMATION) { else if (sentPacket.getType() == Server.ANIMATION) {
if (disguise.getType().isMisc() || (sentPacket.getIntegers().read(1) == 2 && (!disguise.getType() if (disguise.getType().isMisc() || (sentPacket.getIntegers().read(1) == 2 &&
.isPlayer() || (DisguiseConfig.isBedPacketsEnabled() && ((PlayerWatcher) disguise.getWatcher()) (!disguise.getType().isPlayer() || (DisguiseConfig.isBedPacketsEnabled() &&
.isSleeping())))) { ((PlayerWatcher) disguise.getWatcher()).isSleeping())))) {
packets.clear(); packets.clear();
} }
} }
@ -947,8 +931,8 @@ public class PacketsManager {
else if (sentPacket.getType() == Server.COLLECT) { else if (sentPacket.getType() == Server.COLLECT) {
if (disguise.getType().isMisc()) { if (disguise.getType().isMisc()) {
packets.clear(); packets.clear();
} else if (DisguiseConfig.isBedPacketsEnabled() && disguise.getType() } else if (DisguiseConfig.isBedPacketsEnabled() && disguise.getType().isPlayer() &&
.isPlayer() && ((PlayerWatcher) disguise.getWatcher()).isSleeping()) { ((PlayerWatcher) disguise.getWatcher()).isSleeping()) {
PacketContainer newPacket = new PacketContainer(Server.ANIMATION); PacketContainer newPacket = new PacketContainer(Server.ANIMATION);
StructureModifier<Integer> mods = newPacket.getIntegers(); StructureModifier<Integer> mods = newPacket.getIntegers();
@ -963,17 +947,18 @@ public class PacketsManager {
} }
// Else if the disguise is moving. // Else if the disguise is moving.
else if (sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK || sentPacket else if (sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK ||
.getType() == Server.ENTITY_LOOK || sentPacket.getType() == Server.ENTITY_TELEPORT || sentPacket sentPacket.getType() == Server.ENTITY_LOOK || sentPacket.getType() == Server.ENTITY_TELEPORT ||
.getType() == Server.REL_ENTITY_MOVE) { sentPacket.getType() == Server.REL_ENTITY_MOVE) {
if (disguise.getType() == DisguiseType.RABBIT && (sentPacket if (disguise.getType() == DisguiseType.RABBIT && (sentPacket.getType() == Server.REL_ENTITY_MOVE ||
.getType() == Server.REL_ENTITY_MOVE || sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK)) { sentPacket.getType() == Server.REL_ENTITY_MOVE_LOOK)) {
// Rabbit robbing... // Rabbit robbing...
if (entity.getMetadata("LibsRabbitHop").isEmpty() || System.currentTimeMillis() - entity if (entity.getMetadata("LibsRabbitHop").isEmpty() ||
.getMetadata("LibsRabbitHop").get(0).asLong() < 100 || System.currentTimeMillis() - entity System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() < 100 ||
.getMetadata("LibsRabbitHop").get(0).asLong() > 500) { System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() > 500) {
if (entity.getMetadata("LibsRabbitHop").isEmpty() || System.currentTimeMillis() - entity if (entity.getMetadata("LibsRabbitHop").isEmpty() ||
.getMetadata("LibsRabbitHop").get(0).asLong() > 500) { System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() >
500) {
entity.removeMetadata("LibsRabbitHop", libsDisguises); entity.removeMetadata("LibsRabbitHop", libsDisguises);
entity.setMetadata("LibsRabbitHop", entity.setMetadata("LibsRabbitHop",
new FixedMetadataValue(libsDisguises, System.currentTimeMillis())); new FixedMetadataValue(libsDisguises, System.currentTimeMillis()));
@ -1005,8 +990,8 @@ public class PacketsManager {
bytes.write(0, getYaw(disguise.getType(), entity.getType(), yawValue)); bytes.write(0, getYaw(disguise.getType(), entity.getType(), yawValue));
bytes.write(1, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue)); bytes.write(1, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue));
if (sentPacket.getType() == Server.ENTITY_TELEPORT && disguise if (sentPacket.getType() == Server.ENTITY_TELEPORT &&
.getType() == DisguiseType.ITEM_FRAME) { disguise.getType() == DisguiseType.ITEM_FRAME) {
StructureModifier<Double> doubles = movePacket.getDoubles(); StructureModifier<Double> doubles = movePacket.getDoubles();
Location loc = entity.getLocation(); Location loc = entity.getLocation();
@ -1084,7 +1069,8 @@ public class PacketsManager {
watcher.setValue((byte) ((byte) watcher.getValue() & ~(1 << 4))); watcher.setValue((byte) ((byte) watcher.getValue() & ~(1 << 4)));
} }
// Send the unblock before the itemstack change so that the 2nd metadata packet works. Why? Scheduler // Send the unblock before the itemstack change so that the 2nd metadata packet works. Why?
// Scheduler
// delay. // delay.
PacketContainer packet1 = packets.getPackets().get(0); PacketContainer packet1 = packets.getPackets().get(0);
@ -1094,7 +1080,8 @@ public class PacketsManager {
packets.addPacket(packetUnblock); packets.addPacket(packetUnblock);
packets.addPacket(packet1); packets.addPacket(packet1);
packets.addPacket(packetBlock); packets.addPacket(packetBlock);
// Silly mojang made the right clicking datawatcher value only valid for one use. So I have to reset // Silly mojang made the right clicking datawatcher value only valid for one use. So I have
// to reset
// it. // it.
} }
} }