@@ -73,8 +73,9 @@ public class Notifier
|
|||||||
private static final int MINIMUM_FLASH_DURATION_MILLIS = 2000;
|
private static final int MINIMUM_FLASH_DURATION_MILLIS = 2000;
|
||||||
private static final int MINIMUM_FLASH_DURATION_TICKS = MINIMUM_FLASH_DURATION_MILLIS / Constants.CLIENT_TICK_LENGTH;
|
private static final int MINIMUM_FLASH_DURATION_TICKS = MINIMUM_FLASH_DURATION_MILLIS / Constants.CLIENT_TICK_LENGTH;
|
||||||
|
|
||||||
|
private static final String appName = RuneLiteProperties.getTitle();
|
||||||
|
|
||||||
private final Client client;
|
private final Client client;
|
||||||
private final String appName;
|
|
||||||
private final RuneLiteConfig runeLiteConfig;
|
private final RuneLiteConfig runeLiteConfig;
|
||||||
private final ClientUI clientUI;
|
private final ClientUI clientUI;
|
||||||
private final ScheduledExecutorService executorService;
|
private final ScheduledExecutorService executorService;
|
||||||
@@ -89,12 +90,10 @@ public class Notifier
|
|||||||
final ClientUI clientUI,
|
final ClientUI clientUI,
|
||||||
final Client client,
|
final Client client,
|
||||||
final RuneLiteConfig runeliteConfig,
|
final RuneLiteConfig runeliteConfig,
|
||||||
final RuneLiteProperties runeLiteProperties,
|
|
||||||
final ScheduledExecutorService executorService,
|
final ScheduledExecutorService executorService,
|
||||||
final ChatMessageManager chatMessageManager)
|
final ChatMessageManager chatMessageManager)
|
||||||
{
|
{
|
||||||
this.client = client;
|
this.client = client;
|
||||||
this.appName = runeLiteProperties.getTitle();
|
|
||||||
this.clientUI = clientUI;
|
this.clientUI = clientUI;
|
||||||
this.runeLiteConfig = runeliteConfig;
|
this.runeLiteConfig = runeliteConfig;
|
||||||
this.executorService = executorService;
|
this.executorService = executorService;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import java.util.Locale;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Provider;
|
import javax.inject.Provider;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import joptsimple.ArgumentAcceptingOptionSpec;
|
import joptsimple.ArgumentAcceptingOptionSpec;
|
||||||
import joptsimple.OptionParser;
|
import joptsimple.OptionParser;
|
||||||
import joptsimple.OptionSet;
|
import joptsimple.OptionSet;
|
||||||
@@ -60,6 +61,8 @@ import net.runelite.client.rs.ClientLoader;
|
|||||||
import net.runelite.client.rs.ClientUpdateCheckMode;
|
import net.runelite.client.rs.ClientUpdateCheckMode;
|
||||||
import net.runelite.client.ui.ClientUI;
|
import net.runelite.client.ui.ClientUI;
|
||||||
import net.runelite.client.ui.DrawManager;
|
import net.runelite.client.ui.DrawManager;
|
||||||
|
import net.runelite.client.ui.FatalErrorDialog;
|
||||||
|
import net.runelite.client.ui.SplashScreen;
|
||||||
import net.runelite.client.ui.overlay.OverlayManager;
|
import net.runelite.client.ui.overlay.OverlayManager;
|
||||||
import net.runelite.client.ui.overlay.OverlayRenderer;
|
import net.runelite.client.ui.overlay.OverlayRenderer;
|
||||||
import net.runelite.client.ui.overlay.WidgetOverlay;
|
import net.runelite.client.ui.overlay.WidgetOverlay;
|
||||||
@@ -77,6 +80,7 @@ public class RuneLite
|
|||||||
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite");
|
public static final File RUNELITE_DIR = new File(System.getProperty("user.home"), ".runelite");
|
||||||
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
|
public static final File PROFILES_DIR = new File(RUNELITE_DIR, "profiles");
|
||||||
public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots");
|
public static final File SCREENSHOT_DIR = new File(RUNELITE_DIR, "screenshots");
|
||||||
|
public static final File LOGS_DIR = new File(RUNELITE_DIR, "logs");
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static Injector injector;
|
private static Injector injector;
|
||||||
@@ -197,40 +201,61 @@ public class RuneLite
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
final ClientLoader clientLoader = new ClientLoader(options.valueOf(updateMode));
|
SplashScreen.init();
|
||||||
|
SplashScreen.stage(0, "Retrieving client", "");
|
||||||
|
|
||||||
new Thread(() ->
|
try
|
||||||
{
|
{
|
||||||
clientLoader.get();
|
final ClientLoader clientLoader = new ClientLoader(options.valueOf(updateMode));
|
||||||
ClassPreloader.preload();
|
|
||||||
}, "Preloader").start();
|
|
||||||
|
|
||||||
final boolean developerMode = options.has("developer-mode") && RuneLiteProperties.getLauncherVersion() == null;
|
new Thread(() ->
|
||||||
|
|
||||||
if (developerMode)
|
|
||||||
{
|
|
||||||
boolean assertions = false;
|
|
||||||
assert assertions = true;
|
|
||||||
if (!assertions)
|
|
||||||
{
|
{
|
||||||
throw new RuntimeException("Developers should enable assertions; Add `-ea` to your JVM arguments`");
|
clientLoader.get();
|
||||||
|
ClassPreloader.preload();
|
||||||
|
}, "Preloader").start();
|
||||||
|
|
||||||
|
final boolean developerMode = options.has("developer-mode") && RuneLiteProperties.getLauncherVersion() == null;
|
||||||
|
|
||||||
|
if (developerMode)
|
||||||
|
{
|
||||||
|
boolean assertions = false;
|
||||||
|
assert assertions = true;
|
||||||
|
if (!assertions)
|
||||||
|
{
|
||||||
|
SwingUtilities.invokeLater(() ->
|
||||||
|
new FatalErrorDialog("Developers should enable assertions; Add `-ea` to your JVM arguments`")
|
||||||
|
.addBuildingGuide()
|
||||||
|
.open());
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PROFILES_DIR.mkdirs();
|
||||||
|
|
||||||
|
final long start = System.currentTimeMillis();
|
||||||
|
|
||||||
|
injector = Guice.createInjector(new RuneLiteModule(
|
||||||
|
clientLoader,
|
||||||
|
developerMode));
|
||||||
|
|
||||||
|
injector.getInstance(RuneLite.class).start();
|
||||||
|
|
||||||
|
final long end = System.currentTimeMillis();
|
||||||
|
final RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
||||||
|
final long uptime = rb.getUptime();
|
||||||
|
log.info("Client initialization took {}ms. Uptime: {}ms", end - start, uptime);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.warn("Failure during startup", e);
|
||||||
|
SwingUtilities.invokeLater(() ->
|
||||||
|
new FatalErrorDialog("RuneLite has encountered an unexpected error during startup.")
|
||||||
|
.open());
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
SplashScreen.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
PROFILES_DIR.mkdirs();
|
|
||||||
|
|
||||||
final long start = System.currentTimeMillis();
|
|
||||||
|
|
||||||
injector = Guice.createInjector(new RuneLiteModule(
|
|
||||||
clientLoader,
|
|
||||||
developerMode));
|
|
||||||
|
|
||||||
injector.getInstance(RuneLite.class).start();
|
|
||||||
|
|
||||||
final long end = System.currentTimeMillis();
|
|
||||||
final RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
|
|
||||||
final long uptime = rb.getUptime();
|
|
||||||
log.info("Client initialization took {}ms. Uptime: {}ms", end - start, uptime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start() throws Exception
|
public void start() throws Exception
|
||||||
@@ -244,6 +269,8 @@ public class RuneLite
|
|||||||
injector.injectMembers(client);
|
injector.injectMembers(client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SplashScreen.stage(.57, null, "Loading configuration");
|
||||||
|
|
||||||
// Load user configuration
|
// Load user configuration
|
||||||
configManager.load();
|
configManager.load();
|
||||||
|
|
||||||
@@ -257,6 +284,8 @@ public class RuneLite
|
|||||||
// This will initialize configuration
|
// This will initialize configuration
|
||||||
pluginManager.loadCorePlugins();
|
pluginManager.loadCorePlugins();
|
||||||
|
|
||||||
|
SplashScreen.stage(.70, null, "Finalizing configuration");
|
||||||
|
|
||||||
// Plugins have provided their config, so set default config
|
// Plugins have provided their config, so set default config
|
||||||
// to main settings
|
// to main settings
|
||||||
pluginManager.loadDefaultPluginConfiguration();
|
pluginManager.loadDefaultPluginConfiguration();
|
||||||
@@ -264,8 +293,10 @@ public class RuneLite
|
|||||||
// Start client session
|
// Start client session
|
||||||
clientSessionManager.start();
|
clientSessionManager.start();
|
||||||
|
|
||||||
|
SplashScreen.stage(.75, null, "Starting core interface");
|
||||||
|
|
||||||
// Initialize UI
|
// Initialize UI
|
||||||
clientUI.open(this);
|
clientUI.init(this);
|
||||||
|
|
||||||
// Initialize Discord service
|
// Initialize Discord service
|
||||||
discordService.init();
|
discordService.init();
|
||||||
@@ -301,6 +332,10 @@ public class RuneLite
|
|||||||
|
|
||||||
// Start plugins
|
// Start plugins
|
||||||
pluginManager.startCorePlugins();
|
pluginManager.startCorePlugins();
|
||||||
|
|
||||||
|
SplashScreen.stop();
|
||||||
|
|
||||||
|
clientUI.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void shutdown()
|
public void shutdown()
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ public class RuneLiteModule extends AbstractModule
|
|||||||
bind(ItemManager.class);
|
bind(ItemManager.class);
|
||||||
bind(Scheduler.class);
|
bind(Scheduler.class);
|
||||||
bind(PluginManager.class);
|
bind(PluginManager.class);
|
||||||
bind(RuneLiteProperties.class);
|
|
||||||
bind(SessionManager.class);
|
bind(SessionManager.class);
|
||||||
|
|
||||||
bind(Callbacks.class).to(Hooks.class);
|
bind(Callbacks.class).to(Hooks.class);
|
||||||
|
|||||||
@@ -28,12 +28,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
|
||||||
import javax.inject.Singleton;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
@Singleton
|
|
||||||
@Slf4j
|
|
||||||
public class RuneLiteProperties
|
public class RuneLiteProperties
|
||||||
{
|
{
|
||||||
private static final String RUNELITE_TITLE = "runelite.title";
|
private static final String RUNELITE_TITLE = "runelite.title";
|
||||||
@@ -45,58 +40,60 @@ public class RuneLiteProperties
|
|||||||
private static final String WIKI_LINK = "runelite.wiki.link";
|
private static final String WIKI_LINK = "runelite.wiki.link";
|
||||||
private static final String PATREON_LINK = "runelite.patreon.link";
|
private static final String PATREON_LINK = "runelite.patreon.link";
|
||||||
private static final String LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version";
|
private static final String LAUNCHER_VERSION_PROPERTY = "runelite.launcher.version";
|
||||||
|
private static final String TROUBLESHOOTING_LINK = "runelite.wiki.troubleshooting.link";
|
||||||
|
private static final String BUILDING_LINK = "runelite.wiki.building.link";
|
||||||
|
private static final String DNS_CHANGE_LINK = "runelite.dnschange.link";
|
||||||
|
|
||||||
private final Properties properties = new Properties();
|
private static final Properties properties = new Properties();
|
||||||
|
|
||||||
@Inject
|
static
|
||||||
public RuneLiteProperties()
|
|
||||||
{
|
{
|
||||||
try (InputStream in = getClass().getResourceAsStream("runelite.properties"))
|
try (InputStream in = RuneLiteProperties.class.getResourceAsStream("runelite.properties"))
|
||||||
{
|
{
|
||||||
properties.load(in);
|
properties.load(in);
|
||||||
}
|
}
|
||||||
catch (IOException ex)
|
catch (IOException ex)
|
||||||
{
|
{
|
||||||
log.warn("unable to load propertries", ex);
|
throw new RuntimeException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTitle()
|
public static String getTitle()
|
||||||
{
|
{
|
||||||
return properties.getProperty(RUNELITE_TITLE);
|
return properties.getProperty(RUNELITE_TITLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getVersion()
|
public static String getVersion()
|
||||||
{
|
{
|
||||||
return properties.getProperty(RUNELITE_VERSION);
|
return properties.getProperty(RUNELITE_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getRunescapeVersion()
|
public static String getRunescapeVersion()
|
||||||
{
|
{
|
||||||
return properties.getProperty(RUNESCAPE_VERSION);
|
return properties.getProperty(RUNESCAPE_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDiscordAppId()
|
public static String getDiscordAppId()
|
||||||
{
|
{
|
||||||
return properties.getProperty(DISCORD_APP_ID);
|
return properties.getProperty(DISCORD_APP_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDiscordInvite()
|
public static String getDiscordInvite()
|
||||||
{
|
{
|
||||||
return properties.getProperty(DISCORD_INVITE);
|
return properties.getProperty(DISCORD_INVITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getGithubLink()
|
public static String getGithubLink()
|
||||||
{
|
{
|
||||||
return properties.getProperty(GITHUB_LINK);
|
return properties.getProperty(GITHUB_LINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getWikiLink()
|
public static String getWikiLink()
|
||||||
{
|
{
|
||||||
return properties.getProperty(WIKI_LINK);
|
return properties.getProperty(WIKI_LINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getPatreonLink()
|
public static String getPatreonLink()
|
||||||
{
|
{
|
||||||
return properties.getProperty(PATREON_LINK);
|
return properties.getProperty(PATREON_LINK);
|
||||||
}
|
}
|
||||||
@@ -106,4 +103,19 @@ public class RuneLiteProperties
|
|||||||
{
|
{
|
||||||
return System.getProperty(LAUNCHER_VERSION_PROPERTY);
|
return System.getProperty(LAUNCHER_VERSION_PROPERTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getTroubleshootingLink()
|
||||||
|
{
|
||||||
|
return properties.getProperty(TROUBLESHOOTING_LINK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getBuildingLink()
|
||||||
|
{
|
||||||
|
return properties.getProperty(BUILDING_LINK);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDNSChangeLink()
|
||||||
|
{
|
||||||
|
return properties.getProperty(DNS_CHANGE_LINK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,6 @@ import net.runelite.discord.DiscordUser;
|
|||||||
public class DiscordService implements AutoCloseable
|
public class DiscordService implements AutoCloseable
|
||||||
{
|
{
|
||||||
private final EventBus eventBus;
|
private final EventBus eventBus;
|
||||||
private final RuneLiteProperties runeLiteProperties;
|
|
||||||
private final ScheduledExecutorService executorService;
|
private final ScheduledExecutorService executorService;
|
||||||
private final DiscordRPC discordRPC;
|
private final DiscordRPC discordRPC;
|
||||||
|
|
||||||
@@ -62,12 +61,10 @@ public class DiscordService implements AutoCloseable
|
|||||||
@Inject
|
@Inject
|
||||||
private DiscordService(
|
private DiscordService(
|
||||||
final EventBus eventBus,
|
final EventBus eventBus,
|
||||||
final RuneLiteProperties runeLiteProperties,
|
|
||||||
final ScheduledExecutorService executorService)
|
final ScheduledExecutorService executorService)
|
||||||
{
|
{
|
||||||
|
|
||||||
this.eventBus = eventBus;
|
this.eventBus = eventBus;
|
||||||
this.runeLiteProperties = runeLiteProperties;
|
|
||||||
this.executorService = executorService;
|
this.executorService = executorService;
|
||||||
|
|
||||||
DiscordRPC discordRPC = null;
|
DiscordRPC discordRPC = null;
|
||||||
@@ -106,7 +103,7 @@ public class DiscordService implements AutoCloseable
|
|||||||
discordEventHandlers.joinGame = this::joinGame;
|
discordEventHandlers.joinGame = this::joinGame;
|
||||||
discordEventHandlers.spectateGame = this::spectateGame;
|
discordEventHandlers.spectateGame = this::spectateGame;
|
||||||
discordEventHandlers.joinRequest = this::joinRequest;
|
discordEventHandlers.joinRequest = this::joinRequest;
|
||||||
discordRPC.Discord_Initialize(runeLiteProperties.getDiscordAppId(), discordEventHandlers, true, null);
|
discordRPC.Discord_Initialize(RuneLiteProperties.getDiscordAppId(), discordEventHandlers, true, null);
|
||||||
executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS);
|
executorService.scheduleAtFixedRate(discordRPC::Discord_RunCallbacks, 0, 2, TimeUnit.SECONDS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ import net.runelite.client.events.PluginChanged;
|
|||||||
import net.runelite.client.task.Schedule;
|
import net.runelite.client.task.Schedule;
|
||||||
import net.runelite.client.task.ScheduledMethod;
|
import net.runelite.client.task.ScheduledMethod;
|
||||||
import net.runelite.client.task.Scheduler;
|
import net.runelite.client.task.Scheduler;
|
||||||
|
import net.runelite.client.ui.SplashScreen;
|
||||||
import net.runelite.client.util.GameEventManager;
|
import net.runelite.client.util.GameEventManager;
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
@@ -200,6 +201,7 @@ public class PluginManager
|
|||||||
public void startCorePlugins()
|
public void startCorePlugins()
|
||||||
{
|
{
|
||||||
List<Plugin> scannedPlugins = new ArrayList<>(plugins);
|
List<Plugin> scannedPlugins = new ArrayList<>(plugins);
|
||||||
|
int loaded = 0;
|
||||||
for (Plugin plugin : scannedPlugins)
|
for (Plugin plugin : scannedPlugins)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -211,11 +213,15 @@ public class PluginManager
|
|||||||
log.warn("Unable to start plugin {}. {}", plugin.getClass().getSimpleName(), ex);
|
log.warn("Unable to start plugin {}. {}", plugin.getClass().getSimpleName(), ex);
|
||||||
plugins.remove(plugin);
|
plugins.remove(plugin);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loaded++;
|
||||||
|
SplashScreen.stage(.80, 1, null, "Starting plugins", loaded, scannedPlugins.size(), false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException
|
List<Plugin> scanAndInstantiate(ClassLoader classLoader, String packageName) throws IOException
|
||||||
{
|
{
|
||||||
|
SplashScreen.stage(.59, null, "Loading Plugins");
|
||||||
MutableGraph<Class<? extends Plugin>> graph = GraphBuilder
|
MutableGraph<Class<? extends Plugin>> graph = GraphBuilder
|
||||||
.directed()
|
.directed()
|
||||||
.build();
|
.build();
|
||||||
@@ -280,20 +286,22 @@ public class PluginManager
|
|||||||
List<Class<? extends Plugin>> sortedPlugins = topologicalSort(graph);
|
List<Class<? extends Plugin>> sortedPlugins = topologicalSort(graph);
|
||||||
sortedPlugins = Lists.reverse(sortedPlugins);
|
sortedPlugins = Lists.reverse(sortedPlugins);
|
||||||
|
|
||||||
|
int loaded = 0;
|
||||||
for (Class<? extends Plugin> pluginClazz : sortedPlugins)
|
for (Class<? extends Plugin> pluginClazz : sortedPlugins)
|
||||||
{
|
{
|
||||||
Plugin plugin;
|
Plugin plugin;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
plugin = instantiate(scannedPlugins, (Class<Plugin>) pluginClazz);
|
plugin = instantiate(scannedPlugins, (Class<Plugin>) pluginClazz);
|
||||||
|
scannedPlugins.add(plugin);
|
||||||
}
|
}
|
||||||
catch (PluginInstantiationException ex)
|
catch (PluginInstantiationException ex)
|
||||||
{
|
{
|
||||||
log.warn("Error instantiating plugin!", ex);
|
log.warn("Error instantiating plugin!", ex);
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
scannedPlugins.add(plugin);
|
loaded++;
|
||||||
|
SplashScreen.stage(.60, .70, null, "Loading Plugins", loaded, sortedPlugins.size(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return scannedPlugins;
|
return scannedPlugins;
|
||||||
|
|||||||
@@ -68,9 +68,6 @@ public class ChatNotificationsPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private Notifier notifier;
|
private Notifier notifier;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RuneLiteProperties runeLiteProperties;
|
|
||||||
|
|
||||||
//Custom Highlights
|
//Custom Highlights
|
||||||
private Pattern usernameMatcher = null;
|
private Pattern usernameMatcher = null;
|
||||||
private String usernameReplacer = "";
|
private String usernameReplacer = "";
|
||||||
@@ -148,7 +145,7 @@ public class ChatNotificationsPlugin extends Plugin
|
|||||||
break;
|
break;
|
||||||
case CONSOLE:
|
case CONSOLE:
|
||||||
// Don't notify for notification messages
|
// Don't notify for notification messages
|
||||||
if (chatMessage.getName().equals(runeLiteProperties.getTitle()))
|
if (chatMessage.getName().equals(RuneLiteProperties.getTitle()))
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,9 +91,6 @@ public class DiscordPlugin extends Plugin
|
|||||||
@Inject
|
@Inject
|
||||||
private ClientToolbar clientToolbar;
|
private ClientToolbar clientToolbar;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RuneLiteProperties properties;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DiscordState discordState;
|
private DiscordState discordState;
|
||||||
|
|
||||||
@@ -125,7 +122,7 @@ public class DiscordPlugin extends Plugin
|
|||||||
.tab(false)
|
.tab(false)
|
||||||
.tooltip("Join Discord")
|
.tooltip("Join Discord")
|
||||||
.icon(icon)
|
.icon(icon)
|
||||||
.onClick(() -> LinkBrowser.browse(properties.getDiscordInvite()))
|
.onClick(() -> LinkBrowser.browse(RuneLiteProperties.getDiscordInvite()))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
clientToolbar.addNavigation(discordButton);
|
clientToolbar.addNavigation(discordButton);
|
||||||
|
|||||||
@@ -58,16 +58,14 @@ class DiscordState
|
|||||||
private final DiscordService discordService;
|
private final DiscordService discordService;
|
||||||
private final DiscordConfig config;
|
private final DiscordConfig config;
|
||||||
private PartyService party;
|
private PartyService party;
|
||||||
private final RuneLiteProperties properties;
|
|
||||||
private DiscordPresence lastPresence;
|
private DiscordPresence lastPresence;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private DiscordState(final DiscordService discordService, final DiscordConfig config, final PartyService party, final RuneLiteProperties properties)
|
private DiscordState(final DiscordService discordService, final DiscordConfig config, final PartyService party)
|
||||||
{
|
{
|
||||||
this.discordService = discordService;
|
this.discordService = discordService;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.party = party;
|
this.party = party;
|
||||||
this.properties = properties;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,12 +171,12 @@ class DiscordState
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Replace snapshot with + to make tooltip shorter (so it will span only 1 line)
|
// Replace snapshot with + to make tooltip shorter (so it will span only 1 line)
|
||||||
final String versionShortHand = properties.getVersion().replace("-SNAPSHOT", "+");
|
final String versionShortHand = RuneLiteProperties.getVersion().replace("-SNAPSHOT", "+");
|
||||||
|
|
||||||
final DiscordPresence.DiscordPresenceBuilder presenceBuilder = DiscordPresence.builder()
|
final DiscordPresence.DiscordPresenceBuilder presenceBuilder = DiscordPresence.builder()
|
||||||
.state(MoreObjects.firstNonNull(state, ""))
|
.state(MoreObjects.firstNonNull(state, ""))
|
||||||
.details(MoreObjects.firstNonNull(details, ""))
|
.details(MoreObjects.firstNonNull(details, ""))
|
||||||
.largeImageText(properties.getTitle() + " v" + versionShortHand)
|
.largeImageText(RuneLiteProperties.getTitle() + " v" + versionShortHand)
|
||||||
.startTimestamp(event.getStart())
|
.startTimestamp(event.getStart())
|
||||||
.smallImageKey(imageKey)
|
.smallImageKey(imageKey)
|
||||||
.partyMax(PARTY_MAX)
|
.partyMax(PARTY_MAX)
|
||||||
|
|||||||
@@ -79,9 +79,6 @@ public class InfoPanel extends PluginPanel
|
|||||||
@Nullable
|
@Nullable
|
||||||
private Client client;
|
private Client client;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private RuneLiteProperties runeLiteProperties;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private EventBus eventBus;
|
private EventBus eventBus;
|
||||||
|
|
||||||
@@ -117,7 +114,7 @@ public class InfoPanel extends PluginPanel
|
|||||||
|
|
||||||
final Font smallFont = FontManager.getRunescapeSmallFont();
|
final Font smallFont = FontManager.getRunescapeSmallFont();
|
||||||
|
|
||||||
JLabel version = new JLabel(htmlLabel("RuneLite version: ", runeLiteProperties.getVersion()));
|
JLabel version = new JLabel(htmlLabel("RuneLite version: ", RuneLiteProperties.getVersion()));
|
||||||
version.setFont(smallFont);
|
version.setFont(smallFont);
|
||||||
|
|
||||||
JLabel revision = new JLabel();
|
JLabel revision = new JLabel();
|
||||||
@@ -176,10 +173,10 @@ public class InfoPanel extends PluginPanel
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
actionsContainer.add(buildLinkPanel(GITHUB_ICON, "Report an issue or", "make a suggestion", runeLiteProperties.getGithubLink()));
|
actionsContainer.add(buildLinkPanel(GITHUB_ICON, "Report an issue or", "make a suggestion", RuneLiteProperties.getGithubLink()));
|
||||||
actionsContainer.add(buildLinkPanel(DISCORD_ICON, "Talk to us on our", "discord server", runeLiteProperties.getDiscordInvite()));
|
actionsContainer.add(buildLinkPanel(DISCORD_ICON, "Talk to us on our", "discord server", RuneLiteProperties.getDiscordInvite()));
|
||||||
actionsContainer.add(buildLinkPanel(PATREON_ICON, "Become a patron to", "help support RuneLite", runeLiteProperties.getPatreonLink()));
|
actionsContainer.add(buildLinkPanel(PATREON_ICON, "Become a patron to", "help support RuneLite", RuneLiteProperties.getPatreonLink()));
|
||||||
actionsContainer.add(buildLinkPanel(WIKI_ICON, "Information about", "RuneLite and plugins", runeLiteProperties.getWikiLink()));
|
actionsContainer.add(buildLinkPanel(WIKI_ICON, "Information about", "RuneLite and plugins", RuneLiteProperties.getWikiLink()));
|
||||||
|
|
||||||
add(versionPanel, BorderLayout.NORTH);
|
add(versionPanel, BorderLayout.NORTH);
|
||||||
add(actionsContainer, BorderLayout.CENTER);
|
add(actionsContainer, BorderLayout.CENTER);
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import io.sigpipe.jbsdiff.InvalidHeaderException;
|
|||||||
import io.sigpipe.jbsdiff.Patch;
|
import io.sigpipe.jbsdiff.Patch;
|
||||||
import java.applet.Applet;
|
import java.applet.Applet;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.FilterInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
@@ -48,11 +49,14 @@ import java.util.Map;
|
|||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import java.util.jar.JarEntry;
|
import java.util.jar.JarEntry;
|
||||||
import java.util.jar.JarInputStream;
|
import java.util.jar.JarInputStream;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.runelite.api.Client;
|
import net.runelite.api.Client;
|
||||||
import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO;
|
import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO;
|
||||||
import static net.runelite.client.rs.ClientUpdateCheckMode.NONE;
|
import static net.runelite.client.rs.ClientUpdateCheckMode.NONE;
|
||||||
import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA;
|
import static net.runelite.client.rs.ClientUpdateCheckMode.VANILLA;
|
||||||
|
import net.runelite.client.ui.FatalErrorDialog;
|
||||||
|
import net.runelite.client.ui.SplashScreen;
|
||||||
import net.runelite.http.api.RuneLiteAPI;
|
import net.runelite.http.api.RuneLiteAPI;
|
||||||
import okhttp3.Request;
|
import okhttp3.Request;
|
||||||
import okhttp3.Response;
|
import okhttp3.Response;
|
||||||
@@ -62,7 +66,7 @@ import org.apache.commons.compress.compressors.CompressorException;
|
|||||||
public class ClientLoader implements Supplier<Applet>
|
public class ClientLoader implements Supplier<Applet>
|
||||||
{
|
{
|
||||||
private ClientUpdateCheckMode updateCheckMode;
|
private ClientUpdateCheckMode updateCheckMode;
|
||||||
private Applet client = null;
|
private Object client = null;
|
||||||
|
|
||||||
public ClientLoader(ClientUpdateCheckMode updateCheckMode)
|
public ClientLoader(ClientUpdateCheckMode updateCheckMode)
|
||||||
{
|
{
|
||||||
@@ -76,10 +80,15 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
{
|
{
|
||||||
client = doLoad();
|
client = doLoad();
|
||||||
}
|
}
|
||||||
return client;
|
|
||||||
|
if (client instanceof Throwable)
|
||||||
|
{
|
||||||
|
throw new RuntimeException((Throwable) client);
|
||||||
|
}
|
||||||
|
return (Applet) client;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Applet doLoad()
|
private Object doLoad()
|
||||||
{
|
{
|
||||||
if (updateCheckMode == NONE)
|
if (updateCheckMode == NONE)
|
||||||
{
|
{
|
||||||
@@ -88,6 +97,7 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
SplashScreen.stage(0, null, "Fetching applet viewer config");
|
||||||
RSConfig config = ClientConfigLoader.fetch();
|
RSConfig config = ClientConfigLoader.fetch();
|
||||||
|
|
||||||
Map<String, byte[]> zipFile = new HashMap<>();
|
Map<String, byte[]> zipFile = new HashMap<>();
|
||||||
@@ -102,7 +112,26 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
|
|
||||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||||
{
|
{
|
||||||
JarInputStream jis = new JarInputStream(response.body().byteStream());
|
int length = (int) response.body().contentLength();
|
||||||
|
if (length < 0)
|
||||||
|
{
|
||||||
|
length = 3 * 1024 * 1024;
|
||||||
|
}
|
||||||
|
final int flength = length;
|
||||||
|
InputStream istream = new FilterInputStream(response.body().byteStream())
|
||||||
|
{
|
||||||
|
private int read = 0;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException
|
||||||
|
{
|
||||||
|
int thisRead = super.read(b, off, len);
|
||||||
|
this.read += thisRead;
|
||||||
|
SplashScreen.stage(.05, .35, null, "Downloading Old School RuneScape", this.read, flength, true);
|
||||||
|
return thisRead;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
JarInputStream jis = new JarInputStream(istream);
|
||||||
|
|
||||||
byte[] tmp = new byte[4096];
|
byte[] tmp = new byte[4096];
|
||||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
|
||||||
@@ -146,9 +175,19 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
|
|
||||||
if (updateCheckMode == AUTO)
|
if (updateCheckMode == AUTO)
|
||||||
{
|
{
|
||||||
|
SplashScreen.stage(.35, null, "Patching");
|
||||||
Map<String, String> hashes;
|
Map<String, String> hashes;
|
||||||
try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/hashes.json"))
|
try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/hashes.json"))
|
||||||
{
|
{
|
||||||
|
if (is == null)
|
||||||
|
{
|
||||||
|
SwingUtilities.invokeLater(() ->
|
||||||
|
new FatalErrorDialog("The client-patch is missing from the classpath. If you are building " +
|
||||||
|
"the client you need to re-run maven")
|
||||||
|
.addBuildingGuide()
|
||||||
|
.open());
|
||||||
|
throw new NullPointerException();
|
||||||
|
}
|
||||||
hashes = new Gson().fromJson(new InputStreamReader(is), new TypeToken<HashMap<String, String>>()
|
hashes = new Gson().fromJson(new InputStreamReader(is), new TypeToken<HashMap<String, String>>()
|
||||||
{
|
{
|
||||||
}.getType());
|
}.getType());
|
||||||
@@ -197,11 +236,14 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
file.setValue(patchOs.toByteArray());
|
file.setValue(patchOs.toByteArray());
|
||||||
|
|
||||||
++patchCount;
|
++patchCount;
|
||||||
|
SplashScreen.stage(.38, .45, null, "Patching", patchCount, zipFile.size(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Patched {} classes", patchCount);
|
log.debug("Patched {} classes", patchCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SplashScreen.stage(.465, "Starting", "Starting Old School RuneScape");
|
||||||
|
|
||||||
String initialClass = config.getInitialClass();
|
String initialClass = config.getInitialClass();
|
||||||
|
|
||||||
ClassLoader rsClassLoader = new ClassLoader(ClientLoader.class.getClassLoader())
|
ClassLoader rsClassLoader = new ClassLoader(ClientLoader.class.getClassLoader())
|
||||||
@@ -230,21 +272,18 @@ public class ClientLoader implements Supplier<Applet>
|
|||||||
log.info("client-patch {}", ((Client) rs).getBuildID());
|
log.info("client-patch {}", ((Client) rs).getBuildID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SplashScreen.stage(.5, null, "Starting core classes");
|
||||||
|
|
||||||
return rs;
|
return rs;
|
||||||
}
|
}
|
||||||
catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException
|
catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException
|
||||||
| CompressorException | InvalidHeaderException | CertificateException | VerificationException
|
| CompressorException | InvalidHeaderException | CertificateException | VerificationException
|
||||||
| SecurityException e)
|
| SecurityException e)
|
||||||
{
|
{
|
||||||
if (e instanceof ClassNotFoundException)
|
|
||||||
{
|
|
||||||
log.error("Unable to load client - class not found. This means you"
|
|
||||||
+ " are not running RuneLite with Maven as the client patch"
|
|
||||||
+ " is not in your classpath.");
|
|
||||||
}
|
|
||||||
|
|
||||||
log.error("Error loading RS!", e);
|
log.error("Error loading RS!", e);
|
||||||
return null;
|
|
||||||
|
SwingUtilities.invokeLater(() -> FatalErrorDialog.showNetErrorWindow("loading the client", e));
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
*/
|
*/
|
||||||
package net.runelite.client.rs;
|
package net.runelite.client.rs;
|
||||||
|
|
||||||
class VerificationException extends Exception
|
public class VerificationException extends Exception
|
||||||
{
|
{
|
||||||
public VerificationException(String message)
|
public VerificationException(String message)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,7 +53,6 @@ import javax.swing.JButton;
|
|||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JOptionPane;
|
import javax.swing.JOptionPane;
|
||||||
import static javax.swing.JOptionPane.ERROR_MESSAGE;
|
|
||||||
import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
|
import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
@@ -111,7 +110,6 @@ public class ClientUI
|
|||||||
@Getter
|
@Getter
|
||||||
private TrayIcon trayIcon;
|
private TrayIcon trayIcon;
|
||||||
|
|
||||||
private final RuneLiteProperties properties;
|
|
||||||
private final RuneLiteConfig config;
|
private final RuneLiteConfig config;
|
||||||
private final KeyManager keyManager;
|
private final KeyManager keyManager;
|
||||||
private final MouseManager mouseManager;
|
private final MouseManager mouseManager;
|
||||||
@@ -138,7 +136,6 @@ public class ClientUI
|
|||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ClientUI(
|
private ClientUI(
|
||||||
RuneLiteProperties properties,
|
|
||||||
RuneLiteConfig config,
|
RuneLiteConfig config,
|
||||||
KeyManager keyManager,
|
KeyManager keyManager,
|
||||||
MouseManager mouseManager,
|
MouseManager mouseManager,
|
||||||
@@ -146,7 +143,6 @@ public class ClientUI
|
|||||||
ConfigManager configManager,
|
ConfigManager configManager,
|
||||||
Provider<ClientThread> clientThreadProvider)
|
Provider<ClientThread> clientThreadProvider)
|
||||||
{
|
{
|
||||||
this.properties = properties;
|
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.keyManager = keyManager;
|
this.keyManager = keyManager;
|
||||||
this.mouseManager = mouseManager;
|
this.mouseManager = mouseManager;
|
||||||
@@ -261,7 +257,7 @@ public class ClientUI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final Client client = (Client)this.client;
|
final Client client = (Client) this.client;
|
||||||
final ClientThread clientThread = clientThreadProvider.get();
|
final ClientThread clientThread = clientThreadProvider.get();
|
||||||
|
|
||||||
// Keep scheduling event until we get our name
|
// Keep scheduling event until we get our name
|
||||||
@@ -286,18 +282,17 @@ public class ClientUI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame.setTitle(properties.getTitle() + " - " + name);
|
frame.setTitle(RuneLiteProperties.getTitle() + " - " + name);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize UI.
|
* Initialize UI.
|
||||||
*
|
|
||||||
* @param runelite runelite instance that will be shut down on exit
|
* @param runelite runelite instance that will be shut down on exit
|
||||||
* @throws Exception exception that can occur during creation of the UI
|
* @throws Exception exception that can occur during creation of the UI
|
||||||
*/
|
*/
|
||||||
public void open(final RuneLite runelite) throws Exception
|
public void init(final RuneLite runelite) throws Exception
|
||||||
{
|
{
|
||||||
SwingUtilities.invokeAndWait(() ->
|
SwingUtilities.invokeAndWait(() ->
|
||||||
{
|
{
|
||||||
@@ -316,7 +311,7 @@ public class ClientUI
|
|||||||
// Try to enable fullscreen on OSX
|
// Try to enable fullscreen on OSX
|
||||||
OSXUtil.tryEnableFullscreen(frame);
|
OSXUtil.tryEnableFullscreen(frame);
|
||||||
|
|
||||||
frame.setTitle(properties.getTitle());
|
frame.setTitle(RuneLiteProperties.getTitle());
|
||||||
frame.setIconImage(ICON);
|
frame.setIconImage(ICON);
|
||||||
frame.getLayeredPane().setCursor(Cursor.getDefaultCursor()); // Prevent substance from using a resize cursor for pointing
|
frame.getLayeredPane().setCursor(Cursor.getDefaultCursor()); // Prevent substance from using a resize cursor for pointing
|
||||||
frame.setLocationRelativeTo(frame.getOwner());
|
frame.setLocationRelativeTo(frame.getOwner());
|
||||||
@@ -453,13 +448,19 @@ public class ClientUI
|
|||||||
|
|
||||||
titleToolbar.addComponent(sidebarNavigationButton, sidebarNavigationJButton);
|
titleToolbar.addComponent(sidebarNavigationButton, sidebarNavigationJButton);
|
||||||
toggleSidebar();
|
toggleSidebar();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void show()
|
||||||
|
{
|
||||||
|
SwingUtilities.invokeLater(() ->
|
||||||
|
{
|
||||||
// Layout frame
|
// Layout frame
|
||||||
frame.pack();
|
frame.pack();
|
||||||
frame.revalidateMinimumSize();
|
frame.revalidateMinimumSize();
|
||||||
|
|
||||||
// Create tray icon (needs to be created after frame is packed)
|
// Create tray icon (needs to be created after frame is packed)
|
||||||
trayIcon = SwingUtil.createTrayIcon(ICON, properties.getTitle(), frame);
|
trayIcon = SwingUtil.createTrayIcon(ICON, RuneLiteProperties.getTitle(), frame);
|
||||||
|
|
||||||
// Move frame around (needs to be done after frame is packed)
|
// Move frame around (needs to be done after frame is packed)
|
||||||
if (config.rememberScreenBounds())
|
if (config.rememberScreenBounds())
|
||||||
@@ -516,14 +517,7 @@ public class ClientUI
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Show out of date dialog if needed
|
// Show out of date dialog if needed
|
||||||
if (client == null)
|
if (client != null && !(client instanceof Client))
|
||||||
{
|
|
||||||
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(frame,
|
|
||||||
"Error loading client! Check your logs for more details.",
|
|
||||||
"Unable to load client",
|
|
||||||
ERROR_MESSAGE));
|
|
||||||
}
|
|
||||||
else if (!(client instanceof Client))
|
|
||||||
{
|
{
|
||||||
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(frame,
|
SwingUtilities.invokeLater(() -> JOptionPane.showMessageDialog(frame,
|
||||||
"RuneLite has not yet been updated to work with the latest\n"
|
"RuneLite has not yet been updated to work with the latest\n"
|
||||||
@@ -603,10 +597,10 @@ public class ClientUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes cursor for client window. Requires ${@link ClientUI#open(RuneLite)} to be called first.
|
* Changes cursor for client window. Requires ${@link ClientUI#init(RuneLite)} to be called first.
|
||||||
* FIXME: This is working properly only on Windows, Linux and Mac are displaying cursor incorrectly
|
* FIXME: This is working properly only on Windows, Linux and Mac are displaying cursor incorrectly
|
||||||
* @param image cursor image
|
* @param image cursor image
|
||||||
* @param name cursor name
|
* @param name cursor name
|
||||||
*/
|
*/
|
||||||
public void setCursor(final BufferedImage image, final String name)
|
public void setCursor(final BufferedImage image, final String name)
|
||||||
{
|
{
|
||||||
@@ -839,12 +833,12 @@ public class ClientUI
|
|||||||
|
|
||||||
if (player != null && player.getName() != null)
|
if (player != null && player.getName() != null)
|
||||||
{
|
{
|
||||||
frame.setTitle(properties.getTitle() + " - " + player.getName());
|
frame.setTitle(RuneLiteProperties.getTitle() + " - " + player.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
frame.setTitle(properties.getTitle());
|
frame.setTitle(RuneLiteProperties.getTitle());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (frame.isAlwaysOnTopSupported())
|
if (frame.isAlwaysOnTopSupported())
|
||||||
|
|||||||
@@ -0,0 +1,240 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Abex
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
|
import java.awt.Desktop;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.event.WindowAdapter;
|
||||||
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.ConnectException;
|
||||||
|
import java.net.UnknownHostException;
|
||||||
|
import java.security.GeneralSecurityException;
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.runelite.client.RuneLite;
|
||||||
|
import net.runelite.client.RuneLiteProperties;
|
||||||
|
import net.runelite.client.rs.VerificationException;
|
||||||
|
import net.runelite.client.util.LinkBrowser;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class FatalErrorDialog extends JDialog
|
||||||
|
{
|
||||||
|
private static final AtomicBoolean alreadyOpen = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
private final JPanel rightColumn = new JPanel();
|
||||||
|
private final Font font = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||||
|
|
||||||
|
public FatalErrorDialog(String message)
|
||||||
|
{
|
||||||
|
if (alreadyOpen.getAndSet(true))
|
||||||
|
{
|
||||||
|
throw new IllegalStateException("Fatal error during fatal error: " + message);
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
UIManager.put("Button.select", ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
BufferedImage logo = ImageIO.read(SplashScreen.class.getResourceAsStream("runelite_transparent.png"));
|
||||||
|
setIconImage(logo);
|
||||||
|
|
||||||
|
JLabel runelite = new JLabel();
|
||||||
|
runelite.setIcon(new ImageIcon(logo));
|
||||||
|
runelite.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
runelite.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||||
|
runelite.setOpaque(true);
|
||||||
|
rightColumn.add(runelite);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
addWindowListener(new WindowAdapter()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e)
|
||||||
|
{
|
||||||
|
System.exit(-1);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
setTitle("Fatal error starting RuneLite");
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
Container pane = getContentPane();
|
||||||
|
pane.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
|
||||||
|
JPanel leftPane = new JPanel();
|
||||||
|
leftPane.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
leftPane.setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
JLabel title = new JLabel("There was a fatal error starting RuneLite");
|
||||||
|
title.setForeground(Color.WHITE);
|
||||||
|
title.setFont(font.deriveFont(16.f));
|
||||||
|
title.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||||
|
leftPane.add(title, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
leftPane.setPreferredSize(new Dimension(400, 200));
|
||||||
|
JTextArea textArea = new JTextArea(message);
|
||||||
|
textArea.setFont(font);
|
||||||
|
textArea.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
textArea.setForeground(Color.LIGHT_GRAY);
|
||||||
|
textArea.setLineWrap(true);
|
||||||
|
textArea.setWrapStyleWord(true);
|
||||||
|
textArea.setBorder(new EmptyBorder(10, 10, 10, 10));
|
||||||
|
textArea.setEditable(false);
|
||||||
|
leftPane.add(textArea, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
pane.add(leftPane, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
rightColumn.setLayout(new BoxLayout(rightColumn, BoxLayout.Y_AXIS));
|
||||||
|
rightColumn.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||||
|
rightColumn.setMaximumSize(new Dimension(200, Integer.MAX_VALUE));
|
||||||
|
|
||||||
|
addButton("Open logs folder", () ->
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Desktop.getDesktop().open(RuneLite.LOGS_DIR);
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
log.warn("Unable to open logs", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addButton("Get help on Discord", () -> LinkBrowser.browse(RuneLiteProperties.getDiscordInvite()));
|
||||||
|
addButton("Troubleshooting steps", () -> LinkBrowser.browse(RuneLiteProperties.getTroubleshootingLink()));
|
||||||
|
|
||||||
|
pane.add(rightColumn, BorderLayout.EAST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void open()
|
||||||
|
{
|
||||||
|
addButton("Exit", () -> System.exit(-1));
|
||||||
|
|
||||||
|
pack();
|
||||||
|
SplashScreen.stop();
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FatalErrorDialog addButton(String message, Runnable action)
|
||||||
|
{
|
||||||
|
JButton button = new JButton(message);
|
||||||
|
button.addActionListener(e -> action.run());
|
||||||
|
button.setFont(font);
|
||||||
|
button.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||||
|
button.setForeground(Color.LIGHT_GRAY);
|
||||||
|
button.setBorder(BorderFactory.createCompoundBorder(
|
||||||
|
BorderFactory.createMatteBorder(1, 0, 0, 0, ColorScheme.DARK_GRAY_COLOR.brighter()),
|
||||||
|
new EmptyBorder(4, 4, 4, 4)
|
||||||
|
));
|
||||||
|
button.setAlignmentX(Component.CENTER_ALIGNMENT);
|
||||||
|
button.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE));
|
||||||
|
button.setFocusPainted(false);
|
||||||
|
button.addChangeListener(ev ->
|
||||||
|
{
|
||||||
|
if (button.getModel().isPressed())
|
||||||
|
{
|
||||||
|
button.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
}
|
||||||
|
else if (button.getModel().isRollover())
|
||||||
|
{
|
||||||
|
button.setBackground(ColorScheme.DARK_GRAY_HOVER_COLOR);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
button.setBackground(ColorScheme.DARK_GRAY_COLOR);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rightColumn.add(button);
|
||||||
|
rightColumn.revalidate();
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FatalErrorDialog addBuildingGuide()
|
||||||
|
{
|
||||||
|
return addButton("Building guide", () -> LinkBrowser.browse(RuneLiteProperties.getBuildingLink()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showNetErrorWindow(String action, Throwable err)
|
||||||
|
{
|
||||||
|
if (err instanceof VerificationException || err instanceof GeneralSecurityException)
|
||||||
|
{
|
||||||
|
new FatalErrorDialog("RuneLite was unable to verify the security of its connection to the internet while " +
|
||||||
|
action + ". You may have a misbehaving antivirus, internet service provider, a proxy, or an incomplete" +
|
||||||
|
" java installation.")
|
||||||
|
.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err instanceof ConnectException)
|
||||||
|
{
|
||||||
|
new FatalErrorDialog("RuneLite is unable to connect to a required server while " + action + ". " +
|
||||||
|
"Please check your internet connection")
|
||||||
|
.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err instanceof UnknownHostException)
|
||||||
|
{
|
||||||
|
new FatalErrorDialog("RuneLite is unable to resolve the address of a required server while " + action + ". " +
|
||||||
|
"Your DNS resolver may be misconfigured, pointing to an inaccurate resolver, or your internet connection may " +
|
||||||
|
"be down. ")
|
||||||
|
.addButton("Change your DNS resolver", () -> LinkBrowser.browse(RuneLiteProperties.getDNSChangeLink()))
|
||||||
|
.open();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new FatalErrorDialog("RuneLite encountered a fatal error while " + action + ".").open();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,232 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2019 Abex
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||||
|
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||||
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||||
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package net.runelite.client.ui;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Container;
|
||||||
|
import java.awt.Font;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import javax.swing.ImageIcon;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JProgressBar;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
import javax.swing.plaf.basic.BasicProgressBarUI;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class SplashScreen extends JFrame implements ActionListener
|
||||||
|
{
|
||||||
|
private static final int WIDTH = 200;
|
||||||
|
private static final int PAD = 10;
|
||||||
|
|
||||||
|
private static SplashScreen INSTANCE;
|
||||||
|
|
||||||
|
private final JLabel action = new JLabel("Loading");
|
||||||
|
private final JProgressBar progress = new JProgressBar();
|
||||||
|
private final JLabel subAction = new JLabel();
|
||||||
|
private final Timer timer;
|
||||||
|
|
||||||
|
private volatile double overallProgress = 0;
|
||||||
|
private volatile String actionText = "Loading";
|
||||||
|
private volatile String subActionText = "";
|
||||||
|
private volatile String progressText = null;
|
||||||
|
|
||||||
|
private SplashScreen() throws IOException
|
||||||
|
{
|
||||||
|
BufferedImage logo = ImageIO.read(SplashScreen.class.getResourceAsStream("runelite_transparent.png"));
|
||||||
|
|
||||||
|
setTitle("RuneLite Launcher");
|
||||||
|
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setUndecorated(true);
|
||||||
|
setIconImage(logo);
|
||||||
|
setLayout(null);
|
||||||
|
Container pane = getContentPane();
|
||||||
|
pane.setBackground(ColorScheme.DARKER_GRAY_COLOR);
|
||||||
|
|
||||||
|
Font font = new Font(Font.DIALOG, Font.PLAIN, 12);
|
||||||
|
|
||||||
|
JLabel logoLabel = new JLabel(new ImageIcon(logo));
|
||||||
|
pane.add(logoLabel);
|
||||||
|
logoLabel.setBounds(0, 0, WIDTH, WIDTH);
|
||||||
|
|
||||||
|
int y = WIDTH;
|
||||||
|
|
||||||
|
pane.add(action);
|
||||||
|
action.setForeground(Color.WHITE);
|
||||||
|
action.setBounds(0, y, WIDTH, 16);
|
||||||
|
action.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
action.setFont(font);
|
||||||
|
y += action.getHeight() + PAD;
|
||||||
|
|
||||||
|
pane.add(progress);
|
||||||
|
progress.setForeground(ColorScheme.BRAND_ORANGE);
|
||||||
|
progress.setBackground(ColorScheme.BRAND_ORANGE.darker().darker());
|
||||||
|
progress.setBorder(new EmptyBorder(0, 0, 0, 0));
|
||||||
|
progress.setBounds(0, y, WIDTH, 14);
|
||||||
|
progress.setFont(font);
|
||||||
|
progress.setUI(new BasicProgressBarUI()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected Color getSelectionBackground()
|
||||||
|
{
|
||||||
|
return Color.BLACK;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Color getSelectionForeground()
|
||||||
|
{
|
||||||
|
return Color.BLACK;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
y += 12 + PAD;
|
||||||
|
|
||||||
|
pane.add(subAction);
|
||||||
|
subAction.setForeground(Color.LIGHT_GRAY);
|
||||||
|
subAction.setBounds(0, y, WIDTH, 16);
|
||||||
|
subAction.setHorizontalAlignment(SwingConstants.CENTER);
|
||||||
|
subAction.setFont(font);
|
||||||
|
y += subAction.getHeight() + PAD;
|
||||||
|
|
||||||
|
setSize(WIDTH, y);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
|
||||||
|
timer = new Timer(100, this);
|
||||||
|
timer.setRepeats(true);
|
||||||
|
timer.start();
|
||||||
|
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e)
|
||||||
|
{
|
||||||
|
action.setText(actionText);
|
||||||
|
subAction.setText(subActionText);
|
||||||
|
progress.setMaximum(1000);
|
||||||
|
progress.setValue((int) (overallProgress * 1000));
|
||||||
|
|
||||||
|
String progressText = this.progressText;
|
||||||
|
if (progressText == null)
|
||||||
|
{
|
||||||
|
progress.setStringPainted(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
progress.setStringPainted(true);
|
||||||
|
progress.setString(progressText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void init()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SwingUtilities.invokeAndWait(() ->
|
||||||
|
{
|
||||||
|
if (INSTANCE != null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
|
||||||
|
INSTANCE = new SplashScreen();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
log.warn("Unable to start splash screen", e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (InterruptedException | InvocationTargetException bs)
|
||||||
|
{
|
||||||
|
throw new RuntimeException(bs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stop()
|
||||||
|
{
|
||||||
|
SwingUtilities.invokeLater(() ->
|
||||||
|
{
|
||||||
|
if (INSTANCE == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
INSTANCE.timer.stop();
|
||||||
|
INSTANCE.dispose();
|
||||||
|
INSTANCE = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stage(double overallProgress, @Nullable String actionText, String subActionText)
|
||||||
|
{
|
||||||
|
stage(overallProgress, actionText, subActionText, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stage(double startProgress, double endProgress,
|
||||||
|
@Nullable String actionText, String subActionText,
|
||||||
|
int done, int total, boolean mib)
|
||||||
|
{
|
||||||
|
String progress;
|
||||||
|
if (mib)
|
||||||
|
{
|
||||||
|
final double MiB = 1024 * 1042;
|
||||||
|
progress = String.format("%.1f / %.1f MiB", done / MiB, total / MiB);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
progress = done + " / " + total;
|
||||||
|
}
|
||||||
|
stage(startProgress + ((endProgress - startProgress) * done / total), actionText, subActionText, progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stage(double overallProgress, @Nullable String actionText, String subActionText, @Nullable String progressText)
|
||||||
|
{
|
||||||
|
if (INSTANCE != null)
|
||||||
|
{
|
||||||
|
INSTANCE.overallProgress = overallProgress;
|
||||||
|
if (actionText != null)
|
||||||
|
{
|
||||||
|
INSTANCE.actionText = actionText;
|
||||||
|
}
|
||||||
|
INSTANCE.subActionText = subActionText;
|
||||||
|
INSTANCE.progressText = progressText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,3 +6,6 @@ runelite.discord.invite=https://discord.gg/R4BQ8tU
|
|||||||
runelite.github.link=https://github.com/runelite
|
runelite.github.link=https://github.com/runelite
|
||||||
runelite.wiki.link=https://github.com/runelite/runelite/wiki
|
runelite.wiki.link=https://github.com/runelite/runelite/wiki
|
||||||
runelite.patreon.link=https://www.patreon.com/runelite
|
runelite.patreon.link=https://www.patreon.com/runelite
|
||||||
|
runelite.wiki.troubleshooting.link=https://github.com/runelite/runelite/wiki/Troubleshooting-problems-with-the-client
|
||||||
|
runelite.wiki.building.link=https://github.com/runelite/runelite/wiki/Building-with-IntelliJ-IDEA#client-failing-to-start
|
||||||
|
runelite.dnschange.link=https://1.1.1.1/dns/
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 30 KiB |
Reference in New Issue
Block a user