bakbuk 1 Posted July 16, 2024 (edited) Barbaughter: What is this? aka About Simple script that trains magic and loot stuff by slaughtering at Barbarians from a safe spot until desired level achieved. Why is this? aka Reasoning Actually, first OSRS script ever (🎉), this is not the fastest nor the cheapest [UPDATE: support wind strike for the cheapest training] method to train magic, but it works for me, I wrote it for fun and since there was nothing else that will let me train magic without competition with other bots as well as return part of the Invesment with looting. How is this? Aka Requirements - Fire Staff [ OR Air Staff in wind Strike only mode] - Air runes (30.5K from lever 1 to level 55) [No need in Wind Strike only mode] - Mind runes (15.5K from lever 1 to level 55) [Recommended to wear armor for partial splashing so kill takes longer and XP gain will get a bit faster as well as AFK reduce ban rate I assume] [Can be interrupted with manual actions to increase randomness and script should overcome them and keep going strong] Support setting change via user friendly csv file can be opened with Exell or simple notepad, script must be refreshed after settings changes. Support QuickStart parameters example: java -jar C:\Users\YOUR_USER\DreamBot\BotData\client.jar -script "Barbaughter" -account "ACCOUNT" -params target_level=99 loot_value_threshold=170 bury_bones=0 winds_strike_only=0 When is this? Aka How long does it takes to train From level 1 to 55, Rate of 15KXP/h~ but with breaks took me around 14 hours. Rate of wind strike is about 7KXP/h. Loot and Bury bones will dramatically reduce Magic XP (11KXP/h) rate but I think it's a good anti-ban measure since bots usually not doing that, however more investigation needed. Before you stop reading, I didn't implement an anti-ban mechanism (yet) so you must use Dreambots' breaks. Otherwise, the game will be anger on you (as show in attached screenshot). Where is this? Aka Location At the barbarian village, but if you have some different suggestions, tell me and I'll consider adding them. Who is this? Aka '' Nothing else to add, but if anyone have a suggestion, bug report or just want to see the source code (for learning purposes) please let me know. Edited July 28, 2024 by bakbuk
bakbuk 1 Author Posted July 17, 2024 (edited) Changelog: 1.1: Spoiler - Progressively choose spell. - Support banking (loot / equipment). - Add CLI support "target_level 99" as default. - On exit conclude how much XP has been made. 1.2: Spoiler - Added Quickstart parameters [target_level, loot_value_threshold, bury_bones, winds_trike_only] - Added loot Bones & Coins and bury bones option - Added Wind Strike only mode - Changed algorithm to attack random or closer target - Redundant the need to disable level notifications 1.3: Spoiler - Fix typo in scripts parameters - Improve target attacking logic - Extend fighting area - Stop chase targets who are out of location - Anti-ban feature, added WindMouse 1.4: Spoiler - Fixed not stop on target level. - Improve setting to use file in addition to Quickstart - Add user-friendly setting button to edit quickly. 1.5: Spoiler - Fixed issue prevent config to be created. - Minor code cleaning. Since I am busy lately I am adding the source code in here public class Barbaughter extends AbstractScript implements ExperienceListener, HumanMouseListener { // public Preferences pref = Preferences.userRoot().node(this.getClass().getName()); private String staff = "Staff of fire"; private NPC active_target = null; private final Timer timeRan = new Timer(); private int magicXpGained = 0; private final Area BARBARIAN_SAFESPOT = new Area(3081, 3421, 3080, 3421, 0); private final Area BARBARIAN_FIGHT = new Area( new Tile(3072, 3426, 0), new Tile(3087, 3426, 0), new Tile(3088, 3412, 0), new Tile(3080, 3412, 0), new Tile(3073, 3419, 0), new Tile(3078, 3422, 0), new Tile(3082, 3421, 0), new Tile(3082, 3419, 0), new Tile(3079, 3419, 0)); Rectangle SETTINGS_CLICK_AREA = new Rectangle(716, 47, 48, 18); private final String CONFIG_FILE_FOLDER = System.getProperty("scripts.path") + "barbaughter" + File.separator; private final String CONFIG_FILE = CONFIG_FILE_FOLDER + "config.csv"; private final HashMap<String, Integer> settings = new HashMap<String, Integer>( // Default settings ) {{ put("target_level", 99); put("loot_value_threshold", 170); put("bury_bones", 0); put("winds_strike_only", 0); }}; @Override public void onStart() { Logger.log("Script is Starting."); // Get the settings from the csv config file name CONFIG_FILE_NAME loadConfig(); starting(); } @Override public void onStart(String... params) { Logger.log("Script is Starting with params."); if (params != null && params.length > 0) { parseSettings(params); } starting(); } private void starting() { Mouse.setMouseAlgorithm(new WindMouse()); // If we need to use wind strike then we need staff of air if (settings.get("winds_strike_only") > 0) { staff = "Staff of air"; } } private void parseSettings(String... params) { // Foreach parameters for (String param : params) { // Split the parameter String[] split = param.split("="); // If the split has 2 items if (split.length == 2) { // Get the setting name String setting = split[0]; // Get the setting value String value = split[1]; // Add the setting to the settings hashmap if it exists if (settings.containsKey(setting)) { settings.put(setting, Integer.parseInt(value)); Logger.log("Setting " + setting + " to " + value); } else { Logger.error("Invalid setting " + setting); stop(); } } else { Logger.error("Invalid script parameter." + param); stop(); } } } @Override public void onLevelUp(ExperienceEvent e) { Logger.log("Skill: " + e.getSkill() + " level up! getType: " + e.getType() + " Total level: " + Skills.getRealLevel(e.getSkill())); // If magic is 55 we can stop if (e.getSkill() == Skill.MAGIC && Skills.getRealLevel(e.getSkill()) + 1 >= settings.get("target_level")) { Logger.log("Magic level achieved, stopping the script."); stop(); } } @Override public void onGained(ExperienceEvent e) { if (e.getSkill() == Skill.MAGIC) { magicXpGained += e.getChange(); } } @Override public int onLoop() { if (!SanityCheck()) { // Missing items, open the bank and get the items fetchItems(); } else { KillBarbarians(); } return Calculations.random(600, 1200); } private void fetchItems() { Logger.log("Getting items from the bank."); if (Bank.open()) { Bank.depositAllItems(); // Get runes from the bank // No need air if we are using wind strike only if (!Inventory.contains("Air rune") && settings.get("winds_strike_only") == 0) { if (!Bank.contains("Air rune")) { Logger.error("Bank doesn't have air runes."); stop(); } Bank.withdrawAll("Air rune"); Sleep.sleepUntil(() -> Inventory.contains("Air rune"), 3500); } if (!Inventory.contains("Mind rune")) { if (!Bank.contains("Mind rune")) { Logger.error("Bank doesn't have mind runes."); stop(); } Bank.withdrawAll("Mind rune"); Sleep.sleepUntil(() -> Inventory.contains("Mind rune"), 3500); } Logger.log(String.format("Equipment.contains(%s) %s", staff, Equipment.contains(staff))); // fire staff if (!Equipment.contains(staff)) { if (!Bank.contains(staff)) { Logger.error("Bank doesn't have " + staff + "."); stop(); } Bank.withdraw(staff, 1); Sleep.sleepUntil(() -> Inventory.contains(staff), 3500); } } } private boolean SanityCheck() { boolean sanity = true; // Make sure bot is logged in if (!Client.isLoggedIn()) { Sleep.sleepUntil(Client::isLoggedIn, 15000); // Sleep a little to not rush things Sleep.sleep(2000, 7000); } // If dialog is open then close it if (Dialogues.inDialogue()) { Dialogues.spaceToContinue(); Logger.log("Closing dialogue"); Sleep.sleep(2000, 5000); } // Check if inventory is full if (Inventory.isFull()) { Logger.error("Inventory is full."); sanity = false; } // Check if we have air runes in inventory but not needed if we are using wind strike only if (!Inventory.contains("Mind rune") || (!Inventory.contains("Air rune") && settings.get("winds_strike_only") == 0)) { Logger.error("We don't have enough runes in inventory."); sanity = false; } // If we have [staff] in inventory but not equipped wear it if (Inventory.contains(staff) && !Equipment.contains(staff)) { Logger.log(String.format("Equipment.contains(%s) equipping", staff)); Objects.requireNonNull(Inventory.get(staff)).interact("Wield"); Sleep.sleepTick(); } else if (!Equipment.contains(staff)) { // Check if bot wearing [staff] Logger.error(String.format("We don't have %s equipped.", staff)); sanity = false; } Spell activeSpell = Normal.FIRE_STRIKE; // If Magic level is less than 13 or the user wants to use wind strike only if (Skills.getRealLevel(Skill.MAGIC) < 13 || settings.get("winds_strike_only") > 0) { activeSpell = Normal.WIND_STRIKE; } // Make sure the Fire strike spell is selected (if not sanity probably not having runes) if (Magic.getAutocastSpell() != activeSpell && sanity) { Magic.setAutocastSpell(activeSpell); // Open magic tab Tabs.openWithMouse(Tab.INVENTORY); } return sanity; } private void KillBarbarians() { // Make sure we are in the BARBARIAN_SAFESPOT if (!BARBARIAN_SAFESPOT.contains(Players.getLocal().getTile())) { // Walking Logger.log("Walking to BARBARIAN_SAFESPOT"); Walking.walk(BARBARIAN_SAFESPOT); // Sleep a little so the bot can walk to the safe spot Sleep.sleepUntil(() -> BARBARIAN_SAFESPOT.contains(Players.getLocal().getTile()), 3500); } // If active fight is dead or not in range anymore then pick up the items if (active_target != null && (!active_target.exists() || active_target.getTile().distance(Players.getLocal()) > 15)) { Logger.log("NPC was in location " + active_target.getTile().toString()); active_target = null; GetValuableItems(); // Walk back to safe spot Walking.walk(BARBARIAN_SAFESPOT); // Wait for bot to walk back to safe spot Sleep.sleepUntil(() -> BARBARIAN_SAFESPOT.contains(Players.getLocal().getTile()), 3500); } // Search barbarians to attack if (active_target == null) { // If we need to bury bones if (settings.get("bury_bones") > 0) { Logger.log("Burying bones"); // Bury bones Inventory.all(item -> item.getName().contains("Bones")).forEach(bone -> { bone.interact("Bury"); Sleep.sleep(1200, 2200); }); } // Only attack when we are in the safe spot if (BARBARIAN_SAFESPOT.contains(Players.getLocal().getTile())) { Logger.log("Searching target to attack"); // Get NPCs that are in BARBARIAN_FIGHT area List<NPC> barbarians = NPCs.all("barbarian"); // Sort the NPCs by distance 50% of the times if (Calculations.random(-1, 1) >= 0) { Logger.log("Randomly sorting by distance"); barbarians.sort((npc1, npc2) -> { if (npc1 == null || npc2 == null) { return 0; } return (int) (npc1.getTile().distance(Players.getLocal()) - npc2.getTile().distance(Players.getLocal())); }); } for (NPC npc : barbarians) { if (npc != null && BARBARIAN_FIGHT.contains(npc)) { Logger.log("Attacking NPC"); npc.interact("Attack"); active_target = npc; Sleep.sleepUntil(() -> Players.getLocal().isInCombat(), 2000); Sleep.sleep(1500); // Draw the NPC tile //getClient().getCanvas().drawPolygon(npc.getTile().getPolygon(getClient())); break; } } } } else { // If for some reason it glitches and not fighting then attack again if (!active_target.isInteractedWith()) { // active_target = null; // Logger.log("Target lost, resetting target."); // Not in a fight area if (!BARBARIAN_FIGHT.contains(active_target)) { Logger.log("Target is not in fight area anymore."); active_target = null; } else { Logger.log("Re-attacking NPC"); active_target.interact("Attack"); Sleep.sleepUntil(() -> Players.getLocal().isInCombat(), 2000); } } else { Logger.log("Still fighting with " + active_target.getName() + " in location " + active_target.getTile().toString()); // Sleep a little so the bot can fight Sleep.sleepUntil(() -> !active_target.exists(), 2500); } } } @Override public void onExit() { Logger.log("We are done, gained " + magicXpGained + " magic xp."); Logger.log("Script is stopping."); } public void GetValuableItems() { // Check if there is a drop that costs more than 150 coins GroundItems.all(drop -> drop != null && // Not too far drop.distance() < 10 && // Valuable drop (drop.getItem().getLivePrice() * drop.getAmount() > settings.get("loot_value_threshold") || // Or bury bones ( Will enable taking coins as well) (settings.get("bury_bones") > 0 && (drop.getName().contains("Bones") || drop.getName().contains("Coins"))) ) ).forEach(valuableDrop -> { Logger.log("Found valuable drop: " + valuableDrop.getName()); // Interact with the drop valuableDrop.interact("Take"); // Wait until the item is picked up Sleep.sleepUntil(() -> !valuableDrop.exists(), 8000); }); } @Override public void onPaint(Graphics2D g) { Font font = new Font("Times new roman", Font.PLAIN, 19); g.setFont(font); g.setColor(Color.RED); g.drawString("Barbaughter by Bakbuk", 581, 15); // Calculate magic xp per hour int magicXpPerHour = (int) (magicXpGained * 3600000D / timeRan.elapsed()); g.drawString(magicXpPerHour + "XPh", 686, 30); // for (Tile t : BARBARIAN_FIGHT.getTiles()) { // g.drawPolygon(Map.getPolygon(t)); g.drawString(timeRan.formatTime(), 700, 45); Font font2 = new Font("Times new roman", Font.PLAIN, 9); g.setFont(font2); g.drawString("SETTINGS", 720, 60); g.draw(SETTINGS_CLICK_AREA); } public void saveConfig() { try { // Make sure folder exist File storageDirectory = new File(CONFIG_FILE_FOLDER); if (!storageDirectory.exists()) { Logger.log("Folder not found, creating folder for config file."); if (!storageDirectory.mkdir()) { throw new RuntimeException("Couldn't create directory for config file."); } } FileWriter file = new FileWriter(CONFIG_FILE); Logger.log("Saving config file."); BufferedWriter writer = new BufferedWriter(file); for (Map.Entry<String, Integer> entry : settings.entrySet()) { writer.write(entry.getKey() + "," + entry.getValue() + "\n"); } writer.close(); } catch (IOException e) { Logger.error("Error saving config file, you will have to create the file manually."); } } public void loadConfig() { try { // Get the file File f = new File(CONFIG_FILE); Logger.log("File path: " + f.getAbsolutePath()); // Check if the file exists FileReader file = new FileReader(f); Logger.log("Loading config file."); BufferedReader reader = new BufferedReader(file); String line; while ((line = reader.readLine()) != null) { String[] parts = line.split(","); if (parts.length == 2) { // To to load settings String name = parts[0]; try { Integer.parseInt(parts[1]); } catch (NumberFormatException e) { Logger.error("Invalid setting value " + parts[1] + " skipping setting " + name); continue; } int value = Integer.parseInt(parts[1]); if (settings.containsKey(name)) { settings.put(name, value); Logger.log("Setting " + name + " to " + value); } else { Logger.error("Invalid setting " + name); } } } reader.close(); } catch (IOException e) { // If file not exists try to create default config file if (e instanceof FileNotFoundException) { Logger.log("Config file not found, creating default config file."); saveConfig(); } else { Logger.error("Error loading config file."); } } } @Override public void onMouseClicked(MouseEvent e) { // If user clicked on settings try to open them if (SETTINGS_CLICK_AREA.contains(e.getPoint())) { log("Opening settings: " + CONFIG_FILE); File file = new File (CONFIG_FILE); Desktop desktop = Desktop.getDesktop(); try { desktop.open(file); } catch (IllegalArgumentException ex) { Logger.error("Config file isn't found, you might need to create it manually."); throw new RuntimeException(ex); } catch (IOException ex) { throw new RuntimeException(ex); } } } } Edited January 26 by bakbuk
rsrose 3 Posted July 18, 2024 Could there be a setting to autobuy from GE the amount of runes/ wiz gear? - thanks!
bakbuk 1 Author Posted July 18, 2024 19 minutes ago, rsrose said: Could there be a setting to autobuy from GE the amount of runes/ wiz gear? - thanks! Sure thing.
taltonis 3 Posted July 19, 2024 I dont think barbarians have an elemental weakness only casting air strike might be the best in terms of dps and cost. Could be wrong
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now