Commit 0096b127b27e347ec48db05f3783971cbc707ea7

Authored by Mumfrey
1 parent d634cd86

updating enumeration, adding support for "ModType" META entry, removing support …

…for .zip, code cleanup
java/common/com/mumfrey/liteloader/core/api/EnumeratorModuleFolder.java
... ... @@ -2,19 +2,18 @@ package com.mumfrey.liteloader.core.api;
2 2  
3 3 import java.io.File;
4 4 import java.io.FilenameFilter;
5   -import java.io.IOException;
6 5 import java.net.MalformedURLException;
7 6 import java.util.ArrayList;
8 7 import java.util.HashMap;
9 8 import java.util.List;
10 9 import java.util.Map;
11   -import java.util.TreeSet;
12 10 import java.util.Map.Entry;
13   -import java.util.zip.ZipEntry;
14   -import java.util.zip.ZipFile;
  11 +import java.util.Set;
  12 +import java.util.TreeSet;
15 13  
16 14 import net.minecraft.launchwrapper.LaunchClassLoader;
17 15  
  16 +import com.google.common.base.Charsets;
18 17 import com.mumfrey.liteloader.api.EnumeratorModule;
19 18 import com.mumfrey.liteloader.common.LoadingProgress;
20 19 import com.mumfrey.liteloader.core.LiteLoaderVersion;
... ... @@ -47,27 +46,25 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule
47 46  
48 47 protected File directory;
49 48  
50   - protected boolean readZipFiles;
51 49 protected boolean readJarFiles;
52 50 protected boolean loadTweaks;
53 51  
54 52 /**
55   - * True if this is a general, unversioned folder and the enumerator should only add files which have valid version metadata
  53 + * True if this is a versioned folder and the enumerator should also try to load tweak jars which would normally be ignored
56 54 */
57   - private final boolean requireMetaData;
  55 + protected final boolean loadTweakJars;
58 56  
59   - public EnumeratorModuleFolder(LiteLoaderCoreAPI coreAPI, File directory, boolean requireMetaData)
  57 + public EnumeratorModuleFolder(LiteLoaderCoreAPI coreAPI, File directory, boolean loadTweakJars)
