Commit faa26f42c4d95b314c6c9f24e70e6fb488b620f5

Authored by Mumfrey
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,15 +9,15 @@
9 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar"/> 9 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar"/>
10 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/com/google/guava/guava/15.0/guava-15.0.jar"/> 10 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/com/google/guava/guava/15.0/guava-15.0.jar"/>
11 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/commons-io/commons-io/2.4/commons-io-2.4.jar"/> 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 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar"/> 13 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar"/>
14 <classpathentry kind="lib" path="/Client/jars/libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar"/> 14 <classpathentry kind="lib" path="/Client/jars/libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar"/>
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"/> 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 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar"/> 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 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar"/> 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 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar"/> 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 <classpathentry exported="true" kind="lib" path="/Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.1/lwjgl-2.9.1.jar"/> 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 <classpathentry kind="output" path="bin"/> 22 <classpathentry kind="output" path="bin"/>
23 </classpath> 23 </classpath>
LiteLoader.iml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <libelement value="file:///Client/jars/libraries/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar" /> 4 <libelement value="file:///Client/jars/libraries/com/google/code/gson/gson/2.2.4/gson-2.2.4.jar" />
5 <libelement value="file:///Client/jars/libraries/com/google/guava/guava/15.0/guava-15.0.jar" /> 5 <libelement value="file:///Client/jars/libraries/com/google/guava/guava/15.0/guava-15.0.jar" />
6 <libelement value="file:///Client/jars/libraries/commons-io/commons-io/2.4/commons-io-2.4.jar" /> 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 <libelement value="jar://$MODULE_DIR$/lib/asm-debug-all-4.1.jar!/" /> 8 <libelement value="jar://$MODULE_DIR$/lib/asm-debug-all-4.1.jar!/" />
9 <libelement value="file:///Client/jars/libraries/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar" /> 9 <libelement value="file:///Client/jars/libraries/org/apache/commons/commons-lang3/3.1/commons-lang3-3.1.jar" />
10 <libelement value="file:///Client/jars/libraries/net/sf/jopt-simple/jopt-simple/4.5/jopt-simple-4.5.jar" /> 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,7 +12,7 @@
12 <libelement value="file:///Client/jars/libraries/org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar" /> 12 <libelement value="file:///Client/jars/libraries/org/apache/logging/log4j/log4j-api/2.0-beta9/log4j-api-2.0-beta9.jar" />
13 <libelement value="file:///Client/jars/libraries/org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar" /> 13 <libelement value="file:///Client/jars/libraries/org/apache/logging/log4j/log4j-core/2.0-beta9/log4j-core-2.0-beta9.jar" />
14 <libelement value="file:///Client/jars/libraries/net/java/jinput/jinput/2.0.5/jinput-2.0.5.jar" /> 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 <libelement value="file:///Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.1/lwjgl-2.9.1.jar" /> 16 <libelement value="file:///Client/jars/libraries/org/lwjgl/lwjgl/lwjgl/2.9.1/lwjgl-2.9.1.jar" />
17 <src_description expected_position="0"> 17 <src_description expected_position="0">
18 <src_folder value="file://$MODULE_DIR$/debug" expected_position="0" /> 18 <src_folder value="file://$MODULE_DIR$/debug" expected_position="0" />
@@ -34,9 +34,9 @@ @@ -34,9 +34,9 @@
34 <orderEntry type="module" module-name="Client" exported="" /> 34 <orderEntry type="module" module-name="Client" exported="" />
35 <orderEntry type="jdk" jdkName="JavaSE-1.6" jdkType="JavaSDK" /> 35 <orderEntry type="jdk" jdkName="JavaSE-1.6" jdkType="JavaSDK" />
36 <orderEntry type="module-library" exported=""> 36 <orderEntry type="module-library" exported="">
37 - <library name="launchwrapper-1.9.jar"> 37 + <library name="launchwrapper-1.11.jar">
38 <CLASSES> 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 </CLASSES> 40 </CLASSES>
41 <JAVADOC /> 41 <JAVADOC />
42 <SOURCES> 42 <SOURCES>
@@ -47,7 +47,7 @@ @@ -47,7 +47,7 @@
47 <orderEntry type="module-library" exported=""> 47 <orderEntry type="module-library" exported="">
48 <library> 48 <library>
49 <CLASSES> 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 </CLASSES> 51 </CLASSES>
52 <JAVADOC /> 52 <JAVADOC />
53 <SOURCES /> 53 <SOURCES />
debug/com/mumfrey/liteloader/debug/LoginManager.java
@@ -4,6 +4,7 @@ import java.io.File; @@ -4,6 +4,7 @@ import java.io.File;
4 import java.io.FileReader; 4 import java.io.FileReader;
5 import java.io.FileWriter; 5 import java.io.FileWriter;
6 import java.io.IOException; 6 import java.io.IOException;
  7 +import java.lang.reflect.Type;
7 import java.net.Proxy; 8 import java.net.Proxy;
8 import java.util.HashMap; 9 import java.util.HashMap;
9 import java.util.Map; 10 import java.util.Map;
@@ -14,12 +15,19 @@ import javax.swing.JOptionPane; @@ -14,12 +15,19 @@ import javax.swing.JOptionPane;
14 import com.google.common.base.Strings; 15 import com.google.common.base.Strings;
15 import com.google.gson.Gson; 16 import com.google.gson.Gson;
16 import com.google.gson.GsonBuilder; 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 import com.google.gson.annotations.SerializedName; 24 import com.google.gson.annotations.SerializedName;
18 import com.mojang.authlib.Agent; 25 import com.mojang.authlib.Agent;
19 import com.mojang.authlib.GameProfile; 26 import com.mojang.authlib.GameProfile;
20 import com.mojang.authlib.UserType; 27 import com.mojang.authlib.UserType;
21 import com.mojang.authlib.exceptions.AuthenticationException; 28 import com.mojang.authlib.exceptions.AuthenticationException;
22 import com.mojang.authlib.exceptions.InvalidCredentialsException; 29 import com.mojang.authlib.exceptions.InvalidCredentialsException;
  30 +import com.mojang.authlib.properties.Property;
