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:
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
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:
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
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:
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:
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:
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.
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):
And the ways of getting items are:
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:
and as it says in the function the Items it finds is given to you in an array of TGroundItem, and a TGrounItem is:
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 likewhile(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.