Welcome to TRiBot Forums

Register now to gain access to all of our features. Once registered and logged in, you will be able to contribute to this site by submitting your own content or replying to existing content. You'll be able to customize your profile, receive reputation points as a reward for submitting content, while also communicating with other members via your own private inbox, plus much more! This message will be removed once you have signed in.

Sign in to follow this  
Followers 0
TRiLeZ

Guide to Implementing ABC2

30 posts in this topic

ABC2 is the second version of TRiBot's Anti-Ban Compliance utility, whose aim is to provide scripts with a standardized anti-ban, backed by character profiles. ABC2 has been built upon statistical analysis of human playing data, making our anti-ban the most human-like on the market. Read more about the importance of modeling human playing data here: https://tribot.org/forums/topic/60719-tribot-release-9300-0-abc2/.
 
So now you must be wondering how to implement ABC2 in your script. First, I will link the main utility: https://tribot.org/doc/org/tribot/api/util/abc/ABCUtil.html. Each script should use one instance of ABCUtil, unless the script switches RuneScape accounts during runtime. Since each ABCUtil instance is tied to a single character profile for an account, the script must create a new ABCUtil instance if a new RuneScape account starts to be used throughout the runtime of the script.
 
Upon creating a new ABCUtil instance, a thread will be started which is in charge of tracking XP gains, and making the mouse enter/leave the game screen. For this reason, it is important to call ABCUtil#close when you are finished with a specific ABCUtil instance to stop the background thread from executing, and to clean-up.
 
Now, there are four types of scenarios which ABCUtil oversees:

Timed Actions
 
These are actions which are performed based on internal timers. For each timed action, simply use the should method to check if you should perform the action. If true, call the other corresponding method to perform the action. These actions should only be performed when the player isn't particularly busy at the time. Ex: If the player is woodcutting, these actions should be checked/performed while chopping down the tree.
 
Example on how to use the methods:

// Here our player is idling, so we can check/perform the timed actions.
if (this.abc_util.shouldCheckTabs())
	this.abc_util.checkTabs();

if (this.abc_util.shouldCheckXP())	
	this.abc_util.checkXP();

if (this.abc_util.shouldExamineEntity())
	this.abc_util.examineEntity();

if (this.abc_util.shouldMoveMouse())
	this.abc_util.moveMouse();

if (this.abc_util.shouldPickupMouse())
	this.abc_util.pickupMouse();

if (this.abc_util.shouldRightClick())
	this.abc_util.rightClick();

if (this.abc_util.shouldRotateCamera())
	this.abc_util.rotateCamera();

if (this.abc_util.shouldLeaveGame())
	this.abc_util.leaveGame();

Preferences
 
These are preferred ways of doing things as specified by the player's character profile. Note that the preference generated by each method isn't constant, so we should not store the returned value of the generation method. So when an area covered by ABC preferences comes up, we must call the generation method, and act upon the returned value.
 
Example: Let's say we want to open the bank using custom methods. We then use ABCUtil#generateOpenBankPreference to generate the preferred way to open the bank.

final OpenBankPreference pref = this.abc_util.generateOpenBankPreference();
switch (pref) {
 case BANKER:
  openBankBanker();
  break;

 case BOOTH:
  openBankBooth();
  break;

 default:
  throw new RuntimeException("Unhandled open bank preference.");
}

Note that Banking#openBank, GameTab#open, and web walking all take ABC preferences into account, so we don't have to worry about handling preferences if we use those methods.
 
Next Target Preference
 
ABCUtil#selectNextTarget selects the positionable entity from the given list which should be our next target.  We should store this value until we switch targets (i.e. the entity which we are interacting with), because the output of this method isn't constant. I.e. We call this method to determine which entity to interact with next, and store the returned value so we aren't constantly calling this method. We can re-call this method and re-store the returned value when we move on to a different target entity.
 
If an entity spawns which is closer than the original closest entity, then we can re-call this method to re-select the next target entity. Otherwise, we should stick with the stored value.
 
Note that when we chose an entity which is not the closest, that entity will be within a close distance to the closest, and if the entity implements Clickable07, we will check if it is clickable via Clickable07#isClickable.
 
