SRL Archive - Research & Development Lounge

MMouseBox


CX gamer

2010-08-01 09:31:31

Hi,

I wanted to make a mouse function, so firstly I recorded my own mouse behaviour, this is the speed every 10 ms;
http://a.imageshack.us/img375/9711/speedf.png
I made a mouse function that moves with 'pulses';
This pulse determens the speed of the moving mouse and takes about 150 to 300 milliseconds.
Firstly it estimates the angle under which it must move, which is randomly chosen by a gauss function;
To get to that, I needed to convert a linear random to a gauss random, I achieved this by using this function;
Then it moves for the 150-300 ms along the pulse, encountering randomised angle-acceleration to ensure a random but smooth path. The mouse is also under the effect of some minor 'jitter', but is turned off at slow speeds.

At the end of a pulse, it uses the linear first part to determen where the next pulse should start, so it can continue without interrupts.

My script could use some tweaking, could you guys give it a few runs and tell me which constants you find best? Thanks. :)
You can also edit some of the coding if you find it nessecary.

This is a comparision; tell me which looks best. :D
One of them is MMouse, the other one is my script. Not saying which is which. :P

[PHP]program Mouse;
const
jitter = 1; // Randomized pixel movement
misjudgement = 0.04; // The amount the angle can be off during a pulse
freedom = 5; // Limiting the misjudgement
fps = 100; // The number of times it updates the mouse per second
accuracy = 0.8; // The accuracy of the angle estimated before each pulse

{*******************************************************************************
function getAngle(xs, ys : extended; xe, ye : integer) : extended;
By: CX
Description: Returns the angle considering 2 points
*******************************************************************************}
function getAngle(xs, ys : extended; xe, ye : integer) : extended;
begin
if xs = xe then
begin
if ys > ye then
begin
result := 3 * PI / 2;
end else
result := - PI / 2;
end else
result := arcTan((ye - ys)/(xe - xs));
if xs > xe then result := result + PI;
fixR(result);
end;

{*******************************************************************************
function randomGauss : extended;
By: CX
Description: Returns a random gaussian number between -1 and 1.
*******************************************************************************}
function randomGauss : extended;
var
r : extended;
begin
r := (random(20000) - 10000) / 10000;
result := 0.2 * r + 0.8 * pow(r, 5);
end;

{*******************************************************************************
function angleDiff(a1, a2 : extended) : extended;
By: CX
Description: Calculates the difference between 2 angles in radians
*******************************************************************************}
function angleDiff(a1, a2 : extended) : extended;
begin
a1 := fixR(a1);
a2 := fixR(a2);
result := a2 - a1;
if (result > PI) then result := - 2 * PI + result;
if (result < -PI) then result := 2 * PI + result;
end;

{*******************************************************************************
procedure MMouseBox(xs, ys, xe, ye : integer);
By: CX
Description: Moves the mouse inside the box
*******************************************************************************}
procedure MMouseBox(xs, ys, xe, ye : integer);
var
angle, speed, a, i, r, x, y, pulse : extended;
mx, my, xdes, ydes, frq, t, pulseLength : integer;
box : TBox;
begin
box.x1 := xs;
box.x2 := xe;
box.y1 := ys;
box.y2 := ye;
xdes := (xs + xe) / 2;
ydes := (ys + ye) / 2;
frq := 1000 / fps;
getMousePos(mx, my);
x := mx;
y := my;
i := 0;
angle := getAngle(x, y, xdes, ydes) + accuracy * randomGauss;

repeat
t := getTickCount;
pulseLength := randomRange(150, 300);
pulse := distance(round(x), round(y), xdes, ydes) / randomRange(325, 400);

repeat
r := random(11) / 1000 + 0.03;
i := i + r;
a := a + misjudgement * randomGauss;
angle := angle + a - angleDiff(getAngle(x, y, xdes, ydes), angle) / freedom;
speed := 200 * i * exp(-4 * i) * pulse;
x := x + round(cos(angle) * speed);
y := y + round(sin(angle) * speed);
if (speed > 2) then
begin
x := x + randomRange(-jitter, jitter + 1);
y := y + randomRange(-jitter, jitter + 1);
end;
wait(frq);
moveMouse(round(x), round(y));
until ((getTickCount - t) >= pulseLength);
i := speed / (200 * pulse);
angle := angle - angleDiff(getAngle(x, y, xdes, ydes), angle) * accuracy;
until IntInBox(round(x), round(y), box);
end;

