Better Splash

A bit more informative as to the load time, I think it's pretty accurate in stepping.
This commit is contained in:
zeruth
2019-04-26 21:54:11 -04:00
parent 3473d17084
commit 7dd4662977
4 changed files with 105 additions and 27 deletions

View File

@@ -84,7 +84,7 @@ public class RuneLite
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
public static final File PLUGIN_DIR = new File(RUNELITE_DIR, "plugins");
public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots");
private static final RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen();
public static RuneLiteSplashScreen splashScreen = new RuneLiteSplashScreen();
@Getter
@@ -233,7 +233,8 @@ public class RuneLite
}
// The submessage is shown in case the connection is slow
splashScreen.setMessage("Loading client", "And checking for updates...");
splashScreen.setMessage("Starting RuneLite Injector");
splashScreen.setSubMessage( " ");
final long start = System.currentTimeMillis();
@@ -242,7 +243,7 @@ public class RuneLite
developerMode));
injector.getInstance(RuneLite.class).start();
splashScreen.setProgress(1, 4);
final long end = System.currentTimeMillis();
final RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
final long uptime = rb.getUptime();
@@ -263,6 +264,7 @@ public class RuneLite
// Load user configuration
splashScreen.setMessage("Loading configuration");
configManager.load();
splashScreen.setProgress(2, 4);
// Load the session, including saved configuration
sessionManager.loadSession();
@@ -275,8 +277,10 @@ public class RuneLite
// Load the plugins, but does not start them yet.
// This will initialize configuration
splashScreen.setMessage("Loading plugins and patches", "Starting session...");
splashScreen.setMessage("Loading plugins and patches");
splashScreen.setSubMessage("Starting session...");
pluginManager.loadCorePlugins();
splashScreen.setProgress(3, 4);
// Plugins have provided their config, so set default config
// to main settings
@@ -287,6 +291,7 @@ public class RuneLite
// Load the session, including saved configuration
splashScreen.setMessage("Loading interface");
splashScreen.setProgress(4, 4);
// Initialize UI
clientUI.open(this);

View File

