package com.carpentersblocks;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;
import javax.imageio.ImageIO;
import net.minecraft.client.Minecraft;
import net.minecraft.client.resources.ResourcePackFileNotFoundException;
import net.minecraft.client.resources.SimpleReloadableResourceManager;
import org.apache.commons.io.FilenameUtils;
import org.apache.logging.log4j.Level;
import com.carpentersblocks.util.ModLogger;
import com.carpentersblocks.util.handler.DesignHandler;
import com.google.common.base.Charsets;
import cpw.mods.fml.client.FMLClientHandler;
import cpw.mods.fml.client.FMLFileResourcePack;
import cpw.mods.fml.common.DummyModContainer;
import cpw.mods.fml.common.ModContainer;
import cpw.mods.fml.common.ModMetadata;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
@SideOnly(Side.CLIENT)
public class CarpentersBlocksCachedResources extends DummyModContainer {
public final static CarpentersBlocksCachedResources INSTANCE = new CarpentersBlocksCachedResources();
private String MODID = "CarpentersBlocksCachedResources";
private String resourceDir = FilenameUtils.normalizeNoEndSeparator(Minecraft.getMinecraft().mcDataDir.getAbsolutePath()) + File.separator + "mods" + File.separator + CarpentersBlocks.MODID.toLowerCase();
private static ZipFile resourcePackZipFile;
private static ArrayList<Object[]> resources = new ArrayList<Object[]>();
private final int RESOURCE_PATH = 0;
private final int RESOURCE_IMAGE = 1;
private CarpentersBlocksCachedResources()
{
super(new ModMetadata());
ModMetadata meta = getMetadata();
meta.modId = MODID;
meta.name = "Carpenter's Blocks Cached Resources";
meta.description = "Holds dynamically-created resources used with Carpenter's Blocks.";
}
/**
* Initializes
*/
public void init()
{
FMLClientHandler.instance().addModAsResource(this);
// Add resource pack to global list without triggering a full refresh
((SimpleReloadableResourceManager)Minecraft.getMinecraft().getResourceManager()).reloadResourcePack(FMLClientHandler.instance().getResourcePackFor(MODID));
}
public static class DynamicFileResourcePack extends FMLFileResourcePack {
public DynamicFileResourcePack(ModContainer container)
{
super(container);
}
public ZipFile getResourcePackZipFile()
{
if (resourcePackZipFile == null) {
INSTANCE.rebuildCache();
}
return resourcePackZipFile;
}
@Override
protected InputStream getInputStreamByName(String resourceName) throws IOException
{
ZipFile zipfile = getResourcePackZipFile();
ZipEntry zipentry = zipfile.getEntry(resourceName);
try {
if ("pack.mcmeta".equals(resourceName)) {
return new ByteArrayInputStream(("{\n"+" \"pack\": {\n"+" \"description\": \"dummy FML pack for "+getPackName()+"\",\n"+" \"pack_format\": 1\n"+"}\n" + "}").getBytes(Charsets.UTF_8));
} else {
return zipfile.getInputStream(zipentry);
}
} catch (IOException e) {
throw new ResourcePackFileNotFoundException(resourcePackFile, resourceName);
}
}
@Override
public boolean hasResourceName(String resourceName)
{
return getResourcePackZipFile().getEntry(resourceName) != null;
}
}
@Override
public File getSource()
{
return new File(resourceDir, MODID + ".zip");
}
@Override
public Class<?> getCustomResourcePackClass()
{
return DynamicFileResourcePack.class;
}
/**
* Adds a resource to list to be added to resource pack.
*/
public void addResource(String path, BufferedImage bufferedImage)
{
resources.add(new Object[] { path, bufferedImage });
}
/**
* Creates final resource pack zip file.
*/
private void createResourceZipFile()
{
try {
if (createDirectory()) {
createZip(resourceDir, MODID + ".zip");
resourcePackZipFile = new ZipFile(getSource());
}
} catch (Exception e) {
ModLogger.log(Level.WARN, "Cache rebuild failed: " + e.getMessage());
}
}
/**
* Creates directory for resource file.
*/
private boolean createDirectory() throws Exception
{
File dir = new File(resourceDir);
if (!dir.exists()) {
dir.mkdir();
}
return dir.exists();
}
/**
* Creates resource zip file.
*/
private void createZip(String dir, String fileName) throws Exception
{
File file = new File(dir, fileName);
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(file));
for (Object[] object : resources) {
out.putNextEntry(new ZipEntry("assets/" + MODID.toLowerCase() + (String) object[RESOURCE_PATH] + ".png"));
ImageIO.write((BufferedImage) object[RESOURCE_IMAGE], "png", out);
out.closeEntry();
}
out.flush();
out.close();
}
/**
* Refreshes dynamic resources and creates new resource pack.
*/
public void rebuildCache()
{
DesignHandler.addResources(Minecraft.getMinecraft().getResourceManager());
createResourceZipFile();
resources.clear();
}
}