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.

TheD

[Tutorial/Snippet] DTimer

23 posts in this topic

Hi Guys,

Lately I am using a separate class for some of my timing actions, and a feature I use a lot, which I call EndTimer. Not everybody has tons of time to maintain a bot farm, Or people want to bot over night, but only for a few hours. With EndTimer we cover some of these features, and it is all possible, and your script could be a whole lot more useful to some people. 

You can find the source code at the bottom of this tutorial.

 

About EndTimer

EndTimer is a really simple concept that logs you out after a certain time. You decide the global duration, and the res will be randomized. By default EndTimer is not on.

 

About DTimer in general

Next to EndTimer I also decided to add a couple of my other timing actions to the class. Like getting the current hour, minute and second.

 

Setting up DTimer

At the top of the script you'll see "package scripts.DTools;" 
Create a directory named DTools inside your scripts folder. Create a new Class named DTimer.java Copy the entire content from the pastebin link below, and paste it in DTimer.java

 

Using DTimer in your Script

Inside your run() function paste this:

DTimer.startScriptTimer(); //We want to start our timer
DTimer.callGUI(); //Call the GUI to let the user set-up EndTimer

We want the user to declare when we should end the script. We can either use the default GUI in EndTimer, which we call by using DTimer.callGUI(); or we can use DTimer.setEnd(HourToEndAt); if you would like to use your own GUI.

 

Placing EndTimer in your Script

Inside your loop we need to check a little something. To give you an example how it could look:

@Override
public void run() 
{
  while(true)
  {
  	if(DTimer.checkEndTimer()) //returns true if we succesfully logged out & are not in combat
  	{
		this.stopScript();
  	}
    
    //all the other code you have
    //even more code you have
    //moremoremore
    //somuchmore
    //feelsbadman still more
  }
}

The code you need to look at:

	if(DTimer.checkEndTimer()) //returns true if we succesfully logged out & are not in combat
  	{
		this.stopScript();
  	}

 

To display the time ran we could add a line like this in our paint:

g.drawString("time ran: "+ DTimer.getHour() + ":" + DTimer.getMinute() + ":" + DTimer.getSecond(), 5,305);

To also show the end time in our script you could use:

	if(DTimer.getEndAfterTime()) g.drawString("Ending script when we ran "+(DTimer.getEndHour())+":"+(DTimer.getEndMinute())+":"+(DTimer.getEndSeconds())+" (HH:MM:SS)", 10,315);
	if(!DTimer.getEndAfterTime()) g.drawString("Not using End-timer", 10,315);

 

Read the pastebin code and annotations for further information about the code!

 

http://pastebin.com/9dBcc7Aa

 

Side note: This could also be done using a Timer class. 

My colleague script writers gave some great examples: 

 

 

Share this post


Link to post
Share on other sites

Good contribution, I add a max runtime and/or "end at level" to most of my personal scripts so that they stop if I forget to turn them off or something. It really helps when you are managing or training a lot of accounts at once.

Share this post


Link to post
Share on other sites

Half of this code is re-inventing a date/time class:

getSecond/hour/minute/etc/etc/etc. You can remove half of this code immediately using a few off the shelf built right into the core api classes, such as the new Java 8 LocalDateTime class. Prior to 8 we had classes that handled this as well, why reinvent the wheel?

 

Let me preface the rest of my feedback on the fact that I did not read through all of this code.

It would appear I can only set a time in hours which is a bit crazy considering we are looking at a 450 line timer class.


This checkEndTimer method makes a few improper assumptions, has the ability to get stuck in an infinite loop, and has the ability to slow a script by potentially 3 seconds every loop cycle. There is no reason to check if the player is in combat if the next end time is in 13 hours. Furthermore, a 3 second wait is no guarantee on a player leaving combat. There is also no reason to do any of this if we are not even using the timer (end_after_time). The if statement to determine if the script has passed it’s end time is long winded, and can be simplified. The logout while loop has no exit point in the case something goes wrong, not even a timeout. So you potentially could be trying to logout for multiple minutes spam clicking the logout button every 1-5 seconds until your player dies, you get banned, or lose connection etc..

 

Warfront1

Edited by warfront1
3 people like this

Share this post


Link to post
Share on other sites
25 minutes ago, warfront1 said:

Half of this code is re-inventing a date/time class:

getSecond/hour/minute/etc/etc/etc. You can remove half of this code immediately using a few off the shelf built right into the core api classes, such as the new Java 8 LocalDateTime class. Prior to 8 we had classes that handled this as well, why reinvent the wheel?

 

Let me preface the rest of my feedback on the fact that I did not read through all of this code.

It would appear I can only set a time in hours which is a bit crazy considering we are looking at a 450 line timer class.


