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