60 58 {
61 59 this.coreAPI = coreAPI;
62 60 this.directory = directory;
63   - this.requireMetaData = requireMetaData;
  61 + this.loadTweakJars = loadTweakJars;
64 62 }
65 63  
66 64 @Override
67 65 public void init(LoaderEnvironment environment, LoaderProperties properties)
68 66 {
69 67 this.loadTweaks = properties.loadTweaksEnabled();
70   - this.readZipFiles = properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_SEARCH_ZIPFILES, false);
71 68 this.readJarFiles = properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_SEARCH_JARFILES, true);
72 69  
73 70 this.coreAPI.writeDiscoverySettings();
... ... @@ -79,7 +76,6 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule
79 76 @Override
80 77 public void writeSettings(LoaderEnvironment environment, LoaderProperties properties)
81 78 {
82   - properties.setBooleanProperty(LoaderProperties.OPTION_SEARCH_ZIPFILES, this.readZipFiles);
83 79 properties.setBooleanProperty(LoaderProperties.OPTION_SEARCH_JARFILES, this.readJarFiles);
84 80 }
85 81  
... ... @@ -118,14 +114,12 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule
118 114 {
119 115 fileName = fileName.toLowerCase();
120 116  
121   - if (fileName.endsWith(".litemod.zip") && !this.readZipFiles)
  117 + if (fileName.endsWith(".litemod.zip"))
122 118 {
123 119 LiteLoaderLogger.warning("Found %s with unsupported extension .litemod.zip. Please change file extension to .litemod to allow this file to be loaded!", fileName);
124 120 }
125 121  
126   - return fileName.endsWith(".litemod")
127   - || (this.readZipFiles && fileName.endsWith(".zip"))
128   - || (this.readJarFiles && fileName.endsWith(".jar"));
  122 + return fileName.endsWith(".litemod") || fileName.endsWith(".jar");
129 123 }
130 124  
131 125 /* (non-Javadoc)
... ... @@ -139,97 +133,137 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule
139 133 LiteLoaderLogger.info("Discovering valid mod files in folder %s", this.directory.getPath());
140 134  
141 135 this.findValidFiles(enumerator);
142   - this.sortAndAllocateFiles(enumerator);
143   - this.versionOrderingSets.clear();
  136 + this.sortAndRegisterFiles(enumerator);
144 137 }
145 138 }
146 139  
147 140 /**
  141 + * Search the folder for (potentially) valid files
148 142 */
149 143 private void findValidFiles(ModularEnumerator enumerator)
150 144 {
151   - for (File candidateFile : this.directory.listFiles(this.getFilenameFilter()))
  145 + for (File file : this.directory.listFiles(this.getFilenameFilter()))
152 146 {
153   - ZipFile candidateZip = null;
154   -
  147 + LoadableFile candidateFile = new LoadableFile(file);
155 148 try
156 149 {
157   - candidateZip = new ZipFile(candidateFile);
158   - ZipEntry versionEntry = candidateZip.getEntry(LoadableMod.METADATA_FILENAME);
159   - ZipEntry legacyVersionEntry = candidateZip.getEntry(LoadableMod.LEGACY_METADATA_FILENAME);
160   -
161   - // Check for a version file
162   - if (versionEntry != null)
163   - {
164   - String strVersion = null;
165   - try
166   - {
167   - strVersion = LoadableModFile.zipEntryToString(candidateZip, versionEntry);
168   - }
169   - catch (IOException ex)
170   - {
171   - LiteLoaderLogger.warning("Error reading version data from %s", candidateZip.getName());
172   - }
173   -
174   - if (strVersion != null)
175   - {
176   - this.addModFile(candidateFile, strVersion);
177   - }
178   - }
179   - else if (legacyVersionEntry != null)
180   - {
181   - LiteLoaderLogger.warning("%s is no longer supported, ignoring outdated mod file: %s", LoadableMod.LEGACY_METADATA_FILENAME, candidateFile.getAbsolutePath());
182   - }
183   - else if (!this.requireMetaData && this.loadTweaks && this.readJarFiles && candidateFile.getName().toLowerCase().endsWith(".jar"))
184   - {
185   - LoadableFile container = new LoadableFile(candidateFile);
186   - enumerator.registerTweakContainer(container);
187   - }
  150 + this.inspectFile(enumerator, candidateFile);
188 151 }
189 152 catch (Exception ex)
190 153 {
191   - LiteLoaderLogger.info("Error enumerating '%s': Invalid zip file or error reading file", candidateFile.getAbsolutePath());
  154 + LiteLoaderLogger.warning(ex, "An error occurred whilst inspecting %s", candidateFile);
  155 + }
  156 + }
  157 + }
  158 +
  159 + /**
  160 + * Check whether a particular file is valid, and add it to the candiates list if it appears to be acceptable
  161 + *
  162 + * @param enumerator
  163 + * @param candidateFile
  164 + */
  165 + protected void inspectFile(ModularEnumerator enumerator, LoadableFile candidateFile)
  166 + {
  167 + if (this.isValidFile(candidateFile))
  168 + {
  169 + String metaData = candidateFile.getFileContents(LoadableMod.METADATA_FILENAME, Charsets.UTF_8);
  170 + if (metaData != null)
  171 + {
  172 + LoadableMod<File> modFile = this.getModFile(candidateFile, metaData);
  173 + this.addModFile(enumerator, modFile);
  174 + return;
192 175 }
193   - finally
  176 + else if (this.isValidTweakContainer(candidateFile))
194 177 {
195   - if (candidateZip != null)
196   - {
197   - try
198   - {
199   - candidateZip.close();
200   - }
201   - catch (IOException ex) {}
202   - }
  178 + TweakContainer<File> container = this.getTweakFile(candidateFile);
  179 + this.addTweakFile(enumerator, container);
  180 + return;
  181 + }
  182 + else
  183 + {
  184 + LiteLoaderLogger.info("Ignoring %s", candidateFile);
203 185 }
204 186 }
205 187 }
206 188  
207 189 /**
  190 + * Check whether the specified file is a valid mod container
  191 + *
  192 + * @param candidateFile
  193 + */
  194 + protected boolean isValidFile(LoadableFile candidateFile)
  195 + {
  196 + String filename = candidateFile.getName().toLowerCase();
  197 + if (filename.endsWith(".litemod"))
  198 + {
  199 + return true;
  200 + }
  201 + else if (filename.endsWith(".jar"))
  202 + {
  203 + Set<String> modSystems = candidateFile.getModSystems();
  204 + boolean hasLiteLoader = modSystems.contains("LiteLoader");
  205 + if (modSystems.size() > 0)
  206 + {
  207 + LiteLoaderLogger.info("%s supports mod systems %s", candidateFile, modSystems);
  208 + if (!hasLiteLoader) return false;
  209 + }
  210 +
  211 + return this.loadTweakJars || this.readJarFiles || hasLiteLoader;
  212 + }
  213 +
  214 + return false;
  215 + }
  216 +
  217 + /**
  218 + * Called only if the file is not a valid mod container (has no mod metadata) to check whether it
  219 + * could instead be a potential tweak container
  220 + *
  221 + * @param candidateFile
  222 + */
  223 + protected boolean isValidTweakContainer(LoadableFile candidateFile)
  224 + {
  225 + return this.loadTweakJars && this.loadTweaks && candidateFile.getName().toLowerCase().endsWith(".jar");
  226 + }
  227 +
  228 + /**
208 229 * Get the {@link FilenameFilter} to use to filter candidate files
209 230 */
210 231 protected FilenameFilter getFilenameFilter()
211 232 {
212   - // Stub for subclasses
213 233 return this;
214 234 }
215 235  
216 236 /**
217 237 * @param modFile
218 238 */
219   - protected boolean isFileSupported(LoadableModFile modFile)
  239 + protected boolean isFileSupported(LoadableMod<File> modFile)
