tags:

views:

160

answers:

4

As of now I'm using a while(true) method to detect changes in memory. The problem with this is it's kill the applications performance. I have a list of 30 pointers that need checked as rapidly as possible for changes, without sacrificing a huge performance loss. Anyone have ideas on this?

EDIT** The idea of this is to detect changed in memory caused by certain applications while running an online shooter game. Not really an anti-cheat, but it's along those lines.

memScan = new Thread(ScanMem);

public static void ScanMem()
        {            
            int i = addy.Length;
            while (true)
            {
                Thread.Sleep(30000); //I do this to cut down on cpu usage
                for (int j = 0; j < i; j++)
                {
                    string[] values = addy[j].Split(new char[] { Convert.ToChar(",") });
                    //MessageBox.Show(values[2]);
                    try
                    {
                        if (Memory.Scanner.getIntFromMem(hwnd, (IntPtr)Convert.ToInt32(values[0], 16), 32).ToString() != values[1].ToString())
                        {
                            //Ok, it changed lets do our work
                            //work 
                            if (Globals.Working)
                                return;                            
                            SomeFunction("Results: " + values[2].ToString(), "Memory");
                            Globals.Working = true;
                        }//end if
                    }//end try
                    catch { }
                }//end for
            }//end while
        }//end void
+3  A: 

why loop through the pointers to find changes? why not use an event based mechanism?

i presume the pointers are pointing at a class? have that class raise an event each time it becomes 'dirty' and then have a supervisory class that monitors the classes and handles any events that are raised.

yamspog
Sorry, when I said pointers I was meaning 0x823F4 and such. I want to read that address from a certain application (among 29 other addresses) and make sure those values do not change, is so detect it and notify me.
Dremation
@Dremation: Who/what changes the values at those addresses?
Jason Punyon
I'll edit the question to explain.
Dremation
+1  A: 

Assuming that there's no way to get the monitored code to throw events on-dirty, this is approximately the best solution available.

Nit-picking (since I hope these were just trimmed for the snippet):

  • I hope that you have a good reason to call string.Split inside the loop like that. Obviously, if the addy variable is not changing, it would be better to store int arrays and use that
  • Similary, an int comparison would be better than a string comparison
  • I really hope you aren't just ignoring exceptions like that

Fixing those (assuming they can be addressed in the real code) would help performance marginally. Also, I really doubt that your pause needs to be 30 seconds, you could probably cut CPU almost as much with just a 1 second pause.

jsight
Ok, so I [was] doing the split in the loop, that was a big mistake. I've moved that up out of the loop. And no, we are not ignoring the exceptions. I simply edited it out to cut out on the size of the snippet. The idea of the 30 seconds interval was to cut down on lag as well. This code will be ran along side an online shooter game. Thanks.
Dremation
+2  A: 

You need not check all the elements at once. You can implement pipelining. So that in every iteration you end up checking only one element at a time. This way you will not face any performance related issues and you will end up checking all elements in 30 iterations. So just reduce your sleep and move it inside the inner for loop as shown below. I think should improve your performance.

memScan = new Thread(ScanMem);

public static void ScanMem()
    {            
        int i = addy.Length;

        while (true)
        {
            for (int j = 0; j < i; j++)
            {

                Thread.Sleep(10000); // Reduce sleep

                string[] values = addy[j].Split(new char[] { Convert.ToChar(",") });
                //MessageBox.Show(values[2]);
                try
                {
                    if (Memory.Scanner.getIntFromMem(hwnd, (IntPtr)Convert.ToInt32(values[0], 16), 32).ToString() != values[1].ToString())
                    {
                        //Ok, it changed lets do our work
                        //work 
                        if (Globals.Working)
                            return;                            
                        SomeFunction("Results: " + values[2].ToString(), "Memory");
                        Globals.Working = true;
                    }//end if
                }//end try
                catch { }
            }//end for
        }//end while
    }//end void
Pankaj
I'll try this along with @jsight's suggestion. Thanks.
Dremation
+1  A: 

Cycle's variable j is only used to select from addy. Perhaps, aside from polling, it would be good idea to change for() to Parallel.For() ?

PS. I don't know how "heavy" SomeFunction and Memory.Scanner are (perhaps they also change some global state) and what other operations you do perform at the same time.

Andrei Taptunov