diff --git a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java index f75405160..fc3c86dd4 100644 --- a/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java +++ b/core/src/main/java/org/geysermc/geyser/level/GeyserAdvancement.java @@ -28,6 +28,7 @@ package org.geysermc.geyser.level; import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; import lombok.NonNull; import org.geysermc.geyser.session.cache.AdvancementsCache; +import org.geysermc.geyser.text.ChatColor; import java.util.List; @@ -69,6 +70,14 @@ public class GeyserAdvancement { return this.advancement.getDisplayData(); } + /** + * @return Purple for challenges and green for normal advancements + */ + public String getDisplayColor() { + Advancement.DisplayData displayData = getDisplayData(); + return displayData != null && displayData.getFrameType() == Advancement.DisplayData.FrameType.CHALLENGE ? ChatColor.LIGHT_PURPLE : ChatColor.GREEN; + } + public String getRootId(AdvancementsCache advancementsCache) { if (rootId == null) { if (this.advancement.getParentId() == null) { diff --git a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java index 0df842d1d..206d97b0b 100644 --- a/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java +++ b/core/src/main/java/org/geysermc/geyser/session/cache/AdvancementsCache.java @@ -38,6 +38,7 @@ import org.geysermc.geyser.text.MinecraftLocale; import org.geysermc.cumulus.SimpleForm; import org.geysermc.cumulus.response.SimpleFormResponse; +import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -76,15 +77,15 @@ public class AdvancementsCache { .translator(MinecraftLocale::getLocaleString, session.getLocale()) .title("gui.advancements"); - boolean hasAdvancements = false; + List rootAdvancementIds = new ArrayList<>(); for (Map.Entry advancement : storedAdvancements.entrySet()) { if (advancement.getValue().getParentId() == null) { // No parent means this is a root advancement - hasAdvancements = true; builder.button(MessageTranslator.convertMessage(advancement.getValue().getDisplayData().getTitle(), session.getLocale())); + rootAdvancementIds.add(advancement.getKey()); } } - if (!hasAdvancements) { + if (rootAdvancementIds.isEmpty()) { builder.content("advancements.empty"); } @@ -94,20 +95,7 @@ public class AdvancementsCache { return; } - String id = ""; - - int advancementIndex = 0; - for (Map.Entry advancement : storedAdvancements.entrySet()) { - if (advancement.getValue().getParentId() == null) { // Root advancement - if (advancementIndex == response.getClickedButtonId()) { - id = advancement.getKey(); - break; - } else { - advancementIndex++; - } - } - } - + String id = rootAdvancementIds.get(response.getClickedButtonId()); if (!id.equals("")) { if (id.equals(currentAdvancementCategoryId)) { // The server thinks we are already on this tab @@ -136,12 +124,16 @@ public class AdvancementsCache { .title(MessageTranslator.convertMessage(categoryAdvancement.getDisplayData().getTitle(), language)) .content(MessageTranslator.convertMessage(categoryAdvancement.getDisplayData().getDescription(), language)); + List visibleAdvancements = new ArrayList<>(); if (currentAdvancementCategoryId != null) { for (GeyserAdvancement advancement : storedAdvancements.values()) { - if (advancement != null) { + boolean earned = isEarned(advancement); + if (earned || !advancement.getDisplayData().isHidden()) { if (advancement.getParentId() != null && currentAdvancementCategoryId.equals(advancement.getRootId(this))) { - boolean color = isEarned(advancement) || !advancement.getDisplayData().isShowToast(); - builder.button((color ? ChatColor.DARK_GREEN : "") + MessageTranslator.convertMessage(advancement.getDisplayData().getTitle()) + '\n'); + String color = earned ? advancement.getDisplayColor() : ""; + builder.button(color + MessageTranslator.convertMessage(advancement.getDisplayData().getTitle()) + '\n'); + + visibleAdvancements.add(advancement); } } } @@ -157,22 +149,8 @@ public class AdvancementsCache { return; } - GeyserAdvancement advancement = null; - int advancementIndex = 0; - // Loop around to find the advancement that the client pressed - for (GeyserAdvancement advancementEntry : storedAdvancements.values()) { - if (advancementEntry.getParentId() != null && - currentAdvancementCategoryId.equals(advancementEntry.getRootId(this))) { - if (advancementIndex == response.getClickedButtonId()) { - advancement = advancementEntry; - break; - } else { - advancementIndex++; - } - } - } - - if (advancement != null) { + if (response.getClickedButtonId() < visibleAdvancements.size()) { + GeyserAdvancement advancement = visibleAdvancements.get(response.getClickedButtonId()); buildAndShowInfoForm(advancement); } else { buildAndShowMenuForm(); diff --git a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java index f65c17374..a1d8da90c 100644 --- a/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java +++ b/core/src/main/java/org/geysermc/geyser/translator/protocol/java/JavaUpdateAdvancementsTranslator.java @@ -27,7 +27,7 @@ package org.geysermc.geyser.translator.protocol.java; import com.github.steveice10.mc.protocol.data.game.advancement.Advancement; import com.github.steveice10.mc.protocol.packet.ingame.clientbound.ClientboundUpdateAdvancementsPacket; -import com.nukkitx.protocol.bedrock.packet.SetTitlePacket; +import com.nukkitx.protocol.bedrock.packet.ToastRequestPacket; import org.geysermc.geyser.session.GeyserSession; import org.geysermc.geyser.translator.protocol.PacketTranslator; import org.geysermc.geyser.translator.protocol.Translator; @@ -36,7 +36,7 @@ import org.geysermc.geyser.session.cache.AdvancementsCache; import org.geysermc.geyser.level.GeyserAdvancement; import org.geysermc.geyser.text.MinecraftLocale; -import java.util.Map; +import java.util.Locale; @Translator(packet = ClientboundUpdateAdvancementsPacket.class) public class JavaUpdateAdvancementsTranslator extends PacketTranslator { @@ -56,48 +56,39 @@ public class JavaUpdateAdvancementsTranslator extends PacketTranslator> progress : packet.getProgress().entrySet()) { - GeyserAdvancement advancement = session.getAdvancementsCache().getStoredAdvancements().get(progress.getKey()); + for (String advancementId : packet.getProgress().keySet()) { + GeyserAdvancement advancement = session.getAdvancementsCache().getStoredAdvancements().get(advancementId); if (advancement != null && advancement.getDisplayData() != null) { - if (session.getAdvancementsCache().isEarned(advancement)) { - // Java uses some pink color for toast challenge completes - String color = advancement.getDisplayData().getFrameType() == Advancement.DisplayData.FrameType.CHALLENGE ? - "§d" : "§a"; + if (advancement.getDisplayData().isShowToast() && session.getAdvancementsCache().isEarned(advancement)) { + String frameType = advancement.getDisplayData().getFrameType().toString().toLowerCase(Locale.ROOT); + String frameTitle = advancement.getDisplayColor() + MinecraftLocale.getLocaleString("advancements.toast." + frameType, session.getLocale()); String advancementName = MessageTranslator.convertMessage(advancement.getDisplayData().getTitle(), session.getLocale()); - // Send an action bar message stating they earned an achievement - // Sent for instances where broadcasting advancements through chat are disabled - SetTitlePacket titlePacket = new SetTitlePacket(); - titlePacket.setText(color + "[" + MinecraftLocale.getLocaleString("advancements.toast." + - advancement.getDisplayData().getFrameType().toString().toLowerCase(), session.getLocale()) + "]§f " + advancementName); - titlePacket.setType(SetTitlePacket.Type.ACTIONBAR); - titlePacket.setFadeOutTime(3); - titlePacket.setFadeInTime(3); - titlePacket.setStayTime(3); - titlePacket.setXuid(""); - titlePacket.setPlatformOnlineId(""); - session.sendUpstreamPacket(titlePacket); + ToastRequestPacket toastRequestPacket = new ToastRequestPacket(); + toastRequestPacket.setTitle(frameTitle); + toastRequestPacket.setContent(advancementName); + session.sendUpstreamPacket(toastRequestPacket); } } }