This checkEndTimer method makes a few improper assumptions, has the ability to get stuck in an infinite loop, and has the ability to slow a script by potentially 3 seconds every loop cycle. There is no reason to check if the player is in combat if the next end time is in 13 hours. Furthermore, a 3 second wait is no guarantee on a player leaving combat. There is also no reason to do any of this if we are not even using the timer (end_after_time). The if statement to determine if the script has passed it’s end time is long winded, and can be simplified. The logout while loop has no exit point in the case something goes wrong, not even a timeout. So you potentially could be trying to logout for multiple minutes spam clicking the logout button every 1-5 seconds until your player dies, you get banned, or lose connection etc..

 

Warfront1

Hi Warfront1,

Thanks for your feedback!

I overlooked the combat checker, I added it last minute, and indeed it was placed wrong. Since we would always wait, no matter if we should actually end the script already.
Changed it & updated code. Thanks. I also added a timeout to the while loop, just in case. You were right there too :).

I looked up the LocalDataTime class you were talking about : https://docs.oracle.com/javase/8/docs/api/java/time/LocalDateTime.html
Isn't this just for the time based on the real time, not based on time ran?

Would like to see a reply on it.

Thanks again!

DScripting

Share this post


Link to post
Share on other sites
9 minutes ago, kylezell said:

roasted^

He was giving him feedback on his code and how he can improve, not roasting him.

Share this post


Link to post
Share on other sites
9 minutes ago, Sphiinx said:

He was giving him feedback on his code and how he can improve, not roasting him.

Thats how I took it too :)

Share this post


Link to post
Share on other sites
                if(Player.getRSPlayer().isInCombat()) General.sleep(500,3000); //We could be in combat, so we wait a sec.
                if(Player.getRSPlayer().isInCombat()) return false; //still in combat, not going to spam log-out.

- Player#getRSPlayer can and will return null using your current logic. This will crash the script after an exception is thrown
- Using static sleeps won't guarantee that you've exited combat, use dynamic 
- I doubt 0.5 to 3 seconds is even close to the average amount of time  a player is in combat for
 

A lot of your code can be simplified. Having a timer object would make your life a lot easier:

import org.tribot.api.Timing;

public class Timer {

    private long startTime;
    private long timeout;

    public Timer() {
        restart();
    }

    public Timer(long timeout) {
        this.timeout = timeout + startTime;
        restart();
    }

    public void restart() {
        this.startTime = System.currentTimeMillis();
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }
    
    public long getElapsedTime() {
        return System.currentTimeMillis() - startTime;
    }

    public long getPerHour(long value) {
        return value * 3600000 / getElapsedTime();
    }

    public String toElapsedString() {
        return Timing.msToString(getElapsedTime());
    }

    public boolean isActive() {
        return timeout > System.currentTimeMillis();
    }

}


 

Edited by Flamo353

Share this post


Link to post
Share on other sites

Let me just preface this by saying that this isn't a personal attack or anything since there is quite a few of us criticizing, but I feel like you over complicated a relatively simple thing.
Here's a simple Timer class I made http://pastebin.com/xCemqeEq. It's basically a countdown timer. Java has a Timer class in the standard library, but even that felt too complicated for this.

So now your script will be something like this

boolean runScript;
Timer timer;

@Override
public void run() {
    runScript = true;
    long duration = value from GUI (converted to milliseconds)
    timer = new Timer(duration);
    while (runScript && timer.isRunning()) {
        // execute script tasks
    }
    // perform end script tasks such as getting out of combat and logging out
}

@Override
public void onPaint(Graphics g) {
    // Use TRiBot's built in msToString method to convert the remaining time to HH:MM:SS format
    g.drawString("Running Time: " + Timing.msToString(this.getRunningTime()), 10, 80);
    g.drawString("Remaining Time: " + Timing.msToString(timer.remainingTime()), 10, 100);
}

 

Edited by Encoded

Share this post


Link to post
Share on other sites
10 hours ago, Encoded said:

Let me just preface this by saying that this isn't a personal attack or anything since there is quite a few of us criticizing, but I feel like you over complicated a relatively simple thing.
Here's a simple Timer class I made http://pastebin.com/xCemqeEq. It's basically a countdown timer. Java has a Timer class in the standard library, but even that felt too complicated for this.

So now your script will be something like this


boolean runScript;
Timer timer;

@Override
public void run() {
    runScript = true;
    long duration = value from GUI (converted to milliseconds)
    timer = new Timer(duration);
    while (runScript && timer.isRunning()) {
        // execute script tasks
    }
    // perform end script tasks such as getting out of combat and logging out
}

