SRL Archive - Reflection Tutorials

Basics of Reflection


Seroko

2008-10-09 04:08:27

Reflection

What is Reflection?
Reflection is a method of hooking with java programs (Such as the Runescape applet) which allows us to basically read variables and classes directly from the client putting it short. So Why is reflection fairly new to scar? Because until Benland created S.M.A.R.T. and included reading variables from the smart client we had no way to do this. Reflection and hooking are the core of how many other runescape bots work such as rsbot and kyab.

Getting started with Reflection:
The first thing you have to do is download the include, this isn't included with SRL, a good tutorial on this by MasterKill can be found: http://www.villavu.com/forum/showthread.php?t=33416, a small catch with reflection is: You must always have your hooks up to date with the current build of runescape for it to work. This means roughly 2-3 times a month you will have to update your Reflection include [Basically everytime Runescape updates].

Using Reflection
First off you must include reflection in your script this is simply done by:
{.includes srl/srl/reflection/reflection.scar}
Also note that you HAVE to use smart to use reflection as mentioned earlier.

Now that we have Reflection included into our script what can we do?
I personally like to break reflection down into these categories:
1. Me (Your Player)
2. Players (Other Players)
3. NPCs (Non-Playable Characters such as bankers)
4. Objects (Graphics and things on the ground, such as Trees and Rocks)
5. Ground Items (Items on the ground, like a creatures loot)

Almost everything in reflection is done based off tiles, these are stored in a TPoint. This is an x,y coordinate on runescapes map, this is NOT our mouse position. Runescape is broken down into tiles putting it simply if you was standing on tile 500,500 and walked one step east you would be on tile 501, 500. You can also convert a tile to a mainscreen position or minimap position using
{*******************************************************************************
function TileToMS(Tile:TPoint; height: integer): TPoint;
By: BenLand100
Description: Converts the tile position tileX,tileY to a mainscreen location
Height is the distance (in px) above the ground
*******************************************************************************}
function TileToMS(Tile:TPoint; height: integer): TPoint;

{*******************************************************************************
function TileToMM(Tile: TPoint): TPoint;
By: BenLand100
Description: Converts the tile position tileX,tileY to a minimap location
*******************************************************************************}
function TileToMM(Tile: TPoint): TPoint;

Breaking it down: Me
This is your character your player, there are several things you can do in this category you can do functions like GetMyPos which will return the tile your player is standing on or the big one, GetMe. GetMe returns a variable of TME which is:
  TMe = record
Tile, MS: TPoint;
animation, speed, LoginIndex: integer;
HPRatio, height, level, Combat: integer;
Name: string;
InFight: boolean;
Experience, Levels: array[0..23] of Integer;
end;
So lets say you know cutting a tree with a dragon axe has an animation 1337 (This is not the actual animation) you could do something like
while(GetMe.Animation=1337) do
begin
Wait(100+Random(500));
FindMyRandoms;
DoMyAntiBan;
end;

Breaking it down: Players
Reflection finds players based on a hook to find Player count and looping through all the players in the player count, the two main functions here are
{*******************************************************************************
function GetPlayers: array of TPlayer;
By: Widget
Description: Returns all the players on the minimap
*******************************************************************************}
function GetPlayers: array of TPlayer;

{*******************************************************************************
function GetPlayer(name: string): TPlayer;
By: Widget
Description: Gets available information for a player.
*******************************************************************************}
function GetPlayer(name: string): TPlayer;

Basically GetPlayer uses GetPlayers then sorts through the results returning you one Player out of the list of players it found, Players are stores as a TPlayer which is:
  TPlayer = record
Tile, MS, MM: TPoint;
animation, speed: integer;
HPRatio, height, level: integer;
Name: string;
end;

So you can monitor what other players are doing if you wished, how many players there are, their names, their levels, where they are standing, what ever you would want. You can go as far as getting their HPRatio and combining this with a quick lookup you can get their health if its high enough (Theres quirks with low health players) See Shady?'s Hp over head script for more information on doing things like that :)

Breaking it down: NPCs
Ah, now for the big ones! NPCs these are your non-playable characters, these are your bankers, your quest givers, etc. NPC information is gathered similar to players, we use a hook for the npc array and loop through the array to gather individual npc information. There is as usual one big Get for npcs and then functions that sort through the results returning more specific information for you, NPCs are stored as a TNPC. The Main Get function is:
{*******************************************************************************
function GetNPCs:array of TNPC;
By: Widget
Description: Returns all the currently loaded NPCs
*******************************************************************************}
function GetNPCs:array of TNPC;
And as mentioned earlier it returns a TNPC which is:
TNPC = record
Tile, MS, MM: TPoint;
NPCType, height, animation: integer;
HPRatio, TurnDirection: integer;
Name : string;
InFight, IsMoving: boolean;
end;

There is two functions available to sort through this and return a single npc more specific npcs to us, they both still return an array of TNPC due to their is often multiple NPCs (such as monsters) thats exactly alike minus their position etc, these two functions are:
{*******************************************************************************
Function GetNPCsByName(name:string):array of TNPC;
By: Widget
Description: Returns NPCs matching the name.
*******************************************************************************}
function GetNPCsByName(name:string): array of TNPC;

{*******************************************************************************
Function GetNPCsByID(TheType:integer):array of TNPC;
By: Widget
Description: Returns NPCs matching the ID.
*******************************************************************************}
function GetNPCsByID(TheType:integer): array of TNPC;

