kihira.tails.common.FoxLibManager.java Source code

Java tutorial

Introduction

Here is the source code for kihira.tails.common.FoxLibManager.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 Zoe Lee (Kihira) and iLexiconn
 *
 * See LICENSE for full License
 */

package kihira.tails.common;

import cpw.mods.fml.client.CustomModLoadingErrorDisplayException;
import cpw.mods.fml.common.FMLCommonHandler;
import cpw.mods.fml.common.FMLLog;
import cpw.mods.fml.common.Loader;
import cpw.mods.fml.common.SidedProxy;
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
import cpw.mods.fml.common.gameevent.TickEvent;
import cpw.mods.fml.common.versioning.VersionParser;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
import net.minecraft.client.resources.I18n;
import net.minecraft.launchwrapper.Launch;
import net.minecraft.util.IProgressUpdate;
import net.minecraft.util.StatCollector;
import org.apache.commons.io.IOCase;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.filefilter.WildcardFileFilter;
import org.apache.commons.io.output.CountingOutputStream;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.awt.*;
import java.io.*;
import java.net.URI;
import java.net.URL;

public class FoxLibManager {

    public static final String foxlibVersion = "@FOXLIBVERSION@";
    public static final String foxlibReqVersion = "[1.7.10-0.6.0,)";
    public static final String foxlibFileName = "FoxLib-" + foxlibVersion + ".jar";
    public static final String foxlibDownloadLink = "http://maven.kihirakreations.co.uk/kihira/FoxLib/"
            + foxlibVersion + "/" + foxlibFileName;
    public static final String foxlibDownloadFallback = "http://minecraft.curseforge.com/mc-mods/223291-foxlib/files";
    public static final Logger logger = LogManager.getLogger("FoxLib Manager");

    @SidedProxy(serverSide = "kihira.tails.common.FoxLibManager$CommonProxy", clientSide = "kihira.tails.common.FoxLibManager$ClientProxy")
    public static CommonProxy proxy;
    public static boolean outdated;
    long totalSize;

