minecraft-src/net/minecraft/client/multiplayer/ClientAdvancements.java
2025-07-04 03:45:38 +03:00

120 lines
4.5 KiB
Java

package net.minecraft.client.multiplayer;
import com.mojang.logging.LogUtils;
import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Map.Entry;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.advancements.AdvancementHolder;
import net.minecraft.advancements.AdvancementNode;
import net.minecraft.advancements.AdvancementProgress;
import net.minecraft.advancements.AdvancementTree;
import net.minecraft.advancements.DisplayInfo;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.components.toasts.AdvancementToast;
import net.minecraft.client.telemetry.WorldSessionTelemetryManager;
import net.minecraft.network.protocol.game.ClientboundUpdateAdvancementsPacket;
import net.minecraft.network.protocol.game.ServerboundSeenAdvancementsPacket;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@Environment(EnvType.CLIENT)
public class ClientAdvancements {
private static final Logger LOGGER = LogUtils.getLogger();
private final Minecraft minecraft;
private final WorldSessionTelemetryManager telemetryManager;
private final AdvancementTree tree = new AdvancementTree();
private final Map<AdvancementHolder, AdvancementProgress> progress = new Object2ObjectOpenHashMap<>();
@Nullable
private ClientAdvancements.Listener listener;
@Nullable
private AdvancementHolder selectedTab;
public ClientAdvancements(Minecraft minecraft, WorldSessionTelemetryManager telemetryManager) {
this.minecraft = minecraft;
this.telemetryManager = telemetryManager;
}
public void update(ClientboundUpdateAdvancementsPacket packet) {
if (packet.shouldReset()) {
this.tree.clear();
this.progress.clear();
}
this.tree.remove(packet.getRemoved());
this.tree.addAll(packet.getAdded());
for (Entry<ResourceLocation, AdvancementProgress> entry : packet.getProgress().entrySet()) {
AdvancementNode advancementNode = this.tree.get((ResourceLocation)entry.getKey());
if (advancementNode != null) {
AdvancementProgress advancementProgress = (AdvancementProgress)entry.getValue();
advancementProgress.update(advancementNode.advancement().requirements());
this.progress.put(advancementNode.holder(), advancementProgress);
if (this.listener != null) {
this.listener.onUpdateAdvancementProgress(advancementNode, advancementProgress);
}
if (!packet.shouldReset() && advancementProgress.isDone()) {
if (this.minecraft.level != null) {
this.telemetryManager.onAdvancementDone(this.minecraft.level, advancementNode.holder());
}
Optional<DisplayInfo> optional = advancementNode.advancement().display();
if (packet.shouldShowAdvancements() && optional.isPresent() && ((DisplayInfo)optional.get()).shouldShowToast()) {
this.minecraft.getToastManager().addToast(new AdvancementToast(advancementNode.holder()));
}
}
} else {
LOGGER.warn("Server informed client about progress for unknown advancement {}", entry.getKey());
}
}
}
public AdvancementTree getTree() {
return this.tree;
}
public void setSelectedTab(@Nullable AdvancementHolder advancement, boolean tellServer) {
ClientPacketListener clientPacketListener = this.minecraft.getConnection();
if (clientPacketListener != null && advancement != null && tellServer) {
clientPacketListener.send(ServerboundSeenAdvancementsPacket.openedTab(advancement));
}
if (this.selectedTab != advancement) {
this.selectedTab = advancement;
if (this.listener != null) {
this.listener.onSelectedTabChanged(advancement);
}
}
}
public void setListener(@Nullable ClientAdvancements.Listener listener) {
this.listener = listener;
this.tree.setListener(listener);
if (listener != null) {
this.progress.forEach((advancementHolder, advancementProgress) -> {
AdvancementNode advancementNode = this.tree.get(advancementHolder);
if (advancementNode != null) {
listener.onUpdateAdvancementProgress(advancementNode, advancementProgress);
}
});
listener.onSelectedTabChanged(this.selectedTab);
}
}
@Nullable
public AdvancementHolder get(ResourceLocation id) {
AdvancementNode advancementNode = this.tree.get(id);
return advancementNode != null ? advancementNode.holder() : null;
}
@Environment(EnvType.CLIENT)
public interface Listener extends AdvancementTree.Listener {
void onUpdateAdvancementProgress(AdvancementNode advancement, AdvancementProgress advancementProgress);
void onSelectedTabChanged(@Nullable AdvancementHolder advancement);
}
}