Example:

final RSObject[] objects = getPossibleTargets();
if (objects == null || objects.length < 1) 
return;

final RSObject next_target = (RSObject) this.abc_util.selectNextTarget(objects);

Action Conditions
 
These are actions which depend on a condition generated by ABCUtil. Note that the conditions generated by each method isn't persistent, and we want a certain level of persistence for each type of action. Therefore, we must store the returned value of the methods for a certain period of time, specified below.
 
HP to Eat At
 
ABCUtil#generateEatAtHP will generate the hitpoints percentage at which we should eat at. We store the generated value and use it until we eat the next food item. At that time, we generate a new value and store it.
 
Example:

int eat_at = this.abc_util.generateEatAtHP(); // Global variable, persistent...
// Inside of a local method
if (getHPPercent() <= this.eat_at) {
 eatFood();
 this.eat_at = this.abc_util.generateEatAtHP(); // Generate a new HP percentage to eat at
}

Energy to Activate Run At
 
ABCUtil#generateRunActivation will generate the run energy at which we should activate run at. We store the generated value and use it until we turn run on. At that time, we generate a new value and store it.
 
Example:

int run_at = this.abc_util.generateRunActivation(); // Global variable, persistent...
// Inside of a local method
if (!Game.isRunOn() && Game.getRunEnergy() >= this.run_at) {
 Options.setRunOn(true);
 this.run_at = this.abc_util.generateRunActivation(); // Generate a new run energy to activate run at
}

Moving to Anticipated Location
 
When we finish interacting with our latest target/resource, there may or may not be a next target/resource available. If there is, then we simply go to that target/resource as usual and ignore this action condition. However, if there is no next target/resource currently available, then we check this action condition.
 
We check ABCUtil#shouldMoveToAnticipated immediately after we finish up with our latest target/resource. If the method returns true, we move to the location in which we anticipate our next target/resource will spawn. If it returns false, we do nothing.
 
Example:

// Here we just finished cutting a yew tree
if (!findNextTarget()) { // If we are here, then there does not exist a next target/resource yet
 if (this.abc_util.shouldMoveToAnticipated()) { // Check if we should move to the anticipated location...	
  performReactionTimeWait(); // Sleep for the generated reaction time		
  moveToAnticipated(); // Move to the anticipated location	
 }
 // Now we simply wait until a new target/resource spawns	
 // Do not keep checking if we should move to the anticipated location	
 // Only perform this check once after each target/resource becomes unavailable
}

Resource Switching Upon High Competition
 
ABCUtil#shouldSwitchResources will decide if we should switch targets/resources based on the amount of competing players. We should check this condition every 20-30 seconds, but only if we are not winning very many resources from the other competing players. This is vague because it depends on the script and individual preferences.
 
Example:

