Commit a1377b8d403baf8188f23daf54ea5ff2d5146f25
1 parent
70fa603a
LiteLoader 1.6.2 - replaced version.txt functionality with litemod.json, added v…
…ersion ordering and filtering for mods
Showing
9 changed files
with
795 additions
and
416 deletions
.classpath
@@ -6,5 +6,6 @@ | @@ -6,5 +6,6 @@ | ||
6 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> | 6 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> |
7 | <classpathentry kind="lib" path="/Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar"/> | 7 | <classpathentry kind="lib" path="/Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar"/> |
8 | <classpathentry kind="lib" path="/Client/jars/versions/1.6.2/1.6.2.jar"/> | 8 | <classpathentry kind="lib" path="/Client/jars/versions/1.6.2/1.6.2.jar"/> |
9 | + <classpathentry kind="lib" path="/Client/jars/libraries/com/google/code/gson/gson/2.2.2/gson-2.2.2.jar"/> | ||
9 | <classpathentry kind="output" path="bin"/> | 10 | <classpathentry kind="output" path="bin"/> |
10 | </classpath> | 11 | </classpath> |
java/com/mumfrey/liteloader/core/HookChat.java
@@ -136,39 +136,39 @@ public class HookChat extends Packet3Chat | @@ -136,39 +136,39 @@ public class HookChat extends Packet3Chat | ||
136 | /** | 136 | /** |
137 | * Register this packet as the new packet for packet ID 3 | 137 | * Register this packet as the new packet for packet ID 3 |
138 | */ | 138 | */ |
139 | - public static void register() | ||
140 | - { | ||
141 | - register(false); | ||
142 | - } | ||
143 | - | ||
144 | - /** | ||
145 | - * Register this packet as the new packet for packet ID 3 and optionally force re-registration even | ||
146 | - * if registration was performed already. | ||
147 | - * | ||
148 | - * @param force Force registration even if registration was already performed previously. | ||
149 | - */ | ||
150 | - @SuppressWarnings({ "unchecked", "rawtypes" }) | 139 | + public static void register() |
140 | + { | ||
141 | + register(false); | ||
142 | + } | ||
143 | + | ||
144 | + /** | ||
145 | + * Register this packet as the new packet for packet ID 3 and optionally force re-registration even | ||
146 | + * if registration was performed already. | ||
147 | + * | ||
148 | + * @param force Force registration even if registration was already performed previously. | ||
149 | + */ | ||
150 | + @SuppressWarnings({ "unchecked", "rawtypes" }) | ||
151 | public static void register(boolean force) | 151 | public static void register(boolean force) |
152 | { | 152 | { |
153 | if (!registered || force) | 153 | if (!registered || force) |
154 | { | 154 | { |
155 | try | 155 | try |
156 | { | 156 | { |
157 | - IntHashMap packetIdToClassMap = Packet.packetIdToClassMap; | ||
158 | - proxyClass = (Class<? extends Packet>)packetIdToClassMap.lookup(3); | ||
159 | - | ||
160 | - if (proxyClass.equals(Packet3Chat.class)) | ||
161 | - { | ||
162 | - proxyClass = null; | ||
163 | - } | ||
164 | - | ||
165 | - packetIdToClassMap.removeObject(3); | ||
166 | - packetIdToClassMap.addKey(3, HookChat.class); | ||
167 | - | ||
168 | - Map packetClassToIdMap = PrivateFields.StaticFields.packetClassToIdMap.get(); | ||
169 | - packetClassToIdMap.put(HookChat.class, Integer.valueOf(3)); | ||
170 | - | ||
171 | - registered = true; | 157 | + IntHashMap packetIdToClassMap = Packet.packetIdToClassMap; |
158 | + proxyClass = (Class<? extends Packet>)packetIdToClassMap.lookup(3); | ||
159 | + | ||
160 | + if (proxyClass.equals(Packet3Chat.class)) | ||
161 | + { | ||
162 | + proxyClass = null; | ||
163 | + } | ||
164 | + | ||
165 | + packetIdToClassMap.removeObject(3); | ||
166 | + packetIdToClassMap.addKey(3, HookChat.class); | ||
167 | + | ||
168 | + Map packetClassToIdMap = PrivateFields.StaticFields.packetClassToIdMap.get(); | ||
169 | + packetClassToIdMap.put(HookChat.class, Integer.valueOf(3)); | ||
170 | + | ||
171 | + registered = true; | ||
172 | } | 172 | } |
173 | catch (Exception ex) | 173 | catch (Exception ex) |
174 | { | 174 | { |
java/com/mumfrey/liteloader/core/HookPluginChannels.java
@@ -128,39 +128,39 @@ public class HookPluginChannels extends Packet250CustomPayload | @@ -128,39 +128,39 @@ public class HookPluginChannels extends Packet250CustomPayload | ||
128 | /** | 128 | /** |
129 | * Register this packet as the new packet for packet ID 250 | 129 | * Register this packet as the new packet for packet ID 250 |
130 | */ | 130 | */ |
131 | - public static void register() | ||
132 | - { | ||
133 | - register(false); | ||
134 | - } | ||
135 | - | ||
136 | - /** | ||
137 | - * Register this packet as the new packet for packet ID 250 and optionally force re-registration even | ||
138 | - * if registration was performed already. | ||
139 | - * | ||
140 | - * @param force Force registration even if registration was already performed previously. | ||
141 | - */ | ||
142 | - @SuppressWarnings({ "unchecked", "rawtypes" }) | 131 | + public static void register() |
132 | + { | ||
133 | + register(false); | ||
134 | + } | ||
135 | + | ||
136 | + /** | ||
137 | + * Register this packet as the new packet for packet ID 250 and optionally force re-registration even | ||
138 | + * if registration was performed already. | ||
139 | + * | ||
140 | + * @param force Force registration even if registration was already performed previously. | ||
141 | + */ | ||
142 | + @SuppressWarnings({ "unchecked", "rawtypes" }) | ||
143 | public static void register(boolean force) | 143 | public static void register(boolean force) |
144 | { | 144 | { |
145 | if (!registered || force) | 145 | if (!registered || force) |
146 | { | 146 | { |
147 | try | 147 | try |
148 | { | 148 | { |
149 | - IntHashMap packetIdToClassMap = Packet.packetIdToClassMap; | ||
150 | - proxyClass = (Class<? extends Packet>)packetIdToClassMap.lookup(250); | ||
151 | - | ||
152 | - if (proxyClass.equals(Packet250CustomPayload.class)) | ||
153 | - { | ||
154 | - proxyClass = null; | ||
155 | - } | ||
156 | - | ||
157 | - packetIdToClassMap.removeObject(250); | ||
158 | - packetIdToClassMap.addKey(250, HookPluginChannels.class); | ||
159 | - | ||
160 | - Map packetClassToIdMap = PrivateFields.StaticFields.packetClassToIdMap.get(); | ||
161 | - packetClassToIdMap.put(HookPluginChannels.class, Integer.valueOf(250)); | ||
162 | - | ||
163 | - registered = true; | 149 | + IntHashMap packetIdToClassMap = Packet.packetIdToClassMap; |
150 | + proxyClass = (Class<? extends Packet>)packetIdToClassMap.lookup(250); | ||
151 | + | ||
152 | + if (proxyClass.equals(Packet250CustomPayload.class)) | ||
153 | + { | ||
154 | + proxyClass = null; | ||
155 | + } | ||
156 | + | ||
157 | + packetIdToClassMap.removeObject(250); | ||
158 | + packetIdToClassMap.addKey(250, HookPluginChannels.class); | ||
159 | + | ||
160 | + Map packetClassToIdMap = PrivateFields.StaticFields.packetClassToIdMap.get(); | ||
161 | + packetClassToIdMap.put(HookPluginChannels.class, Integer.valueOf(250)); | ||
162 | + | ||
163 | + registered = true; | ||
164 | } | 164 | } |
165 | catch (Exception ex) | 165 | catch (Exception ex) |
166 | { | 166 | { |
java/com/mumfrey/liteloader/core/LiteLoader.java
@@ -10,16 +10,23 @@ import java.io.IOException; | @@ -10,16 +10,23 @@ import java.io.IOException; | ||
10 | import java.io.InputStream; | 10 | import java.io.InputStream; |
11 | import java.io.InputStreamReader; | 11 | import java.io.InputStreamReader; |
12 | import java.io.PrintStream; | 12 | import java.io.PrintStream; |
13 | +import java.io.UnsupportedEncodingException; | ||
13 | import java.lang.reflect.Method; | 14 | import java.lang.reflect.Method; |
15 | +import java.net.MalformedURLException; | ||
16 | +import java.net.URISyntaxException; | ||
14 | import java.net.URL; | 17 | import java.net.URL; |
15 | import java.net.URLClassLoader; | 18 | import java.net.URLClassLoader; |
16 | import java.net.URLDecoder; | 19 | import java.net.URLDecoder; |
17 | import java.nio.charset.Charset; | 20 | import java.nio.charset.Charset; |
21 | +import java.util.ArrayList; | ||
18 | import java.util.HashMap; | 22 | import java.util.HashMap; |
19 | import java.util.Iterator; | 23 | import java.util.Iterator; |
20 | import java.util.LinkedList; | 24 | import java.util.LinkedList; |
21 | import java.util.List; | 25 | import java.util.List; |
26 | +import java.util.Map; | ||
27 | +import java.util.Map.Entry; | ||
22 | import java.util.Properties; | 28 | import java.util.Properties; |
29 | +import java.util.TreeSet; | ||
23 | import java.util.logging.FileHandler; | 30 | import java.util.logging.FileHandler; |
24 | import java.util.logging.Formatter; | 31 | import java.util.logging.Formatter; |
25 | import java.util.logging.Level; | 32 | import java.util.logging.Level; |
@@ -71,7 +78,6 @@ import com.mumfrey.liteloader.util.PrivateFields; | @@ -71,7 +78,6 @@ import com.mumfrey.liteloader.util.PrivateFields; | ||
71 | * @author Adam Mummery-Smith | 78 | * @author Adam Mummery-Smith |
72 | * @version 1.6.2 | 79 | * @version 1.6.2 |
73 | */ | 80 | */ |
74 | -@SuppressWarnings("rawtypes") | ||
75 | public final class LiteLoader implements FilenameFilter, IPlayerUsage | 81 | public final class LiteLoader implements FilenameFilter, IPlayerUsage |
76 | { | 82 | { |
77 | /** | 83 | /** |
@@ -115,6 +121,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -115,6 +121,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
115 | private static String profile = ""; | 121 | private static String profile = ""; |
116 | 122 | ||
117 | /** | 123 | /** |
124 | + * List of mods passed into the command line | ||
125 | + */ | ||
126 | + private static List<String> modNameFilter = null; | ||
127 | + | ||
128 | + /** | ||
118 | * Mods folder which contains mods and legacy config files | 129 | * Mods folder which contains mods and legacy config files |
119 | */ | 130 | */ |
120 | private File modsFolder; | 131 | private File modsFolder; |
@@ -173,6 +184,16 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -173,6 +184,16 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
173 | private Timer minecraftTimer; | 184 | private Timer minecraftTimer; |
174 | 185 | ||
175 | /** | 186 | /** |
187 | + * Classes to load, mapped by class name | ||
188 | + */ | ||
189 | + private Map<String, Class<? extends LiteMod>> modsToLoad = new HashMap<String, Class<? extends LiteMod>>(); | ||
190 | + | ||
191 | + /** | ||
192 | + * Mod metadata from version file | ||
193 | + */ | ||
194 | + private Map<String, ModFile> modFiles = new HashMap<String, ModFile>(); | ||
195 | + | ||
196 | + /** | ||
176 | * List of loaded mods, for crash reporting | 197 | * List of loaded mods, for crash reporting |
177 | */ | 198 | */ |
178 | private String loadedModsList = "none"; | 199 | private String loadedModsList = "none"; |
@@ -280,8 +301,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -280,8 +301,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
280 | * Permission Manager | 301 | * Permission Manager |
281 | */ | 302 | */ |
282 | private static PermissionsManagerClient permissionsManager = PermissionsManagerClient.getInstance(); | 303 | private static PermissionsManagerClient permissionsManager = PermissionsManagerClient.getInstance(); |
283 | - | ||
284 | - public static final void init(File gameDirectory, File assetsDirectory, String profile) | 304 | + |
305 | + public static final void init(File gameDirectory, File assetsDirectory, String profile, List<String> modNameFilter) | ||
285 | { | 306 | { |
286 | if (instance == null) | 307 | if (instance == null) |
287 | { | 308 | { |
@@ -289,6 +310,22 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -289,6 +310,22 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
289 | LiteLoader.assetsDirectory = assetsDirectory; | 310 | LiteLoader.assetsDirectory = assetsDirectory; |
290 | LiteLoader.profile = profile; | 311 | LiteLoader.profile = profile; |
291 | 312 | ||
313 | + try | ||
314 | + { | ||
315 | + if (modNameFilter != null) | ||
316 | + { | ||
317 | + LiteLoader.modNameFilter = new ArrayList<String>(); | ||
318 | + for (String filterEntry : modNameFilter) | ||
319 | + { | ||
320 | + LiteLoader.modNameFilter.add(filterEntry.toLowerCase().trim()); | ||
321 | + } | ||
322 | + } | ||
323 | + } | ||
324 | + catch (Exception ex) | ||
325 | + { | ||
326 | + LiteLoader.modNameFilter = null; | ||
327 | + } | ||
328 | + | ||
292 | instance = new LiteLoader(); | 329 | instance = new LiteLoader(); |
293 | instance.initLoader(); | 330 | instance.initLoader(); |
294 | } | 331 | } |
@@ -371,14 +408,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -371,14 +408,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
371 | this.commonConfigFolder = new File(this.configBaseFolder, "common"); | 408 | this.commonConfigFolder = new File(this.configBaseFolder, "common"); |
372 | this.versionConfigFolder = this.inflectVersionedConfigPath(LiteLoader.VERSION); | 409 | this.versionConfigFolder = this.inflectVersionedConfigPath(LiteLoader.VERSION); |
373 | 410 | ||
374 | - if (!this.modsFolder.exists()) | ||
375 | - this.modsFolder.mkdirs(); | ||
376 | - if (!this.configBaseFolder.exists()) | ||
377 | - this.configBaseFolder.mkdirs(); | ||
378 | - if (!this.commonConfigFolder.exists()) | ||
379 | - this.commonConfigFolder.mkdirs(); | ||
380 | - if (!this.versionConfigFolder.exists()) | ||
381 | - this.versionConfigFolder.mkdirs(); | 411 | + if (!this.modsFolder.exists()) this.modsFolder.mkdirs(); |
412 | + if (!this.configBaseFolder.exists()) this.configBaseFolder.mkdirs(); | ||
413 | + if (!this.commonConfigFolder.exists()) this.commonConfigFolder.mkdirs(); | ||
414 | + if (!this.versionConfigFolder.exists()) this.versionConfigFolder.mkdirs(); | ||
382 | 415 | ||
383 | this.propertiesFile = new File(this.configBaseFolder, "liteloader.properties"); | 416 | this.propertiesFile = new File(this.configBaseFolder, "liteloader.properties"); |
384 | } | 417 | } |
@@ -402,8 +435,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -402,8 +435,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
402 | */ | 435 | */ |
403 | private void initLoader() | 436 | private void initLoader() |
404 | { | 437 | { |
405 | - if (this.loaderStartupDone) | ||
406 | - return; | 438 | + if (this.loaderStartupDone) return; |
407 | this.loaderStartupDone = true; | 439 | this.loaderStartupDone = true; |
408 | 440 | ||
409 | // Set up loader, initialises any reflection methods needed | 441 | // Set up loader, initialises any reflection methods needed |
@@ -700,8 +732,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -700,8 +732,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
700 | /** | 732 | /** |
701 | * Get a reference to a loaded mod, if the mod exists | 733 | * Get a reference to a loaded mod, if the mod exists |
702 | * | 734 | * |
703 | - * @param modName | ||
704 | - * Mod's name or class name | 735 | + * @param modName Mod's name or class name |
705 | * @return | 736 | * @return |
706 | * @throws InvalidActivityException | 737 | * @throws InvalidActivityException |
707 | */ | 738 | */ |
@@ -728,13 +759,65 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -728,13 +759,65 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
728 | } | 759 | } |
729 | 760 | ||
730 | /** | 761 | /** |
762 | + * Get whether the specified mod is installed | ||
763 | + * | ||
764 | + * @param modName | ||
765 | + * @return | ||
766 | + */ | ||
767 | + public boolean isModInstalled(String modName) | ||
768 | + { | ||
769 | + if (!this.loaderStartupComplete || modName == null) return false; | ||
770 | + | ||
771 | + for (LiteMod mod : this.mods) | ||
772 | + { | ||
773 | + if (modName.equalsIgnoreCase(mod.getName()) || modName.equalsIgnoreCase(mod.getClass().getSimpleName())) return true; | ||
774 | + } | ||
775 | + | ||
776 | + return true; | ||
777 | + } | ||
778 | + | ||
779 | + /** | ||
780 | + * Get metadata for the specified mod, attempts to retrieve the mod by name first | ||
781 | + * | ||
782 | + * @param mod | ||
783 | + * @param metaDataKey | ||
784 | + * @param defaultValue | ||
785 | + * @return | ||
786 | + * @throws InvalidActivityException | ||
787 | + * @throws IllegalArgumentException | ||
788 | + */ | ||
789 | + public String getModMetaData(String mod, String metaDataKey, String defaultValue) throws InvalidActivityException, IllegalArgumentException | ||
790 | + { | ||
791 | + return this.getModMetaData(this.getMod(mod), metaDataKey, defaultValue); | ||
792 | + } | ||
793 | + | ||
794 | + /** | ||
795 | + * Get a metadata value for the specified mod | ||
796 | + * | ||
797 | + * @param mod | ||
798 | + * @param metaDataKey | ||
799 | + * @param defaultValue | ||
800 | + * @return | ||
801 | + */ | ||
802 | + public String getModMetaData(LiteMod mod, String metaDataKey, String defaultValue) | ||
803 | + { | ||
804 | + if (mod == null || metaDataKey == null) return defaultValue; | ||
805 | + | ||
806 | + String modClassName = mod.getClass().getSimpleName(); | ||
807 | + if (!this.modFiles.containsKey(modClassName)) return defaultValue; | ||
808 | + | ||
809 | + ModFile modFile = this.modFiles.get(modClassName); | ||
810 | + return modFile.getMetaValue(metaDataKey, defaultValue); | ||
811 | + } | ||
812 | + | ||
813 | + /** | ||
731 | * Enumerate the java class path and "mods" folder to find mod classes, then | 814 | * Enumerate the java class path and "mods" folder to find mod classes, then |
732 | * load the classes | 815 | * load the classes |
733 | */ | 816 | */ |
734 | private void prepareMods(boolean searchMods, boolean searchProtectionDomain, boolean searchClassPath) | 817 | private void prepareMods(boolean searchMods, boolean searchProtectionDomain, boolean searchClassPath) |
735 | { | 818 | { |
736 | // List of mod files in the "mods" folder | 819 | // List of mod files in the "mods" folder |
737 | - LinkedList<File> modFiles = new LinkedList<File>(); | 820 | + List<ModFile> modFiles = new LinkedList<ModFile>(); |
738 | 821 | ||
739 | if (searchMods) | 822 | if (searchMods) |
740 | { | 823 | { |
@@ -748,8 +831,6 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -748,8 +831,6 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
748 | } | 831 | } |
749 | } | 832 | } |
750 | 833 | ||
751 | - // Find and enumerate classes on the class path | ||
752 | - HashMap<String, Class> modsToLoad = null; | ||
753 | try | 834 | try |
754 | { | 835 | { |
755 | logger.info("Enumerating class path..."); | 836 | logger.info("Enumerating class path..."); |
@@ -763,7 +844,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -763,7 +844,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
763 | 844 | ||
764 | if (searchProtectionDomain || searchClassPath) | 845 | if (searchProtectionDomain || searchClassPath) |
765 | logger.info("Discovering mods on class path..."); | 846 | logger.info("Discovering mods on class path..."); |
766 | - modsToLoad = this.findModClasses(classPathEntries, modFiles, searchProtectionDomain, searchClassPath); | 847 | + |
848 | + this.findModClasses(classPathEntries, modFiles, searchProtectionDomain, searchClassPath); | ||
767 | 849 | ||
768 | logger.info("Mod class discovery completed"); | 850 | logger.info("Mod class discovery completed"); |
769 | } | 851 | } |
@@ -773,44 +855,87 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -773,44 +855,87 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
773 | return; | 855 | return; |
774 | } | 856 | } |
775 | 857 | ||
776 | - this.loadMods(modsToLoad); | 858 | + this.loadMods(); |
777 | } | 859 | } |
778 | 860 | ||
779 | /** | 861 | /** |
780 | * Find mod files in the "mods" folder | 862 | * Find mod files in the "mods" folder |
781 | * | 863 | * |
782 | - * @param modFolder | ||
783 | - * Folder to search | ||
784 | - * @param modFiles | ||
785 | - * List of mod files to load | 864 | + * @param modFolder Folder to search |
865 | + * @param modFiles List of mod files to load | ||
786 | */ | 866 | */ |
787 | - protected void findModFiles(File modFolder, LinkedList<File> modFiles) | 867 | + protected void findModFiles(File modFolder, List<ModFile> modFiles) |
788 | { | 868 | { |
869 | + Map<String, TreeSet<ModFile>> versionOrderingSets = new HashMap<String, TreeSet<ModFile>>(); | ||
870 | + | ||
789 | for (File modFile : modFolder.listFiles(this)) | 871 | for (File modFile : modFolder.listFiles(this)) |
790 | { | 872 | { |
791 | try | 873 | try |
792 | { | 874 | { |
875 | + String strVersion = null; | ||
876 | + | ||
793 | // Check for a version file | 877 | // Check for a version file |
794 | ZipFile modZip = new ZipFile(modFile); | 878 | ZipFile modZip = new ZipFile(modFile); |
795 | - ZipEntry version = modZip.getEntry("version.txt"); | 879 | + ZipEntry version = modZip.getEntry("litemod.json"); |
880 | + | ||
881 | + if (version == null) | ||
882 | + { | ||
883 | + version = modZip.getEntry("version.txt"); | ||
884 | + } | ||
796 | 885 | ||
797 | if (version != null) | 886 | if (version != null) |
798 | { | 887 | { |
799 | - // Read the version string | ||
800 | - InputStream versionStream = modZip.getInputStream(version); | ||
801 | - BufferedReader versionReader = new BufferedReader(new InputStreamReader(versionStream)); | ||
802 | - String strVersion = versionReader.readLine(); | ||
803 | - versionReader.close(); | 888 | + BufferedReader versionReader = null; |
889 | + StringBuilder versionBuilder = new StringBuilder(); | ||
804 | 890 | ||
805 | - // Only add the mod if the version matches and we were able | ||
806 | - // to successfully add it to the class path | ||
807 | - if (LiteLoader.VERSION.isVersionSupported(strVersion) && this.addURLToClassPath(modFile.toURI().toURL())) | 891 | + try |
808 | { | 892 | { |
809 | - modFiles.add(modFile); | 893 | + // Read the version string |
894 | + InputStream versionStream = modZip.getInputStream(version); | ||
895 | + versionReader = new BufferedReader(new InputStreamReader(versionStream)); | ||
896 | + | ||
897 | + String versionFileLine; | ||
898 | + while ((versionFileLine = versionReader.readLine()) != null) | ||
899 | + versionBuilder.append(versionFileLine); | ||
900 | + | ||
901 | + strVersion = versionBuilder.toString(); | ||
810 | } | 902 | } |
811 | - else | 903 | + catch (Exception ex) |
904 | + { | ||
905 | + logger.warning("Error reading version data from " + modFile.getName()); | ||
906 | + } | ||
907 | + finally | ||
812 | { | 908 | { |
813 | - logger.info("Not adding invalid or outdated mod file: " + modFile.getAbsolutePath()); | 909 | + if (versionReader != null) versionReader.close(); |
910 | + } | ||
911 | + | ||
912 | + if (strVersion != null) | ||
913 | + { | ||
914 | + ModFile modFileInfo = new ModFile(modFile, strVersion); | ||
915 | + | ||
916 | + if (modFileInfo.isValid()) | ||
917 | + { | ||
918 | + // Only add the mod if the version matches and we were able | ||
919 | + // to successfully add it to the class path | ||
920 | + if (LiteLoader.VERSION.isVersionSupported(modFileInfo.getVersion())) | ||
921 | + { | ||
922 | + if (!modFileInfo.isJson()) | ||
923 | + { | ||
924 | + logger.warning("Missing or invalid litemod.json reading mod file: " + modFile.getAbsolutePath()); | ||
925 | + } | ||
926 | + | ||
927 | + if (!versionOrderingSets.containsKey(modFileInfo.getName())) | ||
928 | + { | ||
929 | + versionOrderingSets.put(modFileInfo.getName(), new TreeSet<ModFile>()); | ||
930 | + } | ||
931 | + | ||
932 | + versionOrderingSets.get(modFileInfo.getName()).add(modFileInfo); | ||
933 | + } | ||
934 | + else | ||
935 | + { | ||
936 | + logger.info("Not adding invalid or outdated mod file: " + modFile.getAbsolutePath()); | ||
937 | + } | ||
938 | + } | ||
814 | } | 939 | } |
815 | } | 940 | } |
816 | 941 | ||
@@ -818,9 +943,28 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -818,9 +943,28 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
818 | } | 943 | } |
819 | catch (Exception ex) | 944 | catch (Exception ex) |
820 | { | 945 | { |
946 | + ex.printStackTrace(System.err); | ||
821 | logger.warning("Error enumerating '" + modFile.getAbsolutePath() + "': Invalid zip file or error reading file"); | 947 | logger.warning("Error enumerating '" + modFile.getAbsolutePath() + "': Invalid zip file or error reading file"); |
822 | } | 948 | } |
823 | } | 949 | } |
950 | + | ||
951 | + // Copy the first entry in every version set into the modfiles list | ||
952 | + for (Entry<String, TreeSet<ModFile>> modFileEntry : versionOrderingSets.entrySet()) | ||
953 | + { | ||
954 | + ModFile newestVersion = modFileEntry.getValue().iterator().next(); | ||
955 | + | ||
956 | + try | ||
957 | + { | ||
958 | + if (this.addURLToClassPath(newestVersion.toURI().toURL())) | ||
959 | + { | ||
960 | + modFiles.add(newestVersion); | ||
961 | + } | ||
962 | + } | ||
963 | + catch (Exception ex) | ||
964 | + { | ||
965 | + logger.warning("Error injecting '" + newestVersion.getAbsolutePath() + "' into classPath. The mod will not be loaded"); | ||
966 | + } | ||
967 | + } | ||
824 | } | 968 | } |
825 | 969 | ||
826 | /* | 970 | /* |
@@ -837,66 +981,15 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -837,66 +981,15 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
837 | /** | 981 | /** |
838 | * Find mod classes in the class path and enumerated mod files list | 982 | * Find mod classes in the class path and enumerated mod files list |
839 | * | 983 | * |
840 | - * @param classPathEntries | ||
841 | - * Java class path split into string entries | ||
842 | - * @return map of classes to load | 984 | + * @param classPathEntries Java class path split into string entries |
843 | */ | 985 | */ |
844 | - private HashMap<String, Class> findModClasses(String[] classPathEntries, LinkedList<File> modFiles, boolean searchProtectionDomain, boolean searchClassPath) | 986 | + private void findModClasses(String[] classPathEntries, List<ModFile> modFiles, boolean searchProtectionDomain, boolean searchClassPath) |
845 | { | 987 | { |
846 | - // To try to avoid loading the same mod multiple times if it appears in | ||
847 | - // more than one entry in the class path, we index | ||
848 | - // the mods by name and hopefully match only a single instance of a | ||
849 | - // particular mod | ||
850 | - HashMap<String, Class> modsToLoad = new HashMap<String, Class>(); | ||
851 | - | ||
852 | if (searchProtectionDomain) | 988 | if (searchProtectionDomain) |
853 | { | 989 | { |
854 | try | 990 | try |
855 | { | 991 | { |
856 | - logger.info("Searching protection domain code source..."); | ||
857 | - | ||
858 | - File packagePath = null; | ||
859 | - | ||
860 | - URL protectionDomainLocation = LiteLoader.class.getProtectionDomain().getCodeSource().getLocation(); | ||
861 | - if (protectionDomainLocation != null) | ||
862 | - { | ||
863 | - if (protectionDomainLocation.toString().indexOf('!') > -1 && protectionDomainLocation.toString().startsWith("jar:")) | ||
864 | - { | ||
865 | - protectionDomainLocation = new URL(protectionDomainLocation.toString().substring(4, protectionDomainLocation.toString().indexOf('!'))); | ||
866 | - } | ||
867 | - | ||
868 | - packagePath = new File(protectionDomainLocation.toURI()); | ||
869 | - } | ||
870 | - else | ||
871 | - { | ||
872 | - // Fix (?) for forge and other mods which screw up the | ||
873 | - // protection domain | ||
874 | - String reflectionClassPath = LiteLoader.class.getResource("/com/mumfrey/liteloader/core/LiteLoader.class").getPath(); | ||
875 | - | ||
876 | - if (reflectionClassPath.indexOf('!') > -1) | ||
877 | - { | ||
878 | - reflectionClassPath = URLDecoder.decode(reflectionClassPath, "UTF-8"); | ||
879 | - packagePath = new File(reflectionClassPath.substring(5, reflectionClassPath.indexOf('!'))); | ||
880 | - } | ||
881 | - } | ||
882 | - | ||
883 | - if (packagePath != null) | ||
884 | - { | ||
885 | - LinkedList<Class> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod"); | ||
886 | - | ||
887 | - for (Class mod : modClasses) | ||
888 | - { | ||
889 | - if (modsToLoad.containsKey(mod.getSimpleName())) | ||
890 | - { | ||
891 | - logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?"); | ||
892 | - } | ||
893 | - | ||
894 | - modsToLoad.put(mod.getSimpleName(), mod); | ||
895 | - } | ||
896 | - | ||
897 | - if (modClasses.size() > 0) | ||
898 | - logger.info(String.format("Found %s potential matches", modClasses.size())); | ||
899 | - } | 992 | + this.searchProtectionDomain(); |
900 | } | 993 | } |
901 | catch (Throwable th) | 994 | catch (Throwable th) |
902 | { | 995 | { |
@@ -907,78 +1000,158 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -907,78 +1000,158 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
907 | if (searchClassPath) | 1000 | if (searchClassPath) |
908 | { | 1001 | { |
909 | // Search through the class path and find mod classes | 1002 | // Search through the class path and find mod classes |
910 | - for (String classPathPart : classPathEntries) | 1003 | + this.searchClassPath(classPathEntries); |
1004 | + } | ||
1005 | + | ||
1006 | + // Search through mod files and find mod classes | ||
1007 | + this.searchModFiles(modFiles); | ||
1008 | + } | ||
1009 | + | ||
1010 | + /** | ||
1011 | + * @param modsToLoad | ||
1012 | + * @throws MalformedURLException | ||
1013 | + * @throws URISyntaxException | ||
1014 | + * @throws UnsupportedEncodingException | ||
1015 | + */ | ||
1016 | + @SuppressWarnings("unchecked") | ||
1017 | + private void searchProtectionDomain() throws MalformedURLException, URISyntaxException, UnsupportedEncodingException | ||
1018 | + { | ||
1019 | + logger.info("Searching protection domain code source..."); | ||
1020 | + | ||
1021 | + File packagePath = null; | ||
1022 | + | ||
1023 | + URL protectionDomainLocation = LiteLoader.class.getProtectionDomain().getCodeSource().getLocation(); | ||
1024 | + if (protectionDomainLocation != null) | ||
1025 | + { | ||
1026 | + if (protectionDomainLocation.toString().indexOf('!') > -1 && protectionDomainLocation.toString().startsWith("jar:")) | ||
911 | { | 1027 | { |
912 | - logger.info(String.format("Searching %s...", classPathPart)); | ||
913 | - | ||
914 | - File packagePath = new File(classPathPart); | ||
915 | - LinkedList<Class> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod"); | 1028 | + protectionDomainLocation = new URL(protectionDomainLocation.toString().substring(4, protectionDomainLocation.toString().indexOf('!'))); |
1029 | + } | ||
1030 | + | ||
1031 | + packagePath = new File(protectionDomainLocation.toURI()); | ||
1032 | + } | ||
1033 | + else | ||
1034 | + { | ||
1035 | + // Fix (?) for forge and other mods which screw up the | ||
1036 | + // protection domain | ||
1037 | + String reflectionClassPath = LiteLoader.class.getResource("/com/mumfrey/liteloader/core/LiteLoader.class").getPath(); | ||
1038 | + | ||
1039 | + if (reflectionClassPath.indexOf('!') > -1) | ||
1040 | + { | ||
1041 | + reflectionClassPath = URLDecoder.decode(reflectionClassPath, "UTF-8"); | ||
1042 | + packagePath = new File(reflectionClassPath.substring(5, reflectionClassPath.indexOf('!'))); | ||
1043 | + } | ||
1044 | + } | ||
1045 | + | ||
1046 | + if (packagePath != null) | ||
1047 | + { | ||
1048 | + LinkedList<Class<?>> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod"); | ||
1049 | + | ||
1050 | + for (Class<?> mod : modClasses) | ||
1051 | + { | ||
1052 | + if (this.modsToLoad.containsKey(mod.getSimpleName())) | ||
1053 | + { | ||
1054 | + logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?"); | ||
1055 | + } | ||
916 | 1056 | ||
917 | - for (Class mod : modClasses) | 1057 | + this.modsToLoad.put(mod.getSimpleName(), (Class<? extends LiteMod>)mod); |
1058 | + } | ||
1059 | + | ||
1060 | + if (modClasses.size() > 0) | ||
1061 | + logger.info(String.format("Found %s potential matches", modClasses.size())); | ||
1062 | + } | ||
1063 | + } | ||
1064 | + | ||
1065 | + /** | ||
1066 | + * @param classPathEntries | ||
1067 | + * @param modsToLoad | ||
1068 | + */ | ||
1069 | + @SuppressWarnings("unchecked") | ||
1070 | + private void searchClassPath(String[] classPathEntries) | ||
1071 | + { | ||
1072 | + for (String classPathPart : classPathEntries) | ||
1073 | + { | ||
1074 | + logger.info(String.format("Searching %s...", classPathPart)); | ||
1075 | + | ||
1076 | + File packagePath = new File(classPathPart); | ||
1077 | + LinkedList<Class<?>> modClasses = getSubclassesFor(packagePath, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod"); | ||
1078 | + | ||
1079 | + for (Class<?> mod : modClasses) | ||
1080 | + { | ||
1081 | + if (this.modsToLoad.containsKey(mod.getSimpleName())) | ||
918 | { | 1082 | { |
919 | - if (modsToLoad.containsKey(mod.getSimpleName())) | ||
920 | - { | ||
921 | - logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?"); | ||
922 | - } | ||
923 | - | ||
924 | - modsToLoad.put(mod.getSimpleName(), mod); | 1083 | + logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?"); |
925 | } | 1084 | } |
926 | 1085 | ||
927 | - if (modClasses.size() > 0) | ||
928 | - logger.info(String.format("Found %s potential matches", modClasses.size())); | 1086 | + this.modsToLoad.put(mod.getSimpleName(), (Class<? extends LiteMod>)mod); |
929 | } | 1087 | } |
1088 | + | ||
1089 | + if (modClasses.size() > 0) | ||
1090 | + logger.info(String.format("Found %s potential matches", modClasses.size())); | ||
930 | } | 1091 | } |
931 | - | ||
932 | - // Search through mod files and find mod classes | ||
933 | - for (File modFile : modFiles) | 1092 | + } |
1093 | + | ||
1094 | + /** | ||
1095 | + * @param modFiles | ||
1096 | + * @param modsToLoad | ||
1097 | + */ | ||
1098 | + @SuppressWarnings("unchecked") | ||
1099 | + private void searchModFiles(List<ModFile> modFiles) | ||
1100 | + { | ||
1101 | + for (ModFile modFile : modFiles) | ||
934 | { | 1102 | { |
935 | logger.info(String.format("Searching %s...", modFile.getAbsolutePath())); | 1103 | logger.info(String.format("Searching %s...", modFile.getAbsolutePath())); |
936 | 1104 | ||
937 | - LinkedList<Class> modClasses = getSubclassesFor(modFile, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod"); | 1105 | + LinkedList<Class<?>> modClasses = getSubclassesFor(modFile, Minecraft.class.getClassLoader(), LiteMod.class, "LiteMod"); |
938 | 1106 | ||
939 | - for (Class mod : modClasses) | 1107 | + for (Class<?> mod : modClasses) |
940 | { | 1108 | { |
941 | - if (modsToLoad.containsKey(mod.getSimpleName())) | 1109 | + if (this.modsToLoad.containsKey(mod.getSimpleName())) |
942 | { | 1110 | { |
943 | logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?"); | 1111 | logger.warning("Mod name collision for mod with class '" + mod.getSimpleName() + "', maybe you have more than one copy?"); |
944 | } | 1112 | } |
945 | 1113 | ||
946 | - modsToLoad.put(mod.getSimpleName(), mod); | 1114 | + this.modsToLoad.put(mod.getSimpleName(), (Class<? extends LiteMod>)mod); |
1115 | + this.modFiles.put(mod.getSimpleName(), modFile); | ||
947 | } | 1116 | } |
948 | 1117 | ||
949 | if (modClasses.size() > 0) | 1118 | if (modClasses.size() > 0) |
950 | logger.info(String.format("Found %s potential matches", modClasses.size())); | 1119 | logger.info(String.format("Found %s potential matches", modClasses.size())); |
951 | } | 1120 | } |
952 | - | ||
953 | - return modsToLoad; | ||
954 | } | 1121 | } |
955 | 1122 | ||
956 | /** | 1123 | /** |
957 | * Create mod instances from the enumerated classes | 1124 | * Create mod instances from the enumerated classes |
958 | * | 1125 | * |
959 | - * @param modsToLoad | ||
960 | - * List of mods to load | 1126 | + * @param modsToLoad List of mods to load |
961 | */ | 1127 | */ |
962 | - private void loadMods(HashMap<String, Class> modsToLoad) | 1128 | + private void loadMods() |
963 | { | 1129 | { |
964 | - if (modsToLoad == null) | 1130 | + if (this.modsToLoad == null) |
965 | { | 1131 | { |
966 | logger.info("Mod class discovery failed. Not loading any mods!"); | 1132 | logger.info("Mod class discovery failed. Not loading any mods!"); |
967 | return; | 1133 | return; |
968 | } | 1134 | } |
969 | 1135 | ||
970 | - logger.info("Discovered " + modsToLoad.size() + " total mod(s)"); | 1136 | + logger.info("Discovered " + this.modsToLoad.size() + " total mod(s)"); |
971 | 1137 | ||
972 | - for (Class mod : modsToLoad.values()) | 1138 | + for (Class<? extends LiteMod> mod : this.modsToLoad.values()) |
973 | { | 1139 | { |
974 | try | 1140 | try |
975 | { | 1141 | { |
976 | logger.info("Loading mod from " + mod.getName()); | 1142 | logger.info("Loading mod from " + mod.getName()); |
977 | 1143 | ||
978 | - LiteMod newMod = (LiteMod)mod.newInstance(); | ||
979 | - this.mods.add(newMod); | 1144 | + LiteMod newMod = mod.newInstance(); |
980 | 1145 | ||
981 | - logger.info("Successfully added mod " + newMod.getName() + " version " + newMod.getVersion()); | 1146 | + if (this.shouldAddMod(newMod)) |
1147 | + { | ||
1148 | + this.mods.add(newMod); | ||
1149 | + logger.info("Successfully added mod " + newMod.getName() + " version " + newMod.getVersion()); | ||
1150 | + } | ||
1151 | + else | ||
1152 | + { | ||
1153 | + logger.info("Not loading mod " + newMod.getName() + ", excluded by filter"); | ||
1154 | + } | ||
982 | } | 1155 | } |
983 | catch (Throwable th) | 1156 | catch (Throwable th) |
984 | { | 1157 | { |
@@ -989,6 +1162,26 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -989,6 +1162,26 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
989 | } | 1162 | } |
990 | 1163 | ||
991 | /** | 1164 | /** |
1165 | + * @param name | ||
1166 | + * @return | ||
1167 | + */ | ||
1168 | + private boolean shouldAddMod(LiteMod mod) | ||
1169 | + { | ||
1170 | + if (this.modNameFilter == null) return true; | ||
1171 | + | ||
1172 | + String modClassName = mod.getClass().getSimpleName(); | ||
1173 | + if (!this.modFiles.containsKey(modClassName)) return true; | ||
1174 | + | ||
1175 | + String metaName = this.modFiles.get(modClassName).getModName().toLowerCase(); | ||
1176 | + if (this.modNameFilter.contains(metaName)) | ||
1177 | + { | ||
1178 | + return true; | ||
1179 | + } | ||
1180 | + | ||
1181 | + return false; | ||
1182 | + } | ||
1183 | + | ||
1184 | + /** | ||
992 | * Initialise the mods which were loaded | 1185 | * Initialise the mods which were loaded |
993 | */ | 1186 | */ |
994 | private void initMods() | 1187 | private void initMods() |
@@ -999,28 +1192,29 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -999,28 +1192,29 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
999 | for (Iterator<LiteMod> iter = this.mods.iterator(); iter.hasNext();) | 1192 | for (Iterator<LiteMod> iter = this.mods.iterator(); iter.hasNext();) |
1000 | { | 1193 | { |
1001 | LiteMod mod = iter.next(); | 1194 | LiteMod mod = iter.next(); |
1195 | + String modName = mod.getName(); | ||
1002 | 1196 | ||
1003 | try | 1197 | try |
1004 | { | 1198 | { |
1005 | - logger.info("Initialising mod " + mod.getName() + " version " + mod.getVersion()); | 1199 | + logger.info("Initialising mod " + modName + " version " + mod.getVersion()); |
1006 | 1200 | ||
1007 | try | 1201 | try |
1008 | { | 1202 | { |
1009 | - String modKey = this.getModNameForConfig(mod.getClass(), mod.getName()); | 1203 | + String modKey = this.getModNameForConfig(mod.getClass(), modName); |
1010 | LiteLoaderVersion lastModVersion = LiteLoaderVersion.getVersionFromRevision(this.getLastKnownModRevision(modKey)); | 1204 | LiteLoaderVersion lastModVersion = LiteLoaderVersion.getVersionFromRevision(this.getLastKnownModRevision(modKey)); |
1011 | 1205 | ||
1012 | if (LiteLoader.VERSION.getLoaderRevision() > lastModVersion.getLoaderRevision()) | 1206 | if (LiteLoader.VERSION.getLoaderRevision() > lastModVersion.getLoaderRevision()) |
1013 | { | 1207 | { |
1014 | - logger.info("Performing config upgrade for mod " + mod.getName() + ". Upgrading " + lastModVersion + " to " + LiteLoader.VERSION + "..."); | 1208 | + logger.info("Performing config upgrade for mod " + modName + ". Upgrading " + lastModVersion + " to " + LiteLoader.VERSION + "..."); |
1015 | mod.upgradeSettings(LiteLoader.getVersion(), this.versionConfigFolder, this.inflectVersionedConfigPath(lastModVersion)); | 1209 | mod.upgradeSettings(LiteLoader.getVersion(), this.versionConfigFolder, this.inflectVersionedConfigPath(lastModVersion)); |
1016 | 1210 | ||
1017 | this.storeLastKnownModRevision(modKey); | 1211 | this.storeLastKnownModRevision(modKey); |
1018 | - logger.info("Config upgrade succeeded for mod " + mod.getName()); | 1212 | + logger.info("Config upgrade succeeded for mod " + modName); |
1019 | } | 1213 | } |
1020 | } | 1214 | } |
1021 | catch (Throwable th) | 1215 | catch (Throwable th) |
1022 | { | 1216 | { |
1023 | - logger.warning("Error performing settings upgrade for " + mod.getName() + ". Settings may not be properly migrated"); | 1217 | + logger.warning("Error performing settings upgrade for " + modName + ". Settings may not be properly migrated"); |
1024 | } | 1218 | } |
1025 | 1219 | ||
1026 | mod.init(this.modsFolder); | 1220 | mod.init(this.modsFolder); |
@@ -1059,7 +1253,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1059,7 +1253,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1059 | { | 1253 | { |
1060 | if (mod instanceof ChatFilter) | 1254 | if (mod instanceof ChatFilter) |
1061 | { | 1255 | { |
1062 | - this.logger.warning(String.format("Interface error initialising mod '%1s'. A mod implementing ChatFilter and ChatListener is not supported! Remove one of these interfaces", mod.getName())); | 1256 | + this.logger.warning(String.format("Interface error initialising mod '%1s'. A mod implementing ChatFilter and ChatListener is not supported! Remove one of these interfaces", modName)); |
1063 | } | 1257 | } |
1064 | else | 1258 | else |
1065 | { | 1259 | { |
@@ -1092,12 +1286,12 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1092,12 +1286,12 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1092 | permissionsManager.registerPermissible((Permissible)mod); | 1286 | permissionsManager.registerPermissible((Permissible)mod); |
1093 | } | 1287 | } |
1094 | 1288 | ||
1095 | - this.loadedModsList += String.format("\n - %s version %s", mod.getName(), mod.getVersion()); | 1289 | + this.loadedModsList += String.format("\n - %s version %s", modName, mod.getVersion()); |
1096 | loadedModsCount++; | 1290 | loadedModsCount++; |
1097 | } | 1291 | } |
1098 | catch (Throwable th) | 1292 | catch (Throwable th) |
1099 | { | 1293 | { |
1100 | - logger.log(Level.WARNING, "Error initialising mod '" + mod.getName(), th); | 1294 | + logger.log(Level.WARNING, "Error initialising mod '" + modName, th); |
1101 | iter.remove(); | 1295 | iter.remove(); |
1102 | } | 1296 | } |
1103 | } | 1297 | } |
@@ -1304,9 +1498,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1304,9 +1498,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1304 | * @param superClass | 1498 | * @param superClass |
1305 | * @return | 1499 | * @return |
1306 | */ | 1500 | */ |
1307 | - private static LinkedList<Class> getSubclassesFor(File packagePath, ClassLoader classloader, Class superClass, String prefix) | 1501 | + private static LinkedList<Class<?>> getSubclassesFor(File packagePath, ClassLoader classloader, Class<?> superClass, String prefix) |
1308 | { | 1502 | { |
1309 | - LinkedList<Class> classes = new LinkedList<Class>(); | 1503 | + LinkedList<Class<?>> classes = new LinkedList<Class<?>>(); |
1310 | 1504 | ||
1311 | try | 1505 | try |
1312 | { | 1506 | { |
@@ -1335,7 +1529,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1335,7 +1529,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1335 | * @throws FileNotFoundException | 1529 | * @throws FileNotFoundException |
1336 | * @throws IOException | 1530 | * @throws IOException |
1337 | */ | 1531 | */ |
1338 | - private static void enumerateCompressedPackage(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath) throws FileNotFoundException, IOException | 1532 | + private static void enumerateCompressedPackage(String prefix, Class<?> superClass, ClassLoader classloader, LinkedList<Class<?>> classes, File packagePath) throws FileNotFoundException, IOException |
1339 | { | 1533 | { |
1340 | FileInputStream fileinputstream = new FileInputStream(packagePath); | 1534 | FileInputStream fileinputstream = new FileInputStream(packagePath); |
1341 | ZipInputStream zipinputstream = new ZipInputStream(fileinputstream); | 1535 | ZipInputStream zipinputstream = new ZipInputStream(fileinputstream); |
@@ -1377,7 +1571,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1377,7 +1571,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1377 | * @param packagePath | 1571 | * @param packagePath |
1378 | * @param packageName | 1572 | * @param packageName |
1379 | */ | 1573 | */ |
1380 | - private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath) | 1574 | + private static void enumerateDirectory(String prefix, Class<?> superClass, ClassLoader classloader, LinkedList<Class<?>> classes, File packagePath) |
1381 | { | 1575 | { |
1382 | enumerateDirectory(prefix, superClass, classloader, classes, packagePath, "", 0); | 1576 | enumerateDirectory(prefix, superClass, classloader, classes, packagePath, "", 0); |
1383 | } | 1577 | } |
@@ -1391,7 +1585,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1391,7 +1585,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1391 | * @param packagePath | 1585 | * @param packagePath |
1392 | * @param packageName | 1586 | * @param packageName |
1393 | */ | 1587 | */ |
1394 | - private static void enumerateDirectory(String prefix, Class superClass, ClassLoader classloader, LinkedList<Class> classes, File packagePath, String packageName, int depth) | 1588 | + private static void enumerateDirectory(String prefix, Class<?> superClass, ClassLoader classloader, LinkedList<Class<?>> classes, File packagePath, String packageName, int depth) |
1395 | { | 1589 | { |
1396 | // Prevent crash due to broken recursion | 1590 | // Prevent crash due to broken recursion |
1397 | if (depth > MAX_DISCOVERY_DEPTH) | 1591 | if (depth > MAX_DISCOVERY_DEPTH) |
@@ -1423,15 +1617,14 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1423,15 +1617,14 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1423 | * @param classes | 1617 | * @param classes |
1424 | * @param className | 1618 | * @param className |
1425 | */ | 1619 | */ |
1426 | - @SuppressWarnings("unchecked") | ||
1427 | - private static void checkAndAddClass(ClassLoader classloader, Class superClass, LinkedList<Class> classes, String className) | 1620 | + private static void checkAndAddClass(ClassLoader classloader, Class<?> superClass, LinkedList<Class<?>> classes, String className) |
1428 | { | 1621 | { |
1429 | if (className.indexOf('$') > -1) | 1622 | if (className.indexOf('$') > -1) |
1430 | return; | 1623 | return; |
1431 | 1624 | ||
1432 | try | 1625 | try |
1433 | { | 1626 | { |
1434 | - Class subClass = classloader.loadClass(className); | 1627 | + Class<?> subClass = classloader.loadClass(className); |
1435 | 1628 | ||
1436 | if (subClass != null && !superClass.equals(subClass) && superClass.isAssignableFrom(subClass) && !subClass.isInterface() && !classes.contains(subClass)) | 1629 | if (subClass != null && !superClass.equals(subClass) && superClass.isAssignableFrom(subClass) && !subClass.isInterface() && !classes.contains(subClass)) |
1437 | { | 1630 | { |
@@ -1447,8 +1640,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1447,8 +1640,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1447 | /** | 1640 | /** |
1448 | * Add a URL to the Minecraft classloader class path | 1641 | * Add a URL to the Minecraft classloader class path |
1449 | * | 1642 | * |
1450 | - * @param classUrl | ||
1451 | - * URL of the resource to add | 1643 | + * @param classUrl URL of the resource to add |
1452 | */ | 1644 | */ |
1453 | private boolean addURLToClassPath(URL classUrl) | 1645 | private boolean addURLToClassPath(URL classUrl) |
1454 | { | 1646 | { |
@@ -1596,8 +1788,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1596,8 +1788,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1596 | /** | 1788 | /** |
1597 | * Callback from the tick hook, ticks all tickable mods | 1789 | * Callback from the tick hook, ticks all tickable mods |
1598 | * | 1790 | * |
1599 | - * @param tick | ||
1600 | - * True if this is a new tick (otherwise it's just a new frame) | 1791 | + * @param tick True if this is a new tick (otherwise it's just a new frame) |
1601 | */ | 1792 | */ |
1602 | public void onTick(Profiler profiler, boolean tick) | 1793 | public void onTick(Profiler profiler, boolean tick) |
1603 | { | 1794 | { |
@@ -1728,10 +1919,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | @@ -1728,10 +1919,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage | ||
1728 | /** | 1919 | /** |
1729 | * Delegate to ModUtilities.sendPluginChannelMessage | 1920 | * Delegate to ModUtilities.sendPluginChannelMessage |
1730 | * | 1921 | * |
1731 | - * @param channel | ||
1732 | - * Channel to send data to | ||
1733 | - * @param data | ||
1734 | - * Data to send | 1922 | + * @param channel Channel to send data to |
1923 | + * @param data Data to send | ||
1735 | */ | 1924 | */ |
1736 | public void sendPluginChannelMessage(String channel, byte[] data) | 1925 | public void sendPluginChannelMessage(String channel, byte[] data) |
1737 | { | 1926 | { |
java/com/mumfrey/liteloader/core/LiteLoaderVersion.java
@@ -12,6 +12,8 @@ import java.util.Set; | @@ -12,6 +12,8 @@ import java.util.Set; | ||
12 | public enum LiteLoaderVersion | 12 | public enum LiteLoaderVersion |
13 | { | 13 | { |
14 | LEGACY(0, "-", "-", "-"), | 14 | LEGACY(0, "-", "-", "-"), |
15 | + MC_1_5_2_R1(9, "1.5.2", "1.5.2", "1.5.2"), | ||
16 | + MC_1_5_2_R2(10, "1.5.2", "1.5.2", "1.5.2"), | ||
15 | MC_1_6_1_R0(11, "1.6.1", "1.6.1", "1.6.1", "1.6.r1"), | 17 | MC_1_6_1_R0(11, "1.6.1", "1.6.1", "1.6.1", "1.6.r1"), |
16 | MC_1_6_2_R0(12, "1.6.2", "1.6.2", "1.6.2", "1.6.r2"); | 18 | MC_1_6_2_R0(12, "1.6.2", "1.6.2", "1.6.2", "1.6.r2"); |
17 | 19 |
java/com/mumfrey/liteloader/core/ModFile.java
0 → 100644
1 | +package com.mumfrey.liteloader.core; | ||
2 | + | ||
3 | +import java.io.File; | ||
4 | +import java.util.HashMap; | ||
5 | +import java.util.Map; | ||
6 | + | ||
7 | +import com.google.gson.Gson; | ||
8 | +import com.google.gson.JsonSyntaxException; | ||
9 | + | ||
10 | +/** | ||
11 | + * Wrapper for file which represents a mod file to load with associated version information and | ||
12 | + * metadata. Retrieve this from litemod.xml at enumeration time. We also override comparable to | ||
13 | + * provide our own custom sorting logic based on version info. | ||
14 | + * | ||
15 | + * @author Adam Mummery-Smith | ||
16 | + */ | ||
17 | +public class ModFile extends File | ||
18 | +{ | ||
19 | + private static final long serialVersionUID = -7952147161905688459L; | ||
20 | + | ||
21 | + /** | ||
22 | + * Gson parser for JSON | ||
23 | + */ | ||
24 | + private static Gson gson = new Gson(); | ||
25 | + | ||
26 | + /** | ||
27 | + * True if the metadata information is parsed successfully, the mod will be added | ||
28 | + */ | ||
29 | + private boolean valid = false; | ||
30 | + | ||
31 | + /** | ||
32 | + * True if parsed from JSON, false if fallback mode using legacy version.txt | ||
33 | + */ | ||
34 | + private boolean json = false; | ||
35 | + | ||
36 | + /** | ||
37 | + * Name of the mod specified in the JSON file, this can be any string but should be the same between mod versions | ||
38 | + */ | ||
39 | + private String modName; | ||
40 | + | ||
41 | + /** | ||
42 | + * Loader version | ||
43 | + */ | ||
44 | + private String version; | ||
45 | + | ||
46 | + /** | ||
47 | + * File time stamp, used as sorting criteria when no revision information is found | ||
48 | + */ | ||
49 | + private long timeStamp; | ||
50 | + | ||
51 | + /** | ||
52 | + * Revision number from the json file | ||
53 | + */ | ||
54 | + private float revision = 0.0F; | ||
55 | + | ||
56 | + /** | ||
57 | + * True if the revision number was successfully read, used as a semaphore so that we know when revision is a valid number | ||
58 | + */ | ||
59 | + private boolean hasRevision = false; | ||
60 | + | ||
61 | + /** | ||
62 | + * ALL of the parsed metadata from the file, associated with the mod later on for retrieval via the loader | ||
63 | + */ | ||
64 | + private HashMap<String, String> metaData = new HashMap<String, String>(); | ||
65 | + | ||
66 | + /** | ||
67 | + * @param file | ||
68 | + * @param strVersion | ||
69 | + */ | ||
70 | + public ModFile(File file, String strVersion) | ||
71 | + { | ||
72 | + super(file.getAbsolutePath()); | ||
73 | + | ||
74 | + this.timeStamp = this.lastModified(); | ||
75 | + | ||
76 | + this.parseVersionFile(strVersion); | ||
77 | + } | ||
78 | + | ||
79 | + @SuppressWarnings("unchecked") | ||
80 | + private void parseVersionFile(String strVersionData) | ||
81 | + { | ||
82 | + // Assume that it's json if the file starts with a brace | ||
83 | + if (strVersionData.trim().startsWith("{")) | ||
84 | + { | ||
85 | + try | ||
86 | + { | ||
87 | + this.metaData = ModFile.gson.fromJson(strVersionData, HashMap.class); | ||
88 | + } | ||
89 | + catch (JsonSyntaxException jsx) | ||
90 | + { | ||
91 | + LiteLoader.getLogger().warning("Error reading litemod.json in " + this.getName() + ", JSON syntax exception: " + jsx.getMessage()); | ||
92 | + return; | ||
93 | + } | ||
94 | + | ||
95 | + this.modName = this.metaData.get("name"); | ||
96 | + | ||
97 | + this.version = this.metaData.get("mcversion"); | ||
98 | + if (this.version == null) | ||
99 | + { | ||
100 | + LiteLoader.getLogger().warning("Mod in " + this.getName() + " has no loader version number reading litemod.json"); | ||
101 | + return; | ||
102 | + } | ||
103 | + | ||
104 | + try | ||
105 | + { | ||
106 | + this.revision = Float.parseFloat(this.metaData.get("revision")); | ||
107 | + this.hasRevision = true; | ||
108 | + } | ||
109 | + catch (Exception ex) | ||
110 | + { | ||
111 | + LiteLoader.getLogger().warning("Mod in " + this.getName() + " has an invalid revision number reading litemod.json"); | ||
112 | + } | ||
113 | + | ||
114 | + this.valid = true; | ||
115 | + this.json = true; | ||
116 | + } | ||
117 | + else | ||
118 | + { | ||
119 | + // Legacy version.txt file | ||
120 | + this.version = strVersionData; | ||
121 | + this.valid = true; | ||
122 | + } | ||
123 | + | ||
124 | + if (this.modName == null) | ||
125 | + { | ||
126 | + this.modName = this.getName().replaceAll("[^a-zA-Z]", ""); | ||
127 | + } | ||
128 | + } | ||
129 | + | ||
130 | + public String getModName() | ||
131 | + { | ||
132 | + return this.modName; | ||
133 | + } | ||
134 | + | ||
135 | + public boolean isValid() | ||
136 | + { | ||
137 | + return this.valid; | ||
138 | + } | ||
139 | + | ||
140 | + public boolean isJson() | ||
141 | + { | ||
142 | + return this.json; | ||
143 | + } | ||
144 | + | ||
145 | + public String getVersion() | ||
146 | + { | ||
147 | + return this.version; | ||
148 | + } | ||
149 | + | ||
150 | + public float getRevision() | ||
151 | + { | ||
152 | + return this.revision; | ||
153 | + } | ||
154 | + | ||
155 | + public String getMetaValue(String metaKey, String defaultValue) | ||
156 | + { | ||
157 | + return this.metaData.containsKey(metaKey) ? this.metaData.get(metaKey) : defaultValue; | ||
158 | + } | ||
159 | + | ||
160 | + public Map<String, String> getMetaData() | ||
161 | + { | ||
162 | + return this.metaData; | ||
163 | + } | ||
164 | + | ||
165 | + @Override | ||
166 | + public int compareTo(File other) | ||
167 | + { | ||
168 | + if (other == null || !(other instanceof ModFile)) return -1; | ||
169 | + | ||
170 | + ModFile otherMod = (ModFile)other; | ||
171 | + | ||
172 | + // If the other object has a revision, compare revisions | ||
173 | + if (otherMod.hasRevision) | ||
174 | + { | ||
175 | + return this.hasRevision && this.revision - otherMod.revision > 0 ? -1 : 1; | ||
176 | + } | ||
177 | + | ||
178 | + // If we have a revision and the other object doesn't, then we are higher | ||
179 | + if (this.hasRevision) | ||
180 | + { | ||
181 | + return -1; | ||
182 | + } | ||
183 | + | ||
184 | + // Give up and use timestamp | ||
185 | + return (int)(otherMod.timeStamp - this.timeStamp); | ||
186 | + } | ||
187 | +} |
java/com/mumfrey/liteloader/gui/GuiControlsPaginated.java
@@ -20,58 +20,58 @@ public class GuiControlsPaginated extends GuiScreen | @@ -20,58 +20,58 @@ public class GuiControlsPaginated extends GuiScreen | ||
20 | * Pagination variables | 20 | * Pagination variables |
21 | */ | 21 | */ |
22 | protected int controlsPerPage, startIndex, endIndex; | 22 | protected int controlsPerPage, startIndex, endIndex; |
23 | - | 23 | + |
24 | /** | 24 | /** |
25 | * Parent screen which will be displayed when this screen is closed | 25 | * Parent screen which will be displayed when this screen is closed |
26 | */ | 26 | */ |
27 | protected GuiScreen parentScreen; | 27 | protected GuiScreen parentScreen; |
28 | - | ||
29 | - /** | ||
30 | - * Game settings | ||
31 | - */ | 28 | + |
29 | + /** | ||
30 | + * Game settings | ||
31 | + */ | ||
32 | protected GameSettings gameSettings; | 32 | protected GameSettings gameSettings; |
33 | - | ||
34 | - /** | ||
35 | - * Additional buttons | ||
36 | - */ | 33 | + |
34 | + /** | ||
35 | + * Additional buttons | ||
36 | + */ | ||
37 | protected GuiButton btnNext, btnPrevious; | 37 | protected GuiButton btnNext, btnPrevious; |
38 | - | ||
39 | - /** | ||
40 | - * Title to display | ||
41 | - */ | ||
42 | - protected String screenTitle = "Controls"; | ||
43 | - | ||
44 | - /** | ||
45 | - * ID of the button currently being edited | ||
46 | - */ | ||
47 | - protected int activeButtonId = -1; | ||
48 | - | ||
49 | - public GuiControlsPaginated(GuiScreen parentScreen, GameSettings gameSettings) | ||
50 | - { | ||
51 | - this.parentScreen = parentScreen; | ||
52 | - this.gameSettings = gameSettings; | ||
53 | - | ||
54 | - // Pagination defaults | ||
55 | - this.controlsPerPage = 14; | ||
56 | - this.endIndex = this.gameSettings.keyBindings.length - (this.gameSettings.keyBindings.length % this.controlsPerPage == 0 ? this.controlsPerPage : this.gameSettings.keyBindings.length % this.controlsPerPage); | ||
57 | - } | ||
58 | - | ||
59 | - @SuppressWarnings("unchecked") | 38 | + |
39 | + /** | ||
40 | + * Title to display | ||
41 | + */ | ||
42 | + protected String screenTitle = "Controls"; | ||
43 | + | ||
44 | + /** | ||
45 | + * ID of the button currently being edited | ||
46 | + */ | ||
47 | + protected int activeButtonId = -1; | ||
48 | + | ||
49 | + public GuiControlsPaginated(GuiScreen parentScreen, GameSettings gameSettings) | ||
50 | + { | ||
51 | + this.parentScreen = parentScreen; | ||
52 | + this.gameSettings = gameSettings; | ||
53 | + | ||
54 | + // Pagination defaults | ||
55 | + this.controlsPerPage = 14; | ||
56 | + this.endIndex = this.gameSettings.keyBindings.length - (this.gameSettings.keyBindings.length % this.controlsPerPage == 0 ? this.controlsPerPage : this.gameSettings.keyBindings.length % this.controlsPerPage); | ||
57 | + } | ||
58 | + | ||
59 | + @SuppressWarnings("unchecked") | ||
60 | protected List<GuiButton> getLegacyControlList() | 60 | protected List<GuiButton> getLegacyControlList() |
61 | - { | ||
62 | - return this.buttonList; | ||
63 | - } | ||
64 | - | ||
65 | - protected final int getHeight() | ||
66 | - { | ||
67 | - return this.height; | ||
68 | - } | ||
69 | - | ||
70 | - protected final int getWidth() | ||
71 | - { | ||
72 | - return this.width; | ||
73 | - } | ||
74 | - | 61 | + { |
62 | + return this.buttonList; | ||
63 | + } | ||
64 | + | ||
65 | + protected final int getHeight() | ||
66 | + { | ||
67 | + return this.height; | ||
68 | + } | ||
69 | + | ||
70 | + protected final int getWidth() | ||
71 | + { | ||
72 | + return this.width; | ||
73 | + } | ||
74 | + | ||
75 | public GuiScreen getParentScreen() | 75 | public GuiScreen getParentScreen() |
76 | { | 76 | { |
77 | return this.parentScreen; | 77 | return this.parentScreen; |
@@ -84,40 +84,40 @@ public class GuiControlsPaginated extends GuiScreen | @@ -84,40 +84,40 @@ public class GuiControlsPaginated extends GuiScreen | ||
84 | public void initGui() | 84 | public void initGui() |
85 | { | 85 | { |
86 | this.getLegacyControlList().clear(); | 86 | this.getLegacyControlList().clear(); |
87 | - | 87 | + |
88 | int oldControlsPerPage = this.controlsPerPage; | 88 | int oldControlsPerPage = this.controlsPerPage; |
89 | this.controlsPerPage = ((this.getHeight() - 70) / 24) * 2; | 89 | this.controlsPerPage = ((this.getHeight() - 70) / 24) * 2; |
90 | - this.endIndex = this.gameSettings.keyBindings.length - (this.gameSettings.keyBindings.length % this.controlsPerPage == 0 ? this.controlsPerPage : this.gameSettings.keyBindings.length % this.controlsPerPage); | ||
91 | - if (oldControlsPerPage != this.controlsPerPage) this.startIndex = 0; | ||
92 | - | ||
93 | - for (int controlId = 0; controlId < this.gameSettings.keyBindings.length; controlId++) | ||
94 | - { | ||
95 | - boolean buttonVisible = controlId >= this.startIndex && controlId < this.startIndex + this.controlsPerPage; | 90 | + this.endIndex = this.gameSettings.keyBindings.length - (this.gameSettings.keyBindings.length % this.controlsPerPage == 0 ? this.controlsPerPage : this.gameSettings.keyBindings.length % this.controlsPerPage); |
91 | + if (oldControlsPerPage != this.controlsPerPage) this.startIndex = 0; | ||
92 | + | ||
93 | + for (int controlId = 0; controlId < this.gameSettings.keyBindings.length; controlId++) | ||
94 | + { | ||
95 | + boolean buttonVisible = controlId >= this.startIndex && controlId < this.startIndex + this.controlsPerPage; | ||
96 | int left = buttonVisible ? this.getWidth() / 2 - 155 : this.getWidth() + 10000; | 96 | int left = buttonVisible ? this.getWidth() / 2 - 155 : this.getWidth() + 10000; |
97 | - int top = this.getHeight() / 6 + 24 * ((controlId - this.startIndex) >> 1); | 97 | + int top = this.getHeight() / 6 + 24 * ((controlId - this.startIndex) >> 1); |
98 | this.getLegacyControlList().add(new GuiSmallButton(controlId, left + ((controlId - this.startIndex) % 2) * 160, top, 70, 20, this.gameSettings.getOptionDisplayString(controlId))); | 98 | this.getLegacyControlList().add(new GuiSmallButton(controlId, left + ((controlId - this.startIndex) % 2) * 160, top, 70, 20, this.gameSettings.getOptionDisplayString(controlId))); |
99 | - } | ||
100 | - | ||
101 | - int buttonY = this.getHeight() / 6 + (this.controlsPerPage >> 1) * 24; | ||
102 | - | ||
103 | - // Only bother paginating if there are too many controls to display | 99 | + } |
100 | + | ||
101 | + int buttonY = this.getHeight() / 6 + (this.controlsPerPage >> 1) * 24; | ||
102 | + | ||
103 | + // Only bother paginating if there are too many controls to display | ||
104 | if (this.gameSettings.keyBindings.length > this.controlsPerPage) | 104 | if (this.gameSettings.keyBindings.length > this.controlsPerPage) |
105 | - { | ||
106 | - this.getLegacyControlList().add(this.btnNext = new GuiButton(201, this.getWidth() / 2 - 51, buttonY, 50, 20, ">>")); | ||
107 | - this.getLegacyControlList().add(this.btnPrevious = new GuiButton(202, this.getWidth() / 2 - 103, buttonY, 50, 20, "<<")); | ||
108 | - this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 + 1, buttonY, 100, 20, I18n.func_135053_a("gui.done"))); | ||
109 | - | ||
110 | - this.btnNext.enabled = this.startIndex < this.endIndex; | ||
111 | - this.btnPrevious.enabled = this.startIndex > 0; | ||
112 | - } | ||
113 | - else | ||
114 | - { | ||
115 | - this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 - 100, buttonY, I18n.func_135053_a("gui.done"))); | ||
116 | - } | ||
117 | - | ||
118 | - this.screenTitle = I18n.func_135053_a("controls.title"); | 105 | + { |
106 | + this.getLegacyControlList().add(this.btnNext = new GuiButton(201, this.getWidth() / 2 - 51, buttonY, 50, 20, ">>")); | ||
107 | + this.getLegacyControlList().add(this.btnPrevious = new GuiButton(202, this.getWidth() / 2 - 103, buttonY, 50, 20, "<<")); | ||
108 | + this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 + 1, buttonY, 100, 20, I18n.func_135053_a("gui.done"))); | ||
109 | + | ||
110 | + this.btnNext.enabled = this.startIndex < this.endIndex; | ||
111 | + this.btnPrevious.enabled = this.startIndex > 0; | ||
112 | + } | ||
113 | + else | ||
114 | + { | ||
115 | + this.getLegacyControlList().add(new GuiButton(200, this.getWidth() / 2 - 100, buttonY, I18n.func_135053_a("gui.done"))); | ||
116 | + } | ||
117 | + | ||
118 | + this.screenTitle = I18n.func_135053_a("controls.title"); | ||
119 | } | 119 | } |
120 | - | 120 | + |
121 | /** | 121 | /** |
122 | * @param controlId | 122 | * @param controlId |
123 | * @return | 123 | * @return |
@@ -136,103 +136,103 @@ public class GuiControlsPaginated extends GuiScreen | @@ -136,103 +136,103 @@ public class GuiControlsPaginated extends GuiScreen | ||
136 | protected void actionPerformed(GuiButton guibutton) | 136 | protected void actionPerformed(GuiButton guibutton) |
137 | { | 137 | { |
138 | // Update the button labels with the appropriate key names | 138 | // Update the button labels with the appropriate key names |
139 | - for(int i = 0; i < this.gameSettings.keyBindings.length; i++) | ||
140 | - { | ||
141 | - this.getLegacyControlList().get(i).displayString = this.gameSettings.getOptionDisplayString(i); | ||
142 | - } | ||
143 | - | ||
144 | - if (guibutton.id == 200) // Done button | ||
145 | - { | ||
146 | - this.mc.displayGuiScreen(this.parentScreen); | ||
147 | - } | ||
148 | - else if (guibutton.id == 201) // Next button | ||
149 | - { | ||
150 | - this.startIndex += this.controlsPerPage; | ||
151 | - this.startIndex = Math.min(this.endIndex, this.startIndex); | ||
152 | - this.initGui(); | ||
153 | - } | ||
154 | - else if (guibutton.id == 202) // Previous button | ||
155 | - { | ||
156 | - this.startIndex -= this.controlsPerPage; | ||
157 | - this.startIndex = Math.max(0, this.startIndex); | ||
158 | - this.initGui(); | ||
159 | - } | ||
160 | - else | ||
161 | - { | ||
162 | - this.activeButtonId = guibutton.id; | ||
163 | - guibutton.displayString = String.format("> %s <", this.gameSettings.getOptionDisplayString(guibutton.id)); | ||
164 | - } | 139 | + for(int i = 0; i < this.gameSettings.keyBindings.length; i++) |
140 | + { | ||
141 | + this.getLegacyControlList().get(i).displayString = this.gameSettings.getOptionDisplayString(i); | ||
142 | + } | ||
143 | + | ||
144 | + if (guibutton.id == 200) // Done button | ||
145 | + { | ||
146 | + this.mc.displayGuiScreen(this.parentScreen); | ||
147 | + } | ||
148 | + else if (guibutton.id == 201) // Next button | ||
149 | + { | ||
150 | + this.startIndex += this.controlsPerPage; | ||
151 | + this.startIndex = Math.min(this.endIndex, this.startIndex); | ||
152 | + this.initGui(); | ||
153 | + } | ||
154 | + else if (guibutton.id == 202) // Previous button | ||
155 | + { | ||
156 | + this.startIndex -= this.controlsPerPage; | ||
157 | + this.startIndex = Math.max(0, this.startIndex); | ||
158 | + this.initGui(); | ||
159 | + } | ||
160 | + else | ||
161 | + { | ||
162 | + this.activeButtonId = guibutton.id; | ||
163 | + guibutton.displayString = String.format("> %s <", this.gameSettings.getOptionDisplayString(guibutton.id)); | ||
164 | + } | ||
165 | } | 165 | } |
166 | - | 166 | + |
167 | @Override | 167 | @Override |
168 | - protected void mouseClicked(int mouseX, int mouseY, int mouseButton) | ||
169 | - { | ||
170 | - if (this.activeButtonId >= 0) | ||
171 | - { | ||
172 | - this.gameSettings.setKeyBinding(this.activeButtonId, -100 + mouseButton); | ||
173 | - this.getLegacyControlList().get(this.activeButtonId).displayString = this.gameSettings.getOptionDisplayString(this.activeButtonId); | ||
174 | - this.activeButtonId = -1; | ||
175 | - KeyBinding.resetKeyBindingArrayAndHash(); | ||
176 | - } | ||
177 | - else | ||
178 | - { | ||
179 | - super.mouseClicked(mouseX, mouseY, mouseButton); | ||
180 | - } | ||
181 | - } | ||
182 | - | 168 | + protected void mouseClicked(int mouseX, int mouseY, int mouseButton) |
169 | + { | ||
170 | + if (this.activeButtonId >= 0) | ||
171 | + { | ||
172 | + this.gameSettings.setKeyBinding(this.activeButtonId, -100 + mouseButton); | ||
173 | + this.getLegacyControlList().get(this.activeButtonId).displayString = this.gameSettings.getOptionDisplayString(this.activeButtonId); | ||
174 | + this.activeButtonId = -1; | ||
175 | + KeyBinding.resetKeyBindingArrayAndHash(); | ||
176 | + } | ||
177 | + else | ||
178 | + { | ||
179 | + super.mouseClicked(mouseX, mouseY, mouseButton); | ||
180 | + } | ||
181 | + } | ||
182 | + | ||
183 | @Override | 183 | @Override |
184 | - protected void keyTyped(char keyChar, int keyCode) | ||
185 | - { | ||
186 | - if (this.activeButtonId >= 0) | ||
187 | - { | ||
188 | - this.gameSettings.setKeyBinding(this.activeButtonId, keyCode); | ||
189 | - this.getLegacyControlList().get(this.activeButtonId).displayString = this.gameSettings.getOptionDisplayString(this.activeButtonId); | ||
190 | - this.activeButtonId = -1; | ||
191 | - KeyBinding.resetKeyBindingArrayAndHash(); | ||
192 | - } | ||
193 | - else | ||
194 | - { | ||
195 | - super.keyTyped(keyChar, keyCode); | ||
196 | - } | ||
197 | - } | ||
198 | - | 184 | + protected void keyTyped(char keyChar, int keyCode) |
185 | + { | ||
186 | + if (this.activeButtonId >= 0) | ||
187 | + { | ||
188 | + this.gameSettings.setKeyBinding(this.activeButtonId, keyCode); | ||
189 | + this.getLegacyControlList().get(this.activeButtonId).displayString = this.gameSettings.getOptionDisplayString(this.activeButtonId); | ||
190 | + this.activeButtonId = -1; | ||
191 | + KeyBinding.resetKeyBindingArrayAndHash(); | ||
192 | + } | ||
193 | + else | ||
194 | + { | ||
195 | + super.keyTyped(keyChar, keyCode); | ||
196 | + } | ||
197 | + } | ||
198 | + | ||
199 | @Override | 199 | @Override |
200 | - public void drawScreen(int mouseX, int mouseY, float partialTick) | ||
201 | - { | ||
202 | - this.drawDefaultBackground(); | ||
203 | - this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 20, 0xffffff); | ||
204 | - | ||
205 | - // Draw key labels | ||
206 | - for (int controlId = 0; controlId < this.gameSettings.keyBindings.length; controlId++) | ||
207 | - { | ||
208 | - boolean conflict = false; | ||
209 | - | ||
210 | - for (int id = 0; id < this.gameSettings.keyBindings.length; id++) | ||
211 | - { | ||
212 | - if (id != controlId && this.gameSettings.keyBindings[controlId].keyCode == this.gameSettings.keyBindings[id].keyCode) | ||
213 | - { | ||
214 | - conflict = true; | ||
215 | - break; | ||
216 | - } | ||
217 | - } | ||
218 | - | ||
219 | - if (this.activeButtonId == controlId) | ||
220 | - { | ||
221 | - this.getLegacyControlList().get(controlId).displayString = "\247f> \247e??? \247f<"; | ||
222 | - } | ||
223 | - else if (conflict) | ||
224 | - { | ||
225 | - this.getLegacyControlList().get(controlId).displayString = "\247c" + this.gameSettings.getOptionDisplayString(controlId); | ||
226 | - } | ||
227 | - else | ||
228 | - { | ||
229 | - this.getLegacyControlList().get(controlId).displayString = this.gameSettings.getOptionDisplayString(controlId); | ||
230 | - } | ||
231 | - | ||
232 | - int left = (controlId >= this.startIndex && controlId < this.startIndex + this.controlsPerPage) ? this.getWidth() / 2 - 155 : this.getWidth() + 10000; | ||
233 | - this.drawString(this.fontRenderer, this.getKeybindDescription(controlId), left + ((controlId - this.startIndex) % 2) * 160 + 70 + 6, this.getHeight() / 6 + 24 * ((controlId - this.startIndex) >> 1) + 7, 0xFFFFFF); | ||
234 | - } | ||
235 | - | ||
236 | - super.drawScreen(mouseX, mouseY, partialTick); | ||
237 | - } | 200 | + public void drawScreen(int mouseX, int mouseY, float partialTick) |
201 | + { | ||
202 | + this.drawDefaultBackground(); | ||
203 | + this.drawCenteredString(this.fontRenderer, this.screenTitle, this.width / 2, 20, 0xffffff); | ||
204 | + | ||
205 | + // Draw key labels | ||
206 | + for (int controlId = 0; controlId < this.gameSettings.keyBindings.length; controlId++) | ||
207 | + { | ||
208 | + boolean conflict = false; | ||
209 | + | ||
210 | + for (int id = 0; id < this.gameSettings.keyBindings.length; id++) | ||
211 | + { | ||
212 | + if (id != controlId && this.gameSettings.keyBindings[controlId].keyCode == this.gameSettings.keyBindings[id].keyCode) | ||
213 | + { | ||
214 | + conflict = true; | ||
215 | + break; | ||
216 | + } | ||
217 | + } | ||
218 | + | ||
219 | + if (this.activeButtonId == controlId) | ||
220 | + { | ||
221 | + this.getLegacyControlList().get(controlId).displayString = "\247f> \247e??? \247f<"; | ||
222 | + } | ||
223 | + else if (conflict) | ||
224 | + { | ||
225 | + this.getLegacyControlList().get(controlId).displayString = "\247c" + this.gameSettings.getOptionDisplayString(controlId); | ||
226 | + } | ||
227 | + else | ||
228 | + { | ||
229 | + this.getLegacyControlList().get(controlId).displayString = this.gameSettings.getOptionDisplayString(controlId); | ||
230 | + } | ||
231 | + | ||
232 | + int left = (controlId >= this.startIndex && controlId < this.startIndex + this.controlsPerPage) ? this.getWidth() / 2 - 155 : this.getWidth() + 10000; | ||
233 | + this.drawString(this.fontRenderer, this.getKeybindDescription(controlId), left + ((controlId - this.startIndex) % 2) * 160 + 70 + 6, this.getHeight() / 6 + 24 * ((controlId - this.startIndex) >> 1) + 7, 0xFFFFFF); | ||
234 | + } | ||
235 | + | ||
236 | + super.drawScreen(mouseX, mouseY, partialTick); | ||
237 | + } | ||
238 | } | 238 | } |
239 | \ No newline at end of file | 239 | \ No newline at end of file |
java/com/mumfrey/liteloader/permissions/PermissionsManager.java
@@ -58,13 +58,13 @@ public interface PermissionsManager | @@ -58,13 +58,13 @@ public interface PermissionsManager | ||
58 | */ | 58 | */ |
59 | public abstract void onCustomPayload(String channel, int length, byte[] data); | 59 | public abstract void onCustomPayload(String channel, int length, byte[] data); |
60 | 60 | ||
61 | - /** | ||
62 | - * LiteLoader support, gets the list of plugin channels to listen on | ||
63 | - * | ||
64 | - * @return | ||
65 | - */ | ||
66 | - public abstract List<String> getChannels(); | ||
67 | - | 61 | + /** |
62 | + * LiteLoader support, gets the list of plugin channels to listen on | ||
63 | + * | ||
64 | + * @return | ||
65 | + */ | ||
66 | + public abstract List<String> getChannels(); | ||
67 | + | ||
68 | /** | 68 | /** |
69 | * Register a new event listener, the registered object will receive callbacks for permissions events | 69 | * Register a new event listener, the registered object will receive callbacks for permissions events |
70 | * | 70 | * |
java/com/mumfrey/liteloader/util/ModUtilities.java
@@ -36,47 +36,47 @@ public abstract class ModUtilities | @@ -36,47 +36,47 @@ public abstract class ModUtilities | ||
36 | * @param entityClass | 36 | * @param entityClass |
37 | * @param renderer | 37 | * @param renderer |
38 | */ | 38 | */ |
39 | - @SuppressWarnings("unchecked") | 39 | + @SuppressWarnings("unchecked") |
40 | public static void addRenderer(Class<? extends Entity> entityClass, Render renderer) | 40 | public static void addRenderer(Class<? extends Entity> entityClass, Render renderer) |
41 | - { | ||
42 | - Map<Class<? extends Entity>, Render> entityRenderMap = PrivateFields.entityRenderMap.get(RenderManager.instance); | ||
43 | - entityRenderMap.put(entityClass, renderer); | ||
44 | - renderer.setRenderManager(RenderManager.instance); | ||
45 | - } | ||
46 | - | ||
47 | - /** | ||
48 | - * Register a packet override | ||
49 | - * | ||
50 | - * @param packetId | ||
51 | - * @param newPacket | ||
52 | - */ | ||
53 | - @SuppressWarnings("unchecked") | ||
54 | - public static boolean registerPacketOverride(int packetId, Class<? extends Packet> newPacket) | ||
55 | - { | ||
56 | - if (overriddenPackets.contains(Integer.valueOf(packetId))) | ||
57 | - { | ||
58 | - LiteLoader.getLogger().warning(String.format("Packet with ID %s was already overridden by another mod, one or mods may not function correctly", packetId)); | ||
59 | - } | ||
60 | - | ||
61 | - try | ||
62 | - { | ||
63 | - IntHashMap packetIdToClassMap = Packet.packetIdToClassMap; | ||
64 | - PrivateFields.StaticFields.packetClassToIdMap.get(); | ||
65 | - Map<Class<? extends Packet>, Integer> packetClassToIdMap = PrivateFields.StaticFields.packetClassToIdMap.get(); | ||
66 | - | ||
67 | - packetIdToClassMap.removeObject(packetId); | ||
68 | - packetIdToClassMap.addKey(packetId, newPacket); | ||
69 | - packetClassToIdMap.put(newPacket, Integer.valueOf(packetId)); | ||
70 | - | ||
71 | - return true; | ||
72 | - } | ||
73 | - catch (Exception ex) | ||
74 | - { | ||
75 | - LiteLoader.logger.warning("Error registering packet override for packet id " + packetId + ": " + ex.getMessage()); | ||
76 | - return false; | ||
77 | - } | ||
78 | - } | ||
79 | - | 41 | + { |
42 | + Map<Class<? extends Entity>, Render> entityRenderMap = PrivateFields.entityRenderMap.get(RenderManager.instance); | ||
43 | + entityRenderMap.put(entityClass, renderer); | ||
44 | + renderer.setRenderManager(RenderManager.instance); | ||
45 | + } | ||
46 | + | ||
47 | + /** | ||
48 | + * Register a packet override | ||
49 | + * | ||
50 | + * @param packetId | ||
51 | + * @param newPacket | ||
52 | + */ | ||
53 | + @SuppressWarnings("unchecked") | ||
54 | + public static boolean registerPacketOverride(int packetId, Class<? extends Packet> newPacket) | ||
55 | + { | ||
56 | + if (overriddenPackets.contains(Integer.valueOf(packetId))) | ||
57 | + { | ||
58 | + LiteLoader.getLogger().warning(String.format("Packet with ID %s was already overridden by another mod, one or mods may not function correctly", packetId)); | ||
59 | + } | ||
60 | + | ||
61 | + try | ||
62 | + { | ||
63 | + IntHashMap packetIdToClassMap = Packet.packetIdToClassMap; | ||
64 | + PrivateFields.StaticFields.packetClassToIdMap.get(); | ||
65 | + Map<Class<? extends Packet>, Integer> packetClassToIdMap = PrivateFields.StaticFields.packetClassToIdMap.get(); | ||
66 | + | ||
67 | + packetIdToClassMap.removeObject(packetId); | ||
68 | + packetIdToClassMap.addKey(packetId, newPacket); | ||
69 | + packetClassToIdMap.put(newPacket, Integer.valueOf(packetId)); | ||
70 | + | ||
71 | + return true; | ||
72 | + } | ||
73 | + catch (Exception ex) | ||
74 | + { | ||
75 | + LiteLoader.logger.warning("Error registering packet override for packet id " + packetId + ": " + ex.getMessage()); | ||
76 | + return false; | ||
77 | + } | ||
78 | + } | ||
79 | + | ||
80 | /** | 80 | /** |
81 | * Send a plugin channel (custom payload) packet to the server | 81 | * Send a plugin channel (custom payload) packet to the server |
82 | * | 82 | * |