begin
MMouseBox(536, 404, 616, 480);
end.[/PHP]
Well, it's a start. :)

MylesMadness

2010-08-01 14:46:34

The bottom one is MMouse, I know this because when I was seeing how close the mouse movements were, I moved my mouse more in a arc and srl's didn't look anything like mine

DeSnob

2010-08-01 14:57:32

Damn! Very nice, I love how it isn't so direct. :D

E: A good idea to make your own mouse function would be getting your current coords and adding a few to x, and y to create the box (also doing the same with the target x, and y). Then use the boxes generated in MMouseBox.

Shuttleu

2010-08-01 15:56:41

if i was to choose between them then i would say, inbetween. i think the first one curves out too much, but the second desnt curve out enough

~shut

Gu3st...

2010-08-01 18:44:38

I don't agree with shuttleu… I think it's great!
Imo the speed should differ, as I usually slow down at the end

Cigue

2010-08-01 18:53:48

It's beautiful. Good job CX Gamer, I see the work of a pro here.

How long does the procedure take to run?

EDIT : if this isn't in SRL a month from now expect me to make a custom include involving this.

DeSnob

2010-08-02 05:35:56

From: Cigue
It's beautiful. Good job CX Gamer, I see the work of a pro here.

How long does the procedure take to run?

EDIT : if this isn't in SRL a month from now expect me to make a custom include involving this.


Agreed. I'll also be using this, as much as it may curve it is for sure, less bot-like! :)

Shuttleu

2010-08-02 06:39:39

actually i retract my earlier statement, i didnt really take much notice of the inner lines, but yeah, it seems very good

well done

Promising Newcomer anyone?

~shut

Sabzi

2010-08-02 06:42:29

It would be much more bot-like for me. I move my mouse almost the same as the bottom one.(which is MMouse, right?)
But. I don't really care about the mouse because the current one is not detectable.
Either way, it's fine for me.

i luffs yeww

2010-08-02 07:32:32

^ This. MMouse is fine. And I honestly never really go off my path THAT much.

CX gamer

2010-08-02 11:08:07

Thanks for the positive and constructive feedback, guys. :D

I will make it curve less, and start working on cleaning it and make it suitable for SRL. And I'll see what I can do about making it faster at slow speeds. Please note that this does not (yet) include laptop mouse.

From: DeSnob
E: A good idea to make your own mouse function would be getting your current coords and adding a few to x, and y to create the box (also doing the same with the target x, and y). Then use the boxes generated in MMouseBox.

I'm not sure what you mean by this. My test program just drew 100 lines between a random point inside the green box until it was somewhere inside the red box. MMouseBox always starts at the current mouse position.

The constant values represent the mouse behaviour, do you guys prefer using the same values for everyone who uses the bot?
I could also make a procedure that makes a INI file with randomized mouse values, so everyone has a different mouse behaviour.

Cigue

2010-08-02 13:42:41

From: CX gamer
Thanks for the positive and constructive feedback, guys. :D

I will make it curve less, and start working on cleaning it and make it suitable for SRL. And I'll see what I can do about making it faster at slow speeds. Please note that this does not (yet) include laptop mouse.


I'm not sure what you mean by this. My test program just drew 100 lines between a random point inside the green box until it was somewhere inside the red box. MMouseBox always starts at the current mouse position.

The constant values represent the mouse behaviour, do you guys prefer using the same values for everyone who uses the bot?
I could also make a procedure that makes a INI file with randomized mouse values, so everyone has a different mouse behaviour.


I think the INI would be overkill, if anything just put more Random() in there :) Overall I think it's incredible as it is. Do you think you could make a MMouse out of this?

Also, can you put the point into the box it stops at into a gaussian function too? Like, have twice as much chance to end up in the middle of the box than in one of the corners.

Nava2

2010-08-02 13:48:43

I don't think your gaussian is actually gaussian.

Uhm, I have one lying around, but I didn't write it, so I don't know if I can use it in this project. :(

CX gamer

2010-08-02 14:46:43

Yes, I was kinda affraid of that. Though the function I'm using;
r := (Random(20000) - 10000) / 10000;
Result := 0.2 * r + 0.8 * Pow(r, 5);
Produced the graph you saw in my first post, and that's pretty gaussian.
If you can come up with a better gaussian formula, please do. :)
From: Cigue
I think the INI would be overkill, if anything just put more Random() in there :) Overall I think it's incredible as it is. Do you think you could make a MMouse out of this?

