Commit 5403adcb8967388e8e6704ec11d8c8f75fe0c12c

Authored by Mumfrey
1 parent 6e6559c6

LiteLoader for 1.4.7

+ Merged fixes for examining class path under FML 1.4.6 and later
 + Added additional post-render callbacks, useful for mods that want to render arbitrary things in the world transform
 + Added branding support, so that the particular mod pack distribution or repackage will be reported in crash reports
 + Added options file for choosing WHERE to look for mods
 + Added fix (?) for infinite recursion under Mac OS when using Magic Launcher
 + Added redirect to stdout via config file or JVM flag
 + 20% more awesome
java/com/mumfrey/liteloader/PostRenderListener.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader;
  2 +
  3 +/**
  4 + * Render callback that gets called AFTER entities are rendered
  5 + *
  6 + * @author Adam Mummery-Smith
  7 + */
  8 +public interface PostRenderListener extends LiteMod
  9 +{
  10 + /**
  11 + * Called after entities are rendered but before particles
  12 + *
  13 + * @param partialTicks
  14 + */
  15 + public abstract void onPostRenderEntities(float partialTicks);
  16 +
  17 + /**
  18 + * Called after all world rendering is completed
  19 + *
  20 + * @param partialTicks
  21 + */
  22 + public abstract void onPostRender(float partialTicks);
  23 +}
java/com/mumfrey/liteloader/core/CallableLiteLoaderBrand.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.core;
  2 +
  3 +import java.util.concurrent.Callable;
  4 +
  5 +import net.minecraft.src.CrashReport;
  6 +
  7 +public class CallableLiteLoaderBrand implements Callable<String>
  8 +{
  9 + final CrashReport crashReport;
  10 +
  11 + public CallableLiteLoaderBrand(CrashReport report)
  12 + {
  13 + this.crashReport = report;
  14 + }
  15 +
  16 + /* (non-Javadoc)
  17 + * @see java.util.concurrent.Callable#call()
  18 + */
  19 + @Override
  20 + public String call() throws Exception
  21 + {
  22 + String brand = LiteLoader.getInstance().getBranding();
  23 + return brand == null ? "Unknown / None" : brand;
  24 + }
  25 +}
java/com/mumfrey/liteloader/core/HookProfiler.java
@@ -135,16 +135,21 @@ public class HookProfiler extends Profiler @@ -135,16 +135,21 @@ public class HookProfiler extends Profiler
135 loader.onInit(); 135 loader.onInit();
136 } 136 }
137 137
138 - if ("gameRenderer".equalsIgnoreCase(sectionName) && "root".equalsIgnoreCase(sectionStack.getLast())) 138 + if ("gameRenderer".equals(sectionName) && "root".equals(sectionStack.getLast()))
139 { 139 {
140 loader.onRender(); 140 loader.onRender();
141 } 141 }
142 142
143 - if ("frustrum".equalsIgnoreCase(sectionName) && "level".equalsIgnoreCase(sectionStack.getLast())) 143 + if ("frustrum".equals(sectionName) && "level".equals(sectionStack.getLast()))
144 { 144 {
145 loader.onSetupCameraTransform(); 145 loader.onSetupCameraTransform();
146 } 146 }
147 147
  148 + if ("litParticles".equals(sectionName))
  149 + {
  150 + loader.postRenderEntities();
  151 + }
  152 +
148 if ("animateTick".equals(sectionName)) tick = true; 153 if ("animateTick".equals(sectionName)) tick = true;
149 sectionStack.add(sectionName); 154 sectionStack.add(sectionName);
150 super.startSection(sectionName); 155 super.startSection(sectionName);
@@ -190,5 +195,9 @@ public class HookProfiler extends Profiler @@ -190,5 +195,9 @@ public class HookProfiler extends Profiler
190 { 195 {
191 loader.onBeforeGuiRender(); 196 loader.onBeforeGuiRender();
192 } 197 }
  198 + else if ("hand".equals(endingSection) && "level".equals(sectionStack.getLast()))
  199 + {
  200 + loader.postRender();
  201 + }
193 } 202 }
194 } 203 }
java/com/mumfrey/liteloader/core/LiteLoader.java
1 package com.mumfrey.liteloader.core; 1 package com.mumfrey.liteloader.core;
2 2
3 -import java.io.*; 3 +import java.io.BufferedReader;
  4 +import java.io.ByteArrayOutputStream;
  5 +import java.io.File;
  6 +import java.io.FileInputStream;
  7 +import java.io.FileNotFoundException;
  8 +import java.io.FileWriter;
  9 +import java.io.FilenameFilter;
  10 +import java.io.IOException;
  11 +import java.io.InputStream;
  12 +import java.io.InputStreamReader;
  13 +import java.io.PrintStream;
4 import java.lang.reflect.Constructor; 14 import java.lang.reflect.Constructor;
5 import java.lang.reflect.Method; 15 import java.lang.reflect.Method;
6 import java.net.URL; 16 import java.net.URL;
7 import java.net.URLClassLoader; 17 import java.net.URLClassLoader;
8 import java.net.URLDecoder; 18 import java.net.URLDecoder;
9 -import java.nio.CharBuffer;  
10 import java.nio.charset.Charset; 19 import java.nio.charset.Charset;
11 -import java.util.*;  
12 -import java.util.concurrent.Callable;  
13 -import java.util.logging.*; 20 +import java.util.Arrays;
  21 +import java.util.HashMap;
  22 +import java.util.Iterator;
  23 +import java.util.LinkedList;
  24 +import java.util.List;
  25 +import java.util.Properties;
  26 +import java.util.logging.FileHandler;
14 import java.util.logging.Formatter; 27 import java.util.logging.Formatter;
  28 +import java.util.logging.Level;
  29 +import java.util.logging.Logger;
  30 +import java.util.logging.StreamHandler;
15 import java.util.zip.ZipEntry; 31 import java.util.zip.ZipEntry;
16 import java.util.zip.ZipFile; 32 import java.util.zip.ZipFile;
17 import java.util.zip.ZipInputStream; 33 import java.util.zip.ZipInputStream;
18 34
19 -import com.mumfrey.liteloader.*;  
20 -import com.mumfrey.liteloader.util.ModUtilities;  
21 -import com.mumfrey.liteloader.util.PrivateFields;  
22 -  
23 import net.minecraft.client.Minecraft; 35 import net.minecraft.client.Minecraft;
24 -import net.minecraft.src.*; 36 +import net.minecraft.src.ConsoleLogManager;
  37 +import net.minecraft.src.NetHandler;
  38 +import net.minecraft.src.Packet1Login;
  39 +import net.minecraft.src.Packet3Chat;
  40 +import net.minecraft.src.Profiler;
25 import net.minecraft.src.Timer; 41 import net.minecraft.src.Timer;
26 42
  43 +import com.mumfrey.liteloader.ChatFilter;
  44 +import com.mumfrey.liteloader.ChatListener;
  45 +import com.mumfrey.liteloader.InitCompleteListener;
  46 +import com.mumfrey.liteloader.LiteMod;
  47 +import com.mumfrey.liteloader.LoginListener;
  48 +import com.mumfrey.liteloader.PluginChannelListener;
  49 +import com.mumfrey.liteloader.PostRenderListener;
  50 +import com.mumfrey.liteloader.PreLoginListener;
  51 +import com.mumfrey.liteloader.RenderListener;
  52 +import com.mumfrey.liteloader.Tickable;
  53 +import com.mumfrey.liteloader.util.ModUtilities;
  54 +import com.mumfrey.liteloader.util.PrivateFields;
  55 +
