diff --git a/runelite-client/pom.xml b/runelite-client/pom.xml index 1978e7ae8a9..eb5c87c18ea 100644 --- a/runelite-client/pom.xml +++ b/runelite-client/pom.xml @@ -41,7 +41,7 @@ nogit false false - 2.0.34 + 2.0.35 nogit diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 5270f5d1734..36a3eef4c99 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -724,12 +724,11 @@ public void load() log.info("Creating profile: {} ({})", profile.getName(), profile.getId()); } - // synced profile need to be fetched if outdated + // synced profautoogile need to be fetched if outdated syncRemote(lock, profile, remoteProfiles); this.profile = profile; configProfile = new ConfigData(ProfileManager.profileConfigFile(profile)); - LoginManager.setActiveProfile(profile); } eventBus.post(new ProfileChanged()); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/accountselector/AutoLoginScript.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/accountselector/AutoLoginScript.java index 4bcb093913e..bb5c9d9376e 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/accountselector/AutoLoginScript.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/accountselector/AutoLoginScript.java @@ -23,15 +23,15 @@ */ @Slf4j public class AutoLoginScript extends Script { - + // ban detection constants private static final int BANNED_LOGIN_INDEX = 14; - + // ban detection state public static boolean isBanned = false; private static String lastKnownPlayerName = ""; private boolean wasLoggedIn = false; - + // Login state management private enum LoginState { WAITING_FOR_LOGIN_SCREEN, @@ -39,7 +39,7 @@ private enum LoginState { LOGIN_EXTENDED_SLEEP, ERROR } - + private LoginState loginState = LoginState.WAITING_FOR_LOGIN_SCREEN; private int retryCount = 0; private Instant loginWatchdogStartTime = null; @@ -50,17 +50,16 @@ private enum LoginState { public boolean run(AutoLoginConfig autoLoginConfig) { log.info("Starting AutoLogin script with world selection"); - + mainScheduledFuture = scheduledExecutorService.scheduleWithFixedDelay(() -> { try { if (!super.run()) return; if (BreakHandlerScript.isBreakActive() || BreakHandlerScript.isMicroBreakActive()) return; - // check for ban detection first checkForBan(); updatePlayerNameCache(); - + // only continue with login if not banned if (!isBanned) { processAutoLoginStateMachine(autoLoginConfig); @@ -73,7 +72,7 @@ public boolean run(AutoLoginConfig autoLoginConfig) { }, 0, 600, TimeUnit.MILLISECONDS); return true; } - + /** * Main state machine for auto login processing. */ @@ -94,7 +93,7 @@ private void processAutoLoginStateMachine(AutoLoginConfig config) { return; } } - + /** * State: WAITING_FOR_LOGIN_SCREEN * Monitoring for login screen to appear. @@ -105,15 +104,12 @@ private void handleWaitingForLoginScreenState(AutoLoginConfig config) { resetLoginState(); return; } - - - if (Microbot.getClient()!=null && Microbot.getClient().getGameState() == GameState.LOGIN_SCREEN) { - log.info("Login screen detected, initiating login"); - initiateLogin(config); - transitionToState(LoginState.ATTEMPTING_LOGIN); - } + + log.info("Login screen detected, initiating login"); + initiateLogin(config); + transitionToState(LoginState.ATTEMPTING_LOGIN); } - + /** * State: ATTEMPTING_LOGIN * Currently attempting to log in with watchdog monitoring. @@ -125,7 +121,7 @@ private void handleAttemptingLoginState(AutoLoginConfig config) { transitionToState(LoginState.WAITING_FOR_LOGIN_SCREEN); return; } - + // check login watchdog timeout if enabled if (config.enableLoginWatchdog() && loginWatchdogStartTime != null) { long watchdogTime = Duration.between(loginWatchdogStartTime, Instant.now()).toMinutes(); @@ -136,7 +132,7 @@ private void handleAttemptingLoginState(AutoLoginConfig config) { return; } } - + // check if enough time has passed for retry if (lastLoginAttemptTime != null) { long timeSinceLastAttempt = Duration.between(lastLoginAttemptTime, Instant.now()).toSeconds(); @@ -144,7 +140,7 @@ private void handleAttemptingLoginState(AutoLoginConfig config) { return; // wait for retry delay } } - + // check retry limit if (retryCount >= config.maxLoginRetries()) { if (config.enableLoginWatchdog()) { @@ -157,9 +153,9 @@ private void handleAttemptingLoginState(AutoLoginConfig config) { } return; } - + // check if still on login screen - if (Microbot.getClient()!=null && Microbot.getClient().getGameState() == GameState.LOGIN_SCREEN) { + if (Microbot.getClient() != null && Microbot.getClient().getGameState() == GameState.LOGIN_SCREEN) { log.info("Retrying login attempt {} of {}", retryCount + 1, config.maxLoginRetries()); int currentLoginIndex = Microbot.getClient().getLoginIndex(); if (Microbot.getClient().getLoginIndex() == 3 || Microbot.getClient().getLoginIndex() == 24) { // you were disconnected from the server. @@ -171,7 +167,7 @@ private void handleAttemptingLoginState(AutoLoginConfig config) { log.error("Authentication failed, please check credentials"); handleGeneralFailure("Authentication failed - invalid credentials"); transitionToState(LoginState.ERROR); - return; + return; } if (currentLoginIndex == 34) { // we are not a member and cannot login log.error("Account is not a member, cannot login to members world"); @@ -186,18 +182,18 @@ private void handleAttemptingLoginState(AutoLoginConfig config) { transitionToState(LoginState.ERROR); return; } - + // we have to find out other indexes that mean we cannot login initiateLogin(config); } else { - - + + // not on login screen anymore, return to waiting resetLoginState(); transitionToState(LoginState.WAITING_FOR_LOGIN_SCREEN); } } - + /** * State: LOGIN_EXTENDED_SLEEP * Extended sleep state after login failures. @@ -209,13 +205,13 @@ private void handleLoginExtendedSleepState(AutoLoginConfig config) { transitionToState(LoginState.WAITING_FOR_LOGIN_SCREEN); return; } - + if (extendedSleepStartTime == null) { extendedSleepStartTime = Instant.now(); log.info("Extended sleep started for {} minutes", config.extendedSleepDuration()); return; } - + // check if extended sleep period is complete long sleepTime = Duration.between(extendedSleepStartTime, Instant.now()).toMinutes(); if (sleepTime >= config.extendedSleepDuration()) { @@ -231,7 +227,7 @@ private void handleLoginExtendedSleepState(AutoLoginConfig config) { } } } - + /** * Initiates intelligent login based on configuration. */ @@ -242,81 +238,81 @@ private void initiateLogin(AutoLoginConfig config) { loginWatchdogStartTime = Instant.now(); log.info("Login watchdog started for {} minutes", config.loginWatchdogTimeout()); } - + int targetWorld = -1; - + boolean membersOnly = config.membersOnly(); - + // use world selection mode if no preferred world or preferred world not accessible if (targetWorld == -1) { switch (config.worldSelectionMode()) { case CURRENT_PREFERRED_WORLD: boolean isAccessible = Rs2WorldUtil.canAccessWorld(config.world()); - + if (isAccessible) { targetWorld = config.world(); log.info("Using preferred world: {}", targetWorld); } else { ConfigProfile activeProfile = LoginManager.getActiveProfile(); boolean isMemberFromProfile = activeProfile != null && activeProfile.isMember(); - boolean isLocalPlayerAvailable = Microbot.getClient()!=null && Microbot.getClient().getLocalPlayer() != null; - boolean isMemberFromClient = Microbot.getClient()!=null && Microbot.getClient().getLocalPlayer() != null ? Rs2Player.isMember() : false; - log.error("Preferred world {} is not accessible,\n\t ->check if we have member access set in profile(current value {}), or when logged in, have we member access ? (LocalPlayer? {}, isMember? {})", - config.usePreferredWorld(), isMemberFromProfile, isLocalPlayerAvailable, isMemberFromClient); + boolean isLocalPlayerAvailable = Microbot.getClient() != null && Microbot.getClient().getLocalPlayer() != null; + boolean isMemberFromClient = Microbot.getClient() != null && Microbot.getClient().getLocalPlayer() != null ? Rs2Player.isMember() : false; + log.error("Preferred world {} is not accessible,\n\t ->check if we have member access set in profile(current value {}), or when logged in, have we member access ? (LocalPlayer? {}, isMember? {})", + config.usePreferredWorld(), isMemberFromProfile, isLocalPlayerAvailable, isMemberFromClient); } // no specific world selection - use default login break; - + case RANDOM_WORLD: targetWorld = Rs2WorldUtil.getRandomAccessibleWorldFromRegion( - config.regionPreference().getWorldRegion(), - config.avoidEmptyWorlds(), - config.avoidOvercrowdedWorlds(),membersOnly); + config.regionPreference().getWorldRegion(), + config.avoidEmptyWorlds(), + config.avoidOvercrowdedWorlds(), membersOnly); break; - + case BEST_POPULATION: targetWorld = Rs2WorldUtil.getBestAccessibleWorldForLogin( - false, - config.regionPreference().getWorldRegion(), - config.avoidEmptyWorlds(), - config.avoidOvercrowdedWorlds(), - membersOnly); + false, + config.regionPreference().getWorldRegion(), + config.avoidEmptyWorlds(), + config.avoidOvercrowdedWorlds(), + membersOnly); break; - + case BEST_PING: targetWorld = Rs2WorldUtil.getBestAccessibleWorldForLogin( - true, - config.regionPreference().getWorldRegion(), - config.avoidEmptyWorlds(), - config.avoidOvercrowdedWorlds(), - membersOnly - ); + true, + config.regionPreference().getWorldRegion(), + config.avoidEmptyWorlds(), + config.avoidOvercrowdedWorlds(), + membersOnly + ); break; - + case REGIONAL_RANDOM: targetWorld = Rs2WorldUtil.getRandomAccessibleWorldFromRegion( - config.regionPreference().getWorldRegion(), - config.avoidEmptyWorlds(), - config.avoidOvercrowdedWorlds(), - membersOnly - ); + config.regionPreference().getWorldRegion(), + config.avoidEmptyWorlds(), + config.avoidOvercrowdedWorlds(), + membersOnly + ); break; - + default: // fallback to legacy behavior - targetWorld = LoginManager.getRandomWorld(Rs2Player.isMember()); - if(!Rs2WorldUtil.canAccessWorld(targetWorld)) { + targetWorld = LoginManager.getRandomWorld(Rs2Player.isMember()); + if (!Rs2WorldUtil.canAccessWorld(targetWorld)) { log.warn("Randomly selected world {} is not accessible, using default world {}", targetWorld, config.world()); targetWorld = config.world(); - } + } break; } } - + // perform login attempt and track retry state retryCount++; lastLoginAttemptTime = Instant.now(); - + boolean loginInitiated; if (targetWorld != -1) { log.info("Attempting login to selected world: {} (attempt {})", targetWorld, retryCount); @@ -328,17 +324,17 @@ private void initiateLogin(AutoLoginConfig config) { if (!loginInitiated) { log.debug("AutoLogin detected rejected attempt (gameState: {}, attemptActive: {})", - LoginManager.getGameState(), LoginManager.isLoginAttemptActive()); + LoginManager.getGameState(), LoginManager.isLoginAttemptActive()); } - - + + } catch (Exception ex) { log.error("Error during intelligent login", ex); retryCount++; lastLoginAttemptTime = Instant.now(); } } - + /** * Transitions to a new login state. */ @@ -348,7 +344,7 @@ private void transitionToState(LoginState newState) { loginState = newState; } } - + /** * Resets login state variables. */ @@ -360,17 +356,17 @@ private void resetLoginState() { lastExtendedSleepLoggedMinute = -1; loginState = LoginState.WAITING_FOR_LOGIN_SCREEN; } - + /** * checks for ban screen during login attempt or when logged out */ private void checkForBan() { GameState gameState = Microbot.getClient().getGameState(); - + // detect ban screen on login screen boolean banDetected = gameState == GameState.LOGIN_SCREEN && Microbot.getClient().getLoginIndex() == BANNED_LOGIN_INDEX; - + if (banDetected && !isBanned) { isBanned = true; handleBanDetection(); @@ -382,7 +378,7 @@ private void checkForBan() { */ private void updatePlayerNameCache() { boolean currentlyLoggedIn = Microbot.isLoggedIn(); - + // detect fresh login - update player name cache if (currentlyLoggedIn && !wasLoggedIn) { Rs2PlayerModel localPlayer = Rs2Player.getLocalPlayer(); @@ -391,7 +387,7 @@ private void updatePlayerNameCache() { log.info("Updated cached player name: {}", lastKnownPlayerName); } } - + wasLoggedIn = currentlyLoggedIn; } @@ -400,10 +396,10 @@ private void updatePlayerNameCache() { */ private void handleBanDetection() { log.info("Ban screen detected for player: {}", lastKnownPlayerName); - + // send discord notification if webhook is configured sendBanDiscordNotification(); - + // shutdown auto login plugin shutdownPlugin(); } @@ -413,10 +409,10 @@ private void handleBanDetection() { */ private void handleGeneralFailure(String failureReason) { log.info("Login failure detected for player: {} - {}", lastKnownPlayerName, failureReason); - + // send discord notification if webhook is configured sendFailureDiscordNotification(failureReason); - + // shutdown auto login plugin after failure shutdownPlugin(); } @@ -434,11 +430,11 @@ private void sendBanDiscordNotification() { fields.add(Rs2Discord.createField("Source", "AutoLogin", true)); boolean success = Rs2Discord.sendNotificationWithFields( - "🚫 Account Ban Detected", - "Ban screen detected during login attempt.", - 0xDC143C, // crimson red - fields, - "AutoLogin Ban Detection" + "🚫 Account Ban Detected", + "Ban screen detected during login attempt.", + 0xDC143C, // crimson red + fields, + "AutoLogin Ban Detection" ); if (success) { @@ -476,18 +472,18 @@ private void shutdownPlugin() { try { log.info("Shutting down {} plugin due to failure detection", AutoLoginPlugin.class.getSimpleName()); Microbot.stopPlugin(AutoLoginPlugin.class); - + } catch (Exception ex) { log.error("Error shutting down {} plugin", AutoLoginPlugin.class.getSimpleName(), ex); } } - + @Override public void shutdown() { log.info("Auto login script shutting down"); resetLoginState(); super.shutdown(); - + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java index 7104311fc18..a3d695cbb74 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/externalplugins/MicrobotPluginManager.java @@ -1098,18 +1098,19 @@ private void stopPlugin(Plugin plugin) { String pluginName = plugin.getClass().getSimpleName(); try { - if (pluginManager.isPluginEnabled(plugin)) { - pluginManager.setPluginEnabled(plugin, false); - } - if (pluginManager.isPluginActive(plugin)) { - SwingUtilities.invokeAndWait(() -> { - try { - pluginManager.stopPlugin(plugin); - } catch (PluginInstantiationException e) { - log.warn("Error stopping plugin {}: {}", pluginName, e.getMessage()); - } - }); + if (SwingUtilities.isEventDispatchThread()) { + pluginManager.stopPlugin(plugin); + return; + } else { + SwingUtilities.invokeAndWait(() -> { + try { + pluginManager.stopPlugin(plugin); + } catch (PluginInstantiationException e) { + log.warn("Error stopping plugin {}: {}", pluginName, e.getMessage()); + } + }); + } } pluginManager.remove(plugin); } catch (Exception e) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/equipment/Rs2Equipment.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/equipment/Rs2Equipment.java index f917104088c..bbea927887f 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/equipment/Rs2Equipment.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/equipment/Rs2Equipment.java @@ -319,7 +319,7 @@ public static void invokeMenu(Rs2ItemModel rs2Item, String action) { identifier = -1; List actions = rs2Item.getEquipmentActions(); for (int i = 0; i < actions.size(); i++) { - if (action.equalsIgnoreCase(actions.get(i))) { + if (actions.get(i).toLowerCase().contains(action.toLowerCase())) { identifier = i + 2; break; } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2RunePouch.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2RunePouch.java index bf69a4c4873..b83d41e389d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2RunePouch.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/inventory/Rs2RunePouch.java @@ -85,20 +85,32 @@ public static void fullUpdate() * * @param ev The varbit changed event. */ - public static void onVarbitChanged(VarbitChanged ev) { - assert Microbot.getClient().isClientThread(); - - for (int i = 0; i < NUM_SLOTS; i++) { - if (ev.getVarbitId() == RUNE_VARBITS[i]) { - slots.get(i).setRune(Runes.byVarbitId(ev.getValue())); - break; - } - if (ev.getVarbitId() == AMOUNT_VARBITS[i]) { - slots.get(i).setQuantity(ev.getValue()); - break; - } - } - } + public static void onVarbitChanged(VarbitChanged ev) { + assert Microbot.getClient().isClientThread(); + + for (int i = 0; i < NUM_SLOTS; i++) { + if (i >= slots.size()) { + break; // avoid index out of bounds + } + + PouchSlot slot = slots.get(i); + if (slot == null) { + continue; // skip null entries + } + + int varbitId = ev.getVarbitId(); + int value = ev.getValue(); + + if (varbitId == RUNE_VARBITS[i]) { + slot.setRune(Runes.byVarbitId(value)); + break; + } + if (varbitId == AMOUNT_VARBITS[i]) { + slot.setQuantity(value); + break; + } + } + } /** * Handles reading rune pouch loadouts from the bank interface widgets. diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java index da0f7e01da3..1fb5e1598bc 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/microbot/util/security/LoginManager.java @@ -48,14 +48,8 @@ public final class LoginManager { public static ConfigProfile activeProfile = null; public static ConfigProfile getActiveProfile() { - try (ProfileManager.Lock lock = Microbot.getProfileManager().lock()) - { - var profile = lock.getProfiles().stream().filter(ConfigProfile::isActive).findFirst().orElse(null); - if (profile == null) { - profile = lock.getProfiles().get(0); - } - return profile; - } + return Microbot.getConfigManager().getProfile(); + } private LoginManager() { @@ -121,6 +115,7 @@ public static boolean login() { log.warn("No active profile available for login"); return false; } + System.out.println(getActiveProfile()); Client client = Microbot.getClient(); if (client == null) { log.warn("Cannot login - client is not initialised");