Package com.pclewis.mcpatcher

Source Code of com.pclewis.mcpatcher.TexturePackAPI$ChangeHandler

package com.pclewis.mcpatcher;

import net.minecraft.client.Minecraft;
import net.minecraft.src.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.lang.reflect.Field;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class TexturePackAPI {
    private static final MCLogger logger = MCLogger.getLogger("Texture Pack");

    public static TexturePackAPI instance = new TexturePackAPI();
    public static boolean loadFontFromTexturePack;

    private static final ArrayList<Field> textureMapFields = new ArrayList<Field>();

    private static TexturePackBase texturePack;

    static {
        try {
            for (Field field : RenderEngine.class.getDeclaredFields()) {
                if (HashMap.class.isAssignableFrom(field.getType())) {
                    field.setAccessible(true);
                    textureMapFields.add(field);
                }
            }
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public static TexturePackBase getTexturePack() {
        return texturePack;
    }

    static TexturePackBase getCurrentTexturePack() {
        Minecraft minecraft = MCPatcherUtils.getMinecraft();
        if (minecraft == null) {
            return null;
        }
        TexturePackList texturePackList = minecraft.texturePackList;
        if (texturePackList == null) {
            return null;
        }
        return texturePackList.getSelectedTexturePack();
    }

    public static boolean isDefaultTexturePack() {
        return getTexturePack() instanceof TexturePackDefault;
    }

    public static String[] parseTextureName(String s) {
        String[] result = new String[]{null, s};
        if (s.startsWith("##")) {
            result[0] = "##";
            result[1] = s.substring(2);
        } else if (s.startsWith("%")) {
            int index = s.indexOf('%', 1);
            if (index > 0) {
                result[0] = s.substring(0, index + 1);
                result[1] = s.substring(index + 1);
            }
        }
        return result;
    }

    public static InputStream getInputStream(String s) {
        return instance.getInputStreamImpl(s);
    }

    public static boolean hasResource(String s) {
        if (s.endsWith(".png")) {
            return getImage(s) != null;
        } else if (s.endsWith(".properties")) {
            return getProperties(s) != null;
        } else {
            InputStream is = getInputStream(s);
            MCPatcherUtils.close(is);
            return is != null;
        }
    }

    public static BufferedImage getImage(String s) {
        return instance.getImageImpl(s);
    }

    public static BufferedImage getImage(Object o, String s) {
        return getImage(s);
    }

    public static Properties getProperties(String s) {
        Properties properties = new Properties();
        if (getProperties(s, properties)) {
            return properties;
        } else {
            return null;
        }
    }

    public static boolean getProperties(String s, Properties properties) {
        return instance.getPropertiesImpl(s, properties);
    }

    public static String[] listResources(String directory, String suffix) {
        if (directory == null) {
            directory = "";
        }
        if (directory.startsWith("/")) {
            directory = directory.substring(1);
        }
        if (suffix == null) {
            suffix = "";
        }

        ArrayList<String> resources = new ArrayList<String>();
        if (texturePack instanceof TexturePackDefault) {
            // nothing
        } else if (texturePack instanceof TexturePackCustom) {
            ZipFile zipFile = ((TexturePackCustom) texturePack).zipFile;
            if (zipFile != null) {
                for (ZipEntry entry : Collections.list(zipFile.entries())) {
                    final String name = entry.getName();
                    if (name.startsWith(directory) && name.endsWith(suffix)) {
                        resources.add("/" + name);
                    }
                }
            }
        } else if (texturePack instanceof TexturePackFolder) {
            File folder = ((TexturePackFolder) texturePack).getFolder();
            if (folder != null && folder.isDirectory()) {
                String[] list = new File(folder, directory).list();
                if (list != null) {
                    for (String s : list) {
                        if (s.endsWith(suffix)) {
                            resources.add("/" + new File(new File(directory), s).getPath().replace('\\', '/'));
                        }
                    }
                }
            }
        }

        Collections.sort(resources);
        return resources.toArray(new String[resources.size()]);
    }

    public static int getTextureIfLoaded(String s) {
        RenderEngine renderEngine = MCPatcherUtils.getMinecraft().renderEngine;
        for (Field field : textureMapFields) {
            try {
                HashMap map = (HashMap) field.get(renderEngine);
                if (map != null) {
                    Object value = map.get(s);
                    if (value instanceof Integer) {
                        return (Integer) value;
                    }
                }
            } catch (IllegalAccessException e) {
            }
        }
        return -1;
    }

    public static boolean isTextureLoaded(String s) {
        return getTextureIfLoaded(s) >= 0;
    }

    public static int unloadTexture(String s) {
        int texture = getTextureIfLoaded(s);
        if (texture >= 0) {
            logger.finest("unloading texture %s", s);
            RenderEngine renderEngine = MCPatcherUtils.getMinecraft().renderEngine;
            renderEngine.deleteTexture(texture);
            for (Field field : textureMapFields) {
                try {
                    HashMap map = (HashMap) field.get(renderEngine);
                    if (map != null) {
                        map.remove(s);
                    }
                } catch (IllegalAccessException e) {
                }
            }
        }
        return texture;
    }

    public static String getTextureName(int texture) {
        if (texture >= 0) {
            RenderEngine renderEngine = MCPatcherUtils.getMinecraft().renderEngine;
            for (Field field : textureMapFields) {
                try {
                    HashMap map = (HashMap) field.get(renderEngine);
                    for (Object o : map.entrySet()) {
                        Map.Entry entry = (Map.Entry) o;
                        Object value = entry.getValue();
                        Object key = entry.getKey();
                        if (value instanceof Integer && key instanceof String && (Integer) value == texture) {
                            return (String) key;
                        }
                    }
                } catch (IllegalAccessException e) {
                }
            }
        }
        return null;
    }

    protected InputStream getInputStreamImpl(String s) {
        s = parseTextureName(s)[1];
        if (!loadFontFromTexturePack && s.startsWith("/font/")) {
            return TexturePackAPI.class.getResourceAsStream(s);
        } else if (texturePack == null) {
            TexturePackBase currentTexturePack = getCurrentTexturePack();
            if (currentTexturePack == null) {
                return TexturePackAPI.class.getResourceAsStream(s);
            } else {
                return currentTexturePack.getInputStream(s);
            }
        } else {
            return texturePack.getInputStream(s);
        }
    }

    protected BufferedImage getImageImpl(String s) {
        InputStream input = getInputStream(s);
        BufferedImage image = null;
        if (input != null) {
            try {
                image = ImageIO.read(input);
            } catch (IOException e) {
                logger.severe("could not read %s", s);
                e.printStackTrace();
            } finally {
                MCPatcherUtils.close(input);
            }
        }
        return image;
    }

    protected boolean getPropertiesImpl(String s, Properties properties) {
        if (properties != null) {
            InputStream input = getInputStream(s);
            try {
                if (input != null) {
                    properties.load(input);
                    return true;
                }
            } catch (IOException e) {
                logger.severe("could not read %s");
                e.printStackTrace();
            } finally {
                MCPatcherUtils.close(input);
            }
        }
        return false;
    }

    abstract public static class ChangeHandler {
        private static final ArrayList<ChangeHandler> handlers = new ArrayList<ChangeHandler>();
        private static boolean changing;

        private static final boolean autoRefreshTextures = MCPatcherUtils.getBoolean("autoRefreshTextures", false);
        private static long lastCheckTime;

        protected final String name;
        protected final int order;

        protected ChangeHandler(String name, int order) {
            this.name = name;
            this.order = order;
        }

        abstract protected void onChange();

        public static void register(ChangeHandler handler) {
            if (handler != null) {
                if (texturePack != null) {
                    try {
                        logger.info("initializing %s...", handler.name);
                        handler.onChange();
                    } catch (Throwable e) {
                        e.printStackTrace();
                        logger.severe("%s initialization failed", handler.name);
                    }
                }
                handlers.add(handler);
                logger.fine("registered texture pack handler %s, priority %d", handler.name, handler.order);
                Collections.sort(handlers, new Comparator<ChangeHandler>() {
                    public int compare(ChangeHandler o1, ChangeHandler o2) {
                        return o1.order - o2.order;
                    }
                });
            }
        }

        public static void checkForTexturePackChange() {
            Minecraft minecraft = MCPatcherUtils.getMinecraft();
            if (minecraft == null) {
                return;
            }
            TexturePackList texturePackList = minecraft.texturePackList;
            if (texturePackList == null) {
                return;
            }
            TexturePackBase currentTexturePack = texturePackList.getSelectedTexturePack();
            if (currentTexturePack != texturePack) {
                changeTexturePack(currentTexturePack);
            } else if (currentTexturePack instanceof TexturePackCustom) {
                checkFileChange(texturePackList, (TexturePackCustom) currentTexturePack);
            }
        }

        private static void changeTexturePack(TexturePackBase newPack) {
            if (newPack != null && !changing) {
                changing = true;
                long timeDiff = -System.currentTimeMillis();
                Runtime runtime = Runtime.getRuntime();
                long memDiff = -(runtime.totalMemory() - runtime.freeMemory());

                if (texturePack == null) {
                    logger.info("\nsetting texture pack to %s", newPack.texturePackFileName);
                } else if (texturePack == newPack) {
                    logger.info("\nreloading texture pack %s", newPack.texturePackFileName);
                } else {
                    logger.info("\nchanging texture pack from %s to %s", texturePack.texturePackFileName, newPack.texturePackFileName);
                }

                texturePack = newPack;
                for (ChangeHandler handler : handlers) {
                    try {
                        logger.info("refreshing %s...", handler.name);
                        handler.onChange();
                    } catch (Throwable e) {
                        e.printStackTrace();
                        logger.severe("%s refresh failed", handler.name);
                    }
                }

                System.gc();
                timeDiff += System.currentTimeMillis();
                memDiff += runtime.totalMemory() - runtime.freeMemory();
                logger.info("done (%.3fs elapsed, mem usage %+.1fMB)\n", timeDiff / 1000.0, memDiff / 1048576.0);
                changing = false;
            }
        }

        private static boolean openTexturePackFile(TexturePackCustom pack) {
            if (pack.zipFile == null) {
                return false;
            }
            if (pack.origZip != null) {
                return true;
            }
            InputStream input = null;
            OutputStream output = null;
            ZipFile newZipFile = null;
            try {
                pack.lastModified = pack.file.lastModified();
                pack.tmpFile = File.createTempFile("tmpmc", ".zip");
                pack.tmpFile.deleteOnExit();
                MCPatcherUtils.close(pack.zipFile);
                input = new FileInputStream(pack.file);
                output = new FileOutputStream(pack.tmpFile);
                byte[] buffer = new byte[65536];
                while (true) {
                    int nread = input.read(buffer);
                    if (nread <= 0) {
                        break;
                    }
                    output.write(buffer, 0, nread);
                }
                MCPatcherUtils.close(input);
                MCPatcherUtils.close(output);
                newZipFile = new ZipFile(pack.tmpFile);
                pack.origZip = pack.zipFile;
                pack.zipFile = newZipFile;
                newZipFile = null;
                logger.fine("copied %s to %s, lastModified = %d", pack.file.getPath(), pack.tmpFile.getPath(), pack.lastModified);
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } finally {
                MCPatcherUtils.close(input);
                MCPatcherUtils.close(output);
                MCPatcherUtils.close(newZipFile);
            }
            return true;
        }

        private static void closeTexturePackFile(TexturePackCustom pack) {
            if (pack.origZip != null) {
                MCPatcherUtils.close(pack.zipFile);
                pack.zipFile = pack.origZip;
                pack.origZip = null;
                pack.tmpFile.delete();
                logger.fine("deleted %s", pack.tmpFile.getPath());
                pack.tmpFile = null;
            }
        }

        private static boolean checkFileChange(TexturePackList list, TexturePackCustom pack) {
            if (!autoRefreshTextures || !openTexturePackFile(pack)) {
                return false;
            }
            long now = System.currentTimeMillis();
            if (now - lastCheckTime < 1000L) {
                return false;
            }
            lastCheckTime = now;
            long lastModified = pack.file.lastModified();
            if (lastModified == pack.lastModified || lastModified == 0 || pack.lastModified == 0) {
                return false;
            }
            logger.finer("%s lastModified changed from %d to %d", pack.file.getName(), pack.lastModified, lastModified);
            ZipFile tmpZip = null;
            try {
                tmpZip = new ZipFile(pack.file);
            } catch (IOException e) {
                // file is still being written
                return false;
            } finally {
                MCPatcherUtils.close(tmpZip);
            }
            closeTexturePackFile(pack);
            list.updateAvailableTexturePacks();
            return true;
        }
    }
}
TOP

Related Classes of com.pclewis.mcpatcher.TexturePackAPI$ChangeHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.