// Here we start mining a rock
long check_time = Timing.currentTimeMillis() + General.random(20000, 30000);
while (isMining()) {
 if (notWinningManyResources() && Timing.currentTimeMillis() >= check_time) { // Check if we should switch resources
  if (this.abc_util.shouldSwitchResources(getCompetitionCount()) {
    switchResources(); //Switch resources			return;
   }
   check_time = Timing.currentTimeMillis() + General.random(20000, 30000); // Generate a new check time	
  }
 }

Next Target Hovering and Menu Opening
 
ABCUtil#shouldHover will decide if we should hover the mouse over our next target. We should use this method to determine if we should hover when we start interacting with each new target entity, and we store the returned value. While interacting with our current target, if the stored value indicates we should hover our next target, then we should do so. Note that we should only employ hovering when the mouse is in the screen boundary.
 
ABCUtil#shouldOpenMenu will decide if we should open the menu for our next target. We should use this method to determine if we should hover when we start interacting with each new target entity, and we store the returned value. While interacting with our current target, if the stored value indicated we should open the menu for our next target, AND if we are hovering the mouse over the next target, then we should open the menu. Menu opening should only be performed if we are also hovering the next target. Note that we should only employ menu opening when the mouse is in the screen boundary.
 
Example:

boolean should_hover = false; // Global variable, persistent
boolean open_menu = false; // Global variable, persistent...
// Inside of a local method
if (the_object.click("Chop down")) {
 this.should_hover = this.abc_util.shouldHover();
 this.open_menu = this.abc_util.shouldOpenMenu(); // Generate other conditions for actions	handleChopping();
}
// Inside of a different local method, 
handleChoppingwhile(isChopping) {
 if (Mouse.isInBounds() && this.is_hovering) {
  hoverNextTarget();
  if (this.open_menu)
   openMenuForNextTarget();
 } // Other code
}

Reaction Times
 
ABC2's reaction time generator relies on about nine different factors, many of which must be specified by the script. There are two different ways to specify these factors: bit flags and properties.
 
With bit flags, you call ABCUtil#generateBitFlags with the necessary options, and that method will generate the bit flags. With properties, you call ABCUtil#getProperties and set the necessary properties with the returned instance of ABCProperties.
 
Generating Reaction Times
 
You must use ABC2 to generate reaction times, instead of using random sleeps. ABC2's reaction time generator was designed to be very generic, allowing it to be used for all things which require a variable response time. However, we are still in need of some human data to allow us to have it totally generic. When generating reaction times for events with a fixed, very low waiting time, the reaction times are often much higher than a human reaction time. Hence, until we collect some more data and adjust our algorithms, ABC2's reaction time generator should be used for the following circumstances:

  • Waiting in response to a condition where we had to wait a variable amount of time typically greater than a second. Examples:
    • Reacting to when our character stops fishing. The response time will be used before we move on to the next fishing spot, or before we walk to the bank.
    • Reacting to when our character stops mining. The response time will be used before we move on to the next rock, or before we walk to the bank.
    • Reacting to when our character kills our target NPC. The response time will be used before we attack our next target, or before we walk to the bank.

We currently will not use ABC2's reaction time generator for the following circumstances, until more data has been collected and we have adjusted our algorithms:

  • Waiting in response to finishing an alchemy spell (the waiting period for casting the spell is fixed, and thus not covered by ABC2 yet)
  • Waiting in response to us finishing our wait for items to be deposited to the bank after clicking the "Deposit All" button (once again, the waiting period is fixed).

These are only limited scenarios which we specified. There are obviously more scenarios than this, but I'm hoping you're able to figure it out based on the examples.
 
Now, to generate reaction times, you have the chose of two methods:

The first method uses properties, and the second uses bit flags, as discussed above.
 
For generating reaction times, there are currently four factors which must be specified by scripts:

  • Waiting Time: The amount of time we were waiting for in order to perform the action we are wanting to do now.
  • Hovering: If we were hovering over the entity we are about to click immediately prior to calling the method.
  • Menu Open: If we have the menu open for the entity we are about to click immediately prior to calling the method.
  • Under Attack: If we are under attack now, or if we were under attack while waiting.
  • Fixed Waiting: Whether the time at which we were waiting can be fixed to a number of client clock cycles or time (currently not used since we lack data for this, but this is here for the future). This will typically not be set because of the reason explained above.

Example using bit flags:

final int waiting_time = getWaitingTime();
final boolean menu_open = this.abc_util.shouldOpenMenu() && this.abc_util.shouldHover();
final boolean hovering = this.abc_util.shouldHover(); // If the condition is met, we specify the relevant flag, otherwise we set the variable to 0
// When we pass 0 into generateReactionTime as a bit flag option, it will not change anything
final long hover_option = hovering ? ABCUtil.OPTION_HOVERING : 0;
final long menu_open_option = menu_open ? ABCUtil.OPTION_MENU_OPEN : 0;
// Generate the reaction time
final int reaction_time = this.abc_util.generateReactionTime(this.abc_util.generateBitFlags(waiting_time, hover_option, menu_open_option));
// Sleep for the reaction time
try {
 this.abc_util.sleep(reaction_time);
} catch (final InterruptedException e) {

}

Example using properties:

final int waiting_time = getWaitingTime();
final boolean menu_open = this.abc_util.shouldOpenMenu() && this.abc_util.shouldHover();
final boolean hovering = this.abc_util.shouldHover();
final ABCProperties props = this.abc_util.getProperties();
props.setWaitingTime(waiting_time);
props.setHovering(hovering);
props.setMenuOpen(menu_open);
props.setUnderAttack(Combat.isUnderAttack() || wasJustUnderAttack());
props.setWaitingFixed(false);
// Generate the reaction time
final int reaction_time = this.abc_util.generateReactionTime();
// Sleep for the reaction time
try {
 this.abc_util.sleep(reaction_time);
} catch (final InterruptedException e) {

}

When using properties, remember to explicitly set all applicable options so that you don't use old data from previous uses.
 
Generating Supporting Tracker Information
 
A core factor in generating reaction times is whether or not the mouse is currently within the game screen boundary, along with other linked factors which I am keeping secret. ABCUtil's background thread will be responsible for manipulating these factors. In order for it to do so, it must know certain information about the activity being performed. We give it this information via ABCUtil#generateTrackers.
 
ABCUtil#generateTrackers generates variables for performing anti-ban while waiting for something. Specifically, variables relating to how often and when to make the mouse leave the game area. This method should be called right after clicking something which requires us to wait a variable amount of time, or a time which we have to try and count off; i.e. where we will produce a variable reaction time. This includes, but is not limited to, clicking a tree, clicking an interface which we have to wai, say, approx. 10 seconds for.
 
This method requires the script to supply two pieces of information:

  • Estimated waiting time: An estimate for the amount of time we will be waiting for, i.e. how long it takes to perform the action at hand. Example: When woodcutting, the estimated waiting time would be an estimate for how long we are going to be chopping the current tree. Typically, using the average waiting time for the specific action is a good estimate.
  • Under Attack: If we think we are going to be under attack for any of the duration of the waiting time.

Like generating reaction times, calling this method can either be done using bit flags or properties.
 
Example using bit flags:

if (successfullyClickedTree()) {
 final int est_waiting;
 if (this.chopping_count > )
  est_waiting = (int)(this.chopping_time / this.chopping_count);
 else
  est_waiting = 3000; // An arbitrary value, only used at the very beginning of the script
 this.abc_util.generateTrackers(this.abc_util.generateBitFlags(est_waiting));
 while (isChopping()) {
  if (this.abc_util.shouldLeaveGame())
   this.abc_util.shouldLeaveGame();
   // Do other things here, such as hovering and menu opening if the mouse is still in the game screen boundary	
 }
}

Example using properties:

if (successfullyClickedTree()) {
 final int est_waiting;
 if (this.chopping_count > )
  est_waiting = (int)(this.chopping_time / this.chopping_count);
 else est_waiting = 3000; // An arbitrary value, only used at the very beginning of the script	
 final ABCProperties props = this.abc_util.getProperties();
 props.setWaitingTime(est_waiting);
 props.setUnderAttack(false);
 props.setWaitingFixed(false);
 this.abc_util.generateTrackers();
 while (isChopping()) {
  if (this.abc_util.shouldLeaveGame())
   this.abc_util.shouldLeaveGame();
  // Do other things here, such as hovering and menu opening if the mouse is still in the game screen boundary	
 }
}

Now you may be wondering where exactly to call this method. Generally, you'd call this after generating a reaction time using ABC2, after we call ABCUtil#sleep for that reaction time, and after we perform the action which we are reacting to.
 
It's important to keep in mind that calling ABCUtil#generateTrackers is very important because it sets up variables which greatly affect reaction times. Also note that we should be calling ABCUtil#shouldLeaveGame and ABCUtil#leaveGame in the period after calling ABCUtil#generateTrackers, as the method is to be used in conjunction with ABCUtil#shouldLeaveGame and ABCUtil#leaveGame. If we do not ever call those two methods, or don't call them often enough, calling ABCUtil#generateTrackers would be essentially useless, and our reaction times wouldn't be the most human-like.
 
Sleeping for the Length of the Reaction Time
 
it is important to use ABCUtil#sleep to perform all of the reaction time sleeps. ABC2's background thread is in charge of making the mouse return to the game screen boundary if the mouse has been outside of the boundary for a certain period of time. Now, the times at which the background thread makes the mouse return has been pre-determined. It's possible that it makes the mouse return while we are sleeping for the duration of the reaction time. If it does this, then why do we have to continue our reaction time sleep if the mouse is moving (i.e. the player is active)? Simply put, when the mouse returns to the game screen, we should stop sleeping the duration of the reaction time because the player is active.
 
When the script calls ABCUtil#sleep, it allows the background thread to interrupt the reaction time sleep immediately after the bot makes the mouse return to the game screen. The method also prevents two mouse movements from happening at the same time, since the background thread doesn't pause the script while moving the mouse back to the game screen.
 
Calculating Anti-Ban Compliance Levels (ABCL)
 
Refer to the first list. Beside each element is an amount of points (Pts). If your script successfully implements the element, then add those points to your score. Scores are out of 100, which determine the ABCL:

  • [99, 100] Points: ABCL 10
  • [90, 99) Points: ABCL 9
  • [80, 90) Points: ABCL 8
  • [70, 80) Points: ABCL 7
  • [60, 70) Points: ABCL 6
  • [50, 60) Points: ABCL 5
  • [40, 50) Points: ABCL 4
  • [30, 40) Points: ABCL 3
  • [20, 30) Points: ABCL 2
  • [10, 20) Points: ABCL 1
  • [0, 10) Points: ABCL 0

Note: "[" is an inclusive boundary, and ")" is an exclusive boundary.
 
Conclusion
 
There you have it, the guide to implementing Anti-Ban Compliance version two. I hope I have made it clear how to implement ABC2. Make sure to read all of the documentation.
 
I am including a persistent extension of ABCUtil, which makes this utility more like the first version, and easier to use:

PersistentABCUtil.java

Edited by erickho123
Forum Software update made all lines one lined. Attempted to fix it.
7 people like this

Share this post


Link to post
Share on other sites

Much respect for @TRiLeZ always had but this is amazing thank you so much <3 

Share this post


Link to post
Share on other sites

Seems much more well thought than version 1. Also easier for scripters to implement. Thanks.

Share this post


Link to post
Share on other sites

@Tri Could you please implement this to your AIO combat/magic script? Going to be purchasing it in about 4 weeks :)

