Commit aecc5dcf6d2d0ccb9de81de87d2eeb6a9179b529

Authored by Mumfrey
1 parent f2549841

cleaning up the tweaker a bit, moving logic to separate StartupEnvironment class

java/common/com/mumfrey/liteloader/core/LiteLoaderBootstrap.java
@@ -30,6 +30,7 @@ import com.mumfrey.liteloader.interfaces.LoaderEnumerator; @@ -30,6 +30,7 @@ import com.mumfrey.liteloader.interfaces.LoaderEnumerator;
30 import com.mumfrey.liteloader.launch.LoaderBootstrap; 30 import com.mumfrey.liteloader.launch.LoaderBootstrap;
31 import com.mumfrey.liteloader.launch.LoaderEnvironment; 31 import com.mumfrey.liteloader.launch.LoaderEnvironment;
32 import com.mumfrey.liteloader.launch.LoaderProperties; 32 import com.mumfrey.liteloader.launch.LoaderProperties;
  33 +import com.mumfrey.liteloader.launch.StartupEnvironment;
33 import com.mumfrey.liteloader.util.log.LiteLoaderLogger; 34 import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
34 35
35 /** 36 /**
@@ -143,17 +144,17 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP @@ -143,17 +144,17 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP
143 * @param assetsDirectory 144 * @param assetsDirectory
144 * @param profile 145 * @param profile
145 */ 146 */
146 - public LiteLoaderBootstrap(int environmentTypeId, File gameDirectory, File assetsDirectory, String profile, List<String> apisToLoad) 147 + public LiteLoaderBootstrap(StartupEnvironment env)
147 { 148 {
148 - this.environmentType = EnvironmentType.values()[environmentTypeId]; 149 + this.environmentType = EnvironmentType.values()[env.getEnvironmentTypeId()];
149 150
150 - this.apiRegistry = new APIRegistry(this, this); 151 + this.apiRegistry = new APIRegistry(this.getEnvironment(), this.getProperties());
151 152
152 - this.gameDirectory = gameDirectory;  
153 - this.assetsDirectory = assetsDirectory;  
154 - this.profile = profile; 153 + this.gameDirectory = env.getGameDirectory();
  154 + this.assetsDirectory = env.getAssetsDirectory();
  155 + this.profile = env.getProfile();
  156 + this.modsFolder = env.getModsFolder();
155 157
156 - this.modsFolder = new File(this.gameDirectory, "mods");  
157 this.versionedModsFolder = new File(this.modsFolder, LiteLoaderVersion.CURRENT.getMinecraftVersion()); 158 this.versionedModsFolder = new File(this.modsFolder, LiteLoaderVersion.CURRENT.getMinecraftVersion());
158 this.configBaseFolder = new File(this.gameDirectory, "liteconfig"); 159 this.configBaseFolder = new File(this.gameDirectory, "liteconfig");
159 this.logFile = new File(this.configBaseFolder, "liteloader.log"); 160 this.logFile = new File(this.configBaseFolder, "liteloader.log");
@@ -169,7 +170,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP @@ -169,7 +170,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP
169 if (!this.commonConfigFolder.exists()) this.commonConfigFolder.mkdirs(); 170 if (!this.commonConfigFolder.exists()) this.commonConfigFolder.mkdirs();
170 if (!this.versionConfigFolder.exists()) this.versionConfigFolder.mkdirs(); 171 if (!this.versionConfigFolder.exists()) this.versionConfigFolder.mkdirs();
171 172
172 - this.initAPIs(apisToLoad); 173 + this.initAPIs(env.getAPIsToLoad());
173 this.apiProvider = this.apiRegistry.getProvider(); 174 this.apiProvider = this.apiRegistry.getProvider();
174 this.apiAdapter = this.apiRegistry.getAdapter(); 175 this.apiAdapter = this.apiRegistry.getAdapter();
175 } 176 }
@@ -242,6 +243,18 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP @@ -242,6 +243,18 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP
242 return this.environmentType; 243 return this.environmentType;
243 } 244 }
244 245
  246 + @Override
  247 + public LoaderEnvironment getEnvironment()
  248 + {
  249 + return this;
  250 + }
  251 +
  252 + @Override
  253 + public LoaderProperties getProperties()
  254 + {
  255 + return this;
  256 + }
  257 +
245 /* (non-Javadoc) 258 /* (non-Javadoc)
246 * @see com.mumfrey.liteloader.launch.ILoaderBootstrap#preInit(net.minecraft.launchwrapper.LaunchClassLoader, boolean) 259 * @see com.mumfrey.liteloader.launch.ILoaderBootstrap#preInit(net.minecraft.launchwrapper.LaunchClassLoader, boolean)
247 */ 260 */
@@ -307,7 +320,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP @@ -307,7 +320,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP
307 // PreInit failed 320 // PreInit failed
308 if (this.enumerator == null) return; 321 if (this.enumerator == null) return;
309 322
310 - LiteLoader.createInstance(this, this, classLoader); 323 + LiteLoader.createInstance(this.getEnvironment(), this.getProperties(), classLoader);
311 LiteLoader.invokeInit(); 324 LiteLoader.invokeInit();
312 } 325 }
313 326
java/common/com/mumfrey/liteloader/launch/GameEnvironment.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.launch;
  2 +
  3 +import java.io.File;
  4 +
  5 +public interface GameEnvironment
  6 +{
  7 + /**
  8 + * Get the game directory, this is the root directory of the game profile specified by the user in the launcher
  9 + */
  10 + public abstract File getGameDirectory();
  11 +
  12 + /**
  13 + * Get the assets directory
  14 + */
  15 + public abstract File getAssetsDirectory();
  16 +
  17 + /**
  18 + * Get the active profile name
  19 + */
  20 + public abstract String getProfile();
  21 +
  22 + /**
  23 + * Get the "mods" folder, used to get the base path for enumerators and config for legacy mods
  24 + */
  25 + public abstract File getModsFolder();
  26 +}
