minecraft-src/net/minecraft/client/gui/screens/FaviconTexture.java
2025-07-04 03:45:38 +03:00

88 lines
2.7 KiB
Java

package net.minecraft.client.gui.screens;
import com.google.common.hash.Hashing;
import com.mojang.blaze3d.platform.NativeImage;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.Util;
import net.minecraft.client.renderer.texture.DynamicTexture;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.resources.ResourceLocation;
import org.jetbrains.annotations.Nullable;
@Environment(EnvType.CLIENT)
public class FaviconTexture implements AutoCloseable {
private static final ResourceLocation MISSING_LOCATION = ResourceLocation.withDefaultNamespace("textures/misc/unknown_server.png");
private static final int WIDTH = 64;
private static final int HEIGHT = 64;
private final TextureManager textureManager;
private final ResourceLocation textureLocation;
@Nullable
private DynamicTexture texture;
private boolean closed;
private FaviconTexture(TextureManager textureManager, ResourceLocation textureLocation) {
this.textureManager = textureManager;
this.textureLocation = textureLocation;
}
public static FaviconTexture forWorld(TextureManager textureManager, String worldName) {
return new FaviconTexture(
textureManager,
ResourceLocation.withDefaultNamespace(
"worlds/" + Util.sanitizeName(worldName, ResourceLocation::validPathChar) + "/" + Hashing.sha1().hashUnencodedChars(worldName) + "/icon"
)
);
}
public static FaviconTexture forServer(TextureManager textureManager, String worldName) {
return new FaviconTexture(textureManager, ResourceLocation.withDefaultNamespace("servers/" + Hashing.sha1().hashUnencodedChars(worldName) + "/icon"));
}
public void upload(NativeImage image) {
if (image.getWidth() == 64 && image.getHeight() == 64) {
try {
this.checkOpen();
if (this.texture == null) {
this.texture = new DynamicTexture(() -> "Favicon " + this.textureLocation, image);
} else {
this.texture.setPixels(image);
this.texture.upload();
}
this.textureManager.register(this.textureLocation, this.texture);
} catch (Throwable var3) {
image.close();
this.clear();
throw var3;
}
} else {
image.close();
throw new IllegalArgumentException("Icon must be 64x64, but was " + image.getWidth() + "x" + image.getHeight());
}
}
public void clear() {
this.checkOpen();
if (this.texture != null) {
this.textureManager.release(this.textureLocation);
this.texture.close();
this.texture = null;
}
}
public ResourceLocation textureLocation() {
return this.texture != null ? this.textureLocation : MISSING_LOCATION;
}
public void close() {
this.clear();
this.closed = true;
}
private void checkOpen() {
if (this.closed) {
throw new IllegalStateException("Icon already closed");
}
}
}