Jump to content

A Simple Login Handler


Explv

Recommended Posts

import org.osbot.rs07.api.ui.RS2Widget;
import org.osbot.rs07.event.Event;
import org.osbot.rs07.input.mouse.RectangleDestination;
import org.osbot.rs07.listener.LoginResponseCodeListener;
import org.osbot.rs07.utility.ConditionalSleep;

import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public final class LoginEvent extends Event implements LoginResponseCodeListener {
    public enum LoginEventResult {
        UNEXPECTED_SERVER_ERROR(1, "Unexpected server error"),
        LOG_IN(2, "Log in"),
        INVALID_CREDENTIALS(3, "Invalid username or password"),
        BANNED(4, "Username is banned"),
        ACCOUNT_ALREADY_LOGGED_IN(5, "Account is already logged in try again in 60 seconds"),
        RUNESCAPE_UPDATED(6, "Runescape has been updated! Please reload this page."),
        WORLD_IS_FULL(7, "This world is full. Please use a different world."),
        LOGIN_SERVER_OFFLINE(8, "Unable to connect. login server offline."),
        TOO_MANY_CONNECTIONS_FROM_ADDRESS(9, "Login limit exceeded. Too many connections from you address."),
        BAD_SESSION_ID(10, "Unable to connect. Bad session id."),
        PASSWORD_CHANGE_REQUIRED(11, "We suspect someone knows your password. Press 'change your password' on the front page."),
        MEMBERS_ACCOUNT_REQUIRED(12, "You need a members account to login to this world. Please subscribe, or use a different world."),
        TRY_DIFFERENT_WORLD(13, "Could not complete login. Please try using a different world."),
        TRY_AGAIN(14, "The server is being updated. Please wait 1 minute and try again."),
        SERVER_UPDATE(15, "The server is being updated. Please wait 1 minute and try again."),
        TOO_MANY_INCORRECT_LOGINS(16, "Too many incorrect longs from your address. Please wait 5 minutes before trying again."),
        STANDING_IN_MEMBERS_ONLY_AREA(17, "You are standing in a members-only area. To play on this world move to a free area first."),
        ACCOUNT_LOCKED(18, "Account locked as we suspect it has been stolen. Press 'recover a locked account' on front page."),
        CLOSED_BETA(19, "This world is running a closed beta. sorry invited players only. please use a different world."),
        INVALID_LOGIN_SERVER(20, "Invalid loginserver requested please try using a different world."),
        PROFILE_WILL_BE_TRANSFERRED(21, "You have only just left another world. your profile will be transferred in 4seconds."),
        MALFORMED_LOGIN_PACKET(22, "Malformed login packet. Please try again"),
        NO_REPLY_FROM_LOGIN_SERVER(23, "No reply from loginserver. Please wait 1 minute and try again."),
        ERROR_LOADING_PROFILE(24, "Error loading your profile. please contact customer support."),
        UNEXPECTED_LOGIN_SERVER_RESPONSE(25, "Unexepected loginserver response"),
        COMPUTER_ADDRESS_BANNED(26, "This computers address has been blocked as it was used to break our rules."),
        SERVICE_UNAVAILABLE(27, "Service unavailable.");

        int code;
        String message;

        LoginEventResult(int code, String message) {
            this.code = code;
            this.message = message;
        }
    }

    private static final Map<Integer, LoginEventResult> responseCodeLoginResultMap = new HashMap<>();
    static {
        for (LoginEventResult result : LoginEventResult.values()) {
            responseCodeLoginResultMap.put(result.code, result);
        }
    }

    private static final Rectangle TRY_AGAIN_BUTTON = new Rectangle(318, 262, 130, 26);
    private static final Rectangle LOGIN_BUTTON = new Rectangle(240, 310, 120, 20);
    private static final Rectangle EXISTING_USER_BUTTON = new Rectangle(400, 280, 120, 20);
    private static final Rectangle CANCEL_LOGIN_BUTTON = new Rectangle(398, 308, 126, 27);
    private static final Rectangle CANCEL_WORLD_SELECTOR_BUTTON = new Rectangle(712, 8, 42, 8);

    private final String username, password;
    private int maxRetries = 5;

    private LoginEventResult loginEventResult;
    private int retryNumber = 0;

    public LoginEvent(final String username, final String password) {
        this.username = username;
        this.password = password;

        setAsync();
    }

    public LoginEvent(final String username, final String password, final int maxRetries) {
        this(username, password);
        this.maxRetries = maxRetries;
    }

    @Override
    public final int execute() throws InterruptedException {
        if (loginEventResult != null) {
            handleLoginResponse();
        }

        if (retryNumber >= maxRetries) {
            setFailed();
        }

        if (hasFailed()) {
            return 0;
        }

        if (!getBot().isLoaded()) {
            return 1000;
        } else if (getClient().isLoggedIn() && getLobbyButton() == null) {
            setFinished();
            return 0;
        }

        if (getLobbyButton() != null) {
            clickLobbyButton();
        } else if (isOnWorldSelectorScreen()) {
            cancelWorldSelection();
        } else if (!isPasswordEmpty()) {
            clickButton(CANCEL_LOGIN_BUTTON);
        } else {
            login();
        }
        return random(100, 150);
    }

    public LoginEventResult getLoginEventResult() {
        return loginEventResult;
    }

    private void handleLoginResponse() throws InterruptedException {
        switch (loginEventResult) {
            case BANNED:
            case PASSWORD_CHANGE_REQUIRED:
            case ACCOUNT_LOCKED:
            case COMPUTER_ADDRESS_BANNED:
            case UNEXPECTED_SERVER_ERROR:
            case INVALID_CREDENTIALS:
            case RUNESCAPE_UPDATED:
            case LOGIN_SERVER_OFFLINE:
            case TOO_MANY_CONNECTIONS_FROM_ADDRESS:
            case BAD_SESSION_ID:
            case UNEXPECTED_LOGIN_SERVER_RESPONSE:
            case SERVICE_UNAVAILABLE:
            case TOO_MANY_INCORRECT_LOGINS:
            case ERROR_LOADING_PROFILE:
                setFailed();
                break;
            case ACCOUNT_ALREADY_LOGGED_IN:
            case TRY_AGAIN:
            case SERVER_UPDATE:
            case NO_REPLY_FROM_LOGIN_SERVER:
            case MALFORMED_LOGIN_PACKET:
                sleep(random((int)TimeUnit.MINUTES.toMillis(1), (int)TimeUnit.MINUTES.toMillis(2)));
                retryNumber++;
                break;
            case PROFILE_WILL_BE_TRANSFERRED:
                sleep(random((int)TimeUnit.SECONDS.toMillis(5),(int)TimeUnit.SECONDS.toMillis(10)));
                retryNumber++;
                break;
            case WORLD_IS_FULL:
            case TRY_DIFFERENT_WORLD:
            case CLOSED_BETA:
            case INVALID_LOGIN_SERVER:
            case MEMBERS_ACCOUNT_REQUIRED:
            case STANDING_IN_MEMBERS_ONLY_AREA:
                // Should hop to a different world here
                setFailed();
                break;
        }
    }

    private boolean isOnWorldSelectorScreen() {
        return getColorPicker().isColorAt(50, 50, Color.BLACK);
    }

    private void cancelWorldSelection() {
        if (clickButton(CANCEL_WORLD_SELECTOR_BUTTON)) {
            new ConditionalSleep(3000) {
                @Override
                public boolean condition() throws InterruptedException {
                    return !isOnWorldSelectorScreen();
                }
            }.sleep();
        }
    }

    private boolean isPasswordEmpty() {
        return !getColorPicker().isColorAt(350, 260, Color.WHITE);
    }

    private void login() {
        switch (getClient().getLoginUIState()) {
            case 0:
                clickButton(EXISTING_USER_BUTTON);
                break;
            case 1:
                clickButton(LOGIN_BUTTON);
                break;
            case 2:
                enterUserDetails();
                break;
            case 3:
                clickButton(TRY_AGAIN_BUTTON);
                break;
        }
    }

    private void enterUserDetails() {
        if (!getKeyboard().typeString(username)) {
            return;
        }

        if (!getKeyboard().typeString(password)) {
            return;
        }

        new ConditionalSleep(30_000) {
            @Override
            public boolean condition() throws InterruptedException {
                return getLobbyButton() != null ||
                       getClient().isLoggedIn() ||
                       getClient().getLoginUIState() == 3 ||
                       loginEventResult == LoginEventResult.BANNED ||
                       loginEventResult == LoginEventResult.ACCOUNT_LOCKED;
            }
        }.sleep();
    }

    private void clickLobbyButton() {
        if (getLobbyButton() != null && getLobbyButton().interact()) {
            new ConditionalSleep(10_000) {
                @Override
                public boolean condition() throws InterruptedException {
                    return getLobbyButton() == null;
                }
            }.sleep();
        }
    }

    private RS2Widget getLobbyButton() {
        try {
            return getWidgets().getWidgetContainingText("CLICK HERE TO PLAY");
        } catch (NullPointerException e) {
            return null;
        }
    }

    private boolean clickButton(final Rectangle rectangle) {
        return getMouse().click(new RectangleDestination(getBot(), rectangle));
    }

    @Override
    public final void onResponseCode(final int responseCode) {
        if (!responseCodeLoginResultMap.containsKey(responseCode)) {
            log("Got unknown login response code " + responseCode);
            setFailed();
            return;
        }

        this.loginEventResult = responseCodeLoginResultMap.get(responseCode);
        log(String.format("Got login response: %d '%s'", responseCode, loginEventResult.message));
    }
}

 

