diff --git a/pom.xml b/pom.xml
index 6a2b9100..76ab85ce 100644
--- a/pom.xml
+++ b/pom.xml
@@ -64,7 +64,7 @@
2.5.0
- 7.2.4
+ 7.2.4-SNAPSHOT
diff --git a/src/me/libraryaddict/disguise/DisguiseAPI.java b/src/me/libraryaddict/disguise/DisguiseAPI.java
index 1306fab4..1cd095f9 100644
--- a/src/me/libraryaddict/disguise/DisguiseAPI.java
+++ b/src/me/libraryaddict/disguise/DisguiseAPI.java
@@ -52,9 +52,15 @@ public class DisguiseAPI {
return hearSelfDisguise;
}
+ /**
+ * Disguise the next entity to spawn with this disguise. This may not work however if the entity doesn't actually spawn.
+ */
public static void disguiseNextEntity(Disguise disguise) {
if (disguise == null)
return;
+ if (disguise.getEntity() != null || disguises.containsValue(disguise)) {
+ disguise = disguise.clone();
+ }
try {
Field field = net.minecraft.server.v1_6_R2.Entity.class.getDeclaredField("entityCount");
field.setAccessible(true);
@@ -66,10 +72,7 @@ public class DisguiseAPI {
}
/**
- * @param Player
- * - The player to disguise
- * @param Disguise
- * - The disguise to wear
+ * Disguise this entity with this disguise
*/
public static void disguiseToAll(Entity entity, Disguise disguise) {
// If they are trying to disguise a null entity or use a null disguise
@@ -83,12 +86,7 @@ public class DisguiseAPI {
// Just return.
if (event.isCancelled())
return;
- // The event wasn't cancelled. Got to discard the old disguise
- Disguise oldDisguise = getDisguise(entity);
- // If there was a old disguise
- if (oldDisguise != null) {
- oldDisguise.getScheduler().cancel();
- }
+ // The event wasn't cancelled.
// If the disguise entity isn't the same as the one we are disguising
if (disguise.getEntity() != entity) {
// If the disguise entity actually exists
@@ -98,13 +96,17 @@ public class DisguiseAPI {
}
// Set the disguise's entity
disguise.setEntity(entity);
- }
+ } // If there was a old disguise
+ Disguise oldDisguise = getDisguise(entity);
// Stick the disguise in the disguises bin
disguises.put(entity.getEntityId(), disguise);
// Resend the disguised entity's packet
refreshTrackers(entity);
// If he is a player, then self disguise himself
setupPlayerFakeDisguise(disguise);
+ // Discard the disguise
+ if (oldDisguise != null)
+ oldDisguise.discard();
}
/**
@@ -113,7 +115,9 @@ public class DisguiseAPI {
public static Disguise getDisguise(Entity disguiser) {
if (disguiser == null)
return null;
- return disguises.get(disguiser.getEntityId());
+ if (disguises.containsKey(disguiser.getEntityId()))
+ return disguises.get(disguiser.getEntityId());
+ return null;
}
/**
@@ -130,17 +134,22 @@ public class DisguiseAPI {
}
/**
- * @param Disguiser
- * @return boolean - If the disguiser is disguised
+ * Is this entity disguised
*/
public static boolean isDisguised(Entity disguiser) {
return getDisguise(disguiser) != null;
}
+ /**
+ * Is the sound packets caught and modified
+ */
public static boolean isSoundEnabled() {
return PacketsManager.isHearDisguisesEnabled();
}
+ /**
+ * Is the velocity packets sent
+ */
public static boolean isVelocitySent() {
return sendVelocity;
}
@@ -170,7 +179,7 @@ public class DisguiseAPI {
}
}
- private static void removeVisibleDisguise(Player player) {
+ private static void removeSelfDisguise(Player player) {
if (selfDisguisesIds.containsKey(player.getEntityId())) {
// Send a packet to destroy the fake entity
PacketContainer packet = new PacketContainer(Packets.Server.DESTROY_ENTITY);
@@ -203,12 +212,18 @@ public class DisguiseAPI {
}
}
+ /**
+ * Can players hear their own disguises
+ */
public static void setHearSelfDisguise(boolean replaceSound) {
if (hearSelfDisguise != replaceSound) {
hearSelfDisguise = replaceSound;
}
}
+ /**
+ * Set if the disguises play sounds when hurt
+ */
public static void setSoundsEnabled(boolean isSoundsEnabled) {
PacketsManager.setHearDisguisesListener(isSoundsEnabled);
}
@@ -222,7 +237,7 @@ public class DisguiseAPI {
return;
Player player = (Player) disguise.getEntity();
// Remove the old disguise, else we have weird disguises around the place
- removeVisibleDisguise(player);
+ removeSelfDisguise(player);
// If the disguised player can't see himself. Return
if (!disguise.viewSelfDisguise())
return;
@@ -342,7 +357,8 @@ public class DisguiseAPI {
}
/**
- * Undisguise the entity
+ * Undisguise the entity. This doesn't let you cancel the UndisguiseEvent if the entity is no longer valid. Aka removed from
+ * the world.
*/
public static void undisguiseToAll(Entity entity) {
Disguise disguise = getDisguise(entity);
@@ -350,14 +366,20 @@ public class DisguiseAPI {
return;
UndisguiseEvent event = new UndisguiseEvent(entity, disguise);
Bukkit.getPluginManager().callEvent(event);
- if (event.isCancelled() && ((CraftEntity) entity).getHandle().valid)
+ if (event.isCancelled())
return;
- disguise.getScheduler().cancel();
- disguises.remove(entity.getEntityId());
- if (((CraftEntity) entity).getHandle().valid) {
- if (entity instanceof Player)
- removeVisibleDisguise((Player) entity);
- refreshTrackers(entity);
- }
+ disguise.discard();
+ }
+
+ public HashMap getDisguises() {
+ return disguises;
+ }
+
+ public void refreshWatchingPlayers(Entity entity) {
+ refreshTrackers(entity);
+ }
+
+ public void removeVisibleDisguise(Player player) {
+ removeSelfDisguise(player);
}
}
\ No newline at end of file
diff --git a/src/me/libraryaddict/disguise/DisguiseTypes/Disguise.java b/src/me/libraryaddict/disguise/DisguiseTypes/Disguise.java
index f5beee0a..f1f72b95 100644
--- a/src/me/libraryaddict/disguise/DisguiseTypes/Disguise.java
+++ b/src/me/libraryaddict/disguise/DisguiseTypes/Disguise.java
@@ -3,6 +3,7 @@ package me.libraryaddict.disguise.DisguiseTypes;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import me.libraryaddict.disguise.DisguiseAPI;
import me.libraryaddict.disguise.DisguiseTypes.Watchers.AgeableWatcher;
@@ -28,6 +29,7 @@ import com.comphenix.protocol.events.PacketContainer;
import com.comphenix.protocol.reflect.StructureModifier;
public class Disguise {
+ private static DisguiseAPI disguiseAPI = new DisguiseAPI();
private static JavaPlugin plugin;
private DisguiseType disguiseType;
private org.bukkit.entity.Entity entity;
@@ -71,108 +73,6 @@ public class Disguise {
// Ok.. So it aint a horse
}
}
- }
-
- public boolean canHearSelfDisguise() {
- return hearSelfDisguise;
- }
-
- public Disguise clone() {
- Disguise disguise = new Disguise(getType(), replaceSounds());
- disguise.setViewSelfDisguise(viewSelfDisguise());
- return disguise;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Disguise other = (Disguise) obj;
- if (disguiseType != other.disguiseType)
- return false;
- if (hearSelfDisguise != other.hearSelfDisguise)
- return false;
- if (replaceSounds != other.replaceSounds)
- return false;
- if (velocitySent != other.velocitySent)
- return false;
- if (viewSelfDisguise != other.viewSelfDisguise)
- return false;
- if (!watcher.equals(other.watcher))
- return false;
- return true;
- }
-
- /**
- * Get the disguised entity
- */
- public org.bukkit.entity.Entity getEntity() {
- return entity;
- }
-
- /**
- * Get all EntityPlayers who have this entity in their Entity Tracker
- */
- protected EntityPlayer[] getPerverts() {
- EntityTrackerEntry entry = (EntityTrackerEntry) ((WorldServer) ((CraftEntity) entity).getHandle().world).tracker.trackedEntities
- .get(entity.getEntityId());
- if (entry != null) {
- EntityPlayer[] players = (EntityPlayer[]) entry.trackedPlayers.toArray(new EntityPlayer[entry.trackedPlayers.size()]);
- return players;
- }
- return new EntityPlayer[0];
- }
-
- public BukkitRunnable getScheduler() {
- return runnable;
- }
-
- /**
- * Get the disguise type
- */
- public DisguiseType getType() {
- return disguiseType;
- }
-
- /**
- * Get the flag watcher
- */
- public FlagWatcher getWatcher() {
- return watcher;
- }
-
- public boolean isMiscDisguise() {
- return this instanceof MiscDisguise;
- }
-
- public boolean isMobDisguise() {
- return this instanceof MobDisguise;
- }
-
- public boolean isPlayerDisguise() {
- return this instanceof PlayerDisguise;
- }
-
- public boolean isVelocitySent() {
- return velocitySent;
- }
-
- public boolean replaceSounds() {
- return replaceSounds;
- }
-
- /**
- * Set the entity of the disguise. Only used for internal things.
- */
- public void setEntity(final org.bukkit.entity.Entity entity) {
- if (this.entity != null)
- throw new RuntimeException("This disguise is already in use! Try .clone()");
- this.entity = entity;
- setupWatcher();
double fallSpeed = 0.0050;
boolean movement = false;
switch (getType()) {
@@ -292,6 +192,147 @@ public class Disguise {
}
}
};
+ }
+
+ public boolean canHearSelfDisguise() {
+ return hearSelfDisguise;
+ }
+
+ public Disguise clone() {
+ Disguise disguise = new Disguise(getType(), replaceSounds());
+ disguise.setViewSelfDisguise(viewSelfDisguise());
+ return disguise;
+ }
+
+ /**
+ * Destroys the disguise and undisguises the entity if its using this disguise. This doesn't fire a UndisguiseEvent
+ */
+ public void discard() {
+ // If the runnable is null. Just return. Its been discarded already.
+ if (runnable == null)
+ return;
+ // Why the hell can't I safely check if its running?!?!
+ try {
+ runnable.cancel();
+ } catch (Exception ex) {
+ }
+ runnable = null;
+ HashMap disguises = disguiseAPI.getDisguises();
+ // If this disguise has a entity set
+ if (getEntity() != null) {
+ // If the entity is valid
+ if (((CraftEntity) getEntity()).getHandle().valid) {
+ // If this disguise is active
+ if (disguises.containsKey(getEntity().getEntityId()) && disguises.get(getEntity().getEntityId()) == this) {
+ // Gotta do reflection, copy code or open up calls.
+ // Reflection is the cleanest?
+ if (entity instanceof Player) {
+ disguiseAPI.removeVisibleDisguise((Player) entity);
+ }
+ // Better refresh the entity to undisguise it
+ disguiseAPI.refreshWatchingPlayers(getEntity());
+ // Now remove the disguise from the current disguises.
+ disguises.remove(getEntity().getEntityId());
+ }
+ }
+ } else {
+ // Loop through the disguises because it could be used with a unknown entity id.
+ Iterator itel = disguises.keySet().iterator();
+ while (itel.hasNext()) {
+ int id = itel.next();
+ if (disguises.get(id) == this) {
+ itel.remove();
+ }
+ }
+ }
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ Disguise other = (Disguise) obj;
+ if (disguiseType != other.disguiseType)
+ return false;
+ if (hearSelfDisguise != other.hearSelfDisguise)
+ return false;
+ if (replaceSounds != other.replaceSounds)
+ return false;
+ if (velocitySent != other.velocitySent)
+ return false;
+ if (viewSelfDisguise != other.viewSelfDisguise)
+ return false;
+ if (!watcher.equals(other.watcher))
+ return false;
+ return true;
+ }
+
+ /**
+ * Get the disguised entity
+ */
+ public org.bukkit.entity.Entity getEntity() {
+ return entity;
+ }
+
+ /**
+ * Get all EntityPlayers who have this entity in their Entity Tracker
+ */
+ protected EntityPlayer[] getPerverts() {
+ EntityTrackerEntry entry = (EntityTrackerEntry) ((WorldServer) ((CraftEntity) entity).getHandle().world).tracker.trackedEntities
+ .get(entity.getEntityId());
+ if (entry != null) {
+ EntityPlayer[] players = (EntityPlayer[]) entry.trackedPlayers.toArray(new EntityPlayer[entry.trackedPlayers.size()]);
+ return players;
+ }
+ return new EntityPlayer[0];
+ }
+
+ /**
+ * Get the disguise type
+ */
+ public DisguiseType getType() {
+ return disguiseType;
+ }
+
+ /**
+ * Get the flag watcher
+ */
+ public FlagWatcher getWatcher() {
+ return watcher;
+ }
+
+ public boolean isMiscDisguise() {
+ return this instanceof MiscDisguise;
+ }
+
+ public boolean isMobDisguise() {
+ return this instanceof MobDisguise;
+ }
+
+ public boolean isPlayerDisguise() {
+ return this instanceof PlayerDisguise;
+ }
+
+ public boolean isVelocitySent() {
+ return velocitySent;
+ }
+
+ public boolean replaceSounds() {
+ return replaceSounds;
+ }
+
+ /**
+ * Set the entity of the disguise. Only used for internal things.
+ */
+ public void setEntity(final org.bukkit.entity.Entity entity) {
+ if (this.entity != null)
+ throw new RuntimeException("This disguise is already in use! Try .clone()");
+ this.entity = entity;
+ setupWatcher();
runnable.runTaskTimer(plugin, 1, 1);
}
@@ -366,7 +407,7 @@ public class Disguise {
// If they both extend the same base class. They OBVIOUSLY share the same datavalue. Right..?
if (baseClass != null && baseClass.isAssignableFrom(disguiseClass) && baseClass.isAssignableFrom(entityClass))
continue;
-
+
// So they don't extend a basic class.
// Maybe if I check that they extend each other..
// Seeing as I only store the finished forms of entitys. This should raise no problems and allow for more shared
diff --git a/src/me/libraryaddict/disguise/PacketsManager.java b/src/me/libraryaddict/disguise/PacketsManager.java
index 1be49b6c..ef113b45 100644
--- a/src/me/libraryaddict/disguise/PacketsManager.java
+++ b/src/me/libraryaddict/disguise/PacketsManager.java
@@ -101,6 +101,7 @@ public class PacketsManager {
});
// Now add a client listener to cancel them interacting with uninteractable disguised entitys.
// You ain't supposed to be allowed to 'interact' with a item that cannot be clicked.
+ // Kicks you for hacking.
manager.addPacketListener(new PacketAdapter(libsDisguises, ConnectionSide.CLIENT_SIDE, ListenerPriority.NORMAL,
Packets.Client.USE_ENTITY) {
@Override
@@ -120,7 +121,10 @@ public class PacketsManager {
});
}
- public static PacketContainer[] constructPacket(Disguise disguise, Entity disguisedEntity) {
+ /**
+ * Construct the packets I need to spawn in the disguise
+ */
+ public static PacketContainer[] constructSpawnPackets(Disguise disguise, Entity disguisedEntity) {
if (disguise.getEntity() == null)
disguise.setEntity(disguisedEntity);
net.minecraft.server.v1_6_R2.Entity nmsEntity = ((CraftEntity) disguisedEntity).getHandle();
@@ -204,7 +208,7 @@ public class PacketsManager {
item = CraftItemStack.asNMSCopy(((CraftLivingEntity) disguisedEntity).getEquipment().getItemInHand());
}
mods.write(7, (item == null ? 0 : item.id));
- mods.write(8, convertDataWatcher(nmsEntity.getDataWatcher(), disguise.getWatcher()));
+ mods.write(8, createDataWatcher(nmsEntity.getDataWatcher(), disguise.getWatcher()));
} else if (disguise.getType().isMob()) {
@@ -239,7 +243,7 @@ public class PacketsManager {
mods.write(9, (byte) (int) (loc.getPitch() * 256.0F / 360.0F));
if (nmsEntity instanceof EntityLiving)
mods.write(10, (byte) (int) (((EntityLiving) nmsEntity).aA * 256.0F / 360.0F));
- mods.write(11, convertDataWatcher(nmsEntity.getDataWatcher(), disguise.getWatcher()));
+ mods.write(11, createDataWatcher(nmsEntity.getDataWatcher(), disguise.getWatcher()));
// Theres a list sometimes written with this. But no problems have appeared!
// Probably just the metadata to be sent. But the next meta packet after fixes that anyways.
@@ -302,7 +306,10 @@ public class PacketsManager {
return spawnPackets;
}
- private static DataWatcher convertDataWatcher(DataWatcher watcher, FlagWatcher flagWatcher) {
+ /**
+ * Create a new datawatcher but with the 'correct' values
+ */
+ private static DataWatcher createDataWatcher(DataWatcher watcher, FlagWatcher flagWatcher) {
DataWatcher newWatcher = new DataWatcher();
try {
Field map = newWatcher.getClass().getDeclaredField("c");
@@ -320,6 +327,9 @@ public class PacketsManager {
}
+ /**
+ * Add the yaw for the disguises
+ */
private static byte getYaw(DisguiseType disguiseType, DisguiseType entityType, byte value) {
switch (disguiseType) {
case ENDER_DRAGON:
@@ -640,6 +650,9 @@ public class PacketsManager {
}
}
+ /**
+ * Transform the packet magically into the one I have always dreamed off. My true luv!!!
+ */
private static PacketContainer[] transformPacket(PacketContainer sentPacket, Player observer) {
PacketContainer[] packets = new PacketContainer[] { sentPacket };
try {
@@ -653,6 +666,7 @@ public class PacketsManager {
// This packet sends attributes
switch (sentPacket.getID()) {
+
case Packets.Server.UPDATE_ATTRIBUTES:
{
@@ -696,7 +710,7 @@ public class PacketsManager {
case Packets.Server.ENTITY_PAINTING:
{
- packets = constructPacket(disguise, entity);
+ packets = constructSpawnPackets(disguise, entity);
break;
}