Share this post


Link to post
Share on other sites

@Ericho123 & @Tri could you guys please implement this to your scripts? :D

I have a feeling that if it is there they will implement it.   It would be a huge selling point if their scripts had it and others did not.  I thought exShopper and exRunecrafter were already amazing.  I cannot wait to see if after.

Share this post


Link to post
Share on other sites

Well done! Thank you for the detailed tutorial. I also enjoyed the statistical data analysis, thank you for sharing that :). I am excited to get started on a script using these. 

Edited by botsallday

Share this post


Link to post
Share on other sites

Documentation is way better than the initial ABCL documentation. Looks great!

1 person likes this

Share this post


Link to post
Share on other sites

When generating the reaction time, you are determining if you are hovering or if the menu is open by the values returned by the ABCUtil methods shouldHover and shouldOpenMenu, not if you actually are hovering or have the menu open. Is this intended?

Share this post


Link to post
Share on other sites

When generating the reaction time, you are determining if you are hovering or if the menu is open by the values returned by the ABCUtil methods shouldHover and shouldOpenMenu, not if you actually are hovering or have the menu open. Is this intended?

I also found this confusing, and it's worth mentioning that there are many actions in Runescape that humans will spam click, or activities with very little downtime, which humans will react fairly quickly to. What is the ABC2 policy on those? As mentioned in the OP, we're supposed to hold back on implementing any ABC2 reaction time methods for those circumstances until more data is collected? Is there any risk to implementing them now as opposed to short generic random sleeps?