    /**
     * Checks if FoxLib is available and updated to the required version
     * @return If FoxLib is available
     */
    public static boolean checkFoxlib() {
        if (!isFoxlibInstalled()) {
            logger.error("FoxLib is not installed!");
            if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
                FMLCommonHandler.instance().bus().register(new FoxLibManager());
            } else {
                String s = StatCollector.translateToLocalFormatted("foxlib.downloader.missing", Tails.MOD_ID,
                        foxlibDownloadFallback);
                FMLLog.bigWarning(s);
                FMLCommonHandler.instance().getSidedDelegate().haltGame(s, null);
            }
        } else if (!isFoxlibCorrectVersion()) {
            logger.error("FoxLib is not the correct version! Expected " + foxlibVersion + " got "
                    + Loader.instance().getIndexedModList().get("foxlib").getDisplayVersion());
            if (FMLCommonHandler.instance().getEffectiveSide().isClient()) {
                outdated = true;
                FMLCommonHandler.instance().bus().register(new FoxLibManager());
            } else {
                String s = StatCollector.translateToLocalFormatted("foxlib.downloader.outofdate",
                        foxlibDownloadFallback);
                FMLLog.bigWarning(s);
                FMLCommonHandler.instance().getSidedDelegate().haltGame(s, null);
            }
        } else {
            return true;
        }
        return false;
    }

    public static boolean isFoxlibInstalled() {
        return Loader.isModLoaded("foxlib");
    }

    public static boolean isFoxlibCorrectVersion() {
        try {
            //If we are in dev, skip version check
            byte[] bs = Launch.classLoader.getClassBytes("net.minecraft.world.World");
            if (bs != null) {
                logger.warn("We are in a dev environment, skipping version check");
                return true;
            }
        } catch (IOException ignored) {
        }

        System.out.println(
                Loader.instance().getIndexedModList().get("foxlib").getProcessedVersion().getVersionString());

        return VersionParser.parseRange(foxlibReqVersion)
                .containsVersion(Loader.instance().getIndexedModList().get("foxlib").getProcessedVersion());
    }

    @SubscribeEvent
    @SideOnly(Side.CLIENT)
    public void onClientTick(TickEvent.ClientTickEvent e) {
        if (Minecraft.getMinecraft().currentScreen instanceof GuiMainMenu) {
            Minecraft.getMinecraft().displayGuiScreen(new GuiYesNo(new GuiYesNoCallback() {
                @Override
                public void confirmClicked(boolean yesButton, int screenID) {
                    if (yesButton) {
                        if (outdated)
                            deleteOldVersions();
                        downloadFoxlib();
                    } else {
                        if (outdated) {
                            proxy.throwFoxlibError();
                        } else {
                            FMLLog.bigWarning("foxlib.downloader.missing", foxlibDownloadFallback);
                        }
                        Minecraft.getMinecraft().shutdown();
                    }
                }
            }, outdated ? I18n.format("foxlib.downloader.2", Tails.MOD_ID)
                    : I18n.format("foxlib.downloader.0", Tails.MOD_ID),
                    outdated ? I18n.format("foxlib.downloader.3", Tails.MOD_ID)
                            : I18n.format("foxlib.downloader.1"),
                    0));
        }
    }

    @SideOnly(Side.CLIENT)
    public void downloadFoxlib() {
        final GuiScreenWorking screenWorking = new GuiScreenWorking();
        Minecraft.getMinecraft().displayGuiScreen(screenWorking);

        final Thread downloadThread = new Thread(new Runnable() {
            @Override
            public void run() {
                screenWorking.resetProgressAndMessage(I18n.format("foxlib.downloader.downloading"));
                screenWorking.resetProgresAndWorkingMessage("Starting...");

                File target;
                URL download;
                OutputStream output = null;
                InputStream input = null;
                try {
                    target = new File(Minecraft.getMinecraft().mcDataDir + File.separator + "mods" + File.separator
                            + foxlibFileName);
                    download = new URL(foxlibDownloadLink);
                    output = new FileOutputStream(target);
                    input = download.openStream();
                    DownloadCountingOutputStream countingOutputStream = new DownloadCountingOutputStream(output,
                            screenWorking);

                    totalSize = Long.valueOf(download.openConnection().getHeaderField("Content-Length"));
                    screenWorking.displayProgressMessage(
                            String.format("Downloading file (%.3f MB)...", totalSize / 1000000F));

                    IOUtils.copy(input, countingOutputStream);
                } catch (IOException e) {
                    //Delete file on close cause it could be corrupt
                    new File(Minecraft.getMinecraft().mcDataDir + File.separator + "mods" + File.separator
                            + foxlibFileName).deleteOnExit();
                    e.printStackTrace();

                    proxy.showFailedScreen();
                } finally {
                    IOUtils.closeQuietly(output);
                    IOUtils.closeQuietly(input);
                }
            }
        }, "FoxLib Downloader");
        downloadThread.setDaemon(true);
        downloadThread.start();
    }

    private void deleteOldVersions() {
        File modsFolder = new File(Minecraft.getMinecraft().mcDataDir + File.separator + "mods");
        File[] files = modsFolder
                .listFiles((FileFilter) new WildcardFileFilter("*FoxLib*.jar", IOCase.INSENSITIVE));
        if (files != null) {
            for (File file : files) {
                if (file.exists()) {
                    logger.info("Deleting file " + file.toString() + " on exit");
                    file.deleteOnExit();
                }
            }
        }
    }

    private class DownloadCountingOutputStream extends CountingOutputStream {

        private final IProgressUpdate update;

        public DownloadCountingOutputStream(OutputStream out, IProgressUpdate update) {
            super(out);
            this.update = update;
        }

        @Override
        protected void afterWrite(int n) throws IOException {
            super.afterWrite(n);

            if (getByteCount() == totalSize) {
                proxy.showRestartScreen();
            }

            update.setLoadingProgress((int) (getByteCount() / totalSize));
        }
    }

    @SideOnly(Side.CLIENT)
    private static class GuiScreenHold extends GuiScreen {
        private String topMessage;
        private String bottomMessage;

        public GuiScreenHold(String topMessage, String bottomMessage) {
            this.topMessage = topMessage;
            this.bottomMessage = bottomMessage;
        }

        public void drawScreen(int p_73863_1_, int p_73863_2_, float p_73863_3_) {
            drawDefaultBackground();
            drawCenteredString(fontRendererObj, topMessage, width / 2, 90, 16777215);
            drawCenteredString(fontRendererObj, bottomMessage, width / 2, 110, 16777215);
        }

        protected void keyTyped(char character, int keycode) {
        }
    }

    public static class CommonProxy {
        public void throwFoxlibError() {
            FMLLog.bigWarning(
                    StatCollector.translateToLocalFormatted("foxlib.downloader.outofdate", foxlibDownloadFallback));
        }

        public void showRestartScreen() {
        }

        public void showFailedScreen() {
        }
    }

    @SideOnly(Side.CLIENT)
    public static class ClientProxy extends CommonProxy {
        public void throwFoxlibError() {
            throw new CustomModLoadingErrorDisplayException() {
                @Override
                public void initGui(GuiErrorScreen errorScreen, FontRenderer fontRenderer) {
                    try {
                        Desktop.getDesktop().browse(URI.create(foxlibDownloadFallback));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void drawScreen(GuiErrorScreen errorScreen, FontRenderer fontRenderer, int mouseRelX,
                        int mouseRelY, float tickTime) {
                    String s = I18n.format("foxlib.downloader.outofdate");
                    fontRenderer.drawString(s, (errorScreen.width / 2) - (fontRenderer.getStringWidth(s) / 2),
                            errorScreen.height / 2, 0xFFFFFFFF);
                }
            };
        }

        public void showRestartScreen() {
            Minecraft.getMinecraft().displayGuiScreen(new GuiScreenHold(I18n.format("foxlib.downloader.success"),
                    I18n.format("foxlib.downloader.restart")));
        }

        public void showFailedScreen() {
            try {
                Desktop.getDesktop().browse(URI.create(foxlibDownloadFallback));
            } catch (IOException e) {
                e.printStackTrace();
            }
            Minecraft.getMinecraft().displayGuiScreen(
                    new GuiScreenHold(I18n.format("foxlib.downloader.failed.0", foxlibDownloadFallback),
                            I18n.format("foxlib.downloader.failed.1")));
        }
    }
}