Commit 09ab166d80d1cd803a1ff7454f3ac2975af0d25b
Merge branch '1.11.2-backport' into 1.11.2
Showing
28 changed files
with
1433 additions
and
440 deletions
build.gradle
@@ -72,7 +72,7 @@ repositories { | @@ -72,7 +72,7 @@ repositories { | ||
72 | } | 72 | } |
73 | 73 | ||
74 | dependencies { | 74 | dependencies { |
75 | - compile('org.spongepowered:mixin:0.7.1-SNAPSHOT') { | 75 | + compile('org.spongepowered:mixin:0.7.3-SNAPSHOT') { |
76 | exclude module: 'asm-commons' | 76 | exclude module: 'asm-commons' |
77 | exclude module: 'asm-tree' | 77 | exclude module: 'asm-tree' |
78 | exclude module: 'launchwrapper' | 78 | exclude module: 'launchwrapper' |
src/client/java/com/mumfrey/liteloader/client/gui/GuiPanelLiteLoaderLog.java
@@ -290,6 +290,9 @@ class GuiPanelLiteLoaderLog extends GuiPanel implements ScrollPanelContent | @@ -290,6 +290,9 @@ class GuiPanelLiteLoaderLog extends GuiPanel implements ScrollPanelContent | ||
290 | if (logLine.startsWith("tweakClass '")) return 0x5555FF; | 290 | if (logLine.startsWith("tweakClass '")) return 0x5555FF; |
291 | if (logLine.startsWith("baking listener list")) return 0x00AAAA; | 291 | if (logLine.startsWith("baking listener list")) return 0x00AAAA; |
292 | if (logLine.startsWith("generating new event handler")) return 0xFFFF55; | 292 | if (logLine.startsWith("generating new event handler")) return 0xFFFF55; |
293 | + if (logLine.startsWith("resolving mods")) return 0xFFAA00; | ||
294 | + if (logLine.startsWith("resolved artefact")) return 0x00AA00; | ||
295 | + if (logLine.startsWith("evicting")) return 0xFFAA00; | ||
293 | 296 | ||
294 | return 0xCCCCCC; | 297 | return 0xCCCCCC; |
295 | } | 298 | } |
src/client/java/com/mumfrey/liteloader/modconfig/AbstractConfigPanel.java
@@ -105,7 +105,7 @@ public abstract class AbstractConfigPanel implements ConfigPanel | @@ -105,7 +105,7 @@ public abstract class AbstractConfigPanel implements ConfigPanel | ||
105 | /** | 105 | /** |
106 | * Base for config option handle structs | 106 | * Base for config option handle structs |
107 | */ | 107 | */ |
108 | - static abstract class ConfigOption | 108 | + abstract static class ConfigOption |
109 | { | 109 | { |
110 | void onTick() | 110 | void onTick() |
111 | { | 111 | { |
@@ -303,7 +303,7 @@ public abstract class AbstractConfigPanel implements ConfigPanel | @@ -303,7 +303,7 @@ public abstract class AbstractConfigPanel implements ConfigPanel | ||
303 | @Override | 303 | @Override |
304 | public ConfigTextField setRegex(String regex, boolean force) | 304 | public ConfigTextField setRegex(String regex, boolean force) |
305 | { | 305 | { |
306 | - this.textField.setRegex(Pattern.compile(regex), force);; | 306 | + this.textField.setRegex(Pattern.compile(regex), force); |
307 | return this; | 307 | return this; |
308 | } | 308 | } |
309 | 309 | ||
@@ -343,7 +343,8 @@ public abstract class AbstractConfigPanel implements ConfigPanel | @@ -343,7 +343,8 @@ public abstract class AbstractConfigPanel implements ConfigPanel | ||
343 | } | 343 | } |
344 | else | 344 | else |
345 | { | 345 | { |
346 | - this.setValidator((text) -> { | 346 | + this.setValidator((text) -> |
347 | + { | ||
347 | this.validate(text); | 348 | this.validate(text); |
348 | return true; | 349 | return true; |
349 | }); | 350 | }); |
src/main/java/com/mumfrey/liteloader/api/EnumeratorModule.java
@@ -36,10 +36,7 @@ public interface EnumeratorModule | @@ -36,10 +36,7 @@ public interface EnumeratorModule | ||
36 | public abstract void writeSettings(LoaderEnvironment environment, LoaderProperties properties); | 36 | public abstract void writeSettings(LoaderEnvironment environment, LoaderProperties properties); |
37 | 37 | ||
38 | /** | 38 | /** |
39 | - * Find loadable mods in this enumerator's domain, the enumerator module | ||
40 | - * should call back against the enumerator itself to register containers it | ||
41 | - * discovers using the registerModContainer() and registerTweakContainer() | ||
42 | - * callbacks. | 39 | + * Find loadable mods in this enumerator's domain. |
43 | * | 40 | * |
44 | * <p>This method is called during loader PREINIT phase so <b>do not use any | 41 | * <p>This method is called during loader PREINIT phase so <b>do not use any |
45 | * game classes here</b>!</p> | 42 | * game classes here</b>!</p> |
@@ -48,6 +45,20 @@ public interface EnumeratorModule | @@ -48,6 +45,20 @@ public interface EnumeratorModule | ||
48 | * @param profile | 45 | * @param profile |
49 | */ | 46 | */ |
50 | public abstract void enumerate(ModularEnumerator enumerator, String profile); | 47 | public abstract void enumerate(ModularEnumerator enumerator, String profile); |
48 | + | ||
49 | + /** | ||
50 | + * Register loadable mods discovered in this enumerator's domain during the | ||
51 | + * call to {@link #enumerate}, the enumerator module should call back | ||
52 | + * against the enumerator itself to register containers it discovers using | ||
53 | + * the registerModContainer() and registerTweakContainer() callbacks. | ||
54 | + * | ||
55 | + * <p>This method is called during loader PREINIT phase so <b>do not use any | ||
56 | + * game classes here</b>!</p> | ||
57 | + * | ||
58 | + * @param enumerator | ||
59 | + * @param profile | ||
60 | + */ | ||
61 | + public abstract void register(ModularEnumerator enumerator, String profile); | ||
51 | 62 | ||
52 | /** | 63 | /** |
53 | * The enumerator module should inject (as required) any discovered | 64 | * The enumerator module should inject (as required) any discovered |
src/main/java/com/mumfrey/liteloader/core/EnabledModsList.java
@@ -8,7 +8,6 @@ package com.mumfrey.liteloader.core; | @@ -8,7 +8,6 @@ package com.mumfrey.liteloader.core; | ||
8 | import java.io.File; | 8 | import java.io.File; |
9 | import java.io.FileReader; | 9 | import java.io.FileReader; |
10 | import java.io.FileWriter; | 10 | import java.io.FileWriter; |
11 | -import java.io.IOException; | ||
12 | import java.util.List; | 11 | import java.util.List; |
13 | import java.util.Map; | 12 | import java.util.Map; |
14 | import java.util.TreeMap; | 13 | import java.util.TreeMap; |
@@ -186,12 +185,9 @@ public final class EnabledModsList | @@ -186,12 +185,9 @@ public final class EnabledModsList | ||
186 | { | 185 | { |
187 | if (file.exists()) | 186 | if (file.exists()) |
188 | { | 187 | { |
189 | - FileReader reader = null; | ||
190 | - | ||
191 | - try | 188 | + try (FileReader reader = new FileReader(file)) |
192 | { | 189 | { |
193 | - reader = new FileReader(file); | ||
194 | - EnabledModsList instance = gson.fromJson(reader, EnabledModsList.class); | 190 | + EnabledModsList instance = EnabledModsList.gson.fromJson(reader, EnabledModsList.class); |
195 | instance.setEnabledModsFile(file); | 191 | instance.setEnabledModsFile(file); |
196 | return instance; | 192 | return instance; |
197 | } | 193 | } |
@@ -199,20 +195,6 @@ public final class EnabledModsList | @@ -199,20 +195,6 @@ public final class EnabledModsList | ||
199 | { | 195 | { |
200 | ex.printStackTrace(); | 196 | ex.printStackTrace(); |
201 | } | 197 | } |
202 | - finally | ||
203 | - { | ||
204 | - try | ||
205 | - { | ||
206 | - if (reader != null) | ||
207 | - { | ||
208 | - reader.close(); | ||
209 | - } | ||
210 | - } | ||
211 | - catch (IOException ex) | ||
212 | - { | ||
213 | - ex.printStackTrace(); | ||
214 | - } | ||
215 | - } | ||
216 | } | 198 | } |
217 | 199 | ||
218 | EnabledModsList instance = new EnabledModsList(); | 200 | EnabledModsList instance = new EnabledModsList(); |
@@ -229,31 +211,14 @@ public final class EnabledModsList | @@ -229,31 +211,14 @@ public final class EnabledModsList | ||
229 | { | 211 | { |
230 | if (!this.allowSave) return; | 212 | if (!this.allowSave) return; |
231 | 213 | ||
232 | - FileWriter writer = null; | ||
233 | - | ||
234 | - try | 214 | + try (FileWriter writer = new FileWriter(file)) |
235 | { | 215 | { |
236 | - writer = new FileWriter(file); | ||
237 | - gson.toJson(this, writer); | 216 | + EnabledModsList.gson.toJson(this, writer); |
238 | } | 217 | } |
239 | catch (Exception ex) | 218 | catch (Exception ex) |
240 | { | 219 | { |
241 | ex.printStackTrace(); | 220 | ex.printStackTrace(); |
242 | } | 221 | } |
243 | - finally | ||
244 | - { | ||
245 | - try | ||
246 | - { | ||
247 | - if (writer != null) | ||
248 | - { | ||
249 | - writer.close(); | ||
250 | - } | ||
251 | - } | ||
252 | - catch (IOException ex) | ||
253 | - { | ||
254 | - ex.printStackTrace(); | ||
255 | - } | ||
256 | - } | ||
257 | } | 222 | } |
258 | 223 | ||
259 | /** | 224 | /** |
src/main/java/com/mumfrey/liteloader/core/LiteLoaderBootstrap.java
@@ -29,6 +29,7 @@ import com.mumfrey.liteloader.api.manager.APIProvider; | @@ -29,6 +29,7 @@ import com.mumfrey.liteloader.api.manager.APIProvider; | ||
29 | import com.mumfrey.liteloader.api.manager.APIRegistry; | 29 | import com.mumfrey.liteloader.api.manager.APIRegistry; |
30 | import com.mumfrey.liteloader.common.LoadingProgress; | 30 | import com.mumfrey.liteloader.common.LoadingProgress; |
31 | import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; | 31 | import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; |
32 | +import com.mumfrey.liteloader.core.api.repository.Repository; | ||
32 | import com.mumfrey.liteloader.interfaces.LoaderEnumerator; | 33 | import com.mumfrey.liteloader.interfaces.LoaderEnumerator; |
33 | import com.mumfrey.liteloader.launch.ClassTransformerManager; | 34 | import com.mumfrey.liteloader.launch.ClassTransformerManager; |
34 | import com.mumfrey.liteloader.launch.LiteLoaderTweaker; | 35 | import com.mumfrey.liteloader.launch.LiteLoaderTweaker; |
@@ -102,6 +103,16 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -102,6 +103,16 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
102 | * Folder containing version-specific configuration | 103 | * Folder containing version-specific configuration |
103 | */ | 104 | */ |
104 | private final File versionConfigFolder; | 105 | private final File versionConfigFolder; |
106 | + | ||
107 | + /** | ||
108 | + * Mods repo file | ||
109 | + */ | ||
110 | + private final String repositoryFile; | ||
111 | + | ||
112 | + /** | ||
113 | + * Mod repository defined in JSON | ||
114 | + */ | ||
115 | + private final Repository repository; | ||
105 | 116 | ||
106 | /** | 117 | /** |
107 | * File to write log entries to | 118 | * File to write log entries to |
@@ -138,6 +149,8 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -138,6 +149,8 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
138 | 149 | ||
139 | private LaunchClassLoader classLoader; | 150 | private LaunchClassLoader classLoader; |
140 | 151 | ||
152 | + private final StartupEnvironment env; | ||
153 | + | ||
141 | private final ITweaker tweaker; | 154 | private final ITweaker tweaker; |
142 | 155 | ||
143 | private final APIRegistry apiRegistry; | 156 | private final APIRegistry apiRegistry; |
@@ -157,7 +170,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -157,7 +170,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
157 | * List of mods passed into the command line | 170 | * List of mods passed into the command line |
158 | */ | 171 | */ |
159 | private EnabledModsList enabledModsList; | 172 | private EnabledModsList enabledModsList; |
160 | - | 173 | + |
161 | /** | 174 | /** |
162 | * @param env | 175 | * @param env |
163 | * @param tweaker | 176 | * @param tweaker |
@@ -165,6 +178,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -165,6 +178,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
165 | public LiteLoaderBootstrap(StartupEnvironment env, ITweaker tweaker) | 178 | public LiteLoaderBootstrap(StartupEnvironment env, ITweaker tweaker) |
166 | { | 179 | { |
167 | this.environmentType = EnvironmentType.values()[env.getEnvironmentTypeId()]; | 180 | this.environmentType = EnvironmentType.values()[env.getEnvironmentTypeId()]; |
181 | + this.env = env; | ||
168 | this.tweaker = tweaker; | 182 | this.tweaker = tweaker; |
169 | 183 | ||
170 | this.apiRegistry = new APIRegistry(this.getEnvironment(), this.getProperties()); | 184 | this.apiRegistry = new APIRegistry(this.getEnvironment(), this.getProperties()); |
@@ -173,6 +187,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -173,6 +187,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
173 | this.assetsDirectory = env.getAssetsDirectory(); | 187 | this.assetsDirectory = env.getAssetsDirectory(); |
174 | this.profile = env.getProfile(); | 188 | this.profile = env.getProfile(); |
175 | this.modsFolder = env.getModsFolder(); | 189 | this.modsFolder = env.getModsFolder(); |
190 | + this.repositoryFile = env.getModsRepoFile(); | ||
176 | 191 | ||
177 | this.versionedModsFolder = new File(this.modsFolder, LiteLoaderVersion.CURRENT.getMinecraftVersion()); | 192 | this.versionedModsFolder = new File(this.modsFolder, LiteLoaderVersion.CURRENT.getMinecraftVersion()); |
178 | this.configBaseFolder = new File(this.gameDirectory, "liteconfig"); | 193 | this.configBaseFolder = new File(this.gameDirectory, "liteconfig"); |
@@ -183,17 +198,27 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -183,17 +198,27 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
183 | this.commonConfigFolder = new File(this.configBaseFolder, "common"); | 198 | this.commonConfigFolder = new File(this.configBaseFolder, "common"); |
184 | this.versionConfigFolder = this.inflectVersionedConfigPath(LiteLoaderVersion.CURRENT); | 199 | this.versionConfigFolder = this.inflectVersionedConfigPath(LiteLoaderVersion.CURRENT); |
185 | 200 | ||
186 | - if (!this.modsFolder.exists()) this.modsFolder.mkdirs(); | ||
187 | - if (!this.versionedModsFolder.exists()) this.versionedModsFolder.mkdirs(); | ||
188 | - if (!this.configBaseFolder.exists()) this.configBaseFolder.mkdirs(); | ||
189 | - if (!this.commonConfigFolder.exists()) this.commonConfigFolder.mkdirs(); | ||
190 | - if (!this.versionConfigFolder.exists()) this.versionConfigFolder.mkdirs(); | 201 | + this.repository = new Repository(this.gameDirectory, this.versionedModsFolder); |
202 | + | ||
203 | + this.mkdir(this.modsFolder); | ||
204 | + this.mkdir(this.versionedModsFolder); | ||
205 | + this.mkdir(this.configBaseFolder); | ||
206 | + this.mkdir(this.commonConfigFolder); | ||
207 | + this.mkdir(this.versionConfigFolder); | ||
191 | 208 | ||
192 | this.initAPIs(env.getAPIsToLoad()); | 209 | this.initAPIs(env.getAPIsToLoad()); |
193 | this.apiProvider = this.apiRegistry.getProvider(); | 210 | this.apiProvider = this.apiRegistry.getProvider(); |
194 | this.apiAdapter = this.apiRegistry.getAdapter(); | 211 | this.apiAdapter = this.apiRegistry.getAdapter(); |
195 | } | 212 | } |
196 | 213 | ||
214 | + private void mkdir(File dir) | ||
215 | + { | ||
216 | + if (!dir.isDirectory()) | ||
217 | + { | ||
218 | + dir.mkdirs(); | ||
219 | + } | ||
220 | + } | ||
221 | + | ||
197 | /** | 222 | /** |
198 | * @param version | 223 | * @param version |
199 | */ | 224 | */ |
@@ -249,6 +274,12 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -249,6 +274,12 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
249 | { | 274 | { |
250 | return this.enabledModsList; | 275 | return this.enabledModsList; |
251 | } | 276 | } |
277 | + | ||
278 | + @Override | ||
279 | + public Repository getModRepository() | ||
280 | + { | ||
281 | + return this.repository; | ||
282 | + } | ||
252 | 283 | ||
253 | @Override | 284 | @Override |
254 | public LoaderEnumerator getEnumerator() | 285 | public LoaderEnumerator getEnumerator() |
@@ -301,15 +332,20 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -301,15 +332,20 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
301 | * #preInit(net.minecraft.launchwrapper.LaunchClassLoader, boolean) | 332 | * #preInit(net.minecraft.launchwrapper.LaunchClassLoader, boolean) |
302 | */ | 333 | */ |
303 | @Override | 334 | @Override |
304 | - public void preInit(LaunchClassLoader classLoader, boolean loadTweaks, List<String> modsToLoad) | 335 | + public void preInit(LaunchClassLoader classLoader, boolean loadTweaks) |
305 | { | 336 | { |
337 | + List<String> modsToLoad = this.env.getModFilterList(); | ||
338 | + | ||
306 | this.classLoader = classLoader; | 339 | this.classLoader = classLoader; |
307 | this.loadTweaks = loadTweaks; | 340 | this.loadTweaks = loadTweaks; |
308 | 341 | ||
309 | LiteLoaderLogger.info(Verbosity.REDUCED, "LiteLoader begin PREINIT..."); | 342 | LiteLoaderLogger.info(Verbosity.REDUCED, "LiteLoader begin PREINIT..."); |
310 | 343 | ||
311 | // Set up the bootstrap | 344 | // Set up the bootstrap |
312 | - if (!this.prepare()) return; | 345 | + if (!this.prepare()) |
346 | + { | ||
347 | + return; | ||
348 | + } | ||
313 | 349 | ||
314 | LiteLoaderLogger.info(Verbosity.REDUCED, "LiteLoader %s starting up...", LiteLoaderVersion.CURRENT.getLoaderVersion()); | 350 | LiteLoaderLogger.info(Verbosity.REDUCED, "LiteLoader %s starting up...", LiteLoaderVersion.CURRENT.getLoaderVersion()); |
315 | 351 | ||
@@ -323,7 +359,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -323,7 +359,7 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
323 | 359 | ||
324 | this.enabledModsList = EnabledModsList.createFrom(this.enabledModsFile); | 360 | this.enabledModsList = EnabledModsList.createFrom(this.enabledModsFile); |
325 | this.enabledModsList.processModsList(this.profile, modsToLoad); | 361 | this.enabledModsList.processModsList(this.profile, modsToLoad); |
326 | - | 362 | + |
327 | this.enumerator = this.spawnEnumerator(classLoader); | 363 | this.enumerator = this.spawnEnumerator(classLoader); |
328 | this.enumerator.onPreInit(); | 364 | this.enumerator.onPreInit(); |
329 | 365 | ||
@@ -599,6 +635,16 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | @@ -599,6 +635,16 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP | ||
599 | { | 635 | { |
600 | return this.versionConfigFolder; | 636 | return this.versionConfigFolder; |
601 | } | 637 | } |
638 | + | ||
639 | + /** | ||
640 | + * Get the path to a JSON file describing a mod repository layout, can be | ||
641 | + * null if not defined | ||
642 | + */ | ||
643 | + @Override | ||
644 | + public String getModsRepoFile() | ||
645 | + { | ||
646 | + return this.repositoryFile; | ||
647 | + } | ||
602 | 648 | ||
603 | /** | 649 | /** |
604 | * Get a boolean propery from the properties file and also write the new | 650 | * Get a boolean propery from the properties file and also write the new |
src/main/java/com/mumfrey/liteloader/core/LiteLoaderEnumerator.java
@@ -122,7 +122,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -122,7 +122,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
122 | private final FastIterableDeque<EnumerationObserver> observers = new HandlerList<EnumerationObserver>(EnumerationObserver.class); | 122 | private final FastIterableDeque<EnumerationObserver> observers = new HandlerList<EnumerationObserver>(EnumerationObserver.class); |
123 | 123 | ||
124 | protected EnumeratorState state = EnumeratorState.INIT; | 124 | protected EnumeratorState state = EnumeratorState.INIT; |
125 | - | 125 | + |
126 | /** | 126 | /** |
127 | * @param environment | 127 | * @param environment |
128 | * @param properties | 128 | * @param properties |
@@ -144,7 +144,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -144,7 +144,7 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
144 | // Initialise the shared mod list if we haven't already | 144 | // Initialise the shared mod list if we haven't already |
145 | this.getSharedModList(); | 145 | this.getSharedModList(); |
146 | } | 146 | } |
147 | - | 147 | + |
148 | /** | 148 | /** |
149 | * @param environment | 149 | * @param environment |
150 | */ | 150 | */ |
@@ -397,11 +397,13 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -397,11 +397,13 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
397 | { | 397 | { |
398 | this.gotoState(EnumeratorState.DISCOVER); | 398 | this.gotoState(EnumeratorState.DISCOVER); |
399 | 399 | ||
400 | + String profile = this.environment.getProfile(); | ||
401 | + | ||
400 | for (EnumeratorModule module : this.modules) | 402 | for (EnumeratorModule module : this.modules) |
401 | { | 403 | { |
402 | try | 404 | try |
403 | { | 405 | { |
404 | - module.enumerate(this, this.environment.getProfile()); | 406 | + module.enumerate(this, profile); |
405 | } | 407 | } |
406 | catch (Throwable th) | 408 | catch (Throwable th) |
407 | { | 409 | { |
@@ -409,6 +411,18 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -409,6 +411,18 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
409 | } | 411 | } |
410 | } | 412 | } |
411 | 413 | ||
414 | + for (EnumeratorModule module : this.modules) | ||
415 | + { | ||
416 | + try | ||
417 | + { | ||
418 | + module.register(this, profile); | ||
419 | + } | ||
420 | + catch (Throwable th) | ||
421 | + { | ||
422 | + LiteLoaderLogger.warning(th, "Enumerator Module %s encountered an error whilst enumerating", module.getClass().getName()); | ||
423 | + } | ||
424 | + } | ||
425 | + | ||
412 | this.checkDependencies(); | 426 | this.checkDependencies(); |
413 | } | 427 | } |
414 | 428 | ||
@@ -651,7 +665,15 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | @@ -651,7 +665,15 @@ public class LiteLoaderEnumerator implements LoaderEnumerator | ||
651 | if (config.endsWith(".json")) | 665 | if (config.endsWith(".json")) |
652 | { | 666 | { |
653 | LiteLoaderLogger.info(Verbosity.REDUCED, "Registering mixin config %s for %s", config, container.getName()); | 667 | LiteLoaderLogger.info(Verbosity.REDUCED, "Registering mixin config %s for %s", config, container.getName()); |
654 | - Mixins.addConfiguration(config); | 668 | + try |
669 | + { | ||
670 | + Mixins.addConfiguration(config); | ||
671 | + } | ||
672 | + catch (Throwable th) | ||
673 | + { | ||
674 | + LiteLoaderLogger.severe(th, "Error registering mixin config %s for %s", config, container); | ||
675 | + container.registerMixinError(th); | ||
676 | + } | ||
655 | } | 677 | } |
656 | else if (config.contains(".json@")) | 678 | else if (config.contains(".json@")) |
657 | { | 679 | { |
src/main/java/com/mumfrey/liteloader/core/LiteLoaderMods.java
@@ -24,6 +24,7 @@ import com.mumfrey.liteloader.interfaces.FastIterableDeque; | @@ -24,6 +24,7 @@ import com.mumfrey.liteloader.interfaces.FastIterableDeque; | ||
24 | import com.mumfrey.liteloader.interfaces.Loadable; | 24 | import com.mumfrey.liteloader.interfaces.Loadable; |
25 | import com.mumfrey.liteloader.interfaces.LoadableMod; | 25 | import com.mumfrey.liteloader.interfaces.LoadableMod; |
26 | import com.mumfrey.liteloader.interfaces.LoaderEnumerator; | 26 | import com.mumfrey.liteloader.interfaces.LoaderEnumerator; |
27 | +import com.mumfrey.liteloader.interfaces.MixinContainer; | ||
27 | import com.mumfrey.liteloader.interfaces.TweakContainer; | 28 | import com.mumfrey.liteloader.interfaces.TweakContainer; |
28 | import com.mumfrey.liteloader.launch.ClassTransformerManager; | 29 | import com.mumfrey.liteloader.launch.ClassTransformerManager; |
29 | import com.mumfrey.liteloader.launch.LoaderEnvironment; | 30 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
@@ -444,6 +445,12 @@ public class LiteLoaderMods | @@ -444,6 +445,12 @@ public class LiteLoaderMods | ||
444 | String identifier = mod.getIdentifier(); | 445 | String identifier = mod.getIdentifier(); |
445 | if (identifier == null || this.environment.getEnabledModsList().isEnabled(this.environment.getProfile(), identifier)) | 446 | if (identifier == null || this.environment.getEnabledModsList().isEnabled(this.environment.getProfile(), identifier)) |
446 | { | 447 | { |
448 | + if (!this.validateMixins(mod, container)) | ||
449 | + { | ||
450 | + this.onModLoadFailed(container, identifier, "mixins for the specified mod encountered a startup error", null); | ||
451 | + continue; | ||
452 | + } | ||
453 | + | ||
447 | if (!this.enumerator.checkDependencies(container)) | 454 | if (!this.enumerator.checkDependencies(container)) |
448 | { | 455 | { |
449 | this.onModLoadFailed(container, identifier, "the mod was missing a required dependency", null); | 456 | this.onModLoadFailed(container, identifier, "the mod was missing a required dependency", null); |
@@ -474,6 +481,23 @@ public class LiteLoaderMods | @@ -474,6 +481,23 @@ public class LiteLoaderMods | ||
474 | this.observers.all().onPostModLoaded(mod); | 481 | this.observers.all().onPostModLoaded(mod); |
475 | } | 482 | } |
476 | } | 483 | } |
484 | + | ||
485 | + private boolean validateMixins(ModInfo<?> mod, LoadableMod<?> container) | ||
486 | + { | ||
487 | + if (container instanceof MixinContainer) | ||
488 | + { | ||
489 | + @SuppressWarnings("unchecked") | ||
490 | + Collection<Throwable> errors = ((MixinContainer<File>)container).getMixinErrors(); | ||
491 | + for (Throwable error : errors) | ||
492 | + { | ||
493 | + this.registerModStartupError(mod, error, true); | ||
494 | + } | ||
495 | + | ||
496 | + return errors.size() == 0; | ||
497 | + } | ||
498 | + | ||
499 | + return true; | ||
500 | + } | ||
477 | 501 | ||
478 | /** | 502 | /** |
479 | * @param identifier | 503 | * @param identifier |
@@ -697,26 +721,28 @@ public class LiteLoaderMods | @@ -697,26 +721,28 @@ public class LiteLoaderMods | ||
697 | 721 | ||
698 | for (Mod mod : this.loadedMods) | 722 | for (Mod mod : this.loadedMods) |
699 | { | 723 | { |
700 | - if (mod.hasClassTransformers()) | 724 | + if (!mod.hasClassTransformers()) |
701 | { | 725 | { |
702 | - List<String> modTransformers = ((TweakContainer<?>)mod.getContainer()).getClassTransformerClassNames(); | ||
703 | - for (String modTransformer : modTransformers) | 726 | + continue; |
727 | + } | ||
728 | + | ||
729 | + List<String> modTransformers = ((TweakContainer<?>)mod.getContainer()).getClassTransformerClassNames(); | ||
730 | + for (String modTransformer : modTransformers) | ||
731 | + { | ||
732 | + if (!injectedTransformers.contains(modTransformer)) | ||
704 | { | 733 | { |
705 | - if (!injectedTransformers.contains(modTransformer)) | 734 | + List<Throwable> throwables = transformerManager.getTransformerStartupErrors(modTransformer); |
735 | + if (throwables != null) | ||
706 | { | 736 | { |
707 | - List<Throwable> throwables = transformerManager.getTransformerStartupErrors(modTransformer); | ||
708 | - if (throwables != null) | 737 | + for (Throwable th : throwables) |
709 | { | 738 | { |
710 | - for (Throwable th : throwables) | ||
711 | - { | ||
712 | - this.registerModStartupError(mod, th, true); | ||
713 | - } | ||
714 | - } | ||
715 | - else | ||
716 | - { | ||
717 | - this.registerModStartupError(mod, new RuntimeException("Missing class transformer " + modTransformer), true); | 739 | + this.registerModStartupError(mod, th, true); |
718 | } | 740 | } |
719 | } | 741 | } |
742 | + else | ||
743 | + { | ||
744 | + this.registerModStartupError(mod, new RuntimeException("Missing class transformer " + modTransformer), true); | ||
745 | + } | ||
720 | } | 746 | } |
721 | } | 747 | } |
722 | } | 748 | } |
@@ -765,7 +791,11 @@ public class LiteLoaderMods | @@ -765,7 +791,11 @@ public class LiteLoaderMods | ||
765 | private void registerModStartupError(ModInfo<?> mod, Throwable th, boolean critical) | 791 | private void registerModStartupError(ModInfo<?> mod, Throwable th, boolean critical) |
766 | { | 792 | { |
767 | this.startupErrorCount++; | 793 | this.startupErrorCount++; |
768 | - if (critical) this.criticalErrorCount++; | 794 | + if (critical) |
795 | + { | ||
796 | + this.criticalErrorCount++; | ||
797 | + } | ||
798 | + | ||
769 | mod.registerStartupError(th); | 799 | mod.registerStartupError(th); |
770 | 800 | ||
771 | if (!this.loadedMods.contains(mod) && !this.disabledMods.contains(mod)) | 801 | if (!this.loadedMods.contains(mod) && !this.disabledMods.contains(mod)) |
src/main/java/com/mumfrey/liteloader/core/api/EnumeratorModuleClassPath.java
@@ -82,37 +82,43 @@ public class EnumeratorModuleClassPath implements EnumeratorModule | @@ -82,37 +82,43 @@ public class EnumeratorModuleClassPath implements EnumeratorModule | ||
82 | @Override | 82 | @Override |
83 | public void enumerate(ModularEnumerator enumerator, String profile) | 83 | public void enumerate(ModularEnumerator enumerator, String profile) |
84 | { | 84 | { |
85 | - if (this.loadTweaks) | 85 | + } |
86 | + | ||
87 | + @Override | ||
88 | + public void register(ModularEnumerator enumerator, String profile) | ||
89 | + { | ||
90 | + if (!this.loadTweaks) | ||
86 | { | 91 | { |
87 | - LiteLoaderLogger.info("Discovering tweaks on class path..."); | ||
88 | - | ||
89 | - for (String classPathPart : this.classPathEntries) | 92 | + return; |
93 | + } | ||
94 | + | ||
95 | + LiteLoaderLogger.info("Discovering tweaks on class path..."); | ||
96 | + for (String classPathPart : this.classPathEntries) | ||
97 | + { | ||
98 | + try | ||
90 | { | 99 | { |
91 | - try | 100 | + File packagePath = new File(classPathPart); |
101 | + if (packagePath.exists()) | ||
92 | { | 102 | { |
93 | - File packagePath = new File(classPathPart); | ||
94 | - if (packagePath.exists()) | 103 | + LoadableModClassPath classPathMod = new LoadableModClassPath(packagePath); |
104 | + if (enumerator.registerModContainer(classPathMod)) | ||
95 | { | 105 | { |
96 | - LoadableModClassPath classPathMod = new LoadableModClassPath(packagePath); | ||
97 | - if (enumerator.registerModContainer(classPathMod)) | 106 | + this.loadableMods.add(classPathMod); |
107 | + if (classPathMod.requiresPreInitInjection()) | ||
98 | { | 108 | { |
99 | - this.loadableMods.add(classPathMod); | ||
100 | - if (classPathMod.requiresPreInitInjection()) | ||
101 | - { | ||
102 | - enumerator.registerTweakContainer(classPathMod); | ||
103 | - } | ||
104 | - } | ||
105 | - else | ||
106 | - { | ||
107 | - LiteLoaderLogger.info(Verbosity.REDUCED, "Mod %s is disabled or missing a required dependency, not injecting tranformers", | ||
108 | - classPathMod.getIdentifier()); | 109 | + enumerator.registerTweakContainer(classPathMod); |
109 | } | 110 | } |
110 | } | 111 | } |
112 | + else | ||
113 | + { | ||
114 | + LiteLoaderLogger.info(Verbosity.REDUCED, "Mod %s is disabled or missing a required dependency, not injecting tranformers", | ||
115 | + classPathMod.getIdentifier()); | ||
116 | + } | ||
111 | } | 117 | } |
112 | - catch (Throwable th) | ||
113 | - { | ||
114 | - LiteLoaderLogger.warning(th, "Error encountered whilst inspecting %s", classPathPart); | ||
115 | - } | 118 | + } |
119 | + catch (Throwable th) | ||
120 | + { | ||
121 | + LiteLoaderLogger.warning(th, "Error encountered whilst inspecting %s", classPathPart); | ||
116 | } | 122 | } |
117 | } | 123 | } |
118 | } | 124 | } |
src/main/java/com/mumfrey/liteloader/core/api/EnumeratorModuleFiles.java
0 โ 100644
1 | +/* | ||
2 | + * This file is part of LiteLoader. | ||
3 | + * Copyright (C) 2012-16 Adam Mummery-Smith | ||
4 | + * All Rights Reserved. | ||
5 | + */ | ||
6 | +package com.mumfrey.liteloader.core.api; | ||
7 | + | ||
8 | +import java.io.File; | ||
9 | +import java.io.FilenameFilter; | ||
10 | +import java.net.MalformedURLException; | ||
11 | +import java.util.ArrayList; | ||
12 | +import java.util.Iterator; | ||
13 | +import java.util.LinkedHashMap; | ||
14 | +import java.util.List; | ||
15 | +import java.util.Map; | ||
16 | +import java.util.Set; | ||
17 | +import java.util.TreeSet; | ||
18 | + | ||
19 | +import com.google.common.base.Charsets; | ||
20 | +import com.mumfrey.liteloader.api.EnumeratorModule; | ||
21 | +import com.mumfrey.liteloader.common.LoadingProgress; | ||
22 | +import com.mumfrey.liteloader.core.LiteLoaderVersion; | ||
23 | +import com.mumfrey.liteloader.core.api.EnumeratorModuleFiles.ContainerEnvironment.Candidate; | ||
24 | +import com.mumfrey.liteloader.interfaces.LoadableFile; | ||
25 | +import com.mumfrey.liteloader.interfaces.LoadableMod; | ||
26 | +import com.mumfrey.liteloader.interfaces.ModularEnumerator; | ||
27 | +import com.mumfrey.liteloader.interfaces.TweakContainer; | ||
28 | +import com.mumfrey.liteloader.launch.LoaderEnvironment; | ||
29 | +import com.mumfrey.liteloader.launch.LoaderProperties; | ||
30 | +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | ||
31 | +import com.mumfrey.liteloader.util.log.LiteLoaderLogger.Verbosity; | ||
32 | + | ||
33 | +import net.minecraft.launchwrapper.LaunchClassLoader; | ||
34 | + | ||
35 | +public abstract class EnumeratorModuleFiles implements FilenameFilter, EnumeratorModule | ||
36 | +{ | ||
37 | + public static class ContainerEnvironment implements Iterable<ContainerEnvironment.Candidate> | ||
38 | + { | ||
39 | + static class Candidate | ||
40 | + { | ||
41 | + private final Set<LoadableMod<File>> availableFiles = new TreeSet<LoadableMod<File>>(); | ||
42 | + | ||
43 | + private boolean isRegistered; | ||
44 | + | ||
45 | + public void add(LoadableMod<File> modFile) | ||
46 | + { | ||
47 | + if (!this.isRegistered) | ||
48 | + { | ||
49 | + this.availableFiles.add(modFile); | ||
50 | + } | ||
51 | + } | ||
52 | + | ||
53 | + public LoadableMod<File> getNewestVersion() | ||
54 | + { | ||
55 | + return this.availableFiles.iterator().next(); | ||
56 | + } | ||
57 | + | ||
58 | + public boolean isRegistered() | ||
59 | + { | ||
60 | + return this.isRegistered; | ||
61 | + } | ||
62 | + | ||
63 | + public void register() | ||
64 | + { | ||
65 | + this.isRegistered = true; | ||
66 | + } | ||
67 | + } | ||
68 | + | ||
69 | + /** | ||
70 | + * Ordered sets used to sort mods by version/revision | ||
71 | + */ | ||
72 | + private final Map<String, Candidate> orderedCandidates = new LinkedHashMap<String, Candidate>(); | ||
73 | + | ||
74 | + public void addCandidate(LoadableMod<File> modFile) | ||
75 | + { | ||
76 | + if (!this.orderedCandidates.containsKey(modFile.getModName())) | ||
77 | + { | ||
78 | + this.orderedCandidates.put(modFile.getModName(), new Candidate()); | ||
79 | + } | ||
80 | + | ||
81 | + LiteLoaderLogger.info("Considering valid mod file: %s", modFile); | ||
82 | + this.orderedCandidates.get(modFile.getModName()).add(modFile); | ||
83 | + } | ||
84 | + | ||
85 | + @Override | ||
86 | + public Iterator<Candidate> iterator() | ||
87 | + { | ||
88 | + return this.orderedCandidates.values().iterator(); | ||
89 | + } | ||
90 | + } | ||
91 | + | ||
92 | + /** | ||
93 | + * Ordered sets used to sort mods by version/revision | ||
94 | + */ | ||
95 | + private final ContainerEnvironment containers; | ||
96 | + | ||
97 | + /** | ||
98 | + * Mods to add once init is completed | ||
99 | + */ | ||
100 | + private final List<LoadableMod<File>> loadableMods = new ArrayList<LoadableMod<File>>(); | ||
101 | + | ||
102 | + protected final LiteLoaderCoreAPI api; | ||
103 | + | ||
104 | + public EnumeratorModuleFiles(LiteLoaderCoreAPI api, ContainerEnvironment containers) | ||
105 | + { | ||
106 | + this.api = api; | ||
107 | + this.containers = containers; | ||
108 | + } | ||
109 | + | ||
110 | + protected abstract boolean readJarFiles(); | ||
111 | + | ||
112 | + protected abstract boolean loadTweakJars(); | ||
113 | + | ||
114 | + protected abstract boolean loadTweaks(); | ||
115 | + | ||
116 | + protected abstract boolean forceInjection(); | ||
117 | + | ||
118 | + protected abstract File[] getFiles(); | ||
119 | + | ||
120 | + @Override | ||
121 | + public void init(LoaderEnvironment environment, LoaderProperties properties) | ||
122 | + { | ||
123 | + } | ||
124 | + | ||
125 | + /** | ||
126 | + * Write settings | ||
127 | + */ | ||
128 | + @Override | ||
129 | + public void writeSettings(LoaderEnvironment environment, LoaderProperties properties) | ||
130 | + { | ||
131 | + } | ||
132 | + | ||
133 | + /* (non-Javadoc) | ||
134 | + * @see com.mumfrey.liteloader.core.Enumerator#getLoadableMods() | ||
135 | + */ | ||
136 | + public List<LoadableMod<File>> getLoadableMods() | ||
137 | + { | ||
138 | + return this.loadableMods; | ||
139 | + } | ||
140 | + | ||
141 | + /** | ||
142 | + * For FilenameFilter interface | ||
143 | + * | ||
144 | + * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) | ||
145 | + */ | ||
146 | + @Override | ||
147 | + public boolean accept(File dir, String fileName) | ||
148 | + { | ||
149 | + fileName = fileName.toLowerCase(); | ||
150 | + | ||
151 | + if (fileName.endsWith(".litemod.zip")) | ||
152 | + { | ||
153 | + LiteLoaderLogger.warning("Found %s with unsupported extension .litemod.zip." | ||
154 | + + " Please change file extension to .litemod to allow this file to be loaded!", fileName); | ||
155 | + return true; | ||
156 | + } | ||
157 | + | ||
158 | + return fileName.endsWith(".litemod") || fileName.endsWith(".jar"); | ||
159 | + } | ||
160 | + | ||
161 | + /** | ||
162 | + * Search the folder for (potentially) valid files | ||
163 | + */ | ||
164 | + protected void findValidFiles(ModularEnumerator enumerator) | ||
165 | + { | ||
166 | + for (File file : this.getFiles()) | ||
167 | + { | ||
168 | + LoadableFile candidateFile = new LoadableFile(file); | ||
169 | + candidateFile.setForceInjection(this.forceInjection()); | ||
170 | + try | ||
171 | + { | ||
172 | + this.inspectFile(enumerator, candidateFile); | ||
173 | + } | ||
174 | + catch (Exception ex) | ||
175 | + { | ||
176 | + LiteLoaderLogger.warning(ex, "An error occurred whilst inspecting %s", candidateFile); | ||
177 | + } | ||
178 | + } | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
182 | + * Check whether a particular file is valid, and add it to the candiates | ||
183 | + * list if it appears to be acceptable. | ||
184 | + * | ||
185 | + * @param enumerator | ||
186 | + * @param candidateFile | ||
187 | + */ | ||
188 | + protected void inspectFile(ModularEnumerator enumerator, LoadableFile candidateFile) | ||
189 | + { | ||
190 | + if (this.isValidFile(enumerator, candidateFile)) | ||
191 | + { | ||
192 | + String metaData = candidateFile.getFileContents(LoadableMod.METADATA_FILENAME, Charsets.UTF_8); | ||
193 | + if (metaData != null) | ||
194 | + { | ||
195 | + LoadableMod<File> modFile = this.getModFile(candidateFile, metaData); | ||
196 | + this.addModFile(enumerator, modFile); | ||
197 | + return; | ||
198 | + } | ||
199 | + else if (this.isValidTweakContainer(candidateFile)) | ||
200 | + { | ||
201 | + TweakContainer<File> container = this.getTweakFile(candidateFile); | ||
202 | + this.addTweakFile(enumerator, container); | ||
203 | + return; | ||
204 | + } | ||
205 | + else | ||
206 | + { | ||
207 | + LiteLoaderLogger.info("Ignoring %s", candidateFile); | ||
208 | +// enumerator.registerBadContainer(candidateFile, "No metadata"); | ||
209 | + } | ||
210 | + } | ||
211 | +// else | ||
212 | +// { | ||
213 | +// enumerator.registerBadContainer(candidateFile, "Not a valid file"); | ||
214 | +// } | ||
215 | + } | ||
216 | + | ||
217 | + /** | ||
218 | + * Check whether the specified file is a valid mod container | ||
219 | + * | ||
220 | + * @param enumerator | ||
221 | + * @param candidateFile | ||
222 | + */ | ||
223 | + protected boolean isValidFile(ModularEnumerator enumerator, LoadableFile candidateFile) | ||
224 | + { | ||
225 | + String filename = candidateFile.getName().toLowerCase(); | ||
226 | + if (filename.endsWith(".litemod.zip")) | ||
227 | + { | ||
228 | + enumerator.registerBadContainer(candidateFile, "Invalid file extension .litemod.zip"); | ||
229 | + return false; | ||
230 | + } | ||
231 | + else if (filename.endsWith(".litemod")) | ||
232 | + { | ||
233 | + return true; | ||
234 | + } | ||
235 | + else if (filename.endsWith(".jar")) | ||
236 | + { | ||
237 | + Set<String> modSystems = candidateFile.getModSystems(); | ||
238 | + boolean hasLiteLoader = modSystems.contains("LiteLoader"); | ||
239 | + if (modSystems.size() > 0) | ||
240 | + { | ||
241 | + LiteLoaderLogger.info("%s supports mod systems %s", candidateFile, modSystems); | ||
242 | + if (!hasLiteLoader) return false; | ||
243 | + } | ||
244 | + | ||
245 | + return this.loadTweakJars() || this.readJarFiles() || hasLiteLoader; | ||
246 | + } | ||
247 | + | ||
248 | + return false; | ||
249 | + } | ||
250 | + | ||
251 | + /** | ||
252 | + * Called only if the file is not a valid mod container (has no mod | ||
253 | + * metadata) to check whether it could instead be a potential tweak | ||
254 | + * container. | ||
255 | + * | ||
256 | + * @param candidateFile | ||
257 | + */ | ||
258 | + protected boolean isValidTweakContainer(LoadableFile candidateFile) | ||
259 | + { | ||
260 | + return this.loadTweakJars() && this.loadTweaks() && candidateFile.getName().toLowerCase().endsWith(".jar"); | ||
261 | + } | ||
262 | + | ||
263 | + /** | ||
264 | + * Get the {@link FilenameFilter} to use to filter candidate files | ||
265 | + */ | ||
266 | + protected FilenameFilter getFilenameFilter() | ||
267 | + { | ||
268 | + return this; | ||
269 | + } | ||
270 | + | ||
271 | + /** | ||
272 | + * @param modFile | ||
273 | + */ | ||
274 | + protected boolean isFileSupported(LoadableMod<File> modFile) | ||
275 | + { | ||
276 | + return LiteLoaderVersion.CURRENT.isVersionSupported(modFile.getTargetVersion()); | ||
277 | + } | ||
278 | + | ||
279 | + /** | ||
280 | + * @param candidateFile | ||
281 | + * @param metaData | ||
282 | + */ | ||
283 | + protected LoadableMod<File> getModFile(LoadableFile candidateFile, String metaData) | ||
284 | + { | ||
285 | + return new LoadableModFile(candidateFile, metaData); | ||
286 | + } | ||
287 | + | ||
288 | + /** | ||
289 | + * @param candidateFile | ||
290 | + */ | ||
291 | + protected TweakContainer<File> getTweakFile(LoadableFile candidateFile) | ||
292 | + { | ||
293 | + return candidateFile; | ||
294 | + } | ||
295 | + | ||
296 | + /** | ||
297 | + * @param enumerator | ||
298 | + * @param modFile | ||
299 | + */ | ||
300 | + protected void addModFile(ModularEnumerator enumerator, LoadableMod<File> modFile) | ||
301 | + { | ||
302 | + if (modFile.hasValidMetaData()) | ||
303 | + { | ||
304 | + // Only add the mod if the version matches, we add candidates to the versionOrderingSets in | ||
305 | + // order to determine the most recent version available. | ||
306 | + if (this.isFileSupported(modFile)) | ||
307 | + { | ||
308 | + this.containers.addCandidate(modFile); | ||
309 | + } | ||
310 | + else | ||
311 | + { | ||
312 | + LiteLoaderLogger.info(Verbosity.REDUCED, "Not adding invalid or version-mismatched mod file: %s", modFile); | ||
313 | + enumerator.registerBadContainer(modFile, "Version not supported"); | ||
314 | + } | ||
315 | + } | ||
316 | + } | ||
317 | + | ||
318 | + /** | ||
319 | + * @param enumerator | ||
320 | + * @param container | ||
321 | + */ | ||
322 | + protected void addTweakFile(ModularEnumerator enumerator, TweakContainer<File> container) | ||
323 | + { | ||
324 | + enumerator.registerTweakContainer(container); | ||
325 | + } | ||
326 | + | ||
327 | + /** | ||
328 | + * @param enumerator | ||
329 | + */ | ||
330 | + protected void sortAndRegisterFiles(ModularEnumerator enumerator) | ||
331 | + { | ||
332 | + // Copy the first entry in every version set into the modfiles list | ||
333 | + for (Candidate candidate : this.containers) | ||
334 | + { | ||
335 | + if (candidate.isRegistered()) | ||
336 | + { | ||
337 | + continue; | ||
338 | + } | ||
339 | + | ||
340 | + LoadableMod<File> newestVersion = candidate.getNewestVersion(); | ||
341 | + this.registerFile(enumerator, newestVersion); | ||
342 | + candidate.register(); | ||
343 | + } | ||
344 | + } | ||
345 | + | ||
346 | + /** | ||
347 | + * @param enumerator | ||
348 | + * @param modFile | ||
349 | + */ | ||
350 | + @SuppressWarnings("unchecked") | ||
351 | + protected void registerFile(ModularEnumerator enumerator, LoadableMod<File> modFile) | ||
352 | + { | ||
353 | + if (enumerator.registerModContainer(modFile)) | ||
354 | + { | ||
355 | + LiteLoaderLogger.info(Verbosity.REDUCED, "Adding newest valid mod file '%s' at revision %.4f", modFile, modFile.getRevision()); | ||
356 | + this.loadableMods.add(modFile); | ||
357 | + } | ||
358 | + else | ||
359 | + { | ||
360 | + LiteLoaderLogger.info(Verbosity.REDUCED, "Not adding valid mod file '%s', the specified mod is disabled or missing a required dependency", | ||
361 | + modFile); | ||
362 | + } | ||
363 | + | ||
364 | + if (this.loadTweaks()) | ||
365 | + { | ||
366 | + try | ||
367 | + { | ||
368 | + if (modFile instanceof TweakContainer) | ||
369 | + { | ||
370 | + this.addTweakFile(enumerator, (TweakContainer<File>)modFile); | ||
371 | + } | ||
372 | + } | ||
373 | + catch (Throwable th) | ||
374 | + { | ||
375 | + LiteLoaderLogger.warning("Error adding tweaks from '%s'", modFile); | ||
376 | + } | ||
377 | + } | ||
378 | + } | ||
379 | + | ||
380 | + @Override | ||
381 | + public void injectIntoClassLoader(ModularEnumerator enumerator, LaunchClassLoader classLoader) | ||
382 | + { | ||
383 | + LiteLoaderLogger.info("Injecting external mods into class path..."); | ||
384 | + | ||
385 | + for (LoadableMod<?> loadableMod : this.loadableMods) | ||
386 | + { | ||
387 | + try | ||
388 | + { | ||
389 | + if (loadableMod.injectIntoClassPath(classLoader, false)) | ||
390 | + { | ||
391 | + LiteLoaderLogger.info("Successfully injected mod file '%s' into classpath", loadableMod); | ||
392 | + } | ||
393 | + } | ||
394 | + catch (MalformedURLException ex) | ||
395 | + { | ||
396 | + LiteLoaderLogger.warning("Error injecting '%s' into classPath. The mod will not be loaded", loadableMod); | ||
397 | + } | ||
398 | + } | ||
399 | + } | ||
400 | + | ||
401 | + @Override | ||
402 | + public void registerMods(ModularEnumerator enumerator, LaunchClassLoader classLoader) | ||
403 | + { | ||
404 | + LiteLoaderLogger.info(Verbosity.REDUCED, "Discovering mods in valid mod files..."); | ||
405 | + LoadingProgress.incTotalLiteLoaderProgress(this.loadableMods.size()); | ||
406 | + | ||
407 | + for (LoadableMod<?> modFile : this.loadableMods) | ||
408 | + { | ||
409 | + LoadingProgress.incLiteLoaderProgress("Searching for mods in " + modFile.getModName() + "..."); | ||
410 | + LiteLoaderLogger.info("Searching %s...", modFile); | ||
411 | + try | ||
412 | + { | ||
413 | + enumerator.registerModsFrom(modFile, true); | ||
414 | + } | ||
415 | + catch (Exception ex) | ||
416 | + { | ||
417 | + LiteLoaderLogger.warning("Error encountered whilst searching in %s...", modFile); | ||
418 | + } | ||
419 | + } | ||
420 | + } | ||
421 | +} |
src/main/java/com/mumfrey/liteloader/core/api/EnumeratorModuleFolder.java
@@ -6,50 +6,19 @@ | @@ -6,50 +6,19 @@ | ||
6 | package com.mumfrey.liteloader.core.api; | 6 | package com.mumfrey.liteloader.core.api; |
7 | 7 | ||
8 | import java.io.File; | 8 | import java.io.File; |
9 | -import java.io.FilenameFilter; | ||
10 | -import java.net.MalformedURLException; | ||
11 | -import java.util.ArrayList; | ||
12 | -import java.util.HashMap; | ||
13 | -import java.util.List; | ||
14 | -import java.util.Map; | ||
15 | -import java.util.Map.Entry; | ||
16 | -import java.util.Set; | ||
17 | -import java.util.TreeSet; | ||
18 | 9 | ||
19 | -import com.google.common.base.Charsets; | ||
20 | -import com.mumfrey.liteloader.api.EnumeratorModule; | ||
21 | -import com.mumfrey.liteloader.common.LoadingProgress; | ||
22 | -import com.mumfrey.liteloader.core.LiteLoaderVersion; | ||
23 | -import com.mumfrey.liteloader.interfaces.LoadableFile; | ||
24 | -import com.mumfrey.liteloader.interfaces.LoadableMod; | ||
25 | import com.mumfrey.liteloader.interfaces.ModularEnumerator; | 10 | import com.mumfrey.liteloader.interfaces.ModularEnumerator; |
26 | -import com.mumfrey.liteloader.interfaces.TweakContainer; | ||
27 | import com.mumfrey.liteloader.launch.LoaderEnvironment; | 11 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
28 | import com.mumfrey.liteloader.launch.LoaderProperties; | 12 | import com.mumfrey.liteloader.launch.LoaderProperties; |
29 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | 13 | import com.mumfrey.liteloader.util.log.LiteLoaderLogger; |
30 | -import com.mumfrey.liteloader.util.log.LiteLoaderLogger.Verbosity; | ||
31 | - | ||
32 | -import net.minecraft.launchwrapper.LaunchClassLoader; | ||
33 | 14 | ||
34 | /** | 15 | /** |
35 | * Enumerator module which searches for mods and tweaks in a folder | 16 | * Enumerator module which searches for mods and tweaks in a folder |
36 | * | 17 | * |
37 | * @author Adam Mummery-Smith | 18 | * @author Adam Mummery-Smith |
38 | */ | 19 | */ |
39 | -public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | 20 | +public class EnumeratorModuleFolder extends EnumeratorModuleFiles |
40 | { | 21 | { |
41 | - /** | ||
42 | - * Ordered sets used to sort mods by version/revision | ||
43 | - */ | ||
44 | - protected final Map<String, TreeSet<LoadableMod<File>>> versionOrderingSets = new HashMap<String, TreeSet<LoadableMod<File>>>(); | ||
45 | - | ||
46 | - /** | ||
47 | - * Mods to add once init is completed | ||
48 | - */ | ||
49 | - protected final List<LoadableMod<File>> loadableMods = new ArrayList<LoadableMod<File>>(); | ||
50 | - | ||
51 | - protected LiteLoaderCoreAPI coreAPI; | ||
52 | - | ||
53 | protected File directory; | 22 | protected File directory; |
54 | 23 | ||
55 | protected boolean readJarFiles; | 24 | protected boolean readJarFiles; |
@@ -62,13 +31,13 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | @@ -62,13 +31,13 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | ||
62 | */ | 31 | */ |
63 | protected final boolean loadTweakJars; | 32 | protected final boolean loadTweakJars; |
64 | 33 | ||
65 | - public EnumeratorModuleFolder(LiteLoaderCoreAPI coreAPI, File directory, boolean loadTweakJars) | 34 | + public EnumeratorModuleFolder(LiteLoaderCoreAPI api, ContainerEnvironment containers, File directory, boolean loadTweakJars) |
66 | { | 35 | { |
67 | - this.coreAPI = coreAPI; | ||
68 | - this.directory = directory; | ||
69 | - this.loadTweakJars = loadTweakJars; | 36 | + super(api, containers); |
37 | + this.directory = directory; | ||
38 | + this.loadTweakJars = loadTweakJars; | ||
70 | } | 39 | } |
71 | - | 40 | + |
72 | @Override | 41 | @Override |
73 | public void init(LoaderEnvironment environment, LoaderProperties properties) | 42 | public void init(LoaderEnvironment environment, LoaderProperties properties) |
74 | { | 43 | { |
@@ -76,7 +45,7 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | @@ -76,7 +45,7 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | ||
76 | this.readJarFiles = properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_SEARCH_JARFILES, true); | 45 | this.readJarFiles = properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_SEARCH_JARFILES, true); |
77 | this.forceInjection = properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_FORCE_INJECTION, false); | 46 | this.forceInjection = properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_FORCE_INJECTION, false); |
78 | 47 | ||
79 | - this.coreAPI.writeDiscoverySettings(); | 48 | + this.api.writeDiscoverySettings(); |
80 | } | 49 | } |
81 | 50 | ||
82 | /** | 51 | /** |
@@ -88,6 +57,36 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | @@ -88,6 +57,36 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | ||
88 | properties.setBooleanProperty(LoaderProperties.OPTION_SEARCH_JARFILES, this.readJarFiles); | 57 | properties.setBooleanProperty(LoaderProperties.OPTION_SEARCH_JARFILES, this.readJarFiles); |
89 | properties.setBooleanProperty(LoaderProperties.OPTION_FORCE_INJECTION, this.forceInjection); | 58 | properties.setBooleanProperty(LoaderProperties.OPTION_FORCE_INJECTION, this.forceInjection); |
90 | } | 59 | } |
60 | + | ||
61 | + @Override | ||
62 | + protected boolean forceInjection() | ||
63 | + { | ||
64 | + return this.forceInjection; | ||
65 | + } | ||
66 | + | ||
67 | + @Override | ||
68 | + protected boolean loadTweakJars() | ||
69 | + { | ||
70 | + return this.loadTweakJars; | ||
71 | + } | ||
72 | + | ||
73 | + @Override | ||
74 | + protected boolean loadTweaks() | ||
75 | + { | ||
76 | + return this.loadTweaks; | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
80 | + protected boolean readJarFiles() | ||
81 | + { | ||
82 | + return this.readJarFiles; | ||
83 | + } | ||
84 | + | ||
85 | + @Override | ||
86 | + protected File[] getFiles() | ||
87 | + { | ||
88 | + return this.directory.listFiles(this.getFilenameFilter()); | ||
89 | + } | ||
91 | 90 | ||
92 | /* (non-Javadoc) | 91 | /* (non-Javadoc) |
93 | * @see java.lang.Object#toString() | 92 | * @see java.lang.Object#toString() |
@@ -107,34 +106,6 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | @@ -107,34 +106,6 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | ||
107 | } | 106 | } |
108 | 107 | ||
109 | /* (non-Javadoc) | 108 | /* (non-Javadoc) |
110 | - * @see com.mumfrey.liteloader.core.Enumerator#getLoadableMods() | ||
111 | - */ | ||
112 | - public List<LoadableMod<File>> getLoadableMods() | ||
113 | - { | ||
114 | - return this.loadableMods; | ||
115 | - } | ||
116 | - | ||
117 | - /** | ||
118 | - * For FilenameFilter interface | ||
119 | - * | ||
120 | - * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) | ||
121 | - */ | ||
122 | - @Override | ||
123 | - public boolean accept(File dir, String fileName) | ||
124 | - { | ||
125 | - fileName = fileName.toLowerCase(); | ||
126 | - | ||
127 | - if (fileName.endsWith(".litemod.zip")) | ||
128 | - { | ||
129 | - LiteLoaderLogger.warning("Found %s with unsupported extension .litemod.zip." | ||
130 | - + " Please change file extension to .litemod to allow this file to be loaded!", fileName); | ||
131 | - return true; | ||
132 | - } | ||
133 | - | ||
134 | - return fileName.endsWith(".litemod") || fileName.endsWith(".jar"); | ||
135 | - } | ||
136 | - | ||
137 | - /* (non-Javadoc) | ||
138 | * @see com.mumfrey.liteloader.core.Enumerator | 109 | * @see com.mumfrey.liteloader.core.Enumerator |
139 | * #enumerate(com.mumfrey.liteloader.core.EnabledModsList, | 110 | * #enumerate(com.mumfrey.liteloader.core.EnabledModsList, |
140 | * java.lang.String) | 111 | * java.lang.String) |
@@ -145,272 +116,22 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | @@ -145,272 +116,22 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule | ||
145 | if (this.directory.exists() && this.directory.isDirectory()) | 116 | if (this.directory.exists() && this.directory.isDirectory()) |
146 | { | 117 | { |
147 | LiteLoaderLogger.info("Discovering valid mod files in folder %s", this.directory.getPath()); | 118 | LiteLoaderLogger.info("Discovering valid mod files in folder %s", this.directory.getPath()); |
148 | - | ||
149 | this.findValidFiles(enumerator); | 119 | this.findValidFiles(enumerator); |
150 | - this.sortAndRegisterFiles(enumerator); | ||
151 | - } | ||
152 | - } | ||
153 | - | ||
154 | - /** | ||
155 | - * Search the folder for (potentially) valid files | ||
156 | - */ | ||
157 | - private void findValidFiles(ModularEnumerator enumerator) | ||
158 | - { | ||
159 | - for (File file : this.directory.listFiles(this.getFilenameFilter())) | ||
160 | - { | ||
161 | - LoadableFile candidateFile = new LoadableFile(file); | ||
162 | - candidateFile.setForceInjection(this.forceInjection); | ||
163 | - try | ||
164 | - { | ||
165 | - this.inspectFile(enumerator, candidateFile); | ||
166 | - } | ||
167 | - catch (Exception ex) | ||
168 | - { | ||
169 | - LiteLoaderLogger.warning(ex, "An error occurred whilst inspecting %s", candidateFile); | ||
170 | - } | ||
171 | } | 120 | } |
172 | } | 121 | } |
173 | - | ||
174 | - /** | ||
175 | - * Check whether a particular file is valid, and add it to the candiates | ||
176 | - * list if it appears to be acceptable. | ||
177 | - * | ||
178 | - * @param enumerator | ||
179 | - * @param candidateFile | ||
180 | - */ | ||
181 | - protected void inspectFile(ModularEnumerator enumerator, LoadableFile candidateFile) | ||
182 | - { | ||
183 | - if (this.isValidFile(enumerator, candidateFile)) | ||
184 | - { | ||
185 | - String metaData = candidateFile.getFileContents(LoadableMod.METADATA_FILENAME, Charsets.UTF_8); | ||
186 | - if (metaData != null) | ||
187 | - { | ||
188 | - LoadableMod<File> modFile = this.getModFile(candidateFile, metaData); | ||
189 | - this.addModFile(enumerator, modFile); | ||
190 | - return; | ||
191 | - } | ||
192 | - else if (this.isValidTweakContainer(candidateFile)) | ||
193 | - { | ||
194 | - TweakContainer<File> container = this.getTweakFile(candidateFile); | ||
195 | - this.addTweakFile(enumerator, container); | ||
196 | - return; | ||
197 | - } | ||
198 | - else | ||
199 | - { | ||
200 | - LiteLoaderLogger.info("Ignoring %s", candidateFile); | ||
201 | -// enumerator.registerBadContainer(candidateFile, "No metadata"); | ||
202 | - } | ||
203 | - } | ||
204 | -// else | ||
205 | -// { | ||
206 | -// enumerator.registerBadContainer(candidateFile, "Not a valid file"); | ||
207 | -// } | ||
208 | - } | ||
209 | - | ||
210 | - /** | ||
211 | - * Check whether the specified file is a valid mod container | ||
212 | - * | ||
213 | - * @param enumerator | ||
214 | - * @param candidateFile | ||
215 | - */ | ||
216 | - protected boolean isValidFile(ModularEnumerator enumerator, LoadableFile candidateFile) | ||
217 | - { | ||
218 | - String filename = candidateFile.getName().toLowerCase(); | ||
219 | - if (filename.endsWith(".litemod.zip")) | ||
220 | - { | ||
221 | - enumerator.registerBadContainer(candidateFile, "Invalid file extension .litemod.zip"); | ||
222 | - return false; | ||
223 | - } | ||
224 | - else if (filename.endsWith(".litemod")) | ||
225 | - { | ||
226 | - return true; | ||
227 | - } | ||
228 | - else if (filename.endsWith(".jar")) | ||
229 | - { | ||
230 | - Set<String> modSystems = candidateFile.getModSystems(); | ||
231 | - boolean hasLiteLoader = modSystems.contains("LiteLoader"); | ||
232 | - if (modSystems.size() > 0) | ||
233 | - { | ||
234 | - LiteLoaderLogger.info("%s supports mod systems %s", candidateFile, modSystems); | ||
235 | - if (!hasLiteLoader) return false; | ||
236 | - } | ||
237 | - | ||
238 | - return this.loadTweakJars || this.readJarFiles || hasLiteLoader; | ||
239 | - } | ||
240 | - | ||
241 | - return false; | ||
242 | - } | ||
243 | - | ||
244 | - /** | ||
245 | - * Called only if the file is not a valid mod container (has no mod | ||
246 | - * metadata) to check whether it could instead be a potential tweak | ||
247 | - * container. | ||
248 | - * | ||
249 | - * @param candidateFile | ||
250 | - */ | ||
251 | - protected boolean isValidTweakContainer(LoadableFile candidateFile) | ||
252 | - { | ||
253 | - return this.loadTweakJars && this.loadTweaks && candidateFile.getName().toLowerCase().endsWith(".jar"); | ||
254 | - } | ||
255 | - | ||
256 | - /** | ||
257 | - * Get the {@link FilenameFilter} to use to filter candidate files | ||
258 | - */ | ||
259 | - protected FilenameFilter getFilenameFilter() | ||
260 | - { | ||
261 | - return this; | ||
262 | - } | ||
263 | - | ||
264 | - /** | ||
265 | - * @param modFile | ||
266 | - */ | ||
267 | - protected boolean isFileSupported(LoadableMod<File> modFile) | ||
268 | - { | ||
269 | - return LiteLoaderVersion.CURRENT.isVersionSupported(modFile.getTargetVersion()); | ||
270 | - } | ||
271 | - | ||
272 | - /** | ||
273 | - * @param candidateFile | ||
274 | - * @param metaData | ||
275 | - */ | ||
276 | - protected LoadableMod<File> getModFile(LoadableFile candidateFile, String metaData) | ||
277 | - { | ||
278 | - return new LoadableModFile(candidateFile, metaData); | ||
279 | - } | ||
280 | - | ||
281 | - /** | ||
282 | - * @param candidateFile | ||
283 | - */ | ||
284 | - protected TweakContainer<File> getTweakFile(LoadableFile candidateFile) | ||
285 | - { | ||
286 | - return candidateFile; | ||
287 | - } | ||
288 | - | ||
289 | - /** | ||
290 | - * @param enumerator | ||
291 | - * @param modFile | ||
292 | - */ | ||
293 | - protected void addModFile(ModularEnumerator enumerator, LoadableMod<File> modFile) | ||
294 | - { | ||
295 | - if (modFile.hasValidMetaData()) | ||
296 | - { | ||
297 | - // Only add the mod if the version matches, we add candidates to the versionOrderingSets in | ||
298 | - // order to determine the most recent version available. | ||
299 | - if (this.isFileSupported(modFile)) | ||
300 | - { | ||
301 | - if (!this.versionOrderingSets.containsKey(modFile.getName())) | ||
302 | - { | ||
303 | - this.versionOrderingSets.put(modFile.getModName(), new TreeSet<LoadableMod<File>>()); | ||
304 | - } | ||
305 | - | ||
306 | - LiteLoaderLogger.info("Considering valid mod file: %s", modFile); | ||
307 | - this.versionOrderingSets.get(modFil |