Edited by ineu

Share this post


Link to post
Share on other sites

I've placed the timed actions code inside of a method, antiban(), and I call this method whenever I am idling. Is this ok, because I've been watching the bot for like 30 minutes now and I have yet to see any of the antiban actions happen. Also, does it matter what order I call the timed action checks in? I'm sure it would look suspicious during behavioral analysis if a player always checks xp only before the player cursor leaves the game. Also, if I try to add a System.out.println to happen whenever an antiban action is actually happening, the bot will just spazz out with antiban and do timed actions like crazy

Edited by brainblips

Share this post


Link to post
Share on other sites

I've placed the timed actions code inside of a method, antiban(), and I call this method whenever I am idling. Is this ok, because I've been watching the bot for like 30 minutes now and I have yet to see any of the antiban actions happen. Also, does it matter what order I call the timed action checks in? I'm sure it would look suspicious during behavioral analysis if a player always checks xp only before the player cursor leaves the game. Also, if I try to add a System.out.println to happen whenever an antiban action is actually happening, the bot will just spazz out with antiban and do timed actions like crazy

I have mine print out whenever a check returns true and it does the action, and it does not spazz out. You must have missed a bracket or something.

Share this post


Link to post
Share on other sites

Hi, was wondering: If i make a simple bot just mining and dropping, should i implement all kinds of acb utils on that one then? I see good scripts make a good reputation having acbl10, but is that any point if there is some of the features not to be even used?

