2018-10-12 22:56:09 +00:00
|
|
|
/*
|
|
|
|
* This file is part of Baritone.
|
|
|
|
*
|
|
|
|
* Baritone is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* Baritone 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 Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
|
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2018-10-13 02:21:16 +00:00
|
|
|
package baritone.gradle.task;
|
2018-10-12 22:56:09 +00:00
|
|
|
|
|
|
|
import baritone.gradle.util.Determinizer;
|
2018-12-01 11:31:40 +00:00
|
|
|
import baritone.gradle.util.MappingType;
|
|
|
|
import baritone.gradle.util.ReobfWrapper;
|
2018-10-12 22:56:09 +00:00
|
|
|
import org.apache.commons.io.IOUtils;
|
2020-07-15 07:18:01 +00:00
|
|
|
import org.gradle.api.JavaVersion;
|
2018-12-01 11:31:40 +00:00
|
|
|
import org.gradle.api.NamedDomainObjectContainer;
|
2018-10-12 22:56:09 +00:00
|
|
|
import org.gradle.api.artifacts.Configuration;
|
|
|
|
import org.gradle.api.artifacts.Dependency;
|
2020-07-15 07:18:01 +00:00
|
|
|
import org.gradle.api.internal.file.IdentityFileResolver;
|
2018-12-01 11:31:40 +00:00
|
|
|
import org.gradle.api.internal.plugins.DefaultConvention;
|
2018-10-12 22:56:09 +00:00
|
|
|
import org.gradle.api.tasks.Input;
|
|
|
|
import org.gradle.api.tasks.TaskAction;
|
2020-07-15 07:18:01 +00:00
|
|
|
import org.gradle.api.tasks.TaskCollection;
|
|
|
|
import org.gradle.api.tasks.compile.ForkOptions;
|
|
|
|
import org.gradle.api.tasks.compile.JavaCompile;
|
2018-10-12 23:08:15 +00:00
|
|
|
import org.gradle.internal.Pair;
|
2020-07-15 07:18:01 +00:00
|
|
|
import org.gradle.internal.jvm.Jvm;
|
|
|
|
import org.gradle.internal.jvm.inspection.DefaultJvmVersionDetector;
|
|
|
|
import org.gradle.process.internal.DefaultExecActionFactory;
|
2018-10-12 22:56:09 +00:00
|
|
|
|
|
|
|
import java.io.*;
|
2018-12-01 18:45:58 +00:00
|
|
|
import java.lang.reflect.Field;
|
2018-10-12 22:56:09 +00:00
|
|
|
import java.net.URL;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.util.*;
|
|
|
|
import java.util.regex.Matcher;
|
|
|
|
import java.util.regex.Pattern;
|
2018-12-01 18:45:58 +00:00
|
|
|
import java.util.stream.Collectors;
|
2018-10-12 22:56:09 +00:00
|
|
|
import java.util.zip.ZipEntry;
|
|
|
|
import java.util.zip.ZipFile;
|
|
|
|
|
|
|
|
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Brady
|
|
|
|
* @since 10/11/2018
|
|
|
|
*/
|
2018-10-13 02:21:16 +00:00
|
|
|
public class ProguardTask extends BaritoneGradleTask {
|
2018-10-12 22:56:09 +00:00
|
|
|
|
|
|
|
private static final Pattern TEMP_LIBRARY_PATTERN = Pattern.compile("-libraryjars 'tempLibraries\\/([a-zA-Z0-9/_\\-\\.]+)\\.jar'");
|
|
|
|
|
|
|
|
@Input
|
|
|
|
private String url;
|
|
|
|
|
|
|
|
@Input
|
|
|
|
private String extract;
|
|
|
|
|
|
|
|
private List<String> requiredLibraries;
|
|
|
|
|
2019-02-05 03:34:44 +00:00
|
|
|
private File mixin;
|
|
|
|
|
2018-10-12 22:56:09 +00:00
|
|
|
@TaskAction
|
2018-10-13 19:28:20 +00:00
|
|
|
protected void exec() throws Exception {
|
2018-10-13 02:21:16 +00:00
|
|
|
super.verifyArtifacts();
|
|
|
|
|
2018-10-12 22:56:09 +00:00
|
|
|
// "Haha brady why don't you make separate tasks"
|
|
|
|
processArtifact();
|
|
|
|
downloadProguard();
|
|
|
|
extractProguard();
|
|
|
|
generateConfigs();
|
|
|
|
acquireDependencies();
|
|
|
|
proguardApi();
|
|
|
|
proguardStandalone();
|
|
|
|
cleanup();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void processArtifact() throws Exception {
|
|
|
|
if (Files.exists(this.artifactUnoptimizedPath)) {
|
|
|
|
Files.delete(this.artifactUnoptimizedPath);
|
|
|
|
}
|
|
|
|
|
2019-02-05 03:34:44 +00:00
|
|
|
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
|
2018-10-12 22:56:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void downloadProguard() throws Exception {
|
|
|
|
Path proguardZip = getTemporaryFile(PROGUARD_ZIP);
|
|
|
|
if (!Files.exists(proguardZip)) {
|
|
|
|
write(new URL(this.url).openStream(), proguardZip);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void extractProguard() throws Exception {
|
|
|
|
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
|
|
|
|
if (!Files.exists(proguardJar)) {
|
|
|
|
ZipFile zipFile = new ZipFile(getTemporaryFile(PROGUARD_ZIP).toFile());
|
|
|
|
ZipEntry zipJarEntry = zipFile.getEntry(this.extract);
|
|
|
|
write(zipFile.getInputStream(zipJarEntry), proguardJar);
|
|
|
|
zipFile.close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-15 07:18:01 +00:00
|
|
|
private String getJavaBinPathForProguard() {
|
|
|
|
String path;
|
|
|
|
try {
|
|
|
|
path = findJavaPathByGradleConfig();
|
|
|
|
if (path != null) return path;
|
|
|
|
}
|
|
|
|
catch (Exception ex) {
|
|
|
|
System.err.println("Unable to find java by javaCompile options");
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
path = findJavaByJavaHome();
|
|
|
|
if (path != null) return path;
|
|
|
|
}
|
|
|
|
catch(Exception ex) {
|
|
|
|
System.err.println("Unable to find java by JAVA_HOME");
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
path = findJavaByGradleCurrentRuntime();
|
|
|
|
if (path != null) return path;
|
|
|
|
|
|
|
|
throw new RuntimeException("Unable to find java to determine ProGuard libraryjars. Please specify forkOptions.executable in javaCompile," +
|
|
|
|
" JAVA_HOME environment variable, or make sure to run Gradle with the correct JDK (a v1.8 only)");
|
|
|
|
}
|
|
|
|
|
|
|
|
private String findJavaByGradleCurrentRuntime() {
|
|
|
|
String path = Jvm.current().getJavaExecutable().getAbsolutePath();
|
|
|
|
|
|
|
|
if (this.validateJavaVersion(path)) {
|
|
|
|
System.out.println("Using Gradle's runtime Java for ProGuard");
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String findJavaByJavaHome() {
|
|
|
|
final String javaHomeEnv = System.getenv("JAVA_HOME");
|
|
|
|
if (javaHomeEnv != null) {
|
|
|
|
|
|
|
|
String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath();
|
|
|
|
if (this.validateJavaVersion(path)) {
|
|
|
|
System.out.println("Detected Java path by JAVA_HOME");
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private String findJavaPathByGradleConfig() {
|
|
|
|
final TaskCollection<JavaCompile> javaCompiles = super.getProject().getTasks().withType(JavaCompile.class);
|
|
|
|
|
|
|
|
final JavaCompile compileTask = javaCompiles.iterator().next();
|
|
|
|
final ForkOptions forkOptions = compileTask.getOptions().getForkOptions();
|
|
|
|
|
|
|
|
if (forkOptions != null) {
|
|
|
|
String javacPath = forkOptions.getExecutable();
|
|
|
|
if (javacPath != null) {
|
|
|
|
File javacFile = new File(javacPath);
|
|
|
|
if (javacFile.exists()) {
|
|
|
|
File[] maybeJava = javacFile.getParentFile().listFiles(new FilenameFilter() {
|
|
|
|
@Override
|
|
|
|
public boolean accept(File dir, String name) {
|
|
|
|
return name.equals("java");
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
if (maybeJava != null && maybeJava.length > 0) {
|
|
|
|
String path = maybeJava[0].getAbsolutePath();
|
|
|
|
if (this.validateJavaVersion(path)) {
|
|
|
|
System.out.println("Detected Java path by forkOptions");
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
private boolean validateJavaVersion(String java) {
|
|
|
|
final JavaVersion javaVersion = new DefaultJvmVersionDetector(new DefaultExecActionFactory(new IdentityFileResolver())).getJavaVersion(java);
|
|
|
|
|
|
|
|
if (!javaVersion.getMajorVersion().equals("8")) {
|
|
|
|
System.out.println("Failed to validate Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars");
|
|
|
|
// throw new RuntimeException("Java version incorrect: " + javaVersion.getMajorVersion() + " for " + java);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
System.out.println("Validated Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars");
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-10-12 22:56:09 +00:00
|
|
|
private void generateConfigs() throws Exception {
|
|
|
|
Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), REPLACE_EXISTING);
|
|
|
|
|
|
|
|
// Setup the template that will be used to derive the API and Standalone configs
|
|
|
|
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
|
|
|
|
template.add(0, "-injars " + this.artifactPath.toString());
|
|
|
|
template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH));
|
|
|
|
|
|
|
|
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
|
2020-07-15 07:18:01 +00:00
|
|
|
Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start();
|
2018-10-12 22:56:09 +00:00
|
|
|
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
|
|
|
|
template.add(2, "-libraryjars '" + out + "'");
|
|
|
|
|
|
|
|
// API config doesn't require any changes from the changes that we made to the template
|
|
|
|
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);
|
|
|
|
|
|
|
|
// For the Standalone config, don't keep the API package
|
|
|
|
List<String> standalone = new ArrayList<>(template);
|
|
|
|
standalone.removeIf(s -> s.contains("# this is the keep api"));
|
|
|
|
Files.write(getTemporaryFile(PROGUARD_STANDALONE_CONFIG), standalone);
|
|
|
|
|
|
|
|
// Discover all of the libraries that we will need to acquire from gradle
|
|
|
|
this.requiredLibraries = new ArrayList<>();
|
|
|
|
template.forEach(line -> {
|
|
|
|
if (!line.startsWith("#")) {
|
|
|
|
Matcher m = TEMP_LIBRARY_PATTERN.matcher(line);
|
|
|
|
if (m.find()) {
|
|
|
|
this.requiredLibraries.add(m.group(1));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
private void acquireDependencies() throws Exception {
|
|
|
|
|
|
|
|
// Create a map of all of the dependencies that we are able to access in this project
|
|
|
|
// Likely a better way to do this, I just pair the dependency with the first valid configuration
|
|
|
|
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
|
|
|
|
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
|
|
|
|
config.getAllDependencies().forEach(dependency ->
|
2018-10-12 23:08:15 +00:00
|
|
|
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
|
2018-10-12 22:56:09 +00:00
|
|
|
|
|
|
|
// Create the directory if it doesn't already exist
|
|
|
|
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
|
|
|
|
if (!Files.exists(tempLibraries)) {
|
|
|
|
Files.createDirectory(tempLibraries);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Iterate the required libraries to copy them to tempLibraries
|
|
|
|
for (String lib : this.requiredLibraries) {
|
2018-12-01 11:31:40 +00:00
|
|
|
// copy from the forgegradle cache
|
|
|
|
if (lib.equals("minecraft")) {
|
2018-12-01 18:45:58 +00:00
|
|
|
Path cachedJar = getMinecraftJar();
|
|
|
|
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
|
2018-12-01 11:31:40 +00:00
|
|
|
// TODO: maybe try not to copy every time
|
2018-12-01 11:42:21 +00:00
|
|
|
Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
|
2018-12-01 11:31:40 +00:00
|
|
|
|
2018-10-12 22:56:09 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Find a configuration/dependency pair that matches the desired library
|
|
|
|
Pair<Configuration, Dependency> pair = null;
|
|
|
|
for (Map.Entry<String, Pair<Configuration, Dependency>> entry : dependencyLookupMap.entrySet()) {
|
|
|
|
if (entry.getKey().startsWith(lib)) {
|
|
|
|
pair = entry.getValue();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// The pair must be non-null
|
|
|
|
Objects.requireNonNull(pair);
|
|
|
|
|
|
|
|
// Find the library jar file, and copy it to tempLibraries
|
2018-10-12 23:08:15 +00:00
|
|
|
for (File file : pair.getLeft().files(pair.getRight())) {
|
2018-10-12 22:56:09 +00:00
|
|
|
if (file.getName().startsWith(lib)) {
|
2019-02-05 03:34:44 +00:00
|
|
|
if (lib.contains("mixin")) {
|
|
|
|
mixin = file;
|
|
|
|
}
|
2018-10-12 22:56:09 +00:00
|
|
|
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-02-05 03:34:44 +00:00
|
|
|
if (mixin == null) {
|
|
|
|
throw new IllegalStateException("Unable to find mixin jar");
|
|
|
|
}
|
2018-10-12 22:56:09 +00:00
|
|
|
}
|
|
|
|
|
2018-12-01 18:22:11 +00:00
|
|
|
// a bunch of epic stuff to get the path to the cached jar
|
2018-12-01 11:31:40 +00:00
|
|
|
private Path getMinecraftJar() throws Exception {
|
|
|
|
MappingType mappingType;
|
|
|
|
try {
|
|
|
|
mappingType = getMappingType();
|
|
|
|
} catch (Exception e) {
|
2018-12-01 18:22:11 +00:00
|
|
|
System.err.println("Failed to get mapping type, assuming NOTCH.");
|
|
|
|
mappingType = MappingType.NOTCH;
|
2018-12-01 11:31:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
String suffix;
|
|
|
|
switch (mappingType) {
|
|
|
|
case NOTCH:
|
|
|
|
suffix = "";
|
|
|
|
break;
|
|
|
|
case SEARGE:
|
|
|
|
suffix = "-srgBin";
|
|
|
|
break;
|
|
|
|
case CUSTOM:
|
2018-12-01 18:22:11 +00:00
|
|
|
throw new IllegalStateException("Custom mappings not supported!");
|
2018-12-01 11:31:40 +00:00
|
|
|
default:
|
|
|
|
throw new IllegalStateException("Unknown mapping type: " + mappingType);
|
|
|
|
}
|
|
|
|
|
2018-12-01 18:22:11 +00:00
|
|
|
DefaultConvention convention = (DefaultConvention) this.getProject().getConvention();
|
2018-12-01 18:45:58 +00:00
|
|
|
Object extension = convention.getAsMap().get("minecraft");
|
2018-12-01 11:31:40 +00:00
|
|
|
Objects.requireNonNull(extension);
|
|
|
|
|
|
|
|
// for some reason cant use Class.forName
|
2019-01-03 05:08:31 +00:00
|
|
|
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
|
2018-12-01 11:31:40 +00:00
|
|
|
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
|
|
|
|
f_replacer.setAccessible(true);
|
2018-12-01 18:45:58 +00:00
|
|
|
Object replacer = f_replacer.get(extension);
|
2018-12-01 11:31:40 +00:00
|
|
|
Class<?> class_replacementProvider = replacer.getClass();
|
|
|
|
Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap");
|
|
|
|
replacement_replaceMap.setAccessible(true);
|
|
|
|
|
2018-12-01 18:45:58 +00:00
|
|
|
Map<String, Object> replacements = (Map) replacement_replaceMap.get(replacer);
|
|
|
|
String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft";
|
|
|
|
String mcVersion = replacements.get("MC_VERSION").toString();
|
|
|
|
String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString();
|
|
|
|
String fullJarName = "minecraft-" + mcVersion + suffix + ".jar";
|
2018-12-01 11:31:40 +00:00
|
|
|
|
2018-12-01 18:45:58 +00:00
|
|
|
String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion);
|
2018-12-01 11:31:40 +00:00
|
|
|
|
|
|
|
String jarPath;
|
|
|
|
if (mappingType == MappingType.SEARGE) {
|
|
|
|
jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName);
|
|
|
|
} else {
|
|
|
|
jarPath = baseDir + fullJarName;
|
|
|
|
}
|
|
|
|
jarPath = jarPath
|
2018-12-01 18:22:11 +00:00
|
|
|
.replace("/", File.separator)
|
|
|
|
.replace("\\", File.separator); // hecking regex
|
2018-12-01 11:31:40 +00:00
|
|
|
|
|
|
|
return new File(jarPath).toPath();
|
|
|
|
}
|
|
|
|
|
|
|
|
// throws IllegalStateException if mapping type is ambiguous or it fails to find it
|
|
|
|
private MappingType getMappingType() {
|
|
|
|
// if it fails to find this then its probably a forgegradle version problem
|
2018-12-01 18:45:58 +00:00
|
|
|
Set<Object> reobf = (NamedDomainObjectContainer<Object>) this.getProject().getExtensions().getByName("reobf");
|
2018-12-01 11:31:40 +00:00
|
|
|
|
2018-12-01 18:45:58 +00:00
|
|
|
List<MappingType> mappingTypes = getUsedMappingTypes(reobf);
|
|
|
|
long mappingTypesUsed = mappingTypes.size();
|
2018-12-01 18:22:11 +00:00
|
|
|
if (mappingTypesUsed == 0) {
|
2018-12-01 11:31:40 +00:00
|
|
|
throw new IllegalStateException("Failed to find mapping type (no jar task?)");
|
2018-12-01 18:45:58 +00:00
|
|
|
}
|
|
|
|
if (mappingTypesUsed > 1) {
|
2018-12-01 11:31:40 +00:00
|
|
|
throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)");
|
2018-12-01 18:22:11 +00:00
|
|
|
}
|
2018-12-01 11:31:40 +00:00
|
|
|
|
|
|
|
return mappingTypes.get(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
|
|
|
|
return reobf.stream()
|
2018-12-01 18:45:58 +00:00
|
|
|
.map(ReobfWrapper::new)
|
|
|
|
.map(ReobfWrapper::getMappingType)
|
|
|
|
.distinct()
|
|
|
|
.collect(Collectors.toList());
|
2018-12-01 11:31:40 +00:00
|
|
|
}
|
|
|
|
|
2018-10-12 22:56:09 +00:00
|
|
|
private void proguardApi() throws Exception {
|
|
|
|
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
|
2019-02-05 03:34:44 +00:00
|
|
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
|
2019-02-06 20:50:42 +00:00
|
|
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
|
2018-10-12 22:56:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void proguardStandalone() throws Exception {
|
|
|
|
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
|
2019-02-05 03:34:44 +00:00
|
|
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
|
2019-02-06 20:50:42 +00:00
|
|
|
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
|
2018-10-12 22:56:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private void cleanup() {
|
|
|
|
try {
|
|
|
|
Files.delete(this.proguardOut);
|
|
|
|
} catch (IOException ignored) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setUrl(String url) {
|
|
|
|
this.url = url;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void setExtract(String extract) {
|
|
|
|
this.extract = extract;
|
|
|
|
}
|
|
|
|
|
|
|
|
private void runProguard(Path config) throws Exception {
|
|
|
|
// Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves
|
|
|
|
if (Files.exists(this.proguardOut)) {
|
|
|
|
Files.delete(this.proguardOut);
|
|
|
|
}
|
|
|
|
|
|
|
|
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
|
|
|
|
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
|
2018-10-13 02:21:16 +00:00
|
|
|
.directory(getTemporaryFile("").toFile()) // Set the working directory to the temporary folder]
|
2018-10-12 22:56:09 +00:00
|
|
|
.start();
|
|
|
|
|
2018-10-13 02:21:16 +00:00
|
|
|
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this
|
2019-02-04 03:27:28 +00:00
|
|
|
this.printOutputLog(p.getInputStream(), System.out);
|
|
|
|
this.printOutputLog(p.getErrorStream(), System.err);
|
2018-10-13 02:21:16 +00:00
|
|
|
|
2018-10-12 22:56:09 +00:00
|
|
|
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
|
2018-10-13 04:19:11 +00:00
|
|
|
int exitCode = p.waitFor();
|
|
|
|
if (exitCode != 0) {
|
2018-10-27 21:41:25 +00:00
|
|
|
throw new IllegalStateException("Proguard exited with code " + exitCode);
|
2018-10-12 22:56:09 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-04 03:27:28 +00:00
|
|
|
private void printOutputLog(InputStream stream, PrintStream outerr) {
|
2018-10-13 02:21:16 +00:00
|
|
|
new Thread(() -> {
|
|
|
|
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
|
|
|
|
String line;
|
|
|
|
while ((line = reader.readLine()) != null) {
|
2019-02-04 03:27:28 +00:00
|
|
|
outerr.println(line);
|
2018-10-13 02:21:16 +00:00
|
|
|
}
|
2018-12-01 18:45:58 +00:00
|
|
|
} catch (Exception e) {
|
2018-10-13 02:21:16 +00:00
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}).start();
|
2018-10-12 22:56:09 +00:00
|
|
|
}
|
|
|
|
}
|