220 240 {
221   - // Stub for subclasses
222 241 return LiteLoaderVersion.CURRENT.isVersionSupported(modFile.getTargetVersion());
223 242 }
224 243  
225 244 /**
226 245 * @param candidateFile
227   - * @param strVersion
  246 + * @param metaData
228 247 */
229   - protected void addModFile(File candidateFile, String strVersion)
  248 + protected LoadableMod<File> getModFile(LoadableFile candidateFile, String metaData)
  249 + {
  250 + return new LoadableModFile(candidateFile, metaData);
  251 + }
  252 +
  253 + /**
  254 + * @param candidateFile
  255 + */
  256 + protected TweakContainer<File> getTweakFile(LoadableFile candidateFile)
  257 + {
  258 + return candidateFile;
  259 + }
  260 +
  261 + /**
  262 + * @param enumerator
  263 + * @param modFile
  264 + */
  265 + protected void addModFile(ModularEnumerator enumerator, LoadableMod<File> modFile)
230 266 {
231   - LoadableModFile modFile = new LoadableModFile(candidateFile, strVersion);
232   -
233 267 if (modFile.hasValidMetaData())
234 268 {
235 269 // Only add the mod if the version matches, we add candidates to the versionOrderingSets in
... ... @@ -241,51 +275,70 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule
241 275 this.versionOrderingSets.put(modFile.getModName(), new TreeSet<LoadableMod<File>>());
242 276 }
243 277  
244   - LiteLoaderLogger.info("Considering valid mod file: %s", modFile.getAbsolutePath());
  278 + LiteLoaderLogger.info("Considering valid mod file: %s", modFile);
245 279 this.versionOrderingSets.get(modFile.getModName()).add(modFile);
246 280 }
247 281 else
248 282 {
249   - LiteLoaderLogger.info("Not adding invalid or outdated mod file: %s", candidateFile.getAbsolutePath());
  283 + LiteLoaderLogger.info("Not adding invalid or version-mismatched mod file: %s", modFile);
250 284 }
251 285 }
252 286 }
253 287  
254 288 /**
  289 + * @param enumerator
  290 + * @param container
  291 + */
  292 + protected void addTweakFile(ModularEnumerator enumerator, TweakContainer<File> container)
  293 + {
  294 + enumerator.registerTweakContainer(container);
  295 + }
  296 +
  297 + /**
255 298 * @param enumerator
256 299 */
257   - @SuppressWarnings("unchecked")
258   - protected void sortAndAllocateFiles(ModularEnumerator enumerator)
  300 + protected void sortAndRegisterFiles(ModularEnumerator enumerator)
259 301 {
260 302 // Copy the first entry in every version set into the modfiles list
261 303 for (Entry<String, TreeSet<LoadableMod<File>>> modFileEntry : this.versionOrderingSets.entrySet())
262 304 {
263 305 LoadableMod<File> newestVersion = modFileEntry.getValue().iterator().next();
  306 + this.registerFile(enumerator, newestVersion);
  307 + }
  308 +
  309 + this.versionOrderingSets.clear();
  310 + }
