Skip to content

Commit

Permalink
fix: CraftBukkitFacet for bossbars
Browse files Browse the repository at this point in the history
  • Loading branch information
Machine-Maker committed Jun 12, 2022
1 parent 5a7609c commit 2563ccd
Showing 1 changed file with 57 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
Expand All @@ -47,6 +49,7 @@
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function;
import net.kyori.adventure.audience.MessageType;
import net.kyori.adventure.identity.Identity;
import net.kyori.adventure.nbt.BinaryTagIO;
Expand Down Expand Up @@ -81,6 +84,7 @@
import org.jetbrains.annotations.Nullable;

import static java.lang.invoke.MethodHandles.dropArguments;
import static java.lang.invoke.MethodType.genericMethodType;
import static java.lang.invoke.MethodType.methodType;
import static net.kyori.adventure.platform.bukkit.BukkitComponentSerializer.gson;
import static net.kyori.adventure.platform.bukkit.BukkitComponentSerializer.legacy;
Expand Down Expand Up @@ -938,17 +942,63 @@ protected void sendOpenPacket(final @NotNull Player viewer) throws Throwable {

static final class BossBar extends BukkitFacet.BossBar {
private static final Class<?> CLASS_CRAFT_BOSS_BAR = findCraftClass("boss.CraftBossBar");
private static final Class<?> CLASS_BOSS_BAR_ACTION = findClass(
findNmsClassName("PacketPlayOutBoss$Action"),
findMcClassName("network.protocol.game.PacketPlayOutBoss$Action"),
findMcClassName("network.protocol.game.ClientboundBossEventPacket$Operation")
);
private static final Object BOSS_BAR_ACTION_TITLE = findEnum(CLASS_BOSS_BAR_ACTION, "UPDATE_NAME", 3);
private static final Class<?> CLASS_BOSS_BAR_ACTION;
private static final Object BOSS_BAR_ACTION_TITLE;
private static final MethodHandle CRAFT_BOSS_BAR_HANDLE;
private static final MethodHandle NMS_BOSS_BATTLE_SET_NAME;
private static final MethodHandle NMS_BOSS_BATTLE_SEND_UPDATE;

static {
Class<?> classBossBarAction = null;
Object bossBarActionTitle = null;
classBossBarAction = findClass(
findNmsClassName("PacketPlayOutBoss$Action"),
findMcClassName("network.protocol.game.PacketPlayOutBoss$Action"),
findMcClassName("network.protocol.game.ClientboundBossEventPacket$Operation")
);
if (classBossBarAction == null || !classBossBarAction.isEnum()) {
classBossBarAction = null;
final Class<?> packetClass = findClass(
findNmsClassName("PacketPlayOutBoss"),
findMcClassName("network.protocol.game.PacketPlayOutBoss"),
findMcClassName("network.protocol.game.ClientboundBossEventPacket")
);
final Class<?> bossEventClass = findClass(
findNmsClassName("BossBattle"),
findMcClassName("world.BossBattle"),
findMcClassName("world.BossEvent")
);
if (packetClass != null && bossEventClass != null) { // 1.17+
try {
final MethodType methodType = methodType(packetClass, bossEventClass);
String methodName;
try {
packetClass.getDeclaredMethod("createUpdateNamePacket", bossEventClass);
methodName = "createUpdateNamePacket";
} catch (final NoSuchMethodException ignored) {
methodName = "c"; // is same for 1.17, 1.18, 1.19
}
final MethodHandle factoryMethod = lookup().findStatic(packetClass, methodName, methodType);
bossBarActionTitle = LambdaMetafactory.metafactory(
lookup(),
"apply",
methodType(Function.class),
methodType.generic(),
factoryMethod,
methodType
).getTarget().invoke();
classBossBarAction = Function.class;
} catch (final Throwable error) {
logError(error, "Failed to initialize CraftBossBar constructor");
}
}
} else {
bossBarActionTitle = findEnum(classBossBarAction, "UPDATE_NAME", 3);
}

CLASS_BOSS_BAR_ACTION = classBossBarAction;
BOSS_BAR_ACTION_TITLE = bossBarActionTitle;

MethodHandle craftBossBarHandle = null;
MethodHandle nmsBossBattleSetName = null;
MethodHandle nmsBossBattleSendUpdate = null;
Expand All @@ -964,7 +1014,7 @@ static final class BossBar extends BukkitFacet.BossBar {
break;
}
}
nmsBossBattleSendUpdate = lookup().findVirtual(nmsBossBattleType, "sendUpdate", methodType(void.class, CLASS_BOSS_BAR_ACTION));
nmsBossBattleSendUpdate = findMethod(nmsBossBattleType, new String[]{"sendUpdate", "a", "broadcast"}, void.class, CLASS_BOSS_BAR_ACTION);
} catch (final Throwable error) {
logError(error, "Failed to initialize CraftBossBar constructor");
}
Expand Down

0 comments on commit 2563ccd

Please sign in to comment.