Usage example:

import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

@ScriptManifest(author = "Explv", name = "Login Test", version = 0.1, logo = "", info = "")
public class TestScript extends Script {
    private LoginEvent loginEvent;

    @Override
    public void onStart() {
        if (getClient().isLoggedIn()) {
            getLogoutTab().logOut();
        }
        loginToAccount("username", "password");
    }

    @Override
    public int onLoop() throws InterruptedException {
        if (loginEvent != null  ) {
            if (loginEvent.isQueued() || loginEvent.isWorking()) {
                log("LoginEvent is running, script is idle");
                return 2000;
            }
            if (loginEvent.hasFailed()) {
                stop();
            }
            getBot().removeLoginListener(loginEvent);
            loginEvent = null;
        }
        log("Script is doing scripty things");
        return 2000;
    }

    private void loginToAccount(String username, String password) {
        loginEvent = new LoginEvent(username, password);
        getBot().addLoginListener(loginEvent);
        execute(loginEvent);
    }
}


OSBot must be run with random events disabled, for example:

java -jar "OSBot 2.5.59.jar" -allow norandoms

Edited by Explv
  • Like 19
  • Heart 3
Link to comment
Share on other sites

import org.osbot.rs07.api.ui.RS2Widget;
import org.osbot.rs07.constants.ResponseCode;
import org.osbot.rs07.event.Event;
import org.osbot.rs07.input.mouse.RectangleDestination;
import org.osbot.rs07.listener.LoginResponseCodeListener;
import org.osbot.rs07.utility.ConditionalSleep;

