minecraft-src/com/mojang/realmsclient/gui/screens/RealmsBrokenWorldScreen.java
2025-07-04 03:45:38 +03:00

272 lines
9.8 KiB
Java

package com.mojang.realmsclient.gui.screens;
import com.google.common.collect.Lists;
import com.mojang.logging.LogUtils;
import com.mojang.realmsclient.RealmsMainScreen;
import com.mojang.realmsclient.client.RealmsClient;
import com.mojang.realmsclient.dto.RealmsServer;
import com.mojang.realmsclient.dto.RealmsWorldOptions;
import com.mojang.realmsclient.dto.WorldDownload;
import com.mojang.realmsclient.dto.RealmsServer.State;
import com.mojang.realmsclient.exception.RealmsServiceException;
import com.mojang.realmsclient.gui.RealmsWorldSlotButton;
import com.mojang.realmsclient.util.RealmsTextureManager;
import com.mojang.realmsclient.util.task.OpenServerTask;
import com.mojang.realmsclient.util.task.SwitchSlotTask;
import java.util.Collection;
import java.util.List;
import java.util.Map.Entry;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.Button;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.network.chat.CommonComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.ComponentUtils;
import net.minecraft.realms.RealmsScreen;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.ARGB;
import net.minecraft.util.Mth;
import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
@Environment(EnvType.CLIENT)
public class RealmsBrokenWorldScreen extends RealmsScreen {
private static final ResourceLocation SLOT_FRAME_SPRITE = ResourceLocation.withDefaultNamespace("widget/slot_frame");
private static final Logger LOGGER = LogUtils.getLogger();
private static final int DEFAULT_BUTTON_WIDTH = 80;
private final Screen lastScreen;
@Nullable
private RealmsServer serverData;
private final long serverId;
private final Component[] message = new Component[]{
Component.translatable("mco.brokenworld.message.line1"), Component.translatable("mco.brokenworld.message.line2")
};
private int leftX;
private final List<Integer> slotsThatHasBeenDownloaded = Lists.<Integer>newArrayList();
private int animTick;
public RealmsBrokenWorldScreen(Screen lastScreen, long serverId, boolean isMinigame) {
super(isMinigame ? Component.translatable("mco.brokenworld.minigame.title") : Component.translatable("mco.brokenworld.title"));
this.lastScreen = lastScreen;
this.serverId = serverId;
}
@Override
public void init() {
this.leftX = this.width / 2 - 150;
this.addRenderableWidget(Button.builder(CommonComponents.GUI_BACK, button -> this.onClose()).bounds((this.width - 150) / 2, row(13) - 5, 150, 20).build());
if (this.serverData == null) {
this.fetchServerData(this.serverId);
} else {
this.addButtons();
}
}
@Override
public Component getNarrationMessage() {
return ComponentUtils.formatList(
(Collection<? extends Component>)Stream.concat(Stream.of(this.title), Stream.of(this.message)).collect(Collectors.toList()), CommonComponents.SPACE
);
}
private void addButtons() {
for (Entry<Integer, RealmsWorldOptions> entry : this.serverData.slots.entrySet()) {
int i = (Integer)entry.getKey();
boolean bl = i != this.serverData.activeSlot || this.serverData.isMinigameActive();
Button button;
if (bl) {
button = Button.builder(
Component.translatable("mco.brokenworld.play"),
buttonx -> this.minecraft
.setScreen(new RealmsLongRunningMcoTaskScreen(this.lastScreen, new SwitchSlotTask(this.serverData.id, i, this::doSwitchOrReset)))
)
.bounds(this.getFramePositionX(i), row(8), 80, 20)
.build();
button.active = !((RealmsWorldOptions)this.serverData.slots.get(i)).empty;
} else {
button = Button.builder(
Component.translatable("mco.brokenworld.download"),
buttonx -> this.minecraft
.setScreen(
RealmsPopups.infoPopupScreen(this, Component.translatable("mco.configure.world.restore.download.question.line1"), popupScreen -> this.downloadWorld(i))
)
)
.bounds(this.getFramePositionX(i), row(8), 80, 20)
.build();
}
if (this.slotsThatHasBeenDownloaded.contains(i)) {
button.active = false;
button.setMessage(Component.translatable("mco.brokenworld.downloaded"));
}
this.addRenderableWidget(button);
}
}
@Override
public void tick() {
this.animTick++;
}
@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, 17, -1);
for (int i = 0; i < this.message.length; i++) {
guiGraphics.drawCenteredString(this.font, this.message[i], this.width / 2, row(-1) + 3 + i * 12, -6250336);
}
if (this.serverData != null) {
for (Entry<Integer, RealmsWorldOptions> entry : this.serverData.slots.entrySet()) {
if (((RealmsWorldOptions)entry.getValue()).templateImage != null && ((RealmsWorldOptions)entry.getValue()).templateId != -1L) {
this.drawSlotFrame(
guiGraphics,
this.getFramePositionX((Integer)entry.getKey()),
row(1) + 5,
mouseX,
mouseY,
this.serverData.activeSlot == (Integer)entry.getKey() && !this.isMinigame(),
((RealmsWorldOptions)entry.getValue()).getSlotName((Integer)entry.getKey()),
(Integer)entry.getKey(),
((RealmsWorldOptions)entry.getValue()).templateId,
((RealmsWorldOptions)entry.getValue()).templateImage,
((RealmsWorldOptions)entry.getValue()).empty
);
} else {
this.drawSlotFrame(
guiGraphics,
this.getFramePositionX((Integer)entry.getKey()),
row(1) + 5,
mouseX,
mouseY,
this.serverData.activeSlot == (Integer)entry.getKey() && !this.isMinigame(),
((RealmsWorldOptions)entry.getValue()).getSlotName((Integer)entry.getKey()),
(Integer)entry.getKey(),
-1L,
null,
((RealmsWorldOptions)entry.getValue()).empty
);
}
}
}
}
private int getFramePositionX(int index) {
return this.leftX + (index - 1) * 110;
}
private void fetchServerData(long serverId) {
new Thread(() -> {
RealmsClient realmsClient = RealmsClient.getOrCreate();
try {
this.serverData = realmsClient.getOwnRealm(serverId);
this.addButtons();
} catch (RealmsServiceException var5) {
LOGGER.error("Couldn't get own world", (Throwable)var5);
this.minecraft.setScreen(new RealmsGenericErrorScreen(var5, this.lastScreen));
}
}).start();
}
public void doSwitchOrReset() {
new Thread(
() -> {
RealmsClient realmsClient = RealmsClient.getOrCreate();
if (this.serverData.state == State.CLOSED) {
this.minecraft
.execute(() -> this.minecraft.setScreen(new RealmsLongRunningMcoTaskScreen(this, new OpenServerTask(this.serverData, this, true, this.minecraft))));
} else {
try {
RealmsServer realmsServer = realmsClient.getOwnRealm(this.serverId);
this.minecraft.execute(() -> RealmsMainScreen.play(realmsServer, this));
} catch (RealmsServiceException var3) {
LOGGER.error("Couldn't get own world", (Throwable)var3);
this.minecraft.execute(() -> this.minecraft.setScreen(this.lastScreen));
}
}
}
)
.start();
}
private void downloadWorld(int slotIndex) {
RealmsClient realmsClient = RealmsClient.getOrCreate();
try {
WorldDownload worldDownload = realmsClient.requestDownloadInfo(this.serverData.id, slotIndex);
RealmsDownloadLatestWorldScreen realmsDownloadLatestWorldScreen = new RealmsDownloadLatestWorldScreen(
this, worldDownload, this.serverData.getWorldName(slotIndex), bl -> {
if (bl) {
this.slotsThatHasBeenDownloaded.add(slotIndex);
this.clearWidgets();
this.addButtons();
} else {
this.minecraft.setScreen(this);
}
}
);
this.minecraft.setScreen(realmsDownloadLatestWorldScreen);
} catch (RealmsServiceException var5) {
LOGGER.error("Couldn't download world data", (Throwable)var5);
this.minecraft.setScreen(new RealmsGenericErrorScreen(var5, this));
}
}
@Override
public void onClose() {
this.minecraft.setScreen(this.lastScreen);
}
private boolean isMinigame() {
return this.serverData != null && this.serverData.isMinigameActive();
}
private void drawSlotFrame(
GuiGraphics guiGraphics,
int x,
int y,
int mouseX,
int mouseY,
boolean isActiveNonMinigame,
String text,
int slotIndex,
long templateId,
@Nullable String templateImage,
boolean hasTemplateImage
) {
ResourceLocation resourceLocation;
if (hasTemplateImage) {
resourceLocation = RealmsWorldSlotButton.EMPTY_SLOT_LOCATION;
} else if (templateImage != null && templateId != -1L) {
resourceLocation = RealmsTextureManager.worldTemplate(String.valueOf(templateId), templateImage);
} else if (slotIndex == 1) {
resourceLocation = RealmsWorldSlotButton.DEFAULT_WORLD_SLOT_1;
} else if (slotIndex == 2) {
resourceLocation = RealmsWorldSlotButton.DEFAULT_WORLD_SLOT_2;
} else if (slotIndex == 3) {
resourceLocation = RealmsWorldSlotButton.DEFAULT_WORLD_SLOT_3;
} else {
resourceLocation = RealmsTextureManager.worldTemplate(String.valueOf(this.serverData.minigameId), this.serverData.minigameImage);
}
if (isActiveNonMinigame) {
float f = 0.9F + 0.1F * Mth.cos(this.animTick * 0.2F);
guiGraphics.blit(RenderType::guiTextured, resourceLocation, x + 3, y + 3, 0.0F, 0.0F, 74, 74, 74, 74, 74, 74, ARGB.colorFromFloat(1.0F, f, f, f));
guiGraphics.blitSprite(RenderType::guiTextured, SLOT_FRAME_SPRITE, x, y, 80, 80);
} else {
int i = ARGB.colorFromFloat(1.0F, 0.56F, 0.56F, 0.56F);
guiGraphics.blit(RenderType::guiTextured, resourceLocation, x + 3, y + 3, 0.0F, 0.0F, 74, 74, 74, 74, 74, 74, i);
guiGraphics.blitSprite(RenderType::guiTextured, SLOT_FRAME_SPRITE, x, y, 80, 80, i);
}
guiGraphics.drawCenteredString(this.font, text, x + 40, y + 66, -1);
}
}