net.technicpack.launcher.LauncherMain.java Source code

Java tutorial

Introduction

Here is the source code for net.technicpack.launcher.LauncherMain.java

Source

/*
 * This file is part of The Technic Launcher Version 3.
 * Copyright (C) 2013 Syndicate, LLC
 *
 * The Technic Launcher is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The Technic Launcher  is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with the Technic Launcher.  If not, see <http://www.gnu.org/licenses/>.
 */

package net.technicpack.launcher;

import com.beust.jcommander.JCommander;
import net.technicpack.autoupdate.Relauncher;
import net.technicpack.autoupdate.http.HttpUpdateStream;
import net.technicpack.launcher.io.*;
import net.technicpack.launcher.settings.migration.IMigrator;
import net.technicpack.launcher.settings.migration.InitialV3Migrator;
import net.technicpack.launcher.ui.InstallerFrame;
import net.technicpack.launcher.ui.components.discover.DiscoverInfoPanel;
import net.technicpack.launcher.ui.components.modpacks.ModpackSelector;
import net.technicpack.launchercore.auth.IAuthListener;
import net.technicpack.launchercore.auth.IUserStore;
import net.technicpack.launchercore.logging.BuildLogFormatter;
import net.technicpack.launchercore.logging.RotatingFileHandler;
import net.technicpack.launchercore.modpacks.PackLoader;
import net.technicpack.launchercore.modpacks.sources.IAuthoritativePackSource;
import net.technicpack.minecraftcore.mojang.auth.MojangUser;
import net.technicpack.ui.components.Console;
import net.technicpack.ui.components.ConsoleFrame;
import net.technicpack.ui.components.ConsoleHandler;
import net.technicpack.ui.components.LoggerOutputStream;
import net.technicpack.ui.controls.installation.SplashScreen;
import net.technicpack.ui.lang.ResourceLoader;
import net.technicpack.launcher.launch.Installer;
import net.technicpack.launcher.settings.SettingsFactory;
import net.technicpack.launcher.settings.StartupParameters;
import net.technicpack.launcher.settings.TechnicSettings;
import net.technicpack.launcher.ui.LauncherFrame;
import net.technicpack.launcher.ui.LoginFrame;
import net.technicpack.launchercore.auth.IUserType;
import net.technicpack.minecraftcore.mojang.auth.AuthenticationService;
import net.technicpack.launchercore.auth.UserModel;
import net.technicpack.launchercore.image.ImageRepository;
import net.technicpack.launchercore.image.face.MinotarFaceImageStore;
import net.technicpack.launchercore.image.face.WebAvatarImageStore;
import net.technicpack.launchercore.install.ModpackInstaller;
import net.technicpack.minecraftcore.launch.MinecraftLauncher;
import net.technicpack.launchercore.modpacks.ModpackModel;
import net.technicpack.launchercore.modpacks.resources.PackImageStore;
import net.technicpack.launchercore.modpacks.resources.PackResourceMapper;
import net.technicpack.launchercore.modpacks.resources.resourcetype.BackgroundResourceType;
import net.technicpack.launchercore.modpacks.resources.resourcetype.IModpackResourceType;
import net.technicpack.launchercore.modpacks.resources.resourcetype.IconResourceType;
import net.technicpack.launchercore.modpacks.resources.resourcetype.LogoResourceType;
import net.technicpack.launchercore.modpacks.sources.IInstalledPackRepository;
import net.technicpack.launchercore.modpacks.sources.IPackSource;
import net.technicpack.launchercore.install.LauncherDirectories;
import net.technicpack.launchercore.mirror.MirrorStore;
import net.technicpack.launchercore.mirror.secure.rest.JsonWebSecureMirror;
import net.technicpack.platform.IPlatformApi;
import net.technicpack.platform.PlatformPackInfoRepository;
import net.technicpack.platform.http.HttpPlatformApi;
import net.technicpack.platform.io.AuthorshipInfo;
import net.technicpack.solder.ISolderApi;
import net.technicpack.solder.SolderPackSource;
import net.technicpack.solder.http.HttpSolderApi;
import net.technicpack.utilslib.Utils;
import org.apache.commons.lang3.StringUtils;