Also, can you put the point into the box it stops at into a gaussian function too? Like, have twice as much chance to end up in the middle of the box than in one of the corners.

It takes the center point of the box as reference, and tries to move towards that. It is satisfied once the cursor is inside the box. Since it's pulses work randomly, the result should be pretty guassian.

The INI would be overkill? Aww.. :blushing:
It would only be called once, during the setupSRL procedure. It would give each player a personalised style it sticks to. This would cause nightmares to who is assigned to detecting botters. :P

I will be adding more random stuff. :)

Also, I could be adding a new single cordinate MMouse function, though it will have major changes. As a 'human' doesn't do pixel-perfect checks.

DeSnob

2010-08-02 15:00:15

You have (1) Error! Check Below!

I got

[Error] (27:3): Unknown identifier 'fixR' at line 26
Compiling failed.
after trying to compile. I just want to try this out. :)

CX gamer

2010-08-02 15:14:06

Thanks. :D
I hadn't tested it in simba yes. :P

That function should correct any angle to the 0 - 2PI domain, I will write one myself then. :P
Also, I have plans to improve it a little more. :)

Sadly, I NEED to go to sleep now (21:13 now), as I am mailman and need to get up early. :(

Nava2

2010-08-02 15:59:34

I do like the idea of developing a custom mouse behaviour per person, I think this could probably be implemented through some calculations and measurements in a utility, to perhaps map you're mouse movements into the required parameters.

CX gamer

2010-08-03 05:18:20

Yay back from the mail. :D
A packet from bustedtees was messing with my pile. XD

Nava, ghaha, I have thought of the exact same thing. But hasdn't posted it yet. To get a trustworthy result, it requires to have run pleanty of movements. It can be rather tedious for the average script user.
Another option could be to have a number of parameters in a form, and have it graph the average mouse path, maybe even with colour-transitions. Kinda like the speed/accel graph of F-zero;

But ofcourse, all of this is spielerei. Let's get this script compatible for Simba, debug it thoroughly and make it sexy first. :P

EDIT: I ran a large-scale test, and it yielded great results. The black dots are where it clicked. The mouse came flying in from the right side.
EDIT2: Math functions are important, people! I was trying to make it Simba-ready;
[Error] (41:15): Unknown identifier 'arcTan' at line 40
This is going to take me a while.

Rick

2010-08-03 10:08:07

ArcTan is in Simba already.

http://villavu.com/forum/showthread.php?t=58188

nielsie95

2010-08-03 10:36:20

It doesn't want to go into a small box for me (0, 0, 10, 10)? Also, I don't like that it goes very fast over long distances and very slow over small distances. It is true that a small mouse movement is relatively slow, though.

Also, about integrating this into SRL, I don't think it's needed to be honest. I don't believe Jagex actively monitors mouse movements. SRL 5 will have an easy way of using a customized mouse function like this. But because SRL 5 might take another while, I think we could also integrate the technique into SRL 4 so scripters can use their own mouse functions very easy..

And could it be that you're related to Rambozin?

CX gamer

2010-08-03 11:03:50

Sweet! :D
But does that mean that I need to wait before releasing my script until that version becomes stable?

Niels; Hmm, are you using Simba or Scar? The version I posted isn't supported by Simba yet. But I'm working on that now. :)

I will normalise the mouse speed a bit more then. :)

It's true that JaGeX only receives mouse data every 0.6 seconds (was it?), but they do monitor the place that has been clicked in. I would be a link to that I found on freddy's forums to a quote of how the bot detection works, but his site seems to work.
Ofcourse, I'm speaking now in an area I'm unfamiliar with, but client-sided mouse detection may become a future. A future my script is prepared for.

EDIT: This is the log I'm keeping of the changes made so far to the script I posted;
Changelog
---------

1.01:
- The framerate is now constant on slow computers
- More randomness
- Small tweaks
- Fixed the ugly corners in between pulses
- Changing fps no longer changes the mouse speed
- Adjusted the reference point to compensate for under-estimating
- Made the FixRad function for Simba