264 311  
265   - if (enumerator.registerModContainer(newestVersion))
266   - {
267   - LiteLoaderLogger.info("Adding newest valid mod file '%s' at revision %.4f", newestVersion.getLocation(), newestVersion.getRevision());
268   - this.loadableMods.add(newestVersion);
269   - }
270   - else
271   - {
272   - LiteLoaderLogger.info("Not adding valid mod file '%s', the specified mod is disabled or missing a required dependency", newestVersion.getLocation());
273   - }
274   -
275   - if (this.loadTweaks)
  312 + /**
  313 + * @param enumerator
  314 + * @param modFile
  315 + */
  316 + @SuppressWarnings("unchecked")
  317 + protected void registerFile(ModularEnumerator enumerator, LoadableMod<File> modFile)
  318 + {
  319 + if (enumerator.registerModContainer(modFile))
  320 + {
  321 + LiteLoaderLogger.info("Adding newest valid mod file '%s' at revision %.4f", modFile, modFile.getRevision());
  322 + this.loadableMods.add(modFile);
  323 + }
  324 + else
  325 + {
  326 + LiteLoaderLogger.info("Not adding valid mod file '%s', the specified mod is disabled or missing a required dependency", modFile);
  327 + }
  328 +
  329 + if (this.loadTweaks)
  330 + {
  331 + try
276 332 {
277   - try
278   - {
279   - if (newestVersion instanceof TweakContainer)
280   - {
281   - enumerator.registerTweakContainer((TweakContainer<File>)newestVersion);
282   - }
283   - }
284   - catch (Throwable th)
  333 + if (modFile instanceof TweakContainer)
285 334 {
286   - LiteLoaderLogger.warning("Error adding tweaks from '%s'", newestVersion.getLocation());
  335 + this.addTweakFile(enumerator, (TweakContainer<File>)modFile);
287 336 }
288 337 }
  338 + catch (Throwable th)
  339 + {
  340 + LiteLoaderLogger.warning("Error adding tweaks from '%s'", modFile);
  341 + }
289 342 }
290 343 }
291 344  
... ... @@ -300,12 +353,12 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule
300 353 {
301 354 if (loadableMod.injectIntoClassPath(classLoader, false))
302 355 {
303   - LiteLoaderLogger.info("Successfully injected mod file '%s' into classpath", loadableMod.getLocation());
  356 + LiteLoaderLogger.info("Successfully injected mod file '%s' into classpath", loadableMod);
304 357 }
305 358 }
306 359 catch (MalformedURLException ex)
307 360 {
308   - LiteLoaderLogger.warning("Error injecting '%s' into classPath. The mod will not be loaded", loadableMod.getLocation());
  361 + LiteLoaderLogger.warning("Error injecting '%s' into classPath. The mod will not be loaded", loadableMod);
309 362 }
310 363 }
311 364 }
... ... @@ -319,14 +372,14 @@ public class EnumeratorModuleFolder implements FilenameFilter, EnumeratorModule
319 372 for (LoadableMod<?> modFile : this.loadableMods)
320 373 {
321 374 LoadingProgress.incLiteLoaderProgress("Searching for mods in " + modFile.getModName() + "...");
322   - LiteLoaderLogger.info("Searching %s...", modFile.getLocation());
  375 + LiteLoaderLogger.info("Searching %s...", modFile);
323 376 try
324 377 {
325 378 enumerator.registerModsFrom(modFile, true);
326 379 }
327 380 catch (Exception ex)
328 381 {
329   - LiteLoaderLogger.warning("Error encountered whilst searching in %s...", modFile.getLocation());
  382 + LiteLoaderLogger.warning("Error encountered whilst searching in %s...", modFile);
330 383 }
331 384 }
332 385 }
... ...
java/common/com/mumfrey/liteloader/core/api/EnumeratorModuleProtectionDomain.java deleted 100644 → 0
1   -package com.mumfrey.liteloader.core.api;
2   -
3   -import java.io.File;
4   -import java.net.URL;
5   -import java.net.URLDecoder;
6   -
7   -import net.minecraft.launchwrapper.LaunchClassLoader;
8   -
9   -import com.mumfrey.liteloader.api.EnumeratorModule;
10   -import com.mumfrey.liteloader.interfaces.LoadableMod;
11   -import com.mumfrey.liteloader.interfaces.ModularEnumerator;
12   -import com.mumfrey.liteloader.launch.LoaderEnvironment;
13   -import com.mumfrey.liteloader.launch.LoaderProperties;
14   -import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
15   -
16   -/**
17   - * Enumerator module which searches for mods on the classpath
18   - *
19   - * @author Adam Mummery-Smith
20   - */
21   -public class EnumeratorModuleProtectionDomain implements EnumeratorModule
22   -{
23   - private LoadableMod<File> codeSource;
24   -
25   - public EnumeratorModuleProtectionDomain(boolean loadTweaks)
26   - {
27   - this.initPackagePath();
28   - }
29   -
30   - @Override
31   - public String toString()
32   - {
33   - return this.codeSource != null ? this.codeSource.getName() : "<None>";
34   - }
35   -
36   - private void initPackagePath()
37   - {
38   - try
39   - {
40   - URL protectionDomainLocation = EnumeratorModuleProtectionDomain.class.getProtectionDomain().getCodeSource().getLocation();
41   - if (protectionDomainLocation != null)
42   - {
43   - LiteLoaderLogger.info("Determining code source using protection domain");
44   - if (protectionDomainLocation.toString().indexOf('!') > -1 && protectionDomainLocation.toString().startsWith("jar:"))
45   - {
46   - LiteLoaderLogger.info("Protection domain references a jar file");
47   - protectionDomainLocation = new URL(protectionDomainLocation.toString().substring(4, protectionDomainLocation.toString().indexOf('!')));
48   - }
49   -
50   - File packagePath = new File(protectionDomainLocation.toURI());
51   - if (packagePath.isFile() && packagePath.getName().endsWith(".class"))
52   - {
53   - packagePath = packagePath.getParentFile();
54   - }
55   -
56   - this.codeSource = new LoadableModClassPath(packagePath);
57   - }
58   - else
59   - {
60   - LiteLoaderLogger.info("Determining code source using resource");
61   - String reflectionClassPath = EnumeratorModuleProtectionDomain.class.getResource("/net/minecraft/client/main/Main.class").getPath();
62   -
63   - if (reflectionClassPath.indexOf('!') > -1)
64   - {
65   - reflectionClassPath = URLDecoder.decode(reflectionClassPath, "UTF-8");
66   - this.codeSource = new LoadableModClassPath(new File(reflectionClassPath.substring(5, reflectionClassPath.indexOf('!'))));
67   - }
68   - }
69   - }
70   - catch (Throwable th)
71   - {
72   - LiteLoaderLogger.warning("Error determining local protection domain: %s", th.getMessage());
73   - }
74   - }
75   -
76   -
77   - @Override
78   - public void init(LoaderEnvironment environment, LoaderProperties properties)
79   - {
80   - }
81   -
82   - @Override
83   - public void writeSettings(LoaderEnvironment environment, LoaderProperties properties)
84   - {
85   - }
86   -
87   - @Override
88   - public void enumerate(ModularEnumerator enumerator, String profile)
89   - {
90   - }
91   -
92   - @Override
93   - public void injectIntoClassLoader(ModularEnumerator enumerator, LaunchClassLoader classLoader)
94   - {
95   - }
96   -
97   - /**
98   - * @param classLoader
99   - */
100   - @Override
101   - public void registerMods(ModularEnumerator enumerator, LaunchClassLoader classLoader)
102   - {
103   - LiteLoaderLogger.info("Discovering mods in protection domain...");
104   -
105   - try
106   - {
107   - if (this.codeSource != null)
108   - {
109   - enumerator.registerModsFrom(this.codeSource, false);
110   - }
111   - }
112   - catch (Throwable th)
113   - {
114   - LiteLoaderLogger.warning("Error loading from local class path: %s", th.getMessage());
115   - }
116   - }
117   -}
java/common/com/mumfrey/liteloader/core/api/LiteLoaderCoreAPI.java
... ... @@ -28,7 +28,6 @@ public abstract class LiteLoaderCoreAPI implements LiteAPI
28 28 protected LoaderProperties properties;
29 29  
30 30 protected boolean searchClassPath;
31   - protected boolean searchProtectionDomain;
32 31 protected boolean searchModsFolder;
33 32  
34 33 /* (non-Javadoc)
... ... @@ -92,10 +91,9 @@ public abstract class LiteLoaderCoreAPI implements LiteAPI
92 91 void readDiscoverySettings()
93 92 {
94 93 this.searchModsFolder = this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_SEARCH_MODS, true);
95   - this.searchProtectionDomain = this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_SEARCH_JAR, false);
96 94 this.searchClassPath = this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_SEARCH_CLASSPATH, true);
97 95  
98   - if (!this.searchModsFolder && !this.searchProtectionDomain && !this.searchClassPath)
  96 + if (!this.searchModsFolder && !this.searchClassPath)
99 97 {
100 98 LiteLoaderLogger.warning("Invalid configuration, no search locations defined. Enabling all search locations.");
101 99  
... ... @@ -110,7 +108,6 @@ public abstract class LiteLoaderCoreAPI implements LiteAPI
110 108 void writeDiscoverySettings()
111 109 {
112 110 this.properties.setBooleanProperty(LoaderProperties.OPTION_SEARCH_MODS, this.searchModsFolder);
113   - this.properties.setBooleanProperty(LoaderProperties.OPTION_SEARCH_JAR, this.searchProtectionDomain);
114 111 this.properties.setBooleanProperty(LoaderProperties.OPTION_SEARCH_CLASSPATH, this.searchClassPath);
115 112 }
116 113  
... ... @@ -129,19 +126,13 @@ public abstract class LiteLoaderCoreAPI implements LiteAPI
129 126 enumeratorModules.add(new EnumeratorModuleClassPath());
130 127 }
131 128  
132   - if (this.searchProtectionDomain)
133   - {
134   - LiteLoaderLogger.warning("Protection domain searching is no longer required or supported, protection domain search has been disabled");
135   - this.searchProtectionDomain = false;
136   - }
137   -
138 129 if (this.searchModsFolder)
139 130 {
140 131 File modsFolder = this.environment.getModsFolder();
141   - enumeratorModules.add(new EnumeratorModuleFolder(this, modsFolder, true));
  132 + enumeratorModules.add(new EnumeratorModuleFolder(this, modsFolder, false));
142 133  
143 134 File versionedModsFolder = this.environment.getVersionedModsFolder();
144   - enumeratorModules.add(new EnumeratorModuleFolder(this, versionedModsFolder, false));
  135 + enumeratorModules.add(new EnumeratorModuleFolder(this, versionedModsFolder, true));
145 136 }
146 137  
147 138 return Collections.unmodifiableList(enumeratorModules);
... ...
java/common/com/mumfrey/liteloader/core/api/LoadableModClassPath.java
... ... @@ -5,9 +5,7 @@ import java.net.MalformedURLException;
5 5  
6 6 import net.minecraft.launchwrapper.LaunchClassLoader;
7 7  
8   -import com.google.common.base.Charsets;
9 8 import com.mumfrey.liteloader.core.LiteLoaderVersion;
10   -import com.mumfrey.liteloader.interfaces.LoadableMod;
11 9 import com.mumfrey.liteloader.resources.ModResourcePack;
12 10 import com.mumfrey.liteloader.resources.ModResourcePackDir;
13 11 import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
... ... @@ -30,7 +28,7 @@ public class LoadableModClassPath extends LoadableModFile
30 28  
31 29 LoadableModClassPath(File file, String fallbackName)
32 30 {
33   - super(file, LoadableModClassPath.getVersionMetaDataString(file));
  31 + super(file, LoadableModFile.getVersionMetaDataString(file));
34 32  
35 33 if (this.modName == null)
36 34 {
... ... @@ -53,6 +51,12 @@ public class LoadableModClassPath extends LoadableModFile
53 51 }
54 52  
55 53 @Override
  54 + protected void readJarMetaData()
  55 + {
  56 + // Nope
  57 + }
  58 +
  59 + @Override
56 60 protected String getDefaultName()
57 61 {
58 62 return null;
... ... @@ -104,9 +108,4 @@ public class LoadableModClassPath extends LoadableModFile
104 108 this.modName = modName;
105 109 }
106 110 }
107   -
108   - private static String getVersionMetaDataString(File file)
109   - {
110   - return LoadableModFile.getFileContents(file, LoadableMod.METADATA_FILENAME, Charsets.UTF_8);
111   - }
112 111 }
... ...
java/common/com/mumfrey/liteloader/core/api/LoadableModFile.java
... ... @@ -22,7 +22,6 @@ import net.minecraft.client.resources.I18n;
22 22  
23 23 import com.google.common.base.Charsets;
24 24 import com.google.common.io.ByteStreams;
25   -import com.google.common.io.Files;
26 25 import com.google.gson.Gson;
27 26 import com.google.gson.JsonSyntaxException;
28 27 import com.mumfrey.liteloader.api.manager.APIProvider;
... ... @@ -126,21 +125,38 @@ public class LoadableModFile extends LoadableFile implements LoadableMod&lt;File&gt;
126 125  
127 126 /**
128 127 * @param file
129   - * @param strVersion
  128 + * @param metaData
130 129 */
131   - @SuppressWarnings("unchecked")
132   - protected LoadableModFile(File file, String strVersion)
  130 + protected LoadableModFile(File file, String metaData)
