mirror of
https://github.com/DiscordSRV/Ascension.git
synced 2024-11-25 12:25:15 +01:00
Implement nms advancement listener
This commit is contained in:
parent
ec02e5f88a
commit
77ee036cbf
@ -1,22 +1,142 @@
|
|||||||
package com.discordsrv.bukkit.listener.award;
|
package com.discordsrv.bukkit.listener.award;
|
||||||
|
|
||||||
import com.discordsrv.common.DiscordSRV;
|
import com.discordsrv.common.DiscordSRV;
|
||||||
|
import com.discordsrv.common.component.util.ComponentUtil;
|
||||||
|
import net.kyori.adventure.platform.bukkit.BukkitComponentSerializer;
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.advancement.Advancement;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.player.PlayerAdvancementDoneEvent;
|
import org.bukkit.event.player.PlayerAdvancementDoneEvent;
|
||||||
|
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
public class BukkitAdvancementListener extends AbstractBukkitAwardListener {
|
public class BukkitAdvancementListener extends AbstractBukkitAwardListener {
|
||||||
|
|
||||||
|
private final NMS nms;
|
||||||
|
|
||||||
public BukkitAdvancementListener(DiscordSRV discordSRV, IBukkitAwardForwarder forwarder) {
|
public BukkitAdvancementListener(DiscordSRV discordSRV, IBukkitAwardForwarder forwarder) {
|
||||||
super(discordSRV, forwarder);
|
super(discordSRV, forwarder);
|
||||||
|
|
||||||
|
String className = Bukkit.getServer().getClass().getName();
|
||||||
|
String[] packageParts = className.split("\\.");
|
||||||
|
if (packageParts.length != 5) {
|
||||||
|
this.nms = null;
|
||||||
|
logger.error("Server does not have NMS, incompatible with advancements.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String version = packageParts[3];
|
||||||
|
NMS nms = null;
|
||||||
|
try {
|
||||||
|
if ((version.startsWith("v1_19") && !version.startsWith("v1_19_R1") && !version.startsWith("v1_19_R2"))
|
||||||
|
|| version.startsWith("v1_2")) {
|
||||||
|
// 1.19.4+
|
||||||
|
nms = new NMS("org.bukkit.craftbukkit." + version + ".advancement.CraftAdvancement",
|
||||||
|
"k", "d", "i", "a");
|
||||||
|
} else {
|
||||||
|
// <1.19.4
|
||||||
|
nms = new NMS("org.bukkit.craftbukkit." + version + ".advancement.CraftAdvancement",
|
||||||
|
"j", "c", "i", "a");
|
||||||
|
}
|
||||||
|
} catch (Throwable t) {
|
||||||
|
logger.error("Could not get NMS methods for advancements.");
|
||||||
|
logger.debug(t);
|
||||||
|
}
|
||||||
|
this.nms = nms;
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.MONITOR)
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
public void onPlayerAdvancementDone(PlayerAdvancementDoneEvent event) {
|
public void onPlayerAdvancementDone(PlayerAdvancementDoneEvent event) {
|
||||||
// TODO:
|
if (nms == null) {
|
||||||
// - NMS: check if the advancement should be broadcasted to chat, returning if not
|
return;
|
||||||
// - run checkIfShouldSkip from parent
|
}
|
||||||
// - NMS: get advancement and/or 'advancement award message'
|
|
||||||
// - run forwarder.publishEvent
|
try {
|
||||||
|
ReturnData data = nms.getData(event.getAdvancement());
|
||||||
|
if (data == null || checkIfShouldSkip(event.getPlayer())) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
forwarder.publishEvent(
|
||||||
|
event.getPlayer(),
|
||||||
|
data.nameJson != null ? ComponentUtil.toAPI(BukkitComponentSerializer.gson().deserialize(data.nameJson)) : null,
|
||||||
|
data.titleJson != null ? ComponentUtil.toAPI(BukkitComponentSerializer.gson().deserialize(data.titleJson)) : null,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
logger.debug("Failed to get advancement data", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class NMS {
|
||||||
|
|
||||||
|
private final Method handleMethod;
|
||||||
|
private final Method advancementNameMethod;
|
||||||
|
private final Method advancementDisplayMethod;
|
||||||
|
private final Method broadcastToChatMethod;
|
||||||
|
private final Method titleMethod;
|
||||||
|
private final Method toJsonMethod;
|
||||||
|
|
||||||
|
public NMS(
|
||||||
|
String craftAdvancementClassName,
|
||||||
|
String nameMethodName,
|
||||||
|
String displayMethodName,
|
||||||
|
String broadcastToChatMethodName,
|
||||||
|
String titleMethodName
|
||||||
|
) throws ReflectiveOperationException {
|
||||||
|
Class<?> clazz = Class.forName(craftAdvancementClassName);
|
||||||
|
handleMethod = clazz.getDeclaredMethod("getHandle");
|
||||||
|
Class<?> nmsClass = handleMethod.getReturnType();
|
||||||
|
advancementNameMethod = nmsClass.getDeclaredMethod(nameMethodName);
|
||||||
|
advancementDisplayMethod = nmsClass.getDeclaredMethod(displayMethodName);
|
||||||
|
Class<?> displayClass = advancementDisplayMethod.getReturnType();
|
||||||
|
broadcastToChatMethod = displayClass.getDeclaredMethod(broadcastToChatMethodName);
|
||||||
|
titleMethod = displayClass.getDeclaredMethod(titleMethodName);
|
||||||
|
|
||||||
|
Class<?> serializer = Class.forName(titleMethod.getReturnType().getName() + "$ChatSerializer");
|
||||||
|
toJsonMethod = Arrays.stream(serializer.getDeclaredMethods())
|
||||||
|
.filter(method -> method.getReturnType().equals(String.class))
|
||||||
|
.findAny().orElseThrow(() -> new NoSuchMethodException("ChatSerializer toJson"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReturnData getData(Advancement advancement) throws ReflectiveOperationException {
|
||||||
|
Object nms = handleMethod.invoke(advancement);
|
||||||
|
Object display = advancementDisplayMethod.invoke(nms);
|
||||||
|
if (display == null) {
|
||||||
|
// Not something that would be displayed in chat
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean broadcastToChat = (boolean) broadcastToChatMethod.invoke(display);
|
||||||
|
if (!broadcastToChat) {
|
||||||
|
// Not something that would be displayed in chat
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object nameChat = advancementNameMethod.invoke(nms);
|
||||||
|
Object titleChat = titleMethod.invoke(display);
|
||||||
|
|
||||||
|
return new ReturnData(
|
||||||
|
toJson(nameChat),
|
||||||
|
toJson(titleChat)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String toJson(Object chat) throws ReflectiveOperationException {
|
||||||
|
return (String) toJsonMethod.invoke(chat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ReturnData {
|
||||||
|
|
||||||
|
private final String nameJson;
|
||||||
|
private final String titleJson;
|
||||||
|
|
||||||
|
public ReturnData(String nameJson, String titleJson) {
|
||||||
|
this.nameJson = nameJson;
|
||||||
|
this.titleJson = titleJson;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user