package me.gtacraft.plugins.jetpack.util;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
public enum ParticleEffects {
HUGE_EXPLOSION("hugeexplosion", 0), LARGE_EXPLODE("largeexplode", 1), FIREWORKS_SPARK(
"fireworksSpark", 2), BUBBLE("bubble", 3), SUSPEND("suspend", 4), DEPTH_SUSPEND(
"depthSuspend", 5), TOWN_AURA("townaura", 6), CRIT("crit", 7), MAGIC_CRIT(
"magicCrit", 8), MOB_SPELL("mobSpell", 9), MOB_SPELL_AMBIENT(
"mobSpellAmbient", 10), SPELL("spell", 11), INSTANT_SPELL(
"instantSpell", 12), WITCH_MAGIC("witchMagic", 13), NOTE("note", 14), PORTAL(
"portal", 15), ENCHANTMENT_TABLE("enchantmenttable", 16), EXPLODE(
"explode", 17), FLAME("flame", 18), LAVA("lava", 19), FOOTSTEP(
"footstep", 20), SPLASH("splash", 21), LARGE_SMOKE("largesmoke", 22), CLOUD(
"cloud", 23), RED_DUST("reddust", 24), SNOWBALL_POOF(
"snowballpoof", 25), DRIP_WATER("dripWater", 26), DRIP_LAVA(
"dripLava", 27), SNOW_SHOVEL("snowshovel", 28), SLIME("slime", 29), HEART(
"heart", 30), ANGRY_VILLAGER("angryVillager", 31), HAPPY_VILLAGER(
"happyVillager", 32), ICONCRACK("iconcrack", 33), TILECRACK(
"tilecrack", 34);
private String name;
private int id;
ParticleEffects(String name, int id) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public int getId() {
return id;
}
private static final Map<String, ParticleEffects> NAME_MAP = new HashMap<String, ParticleEffects>();
private static final Map<Integer, ParticleEffects> ID_MAP = new HashMap<Integer, ParticleEffects>();
static {
for (ParticleEffects effect : values()) {
NAME_MAP.put(effect.name, effect);
ID_MAP.put(effect.id, effect);
}
}
public static ParticleEffects fromName(String name) {
if (name == null) {
return null;
}
for (Entry<String, ParticleEffects> e : NAME_MAP.entrySet()) {
if (e.getKey().equalsIgnoreCase(name)) {
return e.getValue();
}
}
return null;
}
public static ParticleEffects fromId(int id) {
return ID_MAP.get(id);
}
public void sendToPlayer(Player player, Location location, float offsetX,
float offsetY, float offsetZ, float speed, int count)
{
Object packet = createPacket(this, location, offsetX, offsetY, offsetZ,
speed, count);
sendPacket(player, packet);
}
public static void sendToLocation(ParticleEffects effect,
Location location, float offsetX, float offsetY, float offsetZ,
float speed, int count) {
Object packet = createPacket(effect, location, offsetX, offsetY,
offsetZ, speed, count);
for (Player player : Bukkit.getOnlinePlayers()) {
sendPacket(player, packet);
}
}
public static void sendCrackToPlayer(boolean icon, int id, byte data,
Player player, Location location, float offsetX, float offsetY,
float offsetZ, int count) {
Object packet = createCrackPacket(icon, id, data, location, offsetX,
offsetY, offsetZ, count);
sendPacket(player, packet);
}
public static void sendCrackToLocation(boolean icon, int id, byte data,
Location location, float offsetX, float offsetY, float offsetZ,
int count) {
Object packet = createCrackPacket(icon, id, data, location, offsetX,
offsetY, offsetZ, count);
for (Player player : Bukkit.getOnlinePlayers()) {
sendPacket(player, packet);
}
}
public static Object createPacket(ParticleEffects effect,
Location location, float offsetX, float offsetY, float offsetZ,
float speed, int count) {
try {
if (count <= 0)
count = 1;
Object packet = getPacket63WorldParticles();
setValue(packet, "a", effect.name);
setValue(packet, "b", (float) location.getX());
setValue(packet, "c", (float) location.getY());
setValue(packet, "d", (float) location.getZ());
setValue(packet, "e", offsetX);
setValue(packet, "f", offsetY);
setValue(packet, "g", offsetZ);
setValue(packet, "h", speed);
setValue(packet, "i", count);
return packet;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static Object createCrackPacket(boolean icon, int id, byte data,
Location location, float offsetX, float offsetY, float offsetZ,
int count) {
try {
if (count <= 0)
count = 1;
Object packet = getPacket63WorldParticles();
String modifier = "iconcrack_" + id;
if (!icon) {
modifier = "tilecrack_" + id + "_" + data;
}
setValue(packet, "a", modifier);
setValue(packet, "b", (float) location.getX());
setValue(packet, "c", (float) location.getY());
setValue(packet, "d", (float) location.getZ());
setValue(packet, "e", offsetX);
setValue(packet, "f", offsetY);
setValue(packet, "g", offsetZ);
setValue(packet, "h", 0.1F);
setValue(packet, "i", count);
return packet;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private static void setValue(Object instance, String fieldName, Object value)
throws Exception {
Field field = instance.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
field.set(instance, value);
}
private static Object getEntityPlayer(Player p) throws Exception {
Method getHandle = p.getClass().getMethod("getHandle");
return getHandle.invoke(p);
}
private static String getPackageName() {
return "net.minecraft.server."
+ Bukkit.getServer().getClass().getPackage().getName()
.replace(".", ",").split(",")[3];
}
private static Object getPacket63WorldParticles() throws Exception {
Class<?> packet = Class.forName(getPackageName()
+ ".PacketPlayOutWorldParticles");
for (Constructor cst : packet.getConstructors()) {
if (cst.getParameterTypes().length == 0)
return cst.newInstance();
}
return packet.getConstructors()[0].newInstance();
}
private static void sendPacket(Player p, Object packet) {
try {
Object eplayer = getEntityPlayer(p);
Field playerConnectionField = eplayer.getClass().getField(
"playerConnection");
Object playerConnection = playerConnectionField.get(eplayer);
for (Method m : playerConnection.getClass().getMethods()) {
if (m.getName().equalsIgnoreCase("sendPacket")) {
m.invoke(playerConnection, packet);
return;
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}