SRL Archive - General Botting Help

Reading Mouse Cursor with Simba ?


caused

2014-04-05 10:39:42

Hey,
I've written a plugin for scar years ago.

I wonder if someone did the same for Simba ???
If so, where is it, and how do you use it ?

Thanks :)

caused

Frement

2014-04-05 10:46:11

Can you explain this?

caused

2014-04-05 14:24:25

Yeah. I just want to detect the current Cursor-Graphic and compare it. It's not possible with FindBitmap and similar functions, because the cursor cant be read from the screen.

Brandon

2014-04-05 16:17:47

Using my native library/plugin you can do it.. Otherwise you might have to enable System API's and if you're lucky they would work in Simba without too much effort..

It'll return an image like:



or whatever your cursor looks like..



{$loadlib Riddler}

Function RImageToSImage(Img: Integer): Integer; //Convert a R-Image to Simba Image..
var
Pixels: Pointer;
Width, Height: Integer;
TM: TMufasaBitmap;
Begin
Pixels := GetImagePixels(Img, Width, Height);
TM.Init(Client.GetMBitmaps);
TM.SetPersistentMemory(UInt32(Pixels), Width, Height);
TM.SetTransparentColor(0);
Result := TM.GetIndex();
//ReleaseGC(Pointer(Img)); //Not really needed..
End;

var
Img: Integer;
begin
Img := RImageToSImage(ImageFromCursor());
SaveBitmap(Img, 'C:/Users/Brandon/Desktop/Cursor.bmp');
FreeBitmap(Img);
end.

It has its own set of imaging functions.. Saving, etc.. But for use with Simba's FindBitmap, you'll need to use the above conversion function since Simba doesn't have a FindBitmap that takes a pointer instead of an integer as its first parameter..

I tend to take requests or anything that require native code and add it to the library occasionally.. It is found here: http://villavu.com/forum/showthread.php?t=108229

caused

2014-04-05 18:28:35

That is awesome. Thanks alot.

I hope it doesnt have memory leaks.

Brandon

2014-04-05 19:32:42

From: caused
That is awesome. Thanks alot.

I hope it doesnt have memory leaks.


Can't leak. It has its own garbage collector that cleans immediately once the script thread dies and when the plugin unloads. Otherwise you can also clean up manually if you choose to do so via ReleaseGC functions.


If you mean for the cursor, the code is as follows:


unsigned int Graphics_ImageFromCursor()
{
CURSORINFO Info = {0};
Info.cbSize = sizeof(Info);

if (GetCursorInfo(&Info))
{
HDC MemDC = GetDC(nullptr);
HDC SDC = CreateCompatibleDC(MemDC); //Create a DC.

DrawIcon(SDC, 0, 0, Info.hCursor); //draw the cursor onto the created DC.

ICONINFO II = {0};
BITMAP Bitmap = {0};
GetIconInfo(Info.hCursor, &II); //Get cursor information.
GetObject(II.hbmMask, sizeof(BITMAP), &Bitmap);
DeleteObject(SelectObject(SDC, II.hbmColor));

//ImgManager is a garbage collected image manager.
//Every image created is destroyed in its destructor.
unsigned int result = ImgManager.ImageFromDC(SDC, 0, 0, Bitmap.bmWidth, Bitmap.bmHeight);

DeleteDC(SDC); //Delete the DC
DeleteObject(II.hbmColor); //Delete cursor info.
DeleteObject(II.hbmMask); //Delete cursor info.

return result; //return image number. Exactly like Simba's.
}
return -1;
}

caused

2014-04-10 09:44:14

I finally got to trying it out and when I Try to include riddler I getthe Error: Unable to register type PWChar at line 2.

What can I do :X ?

caused

2014-04-10 09:47:06

Oh. I guess its lape only :x..
Well, since SRL doesnt seem to be compatbile enough I'd need another way to get the cursor.

Anyone ?

//EDIT:

I just figured out that Lape works great :D

Only problem is. Is that my Script is now running faster than intended :D… Easy to fix though.

Thanks alot again.

Oh BTW: It get wrong cusor Colors. Instead of a orange sword cursor it becomes blue. Maybe you can fix that :)

caused

2014-04-11 17:06:34

Your library does leak alot, causing simba to crash after a while ;/.

Try:
repeat
ImageFromCursor();
until false;

And Check the memory.

Any fix for that ?

