mirror of
https://github.com/TeamMidnightDust/PictureSign.git
synced 2025-12-13 04:45:10 +01:00
- Add support for local images - Add support for referencing Minecraft textures Big thanks to @Hendrix-Shen - Code cleanup
162 lines
5.8 KiB
Java
Executable File
162 lines
5.8 KiB
Java
Executable File
package eu.midnightdust.picturesign.util;
|
|
|
|
import eu.midnightdust.picturesign.PictureSignClient;
|
|
import eu.midnightdust.picturesign.config.PictureSignConfig;
|
|
import net.minecraft.client.MinecraftClient;
|
|
import net.minecraft.client.texture.NativeImage;
|
|
import net.minecraft.client.texture.NativeImageBackedTexture;
|
|
import net.minecraft.util.Identifier;
|
|
|
|
import javax.imageio.ImageIO;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.*;
|
|
import java.net.URL;
|
|
import java.util.Hashtable;
|
|
import java.util.concurrent.ExecutorService;
|
|
|
|
import static eu.midnightdust.picturesign.PictureSignClient.MOD_ID;
|
|
import static java.util.concurrent.Executors.newFixedThreadPool;
|
|
|
|
public class PictureDownloader {
|
|
|
|
public static class PictureData {
|
|
public String url;
|
|
public Identifier identifier;
|
|
|
|
public PictureData(String url) {
|
|
this.url = url;
|
|
}
|
|
}
|
|
static PictureDownloader downloader = new PictureDownloader();
|
|
|
|
public static PictureDownloader getInstance() {
|
|
return downloader;
|
|
}
|
|
|
|
// Create a service for downloading the picture
|
|
private final ExecutorService service = newFixedThreadPool(PictureSignConfig.maxThreads);
|
|
|
|
private final Hashtable<String, PictureData> cache = new Hashtable<>();
|
|
|
|
private final Object mutex = new Object();
|
|
|
|
// Downloads the picture, or returns the cached picture
|
|
public PictureData getPicture(String url) {
|
|
synchronized (mutex) {
|
|
// Try to get the picture from cache
|
|
PictureData data = this.cache.get(url);
|
|
if (data == null) {
|
|
// Download the picture if not in cache
|
|
this.loadPicture(url);
|
|
return null;
|
|
}
|
|
|
|
if (data.identifier == null) {
|
|
return null;
|
|
}
|
|
|
|
return data;
|
|
}
|
|
}
|
|
|
|
// Download the image and save it in cache
|
|
private void loadPicture(String url) {
|
|
if (url.startsWith("file:")) loadLocalPicture(url);
|
|
else if (url.startsWith("rp:")) loadResourcePackTexture(url);
|
|
else downloadPicture(url);
|
|
}
|
|
private void downloadPicture(String url) {
|
|
if (PictureSignConfig.debug) PictureSignClient.LOGGER.info("Started downloading picture: " + url);
|
|
this.cache.put(url, new PictureData(url));
|
|
|
|
service.submit(() -> {
|
|
try {
|
|
BufferedInputStream in = new BufferedInputStream(new URL(url).openStream());
|
|
File file = File.createTempFile("."+MOD_ID, "temp");
|
|
file.deleteOnExit();
|
|
|
|
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
|
|
|
|
byte[] dataBuffer = new byte[1024];
|
|
int bytesRead;
|
|
while ((bytesRead = in.read(dataBuffer, 0, 1024)) != -1) {
|
|
out.write(dataBuffer, 0, bytesRead);
|
|
}
|
|
|
|
out.close();
|
|
|
|
Identifier texture = convert2png(file);
|
|
|
|
// Cache the downloaded picture
|
|
synchronized (mutex) {
|
|
PictureData data = this.cache.get(url);
|
|
data.identifier = texture;
|
|
}
|
|
|
|
if (PictureSignConfig.debug) PictureSignClient.LOGGER.info("Finished downloading picture: " + url);
|
|
|
|
} catch (IOException error) {
|
|
PictureSignClient.LOGGER.error("Error downloading picture: " + error);
|
|
}
|
|
});
|
|
}
|
|
private void loadLocalPicture(String url) {
|
|
String realPath = url.replace("file:", "");
|
|
if (PictureSignConfig.debug) PictureSignClient.LOGGER.info("Started loading local picture: " + url);
|
|
|
|
this.cache.put(url, new PictureData(url));
|
|
service.submit(() -> {
|
|
try {
|
|
File file = new File(realPath);
|
|
Identifier texture = convert2png(file);
|
|
synchronized (mutex) {
|
|
PictureData data = this.cache.get(url);
|
|
data.identifier = texture;
|
|
}
|
|
|
|
} catch (IOException error) {
|
|
PictureSignClient.LOGGER.error("Error loading local picture: " + error);
|
|
}
|
|
});
|
|
|
|
if (PictureSignConfig.debug) PictureSignClient.LOGGER.info("Finished loading local picture: " + url);
|
|
}
|
|
private void loadResourcePackTexture(String url) {
|
|
String realIdentifierPath = url.replace("rp:", "");
|
|
if (!realIdentifierPath.endsWith(".png")) realIdentifierPath += ".png";
|
|
|
|
if (PictureSignConfig.debug) PictureSignClient.LOGGER.info("Started loading resource pack picture: " + url);
|
|
Identifier id = Identifier.tryParse(realIdentifierPath);
|
|
if (id == null) {
|
|
PictureSignClient.LOGGER.error("Unable to locate resource texture: " + url);
|
|
return;
|
|
}
|
|
|
|
this.cache.put(url, new PictureData(url));
|
|
service.submit(() -> {
|
|
synchronized (mutex) {
|
|
PictureData data = this.cache.get(url);
|
|
data.identifier = id;
|
|
}
|
|
});
|
|
|
|
if (PictureSignConfig.debug) PictureSignClient.LOGGER.info("Finished loading resource pack picture: " + url);
|
|
}
|
|
|
|
private static Identifier convert2png(File file) throws IOException {
|
|
BufferedImage bufferedImage = ImageIO.read(file);
|
|
|
|
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
ImageIO.write(bufferedImage, "png", byteArrayOutputStream);
|
|
|
|
InputStream inputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
|
|
|
NativeImage nativeImage = NativeImage.read(inputStream);
|
|
NativeImageBackedTexture nativeImageBackedTexture = new NativeImageBackedTexture(nativeImage);
|
|
|
|
return MinecraftClient.getInstance().getTextureManager().registerDynamicTexture("picturesign/image",
|
|
nativeImageBackedTexture);
|
|
}
|
|
}
|
|
|