SRL Archive - Download S.M.A.R.T.

SMARTv2 (Finalish Release)


BenLand100

2007-12-22 22:35:47

This should be getting more towards the done state, here's an example of the reflection system and what it can do (really, it can do anything you are willing to maintain, or nothing assuming no one will maintain it ;)) This does not do everything (the MaxLevels and Experiences hooks aren't even used) but it gives you enough information to expand. All GetField methods now take an Object as the first parameter, if the field is static, this value should be 0, if its a field in an object, this should be the object. Look at GetMyPos.

Note, any method that returns an Object MUST be freed with SmartFreeObject unless you really want to crash Scar/Smart/Java all at the same time ;)

@Anyone who knows the client, feel free to extend this however, if you have any questions, post/ask.

const
//Global Static Hooks
SettingsArray = 'jb.k'; //int[]
CurrentLevels = 'ca.jb'; //int[]
MaxLevels = 'ma.V'; //int[]
Experiances = 'oa.d'; //int[]
BaseX = 'oa.a'; //int
BaseY = 'dd.b'; //int
MyPlayer = 'nf.j'; //Player
CompassAngle = 'rg.o'; //int (MinimapInt1)
MapOffsetAngle = 'vf.c'; //int (MinimapInt2)

//Character Hooks
CurrentX = 'nb'; //int
CurrentY = 'db'; //int
CharAnim = 'ac'; //int
CharMotion = 'T'; //int
CharName = 'W'; //StringWrap

//StringWrap Hooks
StringBytes = 'K'; //byte[]

//Returns the current level of your player (its a funny array)
function GetLevel(index: integer): integer;
begin
result:= SmartGetFieldArrayInt(0,CurrentLevels,index);
end;

//Converts a byte[] from StringWrap to a DelphiString (max length 256)
function StringFromBytes(jbytearray: integer): string;
begin
SetLength(result, 256);
SetLength(result, SmartStringFromBytes(jbytearray,result));
end;

//Returns last logged in player's name
function GetMyName: string;
var
bytes: Integer;
begin
bytes:= SmartGetFieldObject(0,MyPlayer+'.'+CharName+'.'+StringBytes);
result:= StringFromBytes(bytes);
SmartFreeObject(bytes);
end;

//Returns your animation
function GetMyAnim: integer;
begin
result:= SmartGetFieldInt(0,MyPlayer+'.'+CharAnim);
end;

//True if you are moving
function GetMyMoving: boolean;
begin
result:= SmartGetFieldInt(0,MyPlayer+'.'+CharMotion) > 0;
end;

//Calculates your x,y position or [somehugenumber] if not logged in
procedure GetMyPos(var x, y: Integer);
var
me: Integer;
begin
me:= SmartGetFieldObject(0,MyPlayer);
x:= SmartGetFieldInt(0,BaseX) + SmartGetFieldInt(me,CurrentX) shr 7;
y:= SmartGetFieldInt(0,BaseY) + SmartGetFieldInt(me,CurrentY) shr 7;
SmartFreeObject(me);
end;

//Dumps the settings array to an integer array
function DumpSettingArray: array[0..1999] of integer;
var
i: integer;
begin
for i:= 0 to 1999 do
Result[i]:= SmartGetFieldArrayInt(0,SettingsArray,i);
end;

//Returns -1 if no box open or 0..2 for the correct answer to the box
function BoxAnswer: integer;
var
boxIndex: Integer;
begin
boxIndex:= SmartGetFieldArrayInt(0,SettingsArray,312);
if boxIndex = 0 then
result:= -1
else
result:= (boxIndex shr 24) and $FF;
end;

//Returns the current Map angle in degrees
function GetMinimapAngleDeg: extended;
var
clientAngle: integer;
begin
clientAngle:= (SmartGetFieldInt(0,CompassAngle) + SmartGetFieldInt(0,MapOffsetAngle)) mod 2048;
result:= clientAngle * 180 / 1024;
end;