@Override
public void onPaint(Graphics g) {
    // Use TRiBot's built in msToString method to convert the remaining time to HH:MM:SS format
    g.drawString("Running Time: " + Timing.msToString(this.getRunningTime()), 10, 80);
    g.drawString("Remaining Time: " + Timing.msToString(timer.remainingTime()), 10, 100);
}

 

Hi Encoded,

Thanks for taking a moment to review my code and giving me feedback, I really appreciate it. 

The option you gave me would be a really efficient way to get the running time etc. Thanks for that. I also like how you made your timer class short and simple. :)

My goal with writing this was mainly to practice and to help new scripters with a stand-alone class including a simple set-up GUI for using EndTimer, as I saw a lot of scripts do not yet have this feature. 

Second to that, I wanted it to be as dynamic as possible for everyone so you can use it for everything. I must admit I did not know about "Timing.msToString" really efficient method! 
 

As you can read here I have been away for quite some time, so once again. Thanks for reviewing my code. I won't let your time go to waste, and will use it see how I can improve my code while still reaching my goals with the class.

Thanks

DScripting

 

10 hours ago, Flamo353 said:

                if(Player.getRSPlayer().isInCombat()) General.sleep(500,3000); //We could be in combat, so we wait a sec.
                if(Player.getRSPlayer().isInCombat()) return false; //still in combat, not going to spam log-out.

- Player#getRSPlayer can and will return null using your current logic. This will crash the script after an exception is thrown
- Using static sleeps won't guarantee that you've exited combat, use dynamic 
- I doubt 0.5 to 3 seconds is even close to the average longest amount of time  a player is in combat for
 

A lot of your code can be simplified. Having a timer object would make your life a lot easier:


import org.tribot.api.Timing;

public class Timer {

    private long startTime;
    private long timeout;

    public Timer() {
        restart();
    }

    public Timer(long timeout) {
        this.timeout = timeout + startTime;
        restart();
    }

    public void restart() {
        this.startTime = System.currentTimeMillis();
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }
    
    public long getElapsedTime() {
        return System.currentTimeMillis() - startTime;
    }

    public long getPerHour(long value) {
        return value * 3600000 / getElapsedTime();
    }

    public String toElapsedString() {
        return Timing.msToString(getElapsedTime());
    }

    public boolean isActive() {
        return timeout > System.currentTimeMillis();
    }

}


 

Hi Flamo353,

Thanks for your time reading my code and reviewing it. 


1. Thanks for the tip I will add a null checker for getRSPlayer
2. Very aware that we do not really wait for the player to get out of combat. The reason I left it this way is I don't want to stop the script if the player is in-combat, as the player could die with stronger monsters. I am still thinking about a more efficient way. to do this tho.
3. see point 2.

A timer object would indeed make life a whole lot easier. I must admit, just like I said to Encoded, I did not think about creating a Timer class. It would indeed be easier. Instead, I copied and pasted my old paint method that collects hour, minute and second. Used that to make it easier to collect these details. 

Once again, yes, a Timer class would be more efficient.

As you can read here I have been away for quite some time, so once again. Thanks for reviewing my code. I won't let your time go to waste.

Thanks

DScripting

3 people like this

Share this post


Link to post
Share on other sites
8 hours ago, TheD said:

Hi Encoded,

Thanks for taking a moment to review my code and giving me feedback, I really appreciate it. 

The option you gave me would be a really efficient way to get the running time etc. Thanks for that. I also like how you made your timer class short and simple. :)

My goal with writing this was mainly to practice and to help new scripters with a stand-alone class including a simple set-up GUI for using EndTimer, as I saw a lot of scripts do not yet have this feature. 

Second to that, I wanted it to be as dynamic as possible for everyone so you can use it for everything. I must admit I did not know about "Timing.msToString" really efficient method! 
 

As you can read here I have been away for quite some time, so once again. Thanks for reviewing my code. I won't let your time go to waste, and will use it see how I can improve my code while still reaching my goals with the class.

Thanks

DScripting

 

Hi Flamo353,

Thanks for your time reading my code and reviewing it. 


1. Thanks for the tip I will add a null checker for getRSPlayer
2. Very aware that we do not really wait for the player to get out of combat. The reason I left it this way is I don't want to stop the script if the player is in-combat, as the player could die with stronger monsters. I am still thinking about a more efficient way. to do this tho.
3. see point 2.

A timer object would indeed make life a whole lot easier. I must admit, just like I said to Encoded, I did not think about creating a Timer class. It would indeed be easier. Instead, I copied and pasted my old paint method that collects hour, minute and second. Used that to make it easier to collect these details. 

Once again, yes, a Timer class would be more efficient.

