Skip to content
Merged

2.0.0 #1465

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
152 commits
Select commit Hold shift + click to select a range
58b2a84
feat(AIOFighter): Add Wait for Loot feature
Jul 23, 2025
fb6063d
Merge upstream/development branch changes
Aug 19, 2025
b2ab130
fix(AIOFighter): Fix wait-for-loot interrupting looting actions
Aug 19, 2025
7f1b5f9
fix(AIOFighter): Remove unnecessary formatting changes from LootScript
Aug 19, 2025
02141e3
Merge branch 'development' of https://github.com/chsami/Microbot into…
Aug 21, 2025
b2e5a93
fix(AIOFighter): Improve wait-for-loot reliability based on PR feedback
Aug 21, 2025
83f6db3
fix(AIOFighter): Allow looting during wait period even when attacked
Aug 21, 2025
cfd416d
Merge branch 'development' of https://github.com/chsami/Microbot into…
Aug 23, 2025
f202325
feat(aiofighter): add looting bag support and blighted food detection
Aug 23, 2025
e479d0e
Merge branch 'development' of https://github.com/chsami/Microbot into…
Aug 24, 2025
91ac511
fix(aiofighter): use NPC index comparison instead of object reference
Aug 24, 2025
8c75bd8
fix(aiofighter): add thread safety for wait-for-loot state variables
Aug 24, 2025
feaaade
fix(aiofighter): ensure pauseAllScripts is released in finally block
Aug 24, 2025
ff781f1
fix(aiofighter): correct instanceof check for Rs2NpcModel in target c…
Aug 24, 2025
e23cae4
fix(aiofighter): add volatile to cachedTargetNpcIndex and clamp timer…
Aug 24, 2025
ee5d188
chore(aiofighter): remove changes accidentally introduced from anothe…
Aug 24, 2025
9f1a7b2
Merge branch 'development' of https://github.com/chsami/Microbot into…
Aug 24, 2025
93ec43b
fix(aiofighter): improve UX with immediate status, cleanup imports, a…
Aug 24, 2025
e86c272
fix(aiofighter): improve inventory handling with fast food and re-check
Aug 25, 2025
285c006
fix(aiofighter): preserve concurrent pause state in LootScript
Aug 25, 2025
dd44c73
Merge branch 'development' of https://github.com/chsami/Microbot into…
Aug 25, 2025
750385a
fix(AIOfighter): fix line endings
Aug 26, 2025
b86c8bf
fix(plugin-hub): configure Cache-Control header when retrieving plugi…
gmason0 Aug 27, 2025
0b6dc49
fix(shortest-path): fix watchtower teleport & ladder
gmason0 Aug 27, 2025
563989f
fix(Rs2Spellbook): corrected the worldpoint for Tyss, fixed switchTo …
Gage307 Aug 27, 2025
622570a
fix(walker): handle boat dialouge options near molch & shaziyen
gmason0 Aug 28, 2025
8781d9f
chore: remove mta plugin
gmason0 Aug 28, 2025
861e4f3
chore: remove chompy script
gmason0 Aug 28, 2025
fdaae81
chore: prepare Varlamore Part 3 quests (#2188)
pajlada Jul 23, 2025
289d4f4
fix: Allow npcs to highlight based on composition id (#2192)
Zoinkwiz Jul 24, 2025
2720c31
feat: implement Vale Totems miniquest (#2190)
pajlada Jul 25, 2025
4c204e8
fix: Ensure rune pouch checks don't have invalid null items (#2196)
Zoinkwiz Jul 29, 2025
35b16e5
quest-helper: update sync tracking after partial sync
Voxsylvae Aug 28, 2025
8742d41
quest-helper: implement Shadows of Custodia quest (#2189)
Voxsylvae Aug 28, 2025
2b9b336
feat: implement the Scrambled! quest (#2194)
pajlada Jul 30, 2025
3c3db8a
feat: make quest section headers a JTextPane instead of JLabel (#2200)
pajlada Jul 30, 2025
480b453
Feat: the final dawn (#2193)
Zoinkwiz Jul 30, 2025
5a651fd
fix(Curse of Arrav): metal door solver (#2198)
pajlada Jul 30, 2025
bbf20b1
chore: update readme (#2201)
pajlada Jul 30, 2025
1907051
fix: Use correct title check for Clock Tower start check (#2210)
Zoinkwiz Jul 30, 2025
0ea0f8a
fix: remove varlamore part 3 quests that didn't exist (#2211)
pajlada Jul 30, 2025
3cebb0a
add food (#2185)
Zylviij Aug 9, 2025
25c6a32
fix: Allow for pure essence in ESSENCE_LOW ItemCollection (#2186)
Zoinkwiz Aug 9, 2025
0114881
fix: Update slashItem tooltip to include Noxius Halberd (#2202)
bfur66 Aug 9, 2025
3770531
Polish The Restless Ghost (#2203)
pajlada Aug 9, 2025
01a810b
fix: don't render arrow for itemsteps if option is disabled (#2204)
pajlada Aug 9, 2025
9aab9cb
feat: allow disabling of world map hint (#2205)
pajlada Aug 9, 2025
d89050f
chore: Devious Minds teleport Recommendation are more precise (#2207)
kappelhoj Aug 9, 2025
4dcb2b0
fix: The Great Brain Robbery correctly requires a disposable hammer (…
kappelhoj Aug 9, 2025
f285dc5
fix: add Amy's saw (offhand) as a possible Saw (#2213)
pajlada Aug 9, 2025
c34cab5
polish: Cook's Assistant (#2215)
pajlada Aug 9, 2025
d3b4103
Update RomeoAndJuliet.java (#2216)
mattmascolo Aug 9, 2025
573a442
fix(Scrambled!): Always suggest getting the nails (#2217)
pajlada Aug 9, 2025
f9b4982
feat: add a quest reload button in developer mode (#2224)
pajlada Aug 9, 2025
f51e870
feat(puzzle-wrapper): create with alternate text + default text (#2225)
pajlada Aug 9, 2025
5e055ee
feat(DigStep): allow customizing spade and highlight requirement (#2227)
pajlada Aug 9, 2025
04bd1ce
polish: Witch's Potion (#2229)
pajlada Aug 9, 2025
82b7dd3
polish: Sheep Shearer (#2219)
pajlada Aug 9, 2025
73a93b9
fix(The Final Dawn): step typo (#2234)
pajlada Aug 9, 2025
206d275
refactor: reformat/reorganize
pajlada Aug 2, 2025
c6998f0
fix: puzzlewrapper third & fourth puzzle
pajlada Aug 3, 2025
e230791
chore: add myself to copyright
pajlada Aug 4, 2025
02cc019
Costume needle substitution exceptions (#2233)
CritoCantCode Aug 15, 2025
240d2a3
polish: Tree Gnome Village (#2246)
pajlada Aug 15, 2025
f460892
Fremennik Isles: Go to next step after getting Jester outfit (#2249)
Zantier Aug 15, 2025
bcd43f4
polish: Barbarian training mithril dragon requirements (#2252)
jesmaail Aug 15, 2025
e697d00
feat: add option to always show debug overlay in developer mode (#2254)
pajlada Aug 15, 2025
53299fb
feat(PanelDetails): static locked panel creator (#2264)
pajlada Aug 25, 2025
a0f2b2c
polish: Pirate's Treasure (#2265)
pajlada Aug 25, 2025
cc78876
Shadows of Custodia: Change "all" damage to "most" (#2273)
Frosty-J Aug 27, 2025
9f160f1
Clarify 65 fishing is only needed for Tai Bwo Wannai trio as iron if …
ewnavilae Aug 27, 2025
07806c6
polish: Creature of Fenkenstrain (#2275)
pimpeters Aug 27, 2025
f1d432e
fix: hide mourner outfit req for ardy hard if SOTE completed (#2284)
Zoinkwiz Aug 27, 2025
649c9b0
quest-helper: complete sync to version 4.10.0
Voxsylvae Aug 28, 2025
cb416ef
quest-helper: polish Enakhras Lament
Voxsylvae Aug 29, 2025
b8014ab
quest-helper: move and update sync tracking file
Voxsylvae Aug 29, 2025
a787b6f
quest-helper: clean up old sync file location
Voxsylvae Aug 29, 2025
a913f0c
feat(agility): Add efficient alching mode with improved obstacle comp…
runsonmypc Aug 29, 2025
46620f9
chore: remove auto herblore - this is covered by bank stander
gmason0 Aug 29, 2025
5114a33
microbot:
See1Duck Aug 29, 2025
a60806f
Updated Farm Tree Runner (#1414)
Lobotobag Aug 29, 2025
a9b3fd6
feat(agility): Add Agility Pyramid course support (#1417)
runsonmypc Aug 29, 2025
5b1c8d5
feat(AIOFighter): cast Demonic Offering and Sinister Offering to proc…
Krulvis Aug 29, 2025
2baf85b
feat(webwalker): add Travel to Quest and Clue locations (#1432)
runsonmypc Aug 29, 2025
d8007f0
Merge pull request #1436 from Gage307/development
gmason0 Aug 29, 2025
9fa319a
Merge pull request #1443 from See1Duck/development
gmason0 Aug 29, 2025
3aa7491
feat(sandminer): drop empty waterskins when humidify disabled (#1440)
runsonmypc Aug 29, 2025
9d2a7bc
Update README.md
chsami Aug 30, 2025
1f5790b
Update README.md
chsami Aug 30, 2025
9a9cf66
Merge pull request #1442 from Voxsylvae/quest-helper-update-20250829_…
chsami Aug 30, 2025
b7b8733
microbot:
See1Duck Aug 30, 2025
8326671
ShortestPathPlugin: fix(getClosestLocation): restore original bank it…
See1Duck Aug 30, 2025
3e5467f
microbot:
See1Duck Aug 30, 2025
35fe1b1
FlickerScript: fix(lastAttack): include NPC animation check for force…
See1Duck Aug 30, 2025
89487b6
LootScript:
See1Duck Aug 30, 2025
6dc57e7
Merge branch 'chsami:development' into development
See1Duck Aug 30, 2025
f4d1c61
Frostyrc fixes (#1429)
Netoxique Aug 30, 2025
8b1374b
fix(mahoganyhomes): optimize banking and NPC interaction performance …
runsonmypc Aug 30, 2025
c8fdb64
feat(QoL): Add Grand Exchange paste and search hotkey
RogerAngell99 Aug 30, 2025
f1cf4b2
Merge pull request #3 from chsami/main
Netoxique Aug 30, 2025
d78b9a8
Check logout setting as boolean.
Netoxique Aug 30, 2025
ce17e9d
Also actually log out if logout option is enabled..
Netoxique Aug 30, 2025
83bbbfb
Added tracking for the pre-break world and if a logout occurred.
Netoxique Aug 30, 2025
f6f0dcc
Fixed typo.
Netoxique Aug 30, 2025
9a40cfa
Added region filter drop-down for Random World.
Netoxique Aug 30, 2025
436dcf8
Added check for random world check and region filter.
Netoxique Aug 30, 2025
ac9c0f3
Enum for region filter selection.
Netoxique Aug 30, 2025
771f1d2
Changed version since new feature, random world filter, was added.
Netoxique Aug 30, 2025
ee2f71b
feat(microbot): migrate installedPlugins into the runelite config to …
gmason0 Aug 30, 2025
4c7284d
fix(bf): simplfy energy potion/stamina potion usage
gmason0 Aug 30, 2025
6ea7322
Added checks for microbreak option when checking for break cases.
Netoxique Aug 30, 2025
04f081a
Ensured the Antiban now evaluates microbreak only when micro breaks a…
Netoxique Aug 30, 2025
10eb2d8
Revert "Ensured the Antiban now evaluates microbreak only when micro …
Netoxique Aug 30, 2025
481b3be
Revert "Added checks for microbreak option when checking for break ca…
Netoxique Aug 30, 2025
110d7f4
autologin region filters (#1448)
v3tcn Aug 31, 2025
59e35d3
chore: bump to 1.9.9.2
gmason0 Aug 31, 2025
2d4a7f8
refactor(BlockingEventManager): implement exponential backoff for eve…
chsami Aug 31, 2025
d81bc06
Merge remote-tracking branch 'origin/development' into development
chsami Aug 31, 2025
943ba82
fix(version-checker): only display message in title if the remote ver…
gmason0 Aug 31, 2025
f1925a9
fix(MicrobotPluginManager): implement no-proxy OkHttpClient for plugi…
chsami Aug 31, 2025
37b8fc8
fix(plugin-manager): make getInstalledPlugins return a mutable list i…
gmason0 Aug 31, 2025
d0af195
feat(proxy): implement proxy configuration and detection for microbot
chsami Aug 31, 2025
20d8ff2
Merge pull request #1452 from ErnestoReza/break_handler_fixes
chsami Aug 31, 2025
5a88cb1
feat(proxy): implement proxy configuration and detection for microbot
chsami Aug 31, 2025
8ca05cb
fix(SplashScreen): refactor scheduled executor service for random facts
chsami Aug 31, 2025
b69dcc5
Merge pull request #1455 from chsami/chsami/proxy_splashsscreen_rework
chsami Aug 31, 2025
7362733
Fix Rs2Inventory to check for stackable birdsnares
T-edit Aug 31, 2025
8efbf38
Merge pull request #1457 from T-edit/birdhuntertrap
chsami Sep 1, 2025
a48a401
Isle of Souls dungeon cave entrance/exit added. (#1459)
Sunny-P Sep 1, 2025
eeb3a84
fix(util/npc): Ensure thread safety in NPC fetching
MakeCD Sep 1, 2025
95cfb06
feat(prayer): add options to use bounds of widget to click the prayer…
gmason0 Sep 1, 2025
a878a4e
Merge pull request #1449 from RogerAngell99/feat/qol-ge-hotkey
chsami Sep 1, 2025
a1c9a4d
Merge pull request #1460 from MakeCD/fix-getNpcs-function
chsami Sep 2, 2025
fef4210
fix(plugin-hub): further improvements to loading & unloading plugins …
gmason0 Sep 2, 2025
2877ef4
chore(SplashScreen): add copyright notice and licensing information
chsami Sep 2, 2025
5896a42
chore(pluginmanager): migrate filtering/loading microbot core plugins…
gmason0 Sep 3, 2025
1d4a2cc
chore(pluginmanager): recommended changes from coderabbit
gmason0 Sep 3, 2025
0b26cdd
Frostyrc break + startup fixes (#1461)
Netoxique Sep 3, 2025
66efea8
fix(Moons Of Peril): Improvements to inventory management during resu…
FunkyMonkeyCloud Sep 3, 2025
e1d49dd
chore(shortest-path): restrict vines in catacombs of kourend to preve…
gmason0 Sep 2, 2025
b61c770
chore(shortest-path): move handleTrapdoor logic into handleObjectExce…
gmason0 Sep 2, 2025
c8a29ec
chore(shortest-path): add manual restrictions near castle wars
gmason0 Sep 3, 2025
bf27dde
chore(walker): reduce constants duplication
gmason0 Sep 3, 2025
b10e49b
chore: remove plugins migrated to plugin hub
gmason0 Sep 3, 2025
0cfb4a1
chore: fix build issues
gmason0 Sep 3, 2025
e2e7ab5
Merge pull request #1462 from g-mason0/fix/plugin-hub-profiles
chsami Sep 3, 2025
bcb803e
Merge pull request #1463 from g-mason0/feat/rs2prayer-refactor
chsami Sep 3, 2025
51d4777
Merge pull request #1402 from runsonmypc/aio-fighter-wait-for-loot
chsami Sep 3, 2025
5fb5ad0
Merge branch 'development' into development
chsami Sep 3, 2025
ae74da5
Merge pull request #1445 from See1Duck/development
chsami Sep 3, 2025
05a37e4
chore(SplashScreen): add copyright notice and licensing information
chsami Sep 3, 2025
19fa74d
chore(pom.xml): update microbot version to 2.0.0
chsami Sep 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,32 @@ If you have any questions, please join our [Discord](https://discord.gg/zaGrfqFE

If you enjoy my open source work and would like to support me, consider buying me a coffee! Your support helps me stay caffeinated and motivated to keep improving and creating awesome projects.

## Quest Helper Integration

The integrated Quest Helper works together with other plugins to give a nice unified experience while questing.

### Not Enough Runes

If you have the [Not Enough Runes](https://runelite.net/plugin-hub/show/not-enough-runes) plugin installed, you can
right-click item requirements and click `Go to NER...` to look that item up in Not Enough Runes.

![Not Enough Runes context menu](./images/not-enough-runes-01.png)

### Shortest Path

If you have the [Shortest Path](https://runelite.net/plugin-hub/show/shortest-path) plugin installed, you can enable the
the "Use 'Shortest Path' plugin" in the Quest Helper config.

![](./images/shortest-path-01.png)

Next time you start a quest, the Shortest Path plugin will help you take the shortest path to the destination.

![Shortest Path path overlay example](./images/shortest-path-02.png)

You can configure what teleportation methods, or the aesthetic of the path in the Shortest Path config.

## Help and discussion

[![Buy Me a Coffee](https://img.shields.io/badge/Buy%20Me%20a%20Coffee-donate-yellow)](https://www.paypal.com/paypalme/MicrobotBE?country.x=BE)


Expand Down
Binary file added images/not-enough-runes-01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/shortest-path-01.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/shortest-path-02.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion runelite-client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
<git.commit.id.abbrev>nogit</git.commit.id.abbrev>
<git.dirty>false</git.dirty>
<shade.skip>false</shade.skip>
<microbot.version>1.9.9.1</microbot.version>
<microbot.version>2.0.0</microbot.version>
<microbot.commit.sha>nogit</microbot.commit.sha>
</properties>

Expand Down
66 changes: 22 additions & 44 deletions runelite-client/src/main/java/net/runelite/client/RuneLite.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.externalplugins.ExternalPluginManager;
import net.runelite.client.plugins.PluginManager;
import net.runelite.client.plugins.microbot.Microbot;
import net.runelite.client.plugins.microbot.externalplugins.MicrobotPluginManager;
import net.runelite.client.proxy.ProxyChecker;
import net.runelite.client.proxy.ProxyConfiguration;
import net.runelite.client.rs.ClientLoader;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.FatalErrorDialog;
Expand Down Expand Up @@ -76,8 +79,6 @@
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
Expand Down Expand Up @@ -186,9 +187,8 @@ public static void main(String[] args) throws Exception {
parser.accepts("noupdate", "Skips the launcher update");
parser.accepts("clean-randomdat", "Clean random dat file");

final ArgumentAcceptingOptionSpec<String> proxyInfo = parser.accepts("proxy", "Use a proxy server for your runelite session")
final ArgumentAcceptingOptionSpec<String> proxyInfo = parser.accepts("proxy", "Use a specified proxy. Format: scheme://user:pass@host:port")
.withRequiredArg().ofType(String.class);
parser.accepts("proxy-type", "The Type of proxy: HTTP or SOCKS").withRequiredArg().ofType(String.class);
final ArgumentAcceptingOptionSpec<File> sessionfile = parser.accepts("sessionfile", "Use a specified session file")
.withRequiredArg()
.withValuesConvertedBy(new ConfigFileConverter())
Expand Down Expand Up @@ -249,46 +249,7 @@ public static void main(String[] args) throws Exception {
}
}

//More information about java proxies can be found here
//https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
//usage: -proxy=IP:PORT:USER:PASS -proxytype=SOCKS
//OR
//usage: -proxy=IP:PORT:USER:PASS -proxytype=HTTP
if (options.has("proxy")) {
String[] proxy = options.valueOf(proxyInfo).split(":");
boolean httpProxy = false;
boolean socksProxy = true; //default we take socks proxy
if (options.has("proxy-type")) {
socksProxy = options.valueOf("proxy-type").toString().equalsIgnoreCase("SOCKS");
httpProxy = options.valueOf("proxy-type").toString().equalsIgnoreCase("HTTP");
}

ClientUI.proxyMessage = (socksProxy ? "SOCKS" : "HTTP") + " Proxy with address " + options.valueOf(proxyInfo);

if (httpProxy && proxy.length >= 2) {
System.setProperty("http.proxyHost", proxy[0]);
System.setProperty("http.proxyPort", proxy[1]);
} else if (socksProxy && proxy.length >= 2) {
System.setProperty("socksProxyHost", proxy[0]);
System.setProperty("socksProxyPort", proxy[1]);
}

if (socksProxy && proxy.length >= 4) {
System.setProperty("java.net.socks.username", proxy[2]);
System.setProperty("java.net.socks.password", proxy[3]);

final String user = proxy[2];
final char[] pass = proxy[3].toCharArray();

Authenticator.setDefault(new Authenticator() {
private final PasswordAuthentication auth = new PasswordAuthentication(user, pass);

protected PasswordAuthentication getPasswordAuthentication() {
return auth;
}
});
}
}
ProxyConfiguration.setupProxy(options, proxyInfo);

Thread.setDefaultUncaughtExceptionHandler((thread, throwable) ->
{
Expand All @@ -302,6 +263,19 @@ protected PasswordAuthentication getPasswordAuthentication() {
RuneLiteAPI.CLIENT = okHttpClient;

SplashScreen.init();

SplashScreen.stage(0, "Setting up proxy", "Testing proxy address...");

if (options.has(proxyInfo)) {
String ip = ProxyChecker.getDetectedIp(okHttpClient);
if (ip.isEmpty()) {
Microbot.showMessage("Failed to detect external IP address, check your proxy settings. \n\n Make sure to use the format scheme://user:pass@host:port");
System.exit(1);
}

ClientUI.proxyMessage = " - Proxy enabled (detected IP " + ip + ")";
}

SplashScreen.stage(0, "Preparing RuneScape", "");

try
Expand Down Expand Up @@ -458,6 +432,9 @@ public void start() throws Exception
// Load user configuration
configManager.load();

// Initialize MicrobotPluginManager after configManager is loaded
microbotPluginManager.init();

// Update check requires ConfigManager to be ready before it runs
Updater updater = injector.getInstance(Updater.class);
updater.update(); // will exit if an update is in progress
Expand Down Expand Up @@ -492,6 +469,7 @@ public void start() throws Exception
eventBus.register(clientUI);
eventBus.register(pluginManager);
eventBus.register(externalPluginManager);
eventBus.register(microbotPluginManager);
eventBus.register(overlayManager);
eventBus.register(configManager);
eventBus.register(discordService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,10 @@
import net.runelite.client.eventbus.EventBus;
import net.runelite.client.externalplugins.ExternalPluginManager;
import net.runelite.client.plugins.PluginManager;
import net.runelite.client.plugins.microbot.Microbot;
import net.runelite.client.plugins.microbot.MicrobotClientLoader;
import net.runelite.client.plugins.microbot.externalplugins.MicrobotPluginManager;
import net.runelite.client.proxy.ProxyChecker;
import net.runelite.client.ui.ClientUI;
import net.runelite.client.ui.FatalErrorDialog;
import net.runelite.client.ui.SplashScreen;
Expand Down Expand Up @@ -73,8 +75,6 @@
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.Authenticator;
import java.net.PasswordAuthentication;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
Expand Down Expand Up @@ -174,7 +174,6 @@ public static void main(String[] args) throws Exception {

final ArgumentAcceptingOptionSpec<String> proxyInfo = parser.accepts("proxy", "Use a proxy server for your runelite session")
.withRequiredArg().ofType(String.class);
parser.accepts("proxy-type", "The Type of proxy: HTTP or SOCKS").withRequiredArg().ofType(String.class);
final ArgumentAcceptingOptionSpec<File> sessionfile = parser.accepts("sessionfile", "Use a specified session file")
.withRequiredArg()
.withValuesConvertedBy(new ConfigFileConverter())
Expand Down Expand Up @@ -208,47 +207,6 @@ public static void main(String[] args) throws Exception {
logger.setLevel(Level.DEBUG);
}

//More information about java proxies can be found here
//https://docs.oracle.com/javase/8/docs/technotes/guides/net/proxies.html
//usage: -proxy=IP:PORT:USER:PASS -proxytype=SOCKS
//OR
//usage: -proxy=IP:PORT:USER:PASS -proxytype=HTTP
if (options.has("proxy")) {
String[] proxy = options.valueOf(proxyInfo).split(":");
boolean httpProxy = false;
boolean socksProxy = true; //default we take socks proxy
if (options.has("proxy-type")) {
socksProxy = options.valueOf("proxy-type").toString().equalsIgnoreCase("SOCKS");
httpProxy = options.valueOf("proxy-type").toString().equalsIgnoreCase("HTTP");
}

ClientUI.proxyMessage = (socksProxy ? "SOCKS" : "HTTP") + " Proxy with address " + options.valueOf(proxyInfo);

if (httpProxy && proxy.length >= 2) {
System.setProperty("http.proxyHost", proxy[0]);
System.setProperty("http.proxyPort", proxy[1]);
} else if (socksProxy && proxy.length >= 2) {
System.setProperty("socksProxyHost", proxy[0]);
System.setProperty("socksProxyPort", proxy[1]);
}

if (socksProxy && proxy.length >= 4) {
System.setProperty("java.net.socks.username", proxy[2]);
System.setProperty("java.net.socks.password", proxy[3]);

final String user = proxy[2];
final char[] pass = proxy[3].toCharArray();

Authenticator.setDefault(new Authenticator() {
private final PasswordAuthentication auth = new PasswordAuthentication(user, pass);

protected PasswordAuthentication getPasswordAuthentication() {
return auth;
}
});
}
}

Thread.setDefaultUncaughtExceptionHandler((thread, throwable) ->
{
log.error("Uncaught exception:", throwable);
Expand All @@ -262,6 +220,17 @@ protected PasswordAuthentication getPasswordAuthentication() {
RuneLiteAPI.CLIENT = okHttpClient;

SplashScreen.init();

if (options.has(proxyInfo)) {
String ip = ProxyChecker.getDetectedIp(okHttpClient);
if (ip.isEmpty()) {
Microbot.showMessage("Failed to detect external IP address, check your proxy settings. \n\n Make sure to use the format scheme://user:pass@host:port");
System.exit(1);
}

ClientUI.proxyMessage = " - Proxy enabled (detected IP " + ip + ")";
}

SplashScreen.stage(0, "Retrieving client", "");

try {
Expand Down Expand Up @@ -364,6 +333,9 @@ public void start() throws Exception {
// Load user configuration
configManager.load();

// Initialize MicrobotPluginManager after configManager is loaded
microbotPluginManager.init();

// Update check requires ConfigManager to be ready before it runs
Updater updater = injector.getInstance(Updater.class);
updater.update(); // will exit if an update is in progress
Expand All @@ -390,6 +362,7 @@ public void start() throws Exception {
eventBus.register(clientUI);
eventBus.register(pluginManager);
eventBus.register(externalPluginManager);
eventBus.register(microbotPluginManager);
eventBus.register(overlayManager);
eventBus.register(configManager);
eventBus.register(discordService);
Expand All @@ -403,7 +376,7 @@ public void start() throws Exception {

clientUI.show();

pluginManager.loadRuneliteCorePlugins();
pluginManager.loadCoreRunelitePlugins();

microbotPluginManager.loadCorePlugins(pluginsToDebug);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,58 +215,48 @@ public void startPlugins() {
}
}

public void loadCorePlugins() throws IOException, PluginInstantiationException {
SplashScreen.stage(.59, null, "Loading plugins");
/**
* Loads core RuneLite plugins, excluding any Microbot-related plugins.
* This method filters out plugins from the microbot package hierarchy.
*/
public void loadCoreRunelitePlugins() throws IOException, PluginInstantiationException {
SplashScreen.stage(.59, null, "Loading core RuneLite plugins");
ClassPath classPath = ClassPath.from(getClass().getClassLoader());

List<Class<?>> plugins = classPath.getTopLevelClassesRecursive(PLUGIN_PACKAGE).stream()
.map(ClassInfo::load)
.filter(clazz -> !isMicrobotRelatedClass(clazz))
.collect(Collectors.toList());

loadPlugins(plugins, (loaded, total) ->
SplashScreen.stage(.60, .70, null, "Loading plugins", loaded, total, false));
SplashScreen.stage(.60, .70, null, "Loading core RuneLite plugins", loaded, total, false));
}

/**
* This excludes any microbot plugin
* Determines if a class is related to Microbot and should be excluded from core RuneLite plugin loading.
*
* @throws IOException
* @throws PluginInstantiationException
* @param clazz the class to check
* @return true if the class is Microbot-related and should be filtered out
*/
public void loadRuneliteCorePlugins() throws IOException, PluginInstantiationException {
private static boolean isMicrobotRelatedClass(Class<?> clazz) {
if (clazz == null || clazz.getPackage() == null) {
return false;
}

String packageName = clazz.getPackage().getName();

return packageName.startsWith(PLUGIN_PACKAGE + ".microbot");
}

public void loadCorePlugins() throws IOException, PluginInstantiationException {
SplashScreen.stage(.59, null, "Loading plugins");
ClassPath classPath = ClassPath.from(getClass().getClassLoader());

List<Class<?>> microbotPlugins = new ArrayList<>();
List<Class<?>> otherPlugins = new ArrayList<>();

for (ClassInfo classInfo : classPath.getTopLevelClassesRecursive(PLUGIN_PACKAGE)) {

Class<?> clazz = classInfo.load();
String pkg = clazz.getPackageName().toLowerCase();


/**
* TODO: Over time these should be moved into a core folder within the microbot plugins folder
* This way we can easily detect any core plugins required to run microbot
*/
if (pkg.contains(".microbot") && (
pkg.contains(".util")
|| pkg.contains(".ui")
|| pkg.endsWith("microbot")
|| pkg.contains(".shortestpath")
|| pkg.contains(".rs2cachedebugger")
|| pkg.contains("pluginscheduler")
|| pkg.contains("inventorysetups"))) {
microbotPlugins.add(clazz);
} else if (!pkg.contains("microbot")) {
otherPlugins.add(clazz);
}
}

otherPlugins.addAll(microbotPlugins);
List<Class<?>> plugins = classPath.getTopLevelClassesRecursive(PLUGIN_PACKAGE).stream()
.map(ClassInfo::load)
.collect(Collectors.toList());

loadPlugins(otherPlugins, (loaded, total) ->
loadPlugins(plugins, (loaded, total) ->
SplashScreen.stage(.60, .70, null, "Loading plugins", loaded, total, false));
}

Expand Down
Loading