@@ -92,6 +92,7 @@ public class ClientLoader
private ClientUpdateCheckMode updateCheckMode;
private JarOutputStream target;
private static String[] preotectedStuffs;
private static int stepCount;
@Inject
private ClientLoader(
@@ -240,6 +241,7 @@ public class ClientLoader
hooks.actorClass.equals("") ||
hooks.playerClass.equals("")) {
System.out.println("[RuneLitePlus] Bad hooks, re-scraping.");
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.findHooks(injectedClientFile.getPath());
} else {
@@ -250,6 +252,7 @@ public class ClientLoader
} else {
System.out.println("[RuneLitePlus] Hooks file not found, scraping hooks.");
stepCount = getStepCount(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.clientInstance = initHookScrape(ByteCodeUtils.injectedClientFile.getPath());
ByteCodePatcher.hooks.protectedStuff = preotectedStuffs;
ByteCodePatcher.findHooks(injectedClientFile.getPath());
@@ -340,7 +343,35 @@ public class ClientLoader
return certificates.toArray(new Certificate[certificates.size()]);
}
public static int getStepCount(String jarFile) {
int stepCount = 0;
JarClassLoader jcl = new JarClassLoader();
try {
ClassPool classPool = new ClassPool(true);
classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar");
} catch (NotFoundException e) {
e.printStackTrace();
}
try {
jcl.add(new FileInputStream(jarFile));
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jarFile)))) {
JarEntry entry;
while ((entry = in.getNextJarEntry()) != null) {
if (entry.getName().endsWith(".class")) {
stepCount++;
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return stepCount;
}
public static String initHookScrape(String jarFile) {
int currentStep = 0;
RuneLite.splashScreen.setMessage("Analyzing injected client");
List protectedStuff = new ArrayList<String>();
String clientInstance = "";
JarClassLoader jcl = new JarClassLoader();
@@ -366,6 +397,9 @@ public class ClientLoader
);
try {
Class classToLoad = Class.forName(entry.getName().replace(".class", ""), false, child);
RuneLite.splashScreen.setSubMessage(entry.getName());
currentStep++;
RuneLite.splashScreen.setProgress(currentStep, stepCount);
JarClassLoader jcl2 = new JarClassLoader();
try {
jcl2.add(new FileInputStream(ByteCodeUtils.injectedClientFile));
@@ -386,6 +420,8 @@ public class ClientLoader
}
}
for (Method m : methods) {
RuneLite.splashScreen.setSubMessage("Checked "+m.getName());
RuneLite.splashScreen.setProgress(currentStep, stepCount);
if (m.getName().contains("$")) {
protectedStuff.add(classToLoad.getName()+"."+m.getName());
}
@@ -396,7 +432,7 @@ public class ClientLoader
} catch (Exception e) {
e.printStackTrace();
}
RuneLite.splashScreen.setProgress(2, 5);
} catch (Exception e) {
e.printStackTrace();
System.out.println("Class not found: "+entry.getName());

View File

@@ -15,6 +15,7 @@ import net.runelite.client.rs.bytecode.transformers.ProjectileTransform;
import net.runelite.http.api.RuneLiteAPI;
import org.xeustechnologies.jcl.JarClassLoader;
import javax.swing.*;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
@@ -37,27 +38,42 @@ public class ByteCodePatcher {
public static JarClassLoader jcl = new JarClassLoader();
public static ClassPool classPool = null;
public static ClassLoader cl = ClassLoader.getSystemClassLoader();
public static int classCount = 0;
public static void applyHooks(File jf, Hooks hooks) {
RuneLite.splashScreen.setProgress(0, 5);
RuneLite.splashScreen.setMessage("Applying cached bytecode patches...");
try {
URLClassLoader child = new URLClassLoader(
new URL[] {jf.toURI().toURL()},
cl
);
try {
RuneLite.splashScreen.setSubMessage("Transforming Actor");
Class actorClass = Class.forName(hooks.actorClass, false, child);
transformActor(actorClass);
RuneLite.splashScreen.setProgress(1, 5);
RuneLite.splashScreen.setSubMessage("Transforming Projectile");
Class projectileClass = Class.forName(hooks.projectileClass, false, child);
transformProjectile(projectileClass);
RuneLite.splashScreen.setProgress(2, 5);
RuneLite.splashScreen.setSubMessage("Transforming Player");
Class playerClass = Class.forName(hooks.playerClass, false, child);
transformPlayer(playerClass);
RuneLite.splashScreen.setProgress(3, 5);
RuneLite.splashScreen.setSubMessage("Transforming Client");
Class clientClass = Class.forName("client", false, child);
transformClient(clientClass);
RuneLite.splashScreen.setProgress(4, 5);
//Odds and ends
RuneLite.splashScreen.setSubMessage("Transforming Error method");
ErrorTransform et = new ErrorTransform();
et.modify(null);
RuneLite.splashScreen.setProgress(5, 5);
ByteCodeUtils.updateHijackedJar();
} catch (Exception e) {
e.printStackTrace();
@@ -69,6 +85,7 @@ public class ByteCodePatcher {
}
public static void findHooks(String jf) {
RuneLite.splashScreen.setMessage("Intercepting Classes");
try {
classPool = new ClassPool(true);
classPool.appendClassPath(RuneLite.RUNELITE_DIR+"/injectedClient-"+ RuneLiteAPI.getVersion() +"-.jar");
@@ -82,7 +99,20 @@ public class ByteCodePatcher {
JarEntry entry;
while ((entry = in.getNextJarEntry()) != null) {
if (entry.getName().endsWith(".class")) {
classCount++;
}
}
}
int i = 0;
jcl.add(new FileInputStream(jf));
try (JarInputStream in = new JarInputStream(new BufferedInputStream(new FileInputStream(jf)))) {
JarEntry entry;
while ((entry = in.getNextJarEntry()) != null) {
if (entry.getName().endsWith(".class")) {
RuneLite.splashScreen.setProgress(i, classCount);
RuneLite.splashScreen.setSubMessage("Checking "+entry.getName());
checkClasses(new File(jf), entry);
i++;
}
}
}
@@ -194,5 +224,4 @@ public class ByteCodePatcher {
bt.modify(clazz);
}
}

View File

@@ -51,10 +51,10 @@ public class RuneLiteSplashScreen
{
private RuneLiteProperties runeLiteProperties = new RuneLiteProperties();
private JFrame frame;
private JLabel messageLabel;
private JLabel subMessageLabel;
private JProgressBar progressBar;
public JFrame frame;
public JLabel messageLabel;
public JLabel subMessageLabel;
public JProgressBar progressBar;
private int currentStep;
@@ -191,21 +191,7 @@ public class RuneLiteSplashScreen
});
}
/**
* Set a loading message. The subMessage will also be removed.
* @param message The main message. It will automatically append an ellipsis.
*/
public void setMessage(final String message)
{
setMessage(message, " ");
}
/**
* Set a loading message.
* @param message The main message. It will automatically append an ellipsis.
* @param subMessage A separate alternate title.
*/
public void setMessage(final String message, final String subMessage)
{
SwingUtilities.invokeLater(() ->
{
@@ -213,10 +199,32 @@ public class RuneLiteSplashScreen
{
return;
}
messageLabel.setText(message);
});
}
messageLabel.setText(message + "...");
public void setSubMessage(final String subMessage)
{
SwingUtilities.invokeLater(() ->
{
if (notActive())
{
return;
}
subMessageLabel.setText(subMessage);
progressBar.setValue(++currentStep);
});
}
public void setProgress(int currentProgress, int progressGoal)
{
SwingUtilities.invokeLater(() ->
{
if (notActive())
{
return;
}
progressBar.setMaximum(progressGoal);
progressBar.setValue(currentProgress);
});
}
}