TabooLib/src/main/scala/io/izzel/taboolib/module/hologram/THologramHandler.java

217 lines
7.0 KiB
Java

package io.izzel.taboolib.module.hologram;
import com.google.common.collect.Lists;
import com.google.common.collect.Queues;
import io.izzel.taboolib.TabooLib;
import io.izzel.taboolib.Version;
import io.izzel.taboolib.module.inject.TListener;
import io.izzel.taboolib.module.lite.SimpleReflection;
import io.izzel.taboolib.module.packet.Packet;
import io.izzel.taboolib.module.packet.TPacket;
import io.izzel.taboolib.util.Ref;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.entity.ArmorStand;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.*;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.List;
import java.util.Queue;
import java.util.UUID;
/**
* @Author sky
* @Since 2020-03-07 14:23
*/
@TListener
class THologramHandler implements Listener {
private static ArmorStand learnTarget = null;
private static Packet packetInit = null;
private static Packet packetSpawn = null;
private static Packet packetName = null;
private static THologramSchedule currentSchedule = null;
private static Queue<THologramSchedule> queueSchedule = Queues.newArrayDeque();
private static boolean learned = false;
@TPacket(type = TPacket.Type.RECEIVE)
static boolean d(Player player, Packet packet) {
if (packet.is("PacketPlayInPosition") && !learned) {
learned = true;
Bukkit.getScheduler().runTask(TabooLib.getPlugin(), () -> learn(player));
}
if (packet.is("PacketPlayInUseEntity")) {
int id = packet.read("a", Integer.TYPE);
for (Hologram hologram : THologram.getHolograms()) {
HologramViewer viewer = hologram.getViewer(player);
if (viewer != null && viewer.getId() == id) {
hologram.getEvent().accept(player);
}
}
}
return true;
}
@TPacket(type = TPacket.Type.SEND)
static boolean e(Player player, Packet packet) {
if (learnTarget == null) {
return true;
}
if (packet.is("PacketPlayOutSpawnEntity") && packet.read("a", Integer.TYPE) == learnTarget.getEntityId()) {
packetSpawn = packet;
return false;
}
if (packet.is("PacketPlayOutEntityMetadata") && packet.read("a", Integer.TYPE) == learnTarget.getEntityId()) {
if (currentSchedule != null) {
currentSchedule.after(packet);
} else {
packetInit = packet;
}
return false;
}
return true;
}
public static boolean isLearned() {
return packetInit != null && packetSpawn != null && packetName != null;
}
public static Packet copy(int id, Location location) {
Packet packet = THologramHandler.getPacketSpawn().copy("e", "f", "j", "h", "i", "j", "k", "l");
packet.write("a", id);
if (Version.isAfter(Version.v1_9)) {
packet.write("b", UUID.randomUUID());
packet.write("c", location.getX());
packet.write("d", location.getY());
packet.write("e", location.getZ());
} else {
packet.write("b", location.getX());
packet.write("c", location.getY());
packet.write("d", location.getZ());
}
return packet;
}
public static Packet copy(int id) {
Packet packet = THologramHandler.getPacketInit().copy("b");
packet.write("a", id);
return packet;
}
public static Packet copy(int id, String name) {
Packet packet = THologramHandler.getPacketName().copy();
packet.write("a", id);
List copy = Lists.newArrayList();
List item = THologramHandler.getPacketName().read("b", List.class);
for (Object element : item) {
SimpleReflection.checkAndSave(element.getClass());
Object a = SimpleReflection.getFieldValue(element.getClass(), element, "a");
Object c = SimpleReflection.getFieldValue(element.getClass(), element, "c");
try {
Object i = Ref.getUnsafe().allocateInstance(element.getClass());
SimpleReflection.setFieldValue(element.getClass(), i, "a", a);
SimpleReflection.setFieldValue(element.getClass(), i, "b", name);
SimpleReflection.setFieldValue(element.getClass(), i, "c", c);
copy.add(i);
} catch (InstantiationException e) {
e.printStackTrace();
}
}
packet.write("b", copy);
return packet;
}
public static void reset() {
queueSchedule.clear();
queueSchedule.offer(new THologramSchedule(() -> packetInit != null) {
@Override
public void before() {
learnTarget.setCustomName(" ");
}
@Override
public void after(Packet packet) {
packetName = packet;
}
});
}
public static void learn(Player player) {
player.getWorld().spawn(player.getLocation(), ArmorStand.class, c -> {
learnTarget = c;
learnTarget.setMarker(true);
learnTarget.setVisible(false);
learnTarget.setCustomName(" ");
learnTarget.setCustomNameVisible(true);
learnTarget.setBasePlate(false);
});
reset();
new BukkitRunnable() {
@Override
public void run() {
THologramSchedule schedule = queueSchedule.peek();
if (schedule == null) {
cancel();
learnTarget.remove();
} else if (schedule.check()) {
currentSchedule = queueSchedule.poll();
currentSchedule.before();
}
}
}.runTaskTimer(TabooLib.getPlugin(), 1, 1);
}
@EventHandler
public void e(PlayerJoinEvent e) {
THologram.refresh(e.getPlayer());
}
@EventHandler
public void e(PlayerQuitEvent e) {
THologram.remove(e.getPlayer());
}
@EventHandler
public void e(PlayerTeleportEvent e) {
THologram.refresh(e.getPlayer());
}
@EventHandler
public void e(PlayerChangedWorldEvent e) {
THologram.refresh(e.getPlayer());
}
@EventHandler
public void e(PlayerMoveEvent e) {
if (!e.getFrom().getBlock().equals(e.getTo().getBlock())) {
Bukkit.getScheduler().runTaskAsynchronously(TabooLib.getPlugin(), () -> THologram.refresh(e.getPlayer()));
}
}
// *********************************
//
// Getter and Setter
//
// *********************************
public static ArmorStand getLearnTarget() {
return learnTarget;
}
public static Packet getPacketSpawn() {
return packetSpawn;
}
public static Packet getPacketInit() {
return packetInit;
}
public static Packet getPacketName() {
return packetName;
}
}