mirror of
https://github.com/SKCraft/Launcher.git
synced 2024-11-27 12:46:22 +01:00
Add support for mod loader installation.
This commit is contained in:
parent
7c887ad5a3
commit
883eaf63eb
10
pom.xml
10
pom.xml
@ -44,6 +44,16 @@
|
||||
<artifactId>jcommander</artifactId>
|
||||
<version>1.32</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.tukaani</groupId>
|
||||
<artifactId>xz</artifactId>
|
||||
<version>1.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.9</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@ -7,6 +7,7 @@
|
||||
package com.skcraft.launcher.builder;
|
||||
|
||||
import com.beust.jcommander.Parameter;
|
||||
import com.beust.jcommander.ParameterException;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.File;
|
||||
@ -15,14 +16,6 @@ import java.io.File;
|
||||
public class BuilderOptions {
|
||||
|
||||
// Configuration
|
||||
@Parameter(names = "--config")
|
||||
private File configPath;
|
||||
@Parameter(names = "--version-file")
|
||||
private File versionManifestPath;
|
||||
@Parameter(names = "--libs-url")
|
||||
private String librariesLocation;
|
||||
@Parameter(names = "--objects-url")
|
||||
private String objectsLocation;
|
||||
|
||||
// Override config
|
||||
@Parameter(names = "--name")
|
||||
@ -35,17 +28,82 @@ public class BuilderOptions {
|
||||
// Required
|
||||
@Parameter(names = "--version", required = true)
|
||||
private String version;
|
||||
|
||||
// Paths
|
||||
@Parameter(names = "--files", required = true)
|
||||
private File filesDir;
|
||||
@Parameter(names = "--manifest-dest", required = true)
|
||||
private File manifestPath;
|
||||
@Parameter(names = "--objects-dest", required = true)
|
||||
|
||||
// Overall paths
|
||||
@Parameter(names = {"--input", "-i"})
|
||||
private File inputPath;
|
||||
@Parameter(names = {"--output", "-o"})
|
||||
private File outputPath;
|
||||
|
||||
// Input paths
|
||||
@Parameter(names = "--config")
|
||||
private File configPath;
|
||||
@Parameter(names = "--version-file")
|
||||
private File versionManifestPath;
|
||||
@Parameter(names = "--files")
|
||||
private File filesDir;
|
||||
@Parameter(names = "--loaders")
|
||||
private File loadersDir;
|
||||
|
||||
// Output paths
|
||||
@Parameter(names = "--objects-dest")
|
||||
private File objectsDir;
|
||||
@Parameter(names = "--libraries-dest")
|
||||
private File librariesDir;
|
||||
|
||||
@Parameter(names = "--libs-url")
|
||||
private String librariesLocation = "libraries";
|
||||
@Parameter(names = "--objects-url")
|
||||
private String objectsLocation = "objects";
|
||||
|
||||
// Misc
|
||||
@Parameter(names = "--pretty-print")
|
||||
private boolean prettyPrinting;
|
||||
|
||||
public void choosePaths() throws ParameterException {
|
||||
if (configPath == null) {
|
||||
requireInputPath("--config");
|
||||
configPath = new File(inputPath, "modpack.json");
|
||||
}
|
||||
|
||||
if (versionManifestPath == null) {
|
||||
requireInputPath("--version");
|
||||
versionManifestPath = new File(inputPath, "version.json");
|
||||
}
|
||||
|
||||
if (filesDir == null) {
|
||||
requireInputPath("--files");
|
||||
filesDir = new File(inputPath, "src");
|
||||
}
|
||||
|
||||
if (loadersDir == null) {
|
||||
requireInputPath("--loaders");
|
||||
loadersDir = new File(inputPath, "loaders");
|
||||
}
|
||||
|
||||
if (objectsDir == null) {
|
||||
requireOutputPath("--objects-dest");
|
||||
objectsDir = new File(outputPath, objectsLocation);
|
||||
}
|
||||
|
||||
if (librariesDir == null) {
|
||||
requireOutputPath("--libs-dest");
|
||||
librariesDir = new File(outputPath, librariesLocation);
|
||||
}
|
||||
}
|
||||
|
||||
private void requireOutputPath(String name) throws ParameterException {
|
||||
if (outputPath == null) {
|
||||
throw new ParameterException("Because " + name + " was not specified, --output needs to be specified as the output directory and then " + name + " will be default to a pre-set path within the output directory");
|
||||
}
|
||||
}
|
||||
|
||||
private void requireInputPath(String name) throws ParameterException {
|
||||
if (inputPath == null) {
|
||||
throw new ParameterException("Because " + name + " was not specified, --input needs to be specified as the project directory and then " + name + " will be default to a pre-set path within the project directory");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
52
src/main/java/com/skcraft/launcher/builder/BuilderUtils.java
Normal file
52
src/main/java/com/skcraft/launcher/builder/BuilderUtils.java
Normal file
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* SK's Minecraft Launcher
|
||||
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||
* Please see LICENSE.txt for license information.
|
||||
*/
|
||||
|
||||
package com.skcraft.launcher.builder;
|
||||
|
||||
import com.beust.jcommander.internal.Lists;
|
||||
import org.apache.commons.compress.compressors.CompressorStreamFactory;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public final class BuilderUtils {
|
||||
|
||||
private BuilderUtils() {
|
||||
}
|
||||
|
||||
public static String normalizePath(String path) {
|
||||
return path.replaceAll("^[/\\\\]*", "").replaceAll("[/\\\\]+", "/");
|
||||
}
|
||||
|
||||
public static ZipEntry getZipEntry(ZipFile jarFile, String path) {
|
||||
Enumeration<? extends ZipEntry> entries = jarFile.entries();
|
||||
String expected = normalizePath(path);
|
||||
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
String test = normalizePath(entry.getName());
|
||||
if (expected.equals(test)) {
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static List<Compressor> getCompressors(String repoUrl) {
|
||||
if (repoUrl.matches("^https?://files.minecraftforge.net/maven/")) {
|
||||
return Lists.newArrayList(
|
||||
new Compressor("xz", CompressorStreamFactory.XZ),
|
||||
new Compressor("pack", CompressorStreamFactory.PACK200));
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
48
src/main/java/com/skcraft/launcher/builder/Compressor.java
Normal file
48
src/main/java/com/skcraft/launcher/builder/Compressor.java
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* SK's Minecraft Launcher
|
||||
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||
* Please see LICENSE.txt for license information.
|
||||
*/
|
||||
|
||||
package com.skcraft.launcher.builder;
|
||||
|
||||
import org.apache.commons.compress.compressors.CompressorException;
|
||||
import org.apache.commons.compress.compressors.CompressorStreamFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class Compressor {
|
||||
|
||||
private static final CompressorStreamFactory factory = new CompressorStreamFactory();
|
||||
|
||||
private final String extension;
|
||||
private final String format;
|
||||
|
||||
public Compressor(String extension, String format) {
|
||||
this.extension = extension;
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public String transformPathname(String filename) {
|
||||
return filename + "." + extension;
|
||||
}
|
||||
|
||||
public InputStream createInputStream(InputStream inputStream) throws IOException {
|
||||
try {
|
||||
return factory.createCompressorInputStream(format, inputStream);
|
||||
} catch (CompressorException e) {
|
||||
throw new IOException("Failed to create decompressor", e);
|
||||
}
|
||||
}
|
||||
|
||||
public OutputStream createOutputStream(OutputStream outputStream) throws IOException {
|
||||
try {
|
||||
return factory.createCompressorOutputStream(format, outputStream);
|
||||
} catch (CompressorException e) {
|
||||
throw new IOException("Failed to create compressor", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SK's Minecraft Launcher
|
||||
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||
* Please see LICENSE.txt for license information.
|
||||
*/
|
||||
|
||||
package com.skcraft.launcher.builder;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
|
||||
public class JarFileFilter implements FileFilter {
|
||||
|
||||
@Override
|
||||
public boolean accept(File pathname) {
|
||||
return pathname.getName().toLowerCase().endsWith(".jar");
|
||||
}
|
||||
|
||||
}
|
@ -7,21 +7,43 @@
|
||||
package com.skcraft.launcher.builder;
|
||||
|
||||
import com.beust.jcommander.JCommander;
|
||||
import com.beust.jcommander.ParameterException;
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.core.type.TypeReference;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.ObjectWriter;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import com.google.common.io.CharStreams;
|
||||
import com.google.common.io.Closer;
|
||||
import com.google.common.io.Files;
|
||||
import com.skcraft.launcher.Launcher;
|
||||
import com.skcraft.launcher.LauncherUtils;
|
||||
import com.skcraft.launcher.model.loader.InstallProfile;
|
||||
import com.skcraft.launcher.model.minecraft.Library;
|
||||
import com.skcraft.launcher.model.minecraft.VersionManifest;
|
||||
import com.skcraft.launcher.model.modpack.Manifest;
|
||||
import com.skcraft.launcher.util.Environment;
|
||||
import com.skcraft.launcher.util.HttpRequest;
|
||||
import com.skcraft.launcher.util.SimpleLogFormatter;
|
||||
import lombok.Getter;
|
||||
import lombok.NonNull;
|
||||
import lombok.extern.java.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.logging.Level;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.zip.ZipEntry;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static com.google.common.base.Strings.emptyToNull;
|
||||
import static com.skcraft.launcher.util.HttpRequest.url;
|
||||
|
||||
/**
|
||||
* Builds packages for the launcher.
|
||||
@ -29,12 +51,17 @@ import static com.google.common.base.Strings.emptyToNull;
|
||||
@Log
|
||||
public class PackageBuilder {
|
||||
|
||||
private static final Pattern TWEAK_CLASS_ARG = Pattern.compile("--tweakClass\\s+([^\\s]+)");
|
||||
|
||||
private final Properties properties;
|
||||
private final ObjectMapper mapper;
|
||||
private ObjectWriter writer;
|
||||
private final Manifest manifest;
|
||||
private final PropertiesApplicator applicator;
|
||||
@Getter
|
||||
private boolean prettyPrint = false;
|
||||
private List<Library> loaderLibraries = Lists.newArrayList();
|
||||
private List<String> mavenRepos;
|
||||
|
||||
/**
|
||||
* Create a new package builder.
|
||||
@ -42,11 +69,22 @@ public class PackageBuilder {
|
||||
* @param mapper the mapper
|
||||
* @param manifest the manifest
|
||||
*/
|
||||
public PackageBuilder(@NonNull ObjectMapper mapper, @NonNull Manifest manifest) {
|
||||
public PackageBuilder(@NonNull ObjectMapper mapper, @NonNull Manifest manifest) throws IOException {
|
||||
this.properties = LauncherUtils.loadProperties(Launcher.class,
|
||||
"launcher.properties", "com.skcraft.launcher.propertiesFile");
|
||||
|
||||
this.mapper = mapper;
|
||||
this.manifest = manifest;
|
||||
this.applicator = new PropertiesApplicator(manifest);
|
||||
setPrettyPrint(false); // Set writer
|
||||
|
||||
Closer closer = Closer.create();
|
||||
try {
|
||||
mavenRepos = mapper.readValue(closer.register(Launcher.class.getResourceAsStream("maven_repos.json")), new TypeReference<List<String>>() {
|
||||
});
|
||||
} finally {
|
||||
closer.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void setPrettyPrint(boolean prettyPrint) {
|
||||
@ -71,6 +109,156 @@ public class PackageBuilder {
|
||||
collector.walk(dir);
|
||||
}
|
||||
|
||||
public void addLoaders(File dir, File librariesDir) {
|
||||
logSection("Checking for mod loaders to install...");
|
||||
|
||||
File[] files = dir.listFiles(new JarFileFilter());
|
||||
if (files != null) {
|
||||
for (File file : files) {
|
||||
try {
|
||||
processLoader(file, librariesDir);
|
||||
} catch (IOException e) {
|
||||
log.log(Level.WARNING, "Failed to add the loader at " + file.getAbsolutePath(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void processLoader(File file, File librariesDir) throws IOException {
|
||||
log.info("Installing " + file.getName() + "...");
|
||||
|
||||
JarFile jarFile = new JarFile(file);
|
||||
Closer closer = Closer.create();
|
||||
|
||||
try {
|
||||
ZipEntry profileEntry = BuilderUtils.getZipEntry(jarFile, "install_profile.json");
|
||||
|
||||
if (profileEntry != null) {
|
||||
InputStream stream = jarFile.getInputStream(profileEntry);
|
||||
|
||||
// Read file
|
||||
String data = CharStreams.toString(closer.register(new InputStreamReader(stream)));
|
||||
data = data.replaceAll(",\\s*\\}", "}"); // Fix issues with trailing commas
|
||||
|
||||
InstallProfile profile = mapper.readValue(data, InstallProfile.class);
|
||||
VersionManifest version = manifest.getVersionManifest();
|
||||
|
||||
// Copy tweak class arguments
|
||||
String args = profile.getVersionInfo().getMinecraftArguments();
|
||||
if (args != null) {
|
||||
String existingArgs = Strings.nullToEmpty(version.getMinecraftArguments());
|
||||
|
||||
Matcher m = TWEAK_CLASS_ARG.matcher(args);
|
||||
while (m.find()) {
|
||||
version.setMinecraftArguments(existingArgs + " " + m.group());
|
||||
log.info("Adding " + m.group() + " to launch arguments");
|
||||
}
|
||||
}
|
||||
|
||||
// Add libraries
|
||||
List<Library> libraries = profile.getVersionInfo().getLibraries();
|
||||
if (libraries != null) {
|
||||
version.getLibraries().addAll(libraries);
|
||||
loaderLibraries.addAll(libraries);
|
||||
}
|
||||
|
||||
// Copy main class
|
||||
String mainClass = profile.getVersionInfo().getMainClass();
|
||||
if (mainClass != null) {
|
||||
version.setMainClass(mainClass);
|
||||
log.info("Using " + mainClass + " as the main class");
|
||||
}
|
||||
|
||||
// Extract the library
|
||||
String filePath = profile.getInstallData().getFilePath();
|
||||
String libraryPath = profile.getInstallData().getPath();
|
||||
|
||||
if (filePath != null && libraryPath != null) {
|
||||
ZipEntry libraryEntry = BuilderUtils.getZipEntry(jarFile, filePath);
|
||||
|
||||
if (libraryEntry != null) {
|
||||
Library library = new Library();
|
||||
library.setName(libraryPath);
|
||||
File extractPath = new File(librariesDir, library.getPath(Environment.getInstance()));
|
||||
Files.createParentDirs(extractPath);
|
||||
ByteStreams.copy(closer.register(jarFile.getInputStream(libraryEntry)), Files.newOutputStreamSupplier(extractPath));
|
||||
} else {
|
||||
log.warning("Could not find the file '" + filePath + "' in " + file.getAbsolutePath() + ", which means that this mod loader will not work correctly");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.warning("The file at " + file.getAbsolutePath() + " did not appear to have an " +
|
||||
"install_profile.json file inside -- is it actually an installer for a mod loader?");
|
||||
}
|
||||
} finally {
|
||||
closer.close();
|
||||
jarFile.close();
|
||||
}
|
||||
}
|
||||
|
||||
public void downloadLibraries(File librariesDir) throws IOException, InterruptedException {
|
||||
logSection("Downloading libraries...");
|
||||
|
||||
// TODO: Download libraries for different environments -- As of writing, this is not an issue
|
||||
Environment env = Environment.getInstance();
|
||||
|
||||
for (Library library : loaderLibraries) {
|
||||
File outputPath = new File(librariesDir, library.getPath(env));
|
||||
|
||||
if (!outputPath.exists()) {
|
||||
Files.createParentDirs(outputPath);
|
||||
boolean found = false;
|
||||
|
||||
// Gather a list of repositories to download from
|
||||
List<String> sources = Lists.newArrayList();
|
||||
if (library.getBaseUrl() != null) {
|
||||
sources.add(library.getBaseUrl());
|
||||
}
|
||||
sources.addAll(mavenRepos);
|
||||
|
||||
// Try each repository
|
||||
for (String baseUrl : sources) {
|
||||
String pathname = library.getPath(env);
|
||||
|
||||
// Some repositories compress their files
|
||||
List<Compressor> compressors = BuilderUtils.getCompressors(baseUrl);
|
||||
for (Compressor compressor : Lists.reverse(compressors)) {
|
||||
pathname = compressor.transformPathname(pathname);
|
||||
}
|
||||
|
||||
URL url = new URL(baseUrl + pathname);
|
||||
File tempFile = File.createTempFile("launcherlib", null);
|
||||
|
||||
try {
|
||||
log.info("Downloading library " + library.getName() + " from " + url + "...");
|
||||
HttpRequest.get(url).execute().expectResponseCode(200).saveContent(tempFile);
|
||||
} catch (IOException e) {
|
||||
log.info("Could not get file from " + url + ": " + e.getMessage());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Decompress (if needed) and write to file
|
||||
Closer closer = Closer.create();
|
||||
InputStream inputStream = closer.register(new FileInputStream(tempFile));
|
||||
inputStream = closer.register(new BufferedInputStream(inputStream));
|
||||
for (Compressor compressor : compressors) {
|
||||
inputStream = closer.register(compressor.createInputStream(inputStream));
|
||||
}
|
||||
ByteStreams.copy(inputStream, closer.register(new FileOutputStream(outputPath)));
|
||||
|
||||
tempFile.delete();
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
log.warning("!! Failed to download the library " + library.getName() + " -- this means your copy of the libraries will lack this file");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void validateManifest() {
|
||||
checkNotNull(emptyToNull(manifest.getName()), "Package name is not defined");
|
||||
checkNotNull(emptyToNull(manifest.getGameVersion()), "Game version is not defined");
|
||||
@ -84,14 +272,33 @@ public class PackageBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
public void readVersionManifest(File path) throws IOException {
|
||||
if (path != null) {
|
||||
public void readVersionManifest(File path) throws IOException, InterruptedException {
|
||||
logSection("Reading version manifest...");
|
||||
|
||||
if (path.exists()) {
|
||||
VersionManifest versionManifest = read(path, VersionManifest.class);
|
||||
manifest.setVersionManifest(versionManifest);
|
||||
|
||||
log.info("Loaded version manifest from " + path.getAbsolutePath());
|
||||
} else {
|
||||
URL url = url(String.format(
|
||||
properties.getProperty("versionManifestUrl"),
|
||||
manifest.getGameVersion()));
|
||||
|
||||
log.info("Fetching version manifest from " + url + "...");
|
||||
|
||||
manifest.setVersionManifest(HttpRequest
|
||||
.get(url)
|
||||
.execute()
|
||||
.expectResponseCode(200)
|
||||
.returnContent()
|
||||
.asJson(VersionManifest.class));
|
||||
}
|
||||
}
|
||||
|
||||
public void writeManifest(@NonNull File path) throws IOException {
|
||||
logSection("Writing manifest...");
|
||||
|
||||
manifest.setFeatures(applicator.getFeaturesInUse());
|
||||
VersionManifest versionManifest = manifest.getVersionManifest();
|
||||
if (versionManifest != null) {
|
||||
@ -100,11 +307,14 @@ public class PackageBuilder {
|
||||
validateManifest();
|
||||
path.getAbsoluteFile().getParentFile().mkdirs();
|
||||
writer.writeValue(path, manifest);
|
||||
|
||||
log.info("Wrote manifest to " + path.getAbsolutePath());
|
||||
}
|
||||
|
||||
private static BuilderOptions parseArgs(String[] args) {
|
||||
BuilderOptions options = new BuilderOptions();
|
||||
new JCommander(options, args);
|
||||
options.choosePaths();
|
||||
return options;
|
||||
}
|
||||
|
||||
@ -127,9 +337,18 @@ public class PackageBuilder {
|
||||
*
|
||||
* @param args arguments
|
||||
* @throws IOException thrown on I/O error
|
||||
* @throws InterruptedException on interruption
|
||||
*/
|
||||
public static void main(String[] args) throws IOException {
|
||||
BuilderOptions options = parseArgs(args);
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
BuilderOptions options;
|
||||
try {
|
||||
options = parseArgs(args);
|
||||
} catch (ParameterException e) {
|
||||
new JCommander().usage();
|
||||
System.err.println("error: " + e.getMessage());
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// Initialize
|
||||
SimpleLogFormatter.configureGlobalLogger();
|
||||
@ -155,10 +374,18 @@ public class PackageBuilder {
|
||||
|
||||
builder.scan(options.getFilesDir());
|
||||
builder.addFiles(options.getFilesDir(), options.getObjectsDir());
|
||||
builder.addLoaders(options.getLoadersDir(), options.getLibrariesDir());
|
||||
builder.downloadLibraries(options.getLibrariesDir());
|
||||
builder.writeManifest(options.getManifestPath());
|
||||
|
||||
log.info("Wrote manifest to " + options.getManifestPath().getAbsolutePath());
|
||||
log.info("Done.");
|
||||
logSection("Done");
|
||||
|
||||
log.info("Now upload the contents of " + options.getOutputPath() + " to your web server or CDN!");
|
||||
}
|
||||
|
||||
private static void logSection(String name) {
|
||||
log.info("");
|
||||
log.info("--- " + name + " ---");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* SK's Minecraft Launcher
|
||||
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||
* Please see LICENSE.txt for license information.
|
||||
*/
|
||||
|
||||
package com.skcraft.launcher.model.loader;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class InstallData {
|
||||
|
||||
private String path;
|
||||
private String filePath;
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* SK's Minecraft Launcher
|
||||
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||
* Please see LICENSE.txt for license information.
|
||||
*/
|
||||
|
||||
package com.skcraft.launcher.model.loader;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class InstallProfile {
|
||||
|
||||
@JsonProperty("install")
|
||||
private InstallData installData;
|
||||
private VersionInfo versionInfo;
|
||||
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* SK's Minecraft Launcher
|
||||
* Copyright (C) 2010-2014 Albert Pham <http://www.sk89q.com> and contributors
|
||||
* Please see LICENSE.txt for license information.
|
||||
*/
|
||||
|
||||
package com.skcraft.launcher.model.loader;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import com.skcraft.launcher.model.minecraft.Library;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
public class VersionInfo {
|
||||
|
||||
private String minecraftArguments;
|
||||
private String mainClass;
|
||||
private List<Library> libraries;
|
||||
|
||||
}
|
@ -25,6 +25,8 @@ public class Library {
|
||||
private transient String group;
|
||||
private transient String artifact;
|
||||
private transient String version;
|
||||
@JsonProperty("url")
|
||||
private String baseUrl;
|
||||
private Map<String, String> natives;
|
||||
private Extract extract;
|
||||
private List<Rule> rules;
|
||||
@ -122,6 +124,24 @@ public class Library {
|
||||
return path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
Library library = (Library) o;
|
||||
|
||||
if (name != null ? !name.equals(library.name) : library.name != null)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return name != null ? name.hashCode() : 0;
|
||||
}
|
||||
|
||||
@Data
|
||||
public static class Rule {
|
||||
private Action action;
|
||||
|
@ -11,7 +11,7 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.LinkedHashSet;
|
||||
|
||||
@Data
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@ -26,7 +26,7 @@ public class VersionManifest {
|
||||
private String minecraftArguments;
|
||||
private String mainClass;
|
||||
private int minimumLauncherVersion;
|
||||
private List<Library> libraries;
|
||||
private LinkedHashSet<Library> libraries;
|
||||
|
||||
@JsonIgnore
|
||||
public String getAssetsIndex() {
|
||||
|
5
src/main/resources/com/skcraft/launcher/maven_repos.json
Normal file
5
src/main/resources/com/skcraft/launcher/maven_repos.json
Normal file
@ -0,0 +1,5 @@
|
||||
[
|
||||
"https://libraries.minecraft.net/",
|
||||
"https://central.maven.org/maven2/",
|
||||
"http://maven.apache.org/"
|
||||
]
|
Loading…
Reference in New Issue
Block a user