Package com.sk89q.skmcl.minecraft

Source Code of com.sk89q.skmcl.minecraft.MinecraftInstall

/*
* SK's Minecraft Launcher
* Copyright (C) 2010, 2011 Albert Pham <http://www.sk89q.com>
*
* This program 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.
*
* This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/

package com.sk89q.skmcl.minecraft;

import com.sk89q.skmcl.application.Instance;
import com.sk89q.skmcl.application.UpdateRequiredException;
import com.sk89q.skmcl.application.Version;
import com.sk89q.skmcl.concurrent.AbstractWorker;
import com.sk89q.skmcl.install.FileResource;
import com.sk89q.skmcl.install.ZipExtract;
import com.sk89q.skmcl.launch.JavaProcessBuilder;
import com.sk89q.skmcl.launch.LaunchContext;
import com.sk89q.skmcl.launch.LaunchedProcess;
import com.sk89q.skmcl.minecraft.model.Library;
import com.sk89q.skmcl.minecraft.model.ReleaseManifest;
import com.sk89q.skmcl.profile.Profile;
import com.sk89q.skmcl.session.Identity;
import com.sk89q.skmcl.session.Session;
import com.sk89q.skmcl.util.Environment;
import com.sk89q.skmcl.util.Persistence;
import com.sk89q.skmcl.util.Platform;
import lombok.Getter;
import lombok.NonNull;
import lombok.ToString;
import org.apache.commons.io.FileUtils;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.File;
import java.io.IOException;

import static com.sk89q.skmcl.minecraft.model.Library.Extract;

/**
* An installed version of Minecraft.
*/
@ToString
public class MinecraftInstall implements Instance {

    @Getter
    private final Profile profile;
    @Getter
    private final Version version;
    @Getter
    private final String versionPath;
    @Getter
    private final Environment environment;
    @Getter
    private JarBuilder jarPatcher;

    /**
     * Create a new instance.
     *
     * @param profile the profile containing this installation
     * @param version the version
     * @param environment the environment
     */
    public MinecraftInstall(@NonNull final Profile profile,
                            @NonNull final Version version,
                            @NonNull final Environment environment) {
        this.profile = profile;
        this.version = version;
        this.environment = environment;
        versionPath = String.format("versions/%1$s/%1$s", version.getId());

        // JAR patcher configuration
        File file = new File(getProfile().getContentDir(), versionPath + "-patches.json");
        File dir = new File(getProfile().getContentDir(), versionPath + "-jar-patches");
        File patchedJar = new File(getProfile().getContentDir(), versionPath + "-patched.jar");

        jarPatcher = Persistence.load(file, JarBuilder.class);
        jarPatcher.setPaths(getJarPath(), patchedJar, dir);
        Persistence.bind(jarPatcher, file);
    }

    /**
     * Get the path to the manifest .json file for this version.
     *
     * @return the path
     */
    public File getManifestPath() {
        return new File(getProfile().getContentDir(), versionPath + ".json");
    }

    /**
     * Get the path to the .jar file for this version.
     *
     * @return the path
     */
    public File getJarPath() {
        return new File(getProfile().getContentDir(), versionPath + ".jar");
    }

    /**
     * Get the path to shared assets directory.
     *
     * @return the path
     */
    public File getAssetsDir() {
        return new File(getProfile().getSharedDir(), "assets");
    }

    /**
     * Get the path to shared libraries directory.
     *
     * @return the path
     */
    public File getLibrariesDir() {
        return new File(getProfile().getSharedDir(), "libraries");
    }

    /**
     * Get the path to a new temporary directory to store extracted libraries.
     *
     * <p>The returned directory can be deleted at any point in time.</p>
     *
     * @return the path
     */
    protected File createExtractDir() {
        String id = "-natives-" + System.currentTimeMillis();
        return new File(getProfile().getContentDir(), versionPath + id);
    }

    @Override
    public AbstractWorker getUpdater() {
        return new MinecraftUpdater(this);
    }

    @Override
    public LaunchedProcess launch(final LaunchContext context)
            throws IOException, UpdateRequiredException {
        if (!getJarPath().exists()) {
            throw new UpdateRequiredException("Not yet installed");
        }

        Identity identity = context.getIdentity();
        ObjectMapper mapper = new ObjectMapper();
        final File extractDir = createExtractDir();
        JavaProcessBuilder builder = new JavaProcessBuilder();
        ReleaseManifest manifest = mapper.readValue(
                getManifestPath(), ReleaseManifest.class);
        String clientToken = identity.getClientToken();

        // Add libraries to classpath or extract the libraries as necessary
        for (Library library : manifest.getLibraries()) {
            File path = new File(getLibrariesDir(), library.getPath(context.getEnvironment()));

            if (path.exists()) {
                Extract extract = library.getExtract();
                if (extract != null) {
                    ZipExtract zipExtract = new ZipExtract(
                            new FileResource(path), extractDir);
                    zipExtract.setExclude(extract.getExclude());
                    zipExtract.run();
                } else {
                    builder.classPath(path);
                }
            }
        }

        // Add arguments for the .jar
        String[] args = manifest.getMinecraftArguments().split(" +");
        for (String arg : args) {
            arg = arg.replace("${version_name}", manifest.getId());
            arg = arg.replace("${game_directory}", getProfile().getContentDir().getAbsolutePath());
            arg = arg.replace("${game_assets}", getAssetsDir().getAbsolutePath());
            arg = arg.replace("${auth_player_name}", identity.getName());
            arg = arg.replace("${auth_username}", identity.getName());
            arg = arg.replace("${auth_access_token}", identity.getAccessToken());
            arg = arg.replace("${auth_session}", clientToken);
            builder.getArgs().add(arg);
        }

        // Mac OS X arguments
        if (getEnvironment().getPlatform() == Platform.MAC_OS_X) {
            File icnsPath = new File(getAssetsDir(), "icons/minecraft.icns");
            builder.getFlags().add("-Xdock:icon=" + icnsPath.getAbsolutePath());
            builder.getFlags().add("-Xdock:name=Minecraft");
        }

        builder.getFlags().add("-Djava.library.path=" + extractDir.getAbsoluteFile());
        builder.classPath(getJarPatcher().getExecutedPath());
        builder.setMainClass(manifest.getMainClass());

        ProcessBuilder processBuilder = new ProcessBuilder(builder.buildCommand());
        processBuilder.directory(getProfile().getContentDir());
        Process process = processBuilder.start();

        // Return the process
        return new LaunchedProcess(process) {
            @Override
            public void close() throws IOException {
                FileUtils.deleteDirectory(extractDir);
            }
        };
    }

}
TOP

Related Classes of com.sk89q.skmcl.minecraft.MinecraftInstall

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.