23 import com.mojang.authlib.properties.PropertyMap; 31 import com.mojang.authlib.properties.PropertyMap;
24 import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService; 32 import com.mojang.authlib.yggdrasil.YggdrasilAuthenticationService;
25 import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication; 33 import com.mojang.authlib.yggdrasil.YggdrasilUserAuthentication;
@@ -315,9 +323,32 @@ public class LoginManager @@ -315,9 +323,32 @@ public class LoginManager
315 public String getUserProperties() 323 public String getUserProperties()
316 { 324 {
317 PropertyMap userProperties = this.authentication.getUserProperties(); 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 * Struct for Gson serialisation of authenticaion settings 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,16 +5,20 @@ import net.minecraft.client.gui.GuiIngameMenu;
5 import net.minecraft.client.gui.GuiMainMenu; 5 import net.minecraft.client.gui.GuiMainMenu;
6 import net.minecraft.client.gui.GuiOptions; 6 import net.minecraft.client.gui.GuiOptions;
7 import net.minecraft.client.gui.GuiScreen; 7 import net.minecraft.client.gui.GuiScreen;
  8 +import net.minecraft.client.resources.I18n;
8 9
9 import org.lwjgl.input.Keyboard; 10 import org.lwjgl.input.Keyboard;
10 11
11 import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel; 12 import com.mumfrey.liteloader.client.gui.GuiLiteLoaderPanel;
12 import com.mumfrey.liteloader.common.GameEngine; 13 import com.mumfrey.liteloader.common.GameEngine;
13 import com.mumfrey.liteloader.core.LiteLoaderMods; 14 import com.mumfrey.liteloader.core.LiteLoaderMods;
  15 +import com.mumfrey.liteloader.core.LiteLoaderUpdateSite;
  16 +import com.mumfrey.liteloader.core.LiteLoaderVersion;
14 import com.mumfrey.liteloader.interfaces.PanelManager; 17 import com.mumfrey.liteloader.interfaces.PanelManager;
15 import com.mumfrey.liteloader.launch.LoaderEnvironment; 18 import com.mumfrey.liteloader.launch.LoaderEnvironment;
16 import com.mumfrey.liteloader.launch.LoaderProperties; 19 import com.mumfrey.liteloader.launch.LoaderProperties;
17 import com.mumfrey.liteloader.modconfig.ConfigManager; 20 import com.mumfrey.liteloader.modconfig.ConfigManager;
  21 +import com.mumfrey.liteloader.util.log.LiteLoaderLogger;
18 22
19 /** 23 /**
20 * Observer which handles the display of the mod panel 24 * Observer which handles the display of the mod panel
@@ -23,9 +27,6 @@ import com.mumfrey.liteloader.modconfig.ConfigManager; @@ -23,9 +27,6 @@ import com.mumfrey.liteloader.modconfig.ConfigManager;
23 */ 27 */
24 public class LiteLoaderPanelManager implements PanelManager<GuiScreen> 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 private final LoaderEnvironment environment; 30 private final LoaderEnvironment environment;
30 31
31 /** 32 /**
@@ -54,6 +55,10 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -54,6 +55,10 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
54 * can temporarily disable the function without having to change the underlying property 55 * can temporarily disable the function without having to change the underlying property
55 */ 56 */
56 private boolean hideModInfoScreenTab = false; 57 private boolean hideModInfoScreenTab = false;
  58 +
  59 + private boolean checkForUpdate = false;
  60 +
  61 + private String notification;
57 62
58 /** 63 /**
59 * Active "mod info" screen, drawn as an overlay when in the main menu and made the active screen if 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&lt;GuiScreen&gt; @@ -72,8 +77,24 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
72 this.properties = properties; 77 this.properties = properties;
73 this.minecraft = ((GameEngine<Minecraft, ?>)engine).getClient(); 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 @Override 100 @Override
@@ -83,6 +104,15 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -83,6 +104,15 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
83 this.configManager = configManager; 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 /* (non-Javadoc) 116 /* (non-Javadoc)
87 * @see com.mumfrey.liteloader.api.TickObserver#onTick(boolean, float, boolean) 117 * @see com.mumfrey.liteloader.api.TickObserver#onTick(boolean, float, boolean)
88 */ 118 */
@@ -93,6 +123,20 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -93,6 +123,20 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
93 { 123 {
94 this.panelHost.updateScreen(); 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 /* (non-Javadoc) 142 /* (non-Javadoc)
@@ -103,14 +147,18 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -103,14 +147,18 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
103 { 147 {
104 if (this.mods == null) return; 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 if (this.isPanelSupportedOnScreen(this.minecraft.currentScreen) && ((this.displayModInfoScreenTab && !tabHidden) || (this.panelHost != null && this.panelHost.isOpen()))) 152 if (this.isPanelSupportedOnScreen(this.minecraft.currentScreen) && ((this.displayModInfoScreenTab && !tabHidden) || (this.panelHost != null && this.panelHost.isOpen())))
109 { 153 {
110 // If we're at the main menu, prepare the overlay 154 // If we're at the main menu, prepare the overlay
111 if (this.panelHost == null || this.panelHost.getScreen() != this.minecraft.currentScreen) 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 this.minecraft.entityRenderer.setupOverlayRendering(); 164 this.minecraft.entityRenderer.setupOverlayRendering();
@@ -127,7 +175,7 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -127,7 +175,7 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
127 this.displayLiteLoaderPanel(this.minecraft.currentScreen); 175 this.displayLiteLoaderPanel(this.minecraft.currentScreen);
128 } 176 }
129 } 177 }
130 - 178 +
131 /** 179 /**
132 * Set the "mod info" screen tab to hidden, regardless of the property setting 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&lt;GuiScreen&gt; @@ -137,6 +185,11 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
137 this.hideModInfoScreenTab = true; 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 * Set whether the "mod info" screen tab should be shown in the main menu 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&lt;GuiScreen&gt; @@ -144,7 +197,7 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
144 public void setTabVisible(boolean show) 197 public void setTabVisible(boolean show)
145 { 198 {
146 this.displayModInfoScreenTab = show; 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 this.properties.writeProperties(); 201 this.properties.writeProperties();
149 } 202 }
150 203
@@ -161,7 +214,7 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -161,7 +214,7 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
161 public void setTabAlwaysExpanded(boolean expand) 214 public void setTabAlwaysExpanded(boolean expand)
162 { 215 {
163 this.tabAlwaysExpanded = expand; 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 this.properties.writeProperties(); 218 this.properties.writeProperties();
166 } 219 }
167 220
@@ -171,6 +224,19 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -171,6 +224,19 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
171 return this.tabAlwaysExpanded; 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 * Display the liteloader panel over the specified GUI 241 * Display the liteloader panel over the specified GUI
176 * 242 *
@@ -181,7 +247,7 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -181,7 +247,7 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
181 { 247 {
182 if (this.isPanelSupportedOnScreen(parentScreen)) 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 this.minecraft.displayGuiScreen(this.panelHost); 251 this.minecraft.displayGuiScreen(this.panelHost);
186 } 252 }
187 } 253 }
@@ -198,6 +264,18 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt; @@ -198,6 +264,18 @@ public class LiteLoaderPanelManager implements PanelManager&lt;GuiScreen&gt;
198 return this.mods.getCriticalErrorCount(); 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 private boolean isPanelSupportedOnScreen(GuiScreen guiScreen) 279 private boolean isPanelSupportedOnScreen(GuiScreen guiScreen)
202 { 280 {
203 return ( 281 return (
java/client/com/mumfrey/liteloader/client/gen/GenProfilerTransformer.java
@@ -77,7 +77,7 @@ public class GenProfilerTransformer implements IClassTransformer @@ -77,7 +77,7 @@ public class GenProfilerTransformer implements IClassTransformer
77 77
78 for (Entry<MethodInsnNode, String> node : injectionNodes.entrySet()) 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 method.instructions.insert(node.getKey(), new LdcInsnNode(node.getValue())); 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,6 +31,7 @@ import com.mumfrey.liteloader.core.LiteLoaderMods;
31 import com.mumfrey.liteloader.core.ModInfo; 31 import com.mumfrey.liteloader.core.ModInfo;
32 import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI; 32 import com.mumfrey.liteloader.core.api.LiteLoaderCoreAPI;
33 import com.mumfrey.liteloader.launch.LoaderEnvironment; 33 import com.mumfrey.liteloader.launch.LoaderEnvironment;
  34 +import com.mumfrey.liteloader.launch.LoaderProperties;
34 import com.mumfrey.liteloader.modconfig.ConfigManager; 35 import com.mumfrey.liteloader.modconfig.ConfigManager;
35 import com.mumfrey.liteloader.modconfig.ConfigPanel; 36 import com.mumfrey.liteloader.modconfig.ConfigPanel;
36 37
@@ -69,6 +70,11 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -69,6 +70,11 @@ public class GuiLiteLoaderPanel extends GuiScreen
69 */ 70 */
70 private GuiScreen parentScreen; 71 private GuiScreen parentScreen;
71 72
  73 + @SuppressWarnings("unused")
  74 + private final LoaderEnvironment environment;
  75 +
  76 + private final LoaderProperties properties;
  77 +
72 /** 78 /**
73 * Tick number (update counter) used for tweening 79 * Tick number (update counter) used for tweening
74 */ 80 */
@@ -87,7 +93,7 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -87,7 +93,7 @@ public class GuiLiteLoaderPanel extends GuiScreen
87 /** 93 /**
88 * Since we don't get real mouse events we have to simulate them by tracking the mouse state 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 * Hover opacity for the tab 99 * Hover opacity for the tab
@@ -123,18 +129,25 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -123,18 +129,25 @@ public class GuiLiteLoaderPanel extends GuiScreen
123 129
124 private int startupErrorCount = 0, criticalErrorCount = 0; 130 private int startupErrorCount = 0, criticalErrorCount = 0;
125 131
  132 + private String notification;
  133 +
126 /** 134 /**
127 * @param minecraft 135 * @param minecraft
128 * @param parentScreen 136 * @param parentScreen
129 * @param mods 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 this.mc = minecraft; 141 this.mc = minecraft;
134 this.fontRendererObj = minecraft.fontRendererObj; 142 this.fontRendererObj = minecraft.fontRendererObj;
135 this.parentScreen = parentScreen; 143 this.parentScreen = parentScreen;
136 this.showTab = showTab; 144 this.showTab = showTab;
137 145
  146 + this.environment = environment;
  147 + this.properties = properties;
  148 +
  149 + this.toggleable = true;
  150 +
138 this.versionText = I18n.format("gui.about.versiontext", LiteLoader.getVersion()); 151 this.versionText = I18n.format("gui.about.versiontext", LiteLoader.getVersion());
139 this.activeModText = I18n.format("gui.about.modsloaded", mods.getLoadedMods().size()); 152 this.activeModText = I18n.format("gui.about.modsloaded", mods.getLoadedMods().size());
140 153
@@ -233,6 +246,16 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -233,6 +246,16 @@ public class GuiLiteLoaderPanel extends GuiScreen
233 { 246 {
234 return this.tweenAmount > 0.0; 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 /* (non-Javadoc) 260 /* (non-Javadoc)
238 * @see net.minecraft.client.gui.GuiScreen#initGui() 261 * @see net.minecraft.client.gui.GuiScreen#initGui()
@@ -247,7 +270,11 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -247,7 +270,11 @@ public class GuiLiteLoaderPanel extends GuiScreen
247 this.currentPanel.setSize(this.width - LEFT_EDGE, this.height); 270 this.currentPanel.setSize(this.width - LEFT_EDGE, this.height);
248 271
249 this.buttonList.add(new GuiHoverLabel(2, LEFT_EDGE + MARGIN, this.height - PANEL_BOTTOM + 9, this.fontRendererObj, I18n.format("gui.about.taboptions"), this.brandColour)); 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 Keyboard.enableRepeatEvents(true); 279 Keyboard.enableRepeatEvents(true);
253 } 280 }
@@ -290,7 +317,7 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -290,7 +317,7 @@ public class GuiLiteLoaderPanel extends GuiScreen
290 this.mc.currentScreen = this; 317 this.mc.currentScreen = this;
291 } 318 }
292 319
293 - if (this.toggled) 320 + if (this.toggled && this.toggleable)
294 { 321 {
295 this.onToggled(); 322 this.onToggled();
296 } 323 }
@@ -338,7 +365,7 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -338,7 +365,7 @@ public class GuiLiteLoaderPanel extends GuiScreen
338 this.handleMouseClick(offsetMouseX, mouseY, partialTicks, active, mouseOverTab); 365 this.handleMouseClick(offsetMouseX, mouseY, partialTicks, active, mouseOverTab);
339 366
340 // Calculate the tab opacity, not framerate adjusted because we don't really care 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 // Draw the panel contents 370 // Draw the panel contents
344 this.drawPanel(offsetMouseX, mouseY, partialTicks, active, xOffset); 371 this.drawPanel(offsetMouseX, mouseY, partialTicks, active, xOffset);
@@ -373,6 +400,10 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -373,6 +400,10 @@ public class GuiLiteLoaderPanel extends GuiScreen
373 { 400 {
374 glDrawTexturedRect(LEFT_EDGE - TAB_WIDTH + 7, TAB_TOP + 2, 12, 12, 134, 92, 134 + 12, 92 + 12, 0.5F + this.tabOpacity); 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 else 408 else
378 { 409 {
@@ -448,25 +479,34 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -448,25 +479,34 @@ public class GuiLiteLoaderPanel extends GuiScreen
448 479
449 private void drawTooltips(int mouseX, int mouseY, float partialTicks, boolean active, float xOffset, boolean mouseOverTab) 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 if (mouseOverTab && this.tweenAmount < 0.01) 484 if (mouseOverTab && this.tweenAmount < 0.01)
452 { 485 {
453 GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, LiteLoader.getVersionDisplayString(), mouseX, mouseY, this.width, this.height, 0xFFFFFF, 0xB0000000); 486 GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, LiteLoader.getVersionDisplayString(), mouseX, mouseY, this.width, this.height, 0xFFFFFF, 0xB0000000);
454 GuiLiteLoaderPanel.drawTooltip(this.fontRendererObj, this.activeModText, mouseX, mouseY + 13, this.width, this.height, 0xCCCCCC, 0xB0000000); 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 /* (non-Javadoc) 512 /* (non-Javadoc)
@@ -482,7 +522,7 @@ public class GuiLiteLoaderPanel extends GuiScreen @@ -482,7 +522,7 @@ public class GuiLiteLoaderPanel extends GuiScreen
482 522
483 if (button.id == 3) 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,6 +3,7 @@ package com.mumfrey.liteloader.client.gui;
3 import org.lwjgl.input.Keyboard; 3 import org.lwjgl.input.Keyboard;
4 4
5 import com.mumfrey.liteloader.core.LiteLoader; 5 import com.mumfrey.liteloader.core.LiteLoader;
  6 +import com.mumfrey.liteloader.interfaces.PanelManager;
6 7
7 import net.minecraft.client.Minecraft; 8 import net.minecraft.client.Minecraft;
8 import net.minecraft.client.gui.FontRenderer; 9 import net.minecraft.client.gui.FontRenderer;
@@ -13,12 +14,11 @@ class GuiPanelSettings extends GuiPanel @@ -13,12 +14,11 @@ class GuiPanelSettings extends GuiPanel
13 { 14 {
14 private GuiLiteLoaderPanel parentScreen; 15 private GuiLiteLoaderPanel parentScreen;
15 16
16 - private GuiCheckbox chkShowTab;  
17 - private GuiCheckbox chkNoHide; 17 + private GuiCheckbox chkShowTab, chkNoHide, chkForceUpdate;
18 18
19 private boolean hide; 19 private boolean hide;
20 20
21 - private String[] helpText = new String[3]; 21 + private String[] helpText = new String[5];
22 22
23 GuiPanelSettings(GuiLiteLoaderPanel parentScreen, Minecraft minecraft) 23 GuiPanelSettings(GuiLiteLoaderPanel parentScreen, Minecraft minecraft)
24 { 24 {
@@ -29,6 +29,8 @@ class GuiPanelSettings extends GuiPanel @@ -29,6 +29,8 @@ class GuiPanelSettings extends GuiPanel
29 this.helpText[0] = I18n.format("gui.settings.showtab.help1"); 29 this.helpText[0] = I18n.format("gui.settings.showtab.help1");
30 this.helpText[1] = I18n.format("gui.settings.showtab.help2"); 30 this.helpText[1] = I18n.format("gui.settings.showtab.help2");
31 this.helpText[2] = I18n.format("gui.settings.notabhide.help1"); 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 @Override 36 @Override
@@ -53,26 +55,32 @@ class GuiPanelSettings extends GuiPanel @@ -53,26 +55,32 @@ class GuiPanelSettings extends GuiPanel
53 this.controls.add(new GuiButton(-1, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, I18n.format("gui.done"))); 55 this.controls.add(new GuiButton(-1, this.width - 99 - MARGIN, this.height - BOTTOM + 9, 100, 20, I18n.format("gui.done")));
54 this.controls.add(this.chkShowTab = new GuiCheckbox(0, 34, 90, I18n.format("gui.settings.showtab.label"))); 56 this.controls.add(this.chkShowTab = new GuiCheckbox(0, 34, 90, I18n.format("gui.settings.showtab.label")));
55 this.controls.add(this.chkNoHide = new GuiCheckbox(1, 34, 128, I18n.format("gui.settings.notabhide.label"))); 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 this.updateCheckBoxes(); 60 this.updateCheckBoxes();
58 } 61 }
59 62
60 private void updateCheckBoxes() 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 private void updateSettings() 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 @Override 81 @Override
73 void draw(int mouseX, int mouseY, float partialTicks) 82 void draw(int mouseX, int mouseY, float partialTicks)
74 { 83 {
75 - this.setSize(this.width, this.height);  
76 this.parentScreen.drawInfoPanel(mouseX, mouseY, partialTicks, 0, 38); 84 this.parentScreen.drawInfoPanel(mouseX, mouseY, partialTicks, 0, 38);
77 85
78 FontRenderer fontRenderer = this.mc.fontRendererObj; 86 FontRenderer fontRenderer = this.mc.fontRendererObj;
@@ -81,6 +89,8 @@ class GuiPanelSettings extends GuiPanel @@ -81,6 +89,8 @@ class GuiPanelSettings extends GuiPanel
81 fontRenderer.drawString(this.helpText[0], 50, 104, brandColour); 89 fontRenderer.drawString(this.helpText[0], 50, 104, brandColour);
82 fontRenderer.drawString(this.helpText[1], 50, 114, brandColour); 90 fontRenderer.drawString(this.helpText[1], 50, 114, brandColour);
83 fontRenderer.drawString(this.helpText[2], 50, 142, brandColour); 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 super.draw(mouseX, mouseY, partialTicks); 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,15 +2,19 @@ package com.mumfrey.liteloader.client.gui;
2 2
3 import java.net.URI; 3 import java.net.URI;
4 4
5 -import org.lwjgl.input.Keyboard;  
6 -  
7 -import com.mumfrey.liteloader.update.UpdateSite;  
8 -  
9 import net.minecraft.client.Minecraft; 5 import net.minecraft.client.Minecraft;
10 import net.minecraft.client.gui.FontRenderer; 6 import net.minecraft.client.gui.FontRenderer;
11 import net.minecraft.client.gui.GuiButton; 7 import net.minecraft.client.gui.GuiButton;
  8 +import net.minecraft.client.gui.ScaledResolution;
12 import net.minecraft.client.resources.I18n; 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 * "Check for updates" panel which docks in the mod info screen 19 * "Check for updates" panel which docks in the mod info screen
16 * 20 *
@@ -23,15 +27,17 @@ class GuiPanelUpdateCheck extends GuiPanel @@ -23,15 +27,17 @@ class GuiPanelUpdateCheck extends GuiPanel
23 */ 27 */
24 private static final URI DOWNLOAD_URI = URI.create("http://dl.liteloader.com"); 28 private static final URI DOWNLOAD_URI = URI.create("http://dl.liteloader.com");
25 29
  30 + private final GuiLiteLoaderPanel parentScreen;
  31 +
26 /** 32 /**
27 * Update site to contact 33 * Update site to contact
28 */ 34 */
29 - private UpdateSite updateSite; 35 + private final UpdateSite updateSite;
30 36
31 /** 37 /**
32 * Panel title 38 * Panel title
33 */ 39 */
34 - private String panelTitle; 40 + private final String panelTitle;
35 41
36 /** 42 /**
37 * Buttons 43 * Buttons
@@ -43,12 +49,17 @@ class GuiPanelUpdateCheck extends GuiPanel @@ -43,12 +49,17 @@ class GuiPanelUpdateCheck extends GuiPanel
43 */ 49 */
44 private int throb; 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 super(minecraft); 56 super(minecraft);
49 57
  58 + this.parentScreen = parentScreen;
50 this.updateSite = updateSite; 59 this.updateSite = updateSite;
51 this.panelTitle = I18n.format("gui.updates.title", updateName); 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 @Override 65 @Override
@@ -56,9 +67,9 @@ class GuiPanelUpdateCheck extends GuiPanel @@ -56,9 +67,9 @@ class GuiPanelUpdateCheck extends GuiPanel
56 { 67 {
57 super.setSize(width, height); 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 this.controls.add(this.btnCheck = new GuiButton(1, MARGIN + 16, TOP + 16, 100, 20, I18n.format("gui.checknow"))); 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 @Override 75 @Override
@@ -73,7 +84,7 @@ class GuiPanelUpdateCheck extends GuiPanel @@ -73,7 +84,7 @@ class GuiPanelUpdateCheck extends GuiPanel
73 drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999); 84 drawRect(MARGIN, TOP - 4, this.width - MARGIN, TOP - 3, 0xFF999999);
74 drawRect(MARGIN, this.height - BOTTOM + 2, this.width - MARGIN, this.height - BOTTOM + 3, 0xFF999999); 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 this.btnDownload.visible = false; 88 this.btnDownload.visible = false;
78 89
79 if (this.updateSite.isCheckInProgress()) 90 if (this.updateSite.isCheckInProgress())
@@ -92,10 +103,15 @@ class GuiPanelUpdateCheck extends GuiPanel @@ -92,10 +103,15 @@ class GuiPanelUpdateCheck extends GuiPanel
92 fontRenderer.drawString(I18n.format("gui.updates.available.title"), MARGIN + 18, TOP + 70, 0xFFFFFFFF); 103 fontRenderer.drawString(I18n.format("gui.updates.available.title"), MARGIN + 18, TOP + 70, 0xFFFFFFFF);
93 if (this.updateSite.isUpdateAvailable()) 104 if (this.updateSite.isUpdateAvailable())
94 { 105 {
95 - this.btnDownload.visible = true; 106 + this.btnDownload.visible = !this.updateForced;
96 fontRenderer.drawString(I18n.format("gui.updates.available.newversion"), MARGIN + 18, TOP + 84, 0xFFFFFFFF); 107 fontRenderer.drawString(I18n.format("gui.updates.available.newversion"), MARGIN + 18, TOP + 84, 0xFFFFFFFF);
97 fontRenderer.drawString(I18n.format("gui.updates.available.version", this.updateSite.getAvailableVersion()), MARGIN + 18, TOP + 94, 0xFFFFFFFF); 108 fontRenderer.drawString(I18n.format("gui.updates.available.version", this.updateSite.getAvailableVersion()), MARGIN + 18, TOP + 94, 0xFFFFFFFF);
98 fontRenderer.drawString(I18n.format("gui.updates.available.date", this.updateSite.getAvailableVersionDate()), MARGIN + 18, TOP + 104, 0xFFFFFFFF); 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 else 116 else
101 { 117 {
@@ -110,6 +126,17 @@ class GuiPanelUpdateCheck extends GuiPanel @@ -110,6 +126,17 @@ class GuiPanelUpdateCheck extends GuiPanel
110 126
111 super.draw(mouseX, mouseY, partialTicks); 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 * @param control 142 * @param control
@@ -117,11 +144,31 @@ class GuiPanelUpdateCheck extends GuiPanel @@ -117,11 +144,31 @@ class GuiPanelUpdateCheck extends GuiPanel
117 @Override 144 @Override
118 void actionPerformed(GuiButton control) 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 if (control.id == 1) this.updateSite.beginUpdateCheck(); 157 if (control.id == 1) this.updateSite.beginUpdateCheck();
122 if (control.id == 2) 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 this.btnDownload.enabled = false; 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,7 +58,7 @@ public class CrashReportTransformer extends ClassTransformer
58 { 58 {
59 InsnList code = new InsnList(); 59 InsnList code = new InsnList();
60 code.add(new VarInsnNode(Opcodes.ALOAD, 1)); 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 ListIterator<AbstractInsnNode> insns = ctor.instructions.iterator(); 63 ListIterator<AbstractInsnNode> insns = ctor.instructions.iterator();
64 while (insns.hasNext()) 64 while (insns.hasNext())
java/client/com/mumfrey/liteloader/client/transformers/MinecraftOverlayTransformer.java
@@ -66,8 +66,8 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer @@ -66,8 +66,8 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer
66 LiteLoaderLogger.info("MinecraftOverlayTransformer found INIT injection point, this is good."); 66 LiteLoaderLogger.info("MinecraftOverlayTransformer found INIT injection point, this is good.");
67 found = true; 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,11 +78,11 @@ public class MinecraftOverlayTransformer extends ClassOverlayTransformer
78 LdcInsnNode ldcInsn = (LdcInsnNode)insn; 78 LdcInsnNode ldcInsn = (LdcInsnNode)insn;
79 if ("textures/blocks".equals(ldcInsn.cst)) 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,7 +154,7 @@ public final class LiteLoader
154 * Mod panel manager, deliberately raw 154 * Mod panel manager, deliberately raw
155 */ 155 */
156 @SuppressWarnings("rawtypes") 156 @SuppressWarnings("rawtypes")
157 - private PanelManager modPanelManager; 157 + private PanelManager panelManager;
158 158
159 /** 159 /**
160 * Interface Manager 160 * Interface Manager
@@ -519,7 +519,7 @@ public final class LiteLoader @@ -519,7 +519,7 @@ public final class LiteLoader
519 @SuppressWarnings({ "cast", "unchecked" }) 519 @SuppressWarnings({ "cast", "unchecked" })
520 public static <T> PanelManager<T> getModPanelManager() 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,10 +869,10 @@ public final class LiteLoader
869 } 869 }
870 870
871 // Get the mod panel manager 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 // Create the interface manager 878 // Create the interface manager
@@ -933,6 +933,11 @@ public final class LiteLoader @@ -933,6 +933,11 @@ public final class LiteLoader
933 { 933 {
934 coreProvider.onStartupComplete(); 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,7 +1048,7 @@ public final class LiteLoader
1043 @Deprecated 1048 @Deprecated
1044 public boolean getDisplayModInfoScreenTab() 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,7 +1063,7 @@ public final class LiteLoader
1058 public void displayModInfoScreen(Object parentScreen) 1063 public void displayModInfoScreen(Object parentScreen)
1059 { 1064 {
1060 // Use implicit cast, because we want this to fail if the user tries to give us an invalid class 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,6 +575,26 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP
575 { 575 {
576 this.localProperties.setProperty(propertyName, String.valueOf(value)); 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 * Store current revision for mod in the config file 600 * Store current revision for mod in the config file
@@ -692,4 +712,16 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP @@ -692,4 +712,16 @@ class LiteLoaderBootstrap implements LoaderBootstrap, LoaderEnvironment, LoaderP
692 { 712 {
693 return this.apiAdapter.getPacketTransformers(); 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,8 +3,6 @@ package com.mumfrey.liteloader.core;
3 import java.util.HashSet; 3 import java.util.HashSet;
4 import java.util.Set; 4 import java.util.Set;
5 5
6 -import com.mumfrey.liteloader.update.UpdateSite;  
7 -  
8 /** 6 /**
9 * LiteLoader version table 7 * LiteLoader version table
10 * 8 *
@@ -46,11 +44,7 @@ public enum LiteLoaderVersion @@ -46,11 +44,7 @@ public enum LiteLoaderVersion
46 */ 44 */
47 public static final LiteLoaderVersion CURRENT = LiteLoaderVersion.MC_1_7_10_R4; 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 private final int revision; 49 private final int revision;
56 50
@@ -131,7 +125,7 @@ public enum LiteLoaderVersion @@ -131,7 +125,7 @@ public enum LiteLoaderVersion
131 return this.loaderVersion; 125 return this.loaderVersion;
132 } 126 }
133 127
134 - public static UpdateSite getUpdateSite() 128 + public static LiteLoaderUpdateSite getUpdateSite()
135 { 129 {
136 return LiteLoaderVersion.updateSite; 130 return LiteLoaderVersion.updateSite;
137 } 131 }
java/common/com/mumfrey/liteloader/interfaces/PanelManager.java
@@ -19,6 +19,11 @@ public interface PanelManager&lt;TParentScreen&gt; extends TickObserver, PostRenderObs @@ -19,6 +19,11 @@ public interface PanelManager&lt;TParentScreen&gt; extends TickObserver, PostRenderObs
19 * @param configManager 19 * @param configManager
20 */ 20 */
21 public abstract void init(LiteLoaderMods mods, ConfigManager configManager); 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&lt;TParentScreen&gt; extends TickObserver, PostRenderObs @@ -59,4 +64,19 @@ public interface PanelManager&lt;TParentScreen&gt; extends TickObserver, PostRenderObs
59 * @return 64 * @return
60 */ 65 */
61 public abstract int getCriticalErrorCount(); 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,6 +12,7 @@ import java.security.AccessController;
12 import java.security.PrivilegedActionException; 12 import java.security.PrivilegedActionException;
13 import java.security.PrivilegedExceptionAction; 13 import java.security.PrivilegedExceptionAction;
14 import java.util.ArrayList; 14 import java.util.ArrayList;
  15 +import java.util.Iterator;
15 import java.util.Map; 16 import java.util.Map;
16 import java.util.Map.Entry; 17 import java.util.Map.Entry;
17 import java.util.Stack; 18 import java.util.Stack;
@@ -58,6 +59,8 @@ public abstract class ClassPathUtilities @@ -58,6 +59,8 @@ public abstract class ClassPathUtilities
58 59
59 private static boolean canInject; 60 private static boolean canInject;
60 61
  62 + private static boolean canTerminate;
  63 +
61 static 64 static
62 { 65 {
63 try 66 try
@@ -221,6 +224,33 @@ public abstract class ClassPathUtilities @@ -221,6 +224,33 @@ public abstract class ClassPathUtilities
221 catch (Exception ex) {} 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 * Gets the file containing the specified resource 256 * Gets the file containing the specified resource
@@ -285,29 +315,20 @@ public abstract class ClassPathUtilities @@ -285,29 +315,20 @@ public abstract class ClassPathUtilities
285 315
286 if (jar != null && parentJar != null && jar.getName().equals(parentJar.getName())) 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 try 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 return deleted; 332 return deleted;
312 } 333 }
313 catch (PrivilegedActionException ex) 334 catch (PrivilegedActionException ex)
@@ -323,6 +344,18 @@ public abstract class ClassPathUtilities @@ -323,6 +344,18 @@ public abstract class ClassPathUtilities
323 344
324 return false; 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 * @param classLoader 361 * @param classLoader
@@ -341,8 +374,11 @@ public abstract class ClassPathUtilities @@ -341,8 +374,11 @@ public abstract class ClassPathUtilities
341 URLClassPath classPath = (URLClassPath)ClassPathUtilities.ucp.get(classLoader); 374 URLClassPath classPath = (URLClassPath)ClassPathUtilities.ucp.get(classLoader);
342 Map<String, ?> loaderMap = (Map<String, ?>)ClassPathUtilities.classPathLoaderMap.get(classPath); 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 String url = loaderEntry.getKey(); 382 String url = loaderEntry.getKey();
347 383
348 if (url.endsWith(fileName)) 384 if (url.endsWith(fileName))
@@ -362,7 +398,7 @@ public abstract class ClassPathUtilities @@ -362,7 +398,7 @@ public abstract class ClassPathUtilities
362 ArrayList<?> loaders = (ArrayList<?>)ClassPathUtilities.classPathLoaderList.get(classPath); 398 ArrayList<?> loaders = (ArrayList<?>)ClassPathUtilities.classPathLoaderList.get(classPath);
363 399
364 loaders.remove(loader); 400 loaders.remove(loader);
365 - loaderMap.remove(url); 401 + iter.remove();
366 402
367 URL jarURL = new URL(url); 403 URL jarURL = new URL(url);
368 urls.remove(jarURL); 404 urls.remove(jarURL);
@@ -382,3 +418,40 @@ public abstract class ClassPathUtilities @@ -382,3 +418,40 @@ public abstract class ClassPathUtilities
382 return jar; 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 \ No newline at end of file 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,7 +40,7 @@ public class LiteLoaderTransformer extends ClassTransformer
40 { 40 {
41 if ("main".equals(method.name)) 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,6 +43,31 @@ public interface LoaderProperties
43 public abstract boolean getAndStoreBooleanProperty(String propertyName, boolean defaultValue); 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 * Get a stored mod revision number from the properties file 71 * Get a stored mod revision number from the properties file
47 * 72 *
48 * @param modKey 73 * @param modKey
@@ -69,6 +94,8 @@ public interface LoaderProperties @@ -69,6 +94,8 @@ public interface LoaderProperties
69 public static final String OPTION_NO_HIDE_TAB = "tabAlwaysExpanded"; 94 public static final String OPTION_NO_HIDE_TAB = "tabAlwaysExpanded";
70 public static final String OPTION_BRAND = "brand"; 95 public static final String OPTION_BRAND = "brand";
71 public static final String OPTION_LOADING_BAR = "loadingbar"; 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 // Enumerator properties 100 // Enumerator properties
74 public static final String OPTION_SEARCH_MODS = "search.mods"; 101 public static final String OPTION_SEARCH_MODS = "search.mods";
java/common/com/mumfrey/liteloader/launch/OperatingSystem.java 0 → 100644
  1 +package com.mumfrey.liteloader.launch;
  2 +
  3 +public class OperatingSystem
  4 +{
  5 +
  6 + public OperatingSystem()
  7 + {
  8 + // TODO Auto-generated constructor stub
  9 + }
  10 +
  11 +}
java/common/com/mumfrey/liteloader/transformers/CallbackInjectionTransformer.java
@@ -221,7 +221,7 @@ public abstract class CallbackInjectionTransformer extends ClassTransformer @@ -221,7 +221,7 @@ public abstract class CallbackInjectionTransformer extends ClassTransformer
221 private InsnList genProfilerCallbackInsns(InsnList injected, Callback callback, int refNumber) 221 private InsnList genProfilerCallbackInsns(InsnList injected, Callback callback, int refNumber)
222 { 222 {
223 injected.add(new LdcInsnNode(refNumber)); 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 if (callback.getChainedCallbacks().size() > 0) 226 if (callback.getChainedCallbacks().size() > 0)
227 { 227 {
@@ -297,7 +297,7 @@ public abstract class CallbackInjectionTransformer extends ClassTransformer @@ -297,7 +297,7 @@ public abstract class CallbackInjectionTransformer extends ClassTransformer
297 String callbackMethodDesc = String.format("(%s%s%s%s)%s", hasReturnRef ? callbackReturnValueArg : "", hasReturnRef ? "I" : "", classInstanceArg, CallbackInjectionTransformer.getMethodArgs(methodNode), callbackReturnType); 297 String callbackMethodDesc = String.format("(%s%s%s%s)%s", hasReturnRef ? callbackReturnValueArg : "", hasReturnRef ? "I" : "", classInstanceArg, CallbackInjectionTransformer.getMethodArgs(methodNode), callbackReturnType);
298 298
299 // Add the callback method insn to the injected instructions list 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 // If the callback RETURNs a value then push the appropriate RETURN opcode into the insns list 302 // If the callback RETURNs a value then push the appropriate RETURN opcode into the insns list
303 if (callback.injectReturn()) 303 if (callback.injectReturn())
java/common/com/mumfrey/liteloader/transformers/PacketTransformer.java
@@ -190,7 +190,7 @@ public abstract class PacketTransformer extends ClassTransformer @@ -190,7 +190,7 @@ public abstract class PacketTransformer extends ClassTransformer
190 insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); 190 insns.add(new VarInsnNode(Opcodes.ALOAD, 0));
191 191
192 // Invoke the handler function with the args we just pushed onto the stack 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 method.instructions.insert(method.instructions.getFirst(), insns); 195 method.instructions.insert(method.instructions.getFirst(), insns);
196 } 196 }
@@ -217,7 +217,7 @@ public abstract class PacketTransformer extends ClassTransformer @@ -217,7 +217,7 @@ public abstract class PacketTransformer extends ClassTransformer
217 method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0)); 217 method.instructions.add(new VarInsnNode(Opcodes.ALOAD, 0));
218 218
219 // Invoke the handler function with the args we just pushed onto the stack 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 // Return if no exception 222 // Return if no exception
223 method.instructions.add(new InsnNode(Opcodes.RETURN)); 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&lt;Event&gt; @@ -309,13 +309,13 @@ public class Event implements Comparable&lt;Event&gt;
309 insns.add(new LdcInsnNode(this.name)); ctorMAXS++; 309 insns.add(new LdcInsnNode(this.name)); ctorMAXS++;
310 insns.add(this.methodIsStatic ? new InsnNode(Opcodes.ACONST_NULL) : new VarInsnNode(Opcodes.ALOAD, 0)); ctorMAXS++; 310 insns.add(this.methodIsStatic ? new InsnNode(Opcodes.ACONST_NULL) : new VarInsnNode(Opcodes.ALOAD, 0)); ctorMAXS++;
311 insns.add(new InsnNode(cancellable ? Opcodes.ICONST_1 : Opcodes.ICONST_0)); ctorMAXS++; 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 insns.add(new VarInsnNode(Opcodes.ASTORE, eventInfoVar)); 313 insns.add(new VarInsnNode(Opcodes.ASTORE, eventInfoVar));
314 314
315 // Call the event handler method in the proxy 315 // Call the event handler method in the proxy
316 insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar)); 316 insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar));
317 Event.pushArgs(argumentTypes, insns, this.methodIsStatic); 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 if (cancellable) 320 if (cancellable)
321 { 321 {
@@ -340,7 +340,7 @@ public class Event implements Comparable&lt;Event&gt; @@ -340,7 +340,7 @@ public class Event implements Comparable&lt;Event&gt;
340 protected void injectCancellationCode(final InsnList insns, final AbstractInsnNode injectionPoint, int eventInfoVar) 340 protected void injectCancellationCode(final InsnList insns, final AbstractInsnNode injectionPoint, int eventInfoVar)
341 { 341 {
342 insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar)); 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 LabelNode notCancelled = new LabelNode(); 345 LabelNode notCancelled = new LabelNode();
346 insns.add(new JumpInsnNode(Opcodes.IFEQ, notCancelled)); 346 insns.add(new JumpInsnNode(Opcodes.IFEQ, notCancelled));
@@ -371,7 +371,7 @@ public class Event implements Comparable&lt;Event&gt; @@ -371,7 +371,7 @@ public class Event implements Comparable&lt;Event&gt;
371 insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar)); 371 insns.add(new VarInsnNode(Opcodes.ALOAD, eventInfoVar));
372 String accessor = ReturnEventInfo.getReturnAccessor(this.methodReturnType); 372 String accessor = ReturnEventInfo.getReturnAccessor(this.methodReturnType);
373 String descriptor = ReturnEventInfo.getReturnDescriptor(this.methodReturnType); 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 if (this.methodReturnType.getSort() == Type.OBJECT) 375 if (this.methodReturnType.getSort() == Type.OBJECT)
376 { 376 {
377 insns.add(new TypeInsnNode(Opcodes.CHECKCAST, this.methodReturnType.getInternalName())); 377 insns.add(new TypeInsnNode(Opcodes.CHECKCAST, this.methodReturnType.getInternalName()));
@@ -509,7 +509,7 @@ public class Event implements Comparable&lt;Event&gt; @@ -509,7 +509,7 @@ public class Event implements Comparable&lt;Event&gt;
509 insns.add(new LineNumberNode(++lineNumber, lineNumberLabel)); 509 insns.add(new LineNumberNode(++lineNumber, lineNumberLabel));
510 510
511 Event.pushArgs(args, insns, true); 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 insns.add(tryCatchEnd); // } 515 insns.add(tryCatchEnd); // }
@@ -517,12 +517,12 @@ public class Event implements Comparable&lt;Event&gt; @@ -517,12 +517,12 @@ public class Event implements Comparable&lt;Event&gt;
517 517
518 insns.add(tryCatchHandler1); // catch (NoSuchMethodError err) { 518 insns.add(tryCatchHandler1); // catch (NoSuchMethodError err) {
519 insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); 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 insns.add(new JumpInsnNode(Opcodes.GOTO, tryCatchExit)); 521 insns.add(new JumpInsnNode(Opcodes.GOTO, tryCatchExit));
522 522
523 insns.add(tryCatchHandler2); // } catch (NoClassDefFoundError err) { 523 insns.add(tryCatchHandler2); // } catch (NoClassDefFoundError err) {
524 insns.add(new VarInsnNode(Opcodes.ALOAD, 0)); 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 insns.add(new JumpInsnNode(Opcodes.GOTO, tryCatchExit)); 526 insns.add(new JumpInsnNode(Opcodes.GOTO, tryCatchExit));
527 527
528 insns.add(tryCatchExit); // } 528 insns.add(tryCatchExit); // }
java/common/com/mumfrey/liteloader/update/UpdateSite.java
@@ -139,6 +139,7 @@ public class UpdateSite implements Comparator&lt;Long&gt; @@ -139,6 +139,7 @@ public class UpdateSite implements Comparator&lt;Long&gt;
139 { 139 {
140 if (this.stringRetriever == null) 140 if (this.stringRetriever == null)
141 { 141 {
  142 + LiteLoaderLogger.debug("Update site for %s is starting the update check", this.artefact);
142 this.stringRetriever = new HttpStringRetriever(String.format("%s%s", this.updateSiteUrl, this.updateSiteJsonFileName)); 143 this.stringRetriever = new HttpStringRetriever(String.format("%s%s", this.updateSiteUrl, this.updateSiteJsonFileName));
143 this.stringRetriever.start(); 144 this.stringRetriever.start();
144 } 145 }
@@ -231,10 +232,13 @@ public class UpdateSite implements Comparator&lt;Long&gt; @@ -231,10 +232,13 @@ public class UpdateSite implements Comparator&lt;Long&gt;
231 { 232 {
232 try 233 try
233 { 234 {
  235 + LiteLoaderLogger.debug("Update site for %s is parsing the update response", this.artefact);
234 this.parseData(this.stringRetriever.getString()); 236 this.parseData(this.stringRetriever.getString());
  237 + LiteLoaderLogger.debug("Update site for %s successfully parsed the update response", this.artefact);
235 } 238 }
236 catch (Exception ex) 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 this.checkSuccess = false; 242 this.checkSuccess = false;
239 ex.printStackTrace(); 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,6 +13,9 @@ gui.settings.showtab.help1=If you disable this option, use CTRL+SHIFT+TAB
13 gui.settings.showtab.help2=to open the LiteLoader panel 13 gui.settings.showtab.help2=to open the LiteLoader panel
14 gui.settings.notabhide.label=LiteLoader Tab Always Expanded 14 gui.settings.notabhide.label=LiteLoader Tab Always Expanded
15 gui.settings.notabhide.help1=Only applies if the above option is also checked 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 gui.about.taboptions=§nLiteLoader Panel Options 20 gui.about.taboptions=§nLiteLoader Panel Options
18 21
@@ -55,9 +58,13 @@ gui.updates.available.newversion=§aNew version available @@ -55,9 +58,13 @@ gui.updates.available.newversion=§aNew version available
55 gui.updates.available.version=Version: §a%s 58 gui.updates.available.version=Version: §a%s
56 gui.updates.available.date=Release date: §a%s 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 gui.checknow=Check now 63 gui.checknow=Check now
59 gui.installupdate=Install now 64 gui.installupdate=Install now
60 gui.downloadupdate=Download now 65 gui.downloadupdate=Download now
  66 +gui.forceupdate=Force update
  67 +gui.exitgame=Exit Game
61 68
62 gui.log.button=LiteLoader Log 69 gui.log.button=LiteLoader Log
63 gui.log.title=LiteLoader Log Viewer 70 gui.log.title=LiteLoader Log Viewer
@@ -70,4 +77,6 @@ gui.log.closedialog=Close @@ -70,4 +77,6 @@ gui.log.closedialog=Close
70 77
71 gui.error.title=Startup errors for %s 78 gui.error.title=Startup errors for %s
72 79
73 -gui.error.tooltip=%d mod startup error(s) detected (%d critical)  
74 \ No newline at end of file 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 \ No newline at end of file 84 \ No newline at end of file