1 package com.irtimaled.bbor.client.gui;
3 import com.google.common.hash.Hashing;
4 import com.irtimaled.bbor.client.interop.ClientInterop;
5 import com.irtimaled.bbor.client.renderers.RenderHelper;
6 import net.minecraft.client.MinecraftClient;
7 import net.minecraft.client.gui.DrawableHelper;
8 import net.minecraft.client.texture.NativeImage;
9 import net.minecraft.client.texture.NativeImageBackedTexture;
10 import net.minecraft.client.util.math.MatrixStack;
11 import net.minecraft.nbt.NbtIo;
12 import net.minecraft.util.Identifier;
13 import net.minecraft.util.Util;
14 import net.minecraft.util.WorldSavePath;
15 import net.minecraft.world.level.storage.LevelStorage;
16 import net.minecraft.world.level.storage.LevelSummary;
17 import org.apache.logging.log4j.LogManager;
18 import org.apache.logging.log4j.Logger;
21 import java.io.FileInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.nio.file.Path;
25 import java.text.DateFormat;
26 import java.text.SimpleDateFormat;
27 import java.util.Date;
28 import java.util.function.Consumer;
30 public class WorldSaveRow extends ControlListEntry implements Comparable<WorldSaveRow> {
31 private static final Logger LOGGER = LogManager.getLogger();
32 private static final DateFormat DATE_FORMAT = new SimpleDateFormat();
33 private static final Identifier ICON_MISSING = new Identifier("textures/misc/unknown_server.png");
34 private static final int ICON_SIZE = 20;
35 private final MinecraftClient client;
36 private final LevelSummary worldSummary;
37 private final LevelStorage saveLoader;
38 private final Consumer<ControlListEntry> setSelectedEntry;
39 private final Identifier iconLocation;
40 private final NativeImageBackedTexture icon;
42 private Path iconPath;
43 private long lastClickTime;
45 WorldSaveRow(LevelSummary worldSummary, LevelStorage saveLoader, Consumer<ControlListEntry> setSelectedEntry) {
46 this.worldSummary = worldSummary;
47 this.saveLoader = saveLoader;
48 this.setSelectedEntry = setSelectedEntry;
49 this.client = MinecraftClient.getInstance();
50 this.iconPath = worldSummary.getIconPath();
51 this.iconLocation = new Identifier(this.iconPath.toString());
53 this.icon = this.loadIcon();
57 public boolean isMouseOver(double mouseX, double mouseY) {
58 return mouseX > this.getX() &&
59 mouseX < this.getX() + ControlList.CONTROLS_WIDTH &&
60 mouseY > this.getY() &&
61 mouseY < this.getY() + this.getControlHeight();
65 public boolean mouseClicked(double mouseX, double mouseY, int button) {
66 if (!isMouseOver(mouseX, mouseY)) return false;
68 this.setSelectedEntry.accept(this);
69 if (Util.getMeasuringTimeMs() - this.lastClickTime < 250L) {
72 this.lastClickTime = Util.getMeasuringTimeMs();
79 String fileName = this.worldSummary.getName();
80 LevelStorage.Session worldInfo = null;
82 worldInfo = saveLoader.createSession(fileName);
83 } catch (IOException e) {
87 long seed = NbtIo.readCompressed(new FileInputStream(worldInfo.getDirectory(WorldSavePath.LEVEL_DAT).toFile()))
89 .getCompound("WorldGenSettings").getLong("seed");
91 ClientInterop.saveLoaded(fileName, seed);
92 } catch (IOException ignored) {
96 private NativeImageBackedTexture loadIcon() {
97 try (InputStream stream = new FileInputStream(this.iconPath.toFile())) {
98 NativeImageBackedTexture texture = new NativeImageBackedTexture(NativeImage.read(stream));
99 this.client.getTextureManager().registerTexture(this.iconLocation, texture);
101 } catch (Throwable exception) {
102 LOGGER.error("Invalid icon for world {}", this.worldSummary.getName(), exception);
108 public void render(MatrixStack matrixStack, int mouseX, int mouseY) {
109 String displayName = this.worldSummary.getDisplayName();
110 String details = this.worldSummary.getName() + " (" + DATE_FORMAT.format(new Date(this.worldSummary.getLastPlayed())) + ")";
114 this.client.textRenderer.draw(matrixStack, displayName, (float) (x + ICON_SIZE + 3), (float) (y + 1), 16777215);
115 this.client.textRenderer.draw(matrixStack, details, (float) (x + ICON_SIZE + 3), (float) (y + 1 + this.client.textRenderer.fontHeight + 1), 8421504);
116 this.client.getTextureManager().bindTexture(this.icon != null ? this.iconLocation : ICON_MISSING);
117 RenderHelper.enableBlend();
118 DrawableHelper.drawTexture(matrixStack, x, y, 0.0F, 0.0F, ICON_SIZE, ICON_SIZE, 32, 32);
119 RenderHelper.disableBlend();
123 public void filter(String lowerValue) {
124 super.setVisible(lowerValue.isEmpty() ||
125 this.worldSummary.getDisplayName().toLowerCase().contains(lowerValue) ||
126 this.worldSummary.getName().toLowerCase().contains(lowerValue));
130 public void close() {
131 if (this.icon != null) {
137 public int compareTo(WorldSaveRow other) {
138 return this.worldSummary.compareTo(other.worldSummary);