import javax.swing.*;
import java.awt.*;
import java.io.File;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

public class LauncherMain {

    public static ConsoleFrame consoleFrame;

    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (Exception ex) {
            Utils.getLogger().log(Level.SEVERE, ex.getMessage(), ex);
        }

        StartupParameters params = new StartupParameters(args);
        try {
            new JCommander(params, args);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        Relauncher launcher = new Relauncher(
                new HttpUpdateStream("http://beta.technicpack.net/api/launcher/version/"));
        TechnicSettings settings = null;

        try {
            settings = SettingsFactory.buildSettingsObject(launcher.getRunningPath(LauncherMain.class),
                    params.isMover());
        } catch (UnsupportedEncodingException ex) {
            ex.printStackTrace();
        }

        if (settings == null) {
            ResourceLoader installerResources = new ResourceLoader("net", "technicpack", "launcher", "resources");
            installerResources.setLocale(ResourceLoader.DEFAULT_LOCALE);
            InstallerFrame dialog = new InstallerFrame(installerResources, params);
            dialog.setVisible(true);
            return;
        }

        LauncherDirectories directories = new TechnicLauncherDirectories(settings.getTechnicRoot());
        ResourceLoader resources = new ResourceLoader("net", "technicpack", "launcher", "resources");
        resources.setLocale(settings.getLanguageCode());

        setupLogging(directories, resources);

        boolean needsReboot = false;

        if (System.getProperty("awt.useSystemAAFontSettings") == null
                || !System.getProperty("awt.useSystemAAFontSettings").equals("lcd"))
            needsReboot = true;
        else if (!Boolean.parseBoolean(System.getProperty("java.net.preferIPv4Stack")))
            needsReboot = true;

        if (params.isLauncher())
            startLauncher(settings, params, directories, resources);
        else if (params.isMover())
            startMover(params, launcher);
        else if (needsReboot && StringUtils.isNumeric(resources.getLauncherBuild())) {
            // ^^^^^
            //The debugger can't really relaunch so double check the build number to make sure we're operating in a valid environment
            launcher.launch(null, LauncherMain.class, params.getArgs());
            return;
        } else {
            updateAndRelaunch(params, directories, resources, settings, launcher);
        }
    }