import java.awt.*;

public final class LoginEvent extends Event implements LoginResponseCodeListener {

    private String username, password;

    public LoginEvent() {}

    public LoginEvent(final String username, final String password) {
        this.username = username;
        this.password = password;
    }

    public void setUsername(final String username) {
        this.username = username;
    }

    public void setPassword(final String password) {
        this.password = password;
    }

    @[member='Override']
    public final int execute() throws InterruptedException {
        if (getClient().isLoggedIn() && getLobbyButton() == null) {
            setFinished();
        } else if (getLobbyButton() != null) {
            clickLobbyButton();
        } else if (isOnWorldSelectorScreen()) {
            cancelWorldSelection();
        } else {
            login();
        }
        return random(100, 150);
    }

    private boolean isOnWorldSelectorScreen() {
        return getColorPicker().isColorAt(50, 50, Color.BLACK);
    }

    private void cancelWorldSelection() {
        if (getMouse().click(new RectangleDestination(getBot(), 712, 8, 42, 8))) {
            new ConditionalSleep(3000) {
                @[member='Override']
                public boolean condition() throws InterruptedException {
                    return !isOnWorldSelectorScreen();
                }
            }.sleep();
        }
    }

    private void login() {
        switch (getClient().getLoginUIState()) {
            case 0:
                clickExistingUsersButton();
                break;
            case 1:
                clickLoginButton();
                break;
            case 2:
                enterUserDetails();
                break;
        }
    }

    private void clickExistingUsersButton() {
        getMouse().click(new RectangleDestination(getBot(), 400, 280, 120, 20));
    }