27 /** 56 /**
28 * LiteLoader is a simple loader which provides tick events to loaded mods 57 * LiteLoader is a simple loader which provides tick events to loaded mods
29 * 58 *
30 * @author Adam Mummery-Smith 59 * @author Adam Mummery-Smith
31 - * @version 1.4.6 60 + * @version 1.4.7
32 */ 61 */
33 @SuppressWarnings("rawtypes") 62 @SuppressWarnings("rawtypes")
34 public final class LiteLoader implements FilenameFilter 63 public final class LiteLoader implements FilenameFilter
@@ -36,19 +65,24 @@ public final class LiteLoader implements FilenameFilter @@ -36,19 +65,24 @@ public final class LiteLoader implements FilenameFilter
36 /** 65 /**
37 * Liteloader version 66 * Liteloader version
38 */ 67 */
39 - private static final String LOADER_VERSION = "1.4.6"; 68 + private static final String LOADER_VERSION = "1.4.7";
40 69
41 /** 70 /**
42 * Loader revision, can be used by mods to determine whether the loader is sufficiently up-to-date 71 * Loader revision, can be used by mods to determine whether the loader is sufficiently up-to-date
43 */ 72 */
44 - private static final int LOADER_REVISION = 6; 73 + private static final int LOADER_REVISION = 7;
45 74
46 /** 75 /**
47 * Minecraft versions that we will load mods for, this will be compared 76 * Minecraft versions that we will load mods for, this will be compared
48 * against the version.txt value in mod files to prevent outdated mods being 77 * against the version.txt value in mod files to prevent outdated mods being
49 * loaded!!! 78 * loaded!!!
50 */ 79 */
51 - private static final String[] SUPPORTED_VERSIONS = { "1.4.6" }; 80 + private static final String[] SUPPORTED_VERSIONS = { "1.4.6", "1.4.7" };
  81 +
  82 + /**
  83 + * Maximum recursion depth for mod discovery
  84 + */
  85 + private static final int MAX_DISCOVERY_DEPTH = 16;
52 86
53 /** 87 /**
54 * LiteLoader is a singleton, this is the singleton instance 88 * LiteLoader is a singleton, this is the singleton instance
@@ -61,6 +95,11 @@ public final class LiteLoader implements FilenameFilter @@ -61,6 +95,11 @@ public final class LiteLoader implements FilenameFilter
61 public static Logger logger = Logger.getLogger("liteloader"); 95 public static Logger logger = Logger.getLogger("liteloader");
62 96
63 /** 97 /**
  98 + * Use stdout rather than stderr
  99 + */
  100 + private static boolean useStdOut = false;
  101 +
  102 + /**
64 * "mods" folder which contains mods and config files 103 * "mods" folder which contains mods and config files
65 */ 104 */
66 private File modsFolder; 105 private File modsFolder;
@@ -71,6 +110,26 @@ public final class LiteLoader implements FilenameFilter @@ -71,6 +110,26 @@ public final class LiteLoader implements FilenameFilter
71 private Minecraft minecraft = Minecraft.getMinecraft(); 110 private Minecraft minecraft = Minecraft.getMinecraft();
72 111
73 /** 112 /**
  113 + * File containing the properties
  114 + */
  115 + private File propertiesFile = new File(Minecraft.getMinecraftDir(), "liteloader.properties");
  116 +
  117 + /**
  118 + * Internal properties loaded from inside the jar
  119 + */
  120 + private Properties internalProperties = new Properties();
  121 +
  122 + /**
  123 + * LiteLoader properties
  124 + */
  125 + private Properties localProperties = new Properties();
  126 +
  127 + /**
  128 + * Pack brand from properties, used to put the modpack/compilation name in crash reports
  129 + */
  130 + private String branding = null;
  131 +
  132 + /**
74 * Reference to the minecraft timer 133 * Reference to the minecraft timer
75 */ 134 */
76 private Timer minecraftTimer; 135 private Timer minecraftTimer;
@@ -103,6 +162,11 @@ public final class LiteLoader implements FilenameFilter @@ -103,6 +162,11 @@ public final class LiteLoader implements FilenameFilter
103 private LinkedList<RenderListener> renderListeners = new LinkedList<RenderListener>(); 162 private LinkedList<RenderListener> renderListeners = new LinkedList<RenderListener>();
104 163
105 /** 164 /**
  165 + * List of mods which implement the PostRenderListener interface and want to render entities
  166 + */
  167 + private LinkedList<PostRenderListener> postRenderListeners = new LinkedList<PostRenderListener>();
  168 +
  169 + /**
106 * List of mods which implement ChatListener interface and will receive chat 170 * List of mods which implement ChatListener interface and will receive chat
107 * events 171 * events
108 */ 172 */
@@ -144,6 +208,9 @@ public final class LiteLoader implements FilenameFilter @@ -144,6 +208,9 @@ public final class LiteLoader implements FilenameFilter
144 */ 208 */
145 private boolean loaderStartupDone, loaderStartupComplete, lateInitDone; 209 private boolean loaderStartupDone, loaderStartupComplete, lateInitDone;
146 210
  211 + /**
  212 + * Flags which keep track of whether hooks have been applied
  213 + */