//EDIT:
I just tried some more functions from your library, and "ClearImages;" does seem to immediately fix the memory garbage. Is that how its intended :x ?

Any Feedback is greatly appreciated :). (Also about the wrong colors)

Brandon

2014-04-11 19:35:23

From: caused
Your library does leak alot, causing simba to crash after a while ;/

@caused;
EDIT: I added debugging to demonstrate garbage cleanup works and that there are/were no leaks.. I also fixed the RGBA to BGRA so you may now test that.. I also monitored task manager.



To answer your questions:

Yes there is garbage cleanup but as mentioned, it will only automatically clean up for you when the script thread dies or when you call ReleaseGC..

Deliberately temporarily leaking it by doing:


begin
repeat
ImageFromCursor; //not even using the returned result..
Sleep(1);
until(false);
end.


Is a no-no.. Repeating that until "FALSE" or putting it in an infinite loop. Even with the above, it does NOT leak. As soon as the exception is thrown or the script terminates, the garbage cleanup kicks in. You can manually invoke it as well..





It's roughly this much allocations for your script above:

32x32 cursor on my system. 32 x 32 x SizeOf(RGBA) = 32 x 32 x 4. Add that to the size of a pointer and the internal storage for garbage collection.. lets assume that's a total of: 4176 bytes each loop..

Max heap size on most x64 systems with 6gb ram is ROUGHLY: 2gb or 2147483648 bytes (also the max size of a Java string on my school computer). I am able to allocate 4gb on my system..

2147483648 / 4176 = 514244 allocations.. This is assuming that Simba makes 0 allocations of its own.


Using the following snipper:


{$loadlib Riddler}

var
I, J: Integer;
begin
repeat
ImageFromCursor;
if (I > 10000) then
begin
J := I;
I := 0;
writeln(J);
end;
I := I + 1;
Sleep(1);
until(false);
end.

The results of letting it run until an exception was thrown or it ran out of memory was: 503k allocations/images..


That is a LOT! That's far more bitmaps than you would use on average running a script..





The wrong colours aren't actually "wrong". It's how Simba interprets it that is different. It returns pixels to you in RGRA format and Simba probably interprets them in BGBA format. I've had this problem with feeding colours to SMART as well. You can either swap the B and R values or I can swap them..

I fixed it and made it export as BGRA instead of RGBA.

caused

2014-04-12 06:00:11

Wow, thanks alot :)

How does ReleaseGC Work. What parameters do you give it in the example above ?

I'm still getting crashes using this code (even without the try error).

program new;
{$loadlib Riddler}

var
I, J: Integer;
begin
repeat
try
ImageFromCursor;
except
writeln('> Error in ImageFromCursor');
end;
//ReleaseGC('');
if (I > 10000) then
begin
J := I;
I := 0;
writeln(J);
end;
I := I + 1;
Sleep(1);
until(false);
end.
The memory view looks like this.
a) Simba Idle
b) Starting Script
c) Simba crashed

[ATTACH=CONFIG]23179[/ATTACH]

So it seems like its cleaning up once and on the next ecxeption dies. Though "Writeln('….')" is never called.

EDIT:
This also crashes Simba after a while. No Memory filling up though.

repeat
ReleaseGC(Pointer(ImageFromCursor));
ClearImages;
sleep(1);
until false;

Brandon

2014-04-12 09:57:08

From: caused
…


Release_GC is for Objects such as strings and anything else that it returns. Things like threads, etc.. Images have their own GC.


For Images it is DeleteImage(Img); or ClearImages; When I have time, I'll make them all use the same GC. I separated it though so you could see image allocations vs. other resource allocations as in the picture above.


The safer example of your code would be:


program new;
{$loadlib Riddler}

var
I, J, Img: Integer;
begin
repeat
try
Img := ImageFromCursor;
except
writeln('> Error in ImageFromCursor'); //This has never been reached with Sleep(100);
end;

DeleteImage(Img);

if (I > 10000) then
begin
J := I;
I := 0;
writeln(J);
end;
I := I + 1;
Sleep(100);
until(false);
end.


Try NOT to use so much CPU or you're going to lag like hell! You're looping infinitely and giving very little sleep time to the CPU. CPU resources must be shared amongst other processes as well (not just Simba hogging it all).. Sleep(10) is more efficient than Sleep(1). Even Sleep(100) will show a drastic improvement. You are after all capturing a system resource (the cursor).. There was a post some years ago that showed Sleep(0) being very efficient but sometimes it completely stalled the program. Regular Simba script also must sleep similarly as well.

