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 | 6 | <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> |
7 | 7 | <classpathentry kind="lib" path="/Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.0/lwjgl-2.9.0.jar"/> |
8 | 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 | 10 | <classpathentry kind="output" path="bin"/> |
10 | 11 | </classpath> | ... | ... |
java/com/mumfrey/liteloader/core/HookChat.java
... | ... | @@ -136,39 +136,39 @@ public class HookChat extends Packet3Chat |
136 | 136 | /** |
137 | 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 | 151 | public static void register(boolean force) |
152 | 152 | { |
153 | 153 | if (!registered || force) |
154 | 154 | { |
155 | 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 | 173 | catch (Exception ex) |
174 | 174 | { | ... | ... |
java/com/mumfrey/liteloader/core/HookPluginChannels.java
... | ... | @@ -128,39 +128,39 @@ public class HookPluginChannels extends Packet250CustomPayload |
128 | 128 | /** |
129 | 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 | 143 | public static void register(boolean force) |
144 | 144 | { |
145 | 145 | if (!registered || force) |
146 | 146 | { |
147 | 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 | 165 | catch (Exception ex) |
166 | 166 | { | ... | ... |
java/com/mumfrey/liteloader/core/LiteLoader.java
... | ... | @@ -10,16 +10,23 @@ import java.io.IOException; |
10 | 10 | import java.io.InputStream; |
11 | 11 | import java.io.InputStreamReader; |
12 | 12 | import java.io.PrintStream; |
13 | +import java.io.UnsupportedEncodingException; | |
13 | 14 | import java.lang.reflect.Method; |
15 | +import java.net.MalformedURLException; | |
16 | +import java.net.URISyntaxException; | |
14 | 17 | import java.net.URL; |
15 | 18 | import java.net.URLClassLoader; |
16 | 19 | import java.net.URLDecoder; |
17 | 20 | import java.nio.charset.Charset; |
21 | +import java.util.ArrayList; | |
18 | 22 | import java.util.HashMap; |
19 | 23 | import java.util.Iterator; |
20 | 24 | import java.util.LinkedList; |
21 | 25 | import java.util.List; |
26 | +import java.util.Map; | |
27 | +import java.util.Map.Entry; | |
22 | 28 | import java.util.Properties; |
29 | +import java.util.TreeSet; | |
23 | 30 | import java.util.logging.FileHandler; |
24 | 31 | import java.util.logging.Formatter; |
25 | 32 | import java.util.logging.Level; |
... | ... | @@ -71,7 +78,6 @@ import com.mumfrey.liteloader.util.PrivateFields; |
71 | 78 | * @author Adam Mummery-Smith |
72 | 79 | * @version 1.6.2 |
73 | 80 | */ |
74 | -@SuppressWarnings("rawtypes") | |
75 | 81 | public final class LiteLoader implements FilenameFilter, IPlayerUsage |
76 | 82 | { |
77 | 83 | /** |
... | ... | @@ -115,6 +121,11 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
115 | 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 | 129 | * Mods folder which contains mods and legacy config files |
119 | 130 | */ |
120 | 131 | private File modsFolder; |
... | ... | @@ -173,6 +184,16 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
173 | 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 | 197 | * List of loaded mods, for crash reporting |
177 | 198 | */ |
178 | 199 | private String loadedModsList = "none"; |
... | ... | @@ -280,8 +301,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
280 | 301 | * Permission Manager |
281 | 302 | */ |
282 | 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 | 307 | if (instance == null) |
287 | 308 | { |
... | ... | @@ -289,6 +310,22 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
289 | 310 | LiteLoader.assetsDirectory = assetsDirectory; |
290 | 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 | 329 | instance = new LiteLoader(); |
293 | 330 | instance.initLoader(); |
294 | 331 | } |
... | ... | @@ -371,14 +408,10 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
371 | 408 | this.commonConfigFolder = new File(this.configBaseFolder, "common"); |
372 | 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 | 416 | this.propertiesFile = new File(this.configBaseFolder, "liteloader.properties"); |
384 | 417 | } |
... | ... | @@ -402,8 +435,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
402 | 435 | */ |
403 | 436 | private void initLoader() |
404 | 437 | { |
405 | - if (this.loaderStartupDone) | |
406 | - return; | |
438 | + if (this.loaderStartupDone) return; | |
407 | 439 | this.loaderStartupDone = true; |
408 | 440 | |
409 | 441 | // Set up loader, initialises any reflection methods needed |
... | ... | @@ -700,8 +732,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
700 | 732 | /** |
701 | 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 | 736 | * @return |
706 | 737 | * @throws InvalidActivityException |
707 | 738 | */ |
... | ... | @@ -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 | 814 | * Enumerate the java class path and "mods" folder to find mod classes, then |
732 | 815 | * load the classes |
733 | 816 | */ |
734 | 817 | private void prepareMods(boolean searchMods, boolean searchProtectionDomain, boolean searchClassPath) |
735 | 818 | { |
736 | 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 | 822 | if (searchMods) |
740 | 823 | { |
... | ... | @@ -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 | 834 | try |
754 | 835 | { |
755 | 836 | logger.info("Enumerating class path..."); |
... | ... | @@ -763,7 +844,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
763 | 844 | |
764 | 845 | if (searchProtectionDomain || searchClassPath) |
765 | 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 | 850 | logger.info("Mod class discovery completed"); |
769 | 851 | } |
... | ... | @@ -773,44 +855,87 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
773 | 855 | return; |
774 | 856 | } |
775 | 857 | |
776 | - this.loadMods(modsToLoad); | |
858 | + this.loadMods(); | |
777 | 859 | } |
778 | 860 | |
779 | 861 | /** |
780 | 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 | 871 | for (File modFile : modFolder.listFiles(this)) |
790 | 872 | { |
791 | 873 | try |
792 | 874 | { |
875 | + String strVersion = null; | |
876 | + | |
793 | 877 | // Check for a version file |
794 | 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 | 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 | 943 | } |
819 | 944 | catch (Exception ex) |
820 | 945 | { |
946 | + ex.printStackTrace(System.err); | |
821 | 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 | 981 | /** |
838 | 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 | 988 | if (searchProtectionDomain) |
853 | 989 | { |
854 | 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 | 994 | catch (Throwable th) |
902 | 995 | { |
... | ... | @@ -907,78 +1000,158 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
907 | 1000 | if (searchClassPath) |
908 | 1001 | { |
909 | 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 | 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 | 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 | 1118 | if (modClasses.size() > 0) |
950 | 1119 | logger.info(String.format("Found %s potential matches", modClasses.size())); |
951 | 1120 | } |
952 | - | |
953 | - return modsToLoad; | |
954 | 1121 | } |
955 | 1122 | |
956 | 1123 | /** |
957 | 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 | 1132 | logger.info("Mod class discovery failed. Not loading any mods!"); |
967 | 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 | 1140 | try |
975 | 1141 | { |
976 | 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 | 1156 | catch (Throwable th) |
984 | 1157 | { |
... | ... | @@ -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 | 1185 | * Initialise the mods which were loaded |
993 | 1186 | */ |
994 | 1187 | private void initMods() |
... | ... | @@ -999,28 +1192,29 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
999 | 1192 | for (Iterator<LiteMod> iter = this.mods.iterator(); iter.hasNext();) |
1000 | 1193 | { |
1001 | 1194 | LiteMod mod = iter.next(); |
1195 | + String modName = mod.getName(); | |
1002 | 1196 | |
1003 | 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 | 1201 | try |
1008 | 1202 | { |
1009 | - String modKey = this.getModNameForConfig(mod.getClass(), mod.getName()); | |
1203 | + String modKey = this.getModNameForConfig(mod.getClass(), modName); | |
1010 | 1204 | LiteLoaderVersion lastModVersion = LiteLoaderVersion.getVersionFromRevision(this.getLastKnownModRevision(modKey)); |
1011 | 1205 | |
1012 | 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 | 1209 | mod.upgradeSettings(LiteLoader.getVersion(), this.versionConfigFolder, this.inflectVersionedConfigPath(lastModVersion)); |
1016 | 1210 | |
1017 | 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 | 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 | 1220 | mod.init(this.modsFolder); |
... | ... | @@ -1059,7 +1253,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1059 | 1253 | { |
1060 | 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 | 1258 | else |
1065 | 1259 | { |
... | ... | @@ -1092,12 +1286,12 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1092 | 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 | 1290 | loadedModsCount++; |
1097 | 1291 | } |
1098 | 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 | 1295 | iter.remove(); |
1102 | 1296 | } |
1103 | 1297 | } |
... | ... | @@ -1304,9 +1498,9 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1304 | 1498 | * @param superClass |
1305 | 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 | 1505 | try |
1312 | 1506 | { |
... | ... | @@ -1335,7 +1529,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1335 | 1529 | * @throws FileNotFoundException |
1336 | 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 | 1534 | FileInputStream fileinputstream = new FileInputStream(packagePath); |
1341 | 1535 | ZipInputStream zipinputstream = new ZipInputStream(fileinputstream); |
... | ... | @@ -1377,7 +1571,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1377 | 1571 | * @param packagePath |
1378 | 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 | 1576 | enumerateDirectory(prefix, superClass, classloader, classes, packagePath, "", 0); |
1383 | 1577 | } |
... | ... | @@ -1391,7 +1585,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1391 | 1585 | * @param packagePath |
1392 | 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 | 1590 | // Prevent crash due to broken recursion |
1397 | 1591 | if (depth > MAX_DISCOVERY_DEPTH) |
... | ... | @@ -1423,15 +1617,14 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1423 | 1617 | * @param classes |
1424 | 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 | 1622 | if (className.indexOf('$') > -1) |
1430 | 1623 | return; |
1431 | 1624 | |
1432 | 1625 | try |
1433 | 1626 | { |
1434 | - Class subClass = classloader.loadClass(className); | |
1627 | + Class<?> subClass = classloader.loadClass(className); | |
1435 | 1628 | |
1436 | 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 | 1640 | /** |
1448 | 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 | 1645 | private boolean addURLToClassPath(URL classUrl) |
1454 | 1646 | { |
... | ... | @@ -1596,8 +1788,7 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1596 | 1788 | /** |
1597 | 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 | 1793 | public void onTick(Profiler profiler, boolean tick) |
1603 | 1794 | { |
... | ... | @@ -1728,10 +1919,8 @@ public final class LiteLoader implements FilenameFilter, IPlayerUsage |
1728 | 1919 | /** |
1729 | 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 | 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 | 12 | public enum LiteLoaderVersion |
13 | 13 | { |
14 | 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 | 17 | MC_1_6_1_R0(11, "1.6.1", "1.6.1", "1.6.1", "1.6.r1"), |
16 | 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 | 20 | * Pagination variables |
21 | 21 | */ |
22 | 22 | protected int controlsPerPage, startIndex, endIndex; |
23 | - | |
23 | + | |
24 | 24 | /** |
25 | 25 | * Parent screen which will be displayed when this screen is closed |
26 | 26 | */ |
27 | 27 | protected GuiScreen parentScreen; |
28 | - | |
29 | - /** | |
30 | - * Game settings | |
31 | - */ | |
28 | + | |
29 | + /** | |
30 | + * Game settings | |
31 | + */ | |
32 | 32 | protected GameSettings gameSettings; |
33 | - | |
34 | - /** | |
35 | - * Additional buttons | |
36 | - */ | |
33 | + | |
34 | + /** | |
35 | + * Additional buttons | |
36 | + */ | |
37 | 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 | 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 | 75 | public GuiScreen getParentScreen() |
76 | 76 | { |
77 | 77 | return this.parentScreen; |
... | ... | @@ -84,40 +84,40 @@ public class GuiControlsPaginated extends GuiScreen |
84 | 84 | public void initGui() |
85 | 85 | { |
86 | 86 | this.getLegacyControlList().clear(); |
87 | - | |
87 | + | |
88 | 88 | int oldControlsPerPage = this.controlsPerPage; |
89 | 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 | 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 | 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 | 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 | 122 | * @param controlId |
123 | 123 | * @return |
... | ... | @@ -136,103 +136,103 @@ public class GuiControlsPaginated extends GuiScreen |
136 | 136 | protected void actionPerformed(GuiButton guibutton) |
137 | 137 | { |
138 | 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 | 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 | 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 | 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 | 239 | \ No newline at end of file | ... | ... |
java/com/mumfrey/liteloader/permissions/PermissionsManager.java
... | ... | @@ -58,13 +58,13 @@ public interface PermissionsManager |
58 | 58 | */ |
59 | 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 | 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 | 36 | * @param entityClass |
37 | 37 | * @param renderer |
38 | 38 | */ |
39 | - @SuppressWarnings("unchecked") | |
39 | + @SuppressWarnings("unchecked") | |
40 | 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 | 81 | * Send a plugin channel (custom payload) packet to the server |
82 | 82 | * | ... | ... |