147 private boolean chatHooked, loginHooked, pluginChannelHooked, tickHooked; 214 private boolean chatHooked, loginHooked, pluginChannelHooked, tickHooked;
148 215
149 /** 216 /**
@@ -174,6 +241,11 @@ public final class LiteLoader implements FilenameFilter @@ -174,6 +241,11 @@ public final class LiteLoader implements FilenameFilter
174 return logger; 241 return logger;
175 } 242 }
176 243
  244 + public static final PrintStream getConsoleStream()
  245 + {
  246 + return useStdOut ? System.out : System.err;
  247 + }
  248 +
177 /** 249 /**
178 * Get LiteLoader version 250 * Get LiteLoader version
179 * 251 *
@@ -203,28 +275,54 @@ public final class LiteLoader implements FilenameFilter @@ -203,28 +275,54 @@ public final class LiteLoader implements FilenameFilter
203 275
204 private void initLoader() 276 private void initLoader()
205 { 277 {
206 - if (loaderStartupDone) return;  
207 - loaderStartupDone = true; 278 + if (this.loaderStartupDone) return;
  279 + this.loaderStartupDone = true;
208 280
209 // Set up base class overrides 281 // Set up base class overrides
210 - prepareClassOverrides(); 282 + this.prepareClassOverrides();
211 283
212 // Set up loader, initialises any reflection methods needed 284 // Set up loader, initialises any reflection methods needed
213 - if (prepareLoader()) 285 + if (this.prepareLoader())
214 { 286 {
215 - logger.info("LiteLoader " + LOADER_VERSION + " starting up..."); 287 + logger.info(String.format("LiteLoader %s starting up...", LOADER_VERSION));
  288 +
  289 + // Print the branding version if any was provided
  290 + if (this.branding != null)
  291 + {
  292 + logger.info(String.format("Active Pack: %s", this.branding));
  293 + }
  294 +
216 logger.info(String.format("Java reports OS=\"%s\"", System.getProperty("os.name").toLowerCase())); 295 logger.info(String.format("Java reports OS=\"%s\"", System.getProperty("os.name").toLowerCase()));
  296 +
  297 + boolean searchMods = this.localProperties.getProperty("search.mods", "true").equalsIgnoreCase("true");
  298 + boolean searchProtectionDomain = this.localProperties.getProperty("search.jar", "true").equalsIgnoreCase("true");
  299 + boolean searchClassPath = this.localProperties.getProperty("search.classpath", "true").equalsIgnoreCase("true");
  300 +
  301 + if (!searchMods && !searchProtectionDomain && !searchClassPath)
  302 + {
  303 + logger.warning("Invalid configuration, no search locations defined. Enabling all search locations.");
  304 +
  305 + this.localProperties.setProperty("search.mods", "true");
  306 + this.localProperties.setProperty("search.jar", "true");
  307 + this.localProperties.setProperty("search.classpath", "true");
  308 +
  309 + searchMods = true;
  310 + searchProtectionDomain = true;
  311 + searchClassPath = true;
  312 + }
217 313
218 // Examines the class path and mods folder and locates loadable mods 314 // Examines the class path and mods folder and locates loadable mods
219 - prepareMods(); 315 + this.prepareMods(searchMods, searchProtectionDomain, searchClassPath);
220 316
221 // Initialises enumerated mods 317 // Initialises enumerated mods
222 - initMods(); 318 + this.initMods();
223 319
224 // Initialises the required hooks for loaded mods 320 // Initialises the required hooks for loaded mods
225 - initHooks(); 321 + this.initHooks();
226 322
227 - loaderStartupComplete = true; 323 + this.loaderStartupComplete = true;
  324 +
  325 + this.writeProperties();
228 } 326 }
229 } 327 }
230 328
@@ -233,7 +331,7 @@ public final class LiteLoader implements FilenameFilter @@ -233,7 +331,7 @@ public final class LiteLoader implements FilenameFilter
233 */ 331 */
234 private void prepareClassOverrides() 332 private void prepareClassOverrides()
235 { 333 {
236 - registerBaseClassOverride(ModUtilities.getObfuscatedFieldName("net.minecraft.src.CallableJVMFlags", "g"), "g"); 334 + this.registerBaseClassOverride(ModUtilities.getObfuscatedFieldName("net.minecraft.src.CallableJVMFlags", "g"), "g");
237 } 335 }
238 336
239 /** 337 /**
@@ -282,39 +380,29 @@ public final class LiteLoader implements FilenameFilter @@ -282,39 +380,29 @@ public final class LiteLoader implements FilenameFilter
282 /** 380 /**
283 * Set up reflection methods required by the loader 381 * Set up reflection methods required by the loader
284 */ 382 */
285 - @SuppressWarnings("unchecked")  
286 private boolean prepareLoader() 383 private boolean prepareLoader()
287 { 384 {
288 try 385 try
289 { 386 {
290 // addURL method is used by the class loader to 387 // addURL method is used by the class loader to
291 - mAddUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);  
292 - mAddUrl.setAccessible(true); 388 + this.mAddUrl = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
  389 + this.mAddUrl.setAccessible(true);
293 390
294 - Formatter minecraftLogFormatter = null; 391 + // Prepare the properties
  392 + this.prepareProperties();
295 393
296 - try  
297 - {  
298 - Class<? extends Formatter> formatterClass = (Class<? extends Formatter>)Minecraft.class.getClassLoader().loadClass(ModUtilities.getObfuscatedFieldName("net.minecraft.src.ConsoleLogFormatter", "em"));  
299 - Constructor<? extends Formatter> defaultConstructor = formatterClass.getDeclaredConstructor();  
300 - defaultConstructor.setAccessible(true);  
301 - minecraftLogFormatter = defaultConstructor.newInstance();  
302 - }  
303 - catch (Exception ex)  
304 - {  
305 - ConsoleLogManager.init();  
306 - minecraftLogFormatter = ConsoleLogManager.loggerLogManager.getHandlers()[0].getFormatter();  
307 - } 394 + // Prepare the log writer
  395 + this.prepareLogger();
308 396
309 - logger.setUseParentHandlers(false); 397 + this.branding = this.internalProperties.getProperty("brand", null);
  398 + if (this.branding != null && this.branding.length() < 1) this.branding = null;
310 399
311 - StreamHandler consoleHandler = new ConsoleHandler();  
312 - if (minecraftLogFormatter != null) consoleHandler.setFormatter(minecraftLogFormatter);  
313 - logger.addHandler(consoleHandler); 400 + // Save appropriate branding in the local properties file
  401 + if (this.branding != null)
  402 + this.localProperties.setProperty("brand", this.branding);
  403 + else
  404 + this.localProperties.remove("brand");
314 405
315 - FileHandler logFileHandler = new FileHandler(new File(Minecraft.getMinecraftDir(), "LiteLoader.txt").getAbsolutePath());  
316 - if (minecraftLogFormatter != null) logFileHandler.setFormatter(minecraftLogFormatter);  
317 - logger.addHandler(logFileHandler);  
318 } 406 }
319 catch (Throwable th) 407 catch (Throwable th)
320 { 408 {
@@ -324,28 +412,131 @@ public final class LiteLoader implements FilenameFilter @@ -324,28 +412,131 @@ public final class LiteLoader implements FilenameFilter
324 412
325 return true; 413 return true;
326 } 414 }
  415 +
  416 + /**
  417 + * @throws SecurityException
  418 + * @throws IOException
  419 + */
  420 + @SuppressWarnings("unchecked")
  421 + private void prepareLogger() throws SecurityException, IOException
  422 + {
  423 + Formatter minecraftLogFormatter = null;
  424 +
  425 + try
  426 + {
  427 + Class<? extends Formatter> formatterClass = (Class<? extends Formatter>)Minecraft.class.getClassLoader().loadClass(ModUtilities.getObfuscatedFieldName("net.minecraft.src.ConsoleLogFormatter", "em"));
  428 + Constructor<? extends Formatter> defaultConstructor = formatterClass.getDeclaredConstructor();
  429 + defaultConstructor.setAccessible(true);
  430 + minecraftLogFormatter = defaultConstructor.newInstance();
  431 + }
  432 + catch (Exception ex)
  433 + {
  434 + ConsoleLogManager.init();
  435 + minecraftLogFormatter = ConsoleLogManager.loggerLogManager.getHandlers()[0].getFormatter();
  436 + }
  437 +
  438 + logger.setUseParentHandlers(false);
  439 +
  440 + this.useStdOut = System.getProperty("liteloader.log", "stderr").equalsIgnoreCase("stdout") || this.localProperties.getProperty("log", "stderr").equalsIgnoreCase("stdout");
  441 +
  442 + StreamHandler consoleHandler = useStdOut ? new com.mumfrey.liteloader.util.log.ConsoleHandler() : new java.util.logging.ConsoleHandler();
  443 + if (minecraftLogFormatter != null) consoleHandler.setFormatter(minecraftLogFormatter);
  444 + logger.addHandler(consoleHandler);
  445 +
  446 + FileHandler logFileHandler = new FileHandler(new File(Minecraft.getMinecraftDir(), "LiteLoader.txt").getAbsolutePath());
  447 + if (minecraftLogFormatter != null) logFileHandler.setFormatter(minecraftLogFormatter);
  448 + logger.addHandler(logFileHandler);
  449 + }
  450 +
  451 + /**
  452 + * Prepare the loader properties
  453 + */
  454 + private void prepareProperties()
  455 + {
  456 + try
  457 + {
  458 + InputStream propertiesStream = LiteLoader.class.getResourceAsStream("/liteloader.properties");
  459 +
  460 + if (propertiesStream != null)
  461 + {
  462 + this.internalProperties.load(propertiesStream);
  463 + propertiesStream.close();
  464 + }
  465 + }
  466 + catch (Throwable th)
  467 + {
  468 + this.internalProperties = new Properties();
  469 + }
  470 +
  471 + try
  472 + {
  473 + InputStream localPropertiesStream = this.getLocalPropertiesStream();
  474 +
  475 + if (localPropertiesStream != null)
  476 + {
  477 + this.localProperties.load(localPropertiesStream);
  478 + localPropertiesStream.close();
  479 + }
  480 + }
  481 + catch (Throwable th)
  482 + {
  483 + this.localProperties = new Properties();
  484 + }
  485 + }
  486 +
  487 + /**
  488 + * Get the properties stream either from the jar or from the properties file in the minecraft folder
  489 + *
  490 + * @return
  491 + * @throws FileNotFoundException
  492 + */
  493 + private InputStream getLocalPropertiesStream() throws FileNotFoundException
  494 + {
  495 + if (this.propertiesFile.exists())
  496 + {
  497 + return new FileInputStream(this.propertiesFile);
  498 + }
  499 +
  500 + // Otherwise read settings from the config
  501 + return LiteLoader.class.getResourceAsStream("/liteloader.properties");
  502 + }
327 503
328 /** 504 /**
  505 + * Write current properties to the properties file
  506 + */
  507 + private void writeProperties()
  508 + {
  509 + try
  510 + {
  511 + this.localProperties.store(new FileWriter(this.propertiesFile), String.format("Properties for LiteLoader %s", LOADER_VERSION));
  512 + }
  513 + catch (Throwable th)
  514 + {
  515 + logger.log(Level.WARNING, "Error writing liteloader properties", th);
  516 + }
  517 + }
  518 +
  519 + /**
329 * Get the "mods" folder 520 * Get the "mods" folder
330 */ 521 */
331 public File getModsFolder() 522 public File getModsFolder()
332 { 523 {
333 - if (modsFolder == null) 524 + if (this.modsFolder == null)
334 { 525 {
335 - modsFolder = new File(Minecraft.getMinecraftDir(), "mods"); 526 + this.modsFolder = new File(Minecraft.getMinecraftDir(), "mods");
336 527
337 - if (!modsFolder.exists() || !modsFolder.isDirectory()) 528 + if (!this.modsFolder.exists() || !this.modsFolder.isDirectory())
338 { 529 {
339 try 530 try
340 { 531 {
341 // Attempt to create the "mods" folder if it does not already exist 532 // Attempt to create the "mods" folder if it does not already exist
342 - modsFolder.mkdirs(); 533 + this.modsFolder.mkdirs();
343 } 534 }
344 catch (Exception ex) {} 535 catch (Exception ex) {}
345 } 536 }
346 } 537 }
347 538
348 - return modsFolder; 539 + return this.modsFolder;
349 } 540 }
350 541
351 /** 542 /**
@@ -355,24 +546,37 @@ public final class LiteLoader implements FilenameFilter @@ -355,24 +546,37 @@ public final class LiteLoader implements FilenameFilter
355 */ 546 */
356 public String getLoadedModsList() 547 public String getLoadedModsList()
357 { 548 {
358 - return loadedModsList; 549 + return this.loadedModsList;
  550 + }
  551 +
  552 + /**
  553 + * Used to get the name of the modpack being used
  554 + *
  555 + * @return name of the modpack in use or null if no pack
  556 + */
  557 + public String getBranding()
  558 + {
  559 + return this.branding;
359 } 560 }
360 561
361 /** 562 /**
362 * Enumerate the java class path and "mods" folder to find mod classes, then load the classes 563 * Enumerate the java class path and "mods" folder to find mod classes, then load the classes
363 */ 564 */
364 - private void prepareMods() 565 + private void prepareMods(boolean searchMods, boolean searchProtectionDomain, boolean searchClassPath)
365 { 566 {
366 // List of mod files in the "mods" folder 567 // List of mod files in the "mods" folder
367 LinkedList<File> modFiles = new LinkedList<File>(); 568 LinkedList<File> modFiles = new LinkedList<File>();
368 569
369 - // Find and enumerate the "mods" folder  
370 - File modFolder = getModsFolder();  
371 - if (modFolder.exists() && modFolder.isDirectory()) 570 + if (searchMods)
372 { 571 {
373 - logger.info("Mods folder found, searching " + modFolder.getPath());  
374 - findModFiles(modFolder, modFiles);  
375 - logger.info("Found " + modFiles.size() + " mod file(s)"); 572 + // Find and enumerate the "mods" folder
  573 + File modFolder = this.getModsFolder();
  574 + if (modFolder.exists() && modFolder.isDirectory())
  575 + {
  576 + logger.info("Mods folder found, searching " + modFolder.getPath());
  577 + this.findModFiles(modFolder, modFiles);
  578 + logger.info("Found " + modFiles.size() + " mod file(s)");
  579 + }
376 } 580 }
377 581
378 // Find and enumerate classes on the class path 582 // Find and enumerate classes on the class path
@@ -388,9 +592,8 @@ public final class LiteLoader implements FilenameFilter @@ -388,9 +592,8 @@ public final class LiteLoader implements FilenameFilter
388 logger.info(String.format("Class path separator=\"%s\"", classPathSeparator)); 592 logger.info(String.format("Class path separator=\"%s\"", classPathSeparator));
389 logger.info(String.format("Class path entries=(\n classpathEntry=%s\n)", classPath.replace(classPathSeparator, "\n classpathEntry="))); 593 logger.info(String.format("Class path entries=(\n classpathEntry=%s\n)", classPath.replace(classPathSeparator, "\n classpathEntry=")));
390 594
391 - logger.info("Loading mods from class path...");  
392 -  
393 - modsToLoad = findModClasses(classPathEntries, modFiles); 595 + if (searchProtectionDomain || searchClassPath) logger.info("Discovering mods on class path...");
  596 + modsToLoad = this.findModClasses(classPathEntries, modFiles, searchProtectionDomain, searchClassPath);
394 597
395 logger.info("Mod class discovery completed"); 598 logger.info("Mod class discovery completed");
396 } 599 }
@@ -400,7 +603,7 @@ public final class LiteLoader implements FilenameFilter @@ -400,7 +603,7 @@ public final class LiteLoader implements FilenameFilter
400 return; 603 return;
401 } 604 }
402 605
403 - loadMods(modsToLoad); 606 + this.loadMods(modsToLoad);
404 } 607 }
405 608
406 /** 609 /**
@@ -460,36 +663,68 @@ public final class LiteLoader implements FilenameFilter @@ -460,36 +663,68 @@ public final class LiteLoader implements FilenameFilter
460 * @param classPathEntries Java class path split into string entries 663 * @param classPathEntries Java class path split into string entries
461 * @return map of classes to load 664 * @return map of classes to load
462 */ 665 */
463 - private HashMap<String, Class> findModClasses(String[] classPathEntries, LinkedList<File> modFiles) 666 + private HashMap<String, Class> findModClasses(String[] classPathEntries, LinkedList<File> modFiles, boolean searchProtectionDomain, boolean searchClassPath)
464 { 667 {
465 // To try to avoid loading the same mod multiple times if it appears in more than one entry in the class path, we index 668 // To try to avoid loading the same mod multiple times if it appears in more than one entry in the class path, we index
466 // the mods by name and hopefully match only a single instance of a particular mod 669 // the mods by name and hopefully match only a single instance of a particular mod
467 HashMap<String, Class> modsToLoad = new HashMap<String, Class>(); 670 HashMap<String, Class> modsToLoad = new HashMap<String, Class>();
468 671
469 - try 672 + if (searchProtectionDomain)
470 { 673 {
471 - logger.info("Searching protection domain code source...");  
472 -  
473 - File packagePath = null;  
474 -  
475 - if (LiteLoader.class.getProtectionDomain().getCodeSource().getLocation() != null)  
476 - {  
477 - packagePath = new File(LiteLoader.class.getProtectionDomain().getCodeSource().getLocation().toURI());  
478 - }  
479 - else 674 + try
480 { 675 {
481 - // Fix (?) for forge and other mods which screw up the protection domain  
482 - String reflectionClassPath = LiteLoader.class.getResource("/com/mumfrey/liteloader/core/LiteLoader.class").getPath(); 676 + logger.info("Searching protection domain code source...");
  677 +
  678 + File packagePath = null;
  679 +
  680 + URL protectionDomainLocation = LiteLoader.class.getProtectionDomain().getCodeSource().getLocation();
  681 + if (protectionDomainLocation != null)
  682 + {
  683 + if (protectionDomainLocation.toString().indexOf('!') > -1 && protectionDomainLocation.toString().startsWith("jar:"))
  684 + {
  685 + protectionDomainLocation = new URL(protectionDomainLocation.toString().substring(4, protectionDomainLocation.toString().indexOf('!')));
  686 + }
  687 +
  688 + packagePath = new File(protectionDomainLocation.toURI());
  689 + }
  690 + else
  691 + {
  692 + // Fix (?) for forge and other mods which screw up the protection domain
  693 + String reflectionClassPath = LiteLoader.class.getResource("/com/mumfrey/liteloader/core/LiteLoader.class").getPath();
  694 +
  695 + if (reflectionClassPath.indexOf('!') > -1)
  696 + {
  697 + reflectionClassPath = URLDecoder.decode(reflectionClassPath, "UTF-8");
  698 + packagePath = new File(reflectionClassPath.substring(5, reflectionClassPath.indexOf('!')));
  699 + }
  700 + }
483 701
484 - if (reflectionClassPath.indexOf('!') > -1) 702 + if (packagePath != null)
485 { 703 {
486 - reflectionClassPath = URLDecoder.decode(reflectionClassPath, "UTF-8");  
487 - packagePath = new File(reflectionClassPath.substring(5, reflectionClassPath.indexOf('!'))); 704 + LinkedList<Class> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod");
  705 +
  706 + for (Class mod : modClasses)
  707 + {
  708 + modsToLoad.put(mod.getSimpleName(), mod);
  709 + }
  710 +
  711 + if (modClasses.size() > 0) logger.info(String.format("Found %s potential matches", modClasses.size()));
488 } 712 }
489 } 713 }
490 -  
491 - if (packagePath != null) 714 + catch (Throwable th)
  715 + {
  716 + logger.warning("Error loading from local class path: " + th.getMessage());
  717 + }
  718 + }
  719 +
  720 + if (searchClassPath)
  721 + {
  722 + // Search through the class path and find mod classes
  723 + for (String classPathPart : classPathEntries)
492 { 724 {
  725 + logger.info(String.format("Searching %s...", classPathPart));
  726 +
  727 + File packagePath = new File(classPathPart);
493 LinkedList<Class> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod"); 728 LinkedList<Class> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod");
494 729
495 for (Class mod : modClasses) 730 for (Class mod : modClasses)
@@ -500,26 +735,6 @@ public final class LiteLoader implements FilenameFilter @@ -500,26 +735,6 @@ public final class LiteLoader implements FilenameFilter
500 if (modClasses.size() > 0) logger.info(String.format("Found %s potential matches", modClasses.size())); 735 if (modClasses.size() > 0) logger.info(String.format("Found %s potential matches", modClasses.size()));
501 } 736 }
502 } 737 }
503 - catch (Throwable th)  
504 - {  
505 - logger.warning("Error loading from local class path: " + th.getMessage());  
506 - }  
507 -  
508 - // Search through the class path and find mod classes  
509 - for (String classPathPart : classPathEntries)  
510 - {  
511 - logger.info(String.format("Searching %s...", classPathPart));  
512 -  
513 - File packagePath = new File(classPathPart);  
514 - LinkedList<Class> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod");  
515 -  
516 - for (Class mod : modClasses)  
517 - {  
518 - modsToLoad.put(mod.getSimpleName(), mod);  
519 - }  
520 -  
521 - if (modClasses.size() > 0) logger.info(String.format("Found %s potential matches", modClasses.size()));  
522 - }  
523 738
524 // Search through mod files and find mod classes 739 // Search through mod files and find mod classes
525 for (File modFile : modFiles) 740 for (File modFile : modFiles)
@@ -561,7 +776,7 @@ public final class LiteLoader implements FilenameFilter @@ -561,7 +776,7 @@ public final class LiteLoader implements FilenameFilter
561 logger.info("Loading mod from " + mod.getName()); 776 logger.info("Loading mod from " + mod.getName());
562 777
563 LiteMod newMod = (LiteMod)mod.newInstance(); 778 LiteMod newMod = (LiteMod)mod.newInstance();
564 - mods.add(newMod); 779 + this.mods.add(newMod);
565 780
566 logger.info("Successfully added mod " + newMod.getName() + " version " + newMod.getVersion()); 781 logger.info("Successfully added mod " + newMod.getName() + " version " + newMod.getVersion());
567 } 782 }
@@ -578,7 +793,7 @@ public final class LiteLoader implements FilenameFilter @@ -578,7 +793,7 @@ public final class LiteLoader implements FilenameFilter
578 */ 793 */
579 private void initMods() 794 private void initMods()
580 { 795 {
581 - loadedModsList = ""; 796 + this.loadedModsList = "";
582 int loadedModsCount = 0; 797 int loadedModsCount = 0;
583 798
584 for (Iterator<LiteMod> iter = mods.iterator(); iter.hasNext();) 799 for (Iterator<LiteMod> iter = mods.iterator(); iter.hasNext();)
@@ -593,45 +808,50 @@ public final class LiteLoader implements FilenameFilter @@ -593,45 +808,50 @@ public final class LiteLoader implements FilenameFilter
593 808
594 if (mod instanceof Tickable) 809 if (mod instanceof Tickable)
595 { 810 {
596 - addTickListener((Tickable)mod); 811 + this.addTickListener((Tickable)mod);
597 } 812 }
598 813
599 if (mod instanceof InitCompleteListener) 814 if (mod instanceof InitCompleteListener)
600 { 815 {
601 - addInitListener((InitCompleteListener)mod); 816 + this.addInitListener((InitCompleteListener)mod);
602 } 817 }
603 818
604 if (mod instanceof RenderListener) 819 if (mod instanceof RenderListener)
605 { 820 {
606 - addRenderListener((RenderListener)mod); 821 + this.addRenderListener((RenderListener)mod);
  822 + }
  823 +
  824 + if (mod instanceof PostRenderListener)
  825 + {
  826 + this.addPostRenderListener((PostRenderListener)mod);
607 } 827 }
608 828
609 if (mod instanceof ChatFilter) 829 if (mod instanceof ChatFilter)
610 { 830 {
611 - addChatFilter((ChatFilter)mod); 831 + this.addChatFilter((ChatFilter)mod);
612 } 832 }
613 833
614 if (mod instanceof ChatListener && !(mod instanceof ChatFilter)) 834 if (mod instanceof ChatListener && !(mod instanceof ChatFilter))
615 { 835 {
616 - addChatListener((ChatListener)mod); 836 + this.addChatListener((ChatListener)mod);
617 } 837 }
618 838
619 if (mod instanceof PreLoginListener) 839 if (mod instanceof PreLoginListener)
620 { 840 {
621 - addPreLoginListener((PreLoginListener)mod); 841 + this.addPreLoginListener((PreLoginListener)mod);
622 } 842 }
623 843
624 if (mod instanceof LoginListener) 844 if (mod instanceof LoginListener)
625 { 845 {
626 - addLoginListener((LoginListener)mod); 846 + this.addLoginListener((LoginListener)mod);
627 } 847 }
628 848
629 if (mod instanceof PluginChannelListener) 849 if (mod instanceof PluginChannelListener)
630 { 850 {
631 - addPluginChannelListener((PluginChannelListener)mod); 851 + this.addPluginChannelListener((PluginChannelListener)mod);
632 } 852 }
633 853
634 - loadedModsList += String.format("\n - %s version %s", mod.getName(), mod.getVersion()); 854 + this.loadedModsList += String.format("\n - %s version %s", mod.getName(), mod.getVersion());
635 loadedModsCount++; 855 loadedModsCount++;
636 } 856 }
637 catch (Throwable th) 857 catch (Throwable th)
@@ -641,7 +861,7 @@ public final class LiteLoader implements FilenameFilter @@ -641,7 +861,7 @@ public final class LiteLoader implements FilenameFilter
641 } 861 }
642 } 862 }
643 863
644 - loadedModsList = String.format("%s loaded mod(s)%s", loadedModsCount, loadedModsList); 864 + this.loadedModsList = String.format("%s loaded mod(s)%s", loadedModsCount, this.loadedModsList);
645 } 865 }
646 866
647 /** 867 /**
@@ -652,34 +872,34 @@ public final class LiteLoader implements FilenameFilter @@ -652,34 +872,34 @@ public final class LiteLoader implements FilenameFilter
652 try 872 try
653 { 873 {
654 // Chat hook 874 // Chat hook
655 - if ((chatListeners.size() > 0 || chatFilters.size() > 0) && !chatHooked) 875 + if ((this.chatListeners.size() > 0 || this.chatFilters.size() > 0) && !this.chatHooked)
656 { 876 {
657 - chatHooked = true; 877 + this.chatHooked = true;
658 HookChat.Register(); 878 HookChat.Register();
659 HookChat.RegisterPacketHandler(this); 879 HookChat.RegisterPacketHandler(this);
660 } 880 }
661 881
662 // Login hook 882 // Login hook
663 - if ((preLoginListeners.size() > 0 || loginListeners.size() > 0) && !loginHooked) 883 + if ((this.preLoginListeners.size() > 0 || this.loginListeners.size() > 0) && !this.loginHooked)
664 { 884 {
665 - loginHooked = true; 885 + this.loginHooked = true;
666 ModUtilities.registerPacketOverride(1, HookLogin.class); 886 ModUtilities.registerPacketOverride(1, HookLogin.class);
667 HookLogin.loader = this; 887 HookLogin.loader = this;
668 } 888 }
669 889
670 // Plugin channels hook 890 // Plugin channels hook
671 - if (pluginChannelListeners.size() > 0 && !pluginChannelHooked) 891 + if (this.pluginChannelListeners.size() > 0 && !this.pluginChannelHooked)
672 { 892 {
673 - pluginChannelHooked = true; 893 + this.pluginChannelHooked = true;
674 HookPluginChannels.Register(); 894 HookPluginChannels.Register();
675 HookPluginChannels.RegisterPacketHandler(this); 895 HookPluginChannels.RegisterPacketHandler(this);
676 } 896 }
677 897
678 // Tick hook 898 // Tick hook
679 - if (!tickHooked) 899 + if (!this.tickHooked)
680 { 900 {
681 - tickHooked = true;  
682 - PrivateFields.minecraftProfiler.SetFinal(minecraft, new HookProfiler(this, logger)); 901 + this.tickHooked = true;
  902 + PrivateFields.minecraftProfiler.SetFinal(this.minecraft, new HookProfiler(this, logger));
683 } 903 }
684 } 904 }
685 catch (Exception ex) 905 catch (Exception ex)
@@ -694,10 +914,10 @@ public final class LiteLoader implements FilenameFilter @@ -694,10 +914,10 @@ public final class LiteLoader implements FilenameFilter
694 */ 914 */
695 public void addTickListener(Tickable tickable) 915 public void addTickListener(Tickable tickable)
696 { 916 {
697 - if (!tickListeners.contains(tickable)) 917 + if (!this.tickListeners.contains(tickable))
698 { 918 {
699 - tickListeners.add(tickable);  
700 - if (loaderStartupComplete) initHooks(); 919 + this.tickListeners.add(tickable);
  920 + if (this.loaderStartupComplete) this.initHooks();
701 } 921 }
702 } 922 }
703 923
@@ -706,10 +926,10 @@ public final class LiteLoader implements FilenameFilter @@ -706,10 +926,10 @@ public final class LiteLoader implements FilenameFilter
706 */ 926 */
707 public void addInitListener(InitCompleteListener initCompleteListener) 927 public void addInitListener(InitCompleteListener initCompleteListener)
708 { 928 {
709 - if (!initListeners.contains(initCompleteListener)) 929 + if (!this.initListeners.contains(initCompleteListener))
710 { 930 {
711 - initListeners.add(initCompleteListener);  
712 - if (loaderStartupComplete) initHooks(); 931 + this.initListeners.add(initCompleteListener);
  932 + if (this.loaderStartupComplete) this.initHooks();
713 } 933 }
714 } 934 }
715 935
@@ -718,10 +938,22 @@ public final class LiteLoader implements FilenameFilter @@ -718,10 +938,22 @@ public final class LiteLoader implements FilenameFilter
718 */ 938 */
719 public void addRenderListener(RenderListener tickable) 939 public void addRenderListener(RenderListener tickable)
720 { 940 {
721 - if (!renderListeners.contains(tickable)) 941 + if (!this.renderListeners.contains(tickable))
  942 + {
  943 + this.renderListeners.add(tickable);
  944 + if (this.loaderStartupComplete) this.initHooks();
  945 + }
  946 + }
  947 +
  948 + /**
  949 + * @param tickable
  950 + */
  951 + public void addPostRenderListener(PostRenderListener tickable)
  952 + {
  953 + if (!this.postRenderListeners.contains(tickable))
722 { 954 {
723 - renderListeners.add(tickable);  
724 - if (loaderStartupComplete) initHooks(); 955 + this.postRenderListeners.add(tickable);
  956 + if (this.loaderStartupComplete) this.initHooks();
725 } 957 }
726 } 958 }
727 959
@@ -730,10 +962,10 @@ public final class LiteLoader implements FilenameFilter @@ -730,10 +962,10 @@ public final class LiteLoader implements FilenameFilter
730 */ 962 */
731 public void addChatFilter(ChatFilter chatFilter) 963 public void addChatFilter(ChatFilter chatFilter)
732 { 964 {
733 - if (!chatFilters.contains(chatFilter)) 965 + if (!this.chatFilters.contains(chatFilter))
734 { 966 {
735 - chatFilters.add(chatFilter);  
736 - if (loaderStartupComplete) initHooks(); 967 + this.chatFilters.add(chatFilter);
  968 + if (this.loaderStartupComplete) this.initHooks();
737 } 969 }
738 } 970 }
739 971
@@ -742,10 +974,10 @@ public final class LiteLoader implements FilenameFilter @@ -742,10 +974,10 @@ public final class LiteLoader implements FilenameFilter
742 */ 974 */
743 public void addChatListener(ChatListener chatListener) 975 public void addChatListener(ChatListener chatListener)
744 { 976 {
745 - if (!chatListeners.contains(chatListener)) 977 + if (!this.chatListeners.contains(chatListener))
746 { 978 {
747 - chatListeners.add(chatListener);  
748 - if (loaderStartupComplete) initHooks(); 979 + this.chatListeners.add(chatListener);
  980 + if (this.loaderStartupComplete) this.initHooks();
749 } 981 }
750 } 982 }
751 983
@@ -754,10 +986,10 @@ public final class LiteLoader implements FilenameFilter @@ -754,10 +986,10 @@ public final class LiteLoader implements FilenameFilter
754 */ 986 */
755 public void addPreLoginListener(PreLoginListener loginListener) 987 public void addPreLoginListener(PreLoginListener loginListener)
756 { 988 {
757 - if (!preLoginListeners.contains(loginListener)) 989 + if (!this.preLoginListeners.contains(loginListener))
758 { 990 {
759 - preLoginListeners.add(loginListener);  
760 - if (loaderStartupComplete) initHooks(); 991 + this.preLoginListeners.add(loginListener);
  992 + if (this.loaderStartupComplete) this.initHooks();
761 } 993 }
762 } 994 }
763 995
@@ -766,10 +998,10 @@ public final class LiteLoader implements FilenameFilter @@ -766,10 +998,10 @@ public final class LiteLoader implements FilenameFilter
766 */ 998 */
767 public void addLoginListener(LoginListener loginListener) 999 public void addLoginListener(LoginListener loginListener)
768 { 1000 {
769 - if (!loginListeners.contains(loginListener)) 1001 + if (!this.loginListeners.contains(loginListener))
770 { 1002 {
771 - loginListeners.add(loginListener);  
772 - if (loaderStartupComplete) initHooks(); 1003 + this.loginListeners.add(loginListener);
  1004 + if (this.loaderStartupComplete) this.initHooks();
773 } 1005 }
774 } 1006 }
775 1007
@@ -778,10 +1010,10 @@ public final class LiteLoader implements FilenameFilter @@ -778,10 +1010,10 @@ public final class LiteLoader implements FilenameFilter
778 */ 1010 */
779 public void addPluginChannelListener(PluginChannelListener pluginChannelListener) 1011 public void addPluginChannelListener(PluginChannelListener pluginChannelListener)
780 { 1012 {
781 - if (!pluginChannelListeners.contains(pluginChannelListener)) 1013 + if (!this.pluginChannelListeners.contains(pluginChannelListener))
782 { 1014 {
783 - pluginChannelListeners.add(pluginChannelListener);  
784 - if (loaderStartupComplete) initHooks(); 1015 + this.pluginChannelListeners.add(pluginChannelListener);
  1016 + if (this.loaderStartupComplete) this.initHooks();
785 } 1017 }
786 } 1018 }
787 1019
@@ -867,7 +1099,7 @@ public final class LiteLoader implements FilenameFilter @@ -867,7 +1099,7 @@ public final class LiteLoader implements FilenameFilter
867 */ 1099 */
868 private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath) 1100 private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath)
869 { 1101 {
870 - enumerateDirectory(prefix, superClass, classloader, classes, packagePath, ""); 1102 + enumerateDirectory(prefix, superClass, classloader, classes, packagePath, "", 0);
871 } 1103 }
872 1104
873 /** 1105 /**
@@ -879,15 +1111,18 @@ public final class LiteLoader implements FilenameFilter @@ -879,15 +1111,18 @@ public final class LiteLoader implements FilenameFilter
879 * @param packagePath 1111 * @param packagePath
880 * @param packageName 1112 * @param packageName
881 */ 1113 */
882 - private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath, String packageName) 1114 + private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath, String packageName, int depth)
883 { 1115 {
  1116 + // Prevent crash due to broken recursion
  1117 + if (depth > MAX_DISCOVERY_DEPTH) return;
  1118 +
884 File[] classFiles = packagePath.listFiles(); 1119 File[] classFiles = packagePath.listFiles();
885 1120
886 for (File classFile : classFiles) 1121 for (File classFile : classFiles)
887 { 1122 {
888 if (classFile.isDirectory()) 1123 if (classFile.isDirectory())
889 { 1124 {
890 - enumerateDirectory(prefix, superClass, classloader, classes, classFile, packageName + classFile.getName() + "."); 1125 + enumerateDirectory(prefix, superClass, classloader, classes, classFile, packageName + classFile.getName() + ".", depth + 1);
891 } 1126 }
892 else 1127 else
893 { 1128 {
@@ -937,10 +1172,10 @@ public final class LiteLoader implements FilenameFilter @@ -937,10 +1172,10 @@ public final class LiteLoader implements FilenameFilter
937 { 1172 {
938 try 1173 try
939 { 1174 {
940 - if (Minecraft.class.getClassLoader() instanceof URLClassLoader && mAddUrl != null && mAddUrl.isAccessible()) 1175 + if (Minecraft.class.getClassLoader() instanceof URLClassLoader && this.mAddUrl != null && this.mAddUrl.isAccessible())
941 { 1176 {
942 URLClassLoader classLoader = (URLClassLoader)Minecraft.class.getClassLoader(); 1177 URLClassLoader classLoader = (URLClassLoader)Minecraft.class.getClassLoader();
943 - mAddUrl.invoke(classLoader, classUrl); 1178 + this.mAddUrl.invoke(classLoader, classUrl);
944 return true; 1179 return true;
945 } 1180 }
946 } 1181 }
@@ -957,16 +1192,16 @@ public final class LiteLoader implements FilenameFilter @@ -957,16 +1192,16 @@ public final class LiteLoader implements FilenameFilter
957 */ 1192 */
958 public void onInit() 1193 public void onInit()
959 { 1194 {
960 - if (!lateInitDone) 1195 + if (!this.lateInitDone)
961 { 1196 {
962 - lateInitDone = true; 1197 + this.lateInitDone = true;
963 1198
964 - for (InitCompleteListener initMod : initListeners) 1199 + for (InitCompleteListener initMod : this.initListeners)
965 { 1200 {
966 try 1201 try
967 { 1202 {
968 logger.info("Calling late init for mod " + initMod.getName()); 1203 logger.info("Calling late init for mod " + initMod.getName());
969 - initMod.onInitCompleted(minecraft, this); 1204 + initMod.onInitCompleted(this.minecraft, this);
970 } 1205 }
971 catch (Throwable th) 1206 catch (Throwable th)
972 { 1207 {
@@ -981,17 +1216,39 @@ public final class LiteLoader implements FilenameFilter @@ -981,17 +1216,39 @@ public final class LiteLoader implements FilenameFilter
981 */ 1216 */
982 public void onRender() 1217 public void onRender()
983 { 1218 {
984 - for (RenderListener renderListener : renderListeners) 1219 + for (RenderListener renderListener : this.renderListeners)
985 renderListener.onRender(); 1220 renderListener.onRender();
986 } 1221 }
  1222 +
  1223 + /**
  1224 + * Callback from the tick hook, post render entities
  1225 + */
  1226 + public void postRenderEntities()
  1227 + {
  1228 + float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
  1229 +
  1230 + for (PostRenderListener renderListener : this.postRenderListeners)
  1231 + renderListener.onPostRenderEntities(partialTicks);
  1232 + }
  1233 +
  1234 + /**
  1235 + * Callback from the tick hook, post render
  1236 + */
  1237 + public void postRender()
  1238 + {
  1239 + float partialTicks = (this.minecraftTimer != null) ? this.minecraftTimer.elapsedPartialTicks : 0.0F;
  1240 +
  1241 + for (PostRenderListener renderListener : this.postRenderListeners)
  1242 + renderListener.onPostRender(partialTicks);
  1243 + }
987 1244
988 /** 1245 /**
989 * Called immediately before the current GUI is rendered 1246 * Called immediately before the current GUI is rendered
990 */ 1247 */
991 public void onBeforeGuiRender() 1248 public void onBeforeGuiRender()
992 { 1249 {
993 - for (RenderListener renderListener : renderListeners)  
994 - renderListener.onRenderGui(minecraft.currentScreen); 1250 + for (RenderListener renderListener : this.renderListeners)
  1251 + renderListener.onRenderGui(this.minecraft.currentScreen);
995 } 1252 }
996 1253
997 /** 1254 /**
@@ -999,7 +1256,7 @@ public final class LiteLoader implements FilenameFilter @@ -999,7 +1256,7 @@ public final class LiteLoader implements FilenameFilter
999 */ 1256 */
1000 public void onSetupCameraTransform() 1257 public void onSetupCameraTransform()
1001 { 1258 {
1002 - for (RenderListener renderListener : renderListeners) 1259 + for (RenderListener renderListener : this.renderListeners)
1003 renderListener.onSetupCameraTransform(); 1260 renderListener.onSetupCameraTransform();
1004 } 1261 }
1005 1262
@@ -1013,26 +1270,26 @@ public final class LiteLoader implements FilenameFilter @@ -1013,26 +1270,26 @@ public final class LiteLoader implements FilenameFilter
1013 float partialTicks = 0.0F; 1270 float partialTicks = 0.0F;
1014 1271
1015 // Try to get the minecraft timer object and determine the value of the partialTicks 1272 // Try to get the minecraft timer object and determine the value of the partialTicks
1016 - if (tick || minecraftTimer == null) 1273 + if (tick || this.minecraftTimer == null)
1017 { 1274 {
1018 - minecraftTimer = PrivateFields.minecraftTimer.Get(minecraft); 1275 + this.minecraftTimer = PrivateFields.minecraftTimer.Get(this.minecraft);
1019 } 1276 }
1020 1277
1021 // Hooray, we got the timer reference 1278 // Hooray, we got the timer reference
1022 - if (minecraftTimer != null) 1279 + if (this.minecraftTimer != null)
1023 { 1280 {
1024 - partialTicks = minecraftTimer.elapsedPartialTicks;  
1025 - tick = minecraftTimer.elapsedTicks > 0; 1281 + partialTicks = this.minecraftTimer.elapsedPartialTicks;
  1282 + tick = this.minecraftTimer.elapsedTicks > 0;
1026 } 1283 }
1027 1284
1028 // Flag indicates whether we are in game at the moment 1285 // Flag indicates whether we are in game at the moment
1029 - boolean inGame = minecraft.renderViewEntity != null && minecraft.renderViewEntity.worldObj != null; 1286 + boolean inGame = this.minecraft.renderViewEntity != null && this.minecraft.renderViewEntity.worldObj != null;
1030 1287
1031 // Iterate tickable mods 1288 // Iterate tickable mods
1032 - for (Tickable tickable : tickListeners) 1289 + for (Tickable tickable : this.tickListeners)
1033 { 1290 {
1034 profiler.startSection(tickable.getClass().getSimpleName()); 1291 profiler.startSection(tickable.getClass().getSimpleName());
1035 - tickable.onTick(minecraft, partialTicks, inGame, tick); 1292 + tickable.onTick(this.minecraft, partialTicks, inGame, tick);
1036 profiler.endSection(); 1293 profiler.endSection();
1037 } 1294 }
1038 } 1295 }
@@ -1046,12 +1303,12 @@ public final class LiteLoader implements FilenameFilter @@ -1046,12 +1303,12 @@ public final class LiteLoader implements FilenameFilter
1046 public boolean onChat(Packet3Chat chatPacket) 1303 public boolean onChat(Packet3Chat chatPacket)
1047 { 1304 {
1048 // Chat filters get a stab at the chat first, if any filter returns false the chat is discarded 1305 // Chat filters get a stab at the chat first, if any filter returns false the chat is discarded
1049 - for (ChatFilter chatFilter : chatFilters) 1306 + for (ChatFilter chatFilter : this.chatFilters)
1050 if (!chatFilter.onChat(chatPacket)) 1307 if (!chatFilter.onChat(chatPacket))
1051 return false; 1308 return false;
1052 1309
1053 // Chat listeners get the chat if no filter removed it 1310 // Chat listeners get the chat if no filter removed it
1054 - for (ChatListener chatListener : chatListeners) 1311 + for (ChatListener chatListener : this.chatListeners)
1055 chatListener.onChat(chatPacket.message); 1312 chatListener.onChat(chatPacket.message);
1056 1313
1057 return true; 1314 return true;
@@ -1068,7 +1325,7 @@ public final class LiteLoader implements FilenameFilter @@ -1068,7 +1325,7 @@ public final class LiteLoader implements FilenameFilter
1068 { 1325 {
1069 boolean cancelled = false; 1326 boolean cancelled = false;
1070 1327
1071 - for (PreLoginListener loginListener : preLoginListeners) 1328 + for (PreLoginListener loginListener : this.preLoginListeners)
1072 { 1329 {
1073 cancelled |= !loginListener.onPreLogin(netHandler, loginPacket); 1330 cancelled |= !loginListener.onPreLogin(netHandler, loginPacket);
1074 } 1331 }
@@ -1084,7 +1341,7 @@ public final class LiteLoader implements FilenameFilter @@ -1084,7 +1341,7 @@ public final class LiteLoader implements FilenameFilter
1084 */ 1341 */
1085 public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket) 1342 public void onConnectToServer(NetHandler netHandler, Packet1Login loginPacket)
1086 { 1343 {
1087 - for (LoginListener loginListener : loginListeners) 1344 + for (LoginListener loginListener : this.loginListeners)
1088 loginListener.onLogin(netHandler, loginPacket); 1345 loginListener.onLogin(netHandler, loginPacket);
1089 1346
1090 setupPluginChannels(); 1347 setupPluginChannels();
@@ -1097,9 +1354,9 @@ public final class LiteLoader implements FilenameFilter @@ -1097,9 +1354,9 @@ public final class LiteLoader implements FilenameFilter
1097 */ 1354 */
1098 public void onPluginChannelMessage(HookPluginChannels hookPluginChannels) 1355 public void onPluginChannelMessage(HookPluginChannels hookPluginChannels)
1099 { 1356 {
1100 - if (hookPluginChannels != null && hookPluginChannels.channel != null && pluginChannels.containsKey(hookPluginChannels.channel)) 1357 + if (hookPluginChannels != null && hookPluginChannels.channel != null && this.pluginChannels.containsKey(hookPluginChannels.channel))
1101 { 1358 {
1102 - for (PluginChannelListener pluginChannelListener : pluginChannels.get(hookPluginChannels.channel)) 1359 + for (PluginChannelListener pluginChannelListener : this.pluginChannels.get(hookPluginChannels.channel))
1103 { 1360 {
1104 try 1361 try
1105 { 1362 {
@@ -1127,10 +1384,10 @@ public final class LiteLoader implements FilenameFilter @@ -1127,10 +1384,10 @@ public final class LiteLoader implements FilenameFilter
1127 protected void setupPluginChannels() 1384 protected void setupPluginChannels()
1128 { 1385 {
1129 // Clear any channels from before 1386 // Clear any channels from before
1130 - pluginChannels.clear(); 1387 + this.pluginChannels.clear();
1131 1388
1132 // Enumerate mods for plugin channels 1389 // Enumerate mods for plugin channels
1133 - for (PluginChannelListener pluginChannelListener : pluginChannelListeners) 1390 + for (PluginChannelListener pluginChannelListener : this.pluginChannelListeners)
1134 { 1391 {
1135 List<String> channels = pluginChannelListener.getChannels(); 1392 List<String> channels = pluginChannelListener.getChannels();
1136 1393
@@ -1141,23 +1398,23 @@ public final class LiteLoader implements FilenameFilter @@ -1141,23 +1398,23 @@ public final class LiteLoader implements FilenameFilter
1141 if (channel.length() > 16 || channel.toUpperCase().equals("REGISTER") || channel.toUpperCase().equals("UNREGISTER")) 1398 if (channel.length() > 16 || channel.toUpperCase().equals("REGISTER") || channel.toUpperCase().equals("UNREGISTER"))
1142 continue; 1399 continue;
1143 1400
1144 - if (!pluginChannels.containsKey(channel)) 1401 + if (!this.pluginChannels.containsKey(channel))
1145 { 1402 {
1146 - pluginChannels.put(channel, new LinkedList<PluginChannelListener>()); 1403 + this.pluginChannels.put(channel, new LinkedList<PluginChannelListener>());
1147 } 1404 }
1148 1405
1149 - pluginChannels.get(channel).add(pluginChannelListener); 1406 + this.pluginChannels.get(channel).add(pluginChannelListener);
1150 } 1407 }
1151 } 1408 }
1152 } 1409 }
1153 1410
1154 // If any mods have registered channels, send the REGISTER packet 1411 // If any mods have registered channels, send the REGISTER packet
1155 - if (pluginChannels.keySet().size() > 0) 1412 + if (this.pluginChannels.keySet().size() > 0)
1156 { 1413 {
1157 StringBuilder channelList = new StringBuilder(); 1414 StringBuilder channelList = new StringBuilder();
1158 boolean separator = false; 1415 boolean separator = false;
1159 1416
1160 - for (String channel : pluginChannels.keySet()) 1417 + for (String channel : this.pluginChannels.keySet())
1161 { 1418 {
1162 if (separator) channelList.append("\u0000"); 1419 if (separator) channelList.append("\u0000");
1163 channelList.append(channel); 1420 channelList.append(channel);
java/com/mumfrey/liteloader/util/log/ConsoleHandler.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.util.log;
  2 +
  3 +import java.util.logging.LogRecord;
  4 +import java.util.logging.StreamHandler;
  5 +
  6 +public class ConsoleHandler extends StreamHandler
  7 +{
  8 + /**
  9 + * Create a <tt>ConsoleHandler</tt> for <tt>System.err</tt>.
  10 + * <p>
  11 + * The <tt>ConsoleHandler</tt> is configured based on <tt>LogManager</tt>
  12 + * properties (or their default values).
  13 + *
  14 + */
  15 + public ConsoleHandler()
  16 + {
  17 + setOutputStream(System.out);
  18 + }
  19 +
  20 + /**
  21 + * Publish a <tt>LogRecord</tt>.
  22 + * <p>
  23 + * The logging request was made initially to a <tt>Logger</tt> object, which
  24 + * initialized the <tt>LogRecord</tt> and forwarded it here.
  25 + * <p>
  26 + *
  27 + * @param record
  28 + * description of the log event. A null record is silently
  29 + * ignored and is not published
  30 + */
  31 + @Override
  32 + public synchronized void publish(LogRecord record)
  33 + {
  34 + super.publish(record);
  35 + flush();
  36 + }
  37 +
  38 + /**
  39 + * Override <tt>StreamHandler.close</tt> to do a flush but not to close the
  40 + * output stream. That is, we do <b>not</b> close <tt>System.err</tt>.
  41 + */
  42 + @Override
  43 + public synchronized void close()
  44 + {
  45 + flush();
  46 + }
  47 +}
java/net/minecraft/src/CallableJVMFlags.java
@@ -6,6 +6,7 @@ import java.util.Iterator; @@ -6,6 +6,7 @@ import java.util.Iterator;
6 import java.util.List; 6 import java.util.List;
7 import java.util.concurrent.Callable; 7 import java.util.concurrent.Callable;
8 8
  9 +import com.mumfrey.liteloader.core.CallableLiteLoaderBrand;
9 import com.mumfrey.liteloader.core.CallableLiteLoaderMods; 10 import com.mumfrey.liteloader.core.CallableLiteLoaderMods;
10 11
11 class CallableJVMFlags implements Callable 12 class CallableJVMFlags implements Callable
@@ -16,10 +17,14 @@ class CallableJVMFlags implements Callable @@ -16,10 +17,14 @@ class CallableJVMFlags implements Callable
16 CallableJVMFlags(CrashReport par1CrashReport) 17 CallableJVMFlags(CrashReport par1CrashReport)
17 { 18 {
18 this.crashReportJVMFlags = par1CrashReport; 19 this.crashReportJVMFlags = par1CrashReport;
  20 + par1CrashReport.func_85056_g().addCrashSectionCallable("Mod Pack", new CallableLiteLoaderBrand(par1CrashReport));
19 par1CrashReport.func_85056_g().addCrashSectionCallable("LiteLoader Mods", new CallableLiteLoaderMods(par1CrashReport)); 21 par1CrashReport.func_85056_g().addCrashSectionCallable("LiteLoader Mods", new CallableLiteLoaderMods(par1CrashReport));
20 } 22 }
21 23
22 - public String func_71487_a() 24 + /**
  25 + * Returns the number of JVM Flags along with the passed JVM Flags.
  26 + */
  27 + public String getJVMFlagsAsString()
23 { 28 {
24 RuntimeMXBean var1 = ManagementFactory.getRuntimeMXBean(); 29 RuntimeMXBean var1 = ManagementFactory.getRuntimeMXBean();
25 List var2 = var1.getInputArguments(); 30 List var2 = var1.getInputArguments();
@@ -48,6 +53,6 @@ class CallableJVMFlags implements Callable @@ -48,6 +53,6 @@ class CallableJVMFlags implements Callable
48 @Override 53 @Override
49 public Object call() 54 public Object call()
50 { 55 {
51 - return this.func_71487_a(); 56 + return this.getJVMFlagsAsString();
52 } 57 }
53 } 58 }
res/liteloader.properties 0 โ†’ 100644
  1 +search.mods=true
  2 +search.jar=true
  3 +search.classpath=true
  4 +log=stderr
  5 +
  6 +