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. Why do you care if it's more code? Less code does not necessarily mean better code. You're trying to solve a simple problem, so why not use a simple solution.
  2. So let me get this straight, you want a query that does 3 things in one. 1) Lets you search for a match on proxy 2) Lets you search for a match on category 3) Lets you search for a match on both Well, why don't you just use three different god damn queries? You could have written them in the time it took you to make this post. Query 1: SELECT values FROM bot table INNER JOIN proxy table ON bot.proxy_id = proxy.proxy_id AND proxy.proxy = $proxyValue INNER JOIN category table ON bot.category_id = category.category_id Query 2: SELECT values FROM bot table INNER JOIN category table ON bot.category_id = category.category_id AND category .category = $categoryValue INNER JOIN proxy table ON bot.proxy_id = proxy.proxy_id Query 3: SELECT values FROM bot table INNER JOIN proxy table ON bot.proxy_id = proxy.proxy_id AND proxy.proxy = $proxyValue INNER JOIN category table ON bot.category_id = category.category_id AND category .category = $categoryValue And then in PHP: If category is undefined: Execute query 1 Else if proxy is undefined: Execute query 2 Else Execute query 3
  3. This is because the roofs are turned on. I thought I added some code at the start of the script to turn roofs off, however (obviously) it is not working. I will fix this and leave a comment when it is done.
  4. Your logic sounds quite strange. If I understand correctly, it sounds like you want 1 query that does: Select all rows where: the row's proxy_id = $proxyId or the row's category_id = $categoryId or the row's proxy_id = $proxyId AND the row's category_id = $categoryId Well isn't that the exact same as: Select all rows where: the row's proxy_id = $proxyId or the row's category_id = $categoryId Because if the row matches both category id and proxy id, it will still satisfy the above condition. However what your query currently does is: Select all rows where: the row's proxy_id = $proxyId AND the row's category_id = $categoryId Why? Well because you are doing an Inner join on both proxy id and category id. So the resulting values only satisfy this condition. I (think) this would work instead: SELECT a.id, a.rslogin, a.rswachtwoord, a.gebruikersnaam, p.proxy, c.subcategory FROM bots a FULL OUTER JOIN proxy p ON a.proxy_id=p.id FULL OUTER JOIN subcategory c ON a.category_id=c.subcat_id WHERE p.proxy = $proxy OR c.subcat_id = $sub_category; An explanation of what this does: Select all the values we want from The bots table Joined with the proxy table on proxy id (keeping all values from both tables) Joined with the subcategory table on category id (Keeping all values from both tables) Where the proxy value matches or the category matches
  5. import org.osbot.rs07.api.model.RS2Object; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; @ScriptManifest(author = "Explv", name = "Example hover", info = "", version = 0.1, logo = "") public class Example extends Script { private enum State { CHOPPING, HOVERING } private RS2Object chopTree; @Override public int onLoop() throws InterruptedException { switch (getState()) { case CHOPPING: chop(); break; case HOVERING: hover(); break; } return random(200, 300); } private State getState() { if(chopTree == null || !chopTree.exists() || !myPlayer().isAnimating()) return State.CHOPPING; return State.HOVERING; } private void chop() { chopTree = getObjects().closest("Tree"); if(chopTree != null && chopTree.interact("Chop down")) { new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return !chopTree.exists() || myPlayer().isAnimating(); } }.sleep(); } } private void hover() { RS2Object hoverTree = getObjects().closest(obj -> obj.getName().equals("Tree") && obj != chopTree); if(hoverTree != null && !getMouse().isOnCursor(hoverTree)) { hoverTree.hover(); } } } The logic is pretty simple: If the player is not woodcutting, find closest tree and chop it Else find the closest tree, that is not equal to the tree the player is chopping and hover it
  6. Yes, to generate the source code just 'make' the project. Hit Ctrl F9 or Go to Build -> Make Project
  7. My version does not require dragon script loader to be run. You can download it from here: http://osbot.org/forum/topic/84213-explvs-tutorial-island-free-random-characters/
  8. It will either be put on the SDN as a VIP + script (and then maybe in the future be made premium) Or it will live in the Local/Downloadable section for free Regardless, I still intend to complete the script, fix any bugs that arise etc. All the features listed in the post are completed.
  9. I will be releasing the beta this week (for free)
  10. We will need to see some code to determine the issue. One reason could be that you have not set a size on your JFrame? gui.setMinimumSize(new Dimension(500, 500));
  11. It's probably because of this ^^^^^^^^^^^^^. Firstly, this is incorrect because you are only ever looking for a Cow once. If no Cow is found, you never try to find another one, so your script will do nothing. Secondly this will break your script, because you are calling npcs.closest() before the script has been setup. To fix both of the above, you should be doing this in onLoop. Every time you go to attack a new Cow, you will need to call that code to find one. By doing this in onLoop you can also be sure that the script is setup: @Override public int onLoop() throws InterruptedException { if (!getCombat().isFighting()) attackEnemy(); return random(200, 300); } private void attackEnemy() { NPC enemy = getEnemy(); if(enemy != null && enemy.interact("Attack")) { new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return getCombat().isFighting(); } }.sleep(); } } private NPC getEnemy() { return npcs.closest(n-> n.getName().equals("Cow") && n.getCurrentHealth() > 0 && n.isAttackable() && map.canReach(n) ); } I will explain in more detail why this causes your script to crash (Note the code is obfuscated so may be hard to read, I have added comments to make it more clear): There is a class called ScriptExecutor which handles the starting / stopping etc of scripts. In this class there is a method named start, which handles the starting of a new script. It's definition looks like: public void start(Script iiiIIIiIii1) throws InterruptedException { SwingUtilities.invokeLater(new Runnable() { public void run() { BotApplication.iiiIIIiIii().iiiIIIiIii().iiIiIiIIiI.setEnabled(false); BotApplication.iiiIIIiIii().iiiIIIiIii().iIIiIIiiii.setEnabled(true); BotApplication.iiiIIIiIii().iiiIIIiIii().IiIIiIiIii.setEnabled(true); } }); iiiIIIiIii.prepare(iiiIIIiIii1); // Prepare the script before starting if(!iiiIIIiIii.iiiIIIiIii(iiiIIIiIii1)) { // Start the script iiiIIIiIii.stop(); // If starting the script failed, stop the script } iiiIIIiIii.restart(); } Now notice how before starting the script, it makes a call to prepare. The prepare method looks like: public void prepare(Script iiiIIIiIii1) throws InterruptedException { iiiIIIiIii.iIIIIiiiIi.setHumanInputEnabled(false); if(iiiIIIiIii.IiiiIiIIIi) { iiiIIIiIii.stop(false); } iiiIIIiIii.IiiIiIiiII = iiiIIIiIii1; iiiIIIiIii.iiIiiIiIiI = new ScriptExecutor.InternalExecutor(null); iiiIIIiIii.IiiiIiIIIi = true; iiiIIIiIii.IIiIIiiiII = iiiIIIiIii.iIIiIIiiii = false; for(ScriptExecutor var10000 = iiiIIIiIii; !var10000.iIIIIiiiIi.isLoaded(); var10000 = iiiIIIiIii) { Thread.sleep(100L); } iiiIIIiIii1.exchangeContext(iiiIIIiIii.iIIIIiiiIi); // This is what sets up all the methods like getNpcs() etc. iiiIIIiIii.iIIIIiiiIi.getRandomExecutor().IIiIiIiIiI(); iiiIIIiIii.iIIIIiiiIi.addPainter(iiiIIIiIii1); if(!BotApplication.iiiIIIiIii().iiiIIIiIii().iiiIIIiIii()) { Lb var2 = new Lb(iiiIIIiIii.iIIIIiiiIi); iiiIIIiIii.iIIIIiiiIi.addPainter(var2); iiiIIIiIii.iIIIIiiiIi.addMouseListener(var2); } iiiIIIiIii.iIIIIiiiIi.addConfigListener(iiiIIIiIii1); iiiIIIiIii.iIIIIiiiIi.addAudioListener(iiiIIIiIii1); iiiIIIiIii.iIIIIiiiIi.messageEventQueue.clear(); iiiIIIiIii.iIIIIiiiIi.addMessageListener(iiiIIIiIii1); iiiIIIiIii.iIIIIiiiIi.addLoginListener(iiiIIIiIii1); } This prepare method includes a call to exchangeContext. The exchangeContext method is what sets up all the objects like npcs, inventory etc. This is necessary to allow scripters to access the API. The exchangeContext method looks like: public MethodProvider exchangeContext(Bot iiiIIIiIii1) { iiiIIIiIii.bot = iiiIIIiIii1; iiiIIIiIii.client = iiiIIIiIii1.getClient(); iiiIIIiIii.logger = iiiIIIiIii1.getLogger(); iiiIIIiIii.npcs = iiiIIIiIii1.getMethods().npcs; iiiIIIiIii.players = iiiIIIiIii1.getMethods().players; iiiIIIiIii.groundItems = iiiIIIiIii1.getMethods().groundItems; iiiIIIiIii.objects = iiiIIIiIii1.getMethods().objects; iiiIIIiIii.widgets = iiiIIIiIii1.getMethods().widgets; iiiIIIiIii.tabs = iiiIIIiIii1.getMethods().tabs; iiiIIIiIii.inventory = iiiIIIiIii1.getMethods().inventory; iiiIIIiIii.bank = iiiIIIiIii1.getMethods().bank; iiiIIIiIii.depositBox = iiiIIIiIii1.getMethods().depositBox; iiiIIIiIii.store = iiiIIIiIii1.getMethods().store; iiiIIIiIii.equipment = iiiIIIiIii1.getMethods().equipment; iiiIIIiIii.map = iiiIIIiIii1.getMethods().map; iiiIIIiIii.combat = iiiIIIiIii1.getMethods().combat; iiiIIIiIii.magic = iiiIIIiIii1.getMethods().magic; iiiIIIiIii.prayer = iiiIIIiIii1.getMethods().prayer; iiiIIIiIii.configs = iiiIIIiIii1.getMethods().configs; iiiIIIiIii.skills = iiiIIIiIii1.getMethods().skills; iiiIIIiIii.mouse = iiiIIIiIii1.getMethods().mouse; iiiIIIiIii.keyboard = iiiIIIiIii1.getMethods().keyboard; iiiIIIiIii.camera = iiiIIIiIii1.getMethods().camera; iiiIIIiIii.menu = iiiIIIiIii1.getMethods().menu; iiiIIIiIii.antiBan = iiiIIIiIii1.getMethods().antiBan; iiiIIIiIii.dialogues = iiiIIIiIii1.getMethods().dialogues; iiiIIIiIii.settings = iiiIIIiIii1.getMethods().settings; iiiIIIiIii.colorPicker = iiiIIIiIii1.getMethods().colorPicker; iiiIIIiIii.logoutTab = iiiIIIiIii1.getMethods().logoutTab; iiiIIIiIii.doorHandler = iiiIIIiIii1.getMethods().doorHandler; iiiIIIiIii.experienceTracker = iiiIIIiIii1.getMethods().experienceTracker; iiiIIIiIii.localWalker = iiiIIIiIii1.getMethods().localWalker; iiiIIIiIii.walking = iiiIIIiIii1.getMethods().walking; iiiIIIiIii.trade = iiiIIIiIii1.getMethods().trade; iiiIIIiIii.chatbox = iiiIIIiIii1.getMethods().chatbox; iiiIIIiIii.quests = iiiIIIiIii1.getMethods().quests; iiiIIIiIii.hintArrow = iiiIIIiIii1.getMethods().hintArrow; iiiIIIiIii.grandExchange = iiiIIIiIii1.getMethods().grandExchange; iiiIIIiIii.worlds = iiiIIIiIii1.getMethods().worlds; iiiIIIiIii.projectiles = iiiIIIiIii1.getMethods().projectiles; return iiiIIIiIii; } Only after these are setup does it call the onStart method in your script. So why does your code break? Well, where you put the npcs.closest() call in your script, means that it is called when an instance of your script is created. This means that you are calling npcs.closest() before any of the above has happened. This means that exchangeContext has not been called, so npcs is null. The result of this is that your code will throw a NullPointerException, causing your script to not start.
  12. I think that when firemaking the player will always walk in one specific direction after lighting a log. I can't remember if it is North, East, South or West, but it is one of those. So, for example, if the player always walks South after lighting a log. Just make sure that the first position in the line where the player will light, is the Northern most position. That way, the player will never walk back over his fires. However, if this is not possible, you could always check if the player can light a fire in the current position, and walk to a different one if a fire cannot be lit. Maybe something like this would work? private boolean canPlayerLightAFire() { return getObjects().filter(new PositionFilter<>(myPosition())).size() == 0; } Alternatively, you can listen for the message "The player cannot light a fire here", or whatever it is, and move if that happens.
  13. For checking if your player is chopping a tree you can just check if your player is animating: if(myPlayer().isAnimating()) // player is performing the chop animation, so is cutting a tree For finding the tree with the fewest players chopping it, you could try doing something like: private Optional<RS2Object> getTreeWithFewestPlayers() { return getObjects() .getAll() .stream() .filter(obj -> obj.getName().equals("Tree")) .min((tree1, tree2) -> Long.compare(getNumPlayersInteracting(tree1), getNumPlayersInteracting(tree2))); } private long getNumPlayersInteracting(final Entity entity) { return getPlayers().getAll().stream().filter(player -> player.getInteracting() == entity && player.isAnimating()).count(); } For lighting a fire you could sleep until your position changes (because after you light a fire your player walks to another tile): if(!isItemWithNameSelected("Tinderbox")) getInventory().interact("Use", "Tinderbox"); else lightFire(); private boolean isItemWithNameSelected(final String itemName) { final String selectedItemName = getInventory().getSelectedItemName(); return selectedItemName != null && selectedItemName.equals(itemName); } private void lightFire() { if(getInventory().getItem("Logs").interact()){ final Position playerPos = myPosition(); new ConditionalSleep(20_000) { @Override public boolean condition() throws InterruptedException { return !myPosition().equals(playerPos) && !myPlayer().isMoving(); } }.sleep(); } }
  14. I meant RS2Objects* Don't make me hurt you
  15. Items on the ground are GroundItems not RS2Objects. So to get the bones you need to do: GroundItem bones = getGroundItems().closest("Bones"); To check if your player is attacking something you can do: if(myPlayer().getInteracting() != null) Or this may work too: getCombat().isFighting() Also FYI you don't need a separate variable for each target NPC. You can get the closest out of all of them with one statement: NPC enemy = S.getNpcs().closest("Chicken", "Cow", "Cow calf"); But you may also want to check that those npcs are not under attack themselves, and that they are not dead. Perhaps something like: NPC enemy = getNpcs().closest(new NameFilter<>("Chicken", "Cow", "Cow calf"), npc -> !npc.isUnderAttack() && npc.getHealthPercent() > 0);
  16. I think that your portal area checks should not be inside the bank area check. Perhaps if you cleaned up the script a bit, you could more easily identify the issues: import org.osbot.rs07.api.map.Area; import org.osbot.rs07.api.ui.Skill; import org.osbot.rs07.script.Script; import org.osbot.rs07.script.ScriptManifest; import org.osbot.rs07.utility.ConditionalSleep; @ScriptManifest(author = "Explv", name = "Wine Drinker", info = "Drinks Wine", logo = "", version = 0.1) public class WineDrinker extends Script { private enum State { BANKING, DRINKING, WALKING_TO_BANK, WALKING_TO_PORTAL, WALKING_TO_COMBAT, TELEPORTING } private final Area portalArea = new Area(0, 0, 0, 0), bankArea = new Area(0, 0, 0, 0), spawnArea = new Area(0, 0, 0, 0), combatArea = new Area(0, 0, 0, 0); @Override public int onLoop() throws InterruptedException { switch (getState()){ case BANKING: bank(); break; case DRINKING: drink(); break; case WALKING_TO_BANK: getWalking().webWalk(bankArea); break; case WALKING_TO_PORTAL: getWalking().webWalk(portalArea); break; case WALKING_TO_COMBAT: getWalking().webWalk(combatArea); break; case TELEPORTING: teleport(); break; } return random(200, 300); } private State getState() { if(!getInventory().contains("Jug of wine")){ return bankArea.contains(myPosition()) ? State.BANKING : State.WALKING_TO_BANK; } if(spawnArea.contains(myPosition())) return State.WALKING_TO_COMBAT; if(combatArea.contains(myPosition())) return State.DRINKING; return portalArea.contains(myPosition()) ? State.TELEPORTING : State.WALKING_TO_PORTAL; } private void teleport(){ if(getObjects().closest("Free-for-all portal").interact("Enter")){ new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return !portalArea.contains(myPosition()); } }.sleep(); } } private void bank() throws InterruptedException { if(!getBank().isOpen()) { openBank(); } else if(!getInventory().isEmptyExcept("Jug of wine")) { getBank().depositAllExcept("Jug of wine"); } else if(!getInventory().contains("Jug of wine")){ if(getBank().contains("Jug of wine")) getBank().withdrawAll("Jug of wine"); else stop(); } } private void openBank() throws InterruptedException { if(getBank().open()){ new ConditionalSleep(5000) { @Override public boolean condition() throws InterruptedException { return getBank().isOpen(); } }.sleep(); } } private void drink() { if (getSkills().getStatic(Skill.HITPOINTS) - getSkills().getDynamic(Skill.HITPOINTS) > 11) { getInventory().getItem("Jug of wine").interact("Drink"); } } }
  17. Well the only reason that log statement wouldn't work is if your player is not in the area. Feel free to pm me in the chatbox and I can take a look over teamviewer
  18. Try and use a different area, it might be that the one you took from the snippet is incorrect. You can use my map to help you: http://explv.github.io/
  19. He didn't make an instance of Player, he just stored it. That's not the issue
  20. In the future, when posting to the scripting help section, please use the code tags. It is the blue button that looks like: < > Are you sure your player is in one of those areas? What is the code after, that does work?
  21. He integrated my script into his loader
  22. Reflection is blocked in OSBot 2.4.59 so this method will no longer work. I have built a multi account loader in my script though, found here: http://osbot.org/forum/topic/84213-explvs-tutorial-island-free-random-characters/
  23. You are using Intellij Form Designer though right? private JPanel panel; If that JPanel is not bound to the JPanel in Intelij Form Designer, then when you call: add(panel); It will throw a NullPointerException.Here is a graphical example of what I meant in my previous comment. Firs you have to provide a name for the top level JPanel in the .form view: Then in the bound Java class with the same name you do: import javax.swing.*; public class GUI extends JFrame { private JPanel mainPanel; public GUI(){ add(mainPanel); setTitle("Whatever"); setVisible(true); } } This code works perfectly fine.Don't forget you will also need to set a preferred size on your JFrame otherwise it will be very small: import javax.swing.*; import java.awt.*; public class GUI extends JFrame { private JPanel mainPanel; public GUI(){ add(mainPanel); setTitle("Whatever"); setVisible(true); setPreferredSize(new Dimension(400, 400)); } } One more important thing.If you are uploading this script to the SDN, and you are using Intellij Form Designer, you will need to make Intellij compile the .form into Java code in your class. If you don't do this, when you copy over your GUI class file, none of your GUI code will be there, and it will break. To do this you need to go to: File -> Settings -> Editor -> GUI Designer And change the option "Generate GUI into:"'s value to Java source code. And then make the project
  24. Can you post your GUI code?
  25. I need more information about the error, what line number it was thrown on, what threw it etc.

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.