129 lines
5.2 KiB
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();
|
|
}
|
|
}
|
|
} |