Commit 3e896077b180d8a19508857140b0b372e154abeb
1 parent
6f0192d2
LiteLoader 1.6.4_02 - experimental - force permissions query packet on world cha…
…nge for BungeeCord multi-server support
Showing
5 changed files
with
109 additions
and
14 deletions
java/com/mumfrey/liteloader/core/Events.java
@@ -22,17 +22,17 @@ public class Events implements IPlayerUsage | @@ -22,17 +22,17 @@ public class Events implements IPlayerUsage | ||
22 | /** | 22 | /** |
23 | * Reference to the loader instance | 23 | * Reference to the loader instance |
24 | */ | 24 | */ |
25 | - private LiteLoader loader; | 25 | + private final LiteLoader loader; |
26 | 26 | ||
27 | /** | 27 | /** |
28 | * Reference to the game | 28 | * Reference to the game |
29 | */ | 29 | */ |
30 | - private Minecraft minecraft; | 30 | + private final Minecraft minecraft; |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Plugin channel manager | 33 | * Plugin channel manager |
34 | */ | 34 | */ |
35 | - private PluginChannels pluginChannels; | 35 | + private final PluginChannels pluginChannels; |
36 | 36 | ||
37 | /** | 37 | /** |
38 | * Reference to the minecraft timer | 38 | * Reference to the minecraft timer |
@@ -47,7 +47,7 @@ public class Events implements IPlayerUsage | @@ -47,7 +47,7 @@ public class Events implements IPlayerUsage | ||
47 | /** | 47 | /** |
48 | * Profiler hook objects | 48 | * Profiler hook objects |
49 | */ | 49 | */ |
50 | - private HookProfiler profilerHook = new HookProfiler(this); | 50 | + private final HookProfiler profilerHook = new HookProfiler(this); |
51 | 51 | ||
52 | /** | 52 | /** |
53 | * ScaledResolution used by the pre-chat and post-chat render callbacks | 53 | * ScaledResolution used by the pre-chat and post-chat render callbacks |
@@ -128,6 +128,12 @@ public class Events implements IPlayerUsage | @@ -128,6 +128,12 @@ public class Events implements IPlayerUsage | ||
128 | * client login events | 128 | * client login events |
129 | */ | 129 | */ |
130 | private LinkedList<PreLoginListener> preLoginListeners = new LinkedList<PreLoginListener>(); | 130 | private LinkedList<PreLoginListener> preLoginListeners = new LinkedList<PreLoginListener>(); |
131 | + | ||
132 | + /** | ||
133 | + * Hash code of the current world. We don't store the world reference here because we don't want | ||
134 | + * to mess with world GC by mistake | ||
135 | + */ | ||
136 | + private int worldHashCode = 0; | ||
131 | 137 | ||
132 | /** | 138 | /** |
133 | * Package private ctor | 139 | * Package private ctor |
@@ -585,6 +591,21 @@ public class Events implements IPlayerUsage | @@ -585,6 +591,21 @@ public class Events implements IPlayerUsage | ||
585 | tickable.onTick(this.minecraft, partialTicks, inGame, clock); | 591 | tickable.onTick(this.minecraft, partialTicks, inGame, clock); |
586 | profiler.endSection(); | 592 | profiler.endSection(); |
587 | } | 593 | } |
594 | + | ||
595 | + // Detected world change | ||
596 | + if (this.minecraft.theWorld != null) | ||
597 | + { | ||
598 | + if (this.minecraft.theWorld.hashCode() != this.worldHashCode) | ||
599 | + { | ||
600 | + this.worldHashCode = this.minecraft.theWorld.hashCode(); | ||
601 | + this.loader.onWorldChanged(this.minecraft.theWorld); | ||
602 | + } | ||
603 | + } | ||
604 | + else | ||
605 | + { | ||
606 | + this.worldHashCode = 0; | ||
607 | + this.loader.onWorldChanged(null); | ||
608 | + } | ||
588 | } | 609 | } |
589 | 610 | ||
590 | /** | 611 | /** |
java/com/mumfrey/liteloader/core/LiteLoader.java
@@ -29,6 +29,7 @@ import net.minecraft.src.NetHandler; | @@ -29,6 +29,7 @@ import net.minecraft.src.NetHandler; | ||
29 | import net.minecraft.src.Packet1Login; | 29 | import net.minecraft.src.Packet1Login; |
30 | import net.minecraft.src.ResourcePack; | 30 | import net.minecraft.src.ResourcePack; |
31 | import net.minecraft.src.SimpleReloadableResourceManager; | 31 | import net.minecraft.src.SimpleReloadableResourceManager; |
32 | +import net.minecraft.src.World; | ||
32 | 33 | ||
33 | import com.mumfrey.liteloader.*; | 34 | import com.mumfrey.liteloader.*; |
34 | import com.mumfrey.liteloader.crashreport.CallableLiteLoaderBrand; | 35 | import com.mumfrey.liteloader.crashreport.CallableLiteLoaderBrand; |
@@ -639,8 +640,8 @@ public final class LiteLoader | @@ -639,8 +640,8 @@ public final class LiteLoader | ||
639 | * @param metaDataKey | 640 | * @param metaDataKey |
640 | * @param defaultValue | 641 | * @param defaultValue |
641 | * @return | 642 | * @return |
642 | - * @throws InvalidActivityException | ||
643 | - * @throws IllegalArgumentException | 643 | + * @throws InvalidActivityException Thrown by getMod if init is not complete |
644 | + * @throws IllegalArgumentException Thrown by getMod if argument is null | ||
644 | */ | 645 | */ |
645 | public String getModMetaData(String mod, String metaDataKey, String defaultValue) throws InvalidActivityException, IllegalArgumentException | 646 | public String getModMetaData(String mod, String metaDataKey, String defaultValue) throws InvalidActivityException, IllegalArgumentException |
646 | { | 647 | { |
@@ -846,7 +847,24 @@ public final class LiteLoader | @@ -846,7 +847,24 @@ public final class LiteLoader | ||
846 | { | 847 | { |
847 | this.permissionsManager.onLogin(netHandler, loginPacket); | 848 | this.permissionsManager.onLogin(netHandler, loginPacket); |
848 | } | 849 | } |
850 | + | ||
851 | + /** | ||
852 | + * Called when the world reference is changed | ||
853 | + * | ||
854 | + * @param world | ||
855 | + */ | ||
856 | + void onWorldChanged(World world) | ||
857 | + { | ||
858 | + if (world != null) | ||
859 | + { | ||
860 | + // For bungeecord | ||
861 | + this.permissionsManager.scheduleRefresh(); | ||
862 | + } | ||
863 | + } | ||
849 | 864 | ||
865 | + /** | ||
866 | + * On render callback | ||
867 | + */ | ||
850 | void onRender() | 868 | void onRender() |
851 | { | 869 | { |
852 | if (this.paginateControls && this.minecraft.currentScreen != null && this.minecraft.currentScreen.getClass().equals(GuiControls.class)) | 870 | if (this.paginateControls && this.minecraft.currentScreen != null && this.minecraft.currentScreen.getClass().equals(GuiControls.class)) |
@@ -863,6 +881,10 @@ public final class LiteLoader | @@ -863,6 +881,10 @@ public final class LiteLoader | ||
863 | } | 881 | } |
864 | } | 882 | } |
865 | 883 | ||
884 | + /** | ||
885 | + * @param partialTicks | ||
886 | + * @param inGame | ||
887 | + */ | ||
866 | void onTick(float partialTicks, boolean inGame) | 888 | void onTick(float partialTicks, boolean inGame) |
867 | { | 889 | { |
868 | // Tick the permissions manager | 890 | // Tick the permissions manager |
@@ -871,6 +893,11 @@ public final class LiteLoader | @@ -871,6 +893,11 @@ public final class LiteLoader | ||
871 | this.checkAndStoreKeyBindings(); | 893 | this.checkAndStoreKeyBindings(); |
872 | } | 894 | } |
873 | 895 | ||
896 | + /** | ||
897 | + * Register a key for a mod | ||
898 | + * | ||
899 | + * @param binding | ||
900 | + */ | ||
874 | public void registerModKey(KeyBinding binding) | 901 | public void registerModKey(KeyBinding binding) |
875 | { | 902 | { |
876 | LinkedList<KeyBinding> keyBindings = new LinkedList<KeyBinding>(); | 903 | LinkedList<KeyBinding> keyBindings = new LinkedList<KeyBinding>(); |
java/com/mumfrey/liteloader/core/LiteLoaderEnumerator.java
@@ -32,6 +32,7 @@ import java.util.zip.ZipInputStream; | @@ -32,6 +32,7 @@ import java.util.zip.ZipInputStream; | ||
32 | import net.minecraft.launchwrapper.LaunchClassLoader; | 32 | import net.minecraft.launchwrapper.LaunchClassLoader; |
33 | 33 | ||
34 | import com.mumfrey.liteloader.LiteMod; | 34 | import com.mumfrey.liteloader.LiteMod; |
35 | +import com.mumfrey.liteloader.core.exceptions.OutdatedLoaderException; | ||
35 | import com.mumfrey.liteloader.launch.LiteLoaderTweaker; | 36 | import com.mumfrey.liteloader.launch.LiteLoaderTweaker; |
36 | 37 | ||
37 | /** | 38 | /** |
@@ -645,6 +646,11 @@ class LiteLoaderEnumerator implements FilenameFilter | @@ -645,6 +646,11 @@ class LiteLoaderEnumerator implements FilenameFilter | ||
645 | LiteLoaderEnumerator.enumerateCompressedPackage(prefix, superClass, classloader, classes, packagePath); | 646 | LiteLoaderEnumerator.enumerateCompressedPackage(prefix, superClass, classloader, classes, packagePath); |
646 | } | 647 | } |
647 | } | 648 | } |
649 | + catch (OutdatedLoaderException ex) | ||
650 | + { | ||
651 | + classes.clear(); | ||
652 | + LiteLoaderEnumerator.logWarning("Error searching in '%s', missing API component '%s', your loader is probably out of date", packagePath, ex.getMessage()); | ||
653 | + } | ||
648 | catch (Throwable th) | 654 | catch (Throwable th) |
649 | { | 655 | { |
650 | LiteLoaderEnumerator.logger.log(Level.WARNING, "Enumeration error", th); | 656 | LiteLoaderEnumerator.logger.log(Level.WARNING, "Enumeration error", th); |
@@ -700,8 +706,9 @@ class LiteLoaderEnumerator implements FilenameFilter | @@ -700,8 +706,9 @@ class LiteLoaderEnumerator implements FilenameFilter | ||
700 | * @param classes | 706 | * @param classes |
701 | * @param packagePath | 707 | * @param packagePath |
702 | * @param packageName | 708 | * @param packageName |
709 | + * @throws OutdatedLoaderException | ||
703 | */ | 710 | */ |
704 | - private static void enumerateDirectory(String prefix, Class<?> superClass, ClassLoader classloader, LinkedList<Class<?>> classes, File packagePath) | 711 | + private static void enumerateDirectory(String prefix, Class<?> superClass, ClassLoader classloader, LinkedList<Class<?>> classes, File packagePath) throws OutdatedLoaderException |
705 | { | 712 | { |
706 | LiteLoaderEnumerator.enumerateDirectory(prefix, superClass, classloader, classes, packagePath, "", 0); | 713 | LiteLoaderEnumerator.enumerateDirectory(prefix, superClass, classloader, classes, packagePath, "", 0); |
707 | } | 714 | } |
@@ -714,8 +721,9 @@ class LiteLoaderEnumerator implements FilenameFilter | @@ -714,8 +721,9 @@ class LiteLoaderEnumerator implements FilenameFilter | ||
714 | * @param classes | 721 | * @param classes |
715 | * @param packagePath | 722 | * @param packagePath |
716 | * @param packageName | 723 | * @param packageName |
724 | + * @throws OutdatedLoaderException | ||
717 | */ | 725 | */ |
718 | - private static void enumerateDirectory(String prefix, Class<?> superClass, ClassLoader classloader, LinkedList<Class<?>> classes, File packagePath, String packageName, int depth) | 726 | + private static void enumerateDirectory(String prefix, Class<?> superClass, ClassLoader classloader, LinkedList<Class<?>> classes, File packagePath, String packageName, int depth) throws OutdatedLoaderException |
719 | { | 727 | { |
720 | // Prevent crash due to broken recursion | 728 | // Prevent crash due to broken recursion |
721 | if (depth > MAX_DISCOVERY_DEPTH) | 729 | if (depth > MAX_DISCOVERY_DEPTH) |
@@ -746,8 +754,9 @@ class LiteLoaderEnumerator implements FilenameFilter | @@ -746,8 +754,9 @@ class LiteLoaderEnumerator implements FilenameFilter | ||
746 | * @param superClass | 754 | * @param superClass |
747 | * @param classes | 755 | * @param classes |
748 | * @param className | 756 | * @param className |
757 | + * @throws OutdatedLoaderException | ||
749 | */ | 758 | */ |
750 | - private static void checkAndAddClass(ClassLoader classloader, Class<?> superClass, LinkedList<Class<?>> classes, String className) | 759 | + private static void checkAndAddClass(ClassLoader classloader, Class<?> superClass, LinkedList<Class<?>> classes, String className) throws OutdatedLoaderException |
751 | { | 760 | { |
752 | if (className.indexOf('$') > -1) | 761 | if (className.indexOf('$') > -1) |
753 | return; | 762 | return; |
@@ -763,6 +772,15 @@ class LiteLoaderEnumerator implements FilenameFilter | @@ -763,6 +772,15 @@ class LiteLoaderEnumerator implements FilenameFilter | ||
763 | } | 772 | } |
764 | catch (Throwable th) | 773 | catch (Throwable th) |
765 | { | 774 | { |
775 | + String missingClassName = th.getCause().getMessage(); | ||
776 | + if (th.getCause() instanceof NoClassDefFoundError && missingClassName != null) | ||
777 | + { | ||
778 | + if (missingClassName.startsWith("com/mumfrey/liteloader/")) | ||
779 | + { | ||
780 | + throw new OutdatedLoaderException(missingClassName.substring(missingClassName.lastIndexOf('/') + 1)); | ||
781 | + } | ||
782 | + } | ||
783 | + | ||
766 | LiteLoaderEnumerator.logger.log(Level.WARNING, "checkAndAddClass error", th); | 784 | LiteLoaderEnumerator.logger.log(Level.WARNING, "checkAndAddClass error", th); |
767 | } | 785 | } |
768 | } | 786 | } |
java/com/mumfrey/liteloader/core/exceptions/OutdatedLoaderException.java
0 → 100644
1 | +package com.mumfrey.liteloader.core.exceptions; | ||
2 | + | ||
3 | +/** | ||
4 | + * Exception thrown when a mod class references a liteloader interface which does not exist, | ||
5 | + * which more than likely means that it requires a more up-to-date version of the loader than | ||
6 | + * is currently installed. | ||
7 | + * | ||
8 | + * @author Adam Mummery-Smith | ||
9 | + */ | ||
10 | +public class OutdatedLoaderException extends Exception | ||
11 | +{ | ||
12 | + private static final long serialVersionUID = 8770358290208830747L; | ||
13 | + | ||
14 | + /** | ||
15 | + * @param missingAPI Name of the referenced class which is missing | ||
16 | + */ | ||
17 | + public OutdatedLoaderException(String missingAPI) | ||
18 | + { | ||
19 | + super(missingAPI); | ||
20 | + } | ||
21 | +} |
java/com/mumfrey/liteloader/permissions/PermissionsManagerClient.java
@@ -75,7 +75,7 @@ public class PermissionsManagerClient implements PermissionsManager, PluginChann | @@ -75,7 +75,7 @@ public class PermissionsManagerClient implements PermissionsManager, PluginChann | ||
75 | /** | 75 | /** |
76 | * Delay counter for when joining a server | 76 | * Delay counter for when joining a server |
77 | */ | 77 | */ |
78 | - private int loginRegisterTicks = 0; | 78 | + private int pendingRefreshTicks = 0; |
79 | 79 | ||
80 | private int menuTicks = 0; | 80 | private int menuTicks = 0; |
81 | 81 | ||
@@ -166,11 +166,19 @@ public class PermissionsManagerClient implements PermissionsManager, PluginChann | @@ -166,11 +166,19 @@ public class PermissionsManagerClient implements PermissionsManager, PluginChann | ||
166 | @Override | 166 | @Override |
167 | public void onLogin(NetHandler netHandler, Packet1Login loginPacket) | 167 | public void onLogin(NetHandler netHandler, Packet1Login loginPacket) |
168 | { | 168 | { |
169 | - this.loginRegisterTicks = 2; | ||
170 | this.clearServerPermissions(); | 169 | this.clearServerPermissions(); |
170 | + this.scheduleRefresh(); | ||
171 | } | 171 | } |
172 | 172 | ||
173 | /** | 173 | /** |
174 | + * Schedule a permissions refresh | ||
175 | + */ | ||
176 | + public void scheduleRefresh() | ||
177 | + { | ||
178 | + this.pendingRefreshTicks = 2; | ||
179 | + } | ||
180 | + | ||
181 | + /** | ||
174 | * Clears the current replicated server permissions | 182 | * Clears the current replicated server permissions |
175 | */ | 183 | */ |
176 | protected void clearServerPermissions() | 184 | protected void clearServerPermissions() |
@@ -239,11 +247,11 @@ public class PermissionsManagerClient implements PermissionsManager, PluginChann | @@ -239,11 +247,11 @@ public class PermissionsManagerClient implements PermissionsManager, PluginChann | ||
239 | this.minecraft = minecraft; | 247 | this.minecraft = minecraft; |
240 | this.lastTickTime = System.currentTimeMillis(); | 248 | this.lastTickTime = System.currentTimeMillis(); |
241 | 249 | ||
242 | - if (this.loginRegisterTicks > 0) | 250 | + if (this.pendingRefreshTicks > 0) |
243 | { | 251 | { |
244 | - this.loginRegisterTicks--; | 252 | + this.pendingRefreshTicks--; |
245 | 253 | ||
246 | - if (this.loginRegisterTicks == 0 && inGame) | 254 | + if (this.pendingRefreshTicks == 0 && inGame) |
247 | { | 255 | { |
248 | this.sendPermissionQueries(); | 256 | this.sendPermissionQueries(); |
249 | return; | 257 | return; |