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 | * | ... | ... |