From e0bed2d80e6dc2f2c3a426eecd709977ab65a3dd Mon Sep 17 00:00:00 2001 From: Brianna Date: Tue, 1 Jun 2021 16:14:23 -0500 Subject: [PATCH] Added WorldBorder support. --- .../com/songoda/core/world/WorldBorder.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 Core/src/main/java/com/songoda/core/world/WorldBorder.java diff --git a/Core/src/main/java/com/songoda/core/world/WorldBorder.java b/Core/src/main/java/com/songoda/core/world/WorldBorder.java new file mode 100644 index 00000000..b9ae890c --- /dev/null +++ b/Core/src/main/java/com/songoda/core/world/WorldBorder.java @@ -0,0 +1,89 @@ +package com.songoda.core.world; + +import com.songoda.core.compatibility.ServerVersion; +import com.songoda.core.utils.NMSUtils; +import org.bukkit.Location; +import org.bukkit.entity.Player; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class WorldBorder { + + private static Class packetPlayOutWorldBorderEnumClass; + private static Class worldBorderClass; + private static Class craftWorldClass; + private static Constructor packetPlayOutWorldBorderConstructor; + + static { + try { + Class packetPlayOutWorldBorder = NMSUtils.getNMSClass("PacketPlayOutWorldBorder"); + + if(packetPlayOutWorldBorder != null) { + if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_11)) + packetPlayOutWorldBorderEnumClass = packetPlayOutWorldBorder.getDeclaredClasses()[0]; + else + packetPlayOutWorldBorderEnumClass = packetPlayOutWorldBorder.getDeclaredClasses()[1]; + + worldBorderClass = NMSUtils.getNMSClass("WorldBorder"); + craftWorldClass = NMSUtils.getCraftClass("CraftWorld"); + + packetPlayOutWorldBorderConstructor = packetPlayOutWorldBorder.getConstructor(worldBorderClass, + packetPlayOutWorldBorderEnumClass); + } + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void send(Player player, Color color, double size, Location centerLocation) { + try { + if (centerLocation == null || centerLocation.getWorld() == null) + return; + + Object worldBorder = worldBorderClass.getConstructor().newInstance(); + + if (ServerVersion.isServerVersionAtLeast(ServerVersion.V1_9)) { + Object craftWorld = craftWorldClass.cast(centerLocation.getWorld()); + Method getHandleMethod = craftWorld.getClass().getMethod("getHandle"); + Object worldServer = getHandleMethod.invoke(craftWorld); + NMSUtils.setField(worldBorder, "world", worldServer, false); + } + + Method setCenter = worldBorder.getClass().getMethod("setCenter", double.class, double.class); + setCenter.invoke(worldBorder, centerLocation.getX(), centerLocation.getZ()); + + Method setSize = worldBorder.getClass().getMethod("setSize", double.class); + setSize.invoke(worldBorder, size); + + Method setWarningTime = worldBorder.getClass().getMethod("setWarningTime", int.class); + setWarningTime.invoke(worldBorder, 0); + + Method setWarningDistance = worldBorder.getClass().getMethod("setWarningDistance", int.class); + setWarningDistance.invoke(worldBorder, 0); + + Method transitionSizeBetween = worldBorder.getClass().getMethod("transitionSizeBetween", double.class, + double.class, long.class); + + if (color == Color.Green) { + transitionSizeBetween.invoke(worldBorder, size - 0.1D, size, 20000000L); + } else if (color == Color.Red) { + transitionSizeBetween.invoke(worldBorder, size, size - 1.0D, 20000000L); + } + + @SuppressWarnings({"unchecked", "rawtypes"}) + Object packet = packetPlayOutWorldBorderConstructor.newInstance(worldBorder, + Enum.valueOf((Class) packetPlayOutWorldBorderEnumClass, "INITIALIZE")); + NMSUtils.sendPacket(player, packet); + } catch (InstantiationException | InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { + e.printStackTrace(); + } + } + + public enum Color { + + Blue, Green, Red + + } +}