Skip to content
View in the app

A better way to browse. Learn more.

OSBot :: 2007 OSRS Botting

A full-screen app on your home screen with push notifications, badges and more.

To install this app on iOS and iPadOS
  1. Tap the Share icon in Safari
  2. Scroll the menu and tap Add to Home Screen.
  3. Tap Add in the top-right corner.
To install this app on Android
  1. Tap the 3-dot menu (⋮) in the top-right corner of the browser.
  2. Tap Add to Home screen or Install app.
  3. Confirm by tapping Install.

Explv

Scripter II
  • Joined

  • Last visited

Everything posted by Explv

  1. This is not the correct section for this question. Post on the script's thread. As for the error, the scripter is using functionality that is no longer present in the API as of the latest version
  2. You need to add the resources directory to the exported .jar file in the artifacts menu
  3. 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
  4. It seems to work for me. Try running OSBot from the command line in debug mode so you can see any error output from saving/loading. It will help me to know what error you get exactly. You can run OSBot in debug mode by opening CMD / Terminal and typing the command: java -jar "C:\Users\Username\OSBotLocation\OSBot.jar" -debug Replacing the path with the path to your OSBot.jar file Thanks
  5. This is not the correct section for this question.
  6. Explv replied to Annointed's topic in Scripting Help
    Just FYI the: !cow.isUnderAttack() && cow.getHealthPercent() > 0 Is redundant because: cow.isAttackable() Does: npc.getHealthPercent() > 0 && !npc.isUnderAttack() || npc.isInteracting(getMethods().myPlayer()) As for your issue you could try doing: NPC cow = getNpcs().closest(npc -> npc.getName().startsWith("Cow") && cowArea.contains(npc) && npc.isAttackable() && npc.getInteracting() == null);
  7. 1. There is even a video tutorial for setting up OSBot with Intellij: https://www.youtube.com/watch?v=0mIWSUHXB9c 2 & 3. So it's just the layout that you think is harder on Intellij? The layout looks pretty damn similar to me Intellij: Eclipse:
  8. 1. You can google how to setup any IDE, import libraries, export your code to a .jar 2. That is not true at all, Eclipse probably even has more features than Intellij. One of the main reasons people prefer Intellij over Eclipse is because of it's usability. Are you saying usability is a bad thing? Intellij has superior autocomplete, superior indexing and suggestions, these things are beneficial to programmers, regardless of ability. 3. Again, not true. I'm not sure where you are getting this whole "Intellij is harder to use" thing from. I'm not talking about the advanced features, both IDEs have those, and a new programmer won't be using them. At the end of the day, they are IDEs not spaceships. I'm not even sure you have used both Eclipse and Intellij before.
  9. That's not true at all, one is not particularly harder to use than the other. In my opinion Intellij has a better overall user experience, and therefore would be the best choice for OP
  10. Ok, I thought you might be doing something like that, just wanted to make sure
  11. I could add copy/paste functionality if that would solve your problem However I will consider changing the layout of things, maybe separating account from the other options. I will implement one (or maybe both) of these two options in the next version, along with some other new features, expect an update by the end of this weekend. Thanks
  12. That is not currently possible as Alek has said, but perhaps if you detailed your specific use case we could offer an alternative temporary solution? For example if your player always walks past these dangerous npcs, you could web walk to a position just before them, then walk a fixed path around the npcs, then carry on web walking to the destination. Not too sure what you mean by "The destination can only be a single area", maybe you could clarify this
  13. Explv replied to eggsandham77777's topic in Tutorials
    http://osbot.org/forum/topic/87717-fixing-osbot-not-starting/
  14. Explv replied to The Hero of Time's topic in Spam/Off Topic
    Fucking leech
  15. Web walking already handles obstacles, so this code is pretty redundant anyway
  16. Make sure you know what you are doing before making tutorials, otherwise you can spread bad practices to new scripters. I am not trying to discourage you, I just noticed that you have only been a member for 2 months and do not have the scripter rank yet. Good luck, I look forward to seeing the videos
  17. Seriously? A tutorial for reading documentation lel
  18. Beautiful
  19. Explv replied to domp's topic in Scripting Help
    Use the WalkingEvent: WalkingEvent walkingEvent = new WalkingEvent(position); walkingEvent.setMinDistanceThreshold(0); execute(walkingEvent);
  20. Indeed, I have just tested it on Windows 7 and can confirm that it works. Make sure you are using the latest version of my application and opening the .jar with Java 8, either by right clicking and selecting "Open With", setting the default application for .jar files to Java or, as Tom posted, running it from the command line using "java -jar name_of_the_file.jar"
  21. It means that for local scripts (Not on the SDN) we will be able to programmatically switch runescape accounts. This allows for a script to be run on multiple accounts one after the other.
  22. For the love of god please use the code formatting
  23. Yellow lines are warnings. Also that could be simplified to: NPC cow = getNpcs().closest(npc -> npc.getName().startsWith("Cow") && npc.isAttackable() && cowArea.contains(npc));
  24. ConditionalSleep will sleep for MAX the amount of time you specify (in this case 5 seconds) OR until the condition is satisfied. So in the example I gave it would sleep for up to 5 seconds or until the NPC is no longer attackable (either it is dead, someone else is attacking it, or we are attacking it)
  25. You can get the real (walking) distance to the npc / ground item using: int distance = getMap().realDistance(entity); // entity is the npc or ground item Or the direct distance: int distance = myPosition().distance(entity.getPosition()); Then just compare the two distances to find which is less. For attacking the NPC you can just do something like: NPC cow = getNpcs().closest(npc -> npc.getName().equals("Cow") && npc.isAttackable()); if (cow != null && cow.interact("Attack")) { new ConditionalSleep(5000) { @ Override public boolean condition() throws InterruptedException { return !cow.isAttackable(); } }.sleep(); }

Account

Navigation

Search

Search

Configure browser push notifications

Chrome (Android)
  1. Tap the lock icon next to the address bar.
  2. Tap Permissions → Notifications.
  3. Adjust your preference.
Chrome (Desktop)
  1. Click the padlock icon in the address bar.
  2. Select Site settings.
  3. Find Notifications and adjust your preference.