Author: Verrigan
Difficulty: 1/5 (Easy Peasy, Cut and Pastey)
This tutorial is designed to provide you with an alternative to GetTickCount. The reason this tutorial was originally designed was to provide a method to break speed hacks that modify the return value of the GetTickCount API function. It turned out, thanks to Pingu's awesome research, that my method could be broken by changing the local computer's system time. So.. you should still perform checks server-side to ensure that packets are not being sent by the client too fast.
Why should you use this method? It returns the value of the system time in milliseconds.. (Actually, it returns a decimal format with nano seconds after the decimal..) The difference is that this method uses a currency value, which uses 8 bytes, as opposed to the GetTickCount method that returns a long value.
The long value in VB is a signed integer that uses 4 bytes.. Since it is signed, it will sometimes return a negative value.. So.. when your system's tick count reaches 2,147,483,647, it rolls back to -2,147,483,648. This rollover happens about 25 days after your computer was turned on..Then.. about 50 days after that, it will do it again.. With my method, you won't have to worry about rollovers for a very long time. Here's a break-down that I did on December 2nd:
Quote:
Milliseconds Until Roll-Over: 909,527,648,354,217
Seconds Until Roll-Over: 909,527,648,354
Minutes Until Roll-Over: 15,158,794,139
Hours Until Roll-Over: 252,646,568
Days Until Roll-Over: 10,526,940
Years Until Roll-Over: 28,821
I'm thinking that by the time the year 30827 comes along, there will be a better method for checking how many milliseconds have passed over time.
Anyways.. This method
will break the current speed hack applications out there.. but it is very easy to develop a program to constantly change the system time, and effectively speed up the return value of this method.. But doing that would have various different effects on other applications..
For example, I started part-time network administrator work at a school in Seattle, and one of the systems would not run the virus scan because the system's virus definitions were out of date.. It had the same definitions as everyone else, and further investigation revealed that the system's time had been set to about a week in the future.
Anyways.. you can decide whether or not you want to use this method.. Tests done by Pingu and myself have pushed me to this final version of this method, which performs at or about the same speed as the original GetTickCount API function.
All you need to do is add an API declaration to a public module:
Code:
Public Declare Sub GetSysTimeMS Lib "KERNEL32.DLL" Alias "GetSystemTimeAsFileTime" (ByRef lpSystemTimeAsFileTime As Currency)
To use it, declare a variable as type Currency, and pass the variable ByRef to the procedure. The procedure will change the value of the variable to the current system time in milliseconds (and nano-seconds..). Here is an example:
Code:
Private Sub cmdTest_Click()
Dim cTimeStart As Currency
Dim cTimeFinish As Currency
Dim i As Long
Call GetSysTimeMS(cTimeStart)
For i = 1 To 200000000
Call GetSysTimeMS(cTimeFinish)
Next
Call MsgBox("The loop took " & int(cTimeFinish - cTimeStart) / 1000 & " second(s) to complete.")
End Sub
Please post any bugs, comments, gripes, etc.
[Edit]
This tutorial was completely rewritten on December 2nd. Please take that into account.
[Edit]
The following code will demonstrate how to setup a function to use this API call in a similar manner to the way GetTickCount() API currently works.
Code:
Public Function GetTickCountNew() As Currency
GetSysTimeMS GetTickCountNew
End Function
Now just call GetTickCountNew() instead of GetTickCount().
Thanks, Spodi.