As you can read here I have been away for quite some time, so once again. Thanks for reviewing my code. I won't let your time go to waste.

Thanks

DScripting

Excellent attitude

2 people like this

Share this post


Link to post
Share on other sites
14 hours ago, erickho123 said:

Excellent attitude

Hi Erickho123,

Thank you, in my opinion the only correct way to handle feedback. :)

But thanks again.

Kind regards,

DScripting

Share this post


Link to post
Share on other sites
On 6/28/2016 at 9:16 PM, Flamo353 said:

                if(Player.getRSPlayer().isInCombat()) General.sleep(500,3000); //We could be in combat, so we wait a sec.
                if(Player.getRSPlayer().isInCombat()) return false; //still in combat, not going to spam log-out.

- Player#getRSPlayer can and will return null using your current logic. This will crash the script after an exception is thrown
- Using static sleeps won't guarantee that you've exited combat, use dynamic 
- I doubt 0.5 to 3 seconds is even close to the average longest amount of time  a player is in combat for
 

A lot of your code can be simplified. Having a timer object would make your life a lot easier:


import org.tribot.api.Timing;

public class Timer {

    private long startTime;
    private long timeout;

    public Timer() {
        restart();
    }

    public Timer(long timeout) {
        this.timeout = timeout + startTime;
        restart();
    }

    public void restart() {
        this.startTime = System.currentTimeMillis();
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }
    
    public long getElapsedTime() {
        return System.currentTimeMillis() - startTime;
    }

    public long getPerHour(long value) {
        return value * 3600000 / getElapsedTime();
    }

    public String toElapsedString() {
        return Timing.msToString(getElapsedTime());
    }

    public boolean isActive() {
        return timeout > System.currentTimeMillis();
    }

}


 

You're a twat.

1 person likes this

Share this post


Link to post
Share on other sites

Updated my own code, also edited topic to include shortcuts to both @Encoded's part and @Flamo353's part to help people who are looking for such a class. :)

I will soon extend this guide with an regular/easier timer class including EndTimer & Set-up GUI.

Share this post


Link to post
Share on other sites
5 hours ago, TheD said:

Updated my own code, also edited topic to include shortcuts to both @Encoded's part and @Flamo353's part to help people who are looking for such a class. :)

I will soon extend this guide with an regular/easier timer class including EndTimer & Set-up GUI.

Line 57

Player.getRSPlayer() != null && Player.getRSPlayer().isInCombat() 

Can return a Null Pointer Exception according to the docs.

The return of the two calls to the Player method getRSPlayer are not the same.

ie. the object null checked is not equivalent to the one you are firing the isInCombat method on.

 

Warfront1

1 person likes this

Share this post


Link to post
Share on other sites
On 6/30/2016 at 6:29 PM, HeyImJamie said:

You're a twat.

Yeah you're right. Instead of me taking the precious time out of my day to give a total stranger some programming advice, why don't you learn java, learn how to script and help him yourself? 

Share this post


Link to post
Share on other sites
10 hours ago, Flamo353 said:

Yeah you're right. Instead of me taking the precious time out of my day to give a total stranger some programming advice, why don't you learn java, learn how to script and help him yourself? 

 

You read this like a week ago and now you decide to give a sarcastic reply? Na fam. I don't even know Java and I have a higher chance of getting scripter than you l0l0l

Share this post


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

 

You read this like a week ago and now you decide to give a sarcastic reply? Na fam. I don't even know Java and I have a higher chance of getting scripter than you l0l0l

You think I'm being sarcastic? Go learn java, go learn how to script, then take the time out of your day to help The D. I would love to see you try.

Share this post


Link to post
Share on other sites
57 minutes ago, Flamo353 said:

You think I'm being sarcastic? Go learn java, go learn how to script, then take the time out of your day to help The D. I would love to see you try.

Why would I bother when it's not something I'm knowledgeable in? You literally asked on Discord for a reply and we joked about this... When did you jump up on your high horse lmao, you're probably still at school cradling your dads balls for irl gp so I don't even know why you're piping up.

Share this post


Link to post
Share on other sites
26 minutes ago, HeyImJamie said:

I don't even know why you're piping up.

You're a twat.

Share this post


Link to post
Share on other sites
8 minutes ago, HeyImJamie said:

Love you Lamo <3 x

Love you too. By the way, if you need any java or scripting lessons, just hit me up. I could get you to netami's level in about a week.

Share this post


Link to post
Share on other sites
Just now, Flamo353 said:

Love you too. By the way, if you need any java or scripting lessons, just hit me up. I could get you to netami's level in about a week.

Can you NPE like Liam?

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

  • Recently Browsing   0 members

    No registered users viewing this page.