Share this post


Link to post
Share on other sites

Can you give us a small example script? I could really use a learning example to get an idea of what and where exactly should I implement.

Share this post


Link to post
Share on other sites

When generating a large reaction time (example, I had one of ~292000 ms) which allowed the bot to get automatically logged out, the Login bot kicks in and logs the bot in even though it should still be sleeping. Are we meant to disable the login bot for the reaction time? Might be worth noting to do so if the reaction time is exceedingly long.

Share this post


Link to post
Share on other sites
6 hours ago, Ibotrs99 said:

What does "loading human mouse movement data." "could not load human mouse data: reason: human mouse encryption key not found" what does that mean guys?

 

http://prntscr.com/b1ihnm

You need to be a VIP-E in order to use the human mouse movement.

Share this post


Link to post
Share on other sites
29 minutes ago, Kappaccino said:

You need to be a VIP-E in order to use the human mouse movement.

Does it help with anti ban?

Share this post


Link to post
Share on other sites
11 minutes ago, Ibotrs99 said:

Does it help with anti ban?

Many would say so, see how it works here:

In lieu of getting VIP-E, you can submit human mouse data files to get access to the human mouse movements.

 

Share this post


Link to post
Share on other sites

Is it normal If I am making tabs in my POH and the only timed action that happens while I do it is mouse leaving the game? I call abcutil.generateTrackers right before the loop of waiting for the tabs to be made begins. My code is arraged this way:

abcUtil.generateTrackers
while ([inventory contains at least one soft clay]) {
  if (abcUtil.shouldRotateCamera) {
    abcUtil.rotateCamera;
  }
  //and so on with the other timed actions
}

Am i doing sth very very wrong or is that meant to be?

Share this post


Link to post
Share on other sites

When tallying up the points to see which threshold you're at as in ABCL 0,1,2, etc. When i come across this

 

Quote

Note that Banking#openBank, GameTab#open, and web walking all take ABC preferences into account, so we don't have to worry about handling preferences if we use those methods.

If i use those Banking#openBank and Web Walking inside my script, would i just count those points aswell?

Share this post


Link to post
Share on other sites
3 hours ago, montreal176 said:

When tallying up the points to see which threshold you're at as in ABCL 0,1,2, etc. When i come across this

 

If i use those Banking#openBank and Web Walking inside my script, would i just count those points aswell?

As examples:

Banking#openBank() will use abc preferences to decide whether it should do Banking#openBankBooth() or Banking#openBankBanker(), for the booth vs the npc.

GameTab#open will use abc preferences to decide whether it clicks the tab or uses the F key shortcuts to open the tab.

So long as you use those methods for those specific actions or implement it via abc if you need to do it in a custom way, you are good.

1 person likes this

Share this post


Link to post
Share on other sites

Quick question regarding the performTimedActions Method --

I notice mine isnt checking the XP, Is there something special that i have to do to make it check the XP? The reason i ask is because i know you have to use generateTrackers() for the mouse to leave the screen.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0

  • Recently Browsing   0 members

    No registered users viewing this page.