mirror of
https://github.com/GTNewHorizons/CodeChickenCore.git
synced 2026-11-11 15:57:42 +00:00
Bye bye DepLoader
This commit is contained in:
1 parent
4686fe8fa1
commit
7f78ceb921
8 files changed
+22
-582
No files matched your search
+3
-11
@@ -33,7 +33,7 @@ channel = stable
|
||||
mappingsVersion = 12
|
||||
|
||||
# Defines other MCP mappings for dependency deobfuscation.
|
||||
remoteMappings = https://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
|
||||
remoteMappings = https\://raw.githubusercontent.com/MinecraftForge/FML/1.7.10/conf/
|
||||
|
||||
# Select a default username for testing your mod. You can always override this per-run by running
|
||||
# `./gradlew runClient --username=AnotherPlayer`, or configuring this command in your IDE.
|
||||
@@ -55,12 +55,6 @@ generateGradleTokenClass = codechicken.core.asm.Tags
|
||||
# Name of the token containing the project's current version to generate/replace.
|
||||
gradleTokenVersion = VERSION
|
||||
|
||||
# [DEPRECATED] Mod ID replacement token.
|
||||
gradleTokenModId = MODID
|
||||
|
||||
# [DEPRECATED] Mod name replacement token.
|
||||
gradleTokenModName = MODNAME
|
||||
|
||||
# [DEPRECATED]
|
||||
# Multiple source files can be defined here by providing a comma-separated list: Class1.java,Class2.java,Class3.java
|
||||
# public static final String VERSION = "GRADLETOKEN_VERSION";
|
||||
@@ -114,7 +108,7 @@ minimizeShadowedDependencies = true
|
||||
# If disabled, won't rename the shadowed classes.
|
||||
relocateShadowedDependencies = true
|
||||
|
||||
# Adds the GTNH maven, CurseMaven, IC2/Player maven, and some more well-known 1.7.10 repositories.
|
||||
# Adds the GTNH maven, CurseMaven, Modrinth, and some more well-known 1.7.10 repositories.
|
||||
includeWellKnownRepositories = true
|
||||
|
||||
# Change these to your Maven coordinates if you want to publish to a custom Maven repository instead of the default GTNH Maven.
|
||||
@@ -123,7 +117,7 @@ includeWellKnownRepositories = true
|
||||
usesMavenPublishing = true
|
||||
|
||||
# Maven repository to publish the mod to.
|
||||
# mavenPublishUrl = https://nexus.gtnewhorizons.com/repository/releases/
|
||||
# mavenPublishUrl = https\://nexus.gtnewhorizons.com/repository/releases/
|
||||
|
||||
# Publishing to Modrinth requires you to set the MODRINTH_TOKEN environment variable to your current Modrinth API token.
|
||||
#
|
||||
@@ -187,5 +181,3 @@ curseForgeRelations =
|
||||
# This is meant to be set in $HOME/.gradle/gradle.properties.
|
||||
# ideaCheckSpotlessOnBuild = true
|
||||
|
||||
# Non-GTNH properties
|
||||
gradleTokenGroupName = GROUPNAME
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
+1
-1
@@ -17,7 +17,7 @@ pluginManagement {
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.8'
|
||||
id 'com.gtnewhorizons.gtnhsettingsconvention' version '1.0.23'
|
||||
}
|
||||
|
||||
|
||||
@@ -1,113 +1,22 @@
|
||||
package codechicken.core;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.util.ChatComponentText;
|
||||
import net.minecraft.util.StatCollector;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
|
||||
import codechicken.core.launch.CodeChickenCorePlugin;
|
||||
import cpw.mods.fml.common.Loader;
|
||||
import cpw.mods.fml.common.versioning.ComparableVersion;
|
||||
import cpw.mods.fml.relauncher.FMLInjectionData;
|
||||
|
||||
public class CCUpdateChecker {
|
||||
|
||||
private static final ArrayList<String> updates = new ArrayList<String>();
|
||||
public static void tick() {}
|
||||
|
||||
private static class ThreadUpdateCheck extends Thread {
|
||||
|
||||
private final URL url;
|
||||
private final Function<String, Void> handler;
|
||||
|
||||
public ThreadUpdateCheck(URL url, Function<String, Void> handler) {
|
||||
this.url = url;
|
||||
this.handler = handler;
|
||||
|
||||
setName("CodeChicken Update Checker");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setConnectTimeout(5000);
|
||||
conn.setReadTimeout(5000);
|
||||
BufferedReader read = new BufferedReader(new InputStreamReader(conn.getInputStream()));
|
||||
String ret = read.readLine();
|
||||
read.close();
|
||||
if (ret == null) ret = "";
|
||||
handler.apply(ret);
|
||||
} catch (SocketTimeoutException ignored) {} catch (UnknownHostException ignored) {} catch (IOException iox) {
|
||||
iox.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
Minecraft mc = Minecraft.getMinecraft();
|
||||
if (!mc.inGameHasFocus) return;
|
||||
|
||||
synchronized (updates) {
|
||||
for (String s : updates) mc.thePlayer.addChatMessage(new ChatComponentText(s));
|
||||
updates.clear();
|
||||
}
|
||||
}
|
||||
|
||||
public static void addUpdateMessage(String s) {
|
||||
synchronized (updates) {
|
||||
updates.add(s);
|
||||
}
|
||||
}
|
||||
public static void addUpdateMessage(String s) {}
|
||||
|
||||
public static String mcVersion() {
|
||||
return (String) FMLInjectionData.data()[4];
|
||||
}
|
||||
|
||||
public static void updateCheck(final String mod, final String version) {
|
||||
updateCheck(
|
||||
"http://www.chickenbones.net/Files/notification/version.php?" + "version="
|
||||
+ mcVersion()
|
||||
+ "&"
|
||||
+ "file="
|
||||
+ mod,
|
||||
new Function<String, Void>() {
|
||||
public static void updateCheck(final String mod, final String version) {}
|
||||
|
||||
@Override
|
||||
public Void apply(String ret) {
|
||||
if (!ret.startsWith("Ret: ")) {
|
||||
CodeChickenCorePlugin.logger
|
||||
.error("Failed to check update for " + mod + " returned: " + ret);
|
||||
return null;
|
||||
}
|
||||
ComparableVersion newversion = new ComparableVersion(ret.substring(5));
|
||||
if (newversion.compareTo(new ComparableVersion(version)) > 0) addUpdateMessage(
|
||||
StatCollector.translateToLocalFormatted("codechickencore.update", newversion, mod));
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
public static void updateCheck(String mod) {}
|
||||
|
||||
public static void updateCheck(String mod) {
|
||||
updateCheck(mod, Loader.instance().getIndexedModList().get(mod).getVersion());
|
||||
}
|
||||
|
||||
public static void updateCheck(String url, Function<String, Void> handler) {
|
||||
try {
|
||||
new ThreadUpdateCheck(new URL(url), handler).start();
|
||||
} catch (MalformedURLException e) {
|
||||
CodeChickenCorePlugin.logger.error("Malformed URL: " + url, e);
|
||||
}
|
||||
}
|
||||
public static void updateCheck(String url, Function<String, Void> handler) {}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ import net.minecraftforge.common.MinecraftForge;
|
||||
import com.google.common.eventbus.EventBus;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
|
||||
import codechicken.core.CCUpdateChecker;
|
||||
import codechicken.core.ClientUtils;
|
||||
import codechicken.core.featurehack.LiquidTextures;
|
||||
import codechicken.core.internal.CCCEventHandler;
|
||||
@@ -75,8 +74,6 @@ public class CodeChickenCoreModContainer extends DummyModContainer {
|
||||
@Subscribe
|
||||
public void init(FMLInitializationEvent event) {
|
||||
if (event.getSide().isClient()) {
|
||||
if (config.getTag("checkUpdates").getBooleanValue(true)) CCUpdateChecker.updateCheck(getModId());
|
||||
|
||||
ClientUtils.enhanceSupportersList("CodeChickenCore");
|
||||
|
||||
FMLCommonHandler.instance().bus().register(new CCCEventHandler());
|
||||
|
||||
@@ -2,7 +2,6 @@ package codechicken.core.internal;
|
||||
|
||||
import net.minecraftforge.client.event.GuiScreenEvent;
|
||||
|
||||
import codechicken.core.CCUpdateChecker;
|
||||
import codechicken.core.GuiModListScroll;
|
||||
import cpw.mods.fml.client.GuiModList;
|
||||
import cpw.mods.fml.common.eventhandler.SubscribeEvent;
|
||||
@@ -19,7 +18,6 @@ public class CCCEventHandler {
|
||||
@SubscribeEvent
|
||||
public void clientTick(TickEvent.ClientTickEvent event) {
|
||||
if (event.phase == Phase.END) {
|
||||
CCUpdateChecker.tick();
|
||||
renderTime++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ public class CodeChickenCorePlugin implements IFMLLoadingPlugin, IFMLCallHook {
|
||||
minecraftDir = (File) FMLInjectionData.data()[6];
|
||||
currentMcVersion = (String) FMLInjectionData.data()[4];
|
||||
|
||||
DepLoader.load();
|
||||
injectDeobfPlugin();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,63 +1,17 @@
|
||||
package codechicken.core.launch;
|
||||
|
||||
import java.awt.Desktop;
|
||||
import java.awt.Dialog.ModalityType;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.net.URLConnection;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JDialog;
|
||||
import javax.swing.JEditorPane;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JProgressBar;
|
||||
import javax.swing.WindowConstants;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
|
||||
import net.minecraft.launchwrapper.LaunchClassLoader;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
|
||||
import cpw.mods.fml.common.versioning.ComparableVersion;
|
||||
import cpw.mods.fml.relauncher.FMLInjectionData;
|
||||
import cpw.mods.fml.relauncher.FMLLaunchHandler;
|
||||
import cpw.mods.fml.relauncher.IFMLCallHook;
|
||||
import cpw.mods.fml.relauncher.IFMLLoadingPlugin;
|
||||
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.MCVersion;
|
||||
import sun.misc.URLClassPath;
|
||||
import sun.net.util.URLUtil;
|
||||
|
||||
/**
|
||||
* For autodownloading stuff. This is really unoriginal, mostly ripped off FML, credits to cpw.
|
||||
@@ -65,10 +19,6 @@ import sun.net.util.URLUtil;
|
||||
@MCVersion("1.7.10")
|
||||
public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
|
||||
|
||||
private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23);
|
||||
private static final String owner = "CB's DepLoader";
|
||||
private static DepLoadInst inst;
|
||||
|
||||
public interface IDownloadDisplay {
|
||||
|
||||
void resetProgress(int sizeGuess);
|
||||
@@ -89,140 +39,39 @@ public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
|
||||
@SuppressWarnings("serial")
|
||||
public static class Downloader extends JOptionPane implements IDownloadDisplay {
|
||||
|
||||
private JDialog container;
|
||||
private JLabel currentActivity;
|
||||
private JProgressBar progress;
|
||||
boolean stopIt;
|
||||
Thread pokeThread;
|
||||
|
||||
private Box makeProgressPanel() {
|
||||
Box box = Box.createVerticalBox();
|
||||
box.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
JLabel welcomeLabel = new JLabel(
|
||||
"<html><b><font size='+1'>" + owner
|
||||
+ " is setting up your minecraft environment</font></b></html>");
|
||||
box.add(welcomeLabel);
|
||||
welcomeLabel.setAlignmentY(LEFT_ALIGNMENT);
|
||||
welcomeLabel = new JLabel(
|
||||
"<html>Please wait, " + owner + " has some tasks to do before you can play</html>");
|
||||
welcomeLabel.setAlignmentY(LEFT_ALIGNMENT);
|
||||
box.add(welcomeLabel);
|
||||
box.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
currentActivity = new JLabel("Currently doing ...");
|
||||
box.add(currentActivity);
|
||||
box.add(Box.createRigidArea(new Dimension(0, 10)));
|
||||
progress = new JProgressBar(0, 100);
|
||||
progress.setStringPainted(true);
|
||||
box.add(progress);
|
||||
box.add(Box.createRigidArea(new Dimension(0, 30)));
|
||||
return box;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JDialog makeDialog() {
|
||||
if (container != null) return container;
|
||||
|
||||
setMessageType(JOptionPane.INFORMATION_MESSAGE);
|
||||
setMessage(makeProgressPanel());
|
||||
setOptions(new Object[] { "Stop" });
|
||||
addPropertyChangeListener(new PropertyChangeListener() {
|
||||
|
||||
@Override
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (evt.getSource() == Downloader.this && evt.getPropertyName() == VALUE_PROPERTY) {
|
||||
requestClose("This will stop minecraft from launching\nAre you sure you want to do this?");
|
||||
}
|
||||
}
|
||||
});
|
||||
container = new JDialog(null, "Hello", ModalityType.MODELESS);
|
||||
container.setResizable(false);
|
||||
container.setLocationRelativeTo(null);
|
||||
container.add(this);
|
||||
this.updateUI();
|
||||
container.pack();
|
||||
container.setMinimumSize(container.getPreferredSize());
|
||||
container.setVisible(true);
|
||||
container.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||
container.addWindowListener(new WindowAdapter() {
|
||||
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
requestClose(
|
||||
"Closing this window will stop minecraft from launching\nAre you sure you wish to do this?");
|
||||
}
|
||||
});
|
||||
return container;
|
||||
return null;
|
||||
}
|
||||
|
||||
protected void requestClose(String message) {
|
||||
int shouldClose = JOptionPane.showConfirmDialog(
|
||||
container,
|
||||
message,
|
||||
"Are you sure you want to stop?",
|
||||
JOptionPane.YES_NO_OPTION,
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
if (shouldClose == JOptionPane.YES_OPTION) container.dispose();
|
||||
|
||||
stopIt = true;
|
||||
if (pokeThread != null) pokeThread.interrupt();
|
||||
}
|
||||
protected void requestClose(String message) {}
|
||||
|
||||
@Override
|
||||
public void updateProgressString(String progressUpdate, Object... data) {
|
||||
// FMLLog.finest(progressUpdate, data);
|
||||
if (currentActivity != null) currentActivity.setText(String.format(progressUpdate, data));
|
||||
}
|
||||
public void updateProgressString(String progressUpdate, Object... data) {}
|
||||
|
||||
@Override
|
||||
public void resetProgress(int sizeGuess) {
|
||||
if (progress != null) progress.getModel().setRangeProperties(0, 0, 0, sizeGuess, false);
|
||||
}
|
||||
public void resetProgress(int sizeGuess) {}
|
||||
|
||||
@Override
|
||||
public void updateProgress(int fullLength) {
|
||||
if (progress != null) progress.getModel().setValue(fullLength);
|
||||
}
|
||||
public void updateProgress(int fullLength) {}
|
||||
|
||||
@Override
|
||||
public void setPokeThread(Thread currentThread) {
|
||||
this.pokeThread = currentThread;
|
||||
}
|
||||
public void setPokeThread(Thread currentThread) {}
|
||||
|
||||
@Override
|
||||
public boolean shouldStopIt() {
|
||||
return stopIt;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void showErrorDialog(String name, String url) {
|
||||
JEditorPane ep = new JEditorPane(
|
||||
"text/html",
|
||||
"<html>" + owner
|
||||
+ " was unable to download required library "
|
||||
+ name
|
||||
+ "<br>Check your internet connection and try restarting or download it manually from"
|
||||
+ "<br><a href=\""
|
||||
+ url
|
||||
+ "\">"
|
||||
+ url
|
||||
+ "</a> and put it in your mods folder"
|
||||
+ "</html>");
|
||||
|
||||
ep.setEditable(false);
|
||||
ep.setOpaque(false);
|
||||
ep.addHyperlinkListener(new HyperlinkListener() {
|
||||
|
||||
@Override
|
||||
public void hyperlinkUpdate(HyperlinkEvent event) {
|
||||
try {
|
||||
if (event.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED))
|
||||
Desktop.getDesktop().browse(event.getURL().toURI());
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
});
|
||||
|
||||
JOptionPane.showMessageDialog(null, ep, "A download error has occurred", JOptionPane.ERROR_MESSAGE);
|
||||
}
|
||||
public void showErrorDialog(String name, String url) {}
|
||||
}
|
||||
|
||||
public static class DummyDownloader implements IDownloadDisplay {
|
||||
@@ -298,316 +147,12 @@ public class DepLoader implements IFMLLoadingPlugin, IFMLCallHook {
|
||||
|
||||
public static class DepLoadInst {
|
||||
|
||||
private File modsDir;
|
||||
private File v_modsDir;
|
||||
private IDownloadDisplay downloadMonitor;
|
||||
private JDialog popupWindow;
|
||||
public DepLoadInst() {}
|
||||
|
||||
private Map<String, Dependency> depMap = new HashMap<String, Dependency>();
|
||||
private HashSet<String> depSet = new HashSet<String>();
|
||||
|
||||
public DepLoadInst() {
|
||||
String mcVer = (String) FMLInjectionData.data()[4];
|
||||
File mcDir = (File) FMLInjectionData.data()[6];
|
||||
|
||||
modsDir = new File(mcDir, "mods");
|
||||
v_modsDir = new File(mcDir, "mods/" + mcVer);
|
||||
if (!v_modsDir.exists()) v_modsDir.mkdirs();
|
||||
}
|
||||
|
||||
private void addClasspath(String name) {
|
||||
try {
|
||||
((LaunchClassLoader) DepLoader.class.getClassLoader())
|
||||
.addURL(new File(v_modsDir, name).toURI().toURL());
|
||||
} catch (MalformedURLException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void deleteMod(File mod) {
|
||||
if (mod.delete()) return;
|
||||
|
||||
try {
|
||||
ClassLoader cl = DepLoader.class.getClassLoader();
|
||||
URL url = mod.toURI().toURL();
|
||||
Field f_ucp = URLClassLoader.class.getDeclaredField("ucp");
|
||||
Field f_loaders = URLClassPath.class.getDeclaredField("loaders");
|
||||
Field f_lmap = URLClassPath.class.getDeclaredField("lmap");
|
||||
f_ucp.setAccessible(true);
|
||||
f_loaders.setAccessible(true);
|
||||
f_lmap.setAccessible(true);
|
||||
|
||||
URLClassPath ucp = (URLClassPath) f_ucp.get(cl);
|
||||
Closeable loader = ((Map<String, Closeable>) f_lmap.get(ucp)).remove(URLUtil.urlNoFragString(url));
|
||||
if (loader != null) {
|
||||
loader.close();
|
||||
((List<?>) f_loaders.get(ucp)).remove(loader);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (!mod.delete()) {
|
||||
mod.deleteOnExit();
|
||||
String msg = owner + " was unable to delete file "
|
||||
+ mod.getPath()
|
||||
+ " the game will now try to delete it on exit. If this dialog appears again, delete it manually.";
|
||||
CodeChickenCorePlugin.logger.error(msg);
|
||||
if (!GraphicsEnvironment.isHeadless())
|
||||
JOptionPane.showMessageDialog(null, msg, "An update error has occurred", JOptionPane.ERROR_MESSAGE);
|
||||
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private void download(Dependency dep) {
|
||||
popupWindow = (JDialog) downloadMonitor.makeDialog();
|
||||
File libFile = new File(v_modsDir, dep.file.filename);
|
||||
try {
|
||||
URL libDownload = new URL(dep.url + '/' + dep.file.filename);
|
||||
downloadMonitor.updateProgressString("Downloading file %s", libDownload.toString());
|
||||
CodeChickenCorePlugin.logger.debug("Downloading file " + libDownload);
|
||||
URLConnection connection = libDownload.openConnection();
|
||||
connection.setConnectTimeout(5000);
|
||||
connection.setReadTimeout(5000);
|
||||
connection.setRequestProperty("User-Agent", "" + owner + " Downloader");
|
||||
int sizeGuess = connection.getContentLength();
|
||||
download(connection.getInputStream(), sizeGuess, libFile);
|
||||
downloadMonitor.updateProgressString("Download complete");
|
||||
CodeChickenCorePlugin.logger.trace("Download complete");
|
||||
|
||||
scanDepInfo(libFile);
|
||||
} catch (Exception e) {
|
||||
libFile.delete();
|
||||
if (downloadMonitor.shouldStopIt()) {
|
||||
CodeChickenCorePlugin.logger
|
||||
.error("You have stopped the downloading operation before it could complete");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
downloadMonitor.showErrorDialog(dep.file.filename, dep.url + '/' + dep.file.filename);
|
||||
throw new RuntimeException("A download error occured", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void download(InputStream is, int sizeGuess, File target) throws Exception {
|
||||
if (sizeGuess > downloadBuffer.capacity()) throw new Exception(
|
||||
String.format(
|
||||
"The file %s is too large to be downloaded by " + owner + " - the download is invalid",
|
||||
target.getName()));
|
||||
|
||||
downloadBuffer.clear();
|
||||
|
||||
int bytesRead, fullLength = 0;
|
||||
|
||||
downloadMonitor.resetProgress(sizeGuess);
|
||||
try {
|
||||
downloadMonitor.setPokeThread(Thread.currentThread());
|
||||
byte[] smallBuffer = new byte[1024];
|
||||
while ((bytesRead = is.read(smallBuffer)) >= 0) {
|
||||
downloadBuffer.put(smallBuffer, 0, bytesRead);
|
||||
fullLength += bytesRead;
|
||||
if (downloadMonitor.shouldStopIt()) {
|
||||
break;
|
||||
}
|
||||
downloadMonitor.updateProgress(fullLength);
|
||||
}
|
||||
is.close();
|
||||
downloadMonitor.setPokeThread(null);
|
||||
downloadBuffer.limit(fullLength);
|
||||
downloadBuffer.position(0);
|
||||
} catch (InterruptedIOException e) {
|
||||
// We were interrupted by the stop button. We're stopping now.. clear interruption flag.
|
||||
Thread.interrupted();
|
||||
throw new Exception("Stop");
|
||||
} catch (IOException e) {
|
||||
throw e;
|
||||
}
|
||||
|
||||
try {
|
||||
/*
|
||||
* String cksum = generateChecksum(downloadBuffer); if (cksum.equals(validationHash)) {
|
||||
*/
|
||||
if (!target.exists()) target.createNewFile();
|
||||
|
||||
downloadBuffer.position(0);
|
||||
FileOutputStream fos = new FileOutputStream(target);
|
||||
fos.getChannel().write(downloadBuffer);
|
||||
fos.close();
|
||||
/*
|
||||
* } else { throw new RuntimeException(String.
|
||||
* format("The downloaded file %s has an invalid checksum %s (expecting %s). The download did not succeed correctly and the file has been deleted. Please try launching again."
|
||||
* , target.getName(), cksum, validationHash)); }
|
||||
*/
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private String checkExisting(Dependency dep) {
|
||||
for (File f : modsDir.listFiles()) {
|
||||
VersionedFile vfile = new VersionedFile(f.getName(), dep.file.pattern);
|
||||
if (!vfile.matches() || !vfile.name.equals(dep.file.name)) continue;
|
||||
|
||||
if (f.renameTo(new File(v_modsDir, f.getName()))) continue;
|
||||
|
||||
deleteMod(f);
|
||||
}
|
||||
|
||||
for (File f : v_modsDir.listFiles()) {
|
||||
VersionedFile vfile = new VersionedFile(f.getName(), dep.file.pattern);
|
||||
if (!vfile.matches() || !vfile.name.equals(dep.file.name)) continue;
|
||||
|
||||
int cmp = vfile.version.compareTo(dep.file.version);
|
||||
if (cmp < 0) {
|
||||
CodeChickenCorePlugin.logger.warn("Deleted old version " + f.getName());
|
||||
deleteMod(f);
|
||||
return null;
|
||||
}
|
||||
if (cmp > 0) {
|
||||
CodeChickenCorePlugin.logger.warn(
|
||||
"Warning: version of " + dep.file.name
|
||||
+ ", "
|
||||
+ vfile.version
|
||||
+ " is newer than request "
|
||||
+ dep.file.version);
|
||||
return f.getName();
|
||||
}
|
||||
return f.getName(); // found dependency
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
scanDepInfos();
|
||||
if (depMap.isEmpty()) return;
|
||||
|
||||
loadDeps();
|
||||
activateDeps();
|
||||
}
|
||||
|
||||
private void activateDeps() {
|
||||
for (Dependency dep : depMap.values()) if (dep.coreLib) addClasspath(dep.existing);
|
||||
}
|
||||
|
||||
private void loadDeps() {
|
||||
downloadMonitor = FMLLaunchHandler.side().isClient() ? new Downloader() : new DummyDownloader();
|
||||
try {
|
||||
while (!depSet.isEmpty()) {
|
||||
Iterator<String> it = depSet.iterator();
|
||||
Dependency dep = depMap.get(it.next());
|
||||
it.remove();
|
||||
load(dep);
|
||||
}
|
||||
} finally {
|
||||
if (popupWindow != null) {
|
||||
popupWindow.setVisible(false);
|
||||
popupWindow.dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void load(Dependency dep) {
|
||||
dep.existing = checkExisting(dep);
|
||||
if (dep.existing == null) // download dep
|
||||
{
|
||||
download(dep);
|
||||
dep.existing = dep.file.filename;
|
||||
}
|
||||
}
|
||||
|
||||
private List<File> modFiles() {
|
||||
List<File> list = new LinkedList<File>();
|
||||
list.addAll(Arrays.asList(modsDir.listFiles()));
|
||||
list.addAll(Arrays.asList(v_modsDir.listFiles()));
|
||||
return list;
|
||||
}
|
||||
|
||||
private void scanDepInfos() {
|
||||
for (File file : modFiles()) {
|
||||
if (!file.getName().endsWith(".jar") && !file.getName().endsWith(".zip")) continue;
|
||||
|
||||
scanDepInfo(file);
|
||||
}
|
||||
}
|
||||
|
||||
private void scanDepInfo(File file) {
|
||||
try {
|
||||
ZipFile zip = new ZipFile(file);
|
||||
ZipEntry e = zip.getEntry("dependancies.info");
|
||||
if (e == null) e = zip.getEntry("dependencies.info");
|
||||
if (e != null) loadJSon(zip.getInputStream(e));
|
||||
zip.close();
|
||||
} catch (Exception e) {
|
||||
CodeChickenCorePlugin.logger
|
||||
.error("Failed to load dependencies.info from " + file.getName() + " as JSON");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadJSon(InputStream input) throws IOException {
|
||||
InputStreamReader reader = new InputStreamReader(input);
|
||||
JsonElement root = new JsonParser().parse(reader);
|
||||
if (root.isJsonArray()) loadJSonArr(root);
|
||||
else loadJson(root.getAsJsonObject());
|
||||
reader.close();
|
||||
}
|
||||
|
||||
private void loadJSonArr(JsonElement root) throws IOException {
|
||||
for (JsonElement node : root.getAsJsonArray()) loadJson(node.getAsJsonObject());
|
||||
}
|
||||
|
||||
private void loadJson(JsonObject node) throws IOException {
|
||||
boolean obfuscated = ((LaunchClassLoader) DepLoader.class.getClassLoader())
|
||||
.getClassBytes("net.minecraft.world.World") == null;
|
||||
|
||||
String testClass = node.get("class").getAsString();
|
||||
if (DepLoader.class.getResource("/" + testClass.replace('.', '/') + ".class") != null) return;
|
||||
|
||||
String repo = node.get("repo").getAsString();
|
||||
String filename = node.get("file").getAsString();
|
||||
if (!obfuscated && node.has("dev")) filename = node.get("dev").getAsString();
|
||||
|
||||
boolean coreLib = node.has("coreLib") && node.get("coreLib").getAsBoolean();
|
||||
|
||||
Pattern pattern = null;
|
||||
try {
|
||||
if (node.has("pattern")) pattern = Pattern.compile(node.get("pattern").getAsString());
|
||||
} catch (PatternSyntaxException e) {
|
||||
CodeChickenCorePlugin.logger.error("Invalid filename pattern: " + node.get("pattern"));
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (pattern == null) pattern = Pattern.compile("(\\w+).*?([\\d\\.]+)[-\\w]*\\.[^\\d]+");
|
||||
|
||||
VersionedFile file = new VersionedFile(filename, pattern);
|
||||
if (!file.matches()) throw new RuntimeException("Invalid filename format for dependency: " + filename);
|
||||
|
||||
addDep(new Dependency(repo, file, coreLib));
|
||||
}
|
||||
|
||||
private void addDep(Dependency newDep) {
|
||||
if (mergeNew(depMap.get(newDep.file.name), newDep)) {
|
||||
depMap.put(newDep.file.name, newDep);
|
||||
depSet.add(newDep.file.name);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean mergeNew(Dependency oldDep, Dependency newDep) {
|
||||
if (oldDep == null) return true;
|
||||
|
||||
Dependency newest = newDep.file.version.compareTo(oldDep.file.version) > 0 ? newDep : oldDep;
|
||||
newest.coreLib = newDep.coreLib || oldDep.coreLib;
|
||||
|
||||
return newest == newDep;
|
||||
}
|
||||
public void load() {}
|
||||
}
|
||||
|
||||
public static void load() {
|
||||
if (inst == null) {
|
||||
inst = new DepLoadInst();
|
||||
inst.load();
|
||||
}
|
||||
}
|
||||
public static void load() {}
|
||||
|
||||
@Override
|
||||
public String[] getASMTransformerClass() {
|
||||
|
||||
Reference in new issue
Block a user