]> git.lizzy.rs Git - BoundingBoxOutlineReloaded.git/blob - src/main/java/com/irtimaled/bbor/client/gui/WorldSaveRow.java
3c8aca227e191840dd12cfa5ab7f0bb5c851e2c1
[BoundingBoxOutlineReloaded.git] / src / main / java / com / irtimaled / bbor / client / gui / WorldSaveRow.java
1 package com.irtimaled.bbor.client.gui;
2
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;
19
20 import java.io.File;
21 import java.io.FileInputStream;
22 import java.io.IOException;
23 import java.io.InputStream;
24 import java.text.DateFormat;
25 import java.text.SimpleDateFormat;
26 import java.util.Date;
27 import java.util.function.Consumer;
28
29 public class WorldSaveRow extends ControlListEntry implements Comparable<WorldSaveRow> {
30     private static final Logger LOGGER = LogManager.getLogger();
31     private static final DateFormat DATE_FORMAT = new SimpleDateFormat();
32     private static final Identifier ICON_MISSING = new Identifier("textures/misc/unknown_server.png");
33     private static final int ICON_SIZE = 20;
34     private final MinecraftClient client;
35     private final LevelSummary worldSummary;
36     private final LevelStorage saveLoader;
37     private final Consumer<ControlListEntry> setSelectedEntry;
38     private final Identifier iconLocation;
39     private final NativeImageBackedTexture icon;
40
41     private File iconFile;
42     private long lastClickTime;
43
44     WorldSaveRow(LevelSummary worldSummary, LevelStorage saveLoader, Consumer<ControlListEntry> setSelectedEntry) {
45         this.worldSummary = worldSummary;
46         this.saveLoader = saveLoader;
47         this.setSelectedEntry = setSelectedEntry;
48         this.client = MinecraftClient.getInstance();
49         this.iconLocation = new Identifier("worlds/" + Hashing.sha1().hashUnencodedChars(worldSummary.getName()) + "/icon");
50         this.iconFile = worldSummary.getFile();
51         if (!this.iconFile.isFile()) {
52             this.iconFile = null;
53         }
54
55         this.icon = this.loadIcon();
56     }
57
58     @Override
59     public boolean isMouseOver(double mouseX, double mouseY) {
60         return mouseX > this.getX() &&
61                 mouseX < this.getX() + ControlList.CONTROLS_WIDTH &&
62                 mouseY > this.getY() &&
63                 mouseY < this.getY() + this.getControlHeight();
64     }
65
66     @Override
67     public boolean mouseClicked(double mouseX, double mouseY, int button) {
68         if (!isMouseOver(mouseX, mouseY)) return false;
69
70         this.setSelectedEntry.accept(this);
71         if (Util.getMeasuringTimeMs() - this.lastClickTime < 250L) {
72             done();
73         } else {
74             this.lastClickTime = Util.getMeasuringTimeMs();
75         }
76         return true;
77     }
78
79     @Override
80     public void done() {
81         String fileName = this.worldSummary.getName();
82         LevelStorage.Session worldInfo = null;
83         try {
84             worldInfo = saveLoader.createSession(fileName);
85         } catch (IOException e) {
86             e.printStackTrace();
87         }
88         try {
89             long seed = NbtIo.readCompressed(new FileInputStream(worldInfo.getDirectory(WorldSavePath.LEVEL_DAT).toFile()))
90                     .getCompound("Data")
91                     .getCompound("WorldGenSettings").getLong("seed");
92             worldInfo.close();
93             ClientInterop.saveLoaded(fileName, seed);
94         } catch (IOException ignored) {
95         }
96     }
97
98     private NativeImageBackedTexture loadIcon() {
99         if (this.iconFile == null || !this.iconFile.isFile()) {
100             this.client.getTextureManager().destroyTexture(this.iconLocation);
101             return null;
102         }
103
104         try (InputStream stream = new FileInputStream(this.iconFile)) {
105             NativeImageBackedTexture texture = new NativeImageBackedTexture(NativeImage.read(stream));
106             this.client.getTextureManager().registerTexture(this.iconLocation, texture);
107             return texture;
108         } catch (Throwable exception) {
109             LOGGER.error("Invalid icon for world {}", this.worldSummary.getName(), exception);
110             this.iconFile = null;
111             return null;
112         }
113     }
114
115     @Override
116     public void render(MatrixStack matrixStack, int mouseX, int mouseY) {
117         String displayName = this.worldSummary.getDisplayName();
118         String details = this.worldSummary.getName() + " (" + DATE_FORMAT.format(new Date(this.worldSummary.getLastPlayed())) + ")";
119
120         int x = this.getX();
121         int y = this.getY();
122         this.client.textRenderer.draw(matrixStack, displayName, (float) (x + ICON_SIZE + 3), (float) (y + 1), 16777215);
123         this.client.textRenderer.draw(matrixStack, details, (float) (x + ICON_SIZE + 3), (float) (y + 1 + this.client.textRenderer.fontHeight + 1), 8421504);
124         this.client.getTextureManager().bindTexture(this.icon != null ? this.iconLocation : ICON_MISSING);
125         RenderHelper.enableBlend();
126         DrawableHelper.drawTexture(matrixStack, x, y, 0.0F, 0.0F, ICON_SIZE, ICON_SIZE, 32, 32);
127         RenderHelper.disableBlend();
128     }
129
130     @Override
131     public void filter(String lowerValue) {
132         super.setVisible(lowerValue.isEmpty() ||
133                 this.worldSummary.getDisplayName().toLowerCase().contains(lowerValue) ||
134                 this.worldSummary.getName().toLowerCase().contains(lowerValue));
135     }
136
137     @Override
138     public void close() {
139         if (this.icon != null) {
140             this.icon.close();
141         }
142     }
143
144     @Override
145     public int compareTo(WorldSaveRow other) {
146         return this.worldSummary.compareTo(other.worldSummary);
147     }
148 }