2022-01-10 02:35:24 +01:00
|
|
|
package com.falsepattern.lib;
|
|
|
|
|
|
2022-01-10 18:21:27 +01:00
|
|
|
import com.falsepattern.lib.api.Version;
|
2022-01-10 02:35:24 +01:00
|
|
|
import cpw.mods.fml.common.DummyModContainer;
|
|
|
|
|
import cpw.mods.fml.common.ModMetadata;
|
2022-01-10 18:21:27 +01:00
|
|
|
import lombok.NonNull;
|
2022-01-10 02:35:24 +01:00
|
|
|
import lombok.val;
|
|
|
|
|
import lombok.var;
|
|
|
|
|
import net.minecraft.launchwrapper.Launch;
|
|
|
|
|
import net.minecraft.launchwrapper.LaunchClassLoader;
|
|
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
|
|
|
import org.apache.logging.log4j.Logger;
|
|
|
|
|
import scala.actors.threadpool.Arrays;
|
|
|
|
|
|
|
|
|
|
import javax.net.ssl.HttpsURLConnection;
|
|
|
|
|
import java.io.*;
|
|
|
|
|
import java.net.URL;
|
|
|
|
|
import java.util.*;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public class FalsePatternLib extends DummyModContainer {
|
|
|
|
|
public static Logger libLog = LogManager.getLogger(ModInfo.MODNAME);
|
|
|
|
|
public static final boolean developerEnvironment = (boolean) Launch.blackboard.get("fml.deobfuscatedEnvironment");
|
|
|
|
|
|
2022-01-10 18:21:27 +01:00
|
|
|
private static final Map<String, Version> loadedLibraries = new HashMap<>();
|
|
|
|
|
private static final Map<String, String> loadedLibraryMods = new HashMap<>();
|
|
|
|
|
private static final Set<String> mavenRepositories = new HashSet<>();
|
2022-01-10 02:35:24 +01:00
|
|
|
|
2022-01-10 18:21:27 +01:00
|
|
|
@SuppressWarnings("unchecked")
|
2022-01-10 02:35:24 +01:00
|
|
|
public FalsePatternLib() {
|
|
|
|
|
super(new ModMetadata());
|
|
|
|
|
libLog.info("All your libraries are belong to us!");
|
|
|
|
|
val meta = getMetadata();
|
|
|
|
|
meta.modId = ModInfo.MODID;
|
|
|
|
|
meta.name = ModInfo.MODNAME;
|
|
|
|
|
meta.version = ModInfo.VERSION;
|
|
|
|
|
meta.url = ModInfo.URL;
|
|
|
|
|
meta.credits = ModInfo.CREDITS;
|
|
|
|
|
meta.authorList = Arrays.asList(ModInfo.AUTHORS);
|
|
|
|
|
meta.description = ModInfo.DESCRIPTION;
|
|
|
|
|
meta.useDependencyInformation = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static void addMavenRepo(String url) {
|
|
|
|
|
mavenRepositories.add(url);
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-10 18:21:27 +01:00
|
|
|
@SuppressWarnings("ResultOfMethodCallIgnored")
|
2022-01-11 00:23:51 +01:00
|
|
|
public static void loadLibrary(String loadingModId, String groupId, String artifactId, @NonNull Version minVersion, Version maxVersion, @NonNull Version preferredVersion, String devSuffix) {
|
2022-01-10 18:21:27 +01:00
|
|
|
libLog.info("Adding library {}:{}:{}, requested by mod {}", groupId, artifactId, preferredVersion, loadingModId);
|
2022-01-10 02:35:24 +01:00
|
|
|
var artifact = groupId + ":" + artifactId;
|
|
|
|
|
if (loadedLibraries.containsKey(artifact)) {
|
|
|
|
|
val currentVer = loadedLibraries.get(artifact);
|
2022-01-10 18:21:27 +01:00
|
|
|
if (currentVer.equals(preferredVersion)) return;
|
|
|
|
|
val rangeString = "(minimum: " + minVersion + (maxVersion == null ? "" : ", maximum: " + maxVersion) + ")";
|
|
|
|
|
if (minVersion.compareTo(currentVer) > 0 || (maxVersion != null && maxVersion.compareTo(currentVer) < 0)) {
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
|
libLog.fatal("ALERT VVVVVVVVVVVV ALERT");
|
|
|
|
|
}
|
|
|
|
|
libLog.fatal("Library {}:{} already loaded with version {}, " +
|
|
|
|
|
"but a version in the range {} was requested! Thing may go horribly wrong! " +
|
|
|
|
|
"Requested by mod: {}, previously loaded by mod: {}",
|
|
|
|
|
groupId, artifactId, currentVer,
|
|
|
|
|
rangeString,
|
|
|
|
|
loadingModId, loadedLibraryMods.get(artifact));
|
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
|
|
|
libLog.fatal("ALERT ^^^^^^^^^^^^ ALERT");
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
libLog.info("Attempted loading of library {}:{} with preferred version {}, " +
|
|
|
|
|
"but version {} was already loaded, which matched the range {}. This is not an error. " +
|
|
|
|
|
"Requested by mod: {}, previously loaded by mod: {}",
|
|
|
|
|
groupId, artifactId, preferredVersion,
|
|
|
|
|
currentVer, rangeString,
|
|
|
|
|
loadingModId, loadedLibraryMods.get(artifact));
|
2022-01-10 02:35:24 +01:00
|
|
|
}
|
2022-01-10 18:21:27 +01:00
|
|
|
return;
|
2022-01-10 02:35:24 +01:00
|
|
|
}
|
|
|
|
|
val modsDir = new File(CoreLoadingPlugin.mcDir, "mods");
|
2022-01-10 18:39:15 +01:00
|
|
|
val mavenJarName = String.format("%s-%s%s.jar", artifactId, preferredVersion, (developerEnvironment && devSuffix != null) ? ("-" + devSuffix) : "");
|
2022-01-11 00:23:51 +01:00
|
|
|
val jarName = groupId + "-" + mavenJarName;
|
|
|
|
|
val libDir = new File(modsDir, "falsepattern");
|
|
|
|
|
if (!libDir.exists()) {
|
|
|
|
|
libDir.mkdirs();
|
2022-01-10 02:35:24 +01:00
|
|
|
}
|
2022-01-11 00:23:51 +01:00
|
|
|
val file = new File(libDir, jarName);
|
2022-01-10 02:35:24 +01:00
|
|
|
if (file.exists()) {
|
|
|
|
|
try {
|
2022-01-11 00:23:51 +01:00
|
|
|
addToClasspath(file);
|
2022-01-10 18:21:27 +01:00
|
|
|
loadedLibraries.put(artifact, preferredVersion);
|
|
|
|
|
libLog.info("Library {}:{}:{} successfully loaded from disk!", groupId, artifactId, preferredVersion);
|
2022-01-10 02:35:24 +01:00
|
|
|
return;
|
|
|
|
|
} catch (RuntimeException e) {
|
2022-01-10 18:21:27 +01:00
|
|
|
libLog.warn("Failed to load library {}:{}:{} from file! Redownloading...", groupId, artifactId, preferredVersion);
|
2022-01-10 02:35:24 +01:00
|
|
|
file.delete();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
for (var repo: mavenRepositories) {
|
|
|
|
|
try {
|
|
|
|
|
if (!repo.endsWith("/")) repo = repo + "/";
|
2022-01-10 18:39:15 +01:00
|
|
|
val url = new URL(String.format("%s%s/%s/%s/%s", repo, groupId.replace('.', '/'), artifactId, preferredVersion, mavenJarName));
|
2022-01-10 02:35:24 +01:00
|
|
|
|
|
|
|
|
val connection = (HttpsURLConnection) url.openConnection();
|
|
|
|
|
connection.setConnectTimeout(1500);
|
|
|
|
|
connection.setReadTimeout(1500);
|
|
|
|
|
connection.setRequestProperty("User-Agent", "FalsePatternLib Downloader");
|
|
|
|
|
if (connection.getResponseCode() != 200) {
|
2022-01-10 18:21:27 +01:00
|
|
|
libLog.info("Artifact {}:{}:{} was not found on repo {}", groupId, artifactId, preferredVersion, repo);
|
2022-01-10 02:35:24 +01:00
|
|
|
connection.disconnect();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2022-01-10 18:21:27 +01:00
|
|
|
libLog.info("Downloading {}:{}:{} from {}", groupId, artifactId, preferredVersion, repo);
|
2022-01-10 02:35:24 +01:00
|
|
|
download(connection.getInputStream(), file);
|
2022-01-10 18:21:27 +01:00
|
|
|
libLog.info("Downloaded {}:{}:{}", groupId, artifactId, preferredVersion);
|
|
|
|
|
loadedLibraries.put(artifact, preferredVersion);
|
|
|
|
|
loadedLibraryMods.put(artifact, loadingModId);
|
2022-01-10 02:35:24 +01:00
|
|
|
addToClasspath(file);
|
|
|
|
|
return;
|
|
|
|
|
} catch (IOException ignored) {}
|
|
|
|
|
}
|
2022-01-10 18:21:27 +01:00
|
|
|
val errorMessage = "Failed to download library " + groupId + ":" + artifactId + ":" + preferredVersion + " from any repository! Requested by mod: " + loadingModId;
|
|
|
|
|
libLog.fatal(errorMessage);
|
|
|
|
|
throw new IllegalStateException(errorMessage);
|
2022-01-10 02:35:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void addToClasspath(File file) {
|
|
|
|
|
try {
|
|
|
|
|
val cl = (LaunchClassLoader) FalsePatternLib.class.getClassLoader();
|
|
|
|
|
cl.addURL(file.toURI().toURL());
|
|
|
|
|
libLog.info("Injected file {} into classpath!", file.getPath());
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException("Failed to add library to classpath: " + file.getAbsolutePath(), e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void download(InputStream is, File target) throws IOException {
|
|
|
|
|
if (target.exists()) return;
|
|
|
|
|
|
|
|
|
|
var bytesRead = 0;
|
|
|
|
|
|
|
|
|
|
val fileOutput = new BufferedOutputStream(new FileOutputStream(target));
|
|
|
|
|
byte[] smallBuffer = new byte[4096];
|
|
|
|
|
while ((bytesRead = is.read(smallBuffer)) >= 0) {
|
|
|
|
|
fileOutput.write(smallBuffer, 0, bytesRead);
|
|
|
|
|
}
|
|
|
|
|
fileOutput.close();
|
|
|
|
|
is.close();
|
|
|
|
|
}
|
|
|
|
|
}
|