133 131 {
134 132 super(file.getAbsolutePath());
135   -
  133 + this.init(metaData);
  134 + }
  135 +
  136 + /**
  137 + * @param file
  138 + * @param metaData
  139 + */
  140 + protected LoadableModFile(LoadableFile file, String metaData)
  141 + {
  142 + super(file);
  143 + this.init(metaData);
  144 + }
  145 +
  146 + /**
  147 + * @param metaData
  148 + */
  149 + @SuppressWarnings("unchecked")
  150 + protected void init(String metaData)
  151 + {
136 152 this.timeStamp = this.lastModified();
137 153 this.tweakPriority = 0;
138 154  
139   - if (!Strings.isNullOrEmpty(strVersion))
  155 + if (!Strings.isNullOrEmpty(metaData))
140 156 {
141 157 try
142 158 {
143   - this.metaData = LoadableModFile.gson.fromJson(strVersion, HashMap.class);
  159 + this.metaData = LoadableModFile.gson.fromJson(metaData, HashMap.class);
144 160 }
145 161 catch (JsonSyntaxException jsx)
146 162 {
... ... @@ -148,11 +164,11 @@ public class LoadableModFile extends LoadableFile implements LoadableMod&lt;File&gt;
148 164 return;
149 165 }
150 166  
151   - this.valid = this.parseVersionFile(strVersion);
  167 + this.valid = this.parseMetaData();
152 168 }
153 169 }
154 170  
155   - protected boolean parseVersionFile(String strVersionData)
  171 + protected boolean parseMetaData()
