mirror of
https://github.com/MinecraftForge/MinecraftForge.git
synced 2026-11-13 16:54:22 +00:00
610 lines
24 KiB
Java
610 lines
24 KiB
Java
/*
|
|
* Forge Mod Loader
|
|
* Copyright (c) 2012-2013 cpw.
|
|
* All rights reserved. This program and the accompanying materials
|
|
* are made available under the terms of the GNU Lesser Public License v2.1
|
|
* which accompanies this distribution, and is available at
|
|
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|
*
|
|
* Contributors:
|
|
* cpw - implementation
|
|
*/
|
|
|
|
package cpw.mods.fml.relauncher;
|
|
|
|
import java.io.File;
|
|
import java.io.FileInputStream;
|
|
import java.io.FileOutputStream;
|
|
import java.io.FilenameFilter;
|
|
import java.io.IOException;
|
|
import java.io.InputStream;
|
|
import java.io.InterruptedIOException;
|
|
import java.lang.reflect.Method;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.net.URLConnection;
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.MappedByteBuffer;
|
|
import java.nio.channels.FileChannel;
|
|
import java.nio.channels.FileChannel.MapMode;
|
|
import java.security.MessageDigest;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
import java.util.jar.Attributes;
|
|
import java.util.jar.JarFile;
|
|
import java.util.logging.Level;
|
|
|
|
import cpw.mods.fml.common.CertificateHelper;
|
|
import cpw.mods.fml.relauncher.IFMLLoadingPlugin.TransformerExclusions;
|
|
|
|
public class RelaunchLibraryManager
|
|
{
|
|
private static String[] rootPlugins = { "cpw.mods.fml.relauncher.FMLCorePlugin" , "net.minecraftforge.classloading.FMLForgePlugin" };
|
|
private static List<String> loadedLibraries = new ArrayList<String>();
|
|
private static Map<IFMLLoadingPlugin, File> pluginLocations;
|
|
private static List<IFMLLoadingPlugin> loadPlugins;
|
|
private static List<ILibrarySet> libraries;
|
|
private static boolean deobfuscatedEnvironment;
|
|
|
|
public static void handleLaunch(File mcDir, RelaunchClassLoader actualClassLoader)
|
|
{
|
|
try
|
|
{
|
|
// Are we in a 'decompiled' environment?
|
|
byte[] bs = actualClassLoader.getClassBytes("net.minecraft.world.World");
|
|
if (bs != null)
|
|
{
|
|
FMLRelaunchLog.info("Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation");
|
|
deobfuscatedEnvironment = true;
|
|
}
|
|
}
|
|
catch (IOException e1)
|
|
{
|
|
}
|
|
|
|
if (!deobfuscatedEnvironment)
|
|
{
|
|
FMLRelaunchLog.fine("Enabling runtime deobfuscation");
|
|
}
|
|
pluginLocations = new HashMap<IFMLLoadingPlugin, File>();
|
|
loadPlugins = new ArrayList<IFMLLoadingPlugin>();
|
|
libraries = new ArrayList<ILibrarySet>();
|
|
for (String s : rootPlugins)
|
|
{
|
|
try
|
|
{
|
|
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) Class.forName(s, true, actualClassLoader).newInstance();
|
|
loadPlugins.add(plugin);
|
|
for (String libName : plugin.getLibraryRequestClass())
|
|
{
|
|
libraries.add((ILibrarySet) Class.forName(libName, true, actualClassLoader).newInstance());
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// HMMM
|
|
}
|
|
}
|
|
|
|
if (loadPlugins.isEmpty())
|
|
{
|
|
throw new RuntimeException("A fatal error has occured - no valid fml load plugin was found - this is a completely corrupt FML installation.");
|
|
}
|
|
|
|
downloadMonitor.updateProgressString("All core mods are successfully located");
|
|
// Now that we have the root plugins loaded - lets see what else might be around
|
|
String commandLineCoremods = System.getProperty("fml.coreMods.load","");
|
|
for (String s : commandLineCoremods.split(","))
|
|
{
|
|
if (s.isEmpty())
|
|
{
|
|
continue;
|
|
}
|
|
FMLRelaunchLog.info("Found a command line coremod : %s", s);
|
|
try
|
|
{
|
|
actualClassLoader.addTransformerExclusion(s);
|
|
Class<?> coreModClass = Class.forName(s, true, actualClassLoader);
|
|
TransformerExclusions trExclusions = coreModClass.getAnnotation(IFMLLoadingPlugin.TransformerExclusions.class);
|
|
if (trExclusions!=null)
|
|
{
|
|
for (String st : trExclusions.value())
|
|
{
|
|
actualClassLoader.addTransformerExclusion(st);
|
|
}
|
|
}
|
|
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) coreModClass.newInstance();
|
|
loadPlugins.add(plugin);
|
|
if (plugin.getLibraryRequestClass()!=null)
|
|
{
|
|
for (String libName : plugin.getLibraryRequestClass())
|
|
{
|
|
libraries.add((ILibrarySet) Class.forName(libName, true, actualClassLoader).newInstance());
|
|
}
|
|
}
|
|
}
|
|
catch (Throwable e)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE,e,"Exception occured trying to load coremod %s",s);
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
discoverCoreMods(mcDir, actualClassLoader, loadPlugins, libraries);
|
|
|
|
List<Throwable> caughtErrors = new ArrayList<Throwable>();
|
|
try
|
|
{
|
|
File libDir;
|
|
try
|
|
{
|
|
libDir = setupLibDir(mcDir);
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
caughtErrors.add(e);
|
|
return;
|
|
}
|
|
|
|
for (ILibrarySet lib : libraries)
|
|
{
|
|
for (int i=0; i<lib.getLibraries().length; i++)
|
|
{
|
|
boolean download = false;
|
|
String libName = lib.getLibraries()[i];
|
|
String targFileName = libName.lastIndexOf('/')>=0 ? libName.substring(libName.lastIndexOf('/')) : libName;
|
|
String checksum = lib.getHashes()[i];
|
|
File libFile = new File(libDir, targFileName);
|
|
if (!libFile.exists())
|
|
{
|
|
try
|
|
{
|
|
downloadFile(libFile, lib.getRootURL(), libName, checksum);
|
|
download = true;
|
|
}
|
|
catch (Throwable e)
|
|
{
|
|
caughtErrors.add(e);
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (libFile.exists() && !libFile.isFile())
|
|
{
|
|
caughtErrors.add(new RuntimeException(String.format("Found a file %s that is not a normal file - you should clear this out of the way", libName)));
|
|
continue;
|
|
}
|
|
|
|
if (!download)
|
|
{
|
|
try
|
|
{
|
|
FileInputStream fis = new FileInputStream(libFile);
|
|
FileChannel chan = fis.getChannel();
|
|
MappedByteBuffer mappedFile = chan.map(MapMode.READ_ONLY, 0, libFile.length());
|
|
String fileChecksum = generateChecksum(mappedFile);
|
|
fis.close();
|
|
// bad checksum and I did not download this file
|
|
if (!checksum.equals(fileChecksum))
|
|
{
|
|
caughtErrors.add(new RuntimeException(String.format("The file %s was found in your lib directory and has an invalid checksum %s (expecting %s) - it is unlikely to be the correct download, please move it out of the way and try again.", libName, fileChecksum, checksum)));
|
|
continue;
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE, e, "The library file %s could not be validated", libFile.getName());
|
|
caughtErrors.add(new RuntimeException(String.format("The library file %s could not be validated", libFile.getName()),e));
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (!download)
|
|
{
|
|
downloadMonitor.updateProgressString("Found library file %s present and correct in lib dir", libName);
|
|
}
|
|
else
|
|
{
|
|
downloadMonitor.updateProgressString("Library file %s was downloaded and verified successfully", libName);
|
|
}
|
|
|
|
try
|
|
{
|
|
actualClassLoader.addURL(libFile.toURI().toURL());
|
|
loadedLibraries.add(libName);
|
|
}
|
|
catch (MalformedURLException e)
|
|
{
|
|
caughtErrors.add(new RuntimeException(String.format("Should never happen - %s is broken - probably a somehow corrupted download. Delete it and try again.", libFile.getName()), e));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
if (downloadMonitor.shouldStopIt())
|
|
{
|
|
return;
|
|
}
|
|
if (!caughtErrors.isEmpty())
|
|
{
|
|
FMLRelaunchLog.severe("There were errors during initial FML setup. " +
|
|
"Some files failed to download or were otherwise corrupted. " +
|
|
"You will need to manually obtain the following files from " +
|
|
"these download links and ensure your lib directory is clean. ");
|
|
for (ILibrarySet set : libraries)
|
|
{
|
|
for (String file : set.getLibraries())
|
|
{
|
|
FMLRelaunchLog.severe("*** Download "+set.getRootURL(), file);
|
|
}
|
|
}
|
|
FMLRelaunchLog.severe("<===========>");
|
|
FMLRelaunchLog.severe("The following is the errors that caused the setup to fail. " +
|
|
"They may help you diagnose and resolve the issue");
|
|
for (Throwable t : caughtErrors)
|
|
{
|
|
if (t.getMessage()!=null)
|
|
{
|
|
FMLRelaunchLog.severe(t.getMessage());
|
|
}
|
|
}
|
|
FMLRelaunchLog.severe("<<< ==== >>>");
|
|
FMLRelaunchLog.severe("The following is diagnostic information for developers to review.");
|
|
for (Throwable t : caughtErrors)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE, t, "Error details");
|
|
}
|
|
throw new RuntimeException("A fatal error occured and FML cannot continue");
|
|
}
|
|
}
|
|
|
|
for (IFMLLoadingPlugin plug : loadPlugins)
|
|
{
|
|
if (plug.getASMTransformerClass()!=null)
|
|
{
|
|
for (String xformClass : plug.getASMTransformerClass())
|
|
{
|
|
actualClassLoader.registerTransformer(xformClass);
|
|
}
|
|
}
|
|
}
|
|
// Deobfuscation transformer, always last
|
|
if (!deobfuscatedEnvironment)
|
|
{
|
|
actualClassLoader.registerTransformer("cpw.mods.fml.common.asm.transformers.DeobfuscationTransformer");
|
|
}
|
|
downloadMonitor.updateProgressString("Running coremod plugins");
|
|
Map<String,Object> data = new HashMap<String,Object>();
|
|
data.put("mcLocation", mcDir);
|
|
data.put("coremodList", loadPlugins);
|
|
for (IFMLLoadingPlugin plugin : loadPlugins)
|
|
{
|
|
downloadMonitor.updateProgressString("Running coremod plugin %s", plugin.getClass().getSimpleName());
|
|
data.put("coremodLocation", pluginLocations.get(plugin));
|
|
plugin.injectData(data);
|
|
String setupClass = plugin.getSetupClass();
|
|
if (setupClass != null)
|
|
{
|
|
try
|
|
{
|
|
IFMLCallHook call = (IFMLCallHook) Class.forName(setupClass, true, actualClassLoader).newInstance();
|
|
Map<String,Object> callData = new HashMap<String, Object>();
|
|
callData.put("mcLocation", mcDir);
|
|
callData.put("classLoader", actualClassLoader);
|
|
callData.put("coremodLocation", pluginLocations.get(plugin));
|
|
callData.put("deobfuscationFileName", FMLInjectionData.debfuscationDataName());
|
|
call.injectData(callData);
|
|
call.call();
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
downloadMonitor.updateProgressString("Coremod plugin %s run successfully", plugin.getClass().getSimpleName());
|
|
|
|
String modContainer = plugin.getModContainerClass();
|
|
if (modContainer != null)
|
|
{
|
|
FMLInjectionData.containers.add(modContainer);
|
|
}
|
|
}
|
|
try
|
|
{
|
|
downloadMonitor.updateProgressString("Validating minecraft");
|
|
Class<?> loaderClazz = Class.forName("cpw.mods.fml.common.Loader", true, actualClassLoader);
|
|
Method m = loaderClazz.getMethod("injectData", Object[].class);
|
|
m.invoke(null, (Object)FMLInjectionData.data());
|
|
m = loaderClazz.getMethod("instance");
|
|
m.invoke(null);
|
|
downloadMonitor.updateProgressString("Minecraft validated, launching...");
|
|
downloadBuffer = null;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
// Load in the Loader, make sure he's ready to roll - this will initialize most of the rest of minecraft here
|
|
System.out.println("A CRITICAL PROBLEM OCCURED INITIALIZING MINECRAFT - LIKELY YOU HAVE AN INCORRECT VERSION FOR THIS FML");
|
|
throw new RuntimeException(e);
|
|
}
|
|
}
|
|
|
|
private static void discoverCoreMods(File mcDir, RelaunchClassLoader classLoader, List<IFMLLoadingPlugin> loadPlugins, List<ILibrarySet> libraries)
|
|
{
|
|
downloadMonitor.updateProgressString("Discovering coremods");
|
|
File coreMods = setupCoreModDir(mcDir);
|
|
FilenameFilter ff = new FilenameFilter()
|
|
{
|
|
@Override
|
|
public boolean accept(File dir, String name)
|
|
{
|
|
return name.endsWith(".jar");
|
|
}
|
|
};
|
|
File[] coreModList = coreMods.listFiles(ff);
|
|
Arrays.sort(coreModList);
|
|
|
|
for (File coreMod : coreModList)
|
|
{
|
|
downloadMonitor.updateProgressString("Found a candidate coremod %s", coreMod.getName());
|
|
JarFile jar;
|
|
Attributes mfAttributes;
|
|
try
|
|
{
|
|
jar = new JarFile(coreMod);
|
|
if (jar.getManifest() == null)
|
|
{
|
|
FMLRelaunchLog.warning("Found an un-manifested jar file in the coremods folder : %s, it will be ignored.", coreMod.getName());
|
|
continue;
|
|
}
|
|
mfAttributes = jar.getManifest().getMainAttributes();
|
|
}
|
|
catch (IOException ioe)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE, ioe, "Unable to read the coremod jar file %s - ignoring", coreMod.getName());
|
|
continue;
|
|
}
|
|
|
|
String fmlCorePlugin = mfAttributes.getValue("FMLCorePlugin");
|
|
if (fmlCorePlugin == null)
|
|
{
|
|
FMLRelaunchLog.severe("The coremod %s does not contain a valid jar manifest- it will be ignored", coreMod.getName());
|
|
continue;
|
|
}
|
|
|
|
// String className = fmlCorePlugin.replace('.', '/').concat(".class");
|
|
// JarEntry ent = jar.getJarEntry(className);
|
|
// if (ent ==null)
|
|
// {
|
|
// FMLLog.severe("The coremod %s specified %s as it's loading class but it does not include it - it will be ignored", coreMod.getName(), fmlCorePlugin);
|
|
// continue;
|
|
// }
|
|
// try
|
|
// {
|
|
// Class<?> coreModClass = Class.forName(fmlCorePlugin, false, classLoader);
|
|
// FMLLog.severe("The coremods %s specified a class %s that is already present in the classpath - it will be ignored", coreMod.getName(), fmlCorePlugin);
|
|
// continue;
|
|
// }
|
|
// catch (ClassNotFoundException cnfe)
|
|
// {
|
|
// // didn't find it, good
|
|
// }
|
|
try
|
|
{
|
|
classLoader.addURL(coreMod.toURI().toURL());
|
|
}
|
|
catch (MalformedURLException e)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE, e, "Unable to convert file into a URL. weird");
|
|
continue;
|
|
}
|
|
try
|
|
{
|
|
downloadMonitor.updateProgressString("Loading coremod %s", coreMod.getName());
|
|
classLoader.addTransformerExclusion(fmlCorePlugin);
|
|
Class<?> coreModClass = Class.forName(fmlCorePlugin, true, classLoader);
|
|
TransformerExclusions trExclusions = coreModClass.getAnnotation(IFMLLoadingPlugin.TransformerExclusions.class);
|
|
if (trExclusions!=null)
|
|
{
|
|
for (String st : trExclusions.value())
|
|
{
|
|
classLoader.addTransformerExclusion(st);
|
|
}
|
|
}
|
|
IFMLLoadingPlugin plugin = (IFMLLoadingPlugin) coreModClass.newInstance();
|
|
loadPlugins.add(plugin);
|
|
pluginLocations .put(plugin, coreMod);
|
|
if (plugin.getLibraryRequestClass()!=null)
|
|
{
|
|
for (String libName : plugin.getLibraryRequestClass())
|
|
{
|
|
libraries.add((ILibrarySet) Class.forName(libName, true, classLoader).newInstance());
|
|
}
|
|
}
|
|
downloadMonitor.updateProgressString("Loaded coremod %s", coreMod.getName());
|
|
}
|
|
catch (ClassNotFoundException cnfe)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE, cnfe, "Coremod %s: Unable to class load the plugin %s", coreMod.getName(), fmlCorePlugin);
|
|
}
|
|
catch (ClassCastException cce)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE, cce, "Coremod %s: The plugin %s is not an implementor of IFMLLoadingPlugin", coreMod.getName(), fmlCorePlugin);
|
|
}
|
|
catch (InstantiationException ie)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE, ie, "Coremod %s: The plugin class %s was not instantiable", coreMod.getName(), fmlCorePlugin);
|
|
}
|
|
catch (IllegalAccessException iae)
|
|
{
|
|
FMLRelaunchLog.log(Level.SEVERE, iae, "Coremod %s: The plugin class %s was not accessible", coreMod.getName(), fmlCorePlugin);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param mcDir the minecraft home directory
|
|
* @return the lib directory
|
|
*/
|
|
private static File setupLibDir(File mcDir)
|
|
{
|
|
File libDir = new File(mcDir,"lib");
|
|
try
|
|
{
|
|
libDir = libDir.getCanonicalFile();
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new RuntimeException(String.format("Unable to canonicalize the lib dir at %s", mcDir.getName()),e);
|
|
}
|
|
if (!libDir.exists())
|
|
{
|
|
libDir.mkdir();
|
|
}
|
|
else if (libDir.exists() && !libDir.isDirectory())
|
|
{
|
|
throw new RuntimeException(String.format("Found a lib file in %s that's not a directory", mcDir.getName()));
|
|
}
|
|
return libDir;
|
|
}
|
|
|
|
/**
|
|
* @param mcDir the minecraft home directory
|
|
* @return the coremod directory
|
|
*/
|
|
private static File setupCoreModDir(File mcDir)
|
|
{
|
|
File coreModDir = new File(mcDir,"coremods");
|
|
try
|
|
{
|
|
coreModDir = coreModDir.getCanonicalFile();
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new RuntimeException(String.format("Unable to canonicalize the coremod dir at %s", mcDir.getName()),e);
|
|
}
|
|
if (!coreModDir.exists())
|
|
{
|
|
coreModDir.mkdir();
|
|
}
|
|
else if (coreModDir.exists() && !coreModDir.isDirectory())
|
|
{
|
|
throw new RuntimeException(String.format("Found a coremod file in %s that's not a directory", mcDir.getName()));
|
|
}
|
|
return coreModDir;
|
|
}
|
|
|
|
private static void downloadFile(File libFile, String rootUrl,String realFilePath, String hash)
|
|
{
|
|
try
|
|
{
|
|
URL libDownload = new URL(String.format(rootUrl,realFilePath));
|
|
downloadMonitor.updateProgressString("Downloading file %s", libDownload.toString());
|
|
FMLRelaunchLog.info("Downloading file %s", libDownload.toString());
|
|
URLConnection connection = libDownload.openConnection();
|
|
connection.setConnectTimeout(5000);
|
|
connection.setReadTimeout(5000);
|
|
connection.setRequestProperty("User-Agent", "FML Relaunch Downloader");
|
|
int sizeGuess = connection.getContentLength();
|
|
performDownload(connection.getInputStream(), sizeGuess, hash, libFile);
|
|
downloadMonitor.updateProgressString("Download complete");
|
|
FMLRelaunchLog.info("Download complete");
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
if (downloadMonitor.shouldStopIt())
|
|
{
|
|
FMLRelaunchLog.warning("You have stopped the downloading operation before it could complete");
|
|
return;
|
|
}
|
|
if (e instanceof RuntimeException) throw (RuntimeException)e;
|
|
FMLRelaunchLog.severe("There was a problem downloading the file %s automatically. Perhaps you " +
|
|
"have an environment without internet access. You will need to download " +
|
|
"the file manually or restart and let it try again\n", libFile.getName());
|
|
libFile.delete();
|
|
throw new RuntimeException("A download error occured", e);
|
|
}
|
|
}
|
|
|
|
public static List<String> getLibraries()
|
|
{
|
|
return loadedLibraries;
|
|
}
|
|
|
|
private static ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(1 << 23);
|
|
static IDownloadDisplay downloadMonitor;
|
|
|
|
private static void performDownload(InputStream is, int sizeGuess, String validationHash, File target)
|
|
{
|
|
if (sizeGuess > downloadBuffer.capacity())
|
|
{
|
|
throw new RuntimeException(String.format("The file %s is too large to be downloaded by FML - the coremod 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();
|
|
return;
|
|
}
|
|
catch (IOException e)
|
|
{
|
|
throw new RuntimeException(e);
|
|
}
|
|
|
|
|
|
try
|
|
{
|
|
String cksum = generateChecksum(downloadBuffer);
|
|
if (cksum.equals(validationHash))
|
|
{
|
|
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)
|
|
{
|
|
if (e instanceof RuntimeException) throw (RuntimeException)e;
|
|
throw new RuntimeException(e);
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
private static String generateChecksum(ByteBuffer buffer)
|
|
{
|
|
return CertificateHelper.getFingerprint(buffer);
|
|
}
|
|
}
|