The difference is, you may be wanting to find a Goblin and getting them by name will return you goblins level 2, 7, 10 and what ever else their is around you. But getting them by id theirs a unique id for each of those goblins. Also we can use SortNPCs to sort them by distance based on our location. So using 1337 as an example for a lvl 2 goblin.
function FindGoblin: TPoint;
var
Goblins: array of TNPC;
begin
Goblins := SortNPCs(GetNPCsByID(1337)); // We would now have all level 2 goblins
Result := Goblins[0].MS; // Returning the mainscreen location of the closest level 2 goblin
end;

This is of course just an example. And if the NPC doesn't move (bankers etc) it is almost always better to get the tile ;) and usually better for things that move also, since you can easily check it the TileOnMS etc [Look at core.scar for a more complete list of functions for basic manipulation]. Also Fishing locations are declared npcs.

Breaking it down: Objects
Here is a huge one, there is no way to get an object array or anything like that, to get an object you must specifically check a tile, although you can "dump" all objects which loops through all tiles gathering object information [Slow and a Memory killer imo], but objects are returned as a UID which is (and includes long):
  Long = Record
High, Low: Integer;
End;

UID = Record
objType: Integer;
UID: Long;
End;

And the ways of getting items are:
{*******************************************************************************
Function GetUIDAt(TileX, TileY: Integer): UID;
By: n3ss3s and Bobarkinator
Description: Returns the information about the object at a give tile

*******************************************************************************}

Function GetObjectAt(TileX, TileY: Integer): UID;

{*******************************************************************************
Function FindObject(Var Tile: TPoint; objType: Integer): Boolean;
By: n3ss3s and Bobarkinator
Description: Returns True if objType is found. Tile of objType is returned in
Tile. Make sure to check thatthe Tile is on the MS, if not, walk to it

*******************************************************************************}

Function FindObject(Var Tile: TPoint; objType: Integer): Boolean;

For the most part GetObjectAt is used the most, for example, lets say you have a TPointArray of Coal Veins, You could GetObjectAt and compare the object id to a TIntegerArray you have of ids you know means their is coal there, and if it there is coal there you can walk to / click on the tile you checked.

Breaking it down: Ground Items
My final category is ground items, these are just simply that items on the ground you can pick up such as a monsters drops, or a pickaxe head. The most used function to do this is FindGroundItems which is:
{*******************************************************************************
Function FindGroundItems(Var Items: T2DIntArray; IDs: TIntegerArray; maxSL,
MS: Integer): Boolean;
By: n3ss3s
Description: Finds the ground items with the ID(s).
MaxSL = max sidelength of the box it looks in, 3 is the 3*3 box you are in the
middle of.

The Items array it returns, contains an array of all the items which are
represented by a TPointArray.
Items[index][0] is the item's ID, if you for example want to WriteLn
"We picked up ID blah" or something.
Items[index][1] is the stack size of the item, non-stackable items' stacksize
is 1.

Set MS to bigger than 0 if you want it to return the main screen coords
instead of tiles.

Items[index][2] is the X of the item.
Items[index][3] is the Y of the item.

<3 Yakman for the spiral algorithm.
*******************************************************************************}

Function FindGroundItems(Var Items: Array of TGroundItem; IDs: TIntegerArray; maxSL: Integer): Boolean;


and as it says in the function the Items it finds is given to you in an array of TGroundItem, and a TGrounItem is:
  TGroundItem = Record
MS, Tile: TPoint;
ID, StackSize: Integer;
End;
So again you have your tiles you can walk to, or get the mainscreen location of.

Bonfield

2008-10-09 04:46:51

good tut should help ppl when they atart to learn reflection

Blumblebee

2008-10-09 10:00:48

great tut! +repped

Shady?

2008-10-09 12:23:10

Nice Ian, great tut, answer me on msm b1tch!

Zander

2008-10-22 15:28:49

This is harder than i thought… i keep getting errors saying something that it cannot access S.M.A.R.T…

Shuttleu

2008-10-22 15:40:31

From: Zander
This is harder than i thought… i keep getting errors saying something that it cannot access S.M.A.R.T…


thats because smart doesnt work properly

~shut

Fsoul

2008-10-25 21:01:36

Thank you for a inside look I had heard of reflection but that was it, thanks

Phoenix13nl

2009-02-03 18:34:15

Great tutorial! I never actualy used reflection but im realy going to do now! (another night without sleep :()

Thank you alot!

boss01

2009-02-19 09:29:49

Best reflection tut there is, all other are about walking…

Smarter Child

2009-02-19 14:47:01

URRG, my stupid SMART isn't working..i wish i could actually try these..

curran0021

2009-02-22 09:31:27

thanks thats a big help

n3ss3s

2009-02-22 14:36:21

Because until Benland created S.M.A.R.T. and included reading variables from the smart client we had no way to do this. Reflection and hooking are the core of how many other runescape bots work such as rsbot and kyab.


KYAB was introduced to SRL by Solarwind and Benland over a year before S.M.A.R.T ;)

Press Play

2010-05-29 18:09:06

nice tut! i might attempt a reflection script if i have time :)

Bad Boy JH

2010-05-29 21:52:28

dude, outdated….

Smarter Child

2010-05-30 16:58:14

From: Bad Boy JH
dude, outdated….


You can still learn from this, tutorials can't be grave digged. ;)

Bad Boy JH

2010-05-31 09:08:58

Yes but they can be outdated, I mean reflection is still in development, I mean in the past few days, I have had to change things in scripts. I Have been doing because things like PointToTile, is now Tile and Point To Tile is something different, I now have to call SetupReflection, instead of SetupSRL, its not major changes, but its something people may be confused by if they read this tutorial.

i luffs yeww

2010-05-31 17:38:16

^ Learning things that aren't in use doesn't mean they can't be learned. :)