Commit faa26f42c4d95b314c6c9f24e70e6fb488b620f5
1 parent
349f6093
updated ASM to 5.0.3, support automatic update check and forced update, minor fixes
Showing
26 changed files
with
665 additions
and
108 deletions
.classpath
... | ... | @@ -9,15 +9,15 @@ |
9 | 9 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar"/> |
10 | 10 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/com/google/guava/guava/15.0/guava-15.0.jar"/> |
11 | 11 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/commons-io/commons-io/2.4/commons-io-2.4.jar"/> |
12 | - <classpathentry exported="true" kind="lib" path="lib/launchwrapper-1.9.jar" sourcepath="externals/launchwrapper/src"/> | |
12 | + <classpathentry exported="true" kind="lib" path="lib/launchwrapper-1.11.jar" sourcepath="externals/launchwrapper/src"/> | |
13 | 13 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar"/> |
14 | 14 | <classpathentry kind="lib" path="/Client/jars/libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar"/> |
15 | 15 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/io/netty/netty-all/4.0.10.Final/netty-all-4.0.10.Final.jar"/> |
16 | 16 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar"/> |
17 | 17 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar"/> |
18 | 18 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar"/> |
19 | - <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/com/mojang/authlib/1.5.13/authlib-1.5.13.jar"/> | |
19 | + <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/com/mojang/authlib/1.5.16/authlib-1.5.16.jar"/> | |
20 | 20 | <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.1/lwjgl-2.9.1.jar"/> |
21 | - <classpathentry exported="true" kind="lib" path="lib/asm-debug-all-4.1.jar"/> | |
21 | + <classpathentry exported="true" kind="lib" path="lib/asm-debug-all-5.0.3.jar"/> | |
22 | 22 | <classpathentry kind="output" path="bin"/> |
23 | 23 | </classpath> | ... | ... |
LiteLoader.iml
... | ... | @@ -4,7 +4,7 @@ |
4 | 4 | <libelement value="file:///Client/jars/libraries/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar" /> |
5 | 5 | <libelement value="file:///Client/jars/libraries/com/google/guava/guava/15.0/guava-15.0.jar" /> |
6 | 6 | <libelement value="file:///Client/jars/libraries/commons-io/commons-io/2.4/commons-io-2.4.jar" /> |
7 | - <libelement value="jar://$MODULE_DIR$/lib/launchwrapper-1.9.jar!/" /> | |
7 | + <libelement value="jar://$MODULE_DIR$/lib/launchwrapper-1.11.jar!/" /> | |
8 | 8 | <libelement value="jar://$MODULE_DIR$/lib/asm-debug-all-4.1.jar!/" /> |
9 | 9 | <libelement value="file:///Client/jars/libraries/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar" /> |
10 | 10 | <libelement value="file:///Client/jars/libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar" /> |
... | ... | @@ -12,7 +12,7 @@ |
12 | 12 | <libelement value="file:///Client/jars/libraries/org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar" /> |
13 | 13 | <libelement value="file:///Client/jars/libraries/org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar" /> |
14 | 14 | <libelement value="file:///Client/jars/libraries/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar" /> |
15 | - <libelement value="file:///Client/jars/libraries/com/mojang/authlib/1.5.13/authlib-1.5.13.jar" /> | |
15 | + <libelement value="file:///Client/jars/libraries/com/mojang/authlib/1.5.16/authlib-1.5.16.jar" /> | |
16 | 16 | <libelement value="file:///Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.1/lwjgl-2.9.1.jar" /> |
17 | 17 | <src_description expected_position="0"> |
18 | 18 | <src_folder value="file://$MODULE_DIR$/debug" expected_position="0" /> |
... | ... | @@ -34,9 +34,9 @@ |
34 | 34 | <orderEntry type="module" module-name="Client" exported="" /> |
35 | 35 | <orderEntry type="jdk" jdkName="JavaSE-1.6" jdkType="JavaSDK" /> |
36 | 36 | <orderEntry type="module-library" exported=""> |
37 | - <library name="launchwrapper-1.9.jar"> | |
37 | + <library name="launchwrapper-1.11.jar"> | |
38 | 38 | <CLASSES> |
39 | - <root url="jar://$MODULE_DIR$/lib/launchwrapper-1.9.jar!/" /> | |
39 | + <root url="jar://$MODULE_DIR$/lib/launchwrapper-1.11.jar!/" /> | |
40 | 40 | </CLASSES> |
41 | 41 | <JAVADOC /> |
42 | 42 | <SOURCES> |
... | ... | @@ -47,7 +47,7 @@ |
47 | 47 | <orderEntry type="module-library" exported=""> |
48 | 48 | <library> |
49 | 49 | <CLASSES> |
50 | - <root url="jar://$MODULE_DIR$/lib/asm-debug-all-4.1.jar!/" /> | |
50 | + <root url="jar://$MODULE_DIR$/lib/asm-debug-all-5.0.3.jar!/" /> | |
51 | 51 | </CLASSES> |
52 | 52 | <JAVADOC /> |
53 | 53 | <SOURCES /> | ... | ... |
debug/com/mumfrey/liteloader/debug/LoginManager.java
... | ... | @@ -4,6 +4,7 @@ import java.io.File; |
4 | 4 | import java.io.FileReader; |
5 | 5 | import java.io.FileWriter; |
6 | 6 | import java.io.IOException; |
7 | +import java.lang.reflect.Type; | |
7 | 8 | import java.net.Proxy; |
8 | 9 | import java.util.HashMap; |
9 | 10 | import java.util.Map; |
... | ... | @@ -14,12 +15,19 @@ import javax.swing.JOptionPane; |
14 | 15 | import com.google.common.base.Strings; |
15 | 16 | import com.google.gson.Gson; |
16 | 17 | import com.google.gson.GsonBuilder; |
18 | +import com.google.gson.JsonArray; | |
19 | +import com.google.gson.JsonElement; | |
20 | +import com.google.gson.JsonObject; | |
21 | +import com.google.gson.JsonPrimitive; | |
22 | +import com.google.gson.JsonSerializationContext; | |
23 | +import com.google.gson.JsonSerializer; | |
17 | 24 | import com.google.gson.annotations.SerializedName; |
18 | 25 | import com.mojang.authlib.Agent; |
19 | 26 | import com.mojang.authlib.GameProfile; |
20 | 27 | import com.mojang.authlib.UserType; |
21 | 28 | import com.mojang.authlib.exceptions.AuthenticationException; |
22 | 29 | import com.mojang.authlib.exceptions.InvalidCredentialsException; |
30 | +import com.mojang.authlib.properties.Property; | |
23 | 31 | import com.mojang.authlib.properties.PropertyMap; |
24 | 32 | import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; |
25 | 33 | import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication; |
... | ... | @@ -315,9 +323,32 @@ public class LoginManager |
315 | 323 | public String getUserProperties() |
316 | 324 | { |
317 | 325 | PropertyMap userProperties = this.authentication.getUserProperties(); |
318 | - return userProperties != null ? userProperties.toString() : "{}"; | |
326 | + return userProperties != null ? (new GsonBuilder()).registerTypeAdapter(PropertyMap.class, new UserPropertiesSerializer()).create().toJson(userProperties) : "{}"; | |
319 | 327 | } |
320 | 328 | |
329 | + class UserPropertiesSerializer implements JsonSerializer<PropertyMap> | |
330 | + { | |
331 | + @Override | |
332 | + public JsonElement serialize(PropertyMap propertyMap, Type argType, JsonSerializationContext context) | |
333 | + { | |
334 | + JsonObject result = new JsonObject(); | |
335 | + | |
336 | + for (String key : propertyMap.keySet()) | |
337 | + { | |
338 | + JsonArray values = new JsonArray(); | |
339 | + for (Property property : propertyMap.get(key)) | |
340 | + { | |
341 | + values.add(new JsonPrimitive(property.getValue())); | |
342 | + } | |
343 | + | |
344 | + result.add(key, values); | |
345 | + } | |
346 | + | |
347 | + return result; | |
348 | + } | |
349 | + } | |
350 | + | |
351 | + | |
321 | 352 | /** |
322 | 353 | * Struct for Gson serialisation of authenticaion settings |
323 | 354 | * | ... | ... |
java/client/com/mumfrey/liteloader/client/LiteLoaderPanelManager.java
... | ... | @@ -5,16 +5,20 @@ import net.minecraft.client.gui.GuiIngameMenu; |
5 | 5 | import net.minecraft.client.gui.GuiMainMenu; |
6 | 6 | import net.minecraft.client.gui.GuiOptions; |
7 | 7 | import net.minecraft.client.gui.GuiScreen; |
8 | +import net.minecraft.client.resources.I18n; | |
8 | 9 | |
9 | 10 | import org.lwjgl.input.Keyboard; |
10 | 11 | |
11 | 12 | import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel; |
12 | 13 | import com.mumfrey.liteloader.common.GameEngine; |
13 | 14 | import com.mumfrey.liteloader.core.LiteLoaderMods; |
15 | +import com.mumfrey.liteloader.core.LiteLoaderUpdateSite; | |
16 | +import com.mumfrey.liteloader.core.LiteLoaderVersion; | |
14 | 17 | import com.mumfrey.liteloader.interfaces.PanelManager; |
15 | 18 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
16 | 19 | import com.mumfrey.liteloader.launch.LoaderProperties; |
17 | 20 | import com.mumfrey.liteloader.modconfig.ConfigManager; |
21 | +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | |
18 | 22 | |
19 | 23 | /** |
20 | 24 | * Observer which handles the display of the mod panel |
... | ... | @@ -23,9 +27,6 @@ import com.mumfrey.liteloader.modconfig.ConfigManager; |
23 | 27 | */ |
24 | 28 | public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
25 | 29 | { |
26 | - private static final String OPTION_MOD_INFO_SCREEN = "modInfoScreen"; | |
27 | - private static final String OPTION_NO_HIDE_TAB = "tabAlwaysExpanded"; | |
28 | - | |
29 | 30 | private final LoaderEnvironment environment; |
30 | 31 | |
31 | 32 | /** |
... | ... | @@ -54,6 +55,10 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
54 | 55 | * can temporarily disable the function without having to change the underlying property |
55 | 56 | */ |
56 | 57 | private boolean hideModInfoScreenTab = false; |
58 | + | |
59 | + private boolean checkForUpdate = false; | |
60 | + | |
61 | + private String notification; | |
57 | 62 | |
58 | 63 | /** |
59 | 64 | * Active "mod info" screen, drawn as an overlay when in the main menu and made the active screen if |
... | ... | @@ -72,8 +77,24 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
72 | 77 | this.properties = properties; |
73 | 78 | this.minecraft = ((GameEngine<Minecraft, ?>)engine).getClient(); |
74 | 79 | |
75 | - this.displayModInfoScreenTab = this.properties.getAndStoreBooleanProperty(LiteLoaderPanelManager.OPTION_MOD_INFO_SCREEN, true); | |
76 | - this.tabAlwaysExpanded = this.properties.getAndStoreBooleanProperty(LiteLoaderPanelManager.OPTION_NO_HIDE_TAB, false); | |
80 | + this.displayModInfoScreenTab = this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_MOD_INFO_SCREEN, true); | |
81 | + this.tabAlwaysExpanded = this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_NO_HIDE_TAB, false); | |
82 | + | |
83 | + if (this.properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_FORCE_UPDATE, false)) | |
84 | + { | |
85 | + int updateCheckInterval = this.properties.getIntegerProperty(LoaderProperties.OPTION_UPDATE_CHECK_INTR) + 1; | |
86 | + LiteLoaderLogger.debug("Force update is TRUE, updateCheckInterval = %d", updateCheckInterval); | |
87 | + | |
88 | + if (updateCheckInterval > 10) | |
89 | + { | |
90 | + LiteLoaderLogger.debug("Forcing update check!"); | |
91 | + this.checkForUpdate = true; | |
92 | + updateCheckInterval = 0; | |
93 | + } | |
94 | + | |
95 | + this.properties.setIntegerProperty(LoaderProperties.OPTION_UPDATE_CHECK_INTR, updateCheckInterval); | |
96 | + this.properties.writeProperties(); | |
97 | + } | |
77 | 98 | } |
78 | 99 | |
79 | 100 | @Override |
... | ... | @@ -83,6 +104,15 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
83 | 104 | this.configManager = configManager; |
84 | 105 | } |
85 | 106 | |
107 | + @Override | |
108 | + public void onStartupComplete() | |
109 | + { | |
110 | + if (this.checkForUpdate) | |
111 | + { | |
112 | + LiteLoaderVersion.getUpdateSite().beginUpdateCheck(); | |
113 | + } | |
114 | + } | |
115 | + | |
86 | 116 | /* (non-Javadoc) |
87 | 117 | * @see com.mumfrey.liteloader.api.TickObserver#onTick(boolean, float, boolean) |
88 | 118 | */ |
... | ... | @@ -93,6 +123,20 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
93 | 123 | { |
94 | 124 | this.panelHost.updateScreen(); |
95 | 125 | } |
126 | + | |
127 | + if (clock && this.checkForUpdate) | |
128 | + { | |
129 | + LiteLoaderUpdateSite updateSite = LiteLoaderVersion.getUpdateSite(); | |
130 | + if (!updateSite.isCheckInProgress() && updateSite.isCheckComplete()) | |
131 | + { | |
132 | + LiteLoaderLogger.debug("Scheduled update check completed, success=%s", updateSite.isCheckSucceess()); | |
133 | + this.checkForUpdate = false; | |
134 | + if (updateSite.isCheckSucceess() && updateSite.isUpdateAvailable()) | |
135 | + { | |
136 | + this.setNotification(I18n.format("gui.notifications.updateavailable")); | |
137 | + } | |
138 | + } | |
139 | + } | |
96 | 140 | } |
97 | 141 | |
98 | 142 | /* (non-Javadoc) |
... | ... | @@ -103,14 +147,18 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
103 | 147 | { |
104 | 148 | if (this.mods == null) return; |
105 | 149 | |
106 | - boolean tabHidden = this.hideModInfoScreenTab && this.minecraft.currentScreen instanceof GuiMainMenu; | |
150 | + boolean tabHidden = this.isTabHidden() && this.minecraft.currentScreen instanceof GuiMainMenu; | |
107 | 151 | |
108 | 152 | if (this.isPanelSupportedOnScreen(this.minecraft.currentScreen) && ((this.displayModInfoScreenTab && !tabHidden) || (this.panelHost != null && this.panelHost.isOpen()))) |
109 | 153 | { |
110 | 154 | // If we're at the main menu, prepare the overlay |
111 | 155 | if (this.panelHost == null || this.panelHost.getScreen() != this.minecraft.currentScreen) |
112 | 156 | { |
113 | - this.panelHost = new GuiLiteLoaderPanel(this.minecraft, this.minecraft.currentScreen, this.mods, this.environment, this.configManager, !tabHidden); | |
157 | + this.panelHost = new GuiLiteLoaderPanel(this.minecraft, this.minecraft.currentScreen, this.mods, this.environment, this.properties, this.configManager, !tabHidden); | |
158 | + if (this.notification != null) | |
159 | + { | |
160 | + this.panelHost.setNotification(this.notification); | |
161 | + } | |
114 | 162 | } |
115 | 163 | |
116 | 164 | this.minecraft.entityRenderer.setupOverlayRendering(); |
... | ... | @@ -127,7 +175,7 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
127 | 175 | this.displayLiteLoaderPanel(this.minecraft.currentScreen); |
128 | 176 | } |
129 | 177 | } |
130 | - | |
178 | + | |
131 | 179 | /** |
132 | 180 | * Set the "mod info" screen tab to hidden, regardless of the property setting |
133 | 181 | */ |
... | ... | @@ -137,6 +185,11 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
137 | 185 | this.hideModInfoScreenTab = true; |
138 | 186 | } |
139 | 187 | |
188 | + private boolean isTabHidden() | |
189 | + { | |
190 | + return this.hideModInfoScreenTab && this.getStartupErrorCount() == 0 && this.notification == null; | |
191 | + } | |
192 | + | |
140 | 193 | /** |
141 | 194 | * Set whether the "mod info" screen tab should be shown in the main menu |
142 | 195 | */ |
... | ... | @@ -144,7 +197,7 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
144 | 197 | public void setTabVisible(boolean show) |
145 | 198 | { |
146 | 199 | this.displayModInfoScreenTab = show; |
147 | - this.properties.setBooleanProperty(LiteLoaderPanelManager.OPTION_MOD_INFO_SCREEN, show); | |
200 | + this.properties.setBooleanProperty(LoaderProperties.OPTION_MOD_INFO_SCREEN, show); | |
148 | 201 | this.properties.writeProperties(); |
149 | 202 | } |
150 | 203 | |
... | ... | @@ -161,7 +214,7 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
161 | 214 | public void setTabAlwaysExpanded(boolean expand) |
162 | 215 | { |
163 | 216 | this.tabAlwaysExpanded = expand; |
164 | - this.properties.setBooleanProperty(LiteLoaderPanelManager.OPTION_NO_HIDE_TAB, expand); | |
217 | + this.properties.setBooleanProperty(LoaderProperties.OPTION_NO_HIDE_TAB, expand); | |
165 | 218 | this.properties.writeProperties(); |
166 | 219 | } |
167 | 220 | |
... | ... | @@ -171,6 +224,19 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
171 | 224 | return this.tabAlwaysExpanded; |
172 | 225 | } |
173 | 226 | |
227 | + @Override | |
228 | + public void setForceUpdateEnabled(boolean forceUpdate) | |
229 | + { | |
230 | + this.properties.setBooleanProperty(LoaderProperties.OPTION_FORCE_UPDATE, forceUpdate); | |
231 | + this.properties.writeProperties(); | |
232 | + } | |
233 | + | |
234 | + @Override | |
235 | + public boolean isForceUpdateEnabled() | |
236 | + { | |
237 | + return this.properties.getBooleanProperty(LoaderProperties.OPTION_FORCE_UPDATE); | |
238 | + } | |
239 | + | |
174 | 240 | /** |
175 | 241 | * Display the liteloader panel over the specified GUI |
176 | 242 | * |
... | ... | @@ -181,7 +247,7 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
181 | 247 | { |
182 | 248 | if (this.isPanelSupportedOnScreen(parentScreen)) |
183 | 249 | { |
184 | - this.panelHost = new GuiLiteLoaderPanel(this.minecraft, parentScreen, this.mods, this.environment, this.configManager, !this.hideModInfoScreenTab); | |
250 | + this.panelHost = new GuiLiteLoaderPanel(this.minecraft, parentScreen, this.mods, this.environment, this.properties, this.configManager, !this.isTabHidden()); | |
185 | 251 | this.minecraft.displayGuiScreen(this.panelHost); |
186 | 252 | } |
187 | 253 | } |
... | ... | @@ -198,6 +264,18 @@ public class LiteLoaderPanelManager implements PanelManager<GuiScreen> |
198 | 264 | return this.mods.getCriticalErrorCount(); |
199 | 265 | } |
200 | 266 | |
267 | + @Override | |
268 | + public void setNotification(String notification) | |
269 | + { | |
270 | + LiteLoaderLogger.debug("Setting notification: " + notification); | |
271 | + this.notification = notification; | |
272 | + | |
273 | + if (this.panelHost != null) | |
274 | + { | |
275 | + this.panelHost.setNotification(notification); | |
276 | + } | |
277 | + } | |
278 | + | |
201 | 279 | private boolean isPanelSupportedOnScreen(GuiScreen guiScreen) |
202 | 280 | { |
203 | 281 | return ( | ... | ... |
java/client/com/mumfrey/liteloader/client/gen/GenProfilerTransformer.java
... | ... | @@ -77,7 +77,7 @@ public class GenProfilerTransformer implements IClassTransformer |
77 | 77 | |
78 | 78 | for (Entry<MethodInsnNode, String> node : injectionNodes.entrySet()) |
79 | 79 | { |
80 | - method.instructions.insert(node.getKey(), new MethodInsnNode(Opcodes.INVOKESTATIC, "com/mumfrey/liteloader/core/gen/GenProfiler", "storeSignature", "(Ljava/lang/String;)V")); | |
80 | + method.instructions.insert(node.getKey(), new MethodInsnNode(Opcodes.INVOKESTATIC, "com/mumfrey/liteloader/core/gen/GenProfiler", "storeSignature", "(Ljava/lang/String;)V", false)); | |
81 | 81 | method.instructions.insert(node.getKey(), new LdcInsnNode(node.getValue())); |
82 | 82 | } |
83 | 83 | } | ... | ... |
java/client/com/mumfrey/liteloader/client/gui/GuiLiteLoaderPanel.java
... | ... | @@ -31,6 +31,7 @@ import com.mumfrey.liteloader.core.LiteLoaderMods; |
31 | 31 | import com.mumfrey.liteloader.core.ModInfo; |
32 | 32 | import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; |
33 | 33 | import com.mumfrey.liteloader.launch.LoaderEnvironment; |
34 | +import com.mumfrey.liteloader.launch.LoaderProperties; | |
34 | 35 | import com.mumfrey.liteloader.modconfig.ConfigManager; |
35 | 36 | import com.mumfrey.liteloader.modconfig.ConfigPanel; |
36 | 37 | |
... | ... | @@ -69,6 +70,11 @@ public class GuiLiteLoaderPanel extends GuiScreen |
69 | 70 | */ |
70 | 71 | private GuiScreen parentScreen; |
71 | 72 | |
73 | + @SuppressWarnings("unused") | |
74 | + private final LoaderEnvironment environment; | |
75 | + | |
76 | + private final LoaderProperties properties; | |
77 | + | |
72 | 78 | /** |
73 | 79 | * Tick number (update counter) used for tweening |
74 | 80 | */ |
... | ... | @@ -87,7 +93,7 @@ public class GuiLiteLoaderPanel extends GuiScreen |
87 | 93 | /** |
88 | 94 | * Since we don't get real mouse events we have to simulate them by tracking the mouse state |
89 | 95 | */ |
90 | - private boolean mouseDown, toggled; | |
96 | + private boolean mouseDown, toggled, toggleable; | |
91 | 97 | |
92 | 98 | /** |
93 | 99 | * Hover opacity for the tab |
... | ... | @@ -123,18 +129,25 @@ public class GuiLiteLoaderPanel extends GuiScreen |
123 | 129 | |
124 | 130 | private int startupErrorCount = 0, criticalErrorCount = 0; |
125 | 131 | |
132 | + private String notification; | |
133 | + | |
126 | 134 | /** |
127 | 135 | * @param minecraft |
128 | 136 | * @param parentScreen |
129 | 137 | * @param mods |
130 | 138 | */ |
131 | - public GuiLiteLoaderPanel(Minecraft minecraft, GuiScreen parentScreen, LiteLoaderMods mods, LoaderEnvironment environment, ConfigManager configManager, boolean showTab) | |
139 | + public GuiLiteLoaderPanel(Minecraft minecraft, GuiScreen parentScreen, LiteLoaderMods mods, LoaderEnvironment environment, LoaderProperties properties, ConfigManager configManager, boolean showTab) | |
132 | 140 | { |
133 | 141 | this.mc = minecraft; |
134 | 142 | this.fontRendererObj = minecraft.fontRendererObj; |
135 | 143 | this.parentScreen = parentScreen; |
136 | 144 | this.showTab = showTab; |
137 | 145 | |
146 | + this.environment = environment; | |
147 | + this.properties = properties; | |
148 | + | |
149 | + this.toggleable = true; | |
150 | + | |
138 | 151 | this.versionText = I18n.format("gui.about.versiontext", LiteLoader.getVersion()); |
139 | 152 | this.activeModText = I18n.format("gui.about.modsloaded", mods.getLoadedMods().size()); |
140 | 153 | |
... | ... | @@ -233,6 +246,16 @@ public class GuiLiteLoaderPanel extends GuiScreen |
233 | 246 | { |
234 | 247 | return this.tweenAmount > 0.0; |
235 | 248 | } |
249 | + | |
250 | + public void setToggleable(boolean toggleable) | |
251 | + { | |
252 | + this.toggleable = toggleable; | |
253 | + } | |
254 | + | |
255 | + public void setNotification(String notification) | |
256 | + { | |
257 | + this.notification = notification; | |
258 | + } | |
236 | 259 | |
237 | 260 | /* (non-Javadoc) |
238 | 261 | * @see net.minecraft.client.gui.GuiScreen#initGui() |
... | ... | @@ -247,7 +270,11 @@ public class GuiLiteLoaderPanel extends GuiScreen |
247 | 270 | this.currentPanel.setSize(this.width - LEFT_EDGE, this.height); |
248 | 271 | |
249 | 272 | this.buttonList.add(new GuiHoverLabel(2, LEFT_EDGE + MARGIN, this.height - PANEL_BOTTOM + 9, this.fontRendererObj, I18n.format("gui.about.taboptions"), this.brandColour)); |
250 | - this.buttonList.add(new GuiHoverLabel(3, LEFT_EDGE + MARGIN + 38 + this.fontRendererObj.getStringWidth(this.versionText) + 6, 50, this.fontRendererObj, I18n.format("gui.about.checkupdates"), this.brandColour)); | |
273 | + | |
274 | + if (LiteLoaderVersion.getUpdateSite().canCheckForUpdate() && this.mc.theWorld == null) | |
275 | + { | |
276 | + this.buttonList.add(new GuiHoverLabel(3, LEFT_EDGE + MARGIN + 38 + this.fontRendererObj.getStringWidth(this.versionText) + 6, 50, this.fontRendererObj, I18n.format("gui.about.checkupdates"), this.brandColour)); | |
277 | + } | |
251 | 278 | |
252 | 279 | Keyboard.enableRepeatEvents(true); |
253 | 280 | } |
... | ... | @@ -290,7 +317,7 @@ public class GuiLiteLoaderPanel extends GuiScreen |
290 | 317 | this.mc.currentScreen = this; |
291 | 318 | } |
292 | 319 | |
293 | - if (this.toggled) | |
320 | + if (this.toggled && this.toggleable) | |
294 | 321 | { |
295 | 322 | this.onToggled(); |
296 | 323 | } |
... | ... | @@ -338,7 +365,7 @@ public class GuiLiteLoaderPanel extends GuiScreen |
338 | 365 | this.handleMouseClick(offsetMouseX, mouseY, partialTicks, active, mouseOverTab); |
339 | 366 | |
340 | 367 | // Calculate the tab opacity, not framerate adjusted because we don't really care |
341 | - this.tabOpacity = mouseOverTab || alwaysExpandTab || this.startupErrorCount > 0 || this.isOpen() ? 0.5F : Math.max(0.0F, this.tabOpacity - partialTicks * 0.1F); | |
368 | + this.tabOpacity = mouseOverTab || alwaysExpandTab || this.startupErrorCount > 0 || this.notification != null || this.isOpen() ? 0.5F : Math.max(0.0F, this.tabOpacity - partialTicks * 0.1F); | |
342 | 369 | |
343 | 370 | // Draw the panel contents |
344 | 371 | this.drawPanel(offsetMouseX, mouseY, partialTicks, active, xOffset); |
... | ... | @@ -373,6 +400,10 @@ public class GuiLiteLoaderPanel extends GuiScreen |
373 | 400 | { |
374 | 401 | glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH + 7, TAB_TOP + 2, 12, 12, 134, 92, 134 + 12, 92 + 12, 0.5F + this.tabOpacity); |
375 | 402 | } |
403 | + else if (this.notification != null) | |
404 | + { | |
405 | + glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH + 7, TAB_TOP + 2, 12, 12, 134 + 12, 92, 134 + 24, 92 + 12, 0.5F + this.tabOpacity); | |
406 | + } | |
376 | 407 | } |
377 | 408 | else |
378 | 409 | { |
... | ... | @@ -448,25 +479,34 @@ public class GuiLiteLoaderPanel extends GuiScreen |
448 | 479 | |
449 | 480 | private void drawTooltips(int mouseX, int mouseY, float partialTicks, boolean active, float xOffset, boolean mouseOverTab) |
450 | 481 | { |
482 | + boolean annoyingTip = this.startupErrorCount > 0 || this.notification != null; | |
483 | + | |
451 | 484 | if (mouseOverTab && this.tweenAmount < 0.01) |
452 | 485 | { |
453 | 486 | GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, LiteLoader.getVersionDisplayString(), mouseX, mouseY, this.width, this.height, 0xFFFFFF, 0xB0000000); |
454 | 487 | GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, this.activeModText, mouseX, mouseY + 13, this.width, this.height, 0xCCCCCC, 0xB0000000); |
455 | 488 | |
456 | - if (this.startupErrorCount > 0) | |
489 | + if (annoyingTip) | |
457 | 490 | { |
458 | - this.drawErrorTooltip(mouseX, mouseY - 13); | |
491 | + this.drawNotificationTooltip(mouseX, mouseY - 13); | |
459 | 492 | } |
460 | 493 | } |
461 | - else if (GuiLiteLoaderPanel.displayErrorToolTip && this.startupErrorCount > 0 && !active && this.parentScreen instanceof GuiMainMenu) | |
494 | + else if (GuiLiteLoaderPanel.displayErrorToolTip && annoyingTip && !active && this.parentScreen instanceof GuiMainMenu) | |
462 | 495 | { |
463 | - this.drawErrorTooltip((int)xOffset + LEFT_EDGE - 12, TAB_TOP + 2); | |
496 | + this.drawNotificationTooltip((int)xOffset + LEFT_EDGE - 12, TAB_TOP + 2); | |
464 | 497 | } |
465 | 498 | } |
466 | 499 | |
467 | - private void drawErrorTooltip(int left, int top) | |
500 | + private void drawNotificationTooltip(int left, int top) | |
468 | 501 | { |
469 | - GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, I18n.format("gui.error.tooltip", this.startupErrorCount, this.criticalErrorCount), left, top, this.width, this.height, 0xFF5555, 0xB0330000); | |
502 | + if (this.startupErrorCount > 0) | |
503 | + { | |
504 | + GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, I18n.format("gui.error.tooltip", this.startupErrorCount, this.criticalErrorCount), left, top, this.width, this.height, 0xFF5555, 0xB0330000); | |
505 | + } | |
506 | + else if (this.notification != null) | |
507 | + { | |
508 | + GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, this.notification, left, top, this.width, this.height, 0xFFFFFF, 0xB0000099); | |
509 | + } | |
470 | 510 | } |
471 | 511 | |
472 | 512 | /* (non-Javadoc) |
... | ... | @@ -482,7 +522,7 @@ public class GuiLiteLoaderPanel extends GuiScreen |
482 | 522 | |
483 | 523 | if (button.id == 3) |
484 | 524 | { |
485 | - this.setCurrentPanel(new GuiPanelUpdateCheck(this.mc, LiteLoaderVersion.getUpdateSite(), "LiteLoader")); | |
525 | + this.setCurrentPanel(new GuiPanelUpdateCheck(this, this.mc, LiteLoaderVersion.getUpdateSite(), "LiteLoader", this.properties)); | |
486 | 526 | } |
487 | 527 | } |
488 | 528 | ... | ... |
java/client/com/mumfrey/liteloader/client/gui/GuiPanelSettings.java
... | ... | @@ -3,6 +3,7 @@ package com.mumfrey.liteloader.client.gui; |
3 | 3 | import org.lwjgl.input.Keyboard; |
4 | 4 | |
5 | 5 | import com.mumfrey.liteloader.core.LiteLoader; |
6 | +import com.mumfrey.liteloader.interfaces.PanelManager; | |
6 | 7 | |
7 | 8 | import net.minecraft.client.Minecraft; |
8 | 9 | import net.minecraft.client.gui.FontRenderer; |
... | ... | @@ -13,12 +14,11 @@ class GuiPanelSettings extends GuiPanel |
13 | 14 | { |
14 | 15 | private GuiLiteLoaderPanel parentScreen; |
15 | 16 | |
16 | - private GuiCheckbox chkShowTab; | |
17 | - private GuiCheckbox chkNoHide; | |
17 | + private GuiCheckbox chkShowTab, chkNoHide, chkForceUpdate; | |
18 | 18 | |
19 | 19 | private boolean hide; |
20 | 20 | |
21 | - private String[] helpText = new String[3]; | |
21 | + private String[] helpText = new String[5]; | |
22 | 22 | |
23 | 23 | GuiPanelSettings(GuiLiteLoaderPanel parentScreen, Minecraft minecraft) |
24 | 24 | { |
... | ... | @@ -29,6 +29,8 @@ class GuiPanelSettings extends GuiPanel |
29 | 29 | this.helpText[0] = I18n.format("gui.settings.showtab.help1"); |
30 | 30 | this.helpText[1] = I18n.format("gui.settings.showtab.help2"); |
31 | 31 | this.helpText[2] = I18n.format("gui.settings.notabhide.help1"); |
32 | + this.helpText[3] = I18n.format("gui.settings.forceupdate.help1"); | |
33 | + this.helpText[4] = I18n.format("gui.settings.forceupdate.help2"); | |
32 | 34 | } |
33 | 35 | |
34 | 36 | @Override |
... | ... | @@ -53,26 +55,32 @@ class GuiPanelSettings extends GuiPanel |
53 | 55 | this.controls.add(new GuiButton(-1, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, I18n.format("gui.done"))); |
54 | 56 | this.controls.add(this.chkShowTab = new GuiCheckbox(0, 34, 90, I18n.format("gui.settings.showtab.label"))); |
55 | 57 | this.controls.add(this.chkNoHide = new GuiCheckbox(1, 34, 128, I18n.format("gui.settings.notabhide.label"))); |
58 | + this.controls.add(this.chkForceUpdate = new GuiCheckbox(2, 34, 158, I18n.format("gui.settings.forceupdate.label"))); | |
56 | 59 | |
57 | 60 | this.updateCheckBoxes(); |
58 | 61 | } |
59 | 62 | |
60 | 63 | private void updateCheckBoxes() |
61 | 64 | { |
62 | - this.chkShowTab.checked = LiteLoader.getModPanelManager().isTabVisible(); | |
63 | - this.chkNoHide.checked = LiteLoader.getModPanelManager().isTabAlwaysExpanded(); | |
65 | + PanelManager<?> panelManager = LiteLoader.getModPanelManager(); | |
66 | + | |
67 | + this.chkShowTab.checked = panelManager.isTabVisible(); | |
68 | + this.chkNoHide.checked = panelManager.isTabAlwaysExpanded(); | |
69 | + this.chkForceUpdate.checked = panelManager.isForceUpdateEnabled(); | |
64 | 70 | } |
65 | 71 | |
66 | 72 | private void updateSettings() |
67 | 73 | { |
68 | - LiteLoader.getModPanelManager().setTabVisible(this.chkShowTab.checked); | |
69 | - LiteLoader.getModPanelManager().setTabAlwaysExpanded(this.chkNoHide.checked); | |
74 | + PanelManager<?> panelManager = LiteLoader.getModPanelManager(); | |
75 | + | |
76 | + panelManager.setTabVisible(this.chkShowTab.checked); | |
77 | + panelManager.setTabAlwaysExpanded(this.chkNoHide.checked); | |
78 | + panelManager.setForceUpdateEnabled(this.chkForceUpdate.checked); | |
70 | 79 | } |
71 | 80 | |
72 | 81 | @Override |
73 | 82 | void draw(int mouseX, int mouseY, float partialTicks) |
74 | 83 | { |
75 | - this.setSize(this.width, this.height); | |
76 | 84 | this.parentScreen.drawInfoPanel(mouseX, mouseY, partialTicks, 0, 38); |
77 | 85 | |
78 | 86 | FontRenderer fontRenderer = this.mc.fontRendererObj; |
... | ... | @@ -81,6 +89,8 @@ class GuiPanelSettings extends GuiPanel |
81 | 89 | fontRenderer.drawString(this.helpText[0], 50, 104, brandColour); |
82 | 90 | fontRenderer.drawString(this.helpText[1], 50, 114, brandColour); |
83 | 91 | fontRenderer.drawString(this.helpText[2], 50, 142, brandColour); |
92 | + fontRenderer.drawString(this.helpText[3], 50, 172, brandColour); | |
93 | + fontRenderer.drawString(this.helpText[4], 50, 182, brandColour); | |
84 | 94 | |
85 | 95 | super.draw(mouseX, mouseY, partialTicks); |
86 | 96 | } | ... | ... |
java/client/com/mumfrey/liteloader/client/gui/GuiPanelUpdateCheck.java
... | ... | @@ -2,15 +2,19 @@ package com.mumfrey.liteloader.client.gui; |
2 | 2 | |
3 | 3 | import java.net.URI; |
4 | 4 | |
5 | -import org.lwjgl.input.Keyboard; | |
6 | - | |
7 | -import com.mumfrey.liteloader.update.UpdateSite; | |
8 | - | |
9 | 5 | import net.minecraft.client.Minecraft; |
10 | 6 | import net.minecraft.client.gui.FontRenderer; |
11 | 7 | import net.minecraft.client.gui.GuiButton; |
8 | +import net.minecraft.client.gui.ScaledResolution; | |
12 | 9 | import net.minecraft.client.resources.I18n; |
13 | 10 | |
11 | +import org.lwjgl.input.Keyboard; | |
12 | + | |
13 | +import com.mumfrey.liteloader.core.LiteLoaderUpdateSite; | |
14 | +import com.mumfrey.liteloader.launch.ClassPathUtilities; | |
15 | +import com.mumfrey.liteloader.launch.LoaderProperties; | |
16 | +import com.mumfrey.liteloader.update.UpdateSite; | |
17 | + | |
14 | 18 | /** |
15 | 19 | * "Check for updates" panel which docks in the mod info screen |
16 | 20 | * |
... | ... | @@ -23,15 +27,17 @@ class GuiPanelUpdateCheck extends GuiPanel |
23 | 27 | */ |
24 | 28 | private static final URI DOWNLOAD_URI = URI.create("http://dl.liteloader.com"); |
25 | 29 | |
30 | + private final GuiLiteLoaderPanel parentScreen; | |
31 | + | |
26 | 32 | /** |
27 | 33 | * Update site to contact |
28 | 34 | */ |
29 | - private UpdateSite updateSite; | |
35 | + private final UpdateSite updateSite; | |
30 | 36 | |
31 | 37 | /** |
32 | 38 | * Panel title |
33 | 39 | */ |
34 | - private String panelTitle; | |
40 | + private final String panelTitle; | |
35 | 41 | |
36 | 42 | /** |
37 | 43 | * Buttons |
... | ... | @@ -43,12 +49,17 @@ class GuiPanelUpdateCheck extends GuiPanel |
43 | 49 | */ |
44 | 50 | private int throb; |
45 | 51 | |
46 | - public GuiPanelUpdateCheck(Minecraft minecraft, UpdateSite updateSite, String updateName) | |
52 | + private boolean canForceUpdate, updateForced; | |
53 | + | |
54 | + public GuiPanelUpdateCheck(GuiLiteLoaderPanel parentScreen, Minecraft minecraft, UpdateSite updateSite, String updateName, LoaderProperties properties) | |
47 | 55 | { |
48 | 56 | super(minecraft); |
49 | 57 | |
58 | + this.parentScreen = parentScreen; | |
50 | 59 | this.updateSite = updateSite; |
51 | 60 | this.panelTitle = I18n.format("gui.updates.title", updateName); |
61 | + | |
62 | + this.canForceUpdate = (updateSite instanceof LiteLoaderUpdateSite && ((LiteLoaderUpdateSite)updateSite).canForceUpdate(properties)); | |
52 | 63 | } |
53 | 64 | |
54 | 65 | @Override |
... | ... | @@ -56,9 +67,9 @@ class GuiPanelUpdateCheck extends GuiPanel |
56 | 67 | { |
57 | 68 | super.setSize(width, height); |
58 | 69 | |
59 | - this.controls.add(new GuiButton(0, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, I18n.format("gui.done"))); | |
70 | + this.controls.add(new GuiButton(0, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, this.updateForced ? I18n.format("gui.exitgame") : I18n.format("gui.done"))); | |
60 | 71 | this.controls.add(this.btnCheck = new GuiButton(1, MARGIN + 16, TOP + 16, 100, 20, I18n.format("gui.checknow"))); |
61 | - this.controls.add(this.btnDownload = new GuiButton(2, MARGIN + 16, TOP + 118, 100, 20, I18n.format("gui.downloadupdate"))); | |
72 | + this.controls.add(this.btnDownload = new GuiButton(2, MARGIN + 16, TOP + 118, 100, 20, this.canForceUpdate ? I18n.format("gui.forceupdate") : I18n.format("gui.downloadupdate"))); | |
62 | 73 | } |
63 | 74 | |
64 | 75 | @Override |
... | ... | @@ -73,7 +84,7 @@ class GuiPanelUpdateCheck extends GuiPanel |
73 | 84 | drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999); |
74 | 85 | drawRect(MARGIN, this.height - BOTTOM + 2, this.width - MARGIN, this.height - BOTTOM + 3, 0xFF999999); |
75 | 86 | |
76 | - this.btnCheck.enabled = !this.updateSite.isCheckInProgress(); | |
87 | + this.btnCheck.enabled = !this.updateForced && !this.updateSite.isCheckInProgress(); | |
77 | 88 | this.btnDownload.visible = false; |
78 | 89 | |
79 | 90 | if (this.updateSite.isCheckInProgress()) |
... | ... | @@ -92,10 +103,15 @@ class GuiPanelUpdateCheck extends GuiPanel |
92 | 103 | fontRenderer.drawString(I18n.format("gui.updates.available.title"), MARGIN + 18, TOP + 70, 0xFFFFFFFF); |
93 | 104 | if (this.updateSite.isUpdateAvailable()) |
94 | 105 | { |
95 | - this.btnDownload.visible = true; | |
106 | + this.btnDownload.visible = !this.updateForced; | |
96 | 107 | fontRenderer.drawString(I18n.format("gui.updates.available.newversion"), MARGIN + 18, TOP + 84, 0xFFFFFFFF); |
97 | 108 | fontRenderer.drawString(I18n.format("gui.updates.available.version", this.updateSite.getAvailableVersion()), MARGIN + 18, TOP + 94, 0xFFFFFFFF); |
98 | 109 | fontRenderer.drawString(I18n.format("gui.updates.available.date", this.updateSite.getAvailableVersionDate()), MARGIN + 18, TOP + 104, 0xFFFFFFFF); |
110 | + | |
111 | + if (this.updateForced) | |
112 | + { | |
113 | + fontRenderer.drawString(I18n.format("gui.updates.forced"), MARGIN + 18, TOP + 144, 0xFFFFAA00); | |
114 | + } | |
99 | 115 | } |
100 | 116 | else |
101 | 117 | { |
... | ... | @@ -110,6 +126,17 @@ class GuiPanelUpdateCheck extends GuiPanel |
110 | 126 | |
111 | 127 | super.draw(mouseX, mouseY, partialTicks); |
112 | 128 | } |
129 | + | |
130 | + @Override | |
131 | + public void close() | |
132 | + { | |
133 | + if (this.updateForced) | |
134 | + { | |
135 | + return; | |
136 | + } | |
137 | + | |
138 | + super.close(); | |
139 | + } | |
113 | 140 | |
114 | 141 | /** |
115 | 142 | * @param control |
... | ... | @@ -117,11 +144,31 @@ class GuiPanelUpdateCheck extends GuiPanel |
117 | 144 | @Override |
118 | 145 | void actionPerformed(GuiButton control) |
119 | 146 | { |
120 | - if (control.id == 0) this.close(); | |
147 | + if (control.id == 0) | |
148 | + { | |
149 | + if (this.updateForced) | |
150 | + { | |
151 | + ClassPathUtilities.terminateRuntime(0); | |
152 | + return; | |
153 | + } | |
154 | + | |
155 | + this.close(); | |
156 | + } | |
121 | 157 | if (control.id == 1) this.updateSite.beginUpdateCheck(); |
122 | 158 | if (control.id == 2) |
123 | 159 | { |
124 | - this.openURI(GuiPanelUpdateCheck.DOWNLOAD_URI); | |
160 | + if (this.canForceUpdate && ((LiteLoaderUpdateSite)this.updateSite).forceUpdate()) | |
161 | + { | |
162 | + this.updateForced = true; | |
163 | + this.parentScreen.setToggleable(false); | |
164 | + ScaledResolution sr = new ScaledResolution(this.mc, this.mc.displayWidth, this.mc.displayHeight); | |
165 | + this.parentScreen.setWorldAndResolution(this.mc, sr.getScaledWidth(), sr.getScaledHeight()); | |
166 | + } | |
167 | + else | |
168 | + { | |
169 | + this.openURI(GuiPanelUpdateCheck.DOWNLOAD_URI); | |
170 | + } | |
171 | + | |
125 | 172 | this.btnDownload.enabled = false; |
126 | 173 | } |
127 | 174 | } | ... | ... |
java/client/com/mumfrey/liteloader/client/transformers/CrashReportTransformer.java
... | ... | @@ -58,7 +58,7 @@ public class CrashReportTransformer extends ClassTransformer |
58 | 58 | { |
59 | 59 | InsnList code = new InsnList(); |
60 | 60 | code.add(new VarInsnNode(Opcodes.ALOAD, 1)); |
61 | - code.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "com/mumfrey/liteloader/core/LiteLoader", "populateCrashReport", "(Ljava/lang/Object;)V")); | |
61 | + code.add(new MethodInsnNode(Opcodes.INVOKESTATIC, "com/mumfrey/liteloader/core/LiteLoader", "populateCrashReport", "(Ljava/lang/Object;)V", false)); | |
62 | 62 | |
63 | 63 | ListIterator<AbstractInsnNode> insns = ctor.instructions.iterator(); |
64 | 64 | while (insns.hasNext()) | ... | ... |
java/client/com/mumfrey/liteloader/client/transformers/MinecraftOverlayTransformer.java
... | ... | @@ -66,8 +66,8 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer |
66 | 66 | LiteLoaderLogger.info("MinecraftOverlayTransformer found INIT injection point, this is good."); |
67 | 67 | found = true; |
68 | 68 | |
69 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftOverlayTransformer.LITELOADER_TWEAKER_CLASS, MinecraftOverlayTransformer.METHOD_INIT, "()V")); | |
70 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftOverlayTransformer.LITELOADER_TWEAKER_CLASS, MinecraftOverlayTransformer.METHOD_POSTINIT, "()V")); | |
69 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftOverlayTransformer.LITELOADER_TWEAKER_CLASS, MinecraftOverlayTransformer.METHOD_INIT, "()V", false)); | |
70 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, MinecraftOverlayTransformer.LITELOADER_TWEAKER_CLASS, MinecraftOverlayTransformer.METHOD_POSTINIT, "()V", false)); | |
71 | 71 | } |
72 | 72 | } |
73 | 73 | |
... | ... | @@ -78,11 +78,11 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer |
78 | 78 | LdcInsnNode ldcInsn = (LdcInsnNode)insn; |
79 | 79 | if ("textures/blocks".equals(ldcInsn.cst)) |
80 | 80 | { |
81 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.LoadingBar.ref, "initTextures", "()V")); | |
81 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.LoadingBar.ref, "initTextures", "()V", false)); | |
82 | 82 | } |
83 | 83 | } |
84 | 84 | |
85 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.LoadingBar.ref, "incrementProgress", "()V")); | |
85 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.LoadingBar.ref, "incrementProgress", "()V", false)); | |
86 | 86 | } |
87 | 87 | } |
88 | 88 | ... | ... |
java/common/com/mumfrey/liteloader/core/LiteLoader.java
... | ... | @@ -154,7 +154,7 @@ public final class LiteLoader |
154 | 154 | * Mod panel manager, deliberately raw |
155 | 155 | */ |
156 | 156 | @SuppressWarnings("rawtypes") |
157 | - private PanelManager modPanelManager; | |
157 | + private PanelManager panelManager; | |
158 | 158 | |
159 | 159 | /** |
160 | 160 | * Interface Manager |
... | ... | @@ -519,7 +519,7 @@ public final class LiteLoader |
519 | 519 | @SuppressWarnings({ "cast", "unchecked" }) |
520 | 520 | public static <T> PanelManager<T> getModPanelManager() |
521 | 521 | { |
522 | - return (PanelManager<T>)LiteLoader.instance.modPanelManager; | |
522 | + return (PanelManager<T>)LiteLoader.instance.panelManager; | |
523 | 523 | } |
524 | 524 | |
525 | 525 | /** |
... | ... | @@ -869,10 +869,10 @@ public final class LiteLoader |
869 | 869 | } |
870 | 870 | |
871 | 871 | // Get the mod panel manager |
872 | - this.modPanelManager = this.objectFactory.getModPanelManager(); | |
873 | - if (this.modPanelManager != null) | |
872 | + this.panelManager = this.objectFactory.getModPanelManager(); | |
873 | + if (this.panelManager != null) | |
874 | 874 | { |
875 | - this.modPanelManager.init(this.mods, this.configManager); | |
875 | + this.panelManager.init(this.mods, this.configManager); | |
876 | 876 | } |
877 | 877 | |
878 | 878 | // Create the interface manager |
... | ... | @@ -933,6 +933,11 @@ public final class LiteLoader |
933 | 933 | { |
934 | 934 | coreProvider.onStartupComplete(); |
935 | 935 | } |
936 | + | |
937 | + if (this.panelManager != null) | |
938 | + { | |
939 | + this.panelManager.onStartupComplete(); | |
940 | + } | |
936 | 941 | } |
937 | 942 | |
938 | 943 | /** |
... | ... | @@ -1043,7 +1048,7 @@ public final class LiteLoader |
1043 | 1048 | @Deprecated |
1044 | 1049 | public boolean getDisplayModInfoScreenTab() |
1045 | 1050 | { |
1046 | - return (this.modPanelManager != null) ? this.modPanelManager.isTabVisible() : false; | |
1051 | + return (this.panelManager != null) ? this.panelManager.isTabVisible() : false; | |
1047 | 1052 | } |
1048 | 1053 | |
1049 | 1054 | /** |
... | ... | @@ -1058,7 +1063,7 @@ public final class LiteLoader |
1058 | 1063 | public void displayModInfoScreen(Object parentScreen) |
1059 | 1064 | { |
1060 | 1065 | // Use implicit cast, because we want this to fail if the user tries to give us an invalid class |
1061 | - if (this.modPanelManager != null) this.modPanelManager.displayLiteLoaderPanel(parentScreen); | |
1066 | + if (this.panelManager != null) this.panelManager.displayLiteLoaderPanel(parentScreen); | |
1062 | 1067 | } |
1063 | 1068 | |
1064 | 1069 | /** | ... | ... |
java/common/com/mumfrey/liteloader/core/LiteLoaderBootstrap.java
... | ... | @@ -575,6 +575,26 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP |
575 | 575 | { |
576 | 576 | this.localProperties.setProperty(propertyName, String.valueOf(value)); |
577 | 577 | } |
578 | + | |
579 | + @Override | |
580 | + public int getAndStoreIntegerProperty(String propertyName, int defaultValue) | |
581 | + { | |
582 | + int result = LiteLoaderBootstrap.tryParseInt(this.localProperties.getProperty(propertyName, String.valueOf(defaultValue)), defaultValue); | |
583 | + this.localProperties.setProperty(propertyName, String.valueOf(result)); | |
584 | + return result; | |
585 | + } | |
586 | + | |
587 | + @Override | |
588 | + public int getIntegerProperty(String propertyName) | |
589 | + { | |
590 | + return LiteLoaderBootstrap.tryParseInt(this.localProperties.getProperty(propertyName, "0"), 0); | |
591 | + } | |
592 | + | |
593 | + @Override | |
594 | + public void setIntegerProperty(String propertyName, int value) | |
595 | + { | |
596 | + this.localProperties.setProperty(propertyName, String.valueOf(value)); | |
597 | + } | |
578 | 598 | |
579 | 599 | /** |
580 | 600 | * Store current revision for mod in the config file |
... | ... | @@ -692,4 +712,16 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP |
692 | 712 | { |
693 | 713 | return this.apiAdapter.getPacketTransformers(); |
694 | 714 | } |
715 | + | |
716 | + private static int tryParseInt(String string, int defaultValue) | |
717 | + { | |
718 | + try | |
719 | + { | |
720 | + return Integer.parseInt(string); | |
721 | + } | |
722 | + catch (NumberFormatException ex) | |
723 | + { | |
724 | + return defaultValue; | |
725 | + } | |
726 | + } | |
695 | 727 | } | ... | ... |
java/common/com/mumfrey/liteloader/core/LiteLoaderUpdateSite.java
0 → 100644
1 | +package com.mumfrey.liteloader.core; | |
2 | + | |
3 | +import java.io.File; | |
4 | +import java.io.FileOutputStream; | |
5 | +import java.io.IOException; | |
6 | +import java.io.InputStream; | |
7 | + | |
8 | +import net.minecraft.util.Util; | |
9 | +import net.minecraft.util.Util.EnumOS; | |
10 | + | |
11 | +import com.google.common.io.ByteStreams; | |
12 | +import com.google.common.io.Files; | |
13 | +import com.google.common.io.OutputSupplier; | |
14 | +import com.mumfrey.liteloader.launch.ClassPathUtilities; | |
15 | +import com.mumfrey.liteloader.launch.LoaderProperties; | |
16 | +import com.mumfrey.liteloader.update.UpdateSite; | |
17 | +import com.mumfrey.liteloader.util.log.LiteLoaderLogger; | |
18 | + | |
19 | +public class LiteLoaderUpdateSite extends UpdateSite | |
20 | +{ | |
21 | + private static final String UPDATE_SITE_URL = "http://dl.liteloader.com/versions/"; | |
22 | + private static final String UPDATE_SITE_VERSIONS_JSON = "versions.json"; | |
23 | + private static final String UPDATE_SITE_ARTEFACT_NAME = "com.mumfrey:liteloader"; | |
24 | + | |
25 | + private String mcVersion; | |
26 | + | |
27 | + private File mcDir; | |
28 | + private File jarFile = null; | |
29 | + | |
30 | + private boolean updateForced = false; | |
31 | + | |
32 | + public LiteLoaderUpdateSite(String targetVersion, long currentTimeStamp) | |
33 | + { | |
34 | + super(LiteLoaderUpdateSite.UPDATE_SITE_URL, LiteLoaderUpdateSite.UPDATE_SITE_VERSIONS_JSON, targetVersion, LiteLoaderUpdateSite.UPDATE_SITE_ARTEFACT_NAME, currentTimeStamp); | |
35 | + | |
36 | + this.mcVersion = targetVersion; | |
37 | + } | |
38 | + | |
39 | + public boolean canForceUpdate(LoaderProperties properties) | |
40 | + { | |
41 | + if (!properties.getAndStoreBooleanProperty(LoaderProperties.OPTION_FORCE_UPDATE, false)) | |
42 | + { | |
43 | + return false; | |
44 | + } | |
45 | + | |
46 | + // TODO Enable force update | |
47 | + if (this.hasJarFile()) return true; | |
48 | + return this.findJarFile(); | |
49 | + } | |
50 | + | |
51 | + /** | |
52 | + * @return | |
53 | + */ | |
54 | + private boolean findJarFile() | |
55 | + { | |
56 | + // Find the jar containing liteloader | |
57 | + File jarFile = ClassPathUtilities.getPathToResource(LiteLoader.class, "/" + LiteLoader.class.getName().replace('.', '/') + ".class"); | |
58 | + if (!jarFile.isFile()) return false; | |
59 | + | |
60 | + // Validate that the jar is in the expected name and location | |
61 | + this.mcDir = this.walkAndValidateParents(jarFile, "liteloader-" + this.mcVersion + ".jar", this.mcVersion, "liteloader", "mumfrey", "com", "libraries"); | |
62 | + if (this.mcDir == null) return false; | |
63 | + | |
64 | + // Check that the jar we found is actually on the current classpath | |
65 | + if (!ClassPathUtilities.isJarOnClassPath(jarFile)) return false; | |
66 | + this.jarFile = jarFile; | |
67 | + return true; | |
68 | + } | |
69 | + | |
70 | + private File walkAndValidateParents(File file, String... breadcrumbs) | |
71 | + { | |
72 | + try | |
73 | + { | |
74 | + for (String breadcrumb : breadcrumbs) | |
75 | + { | |
76 | + if (file == null || !file.exists() || !file.getName().equals(breadcrumb)) return null; | |
77 | + file = file.getParentFile(); | |
78 | + } | |
79 | + | |
80 | + return file; | |
81 | + } | |
82 | + catch (Exception ex) | |
83 | + { | |
84 | + ex.printStackTrace(); | |
85 | + } | |
86 | + | |
87 | + return null; | |
88 | + } | |
89 | + | |
90 | + | |
91 | + public boolean canCheckForUpdate() | |
92 | + { | |
93 | + return !this.updateForced; | |
94 | + } | |
95 | + | |
96 | + public boolean hasJarFile() | |
97 | + { | |
98 | + return this.jarFile != null; | |
99 | + } | |
100 | + | |
101 | + public File getJarFile() | |
102 | + { | |
103 | + return this.jarFile; | |
104 | + } | |
105 | + | |
106 | + public boolean forceUpdate() | |
107 | + { | |
108 | + if (this.jarFile != null) | |
109 | + { | |
110 | + LiteLoaderLogger.info("Attempting to force update, extracting jar assassin..."); | |
111 | + | |
112 | + // TODO Enable force update | |
113 | + File jarAssassinOutput = new File(this.jarFile.getParentFile(), "liteloader-update-agent.jar"); | |
114 | + | |
115 | + if (!LiteLoaderUpdateSite.extractFile("/update/liteloader-update-agent.jar", jarAssassinOutput) || !jarAssassinOutput.isFile()) | |
116 | + { | |
117 | + LiteLoaderLogger.info("Couldn't extract jarassassin jar, can't force update"); | |
118 | + return false; | |
119 | + } | |
120 | + | |
121 | + File joptSimple = new File(this.mcDir, "libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar"); | |
122 | + | |
123 | + ProcessBuilder jarAssassinProcBuilder = new ProcessBuilder( | |
124 | + LiteLoaderUpdateSite.getJavaExecutable().getAbsolutePath(), | |
125 | + "-cp", joptSimple.getAbsolutePath(), | |
126 | + "-jar", jarAssassinOutput.getAbsolutePath(), | |
127 | + "--jarFile", this.jarFile.getAbsolutePath()).directory(this.jarFile.getParentFile()); | |
128 | + try | |
129 | + { | |
130 | + System.err.println(jarAssassinProcBuilder.command()); | |
131 | + | |
132 | + @SuppressWarnings("unused") | |
133 | + Process jarAssassin = jarAssassinProcBuilder.start(); | |
134 | + | |
135 | + ClassPathUtilities.deleteClassPathJar(this.jarFile.getAbsolutePath()); | |
136 | + | |
137 | + return true; | |
138 | + } | |
139 | + catch (Throwable th) | |
140 | + { | |
141 | + LiteLoaderLogger.info("Couldn't execute jarassassin jar, can't force update"); | |
142 | + return false; | |
143 | + } | |
144 | + } | |
145 | + | |
146 | + return false; | |
147 | + } | |
148 | + | |
149 | + protected static boolean extractFile(String resourceName, File outputFile) | |
150 | + { | |
151 | + try | |
152 | + { | |
153 | + final InputStream inputStream = LiteLoaderUpdateSite.class.getResourceAsStream(resourceName); | |
154 | + final OutputSupplier<FileOutputStream> outputSupplier = Files.newOutputStreamSupplier(outputFile); | |
155 | + ByteStreams.copy(inputStream, outputSupplier); | |
156 | + } | |
157 | + catch (NullPointerException ex) | |
158 | + { | |
159 | + return false; | |
160 | + } | |
161 | + catch (IOException ex) | |
162 | + { | |
163 | + return false; | |
164 | + } | |
165 | + | |
166 | + return true; | |
167 | + } | |
168 | + | |
169 | + protected static File getJavaExecutable() | |
170 | + { | |
171 | + File javaBin = new File(new File(System.getProperty("java.home")), "bin"); | |
172 | + File javaWin = new File(javaBin, "javaw.exe"); | |
173 | + | |
174 | + return Util.getOSType() == EnumOS.WINDOWS && javaWin.isFile() ? javaWin : new File(javaBin, "java"); | |
175 | + } | |
176 | +} | ... | ... |
java/common/com/mumfrey/liteloader/core/LiteLoaderVersion.java
... | ... | @@ -3,8 +3,6 @@ package com.mumfrey.liteloader.core; |
3 | 3 | import java.util.HashSet; |
4 | 4 | import java.util.Set; |
5 | 5 | |
6 | -import com.mumfrey.liteloader.update.UpdateSite; | |
7 | - | |
8 | 6 | /** |
9 | 7 | * LiteLoader version table |
10 | 8 | * |
... | ... | @@ -46,11 +44,7 @@ public enum LiteLoaderVersion |
46 | 44 | */ |
47 | 45 | public static final LiteLoaderVersion CURRENT = LiteLoaderVersion.MC_1_7_10_R4; |
48 | 46 | |
49 | - private static final String UPDATE_SITE_URL = "http://dl.liteloader.com/versions/"; | |
50 | - private static final String UPDATE_SITE_VERSIONS_JSON = "versions.json"; | |
51 | - private static final String UPDATE_SITE_ARTEFACT_NAME = "com.mumfrey:liteloader"; | |
52 | - | |
53 | - private static final UpdateSite updateSite = new UpdateSite(UPDATE_SITE_URL, UPDATE_SITE_VERSIONS_JSON, LiteLoaderVersion.CURRENT.getMinecraftVersion(), LiteLoaderVersion.UPDATE_SITE_ARTEFACT_NAME, LiteLoaderVersion.CURRENT.getReleaseTimestamp()); | |
47 | + private static final LiteLoaderUpdateSite updateSite = new LiteLoaderUpdateSite(LiteLoaderVersion.CURRENT.getMinecraftVersion(), LiteLoaderVersion.CURRENT.getReleaseTimestamp()); | |
54 | 48 | |
55 | 49 | private final int revision; |
56 | 50 | |
... | ... | @@ -131,7 +125,7 @@ public enum LiteLoaderVersion |
131 | 125 | return this.loaderVersion; |
132 | 126 | } |
133 | 127 | |
134 | - public static UpdateSite getUpdateSite() | |
128 | + public static LiteLoaderUpdateSite getUpdateSite() | |
135 | 129 | { |
136 | 130 | return LiteLoaderVersion.updateSite; |
137 | 131 | } | ... | ... |
java/common/com/mumfrey/liteloader/interfaces/PanelManager.java
... | ... | @@ -19,6 +19,11 @@ public interface PanelManager<TParentScreen> extends TickObserver, PostRenderObs |
19 | 19 | * @param configManager |
20 | 20 | */ |
21 | 21 | public abstract void init(LiteLoaderMods mods, ConfigManager configManager); |
22 | + | |
23 | + /** | |
24 | + * | |
25 | + */ | |
26 | + public abstract void onStartupComplete(); | |
22 | 27 | |
23 | 28 | /** |
24 | 29 | * |
... | ... | @@ -59,4 +64,19 @@ public interface PanelManager<TParentScreen> extends TickObserver, PostRenderObs |
59 | 64 | * @return |
60 | 65 | */ |
61 | 66 | public abstract int getCriticalErrorCount(); |
67 | + | |
68 | + /** | |
69 | + * @param notification | |
70 | + */ | |
71 | + public abstract void setNotification(String notification); | |
72 | + | |
73 | + /** | |
74 | + * @param forceUpdate | |
75 | + */ | |
76 | + public abstract void setForceUpdateEnabled(boolean forceUpdate); | |
77 | + | |
78 | + /** | |
79 | + * @return | |
80 | + */ | |
81 | + public abstract boolean isForceUpdateEnabled(); | |
62 | 82 | } | ... | ... |
java/common/com/mumfrey/liteloader/launch/ClassPathUtilities.java
... | ... | @@ -12,6 +12,7 @@ import java.security.AccessController; |
12 | 12 | import java.security.PrivilegedActionException; |
13 | 13 | import java.security.PrivilegedExceptionAction; |
14 | 14 | import java.util.ArrayList; |
15 | +import java.util.Iterator; | |
15 | 16 | import java.util.Map; |
16 | 17 | import java.util.Map.Entry; |
17 | 18 | import java.util.Stack; |
... | ... | @@ -58,6 +59,8 @@ public abstract class ClassPathUtilities |
58 | 59 | |
59 | 60 | private static boolean canInject; |
60 | 61 | |
62 | + private static boolean canTerminate; | |
63 | + | |
61 | 64 | static |
62 | 65 | { |
63 | 66 | try |
... | ... | @@ -221,6 +224,33 @@ public abstract class ClassPathUtilities |
221 | 224 | catch (Exception ex) {} |
222 | 225 | } |
223 | 226 | } |
227 | + | |
228 | + /** | |
229 | + * Is the specified jar on the game launch classpath | |
230 | + * | |
231 | + * @param jarFile | |
232 | + * @return | |
233 | + */ | |
234 | + public static boolean isJarOnClassPath(File jarFile) | |
235 | + { | |
236 | + try | |
237 | + { | |
238 | + String jarURL = jarFile.toURI().toURL().toString(); | |
239 | + | |
240 | + URL[] classPath = ((URLClassLoader)Launch.class.getClassLoader()).getURLs(); | |
241 | + for (URL classPathEntry : classPath) | |
242 | + { | |
243 | + if (classPathEntry.toString().equals(jarURL)) | |
244 | + return true; | |
245 | + } | |
246 | + } | |
247 | + catch (Exception ex) | |
248 | + { | |
249 | + ex.printStackTrace(); | |
250 | + } | |
251 | + | |
252 | + return false; | |
253 | + } | |
224 | 254 | |
225 | 255 | /** |
226 | 256 | * Gets the file containing the specified resource |
... | ... | @@ -285,29 +315,20 @@ public abstract class ClassPathUtilities |
285 | 315 | |
286 | 316 | if (jar != null && parentJar != null && jar.getName().equals(parentJar.getName())) |
287 | 317 | { |
288 | - final JarFile jarInClassLoader = ClassPathUtilities.getJarFromClassLoader(Launch.classLoader, jarFileName, true); | |
289 | - final JarFile jarInParentClassLoader = ClassPathUtilities.getJarFromClassLoader((URLClassLoader)Launch.class.getClassLoader(), jarFileName, true); | |
318 | + final JarDeletionHandler jarDeletionHandler = new JarDeletionHandler(); | |
319 | + | |
320 | + JarFile jarInClassLoader = ClassPathUtilities.getJarFromClassLoader(Launch.classLoader, jarFileName, true); | |
321 | + JarFile jarInParentClassLoader = ClassPathUtilities.getJarFromClassLoader((URLClassLoader)Launch.class.getClassLoader(), jarFileName, true); | |
290 | 322 | |
291 | - final File jarFileInClassLoader = new File(jarInClassLoader.getName()); | |
292 | - final File jarFileInParentClassLoader = new File(jarInParentClassLoader.getName()); | |
323 | + File jarFileInClassLoader = new File(jarInClassLoader.getName()); | |
324 | + File jarFileInParentClassLoader = new File(jarInParentClassLoader.getName()); | |
325 | + | |
326 | + jarDeletionHandler.setPaths(jarInClassLoader, jarInParentClassLoader, jarFileInClassLoader, jarFileInParentClassLoader); | |
293 | 327 | |
294 | 328 | try |
295 | 329 | { |
296 | - Boolean deleted = AccessController.doPrivileged(new PrivilegedExceptionAction<Boolean>() | |
297 | - { | |
298 | - @Override | |
299 | - public Boolean run() throws Exception | |
300 | - { | |
301 | - jarInClassLoader.close(); | |
302 | - jarInParentClassLoader.close(); | |
303 | - | |
304 | - boolean deletedJarFile = jarFileInClassLoader.delete(); | |
305 | - boolean deletedParentJarFile = jarFileInParentClassLoader.delete(); | |
306 | - | |
307 | - return Boolean.valueOf(deletedJarFile || deletedParentJarFile); | |
308 | - } | |
309 | - }); | |
310 | - | |
330 | + Boolean deleted = AccessController.doPrivileged(jarDeletionHandler); | |
331 | + ClassPathUtilities.canTerminate |= deleted; | |
311 | 332 | return deleted; |
312 | 333 | } |
313 | 334 | catch (PrivilegedActionException ex) |
... | ... | @@ -323,6 +344,18 @@ public abstract class ClassPathUtilities |
323 | 344 | |
324 | 345 | return false; |
325 | 346 | } |
347 | + | |
348 | + public static void terminateRuntime(int status) | |
349 | + { | |
350 | + if (ClassPathUtilities.canTerminate) | |
351 | + { | |
352 | + System.exit(status); | |
353 | + } | |
354 | + else | |
355 | + { | |
356 | + throw new IllegalStateException(); | |
357 | + } | |
358 | + } | |
326 | 359 | |
327 | 360 | /** |
328 | 361 | * @param classLoader |
... | ... | @@ -341,8 +374,11 @@ public abstract class ClassPathUtilities |
341 | 374 | URLClassPath classPath = (URLClassPath)ClassPathUtilities.ucp.get(classLoader); |
342 | 375 | Map<String, ?> loaderMap = (Map<String, ?>)ClassPathUtilities.classPathLoaderMap.get(classPath); |
343 | 376 | |
344 | - for (Entry<String, ?> loaderEntry : loaderMap.entrySet()) | |
377 | + Iterator<?> iter = loaderMap.entrySet().iterator(); | |
378 | + while (iter.hasNext()) | |
345 | 379 | { |
380 | + Entry<String, ?> loaderEntry = (Entry<String, ?>)iter.next(); | |
381 | + | |
346 | 382 | String url = loaderEntry.getKey(); |
347 | 383 | |
348 | 384 | if (url.endsWith(fileName)) |
... | ... | @@ -362,7 +398,7 @@ public abstract class ClassPathUtilities |
362 | 398 | ArrayList<?> loaders = (ArrayList<?>)ClassPathUtilities.classPathLoaderList.get(classPath); |
363 | 399 | |
364 | 400 | loaders.remove(loader); |
365 | - loaderMap.remove(url); | |
401 | + iter.remove(); | |
366 | 402 | |
367 | 403 | URL jarURL = new URL(url); |
368 | 404 | urls.remove(jarURL); |
... | ... | @@ -382,3 +418,40 @@ public abstract class ClassPathUtilities |
382 | 418 | return jar; |
383 | 419 | } |
384 | 420 | } |
421 | + | |
422 | +class JarDeletionHandler implements PrivilegedExceptionAction<Boolean> | |
423 | +{ | |
424 | + JarFile jarInClassLoader, jarInParentClassLoader; | |
425 | + File jarFileInClassLoader, jarFileInParentClassLoader; | |
426 | + | |
427 | + void setPaths(JarFile jarInClassLoader, JarFile jarInParentClassLoader, File jarFileInClassLoader, File jarFileInParentClassLoader) | |
428 | + { | |
429 | + this.jarInClassLoader = jarInClassLoader; | |
430 | + this.jarInParentClassLoader = jarInParentClassLoader; | |
431 | + this.jarFileInClassLoader = jarFileInClassLoader; | |
432 | + this.jarFileInParentClassLoader = jarFileInParentClassLoader; | |
433 | + } | |
434 | + | |
435 | + @Override | |
436 | + public Boolean run() throws Exception | |
437 | + { | |
438 | + this.jarInClassLoader.close(); | |
439 | + this.jarInParentClassLoader.close(); | |
440 | + | |
441 | + try | |
442 | + { | |
443 | + Thread.sleep(5000); | |
444 | + } | |
445 | + catch (Exception ex) | |
446 | + { | |
447 | + ex.printStackTrace(); | |
448 | + } | |
449 | + | |
450 | + boolean deletedJarFile = this.jarFileInClassLoader.delete(); | |
451 | + boolean deletedParentJarFile = this.jarFileInParentClassLoader.delete(); | |
452 | + | |
453 | + System.err.println("deletedJarFile=" + deletedJarFile + " deletedParentJarFile=" + deletedParentJarFile); | |
454 | + | |
455 | + return Boolean.valueOf(deletedJarFile || deletedParentJarFile); | |
456 | + } | |
457 | +} | |
385 | 458 | \ No newline at end of file | ... | ... |
java/common/com/mumfrey/liteloader/launch/LiteLoaderTransformer.java
... | ... | @@ -40,7 +40,7 @@ public class LiteLoaderTransformer extends ClassTransformer |
40 | 40 | { |
41 | 41 | if ("main".equals(method.name)) |
42 | 42 | { |
43 | - method.instructions.insert(new MethodInsnNode(Opcodes.INVOKESTATIC, LiteLoaderTransformer.LITELOADER_TWEAKER_CLASS, LiteLoaderTransformer.METHOD_PRE_BEGIN_GAME, "()V")); | |
43 | + method.instructions.insert(new MethodInsnNode(Opcodes.INVOKESTATIC, LiteLoaderTransformer.LITELOADER_TWEAKER_CLASS, LiteLoaderTransformer.METHOD_PRE_BEGIN_GAME, "()V", false)); | |
44 | 44 | } |
45 | 45 | } |
46 | 46 | ... | ... |
java/common/com/mumfrey/liteloader/launch/LoaderProperties.java
... | ... | @@ -43,6 +43,31 @@ public interface LoaderProperties |
43 | 43 | public abstract boolean getAndStoreBooleanProperty(String propertyName, boolean defaultValue); |
44 | 44 | |
45 | 45 | /** |
46 | + * Set an integer property in the properties file | |
47 | + * | |
48 | + * @param propertyName | |
49 | + * @param value | |
50 | + */ | |
51 | + public abstract void setIntegerProperty(String propertyName, int value); | |
52 | + | |
53 | + /** | |
54 | + * Get an integer property from the properties file | |
55 | + * | |
56 | + * @param propertyName | |
57 | + * @return | |
58 | + */ | |
59 | + public abstract int getIntegerProperty(String propertyName); | |
60 | + | |
61 | + /** | |
62 | + * Get an integer property but write and return the supplied default value if the property doesn't exist | |
63 | + * | |
64 | + * @param propertyName | |
65 | + * @param defaultValue | |
66 | + * @return | |
67 | + */ | |
68 | + public abstract int getAndStoreIntegerProperty(String propertyName, int defaultValue); | |
69 | + | |
70 | + /** | |
46 | 71 | * Get a stored mod revision number from the properties file |
47 | 72 | * |
48 | 73 | * @param modKey |
... | ... | @@ -69,6 +94,8 @@ public interface LoaderProperties |
69 | 94 | public static final String OPTION_NO_HIDE_TAB = "tabAlwaysExpanded"; |
70 | 95 | public static final String OPTION_BRAND = "brand"; |
71 | 96 | public static final String OPTION_LOADING_BAR = "loadingbar"; |
97 | + public static final String OPTION_FORCE_UPDATE = "allowForceUpdate"; | |
98 | + public static final String OPTION_UPDATE_CHECK_INTR = "updateCheckInterval"; | |
72 | 99 | |
73 | 100 | // Enumerator properties |
74 | 101 | public static final String OPTION_SEARCH_MODS = "search.mods"; | ... | ... |
java/common/com/mumfrey/liteloader/launch/OperatingSystem.java
0 → 100644
java/common/com/mumfrey/liteloader/transformers/CallbackInjectionTransformer.java
... | ... | @@ -221,7 +221,7 @@ public abstract class CallbackInjectionTransformer extends ClassTransformer |
221 | 221 | private InsnList genProfilerCallbackInsns(InsnList injected, Callback callback, int refNumber) |
222 | 222 | { |
223 | 223 | injected.add(new LdcInsnNode(refNumber)); |
224 | - injected.add(new MethodInsnNode(Opcodes.INVOKESTATIC, callback.getCallbackClass(), callback.getCallbackMethod(), "(I)V")); | |
224 | + injected.add(new MethodInsnNode(Opcodes.INVOKESTATIC, callback.getCallbackClass(), callback.getCallbackMethod(), "(I)V", false)); | |
225 | 225 | |
226 | 226 | if (callback.getChainedCallbacks().size() > 0) |
227 | 227 | { |
... | ... | @@ -297,7 +297,7 @@ public abstract class CallbackInjectionTransformer extends ClassTransformer |
297 | 297 | String callbackMethodDesc = String.format("(%s%s%s%s)%s", hasReturnRef ? callbackReturnValueArg : "", hasReturnRef ? "I" : "", classInstanceArg, CallbackInjectionTransformer.getMethodArgs(methodNode), callbackReturnType); |
298 | 298 | |
299 | 299 | // Add the callback method insn to the injected instructions list |
300 | - injected.add(new MethodInsnNode(Opcodes.INVOKESTATIC, callback.getCallbackClass(), callback.getCallbackMethod(), callbackMethodDesc)); | |
300 | + injected.add(new MethodInsnNode(Opcodes.INVOKESTATIC, callback.getCallbackClass(), callback.getCallbackMethod(), callbackMethodDesc, false)); | |
301 | 301 | |
302 | 302 | // If the callback RETURNs a value then push the appropriate RETURN opcode into the insns list |
303 | 303 | if (callback.injectReturn()) | ... | ... |
java/common/com/mumfrey/liteloader/transformers/PacketTransformer.java
... | ... | @@ -190,7 +190,7 @@ public abstract class PacketTransformer extends ClassTransformer |
190 | 190 | insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); |
191 | 191 | |
192 | 192 | // Invoke the handler function with the args we just pushed onto the stack |
193 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, this.handlerClassName, this.handlerMethodName, targetMethodSig)); | |
193 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, this.handlerClassName, this.handlerMethodName, targetMethodSig, false)); | |
194 | 194 | |
195 | 195 | method.instructions.insert(method.instructions.getFirst(), insns); |
196 | 196 | } |
... | ... | @@ -217,7 +217,7 @@ public abstract class PacketTransformer extends ClassTransformer |
217 | 217 | method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); |
218 | 218 | |
219 | 219 | // Invoke the handler function with the args we just pushed onto the stack |
220 | - method.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, this.handlerClassName, this.handlerMethodName, targetMethodSig)); | |
220 | + method.instructions.add(new MethodInsnNode(Opcodes.INVOKESTATIC, this.handlerClassName, this.handlerMethodName, targetMethodSig, false)); | |
221 | 221 | |
222 | 222 | // Return if no exception |
223 | 223 | method.instructions.add(new InsnNode(Opcodes.RETURN)); | ... | ... |
java/common/com/mumfrey/liteloader/transformers/event/Event.java
... | ... | @@ -309,13 +309,13 @@ public class Event implements Comparable<Event> |
309 | 309 | insns.add(new LdcInsnNode(this.name)); ctorMAXS++; |
310 | 310 | insns.add(this.methodIsStatic ? new InsnNode(Opcodes.ACONST_NULL) : new VarInsnNode(Opcodes.ALOAD, 0)); ctorMAXS++; |
311 | 311 | insns.add(new InsnNode(cancellable ? Opcodes.ICONST_1 : Opcodes.ICONST_0)); ctorMAXS++; |
312 | - insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, this.eventInfoClass, Obf.constructor.name, EventInfo.getConstructorDescriptor())); | |
312 | + insns.add(new MethodInsnNode(Opcodes.INVOKESPECIAL, this.eventInfoClass, Obf.constructor.name, EventInfo.getConstructorDescriptor(), false)); | |
313 | 313 | insns.add(new VarInsnNode(Opcodes.ASTORE, eventInfoVar)); |
314 | 314 | |
315 | 315 | // Call the event handler method in the proxy |
316 | 316 | insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar)); |
317 | 317 | Event.pushArgs(argumentTypes, insns, this.methodIsStatic); |
318 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Event.getActiveProxyRef(), handler.name, handler.desc)); | |
318 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Event.getActiveProxyRef(), handler.name, handler.desc, false)); | |
319 | 319 | |
320 | 320 | if (cancellable) |
321 | 321 | { |
... | ... | @@ -340,7 +340,7 @@ public class Event implements Comparable<Event> |
340 | 340 | protected void injectCancellationCode(final InsnList insns, final AbstractInsnNode injectionPoint, int eventInfoVar) |
341 | 341 | { |
342 | 342 | insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar)); |
343 | - insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, this.eventInfoClass, EventInfo.getIsCancelledMethodName(), EventInfo.getIsCancelledMethodSig())); | |
343 | + insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, this.eventInfoClass, EventInfo.getIsCancelledMethodName(), EventInfo.getIsCancelledMethodSig(), false)); | |
344 | 344 | |
345 | 345 | LabelNode notCancelled = new LabelNode(); |
346 | 346 | insns.add(new JumpInsnNode(Opcodes.IFEQ, notCancelled)); |
... | ... | @@ -371,7 +371,7 @@ public class Event implements Comparable<Event> |
371 | 371 | insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar)); |
372 | 372 | String accessor = ReturnEventInfo.getReturnAccessor(this.methodReturnType); |
373 | 373 | String descriptor = ReturnEventInfo.getReturnDescriptor(this.methodReturnType); |
374 | - insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, this.eventInfoClass, accessor, descriptor)); | |
374 | + insns.add(new MethodInsnNode(Opcodes.INVOKEVIRTUAL, this.eventInfoClass, accessor, descriptor, false)); | |
375 | 375 | if (this.methodReturnType.getSort() == Type.OBJECT) |
376 | 376 | { |
377 | 377 | insns.add(new TypeInsnNode(Opcodes.CHECKCAST, this.methodReturnType.getInternalName())); |
... | ... | @@ -509,7 +509,7 @@ public class Event implements Comparable<Event> |
509 | 509 | insns.add(new LineNumberNode(++lineNumber, lineNumberLabel)); |
510 | 510 | |
511 | 511 | Event.pushArgs(args, insns, true); |
512 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, listener.ownerRef, listener.getOrInflectName(event.name), handlerMethod.desc)); | |
512 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, listener.ownerRef, listener.getOrInflectName(event.name), handlerMethod.desc, false)); | |
513 | 513 | } |
514 | 514 | |
515 | 515 | insns.add(tryCatchEnd); // } |
... | ... | @@ -517,12 +517,12 @@ public class Event implements Comparable<Event> |
517 | 517 | |
518 | 518 | insns.add(tryCatchHandler1); // catch (NoSuchMethodError err) { |
519 | 519 | insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); |
520 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.EventProxy.ref, "onMissingHandler", "(Ljava/lang/Error;Lcom/mumfrey/liteloader/transformers/event/EventInfo;)V")); | |
520 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.EventProxy.ref, "onMissingHandler", "(Ljava/lang/Error;Lcom/mumfrey/liteloader/transformers/event/EventInfo;)V", false)); | |
521 | 521 | insns.add(new JumpInsnNode(Opcodes.GOTO, tryCatchExit)); |
522 | 522 | |
523 | 523 | insns.add(tryCatchHandler2); // } catch (NoClassDefFoundError err) { |
524 | 524 | insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); |
525 | - insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.EventProxy.ref, "onMissingClass", "(Ljava/lang/Error;Lcom/mumfrey/liteloader/transformers/event/EventInfo;)V")); | |
525 | + insns.add(new MethodInsnNode(Opcodes.INVOKESTATIC, Obf.EventProxy.ref, "onMissingClass", "(Ljava/lang/Error;Lcom/mumfrey/liteloader/transformers/event/EventInfo;)V", false)); | |
526 | 526 | insns.add(new JumpInsnNode(Opcodes.GOTO, tryCatchExit)); |
527 | 527 | |
528 | 528 | insns.add(tryCatchExit); // } | ... | ... |
java/common/com/mumfrey/liteloader/update/UpdateSite.java
... | ... | @@ -139,6 +139,7 @@ public class UpdateSite implements Comparator<Long> |
139 | 139 | { |
140 | 140 | if (this.stringRetriever == null) |
141 | 141 | { |
142 | + LiteLoaderLogger.debug("Update site for %s is starting the update check", this.artefact); | |
142 | 143 | this.stringRetriever = new HttpStringRetriever(String.format("%s%s", this.updateSiteUrl, this.updateSiteJsonFileName)); |
143 | 144 | this.stringRetriever.start(); |
144 | 145 | } |
... | ... | @@ -231,10 +232,13 @@ public class UpdateSite implements Comparator<Long> |
231 | 232 | { |
232 | 233 | try |
233 | 234 | { |
235 | + LiteLoaderLogger.debug("Update site for %s is parsing the update response", this.artefact); | |
234 | 236 | this.parseData(this.stringRetriever.getString()); |
237 | + LiteLoaderLogger.debug("Update site for %s successfully parsed the update response", this.artefact); | |
235 | 238 | } |
236 | 239 | catch (Exception ex) |
237 | 240 | { |
241 | + LiteLoaderLogger.debug("Update site for %s failed parsing the update response: %s:%s", this.artefact, ex.getClass().getSimpleName(), ex.getMessage()); | |
238 | 242 | this.checkSuccess = false; |
239 | 243 | ex.printStackTrace(); |
240 | 244 | } | ... | ... |
lib/asm-debug-all-5.0.3.jar
0 → 100644
No preview for this file type
lib/launchwrapper-1.11.jar
0 → 100644
No preview for this file type
resources/assets/liteloader/lang/en_US.lang
... | ... | @@ -13,6 +13,9 @@ gui.settings.showtab.help1=If you disable this option, use CTRL+SHIFT+TAB |
13 | 13 | gui.settings.showtab.help2=to open the LiteLoader panel |
14 | 14 | gui.settings.notabhide.label=LiteLoader Tab Always Expanded |
15 | 15 | gui.settings.notabhide.help1=Only applies if the above option is also checked |
16 | +gui.settings.forceupdate.label=Periodically Check For Updates | |
17 | +gui.settings.forceupdate.help1=This option is §cexperimental§r and may not work properly | |
18 | +gui.settings.forceupdate.help2=yet, it also enables the "force update" capability. | |
16 | 19 | |
17 | 20 | gui.about.taboptions=§nLiteLoader Panel Options |
18 | 21 | |
... | ... | @@ -55,9 +58,13 @@ gui.updates.available.newversion=§aNew version available |
55 | 58 | gui.updates.available.version=Version: §a%s |
56 | 59 | gui.updates.available.date=Release date: §a%s |
57 | 60 | |
61 | +gui.updates.forced=Update forced, restart the game to apply update | |
62 | + | |
58 | 63 | gui.checknow=Check now |
59 | 64 | gui.installupdate=Install now |
60 | 65 | gui.downloadupdate=Download now |
66 | +gui.forceupdate=Force update | |
67 | +gui.exitgame=Exit Game | |
61 | 68 | |
62 | 69 | gui.log.button=LiteLoader Log |
63 | 70 | gui.log.title=LiteLoader Log Viewer |
... | ... | @@ -70,4 +77,6 @@ gui.log.closedialog=Close |
70 | 77 | |
71 | 78 | gui.error.title=Startup errors for %s |
72 | 79 | |
73 | -gui.error.tooltip=%d mod startup error(s) detected (%d critical) | |
74 | 80 | \ No newline at end of file |
81 | +gui.error.tooltip=%d mod startup error(s) detected (%d critical) | |
82 | + | |
83 | +gui.notifications.updateavailable=LiteLoader Update Available! | |
75 | 84 | \ No newline at end of file | ... | ... |