156 172 {
157 173 try
158 174 {
... ... @@ -165,7 +181,7 @@ public class LoadableModFile extends LoadableFile implements LoadableMod&lt;File&gt;
165 181  
166 182 this.injectionStrategy = InjectionStrategy.parseStrategy(this.getMetaValue("injectAt", null));
167 183  
168   - this.tweakClassName = this.getMetaValue("tweakClass", null);
  184 + this.tweakClassName = this.getMetaValue("tweakClass", this.tweakClassName);
169 185  
170 186 this.getMetaValuesInto(this.classTransformerClassNames, "classTransformerClasses", ",");
171 187 this.getMetaValuesInto(this.dependencies, "dependsOn", ",");
... ... @@ -477,15 +493,6 @@ public class LoadableModFile extends LoadableFile implements LoadableMod&lt;File&gt;
477 493 // Give up and use timestamp
478 494 return (int)(otherMod.timeStamp - this.timeStamp);
479 495 }
480   -
481   - /**
482   - * @param name
483   - * @param charset
484   - */
485   - public String getFileContents(String name, Charset charset)
486   - {
487   - return LoadableModFile.getFileContents(this, name, charset);
488   - }
489 496  
490 497 protected static List<String> enumerateZipFile(File file)
491 498 {
... ... @@ -598,46 +605,8 @@ public class LoadableModFile extends LoadableFile implements LoadableMod&lt;File&gt;
598 605 return new String(bytes, bomOffset, bytes.length - bomOffset, charset);
599 606 }
600 607  
601   - /**
602   - * @param parent
603   - * @param name
604   - * @param charset
605   - */
606   - public static String getFileContents(File parent, String name, Charset charset)
  608 + protected static String getVersionMetaDataString(File file)
607 609 {
608   - try
609   - {
610   - if (parent.isDirectory())
611   - {
612   - File file = new File(parent, name);
613   - if (file.isFile())
614   - {
615   - return Files.toString(file, charset);
616   - }
617   - }
618   - else
619   - {
620   - String content = null;
621   - ZipFile zipFile = new ZipFile(parent);
622   - ZipEntry zipEntry = zipFile.getEntry(name);
623   - if (zipEntry != null)
624   - {
625   - try
626   - {
627   - content = LoadableModFile.zipEntryToString(zipFile, zipEntry);
628   - }
629   - catch (IOException ex) {}
630   - }
631   -
632   - zipFile.close();
633   - return content;
634   - }
635   - }
636   - catch (IOException ex)
637   - {
638   - ex.printStackTrace();
639   - }
640   -
641   - return null;
  610 + return LoadableFile.getFileContents(file, LoadableMod.METADATA_FILENAME, Charsets.UTF_8);
642 611 }
643 612 }
... ...
java/common/com/mumfrey/liteloader/interfaces/LoadableFile.java
... ... @@ -4,14 +4,22 @@ import java.io.File;
4 4 import java.io.IOException;
5 5 import java.net.MalformedURLException;
6 6 import java.net.URL;
  7 +import java.nio.charset.Charset;
