Fanny Posted May 19 Share Posted May 19 I have been trying to write an effective custom sleep handler - I have commented through the method to make it clearer what the purpose of each stage is. I am having trouble with implementation on my latest attempt at a script - I find that when interacting it is tending to spam click when I don't expect that behaviour Any advice? (also free sample code if anyone can make use of it! :)) CS.java import org.osbot.rs07.utility.ConditionalSleep; import java.util.Random; import java.util.function.BooleanSupplier; import org.osbot.rs07.script.Script; public class CS extends ConditionalSleep { private final BooleanSupplier condition; private final Script script; private final int initialDurationMs; private final int additionalDurationMs; private final Random random = new Random(); public CS(Script script, int initialDurationMs, int additionalDurationMs, BooleanSupplier condition) { super(initialDurationMs + additionalDurationMs); this.initialDurationMs = initialDurationMs; this.additionalDurationMs = additionalDurationMs; this.condition = condition; this.script = script; } @Override public boolean condition() throws InterruptedException { boolean mouseOutOfScreen = false; // Small chance to move mouse out of screen immediately if (random.nextDouble() < 0.03) { script.getMouse().moveOutsideScreen(); mouseOutOfScreen = true; } // Capture the external condition to use inside the anonymous class BooleanSupplier localCondition = this.condition; // Small Sleep after action of ~ 300 - 800ms new ConditionalSleep(300 + random.nextInt(800 - 300), 100) { @Override public boolean condition() { return localCondition.getAsBoolean(); } }.sleep(); if(localCondition.getAsBoolean()) { // Small chance to move mouse out of screen after small wait if (random.nextDouble() < 0.10 && !mouseOutOfScreen) { script.getMouse().moveOutsideScreen(); mouseOutOfScreen = true; } // Sleep after the event is already true new ConditionalSleep(this.additionalDurationMs, 100) { @Override public boolean condition() { return false; } }.sleep(); } else { // Larger chance to move mouse out of screen after the condition is still not true if (random.nextDouble() < 0.50 && !mouseOutOfScreen) { script.getMouse().moveOutsideScreen(); mouseOutOfScreen = true; } // Sleep until the event is true, or until the timeout new ConditionalSleep(this.initialDurationMs, 100) { @Override public boolean condition() { return localCondition.getAsBoolean(); } }.sleep(); // Sleep after the event is already true new ConditionalSleep(this.additionalDurationMs, 100) { @Override public boolean condition() { return false; } }.sleep(); } return true; } } here is one example from the main script: (immediately inside onLoop method) for clarity: V just stores variables like V.worldBank is an area fatigueHandler is exactly what it sounds like - handles fatigue over time whilst playing which impacts the ms times it returns The minimum value for getSleepTimeMs() is 41ms However, clearly, from the script usage below, you can see that on bank.interact, it will either: 1) timeout after 5 seconds (in which case I haven't actually handled it yet) 2) succeed, in which case, it won't spam click anyway, since the bank will be open? Neither of these two possibilities involve spam clicking? Really appreciate any tips and advice on this if(V.worldBank.contains(myPlayer().getPosition()) && state == StateEngine.State.BANKING) { if(!getBank().isOpen()){ RS2Object bank = getNearestBank(); if(!bank.exists()){ log("Bank does not exist. Exiting."); onExit(); } bank.interact("Bank"); new CS(this, 5000, fatigueHandler.getSleepTimeMs(), () -> getBank().isOpen()); getBank().depositAll(); new CS(this, 3000, fatigueHandler.getShortSleepTimeMs(), () -> getInventory().isEmpty()); getBank().withdraw("Adamant pickaxe", 1); new CS(this, 3000, fatigueHandler.getShortSleepTimeMs(), () -> getInventory().contains("Adamant pickaxe")); getBank().close(); new CS(this, 3000, fatigueHandler.getShortSleepTimeMs(), () -> !getBank().isOpen()); return 20; } } Off topic, but bonus if anyone knows; regards random events, is there a way to implement only some specific ones and ignore the others? It seems awfully bot-like to just ignore all of them, particularly the genie and the free stuff ones like rick terpentine - don't want to solve any stupid events, but I know if I am playing legit I will just talk to those ones to get free stuff, would like to emulate that Quote Link to comment Share on other sites More sharing options...
yfoo Posted May 20 Share Posted May 20 What is the purpose of this? Is it to add a bit of extra delay after preforming any action along with potentially moving the mouse offscreen? Quote Link to comment Share on other sites More sharing options...
Fanny Posted May 20 Author Share Posted May 20 Yeah that is basically the reason for it - for convenience I was hoping to make a more complex sleep so I can write (or copy-paste) less of my code Since this doesn't seem to work, I am currently writing out the ConditionalSleep, then adding additional sleeps after, and writing the mouse offscreen code each time, which, given the amount of sleeps code tends to do, is annoying! Trying to just call a single function that performs a sleep-cycle the way I want it to sleep - I can then make the function do things like consider fatigue & high intensity play periods, mouse offscreen, and even occasionally AFK-log, only by writing a simple function call I'm pretty new to Java tbh, it is not easy! Quote Link to comment Share on other sites More sharing options...
yfoo Posted May 20 Share Posted May 20 1 hour ago, Fanny said: Yeah that is basically the reason for it - for convenience I was hoping to make a more complex sleep so I can write (or copy-paste) less of my code Since this doesn't seem to work, I am currently writing out the ConditionalSleep, then adding additional sleeps after, and writing the mouse offscreen code each time, which, given the amount of sleeps code tends to do, is annoying! Trying to just call a single function that performs a sleep-cycle the way I want it to sleep - I can then make the function do things like consider fatigue & high intensity play periods, mouse offscreen, and even occasionally AFK-log, only by writing a simple function call I'm pretty new to Java tbh, it is not easy! You can add some log statements into your CS class to debug what is failing. Alternatively do what you are currently doing with... > I am currently writing out the ConditionalSleep, then adding additional sleeps after, and writing the mouse offscreen code each time but separate it out into a static utility method. I have this class that does something along the same lines. It just reattempts something up to n times as there can be race conditions with opening an interface, waiting for the interface actually becoming usable ingame, and attempting to interact with a widget in the interface. public class RetryUtil { public static boolean retry(Callable<Boolean> fx, int maxAttempts, int retryWaitTime) throws InterruptedException { int attempts = 0; boolean isSuccess = false; while (attempts < maxAttempts) { try { isSuccess = fx.call(); } catch (Exception ignored) { } attempts++; if(isSuccess) { break; } MethodProvider.sleep(retryWaitTime); } return isSuccess; } ex usage RetryUtil.retry(() -> bank.withdraw(itemId, amount), 5, 1000) You can try making something similar where you pass in a Callable that has some code you want to run (like bank.open()). Sleep until it is open, then roll to sleep a bit more + move the mouse offscreen. Quote Link to comment Share on other sites More sharing options...
Fanny Posted May 20 Author Share Posted May 20 Thanks! I think this is probably where I am getting stuck, static vs. non-static is a bit confusing to me still I'll try adapting this to suit my use cases & let you know how I get on Quote Link to comment Share on other sites More sharing options...
BravoTaco Posted May 22 Share Posted May 22 (edited) On 5/20/2024 at 5:27 AM, Fanny said: Thanks! I think this is probably where I am getting stuck, static vs. non-static is a bit confusing to me still I'll try adapting this to suit my use cases & let you know how I get on Here's a link to help help explain the difference between static and non-static methods. https://www.geeksforgeeks.org/difference-between-static-and-non-static-method-in-java/ Edited May 22 by BravoTaco Quote Link to comment Share on other sites More sharing options...
Fanny Posted May 23 Author Share Posted May 23 On 5/20/2024 at 11:12 AM, yfoo said: public class RetryUtil { Thanks for sharing this - I genuinely hadn't thought of just looping with a short sleep, but this new approach, combined with understanding now static vs non-static has been extremely useful It has also allowed me to add additional functionality into the loop itself Quote Link to comment Share on other sites More sharing options...