EDIT2: Yes, I have managed to reproduce your problem. I think it has something to do with the x and y values (I used them seperately to use sub-pixel precision) go out of the bounds of the normal screen.

nielsie95

2010-08-03 11:20:31

I was using SCAR.

I'm not sure what mouse data gets logged, but I don't think they can see if you're using a bot purely by looking at the mouse movements. New mouse functions are always nice, though :)

CX gamer

2010-08-03 14:15:07

Yes. I believe they only monitor high mouse speeds, so it doesn't really matter that much at this point..

Cigue

2010-08-03 16:50:06

From: CX gamer
Yes. I believe they only monitor high mouse speeds, so it doesn't really matter that much at this point..


So let me sum this up : a gaussian MMouseBox wouldn't be necessary in the here and now, but it's pretty cool and will possibly be of some use in the future. The RandomGauss function is also pretty sweet, could you extend it to take in parameters? e.g.

RGauss(Ratio : extended; power : integer) : extended;
begin
result := (random(20000) - 10000) / 10000;
result := ratio * result + (1 - ratio) * pow(result, power);
end;

CX gamer

2010-08-04 05:51:58

Yes that's very true. It could very easily be replaced with the normal MMouse but using random gauss values instead of rx and ry.

RGauss; great idea! You also managed to clear 4 bytes of memory! :D
That's crucial for a mouse function, as they are used very often.

Cigue

2010-08-04 12:26:41

From: CX gamer
Yes that's very true. It could very easily be replaced with the normal MMouse


I just suggest you write a set of procs/functions that go G_Mouse, G_MMouse, G_Mousebox and G_MouseItem :) I also think you probably could lower the power of the gaussian thing to 3, just a guess?

CX gamer

2010-08-04 14:27:37

Sure thing, chief. :)

Sir R. M8gic1an

2010-08-07 23:13:20

I like the general look of it :) There's one thing that I might suggest tho:


This sort of mousepath. This 'pattern' usually happens to me when I'm reaching something with the mouse in RS, and it moves or something, so I 'correct' my x / y coord on the way. Also being somewhat distracted causes this :p

I can perfectly see how your pulse implementation shows, this could probably be applied as a second pulse, but on a minor degree and not necessarily "disagreeing" with the general direction of the move.

~RM

CX gamer

2010-08-09 06:59:26

The second pulse? There are continuous pulses until the destination is reached.

What you documented there, should already be in it. Between pulses, it re-estimates the angle and corrects the initial angle for a part, but it keeps a part of the previous angle, so this should make the previous pulse somewhat continuous.
The reason I didn't work with Xspeed and Yspeed, is because it would create a 'box' of mouse velocity, which may be detected if they were smart. :P

I'll work on G_Mouse, G_MMouse, G_Mousebox and G_MouseItem as soon as my mouse own mouse function is up and running. I'm also adding custom 'magnet' points, where the mouse is pullsed to, this is because some moves don't work with the midpoint. Like for example the right-click menu, the user prefers to click somewhere on the left-side of the box, rather than in the middle, I believe this is because of the text being on the left-hand-side.

I'm thinking about benchmarking my own mouse clicks in a box, and so tweak the random gauss function properly. :)

EDIT: Here is something for you guys;
Please do ignore the amount it's sticking out, etc. These are constant values to your own preference.
What was changed;
- It doesn't make corners anymore
- It refers to a base angle during pulses, rather than recalculating the correct angle. This will aid in both processing power, and the ability to overshoot a target.
- The relative speeds are smoothed a bit, this means a bit slower at the start, a bit faster at the end.
- It sometimes overshoots, here it happened 3 times in 101, but it corrects itself promptly without much time lost.

EDIT2: It seems that for G_Mouse, G_MMouse, G_Mousebox and G_MouseItem, using the current MMouse with a random gauss destination cordinates isn't the best solution. As seen in this chart (left is exponent, top is ratio), it tends to make a cross figure. This was taking by 500 samples.
So a better solution would be to take a random linear angle (0, 2PI), and a distance determined by a random gauss with an even power. Or just a random linear angle (0, PI) and a random gauss with an uneven power. Ofcourse, the corners would be omitted, so the domain of the circle would need to be larger than the square area, meaning that there need to be checks wether or not the cordinates are in the box or not.
HOWEVER, a worst-case scenario would create an infinite loop. It's that, skipping corners, having a cross-like shape, or having my own MMouseBox do the dirty work.