+ Reply to Thread
Showing results 1 to 2 of 2

Thread: Hack efficiency: Threading

  1. #1
    Senior Member
    Moderator

    Inquisitor
    SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder has a reputation beyond repute SC_Modder's Avatar
    Join Date
    Nov 2004
    Posts
    4,836
    Blog Entries
    1

    Default Hack efficiency: Threading

    I've noticed a surprising trend lately of "if it works then it's fine" in regards to hack development. There are usually more efficient paths that can be taken if you apply some thinking.

    This particular tutorial will focus on threading.

    You may, in a hack, have felt the need to check for a condition every milisecond, or perform an action every second. While in most normal programming cases, you would create a thread for this sort of thing, along with using Sleep() to create the delay. However, when you add more and more "features" to your hack, I've noticed several people (coughagentcough) tend to create a separate thread for every single timer. This is just plain inefficient and wasteful of CPU cycles.

    Consider the following piece of code:
    Code:
    DWORD WINAPI MyConditionThread(LPVOID lpParam)
    {
    	for(;;) // loop indefinitely
    	{
    		PerformCondition();
    		Sleep(1); // sleeping for 1 is approximately ~10ms depending on conditions
    			  // it is mostly used to prevent 100% CPU usage
    	}
    }
    
    DWORD WINAPI MyActionThread(LPVOID lpParam)
    {
    	for(;;) // loop indefinitely
    	{
    		PerformAction();
    		Sleep(1000); // wait 1 second and do it again
    	}
    }
    Hopefully if you are an experienced programmer you know where I am going with this by now.

    While this obviously works, you are adding two more threads to the queue. Starcraft itself with all of the processing it has to do only has five threads, and only one of which is in charge of handling all game changes and drawing the screen. If starcraft can do all that in a single thread, we should be more than able to ourselves.

    There is a better way. If we combine both threads together and use GetTickCount() for timing, we can only use one thread to do the action and check for the condition.

    Code:
    DWORD WINAPI MyCombinedThread(LPVOID lpParam)
    {
    	DWORD dwPreviousActionTick = 0; // the tick when we last called PerformAction()
    	for(;;) // loop indefinitely
    	{
    		PerformCondition();
    		if( GetTickCount() - dwPreviousActionTick >= 1000 ) // has one second elapsed?
    		{
    			PerformAction();
    			dwPreviousActionTick = GetTickCount(); // reset counter
    		}
    		Sleep(1); // prevent 100% cpu usage by this thread
    	}
    }
    Doing it this way is clearly more effective. You can add lots of function checks into a single thread this way. However there is an even better way to do it. Remember when I mentioned starcraft has a drawing thread that handles all of its screen drawing and game changes? Why don't we hook into this thread and perform our checks from there? While it does require writing a hook to starcraft's memory, doing it this way is more effective because not only do we not add an unnecessary thread to the system, checking for a condition more often than every frame is redundant; the majority of starcraft's data only changes on a per-frame basis. Also, if you have a hook in your hack for drawing to starcraft's screen already then you don't have to add anything (I will not cover creating hooks in this tutorial). You can simply add your conditions to it like so:
    Code:
    void MyDrawingRoutine() // the function that draws everything, called from SC hook
    {
    	static DWORD dwPreviousActionTick = 0; // the tick when we last called PerformAction()
    
       	// static keyword denotes that the variable will not be re-initialized when function
    	// is called again, meaning it will keep its value
    
    	DrawGarbage(); // perform drawing stuff
    
    	PerformCondition();
    	if( GetTickCount() - dwPreviousActionTick >= 1000 ) // has one second elapsed?
    	{
    		PerformAction();
    		dwPreviousActionTick = GetTickCount(); // reset counter
    	}
    }
    Notice the lack of a for() loop. This is because the for() loop is already in starcraft's drawing thread and this function is called once per frame. Adding a for loop would hang the drawing thread indefinitely.

    Also note the lack of a Sleep() call: While it will actually prevent starcraft from using 100% on single-core systems, on older systems this will cause lower framerates because once Sleep is called, the CPU will start processing other threads in the system before continuing execution in this thread. (This was actually the basis of my Sleepy hack, except mine would only call Sleep() if it calculated the frame rate to be at least 35fps.)

    Hopefully you nooby hack makers have learned a few things about threading today. I'm planning on writing more tutorials about other programming/hacking concepts.
    Last edited by SC_Modder : 11-15-2008 at 05:42 PM
    AaronOpfer.com - My music


    Quote Originally Posted by Suzi (aka: ProMasser) View Post
    People say VB6 is the easiest langauge out of all even assembly. I beg to differ I didn't understand one piece of that code

  2. #2
    dt
    dt 15 0FF11|\|3
    Administrator

    Inquisitor
    dt has a reputation beyond repute dt has a reputation beyond repute dt has a reputation beyond repute dt has a reputation beyond repute dt has a reputation beyond repute dt has a reputation beyond repute dt has a reputation beyond repute dt has a reputation beyond repute dt has a reputation beyond repute dt has a reputation beyond repute dt's Avatar
    Join Date
    Jul 2004
    Location
    Germany
    Posts
    4,960
    Blog Entries
    1

    Default

    Good job, that's some pretty important points for n00b programmers to learn.

+ Reply to Thread

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

     

Similar Threads

  1. [Starcraft] Race Changer 1.00
    By nano351 in forum Old downloads
    Replies: 80
    Last Post: 06-05-2008, 03:33 AM
  2. Yay, ggnormhs
    By Cantinflas in forum General Chat
    Replies: 16
    Last Post: 05-23-2008, 11:25 PM
  3. Apocalypse v1.2 - The Ultimate Starcraft multihack
    By AgentGOD in forum Old downloads
    Replies: 98
    Last Post: 02-01-2008, 09:32 PM
  4. [Starcraft] Real-time Ownage Hack v5.19.0
    By AgentGOD in forum Old downloads
    Replies: 98
    Last Post: 01-11-2008, 08:21 PM
  5. Old hacks
    By Firestorm[007] in forum General Chat
    Replies: 23
    Last Post: 12-17-2007, 11:55 PM

Posting Rules

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts