Core/src/eu/univento/core/api/effects/WorldBoarder.java

129 lines
5.2 KiB
Java

package eu.univento.core.api.effects;
import eu.univento.core.Core;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
/**
* @author MrSheepSheep
* @version 0.1
*/
public class WorldBoarder {
private static Method handle, sendPacket;
private static Method center, distance, time, movement;
private static Field player_connection;
private static Constructor<?> constructor, border_constructor;
private static Object constant;
static {
try {
handle = getClass("org.bukkit.craftbukkit", "entity.CraftPlayer").getMethod("getHandle");
player_connection = getClass("net.minecraft.server", "EntityPlayer").getField("playerConnection");
for (Method m : getClass("net.minecraft.server", "PlayerConnection").getMethods()) {
if (m.getName().equals("sendPacket")) {
sendPacket = m;
break;
}
}
Class<?> enumclass;
try {
enumclass = getClass("net.minecraft.server", "EnumWorldBorderAction");
} catch(ClassNotFoundException x) {
enumclass = getClass("net.minecraft.server", "PacketPlayOutWorldBorder$EnumWorldBorderAction");
}
constructor = getClass("net.minecraft.server", "PacketPlayOutWorldBorder").getConstructor(getClass("net.minecraft.server", "WorldBorder"), enumclass);
border_constructor = getClass("net.minecraft.server", "WorldBorder").getConstructor();
Method[] methods = getClass("net.minecraft.server", "WorldBorder").getMethods();
String setCenter = "setCenter";
String setWarningDistance = "setWarningDistance";
String setWarningTime = "setWarningTime";
String transitionSizeBetween = "transitionSizeBetween";
if (!inClass(methods, setCenter))
setCenter = "c";
if (!inClass(methods, setWarningDistance))
setWarningDistance = "c";
if (!inClass(methods, setWarningTime))
setWarningTime = "b";
if (!inClass(methods, transitionSizeBetween))
transitionSizeBetween = "a";
center = getClass("net.minecraft.server", "WorldBorder").getMethod(setCenter, double.class, double.class);
distance = getClass("net.minecraft.server", "WorldBorder").getMethod(setWarningDistance, int.class);
time = getClass("net.minecraft.server", "WorldBorder").getMethod(setWarningTime, int.class);
movement = getClass("net.minecraft.server", "WorldBorder").getMethod(transitionSizeBetween, double.class, double.class, long.class);
for (Object o: enumclass.getEnumConstants()) {
if (o.toString().equals("INITIALIZE")) {
constant = o;
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private static boolean inClass(Method[] methods, String methodName){
for (Method m : methods)
if (Objects.equals(m.getName(), methodName))
return true;
return false;
}
private static Class<?> getClass(String prefix, String name) throws Exception {
return Class.forName((prefix + ".") + Bukkit.getServer().getClass().getPackage().getName().substring(Bukkit.getServer().getClass().getPackage().getName().lastIndexOf(".") + 1) + "." + name);
}
Core plugin;
protected List<String> togglelist = new ArrayList<>();
protected WorldBoarder(Core plugin) {
this.plugin = plugin;
}
protected void sendBorder(Player p, int percentage, int intensity){
percentage = Math.round(percentage / intensity);
setBorder(p, percentage);
fadeBorder(p, percentage, 5);
}
protected void fadeBorder(Player p, int percentage, long time){
int dist = -10000 * percentage + 1300000;
sendWorldBorderPacket(p, 0, 200000D, (double) dist, (long) 1000 * time + 4000); //Add 4000 to make sure the "security" zone does not count in the fade time
}
protected void removeBorder(Player p) {
sendWorldBorderPacket(p, 0, 200000D, 200000D, 0);
}
protected void setBorder(Player p, int percentage){
int dist = -10000 * percentage + 1300000;
sendWorldBorderPacket(p, dist, 200000D, 200000D, 0);
}
protected void sendWorldBorderPacket(Player p, int dist, double oldradius, double newradius, long delay) {
try {
Object worldborder = border_constructor.newInstance();
center.invoke(worldborder, p.getLocation().getX(), p.getLocation().getY());
distance.invoke(worldborder, dist);
time.invoke(worldborder, 15);
movement.invoke(worldborder, oldradius, newradius, delay);
Object packet = constructor.newInstance(worldborder, constant);
sendPacket.invoke(player_connection.get(handle.invoke(p)), packet);
} catch(Exception x) {
x.printStackTrace();
}
}
}