java/common/com/mumfrey/liteloader/launch/LiteLoaderTweaker.java
@@ -5,19 +5,11 @@ import java.lang.reflect.Constructor; @@ -5,19 +5,11 @@ import java.lang.reflect.Constructor;
5 import java.lang.reflect.Method; 5 import java.lang.reflect.Method;
6 import java.net.URL; 6 import java.net.URL;
7 import java.net.URLClassLoader; 7 import java.net.URLClassLoader;
8 -import java.util.ArrayList;  
9 -import java.util.HashMap;  
10 import java.util.HashSet; 8 import java.util.HashSet;
11 import java.util.List; 9 import java.util.List;
12 -import java.util.Map;  
13 -import java.util.Map.Entry;  
14 import java.util.Set; 10 import java.util.Set;
15 import java.util.TreeSet; 11 import java.util.TreeSet;
16 12
17 -import joptsimple.ArgumentAcceptingOptionSpec;  
18 -import joptsimple.NonOptionArgumentSpec;  
19 -import joptsimple.OptionParser;  
20 -import joptsimple.OptionSet;  
21 import net.minecraft.launchwrapper.ITweaker; 13 import net.minecraft.launchwrapper.ITweaker;
22 import net.minecraft.launchwrapper.Launch; 14 import net.minecraft.launchwrapper.Launch;
23 import net.minecraft.launchwrapper.LaunchClassLoader; 15 import net.minecraft.launchwrapper.LaunchClassLoader;
@@ -33,11 +25,13 @@ import com.mumfrey.liteloader.util.log.LiteLoaderLogger; @@ -33,11 +25,13 @@ import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
33 */ 25 */
34 public class LiteLoaderTweaker implements ITweaker 26 public class LiteLoaderTweaker implements ITweaker
35 { 27 {
36 - public static final String VERSION = "1.7.10"; 28 + public static final int ENV_TYPE_CLIENT = 0;
  29 + public static final int ENV_TYPE_DEDICATEDSERVER = 1;
37 30
38 - protected static final int ENV_TYPE_CLIENT = 0; 31 + public static final String VERSION = "1.7.10";
39 32
40 - protected static final int ENV_TYPE_DEDICATEDSERVER = 1; 33 + protected static final String bootstrapClassName = "com.mumfrey.liteloader.core.LiteLoaderBootstrap";
  34 + protected static final String genTransformerClassName = "com.mumfrey.liteloader.client.gen.GenProfilerTransformer";
41 35
42 /** 36 /**
43 * Loader startup state 37 * Loader startup state
@@ -170,172 +164,159 @@ public class LiteLoaderTweaker implements ITweaker @@ -170,172 +164,159 @@ public class LiteLoaderTweaker implements ITweaker
170 164
171 private static LiteLoaderTweaker instance; 165 private static LiteLoaderTweaker instance;
172 166
173 - private URL jarUrl;  
174 -  
175 - private List<String> singularLaunchArgs = new ArrayList<String>();  
176 - private Map<String, String> launchArgs;  
177 -  
178 - private ArgumentAcceptingOptionSpec<String> modsOption;  
179 - private ArgumentAcceptingOptionSpec<String> apisOption;  
180 - private OptionSet parsedOptions; 167 + protected URL jarUrl;
181 168
182 - private int tweakOrder = 0;  
183 - private Set<String> allCascadingTweaks = new HashSet<String>();  
184 - private Set<SortableValue<String>> sortedCascadingTweaks = new TreeSet<SortableValue<String>>(); 169 + protected int tweakOrder = 0;
  170 + protected Set<String> allCascadingTweaks = new HashSet<String>();
  171 + protected Set<SortableValue<String>> sortedCascadingTweaks = new TreeSet<SortableValue<String>>();
185 172
186 - private boolean isPrimary; 173 + protected boolean isPrimary;
  174 +
  175 + protected StartupEnvironment env;
187 176
188 /** 177 /**
189 * Loader bootstrap object 178 * Loader bootstrap object
190 */ 179 */
191 - private LoaderBootstrap bootstrap; 180 + protected LoaderBootstrap bootstrap;
192 181
193 - private LoaderProperties properties; 182 + protected LoaderProperties properties;
194 183
195 /** 184 /**
196 * Transformer manager 185 * Transformer manager
197 */ 186 */
198 - private ClassTransformerManager transformerManager;  
199 -  
200 - private static final String bootstrapClassName = "com.mumfrey.liteloader.core.LiteLoaderBootstrap"; 187 + protected ClassTransformerManager transformerManager;
201 188
202 - private static final String genTransformerClassName = "com.mumfrey.liteloader.client.gen.GenProfilerTransformer";  
203 -  
204 @Override 189 @Override
205 public void acceptOptions(List<String> args, File gameDirectory, File assetsDirectory, String profile) 190 public void acceptOptions(List<String> args, File gameDirectory, File assetsDirectory, String profile)
206 { 191 {
207 Launch.classLoader.addClassLoaderExclusion("com.google.common."); 192 Launch.classLoader.addClassLoaderExclusion("com.google.common.");
208 -  
209 LiteLoaderTweaker.instance = this; 193 LiteLoaderTweaker.instance = this;
210 194
211 - this.initArgs(args, gameDirectory, assetsDirectory);  
212 -  
213 - List<String> modsToLoad = this.getModFilterList();  
214 - List<String> apisToLoad = this.getAPIsToLoad();  
215 -  
216 - this.prepare(gameDirectory, assetsDirectory, profile, apisToLoad); 195 + this.prepare(args, gameDirectory, assetsDirectory, profile);
217 196
218 - this.preInit(modsToLoad); 197 + this.preInit();
219 } 198 }
220 199
221 /** 200 /**
222 - * @return 201 + * @param gameDirectory
  202 + * @param assetsDirectory
  203 + * @param profile
  204 + * @param apisToLoad
223 */ 205 */
224 - private List<String> getModFilterList() 206 + private void prepare(List<String> args, File gameDirectory, File assetsDirectory, String profile)
225 { 207 {
226 - return (this.parsedOptions.has(this.modsOption)) ? this.modsOption.values(this.parsedOptions) : null; 208 + LiteLoaderLogger.info("Bootstrapping LiteLoader " + LiteLoaderTweaker.VERSION);
  209 +
  210 + try
  211 + {
  212 + this.initEnvironment(args, gameDirectory, assetsDirectory, profile);
  213 +
  214 + this.bootstrap = this.spawnBootstrap(LiteLoaderTweaker.bootstrapClassName, Launch.classLoader);
  215 + this.properties = this.bootstrap.getProperties();
  216 +
  217 + this.transformerManager = new ClassTransformerManager(this.bootstrap.getRequiredTransformers());
  218 + this.transformerManager.injectTransformers(this.bootstrap.getPacketTransformers());
  219 +
  220 + StartupState.PREPARE.completed();
  221 + }
  222 + catch (Throwable th)
  223 + {
  224 + LiteLoaderLogger.severe(th, "Error during LiteLoader PREPARE: %s %s", th.getClass().getName(), th.getMessage());
  225 + }
227 } 226 }
228 227
229 /** 228 /**
230 - * @return 229 + * Do the first stage of loader startup, which enumerates mod sources and finds tweakers
231 */ 230 */
232 - private List<String> getAPIsToLoad() 231 + private void preInit()
233 { 232 {
234 - List<String> apisToLoad = new ArrayList<String>();  
235 - this.registerCoreAPIs(apisToLoad);  
236 - if (this.parsedOptions.has(this.apisOption)) 233 + StartupState.PREINIT.gotoState();
  234 +
  235 + try
  236 + {
  237 + this.bootstrap.preInit(Launch.classLoader, true, this.env.getModFilterList());
  238 +
  239 + this.injectDiscoveredTweakClasses();
  240 + StartupState.PREINIT.completed();
  241 + }
  242 + catch (Throwable th)
237 { 243 {
238 - apisToLoad.addAll(this.apisOption.values(this.parsedOptions)); 244 + LiteLoaderLogger.severe(th, "Error during LiteLoader PREINIT: %s %s", th.getClass().getName(), th.getMessage());
239 } 245 }
240 -  
241 - return apisToLoad;  
242 } 246 }
243 247
244 - protected void registerCoreAPIs(List<String> apisToLoad)  
245 - {  
246 - apisToLoad.add(0, "com.mumfrey.liteloader.client.api.LiteLoaderCoreAPIClient");  
247 - }  
248 -  
249 - private void initJar() 248 + public static void preBeginGame()
250 { 249 {
251 - URL[] urls = Launch.classLoader.getURLs();  
252 - this.jarUrl = urls[urls.length - 1]; // probably? 250 + StartupState.BEGINGAME.gotoState();
  251 + try
  252 + {
  253 + LiteLoaderTweaker.instance.transformerManager.injectDownstreamTransformers(Launch.classLoader);
  254 + LiteLoaderTweaker.instance.bootstrap.preBeginGame();
  255 + StartupState.BEGINGAME.completed();
  256 + }
  257 + catch (Throwable th)
  258 + {
  259 + LiteLoaderLogger.severe(th, "Error during LiteLoader BEGINGAME: %s %s", th.getClass().getName(), th.getMessage());
  260 + }
253 } 261 }
254 262
255 /** 263 /**
256 - * @param args  
257 - * @param gameDirectory  
258 - * @param assetsDirectory 264 + * Do the second stage of loader startup
259 */ 265 */
260 - @SuppressWarnings("unchecked")  
261 - public void initArgs(List<String> args, File gameDirectory, File assetsDirectory) 266 + public static void init()
262 { 267 {
263 - OptionParser optionParser = new OptionParser();  
264 - this.modsOption = optionParser.accepts("mods", "Comma-separated list of mods to load").withRequiredArg().ofType(String.class).withValuesSeparatedBy(',');  
265 - this.apisOption = optionParser.accepts("api", "Additional API classes to load").withRequiredArg().ofType(String.class);  
266 - optionParser.allowsUnrecognizedOptions();  
267 - NonOptionArgumentSpec<String> nonOptions = optionParser.nonOptions(); 268 + StartupState.INIT.gotoState();
268 269
269 - this.parsedOptions = optionParser.parse(args.toArray(new String[args.size()]));  
270 - this.launchArgs = (Map<String, String>)Launch.blackboard.get("launchArgs");  
271 - if (this.launchArgs == null) 270 + try
272 { 271 {
273 - this.launchArgs = new HashMap<String, String>();  
274 - Launch.blackboard.put("launchArgs", this.launchArgs); 272 + LiteLoaderTweaker.instance.bootstrap.init(Launch.classLoader);
  273 + StartupState.INIT.completed();
  274 + }
  275 + catch (Throwable th)
  276 + {
  277 + LiteLoaderLogger.severe(th, "Error during LiteLoader INIT: %s %s", th.getClass().getName(), th.getMessage());
275 } 278 }
276 -  
277 - // Parse out the arguments ourself because joptsimple doesn't really provide a good way to  
278 - // add arguments to the unparsed argument list after parsing  
279 - this.parseArgs(this.parsedOptions.valuesOf(nonOptions));  
280 -  
281 - // Put required arguments to the blackboard if they don't already exist there  
282 - this.provideRequiredArgs(gameDirectory, assetsDirectory);  
283 } 279 }
284 - 280 +
285 /** 281 /**
286 - * @param gameDirectory  
287 - * @param assetsDirectory 282 + * Do the second stage of loader startup
288 */ 283 */
289 - public void provideRequiredArgs(File gameDirectory, File assetsDirectory) 284 + public static void postInit()
290 { 285 {
291 - if (!this.launchArgs.containsKey("--version"))  
292 - this.addClassifiedArg("--version", LiteLoaderTweaker.VERSION);  
293 -  
294 - if (!this.launchArgs.containsKey("--gameDir") && gameDirectory != null)  
295 - this.addClassifiedArg("--gameDir", gameDirectory.getAbsolutePath());  
296 -  
297 - if (!this.launchArgs.containsKey("--assetsDir") && assetsDirectory != null)  
298 - this.addClassifiedArg("--assetsDir", assetsDirectory.getAbsolutePath()); 286 + StartupState.POSTINIT.gotoState();
  287 +
  288 + try
  289 + {
  290 + LiteLoaderTweaker.instance.bootstrap.postInit();
  291 + StartupState.POSTINIT.completed();
  292 +
  293 + StartupState.DONE.gotoState();
  294 + }
  295 + catch (Throwable th)
  296 + {
  297 + LiteLoaderLogger.severe(th, "Error during LiteLoader POSTINIT: %s %s", th.getClass().getName(), th.getMessage());
  298 + }
299 } 299 }
300 300
301 - private void parseArgs(List<String> args) 301 + protected void initEnvironment(List<String> args, File gameDirectory, File assetsDirectory, String profile)
302 { 302 {
303 - String classifier = null;  
304 -  
305 - for (String arg : args) 303 + this.env = new StartupEnvironment(args, gameDirectory, assetsDirectory, profile)
306 { 304 {
307 - if (arg.startsWith("-")) 305 + @Override
  306 + public void registerCoreAPIs(List<String> apisToLoad)
308 { 307 {
309 - if (classifier != null)  
310 - {  
311 - this.addClassifiedArg(classifier, "");  
312 - classifier = null;  
313 - }  
314 - else if (arg.contains("="))  
315 - {  
316 - this.addClassifiedArg(arg.substring(0, arg.indexOf('=')), arg.substring(arg.indexOf('=') + 1));  
317 - }  
318 - else  
319 - {  
320 - classifier = arg;  
321 - } 308 + apisToLoad.add(0, "com.mumfrey.liteloader.client.api.LiteLoaderCoreAPIClient");
322 } 309 }
323 - else 310 +
  311 + @Override
  312 + public int getEnvironmentTypeId()
324 { 313 {
325 - if (classifier != null)  
326 - {  
327 - this.addClassifiedArg(classifier, arg);  
328 - classifier = null;  
329 - }  
330 - else  
331 - this.singularLaunchArgs.add(arg); 314 + return LiteLoaderTweaker.ENV_TYPE_CLIENT;
332 } 315 }
333 - }  
334 - } 316 + };
335 317
336 - private void addClassifiedArg(String classifiedArg, String arg)  
337 - {  
338 - this.launchArgs.put(classifiedArg, arg); 318 + URL[] urls = Launch.classLoader.getURLs();
  319 + this.jarUrl = urls[urls.length - 1]; // probably?
339 } 320 }
340 321
341 @Override 322 @Override
@@ -371,21 +352,7 @@ public class LiteLoaderTweaker implements ITweaker @@ -371,21 +352,7 @@ public class LiteLoaderTweaker implements ITweaker
371 @Override 352 @Override
372 public String[] getLaunchArguments() 353 public String[] getLaunchArguments()
373 { 354 {
374 - List<String> args = new ArrayList<String>();  
375 -  
376 - for (String singularArg : this.singularLaunchArgs)  
377 - args.add(singularArg);  
378 -  
379 - for (Entry<String, String> launchArg : this.launchArgs.entrySet())  
380 - {  
381 - args.add(launchArg.getKey().trim());  
382 - args.add(launchArg.getValue().trim());  
383 - }  
384 -  
385 - this.singularLaunchArgs.clear();  
386 - this.launchArgs.clear();  
387 -  
388 - return args.toArray(new String[args.size()]); 355 + return this.env.getLaunchArguments();
389 } 356 }
390 357
391 public static boolean addCascadedTweaker(String tweakClass, int priority) 358 public static boolean addCascadedTweaker(String tweakClass, int priority)
@@ -485,21 +452,21 @@ public class LiteLoaderTweaker implements ITweaker @@ -485,21 +452,21 @@ public class LiteLoaderTweaker implements ITweaker
485 return false; 452 return false;
486 } 453 }
487 454
488 - protected LoaderBootstrap spawnBootstrap(String bootstrapClassName, ClassLoader classLoader, File gameDirectory, File assetsDirectory, String profile, List<String> apisToLoad) 455 + protected LoaderBootstrap spawnBootstrap(String bootstrapClassName, ClassLoader classLoader)
489 { 456 {
490 if (!StartupState.PREPARE.isInState()) 457 if (!StartupState.PREPARE.isInState())
491 { 458 {
492 - throw new IllegalStateException("spawnBootstrap is not valid outside constructor"); 459 + throw new IllegalStateException("spawnBootstrap is not valid outside PREPARE");
493 } 460 }
494 461
495 try 462 try
496 { 463 {
497 @SuppressWarnings("unchecked") 464 @SuppressWarnings("unchecked")
498 Class<? extends LoaderBootstrap> bootstrapClass = (Class<? extends LoaderBootstrap>)Class.forName(bootstrapClassName, false, classLoader); 465 Class<? extends LoaderBootstrap> bootstrapClass = (Class<? extends LoaderBootstrap>)Class.forName(bootstrapClassName, false, classLoader);
499 - Constructor<? extends LoaderBootstrap> bootstrapCtor = bootstrapClass.getDeclaredConstructor(Integer.TYPE, File.class, File.class, String.class, List.class); 466 + Constructor<? extends LoaderBootstrap> bootstrapCtor = bootstrapClass.getDeclaredConstructor(StartupEnvironment.class);
500 bootstrapCtor.setAccessible(true); 467 bootstrapCtor.setAccessible(true);
501 468
502 - return bootstrapCtor.newInstance(this.getEnvironmentTypeId(), gameDirectory, assetsDirectory, profile, apisToLoad); 469 + return bootstrapCtor.newInstance(this.env);
503 } 470 }
504 catch (Throwable th) 471 catch (Throwable th)
505 { 472 {
@@ -508,113 +475,6 @@ public class LiteLoaderTweaker implements ITweaker @@ -508,113 +475,6 @@ public class LiteLoaderTweaker implements ITweaker
508 475
509 return null; 476 return null;
510 } 477 }
511 -  
512 - protected int getEnvironmentTypeId()  
513 - {  
514 - return LiteLoaderTweaker.ENV_TYPE_CLIENT;  
515 - }  
516 -  
517 - /**  
518 - * @param gameDirectory  
519 - * @param assetsDirectory  
520 - * @param profile  
521 - * @param apisToLoad  
522 - */  
523 - private void prepare(File gameDirectory, File assetsDirectory, String profile, List<String> apisToLoad)  
524 - {  
525 - LiteLoaderLogger.info("Bootstrapping LiteLoader " + LiteLoaderTweaker.VERSION);  
526 -  
527 - try  
528 - {  
529 - this.registerCoreAPIs(apisToLoad);  
530 - this.initJar();  
531 -  
532 - this.bootstrap = this.spawnBootstrap(LiteLoaderTweaker.bootstrapClassName, Launch.classLoader, gameDirectory, assetsDirectory, profile, apisToLoad);  
533 - this.properties = this.bootstrap instanceof LoaderProperties ? (LoaderProperties)this.bootstrap : null;  
534 -  
535 - this.transformerManager = new ClassTransformerManager(this.bootstrap.getRequiredTransformers());  
536 - this.transformerManager.injectTransformers(this.bootstrap.getPacketTransformers());  
537 -  
538 - StartupState.PREPARE.completed();  
539 - }  
540 - catch (Throwable th)  
541 - {  
542 - LiteLoaderLogger.severe(th, "Error during LiteLoader PREPARE: %s %s", th.getClass().getName(), th.getMessage());  
543 - }  
544 - }  
545 -  
546 - /**  
547 - * Do the first stage of loader startup, which enumerates mod sources and finds tweakers  
548 - */  
549 - private void preInit(List<String> modsToLoad)  
550 - {  
551 - StartupState.PREINIT.gotoState();  
552 -  
553 - try  
554 - {  
555 - this.bootstrap.preInit(Launch.classLoader, true, modsToLoad);  
556 -  
557 - this.injectDiscoveredTweakClasses();  
558 - StartupState.PREINIT.completed();  
559 - }  
560 - catch (Throwable th)  
561 - {  
562 - LiteLoaderLogger.severe(th, "Error during LiteLoader PREINIT: %s %s", th.getClass().getName(), th.getMessage());  
563 - }  
564 - }  
565 -  
566 - public static void preBeginGame()  
567 - {  
568 - StartupState.BEGINGAME.gotoState();  
569 - try  
570 - {  
571 - LiteLoaderTweaker.instance.transformerManager.injectDownstreamTransformers(Launch.classLoader);  
572 - LiteLoaderTweaker.instance.bootstrap.preBeginGame();  
573 - StartupState.BEGINGAME.completed();  
574 - }  
575 - catch (Throwable th)  
576 - {  
577 - LiteLoaderLogger.severe(th, "Error during LiteLoader BEGINGAME: %s %s", th.getClass().getName(), th.getMessage());  
578 - }  
579 - }  
580 -  
581 - /**  
582 - * Do the second stage of loader startup  
583 - */  
584 - public static void init()  
585 - {  
586 - StartupState.INIT.gotoState();  
587 -  
588 - try  
589 - {  
590 - LiteLoaderTweaker.instance.bootstrap.init(Launch.classLoader);  
591 - StartupState.INIT.completed();  
592 - }  
593 - catch (Throwable th)  
594 - {  
595 - LiteLoaderLogger.severe(th, "Error during LiteLoader INIT: %s %s", th.getClass().getName(), th.getMessage());  
596 - }  
597 - }  
598 -  
599 - /**  
600 - * Do the second stage of loader startup  
601 - */  
602 - public static void postInit()  
603 - {  
604 - StartupState.POSTINIT.gotoState();  
605 -  
606 - try  
607 - {  
608 - LiteLoaderTweaker.instance.bootstrap.postInit();  
609 - StartupState.POSTINIT.completed();  
610 -  
611 - StartupState.DONE.gotoState();  
612 - }  
613 - catch (Throwable th)  
614 - {  
615 - LiteLoaderLogger.severe(th, "Error during LiteLoader POSTINIT: %s %s", th.getClass().getName(), th.getMessage());  
616 - }  
617 - }  
618 478
619 public static URL getJarUrl() 479 public static URL getJarUrl()
620 { 480 {
java/common/com/mumfrey/liteloader/launch/LiteLoaderTweakerServer.java
1 package com.mumfrey.liteloader.launch; 1 package com.mumfrey.liteloader.launch;
2 2
  3 +import java.io.File;
  4 +import java.net.URL;
3 import java.util.List; 5 import java.util.List;
4 6
  7 +import net.minecraft.launchwrapper.Launch;
  8 +
5 public class LiteLoaderTweakerServer extends LiteLoaderTweaker 9 public class LiteLoaderTweakerServer extends LiteLoaderTweaker
6 { 10 {
7 @Override 11 @Override
8 - protected void registerCoreAPIs(List<String> apisToLoad) 12 + protected void initEnvironment(List<String> args, File gameDirectory, File assetsDirectory, String profile)
9 { 13 {
10 - apisToLoad.add(0, "com.mumfrey.liteloader.server.api.LiteLoaderCoreAPIServer"); 14 + this.env = new StartupEnvironment(args, gameDirectory, assetsDirectory, profile)
  15 + {
  16 + @Override
  17 + public void registerCoreAPIs(List<String> apisToLoad)
  18 + {
  19 + apisToLoad.add(0, "com.mumfrey.liteloader.server.api.LiteLoaderCoreAPIServer");
  20 + }
  21 +
  22 + @Override
  23 + public int getEnvironmentTypeId()
  24 + {
  25 + return LiteLoaderTweaker.ENV_TYPE_DEDICATEDSERVER;
  26 + }
  27 + };
  28 +
  29 + URL[] urls = Launch.classLoader.getURLs();
  30 + this.jarUrl = urls[urls.length - 1]; // probably?
11 } 31 }
12 - 32 +
13 @Override 33 @Override
14 public String getLaunchTarget() 34 public String getLaunchTarget()
15 { 35 {
@@ -17,10 +37,4 @@ public class LiteLoaderTweakerServer extends LiteLoaderTweaker @@ -17,10 +37,4 @@ public class LiteLoaderTweakerServer extends LiteLoaderTweaker
17 37
18 return "net.minecraft.server.MinecraftServer"; 38 return "net.minecraft.server.MinecraftServer";
19 } 39 }
20 -  
21 - @Override  
22 - protected int getEnvironmentTypeId()  
23 - {  
24 - return LiteLoaderTweaker.ENV_TYPE_DEDICATEDSERVER;  
25 - }  
26 } 40 }
java/common/com/mumfrey/liteloader/launch/LoaderBootstrap.java
@@ -42,4 +42,8 @@ public interface LoaderBootstrap @@ -42,4 +42,8 @@ public interface LoaderBootstrap
42 public abstract List<String> getRequiredDownstreamTransformers(); 42 public abstract List<String> getRequiredDownstreamTransformers();
43 43
44 public abstract List<String> getPacketTransformers(); 44 public abstract List<String> getPacketTransformers();
  45 +
  46 + public abstract LoaderEnvironment getEnvironment();
  47 +
  48 + public abstract LoaderProperties getProperties();
45 } 49 }
java/common/com/mumfrey/liteloader/launch/LoaderEnvironment.java
@@ -16,7 +16,7 @@ import com.mumfrey.liteloader.interfaces.LoaderEnumerator; @@ -16,7 +16,7 @@ import com.mumfrey.liteloader.interfaces.LoaderEnumerator;
16 * 16 *
17 * @author Adam Mummery-Smith 17 * @author Adam Mummery-Smith
18 */ 18 */
19 -public interface LoaderEnvironment 19 +public interface LoaderEnvironment extends GameEnvironment
20 { 20 {
21 public enum EnvironmentType 21 public enum EnvironmentType
22 { 22 {
@@ -47,26 +47,6 @@ public interface LoaderEnvironment @@ -47,26 +47,6 @@ public interface LoaderEnvironment
47 public abstract LoaderEnumerator getEnumerator(); 47 public abstract LoaderEnumerator getEnumerator();
48 48
49 /** 49 /**
50 - * Get the game directory, this is the root directory of the game profile specified by the user in the launcher  
51 - */  
52 - public abstract File getGameDirectory();  
53 -  
54 - /**  
55 - * Get the assets directory  
56 - */  
57 - public abstract File getAssetsDirectory();  
58 -  
59 - /**  
60 - * Get the active profile name  
61 - */  
62 - public abstract String getProfile();  
63 -  
64 - /**  
65 - * Get the "mods" folder, used to get the base path for enumerators and config for legacy mods  
66 - */  
67 - public abstract File getModsFolder();  
68 -  
69 - /**  
70 * Get the version-specific mods folder 50 * Get the version-specific mods folder
71 */ 51 */
72 public abstract File getVersionedModsFolder(); 52 public abstract File getVersionedModsFolder();
java/common/com/mumfrey/liteloader/launch/StartupEnvironment.java 0 โ†’ 100644
  1 +package com.mumfrey.liteloader.launch;
  2 +
  3 +import java.io.File;
  4 +import java.util.ArrayList;
  5 +import java.util.HashMap;
  6 +import java.util.List;
  7 +import java.util.Map;
  8 +import java.util.Map.Entry;
  9 +
  10 +import net.minecraft.launchwrapper.Launch;
  11 +import joptsimple.ArgumentAcceptingOptionSpec;
  12 +import joptsimple.NonOptionArgumentSpec;
  13 +import joptsimple.OptionParser;
  14 +import joptsimple.OptionSet;
  15 +
  16 +/**
  17 + * Container for startup environment state which also parses the command line options
  18 + *
  19 + * @author Adam Mummery-Smith
  20 + */
  21 +public abstract class StartupEnvironment implements GameEnvironment
  22 +{
  23 + private List<String> singularLaunchArgs = new ArrayList<String>();
  24 + private Map<String, String> launchArgs;
  25 +
  26 + private ArgumentAcceptingOptionSpec<String> modsDirOption;
  27 + private ArgumentAcceptingOptionSpec<String> modsOption;
  28 + private ArgumentAcceptingOptionSpec<String> apisOption;
  29 + private NonOptionArgumentSpec<String> unparsedOptions;
  30 + private OptionSet parsedOptions;
  31 +
  32 + private final File gameDirectory;
  33 + private final File assetsDirectory;
  34 + private final String profile;
  35 +
  36 + public StartupEnvironment(List<String> args, File gameDirectory, File assetsDirectory, String profile)
  37 + {
  38 + this.initArgs(args);
  39 +
  40 + this.gameDirectory = gameDirectory;
  41 + this.assetsDirectory = assetsDirectory;
  42 + this.profile = profile;
  43 + }
  44 +
  45 + public abstract void registerCoreAPIs(List<String> apisToLoad);
  46 +
  47 + public abstract int getEnvironmentTypeId();
  48 +
  49 + /**
  50 + * @param args
  51 + * @param gameDirectory
  52 + * @param assetsDirectory
  53 + */
  54 + @SuppressWarnings("unchecked")
  55 + public void initArgs(List<String> args)
  56 + {
  57 + // Get the launchArgs map from the blackboard, or create it if it's not there
  58 + this.launchArgs = (Map<String, String>)Launch.blackboard.get("launchArgs");
  59 + if (this.launchArgs == null)
  60 + {
  61 + this.launchArgs = new HashMap<String, String>();
  62 + Launch.blackboard.put("launchArgs", this.launchArgs);
  63 + }
  64 +
  65 + // Parse liteloader options using joptsimple
  66 + this.parseOptions(args.toArray(new String[args.size()]));
  67 +
  68 + // Parse out the arguments ourself because joptsimple doesn't really provide a good way to
  69 + // add arguments to the unparsed argument list after parsing
  70 + this.parseArgs(this.parsedOptions.valuesOf(this.unparsedOptions));
  71 +
  72 + // Put required arguments to the blackboard if they don't already exist there
  73 + this.provideRequiredArgs();
  74 + }
  75 +
  76 + private void parseOptions(String[] args)
  77 + {
  78 + OptionParser optionParser = new OptionParser();
  79 + optionParser.allowsUnrecognizedOptions();
  80 +
  81 + this.modsOption = optionParser.accepts("mods", "Comma-separated list of mods to load").withRequiredArg().ofType(String.class).withValuesSeparatedBy(',');
  82 + this.apisOption = optionParser.accepts("api", "Additional API classes to load").withRequiredArg().ofType(String.class);
  83 + this.modsDirOption = optionParser.accepts("modsDir", "Path to 'mods' folder to use instead of default").withRequiredArg().ofType(String.class);
  84 +
  85 + this.unparsedOptions = optionParser.nonOptions();
  86 + this.parsedOptions = optionParser.parse(args);
  87 + }
  88 +
  89 + private void parseArgs(List<String> args)
  90 + {
  91 + String classifier = null;
  92 +
  93 + for (String arg : args)
  94 + {
  95 + if (arg.startsWith("-"))
  96 + {
  97 + if (classifier != null)
  98 + {
  99 + this.addClassifiedArg(classifier, "");
  100 + classifier = null;
  101 + }
  102 + else if (arg.contains("="))
  103 + {
  104 + this.addClassifiedArg(arg.substring(0, arg.indexOf('=')), arg.substring(arg.indexOf('=') + 1));
  105 + }
  106 + else
  107 + {
  108 + classifier = arg;
  109 + }
  110 + }
  111 + else
  112 + {
  113 + if (classifier != null)
  114 + {
  115 + this.addClassifiedArg(classifier, arg);
  116 + classifier = null;
  117 + }
  118 + else
  119 + this.singularLaunchArgs.add(arg);
  120 + }
  121 + }
  122 +
  123 + if (classifier != null) this.singularLaunchArgs.add(classifier);
  124 + }
  125 +
  126 + public void addClassifiedArg(String classifiedArg, String arg)
  127 + {
  128 + this.launchArgs.put(classifiedArg, arg);
  129 + }
  130 +
  131 + /**
  132 + * @param gameDirectory
  133 + * @param assetsDirectory
  134 + */
  135 + public void provideRequiredArgs()
  136 + {
  137 + if (!this.launchArgs.containsKey("--version"))
  138 + this.addClassifiedArg("--version", LiteLoaderTweaker.VERSION);
  139 +
  140 + if (!this.launchArgs.containsKey("--gameDir") && this.gameDirectory != null)
  141 + this.addClassifiedArg("--gameDir", this.gameDirectory.getAbsolutePath());
  142 +
  143 + if (!this.launchArgs.containsKey("--assetsDir") && this.assetsDirectory != null)
  144 + this.addClassifiedArg("--assetsDir", this.assetsDirectory.getAbsolutePath());
  145 + }
  146 +
  147 + public String[] getLaunchArguments()
  148 + {
  149 + List<String> args = new ArrayList<String>();
  150 +
  151 + for (String singularArg : this.singularLaunchArgs)
  152 + args.add(singularArg);
  153 +
  154 + for (Entry<String, String> launchArg : this.launchArgs.entrySet())
  155 + {
  156 + args.add(launchArg.getKey().trim());
  157 + args.add(launchArg.getValue().trim());
  158 + }
  159 +
  160 + this.singularLaunchArgs.clear();
  161 + this.launchArgs.clear();
  162 +
  163 + return args.toArray(new String[args.size()]);
  164 + }
  165 +
  166 + /**
  167 + * @return
  168 + */
  169 + public List<String> getModFilterList()
  170 + {
  171 + return (this.parsedOptions.has(this.modsOption)) ? this.modsOption.values(this.parsedOptions) : null;
  172 + }
  173 +
  174 + /**
  175 + * @return
  176 + */
  177 + public List<String> getAPIsToLoad()
  178 + {
  179 + List<String> apisToLoad = new ArrayList<String>();
  180 + this.registerCoreAPIs(apisToLoad);
  181 + if (this.parsedOptions.has(this.apisOption))
  182 + {
  183 + apisToLoad.addAll(this.apisOption.values(this.parsedOptions));
  184 + }
  185 +
  186 + return apisToLoad;
  187 + }
  188 +
  189 + public File getOptionalDirectory(File baseDirectory, ArgumentAcceptingOptionSpec<String> option, String defaultDir)
  190 + {
  191 + if (this.parsedOptions.has(option))
  192 + {
  193 + String path = option.value(this.parsedOptions);
  194 + File dir = new File(path);
  195 + if (dir.isAbsolute())
  196 + return dir;
  197 +
  198 + return new File(baseDirectory, path);
  199 + }
  200 +
  201 + return new File(baseDirectory, defaultDir);
  202 + }
  203 +
  204 + @Override
  205 + public File getGameDirectory()
  206 + {
  207 + return this.gameDirectory;
  208 + }
  209 +
  210 + @Override
  211 + public File getAssetsDirectory()
  212 + {
  213 + return this.assetsDirectory;
  214 + }
  215 +
  216 + @Override
  217 + public String getProfile()
  218 + {
  219 + return this.profile;
  220 + }
  221 +
  222 + @Override
  223 + public File getModsFolder()
  224 + {
  225 + return this.getOptionalDirectory(this.gameDirectory, this.modsDirOption, "mods");
  226 + }
  227 +}