I'd say 100 or 50 is good enough. Your computer might be a ton faster or more efficient than mine so you might get away with sleeping less but mine lags like hell with anything less than 8..

caused

2014-04-12 11:00:23

Thanks for your effort. But that doesnt solve the problem :(.

I Think I found out what it is. But I dont know how to solve it.

This Script shows the problem really well. The only thing a higher sleep(x) does it, that it delays Simba Crashing.

Once

try
Img := ImageFromCursor;
except
writeln('> Error in ImageFromCursor'); //This has never been reached with Sleep(100);
end;
DeleteImage(Img);
has been executed ~9000 times. Simba crashes. Giving the error Code:


Full Code for testing:
(Warning- May Lag on your PC)

program new;
{$loadlib Riddler}

var
I, J, Img: Integer;
begin
repeat
try
Img := ImageFromCursor;
except
writeln('> Error in ImageFromCursor'); //This has never been reached with Sleep(100);
end;
DeleteImage(Img);

if (I > 8000) then
begin
Writeln(i);
if i > 9800 then
sleep(100);
end;
I := I + 1;
Sleep(0);
until(false);
end.

Any Idea on how to fix that ? Or maybe a workaround ?

Brandon

2014-04-12 12:47:47

From: caused
Thanks for your effort. But that doesnt solve the problem :(.

I Think I found out what it is. But I dont know how to solve it.

Any Idea on how to fix that ? Or maybe a workaround ?



It's not really a "crash" it's an exception I threw purposely within the plugin.. I don't think Simba can catch those. It was to let the user know when an image was a problem. There isn't really a way for plugins to pass exceptions nicely to Simba unless written in pascal =(

I removed this exception only for this cursor image function because it seems to throw an exception if the cursor is in the writing state. Instead if its an invalid image, it will have a width and height of 0 and the handle returned will be max_unsigned_int. Fault images will use no resources.

Also made the cursor function an official function of the imaging class. It will handle it better there. It's also faster now because of this. No wrappers or anything.

caused

2014-04-12 13:18:36

You're a genius :)

It's working great now. Got it looping 50000 times without problems. So it should be perfectly usable now. Also the speed improvement is obvious.

Thanks alot for your help. I was already thinking about writing an own cursor plugin (I did one for scar ages ago).

Much appreciated.

caused

2014-04-13 14:55:44

Bad news.

The latest Update made Simba stop crashing.

But after a while (the same while than it took before for simba to crash).

- The Debug(writeln output) becomes weird displaying 1 char per row.
- All Functions that send keyboard input stop working

And also simba doesnt react to anything. The Script keeps running but you can only stop the script and restart it.

To test it you can just use one of the loop versions from above and let them run for a while.

I also got an error message:
Program exception!
Stacktrace:

Exception class: EOutOfResources
Message: Error creating device context for SplitterFunctionList.TSplitter
$00547413
$00534CE6
$004C3D66
$004C3B7C
$0057AB7D
$0057AA8C
$005557E8
$0053EE34
$00542DA8
$00555732
$0040C3C6
$0054041F
$0059FDAB
$00508391
$00505CF4
$75A962FA
$75A97316
Simba Version: 1004

Brandon

2014-04-13 22:31:56

From: caused

The latest Update made Simba stop crashing.


I just fixed the crash bug. I tested it a lot this time. This should be the largest speed improvement thus far. Extremely noticeable!
It was a bug in passing the data to Simba and getting back the same data.. Example: Give simba handle number 1, receives handle 2 which was non-existent.


Anyway, some tests.. The ability to allocate 200k+ bitmaps in under 5 seconds with 0 latency/lag.. With 1 Riddler-Thread + Simba's main, it reaches over 1m bitmaps in under 5 seconds. That's a lot though, I don't think you need to do that. Your cursor cannot even update that fast. It would probably be a bad idea to thread it lol. 200k snapshots in under 5 seconds is way more than enough. This is with sleeping at 0 too. Again, sleeping with 1 is even faster at times. Let me know if you see an improvement or any other problems. Hopefully there isn't any more. There actually shouldn't be any =( I profiled it as well.




caused

2014-04-13 23:59:14

Gotta test later :). Hope its finally fixed.

Will report back.

//Edit:
No problems anymore. Also the speed is insane :D.