    private static void setupLogging(LauncherDirectories directories, ResourceLoader resources) {
        System.out.println("Setting up logging");
        final Logger logger = Utils.getLogger();
        File logDirectory = new File(directories.getLauncherDirectory(), "logs");
        if (!logDirectory.exists()) {
            logDirectory.mkdir();
        }
        File logs = new File(logDirectory, "techniclauncher_%D.log");
        RotatingFileHandler fileHandler = new RotatingFileHandler(logs.getPath());

        fileHandler.setFormatter(new BuildLogFormatter(resources.getLauncherBuild()));

        for (Handler h : logger.getHandlers()) {
            logger.removeHandler(h);
        }
        logger.addHandler(fileHandler);
        logger.setUseParentHandlers(false);

        LauncherMain.consoleFrame = new ConsoleFrame(2500, resources.getImage("icon.png"));
        Console console = new Console(LauncherMain.consoleFrame, resources.getLauncherBuild());

        logger.addHandler(new ConsoleHandler(console));

        System.setOut(new PrintStream(new LoggerOutputStream(console, Level.INFO, logger), true));
        System.setErr(new PrintStream(new LoggerOutputStream(console, Level.SEVERE, logger), true));

        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                e.printStackTrace();
                logger.log(Level.SEVERE, "Unhandled Exception in " + t, e);

                //                if (errorDialog == null) {
                //                    LauncherFrame frame = null;
                //
                //                    try {
                //                        frame = Launcher.getFrame();
                //                    } catch (Exception ex) {
                //                        //This can happen if we have a very early crash- before Launcher initializes
                //                    }
                //
                //                    errorDialog = new ErrorDialog(frame, e);
                //                    errorDialog.setVisible(true);
                //                }
            }
        });
    }

    private static void startLauncher(TechnicSettings settings, StartupParameters startupParameters,
            LauncherDirectories directories, ResourceLoader resources) {
        UIManager.put("ComboBox.disabledBackground", LauncherFrame.COLOR_FORMELEMENT_INTERNAL);
        UIManager.put("ComboBox.disabledForeground", LauncherFrame.COLOR_GREY_TEXT);
        System.setProperty("xr.load.xml-reader", "org.ccil.cowan.tagsoup.Parser");

        final SplashScreen splash = new SplashScreen(resources.getImage("launch_splash.png"), 0);
        splash.pack();
        splash.setLocationRelativeTo(null);
        splash.setVisible(true);

        IUserStore<MojangUser> users = TechnicUserStore
                .load(new File(directories.getLauncherDirectory(), "users.json"));
        UserModel userModel = new UserModel(users, new AuthenticationService());

        MirrorStore mirrorStore = new MirrorStore(userModel);
        mirrorStore.addSecureMirror("mirror.technicpack.net",
                new JsonWebSecureMirror("http://mirror.technicpack.net/", "mirror.technicpack.net"));

        IModpackResourceType iconType = new IconResourceType();
        IModpackResourceType logoType = new LogoResourceType();
        IModpackResourceType backgroundType = new BackgroundResourceType();

        PackResourceMapper iconMapper = new PackResourceMapper(directories, resources.getImage("icon.png"),
                iconType);
        ImageRepository<ModpackModel> iconRepo = new ImageRepository<ModpackModel>(iconMapper,
                new PackImageStore(iconType, mirrorStore, userModel));
        ImageRepository<ModpackModel> logoRepo = new ImageRepository<ModpackModel>(
                new PackResourceMapper(directories, resources.getImage("modpack/ModImageFiller.png"), logoType),
                new PackImageStore(logoType, mirrorStore, userModel));
        ImageRepository<ModpackModel> backgroundRepo = new ImageRepository<ModpackModel>(
                new PackResourceMapper(directories, null, backgroundType),
                new PackImageStore(backgroundType, mirrorStore, userModel));

        ImageRepository<IUserType> skinRepo = new ImageRepository<IUserType>(
                new TechnicFaceMapper(directories, resources),
                new MinotarFaceImageStore("https://minotar.net/", mirrorStore));

        ImageRepository<AuthorshipInfo> avatarRepo = new ImageRepository<AuthorshipInfo>(
                new TechnicAvatarMapper(directories, resources), new WebAvatarImageStore(mirrorStore));

        ISolderApi solder = new HttpSolderApi(settings.getClientId(), userModel);
        HttpPlatformApi platform = new HttpPlatformApi("http://beta.technicpack.net/", mirrorStore);

        IInstalledPackRepository packStore = TechnicInstalledPackStore
                .load(new File(directories.getLauncherDirectory(), "installedPacks"));
        IAuthoritativePackSource packInfoRepository = new PlatformPackInfoRepository(platform, solder);

        ArrayList<IMigrator> migrators = new ArrayList<IMigrator>(1);
        migrators.add(new InitialV3Migrator(platform));
        SettingsFactory.migrateSettings(settings, packStore, directories, users, migrators);

        PackLoader packList = new PackLoader(directories, packStore, packInfoRepository);
        ModpackSelector selector = new ModpackSelector(resources, packList,
                new SolderPackSource("http://solder.technicpack.net/api/", solder, true), solder, platform,
                iconRepo);
        selector.setBorder(BorderFactory.createEmptyBorder());
        userModel.addAuthListener(selector);

        DiscoverInfoPanel discoverInfoPanel = new DiscoverInfoPanel(resources, startupParameters.getDiscoverUrl(),
                platform, splash);

        MinecraftLauncher launcher = new MinecraftLauncher(platform, directories, userModel,
                settings.getClientId());
        ModpackInstaller modpackInstaller = new ModpackInstaller(platform, settings.getClientId());
        Installer installer = new Installer(startupParameters, mirrorStore, directories, modpackInstaller, launcher,
                settings, iconMapper);

        LauncherFrame frame = new LauncherFrame(resources, skinRepo, userModel, settings, selector, iconRepo,
                logoRepo, backgroundRepo, installer, avatarRepo, platform, directories, packStore,
                startupParameters, discoverInfoPanel);
        userModel.addAuthListener(frame);

        LoginFrame login = new LoginFrame(resources, settings, userModel, skinRepo);
        userModel.addAuthListener(login);
        userModel.addAuthListener(new IAuthListener() {
            @Override
            public void userChanged(Object user) {
                if (user == null)
                    splash.dispose();
            }
        });

        userModel.initAuth();
    }

    private static void startMover(StartupParameters params, Relauncher relauncher) {
        try {
            relauncher.replacePackage(LauncherMain.class, params.getMoveTarget());
        } catch (UnsupportedEncodingException ex) {
            Utils.getLogger().log(Level.SEVERE, "Error attempting to copy downloaded package: ", ex);
            return;
        }

        String[] args = relauncher.buildLauncherArgs(relauncher.buildLauncherArgs(params.getArgs()));
        relauncher.launch(params.getMoveTarget(), LauncherMain.class, args);
    }

    private static void updateAndRelaunch(StartupParameters params, LauncherDirectories directories,
            ResourceLoader resources, TechnicSettings settings, Relauncher relauncher) {
        String launcherBuild = resources.getLauncherBuild();
        int build = -1;

        try {
            build = Integer.parseInt(launcherBuild);
        } catch (NumberFormatException ex) {
            //This is probably a debug build or something, build number is invalid
        }

        if (build < 1) {
            //We're in debug mode do not relaunch
            startLauncher(settings, params, directories, resources);
            return;
        }

        //In order to allow the old launcher to update & maintain backward compatibility we're keeping the old
        //stream pages live, and appending a "4" to the new streams.  So "stable" in the settings file means we
        //pull from "stable4"
        String url = relauncher.getUpdateUrl(settings.getBuildStream() + "4", build, LauncherMain.class);

        String[] args;
        if (url == null) {
            startLauncher(settings, params, directories, resources);
            return;
        }

        SplashScreen screen = new SplashScreen(resources.getImage("launch_splash.png"), 30);
        screen.getProgressBar().setForeground(Color.white);
        screen.getProgressBar().setBackground(LauncherFrame.COLOR_GREEN);
        screen.getProgressBar().setBackFill(LauncherFrame.COLOR_CENTRAL_BACK_OPAQUE);
        screen.getProgressBar().setFont(resources.getFont(ResourceLoader.FONT_OPENSANS, 12));
        screen.pack();
        screen.setLocationRelativeTo(null);
        screen.setVisible(true);

        String tempPath = relauncher.downloadUpdate(url, directories, resources.getString("updater.downloading"),
                screen.getProgressBar());

        if (tempPath == null) {
            Utils.getLogger().severe("The launcher update failed to download.");
            screen.dispose();
            startLauncher(settings, params, directories, resources);
            return;
        }

        try {
            args = relauncher.buildMoverArgs(LauncherMain.class, params.getArgs());
        } catch (UnsupportedEncodingException ex) {
            Utils.getLogger().log(Level.SEVERE, "Error attempting to launch mover mode: ", ex);
            return;
        }
        relauncher.launch(tempPath, LauncherMain.class, args);
    }
}