Cleanup advancement field names, fix skin errors on old versions

This commit is contained in:
Vankka 2025-02-15 16:44:54 +02:00
parent f647d992a5
commit d624eaaacd
No known key found for this signature in database
GPG Key ID: 62E48025ED4E7EBB
10 changed files with 121 additions and 58 deletions

View File

@ -39,7 +39,7 @@ import org.jetbrains.annotations.Nullable;
public class AwardMessageReceiveEvent extends AbstractGameMessageReceiveEvent implements PlayerEvent {
private final DiscordSRVPlayer player;
private MinecraftComponent name;
private MinecraftComponent message;
private MinecraftComponent title;
private MinecraftComponent description;
private AdvancementFrame frame;
@ -48,7 +48,7 @@ public class AwardMessageReceiveEvent extends AbstractGameMessageReceiveEvent im
public AwardMessageReceiveEvent(
@Nullable Object triggeringEvent,
@NotNull DiscordSRVPlayer player,
@Nullable MinecraftComponent name,
@Nullable MinecraftComponent message,
@Nullable MinecraftComponent title,
@Nullable MinecraftComponent description,
@Nullable AdvancementFrame frame,
@ -57,8 +57,8 @@ public class AwardMessageReceiveEvent extends AbstractGameMessageReceiveEvent im
) {
super(triggeringEvent, cancelled);
this.player = player;
this.name = name;
this.title = title;
this.message = message;
this.description = description;
this.frame = frame;
this.gameChannel = gameChannel;
@ -71,12 +71,12 @@ public class AwardMessageReceiveEvent extends AbstractGameMessageReceiveEvent im
}
@Nullable
public MinecraftComponent getName() {
return name;
public MinecraftComponent getMessage() {
return message;
}
public void setName(@Nullable MinecraftComponent name) {
this.name = name;
public void setMessage(@Nullable MinecraftComponent message) {
this.message = message;
}
@Nullable

View File

@ -33,6 +33,7 @@ import org.jetbrains.annotations.NotNull;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Locale;
public class BukkitLegacyAdvancementListener extends AbstractBukkitListener<PlayerAdvancementDoneEvent> {
@ -47,15 +48,35 @@ public class BukkitLegacyAdvancementListener extends AbstractBukkitListener<Play
NMS nms = null;
try {
String nmsVersion = server.getClass().getName().split("\\.")[3];
if ((version.startsWith("1.19") && !version.matches("1.19.[1-3].*"))
|| version.startsWith("1.2")) {
// 1.19.4+
nms = new NMS("org.bukkit.craftbukkit." + nmsVersion + ".advancement.CraftAdvancement",
"d", "i", "a");
String cbClassName = "org.bukkit.craftbukkit." + nmsVersion + ".advancement.CraftAdvancement";
if (version.startsWith("1.12")
|| version.startsWith("1.13")
|| version.startsWith("1.14")
|| version.startsWith("1.15")
|| version.startsWith("1.16")
|| version.startsWith("1.17")
|| version.startsWith("1.18")) {
nms = new NMS(
cbClassName,
// nms Advancement
"c",
// nms AdvancementDisplay
"i", "a", "b", "e",
// nms AdvancementFrameType
"a"
);
} else if (version.startsWith("1.19")) {
nms = new NMS(
cbClassName,
// nms Advancement
"d",
// nms AdvancementDisplay
"i", "a", "b", "e",
// nms AdvancementFrameType
"a"
);
} else {
// <1.19.4
nms = new NMS("org.bukkit.craftbukkit." + nmsVersion + ".advancement.CraftAdvancement",
"c", "i", "a");
logger().error("Unsupported version for legacy advancements: " + version);
}
} catch (Throwable t) {
logger().error("Could not get NMS methods for advancements.");
@ -88,15 +109,21 @@ public class BukkitLegacyAdvancementListener extends AbstractBukkitListener<Play
}
MinecraftComponent title = MinecraftComponent.fromJson(data.titleJson);
MinecraftComponent description = MinecraftComponent.fromJson(data.descriptionJson);
AwardMessageReceiveEvent.AdvancementFrame frame =
data.frameId != null
? AwardMessageReceiveEvent.AdvancementFrame.valueOf(data.frameId.toUpperCase(Locale.ROOT))
: null;
IPlayer srvPlayer = discordSRV.playerProvider().player(event.getPlayer());
discordSRV.eventBus().publish(
new AwardMessageReceiveEvent(
event,
srvPlayer,
null,
title,
null,
null,
null,
description,
frame,
null,
false
)
@ -108,25 +135,50 @@ public class BukkitLegacyAdvancementListener extends AbstractBukkitListener<Play
private static class NMS {
// CraftAdvancement
private final Method handleMethod;
// nms Advancement
private final Method advancementDisplayMethod;
// nms AdvancementDisplay
private final Method broadcastToChatMethod;
private final Method titleMethod;
private final Method descriptionMethod;
private final Method frameMethod;
// nms AdvancementFrameType
private final Method idMethod;
// nms IChatBaseComponent$ChatSerializer
private final Method toJsonMethod;
public NMS(
String craftAdvancementClassName,
// nms Advancement
String displayMethodName,
// nms AdvancementDisplay
String broadcastToChatMethodName,
String titleMethodName
String titleMethodName,
String descriptionName,
String frameMethodName,
// nms AdvancementFrameType
String idMethodName
) throws ReflectiveOperationException {
Class<?> clazz = Class.forName(craftAdvancementClassName);
handleMethod = clazz.getDeclaredMethod("getHandle");
Class<?> nmsClass = handleMethod.getReturnType();
advancementDisplayMethod = nmsClass.getDeclaredMethod(displayMethodName);
Class<?> displayClass = advancementDisplayMethod.getReturnType();
broadcastToChatMethod = displayClass.getDeclaredMethod(broadcastToChatMethodName);
titleMethod = displayClass.getDeclaredMethod(titleMethodName);
Class<?> advancementClass = handleMethod.getReturnType();
advancementDisplayMethod = advancementClass.getDeclaredMethod(displayMethodName);
Class<?> advancementDisplayClass = advancementDisplayMethod.getReturnType();
broadcastToChatMethod = advancementDisplayClass.getDeclaredMethod(broadcastToChatMethodName);
titleMethod = advancementDisplayClass.getDeclaredMethod(titleMethodName);
descriptionMethod = advancementDisplayClass.getDeclaredMethod(descriptionName);
frameMethod = advancementDisplayClass.getDeclaredMethod(frameMethodName);
Class<?> advancementFrameTypeClass = frameMethod.getReturnType();
idMethod = advancementFrameTypeClass.getDeclaredMethod(idMethodName);
Class<?> serializer = Class.forName(titleMethod.getReturnType().getName() + "$ChatSerializer");
toJsonMethod = Arrays.stream(serializer.getDeclaredMethods())
@ -134,23 +186,28 @@ public class BukkitLegacyAdvancementListener extends AbstractBukkitListener<Play
.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) {
public ReturnData getData(Advancement bukkitAdvancement) throws ReflectiveOperationException {
Object advancement = handleMethod.invoke(bukkitAdvancement);
Object advancementDisplay = advancementDisplayMethod.invoke(advancement);
if (advancementDisplay == null) {
// Not something that would be displayed in chat
return null;
}
boolean broadcastToChat = (boolean) broadcastToChatMethod.invoke(display);
boolean broadcastToChat = (boolean) broadcastToChatMethod.invoke(advancementDisplay);
if (!broadcastToChat) {
// Not something that would be displayed in chat
return null;
}
Object titleChat = titleMethod.invoke(display);
Object titleChat = titleMethod.invoke(advancementDisplay);
Object descriptionChat = descriptionMethod.invoke(advancementDisplay);
Enum<?> enumValue = (Enum<?>) frameMethod.invoke(advancementDisplay);
String enumId = enumValue != null ? (String) idMethod.invoke(enumValue) : null;
return new ReturnData(
toJson(titleChat)
toJson(titleChat),
toJson(descriptionChat),
enumId
);
}
@ -162,9 +219,13 @@ public class BukkitLegacyAdvancementListener extends AbstractBukkitListener<Play
private static class ReturnData {
private final String titleJson;
private final String descriptionJson;
private final String frameId;
public ReturnData(String titleJson) {
public ReturnData(String titleJson, String descriptionJson, String frameId) {
this.titleJson = titleJson;
this.descriptionJson = descriptionJson;
this.frameId = frameId;
}
}

View File

@ -41,8 +41,8 @@ public class PaperAdvancementListener extends AbstractBukkitListener<PlayerAdvan
private static final PaperComponentHandle.Get<PlayerAdvancementDoneEvent> MESSAGE_HANDLE
= PaperComponentHandle.get(PlayerAdvancementDoneEvent.class, "message");
private static final PaperComponentHandle.Get<Advancement> ADVANCEMENT_DISPLAY_NAME_HANDLE
= PaperComponentHandle.get(Advancement.class, "displayName");
private static final PaperComponentHandle.Get<AdvancementDisplay> ADVANCEMENT_TITLE_HANDLE
= PaperComponentHandle.get(AdvancementDisplay.class, "title");
private static final PaperComponentHandle.Get<AdvancementDisplay> ADVANCEMENT_DESCRIPTION_HANDLE
= PaperComponentHandle.get(AdvancementDisplay.class, "description");
@ -72,7 +72,7 @@ public class PaperAdvancementListener extends AbstractBukkitListener<PlayerAdvan
}
MinecraftComponent message = MESSAGE_HANDLE.getAPI(event);
MinecraftComponent name = ADVANCEMENT_DISPLAY_NAME_HANDLE.getAPI(advancement);
MinecraftComponent title = ADVANCEMENT_TITLE_HANDLE.getAPI(display);
MinecraftComponent description = ADVANCEMENT_DESCRIPTION_HANDLE.getAPI(display);
IPlayer player = discordSRV.playerProvider().player(event.getPlayer());
@ -80,8 +80,8 @@ public class PaperAdvancementListener extends AbstractBukkitListener<PlayerAdvan
new AwardMessageReceiveEvent(
event,
player,
name,
message,
title,
description,
AwardMessageReceiveEvent.AdvancementFrame.valueOf(display.frame().toString()),
null,

View File

@ -64,16 +64,25 @@ public final class PaperPlayerUtil {
}
@ApiStatus.AvailableSince("Paper 1.16")
public static boolean LOCALE_SUPPORTED = ReflectionUtil.methodExists(Player.class, "locale", new Class[0]);
public static final boolean LOCALE_SUPPORTED = ReflectionUtil.methodExists(Player.class, "locale", new Class[0]);
public static Locale locale(Player player) {
return player.locale();
}
public static boolean SKIN_AVAILABLE = ReflectionUtil.classExists("com.destroystokyo.paper.profile.PlayerProfile");
private static final boolean SKIN_AVAILABLE = ReflectionUtil.classExists("com.destroystokyo.paper.profile.PlayerProfile")
&& ReflectionUtil.methodExists("com.destroystokyo.paper.profile.PlayerProfile", "getTextures");
public static final boolean SKIN_AVAILABLE_ONLINE = SKIN_AVAILABLE && ReflectionUtil.methodExists(Player.class, "getPlayerProfile", new String[0]);
public static final boolean SKIN_AVAILABLE_OFFLINE = SKIN_AVAILABLE && ReflectionUtil.methodExists(Player.class, "getPlayerProfile", new String[0]);
@SuppressWarnings("RedundantCast") // Not redundant
public static SkinInfo getSkinInfo(OfflinePlayer player) {
PlayerProfile playerProfile = player.getPlayerProfile();
PlayerProfile playerProfile;
if (player instanceof Player) {
playerProfile = ((Player) player).getPlayerProfile();
} else {
playerProfile = player.getPlayerProfile();
}
if (!playerProfile.hasTextures()) {
return null;
}

View File

@ -53,8 +53,8 @@ public class BukkitAchievementListener extends AbstractBukkitListener<PlayerAchi
new AwardMessageReceiveEvent(
event,
player,
achievementName,
null,
achievementName,
null,
null,
null,

View File

@ -35,7 +35,7 @@ public class BukkitOfflinePlayerImpl extends BukkitOfflinePlayer {
@Override
public @Nullable SkinInfo skinInfo() {
if (PaperPlayerUtil.SKIN_AVAILABLE) {
if (PaperPlayerUtil.SKIN_AVAILABLE_OFFLINE) {
return PaperPlayerUtil.getSkinInfo(offlinePlayer);
}
if (SpigotPlayerUtil.SKIN_AVAILABLE) {

View File

@ -62,7 +62,7 @@ public class BukkitPlayerImpl extends BukkitPlayer {
@Override
public @Nullable SkinInfo skinInfo() {
if (PaperPlayerUtil.SKIN_AVAILABLE) {
if (PaperPlayerUtil.SKIN_AVAILABLE_ONLINE) {
return PaperPlayerUtil.getSkinInfo(player);
}
if (SpigotPlayerUtil.SKIN_AVAILABLE) {

View File

@ -39,7 +39,7 @@ public class AwardMessageConfig implements IMessageConfig {
.addEmbed(
DiscordMessageEmbed.builder()
.setAuthor(
"%award_title|text:'{player_name} made the advancement {award_name}'%",
"%award_message|text:'{player_name} made the advancement {award_display_name}'%",
null,
"%player_avatar_url%"
)

View File

@ -32,9 +32,7 @@ import com.discordsrv.common.DiscordSRV;
import com.discordsrv.common.config.main.channels.base.BaseChannelConfig;
import com.discordsrv.common.config.main.channels.base.server.ServerBaseChannelConfig;
import com.discordsrv.common.config.main.channels.server.AwardMessageConfig;
import com.discordsrv.common.util.ComponentUtil;
import com.github.benmanes.caffeine.cache.Cache;
import net.kyori.adventure.text.Component;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -92,20 +90,15 @@ public class AwardMessageModule extends AbstractGameMessageModule<AwardMessageCo
@Override
public void setPlaceholders(AwardMessageConfig config, AwardMessageReceiveEvent event, SendableDiscordMessage.Formatter formatter) {
MinecraftComponent nameComponent = event.getName();
Component name = nameComponent != null ? ComponentUtil.fromAPI(nameComponent) : null;
MinecraftComponent titleComponent = event.getTitle();
Component title = titleComponent != null ? ComponentUtil.fromAPI(titleComponent) : null;
MinecraftComponent descriptionComponent = event.getDescription();
Component description = descriptionComponent != null ? ComponentUtil.fromAPI(descriptionComponent) : null;
MinecraftComponent message = event.getMessage();
MinecraftComponent displayName = event.getTitle();
MinecraftComponent description = event.getDescription();
Color color = event.getFrame() != null ? event.getFrame().color() : null;
formatter
.addPlaceholder("award_name", name)
.addPlaceholder("award_title", title)
.addPlaceholder("award_message", message)
.addPlaceholder("award_display_name", displayName)
.addPlaceholder("award_description", description)
.addPlaceholder("award_color", color, "color");
}

View File

@ -60,8 +60,8 @@ public class FabricAdvancementModule extends AbstractFabricModule {
AdvancementDisplay display = displayOptional.get();
AdvancementFrame frame = display.getFrame();
MinecraftComponent name = ComponentUtil.toAPI(discordSRV.getAdventure().asAdventure(display.getTitle()));
MinecraftComponent title = ComponentUtil.toAPI(discordSRV.getAdventure().asAdventure(frame.getChatAnnouncementText(advancementEntry, owner)));
MinecraftComponent message = ComponentUtil.toAPI(discordSRV.getAdventure().asAdventure(frame.getChatAnnouncementText(advancementEntry, owner)));
MinecraftComponent title = ComponentUtil.toAPI(discordSRV.getAdventure().asAdventure(display.getTitle()));
MinecraftComponent description = ComponentUtil.toAPI(discordSRV.getAdventure().asAdventure(display.getDescription()));
IPlayer player = discordSRV.playerProvider().player(owner);
@ -69,7 +69,7 @@ public class FabricAdvancementModule extends AbstractFabricModule {
new AwardMessageReceiveEvent(
null,
player,
name,
message,
title,
description,
AwardMessageReceiveEvent.AdvancementFrame.valueOf(frame.toString()),