I'm a fairly new member to these forums. Recently I've written a simple state machine script to pick up and bank bones at the Al-Kharid palace. As I'm not sure how to properly use this API (the API is written badly tbh) I got recently banned for macroing. Basically I had created an fresh account and just to see how stuff works with these scripts I decided to make a simple bone collector.
I've ran this for around 4 hours total and collected around 1300 bones. I think my account was already flagged after 2 hours which was before I used simple anti ban. Before I started I check the ban meter and it was empty and after 2 hours there was a really small green line.
I've tried to add as much random camera movement and sleeps / delays as possible.
The only real problem I had is that I don't know how to properly handle obstacles (mainly doors).
Here is the code:
@ScriptManifest(author = "Ker", info = "Collects bones at Al-Kharid and banks them", name = "BoneCollector", version = 0, logo = "")
public class main extends Script
{
private static final Area BANK_AREA = new Area(3269, 3171, 3272, 3163);
private static final Area BONE_AREA[] = new Area[]{new Area(3282, 3177, 3287, 3167), new Area(3299, 3177, 3303, 3167), new Area(3287, 3167, 3298, 3172)};
private static Area goalArea = BONE_AREA[0];
private final int MIN_PITCH = 54;
private final int MAX_PITCH = 67;
private final int MIN_YAW = 252;
private final int MAX_YAW = 311;
private final int MAX_EMPTY_TIMEOUT = 15;
private static ScriptState currentState = ScriptState.IDLE;
private static int emptyTimeOut = 0;
private static int bonesCollected = 0;
private static long timeStarted = System.currentTimeMillis();
private static long nextCameraRotation = System.currentTimeMillis();
@Override
public void onStart()
{
this.antiBan.initializeModule();
log("Loading BoneCollector!");
log("BoneCollector Started!");
}
@Override
public int onLoop() throws InterruptedException
{
if (currentState.equals(ScriptState.IDLE)) //Handles IDLE state. Only triggered upon first restart.
{
return this.handleIdle();
}
else if (currentState.equals(ScriptState.TO_BANKING)) //Handles going to the bank.
{
return this.handleToBanking();
}
else if (currentState.equals(ScriptState.BANKING)) //Handles banking.
{
return this.handleBanking();
}
else if (currentState.equals(ScriptState.TO_PICKING)) //Handles walking to an area.
{
return this.handleToPicking();
}
else if (currentState.equals(ScriptState.PICKING)) //Handles picking bones.
{
return this.handlePicking();
}
else //Any other state. Shouldn't be triggered tbh.
{
return this.handleUnknown();
}
}
@Override
public void onExit()
{
log("Bone Collector stopped!");
}
@Override
public void onPaint(Graphics2D g)
{
final Color transparent = new Color(0, 0, 0, 167);
final Color green = new Color(17, 255, 0);
final BasicStroke stroke = new BasicStroke(1.0F);
final Font font1 = new Font("Arial", 0, 11);
long elapsed = System.currentTimeMillis() - timeStarted;
g.setColor(transparent);
g.fillRect(3, 288, 110, 50);
g.setColor(green);
g.setStroke(stroke);
g.drawRect(3, 288, 110, 50);
g.setFont(font1);
g.drawString("Time: " + format(elapsed), 15, 303);
g.drawString("State: " + currentState.name().toLowerCase().replace("_", " "), 15, 315);
g.drawString("Bones: " + bonesCollected, 15, 327);
}
private int handleIdle()
{
currentState = ScriptState.TO_BANKING;
for (Area area : BONE_AREA)
{
if (area.contains(myPlayer()))
{
if (!inventory.isFull())
{
currentState = ScriptState.PICKING;
}
}
}
doRandomCameraRotation();
return random(500, 1500);
}
private int handleToBanking() throws InterruptedException
{
if (BANK_AREA.contains(super.myPlayer()))
{
currentState = ScriptState.BANKING;
getLocalWalker().walk(objects.closest("Bank Booth"));
getCamera().toEntity(objects.closest("Bank Booth"));
getCamera().toTop();
objects.closest("Bank Booth").interact("Bank");
log("Banking");
return random(500, 2000);
}
else
{
if (!super.doorHandler.handleNextObstacle(BANK_AREA.getRandomPosition(0)))
{
super.getLocalWalker().walk(BANK_AREA.getRandomPosition(0), true);
super.getLocalWalker().waitUntilIdle();
}
log("Still walking to bank...");
doRandomCameraRotation();
return random(500, 2500);
}
}
private int handleBanking() throws InterruptedException
{
Bank bank = objects.getBank();
if (bank != null)
{
bank.open();
sleep(random(100, 1000));
bank.depositAll();
sleep(random(100, 500));
if (random(0, 50) >= 30)
{
bank.close();
}
currentState = ScriptState.TO_PICKING;
log("Deposited all bones!");
}
else
{
log("Bank not found :(");
}
doRandomCameraRotation();
return random(500, 1500);
}
private int handleToPicking() throws InterruptedException
{
if (goalArea.contains(super.myPlayer()))
{
currentState = ScriptState.PICKING;
log("Started picking bones!");
}
else
{
if (!doorHandler.handleNextObstacle(goalArea.getRandomPosition(0)))
{
super.getLocalWalker().walk(goalArea.getRandomPosition(0), true);
super.getLocalWalker().waitUntilIdle();
log("Still walking to bone area!");
}
}
doRandomCameraRotation();
return random(500, 1500);
}
private int handlePicking() throws InterruptedException
{
if (camera.getYawAngle() < MIN_YAW || camera.getPitchAngle() < MIN_PITCH)
{
nextCameraRotation = System.currentTimeMillis() - 10000;
doRandomCameraRotation();
}
if (this.myPlayer().isUnderAttack())
{
currentState = ScriptState.TO_BANKING;
log("Being attacked, running to bank!");
return random(100, 600);
}
if (emptyTimeOut >= MAX_EMPTY_TIMEOUT)
{
nextArea();
emptyTimeOut = 0;
return random(100, 400);
}
if (inventory.isFull())
{
currentState = ScriptState.TO_BANKING;
log("Going to bank, inventory full!");
return random(500, 3000);
}
else
{
log("Looking for some bones!");
List<GroundItem> items = this.getGroundItems().getAll();
Collections.shuffle(items);
if (items.isEmpty())
{
if (random(0, 20) == 3)
{
if (!doorHandler.handleNextObstacle(goalArea.getRandomPosition(0)))
{
this.getLocalWalker().walk(goalArea.getRandomPosition(myPlayer().getHeight()), true);
}
}
}
else
{
int beforeSize = inventory.getEmptySlots();
for (GroundItem item : items)
{
if (goalArea.contains(item))
{
if (!item.isVisible() || !item.isOnScreen())
continue;
if (item.getName().equalsIgnoreCase("bones"))
{
if (item.interact("Take"))
{
super.localWalker.waitUntilIdle();
super.doorHandler.handleNextObstacle(goalArea);
super.getLocalWalker().waitUntilIdle();
if (inventory.getEmptySlots() != beforeSize)
++bonesCollected; //Sometimes not updating correctly. Not sure why. Lagg?
emptyTimeOut = 0;
return random(500, 1500);
}
}
}
}
++emptyTimeOut;
}
doRandomCameraRotation();
}
return random(500, 1500);
}
private int handleUnknown()
{
log("Not sure what happened, we ended up in a weird state. Going to bank anyways...");
currentState = ScriptState.TO_BANKING;
return random(100, 500);
}
private void doRandomCameraRotation()
{
if (nextCameraRotation < System.currentTimeMillis())
{
nextCameraRotation = System.currentTimeMillis() + random(2000, 7500);
int i = random(0, 10);
if (i < 4)
getCamera().movePitch(random(0, 360));
else
{
if (i == 10)
{
getCamera().movePitch(random(MIN_PITCH, MAX_PITCH));
}
getCamera().moveYaw(random(0, 360));
}
}
}
private void nextArea()
{
goalArea = BONE_AREA[random(0, BONE_AREA.length - 1)];
currentState = ScriptState.TO_PICKING;
}
//Kudo's to whoever wrote this method. Saved me a little time :P
public String format(long time)
{
StringBuilder string = new StringBuilder();
long totalSeconds = time / 1000L;
long totalMinutes = totalSeconds / 60L;
long totalHours = totalMinutes / 60L;
int seconds = (int)totalSeconds % 60;
int minutes = (int)totalMinutes % 60;
int hours = (int)totalHours % 24;
if (hours > 0) {
string.append(hours + "h ");
}
if (minutes > 0) {
string.append(minutes + "m ");
}
string.append(seconds + "s");
return string.toString();
}
public enum ScriptState
{
IDLE,
PICKING,
BANKING,
TO_PICKING,
TO_BANKING
}
}
Feel free to leave suggestions and feedback. If anyone could give a proper example on how to deal with doors / obstacles when walking to a certain area, that'd be appreciated.
You can compile and try this for yourself however I can not give you any guarantee you won't get banned.
Script feedback & suggestions.
in Scripting Help
Posted · Edited by Ker
Hello all,
I'm a fairly new member to these forums. Recently I've written a simple state machine script to pick up and bank bones at the Al-Kharid palace. As I'm not sure how to properly use this API (the API is written badly tbh) I got recently banned for macroing. Basically I had created an fresh account and just to see how stuff works with these scripts I decided to make a simple bone collector.
I've ran this for around 4 hours total and collected around 1300 bones. I think my account was already flagged after 2 hours which was before I used simple anti ban. Before I started I check the ban meter and it was empty and after 2 hours there was a really small green line.
I've tried to add as much random camera movement and sleeps / delays as possible.
The only real problem I had is that I don't know how to properly handle obstacles (mainly doors).
Here is the code:
Feel free to leave suggestions and feedback. If anyone could give a proper example on how to deal with doors / obstacles when walking to a certain area, that'd be appreciated.
You can compile and try this for yourself however I can not give you any guarantee you won't get banned.
Thanks,
Ker