//Returns the current map angle in radians
function GetMinimapAngleRad: extended;
var
clientAngle: integer;
begin
clientAngle:= (SmartGetFieldInt(0,CompassAngle) + SmartGetFieldInt(0,MapOffsetAngle)) mod 2048;
result:= clientAngle * Pi / 1024;
end;

//converts the tile position tileX,tileY to a minimap location
procedure TileToMinimap(tileX, tileY: integer; var screenX, screenY: integer);
var
angle: extended;
tempX, tempY: integer;
begin
angle:= getMinimapAngleRad;
GetMyPos(tempX, tempY);
tempX:= (tileX - tempX) * 4 - 2;
tempY:= (tempY - tileY) * 4 - 2; //Origin is South-West
screenX:= round(tempX*cos(angle) - tempY*sin(angle)) + 643;
screenY:= round(tempX*sin(angle) + tempY*cos(angle)) + 84;
end;

SKy Scripter

2007-12-23 00:31:44

Good job ben :)

Town

2007-12-23 11:56:15

But there are still 2 more weeks of Winter Break? :p

Ruroken

2007-12-23 14:04:54

:O

SMART is gonna own :p

Markus

2007-12-23 14:24:31

Ben, you should tell me how to make some kind of HP announcer with this ^^

Smartzkid

2007-12-23 15:07:57

From: Town
But there are still 2 more weeks of Winter Break? :p


Plenty of time to add muting :)

BenLand100

2007-12-23 16:07:53

Seems that I had my character position fields backwards (noticed when I wrote a tile to minimap procedure). Also put in the motion hook which I somehow forgot to do.
(CHECK the first post, I edited it)