    private void clickLoginButton() {
        getMouse().click(new RectangleDestination(getBot(), 240, 310, 120, 20));
    }

    private void enterUserDetails() {
        if (!getKeyboard().typeString(username)) {
            setFailed();
            return;
        }
        if (!getKeyboard().typeString(password)) {
            setFailed();
            return;
        }
        new ConditionalSleep(10_000) {
            @[member='Override']
            public boolean condition() throws InterruptedException {
                return getLobbyButton() != null;
            }
        }.sleep();
    }

    private void clickLobbyButton() {
        if (getLobbyButton().interact()) {
            new ConditionalSleep(10_000) {
                @[member='Override']
                public boolean condition() throws InterruptedException {
                    return getLobbyButton() == null;
                }
            }.sleep();
        }
    }

    private RS2Widget getLobbyButton() {
        return getWidgets().getWidgetContainingText("CLICK HERE TO PLAY");
    }

    @[member='Override']
    public final void onResponseCode(final int responseCode) throws InterruptedException {
        if(ResponseCode.isDisabledError(responseCode)) {
            log("Login failed, account is disabled");
            setFailed();
            return;
        }

        if(ResponseCode.isConnectionError(responseCode)) {
            log("Connection error, attempts exceeded");
            setFailed();
            return;
        }
    }
}

Usage:

import org.osbot.rs07.script.Script;
import org.osbot.rs07.script.ScriptManifest;

@ScriptManifest(author = "Explv", name = "LoginExample", info = "", logo = "", version = 0.1)
public class LoginTest extends Script {
    
    private LoginEvent loginEvent;
    
    @[member='Override']
    public void onStart() {
        loginEvent = new LoginEvent();
        getBot().addLoginListener(loginEvent);
        
        loginEvent.setUsername("username");
        loginEvent.setPassword("password");
        execute(loginEvent);
    }

    @[member='Override']
    public int onLoop() throws InterruptedException {
        return 0;
    }
}

Usage (Command Line):

java -jar "OSBot 2.4.99.jar" -login OSBotUser:OSBotPass -bot none:none:0000 -script LoginExample:none -allow norandoms

 

Thanks for this buddy wub.png

Link to comment
Share on other sites

ezgif_com_crop.gif

 

 

Using a bare backbone of the login handler with nothing in my onLoop().

 

Not sure if OsBot client onResponseCode method is little janky atm or whats up but if your account is disabled or error response 'login limit exceeded' it'll repeatedly type your username/password shown above.

 

 

    @ Override
    public final void onResponseCode(final int responseCode) throws InterruptedException {
        if(ResponseCode.isDisabledError(responseCode)) {
            log("Login failed, account is disabled");
            setFailed();
            return;
        }
        if(ResponseCode.isConnectionError(responseCode)) {
            log("Connection error, attempts exceeded");
            setFailed();
            return;
        }
    }

 

 

 

 

^ that should be handling it but for some reason it is not. Sorry to keep bugging! Just only getting banned when login limit exceeded and then it repeatedly types username / password :p

Edited by Bamboozled
Link to comment
Share on other sites

These should help for determining when to run the login task.

 

        public boolean isLoggedIn() {
		return //
		isHopping() || //
				getClient().getLoginStateValue() == 30 || //
				getClient().isLoggedIn() || //
				isLoading();
	}

	public boolean isHopping() {
		return //
		getClient().getLoginStateValue() == 45 || //
				getClient().getLoginStateValue() == 25;//
	}

	public boolean isLoading() {
		return //
		getClient().getLoginState() == LoginState.LOADING || //
				getClient().getLoginState() == LoginState.LOADING_MAP;
	}

Client.isLoggedIn() triggers false when hopping so these checks are good to add in smile.png

 

Edited by House
  • Like 1
Link to comment
Share on other sites

  • 1 month later...

ezgif_com_crop.gif

 

 

Using a bare backbone of the login handler with nothing in my onLoop().

 

Not sure if OsBot client onResponseCode method is little janky atm or whats up but if your account is disabled or error response 'login limit exceeded' it'll repeatedly type your username/password shown above.

 

 

 

 

 

^ that should be handling it but for some reason it is not. Sorry to keep bugging! Just only getting banned when login limit exceeded and then it repeatedly types username / password :p

 

 

Having exactly the same problem. Any idea how to fix this?

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...