7 8 import java.util.ArrayList;
  9 +import java.util.Collections;
  10 +import java.util.HashSet;
8 11 import java.util.List;
  12 +import java.util.Set;
9 13 import java.util.jar.Attributes;
10 14 import java.util.jar.JarFile;
11 15 import java.util.regex.Matcher;
12 16 import java.util.regex.Pattern;
  17 +import java.util.zip.ZipEntry;
  18 +import java.util.zip.ZipFile;
13 19  
  20 +import com.google.common.io.Files;
14 21 import com.google.common.primitives.Ints;
  22 +import com.mumfrey.liteloader.core.api.LoadableModFile;
15 23 import com.mumfrey.liteloader.launch.ClassPathUtilities;
16 24 import com.mumfrey.liteloader.launch.InjectionStrategy;
17 25 import com.mumfrey.liteloader.launch.LiteLoaderTweaker;
... ... @@ -37,6 +45,8 @@ public class LoadableFile extends File implements TweakContainer&lt;File&gt;
37 45 * inject above a specified other library matching "name".
38 46 */
39 47 protected InjectionStrategy injectionStrategy = null;
  48 +
  49 + protected Set<String> modSystems = new HashSet<String>();
40 50  
41 51 /**
42 52 * Name of the tweak class
... ... @@ -67,7 +77,17 @@ public class LoadableFile extends File implements TweakContainer&lt;File&gt;
67 77 super(parent.getAbsolutePath());
68 78 this.displayName = this.getName();
69 79 this.guessVersionFromName();
70   - this.readMetaData();
  80 + this.readJarMetaData();
  81 + }
  82 +
  83 + /**
  84 + * ctor for subclasses
  85 + */
  86 + protected LoadableFile(LoadableFile file)
  87 + {
  88 + super(file.getAbsolutePath());
  89 + this.displayName = this.getName();
  90 + this.assignJarMetaData(file);
71 91 }
72 92  
73 93 /**
... ... @@ -77,6 +97,7 @@ public class LoadableFile extends File implements TweakContainer&lt;File&gt;
77 97 {
78 98 super(pathname);
79 99 this.displayName = this.getName();
  100 + this.readJarMetaData();
80 101 }
81 102  
82 103 private void guessVersionFromName()
... ... @@ -86,21 +107,51 @@ public class LoadableFile extends File implements TweakContainer&lt;File&gt;
86 107 this.version = versionPatternMatcher.group();
87 108 }
88 109  
  110 + protected void assignJarMetaData(LoadableFile file)
  111 + {
  112 + this.modSystems = file.modSystems;
  113 + this.tweakClassName = file.tweakClassName;
  114 + this.classPathEntries = file.classPathEntries;
  115 + this.tweakPriority = file.tweakPriority;
  116 + this.displayName = file.displayName;
  117 + this.version = file.version;
  118 + this.author = file.author;
  119 + this.injectionStrategy = file.injectionStrategy;
  120 + }
  121 +
89 122 /**
90 123 * Search for tweaks in this file
91 124 */
92   - private void readMetaData()
  125 + protected void readJarMetaData()
93 126 {
94 127 JarFile jar = null;
95 128  
  129 + if (this.isDirectory())
  130 + {
  131 + return;
  132 + }
  133 +
96 134 try
97 135 {
98 136 jar = new JarFile(this);
99 137 if (jar.getManifest() != null)
100 138 {
101   - LiteLoaderLogger.info("Searching for tweaks in '%s'", this.getName());
  139 + LiteLoaderLogger.info("Inspecting jar metadata in '%s'", this.getName());
102 140 Attributes manifestAttributes = jar.getManifest().getMainAttributes();
103 141  
  142 + String modSystemList = manifestAttributes.getValue("ModType");
  143 + if (modSystemList != null)
  144 + {
  145 + for (String modSystem : modSystemList.split(","))
  146 + {
  147 + modSystem = modSystem.trim();
  148 + if (modSystem.length() > 0)
  149 + {
  150 + this.modSystems.add(modSystem);
  151 + }
  152 + }
  153 + }
  154 +
104 155 this.tweakClassName = manifestAttributes.getValue("TweakClass");
105 156 if (this.tweakClassName != null)
106 157 {
... ... @@ -110,11 +161,14 @@ public class LoadableFile extends File implements TweakContainer&lt;File&gt;
110 161 this.classPathEntries = classPath.split(" ");
111 162 }
112 163 }
113   -
114   - Integer tweakOrder = Ints.tryParse(manifestAttributes.getValue("TweakOrder"));
115   - if (tweakOrder != null)
  164 +
  165 + if (manifestAttributes.getValue("TweakOrder") != null)
116 166 {
117   - this.tweakPriority = tweakOrder.intValue();
  167 + Integer tweakOrder = Ints.tryParse(manifestAttributes.getValue("TweakOrder"));
  168 + if (tweakOrder != null)
  169 + {
  170 + this.tweakPriority = tweakOrder.intValue();
  171 + }
118 172 }
119 173  
120 174 if (manifestAttributes.getValue("Implementation-Title") != null)
... ... @@ -140,7 +194,7 @@ public class LoadableFile extends File implements TweakContainer&lt;File&gt;
140 194 }
141 195 catch (Exception ex)
142 196 {
143   - LiteLoaderLogger.warning("Error parsing manifest entries in '%s'", this.getAbsolutePath());
  197 + LiteLoaderLogger.warning("Could not parse jar metadata in '%s'", this);
144 198 }
145 199 finally
146 200 {
... ... @@ -152,6 +206,11 @@ public class LoadableFile extends File implements TweakContainer&lt;File&gt;
152 206 }
153 207 }
154 208  
  209 + public Set<String> getModSystems()
  210 + {
  211 + return Collections.unmodifiableSet(this.modSystems);
  212 + }
  213 +
