diff --git a/build.xml b/build.xml index e08d7f462c..1c6b7dec30 100644 --- a/build.xml +++ b/build.xml @@ -146,15 +146,25 @@ - + + + + + + + + + + + - + - + diff --git a/common/cpw/mods/fml/common/launcher/FMLServerTweaker.java b/common/cpw/mods/fml/common/launcher/FMLServerTweaker.java index 2ba98f0a25..1f38e9204a 100644 --- a/common/cpw/mods/fml/common/launcher/FMLServerTweaker.java +++ b/common/cpw/mods/fml/common/launcher/FMLServerTweaker.java @@ -13,6 +13,10 @@ public class FMLServerTweaker extends FMLTweaker { @Override public void injectIntoClassLoader(LaunchClassLoader classLoader) { + classLoader.addTransformerExclusion("cpw.mods.fml.repackage."); + classLoader.addTransformerExclusion("cpw.mods.fml.relauncher."); + classLoader.addTransformerExclusion("cpw.mods.fml.common.asm.transformers."); + classLoader.addClassLoaderExclusion("LZMA."); FMLLaunchHandler.configureForServerLaunch(classLoader, this); } } diff --git a/common/cpw/mods/fml/relauncher/CoreModManager.java b/common/cpw/mods/fml/relauncher/CoreModManager.java index 3cfb15092f..5f12b88035 100644 --- a/common/cpw/mods/fml/relauncher/CoreModManager.java +++ b/common/cpw/mods/fml/relauncher/CoreModManager.java @@ -93,7 +93,7 @@ public class CoreModManager 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"); + FMLRelaunchLog.fine("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(",")) @@ -133,134 +133,6 @@ public class CoreModManager } discoverCoreMods(mcDir, classLoader, loadPlugins, libraries); - List caughtErrors = new ArrayList(); - try - { - File libDir; - try - { - libDir = setupLibDir(mcDir); - } - catch (Exception e) - { - caughtErrors.add(e); - return; - } - - libraries = new ArrayList(); - for (ILibrarySet lib : libraries) - { - for (int i=0; i=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 - { - classLoader.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) @@ -277,14 +149,14 @@ public class CoreModManager { classLoader.registerTransformer("cpw.mods.fml.common.asm.transformers.DeobfuscationTransformer"); } - downloadMonitor.updateProgressString("Running coremod plugins"); + FMLRelaunchLog.fine("Running coremod plugins"); Map data = new HashMap(); data.put("mcLocation", mcDir); data.put("coremodList", loadPlugins); data.put("runtimeDeobfuscationEnabled", !deobfuscatedEnvironment); for (IFMLLoadingPlugin plugin : loadPlugins) { - downloadMonitor.updateProgressString("Running coremod plugin %s", plugin.getClass().getSimpleName()); + FMLRelaunchLog.fine("Running coremod plugin %s", plugin.getClass().getSimpleName()); data.put("coremodLocation", pluginLocations.get(plugin)); plugin.injectData(data); String setupClass = plugin.getSetupClass(); @@ -306,7 +178,7 @@ public class CoreModManager throw new RuntimeException(e); } } - downloadMonitor.updateProgressString("Coremod plugin %s run successfully", plugin.getClass().getSimpleName()); + FMLRelaunchLog.fine("Coremod plugin %s run successfully", plugin.getClass().getSimpleName()); String modContainer = plugin.getModContainerClass(); if (modContainer != null) @@ -316,14 +188,13 @@ public class CoreModManager } try { - downloadMonitor.updateProgressString("Validating minecraft"); + FMLRelaunchLog.fine("Validating minecraft"); Class loaderClazz = Class.forName("cpw.mods.fml.common.Loader", true, classLoader); 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; + FMLRelaunchLog.fine("Minecraft validated, launching..."); } catch (Exception e) { @@ -335,7 +206,7 @@ public class CoreModManager private static void discoverCoreMods(File mcDir, LaunchClassLoader classLoader, List loadPlugins, List libraries) { - downloadMonitor.updateProgressString("Discovering coremods"); + FMLRelaunchLog.fine("Discovering coremods"); File coreMods = setupCoreModDir(mcDir); FilenameFilter ff = new FilenameFilter() { @@ -350,7 +221,7 @@ public class CoreModManager for (File coreMod : coreModList) { - downloadMonitor.updateProgressString("Found a candidate coremod %s", coreMod.getName()); + FMLRelaunchLog.fine("Found a candidate coremod %s", coreMod.getName()); JarFile jar; Attributes mfAttributes; try @@ -404,7 +275,7 @@ public class CoreModManager } try { - downloadMonitor.updateProgressString("Loading coremod %s", coreMod.getName()); + FMLRelaunchLog.fine("Loading coremod %s", coreMod.getName()); classLoader.addTransformerExclusion(fmlCorePlugin); Class coreModClass = Class.forName(fmlCorePlugin, true, classLoader); MCVersion requiredMCVersion = coreModClass.getAnnotation(IFMLLoadingPlugin.MCVersion.class); @@ -444,7 +315,7 @@ public class CoreModManager libraries.add((ILibrarySet) Class.forName(libName, true, classLoader).newInstance()); } } - downloadMonitor.updateProgressString("Loaded coremod %s", coreMod.getName()); + FMLRelaunchLog.fine("Loaded coremod %s", coreMod.getName()); } catch (ClassNotFoundException cnfe) { @@ -465,32 +336,6 @@ public class CoreModManager } } - /** - * @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 @@ -517,114 +362,8 @@ public class CoreModManager 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 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); - } } diff --git a/common/cpw/mods/fml/relauncher/Downloader.java b/common/cpw/mods/fml/relauncher/Downloader.java deleted file mode 100644 index 4f9d100b1f..0000000000 --- a/common/cpw/mods/fml/relauncher/Downloader.java +++ /dev/null @@ -1,152 +0,0 @@ -/* - * 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.awt.Dialog.ModalityType; -import java.awt.Dimension; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; - -import javax.swing.Box; -import javax.swing.JDialog; -import javax.swing.JFrame; -import javax.swing.JLabel; -import javax.swing.JOptionPane; -import javax.swing.JProgressBar; - -import cpw.mods.fml.common.FMLLog; - -public 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("FML is setting up your minecraft environment"); - box.add(welcomeLabel); - welcomeLabel.setAlignmentY(LEFT_ALIGNMENT); - welcomeLabel = new JLabel("Please wait, FML has some tasks to do before you can play"); - 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; - } - - public JDialog makeDialog() - { - 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(JFrame.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; - } - 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(); - } - } - - public void updateProgressString(String progressUpdate, Object... data) - { - FMLLog.finest(progressUpdate, data); - if (currentActivity!=null) - { - currentActivity.setText(String.format(progressUpdate,data)); - } - } - - public void resetProgress(int sizeGuess) - { - if (progress!=null) - { - progress.getModel().setRangeProperties(0, 0, 0, sizeGuess, false); - } - } - - public void updateProgress(int fullLength) - { - if (progress!=null) - { - progress.getModel().setValue(fullLength); - } - } - - public void makeHeadless() - { - container = null; - progress = null; - currentActivity = null; - } - - @Override - public void setPokeThread(Thread currentThread) - { - this.pokeThread = currentThread; - } - - @Override - public boolean shouldStopIt() - { - return stopIt; - } -} diff --git a/common/cpw/mods/fml/relauncher/DummyDownloader.java b/common/cpw/mods/fml/relauncher/DummyDownloader.java deleted file mode 100644 index dbdc0bffb7..0000000000 --- a/common/cpw/mods/fml/relauncher/DummyDownloader.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * 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.util.logging.Level; - -public class DummyDownloader implements IDownloadDisplay -{ - - @Override - public void resetProgress(int sizeGuess) - { - // TODO Auto-generated method stub - - } - - @Override - public void setPokeThread(Thread currentThread) - { - // TODO Auto-generated method stub - - } - - @Override - public void updateProgress(int fullLength) - { - // TODO Auto-generated method stub - - } - - @Override - public boolean shouldStopIt() - { - // TODO Auto-generated method stub - return false; - } - - @Override - public void updateProgressString(String string, Object... data) - { - FMLRelaunchLog.log(Level.FINE, string, data); - } - - @Override - public Object makeDialog() - { - // TODO Auto-generated method stub - return null; - } - - @Override - public void makeHeadless() - { - // TODO Auto-generated method stub - - } - -} diff --git a/common/cpw/mods/fml/relauncher/FMLLaunchHandler.java b/common/cpw/mods/fml/relauncher/FMLLaunchHandler.java index ef5e089ee2..9aacce89ea 100644 --- a/common/cpw/mods/fml/relauncher/FMLLaunchHandler.java +++ b/common/cpw/mods/fml/relauncher/FMLLaunchHandler.java @@ -12,21 +12,15 @@ package cpw.mods.fml.relauncher; -import java.applet.Applet; import java.io.File; -import java.lang.reflect.Method; -import java.net.URLClassLoader; import java.util.logging.Level; -import javax.swing.JDialog; -import javax.swing.JOptionPane; +import net.minecraft.launchwrapper.LaunchClassLoader; import com.google.common.base.Throwables; import cpw.mods.fml.common.launcher.FMLTweaker; -import net.minecraft.launchwrapper.LaunchClassLoader; - public class FMLLaunchHandler { private static FMLLaunchHandler INSTANCE; @@ -66,15 +60,8 @@ public class FMLLaunchHandler this.classLoader.addTransformerExclusion("cpw.mods.fml.common.patcher."); } - private void showWindow(boolean showIt) - { - if (CoreModManager.downloadMonitor != null) { return; } - CoreModManager.downloadMonitor = new DummyDownloader(); - } - private void setupClient() { - showWindow(true); FMLRelaunchLog.logFileNamePattern = "ForgeModLoader-client-%g.log"; side = Side.CLIENT; setupHome(); @@ -82,7 +69,6 @@ public class FMLLaunchHandler private void setupServer() { - showWindow(false); FMLRelaunchLog.logFileNamePattern = "ForgeModLoader-server-%g.log"; side = Side.SERVER; setupHome(); diff --git a/common/cpw/mods/fml/relauncher/IDownloadDisplay.java b/common/cpw/mods/fml/relauncher/IDownloadDisplay.java deleted file mode 100644 index 9d78987340..0000000000 --- a/common/cpw/mods/fml/relauncher/IDownloadDisplay.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 javax.swing.JDialog; - -public interface IDownloadDisplay -{ - - void resetProgress(int sizeGuess); - - void setPokeThread(Thread currentThread); - - void updateProgress(int fullLength); - - boolean shouldStopIt(); - - void updateProgressString(String string, Object ... data); - - Object makeDialog(); - - void makeHeadless(); - -} diff --git a/common/cpw/mods/fml/relauncher/ServerLaunchWrapper.java b/common/cpw/mods/fml/relauncher/ServerLaunchWrapper.java index 6975689c9e..db6a87b699 100644 --- a/common/cpw/mods/fml/relauncher/ServerLaunchWrapper.java +++ b/common/cpw/mods/fml/relauncher/ServerLaunchWrapper.java @@ -1,12 +1,10 @@ package cpw.mods.fml.relauncher; import java.io.File; +import java.lang.reflect.Method; import java.net.URLClassLoader; import java.util.logging.Level; -import net.minecraft.launchwrapper.Launch; -import net.minecraft.launchwrapper.LaunchClassLoader; - import com.google.common.base.Throwables; public class ServerLaunchWrapper { @@ -26,7 +24,35 @@ public class ServerLaunchWrapper { private void run(String[] args) { - Launch.main(args); + Class launchwrapper = null; + try + { + launchwrapper = Class.forName("net.minecraft.launchwrapper.Launch",true,getClass().getClassLoader()); + Class.forName("org.objectweb.asm.Type",true,getClass().getClassLoader()); + } + catch (Exception e) + { + System.err.printf("We appear to be missing one or more essential library files.\n" + + "You will need to add them to your server before FML and Forge will run successfully."); + e.printStackTrace(System.err); + System.exit(1); + } + + try + { + Method main = launchwrapper.getMethod("main", String[].class); + String[] allArgs = new String[args.length + 2]; + allArgs[0] = "--tweakClass"; + allArgs[1] = "cpw.mods.fml.common.launcher.FMLServerTweaker"; + System.arraycopy(args, 0, allArgs, 2, args.length); + main.invoke(null,(Object)allArgs); + } + catch (Exception e) + { + System.err.printf("A problem occurred running the Server launcher."); + e.printStackTrace(System.err); + System.exit(1); + } } }