package com.mojang.realmsclient.gui.screens; import com.google.common.collect.Lists; import com.mojang.logging.LogUtils; import com.mojang.realmsclient.util.task.RealmCreationTask; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import java.util.stream.Collectors; import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.components.Button; import net.minecraft.client.gui.components.ObjectSelectionList; import net.minecraft.network.chat.CommonComponents; import net.minecraft.network.chat.Component; import net.minecraft.realms.RealmsLabel; import net.minecraft.realms.RealmsScreen; import net.minecraft.world.level.storage.LevelStorageSource; import net.minecraft.world.level.storage.LevelSummary; import org.jetbrains.annotations.Nullable; import org.slf4j.Logger; @Environment(EnvType.CLIENT) public class RealmsSelectFileToUploadScreen extends RealmsScreen { private static final Logger LOGGER = LogUtils.getLogger(); public static final Component TITLE = Component.translatable("mco.upload.select.world.title"); private static final Component UNABLE_TO_LOAD_WORLD = Component.translatable("selectWorld.unable_to_load"); static final Component WORLD_TEXT = Component.translatable("selectWorld.world"); private static final DateFormat DATE_FORMAT = new SimpleDateFormat(); @Nullable private final RealmCreationTask realmCreationTask; private final RealmsResetWorldScreen lastScreen; private final long realmId; private final int slotId; Button uploadButton; List levelList = Lists.newArrayList(); int selectedWorld = -1; RealmsSelectFileToUploadScreen.WorldSelectionList worldSelectionList; public RealmsSelectFileToUploadScreen(@Nullable RealmCreationTask realmCreationTask, long realmId, int slotId, RealmsResetWorldScreen lastScreen) { super(TITLE); this.realmCreationTask = realmCreationTask; this.lastScreen = lastScreen; this.realmId = realmId; this.slotId = slotId; } private void loadLevelList() { LevelStorageSource.LevelCandidates levelCandidates = this.minecraft.getLevelSource().findLevelCandidates(); this.levelList = (List)((List)this.minecraft.getLevelSource().loadLevelSummaries(levelCandidates).join()) .stream() .filter(LevelSummary::canUpload) .collect(Collectors.toList()); for (LevelSummary levelSummary : this.levelList) { this.worldSelectionList.addEntry(levelSummary); } } @Override public void init() { this.worldSelectionList = this.addRenderableWidget(new RealmsSelectFileToUploadScreen.WorldSelectionList()); try { this.loadLevelList(); } catch (Exception var2) { LOGGER.error("Couldn't load level list", (Throwable)var2); this.minecraft.setScreen(new RealmsGenericErrorScreen(UNABLE_TO_LOAD_WORLD, Component.nullToEmpty(var2.getMessage()), this.lastScreen)); return; } this.uploadButton = this.addRenderableWidget( Button.builder(Component.translatable("mco.upload.button.name"), button -> this.upload()).bounds(this.width / 2 - 154, this.height - 32, 153, 20).build() ); this.uploadButton.active = this.selectedWorld >= 0 && this.selectedWorld < this.levelList.size(); this.addRenderableWidget( Button.builder(CommonComponents.GUI_BACK, button -> this.minecraft.setScreen(this.lastScreen)).bounds(this.width / 2 + 6, this.height - 32, 153, 20).build() ); this.addLabel(new RealmsLabel(Component.translatable("mco.upload.select.world.subtitle"), this.width / 2, row(-1), -6250336)); if (this.levelList.isEmpty()) { this.addLabel(new RealmsLabel(Component.translatable("mco.upload.select.world.none"), this.width / 2, this.height / 2 - 20, -1)); } } @Override public Component getNarrationMessage() { return CommonComponents.joinForNarration(this.getTitle(), this.createLabelNarration()); } private void upload() { if (this.selectedWorld != -1) { LevelSummary levelSummary = (LevelSummary)this.levelList.get(this.selectedWorld); this.minecraft.setScreen(new RealmsUploadScreen(this.realmCreationTask, this.realmId, this.slotId, this.lastScreen, levelSummary)); } } @Override public void render(GuiGraphics guiGraphics, int mouseX, int mouseY, float partialTick) { super.render(guiGraphics, mouseX, mouseY, partialTick); guiGraphics.drawCenteredString(this.font, this.title, this.width / 2, 13, -1); } @Override public boolean keyPressed(int keyCode, int scanCode, int modifiers) { if (keyCode == 256) { this.minecraft.setScreen(this.lastScreen); return true; } else { return super.keyPressed(keyCode, scanCode, modifiers); } } static Component gameModeName(LevelSummary levelSummary) { return levelSummary.getGameMode().getLongDisplayName(); } static String formatLastPlayed(LevelSummary levelSummary) { return DATE_FORMAT.format(new Date(levelSummary.getLastPlayed())); } @Environment(EnvType.CLIENT) class Entry extends ObjectSelectionList.Entry { private final LevelSummary levelSummary; private final String name; private final Component id; private final Component info; public Entry(final LevelSummary levelSummary) { this.levelSummary = levelSummary; this.name = levelSummary.getLevelName(); this.id = Component.translatable("mco.upload.entry.id", levelSummary.getLevelId(), RealmsSelectFileToUploadScreen.formatLastPlayed(levelSummary)); this.info = levelSummary.getInfo(); } @Override public void render(GuiGraphics guiGraphics, int index, int top, int left, int width, int height, int mouseX, int mouseY, boolean hovering, float partialTick) { this.renderItem(guiGraphics, index, left, top); } @Override public boolean mouseClicked(double mouseX, double mouseY, int button) { RealmsSelectFileToUploadScreen.this.worldSelectionList.setSelectedIndex(RealmsSelectFileToUploadScreen.this.levelList.indexOf(this.levelSummary)); return super.mouseClicked(mouseX, mouseY, button); } protected void renderItem(GuiGraphics guiGraphics, int index, int x, int y) { String string; if (this.name.isEmpty()) { string = RealmsSelectFileToUploadScreen.WORLD_TEXT + " " + (index + 1); } else { string = this.name; } guiGraphics.drawString(RealmsSelectFileToUploadScreen.this.font, string, x + 2, y + 1, -1); guiGraphics.drawString(RealmsSelectFileToUploadScreen.this.font, this.id, x + 2, y + 12, -8355712); guiGraphics.drawString(RealmsSelectFileToUploadScreen.this.font, this.info, x + 2, y + 12 + 10, -8355712); } @Override public Component getNarration() { Component component = CommonComponents.joinLines( Component.literal(this.levelSummary.getLevelName()), Component.literal(RealmsSelectFileToUploadScreen.formatLastPlayed(this.levelSummary)), RealmsSelectFileToUploadScreen.gameModeName(this.levelSummary) ); return Component.translatable("narrator.select", component); } } @Environment(EnvType.CLIENT) class WorldSelectionList extends ObjectSelectionList { public WorldSelectionList() { super( Minecraft.getInstance(), RealmsSelectFileToUploadScreen.this.width, RealmsSelectFileToUploadScreen.this.height - 40 - RealmsSelectFileToUploadScreen.row(0), RealmsSelectFileToUploadScreen.row(0), 36 ); } public void addEntry(LevelSummary levelSummary) { this.addEntry(RealmsSelectFileToUploadScreen.this.new Entry(levelSummary)); } public void setSelected(@Nullable RealmsSelectFileToUploadScreen.Entry entry) { super.setSelected(entry); RealmsSelectFileToUploadScreen.this.selectedWorld = this.children().indexOf(entry); RealmsSelectFileToUploadScreen.this.uploadButton.active = RealmsSelectFileToUploadScreen.this.selectedWorld >= 0 && RealmsSelectFileToUploadScreen.this.selectedWorld < this.getItemCount(); } @Override public int getRowWidth() { return (int)(this.width * 0.6); } } }