@Markus: Get the max level amount and current level amount (you'll need to copy the current level amount function and swap the fields) from the levels arrays (index 4 I think) and do as you please ;)

Yakman

2007-12-23 16:19:14

cant make hp announcers anymore :(
there used to be a current/max hp field, which you could get and blurt out.

but now there is a single field, which i call hpRatio, because its simply (currentHP / maxHP * 30)
so a number between 0 and 30, 0 being dead, 30 being full health.
you cant tell what the exact values are anymore :(

if you use those arrays, you can only find your own hp, not anyone elses, no point spamming that out IMO

Markus

2007-12-23 16:43:21

I know about the ratio, but can't we just spam 'Markus has 1% of his hp' and 'Yakman has 100% of his HP'?
And I got something to work that spams my own HP, pretty useless tbh. I tried using SmartGetFieldArrayObject at the Player array, didn't work, SmartGetFieldObject did, but I couldn't get any useful info out of it (everything I tried returned -1).

BenLand100

2007-12-23 17:16:34

From: Markus
I know about the ratio, but can't we just spam 'Markus has 1% of his hp' and 'Yakman has 100% of his HP'?
And I got something to work that spams my own HP, pretty useless tbh. I tried using SmartGetFieldArrayObject at the Player array, didn't work, SmartGetFieldObject did, but I couldn't get any useful info out of it (everything I tried returned -1).

I assume you know the hook for the player array? 'ea.s' But the index array is 'qb.F' I think… Anyway I'm pretty sure you have to be logged in to get info out of the player array if you weren't. Once you got the player object out of the array, you'd have to get the hpRatio out of it ('rb' methinks, so SmartGetFieldInt(player,'rb') ) then free the object.

Wizzup?

2007-12-25 05:05:26

From: BenLand100
Seems that I had my character position fields backwards (noticed when I wrote a tile to minimap procedure). Also put in the motion hook which I somehow forgot to do.
(CHECK the first post, I edited it)


You bitch. It took me ages to figure that out. :p
I had to make the x dist negative for it to work…

Anyway, no more need for my code, let's use yours. :garfield:


——–

EDIT: Your TileToMM is evil. (aka doesn't work properly)
My method works better now, I updated it.
LINK: http://www.srl-forums.com/forum/tilewalking-t25321.html?p=304820#post304820

BenLand100

2007-12-25 09:15:44

From: Wizzup?
EDIT: Your TileToMM is evil. (aka doesn't work properly)
My method works better now, I updated it.
LINK: http://www.srl-forums.com/forum/tilewalking-t25321.html?p=304820#post304820

Erm, perhaps you didn't use it correctly? I tested it and it works fine… Always goes to the right tile regardless of minimap angle… Maybe if you didn't assume that I do everything wrong and that you always use everything right… Maybe the reason it didn't work for you is that you don't have the paths in the right order (CurrentX/Y) or you recorded the path in the wrong order.
  GetMyPos(x,y);
TileToMinimap(x+10,y+10,x1,y1);
MoveMouse(x1,y1);

Wizzup?

2007-12-25 10:45:28

Maybe if you didn't assume that I do everything wrong and that you always use everything right…


lol.

From: BenLand100
Erm, perhaps you didn't use it correctly? I tested it and it works fine… Always goes to the right tile regardless of minimap angle… Maybe the reason it didn't work for you is that you don't have the paths in the right order (CurrentX/Y) or you recorded the path in the wrong order.
  GetMyPos(x,y);
TileToMinimap(x+10,y+10,x1,y1);
MoveMouse(x1,y1);


Afaik I used it like: TileToMinimap(path.x, path.y, x, y);

Anyway:


Vial Buyer 0.01

Worked for 13 Minutes and 11 Seconds
WaterVials Banked : 189
Banking at a rate of 859 WaterVials p/h.

And the entire walking:

  //RecordPath;
SetLength(TPA, 6);
TPA[0].X := 2615;
TPA[0].Y := 3332;
TPA[1].X := 2608;
TPA[1].Y := 3327;
TPA[2].X := 2608;
TPA[2].Y := 3317;
TPA[3].X := 2607;
TPA[3].Y := 3308;
TPA[4].X := 2608;
TPA[4].Y := 3299;
TPA[5].X := 2614;
TPA[5].Y := 3296;

    for i := low(tpa) to high(tpa) do
begin
GetMyPos(P.X, P.Y);
writeln(inttostr(tpa[i].x) + ','+inttostr(tpa[i].y));
writeln('Walking tile number: ' + inttostr(i));
WalkTile(tpa[i], 3, 0);
end;

    for i := high(tpa) downto low(tpa) do
begin
GetMyPos(P.X, P.Y);
writeln(inttostr(tpa[i].x) + ', '+inttostr(tpa[i].y));
writeln('Walking tile number: ' + inttostr(i));
WalkTile(tpa[i], 3, 0);
end;

Wizzup?

2007-12-26 14:16:00

program New;

{.include smart.scar}
{.include srl/srl.scar}

{
Wizzup Vial Buyer 0.01

Worked for 34 Minutes and 15 Seconds
WaterVials Banked : 621
Banking at a rate of 1087 WaterVials p/h.}

Var
WaterVials: LongInt;

Procedure DeclarePlayers;

Begin
NumberOfPlayers( 1 );
CurrentPlayer := 0;

Players[0].Name :='';
Players[0].Pass :='';
Players[0].Nick :='';
Players[0].Active := True;
Players[0].Loc := 'Bank';

Writeln( IntToStr ( HowManyPlayers ) + ' Players' );
SetPlayerNameTPAs;
End;

Function AtTile(Tile: TPoint; Dist: Integer): Boolean;

Var
P: TPoint;
Begin
GetMyPos(P.X, P.Y);
Result := Distance(P.X, P.Y, Tile.X, Tile.Y) <= Dist;
//writeln('Current Tile: (' + inttostr(p.x) + ', '+inttostr(p.y) + ')');
End;

Function WalkTile(Tile: TPoint; Disttol, Randomness: Integer): Boolean;

Var
wTile, P: TPoint;
d, degs: extended;
dist, t: integer;

Begin
Result := False;
Tile.X := Randomize(Tile.X, Randomness);
Tile.Y := Randomize(Tile.Y, Randomness);
//TileToMinimap(Tile.X, Tile.Y, wTile.X, wTile.Y);

GetMyPos(P.X, P.Y);
Degs := rs_GetCompassAngleDegrees;
D := Degrees(ArcTan2(p.y - tile.y, p.x-tile.x)) - 90;
d := d - degs;
dist := Distance(MMCX, MMCY, p.x-tile.x + mmcx, p.y-tile.y + mmcy) * 4;
wTile.X := Round(MMCX + dist * Sin(D * pi / 180)) - 2;
wTile.Y := Round(MMCY + dist * Cos(D * pi / 180)) - 2;

If Not rs_OnMiniMap(wTile.X, wTile.Y) Then
Begin
WriteLn('Not in minimap');
WriteLn('('+inttostr(wtile.x)+','+inttostr(wtile.y)+')');
LogOut;
TerminateScript;
Exit;
End;
Result := True;
If AtTile(Tile, DistTol) Then
Begin
WriteLn('Already at tile');
Exit;
End;
MFNF(wtile.x, wtile.y, -1, -1);
t := getsystemtime;
While Not AtTile(Tile, DistTol) And ((getsystemtime - t) < 60000) Do
Wait(500);
Result := (GetSystemTime - t) < 60000;
If not result then
begin
LogOut;
TerminateScript;
end;
End;

Procedure RecordPath;

Var
I, x, y: Integer;
Begin
Repeat
Wait(500);
If IsFKeyDown(11) Then
Begin
GetMyPos(x, y);
WriteLn('TPA['+IntToStr(I) + '].X := ' + IntToStr(x)+';');
WriteLn('TPA['+IntToStr(I) + '].Y := ' + IntToStr(y)+';');
I := I + 1;
End;
Until IsFKeyDown(8);
End;

Function ShopKeeper: Boolean;

Var
x, y, t: Integer;

Begin
Result := False;
If FindObjTPA(x, y, 3235209, 9, 2, 5, 5, 5, 'Talk') Then
Begin
Mouse(x, y, 0, 0, False);
Wait(50);
If Not ChooseOption('rade') Then
Exit;
t := getsystemtime;
While Not (GetColor(161, 41) = 2070783) And (getsystemtime - t < 10000) Do
Wait(50);
If (GetSystemTime - t) >= 6000 Then
Exit;
Mouse(80, 120, 10, 10, False);
Wait(50);
If Not ChooseOption('Buy X') Then
Exit;
Wait(2000);
TypeSend(IntToStr(28+Random(100)));
Result := True;
End;
End;

{var
x, y: integer; }

Procedure ProgressReport;

Var
Sec, Rate: Integer;
Begin
Sec:= GetTimeRunning div 1000+1;
Rate:= 3600*WaterVials/Sec; // by mastaraymond.
WriteLn('----------------------------');
WriteLn('');
WriteLn('Wizzup Vial Buyer 0.01');
WriteLn('');
WriteLn('Worked for '+ TimeRunning);
WriteLn('WaterVials Banked : '+IntToStr(WaterVials));
WriteLn('Banking at a rate of ' + IntToStr(Rate) + ' WaterVials p/h.');
WriteLn('');
WriteLn('');
WriteLn('----------------------------');
SRLRandomsReport;
End;

Var
TPA: TPointArray;
p:tpoint;
i, t:integer;

begin
ClearDebug;
SmartSetup('ams5', false, false);
SetTargetDC(SmartGetDC);
setupsrl;
declareplayers;
loginplayer;
highestangle;
//RecordPath;
SetLength(TPA, 6);
TPA[0].X := 2655;
TPA[0].Y := 3283;
TPA[1].X := 2646;
TPA[1].Y := 3283;
TPA[2].X := 2638;
TPA[2].Y := 3288;
TPA[3].X := 2630;
TPA[3].Y := 3296;
TPA[4].X := 2619;
TPA[4].Y := 3297;
TPA[5].X := 2614;
TPA[5].Y := 3296;
repeat
for i := low(tpa) to high(tpa) do
begin
WalkTile(tpa[i], 3, 1);
end;

fflag(0);
wait(1500 + random(500));
t := getsystemtime;
repeat
wait(500);
findnormalrandoms;
if getsystemtime -t > 60000 then
break;
until shopkeeper;
findnormalrandoms;

if getsystemtime -t < 60000 then
WaterVials := WaterVials + 27;

for i := high(tpa) downto low(tpa) do
begin
WalkTile(tpa[i], 3, 1);
end;
fflag(0);
wait(1500 + random(500));
colortolerancespeed(1);

openbankfast('db');

Deposit(2, 28, 2);
ProgressReport;
until false;
end.

Ben, Try this script. (Ardougne South-East bank. Take some cash)

First use:

  GetMyPos(P.X, P.Y);
Degs := rs_GetCompassAngleDegrees;
D := Degrees(ArcTan2(p.y - tile.y, p.x-tile.x)) - 90;
d := d - degs;
dist := Distance(MMCX, MMCY, p.x-tile.x + mmcx, p.y-tile.y + mmcy) * 4;
wTile.X := Round(MMCX + dist * Sin(D * pi / 180)) - 2;
wTile.Y := Round(MMCY + dist * Cos(D * pi / 180)) - 2;

Then blank all that and try this:

  TileToMinimap(Tile.X, Tile.Y, wTile.X, wTile.Y);

Try and see if they sort of give the same results… TileToMinimap clicks in the wrong direction for me… I think it messes up at index 2 of the path.

Renax

2007-12-26 14:56:50

forgive me, but would someone mind catching me up on the whole smart thing ?

Town

2007-12-26 15:35:35

It's a minimizable client that now has the ability to read indexes from the client. -ish

Renax

2007-12-26 15:39:12

i was hoping for a more technical explanation :) i gotta play catch up to all you guys ;)

BenLand100

2007-12-26 16:18:31

From: Wizzup?
Try and see if they sort of give the same results… TileToMinimap clicks in the wrong direction for me… I think it messes up at index 2 of the path.

I stopped paying membership a long time ago, however, its possible that it does click in the wrong direction. When I wrote that I assumed 0,0 was in the North-West corner of the world, if its not, then the tempX-tileX/tempY-tileY needs to be swapped. The way I tested it wouldn't have shown that, since I used relative values to the player. I know the rotation part is correct (and more accurate since it uses the actual map rotation), however the figuring of the relative position of tile might be getting the signs messed up.

@Renax - I assume you know about the SMART that is released to members, this new version provides Scar with a way to access fields within the client via. reflection. Essentially, it can do anything that a java bot could do, but entirely from within Scar. SMART does not need to be updated with the client, does not modify the client, and does not rely on the client at all. Any client-specific code should be (and is) done within Scar.

Renax

2007-12-26 16:21:57

things we only dreamed of back in the day :), i'm gonna try and catch you on msn sometime ben.

BenLand100

2007-12-26 17:00:49

From: Renax
things we only dreamed of back in the day :), i'm gonna try and catch you on msn sometime ben.

Like tonight when I get back from the ice cream shop? :p

Pyro

2007-12-26 18:03:21

Ben. I believe it is the bottem left now that is the origin of co ords.

Renax

2007-12-26 18:16:05

yes ben, after your precious ice cream.

BenLand100

2007-12-26 18:28:26

From: Pyro
Ben. I believe it is the bottem left now that is the origin of co ords.

Sure enough, jagex has to be special :rolleyes: That means the Y tile/temp subtraction should be reversed I'll edit it in.

Yakman

2007-12-27 16:50:36

From: BenLand100
Essentially, it can do anything that a java bot could do, but entirely from within Scar.


Misleading :rolleyes:
it can do most things, but you cant add client events of your own, as in, the procedure OnServerMessage(String) is called when that happens in the client, or something like that.
but you'll probably never need to use that stuff anyway.

BenLand100

2007-12-27 17:46:14

From: Yakman
Misleading :rolleyes:
it can do most things, but you cant add client events of your own, as in, the procedure OnServerMessage(String) is called when that happens in the client, or something like that.
but you'll probably never need to use that stuff anyway.

Lol, anything a java bot can do without editing the client, how's that ;)