155 214 @Override
156 215 public File getTarget()
157 216 {
... ... @@ -309,4 +368,62 @@ public class LoadableFile extends File implements TweakContainer&lt;File&gt;
309 368 {
310 369 return environment.getEnabledModsList().isEnabled(environment.getProfile(), this.getIdentifier());
311 370 }
  371 +
  372 + @Override
  373 + public String toString()
  374 + {
  375 + return this.getLocation();
  376 + }
  377 +
  378 + /**
  379 + * @param name
  380 + * @param charset
  381 + */
  382 + public String getFileContents(String name, Charset charset)
  383 + {
  384 + return LoadableFile.getFileContents(this, name, charset);
  385 + }
  386 +
  387 + /**
  388 + * @param parent
  389 + * @param name
  390 + * @param charset
  391 + */
  392 + public static String getFileContents(File parent, String name, Charset charset)
  393 + {
  394 + try
  395 + {
  396 + if (parent.isDirectory())
  397 + {
  398 + File file = new File(parent, name);
  399 + if (file.isFile())
  400 + {
  401 + return Files.toString(file, charset);
  402 + }
  403 + }
  404 + else
  405 + {
  406 + String content = null;
  407 + ZipFile zipFile = new ZipFile(parent);
  408 + ZipEntry zipEntry = zipFile.getEntry(name);
  409 + if (zipEntry != null)
  410 + {
  411 + try
  412 + {
  413 + content = LoadableModFile.zipEntryToString(zipFile, zipEntry);
  414 + }
  415 + catch (IOException ex) {}
  416 + }
  417 +
  418 + zipFile.close();
  419 + return content;
  420 + }
  421 + }
  422 + catch (IOException ex)
  423 + {
  424 + ex.printStackTrace();
  425 + }
  426 +
  427 + return null;
  428 + }
312 429 }
313 430 \ No newline at end of file
... ...
java/common/com/mumfrey/liteloader/interfaces/LoadableMod.java
... ... @@ -8,6 +8,7 @@ import java.util.HashSet;
8 8 import java.util.List;
9 9 import java.util.Set;
10 10  
  11 +import com.google.common.collect.ImmutableSet;
11 12 import com.mumfrey.liteloader.launch.InjectionStrategy;
12 13 import com.mumfrey.liteloader.launch.LoaderEnvironment;
13 14  
... ... @@ -24,8 +25,11 @@ public interface LoadableMod&lt;L&gt; extends Loadable&lt;L&gt;, Injectable
24 25 {
25 26 static final String METADATA_FILENAME = "litemod.json";
26 27  
27   - static final String LEGACY_METADATA_FILENAME = "version.txt";
28   -
  28 + /**
  29 + * Get the mod systems declared in the jar metadata
  30 + */
  31 + public abstract Set<String> getModSystems();
  32 +
29 33 /**
30 34 * Get the name of the mod
31 35 */
... ... @@ -132,6 +136,8 @@ public interface LoadableMod&lt;L&gt; extends Loadable&lt;L&gt;, Injectable
132 136 */
133 137 public class EmptyModContainer implements LoadableMod<File>
134 138 {
  139 + private static final ImmutableSet<String> EMPTY_SET = ImmutableSet.<String>of();
  140 +
135 141 EmptyModContainer() {}
136 142  
137 143 @Override
... ... @@ -139,6 +145,12 @@ public interface LoadableMod&lt;L&gt; extends Loadable&lt;L&gt;, Injectable
139 145 {
140 146 return null;
141 147 }
  148 +
  149 + @Override
  150 + public Set<String> getModSystems()
  151 + {
  152 + return EmptyModContainer.EMPTY_SET;
  153 + }
142 154  
143 155 @Override
144 156 public String getName()
... ...
java/common/com/mumfrey/liteloader/launch/LoaderProperties.java
... ... @@ -94,8 +94,6 @@ public interface LoaderProperties
94 94  
95 95 // Enumerator properties
96 96 public static final String OPTION_SEARCH_MODS = "search.mods";
97   - public static final String OPTION_SEARCH_JAR = "search.jar";
98 97 public static final String OPTION_SEARCH_CLASSPATH = "search.classpath";
99   - public static final String OPTION_SEARCH_ZIPFILES = "search.zipfiles";
100 98 public static final String OPTION_SEARCH_JARFILES = "search.jarfiles";
101 99 }
... ...