Temporary patch for sounds not working

Replaced some code with Craftbukkit versions
This commit is contained in:
NavidK0 2016-03-06 03:38:14 -05:00
parent 99daf8246d
commit c972d02113
3 changed files with 254 additions and 249 deletions

View File

@ -1,9 +1,7 @@
package me.libraryaddict.disguise.utilities;
import com.comphenix.protocol.wrappers.MinecraftKey;
import org.bukkit.Sound;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
@ -125,22 +123,6 @@ public enum DisguiseSound {
}
}
/**
* Necessary for 1.9
* @return
*/
public static String convertSoundEffectToString(Object soundEffect) {
try {
Field f_getMinecraftKey = ReflectionManager.getNmsField("SoundEffect", "b");
f_getMinecraftKey.setAccessible(true);
MinecraftKey key = MinecraftKey.fromHandle(f_getMinecraftKey.get(soundEffect));
return key.getKey();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public float getDamageAndIdleSoundVolume() {
return damageSoundVolume;
}

View File

@ -22,18 +22,15 @@ import me.libraryaddict.disguise.disguisetypes.Disguise;
import me.libraryaddict.disguise.disguisetypes.DisguiseType;
import me.libraryaddict.disguise.disguisetypes.FlagWatcher;
import me.libraryaddict.disguise.disguisetypes.MiscDisguise;
import me.libraryaddict.disguise.disguisetypes.MobDisguise;
import me.libraryaddict.disguise.disguisetypes.PlayerDisguise;
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.PlayerWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.SheepWatcher;
import me.libraryaddict.disguise.disguisetypes.watchers.WolfWatcher;
import me.libraryaddict.disguise.utilities.DisguiseSound.SoundType;
import org.bukkit.Art;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Ageable;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Entity;
@ -42,7 +39,6 @@ import org.bukkit.entity.ExperienceOrb;
import org.bukkit.entity.Item;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Zombie;
import org.bukkit.inventory.EquipmentSlot;
import org.bukkit.inventory.ItemStack;
import org.bukkit.metadata.FixedMetadataValue;
@ -51,7 +47,6 @@ import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.UUID;
public class PacketsManager {
@ -325,6 +320,7 @@ public class PacketsManager {
* Create a new datawatcher but with the 'correct' values
*/
private static WrappedDataWatcher createDataWatcher(WrappedDataWatcher watcher, FlagWatcher flagWatcher) {
//TODO: Specify a serializer...
WrappedDataWatcher newWatcher = new WrappedDataWatcher();
try {
List<WrappedWatchableObject> list = DisguiseConfig.isMetadataPacketsEnabled() ?
@ -495,226 +491,227 @@ public class PacketsManager {
Server.ENTITY_STATUS) {
@Override
public void onPacketSending(PacketEvent event) {
if (event.isCancelled()) {
return;
}
event.setPacket(event.getPacket().deepClone());
StructureModifier<Object> mods = event.getPacket().getModifier();
Player observer = event.getPlayer();
if (event.getPacketType() == Server.NAMED_SOUND_EFFECT) {
if (event.isAsync()) {
return;
}
Object soundEffect = mods.read(0);
SoundType soundType = null;
Location soundLoc = new Location(observer.getWorld(), ((Integer) mods.read(1)) / 8D,
((Integer) mods.read(2)) / 8D, ((Integer) mods.read(3)) / 8D);
Entity disguisedEntity = null;
DisguiseSound entitySound = null;
Disguise disguise = null;
Entity[] entities = soundLoc.getChunk().getEntities();
for (Entity entity : entities) {
Disguise entityDisguise = DisguiseAPI.getDisguise(observer, entity);
if (entityDisguise != null) {
Location loc = entity.getLocation();
loc = new Location(observer.getWorld(), ((int) (loc.getX() * 8)) / 8D, ((int) (loc.getY() * 8)) / 8D,
((int) (loc.getZ() * 8)) / 8D);
if (loc.equals(soundLoc)) {
entitySound = DisguiseSound.getType(entity.getType().name());
if (entitySound != null) {
Object obj = null;
if (entity instanceof LivingEntity) {
try {
// Use reflection so that this works for either int or double methods
obj = LivingEntity.class.getMethod("getHealth").invoke(entity);
if (obj instanceof Double ? (Double) obj == 0 : (Integer) obj == 0) {
soundType = SoundType.DEATH;
} else {
obj = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (obj == null) {
boolean hasInvun = false;
Object nmsEntity = ReflectionManager.getNmsEntity(entity);
try {
if (entity instanceof LivingEntity) {
hasInvun = ReflectionManager.getNmsField("Entity", "noDamageTicks").getInt(
nmsEntity) == ReflectionManager.getNmsField("EntityLiving",
"maxNoDamageTicks").getInt(nmsEntity);
} else {
Class clazz = ReflectionManager.getNmsClass("DamageSource");
hasInvun = (Boolean) ReflectionManager.getNmsMethod("Entity", "isInvulnerable", clazz)
.invoke(nmsEntity, ReflectionManager.getNmsField(clazz, "GENERIC"));
}
} catch (Exception ex) {
ex.printStackTrace();
}
soundType = entitySound.getType(DisguiseSound.convertSoundEffectToString(soundEffect), !hasInvun);
}
if (soundType != null) {
disguise = entityDisguise;
disguisedEntity = entity;
break;
}
}
}
}
}
if (disguise != null) {
if (disguise.isSelfDisguiseSoundsReplaced() || disguisedEntity != event.getPlayer()) {
if (disguise.isSoundsReplaced()) {
String sound = null;
DisguiseSound dSound = DisguiseSound.getType(disguise.getType().name());
if (dSound != null)
sound = dSound.getSound(soundType);
if (sound == null) {
event.setCancelled(true);
} else {
if (sound.equals("step.grass")) {
try {
int typeId = soundLoc.getWorld().getBlockTypeIdAt(soundLoc.getBlockX(),
soundLoc.getBlockY() - 1, soundLoc.getBlockZ());
Object block = ReflectionManager.getNmsMethod("RegistryMaterials", "a", int.class)
.invoke(ReflectionManager.getNmsField("Block", "REGISTRY").get(null),
typeId);
if (block != null) {
Object step = ReflectionManager.getNmsField("Block", "stepSound").get(block);
mods.write(0, ReflectionManager.getNmsMethod(step.getClass(), "getStepSound").invoke(step));
}
} catch (Exception ex) {
ex.printStackTrace();
}
// There is no else statement. Because seriously. This should never be null. Unless
// someone is
// sending fake sounds. In which case. Why cancel it.
} else {
mods.write(0, sound);
// Time to change the pitch and volume
if (soundType == SoundType.HURT || soundType == SoundType.DEATH
|| soundType == SoundType.IDLE) {
// If the volume is the default
if (mods.read(4).equals(entitySound.getDamageAndIdleSoundVolume())) {
mods.write(4, dSound.getDamageAndIdleSoundVolume());
}
// Here I assume its the default pitch as I can't calculate if its real.
if (disguise instanceof MobDisguise && disguisedEntity instanceof LivingEntity
&& ((MobDisguise) disguise).doesDisguiseAge()) {
boolean baby = false;
if (disguisedEntity instanceof Zombie) {
baby = ((Zombie) disguisedEntity).isBaby();
} else if (disguisedEntity instanceof Ageable) {
baby = !((Ageable) disguisedEntity).isAdult();
}
if (((MobDisguise) disguise).isAdult() == baby) {
float pitch = (Integer) mods.read(5);
if (baby) {
// If the pitch is not the expected
if (pitch > 97 || pitch < 111)
return;
pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.5F;
// Min = 1.5
// Cap = 97.5
// Max = 1.7
// Cap = 110.5
} else {
// If the pitch is not the expected
if (pitch >= 63 || pitch <= 76)
return;
pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.0F;
// Min = 1
// Cap = 63
// Max = 1.2
// Cap = 75.6
}
pitch *= 63;
if (pitch < 0)
pitch = 0;
if (pitch > 255)
pitch = 255;
mods.write(5, (int) pitch);
}
}
}
}
}
}
}
}
} else if (event.getPacketType() == Server.ENTITY_STATUS) {
if ((byte) mods.read(1) == 2) {
// It made a damage animation
Entity entity = event.getPacket().getEntityModifier(observer.getWorld()).read(0);
Disguise disguise = DisguiseAPI.getDisguise(observer, entity);
if (disguise != null && !disguise.getType().isPlayer()
&& (disguise.isSelfDisguiseSoundsReplaced() || entity != event.getPlayer())) {
DisguiseSound disSound = DisguiseSound.getType(entity.getType().name());
if (disSound == null)
return;
SoundType soundType = null;
Object obj = null;
if (entity instanceof LivingEntity) {
try {
obj = LivingEntity.class.getMethod("getHealth").invoke(entity);
if (obj instanceof Double ? (Double) obj == 0 : (Integer) obj == 0) {
soundType = SoundType.DEATH;
} else {
obj = null;
}
} catch (Exception e) {
e.printStackTrace();
}
}
if (obj == null) {
soundType = SoundType.HURT;
}
if (disSound.getSound(soundType) == null
|| (disguise.isSelfDisguiseSoundsReplaced() && entity == event.getPlayer())) {
if (disguise.isSelfDisguiseSoundsReplaced() && entity == event.getPlayer()) {
cancelSound = !cancelSound;
if (cancelSound)
return;
}
disSound = DisguiseSound.getType(disguise.getType().name());
if (disSound != null) {
String sound = disSound.getSound(soundType);
if (sound != null) {
Location loc = entity.getLocation();
PacketContainer packet = new PacketContainer(Server.NAMED_SOUND_EFFECT);
mods = packet.getModifier();
mods.write(0, sound);
mods.write(1, (int) (loc.getX() * 8D));
mods.write(2, (int) (loc.getY() * 8D));
mods.write(3, (int) (loc.getZ() * 8D));
mods.write(4, disSound.getDamageAndIdleSoundVolume());
float pitch;
if (disguise instanceof MobDisguise && !((MobDisguise) disguise).isAdult()) {
pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.5F;
} else
pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.0F;
if (disguise.getType() == DisguiseType.BAT)
pitch *= 95F;
pitch *= 63;
if (pitch < 0)
pitch = 0;
if (pitch > 255)
pitch = 255;
mods.write(5, (int) pitch);
try {
ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}
}
}
//TODO: Fix this later once ProtocolLib's deepClone for NamedSoundEffect and EntityStatus is fixed
// if (event.isCancelled()) {
// return;
// }
// event.setPacket(event.getPacket().deepClone());
// StructureModifier<Object> mods = event.getPacket().getModifier();
// Player observer = event.getPlayer();
// if (event.getPacketType() == Server.NAMED_SOUND_EFFECT) {
//// if (event.isAsync()) {
//// return;
//// }
//// Object soundEffect = mods.read(0);
//// SoundType soundType = null;
//// Location soundLoc = new Location(observer.getWorld(), ((Integer) mods.read(2)) / 8D,
//// ((Integer) mods.read(3)) / 8D, ((Integer) mods.read(4)) / 8D);
//// Entity disguisedEntity = null;
//// DisguiseSound entitySound = null;
//// Disguise disguise = null;
//// Entity[] entities = soundLoc.getChunk().getEntities();
//// for (Entity entity : entities) {
//// Disguise entityDisguise = DisguiseAPI.getDisguise(observer, entity);
//// if (entityDisguise != null) {
//// Location loc = entity.getLocation();
//// loc = new Location(observer.getWorld(), ((int) (loc.getX() * 8)) / 8D, ((int) (loc.getY() * 8)) / 8D,
//// ((int) (loc.getZ() * 8)) / 8D);
//// if (loc.equals(soundLoc)) {
//// entitySound = DisguiseSound.getType(entity.getType().name());
//// if (entitySound != null) {
//// Object obj = null;
//// if (entity instanceof LivingEntity) {
//// try {
//// // Use reflection so that this works for either int or double methods
//// obj = LivingEntity.class.getMethod("getHealth").invoke(entity);
//// if (obj instanceof Double ? (Double) obj == 0 : (Integer) obj == 0) {
//// soundType = SoundType.DEATH;
//// } else {
//// obj = null;
//// }
//// } catch (Exception e) {
//// e.printStackTrace();
//// }
//// }
//// if (obj == null) {
//// boolean hasInvun = false;
//// Object nmsEntity = ReflectionManager.getNmsEntity(entity);
//// try {
//// if (entity instanceof LivingEntity) {
//// hasInvun = ReflectionManager.getNmsField("Entity", "noDamageTicks").getInt(
//// nmsEntity) == ReflectionManager.getNmsField("EntityLiving",
//// "maxNoDamageTicks").getInt(nmsEntity);
//// } else {
//// Class clazz = ReflectionManager.getNmsClass("DamageSource");
//// hasInvun = (Boolean) ReflectionManager.getNmsMethod("Entity", "isInvulnerable", clazz)
//// .invoke(nmsEntity, ReflectionManager.getNmsField(clazz, "GENERIC"));
//// }
//// } catch (Exception ex) {
//// ex.printStackTrace();
//// }
//// soundType = entitySound.getType(ReflectionManager.convertSoundEffectToString(soundEffect), !hasInvun);
//// }
//// if (soundType != null) {
//// disguise = entityDisguise;
//// disguisedEntity = entity;
//// break;
//// }
//// }
//// }
//// }
//// }
//// if (disguise != null) {
//// if (disguise.isSelfDisguiseSoundsReplaced() || disguisedEntity != event.getPlayer()) {
//// if (disguise.isSoundsReplaced()) {
//// String sound = null;
//// DisguiseSound dSound = DisguiseSound.getType(disguise.getType().name());
//// if (dSound != null)
//// sound = dSound.getSound(soundType);
////
//// if (sound == null) {
//// event.setCancelled(true);
//// } else {
//// if (sound.equals("step.grass")) {
//// try {
//// int typeId = soundLoc.getWorld().getBlockTypeIdAt(soundLoc.getBlockX(),
//// soundLoc.getBlockY() - 1, soundLoc.getBlockZ());
//// Object block = ReflectionManager.getNmsMethod("RegistryMaterials", "a", int.class)
//// .invoke(ReflectionManager.getNmsField("Block", "REGISTRY").get(null),
//// typeId);
//// if (block != null) {
//// Object step = ReflectionManager.getNmsField("Block", "stepSound").get(block);
//// mods.write(0, ReflectionManager.getNmsMethod(step.getClass(), "getStepSound").invoke(step));
//// }
//// } catch (Exception ex) {
//// ex.printStackTrace();
//// }
//// // There is no else statement. Because seriously. This should never be null. Unless
//// // someone is
//// // sending fake sounds. In which case. Why cancel it.
//// } else {
//// mods.write(0, ReflectionManager.getCraftSoundEffect(sound));
//// // Time to change the pitch and volume
//// if (soundType == SoundType.HURT || soundType == SoundType.DEATH
//// || soundType == SoundType.IDLE) {
//// // If the volume is the default
//// if (mods.read(5).equals(entitySound.getDamageAndIdleSoundVolume())) {
//// mods.write(5, dSound.getDamageAndIdleSoundVolume());
//// }
//// // Here I assume its the default pitch as I can't calculate if its real.
//// if (disguise instanceof MobDisguise && disguisedEntity instanceof LivingEntity
//// && ((MobDisguise) disguise).doesDisguiseAge()) {
//// boolean baby = false;
//// if (disguisedEntity instanceof Zombie) {
//// baby = ((Zombie) disguisedEntity).isBaby();
//// } else if (disguisedEntity instanceof Ageable) {
//// baby = !((Ageable) disguisedEntity).isAdult();
//// }
//// if (((MobDisguise) disguise).isAdult() == baby) {
////
//// float pitch = (Integer) mods.read(5);
//// if (baby) {
//// // If the pitch is not the expected
//// if (pitch > 97 || pitch < 111)
//// return;
//// pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.5F;
//// // Min = 1.5
//// // Cap = 97.5
//// // Max = 1.7
//// // Cap = 110.5
//// } else {
//// // If the pitch is not the expected
//// if (pitch >= 63 || pitch <= 76)
//// return;
//// pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.0F;
//// // Min = 1
//// // Cap = 63
//// // Max = 1.2
//// // Cap = 75.6
//// }
//// pitch *= 63;
//// if (pitch < 0)
//// pitch = 0;
//// if (pitch > 255)
//// pitch = 255;
//// mods.write(6, (int) pitch);
//// }
//// }
//// }
//// }
//// }
//// }
//// }
//// }
// } else if (event.getPacketType() == Server.ENTITY_STATUS) {
// if ((byte) mods.read(1) == 2) {
// // It made a damage animation
// Entity entity = event.getPacket().getEntityModifier(observer.getWorld()).read(0);
// Disguise disguise = DisguiseAPI.getDisguise(observer, entity);
// if (disguise != null && !disguise.getType().isPlayer()
// && (disguise.isSelfDisguiseSoundsReplaced() || entity != event.getPlayer())) {
// DisguiseSound disSound = DisguiseSound.getType(entity.getType().name());
// if (disSound == null)
// return;
// SoundType soundType = null;
// Object obj = null;
// if (entity instanceof LivingEntity) {
// try {
// obj = LivingEntity.class.getMethod("getHealth").invoke(entity);
// if (obj instanceof Double ? (Double) obj == 0 : (Integer) obj == 0) {
// soundType = SoundType.DEATH;
// } else {
// obj = null;
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// if (obj == null) {
// soundType = SoundType.HURT;
// }
// if (disSound.getSound(soundType) == null
// || (disguise.isSelfDisguiseSoundsReplaced() && entity == event.getPlayer())) {
// if (disguise.isSelfDisguiseSoundsReplaced() && entity == event.getPlayer()) {
// cancelSound = !cancelSound;
// if (cancelSound)
// return;
// }
// disSound = DisguiseSound.getType(disguise.getType().name());
// if (disSound != null) {
// String sound = disSound.getSound(soundType);
// if (sound != null) {
// Location loc = entity.getLocation();
// PacketContainer packet = new PacketContainer(Server.NAMED_SOUND_EFFECT);
// mods = packet.getModifier();
// mods.write(0, sound);
// mods.write(1, (int) (loc.getX() * 8D));
// mods.write(2, (int) (loc.getY() * 8D));
// mods.write(3, (int) (loc.getZ() * 8D));
// mods.write(4, disSound.getDamageAndIdleSoundVolume());
// float pitch;
// if (disguise instanceof MobDisguise && !((MobDisguise) disguise).isAdult()) {
// pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.5F;
// } else
// pitch = (new Random().nextFloat() - new Random().nextFloat()) * 0.2F + 1.0F;
// if (disguise.getType() == DisguiseType.BAT)
// pitch *= 95F;
// pitch *= 63;
// if (pitch < 0)
// pitch = 0;
// if (pitch > 255)
// pitch = 255;
// mods.write(5, (int) pitch);
// try {
// ProtocolLibrary.getProtocolManager().sendServerPacket(observer, packet);
// } catch (InvocationTargetException e) {
// e.printStackTrace();
// }
// }
// }
// }
// }
// }
// }
}
};
viewDisguisesListener = new PacketAdapter(libsDisguises, ListenerPriority.HIGH,
@ -1322,16 +1319,14 @@ public class PacketsManager {
|| sentPacket.getType() == Server.ENTITY_LOOK
|| sentPacket.getType() == Server.ENTITY_TELEPORT
|| sentPacket.getType() == Server.REL_ENTITY_MOVE) {
if (disguise.getType() == DisguiseType.RABBIT
&& (sentPacket.getType() == Server.REL_ENTITY_MOVE || sentPacket.getType() == Server.ENTITY_MOVE_LOOK)) {
if (disguise.getType() == DisguiseType.RABBIT && (sentPacket.getType() == Server.REL_ENTITY_MOVE || sentPacket.getType() == Server.ENTITY_MOVE_LOOK)) {
if (entity.getMetadata("LibsRabbitHop").isEmpty()
|| System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() < 100
|| System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() > 500) {
if (entity.getMetadata("LibsRabbitHop").isEmpty()
|| System.currentTimeMillis() - entity.getMetadata("LibsRabbitHop").get(0).asLong() > 500) {
entity.removeMetadata("LibsRabbitHop", libsDisguises);
entity.setMetadata("LibsRabbitHop",
new FixedMetadataValue(libsDisguises, System.currentTimeMillis()));
entity.setMetadata("LibsRabbitHop", new FixedMetadataValue(libsDisguises, System.currentTimeMillis()));
}
packets = Arrays.copyOf(packets, packets.length + 1);
packets[1] = new PacketContainer(Server.ENTITY_STATUS);
@ -1340,16 +1335,17 @@ public class PacketsManager {
}
}
if (sentPacket.getType() == Server.ENTITY_LOOK
&& disguise.getType() == DisguiseType.WITHER_SKULL) {
if (sentPacket.getType() == Server.ENTITY_LOOK && disguise.getType() == DisguiseType.WITHER_SKULL) {
packets = new PacketContainer[0];
} else if (sentPacket.getType() != Server.REL_ENTITY_MOVE) {
packets[0] = sentPacket.shallowClone();
StructureModifier<Byte> bytes = packets[0].getBytes();
byte yawValue = bytes.read(1);
bytes.write(1, getYaw(disguise.getType(), entity.getType(), yawValue));
byte pitchValue = bytes.read(0);
bytes.write(0, getPitch(disguise.getType(), DisguiseType.getType(entity.getType()), pitchValue));
if (sentPacket.getType() == Server.ENTITY_TELEPORT && disguise.getType() == DisguiseType.ITEM_FRAME) {
StructureModifier<Double> doubles = packets[0].getDoubles();
Location loc = entity.getLocation();

View File

@ -1,5 +1,6 @@
package me.libraryaddict.disguise.utilities;
import com.comphenix.protocol.wrappers.MinecraftKey;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Registry;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.Serializer;
import com.comphenix.protocol.wrappers.WrappedDataWatcher.WrappedDataWatcherObject;
@ -569,6 +570,32 @@ public class ReflectionManager {
}
}
/**
* Necessary for 1.9
* @return
*/
public static String convertSoundEffectToString(Object soundEffect) {
try {
Field f_getMinecraftKey = getNmsField("SoundEffect", "b");
f_getMinecraftKey.setAccessible(true);
MinecraftKey key = MinecraftKey.fromHandle(f_getMinecraftKey.get(soundEffect));
return key.getKey();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
public static Object getCraftSoundEffect(String sound) {
Method nmsMethod = getNmsMethod("CraftSound", "getSoundEffect");
try {
return nmsMethod.invoke(null, sound);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
/**
* This creates a DataWatcherItem usable with WrappedWatchableObject
* @param id