mirror of
https://github.com/TotalFreedomMC/TF-LibsDisguises.git
synced 2025-02-15 13:11:23 +00:00
![libraryaddict](/assets/img/avatar_default.png)
Added boolean to disguise which tells you simply if the disguise is in use or not. In use means that the plugin stores a reference, doesn't nessercerily mean there is a entity. Added method startDisguise() to disguise and cleaned up setEntity(). Helps counter the idiots who hate DisguiseAPI
344 lines
No EOL
15 KiB
Java
344 lines
No EOL
15 KiB
Java
package me.libraryaddict.disguise;
|
|
|
|
import java.lang.reflect.Field;
|
|
import java.lang.reflect.Method;
|
|
import java.util.Arrays;
|
|
import java.util.Collection;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
|
|
import me.libraryaddict.disguise.disguisetypes.AnimalColor;
|
|
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.TargetedDisguise;
|
|
import me.libraryaddict.disguise.disguisetypes.TargetedDisguise.TargetType;
|
|
import me.libraryaddict.disguise.disguisetypes.watchers.HorseWatcher;
|
|
import me.libraryaddict.disguise.disguisetypes.watchers.LivingWatcher;
|
|
import me.libraryaddict.disguise.events.DisguiseEvent;
|
|
import me.libraryaddict.disguise.events.UndisguiseEvent;
|
|
import me.libraryaddict.disguise.utilities.DisguiseUtilities;
|
|
import me.libraryaddict.disguise.utilities.ReflectionManager;
|
|
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.DyeColor;
|
|
import org.bukkit.Material;
|
|
import org.bukkit.entity.Entity;
|
|
import org.bukkit.entity.LivingEntity;
|
|
import org.bukkit.entity.Player;
|
|
import org.bukkit.inventory.EntityEquipment;
|
|
import org.bukkit.inventory.ItemStack;
|
|
import org.bukkit.potion.PotionEffect;
|
|
|
|
public class DisguiseAPI {
|
|
|
|
public static Disguise constructDisguise(Entity entity) {
|
|
return constructDisguise(entity, true, true, true);
|
|
}
|
|
|
|
public static Disguise constructDisguise(Entity entity, boolean doEnquipment, boolean doSneak, boolean doSprint) {
|
|
DisguiseType disguiseType = DisguiseType.getType(entity);
|
|
Disguise disguise;
|
|
if (disguiseType.isMisc()) {
|
|
disguise = new MiscDisguise(disguiseType);
|
|
} else if (disguiseType.isMob()) {
|
|
disguise = new MobDisguise(disguiseType);
|
|
} else {
|
|
disguise = new PlayerDisguise(((Player) entity).getName());
|
|
}
|
|
FlagWatcher watcher = disguise.getWatcher();
|
|
if (entity instanceof LivingEntity) {
|
|
for (PotionEffect effect : ((LivingEntity) entity).getActivePotionEffects()) {
|
|
((LivingWatcher) watcher).addPotionEffect(effect.getType());
|
|
if (effect.getType().getName().equals("INVISIBILITY")) {
|
|
watcher.setInvisible(true);
|
|
}
|
|
}
|
|
}
|
|
if (entity.getFireTicks() > 0) {
|
|
watcher.setBurning(true);
|
|
}
|
|
if (doEnquipment && entity instanceof LivingEntity) {
|
|
EntityEquipment enquip = ((LivingEntity) entity).getEquipment();
|
|
watcher.setArmor(enquip.getArmorContents());
|
|
watcher.setItemInHand(enquip.getItemInHand());
|
|
if (disguiseType.getEntityType().name().equals("HORSE")) {
|
|
try {
|
|
Object horseInv = entity.getClass().getMethod("getInventory").invoke(entity);
|
|
Object item = horseInv.getClass().getMethod("getSaddle").invoke(horseInv);
|
|
if (item != null && ((ItemStack) item).getType() == Material.SADDLE) {
|
|
((HorseWatcher) watcher).setSaddled(true);
|
|
}
|
|
((HorseWatcher) watcher)
|
|
.setHorseArmor((ItemStack) horseInv.getClass().getMethod("getArmor").invoke(horseInv));
|
|
} catch (Exception ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
for (Method method : entity.getClass().getMethods()) {
|
|
if ((doSneak || !method.getName().equals("setSneaking")) && (doSprint || !method.getName().equals("setSprinting"))
|
|
&& method.getParameterTypes().length == 0 && method.getReturnType() != void.class) {
|
|
Class methodReturn = method.getReturnType();
|
|
if (methodReturn == float.class || methodReturn == Float.class || methodReturn == Double.class) {
|
|
methodReturn = double.class;
|
|
}
|
|
int firstCapitalMethod = firstCapital(method.getName());
|
|
if (firstCapitalMethod > 0) {
|
|
for (Method watcherMethod : watcher.getClass().getMethods()) {
|
|
if (!watcherMethod.getName().startsWith("get") && watcherMethod.getReturnType() == void.class
|
|
&& watcherMethod.getParameterTypes().length == 1) {
|
|
int firstCapitalWatcher = firstCapital(watcherMethod.getName());
|
|
if (firstCapitalWatcher > 0
|
|
&& method.getName().substring(firstCapitalMethod)
|
|
.equalsIgnoreCase(watcherMethod.getName().substring(firstCapitalWatcher))) {
|
|
Class methodParam = watcherMethod.getParameterTypes()[0];
|
|
if (methodParam == float.class || methodParam == Float.class || methodParam == Double.class) {
|
|
methodParam = double.class;
|
|
} else if (methodParam == AnimalColor.class) {
|
|
methodParam = DyeColor.class;
|
|
}
|
|
if (methodReturn == methodParam) {
|
|
try {
|
|
Object value = method.invoke(entity);
|
|
if (value != null) {
|
|
Class toCast = watcherMethod.getParameterTypes()[0];
|
|
if (!(toCast.isInstance(value))) {
|
|
if (toCast == float.class) {
|
|
if (value instanceof Float) {
|
|
value = ((Float) value).floatValue();
|
|
} else {
|
|
double d = (Double) value;
|
|
value = (float) d;
|
|
}
|
|
} else if (toCast == double.class) {
|
|
if (value instanceof Double) {
|
|
value = ((Double) value).doubleValue();
|
|
} else {
|
|
float d = (Float) value;
|
|
value = (double) d;
|
|
}
|
|
} else if (toCast == AnimalColor.class) {
|
|
value = AnimalColor.valueOf(((DyeColor) value).name());
|
|
}
|
|
}
|
|
if (value instanceof Boolean && !(Boolean) value
|
|
&& watcherMethod.getDeclaringClass() == FlagWatcher.class) {
|
|
continue;
|
|
}
|
|
}
|
|
watcherMethod.invoke(watcher, value);
|
|
} catch (Exception ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return disguise;
|
|
}
|
|
|
|
public static void disguiseEntity(Entity entity, Disguise disguise) {
|
|
// If they are trying to disguise a null entity or use a null disguise
|
|
// Just return.
|
|
if (entity == null || disguise == null)
|
|
return;
|
|
// Fire a disguise event
|
|
DisguiseEvent event = new DisguiseEvent(entity, disguise);
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
// If they cancelled this disguise event. No idea why.
|
|
// Just return.
|
|
if (event.isCancelled())
|
|
return;
|
|
// 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
|
|
if (disguise.getEntity() != null) {
|
|
// Clone the disguise
|
|
disguise = disguise.clone();
|
|
}
|
|
// Set the disguise's entity
|
|
disguise.setEntity(entity);
|
|
}
|
|
disguise.startDisguise();
|
|
}
|
|
|
|
public static void disguiseIgnorePlayers(Entity entity, Disguise disguise, Collection playersToNotSeeDisguise) {
|
|
if (disguise.getEntity() != null) {
|
|
disguise = disguise.clone();
|
|
}
|
|
((TargetedDisguise) disguise).setDisguiseTarget(TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS);
|
|
for (Object obj : playersToNotSeeDisguise) {
|
|
if (obj instanceof String) {
|
|
((TargetedDisguise) disguise).addPlayer((String) obj);
|
|
} else if (obj instanceof Player) {
|
|
((TargetedDisguise) disguise).addPlayer(((Player) obj).getName());
|
|
}
|
|
}
|
|
disguiseEntity(entity, disguise);
|
|
}
|
|
|
|
@Deprecated
|
|
public static void disguiseIgnorePlayers(Entity entity, Disguise disguise, List<String> playersToNotSeeDisguise) {
|
|
disguiseIgnorePlayers(entity, disguise, (Collection) playersToNotSeeDisguise);
|
|
}
|
|
|
|
public static void disguiseIgnorePlayers(Entity entity, Disguise disguise, Player... playersToNotSeeDisguise) {
|
|
disguiseIgnorePlayers(entity, disguise, (Collection) Arrays.asList(playersToNotSeeDisguise));
|
|
}
|
|
|
|
public static void disguiseIgnorePlayers(Entity entity, Disguise disguise, String... playersToNotSeeDisguise) {
|
|
disguiseIgnorePlayers(entity, disguise, (Collection) Arrays.asList(playersToNotSeeDisguise));
|
|
}
|
|
|
|
/**
|
|
* Disguise the next entity to spawn with this disguise. This may not work however if the entity doesn't actually spawn.
|
|
*/
|
|
public static int disguiseNextEntity(Disguise disguise) {
|
|
if (disguise == null)
|
|
return -1;
|
|
if (disguise.getEntity() != null || DisguiseUtilities.getDisguises().containsValue(disguise)) {
|
|
disguise = disguise.clone();
|
|
}
|
|
try {
|
|
Field field = ReflectionManager.getNmsClass("Entity").getDeclaredField("entityCount");
|
|
field.setAccessible(true);
|
|
int id = field.getInt(null);
|
|
DisguiseUtilities.addFutureDisguise(id, (TargetedDisguise) disguise);
|
|
return id;
|
|
} catch (Exception ex) {
|
|
ex.printStackTrace();
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Disguise this entity with this disguise
|
|
*/
|
|
public static void disguiseToAll(Entity entity, Disguise disguise) {
|
|
if (disguise.getEntity() != null) {
|
|
disguise = disguise.clone();
|
|
}
|
|
// You called the disguiseToAll method foolish mortal! Prepare to have your custom settings wiped!!!
|
|
((TargetedDisguise) disguise).setDisguiseTarget(TargetType.SHOW_TO_EVERYONE_BUT_THESE_PLAYERS);
|
|
for (String observer : ((TargetedDisguise) disguise).getObservers())
|
|
((TargetedDisguise) disguise).removePlayer(observer);
|
|
disguiseEntity(entity, disguise);
|
|
}
|
|
|
|
public static void disguiseToPlayers(Entity entity, Disguise disguise, Collection playersToViewDisguise) {
|
|
if (disguise.getEntity() != null) {
|
|
disguise = disguise.clone();
|
|
}
|
|
((TargetedDisguise) disguise).setDisguiseTarget(TargetType.HIDE_DISGUISE_TO_EVERYONE_BUT_THESE_PLAYERS);
|
|
for (Object obj : playersToViewDisguise) {
|
|
if (obj instanceof String) {
|
|
((TargetedDisguise) disguise).addPlayer((String) obj);
|
|
} else if (obj instanceof Player) {
|
|
((TargetedDisguise) disguise).addPlayer(((Player) obj).getName());
|
|
}
|
|
}
|
|
disguiseEntity(entity, disguise);
|
|
}
|
|
|
|
@Deprecated
|
|
public static void disguiseToPlayers(Entity entity, Disguise disguise, List<String> playersToViewDisguise) {
|
|
disguiseToPlayers(entity, disguise, (Collection) playersToViewDisguise);
|
|
}
|
|
|
|
public static void disguiseToPlayers(Entity entity, Disguise disguise, Player... playersToViewDisguise) {
|
|
disguiseToPlayers(entity, disguise, (Collection) Arrays.asList(playersToViewDisguise));
|
|
}
|
|
|
|
public static void disguiseToPlayers(Entity entity, Disguise disguise, String... playersToViewDisguise) {
|
|
disguiseToPlayers(entity, disguise, (Collection) Arrays.asList(playersToViewDisguise));
|
|
}
|
|
|
|
private static int firstCapital(String str) {
|
|
for (int i = 0; i < str.length(); i++) {
|
|
if (Character.isUpperCase(str.charAt(i))) {
|
|
return i;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Get the disguise of a entity
|
|
*/
|
|
public static Disguise getDisguise(Entity disguised) {
|
|
if (disguised == null)
|
|
return null;
|
|
return DisguiseUtilities.getMainDisguise(disguised.getUniqueId());
|
|
}
|
|
|
|
/**
|
|
* Get the disguise of a entity
|
|
*/
|
|
public static Disguise getDisguise(Player observer, Entity disguised) {
|
|
if (disguised == null || observer == null)
|
|
return null;
|
|
return DisguiseUtilities.getDisguise(observer, disguised);
|
|
}
|
|
|
|
/**
|
|
* Get the disguises of a entity
|
|
*/
|
|
public static Disguise[] getDisguises(Entity disguised) {
|
|
if (disguised == null)
|
|
return null;
|
|
return DisguiseUtilities.getDisguises(disguised.getUniqueId());
|
|
}
|
|
|
|
/**
|
|
* Get the ID of a fake disguise for a entityplayer
|
|
*/
|
|
public static int getFakeDisguise(UUID entityId) {
|
|
if (DisguiseUtilities.getSelfDisguisesIds().containsKey(entityId))
|
|
return DisguiseUtilities.getSelfDisguisesIds().get(entityId);
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* Is this entity disguised
|
|
*/
|
|
public static boolean isDisguised(Entity disguised) {
|
|
return getDisguise(disguised) != null;
|
|
}
|
|
|
|
/**
|
|
* Is this entity disguised
|
|
*/
|
|
public static boolean isDisguised(Player observer, Entity disguised) {
|
|
return getDisguise(observer, disguised) != null;
|
|
}
|
|
|
|
public static boolean isDisguiseInUse(Disguise disguise) {
|
|
return disguise.isDisguiseInUse();
|
|
}
|
|
|
|
/**
|
|
* 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[] disguises = getDisguises(entity);
|
|
for (Disguise disguise : disguises) {
|
|
UndisguiseEvent event = new UndisguiseEvent(entity, disguise);
|
|
Bukkit.getPluginManager().callEvent(event);
|
|
if (event.isCancelled())
|
|
continue;
|
|
disguise.removeDisguise();
|
|
}
|
|
}
|
|
|
|
private DisguiseAPI() {
|
|
}
|
|
} |