SRL Archive - Includes, Plugins, and Snippets

OpenGL plugins


Brandon

2013-07-23 01:13:43

Hooks Plugin (bin folder contains the plugins):
https://github.com/Brandon-T/GLX


Windows Only (Colour - C++): https://github.com/Brandon-T/GLX-Colour/releases

Windows & Linux (Colour - C): http://www.mediafire.com/download/ba72ox41gdkc6g1/libGL.zip

GLX Include:
https://github.com/Brandon-T/SRL-GLX


Most of Simba's functions ported to C++ (pretty OLD code):
https://github.com/Brandon-T/PurelyCPP/tree/master/src


Extras:

OpenGL Walking algorithm by Bart (Master-BB) in C++.. Ported to RS3 and written in Pascal/Lape by me:

{$include_once GLX/GLXCore.Simba}
{$include_once GLX/Misc/Map.Simba}
{$include_once GLX/Misc/Smart.Simba}
{$include_once GLX/Misc/Graphics.Simba}
{$include_once GLX/Mouse.Simba}
{$include_once GLX/Login.Simba}
{$include_once GLX/Text.Simba}
{$include_once GLX/Bank.Simba}
{$include_once GLX/Inventory.Simba}


{* Get's the bounds of the minimap *}
Function GL_GetMMBounds: TBox;
var
I: Integer;
Background, Corners: glTextureArray;
Begin
Background := glGetTextures(3786240);
Corners := glGetTextures(386460);
If (Length(Background) < 1) or (Length(Corners) < 1) Then Exit;

For I := 0 To High(Background) Do
If (PointInBox(Point(Corners[0].X, Corners[0].Y), Background[I].Bounds)) then
Begin
Result := Background[I].Bounds;
Exit;
End;
End;

type FPoint = record
X, Y: Single;
end;

Function ToFPoint(X, Y: Single): FPoint;
Begin
Result.X := X;
Result.Y := Y;
End;


{* Get's the coordinates on the screen where the map is rendered *}
Procedure GL_GetMapCoords(var TL, BL, BR, TR: FPoint);
var
X, Y: Array[0..3] of single;
begin
GLXMapCoords(X, Y);
TL := ToFPoint(X[0], Y[0]);
BL := ToFPoint(X[1], Y[1]);
BR := ToFPoint(X[2], Y[2]);
TR := ToFPoint(X[3], Y[3]);
end;

{* Projects our player position onto the Map. Essentially getting our position within the current map with 100% accuracy *}
Function GetLocalPos: TPoint;
var
Player: TPoint;
TL, BL, BR, TR: FPoint;
PPX, PPY, PPZ: Double;
TVX, TVY, BVX, BVY: Double;
Begin
If (Not GL_LoggedIn) Then Exit;
GL_GetMapCoords(TL, BL, BR, TR);
Player := MiddleBox(GL_GetMMBounds); //Player is always in the middle of the MM. Map is drawn around the player.

TVX := TR.X - TL.X;
TVY := TR.Y - TL.Y;
BVX := BL.X - TL.X;
BVY := BL.Y - TL.Y;
PPX := Player.X - TL.X;
PPY := Player.Y - TL.Y;
PPZ := (TVX * BVY) - (TVY * BVX);
Result.X := Round(((PPX * BVY) - (PPY * BVX)) * 512.0 / PPZ);
Result.Y := Round(((PPY * TVX) - (PPX * TVY)) * 512.0 / PPZ);
End;


{* Project our position onto the minimap. Does not work if the map is rotated. To do so, simply reverse the above/previous algorithm *}
Function LocalPosToMM(Pos: TPoint): TPoint;
var
Me: TPoint;
DX, DY: Integer;
Begin
Me := GetLocalPos;
DX := Pos.X - Me.X;
DY := Pos.Y - Me.Y;

Me := MiddleBox(GL_GetMMBounds);
Result.X := Me.X + DX;
Result.Y := Me.Y + DY;
End;

var
T: TSmart;
P: TPoint;
X, Y, Map: Integer;
begin
ClearDebug;
T.Create(1350, 650, '', ['OpenGL32.dll']);
GLXMapHooks(T.CurrentClient);
glDebug(GL_MODE_HUD, 386460, 0, 0, T.Width, T.Height);
T.GetGraphics().Clear;
P := GetLocalPos;
TerminateScript();
end.


Original Algorithm cleaned up:

void MapLog::CalculatePosition(int &x, int &y)
{
struct Point{double X, Y;};
Point Player = {MMCX, MMCY};
Point TopLeft = {X[0], Y[0]}, TopRight = {X[3], Y[3]}, BottomLeft = {X[1], Y[1]};

double TopVectorX = TopRight.X - TopLeft.X;
double TopVectorY = TopRight.Y - TopLeft.Y;

double BottomVectorX = BottomLeft.X - TopLeft.X;
double BottomVectorY = BottomLeft.Y - TopLeft.Y;

double PlayerPVectorX = Player.X - TopLeft.X;
double PlayerPVectorY = Player.Y - TopLeft.Y;

double perP1 = (PlayerPVectorX * BottomVectorY) - (PlayerPVectorY * BottomVectorX);
double perP2 = (PlayerPVectorY * TopVectorX) - (PlayerPVectorX * TopVectorY);
double perP3 = (TopVectorX * BottomVectorY) - (TopVectorY * BottomVectorX);
x = std::round((perP1 * 512.0d) / perP3);
y = std::round((perP2 * 512.0d) / perP3);
}

DrChill

2013-07-23 01:31:08

I'm curious as to what the ban rates on this are, how detectable is it/are they currently doing detection?

Is this Windows specific, or will it run under Linux?

Sjoe

2013-07-23 01:40:02

hot dang, Christmas already ;)

Brandon

2013-07-23 02:15:52

From: DrChill
I'm curious as to what the ban rates on this are, how detectable is it/are they currently doing detection?

Is this Windows specific, or will it run under Linux?



Banrates on something that loads the same way the game loads OpenGL? It exports all the same functions as the OpenGL32.dll in your System32.dll. Even with Hooks, it doesn't overwrite anything, doesn't touch the VTables, nothing. Just loads as usual and "intercepts" data. That data is still passed as normal to your Original OpenGL32.dll location at C:/Windows/System32. It writes to a shared memory location and Simba reads from that.

According to the library procs for all OS's I can think of, loading the same library twice returns the address of the original. This takes advantage of that by loading when Smart loads. Any dll called "OpenGL32.dll" that is loaded thereafter, the load proc will return the address of mine since it loaded first.

You can read up on how the loading works here: http://villavu.com/forum/showthread.php?t=89645&p=1097257#post1097257
The basics still apply.

The serialization changed drastically.. but this is the "Concept" of how events/signals works.. Smart does the same but using non-blocking sockets.

Picture above is pretty Silly but I couldn't explain it to ppl at the time like the above picture did lol.
It's pretty much fully cross platform since it's opengl and I used little Winapi (for events). Removing the WinAPI or #IFDEF-ing it will make it 100% cross platform. I just gotta boot up a linux machine, install a nice development environment (gcc, g++, etc) and work on that.. Just been lazy is all.

P.S. You can check out here for more Reverse Engineering craps: http://villavu.com/forum/showthread.php?t=100266 <– Can be used to Hide dll's and other files in any process but there is no need.

speedster

2013-07-23 07:53:04

Thank you Brandon! :) Will look at it soonish.

Ashaman88

2013-07-23 08:52:28

Nice I'll check it out tonight! GJ brandon

rj

2013-07-23 10:42:18

Sweet I may just come back to RS :)

Sjoe

2013-07-23 12:20:26

@Brandon

Could u provide a testscript? :p

Can't get it to work :(

Brandon

2013-07-23 13:50:44

From: Sjoe
@Brandon

Could u provide a testscript? :p

Can't get it to work :(




There is no test script. You don't have to do anything. All you do is tell Smart to load it and that's it. There is no setup or anything.

Sjoe

2013-07-23 13:53:11

From: Brandon
There is no test script. You don't have to do anything. All you do is tell Smart to load it and that's it. There is no setup or anything.


Yeah I dunno where to start :p

Kevin

2013-07-23 13:54:46

From: Sjoe
Yeah I dunno where to start :p


It's a smart param change. instead of passing '' at the end, pass 'OpenGl32' instead.

Sjoe

2013-07-23 14:02:42

Tried using this testscript
I got GLHook.simba from your smart-overhaul

But GLCommunication opens up with this error:

[Error] C:\Simba\Includes\GLHook/GLCommunication.Simba(142:10): Unknown identifier 'GLHGeTTextures' at line 141
Compiling failed.


{$DEFINE SMART8}
{$DEFINE GLHOOK}
{$I GLHook/GLHook.Simba}

var
IDs: Array Of Cardinal;
begin
ClearDebug;
Smart_Plugins := 'OpenGL32.dll';
SetupSRL;
SmartSetOperatingMode(0);

if (NOT GLHSetup(ToStr(SMART_CURRENTCLIENT))) THEN
Begin
Writeln('Failed to Setup GLHook. Please Check your Installation.');
TerminateScript;
End;

SmartSetOperatingMode(1);
GLHSetDebug(True, False, 0);
SmartSetMouseInput(True);
SmartSetKeyInput(True);

GLHEnabledFilter(0, True); //Models
GLHEnabledFilter(1, True); //Fonts
GLHEnabledFilter(2, False); //Textures

//Displays debugging for all models, textures, fonts.. Changing the dimensions filters models/textures/fonts by that are.
GLHFilterModelsArea(0, 0, 765, 553);
GLHFilterFontsArea(0, 0, 765, 553);
GLHFilterTexturesArea(0, 0, 765, 553);

GLHDrawTextureHud(507195); //Draw this ID on the hud. Should display the RS compass.
end.

Brandon

2013-07-23 14:36:15

Lol.. COLOUR ONLY atm.
I stated the plugin on OP does NOT have a setup. Not sure what you are setting up. Also only works with Smart v8.2. Not sure how come you're using the old smarts :l
Pascal script is dead. SRL is going to be running in Lape so you shouldn't try to run old scripts with the new plugin..


Atm, the only thing I have written for my own include is:


{$loadlib libsmartremote}

type TSmart = record
__CurrentClient: Integer;
__Width, __Height: Integer;
__ForceNew: Boolean;
end;

Procedure TSmart.Create;
Begin
Self.Create(1024, 768, ['']);
End;

Procedure TSmart.Create(Width, Height: Integer; Plugins: TStringArray); overload;
Begin
Self.Create(Width, Height, 's', Plugins);
End;

Procedure TSmart.Create(Width, Height: Integer; InitSequence: String; Plugins: TStringArray); overload;
var
Params: TStringArray;
Begin
Self.__Width := Width;
Self.__Height := Height;

If (Not Self.__ForceNew And Self.Pair()) then
Exit;

Params := self.GetSmartParams();
If (Length(Params) <> 2) then
begin
Writeln('** Failed To Grab Smart Parameters **');
Writeln('** Please check your internet connection/firewall **');
TerminateScript;
Exit;
end;

Self.__CurrentClient := SmartSpawnClient(Replace(PluginPath, '\', '/', [rfReplaceAll]), Params[0], ',' + Params[1], Width, Height, InitSequence, '', '', Implode(',', Plugins));

If (Self.__CurrentClient > 0) Then
begin
try
SetEIOSTarget('libsmartremote', ToStr(__CurrentClient));
Writeln('Loading SMART: ' + Params[0] + Params[1]);
except
WriteLn('** Fatal Error: Pairing Clients; Terminating Script **');
TerminateScript;
end;
end else
begin
Writeln('** Smart Cannot Spawn Clients **');
TerminateScript;
end;
End;

Function TSmart.CurrentClient: Integer;
Begin
Result := Self.__CurrentClient;
End;

Function TSmart.GetSmartParams: TStringArray;
var
Params: TStringArray;
Page: String;
Begin
Page := Between('<iframe id="game" src="', '"', GetPage('http://www.runescape.com/c=lWWmqzNvQ8k/game.ws?beta=1&j=1'));
Params := Explode(',', Page);
Result := Params;
End;

Function TSmart.SmartGetClientIDs: TIntegerArray;
var
I, Count: Integer;
Begin
Count := SmartGetClients(True);
SetLength(Result, Count);
If (Count > 0) Then
For I:= 0 to Count - 1 do
Result[I] := SmartClientID(I);
End;

Function TSmart.Pair: Boolean;
var
I, Count: Integer;
IDs: TIntegerArray;
Begin
IDs := SmartGetClientIDs;
Count := Length(IDs);
If (Count > 0) Then
For I:= 0 To Count - 1 Do
If SmartPairClient(IDs[I]) then
begin
SetEIOSTarget('libsmartremote', ToStr(IDs[I]));
Writeln('Paired with SMART[' + ToStr(IDs[I]) + ']');
Result := True;
Exit;
end;
End;


And I use it like:


{$I Smart.Simba}

var
Smart: TSmart;
begin
Smart.Create();

//Or: Smart.Create(Width, Height, ['']);
//OR: Smart.Create(Width, Height, ['OpenGL32.dll']);

//etc..
end.

It is object oriented and the TSmart acts as a class. You guys can look at SRL-6 on github. The above is totally unrelated but it is what I personally use. SRL-6 loads smart differently.

For the hook plugin which no one else has except myself and Kasi (has part), I use:

{$loadlib GLX}


type glTexture = record
ID: Integer;
ColourID: Integer;
X, Y: Integer;
Bounds: TBox;
end;

type glModel = record
ID: Cardinal;
TID: Integer;
X, Y: Integer;
end;

type glChar = record
I: Integer;
end;

type glText = record
I: Integer;
end;


type
glCharArray = array of glChar;
glModelArray = array of glModel;
glTextureArray = array of glTexture;

type pModel = ^glModel;
type pglTexture = ^glTexture;

type TGL = record
I: Integer;
end;

Procedure Pointer.Inc(Size: Int64);
Begin
Self := Self + Size;
End;


Function TGL.GetTextures: glTextureArray;
var
Size: Integer;
Ptr: Pointer;
Begin
Result := [];
Ptr := GLXTextures(Size);
SetLength(Result, Size);

For I := 0 To Size - 1 Do
Begin
Result[I] := glTexture(Ptr^);
Ptr.Inc(sizeof(glTexture));
End;
End;

Function TGL.GetTextures(ID: Integer): glTextureArray; overload;
var
Size: Integer;
Ptr: Pointer;
Begin
Result := [];
//Ptr := GLHGetTexturesByID(ID, Size);
SetLength(Result, Size);

For I := 0 To Size - 1 Do
Begin
Result[I] := glTexture(Ptr^);
Ptr.Inc(sizeof(glTexture));
End;
End;

Function TGL.GetTextures(Box: TBox): glTextureArray; overload;
var
Size: Integer;
Ptr: Pointer;
Begin
Result := [];
//Ptr := GLHGetTexturesByArea(Box, Size);
SetLength(Result, Size);

For I := 0 To Size - 1 Do
Begin
Result[I] := glTexture(Ptr^);
Ptr.Inc(sizeof(glTexture));
End;
End;


Function TGL.GetModels: glModelArray;
var
Size: Integer;
Ptr: Pointer;
Begin
Result := [];
//Ptr := GLHGetModels(Size);
SetLength(Result, Size);

For I := 0 To Size - 1 Do
Begin
Result[I] := glModel(Ptr^);
Ptr.Inc(sizeof(glModel));
End;
End;


All of which is subject to change because the only plugin that is finished is the colour one..

Sjoe

2013-07-23 15:08:53

kk then I'll settle with colours.

Brandon

2013-07-25 20:09:09

Updated OP to include the plugin with Hooks and example usage for Lape.

It's a bare-minimum include but everything should be there that is needed.

Functions:


GLXGetTextures //Gets a list of textures displayed on screen. Aka Items, Buttons, Interfaces, etc..
GLXGetModels //Gets a list of models displayed on screen. Aka NPCs, Players, Characters, Rocks, Doors, Buildings, Pets, Familiars, etc..
GLXGetChars //Gets font characters displayed on screen. Text, menu text, player chat, mouse-over text, skill-levels, etc..
GLXCompass //Gets the compass angle. Angle at which the compass is rotated.
GLXEulerAngles //Gets the pitch, yaw, and roll. All X, Y, Z angles of each plane with the player at the center of the map.
GLXCameraPos //Gets the current position of the camera. Camera's translation. Aka player position within the current map.
GLXCameraHeight //Gets the current height of the camera. 0 = lowest angle. Aka the angle looking directly ahead of you. >= 65 = Highest angle. Aka the angle looking down on your character. Anything else is inbetween angle.
GLXMapToImage //Returns the current map that you are standing in. Used for glSPS walking or whatever else.. This image must be freed after being used!

//TODO:
Remove Shadows from fonts and split them up into proper text..
Split fonts by colours for identifying which text is which color..
Write useable include for scripters.. Aka glOpenBank, glInvFull, glLoginPlayer, etc..

Le Jingle

2013-07-25 21:12:25

Seem to load everything fine, just that once I hit the login screen, I get hit with a flashing screen (possible warning for epileptic's)

Super nice though, if I may say so Brandon, NiceWork :)

Edit: Had loaded in DirectX first time around. Switch settings to OGL, closed, re-ran it (loaded in OGL second time around)
Edit: Disabling SMART manually makes it stop flashing

Kasi

2013-07-25 22:17:31

From: Le Jingle
Seem to load everything fine, just that once I hit the login screen, I get hit with a flashing screen (possible warning for epileptic's)

Super nice though, if I may say so Brandon, NiceWork :)

Edit: Had loaded in DirectX first time around. Switch settings to OGL, closed, re-ran it (loaded in OGL second time around)
Edit: Disabling SMART manually makes it stop flashing


Disable the capture.

Brandon

2013-07-28 21:08:49

Updated OP.. Pretty good so far. At least it's a start for a functioning include.. Just needs a bit more work and it'll be able to write full on scripts for RS3.

BenLand100

2013-07-30 13:39:55

From: Le Jingle
Seem to load everything fine, just that once I hit the login screen, I get hit with a flashing screen (possible warning for epileptic's)

Super nice though, if I may say so Brandon, NiceWork :)

Edit: Had loaded in DirectX first time around. Switch settings to OGL, closed, re-ran it (loaded in OGL second time around)
Edit: Disabling SMART manually makes it stop flashing


It sounds like you're not loading the plugin properly. Remember to pass the name of the plugin as the last argument to SmartSpawnClients and then the plugin will configure SMART automatically.

loragnor

2013-07-30 20:26:12

Thanks for the work you're putting in on this @Brandon. I've attempted to set this up and run it, but am running into a couple issues. First, what I've done:

  1. Installed and updated SIMBA v992
  2. Installed SRL 5
  3. Updated to SMART 8.2
  4. Downloaded the GLX.zip and extracted the dll and .so file to the plugin folder and the other files straight into the includes folder.
  5. Modified SmartSpawnClients putting 'OpenGL32' as the last param

Next, I opened Simba and copy / pasted your test_script from your first post and hit ctrl-F9 using the PS interpreter and got this error:
C:\Simba\Scripts\glxtest.simba(2:1): Unable to register function Function GLXMap(var Width, Height: Integer; var X, Y: array[0..3] of Single): Pointer; at line 1

I thought perhaps I needed to use the Lape interpreter, so I switched, hit ctrl-F9 and got this error:
Unknown declaration "FixRad" at line 7, column 10 in file "C:\Simba\Includes\GLX\Misc\Map.Simba"

Do I need to use SRL6 for this? Do I need to use Simba v1.0?

Le Jingle

2013-07-30 20:48:51

From: loragnor
Thanks for the work you're putting in on this @Brandon. I've attempted to set this up and run it, but am running into a couple issues. First, what I've done:

  1. Installed and updated SIMBA v992
  2. Installed SRL 5
  3. Updated to SMART 8.2
  4. Downloaded the GLX.zip and extracted the dll and .so file to the plugin folder and the other files straight into the includes folder.
  5. Modified SmartSpawnClients putting 'OpenGL32' as the last param

Next, I opened Simba and copy / pasted your test_script from your first post and hit ctrl-F9 using the PS interpreter and got this error:
C:\Simba\Scripts\glxtest.simba(2:1): Unable to register function Function GLXMap(var Width, Height: Integer; var X, Y: array[0..3] of Single): Pointer; at line 1

I thought perhaps I needed to use the Lape interpreter, so I switched, hit ctrl-F9 and got this error:
Unknown declaration "FixRad" at line 7, column 10 in file "C:\Simba\Includes\GLX\Misc\Map.Simba"

Do I need to use SRL6 for this? Do I need to use Simba v1.0?


use simba 1.0, http://l0.lt is wiz's buildbot
also use srl6 if you have to.. keep in mind there's a separate OGL include…

loragnor

2013-07-31 04:55:18

From: Le Jingle
use simba 1.0, http://l0.lt is wiz's buildbot


Thank you for the reply and link. I've downloaded Simba 1.0 and installed it. There is no facility for extension management?

Next I downloaded SRL6 and put it in the Includes->SRL folder.

Then I ran the test script but got the error:
Exception in Script: Error loading plugin C:\Simba\Plugins\GLX64.dll

However, I cannot find a GLX64.dll in Brandon's github.


From: Le Jingle
also use srl6 if you have to.. keep in mind there's a separate OGL include…

This has me a bit puzzled. Is this located somewhere else? It is not included in Brandon's GLX include folder.

Brandon

2013-07-31 05:09:34

From: loragnor
Thank you for the reply and link. I've downloaded Simba 1.0 and installed it. There is no facility for extension management?

Next I downloaded SRL6 and put it in the Includes->SRL folder.

Then I ran the test script but got the error:
Exception in Script: Error loading plugin C:\Simba\Plugins\GLX64.dll

However, I cannot find a GLX64.dll in Brandon's github.



This has me a bit puzzled. Is this located somewhere else? It is not included in Brandon's GLX include folder.



You need Simba x32. Runescape cannot run in x64 JVM anyway so it's a waste of time for me to provide an x64 plugin. You can however, compile the plugin to x64 if you wish. It'll work just fine.


Also, the following is a copy of my working Barbarian fisher :D

{$include_once GLX/GLXCore.Simba}
{$include_once GLX/Misc/Map.Simba}
{$include_once GLX/Misc/Smart.Simba}
{$include_once GLX/Misc/Graphics.Simba}
{$include_once GLX/Mouse.Simba}
{$include_once GLX/Login.Simba}
{$include_once GLX/Text.Simba}
{$include_once GLX/Bank.Simba}
{$include_once GLX/Inventory.Simba}

const
MyID = 648933015; //ID of your player.

var
T: TSmart;

Function FindFishingSpot: TPoint;
var
TPA: TPointArray;
I, X1, Y1, X2, Y2: Integer;
FishingSpots: glModelArray;
Begin
FishingSpots := glGetModels(2648051121);
Insert(glGetModels(203893359), FishingSpots);
Insert(glGetModels(2948843458), FishingSpots);
SetLength(TPA, Length(FishingSpots));
For I := 0 To High(FishingSpots) Do
Begin
TPA[I] := Point(FishingSpots[I].X, FishingSpots[I].Y);
End;

GLXViewPort(X1, Y1, X2, Y2);
SortTPAFrom(TPA, Point((X2 - X1) div 2, (Y2 - Y1) div 2));
If (Length(TPA) > 0) then
Result := TPA[0]
else
Result := Point(-1, -1);
End;

Function HasFeathersBait: Boolean;
Begin
Result := (Length(glGetTextures(80835, 2302754, 5)) > 0) or (Length(glGetTextures(36720, 460033, 5)) > 0);
End;

Function GetFishBoxes(Area: TBox): TBoxArray;
var
I, J: Integer;
Textures: glTextureArray;
Begin
Textures := glGetTextures(Area);
SetLength(Result, Length(Textures));

For I := 0 To High(Textures) do
Begin
If ((Textures[I].ID = 49470) and SimilarColors(Textures[I].ColourID, 1118479, 5))
or ((Textures[I].ID = 45900) and SimilarColors(Textures[I].ColourID, 724234, 5))
or ((Textures[I].ID = 62220) and SimilarColors(Textures[I].ColourID, 1249296, 5)) then
begin
Result[J] := Textures[I].Bounds;
Inc(J);
end;
End;
SetLength(Result, J);
End;

Procedure DropAll;
var
I: Integer;
Fish: TBoxArray;
Begin
While(True) Do
Begin
Fish := GetFishBoxes(GL_InvBounds);
If (Length(Fish) < 1) Then Exit;

For I := 0 To High(Fish) Do
Begin
MouseBox(Fish[I], MOUSE_RIGHT);
GL_ChooseOptionMulti(['Drop', 'rop', 'Dro']);
End;
End;
End;

Procedure MarkTime(var T: Integer);
Begin
T := GetSystemTime;
End;

Function TimeFromMark(T: Integer): Integer;
Begin
Result := GetSystemTime - T;
End;

function WaitFindMe(ID: Cardinal; WaitPerLoop, MaxTime: Integer): Boolean;
var
T: Integer;
begin
T := GetSystemTime + MaxTime;
while (GetSystemTime < T) do
begin
if (Length(glGetModels(ID)) > 0) then
begin
Result := True;
Exit;
end;
Wait(WaitPerLoop);
end;
end;

function WaitNotFindMe(ID: Cardinal; WaitPerLoop, MaxTime: Integer): Boolean;
var
T: Integer;
begin
T := GetSystemTime + MaxTime;
while (GetSystemTime < T) do
begin
if (Length(glGetModels(ID)) < 1) then
begin
Result := True;
Exit;
end;
Wait(WaitPerLoop);
end;
end;

Procedure MainLoop;
var
P: TPoint;
MeBox, AnimBox: TBox;
X1, Y1, X2, Y2: Integer;
Begin
GLXViewPort(X1, Y1, X2, Y2);
MeBox := IntToBox(((X2 - X1) div 2) - 30, ((Y2 - Y1) div 2) - 30, ((X2 - X1) div 2) + 30, ((Y2 - Y1) div 2) + 30);
AnimBox := IntToBox(MeBox.X1 + 10, MeBox.Y1 + 10, MeBox.X2 - 10, MeBox.Y2 - 10);

While(True) Do
Begin
If (Not GL_LoggedIn) Then Exit;
If (GL_InvFull) Then DropAll;
If (Not HasFeathersBait) Then Exit;

If WaitFindMe(MyID, 50, 1500) Then
Begin
P := FindFishingSpot;
writeln('Finding Fishing Spot: ' + ToStr(P));
If ((P.X > 0 and P.Y > 0)) Then
Begin
Mouse(P, 5, 5, MOUSE_RIGHT);
If (GL_ChooseOptionMulti(['Use-rod Fishing spot', 'Use-rod', 'rod Fishing spot'])) Then
WaitNotFindMe(MyID, 50, 2500);
End;
End;
End;
End;

begin
ClearDebug;
T.Create(1350, 650, '', ['OpenGL32.dll']);
GLXMapHooks(T.CurrentClient);
glDebug(GL_MODE_Models, 0, 0, 0, T.Width, T.Height);
T.GetGraphics().Clear;
//writeln(glGetModels(IntToBox(702, 306, 755, 356)));
DropAll;
MainLoop;
TerminateScript();
end.

loragnor

2013-07-31 17:09:34

From: Brandon
You need Simba x32. Runescape cannot run in x64 JVM anyway so it's a waste of time for me to provide an x64 plugin. You can however, compile the plugin to x64 if you wish. It'll work just fine.


This was the secret to my success. Thank you. Installed the 32-bit version and it was a snap. I'm looking forward to playing with this. :)

Le Jingle

2013-08-03 01:08:20

Thank you for the update! :)

Sin

2013-08-03 20:40:55

@Brandon I keep receiving this error: [Error] C:\Simba\Includes\GLHook\Misc\Smart.Simba(7:15): Unknown type 'TGraphics' at line 7

I'm using Simba 1.00 32bit version.


Quick edit, this is the new error (the above one went away when i changed the interpreter to Lape):

Skipping plugin due to ABI <= 2
Exception in Script: Unknown declaration "GLXDebug" at line 56, column 3 in file "C:\Simba\Includes\GLHook\GLHCore.Simba"

Brandon

2013-08-03 20:57:18

From: Sin
@Brandon I keep receiving this error: [Error] C:\Simba\Includes\GLHook\Misc\Smart.Simba(7:15): Unknown type 'TGraphics' at line 7

I'm using Simba 1.00 32bit version.


Quick edit, this is the new error (the above one went away when i changed the interpreter to Lape):

Skipping plugin due to ABI <= 2
Exception in Script: Unknown declaration "GLXDebug" at line 56, column 3 in file "C:\Simba\Includes\GLHook\GLHCore.Simba"



What the.. Did a new Simba get released or something? The latest ABI for Simba's plugin system is 2 as far as I'm aware.. And according to the docs: http://docs.villavu.com/simba/simbaref/plugins.html
@Wizzup?; Did something change that wasn't announced?


I checked the source Sin. There isn't anything wrong with the plugins exports or ABI :S Where did you get that Simba 1.00 from?

Sin

2013-08-03 21:01:51

From: Brandon
What the.. Did a new Simba get released or something? The latest ABI for Simba's plugin system is 2 as far as I'm aware.. And according to the docs: http://docs.villavu.com/simba/simbaref/plugins.html
@Wizzup?; Did something change that wasn't announced?


I checked the source Sin. There isn't anything wrong with the plugins exports or ABI :S Where did you get that Simba 1.00 from?


http://nala.villavu.com/downloads/master/500db9894da954a831c47d5eeedcdfeb3f0b8765/
SimbaInstaller.i386-win32.exe

Brandon

2013-08-03 21:16:17

From: Sin
http://nala.villavu.com/downloads/master/500db9894da954a831c47d5eeedcdfeb3f0b8765/
SimbaInstaller.i386-win32.exe



EDIT.. I got it to load. Check your interpreter. Apparently that Simba doesn't save any options. Well for me it doesn't. I had to change my interpreter from "nothing" to Lape. By default, neither PS nor Lape is selected.

Dgby714

2013-08-03 21:25:19

The latest API is still 2, for some reason that WriteLn is incorrect, it should say API < 2 not <=. https://github.com/MerlijnWajer/Simba/blob/500db9894da954a831c47d5eeedcdfeb3f0b8765/Units/MMLAddon/mmlpsthread.pas#L1589

From: Brandon
Wtf.. whoever changed: https://github.com/MerlijnWajer/Simba/blob/master/Units/MMLAddon/mmlpsthread.pas

Really messed it up -__-


It has nothing to do with exporting types to Lape, it was used to parse Lape's internal methods to a usable string for Code Completion.

I added it a few days ago, and it was hacky at best, and caused Lag, niels said he would write a proper dump unit for Lape soon, so I removed i

Sin

2013-08-03 21:38:47

Same thing happens still. The interpreter is on Lape.

Brandon

2013-08-03 21:53:03

From: Sin
Same thing happens still. The interpreter is on Lape.



*sigh* I recompiled the plugin. No changed made to it. Added it to the OP (GLX.zip @ the binaries tag). You can try it. If it doesn't work, then Iunno what to say because there is absolutely nothing wrong with the plugin at all and it does export exactly what it is supposed to and the ABI is 2.. I'm not sure if you're using something old or have a bad setup or what because Jingle and others have it working.. The source for the exports is here: https://github.com/Brandon-T/GLX/blob/master/GLX/Exports.cpp

The include is at: https://github.com/Brandon-T/GLX/tree/master/GLX%20-%20SRLInclude


And the ABI is just fine as shown below:

extern "C" int __declspec(dllexport) GetPluginABIVersion()
{
return 2;
}


EDIT: Organized the OP into sections. Hopefully no one should have problems finding stuff.

Sin

2013-08-03 22:29:44

From: Brandon
*sigh* I recompiled the plugin. No changed made to it. Added it to the OP (GLX.zip @ the binaries tag). You can try it. If it doesn't work, then Iunno what to say because there is absolutely nothing wrong with the plugin at all and it does export exactly what it is supposed to and the ABI is 2.. I'm not sure if you're using something old or have a bad setup or what because Jingle and others have it working.. The source for the exports is here: https://github.com/Brandon-T/GLX/blob/master/GLX/Exports.cpp

The include is at: https://github.com/Brandon-T/GLX/tree/master/GLX%20-%20SRLInclude


And the ABI is just fine as shown below:

extern "C" int __declspec(dllexport) GetPluginABIVersion()
{
return 2;
}


EDIT: Organized the OP into sections. Hopefully no one should have problems finding stuff.


Would you mind making a quick guide on how to install iy correctly?

Brandon

2013-08-03 22:42:47

From: Sin
Would you mind making a quick guide on how to install iy correctly?



https://github.com/Brandon-T/GLX/archive/master.zip

Download that. Copy GLX-SRL-Include to C:/Simba/Includes.
Rename it to GLX.

You can delete the other files. Download: http://villavu.com/forum/attachment.php?attachmentid=22027&d=1375580961

Place the plugins in C:/Simba/Plugins.

If done correctly, you can run this fishing script at Barbarian outpost or any fly-fishing spot (Barbarian village) or do w/e you like.. Atm, it only does fly-fishing and barbarian rod fishing. It's not flawless but it gets the job done for now. Kinda got other things to do.


{$DEFINE SMART}
{$include_once GLX/GLXCore.Simba}
{$include_once GLX/Misc/Map.Simba}
{$include_once GLX/Misc/Smart.Simba}
{$include_once GLX/Misc/Graphics.Simba}
{$include_once GLX/Mouse.Simba}
{$include_once GLX/Login.Simba}
{$include_once GLX/Text.Simba}
{$include_once GLX/Bank.Simba}
{$include_once GLX/Inventory.Simba}

const
MyID = 648933015; //My player ID when not fishing.
FlyFish = True; //True to flyfish, False to barbarian fish.
UseInv = False; //False to Auto detect interface setup. True to use fixed coordinates for setup.

var
T: TSmart;
Inv: Tbox = [1035, 375, 1342, 596];

Procedure MarkTime(var T: Integer);
Begin
T := GetSystemTime;
End;

Function TimeFromMark(T: Integer): Integer;
Begin
Result := GetSystemTime - T;
End;

procedure TypeByte(k: Byte);
begin
{$IFDEF SMART}
If (K = 13) then
K:= 10;
{$ENDIF}
KeyDown(k);
Wait(10 + Random(50));
KeyUp(k);
end;

procedure TypeSend(Text: string);
var
I: Integer;
begin
for i := 1 to Length(Text) do
begin
{$IFDEF SIMBAMAJOR980}
SendKeys(Text[i], 40 + Random(40));
{$ELSE}
SendKeys(Text[i], 30 + Random(30), 30 + Random(30));
{$ENDIF}
Wait(40 + Random(40));
end;
end;

Function InvBox: TBox;
Begin
If UseInv Then
Result := Inv
Else
Result := GL_InvBounds;
End;

Function InvCount: Integer;
Begin
If (Length(glGetTextures(InvBox)) < 1) Then
Result := 0
Else If (GL_BankScreen) Then
Result := Length(glGetTextures(InvBox)) - 47
Else
Result := Length(glGetTextures(InvBox)) - 37;
If (Result < 0) Then Result := 0;
End;

Function InvFull: Boolean;
Begin
Result := InvCount >= 28;
End;

Function FindFishingSpot: TPoint;
var
TPA: TPointArray;
I, X1, Y1, X2, Y2: Integer;
FishingSpots: glModelArray;
Begin
FishingSpots := glGetModels(2648051121);
//Insert(glGetModels(203893359), FishingSpots);
//Insert(glGetModels(2948843458), FishingSpots);
//Insert(glGetModels(1421135458), FishingSpots);
SetLength(TPA, Length(FishingSpots));
For I := 0 To High(FishingSpots) Do
Begin
TPA[I] := Point(FishingSpots[I].X, FishingSpots[I].Y);
End;

If (Length(TPA) > 0) Then
Begin
GLXViewPort(X1, Y1, X2, Y2);
SortTPAFrom(TPA, Point((X2 - X1) div 2, (Y2 - Y1) div 2));
If (Length(TPA) > 0) then
Result := TPA[0]
else
Result := Point(-1, -1);
End;
End;

Function HasFeathersBait: Boolean;
Begin
Result := (Length(glGetTextures(80835, 2302754, 20)) > 0) or (Length(glGetTextures(36720, 460033, 20)) > 0);
End;

Function GetFishBoxes(Area: TBox): TBoxArray;
var
I, J: Integer;
Textures: glTextureArray;
Begin
Textures := glGetTextures(Area);
SetLength(Result, Length(Textures));

For I := 0 To High(Textures) do
Begin
If ((Textures[I].ID = 49470) and SimilarColors(Textures[I].ColourID, 1118479, 5))
or ((Textures[I].ID = 45900) and SimilarColors(Textures[I].ColourID, 724234, 5))
or ((Textures[I].ID = 62220) and SimilarColors(Textures[I].ColourID, 1249296, 5))
or ((Textures[I].ID = 71145) and SimilarColors(Textures[I].ColourID, 2628634, 5))
or ((Textures[I].ID = 71145) and SimilarColors(Textures[I].ColourID, 2697256, 5))
then
begin
Result[J] := Textures[I].Bounds;
Inc(J);
end;
End;
SetLength(Result, J);
End;

Function GetFlyFishBoxes(Salmon: Boolean; Area: TBox): TBoxArray;
var
I, J: Integer;
Textures: glTextureArray;
Begin
Textures := glGetTextures(Area);
SetLength(Result, Length(Textures));

For I := 0 To High(Textures) do
Begin
If (Salmon and ((Textures[I].ID = 71145) and SimilarColors(Textures[I].ColourID, 2628634, 5))) then
begin
Result[J] := Textures[I].Bounds;
Inc(J);
end else if (Not Salmon and ((Textures[I].ID = 71145) and SimilarColors(Textures[I].ColourID, 2697256, 5))) then
begin
Result[J] := Textures[I].Bounds;
Inc(J);
end;
End;
SetLength(Result, J);
End;

Procedure DropAll;
var
I, T: Integer;
Fish: TBoxArray;
Begin
MarkTime(T);
While(True) Do
Begin
Fish := [];
Fish := GetFishBoxes(InvBox);
If (Length(Fish) < 1) or (TimeFromMark(T) > 20000) Then Exit;

For I := 0 To High(Fish) Do
Begin
MouseBox(Fish[I], MOUSE_RIGHT);
GL_ChooseOptionMulti(['Drop', 'rop', 'Dro']);
End;
End;
End;

Procedure DropFlyFish;
var
I, T: Integer;
Salmon, Trout: TBoxArray;
Begin
MarkTime(T);
While(True) Do
Begin
//Salmon := glGetTextures(58905, 2628634, 5, IntToBox(51, 39, 84, 69));
//Trout := glGetTextures(58905, 2697256, 5, IntToBox(87, 39, 121, 70));

Salmon := GetFlyFishBoxes(True, InvBox);
Trout := GetFlyFishBoxes(False, InvBox);
If ((Length(Salmon) < 1) and (Length(Trout) < 1) or (TimeFromMark(T) > 20000)) Then Exit;

For I := 0 To High(Salmon) Do
Begin
TypeSend('1');
wait(50);
End;

For I := 0 To High(Trout) Do
Begin
TypeSend('2');
wait(50);
End;
End;
End;

function WaitFindModel(ID: Cardinal; WaitPerLoop, MaxTime: Integer): Boolean;
var
T: Integer;
begin
T := GetSystemTime + MaxTime;
while (GetSystemTime < T) do
begin
if (Length(glGetModels(ID)) < 1) then
begin
Result := True;
Exit;
end;
Wait(WaitPerLoop);
end;
end;

Procedure MainLoop;
var
P: TPoint;
MeBox, AnimBox: TBox;
X1, Y1, X2, Y2: Integer;
Begin
GLXViewPort(X1, Y1, X2, Y2);
MeBox := IntToBox(637, 291, 716, 367);
AnimBox := IntToBox(MeBox.X1 + 10, MeBox.Y1 + 10, MeBox.X2 - 10, MeBox.Y2 - 10);

While(True) Do
Begin
ClearDebug;
If (Length(GL_GetMouseUpText) > 0) Then
Mouse(RandomRange(867, 354), RandomRange(1041, 534), 0, 0);

If (InvCount >= 27) Then
Begin
writeln('Dropping Fish.');
while(Length(glGetTextures(183600, 6639632, 10, IntToBox(192, 611, 316, 644))) > 0) do
begin
TypeByte(32);
Wait(100);
end;
If (Not FlyFish) then
DropAll
Else
DropFlyFish;
End;

If (Not HasFeathersBait) Then
Begin
writeln('Ran Out Of Feathers/Bait.');
Exit;
End;

while(Length(glGetModels(MyID, MeBox)) < 1) do
begin
Wait(1000);
ClearDebug;
writeln('Fishing..');
end;

P := FindFishingSpot;
writeln('Found Fishing Spot: ' + ToStr(P));
If (P.X > 0 and P.Y > 0) Then
Begin
Mouse(P, 5, 5, MOUSE_RIGHT);
GL_ChooseOptionMulti(['Use-rod Fishing spot', 'Use-rod', 'rod Fishing spot', 'Lure Fish', 'Lure Fishing spot']);
WaitFindModel(MyID, 50, 3500);
End;
End;
End;

begin
ClearDebug;
T.Create(1350, 650, '', ['OpenGL32.dll']);
GLXMapHooks(T.CurrentClient);
glDebug(GL_MODE_MODELS, 0, 0, 0, T.Width, T.Height);
T.GetGraphics().Clear;
//writeln(glGetModels(IntToBox(624, 303, 695, 338)));

MainLoop;
TerminateScript();
end.

Le Jingle

2013-08-03 22:47:15

From: Sin
Would you mind making a quick guide on how to install iy correctly?


It's not too bad, I can't think what else you do besides:
1. http://l0.lt (latest simba builds),
2. install simba,
3. download the gLX zip / src and compile, place libraries into the plugins folder,
4. download ben's 8.2 stable SMART jar / src and compile, place into the plugins folder.
<< 5. don't forget to load RS in OpenGL mode prior, so OGL is default
<< 6. don't forget to use lape (should be default in the later builds)

other than that, it's just the includes left, and I believe Brandon also posted a test script too.

I duno, maybe I forgot something obv, but it indeed works, and works wonders at that! :) Thanks again Brandon! Hopefully this might save you some time with your awesome description posts :p

Cheers,
Le Jingle

edit : sniped -.-

edit2: I think ben's git is updated to a new SMART that has new loading args/params so maybe not that noose bleed, but the one from his post? (or I suppose I haven't looked either to see if brandon somehow already updated to that (though I think ben just mentioned this update of his to SMART a few hours ago), but I'm guessing not since I've loaded the new src with the same smart args, in the old SMART)
So to keep it short, prob try the posted SMART before compiling his src from git.

Sin

2013-08-03 22:52:27

Did that, and now this occurs: Exception in Script: File "GLX/Misc/Graphics.Simba" not found at line 2, column 16 in file "C:\Simba\Includes\GLHook\Misc\Smart.Simba"

Brandon

2013-08-03 22:56:27

From: Sin
Did that, and now this occurs: Exception in Script: File "GLX/Misc/Graphics.Simba" not found at line 2, column 16 in file "C:\Simba\Includes\GLHook\Misc\Smart.Simba"


You're running a bad script or you're messing something up. You're mixing the old RS2 include with the RS3 include.. I gave you the right links on my previous post :l


@Sin;
EDIT.. For the guys having a painful time or lazy.. I uploaded my setup here:
http://www.mediafire.com/download/ofwlxx09rs27a9e/Setup.zip

Added to OP.. Not sure why everyone has a hard time installing it :S

Sin

2013-08-03 23:08:39

Thanks for all the hard work <3

Edit:
@Brandon I don't want to bot in SMART, but rather on the browser/desktop client.
After removing DefineSmart and loading RS in OpenGL, i added this line: GLHSetup(ToStr(T.CurrentClient)

In theory it should work right?


Edit2:
NVM about the last thing, I said fk it and will probably just bot on SMART. Thing is, I can't load SMART into OGL mode. It always defaults to SafeMode and wont allow me to change.

Brandon

2013-08-04 01:16:14

From: Sin
Thanks for all the hard work <3

Edit:
@Brandon I don't want to bot in SMART, but rather on the browser/desktop client.
After removing DefineSmart and loading RS in OpenGL, i added this line: GLHSetup(ToStr(T.CurrentClient)

In theory it should work right?


Edit2:
NVM about the last thing, I said fk it and will probably just bot on SMART. Thing is, I can't load SMART into OGL mode. It always defaults to SafeMode and wont allow me to change.



You can load it in the browser by simply doing GLXSetup(PIDOfBrowserHere);

If you still want to load it in Smart, then you need to make sure that JRE is before JDK in your path.

Ex:

C:\Program Files\Diskeeper Corporation\ExpressCache\;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\2.0\bin\x64;C:\Program Files (x86)\Java\jdk1.7.0_25\jre\bin


Notice that the path has jre\bin.. After that, you can add a jdk\bin if you like.

Sin

2013-08-04 01:25:38

From: Brandon
You can load it in the browser by simply doing GLXSetup(PIDOfBrowserHere);

If you still want to load it in Smart, then you need to make sure that JRE is before JDK in your path.

Ex:



Notice that the path has jre\bin.. After that, you can add a jdk\bin if you like.


Im not sure what you mean on the jre part :s
This is my jdk folder, what changes do I have to make?

http://puu.sh/3ThKD.png

Brandon

2013-08-04 01:43:05

From: Sin
Im not sure what you mean on the jre part :s
This is my jdk folder, what changes do I have to make?

http://puu.sh/3ThKD.png



Just add: C:/Program Files/Java/jdk1.7.0_25/jre/bin to the beginning of your PATH environment variable.

Sin

2013-08-04 01:48:08

From: Brandon
Just add: C:/Program Files/Java/jdk1.7.0_25/jre/bin to the beginning of your PATH environment variable.


Did that and still no dice :(

DemiseScythe

2013-08-04 18:39:35

From: Sin
Did that and still no dice :(


Search your computer for Preferences.dat and Preferences2.dat, might have multiple copies and/or Preference3.dat

Delete these files, load RS on SMART, change to OGL mode and close the graphic settings window back to logon screen, then close SMART. Next time SMART loads, it will load the newly formed Preferences.dat

PS. Not sure if the s is in there at the end, might just be Preference.dat and Preference2.dat

This fixed this issue for me.

Le Jingle

2013-08-04 18:40:04

If anyone needs help with the setup, I can attempt to help out via TeamViewer (send private message here on forums, or Fratello on rizon IRC).

I can't guarantee anything, but I will indeed try.
(Also make sure you have enough allotted time if/when TV happens, so no immediate "rushing to get done" etc.)

Cheers,
Le Jingle.

Sin

2013-08-05 13:09:13

From: DemiseScythe
Search your computer for Preferences.dat and Preferences2.dat, might have multiple copies and/or Preference3.dat

Delete these files, load RS on SMART, change to OGL mode and close the graphic settings window back to logon screen, then close SMART. Next time SMART loads, it will load the newly formed Preferences.dat

PS. Not sure if the s is in there at the end, might just be Preference.dat and Preference2.dat

This fixed this issue for me.


Okay so I deleted all instances of preferences/2.dat, when I load SMART it says it wants to autosetup. Once I click autosetup it automatically goes to Safe mode and wont allow me to change :/

DemiseScythe

2013-08-05 13:28:26

From: Sin
Okay so I deleted all instances of preferences/2.dat, when I load SMART it says it wants to autosetup. Once I click autosetup it automatically goes to Safe mode and wont allow me to change :/


If it does that, it obviously thinks your gpu sucks too much to run OGL or DX, mine goes into DX mode on autosetup, then change to OGL and done. What gpu do you have? Ever been in OGL mode before? Try updating your drivers.

Sin

2013-08-05 13:42:12

From: DemiseScythe
If it does that, it obviously thinks your gpu sucks too much to run OGL or DX, mine goes into DX mode on autosetup, then change to OGL and done. What gpu do you have? Ever been in OGL mode before? Try updating your drivers.


Radeon HD 7770, reference version is XFX.
Drivers are all upto date :s

I've gone on OGL, yes, on the webclient it auto setups me to DirectX max settings >_<

Brandon

2013-08-05 13:51:36

Solved via IRC. He's using the new Smart now. :)

Ragging

2013-08-07 16:55:57

Keep getting this: Exception in Script: Unknown declaration "Client" at line 40, column 19 in file "C:\Simba\Includes\GLX\Misc\Graphics.Simba"

Brandon

2013-08-07 23:57:30

From: Ragging
Keep getting this: Exception in Script: Unknown declaration "Client" at line 40, column 19 in file "C:\Simba\Includes\GLX\Misc\Graphics.Simba"


Update your Simba: http://nala.villavu.com/downloads/master/500db9894da954a831c47d5eeedcdfeb3f0b8765/

NKN

2013-08-08 00:43:24

@Brandon
Edit: ignore all that

Paired with SMART[4328]
Exception in Script: Runtime error: "Access violation" at line 10, column 11
The following bitmaps were not freed: [0]



^That one?
{$DEFINE SMART8}
{$include GLX/GLXCore.Simba}
{$include GLX/Misc/Smart.Simba}


var
T: TSmart;
begin
T.Create(1350, 650, '', ['OpenGL32.dll']);
glxdebug(2,0,0,0,T.Width,T.Height);
T.GetGraphics().Clear;
end.

Brandon

2013-08-08 01:24:09

From: NKN
@Brandon
Edit: ignore all that


You can't expect to ask the plugin to draw without first telling it what to draw or do anything without first telling it which Smart/Browser/Applet to hook.


{$include GLX/GLXCore.Simba}
{$include GLX/Misc/Smart.Simba}


var
T: TSmart;
begin
T.Create(1350, 650, '', ['OpenGL32.dll']);
glXMapHooks(T.ID); //You must tell it which Smart to hook for now.
glDebug(GL_MODE_TEXTURES, 0, 0, 0, T.Width, T.Height); //Use the functions in the include. It's easier. Though you were right anyway.
T.GetGraphics().Clear;
TerminateScript; //For lape since it doesn't have AddOnTerminate yet.
end.

xtrapsp

2013-08-14 11:11:13

I feel stupid for asking these kind of questions, but the whole reflection/OpenGL etc side of Botting is new to me.

I went into the options for OPENGL In RS and it says I can't


JhzBlanco

2013-08-17 18:38:12

I'm sorry in advanced for my noobie question but I am new to simba.
I dropped the GLX and gl hook in includes, and the plugins into plugins, thats it right? Nothing else?
Also, after I've done this, how can I make a script compatible with rs3? Will it need work or can I just go ahead and run?
Again, I'm very sorry for my noobiness but I'm new.

DemiseScythe

2013-08-17 19:22:59

From: JhzBlanco
I'm sorry in advanced for my noobie question but I am new to simba.
I dropped the GLX and gl hook in includes, and the plugins into plugins, thats it right? Nothing else?
Also, after I've done this, how can I make a script compatible with rs3? Will it need work or can I just go ahead and run?
Again, I'm very sorry for my noobiness but I'm new.


You need to rewrite it entirely. The OGL functions work differently from SRL functions and even have different names. If you have a script, it is most likely RS2+Pascal Script. OGL is Lape based so right there, you have some compatibility issues.

Replicating the functions is not hard if you know what you are doing. I rewrote a 2.5k line script in a couple days to work with OGL/RS3. You just need to learn some scripting.

From: xtrapsp
I feel stupid for asking these kind of questions, but the whole reflection/OpenGL etc side of Botting is new to me.

I went into the options for OPENGL In RS and it says I can't



Find Preference.dat and Preference2.dat and delete them from your Disk. You might have multiple copies so search for the files. Also make sure you have only 32-bit Java 7 installed. JRE version, if you have the JDK, you need to add JRE to your path, google can help with that. If you do that, you should be able to switch into OGL mode.

JhzBlanco

2013-08-17 20:01:48

I don't know how to script :/
are there any scripts atm? meanwhile I do hours of research to learn how to code? :/

Brandon

2013-08-17 20:33:00

Anyone unable to get into OpenGL/DirectX modes and don't know how to modify the path or having problems doing it then simply read:

http://villavu.com/forum/showthread.php?t=105462&p=1262087#post1262087

Otherwise just compile the dev Smart yourself if you wish or modify the path properly. Scripting for OpenGL is the same as any other methods of scripting. So once you can script with colour, you can script with OpenGL. There is no specific tutorials because they're unnecessary.. The functions are named the same as their colour counterparts..

The include for the new smart is already done..

Smart.Simba (Line 46): https://github.com/Brandon-T/SRL-GLX/blob/master/Misc/Smart.simba

If you still use the old/current Smart then: https://github.com/Brandon-T/SRL-GLX/blob/master/Misc/Smart8API.simba

Either way.. I shouldn't really hear many problems about loading or anything once Smart is released itself because the include already works with it and I've been using it from the very first day. If your Smart cannot get into OpenGL mode normally (WITHOUT the plugin) then you won't get into OpenGL mode WITH the plugin..

JhzBlanco

2013-08-18 00:34:58

Brandon, are you aware of any scripts that are working for rs3 with this?
It would really help(:
I intend on learning how to script but I would like to bot while I learn :P

DemiseScythe

2013-08-18 01:02:09

Somewhere in this thread, he has posted a fishing script, why don't you give it a try?

Wizzup?

2013-08-19 12:06:59

From: Dgby714
The latest API is still 2, for some reason that WriteLn is incorrect, it should say API < 2 not <=. https://github.com/MerlijnWajer/Simba/blob/500db9894da954a831c47d5eeedcdfeb3f0b8765/Units/MMLAddon/mmlpsthread.pas#L1589


Has this been fixed yet? ;)

Dgby714

2013-08-19 12:25:55

From: Wizzup?
Has this been fixed yet? ;)


No >..>, One sec…

JhzBlanco

2013-08-20 18:32:06

Exception in Script: Plugin(GLX32) has not been found
I got that while trying to run Brandon's barb fishing script, any help please?

Amaranth79

2013-09-08 17:07:57

are the model coordinates supposed to be on screen coordinates or in world? either way they seem to be off for me as they jump around depending on where the camera is and how far zoomed in you are

Brandon

2013-09-08 18:49:21

From: Amaranth79
are the model coordinates supposed to be on screen coordinates or in world? either way they seem to be off for me as they jump around depending on where the camera is and how far zoomed in you are



This does not explain anything to me. I don't know what you mean by "jump around". Coordinates are projected from world coordinates to your screen. It does not project based on your camera or your RS setup. It projects based on the matrices passed to the GFX.

I'm fairly certain it is projected right as it just uses gluUnProject (isn't done manually). I'm botting divination using the include so it can't be off :S Only models that fly are a bit off because their height is on a different tile.

Unless you mean something else. In that case, care to elaborate more?

Amaranth79

2013-09-08 20:22:23

well i'm trying to identity the bank booth models (or npc, or some way of depositing), so i tried iterating through glGetModels(), and drawing the ID over the model.
//T is my TSmart instance
glModels := glGetModels();
numModels := high(glModels);
for i:=0 to numModels do
begin
t.getgraphics().DrawClippedText(inttostr(glModels.id), 'FriendChars', Point(glModels.x, glModels.y));
end;
but for whatever reason, the labels dont seem to match up with any object.
[ATTACH=CONFIG]22183[/ATTACH][ATTACH=CONFIG]22184[/ATTACH]

Brandon

2013-09-08 20:25:09

From: Amaranth79
well i'm trying to identity the bank booth models (or npc, or some way of depositing), so i tried iterating through glGetModels(), and drawing the ID over the model.




There is a function for that.


glDebug(GL_MODE_MODELS, 0, 0, 0, T.Width, T.Height); //where T is your TSmart instance.

If it is still off, then you must have done 3D-world editing. Try another preset and let me know if it fixes it.

Amaranth79

2013-09-08 20:37:39

gldebug is supposed to label all the models? (or textures etc depending on the first parameter?)
also does running a 64bit OS make any difference?

edit: gldebug(…) only works after calling glxViewPort()

further edit: fixed my problem, the coordinates are right if the 3d game window takes up the full view port (ie glxViewport returns an 800x600 window, so it works in classic layout where the 3D component is 800x600.

rj

2013-09-08 20:40:28

@Brandon Does the LocationPoint to MM take the compass angle into account?

Also a lot of the github links are broken :(

Brandon

2013-09-08 21:42:46

From: Amaranth79
gldebug is supposed to label all the models? (or textures etc depending on the first parameter?)
also does running a 64bit OS make any difference?

edit: gldebug(…) only works after calling glxViewPort()

further edit: fixed my problem, the coordinates are right if the 3d game window takes up the full view port (ie glxViewport returns an 800x600 window, so it works in classic layout where the 3D component is 800x600.


Your plugins must be old. You shouldn't have to do anything with the viewport to get rendering to work. And yeah I'm aware that it messes up in that 800x600 Viewport. However, since everything is auto-detected any way, it shouldn't have a problem working in any other layout other than Oldschool. I could fix it but it's just as easy to re-arrange another layout.

I will fix it eventually but I got other things I'm working on. Not to mention I gotta finish the include.


From: Officer Barbrady
@Brandon Does the LocationPoint to MM take the compass angle into account?

Also a lot of the github links are broken :(



No it does not. If you're talking about the walking thing on the OP (LocalPosToMM)? I had partial walking working but Iunno where I put it. It was SPS-like where I ran around all of runescape saving the maps. Either way, that would be the only thing needed to get walking working.. Maps.. But again, to answer your question, it doesn't take angle into account because the algorithm gives your position regardless of whether the map is rotated or not. Only thing you need to do is convert that to a point on the MM and that will definitely need to take angle into account.

I updated the OP.. I was aware the links were broken because I removed them all and I changed everything on my Github..

rj

2013-09-08 21:58:54

From: Brandon
too long


Thanks, I looked at the reflection TileToMM and I think this should work (assuming every 4 pixels on the minimap = 1 tile.. this may have to be ajusted, also is MMCX and MMCY is the direct center of the minimap AKA were the player square is located right?)


99.99% Benlands. (I named the function therfor get .001% credit tee hee)


function GLX_TileToMM(Tile:TPoint):TPoint;
var
Location:TPoint;
angle, tileX, tileY:Extended;
begin
angle := GL_CompassRad;
Location := GetLocalPos;
tileX := ((Tile.x - Location.x) * 4);
tileY := ((Location.y - Tile.y) * 4);
result.x := round(tileX *cos(angle) + tileY*sin(angle)) + MMCX;
result.y := round(tileY*cos(angle) - tileX*sin(angle)) + MMCY;
end;

then ofc walking would be easy
function walkTile(Point:TPoint):boolean
var
pnt:TPoint;
begin
pnt := GLX_TileToMM(Point);
Mouse(pnt.x, pnt.y, 2, 2);
wait(random(200) + 250);
result := FlagPresent;
while (FlagPresent) do
wait(random(50) + 25);
end;

Brandon

2013-09-08 23:11:13

From: Officer Barbrady
Thanks, I looked at the reflection TileToMM and I think this should work (assuming every 4 pixels on the minimap = 1 tile.. this may have to be ajusted, also is MMCX and MMCY is the direct center of the minimap AKA were the player square is located right?)


99.99% Benlands. (I named the function therfor get .001% credit tee hee)


function GLX_TileToMM(Tile:TPoint):TPoint;
var
Location:TPoint;
angle, tileX, tileY:Extended;
begin
angle := GL_CompassRad;
Location := GetLocalPos;
tileX := ((Tile.x - Location.x) * 4);
tileY := ((Location.y - Tile.y) * 4);
result.x := round(tileX *cos(angle) + tileY*sin(angle)) + MMCX;
result.y := round(tileY*cos(angle) - tileX*sin(angle)) + MMCY;
end;

then ofc walking would be easy
function walkTile(Point:TPoint):boolean
var
pnt:TPoint;
begin
pnt := GLX_TileToMM(Point);
Mouse(pnt.x, pnt.y, 2, 2);
wait(random(200) + 250);
result := FlagPresent;
while (FlagPresent) do
wait(random(50) + 25);
end;




Uhh that will never work. Well I tested it and the point is not even close the to MM.. It's far off. Isn't that algorithm for OSRS?

My math skills isn't all that great anymore but I managed to come up with:


Function MSToMM(P: TPoint): TPoint;
var
MMBounds: TBox;
X1, Y1, X2, Y2: Integer;
TL, BL, BR, TR: FloatPoint;
W, H, DX, DY, RatioX, RatioY, Angle: Extended;
begin
MMBounds := GL_MMBounds;
GLXViewPort(X1, Y1, X2, Y2); //Should really use player location but this works well enough.
W := X2 - X1; H := Y2 - Y1;
RatioX := W / MMBounds.Width;
RatioY := H / MMBounds.Height;

DX := (P.X - (W / 2));
DY := (P.Y - (H / 2));
DX := DX / RatioX;
DY := DY / RatioY;

P.X := MMBounds.MidPoint.X;
P.Y := MMBounds.MidPoint.Y;

GL_GetMapCoords(TL, BL, BR, TR);
Angle := FixRad(ArcTan2(TR.Y - TL.Y, TR.X - TL.X));
Result.X := Round(P.X + DX);
Result.Y := Round(P.Y + DY);
Result := RotatePoint(Result, Angle, P.X, P.Y);
//Result.X := Result.X + (MMBounds.Width div 256); //Needed if the minimap is HUGE.
//Result.Y := Result.Y - (MMBounds.Height div 64); //Needed if the minimap is HUGE.
end;

which works pretty well.

riwu

2013-09-10 08:25:25

@Brandon
Is it possible to add a Bounds field to the glModel record (like glTexture)? The Bounds would be the maximum rectangular bound of the model in which it is completely filled, so that instead of clicking on the model's x,y with an arbitrary rx, ry randomness, we can simply click the Bounds
.
Or overload glGetModels to have one that can retrieve all points of the model (so that we can manipulate the points for our desired intent)

Amaranth79

2013-09-11 03:49:28

what about the world space coordinates? could that possibly be used for getting the users global location (assuming you know your model ID)

Brandon

2013-09-11 08:03:06

Bounds clicking is possible but I removed it. There was a function that gets vertices for every model and allowed you to click whichever one you wanted.. However, I got complaints about lag from ppl with old and crappy computers, and so I removed it..

For world space coordinates. OpenGL knows no such thing and there is no way to get it without doing some hacky stuff. Only way to actually get it normally would be to create SPS for OpenGL.

riwu

2013-09-11 08:31:29

From: Brandon
Bounds clicking is possible but I removed it. There was a function that gets vertices for every model and allowed you to click whichever one you wanted.. However, I got complaints about lag from ppl with old and crappy computers, and so I removed it..

For world space coordinates. OpenGL knows no such thing and there is no way to get it without doing some hacky stuff. Only way to actually get it normally would be to create SPS for OpenGL.

Make it such that the points are only retrieved if you pass a boolean arg to the function? So ppl with latency problems can simply ignore the TPA field of glModel.

Also can u get on irc chat? i'm facing a strange problem with glGetChars() atm in which Simba would beep 4 times and the result would be like half way break off:

[{TEXTUREID = 16777215, COLOUR = 281, X = 182, Y = 85, LETTER =


EDIT: found the problem @ https://github.com/Brandon-T/SRL-GLX/commit/106259badf3e4eb94b8f905fb87d4bb10e990e56#GLXCore.simba

Brandon

2013-09-11 11:10:21

From: riwu
Make it such that the points are only retrieved if you pass a boolean arg to the function? So ppl with latency problems can simply ignore the TPA field of glModel.

Also can u get on irc chat? i'm facing a strange problem with glGetChars() atm in which Simba would beep 4 times and the result would be like half way break off:

[{TEXTUREID = 16777215, COLOUR = 281, X = 182, Y = 85, LETTER =


EDIT: found the problem @ https://github.com/Brandon-T/SRL-GLX/commit/106259badf3e4eb94b8f905fb87d4bb10e990e56#GLXCore.simba



This was already fixed: https://github.com/Brandon-T/SRL-GLX/commit/55dc34ec7b9ece09a9b3c41e304b6f8ff35c2324

I'll see if I can add the Model TPA's.. I even wrote it in assembly but apparently it was still slow for them so.. I will have to test lots and see how it goes..

Amaranth79

2013-09-11 17:47:48

would it not be possible to use something along the lines of glProject(…) to get the user location? or using the camera location and pitch/yaw/etc to figure out a lookat coordinate?

Brandon

2013-09-11 18:52:38

From: Amaranth79
would it not be possible to use something along the lines of glProject(…) to get the user location? or using the camera location and pitch/yaw/etc to figure out a lookat coordinate?


Doesn't work like that. It's be difficult for me to explain it but I think I wrote like 2 tutorials somewhere around here that explains a lot.
If you really want me to explain it then I don't mind.. Can also ask Kasi if you wish. I doubt he'd mind.

riwu

2013-09-12 06:08:41

From: Brandon
This was already fixed: https://github.com/Brandon-T/SRL-GLX/commit/55dc34ec7b9ece09a9b3c41e304b6f8ff35c2324

I'll see if I can add the Model TPA's.. I even wrote it in assembly but apparently it was still slow for them so.. I will have to test lots and see how it goes..

You fixed only Function glGetChars(Area: TBox): glCharArray; overload;
I was still having problem calling Function glGetChars: glCharArray;

Is the x,y fields of the glModel the center point of the model? Also what exactly is the ColourID field of glTexture? Are the ColourIDs different for 2 textures as long as they are not completely identical in color?

Kasi

2013-09-12 06:22:11

From: riwu
You fixed only Function glGetChars(Area: TBox): glCharArray; overload;
I was still having problem calling Function glGetChars: glCharArray;

Is the x,y fields of the glModel the center point of the model? Also what exactly is the ColourID field of glTexture? Are the ColourIDs different for 2 textures as long as they are not completely identical in color?


The ColourID is a checksum / average of the texture.

riwu

2013-09-21 05:50:51


glGetChars() couldnt get the amount (706). Not a big deal since i can just use color to get the amount, though does turning on color capture make a significant difference in resource used/performance?

Also the texture ID of the item changes when the amount increases (intervals at 1-9, 10-99, 100-499, 500>), which suggests that the amount is part of the texture?

Kasi

2013-09-21 11:38:30

From: riwu

glGetChars() couldnt get the amount (706). Not a big deal since i can just use color to get the amount, though does turning on color capture make a significant difference in resource used/performance?

Also the texture ID of the item changes when the amount increases (intervals at 1-9, 10-99, 100-499, 500>), which suggests that the amount is part of the texture?



glDebug(GL_MODE_FONTS, 0, 0, 0, S.Width, S.Height);

call that after your SetupGLX. replace S with the first parameter of SetupGLX. if it shows text then your doing something wrong.

The FullColourID(TextureID) changes because the FullColourID is a average of the entire texture, Text included. if you wanna get a stable FullColourID on stacks use ColourID. This is an average for the entire Texture minus the top 12 lines where the text is. both are as stable as each other. Originally all textures were clipped (the top 12 rows of pixels). however some of the smaller textures weren't feasible to this sort of check-sum so i ask brandon to change it.

Edit: mixed up variables :P

Brandon

2013-09-21 11:50:39

From: riwu

glGetChars() couldnt get the amount (706). Not a big deal since i can just use color to get the amount, though does turning on color capture make a significant difference in resource used/performance?

Also the texture ID of the item changes when the amount increases (intervals at 1-9, 10-99, 100-499, 500>), which suggests that the amount is part of the texture?



I turned off colour by default but yes you can easily turn it on using the function. It decreases FPS by 3-5 which is why I had it off. What decreases FPS most if actually fonts. Then again, OpenGL on windows is already slow and for Windows, DirectX is where it's really at. No colour capture does not increase resource usage because the buffer is already created when the plugin loads (created by Smart/browser). If you really care about 3-5 FPS, then you can just flick it on, read your colours, flick it off.

The way jagex does the textures are actually really stupid. It pissed me off lol. What happens is that every frame, a brand new texture is generated and if the amount changes, the server sends a texture with that amount already written into it. There actually is no way to remove the text and then hash/checksum it. The text is part of the texture.

You can view the post I made a year ago here: http://www.gamedeception.net/index.php?threads/hooking-shaders.25217/
that explains the problem and the possible solutions using a Fuzzy-Hash algorithm.


Thus, there are two checksums you can use:


type glTexture = record
ID: Integer;
ColourID: Integer; //Skip the first 12 lines where the numbers are.
FullColourID: Integer; //Checksum of the entire texture with/without numbers.
X, Y: Integer;
Bounds: TBox;
end;

riwu

2013-09-21 22:27:32

From: Brandon
I turned off colour by default but yes you can easily turn it on using the function. It decreases FPS by 3-5 which is why I had it off. What decreases FPS most if actually fonts. Then again, OpenGL on windows is already slow and for Windows, DirectX is where it's really at. No colour capture does not increase resource usage because the buffer is already created when the plugin loads (created by Smart/browser). If you really care about 3-5 FPS, then you can just flick it on, read your colours, flick it off.

The way jagex does the textures are actually really stupid. It pissed me off lol. What happens is that every frame, a brand new texture is generated and if the amount changes, the server sends a texture with that amount already written into it. There actually is no way to remove the text and then hash/checksum it. The text is part of the texture.

You can view the post I made a year ago here: http://www.gamedeception.net/index.php?threads/hooking-shaders.25217/
that explains the problem and the possible solutions using a Fuzzy-Hash algorithm.


Thus, there are two checksums you can use:


type glTexture = record
ID: Integer;
ColourID: Integer; //Skip the first 12 lines where the numbers are.
FullColourID: Integer; //Checksum of the entire texture with/without numbers.
X, Y: Integer;
Bounds: TBox;
end;

3-5 FPS is pretty significant, meh even if its 1 FPS it's still worth that extra few lines of code.

function FindColors(var TPA: TPointArray; Color, x1, y1, x2, y2: Integer): Boolean; override;
begin
GLXSetColourCapture(True);
Result:= Inherited(TPA, Color, x1, y1, x2, y2);
GLXSetColourCapture(False);
end;

If fonts decreases so much FPS is it possible to disable it and only enable it in the glGetChars() function? (like what i did above)



So the reason why i can't get the chars is because the amount is part of textures rather than fonts?



Also i assume the 12 lines are cutting off vertically? (like from Bounds.Y1 to Bounds.Y1 + 12)
Kind of strange that the 2 quantities below have different COLOURID then.


[{ID = 79305, COLOURID = 5258007, FULLCOLOURID = 1120531, X = 27, Y = 151, BOUNDS = {X1 = 9, Y1 = 135, X2 = 45, Y2 = 167}}]

[{ID = 71145, COLOURID = 5652248, FULLCOLOURID = 988946, X = 27, Y = 151, BOUNDS = {X1 = 9, Y1 = 135, X2 = 45, Y2 = 167}}]

Kasi

2013-09-21 22:32:32

From: riwu
3-5 FPS is pretty significant, meh even if its 1 FPS it's still worth that extra few lines of code.

function FindColors(var TPA: TPointArray; Color, x1, y1, x2, y2: Integer): Boolean; override;
begin
GLXSetColourCapture(True);
Result:= Inherited(TPA, Color, x1, y1, x2, y2);
GLXSetColourCapture(False);
end;

not exactly like you did. interpreter wouldn't be able to tell which FindColors function to use as they both have the exact same parameters. you could change the parameters by putting an extra boolean in or integer or do something to change the parameters. colour capture doesnt really affect fps all that much. its a few frames. i dont see why you should really care - botting doesn't really require high fps rate. i would enable it and leave it enabled.

riwu

2013-09-21 22:44:29

From: Kasi
not exactly like you did. interpreter wouldn't be able to tell which FindColors function to use as they both have the exact same parameters. you could change the parameters by putting an extra boolean in or integer or do something to change the parameters. colour capture doesnt really affect fps all that much. its a few frames. i dont see why you should really care - botting doesn't really require high fps rate. i would enable it and leave it enabled.

The interpreter will call the overridden one, which is also the one nearest (order of methods does matter in Pascal)
(before anyone flame me about using override for static scope etc, see nielsie's overridden antiban methods here: http://villavu.com/forum/showthread.php?t=79317 :p)

I'm making some scripts that will be doing clicking while the player is running (make it more human-like and efficient), so the better FPS the better the chance of it clicking accurately.

Brandon

2013-09-21 23:14:09

From: riwu
3-5 FPS is pretty significant, meh even if its 1 FPS it's still worth that extra few lines of code.
If fonts decreases so much FPS is it possible to disable it and only enable it in the glGetChars() function? (like what i did above)
So the reason why i can't get the chars is because the amount is part of textures rather than fonts?

Also i assume the 12 lines are cutting off vertically? (like from Bounds.Y1 to Bounds.Y1 + 12)
Kind of strange that the 2 quantities below have different COLOURID then.


[{ID = 79305, COLOURID = 5258007, FULLCOLOURID = 1120531, X = 27, Y = 151, BOUNDS = {X1 = 9, Y1 = 135, X2 = 45, Y2 = 167}}]

[{ID = 71145, COLOURID = 5652248, FULLCOLOURID = 988946, X = 27, Y = 151, BOUNDS = {X1 = 9, Y1 = 135, X2 = 45, Y2 = 167}}]



Looking at those two pictures with my eyes alone, I am going to take a wild guess and say that they are not the same texture?

However, I just looked into it and the first texture:

and the second:

So according to the plugin and analysis of the textures, they are actually indeed rendered as two different textures. Notice that the second is fatter than the first and a completely different shape. Also notice the GenericID which is the "Jagex" ID for these textures are completely different. However, the colours are pretty much the same actually:


writeln(SimilarColors(5258007, 5652248, 8)); //tolerance of 8. This is actually how the function does it as well.

The first is: 661 and the second is: 449.
Thus jagex is drawing it like:

if (Amount < 1000) then
begin
glBindTexture(GL_TEXTURE_RECTANGLE, 661); //GenericID given to the texture by Jagex.
end else
glBindTexture(GL_TEXTURE_RECTANGLE, 449); //GenericID given to the second texture by Jagex.

glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 36, 32, 0, GL_UNSIGNED_BYTE, 0, Pointer_To_Texture_Pixels);

Seeing as this has happened to me before, the function which was actually invented by @DemiseScythe; to counter such a thing and make searching easier and just as efficient (same speed), you can do:

glGetTextures([FirstID, SecondID], [FirstColourID, SecondColourID], [FirstTolerance, SecondTolerance]);

And it doesn't stop there because it takes arrays so you can search for an infinite amount of textures at once. You should also NOT worry about different "ColourIDs" because no matter what, even when ColourIDs change, it will still find the item. For example, differentiating between a clean dwarfweed and a clean torstol can be done easily and only would need updating if there was a completely graphic overhaul to the herbs.


Fonts:
Yes it is actually possible for me to disable anything in the plugin or export a function to do such things. Whether it be fonts, colours, rendering, etc.. Can also enable things like white-walls, wire-frame mode, etc..

So yeah, the plugin isn't actually broken. I thought it was for a sec but after checking again, it isn't. It's just the way jagex draws stuff.

riwu

2013-09-22 00:13:43

From: Brandon
Looking at those two pictures with my eyes alone, I am going to take a wild guess and say that they are not the same texture?

However, I just looked into it and the first texture:

and the second:

So according to the plugin and analysis of the textures, they are actually indeed rendered as two different textures. Notice that the second is fatter than the first and a completely different shape. Also notice the GenericID which is the "Jagex" ID for these textures are completely different. However, the colours are pretty much the same actually:


writeln(SimilarColors(5258007, 5652248, 8)); //tolerance of 8. This is actually how the function does it as well.

The first is: 661 and the second is: 449.
Thus jagex is drawing it like:

if (Amount < 1000) then
begin
glBindTexture(GL_TEXTURE_RECTANGLE, 661); //GenericID given to the texture by Jagex.
end else
glBindTexture(GL_TEXTURE_RECTANGLE, 449); //GenericID given to the second texture by Jagex.

glTexImage2D(GL_TEXTURE_RECTANGLE, 0, GL_RGBA, 36, 32, 0, GL_UNSIGNED_BYTE, 0, Pointer_To_Texture_Pixels);

Seeing as this has happened to me before, the function which was actually invented by @DemiseScythe; to counter such a thing and make searching easier and just as efficient (same speed), you can do:

glGetTextures([FirstID, SecondID], [FirstColourID, SecondColourID], [FirstTolerance, SecondTolerance]);

And it doesn't stop there because it takes arrays so you can search for an infinite amount of textures at once. You should also NOT worry about different "ColourIDs" because no matter what, even when ColourIDs change, it will still find the item. For example, differentiating between a clean dwarfweed and a clean torstol can be done easily and only would need updating if there was a completely graphic overhaul to the herbs.


Fonts:
Yes it is actually possible for me to disable anything in the plugin or export a function to do such things. Whether it be fonts, colours, rendering, etc.. Can also enable things like white-walls, wire-frame mode, etc..

So yeah, the plugin isn't actually broken. I thought it was for a sec but after checking again, it isn't. It's just the way jagex draws stuff.

Oh i didnt even realize the graphic changes..
Kind of troublesome to have to get the IDs for all the different quantities then.

What do u mean by not having to worry about ColourIDs changes? If the tolerance is not sufficient and u call
Function glGetTextures(ID, ColourID, Tolerance: Integer): glTextureArray; overload;
it won't find the object?


Also is it possible to just remove the color 65535 from the textures? That's the static color for the amount. I know you cant get texture w/o the amount but can u get it then remove it then 'recalculate?' the colourID?
So we should use FullColourID for any textures that don't have an amount? Why not put the function like

Function glGetTextures(ID, ColourID, Tolerance: Integer; UseFullColour: Boolean = True): glTextureArray; overload;



Yeah perhaps u could disable everything and only enable them within the functions (glGetTextures, glGetModels, glGetChars etc) that need them?

Brandon

2013-09-22 00:31:15

From: riwu
Oh i didnt even realize the graphic changes..
Kind of troublesome to have to get the IDs for all the different quantities then.

What do u mean by not having to worry about ColourIDs changes? If the tolerance is not sufficient and u call
Function glGetTextures(ID, ColourID, Tolerance: Integer): glTextureArray; overload;
it won't find the object?


Also is it possible to just remove the color 65535 from the textures? That's the static color for the amount. I know you cant get texture w/o the amount but can u get it then remove it then 'recalculate?' the colourID?
So we should use FullColourID for any textures that don't have an amount? Why not put the function like

Function glGetTextures(ID, ColourID, Tolerance: Integer; UseFullColour: Boolean = True): glTextureArray; overload;



Yeah perhaps u could disable everything and only enable them within the functions (glGetTextures, glGetModels, glGetChars etc) that need them?



Why remove the colour when you can just chop off the top 12 pixels and completely ignore any and all numbers and calculate a checksum from that? And yeah I can add that boolean. You actually don't "have" to use full if you don't want to. You can but it isn't "mandatory".

riwu

2013-09-22 01:24:13

From: Brandon
Why remove the colour when you can just chop off the top 12 pixels and completely ignore any and all numbers and calculate a checksum from that? And yeah I can add that boolean. You actually don't "have" to use full if you don't want to. You can but it isn't "mandatory".

Found some more unexpected results:
{ID = 79305, COLOURID = 3626112, FULLCOLOURID = 2497296, X = 109, Y = 294, BOUNDS = {X1 = 91, Y1 = 278, X2 = 127, Y2 = 310}},

[{ID = 79305, COLOURID = 3560319, FULLCOLOURID = 2431504, X = 109, Y = 294, BOUNDS = {X1 = 91, Y1 = 278, X2 = 127, Y2 = 310}}]


[{ID = 42075, COLOURID = 5323801, FULLCOLOURID = 329736, X = 27, Y = 150, BOUNDS = {X1 = 9, Y1 = 134, X2 = 45, Y2 = 166}}]

[{ID = 42075, COLOURID = 5323799, FULLCOLOURID = 329992, X = 27, Y = 150, BOUNDS = {X1 = 9, Y1 = 134, X2 = 45, Y2 = 166}}]


Looks the same, and same ID, but COLOURID is different when the amount is different. (it should be the same since the amount is chopped off?)

Brandon

2013-09-22 02:42:43

From: riwu
Found some more unexpected results:
{ID = 79305, COLOURID = 3626112, FULLCOLOURID = 2497296, X = 109, Y = 294, BOUNDS = {X1 = 91, Y1 = 278, X2 = 127, Y2 = 310}},

[{ID = 79305, COLOURID = 3560319, FULLCOLOURID = 2431504, X = 109, Y = 294, BOUNDS = {X1 = 91, Y1 = 278, X2 = 127, Y2 = 310}}]


[{ID = 42075, COLOURID = 5323801, FULLCOLOURID = 329736, X = 27, Y = 150, BOUNDS = {X1 = 9, Y1 = 134, X2 = 45, Y2 = 166}}]

[{ID = 42075, COLOURID = 5323799, FULLCOLOURID = 329992, X = 27, Y = 150, BOUNDS = {X1 = 9, Y1 = 134, X2 = 45, Y2 = 166}}]


Looks the same, and same ID, but COLOURID is different when the amount is different. (it should be the same since the amount is chopped off?)


Not sure if you understand RS internals and how RS colours work. The colour of something in RS is NEVER the same. Hence why we have functions with a tolerance, tpa's, etc..

5323801 and 5323799 is almost exactly the same colour. The difference is 801 - 799 and that is the euclidean distance between two colours in the colour space. You can actually plugin that into your DTM editor or any colour viewer and I'm 100% sure it'd look the exact same.

However, roughly 1-2 pixels are different in the image and that results in a different colour. May look the same to the untrained eye but to your graphics card and to the game it is not the same.

Take for example the following Assembly code for GLSL shaders:


!!ARBvp1.0
OPTION ARB_position_invariant;
ATTRIB iPos = vertex.position;
ATTRIB iColour = vertex.color;
ATTRIB iTexCoord = vertex.texcoord[0];
OUTPUT oColour = result.color;
OUTPUT oTexCoord0 = result.texcoord[0];
OUTPUT oTexCoord1 = result.texcoord[1];
OUTPUT oFogCoord = result.fogcoord;
PARAM time = program.local[65];
PARAM turbulence = program.local[64];
PARAM lightAmbient = program.local[66];
PARAM pMatrix[4] = { state.matrix.projection };
PARAM mvMatrix[4] = { state.matrix.modelview };
PARAM ivMatrix[4] = { state.matrix.texture[1] };
PARAM texMatrix[4] = { state.matrix.texture[0] };
PARAM fNoise[64] = { program.local[0..63] };
TEMP noise, viewPos, worldPos, texCoord;
ADDRESS noiseAddr;
DP4 viewPos.x, mvMatrix[0], iPos;
DP4 viewPos.y, mvMatrix[1], iPos;
DP4 viewPos.z, mvMatrix[2], iPos;
DP4 viewPos.w, mvMatrix[3], iPos;
MOV oFogCoord.x, viewPos.z;
DP4 worldPos.x, ivMatrix[0], viewPos;
DP4 worldPos.y, ivMatrix[1], viewPos;
DP4 worldPos.z, ivMatrix[2], viewPos;
DP4 worldPos.w, ivMatrix[3], viewPos;
ADD noise.x, worldPos.x, worldPos.z;SUB noise.y, worldPos.z, worldPos.x;MUL noise, noise, 0.0001220703125;
FRC noise, noise;
MUL noise, noise, 64;
ARL noiseAddr.x, noise.x;
MOV noise.x, fNoise[noiseAddr.x].x;
ARL noiseAddr.x, noise.y;
MOV noise.y, fNoise[noiseAddr.x].y;
MUL noise, noise, turbulence.x;
DP4 texCoord.x, texMatrix[0], iTexCoord;
DP4 texCoord.y, texMatrix[1], iTexCoord;
ADD oTexCoord0.xy, texCoord, noise;
MOV oTexCoord0.z, 0;
MOV oTexCoord0.w, 1;
MUL oTexCoord1.xy, texCoord, 0.125;
MOV oTexCoord1.zw, time.xxxw;
MUL oColour.xyz, iColour, lightAmbient;
MOV oColour.w, iColour.w;
END

Do you see how it adds noise to the game? There are a lot more shaders where that came from. Even for water and basic things such as textures. These affect lighting, alpha transparency, colours, position, smoothing, etc.. The reason the HTML5 version of the game looks so nice but takes so long to load is because of shaders like these.

You can disable shaders using a technique known as bottle-necking/choking but then the game won't look so good and some thing may or may not render properly depending on what the shader is for.


Now here's how the old algorithm worked:


std::uint32_t Math::ColourCheckSum(const void* Data, std::uint32_t &MeanColour, std::size_t Width, std::size_t Height, uint32_t BitsPerPixel)
{
std::uint32_t CheckSum = 0;
int R = 0, G = 0, B = 0, K = 0;

const std::uint8_t* BuffPos = static_cast<const std::uint8_t*>(Data); //Get a pointer to the array of pixels for our texture.


//We will now iterate over the pixels of the texture and average all the colours in it.
for (std::size_t I = Height < 12 ? 1 : 12; I < Height; ++I) //Ignore the first 12 pixels of the texture. This gets rid of the numbers.
{
for (std::size_t J = 0; J < Width; ++J, ++K)
{
R += *(BuffPos++); //Add up all the RValues.
G += *(BuffPos++); //Add up all the GValues.
B += *(BuffPos++); //Add up all the BValues.

CheckSum += *(BuffPos++); //The checksum is the sum of all alpha pixels since alpha pixels do NOT change.
}
}

//Calculate the Average colour in the image.
//Avg_R = Sum(R) / AmountOfR.
//Avg_G = Sum(G) / AmountOfG.
//Avg_B = Sum(B) / AmountOfB.

MeanColour = (K != 0 ? RGB(R / K, G / K, B / K) : RGB(R, G, B));

return CheckSum; //So our TextureID is the sum of all alpha pixels. Our ColourID is the average of all colours in the texture.
}


Now the current algorithm which was created just recently to take into account small textures and give scripters more choice and ability and accuracy (as pointed out by Kasi):


std::uint32_t Math::ColourCheckSum(const void* Data, std::uint32_t &MeanColour, std::uint32_t &ClippedID, std::size_t Width, std::size_t Height)
{
std::uint32_t CheckSum = 0;
int R = 0, G = 0, B = 0, K = 0;
const std::uint8_t* BuffPos = static_cast<const std::uint8_t*>(Data); //Get a pointer to all Pixels in the texture.


//First we will calculate a checksum for the image itself starting at 12 to ignore all numbers if the texture has any.

for (std::size_t I = Height < 12 ? 1 : 12; I < Height; ++I)
{
for (std::size_t J = 0; J < Width; ++J)
{
int b = *(BuffPos++);
int g = *(BuffPos++);
int r = *(BuffPos++);
CheckSum += *(BuffPos++); //Checksum is still the Sum of all alpha pixels in the image.

if (r != 0 && g != 0 && b != 0) //If the colour is NOT black, then we add it.
{
R += r; //Sum of R values.
G += g; //Sum of G values.
B += b; //Sum of B values.
++K; //Amount of R/G/B values.
}
}
}

MeanColour = (K != 0 ? RGB(R / K, G / K, B / K) : RGB(R, G, B)); //Calculate our Average RGB now..



BuffPos = static_cast<const std::uint8_t*>(Data); //Get a pointer to all pixels in the texture..
R = G = B = K = 0;

for (std::size_t I = 0; I < Height; ++I) //Going from Height 0. Aka a checksum of the whole image with/without numbers.
{
for (std::size_t J = 0; J < Width; ++J, ++K)
{
//Should probably check for Black here and ignore it.. for now it is fine..
R += *(BuffPos++);
G += *(BuffPos++);
B += *(BuffPos++);
++BuffPos; //Skip the alpha channel since we already have our TextureID.
}
}

ClippedID = (K != 0 ? RGB(R / K, G / K, B / K) : RGB(R, G, B)); //Calculate Average RGB.
return CheckSum;
}

So in the second version, we now have two sets of Colours.

1. ColourID without numbers. = Average RGB of all pixels starting at the 12th row (font size is only 9 pixels.. this gives much space).
2. ColourID with numbers = Average RGB of all pixels.
3. TextureID = Average amount of Alpha pixels.


Hence in version 1 of the algorithm, TextureID is the same as version 2's.
ColourID in version 1 of the algorithm is the same as version 2's.

However, Version 2 now has an extra ID (FullColourID) just in case you want to be strict or need it (useful for minimap icons and very very small textures). This doesn't mean you can't still use the regular ColourID (infact, the include still doesn't even use the full version yet as I didn't need to).


And finally, on the Lape side, all it does is:


Function glGetTextures(ID, ColourID, Tolerance: Integer): glTextureArray; overload;
var
Ptr: Pointer;
Size, I, J: Cardinal;
ColourIDOffset: Cardinal;
type ptr_glTexture = ^glTexture;
Begin
J := 0;
Result := [];
Ptr := GLXTextures(Size);
SetLength(Result, Size);
ColourIDOffset := (PtrUInt(@(ptr_glTexture(nil + 1)^.ColourID)) - 1);

//Loop through our array of texture info.
//If the TextureID is the exact same and the ColourID is
//"SIMILAR" within a specified tolerance, then we add it to our result.
For I := 0 To Size - 1 Do
Begin
if ((Integer(Ptr^) = ID) and (SimilarColors(Integer((Ptr + ColourIDOffset)^), ColourID, Tolerance))) then
begin
Result[J] := glTexture(Ptr^);
Inc(J);
end;
Ptr.Inc(sizeof(glTexture));
End;
SetLength(Result, J);
End;

For thes reason, you do not need to worry so much about colours changing at all. The most I've seen a texture change is 3 pixels on average. After all, the noise in the shader is hardcoded and it isn't random so you shouldn't expect changes at all really. If you look bar far enough into RS's history, you'll notice that this particular shader is the same one from the first time RS got HD mode ;)

riwu

2013-09-22 02:53:31

Oh sorry, forgot that the color may have changed slightly when i changed the quantity.
I get it now ty :)

serajin

2013-09-26 18:26:26

So how long until we get an include that plays nice with SRL6? =D

Brandon

2013-09-26 22:11:30

From: serajin
So how long until we get an include that plays nice with SRL6? =D


Lol I somehow expected this question but at the same time I forgot such a thing exists..
Uhh I can probably make the who thing compatible in a bit less than a day or so.

Was waiting on the OSR github so I could help rewrite that.. And I'm thinking of a way to get handles from simba other than the debug box but yeah

Uh a day or so.

serajin

2013-09-26 22:35:29

From: Brandon
Lol I somehow expected this question but at the same time I forgot such a thing exists..
Uhh I can probably make the who thing compatible in a bit less than a day or so.

Was waiting on the OSR github so I could help rewrite that.. And I'm thinking of a way to get handles from simba other than the debug box but yeah

Uh a day or so.


Ty Brandon :) This probably answers my PM too. <3

riwu

2013-10-25 02:59:05

@Brandon
1. Is it possible to include the ColourID for models? Apparently different types of ores may have exactly the same model. (eg. both copper and iron ore could have the same ID 182193652)

2. When opening new interfaces/entering new places/hopping to another world, the javaw.exe process's memory usage will increase drastically, hence a script involving world hopping would have the client reaching over 1 GB within minutes. Any way to solve this problem? (such as having a function to free the resources before taking in new ones?)

Brandon

2013-10-25 12:12:41

From: riwu
@Brandon
1. Is it possible to include the ColourID for models? Apparently different types of ores may have exactly the same model. (eg. both copper and iron ore could have the same ID 182193652)

2. When opening new interfaces/entering new places/hopping to another world, the javaw.exe process's memory usage will increase drastically, hence a script involving world hopping would have the client reaching over 1 GB within minutes. Any way to solve this problem? (such as having a function to free the resources before taking in new ones?)



Problem 2.
This can never be fixed. I have tried everything for months on end.. The client simply has a leak. Jagex simply does NOT know how to free objects on windows OR they just wait until the 6-hour thing forces you to restart the client at which time it gets freed.

Try this:

Run Smart WITHOUT the plugin.
Open task manager and monitor java.exe/javaw.exe.

Do the following multiple times:

Begin-Repeat
–Login to the game.
–Logout to the lobby.
–Take note of memory usage.
End-Repeat.

You'll notice that it just keeps rising even without the plugin at all.

I even tried to put a System.gc() into Smart's BlitThread to see if it is Smart. It isn't. All it does is reduce the heap size but it still grows as time passes by. I stripped the plugin down to nothing.. Even colour capture removed. Still the same results..
Eventually I stopped using the plugin and it was the same result as if I was using it..

So I started on a new project: https://github.com/Brandon-T/DXI in hopes that it does better than the OpenGL one..
Don't know if I'll ever complete it at all.. but meh.. Also tried HTML5 just for the hell of it.. :l

I also went so far as to check if a texture already exists in the list.. If it does, simply ignore it and don't bother storing the same texture or model or font twice.. Thus, the plugin never actually stores more than the very very basic essentials..

As for functions that delete, they are all hooked and already there.. These delete everything jagex deletes.. Again, these are "hooks".


void GLHook_glDeleteBuffersARB(GLsizei n, const GLuint* buffers) //hooked function for deleting models/buffers.
{
for (int I = 0; I < n; ++I) //Iterate the list of buffers jagex provides to the graphics card.
{
auto it = std::find_if(ModelBuffer::Buffers.begin(), ModelBuffer::Buffers.end(), [&](const ModelBuffer &B) {return B.ID == buffers[I];});
if (it != ModelBuffer::Buffers.end()) //If that buffer/model was found, erase it from the list.
{
ModelBuffer::Buffers.erase(it);
}
}
ModelBuffer::Buffers.shrink_to_fit(); //shrink the memory.
ptr_glDeleteBuffers(n, buffers); //Call the original function.
}

void GLHook_glDeleteLists(GLuint list, GLsizei range) //hooked function for deleting fonts/lists.
{
for (std::size_t I = list; I < list + range; ++I) //deletes a bunch of fonts specified by the client.
{
auto it = std::find_if(Font::Fonts.begin(), Font::Fonts.end(), [&](const Font &F) {return F.ID == I;});
if (it != Font::Fonts.end())
{
Font::Fonts.erase(it);
}
}
Font::Fonts.shrink_to_fit(); //shrink the memory.
ptr_glDeleteLists(list, range);
}

void GLHook_glDeleteTextures(GLsizei n, const GLuint *textures) //delete a list of textures.
{
for (int I = 0; I < n; ++I)
{
auto it = Texture::IDMap.find(textures[I]);
if (it != Texture::IDMap.end()) //Erase the texture from the ID list.
{
Texture::IDMap.erase(it);
}


//Erase the texture from the texture list.
auto jt = std::remove_if(Texture::Textures.begin(), Texture::Textures.end(), [&](const Texture &T) {return T.ID == textures[I];});
if (jt != Texture::Textures.end())
{
Texture::Textures.erase(jt);
}
}
Texture::Textures.shrink_to_fit(); //shrink the memory.
ptr_glDeleteTextures(n, textures);
}

So yeah there isn't much I can do because the plugin only does exactly what the client does. No more, no less. I must say though.. I haven't had any memory problems with it so far.. I'm 96 divination right now.. Botted all the way and still going.

Problem 1.
As for model colours yeah it's possible but is it worth it to build it into the plugin or is it better to just call findcolourstolerance on the point returned?

I'll see what I can do.

Kasi

2013-10-25 14:19:20

From: Brandon
So I started on a new project: https://github.com/Brandon-T/DXI in hopes that it does better than the OpenGL one..


Debuggers for DirectX are painfully hard to use :(

riwu

2013-10-25 19:45:27

From: Brandon
Problem 2.
This can never be fixed. I have tried everything for months on end.. The client simply has a leak. Jagex simply does NOT know how to free objects on windows OR they just wait until the 6-hour thing forces you to restart the client at which time it gets freed.
So yeah there isn't much I can do because the plugin only does exactly what the client does. No more, no less. I must say though.. I haven't had any memory problems with it so far.. I'm 96 divination right now.. Botted all the way and still going.

Problem 1.
As for model colours yeah it's possible but is it worth it to build it into the plugin or is it better to just call findcolourstolerance on the point returned?

I'll see what I can do.

Sounds like ogl is not suitable for any scripts that involve continuous world hopping/entering and exiting new areas then….
Yeah i have no problem botting divination as well, since you just stay at the same area. Botted to 98 few weeks ago :p

For problem 1, perhaps make an optional parameter like GetColor: Boolean = False for glGetModels(), so it won't use extra resources/time when you dont need the color of the models?
Would it be faster than calling findcolor…?


EDIT:
also the commit https://github.com/Brandon-T/GLX/commit/acd383e1fe555aff53639b12071811f3b62dc035 removed the ability to debug all models in Area? Possible to add this back since it's much easier to get model ids of unknown mobile npcs this way?

J J

2013-10-25 19:54:37

Cool stuff Brandon. I will have C++ next semester and I'm going to give OpenGL hooking another shot during/after that semester :) I'm working on a RS3 toolkit that could actually be approved by Jagex so it's something different.

OpenGL/Java to stay cross platform and it's not modifying the RS3 applet. Full blown API except no keyboard/mouse methods. RSBuddy got approved by Jagex with reflection so this should get approved as well. But it'll take a long time before it's done :P So far I have JFrames for interacting with the hiscores, G/E API and Bestiary API.

DirectX should work better for most people considering nearly everyone uses Windows. I attempted to hook it once.. best I could do was inject the DLL and show a GUI that gave the dimensions of the game lol

Brandon

2013-10-25 20:45:37

@J J;
Cool stuff Brandon. I will have C++ next semester and I'm going to give OpenGL hooking another shot during/after that semester I'm working on a RS3 toolkit that could actually be approved by Jagex so it's something different.

OpenGL/Java to stay cross platform and it's not modifying the RS3 applet. Full blown API except no keyboard/mouse methods. RSBuddy got approved by Jagex with reflection so this should get approved as well. But it'll take a long time before it's done :P So far I have JFrames for interacting with the hiscores, G/E API and Bestiary API.

DirectX should work better for most people considering nearly everyone uses Windows. I attempted to hook it once.. best I could do was inject the DLL and show a GUI that gave the dimensions of the game lol


You're taking a course in school? Damn.. wish my school taught me something.. Are you doing a plugin or how are you going to get colours or anything from the Java side? Or is the plan just to run it in OpenGL without any sort of hooks?



From: riwu
Sounds like ogl is not suitable for any scripts that involve continuous world hopping/entering and exiting new areas then….
Yeah i have no problem botting divination as well, since you just stay at the same area. Botted to 98 few weeks ago :p

For problem 1, perhaps make an optional parameter like GetColor: Boolean = False for glGetModels(), so it won't use extra resources/time when you dont need the color of the models?
Would it be faster than calling findcolor…?


This is the same for Direct-X as well.. Just less memory and way faster on Windows. The only mode that RS has that does not do this, is safe-mode. Maybe file a bug report on RS.. Iunno. All I know is that I'm happy it isn't any of the plugins. It is a trade off between CPU and RAM.

Safemode for me uses 27% CPU for one client and 150mb ram capped at 200mb doing intense world hopping.
Direct-X for me uses 4% CPU and 200mb ram and capped at 300mb doing intense world hopping.
OpenGL for me uses 9% CPU and 250mb ram uncapped.

Direct-X on windows is the clear winner here. Behaviour may vary on linux.



EDIT:
also the commit https://github.com/Brandon-T/GLX/commit/acd383e1fe555aff53639b12071811f3b62dc035 removed the ability to debug all models in Area? Possible to add this back since it's much easier to get model ids of unknown mobile npcs this way?


No it does not remove anything. There is just more parameters to the function than there originally were.


glDebug(GL_DEBUG_MODE.GL_MODE_MODELS, 0, 0, 0, 0, 0, 0, smart.Width, smart.Height);

works just fine.

J J

2013-10-26 09:00:51

From: Brandon
@J J;
You're taking a course in school? Damn.. wish my school taught me something.. Are you doing a plugin or how are you going to get colours or anything from the Java side? Or is the plan just to run it in OpenGL without any sort of hooks?

I'm not completely sure. Just similar to TRiBot on RS3 I would get the models/textures/text with the OpenGL hook. Probably have to use JNI to pass the stuff right?

There are so many people working on botting tools for RuneScape while there aren't that many people working on actual legitting toolkits/clients. It just surprises me.

On the new RSBuddy I've seen that people are even willing to pay for "premium plugins" eg. dungeoneering helper, clue scroll solver helper, etc. Scripters could make plugins using the API. I think it would be rather interesting.

It would be nice to hook the skill array and player position/animation but I'd rather have it OpenGL only. To add reflection in RS3 you would need to decrypt the gamepack first and perhaps Jagex see's that as modifying the client. Or you would need to replace the ZipInputstream or JarInputStream something like that.. so it decrypts itself.

All in all it seems really interesting.

Justin

2013-10-27 08:14:58

Brandon, In your include, Minimap.simba (https://github.com/Brandon-T/SRL-GLX/blob/master/Minimap.simba#L368) you have a 's' after end;. You might want to remove this :)

bg5

2013-11-11 11:49:22

Hey,
I've tried to compile OpenGL.dll ,but some strange issue I have:


g++.exe -shared -Wl,--output-def=bin\Debug\libOpenGL32.def -Wl,--out-implib=bin\Debug\libOpenGL32.a -Wl,--dll obj\Debug\src\Hooks\BufferHook.o obj\Debug\src\Hooks\Communication.o obj\Debug\src\Hooks\Debugger.o obj\Debug\src\Hooks\Exports.o obj\Debug\src\Hooks\Graphics.o obj\Debug\src\Hooks\Hooks.o obj\Debug\src\Hooks\Math.o obj\Debug\src\Hooks\Platform.o obj\Debug\src\Hooks\Render.o obj\Debug\src\Hooks\Serialization.o obj\Debug\src\Hooks\SharedMemory.o obj\Debug\src\Hooks\SmartJNI.o obj\Debug\src\Hooks\Structures.o obj\Debug\src\Imaging\LodePNG.o obj\Debug\src\main.o -o bin\Debug\OpenGL32.dll -static -static-libgcc -static-libstdc++ -Wl,--enable-stdcall-fixup -Wl,--kill-at -d --input-def OpenGL32.def -luser32 -lgdi32
g++.exe: error: OpenGL32.def: No such file or directory

I use Code::Blocks, latest mingw32 and
.def file is already added to the project ( project file (.cbp) is original one from github, I didn't change anything)

I have no idea what to do, any help?

alar82

2013-11-21 03:46:55

Exception in Script: Block expected at line 368, column 5 in file "C:\Simba\Includes\GLX\Minimap.Simba"
Oh that was that extra "s" at line 368:duh:

Kasi

2013-11-21 11:12:54

From: bg5
Hey,
I've tried to compile OpenGL.dll ,but some strange issue I have:


g++.exe -shared -Wl,--output-def=bin\Debug\libOpenGL32.def -Wl,--out-implib=bin\Debug\libOpenGL32.a -Wl,--dll obj\Debug\src\Hooks\BufferHook.o obj\Debug\src\Hooks\Communication.o obj\Debug\src\Hooks\Debugger.o obj\Debug\src\Hooks\Exports.o obj\Debug\src\Hooks\Graphics.o obj\Debug\src\Hooks\Hooks.o obj\Debug\src\Hooks\Math.o obj\Debug\src\Hooks\Platform.o obj\Debug\src\Hooks\Render.o obj\Debug\src\Hooks\Serialization.o obj\Debug\src\Hooks\SharedMemory.o obj\Debug\src\Hooks\SmartJNI.o obj\Debug\src\Hooks\Structures.o obj\Debug\src\Imaging\LodePNG.o obj\Debug\src\main.o -o bin\Debug\OpenGL32.dll -static -static-libgcc -static-libstdc++ -Wl,--enable-stdcall-fixup -Wl,--kill-at -d --input-def OpenGL32.def -luser32 -lgdi32
g++.exe: error: OpenGL32.def: No such file or directory

I use Code::Blocks, latest mingw32 and
.def file is already added to the project ( project file (.cbp) is original one from github, I didn't change anything)

I have no idea what to do, any help?


Copy OpenGL32.def outside the bin folder. i have no idea why its like this.

BigRedJapan

2013-11-23 05:10:05

WIll this work for Rs Private Servers?

rj

2013-11-23 10:33:29

From: Rules of Joe
WIll this work for Rs Private Servers?


If you modify it to, assuming that they have opengl support

alar82

2013-12-18 14:01:14

Not showing debug anymore:/
Those green ids.

{$DEFINE SMART}
{$include_once GLX/Setup.Simba}

var
Smart: TSmart;
Bmp,II: Integer;
pp:TBox;
MMPos: TPoint;
TT,CC: glTextureArray;
TT2: glModelArray;

begin
//ClearDebug;
SetupGLX(Smart, 1110, 770);
// GL_DEBUG_MODE.GL_MODE_MODELS
// GL_DEBUG_MODE.GL_MODE_TEXTURES
// GL_DEBUG_MODE.GL_MODE_FONTS
// GL_DEBUG_MODE.GL_MODE_DISPLAY
GLDebug(GL_DEBUG_MODE.GL_MODE_TEXTURES, 0, 0, 0, 0, 0, 0, Smart.Width, Smart.Height);
GLXSetFontCapture(False);
repeat
Wait(RandomRange(1000, 6675));

writeln('boo');
until(false)
end.

[ATTACH=CONFIG]22579[/ATTACH]

Finally 2 months later I had amaizing idea to use google. I had missing right plugins:s.
Well now I know why its burried, it slows down until it stops.

Got bored and compiled it, tried removing some collected data, still slows. Me thinks that slowdowns are related rendering and textures somehow.
When logged into game I get +20fps for a while. 15 minutes later 15-20fps then when I move away from orignal location fps drops, return to original location fps restores. Logged out and in 1fps:/
Watched with gpu-z video memory usage it did go from 250 to 330MB but thats not much.(cant be video memory fuckup its still longway to go(1GB).)
After looking that code for 2 days ill give up, my head hurts.

Brandon

2014-07-31 23:26:48

Okay.. http://download948.mediafire.com/kg7exo3xlpvg/5qpaawa16yx7bse/libGL.tar.gz

^Linux & Mac source + build that works natively. So now I shouldn't hear any more complaints that nothing works on Linux.


I ran it with the following from terminal:


LD_PRELOAD='/home/master-Kira/Desktop/OpenGL/CLoader/dist/libGL.so.1.2.0' java -jar CLoader.jar

RS will then load it just fine. It will map a shared memory file that you can read the colours from. The SMART plugin interface is implemented as well. I didn't test it much.


What's different? Nothing. I just rewrote it all in C. Both the Windows & Linux code. That's about it. I haven't found a way to get SMART's plugin API working on Linux like it does on Windows.

At the moment, SMART will load the plugin just fine but the overrides/hooks will NOT be called (I think.. I didn't test it much with SMART). Might have to hook things using assembly if push comes to shove. :l
Either that, or I somehow messed up loading SMART. I'll try SMART again later.

For now, it works with browsers and loaders using `LD_PRELOAD` as the method for hooking.


EDIT:

Solved it using a trick quite well known. A library/module cannot truly be loaded twice. Once loaded, subsequent attempts to load it simply return the handle to the already mapped module.

Taking advantage of this, we attempt to load the plugin twice. Once with LD_PRELOAD and the second time with SMART itself.

To do it programmatically, I modified libsmartjni and added: putenv("LD_PRELOAD=Plugin_Path_Here");
Could also use `execle`.


Now everything works with SMART and the Browser and there aren't any bad side effects to this that I can see at this time. Of course, actual hooks and not tricks would be better but meh.. they result in the same thing.

All that's left is to get Simba for linux.

twirap

2014-08-03 16:22:21

I give up. I am getting so pissed off at this point….Everything I set my display mode to OpenGL on my browser or SMART it crashes….Don't know what to do…All the scripts are so broken and misclick and waste hours just running around…Is Simba even worth using for tasks other than dropping logs and cutting trees?

The Mayor

2014-08-03 16:34:04

From: twirap
I give up. I am getting so pissed off at this point….Everything I set my display mode to OpenGL on my browser or SMART it crashes….Don't know what to do…All the scripts are so broken and misclick and waste hours just running around…Is Simba even worth using for tasks other than dropping logs and cutting trees?


If OpenGL doesn't work on your browser, then it's not going to work in SMART.

Ian

2014-08-03 16:51:48

From: twirap
Is Simba even worth using for tasks other than dropping logs and cutting trees?


What do you have in mind? If it's not something like dungeoneering the answer is probably yes.

twirap

2014-08-03 19:21:26

I was hoping I could get the opengl issue fixed…..my laptop stays on 24/7 to bot. Ive tried removing procedures for scripts using SMARt so I can use them on browser but scripts like divination don't work after I have removed SMART procedures…. IDK what to do…

Brandon

2014-08-04 11:03:16

From: twirap
I was hoping I could get the opengl issue fixed…..my laptop stays on 24/7 to bot. Ive tried removing procedures for scripts using SMARt so I can use them on browser but scripts like divination don't work after I have removed SMART procedures…. IDK what to do…



You must be able to get it working in the browser in order for SMART to run it. The divination script can use DirectX as well. If your browser doesn't allow OpenGL, try DirectX.

If it doesn't allow both, you must either have a driver problem or a cache problem. Could also be your Java.


RS has a Wiki for fixing the white/blackscreen/crash on Linux: http://services.runescape.com/m=rswiki/en/Linux_Known_Issues#javacrash

Don't know where their Windows wiki is.

Unfold

2014-08-04 12:00:30

Do you think using VirtualGl will work for those who have a vps?

Turpinator

2014-08-04 13:16:38

From: Unfold
Do you think using VirtualGl will work for those who have a vps?


IIRC, virtualGL still requires a gfx card/compute type server.
so you would be rendering/etc on your own PC, and then sending to the VPS. thats great and all, but doesnt that defeat the purpose of a vps?

Unfold

2014-08-04 13:20:42

From: Turpinator
IIRC, virtualGL still requires a gfx card/compute type server.
so you would be rendering/etc on your own PC, and then sending to the VPS. thats great and all, but doesnt that defeat the purpose of a vps?


:/ yes i guess.

I really hope they make SRL- software mode.

Turpinator

2014-08-04 13:24:10

From: Unfold
:/ yes i guess.

I really hope they make SRL- software mode.


https://github.com/SRL/SRL-5
here you go. you'll just need to tweak everything a bit. ;)

on second thought… this might work decent (with changes ofc) for legacy…

Olly

2014-08-04 13:32:43

The goal was to have safe-mode support also, until i looked into it and every color is different, Even for things like interfaces. :/

Gunner

2014-08-04 14:25:54

From: Olly
The goal was to have safe-mode support also, until i looked into it and every color is different, Even for things like interfaces. :/


Since I can't exactly contribute in the form of coding, perhaps I could at least grab all the colors you need? Why don't you send me a list of all the things you need colors for that would be in the basic includes? Bank screen, main screen interfaces, interface tabs etc? I'm limited in how much I can really contribute around here, but this would be something I could handle.

Brandon

2014-08-04 14:31:16

From: Gunner
Since I can't exactly contribute in the form of coding, perhaps I could at least grab all the colors you need? Why don't you send me a list of all the things you need colors for that would be in the basic includes? Bank screen, main screen interfaces, interface tabs etc? I'm limited in how much I can really contribute around here, but this would be something I could handle.



I was thinking of actually writing or helping write an include to support Safe-mode but I don't have time atm and it's a lot of work.. The problem isn't support or writing it at all. It's mostly maintenance.. Thought about it a lot before but now, not so much..

I haven't seen a computer incapable of both OpenGL AND DirectX in 2014.. Even VMware supports them both on Linux & Windows.

Gunner

2014-08-04 14:37:04

From: Brandon
I might actually write an include to support Safe-mode but I don't have time atm and it's a lot of work.. The problem isn't support or writing it at all. It's mostly maintenance.. Thought about it a lot before but now, not so much..

I haven't seen a computer incapable of both OpenGL AND DirectX in 2014.. Even VMware supports them both.


Yes but wouldn't safe mode lower resource usage by quite a bit? As well as the ability to use safe mode gets us past the 4 client maximum without the need for batch files.

Olly

2014-08-04 14:43:56

From: Gunner
Since I can't exactly contribute in the form of coding, perhaps I could at least grab all the colors you need? Why don't you send me a list of all the things you need colors for that would be in the basic includes? Bank screen, main screen interfaces, interface tabs etc? I'm limited in how much I can really contribute around here, but this would be something I could handle.


It would be a entire include re-write (for colors), and that's alot of work. But as Brandon said it's mostly down to maintenance.

Personally in a graphics mode RS takes up alot less cpu, but I assume that's because I have a graphics card. The whole reason to use a graphics mode to less detectable and work with OGL hooks, tho OGL hooks didn't exactly take off due to the fact that you lose fps at some crazy rate (I was down to about 2 after 30 mins..).

The whole farming thing and a problem with VM's not having OGL and such never came up in discussion, mostly because the dev's talking about only ever botted on one or two accounts.

Gunner

2014-08-04 14:47:44

From: Olly
It would be a entire include re-write (for colors), and that's alot of work. But as Brandon said it's mostly down to maintenance.

Personally in a graphics mode RS takes up alot less cpu, but I assume that's because I have a graphics card. The whole reason to use a graphics mode to less detectable and work with OGL hooks, tho OGL hooks didn't exactly take off due to the fact that you lose fps at some crazy rate (I was down to about 2 after 30 mins..).

The whole farming thing and a problem with VM's not having OGL and such never came up in discussion, mostly because the dev's talking about only ever botted on one or two accounts.


Fair enough. I'm just always looking for a way to pull my weight around here. It certainly isn't going to be in the form of coding, at least not anytime soon. :(

Brandon

2014-08-04 14:50:11

From: Gunner
Yes but wouldn't safe mode lower resource usage by quite a bit? As well as the ability to use safe mode gets us past the 4 client maximum without the need for batch files.



This is true. OpenGL (Direct-X didn't exist yet) was "originally" designed as a "fall-back" method.. See here: https://villavu.com/forum/showthread.php?t=86223

That was actually when Jagex had brought it's shit storm of a fix to break colour bots.. And Wizzup added "Offsets" to Simba for the Image buffer. I guess you could say we were just looking for other solutions and OpenGL was the alternative IFF safe-mode ever broke. Jagex also had introduced glitches into Safemode that was non-existent in the other modes (IE: Half of a rune essence showing, items disappearing). It probably wasn't on purpose but it sure broke stuff. Then the nav-bar was added and so on and since the entire included needed to be fixed to support these changes which happened almost over-night, I guess we decided to just switch modes while we had the chance? It took 3 revisions to get SMART's plugin API down and to get things working (almost flawlessly.. Hence: "Smart v8.3").

The include is more and advanced than it was before. And by far. Whether or not it's a mistake to switch fully is debatable but that's also due to RS3 being introduced as well..

Either way, I don't mind helping out or doing anything. It's just more "maintenance".

And yeah, the hooks were a nice touch while it lasted but then textures aren't being automatically freed by the client (only models are). If I did remove textures from the plugin, there'd be no fps drops (at least not the dramatic 1GB memory usage and 10-fps). But laziness..

Olly

2014-08-04 14:53:05

From: Brandon
I guess we decided to just switch modes while we had the chance?


You hit the nail on the head.

e:

Thought id see if there was any difference apart from the mainscreen and minimap on legacy (safemode > dx}.
Red = Pixels are different…


Unfold

2014-08-04 15:36:04

I might look into SRL-5 and attempt to convert it.
It's just that my computer is garbage. I can only run runescape and nothing else. Also, i'm unable to leave it overnight.

I do have a vps for other stuff and there is enough resources to run 1-2 bots. I'm not looking into gold farming, really just leveling up.

But thanks for the replies guys.

Ian

2014-08-04 15:57:46

From: Brandon
I was thinking of actually writing or helping write an include to support Safe-mode but I don't have time atm and it's a lot of work.. The problem isn't support or writing it at all. It's mostly maintenance.. Thought about it a lot before but now, not so much..

I haven't seen a computer incapable of both OpenGL AND DirectX in 2014.. Even VMware supports them both on Linux & Windows.


My laptop doesn't do OpenGL or DirectX for runescape at least, but it's using integrated intel graphics from 2006.

riwu

2014-09-14 19:59:41

@Brandon
When i use the OldSchool layout the model points retrieved get messed up



Texture works fine. I think this is due to the mainscreen being placed in northwest rather than centre of the applet in oldschool layout.
If i manually offset the Y coordinates of the model by about 204 it'd return correct coordinates.
Is there a way to fix this more elegantly?

Brandon

2014-09-14 20:05:16

From: riwu
…


Set the viewport to whatever the oldschool size is.. Projection to anything on the screen goes by the viewport and the game's internal viewport does not change. All it does is cover parts of it with those "textures" you're seeing called the inventory, chatbox, etc..

If you change the viewport then the projection will adapt to that. Otherwise there's no other way to do it. Btw.. that plugin isn't on my support list so if you need to recompile it to change the vp, then you'd have to do that.

https://github.com/Brandon-T/GLX/blob/master/GLX/src/Exports.cpp#L66 should return the current viewport. If SMART isn't that size, you'll have an offset problem. I haven't tested this plugin in RS in ages so I'm not actually sure if anything changed.


World to screen is here: https://github.com/Brandon-T/GLX/blob/master/OpenGL32/src/Hooks/Math.cpp#L151


The only other way is if I actually fed Simba the points for each model via its buffer. That would allow you to click eyeballs and fingers and stuff.. even flying objects.. but again, I don't have plans for that plugin any longer. No one except a few use it.


On a side note.. I started monitoring the usage of the plugin itself:


then I reduced the memory drastically by disabling "map saving".. You won't be able to save maps to the disk with:


Pixels.resize(Width * Height * 4);
glGetTexImage(target, 0, GL_BGRA, GL_UNSIGNED_BYTE, Pixels.data());

Even though it only takes up (at the absolute most) 512 * 512 * 4 bytes = 1mb.

riwu

2014-09-18 21:28:53

@Brandon
Currently for both simba and opengl the screen searching methods scan from left to right, then top to down (eg. sth at Point(1000, 0) will be found before sth at Point(0, 1)).
Can my code rely on this behavior? (ur gl_invslots() relies on it)
Would it change in the future, or will your html/DX interception plugin (when it's eventually done) not follow the same behavior,
such that i should sort the points myself in the code?


Also i'm currently running the latest SMART with java 6 (changed the canvas class), as java6 seems to cause least problems for me (smart flashing/gaining focus etc). Is there any disadvantage of using java6 to run SMART and the plugin? (other than security issues etc which is not a concern to me)

Brandon

2014-09-18 22:12:47

@riwu; I don't know what you mean it searches from left to right. It does not. It searches for whatever is rendered first in the exact order that it's rendered. If it happens to render from left to right, then that decision was made by Jagex.

The plugin captures in order of what is rendered. If a ruby is rendered before a diamond, it will capture ruby, then diamond and not the other way around.

If for whatever reason the rendering order changes, so will the capturing order. I don't think gl_InvSlots relies on order. It gets all the slot textures and just adds them in the order that they were retrieved (natural order). If slot 28 rendered before slot 1, then slot 28 would be the first slot.

gl_invSlots does not care about the order of inventory slots. It returns slots unsorted. If they happen to be sorted, Jagex had them sorted.


As for side-projects.. What projects? If you mean my signature, I was just messing around with hooking stuff because I was bored as hell and was just trying to find something challenging but when the challenge goes away, it's not fun anymore.

What DX or HTML plugin? I stopped development of the WebGL plugin as soon as I got it working.. Then I realised someone else had also had it working without "hooks": https://github.com/google/angle

For Direct-X, I just hooked models and their indices + vertices and textures.. but again, I never announced anything and there isn't anything to announce. If anyone wants the code, they can have it.



#include "Direct3DDevice9Proxy.hpp"
#include <d3dx9.h>


/** Generates a texture.. Can be used to re-colour models **/
void GenTexture(IDirect3DDevice9 *Device, std::uint8_t *buffer, int width, int height, IDirect3DTexture9 *&Texture)
{
Device->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &Texture, 0);

D3DLOCKED_RECT rect;
Texture->LockRect(0, &rect, nullptr, D3DLOCK_DISCARD);
std::uint8_t *TexturePixels = static_cast<std::uint8_t *>(rect.pBits);
memcpy(TexturePixels, &buffer[0], width * height * 4);
Texture->UnlockRect(0);
}

/** Get's the vertex of the specified model at index **/
D3DXVECTOR3 GetVertex(std::uint8_t *vertices, std::int16_t index, std::uint16_t stride)
{
D3DXVECTOR3 res = {0};
memcpy(&res.x, &vertices[index * stride], sizeof(float));
memcpy(&res.y, &vertices[index * stride + sizeof(float)], sizeof(float));
memcpy(&res.z, &vertices[index * stride + sizeof(float) * 2], sizeof(float));
return res;
}

/** Iterates through all the vertices of a model.. Retrieves the index of that vertex as well as the X, Y, Z.. **/
void ProcessTriangleList(IDirect3DVertexBuffer9 *VertexBuffer, IDirect3DIndexBuffer9 *IndexBuffer, std::uint32_t BaseVertexIndex, std::uint32_t StartIndex, std::uint32_t PrimCount, std::uint32_t Stride)
{
std::uint8_t *vertices = NULL;
std::uint16_t *indices = NULL;
UINT EndIndex = StartIndex + (PrimCount * 3);

VertexBuffer->Lock(0, 0, reinterpret_cast<void **>(&vertices), 0);
IndexBuffer->Lock(0, PrimCount * 3 * sizeof(std::uint16_t), reinterpret_cast<void **>(&indices), 0);

for (UINT I = StartIndex; I < EndIndex; ++I)
{
D3DXVECTOR3 v = GetVertex(vertices, indices[I] + BaseVertexIndex, Stride); //store it somewhere.. check for duplicates in the storage.. Maybe write it to a .obj file and load that into blender.
}

IndexBuffer->Unlock();
VertexBuffer->Unlock();
}

/** Same as above **/
void ProcessTriangleStrip(IDirect3DVertexBuffer9 *VertexBuffer, IDirect3DIndexBuffer9 *IndexBuffer, std::uint32_t BaseVertexIndex, std::uint32_t StartIndex, std::uint32_t PrimCount, std::uint32_t Stride)
{
std::uint8_t *vertices = NULL;
std::uint16_t *indices = NULL;
UINT EndIndex = StartIndex + PrimCount;

VertexBuffer->Lock(0, 0, reinterpret_cast<void **>(&vertices), 0);
IndexBuffer->Lock(0, PrimCount * 3 * sizeof(std::uint16_t), reinterpret_cast<void **>(&indices), 0);

for (UINT I = StartIndex; I < EndIndex; ++I)
{
GetVertex(vertices, indices[I] + BaseVertexIndex, Stride); //store it somewhere.. check for duplicates in the storage..
}

IndexBuffer->Unlock();
VertexBuffer->Unlock();
}

HRESULT Direct3DDevice9Proxy::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount)
{
static UINT stride = 0;
static UINT offset = 0;
static IDirect3DTexture9 *tex = NULL;

if (!tex)
{
DWORD col = D3DCOLOR_RGBA(255, 0, 0, 128);
GenTexture(ptr_Direct3DDevice9, (uint8_t *)&col, 1, 1, tex); //generate a red texture.. re-colour specified models red..
//if (ModelID == 1916)
// ptr_Direct3DDevice9->SetTexture(0, tex); //colour my player's model red..
}

IDirect3DIndexBuffer9 *ppIndexData = NULL;
IDirect3DVertexBuffer9 *ppVertexData = NULL;

ptr_Direct3DDevice9->GetIndices(&ppIndexData);
ptr_Direct3DDevice9->GetStreamSource(0, &ppVertexData, &offset, &stride);


//call process TriangleStrip or TriangleList to get every vertex of said model.. Otherwise WorldToScreen(0, 0, 0) to get the center of the model.

ppIndexData->Release();
ppVertexData->Release();

return ptr_Direct3DDevice9->DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
}


That's all I did. Well.. I did more (ESP, see through walls, etc..) but meh.. The above is enough to hook models for any and all games. I was able to rip the models from the game and load them in blender (.obj format).. It was pretty neat. Too much work for me though and it got boring. I basically just abandoned it all. The same code/logic can actually be used in OpenGL but laziness. FPS doesn't drop in Direct-X at all; which I found weird lol.

Other than that, I don't have any projects I'm working on and I don't plan to release anything.. I only have to support the colour plugins if things break and I'm happy enough doing that.

riwu

2014-09-18 22:35:56

From: Brandon
@riwu; I don't know what you mean it searches from left to right. It does not. It searches for whatever is rendered first in the exact order that it's rendered. If it happens to render from left to right, then that decision was made by Jagex.

The plugin captures in order of what is rendered. If a ruby is rendered before a diamond, it will capture ruby, then diamond and not the other way around.

If for whatever reason the rendering order changes, so will the capturing order. I don't think gl_InvSlots relies on order. It gets all the slot textures and just adds them in the order that they were retrieved (natural order). If slot 28 rendered before slot 1, then slot 28 would be the first slot.

gl_invSlots does not care about the order of inventory slots. It returns slots unsorted. If they happen to be sorted, Jagex had them sorted.

Oh i didnt know the order in which the plugin retrieves models/textures depends on Jagex's rendering…
For Simba's color searching it is made to search from top left to btm right (except in spiral functions), so i'd naively thought that it's the same case for the plugin.


Btw for the map removal change, the model IDs are constantly disappearing and reappearing (when i turned on glxdebug, the IDs kept flashing (disappearing and reappearing))

I tested and confirmed that the problem lies with changes in Structures.cpp/Structures.hpp, but i have no idea what in it could be causing the problem
https://github.com/riwu/GLX/compare/patch-1
If u couldnt see anything wrong as well, i could further debug it (reverting some lines and recompiling) until i find out the exact line/block that is causing the problem.

Brandon

2014-09-19 00:00:49

From: riwu
Oh i didnt know the order in which the plugin retrieves models/textures depends on Jagex's rendering…
For Simba's color searching it is made to search from top left to btm right (except in spiral functions), so i'd naively thought that it's the same case for the plugin.


Btw for the map removal change, the model IDs are constantly disappearing and reappearing (when i turned on glxdebug, the IDs kept flashing (disappearing and reappearing))

I tested and confirmed that the problem lies with changes in Structures.cpp/Structures.hpp, but i have no idea what in it could be causing the problem
https://github.com/riwu/GLX/compare/patch-1
If u couldnt see anything wrong as well, i could further debug it (reverting some lines and recompiling) until i find out the exact line/block that is causing the problem.



I know exactly what is wrong with it. I just didn't have time to revert the "Model" structure. The old structure used to keep a reference to the CurrentModelBuffer but I removed it and that's what happened. Just gotta put it back is all. It needs to record the index buffers and the array buffers instead of just array buffers (vertex buffers).

Clarity

2014-09-19 00:04:29

@Brandon

2 things regarding the GLHook plugins.

1. Textures aren't freed so eventually Simba lags/freezes from so much memory usage. Currently, I have an AHK script that circumvents this:


#persistent
setbatchlines,-1
w:=comobjget("winmgmts:{impersonationlevel=impersonate}!\\.\root\cimv2")
settimer,empty,-2000
return

empty:
for p in w.execquery("select processid from win32_process where name='javaw.exe' or name='Simba.exe'"){
h:=dllcall("OpenProcess",uint,0x001f0fff,int,0,Int,p.processid)
dllcall("SetProcessWorkingSetSize",uint,h,int,-1,int,-1)
dllcall("CloseHandle",int,h)
}
settimer,empty,-2000
return

But it would be nice to not have this issue.

2. When I want to grab models/textures from the client and theoretically save resources by only searching within a specific area, I've discovered that this is not the case because the plugin grabs everything from the game every single time and then the search is narrowed down in Lape. So if I'm searching for minimap icons 10 times, the plugin is searching the whole client 10 times…..wouldn't it be much more efficient/faster for us to be able to pass search parameters to the plugin?

The bigger issue though is the two problems combined - since the texture memory is never freed from these massive searches…10 minimap icon searches would build up the equivalent unfreed memory of 10 entire game screen searches.

Also, a question, what is the proper way of enabling SRL6Compatibility? I've tried putting {$DEFINE SRLCOMPATIBILITY} at the top but I think I'm getting the order wrong of including glx/srl-6 after.

Brandon

2014-09-19 00:36:30

From: Clarity
@Brandon

2 things regarding the GLHook plugins.

1. Textures aren't freed so eventually Simba lags/freezes from so much memory usage. Currently, I have an AHK script that circumvents this:


#persistent
setbatchlines,-1
w:=comobjget("winmgmts:{impersonationlevel=impersonate}!\\.\root\cimv2")
settimer,empty,-2000
return

empty:
for p in w.execquery("select processid from win32_process where name='javaw.exe' or name='Simba.exe'"){
h:=dllcall("OpenProcess",uint,0x001f0fff,int,0,Int,p.processid)
dllcall("SetProcessWorkingSetSize",uint,h,int,-1,int,-1)
dllcall("CloseHandle",int,h)
}
settimer,empty,-2000
return

But it would be nice to not have this issue.

2. When I want to grab models/textures from the client and theoretically save resources by only searching within a specific area, I've discovered that this is not the case because the plugin grabs everything from the game every single time and then the search is narrowed down in Lape. So if I'm searching for minimap icons 10 times, the plugin is searching the whole client 10 times…..wouldn't it be much more efficient/faster for us to be able to pass search parameters to the plugin?

The bigger issue though is the two problems combined - since the texture memory is never freed from these massive searches…10 minimap icon searches would build up the equivalent unfreed memory of 10 entire game screen searches.

Also, a question, what is the proper way of enabling SRL6Compatibility? I've tried putting {$DEFINE SRLCOMPATIBILITY} at the top but I think I'm getting the order wrong of including glx/srl-6 after.



Uhh.. I'm not sure what build up you mean. I had recently posted a pic (and gave riwu a plugin) where it shows that the maximum memory the plugin uses at any given time over any period of time is <= 2mb (NOT including the Simba memory map: W*H*4*2 bytes.


Yes it's possible to write only specific textures or models to the Simba SharedMemory. However, it is NOT possible (well it is but it's the worst idea ever!) to capture only textures in a specific area. If I did that, it will slow down to ZERO fps. I know this because Silabsoft (SimbaGL) did this.

And I'm not kidding when I say ZERO fps.. It's probably even negative (I know it's not possible to be negative) because you can't click anything.

Here's their code: https://github.com/silabsoft/SimbaGL/blob/master/opengl32/opengl32.cpp#L144

that's for allocating memory for the texture's pixels and: https://github.com/silabsoft/SimbaGL/blob/master/opengl32/opengl32.cpp#L146 asks the graphics card to sync with the CPU to get those pixels. THEN and only then, do they calculate the checksum.

Trust me when I say that this is the worst idea you can ever do in OpenGL. Here's how I did it:

https://github.com/Brandon-T/GLX/blob/master/OpenGL32/src/Hooks/Structures.cpp#L237

I have that function. The game calls that function whenever it wants to render a texture. It has to pass the pixels to the gfx but only once. After that, the game is supposed to delete the texture's memory as the gfx already has it. All I did was intercept the pass and do the checksum on the pixels there and then. There's no memory allocated and no GPU/CPU syncing. I store that data in a lookup table for later so that when the game attempts to bind that texture to the screen, I can just look up the hashcode for it without having to generate the ID again and ask for pixels and all that other stuff.

At most, my look-up tables take up 2mb. I haven't seen it go over this. If I stored the pixels, you'd probably crash your computer.. It'd be gigabytes of memory allocations. Roughly 600-1000 textures can be loaded upon log-in (even ones that won't be displayed on screen). There can be anywhere around 6000 to 7000 fonts (characters A-Z 0-9, etc..) loaded at any given time. However, only 200 would be used at any given time lol.

Never the less, only the IDs are stored and the bounds coords.

I can even re-write this plugin entirely in Pascal like I did the Direct-X one and it will make no difference. I even tried re-writing it entirely in C using a linked list..

Here's how many times I've attempted this exact same plugin + some direct-x hooks.. I've even disabled every shader and made the game literally black and white. Logging ONLY models would be the only way to fix this. If I scrapped textures and did only models, that means you'd need to use dtm's to identify inv items, and tesseract for font-recognition or w/e.. Maybe a mix of SRL-6 and the model only plugin. But again, all memory management logs I've checked show a 2mb usage at most from the hooks (NOT from the Simba colour transfer which is 800*600*4 bytes on the ideal fixed mode).



I've re-written it MORE times than I can possibly count.. That's just what's on this current laptop (excludes two other laptops I use for work and development). Some are on mediafire, some are on one-drive, some on megaupload, etc.. I ran out of names to name the folders.. I started numbering them or calling them "Modules". I don't make the same mistake that many times ={ I've even re-written it once in assembly using only registers and stack allocations (automatic memory management). It made no difference. Of course assembly was way faster but really really really really hard to maintain. C was the second fastest but again, the memory usage was the exact same.


There's a reason I gave up on that plugin. There's nothing I or anyone else can do. A Direct-X version would be insanely better. I know this because I've tested it. A zero FPS drop between a direct-x hook and a colour plugin is well.. I don't have words. But it's good.

Again, none of these hook things have my attention though. I'd be willing to even re-write it ONE more time even though I know it would make absolutely no difference (I just can't help thinking I missed something).. If I did, I'd write it in pascal.

Clarity

2014-09-19 02:13:21

Well then, it's safe to say I apparently have no idea what I was talking about in my previous post.
Thanks for explaining it clearly :)

Recurring theme though seems to be that DX hooking is infinitely better, perhaps we should switch? I've heard you have this impression that nobody wants/cares about these hook plugins, but so many people are using them that really appreciate the work you've done.

The Mayor

2014-09-19 02:15:14

I dabbled in OGL scripting about a year ago, but gave up because of the 1fps after an hour. If there is no fps drop in DX then I'd be down for that (if it was compatible with colour too).

Brandon

2014-09-19 03:39:10

From: Clarity
Well then, it's safe to say I apparently have no idea what I was talking about in my previous post.
Thanks for explaining it clearly :)

Recurring theme though seems to be that DX hooking is infinitely better, perhaps we should switch? I've heard you have this impression that nobody wants/cares about these hook plugins, but so many people are using them that really appreciate the work you've done.



It is actually infinitely better. You can hook the camera for perfect walking AFAIK (don't quote me on that, but I'm pretty sure I'm right).. I believe it's SetTransform(DTS_VIEW). To get the view, world, projection, required for walking, etc.. That one function does all three depending on the flag supplied (DTS_VIEW, DTS_WORLD, DTS_PROJECTION). SetTexture(0, SomeTexturePointer) to hook textures.. DrawIndexPrimitive to hook models (as shown 3-4 posts above).

I do have that impression. It would NEVER get accepted into Simba's updater (unlike the colour plugins) even if it were to be 100% perfect with no problems. I can see why. It is actually a colour community and rightfully so. Though side projects are accepted and used, it just isn't the same.

I've seen things like: (Don't hook everything in osrs-reflection.. so that colour can still be used or because it can be done in colour just as well). Or "leave out some hook" or w/e. IMO, if you're doing something, you do it all and do it right, and THEN you can pick and choose use only what you want to user rather than limiting it but meh..

I'd still rather save myself time and energy instead of writing another plugin or at least adding onto the already existing ones. Maintenance would be hell.


Anyway, you guys can try this plugin and monitor the memory. I made sure that you guys cannot remove the memory printing info without re-compiling it. If you can get it to show that there is a leak/build up or anything above 5mb (for everything except Simba memory-maps needed for communication), then I will hunt it down. Otherwise, there isn't much I can do.

For whoever tests it, I hope you fail to find anything.


Attachment: [ATTACH=CONFIG]24035[/ATTACH]

Sample-Script (drag crosshairs on the client or browser.. I used the official client instead of SMART):


{$loadlib GLX}

type
GL_DEBUG_MODE = (GL_MODE_NONE, GL_MODE_TEXTURES, GL_MODE_MODELS, GL_MODE_FONTS, GL_MODE_DISPLAY);


var
Wnd: TNativeWindow;
W, H, ID: Integer;
begin
Wnd := GetNativeWindow(); //TY dgby714 && olly. Best thing ever.

if (GLXSetup(Wnd) and GLXMapHooks(Wnd)) then
begin
//GetClientDimensions(W, H);
//GLXDebug(Ord(GL_MODE_MODELS), ID, ID, ID, 10, 0, 0, W, H);
end else
writeln('Failed.');
end.

Run whatever scripts you have and screenshot the info displayed on screen when the memory gets high. Feel free to modify the plugin's source code and see if I did the calculations right.. I have a tendency to screw up bytes to megabytes and then have slacky or masterbb to correct me :)

The modifications are:


//Note to self.. Bytes to Megabytes are: 1 / (1024 * 1024).

EnableDrawing(Drawing[0], Drawing[1], Drawing[2]);
R.Print(50, 10, 255.0f, 255.0f, 0.0f, "Simba (Image + Debug MemoryMap): % mb", (SharedImageSize * 2) / (1024 * 1024));
R.Print(50, 20, 255.0f, 255.0f, 0.0f, "Simba (Hook MemoryMap): % mb", 5000000 / (1024 * 1024));
R.Print(50, 50, 255.0f, 255.0f, 0.0f, "sizeof(IDMap): % b -- sizeof(Texture): % b", sizeof(std::pair<unsigned int, std::tuple<unsigned int, unsigned int, unsigned int>>), sizeof(Texture));
R.Print(50, 60, 255.0f, 255.0f, 0.0f, "ID-Map Count: % -- Tex Count: %", Texture::IDMap.size(), Texture::Textures.size());
R.Print(50, 70, 255.0f, 255.0f, 0.0f, "ID-Map Mem(HashTable): % mb -- Tex Mem(rendered): % mb", (Texture::IDMap.size() * (sizeof(unsigned int) + sizeof(std::tuple<unsigned int, unsigned int, unsigned int>))) / (1024.0f * 1024.0f), (Texture::Textures.size() * sizeof(Texture)) / (1024.0f * 1024.0f));

R.Print(50, 100, 255.0f, 255.0f, 0.0f, "sizeof(Model): % b -- sizeof(ModelBuffer) % b", sizeof(Model), sizeof(ModelBuffer));
R.Print(50, 110, 255.0f, 255.0f, 0.0f, "Model Count: % -- Buffer Count: %", Model::Models.size(), ModelBuffer::Buffers.size());
R.Print(50, 120, 255.0f, 255.0f, 0.0f, "Buffer Mem(HashTable): % mb -- Model Mem(rendered): % mb", (ModelBuffer::Buffers.size() * sizeof(ModelBuffer)) / (1024.0f * 1024.0f), (Model::Models.size() * sizeof(Model)) / (1024.0f * 1024.0f));

R.Print(50, 150, 255.0f, 255.0f, 0.0f, "sizeof(Font): % b ", sizeof(Font));
R.Print(50, 160, 255.0f, 255.0f, 0.0f, "Font Count: % -- Rendered Font Count: %", Font::Fonts.size(), Font::RenderedFonts.size());
R.Print(50, 170, 255.0f, 255.0f, 0.0f, "Font Mem(HashTable): % mb -- Font Mem(rendered): % mb", (Font::Fonts.size() * sizeof(Font)) / (1024.0f * 1024.0f), (Font::RenderedFonts.size() * sizeof(Font)) / (1024.0f * 1024.0f));
DisableDrawing(Drawing[0], Drawing[1], Drawing[2]);


It will display:


riwu

2014-10-05 06:18:08

@Brandon
When there's more than 3 models at the same coordinate (eg. a loot pile), only 3 models are returned from glGetModels().
Possible to make it retrieve all the models? Or is it because RS blocked the other models so there's nothing we can do?

Brandon

2014-10-05 07:33:43

From: riwu
@Brandon
When there's more than 3 models at the same coordinate (eg. a loot pile), only 3 models are returned from glGetModels().
Possible to make it retrieve all the models? Or is it because RS blocked the other models so there's nothing we can do?


Only 3-5 are rendered at a time. It does not make sense for jagex to render every single model in a pile. They can try but OpenGL might not do it.

riwu

2014-10-05 08:23:17

From: Brandon
Only 3-5 are rendered at a time. It does not make sense for jagex to render every single model in a pile. They can try but OpenGL might not do it.

i see…
btw all the textures rendered seem to be 1 pixel bigger than its clickable area? (x2, y2)

Brandon

2014-10-05 09:38:01

From: riwu
i see…
btw all the textures rendered seem to be 1 pixel bigger than its clickable area? (x2, y2)



No idea what you mean. The plugin records ONLY what the game provides. It does not add one to the width or height.

https://github.com/Brandon-T/GLX/blob/master/OpenGL32/src/Hooks/Structures.cpp#L201

Hoodz

2014-10-05 17:19:49

From: Brandon
@riwu; I don't know what you mean it searches from left to right. It does not. It searches for whatever is rendered first in the exact order that it's rendered. If it happens to render from left to right, then that decision was made by Jagex.

The plugin captures in order of what is rendered. If a ruby is rendered before a diamond, it will capture ruby, then diamond and not the other way around.

If for whatever reason the rendering order changes, so will the capturing order. I don't think gl_InvSlots relies on order. It gets all the slot textures and just adds them in the order that they were retrieved (natural order). If slot 28 rendered before slot 1, then slot 28 would be the first slot.

gl_invSlots does not care about the order of inventory slots. It returns slots unsorted. If they happen to be sorted, Jagex had them sorted.


As for side-projects.. What projects? If you mean my signature, I was just messing around with hooking stuff because I was bored as hell and was just trying to find something challenging but when the challenge goes away, it's not fun anymore.

What DX or HTML plugin? I stopped development of the WebGL plugin as soon as I got it working.. Then I realised someone else had also had it working without "hooks": https://github.com/google/angle

For Direct-X, I just hooked models and their indices + vertices and textures.. but again, I never announced anything and there isn't anything to announce. If anyone wants the code, they can have it.



#include "Direct3DDevice9Proxy.hpp"
#include <d3dx9.h>


/** Generates a texture.. Can be used to re-colour models **/
void GenTexture(IDirect3DDevice9 *Device, std::uint8_t *buffer, int width, int height, IDirect3DTexture9 *&Texture)
{
Device->CreateTexture(width, height, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &Texture, 0);

D3DLOCKED_RECT rect;
Texture->LockRect(0, &rect, nullptr, D3DLOCK_DISCARD);
std::uint8_t *TexturePixels = static_cast<std::uint8_t *>(rect.pBits);
memcpy(TexturePixels, &buffer[0], width * height * 4);
Texture->UnlockRect(0);
}

/** Get's the vertex of the specified model at index **/
D3DXVECTOR3 GetVertex(std::uint8_t *vertices, std::int16_t index, std::uint16_t stride)
{
D3DXVECTOR3 res = {0};
memcpy(&res.x, &vertices[index * stride], sizeof(float));
memcpy(&res.y, &vertices[index * stride + sizeof(float)], sizeof(float));
memcpy(&res.z, &vertices[index * stride + sizeof(float) * 2], sizeof(float));
return res;
}

/** Iterates through all the vertices of a model.. Retrieves the index of that vertex as well as the X, Y, Z.. **/
void ProcessTriangleList(IDirect3DVertexBuffer9 *VertexBuffer, IDirect3DIndexBuffer9 *IndexBuffer, std::uint32_t BaseVertexIndex, std::uint32_t StartIndex, std::uint32_t PrimCount, std::uint32_t Stride)
{
std::uint8_t *vertices = NULL;
std::uint16_t *indices = NULL;
UINT EndIndex = StartIndex + (PrimCount * 3);

VertexBuffer->Lock(0, 0, reinterpret_cast<void **>(&vertices), 0);
IndexBuffer->Lock(0, PrimCount * 3 * sizeof(std::uint16_t), reinterpret_cast<void **>(&indices), 0);

for (UINT I = StartIndex; I < EndIndex; ++I)
{
D3DXVECTOR3 v = GetVertex(vertices, indices[I] + BaseVertexIndex, Stride); //store it somewhere.. check for duplicates in the storage.. Maybe write it to a .obj file and load that into blender.
}

IndexBuffer->Unlock();
VertexBuffer->Unlock();
}

/** Same as above **/
void ProcessTriangleStrip(IDirect3DVertexBuffer9 *VertexBuffer, IDirect3DIndexBuffer9 *IndexBuffer, std::uint32_t BaseVertexIndex, std::uint32_t StartIndex, std::uint32_t PrimCount, std::uint32_t Stride)
{
std::uint8_t *vertices = NULL;
std::uint16_t *indices = NULL;
UINT EndIndex = StartIndex + PrimCount;

VertexBuffer->Lock(0, 0, reinterpret_cast<void **>(&vertices), 0);
IndexBuffer->Lock(0, PrimCount * 3 * sizeof(std::uint16_t), reinterpret_cast<void **>(&indices), 0);

for (UINT I = StartIndex; I < EndIndex; ++I)
{
GetVertex(vertices, indices[I] + BaseVertexIndex, Stride); //store it somewhere.. check for duplicates in the storage..
}

IndexBuffer->Unlock();
VertexBuffer->Unlock();
}

HRESULT Direct3DDevice9Proxy::DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount)
{
static UINT stride = 0;
static UINT offset = 0;
static IDirect3DTexture9 *tex = NULL;

if (!tex)
{
DWORD col = D3DCOLOR_RGBA(255, 0, 0, 128);
GenTexture(ptr_Direct3DDevice9, (uint8_t *)&col, 1, 1, tex); //generate a red texture.. re-colour specified models red..
//if (ModelID == 1916)
// ptr_Direct3DDevice9->SetTexture(0, tex); //colour my player's model red..
}

IDirect3DIndexBuffer9 *ppIndexData = NULL;
IDirect3DVertexBuffer9 *ppVertexData = NULL;

ptr_Direct3DDevice9->GetIndices(&ppIndexData);
ptr_Direct3DDevice9->GetStreamSource(0, &ppVertexData, &offset, &stride);


//call process TriangleStrip or TriangleList to get every vertex of said model.. Otherwise WorldToScreen(0, 0, 0) to get the center of the model.

ppIndexData->Release();
ppVertexData->Release();

return ptr_Direct3DDevice9->DrawIndexedPrimitive(PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
}


That's all I did. Well.. I did more (ESP, see through walls, etc..) but meh.. The above is enough to hook models for any and all games. I was able to rip the models from the game and load them in blender (.obj format).. It was pretty neat. Too much work for me though and it got boring. I basically just abandoned it all. The same code/logic can actually be used in OpenGL but laziness. FPS doesn't drop in Direct-X at all; which I found weird lol.

Other than that, I don't have any projects I'm working on and I don't plan to release anything.. I only have to support the colour plugins if things break and I'm happy enough doing that.

when are you going to release this? (talking about the directX hook)

Ross

2014-10-05 17:27:43

From: Brandon
It is actually a colour community and rightfully so. Though side projects are accepted and used, it just isn't the same.


While I understand exactly what you're saying here, I can probably speak for many people in saying that this would be used for many, many large projects. I have tons of script ideas that I simply cannot fathom doing entirely in colour.

Also, colour compatibility will help maintain community spirit :)

The Mayor

2014-10-05 17:57:48

From: Ross
While I understand exactly what you're saying here, I can probably speak for many people in saying that this would be used for many, many large projects. I have tons of script ideas that I simply cannot fathom doing entirely in colour.

Also, colour compatibility will help maintain community spirit :)


And some things are just easier and more accurate to do in colour, so definitely need compatibility :D

Brandon

2014-10-05 18:23:27

From: hoodz
when are you going to release this? (talking about the directX hook)


I understand everyone wants a sort of reflection for RS3 and I understand the OpenGL plugin is absolute crap and is barely usable.. but..

I don't know :S
I never planned to do another hook plugin. There's not really anyone around that would be able to work on it with me. I get bored working on things.. Villavu alone has seen a TON of my abandoned scripts and projects. Very few programmers around here took game programming or are only used to engines and api's (not raw api's), so I'd be soloing this one. Direct-X debuggers are scarce or really crap so you'll either have to know assembly or a deep deep understanding of what's going on (and I mean deep! because Jagex).

I had help with the OpenGL plugin (from Kasi) but that took long.. Believe me.. We both stayed up nights working on that thing to try and fix the problems with it. Sometimes I went to sleep, woke up and saw him still online working on it and vice-versa.. But he had to learn some OpenGL from scratch to help out with that.

It's also completely different from OpenGL (I really really mean that).. On top of all the game programming is the language itself. HLSL (shader language and shader assembly) and C or C++ (main programming language for Direct-X.. although you can use Pascal or Delphi).

Direct-X is easier but still time consuming. I don't mind publishing what I currently have at all. Whether I plan to continue it is a different story.

I honestly don't mind publishing it or making a github for it. Maybe if I feel like working on it, I could push updates in increments but honestly, I CANNOT PROMISE anything.


Not sure if you were around when Mato was here, but he was good at Direct-X and barely scratched the surface (around the same time I was writing the OpenGL hooks). IIRC he had models and texture ID generation but that was about the most I saw and he left no source or a very very incomplete source.

I'll try to publish what I have or github it soon. If I do ever work on this again, I'd really really have to sit down and plan out every step. I'd have to think of what features to put in and the implementation, etc..

Kasi

2014-10-05 18:34:42

@Brandon; I wouldn't mind helping out with a new plugin, work at uni is piss and i have a 13 hour timetable, shit is more feasible now then it was back then. However saying that, completely up to you if you wanna do it or not, all i'm saying ill be around to help if wanted.

Clarity

2014-10-05 18:41:04

From: Brandon
I understand everyone wants a sort of reflection for RS3 and I understand the OpenGL plugin is absolute crap and is barely usable.. but..

I don't know :S
I never planned to do another hook plugin. There's not really anyone around that would be able to work on it with me. I get bored working on things.. Villavu alone has seen a TON of my abandoned scripts and projects. Very few programmers around here took game programming or are only used to engines and api's (not raw api's), so I'd be soloing this one. Direct-X debuggers are scarce or really crap so you'll either have to know assembly or a deep deep understanding of what's going on (and I mean deep! because Jagex).

I had help with the OpenGL plugin (from Kasi) but that took long.. Believe me.. We both stayed up nights working on that thing to try and fix the problems with it. Sometimes I went to sleep, woke up and saw him still online working on it and vice-versa.. But he had to learn some OpenGL from scratch to help out with that.

It's also completely different from OpenGL (I really really mean that).. On top of all the game programming is the language itself. HLSL (shader language and shader assembly) and C or C++ (main programming language for Direct-X.. although you can use Pascal or Delphi).

Direct-X is easier but still time consuming. I don't mind publishing what I currently have at all. Whether I plan to continue it is a different story.

I honestly don't mind publishing it or making a github for it. Maybe if I feel like working on it, I could push updates in increments but honestly, I CANNOT PROMISE anything.


Not sure if you were around when Mato was here, but he was good at Direct-X and barely scratched the surface (around the same time I was writing the OpenGL hooks). IIRC he had models and texture ID generation but that was about the most I saw and he left no source or a very very incomplete source.

I'll try to publish what I have or github it soon. If I do ever work on this again, I'd really really have to sit down and plan out every step. I'd have to think of what features to put in and the implementation, etc..

While I don't have the knowhow you say is required, I'm happy to test anything work-in-progress if needed.

riwu

2014-10-05 19:46:52

I have no knowledge of dx hooking/c++, so i couldnt help with the plugin…
but i'd definitely help out with building and maintaining the include from scratch, all i need are the functions equivalent to those in glxcore.simba. So u won't have to build/maintain the include if that's what u cant be bothered with.

Also u mentioned before an ogl plugin w/o texture hooks wont have any leaks? but arent the textures already inherently present in the game? (i.e. playing rs w/o the plugin still cause leaks).

NKN

2014-10-05 20:49:52

From: Brandon
I understand everyone wants a sort of reflection for RS3 and I understand the OpenGL plugin is absolute crap and is barely usable.. but..

I don't know :S
I never planned to do another hook plugin. There's not really anyone around that would be able to work on it with me. I get bored working on things.. Villavu alone has seen a TON of my abandoned scripts and projects. Very few programmers around here took game programming or are only used to engines and api's (not raw api's), so I'd be soloing this one. Direct-X debuggers are scarce or really crap so you'll either have to know assembly or a deep deep understanding of what's going on (and I mean deep! because Jagex).

I had help with the OpenGL plugin (from Kasi) but that took long.. Believe me.. We both stayed up nights working on that thing to try and fix the problems with it. Sometimes I went to sleep, woke up and saw him still online working on it and vice-versa.. But he had to learn some OpenGL from scratch to help out with that.

It's also completely different from OpenGL (I really really mean that).. On top of all the game programming is the language itself. HLSL (shader language and shader assembly) and C or C++ (main programming language for Direct-X.. although you can use Pascal or Delphi).

Direct-X is easier but still time consuming. I don't mind publishing what I currently have at all. Whether I plan to continue it is a different story.

I honestly don't mind publishing it or making a github for it. Maybe if I feel like working on it, I could push updates in increments but honestly, I CANNOT PROMISE anything.


Not sure if you were around when Mato was here, but he was good at Direct-X and barely scratched the surface (around the same time I was writing the OpenGL hooks). IIRC he had models and texture ID generation but that was about the most I saw and he left no source or a very very incomplete source.

I'll try to publish what I have or github it soon. If I do ever work on this again, I'd really really have to sit down and plan out every step. I'd have to think of what features to put in and the implementation, etc..


I mean my C++ isn't fantastic, but I'd actually sit down and learn how to maintain/update the plugin if you decide to push it to github. Shouldn't be too hard, am I right? :')

Olly

2014-10-05 21:38:55

From: Brandon
…


Do it in pascal. ;)

Brandon

2014-10-06 01:23:38

@Kasi; Thanks.

From: Olly
Do it in pascal. ;)


Too late.. I uploaded it already and I don't think I want to port to PS.. too much typing.. Language is too wordy for me (maybe in the future).. You guys can find it here: https://github.com/Brandon-T/Genevieve

I didn't know what to call it but I like that name so that it is.. Do whatever you want with it. I dumped all the important crap into the main file, math file, and graphics files.. A lot of it is incomplete but that's the very BASIC amount you'd need to do anything at all (other than screen-scraping).

In fact, if you use the functions in there right now, you'd have models hooked and textures hooked and you'd be able to debug things on screen. Just have to put it together and feed it to Simba.

Models are rendered with stride 12. Floors are stride 16 or 20. Minimap is drawn with DrawPrimitive. Models and textures are drawn with DrawIndexedPrimitive. A model is rendered either when the stride is 12 or when SetStreamSource is called with StreamNumber being 0.
WorldViewProjection is stored in the shader register C0 and is size 4.

Now everyone can work on it.. If you use the classes written, you will find that it is impossible to leak any resources (even if exceptions are thrown).. This design concept is known as RAII:

http://en.wikipedia.org/wiki/Resource_Acquisition_Is_Initialization

The code ONLY uses RAII. No resources/memory are manually allocated. Heavy use of C++11, very little ASMx86. Anyway.. enough talk of Direct-X on this OpenGL thread. It's too unorganised.

Again.. it just needs putting together..

Brandon

2014-10-06 23:30:38

Slight update.. I don't feel like making a D3D hook thread atm..

http://i.imgur.com/v3jlME2.png
http://i.imgur.com/YhhRANM.png

The below code is injected into the game. I didn't get around to making the game "load" it instead of injecting. It's faster to test stuff via injection rather than loading SMART or placing modules in the bin folder. Simple VTable hook really.

Models hooks are pretty much (almost) complete.. I dumped everything into one file to make the post shorter.. Doesn't look like a lot but it uses all the code from the github so yeah..:


#include <windows.h>
#include <iostream>
#include <d3d9.h>
#include <d3dx9.h>
#include <detours.h>
#include <thread>
#include <cstdint>
#include <memory>
#include <fstream>
#include "Graphics.hxx"

#pragma comment(lib, "WS2_32.lib")
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
#pragma comment(lib, "detours.lib")

enum D3D9_vTable
{
QUERYINTERFACE,
ADDREF,
RELEASE,
TESTCOOPERATIVELEVEL,
GETAVAILABLETEXTUREMEM,
EVICTMANAGEDRESOURCES,
GETDIRECT3D,
GET_DEVICE_CAPS,
GETDISPLAYMODE,
GETCREATIONPARAMETERS,
SETCURSORPROPERTIES,
SETCURSORPOSITION,
SHOW_CURSOR,
CREATEADDITIONALSWAPCHAIN,
GETSWAPCHAIN,
GETNUMBEROFSWAPCHAINS,
RESET,
PRESENT,
GETBACKBUFFER,
GETRASTERSTATUS,
SETDIALOGBOXMODE,
GETGAMMARAMP,
SETGAMMARAMP,
CREATETEXTURE,
CREATEVOLUMETEXTURE,
CREATECUBETEXTURE,
CREATEVERTEXBUFFER,
CREATEINDEXBUFFER,
CREATERENDERTARGET,
CREATEDEPTHSTENCILSURFACE,
UPDATESURFACE,
UPDATETEXTURE,
GETRENDERTARGETDATA,
GETFRONTBUFFERDATA,
STRETCHRECT,
COLORFILL,
CREATEOFFSCREENPLAINSURFACE,
SETRENDERTARGET,
GETRENDERTARGET,
SETDEPTHSTENCILSURFACE,
GETDEPTHSTENCILSURFACE,
BEGINSCENE,
ENDSCENE,
CLEAR,
SETTRANSFORM,
GETTRANSFORM,
MULTIPLYTRANSFORM,
SETVIEWPORT,
GETVIEWPORT,
SETMATERIAL,
GETMATERIAL,
SETLIGHT,
GETLIGHT,
LIGHTENABLE,
GETLIGHTENABLE,
SETCLIPPLANE,
GETCLIPPLANE,
SETRENDERSTATE,
GETRENDERSTATE,
CREATESTATEBLOCK,
BEGINSTATEBLOCK,
ENDSTATEBLOCK,
SETCLIPSTATUS,
GETCLIPSTATUS,
GETTEXTURE,
SETTEXTURE,
GETTEXTURESTAGESTATE,
SETTEXTURESTAGESTATE,
GETSAMPLERSTATE,
SETSAMPLERSTATE,
VALIDATEDEVICE,
SET_PALETTE_ENTRIES,
GET_PALETTE_ENTRIES,
SETCURRENTTEXTUREPALETTE,
GETCURRENTTEXTUREPALETTE,
SETSCISSORRECT,
GETSCISSORRECT,
SETSOFTWAREVERTEXPROCESSING,
GETSOFTWAREVERTEXPROCESSING,
SETNPATCHMODE,
GETNPATCHMODE,
DRAWPRIMITIVE,
DRAWINDEXEDPRIMITIVE,
DRAWPRIMITIVEUP,
DRAWINDEXEDPRIMITIVEUP,
PROCESSVERTICES,
CREATEVERTEXDECLARATION,
SETVERTEXDECLARATION,
GETVERTEXDECLARATION,
SETFVF,
GETFVF,
CREATEVERTEXSHADER,
SETVERTEXSHADER,
GETVERTEXSHADER,
SETVERTEXSHADERCONSTANTF,
GETVERTEXSHADERCONSTANTF,
SETVERTEXSHADERCONSTANTI,
GETVERTEXSHADERCONSTANTI,
SETVERTEXSHADERCONSTANTB,
GETVERTEXSHADERCONSTANTB,
SETSTREAMSOURCE,
GETSTREAMSOURCE,
SETSTREAMSOURCEFREQ,
GETSTREAMSOURCEFREQ,
SETINDICES,
GETINDICES,
CREATEPIXELSHADER,
SETPIXELSHADER,
GETPIXELSHADER,
SETPIXELSHADERCONSTANTF,
GETPIXELSHADERCONSTANTF,
SETPIXELSHADERCONSTANTI,
GETPIXELSHADERCONSTANTI,
SETPIXELSHADERCONSTANTB,
GETPIXELSHADERCONSTANTB,
DRAWRECTPATCH,
DRAWTRIPATCH,
DELETEPATCH,
CREATEQUERY,
};

typedef HRESULT(__stdcall *EndScene_t)(LPDIRECT3DDEVICE9 pDevice);
typedef HRESULT(__stdcall *BeginScene_t)(LPDIRECT3DDEVICE9 pDevice);
typedef HRESULT(__stdcall *Reset_t)(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS *pPresentationParameters);
typedef HRESULT(__stdcall *DrawPrimitive_t)(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount);
typedef HRESULT(__stdcall *DrawIndexedPrimitive_t)(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount);
typedef HRESULT(__stdcall *DrawPrimitiveUP_t)(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride);
typedef HRESULT(__stdcall *DrawIndexedPrimitiveUP_t)(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride);
typedef HRESULT(__stdcall *SetTexture_t)(LPDIRECT3DDEVICE9 pDevice, DWORD Sampler, IDirect3DBaseTexture9 *pTexture);

BeginScene_t o_BeginScene;
EndScene_t o_EndScene;
Reset_t o_Reset;
DrawPrimitive_t o_DrawPrimitive;
DrawIndexedPrimitive_t o_DrawIndexedPrimitive;
DrawPrimitiveUP_t o_DrawPrimitiveUP;
DrawIndexedPrimitiveUP_t o_DrawIndexedPrimitiveUP;
SetTexture_t o_SetTexture;
Font* font = NULL;

HRESULT __stdcall DXI_BeginScene(LPDIRECT3DDEVICE9 pDevice)
{
static bool init = false;
if (!init)
{
init = true;
font = new Font(pDevice, "Arial", 8);
}
return o_BeginScene(pDevice);
}

HRESULT __stdcall DXI_EndScene(LPDIRECT3DDEVICE9 pDevice)
{
if (font)
font->Draw(50, 50, "HELLO");
return o_EndScene(pDevice);
}

//When the application is minimised, resources are destroyed and rebuilt automatically. It's how d3d works.
HRESULT __stdcall DXI_Reset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS *pPresentationParameters)
{
if (font)
font->OnLostDevice();

HRESULT res = o_Reset(pDevice, pPresentationParameters);

if (font)
font->OnResetDevice();

return res;
}

HRESULT __stdcall DXI_DrawPrimitive(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount)
{
IDirect3DBaseTexture9* tex = nullptr;
if (SUCCEEDED(pDevice->GetTexture(0, &tex)))
{
LPDIRECT3DTEXTURE9 _tex = (LPDIRECT3DTEXTURE9)tex;
D3DSURFACE_DESC desc;
if (SUCCEEDED(_tex->GetLevelDesc(0, &desc)))
{
if (desc.Width && desc.Height) //51 x 51 = mini-map compass. Better to check on the Simba side. 512 x 512 = map.
{
D3DXMATRIX WVP;
if (SUCCEEDED(pDevice->GetVertexShaderConstantF(0, (float*)&WVP, 4)))
{
D3DXMatrixTranspose(&WVP, &WVP);

D3DXVECTOR3 out;
D3DXVECTOR3 in(0, 0, 0);
D3DXVec3TransformCoord(&out, &in, &WVP);

D3DVIEWPORT9 viewport;
pDevice->GetViewport(&viewport);

out.x = (out.x + 1.0f) * viewport.Width * 0.5f + viewport.X;
out.y = (1.0f - out.y) * viewport.Height * 0.5f + viewport.Y;

if (font)
font->Draw(out.x, out.y, "Compass(%, %)", desc.Width, desc.Height);
}
}
}
tex->Release();
}
return o_DrawPrimitive(pDevice, PrimitiveType, StartVertex, PrimitiveCount);
}

//function in which both textures AND models are drawn. Textures have a primCount of 2 and NumVertices of 4. Basically 2 triangles make up one square/rectangular texture.
//models otherwise..
HRESULT __stdcall DXI_DrawIndexedPrimitive(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount)
{
DWORD ID = GenerateID(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
D3DXVECTOR3 out = WorldToScreen(pDevice); //Get the base center point of the model.. For more advanced accuracy, you can use ProcessVerts to get each and every vertex of said model (fingers, eyes, etc..)

static bool debug = false;
if (GetAsyncKeyState(VK_END) & 1)
debug = !debug;

if (font && debug)
font->Draw(out.x, out.y, 0xFFFF0000, "%", ID);

return o_DrawIndexedPrimitive(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);
}

HRESULT __stdcall DXI_DrawPrimitiveUP(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT PrimitiveCount, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride)
{
return o_DrawPrimitiveUP(pDevice, PrimitiveType, PrimitiveCount, pVertexStreamZeroData, VertexStreamZeroStride);
}

HRESULT __stdcall DXI_DrawIndexedPrimitiveUP(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT MinVertexIndex, UINT NumVertices, UINT PrimitiveCount, CONST void* pIndexData, D3DFORMAT IndexDataFormat, CONST void* pVertexStreamZeroData, UINT VertexStreamZeroStride)
{
return o_DrawIndexedPrimitiveUP(pDevice, PrimitiveType, MinVertexIndex, NumVertices, PrimitiveCount, pIndexData, IndexDataFormat, pVertexStreamZeroData, VertexStreamZeroStride);
}

HRESULT __stdcall DXI_SetTexture(LPDIRECT3DDEVICE9 pDevice, DWORD Sampler, IDirect3DBaseTexture9 *pTexture)
{
return o_SetTexture(pDevice, Sampler, pTexture);
}

DWORD __stdcall InitialiseHooks(void* param);

bool __stdcall DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
DisableThreadLibraryCalls(hinstDLL);
CreateThread(NULL, 0, InitialiseHooks, NULL, 0, 0);
return true;

case DLL_PROCESS_DETACH:
break;

default:
break;
}
return true;
}

DWORD FindPattern(DWORD dwAddress, DWORD dwLen, BYTE *bMask, const char* szMask)
{
auto bCompare = [](const BYTE* pData, const BYTE* bMask, const char* szMask) -> bool
{
for (; *szMask; ++szMask, ++pData, ++bMask)
if (*szMask == 'x' && *pData != *bMask)
return 0;
return (*szMask) == 0;
};

for (DWORD i = 0; i < dwLen; ++i)
if (bCompare(reinterpret_cast<std::uint8_t*>(dwAddress + i), bMask, szMask))
return static_cast<DWORD>(dwAddress + i);
return 0;
}

template<typename T, typename U>
void DetourFunction(T &OriginalFunction, U HookFunction)
{
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&reinterpret_cast<void*&>(OriginalFunction), reinterpret_cast<void*>(HookFunction));
DetourTransactionCommit();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
}

DWORD WINAPI VTableRepatch(void* param)
{
while (true)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
DetourFunction(o_BeginScene, DXI_BeginScene);
DetourFunction(o_EndScene, DXI_EndScene);
DetourFunction(o_Reset, DXI_Reset);
DetourFunction(o_DrawPrimitive, DXI_DrawPrimitive);
DetourFunction(o_DrawIndexedPrimitive, DXI_DrawIndexedPrimitive);
DetourFunction(o_DrawPrimitiveUP, DXI_DrawPrimitiveUP);
DetourFunction(o_DrawIndexedPrimitiveUP, DXI_DrawIndexedPrimitiveUP);
DetourFunction(o_SetTexture, DXI_SetTexture);
}
return 0;
}

DWORD __stdcall InitialiseHooks(void* param)
{
while (!GetModuleHandle("d3d9.dll"))
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}

DWORD* VTable = nullptr;
std::this_thread::sleep_for(std::chrono::milliseconds(100));
static std::uint8_t bMask[] = { 0xC7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x89, 0x86, 0x00, 0x00, 0x00, 0x00, 0x89, 0x86 };
DWORD Address = FindPattern(reinterpret_cast<DWORD>(GetModuleHandle("d3d9.dll")), 0x128000, bMask, "xx????xx????xx");
memcpy(&VTable, reinterpret_cast<void*>(Address + 2), 4);

o_BeginScene = reinterpret_cast<BeginScene_t>(VTable[BEGINSCENE]);
o_EndScene = reinterpret_cast<EndScene_t>(VTable[ENDSCENE]);
o_Reset = reinterpret_cast<Reset_t>(VTable[RESET]);
o_DrawPrimitive = reinterpret_cast<DrawPrimitive_t>(VTable[DRAWPRIMITIVE]);
o_DrawIndexedPrimitive = reinterpret_cast<DrawIndexedPrimitive_t>(VTable[DRAWINDEXEDPRIMITIVE]);
o_DrawPrimitiveUP = reinterpret_cast<DrawPrimitiveUP_t>(VTable[DRAWPRIMITIVEUP]);
o_DrawIndexedPrimitiveUP = reinterpret_cast<DrawIndexedPrimitiveUP_t>(VTable[DRAWINDEXEDPRIMITIVEUP]);
o_SetTexture = reinterpret_cast<SetTexture_t>(VTable[SETTEXTURE]);

DetourFunction(o_BeginScene, DXI_BeginScene);
DetourFunction(o_EndScene, DXI_EndScene);
DetourFunction(o_Reset, DXI_Reset);
DetourFunction(o_DrawPrimitive, DXI_DrawPrimitive);
DetourFunction(o_DrawIndexedPrimitive, DXI_DrawIndexedPrimitive);
DetourFunction(o_DrawPrimitiveUP, DXI_DrawPrimitiveUP);
DetourFunction(o_DrawIndexedPrimitiveUP, DXI_DrawIndexedPrimitiveUP);
DetourFunction(o_SetTexture, DXI_SetTexture);
CreateThread(NULL, 0, VTableRepatch, NULL, 0, 0);
return 0;
}


With this, the FPS is at 50. FPS drops a bit when drawing the ID's on screen but when you run a script you won't be drawing them on screen anyway so that doesn't matter. What matters is the FPS while the script is running or while you are playing and that itself is at 50-53 (I haven't seen lower). Drawing the ID's with D3DXFont is extremely slow ={ I will speed it up later by drawing them manually. Memory usage is nice too. I haven't noticed any lag. There's no leaks. I tested only the above. I got Kasi to test it. He didn't test FPS but it was running very nicely.

I took a look at hooking textures. I have to find a way to save textures to the disk and to generate ID's in memory (my current code for saving and generating crashes because the textures aren't stored in ram.. I might have to wrap IDirect3DTexture9). Will take some time to figure out. I just finally got an OKAY debugger to help me.. Before everything was just assembly..

I dumped shaders such as below:


// Parameters:
//
// float4 DistanceFogPlane;
// float4 HeightFogPlane;
// float4x2 TexCoordMatrix;
// float4x4 WVPMatrix;
//
//
// Registers:
//
// Name Reg Size
// ---------------- ----- ----
// WVPMatrix c0 4
// TexCoordMatrix c4 2
// DistanceFogPlane c6 1
// HeightFogPlane c7 1
//

vs_2_0
def c8, 0, 1, 0, 0
dcl_position v0
dcl_texcoord v1
dcl_color v2
dp4 oPos.x, v0, c0
dp4 oPos.y, v0, c1
dp4 oPos.z, v0, c2
dp4 oPos.w, v0, c3
dp4 oT0.x, v1, c4
dp4 oT0.y, v1, c5
dp4 r0.x, v0, c7
max r0.x, r0.x, c8.x
min oT4.x, r0.x, c8.y
dp4 r0.x, v0, c6
max r0.x, r0.x, c8.x
min oT4.y, r0.x, c8.y
mov oD0, v2
mov oT0.zw, c8.x
mov oT1.xyz, c8.x
mov oT2.xyz, c8.y
mov oT3.xyz, c8.x
mov oT5, c8.x
mov oT6.xyz, c8.x
mov oT7, c8.x

// approximately 20 instruction slots used



// Parameters:
//
// sampler2D SpriteSampler;
//
//
// Registers:
//
// Name Reg Size
// ------------- ----- ----
// SpriteSampler s0 1
//

ps_2_0
dcl t0.xy
dcl v0
dcl_2d s0
texld r0, t0, s0
mul r0, r0, v0
mov oC0, r0

// approximately 3 instruction slots used (1 texture, 2 arithmetic)



// Parameters:
//
// sampler2D DiffuseSampler;
// float3 DistanceFogColour;
// float3 HeightFogColour;
//
//
// Registers:
//
// Name Reg Size
// ----------------- ----- ----
// DistanceFogColour c0 1
// HeightFogColour c1 1
// DiffuseSampler s0 1
//

ps_2_0
def c2, 0, 0, 0, 0
dcl v0
dcl t0.xy
dcl t2.xyz
dcl t4.xy
dcl_2d s0
texld r0, t0, s0
mul r0.xyz, r0, v0
mul r1.xyz, r0, t2
mad r0.xyz, r0, -t2, c1
mov r1.w, v0.w
mov r0.w, c2.x
mad r0, t4.x, r0, r1
add r1.xyz, -r0, c0
mov r1.w, c2.x
mad r0, t4.y, r1, r0
mov oC0, r0

// approximately 11 instruction slots used (1 texture, 10 arithmetic)


//...
vs_2_0
dcl_position v0
dcl_texcoord v1
dcl_color v2
mov oPos, v0
mov oT0.xy, v1
mov oD0, v2

// approximately 3 instruction slots used



// Parameters:
//
// float4x2 TexCoordMatrix;
// float4x4 WVPMatrix;
//
//
// Registers:
//
// Name Reg Size
// -------------- ----- ----
// WVPMatrix c0 4
// TexCoordMatrix c4 2
//

vs_2_0
def c6, 0, 0, 0, 0
dcl_position v0
dcl_color v1
dcl_texcoord v2
dp4 oPos.x, v0, c0
dp4 oPos.y, v0, c1
dp4 oPos.z, v0, c2
dp4 oPos.w, v0, c3
dp4 oT0.x, v2, c4
dp4 oT0.y, v2, c5
mov oD0, v1
mov oT1.x, c6.x

// approximately 8 instruction slots used


It's pretty annoying having to go through these things.. It's a lot harder than OpenGL by far :l There's not really any good debuggers for d3d. PIX (a Microsoft Direct-X debugger) is detected by Jaclib and automatically terminates the process.. You can't just debug RS just like that. It detects it -_-


It detects it because PIX and Olly-Dbg because they start the game process rather than injecting to it during run-time. Olly-Dbg has the phantom plugin but you can't really use Olly-Dbg for Direct-X.

So yeah.. It's hard ={ I'll get it done but I got other things to do as well.. Just thought you guys could see how things are done and if you know anything you can contrib..

Brandon

2014-10-08 03:04:11

Meh.. another boring update.. Most textures hooked.. I didn't get all of them but most.. I have to check what functions are being called or what params are being called for the rest but w/e.. Still progress I guess.

http://i.imgur.com/n3yTYI6.png

EDIT:
http://i.imgur.com/LtgrqYD.png
http://i.imgur.com/NfI7740.png

Hooked the rest of them.. including bitmap fonts -_-.. Now I gotta figure out which is textures and which is fonts.. and generate ID's.. bleh.. -_-..

And the code for that is below.. The cords are not in screen.. Even the mini-map trees are coloured..:


void GetTextureCoords(LPDIRECT3DDEVICE9 pDevice, IDirect3DVertexBuffer9 *VertexBuffer, IDirect3DIndexBuffer9 *IndexBuffer, std::uint32_t BaseVertexIndex, std::uint32_t StartIndex, std::uint32_t PrimCount, std::uint32_t Stride)
{
std::uint8_t *vertices = NULL;
std::uint16_t *indices = NULL;
UINT EndIndex = StartIndex + (PrimCount * 3);

VertexBuffer->Lock(0, 0, reinterpret_cast<void **>(&vertices), 0);
IndexBuffer->Lock(0, PrimCount * 3 * sizeof(std::uint16_t), reinterpret_cast<void **>(&indices), 0);

for (UINT I = StartIndex, J = 0; I < EndIndex; ++I, ++J)
{
D3DXVECTOR3 v = GetVertex(vertices, indices[I] + BaseVertexIndex, Stride);
verts[J].x = v.x;
verts[J].y = v.y;
verts[J].z = v.z;
verts[J].color = D3DCOLOR_ARGB(50, 255, 128, 255);
}

IndexBuffer->Unlock();
VertexBuffer->Unlock();
}

HRESULT __stdcall DXI_DrawIndexedPrimitive(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount)
{
DWORD ID = ...;
D3DXVECTOR3 out = WorldToScreen(pDevice);

static bool debug = false;
if (GetAsyncKeyState(VK_END) & 1)
debug = !debug;

if (font && debug)
font->Draw(out.x, out.y, 0xFFFF0000, "%", ID);

o_DrawIndexedPrimitive(pDevice, PrimitiveType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount);

if (NumVertices == 4 && primCount == 2)
{
if (PrimitiveType == D3DPT_TRIANGLELIST)
{
IDirect3DVertexBuffer9* vb = nullptr;
IDirect3DIndexBuffer9* ib = nullptr;

UINT offset, stride;
pDevice->GetIndices(&ib);
pDevice->GetStreamSource(0, &vb, &offset, &stride);
GetTextureCoords(pDevice, vb, ib, BaseVertexIndex, startIndex, primCount, stride);
ib->Release();
vb->Release();

IDirect3DStateBlock9* block;
pDevice->CreateStateBlock(D3DSBT_ALL, &block);
block->Capture();

pDevice->SetRenderState(D3DRS_LIGHTING, FALSE);
pDevice->SetRenderState(D3DRS_FOGENABLE, FALSE);
pDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
pDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);
pDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
pDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD);
pDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
pDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
pDevice->SetTexture(0, nullptr);
pDevice->SetPixelShader(nullptr);
pDevice->SetVertexShader(nullptr);

#define CUSTOMFVF (D3DFVF_XYZ | D3DFVF_DIFFUSE)
pDevice->SetFVF(CUSTOMFVF);
pDevice->SetTexture(0, nullptr);
pDevice->DrawPrimitiveUP(D3DPT_TRIANGLELIST, 2, &verts[0], sizeof(CUSTOMVERTEX));
block->Apply();
block->Release();
}
}
return D3D_OK; //bad idea.. fix later.
}

The Mayor

2014-10-08 03:18:41

Very impressive. It's nice to hear that the fps is stable and there are no leaks :D I don't know C++ but I'm down to help write an include!

E: Nice scholar cup, I want!

riwu

2014-10-08 07:55:36

Thanks for all the great work Brandon! Looking forward for the dx hook plugin!
Btw is it better to just store model IDs as Integer and let it stretch from negative 2.1bil to positive 2.1b? This would make coding easier as u dont have to cast like glGetModels(TCardinalArray[])

Clarity

2014-10-08 07:59:00

This looks awesome! I would be happy to work on the include as well.

Ashaman88

2014-10-08 08:46:23

@Brandon; you are a scholar and a gentleman. Keep it up!

riwu

2014-12-17 20:54:18

@Brandon
Thanks for updating the plugin, the new version is able to grab some very useful textures! Really appreciate the great work!

I have a few problems with the opengl plugin though, i didnt post as i thought that u will no longer bother to update it. Seeing that u have just updated the plugin i might as well post it if you are interested to fix them :)

Problems with GLX v3.6 (i haven't test on v3.7 extensively to confirm if they still exist)
1.
Occasionally GLXMapCoords returns wrong values for me; at the exact same spot, GL_GetLocalPos would sometimes return different values after restarting smart (i have to restart smart again to fix it)

2.
Sometimes the script got stuck in GLXTextures/GLXModels/GLXFonts/GLXMapCoords, i added debug right before and after them so i'm pretty sure they are stuck in the plugin method.

GLX 3.7:
1.
Most of the new textures from v3.7 seem to have their x2 > x1 or y2 > y1. I have never come across it in v3.6 (except for texts) as i have the following code in most GLXCore methods:

if ((Result[J].Bounds.X2 < Result[J].Bounds.X1) or (Result[J].Bounds.Y2 < Result[J].Bounds.Y1)) then
begin
writeln('x2>x1/y2>y1/y2>y1 in glgettextures!' + toStr(Result[J]));
TerminateScript;
end;
Not a huge problem though as i can simply swap them, but some previously grabbed textures in v3.6 are not present in v3.7. eg. at bank screen.
v3.6 has
{ID = 13769, COLOURID = 2835022, FULLCOLOURID = 3295314, X = 394, Y = 567, BOUNDS = {X1 = 390, Y1 = 563, X2 = 397, Y2 = 570}}
In v3.7, this is replaced by
{ID = 13769, COLOURID = 2835022, FULLCOLOURID = 3295314, X = 369, Y = 575, BOUNDS = {X1 = 348, Y1 = 587, X2 = 389, Y2 = 562}}
So far i haven't come across any crucial textures that i've used in v3.6 that are missing in v3.7 though.

2.
I couldn't compile the latest source, gives the following error
…\GLX-master\OpenGL32\src\Hooks\Hooks.cpp|227|error: invalid conversion from 'int (*)()' to 'PROC {aka long long int (*)()}' [-fpermissive]|
at lines containing

return reinterpret_cast<int (__stdcall *)()>(GLHook_glBindBufferARB);

3. Previously u gave me an update that removed maps to improve fps

For maps.. I had removed: https://github.com/Brandon-T/GLX/blob/master/OpenGL32/src/Hooks/Structures.cpp#L60

I compared my version to your latest version it seems like u haven't removed that in your latest version?

Brandon

2014-12-17 22:57:30

From: riwu
..


1. Patched already (v3.7) unless it still occurs.

2. https://github.com/Brandon-T/GLX/blob/master/GLX/src/Exports.cpp#L72 <— That line that says WAIT_OBJECT_0 means to wait infinitely until something the server (SMART) responds.. That was a BAD design flaw now that I think about it but meh.. Changing it to "timeout" will fix it. I don't have time to do any more patches atm but maybe tomorrow? I don't know yet.. We'll see.. maybe after dinner.. No promises here.


1a. Could not replicate the swap. Test the latest patches and see if it still happens. I did not check if animated textures swap their order or not. I patched what I think was causing some older textures to not show up (see releases v3.7 2014-12-17 10:40PM update): https://github.com/Brandon-T/GLX/commit/3db2035d2aa849e9bb44312946c5c4d07b1bd5f6

2a. You are trying to compile as 64 bit but that function pointer isn't large enough. It's a 32-bit pointer for 32-bit Simba for 32-bit SMART. Cast it to a FARPROC or PROC instead or else compile as 32-bit.

3. At that time, I wasn't able to single out maps from regular textures (so I removed it to not degrade the plugin further).. In the latest plugin, I took the time to do that and so it only ever finds the map ONCE. Whenever a new map is loaded, it stores that ID (replacing the previously stored map). This way, it does not have to store EVERY FRAME (as done previously).. The pixels for a single map is stored once until the new map is rendered.. in which case the pixels are replaced with the new map's pixels until the next map is rendered.. This makes for a nice increase in FPS as maps are 512x512x4 bytes in size and I was storing that every frame. Now it's stored only once per area.

The latest patches should work (I tested it slightly):


If you remind me (sometime in the next few days.. maybe I'll have some time to patch the "sticking"). It's just one line..

riwu

2014-12-21 04:08:45

From: Brandon

2a. You are trying to compile as 64 bit but that function pointer isn't large enough. It's a 32-bit pointer for 32-bit Simba for 32-bit SMART. Cast it to a FARPROC or PROC instead or else compile as 32-bit.

Downloaded 32bit build and moved OpenGL32.layout back and got it to compile :)

From: Brandon

1a. Could not replicate the swap. Test the latest patches and see if it still happens. I did not check if animated textures swap their order or not. I patched what I think was causing some older textures to not show up (see releases v3.7 2014-12-17 10:40PM update): https://github.com/Brandon-T/GLX/commit/3db2035d2aa849e9bb44312946c5c4d07b1bd5f6

Thanks for the patch bank textures are now fixed:

When you rotate the compass to east:
[{ID = 37222, COLOURID = 657159, FULLCOLOURID = 7361410, X = 598, Y = 34, BOUNDS = {X1 = 622, Y1 = 6, X2 = 573, Y2 = 61}}
If it's difficult to fix that it's alright i can simply swap them.

From: Brandon

2. https://github.com/Brandon-T/GLX/blob/master/GLX/src/Exports.cpp#L72 <— That line that says WAIT_OBJECT_0 means to wait infinitely until something the server (SMART) responds.. That was a BAD design flaw now that I think about it but meh.. Changing it to "timeout" will fix it. I don't have time to do any more patches atm but maybe tomorrow? I don't know yet.. We'll see.. maybe after dinner.. No promises here.

I see..why doesnt SMART respond sometimes?

Also i couldn't compile GLX.dll statically, requiring libgcc_s_sjlj-1.dll, libstdc++-6.dll and libwinpthread-1.dll in my simba folder to work.
How do i edit the MakeFile? b/w code didn't work
WinDEP = -static -static-libgcc_s_sjlj-1 -static-libstdc++-6 -static-libwinpthread-1 -static-libgcc -static-libstdc++ -shared -s -o

Is there any way i can rename the opengl32.dll, so that when srl plugin updates it doesn't override it with the color-only version? I renamed the dll (and changed the include's arg) it stopped working…

Brandon

2014-12-21 11:01:55

From: riwu
..


I'll have to look into it to see why the animated texture values are swapped upon rotation. There's no guarantee that it can be fixed (I mean.. I can force it but that's no good) because if that's the ORDER that the vertices are rendered in, that's the order. Remember that this "rotation" and natural order of things is how we calculate the angle of such a texture. If I did patch it, then the texture is always going to be as rest state (not rotated ever).. That means angle would always be 0.

It's probably the same for the Map? Have you checked glMapCoords and see if they also get swapped upon rotation? If it is, then I will not patch because that means the order specifies the angle. Otherwise I will patch it.

I'll look into it.

Those commands are not how you compile statically. I am sure the makefile already has it in place:

-static -static-libgcc -static-libstdc++

compiles statically. The same commands can be set for the codeblocks project->linker settings.


riwu

2014-12-22 02:52:58

From: Brandon
…

Found out why it wasnt compiling statically for me…
When i built GLX.cbp, the glx.dll was output to bin/Debug folder, and GLX.layout with <ActiveTarget name="Debug" /> was autocreated.
Changing that to "Release", or adding the static flags under Debug in glx.cbp fixed the problem.

I only used map for GL_GetLocalPos(), not sure what else i can use it for? Output the current map as bitmap then compare to world map to determine global pos like SPS?

The WAIT_OBJECT_0 is a more pressing issue though, i had to use another Simba to monitor the scripts and restart them whenever the proggy remains the same for > a few minutes. I have to change it to WAIT_TIMEOUT or something?

Brandon

2014-12-22 11:44:13

From: riwu
Found out why it wasnt compiling statically for me…
When i built GLX.cbp, the glx.dll was output to bin/Debug folder, and GLX.layout with <ActiveTarget name="Debug" /> was autocreated.
Changing that to "Release", or adding the static flags under Debug in glx.cbp fixed the problem.

I only used map for GL_GetLocalPos(), not sure what else i can use it for? Output the current map as bitmap then compare to world map to determine global pos like SPS?

The WAIT_OBJECT_0 is a more pressing issue though, i had to use another Simba to monitor the scripts and restart them whenever the proggy remains the same for > a few minutes. I have to change it to WAIT_TIMEOUT or something?


See the documentation for OpenSingleEvent? It has a timeout parameter (the very last parameter).

/** © 2013, Brandon T. All Rights Reserved.
*
* This file is part of the GLX Library.
* GLX is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* GLX is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with GLX. If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef SHAREDMEMORY_HPP_INCLUDED
#define SHAREDMEMORY_HPP_INCLUDED

#if defined _WIN32 || defined _WIN64
#include <windows.h>
#else
#include <sys/types.h>
#include <sys/mman.h>
#include <dlfcn.h>
#include <fcntl.h>
#include <unistd.h>
#endif

#include <tchar.h>
#include <iostream>
#include <map>

/** @file SharedMemory.cpp */

/** @brief A class for mapping
*/
class SharedMemory
{
/** @brief Opens the specified event with the specified access flags.
*
* @param EventName The unique-name of the event to open.
* @param InheritHandle A boolean indicating whether or not to inherit the event's handle.
* @param SaveHandle A boolean indicating whether or not to stored the event's handle. Default = false.
* @param dwDesiredAccess The specified access flags to use when opening the event. Default = EVENT_ALL_ACCESS.
* @param dwMilliseconds Specifies how long to wait for the event. A timeout flag in milliseconds. Default = INFINITE.
* @return An integer indicating whether or not the event was opened successfully. WAIT_FAILED is returned upon failure.
*
*/
std::uint32_t OpenSingleEvent(std::string EventName, bool InheritHandle, bool SaveHandle = false, std::uint32_t dwDesiredAccess = EVENT_ALL_ACCESS, std::uint32_t dwMilliseconds = INFINITE);
};

#endif // SHAREDMEMORY_HPP_INCLUDED


That means you can specify the "timeout" value anywhere that you see OpenSingleEvent being used. http://msdn.microsoft.com/en-us/library/windows/desktop/ms687032%28v=vs.85%29.aspx

says WAIT_TIMEOUT is the return value that happens when the timeout is hit. In that case, all functions will return "false"/"nothing"/"NULL"/"nullptr" upon timeout.

So the only thing you need to change is the timeout value. Nothing more..

Anyway.. I patched it: https://github.com/Brandon-T/GLX/commit/561d5646936e6465f635386918a19d30cfde6bd5

You can change the timeout(in Exports.hpp) if you don't want to wait "2 seconds at most". Maybe lower it or raise it to your liking. I did not test whether or not the timeout works. It should but it'd require me to run RS for a period of time and code in an infinite loop to check if it gets stuck or not. I could simulate getting stuck but meh.. If it doesn't work, then I'll do that. It SHOULD though.

riwu

2014-12-28 17:23:35

@Brandon
Thanks for the fix, no more frozen issue :)
The only remaining problem:

Occasionally GLXMapCoords returns wrong values for me; at the exact same spot, GL_GetLocalPos would sometimes return different values after restarting smart (i have to restart smart again to fix it)

still not fixed in the latest version.

The x-value seems to remain consistent, only the y-value changes occasionally when Smart reloads.

cosmasjdz

2015-01-01 13:10:33

Ok i get this error

Error: Unknown declaration "GLXDebug" at line 142

I hjad that error, then downloaded brandons setup.zip he posted,

now i get these:

Error: Duplicate declaration "procedure((False=0, True=1))" at line 244
Compiling failed.
Error: Unknown declaration "SmartGetClientPID" at line 50

and neither my normal scripts or openglinclude runs :(

riwu

2015-01-10 10:14:53

From: cosmasjdz
Ok i get this error

Error: Unknown declaration "GLXDebug" at line 142

I hjad that error, then downloaded brandons setup.zip he posted,

now i get these:

Error: Duplicate declaration "procedure((False=0, True=1))" at line 244
Compiling failed.
Error: Unknown declaration "SmartGetClientPID" at line 50

and neither my normal scripts or openglinclude runs :(

What script are u trying to run?

@Brandon;
Is there any extra info to hook from models? Different type of mining rocks have the same model ID, so i have to find color within a box of the model point returned, which makes the ore finding more color-based than hooking based…

Brandon

2015-01-10 10:44:46

From: riwu
What script are u trying to run?

@Brandon;
Is there any extra info to hook from models? Different type of mining rocks have the same model ID, so i have to find color within a box of the model point returned, which makes the ore finding more color-based than hooking based…


There is.. but I don't have much time to hook it or dive into hooking it. I heard Jagex fixed OpenGL bugs, yeah?

Everything in RS has a texture. That includes models. If you hook model textures and save them, you'd hash them, you'd have unique ID's per rock model. You could also hook the vertices for each model. Similar to the Direct-X hook code that's on github.

Clarity

2015-01-21 16:31:33

Hey @Brandon, I think Obscurity may have asked, but would it be too much trouble to add in the camera zoom hook? I understand if you're busy, but this would be a gamechanger and appreciated greatly if you get the chance! :)

Brandon

2015-01-22 02:02:12

From: Clarity
Hey @Brandon, I think Obscurity may have asked, but would it be too much trouble to add in the camera zoom hook? I understand if you're busy, but this would be a gamechanger and appreciated greatly if you get the chance! :)


We spoke about it yes and the answer I gave him is the same that I will give to you.. but more detailed I guess..

1. It "might" be possible to hook the camera and its zoom. The first call to glTranslate is the camera's position. However, it would require tracking for me to feed Simba accurate real time camera positions. This is actually VERY hard to do btw.. so it's out of the question.

2. I tested if they reposition or zoom the camera via glRotate*, glScale*, glFrustum, etc.. No cigar. glRotate is called exactly 3 times [rotate x, rotate y, rotate z to create a rotation matrix] during start-up (before logging in). It is never again called (ever!). glScale is called once per frame with the exact same value every single time regardless of camera zoom.. glScalef(0.0078125, 0.0078125, 1). glFrustum is never ever called and instead glOrtho is called meaning that Jagex uses an Orthographic projection.


glRotatef(26, 1, 0, 0);
glRotatef(-12, 0, 1, 0);
glRotatef(0, 0, 0, 1);
glTranslatef(274, 226, 0); //possible a character: "U" as in "Username" on the login screen. Can't be 100% sure.



All in all, everything is calculated on the Java side and then passed to OpenGL. The only thing that I am able to get right now is translations (usually used for fonts as models are positioned via matrices), is the MVPMatrix.

This matrix contains the following information (See GLXMatrices function)..



With that said, you will notice the translate changes upon changing your zoom. Here's some rounded off matrices via GLXMatrices:

[-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 27904, -22267, 16754, 1] //lowest - varrock bank basement compass facing south
[-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 27904, -22407, 19995, 1] //highest - varrock bank basement compass facing south

[-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 26880, -21722, 16707, 1] //lowest - varrock bank facing south
[-1, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 26880, -21861, 19953, 1] //highest - varrock bank facing south

In the above, only the Z value (M11) really drastically changes.

[1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, -28422, 22686, -7576, 1] //lowest basement facing north
[1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, -28423, 23022, -1141, 1] //highest basement facing north


I tried reversing all the matrix calculations (even used GLM's math library to do it.. same result) to get the camera position that is passed to OpenGL. It is ALWAYS (0, 0, 0). So there's no way to get the camera zoom without being able to get the actual height from the client (developer's console: getcamerapos).

The best chance you have is calculating it from the matrices.. You'd have to also take into account the compass angle because as you can see above, it affects it.



EDIT: RS3 does it like:


if(var0.equalsIgnoreCase("getcamerapos")) {
uw var28 = client.il.g(534416751);
if(abp.tl * 768570345 == 4) {
ob var26 = fn.ui.ap((byte)6);
ob var24 = fn.ui.ao(-1014937429);
xa.z("Pos: " + (new uw(dh.nu.b, (int)var26.o >> 9, (int)var26.m >> 9)).toString() + " Height: " + (aok.jb((int)var26.o - (-862318397 * var28.f << 9), (int)var26.m - (var28.u * -2091177201 << 9), dh.nu.b, -1540822537) + (int)var26.g), (byte)-128);
xa.z("Look: " + (new uw(dh.nu.b, (int)var24.o >> 9, (int)var24.m >> 9)).toString() + " Height: " + (aok.jb((int)var24.o - (var28.f * -862318397 << 9), (int)var26.m - (var28.u * -2091177201 << 9), dh.nu.b, -840066305) + (int)var26.g), (byte)-50);
} else {
xa.z("Pos: " + dh.nu.b + "," + (-862318397 * var28.f + (700671177 * ll.ko >> 9) >> 6) + "," + (var28.u * -2091177201 + (va.km * -1603363023 >> 9) >> 6) + "," + ((700671177 * ll.ko >> 9) + var28.f * -862318397 & 63) + "," + (-2091177201 * var28.u + (va.km * -1603363023 >> 9) & 63) + " Height: " + (aok.jb(ll.ko * 700671177, va.km * -1603363023, dh.nu.b, -1051030473) - ik.ke * -964346951), (byte)-16);
xa.z("Look: " + dh.nu.b + "," + (1419755433 * ur.tn + var28.f * -862318397 >> 6) + "," + (-2091177201 * var28.u + cp.ta * -1040741291 >> 6) + "," + (var28.f * -862318397 + ur.tn * 1419755433 & 63) + "," + (var28.u * -2091177201 + -1040741291 * cp.ta & 63) + " Height: " + (aok.jb(1419755433 * ur.tn, cp.ta * -1040741291, dh.nu.b, -1063574590) - -447524101 * jg.tm), (byte)-115);
}

return;
}

riwu

2015-01-23 08:18:25

@Brandon;
Found 2 weird behavior with the new plugin:
1.
There is one small dot at the bottom left of the inventory
{ID = 88625, COLOURID = 1782589, FULLCOLOURID = 1847612, X = 4, Y = 274, BOUNDS = {X1 = 3, Y1 = 273, X2 = 4, Y2 = 275}}
When ur inventory is not empty, it disappears, but sometimes turn into the texture ID of a random object in inventory (bones etc).

2.
(ignore the red box)
the minimap symbol for underground (texture ID 36370) was previously not hooked, the new plugin hooks it but it seems like it could only hook 1 at a time?
the left one is not grabbed when the right one is visible.

Also any clue why GL_GetLocalPos sometimes return different values after restarting smart?

Brandon

2015-01-23 09:02:07

From: riwu
@Brandon;


Found 2 weird behavior with the new plugin:
1.
There is one small dot at the bottom left of the inventory
{ID = 88625, COLOURID = 1782589, FULLCOLOURID = 1847612, X = 4, Y = 274, BOUNDS = {X1 = 3, Y1 = 273, X2 = 4, Y2 = 275}}
When ur inventory is not empty, it disappears, but sometimes turn into the texture ID of a random object in inventory (bones etc).

2.
(ignore the red box)
the minimap symbol for underground (texture ID 36370) was previously not hooked, the new plugin hooks it but it seems like it could only hook 1 at a time?
the left one is not grabbed when the right one is visible.

Also any clue why GL_GetLocalPos sometimes return different values after restarting smart?



1. is linked to 2. So I'll explain it all in 2.

2. https://github.com/Brandon-T/GLX/blob/master/OpenGL32/src/Hooks/Structures.cpp#L256 Animated texture's are determine by a single boolean. As soon as one is found, that boolean is set to false because the next texture loaded COULD be a regular texture OR an animated texture. The real problem is the design of the original plugin.. Same problem that had previously happened with the very first plugin causing me to re-write it and thus 3.5+ was born..

What's that problem? The problem is "adding" new hooks without changing "layout". This is called ABI compatibility. If I add REAL animated textures to the plugin (not the hacked up stuff that's in there right now), I will have to do one of the following:

2a. Change the layout of Textures in the include.
2b. Add new class of Textures to the include.
2c. Add a new internal class and merge them upon transferring to the Simba side.

Of course option C is the easiest but I'm not sure about it. Animated textures were only added very recently and adding them does not take a lot of work (only one function is different compared to textures.. float vs. int) but it does change the plugin AND the include and that's because I never anticipated the need for hooking it before. So what I did was I made animated textures and textures one in the same.. Never really wrote the API for adding extra hooks as I thought models, textures, fonts, maps, angles, matrices, would be all that was needed.. then came Animated textures out of no where -___-

So yes, I can fix it but I'll have to think up a better solution than the above..


3. For localpos, there's an explanation somewhere that describes the problem with it. If you are still asking this, you haven't grasped the problem yet. Each time you enter a new location, a PORTION of a map is drawn and you are placed at one of its edges. When you log out and re-login, you are placed at the CENTER of the portion that you stand. Hence the need for being able to find globalpos arose..


The last one is VERY hard to come up with a solution for..

I'll see what I can do to fix the first two problems. Maybe re-write parts of the plugin and hope I don't break any parts of the include..

Obscurity

2015-01-23 09:54:52

Brandon, I'm at work so can't send any examples ATM, but his map issue may relate to mine.

Whe tracing the coordinates returned by GLX map coords (I don't remember the exact name - again, work), it's off by up to 200px sometimes, if I recall correctly. It's still a perfect rectangle around the map, but the actual map image is in much farther then the actual point given.

I'll give examples and screenshots when I get home, mate. Cheers.

Brandon

2015-01-23 10:30:52

From: Obscurity
Brandon, I'm at work so can't send any examples ATM, but his map issue may relate to mine.

Whe tracing the coordinates returned by GLX map coords (I don't remember the exact name - again, work), it's off by up to 200px sometimes, if I recall correctly. It's still a perfect rectangle around the map, but the actual map image is in much farther then the actual point given.

I'll give examples and screenshots when I get home, mate. Cheers.




Are you talking about:


Because if so, then you are missing the point of the function entirely..


{$DEFINE SMART}
{$DEFINE SmartWrappers}
{$I GLX/Setup.Simba}

var
Smart: TSmart;
TL, BL, BR, TR: FloatPoint;
R: TBox;
begin
ClearDebug();
SetupGLX(Smart, 800, 600);

GL_GetMapCoords(TL, BL, BR, TR);
R := ToRect(TL, BL, BR, TR);

Smart.Graphics().DrawRotatedBoxes([R]);
end.

That function is supposed to return the bounds of the map and it does exactly that (regardless of rotation). Nothing more.. nothing less.. You can try saving the map to the disk and see that it has an alpha layer surrounding it.. So it's not actually wrong. It's just the bounds it returns ALSO includes the transparent pixels surrounding the map..


Hence:


{*
Returns the current loaded map as a bitmap.

Developer Notes:
Returned Bitmap Size: 512x512
*}
Function GL_MapToImageEx: Integer;


{*
Returns the current loaded map as a bitmap with the outline stripped.

Developer Notes:
Original Size: 512x512
Returned Bitmap Size: 408x408
*}
Function GL_MapToImage: Integer;


Is that what you meant?



As for GL_GetLocalPos.. It isn't wrong..



{$DEFINE SMART}
{$DEFINE SmartWrappers}
{$I GLX/Setup.Simba}

Function ToRect(TL, BL, BR, TR: FloatPoint): TBox;
begin
Result.X1 := round(TL.X);
Result.Y1 := round(TL.Y);
Result.X2 := round(BR.X);
Result.Y2 := round(BR.Y);
end;


Function LocalPosToMM(Pos: TPoint): TPoint;
var
Me: TPoint;
DX, DY: Integer;
Begin
Me := GL_GetLocalPos;
DX := Pos.X - Me.X;
DY := Pos.Y - Me.Y;

Me := MiddleBox(GL_MMBounds);
Result.X := Me.X + DX;
Result.Y := Me.Y + DY;
End;


var
Smart: TSmart;
P: TPoint;
TL, BL, BR, TR: FloatPoint;
begin
//ClearDebug();
SetupGLX(Smart, 800, 600);

GL_GetMapCoords(TL, BL, BR, TR);
P := GL_GetLocalPos;
P := LocalPosToMM(P);

Mouse(P);
end.


Remember that the local pos in OpenGL is NOT the same as in Reflection. The LocalPos in OpenGL is the coordinate RELATIVE to the map! (specifically the top left). Assume the map is perfectly north:

MMPos = TopLeftOfMap + P.


Assume the map is perfectly South (upside down):

MMPos = TopLeft - P.

Why minus? Because the top left of the map is literally drawn at the bottom right of the minimap. The player stands at the center of the map.

LocalPos works by returning a negative coord when facing south. If the top left is drawn at the bottom right, the player stands at a negative position relative to the bottom right (top left of the map). It uses CrossProduct to determine the player's position WITHIN the current chunk of the map. NOT the global world map!


The above LocalPos will return a point on the minimap relative to the TopLeft of the map (wherever that is drawn).. Just because the map is upside down (when facing perfectly south), does not mean that it's top left is now the bottom right because that's wrong! The top left is simply "drawn" at a different position (bottom right) but it is STILL the top left (it's the way OpenGL works). Very confusing!


A simpler way of saying it is this: If you want to draw an image upside down, why flip all the pixels? You can simply specify a negative coordinate around the horizontal axis to flip it OR you can swap the Y values.. This will flip the image upside down by simply drawing the top where the bottom is supposed to be and the bottom where the top is supposed to be.. However, the image itself is still upright. It is just "drawn" upside down so the top of the image itself is still the top! Only its coordinates changed.

The original way (Kasi's way) of calculating local pos was to "un-rotate" the map coords around the center of the minimap (such that the top is horizontal and the map faces north) and then calculate position relative to the top left.. but there's no need for that (Bart's way).. Kasi's is probably better for calculating MMPos from a point.



Anyway..

When you log in, the map you are standing in, is the TRUE CHUNK of the global map.. You are placed at the center of this map. However, when you walk to a new map chunk, you are positioned at one of its edges (you are east, walking west when you hit a new map, you will be placed far east on a combined chunk of the map).. This makes LocalPos entirely useless unless you combine it with SPS.. thus making it the "perfect" SPS there can possibly be. Hence.. the need for GlobalPos arose but I never figured out how to get it..



I hope I have covered all the bases and crossed the T's, dotted the I's..

I understand there's very little documentation on the internals but I did explain all this once upon a time I think?

Obscurity

2015-01-23 12:42:49

Ah, I didn't realize it had the alpha layer around it. That was the only thing throwing me for a loop. :-P. Cheers for the explaination!

Obscurity

2015-01-24 21:22:18

I hadn't noticed it earlier, but I'm now having a similar issue as riwu - glGetTextures() is returning an item at the bottom left hand corner of the inventory. When this happens, it's always an item that in the inventory. For me, ATM, it's Lunar Lumber, which will then change to a Lunar Fence Post if it's converted.

Not a big deal if you just use the texture dimensions to make sure it's the real item, and not the tiny thing in the corner.

riwu

2015-01-24 21:54:20

From: Obscurity
I hadn't noticed it earlier, but I'm now having a similar issue as riwu - glGetTextures() is returning an item at the bottom left hand corner of the inventory. When this happens, it's always an item that in the inventory. For me, ATM, it's Lunar Lumber, which will then change to a Lunar Fence Post if it's converted.

Not a big deal if you just use the texture dimensions to make sure it's the real item, and not the tiny thing in the corner.

Yeah it's easy to work around it once u discover the bug, but before u do it'd likely cause abnormal behaviors in ur script…
Do share if u find any other bugs then all of us can take precautions against them :)

Patriq

2015-02-03 14:35:46

I have a few questions :D I hope you dont mind answering to them.

1) Are GL_LoginPlayer and GL_LoginToLobby working?
2) Is there any bug with GL_InvBounds? It doesnt seem to get me any bounds at all.
3) Is there anyway to force SMART to load runescape in OpenGL mode? because using this plugin, I dont know why, it makes runescape load as safe mode and I have to set it up to OpenGL manually.
4) Is the include still updated? I mean if there is still someone working on it so in every update or break, things still work fine? Or was it kinda left out the scene?

I guess that is all! I hope you dont have a hard time answering to them! Thank you very much! I really want people to support OpenGL development since Im loving it so far.

Thank you all,
PatriqDesigns

3Garrett3

2015-02-03 15:14:15

From: PatriqDesigns
I have a few questions :D I hope you dont mind answering to them.

1) Are GL_LoginPlayer and GL_LoginToLobby working?
2) Is there any bug with GL_InvBounds? It doesnt seem to get me any bounds at all.
3) Is there anyway to force SMART to load runescape in OpenGL mode? because using this plugin, I dont know why, it makes runescape load as safe mode and I have to set it up to OpenGL manually.
4) Is the include still updated? I mean if there is still someone working on it so in every update or break, things still work fine? Or was it kinda left out the scene?

I guess that is all! I hope you dont have a hard time answering to them! Thank you very much! I really want people to support OpenGL development since Im loving it so far.

Thank you all,
PatriqDesigns


As far as I know, @Obscurity is working on his obscurityLibrary for OGL functions. It still uses Brandon's plugins but there is talk about updating the plugin.

There are many of us *cough* who need a full-on noob tutorial in order to figure out how to set up OGL. I think Obscurity is also working on putting something like that too. I managed to convince myself I had everything set up right and then all debug attempts ended with nothing showing up. So if you're like me and need a good ol fashioned tutorial, I suggest ruthlessly mentioning Obscurity and @Clarity out of sheer desperation every chance you get.

grats

2015-02-03 15:37:57

From: 3Garrett3
As far as I know, @Obscurity is working on his obscurityLibrary for OGL functions. It still uses Brandon's plugins but there is talk about updating the plugin.

There are many of us *cough* who need a full-on noob tutorial in order to figure out how to set up OGL. I think Obscurity is also working on putting something like that too. I managed to convince myself I had everything set up right and then all debug attempts ended with nothing showing up. So if you're like me and need a good ol fashioned tutorial, I suggest ruthlessly mentioning Obscurity and @Clarity out of sheer desperation every chance you get.



works too well

Obscurity

2015-02-03 15:42:10

1.) No, I wasn't able to get them to work either. Mind you, I last tried a few months ago. If you'd like, I could include something like those into the next release of obscurityLibraryUpload. I'm very grateful for the work that Brandon's been putting into this and would like to lessen his load as much as possible.

2.) If you're looking for inventory functions, again, obscurityLibraryUpload has obsInventoryCount(), obsInventoryFindItem(), obsInventoryIsFull() and such.

3.) That's usually based on your graphics card. It does that on my shitty old laptop and/or when I try to load several on my desktop.

4.) What Garrett said. :P.



The library's got a big update coming. Had planned for it to be release this weekend, but unexpectedly had the baby brother over for the weekend. Can expect it soon.

3Garrett3

2015-02-03 15:51:16

From: grats

works too well


Like taking candy from a baby.

From: Obscurity

The library's got a big update coming. Had planned for it to be release this weekend, but unexpectedly had the baby brother over for the weekend. Can expect it soon.


Once this update happens will there be a "Nub Guide to OGL" on the horizon? Or should I just continue nagging Clarity when he's away on Skype?

Obscurity

2015-02-03 15:53:43

Nagging Clarity. I know he was hoping I'd add to it - so I've been taking a couple minutes here and there to write some stuff up. DW, we won't let you down. :P.

Taric

2015-02-03 17:06:18

From: 3Garrett3
As far as I know, @Obscurity is working on his obscurityLibrary for OGL functions. It still uses Brandon's plugins but there is talk about updating the plugin.

There are many of us *cough* who need a full-on noob tutorial in order to figure out how to set up OGL. I think Obscurity is also working on putting something like that too. I managed to convince myself I had everything set up right and then all debug attempts ended with nothing showing up. So if you're like me and need a good ol fashioned tutorial, I suggest ruthlessly mentioning Obscurity and @Clarity out of sheer desperation every chance you get.


I figured if I sent them enough dick pics they'd finish it faster… but if you say so.

The other day there was something obscuring my vision… no wait. There was an @Obscurity in my vision that prevented me from properly viewing the delightful collection of pron that was laying in front of me. I quickly tried to use the tissues that were in my hand to help clear… To help give my vision the @Clarity that it needed.

Patriq

2015-02-03 17:23:00

I made a script already using this include with ease. I used obscurity include too!
I just wanted to know how updated this include is.
I would love to bet more in OpenGL, because is so much better, and has so many possibilities!

Another thing! Is there any way we could use SRL and GLX? That would be so good! Getting both worlds together!

Clarity

2015-02-03 17:26:06

From: PatriqDesigns
I made a script already using this include with ease. I used obscurity include too!
I just wanted to know how updated this include is.
I would love to bet more in OpenGL, because is so much better, and has so many possibilities!

Another thing! Is there any way we could use SRL and GLX? That would be so good! Getting both worlds together!


Yes. I do so in my DG script like this:


program ClarityDG;
{$DEFINE SRLCOMPATIBILITY}
{$DEFINE SMART}
{$I SRL-6/SRL.simba}
{$I DG-GLX/Setup.simba}
{$I DG-GLX/Clarity/ClarityGLX.simba}
{$I DG-GLX/Obscurity/ObscurityGLX.simba}

The order that you include files is important!

The includes will default to SRL-6 for SMART image drawing, mouse movement, and some other functions. If you are scripting in OGL you will likely be unable to use many of the interface functions for SRL-6, but then again you wouldn't need to at all.

@Others, posting the tutorial tonight after Obscurity looks it over and adds his own things. It covers SRL-6 + OGL combination usage more in depth.

Taric

2015-02-03 17:41:48

From: Clarity

@Others, posting the tutorial tonight after Obscurity looks it over and adds his own things. It covers SRL-6 + OGL combination usage more in depth.


I… I love you.


Patriq

2015-02-03 18:20:07

[ATTACH=CONFIG]24957[/ATTACH]
[ATTACH=CONFIG]24958[/ATTACH]

Am I doing something wrong?

Clarity

2015-02-03 19:11:35

From: PatriqDesigns
[ATTACH=CONFIG]24957[/ATTACH]
[ATTACH=CONFIG]24958[/ATTACH]

Am I doing something wrong?

They are duplicate declarations from the SRL-6 include. Replace them with something like GL_SKILL_ATTACK, GL_SKILL_ etc.

Should compile then.

Patriq

2015-02-03 19:29:23

It keeps sending me to duplicate declarations… :c Wont you be able to provide me your modified GLX include? Thanks once again! :D

Clarity

2015-02-03 21:42:13

From: PatriqDesigns
It keeps sending me to duplicate declarations… :c Wont you be able to provide me your modified GLX include? Thanks once again! :D


This .ZIP will be outdated pretty soon (library update occurring at tutorial release) but here you go: [ATTACH]24961[/ATTACH]

We are also phasing out all these includes for some new, easier to implement stuff. So stay tuned.

Patriq

2015-02-04 02:46:43

[ATTACH=CONFIG]24962[/ATTACH]
Whhyyyy???? :c

The Mayor

2015-02-04 02:49:09

From: PatriqDesigns
[ATTACH=CONFIG]24962[/ATTACH]
Whhyyyy???? :c


Don't worry man, the real fun starts when you've got everything set up and you run your script for 60 minutes ;)

Patriq

2015-02-04 02:59:55

The real fun starts when I will be able to merge color and OpenGL together, and stop depend on color and have a much more precise scripts that will let users run it for days executing pretty complex tasks, like Dung, or like Minigames.

@Clarity , can you add me on skype for further talk and assist? Or should I just wait for the tutorial that will cover how to use both SRL-6 and GLX together?

Patriq

2015-02-07 07:55:42

Still without any luck when it comes to make SRL-6 and GLX compatible :c
I could really use some help.

Ross

2015-02-07 09:38:35

From: PatriqDesigns
Still without any luck when it comes to make SRL-6 and GLX compatible :c
I could really use some help.



Give it a bit, @Clarity and @Obscurity are working on a fix. It has to do with duplications within the includes, so you'd have to look through all of them and see what they are to comment them out. There's no quick fix if you don't know what you're looking for though.

riwu

2015-02-07 10:08:55

Why bother with using SRL6 though? Most methods in SRL6 only works for fixed screen + oldsch layout, whereas you can run in resizable with dynamic interface layouts using ogl interception.

Ross

2015-02-07 10:54:55

From: riwu
Why bother with using SRL6 though? Most methods in SRL6 only works for fixed screen + oldsch layout, whereas you can run in resizable with dynamic interface layouts using ogl interception.


Lots of mouse functions and such are much better in SRL-6.

riwu

2015-02-07 18:42:04

From: Ross
Lots of mouse functions and such are much better in SRL-6.

Ahh yeah i copied over the Mouse functions from SRL6 as well, but other than that there's hardly anything else that could work on resizable RS.
If you need some generic methods, like TBox.contains() etc that cant find found in the glx, then u can simply copy them over as and when you need it.
Much better than trying to include the entire SRL6 to the glx imo.

Ross

2015-02-07 18:51:38

From: riwu
Ahh yeah i copied over the Mouse functions from SRL6 as well, but other than that there's hardly anything else that could work on resizable RS.
If you need some generic methods, like TBox.contains() etc that cant find found in the glx, then u can simply copy them over as and when you need it.
Much better than trying to include the entire SRL6 to the glx imo.



Yeah true, but this will make it more user friendly I think. Another thing I like is that you can set the interfaces to the same size as regular srl-6 interfaces and then use a lot of the same functions there too, just use OGL to get the new bounds.

Patriq

2015-02-07 18:51:49

From: riwu
Ahh yeah i copied over the Mouse functions from SRL6 as well, but other than that there's hardly anything else that could work on resizable RS.
If you need some generic methods, like TBox.contains() etc that cant find found in the glx, then u can simply copy them over as and when you need it.
Much better than trying to include the entire SRL6 to the glx imo.


How about passing 6 hour limit and spawining Smart in OpenGL right away instead of manually doing it from Safe Mode? How about SPS, how about the whole rest, like productionScreens, and shit toon of stuff. Sure you could make a ogl include that would port all of that, but it would take soo long. I would love to work on an amazing piece like that one. Lets combine our forces toghether and designs a OpenGL include that looks exactly the same as SRL-6! That would be awesome, honestly I quite think that is the future of color botting. Either that or DirectX intersection.

riwu

2015-02-07 19:06:39

From: PatriqDesigns
How about passing 6 hour limit and spawining Smart in OpenGL right away instead of manually doing it from Safe Mode? How about SPS, how about the whole rest, like productionScreens, and shit toon of stuff. Sure you could make a ogl include that would port all of that, but it would take soo long. I would love to work on an amazing piece like that one. Lets combine our forces toghether and designs a OpenGL include that looks exactly the same as SRL-6! That would be awesome, honestly I quite think that is the future of color botting. Either that or DirectX intersection.

Idk what u mean by having to manually do it from safe mode? GL_RestartClient() restarts the SMART for you, Brandon even wrote GL_GameSession() for detecting game session ended though i wrote my own to consider rs update etc messages. Never had any problem running my scripts 24/7 with ogl :)

You can modify the SPS include slightly to make it compatible with dynamic interface (using ogl functions to grab the minimap bounds, compass etc).
As for other functions like production screen, i wrote them whenever i needed them.
True enough, there's quite a lot that you have to write yourself, but it's easy to write glx functions and they are much more accurate and dynamic than the SRL6 versions.

If u still prefer to make the include compatible with SRL6, just post whatever compiling error you are getting that you cant solve, we'd be happy to help :)

Patriq

2015-02-07 19:45:11

From: riwu
Idk what u mean by having to manually do it from safe mode? GL_RestartClient() restarts the SMART for you, Brandon even wrote GL_GameSession() for detecting game session ended though i wrote my own to consider rs update etc messages. Never had any problem running my scripts 24/7 with ogl :)

You can modify the SPS include slightly to make it compatible with dynamic interface (using ogl functions to grab the minimap bounds, compass etc).
As for other functions like production screen, i wrote them whenever i needed them.
True enough, there's quite a lot that you have to write yourself, but it's easy to write glx functions and they are much more accurate and dynamic than the SRL6 versions.

If u still prefer to make the include compatible with SRL6, just post whatever compiling error you are getting that you cant solve, we'd be happy to help :)


Well why dont you release what you have done to the community? Why wont you make a repo for it where all could contribute. That would be awesome, and would let OpenGL development be more "accepted" and used.

riwu

2015-02-07 20:47:16

From: PatriqDesigns
Well why dont you release what you have done to the community? Why wont you make a repo for it where all could contribute. That would be awesome, and would let OpenGL development be more "accepted" and used.

I made my include with functional and development efficiency in mind, so the coding conventions/structures do not adhere to the proper standards of a public library. Sometimes when i look at my older codes even i couldnt understand what i was trying to do :p didn't practise commenting and glx scripting is just…numbers everywhere.

I think only someone with the patience of coming up with a lot of constants for IDs/commenting every single ID used would be up to the task of maintaining an ogl include that can be developed and maintained by the public.


Also, there's still a few issues with the plugin that may require modifying the GLXCore functions, eg:https://villavu.com/forum/showthread.php?t=104932&page=5&p=1327181#post1327181
@Brandon; have you thought of the best solution regarding the animated textures?
I'd support option 2b. Add new class of Textures to the include. (with a separate GLX method that grabs them)
Reasons being:
1. Sometimes those animated textures appear in weird places (like the tiny dot in inventory) so scripters can avoid them by not calling the animated texture function. This also ensures that existing scripts that was created using the old plugin would not face any issues (eg. a function might only be expecting 1 gltexture, but the new plugin gives 1 extra animated texture which the function ended up using instead of the normal one)

2. Animated textures are not very often used, so separating them could improve efficiency (by not grabbing the animated textures that wouldnt be used)

3. Makes it easier to grab all animated textures instead of just one.

Brandon

2015-02-07 21:52:06

From: riwu
I'd support option 2b. Add new class of Textures to the include. (with a separate GLX method that grabs them)


I did not think of a solution yet but I am leaning on doing exactly that. I've been trying really HARD to keep the new code-base understandable for all and not just me.. Then I've been working on optimising & micro-optimising (because this is low level graphics) stuff but trying to keep it readable as well..

The current plugin has way too much patch code and it's really hard for me to just stick in new stuff..

For example, some micro-ops would be:

(2195 mod 256) - 11 I've optimised to (2195 & 255) - 11 to avoid the cost of modulo.. Now it may not look like a huge change, but when ran over thousands of times per second and bottle necks the CPU, it counts a lot. I've benched it and tested it.
And since all textures are GL_TEXTURE_2D (power of two's.. about damn time Jagex updated their stuff), it makes this even faster than ever.


Then I got rid of GL_TEXTURE_ARB (non-power of two textures) because the game no longer uses it and there's no need for unnecessary branching and extra checks.. Sometimes it uses it for the tiniest irrelevant code.

I completely re-wrote fonts so that it doesn't have to store almost 10k fonts per frame per area.. Instead, it stores nothing and grabs them on the fly due to the above calculation.. This means that I don't have to delete anything because there's no memory being used..

For example.. Previously I did:


void Font::LogEndList()
{
if (this->Found) //check if a character was possibly rendered.
{
this->LastFont = false; //is this the last character rendered in a font set (256 * however many lists the game loads.. roughly 4k).

if (!this->Fonts.size()) //if this is the last font, reset the next font to start at "32" aka space in ASCII.
this->Letter = 32;
else
this->Letter = (!this->Fonts.back().LastFont) ? this->Fonts.back().Letter + 1 : 32; //Else, the next char is the last char + 1 in the ASCII table.

if (++this->Count >= 255) //Every 256 fonts, we need to reset the font counter and start over.. There's roughly 4k lists to go through.
{
this->Count = 0;
this->LastFont = true;
this->Found = false;
}
this->Fonts.push_back(*this); //Store the current character in the Font vector structure.
}
}


and now I do:


void Font::LogFont(unsigned int List)
{
font->Letter = (List & 0xFF) - 11;
}

And trust me when I say that's probably the biggest improvement so far (because I haven't worked on anything else yet other than raw API code).. I went from storing 10k "Font structures" in a vector or maps and doing a look up to get each letter rendered.. To doing no look ups and storing nothing OR storing on a frame-by-frame basis in the very worst case.


You can see that the new above generic algorithm works for all characters:


1632 % 256 = 96 minus 11 = U
1662 % 256 = 126 minus 11 = s
1648 % 256 = 112 minus 11 = e
1661 % 256 = ? minus 11 = ?
1657 ...
1644 ...

Derived Algorithm: Character = (List % 256) - 11.

Faster Derived algorithm: Character = (List & 255) - 11.

You can test it out for the remaining letters and see that it spells out "Username" which was the text written on the login screen. I tested this on menus, login, etc..


Other than that, I've been working on the math and calculations:


Mat4 Mat4::Transpose() const
{
Mat4 res;
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
res[j][i] = mat[i][j];
}
}
return res;
}

Mat4 Mat4::Identity()
{
Mat4 res;
res[0][0] = 1.0f;
res[1][1] = 1.0f;
res[2][2] = 1.0f;
res[3][3] = 1.0f;
return res;
}

Mat4 Mat4::Orthagonal(float w, float h, float zNear, float zFar)
{
Mat4 res;
res[0][0] = 2.0f / w;
res[1][1] = -2.0f / h;
res[2][2] = -2.0f / (zFar - zNear);
res[3][3] = 1.0f;
res[3][0] = -1.0f;
res[3][1] = 1.0f;
res[3][2] = (zFar + zNear) / (zFar - zNear);
return res;
}

Mat4 Mat4::Perspective(float w, float h, float zNear, float zFar)
{
Mat4 res;
res[0][0] = 2.0f * zNear / w;
res[1][1] = -2.0f * zNear / h;
res[2][2] = ((-zFar - zNear) * zFar) / (zFar - zNear);
res[2][3] = -2.0f * zNear / (zNear - zFar);
res[3][2] = -1.0f;

res[0][2] = 1.0f;
res[1][2] = -1.0f;
return res;
}

Mat4 Mat4::FieldOfView(float fov, float aspect, float zNear, float zFar)
{
Mat4 res;
res[0][0] = 1.0f / tanf(fov / 2.0f);
res[1][1] = aspect / tanf(fov / 2.0f);
res[2][2] = zFar / (zFar - zNear);
res[3][2] = (zFar * zNear) / (zNear - zFar);
res[2][3] = -1.0f;
res[3][3] = 0.0f;
return res;
}

Mat4 Mat4::LookAt(const Vec3& Eye, const Vec3& At, const Vec3& Up)
{
Vec3 XAxis, YAxis, ZAxis;
ZAxis = (Eye - At).Normalise();
XAxis = (Up.Cross(ZAxis)).Normalise();
YAxis = (ZAxis.Cross(XAxis)).Normalise();

Mat4 res;
res[0][0] = XAxis.x;
res[1][0] = XAxis.y;
res[2][0] = XAxis.z;
res[3][0] = -XAxis.Dot(Eye);
res[0][1] = YAxis.x;
res[1][1] = YAxis.y;
res[2][1] = YAxis.z;
res[3][1] = -YAxis.Dot(Eye);
res[0][2] = ZAxis.x;
res[1][2] = ZAxis.y;
res[2][2] = ZAxis.z;
res[3][2] = -ZAxis.Dot(Eye);
res[3][3] = 1.0f;
return res;
}

Mat4 Mat4::RotX(float rad)
{
float ct = cosf(rad);
float st = sinf(rad);
Mat4 res = Identity();
res[1][1] = ct;
res[1][2] = st;
res[2][1] = -st;
res[2][2] = ct;
return res;
}

Mat4 Mat4::RotY(float rad)
{
float ct = cosf(rad);
float st = sinf(rad);
Mat4 res = Identity();
res[0][0] = ct;
res[0][2] = st;
res[2][0] = -st;
res[2][2] = ct;
return res;
}

Mat4 Mat4::RotZ(float rad)
{
float ct = cosf(rad);
float st = sinf(rad);
Mat4 res = Identity();
res[0][0] = ct;
res[0][1] = st;
res[1][0] = -st;
res[1][1] = ct;
return res;
}

Mat4 Mat4::Rot(float pitch, float yaw, float roll)
{
return RotY(yaw) * RotX(pitch) * RotZ(roll);
}

Mat4 Mat4::Scale(float val)
{
return Scale(val, val, val);
}

Mat4 Mat4::Scale(float x, float y, float z)
{
Mat4 res;
res[0][0] = x;
res[1][1] = y;
res[2][2] = z;
res[3][3] = 1.0f;
return res;
}

Mat4 Mat4::Translate(float x, float y, float z)
{
Mat4 res;
res[3][0] = x;
res[3][1] = y;
res[3][2] = z;
res[0][0] = 1.0f;
res[1][1] = 1.0f;
res[2][2] = 1.0f;
res[3][3] = 1.0f;
return res;
}


But I re-wrote a bunch of code as well:


Serialisation is brand spanking new and way faster and more efficient than before:


#ifndef STREAM_HXX_INCLUDED
#define STREAM_HXX_INCLUDED

#include <vector>
#include <list>
#include <string>
#include <sstream>

/********************************************//**
* @brief A class for serialising all data-types & containers into a buffer.
***********************************************/
class Stream
{
private:
std::stringstream Data;

/********************************************//**
* @brief Determines if two types are the exact same when decayed at compile time.
*
* @param T - Type to compare to.
* @param U - Type that is decayed first and compared to T.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T, typename U>
struct is_same_decay : public std::integral_constant<bool, std::is_same<T, typename std::decay<U>::type>::value> {};


/********************************************//**
* @brief Compares a type to a char*, or const char* when decayed at compile time.
*
* @param T - The type to decay and compare.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T>
struct is_cstring : public std::integral_constant<bool, is_same_decay<char*, T>::value || is_same_decay<const char*, T>::value> {};


/********************************************//**
* @brief Compares a type to a wchar_t*, or const wchar_t* when decayed at compile time.
*
* @param T - The type to decay and compare.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T>
struct is_wcstring : public std::integral_constant<bool, is_same_decay<wchar_t*, T>::value || is_same_decay<const wchar_t*, T>::value> {};


public:
/********************************************//**
* @brief Constructs a stream class.
*
* @param Buffer void* - Buffer to serialise/de-serialise data to/from.
* @param BufferSize std::size_t - Size of the specified buffer.
*
***********************************************/
Stream(void* Buffer, std::size_t BufferSize);

template<typename T>
void Read(T &Value);

template<typename T>
void Write(const T &Value);

template<typename T>
typename std::enable_if<!is_cstring<T>::value && !is_wcstring<T>::value, Stream&>::type operator << (const T &Value);

template<typename T>
typename std::enable_if<!is_cstring<T>::value && !is_wcstring<T>::value, Stream&>::type operator >> (T &Value);

template<typename T, typename Allocator>
Stream& operator << (const std::vector<T, Allocator> &Value);

template<typename T, typename Allocator>
Stream& operator << (const std::list<T, Allocator> &Value);

template<typename T, typename Allocator>
Stream& operator << (const std::basic_string<T, Allocator> &Value);


template<typename T, typename Allocator>
Stream& operator >> (std::vector<T, Allocator> &Value);

template<typename T, typename Allocator>
Stream& operator >> (std::list<T, Allocator> &Value);

template<typename T, typename Allocator>
Stream& operator >> (std::basic_string<T, Allocator> &Value);
};
#endif // STREAM_HXX_INCLUDED


Graphics is re-written too:


#ifndef GRAPHICS_HXX_INCLUDED
#define GRAPHICS_HXX_INCLUDED

#include <GL/gl.h>
#include <GL/glext.h>
#include <utility>
#include <string>
#include <cstring>
#include <vector>
#include <fstream>

#if defined _WIN32 || defined _WIN64
#include <windows.h>
#endif

#include "Libraries/LodePNG.hxx"


/********************************************//**
* @brief Structured Union representing a tightly packed RGBA memory layout.
***********************************************/
typedef union RGBA
{
unsigned int Colour;
struct
{
unsigned char R, G, B, A;
};
} *PRGB;



/********************************************//**
* @brief A class representing a 32 bit Image such as Bitmaps and PNGs.
* 24-bit is NOT support on purpose. Graphics cards process 32-bit images faster.
***********************************************/
class Image
{
private:
#ifdef GRAPHICS_IMAGE_LOADING
std::vector<unsigned char> Pixels;
#else
unsigned char* Pixels;
#endif
unsigned int Width;
unsigned int Height;

public:
enum class Format {GL_BMP, GL_PNG};

#ifdef GRAPHICS_IMAGE_LOADING
Image(const char* Path);
#endif // ENABLE_IMAGE_LOADING

Image(unsigned int Target, unsigned int ID);
Image(void* Data, unsigned int Width, unsigned int Height);
~Image();

const void* GetPixels() const;

void Save(const char* Path, Format Fmt = Format::GL_PNG);

void Flip();
void FlipTo(void* Data);
void Transpose();
void TransposeTo(void* Data);
static void Flip(void* In, void* &Out, int width, int height, uint32_t Bpp = 32);
};




/********************************************//**
* @brief A class representing a texture in video memory. Upon destruction, the texture is deleted.
***********************************************/
class Texture
{
private:
unsigned int ID;
unsigned int Target;
unsigned int Width, Height;
unsigned int Format;

public:
/********************************************//**
* @brief Texture Constructor. Initialises a texture in video memory.
*
* @param Target unsigned int - Can be GL_TEXTURE_RECTANGLE OR GL_TEXTURE_2D
* @param Width unsigned int - Width of the texture to create.
* @param Height unsigned int - Height of the texture to create.
* @param unsigned char* Pixels = nullptr - Pixels are optional. If specified, must be in a 32-bit format (ARGB, BGRA, ABGR, etc).
* @param unsigned int Format = GL_BGRA - Format of the 32-bit layout. (ARGB, BGRA, ABGR, etc..) CANNOT be 24-bit formats.
*
***********************************************/
Texture(unsigned int Target, unsigned int Width, unsigned int Height, unsigned char* Pixels = nullptr, unsigned int Format = GL_BGRA);


/********************************************//**
* @brief Texture Destructor. Deletes a texture from video memory. Cleanup.
***********************************************/
~Texture();



/********************************************//**
* @brief Sets the pixels of the entire texture.
* Pixels must be Width * Height * 4 OR ((Width * 32 + 31) / 32) * 4 * Height.
*
* @param unsigned char* Pixels - Buffer containing the pixels to be set.
* @return
*
***********************************************/
void SetPixels(unsigned char* Pixels);


/********************************************//**
* @brief Draws this texture to the back-buffer with glColor4ub(255, 255, 255, 255).
*
* @param X1 float - The X-coordinate of the upper-left corner of the rectangle in which to render this texture.
* @param Y1 float - The Y-coordinate of the upper-left corner of the rectangle in which to render this texture.
* @param X2 float - The X-coordinate of the lower-right corner of the rectangle in which to render this texture.
* @param Y2 float - The Y-coordinate of the lower-right corner of the rectangle in which to render this texture.
* @return void
*
***********************************************/
void Draw(float X1, float Y1, float X2, float Y2);


/********************************************//**
* @brief Returns the ID of the texture generated by this class.
*
* @return unsigned int - ID of the texture in video memory.
*
***********************************************/
unsigned int GetID() const {return ID;}


/********************************************//**
* @brief Returns the PixelFormat of the texture generated by this class. Always returns a 32-bit format.
*
* @return unsigned int - Pixel Format: GL_RGBA, GL_BGRA, etc..
*
***********************************************/
unsigned int GetPixelFormat() const {return Format;}


/********************************************//**
* @brief Returns the Width of this texture as specified upon creation.
*
* @return int
*
***********************************************/
int GetWidth() const {return Width;}


/********************************************//**
* @brief Returns the Height of this texture as specified upon creation.
*
* @return int
*
***********************************************/
int GetHeight() const {return Height;}


/********************************************//**
* @brief Returns the Target of this texture as specified upon creation. GL_TEXTURE_RECTANGLE OR GL_TEXTURE_2D
*
* @return unsigned int
*
***********************************************/
unsigned int GetTarget() const {return Target;}
};




/********************************************//**
* @brief A class representing a Font in Graphics Memory (DeviceContext). Upon destruction, the font is deleted.
***********************************************/
class Font
{
private:
HDC DC;
unsigned int Base;
unsigned int Size;
const char* Name;


/********************************************//**
* @brief Determines if two types are the exact same when decayed at compile time.
*
* @param T - Type to compare to.
* @param U - Type that is decayed first and compared to T.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T, typename U>
struct is_same_decay : public std::integral_constant<bool, std::is_same<T, typename std::decay<U>::type>::value> {};


/********************************************//**
* @brief Compares a type to a char, char*, or const char* when decayed at compile time.
*
* @param T - The type to decay and compare.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T>
struct is_char_type : public std::integral_constant<bool, is_same_decay<char, T>::value || is_same_decay<char*, T>::value || is_same_decay<const char*, T>::value> {};


/********************************************//**
* @brief Overrides std::to_string via ADL but only if the parameter is a char, char* or const char* when decayed.
*
* @param value T to be convert to a string. Must be a char, char* or const char* for this function to be triggered.
* @return An STL string containing the contents of the parameter.
*
***********************************************/
template<typename T>
std::string to_string(T value)
{
static_assert(is_char_type<T>::value, "Argument: Value Must be of literal type.");
std::string Result;
Result += value;
return Result;
}

public:
/********************************************//**
* @brief Constructor for constructing a BitmapFont in video memory.
*
* @param Name const char* - Name of the font to be used. Arial, TimesNewRoman, etc..
* @param DC HDC - Device Context in which to select the new font into.
* @param Size unsigned int - Size of the font.
*
***********************************************/
Font(const char* Name, HDC DC, unsigned int Size);


/********************************************//**
* @brief Destructor deleted the font from video memory.
***********************************************/
~Font();



/********************************************//**
* @brief Variadic template version of PrintF for OpenGL. Draws a string in white.
*
* @param X float - X position on the screen where the top left of the string is to be drawn.
* @param Y float - Y position on the screen where the top left of the string is to be drawn.
* @param Text const char* - Text containing the string as well as the format if necessary.
* @param args Args&&... - Variadic parameter pack containing arguments deduced by the format string if any.
* @return void
*
* Draw(X, Y, "This is a non-formated string");
* Draw(X, Y, "This is a formated string with % number(s), 1);
*
***********************************************/
template<typename... Args>
void Draw(float X, float Y, const char* Text, Args&&... args);


/********************************************//**
* @brief Variadic template version of PrintF for OpenGL. Draws a string in any colour.
*
* @param X float - X position on the screen where the top left of the string is to be drawn.
* @param Y float - Y position on the screen where the top left of the string is to be drawn.
* @param R float - R component in the RGB model of the colour to be used. 0.0f <= R <= 1.0f.
* @param G float - G component in the RGB model of the colour to be used. 0.0f <= G <= 1.0f.
* @param B float - B component in the RGB model of the colour to be used. 0.0f <= B <= 1.0f.
* @param Text const char* - Text containing the string as well as the format if necessary.
* @param args Args&&... - Variadic parameter pack containing arguments deduced by the format string if any.
* @return void
*
* Draw(X, Y, 0.5f, 0.5f, 0.5f, "This is a non-formated string");
* Draw(X, Y, 1.0f, 0.0f, 0.0f, "This is a formated string with % number(s), 1);
***********************************************/
template<typename... Args>
void Draw(float X, float Y, float R, float G, float B, const char* Text, Args&&... args);
};

#endif // GRAPHICS_HXX_INCLUDED



The documentation takes the longest and wastes the most time.. So all in all, I have NOT been working on animated textures or patching the current plugin. I've instead been getting rid of the old code and slowly replacing it with faster and better new code with proper documentation.. That includes the hooking API so that things will be EASIER for me to hook. Otherwise, there's not really a way for me to just shove in a new texture API without headaches..

Also been trying to make it as cross-platform as I can.. The reason for the re-write is simply.. It's impossible to hook model vertices with the current code.. This is something I keep getting asked to implement.. With the new code-base, I can port most of my Direct-X code to OpenGL for model hooks (We'll see if it works).

Things like this: https://github.com/Brandon-T/SRL-GLX/blob/master/GLXCore.simba#L981 NEEDS to be updated.. It was written when Lape was in its earliest release stage and it's extremely nasty. I don't think I even remember how it works -__-..

Patriq

2015-02-08 07:02:34

From: Brandon
I did not think of a solution yet but I am leaning on doing exactly that. I've been trying really HARD to keep the new code-base understandable for all and not just me.. Then I've been working on optimising & micro-optimising (because this is low level graphics) stuff but trying to keep it readable as well..

The current plugin has way too much patch code and it's really hard for me to just stick in new stuff..

For example, some micro-ops would be:

(2195 mod 256) - 11 I've optimised to (2195 & 255) - 11 to avoid the cost of modulo.. Now it may not look like a huge change, but when ran over thousands of times per second and bottle necks the CPU, it counts a lot. I've benched it and tested it.
And since all textures are GL_TEXTURE_2D (power of two's.. about damn time Jagex updated their stuff), it makes this even faster than ever.


Then I got rid of GL_TEXTURE_ARB (non-power of two textures) because the game no longer uses it and there's no need for unnecessary branching and extra checks.. Sometimes it uses it for the tiniest irrelevant code.

I completely re-wrote fonts so that it doesn't have to store almost 10k fonts per frame per area.. Instead, it stores nothing and grabs them on the fly due to the above calculation.. This means that I don't have to delete anything because there's no memory being used..

For example.. Previously I did:


void Font::LogEndList()
{
if (this->Found) //check if a character was possibly rendered.
{
this->LastFont = false; //is this the last character rendered in a font set (256 * however many lists the game loads.. roughly 4k).

if (!this->Fonts.size()) //if this is the last font, reset the next font to start at "32" aka space in ASCII.
this->Letter = 32;
else
this->Letter = (!this->Fonts.back().LastFont) ? this->Fonts.back().Letter + 1 : 32; //Else, the next char is the last char + 1 in the ASCII table.

if (++this->Count >= 255) //Every 256 fonts, we need to reset the font counter and start over.. There's roughly 4k lists to go through.
{
this->Count = 0;
this->LastFont = true;
this->Found = false;
}
this->Fonts.push_back(*this); //Store the current character in the Font vector structure.
}
}


and now I do:


void Font::LogFont(unsigned int List)
{
font->Letter = (List & 0xFF) - 11;
}

And trust me when I say that's probably the biggest improvement so far (because I haven't worked on anything else yet other than raw API code).. I went from storing 10k "Font structures" in a vector or maps and doing a look up to get each letter rendered.. To doing no look ups and storing nothing OR storing on a frame-by-frame basis in the very worst case.


You can see that the new above generic algorithm works for all characters:


1632 % 256 = 96 minus 11 = U
1662 % 256 = 126 minus 11 = s
1648 % 256 = 112 minus 11 = e
1661 % 256 = ? minus 11 = ?
1657 ...
1644 ...

Derived Algorithm: Character = (List % 256) - 11.

Faster Derived algorithm: Character = (List & 255) - 11.

You can test it out for the remaining letters and see that it spells out "Username" which was the text written on the login screen. I tested this on menus, login, etc..


Other than that, I've been working on the math and calculations:


Mat4 Mat4::Transpose() const
{
Mat4 res;
for (int i = 0; i < 4; ++i)
{
for (int j = 0; j < 4; ++j)
{
res[j][i] = mat[i][j];
}
}
return res;
}

Mat4 Mat4::Identity()
{
Mat4 res;
res[0][0] = 1.0f;
res[1][1] = 1.0f;
res[2][2] = 1.0f;
res[3][3] = 1.0f;
return res;
}

Mat4 Mat4::Orthagonal(float w, float h, float zNear, float zFar)
{
Mat4 res;
res[0][0] = 2.0f / w;
res[1][1] = -2.0f / h;
res[2][2] = -2.0f / (zFar - zNear);
res[3][3] = 1.0f;
res[3][0] = -1.0f;
res[3][1] = 1.0f;
res[3][2] = (zFar + zNear) / (zFar - zNear);
return res;
}

Mat4 Mat4::Perspective(float w, float h, float zNear, float zFar)
{
Mat4 res;
res[0][0] = 2.0f * zNear / w;
res[1][1] = -2.0f * zNear / h;
res[2][2] = ((-zFar - zNear) * zFar) / (zFar - zNear);
res[2][3] = -2.0f * zNear / (zNear - zFar);
res[3][2] = -1.0f;

res[0][2] = 1.0f;
res[1][2] = -1.0f;
return res;
}

Mat4 Mat4::FieldOfView(float fov, float aspect, float zNear, float zFar)
{
Mat4 res;
res[0][0] = 1.0f / tanf(fov / 2.0f);
res[1][1] = aspect / tanf(fov / 2.0f);
res[2][2] = zFar / (zFar - zNear);
res[3][2] = (zFar * zNear) / (zNear - zFar);
res[2][3] = -1.0f;
res[3][3] = 0.0f;
return res;
}

Mat4 Mat4::LookAt(const Vec3& Eye, const Vec3& At, const Vec3& Up)
{
Vec3 XAxis, YAxis, ZAxis;
ZAxis = (Eye - At).Normalise();
XAxis = (Up.Cross(ZAxis)).Normalise();
YAxis = (ZAxis.Cross(XAxis)).Normalise();

Mat4 res;
res[0][0] = XAxis.x;
res[1][0] = XAxis.y;
res[2][0] = XAxis.z;
res[3][0] = -XAxis.Dot(Eye);
res[0][1] = YAxis.x;
res[1][1] = YAxis.y;
res[2][1] = YAxis.z;
res[3][1] = -YAxis.Dot(Eye);
res[0][2] = ZAxis.x;
res[1][2] = ZAxis.y;
res[2][2] = ZAxis.z;
res[3][2] = -ZAxis.Dot(Eye);
res[3][3] = 1.0f;
return res;
}

Mat4 Mat4::RotX(float rad)
{
float ct = cosf(rad);
float st = sinf(rad);
Mat4 res = Identity();
res[1][1] = ct;
res[1][2] = st;
res[2][1] = -st;
res[2][2] = ct;
return res;
}

Mat4 Mat4::RotY(float rad)
{
float ct = cosf(rad);
float st = sinf(rad);
Mat4 res = Identity();
res[0][0] = ct;
res[0][2] = st;
res[2][0] = -st;
res[2][2] = ct;
return res;
}

Mat4 Mat4::RotZ(float rad)
{
float ct = cosf(rad);
float st = sinf(rad);
Mat4 res = Identity();
res[0][0] = ct;
res[0][1] = st;
res[1][0] = -st;
res[1][1] = ct;
return res;
}

Mat4 Mat4::Rot(float pitch, float yaw, float roll)
{
return RotY(yaw) * RotX(pitch) * RotZ(roll);
}

Mat4 Mat4::Scale(float val)
{
return Scale(val, val, val);
}

Mat4 Mat4::Scale(float x, float y, float z)
{
Mat4 res;
res[0][0] = x;
res[1][1] = y;
res[2][2] = z;
res[3][3] = 1.0f;
return res;
}

Mat4 Mat4::Translate(float x, float y, float z)
{
Mat4 res;
res[3][0] = x;
res[3][1] = y;
res[3][2] = z;
res[0][0] = 1.0f;
res[1][1] = 1.0f;
res[2][2] = 1.0f;
res[3][3] = 1.0f;
return res;
}


But I re-wrote a bunch of code as well:


Serialisation is brand spanking new and way faster and more efficient than before:


#ifndef STREAM_HXX_INCLUDED
#define STREAM_HXX_INCLUDED

#include <vector>
#include <list>
#include <string>
#include <sstream>

/********************************************//**
* @brief A class for serialising all data-types & containers into a buffer.
***********************************************/
class Stream
{
private:
std::stringstream Data;

/********************************************//**
* @brief Determines if two types are the exact same when decayed at compile time.
*
* @param T - Type to compare to.
* @param U - Type that is decayed first and compared to T.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T, typename U>
struct is_same_decay : public std::integral_constant<bool, std::is_same<T, typename std::decay<U>::type>::value> {};


/********************************************//**
* @brief Compares a type to a char*, or const char* when decayed at compile time.
*
* @param T - The type to decay and compare.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T>
struct is_cstring : public std::integral_constant<bool, is_same_decay<char*, T>::value || is_same_decay<const char*, T>::value> {};


/********************************************//**
* @brief Compares a type to a wchar_t*, or const wchar_t* when decayed at compile time.
*
* @param T - The type to decay and compare.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T>
struct is_wcstring : public std::integral_constant<bool, is_same_decay<wchar_t*, T>::value || is_same_decay<const wchar_t*, T>::value> {};


public:
/********************************************//**
* @brief Constructs a stream class.
*
* @param Buffer void* - Buffer to serialise/de-serialise data to/from.
* @param BufferSize std::size_t - Size of the specified buffer.
*
***********************************************/
Stream(void* Buffer, std::size_t BufferSize);

template<typename T>
void Read(T &Value);

template<typename T>
void Write(const T &Value);

template<typename T>
typename std::enable_if<!is_cstring<T>::value && !is_wcstring<T>::value, Stream&>::type operator << (const T &Value);

template<typename T>
typename std::enable_if<!is_cstring<T>::value && !is_wcstring<T>::value, Stream&>::type operator >> (T &Value);

template<typename T, typename Allocator>
Stream& operator << (const std::vector<T, Allocator> &Value);

template<typename T, typename Allocator>
Stream& operator << (const std::list<T, Allocator> &Value);

template<typename T, typename Allocator>
Stream& operator << (const std::basic_string<T, Allocator> &Value);


template<typename T, typename Allocator>
Stream& operator >> (std::vector<T, Allocator> &Value);

template<typename T, typename Allocator>
Stream& operator >> (std::list<T, Allocator> &Value);

template<typename T, typename Allocator>
Stream& operator >> (std::basic_string<T, Allocator> &Value);
};
#endif // STREAM_HXX_INCLUDED


Graphics is re-written too:


#ifndef GRAPHICS_HXX_INCLUDED
#define GRAPHICS_HXX_INCLUDED

#include <GL/gl.h>
#include <GL/glext.h>
#include <utility>
#include <string>
#include <cstring>
#include <vector>
#include <fstream>

#if defined _WIN32 || defined _WIN64
#include <windows.h>
#endif

#include "Libraries/LodePNG.hxx"


/********************************************//**
* @brief Structured Union representing a tightly packed RGBA memory layout.
***********************************************/
typedef union RGBA
{
unsigned int Colour;
struct
{
unsigned char R, G, B, A;
};
} *PRGB;



/********************************************//**
* @brief A class representing a 32 bit Image such as Bitmaps and PNGs.
* 24-bit is NOT support on purpose. Graphics cards process 32-bit images faster.
***********************************************/
class Image
{
private:
#ifdef GRAPHICS_IMAGE_LOADING
std::vector<unsigned char> Pixels;
#else
unsigned char* Pixels;
#endif
unsigned int Width;
unsigned int Height;

public:
enum class Format {GL_BMP, GL_PNG};

#ifdef GRAPHICS_IMAGE_LOADING
Image(const char* Path);
#endif // ENABLE_IMAGE_LOADING

Image(unsigned int Target, unsigned int ID);
Image(void* Data, unsigned int Width, unsigned int Height);
~Image();

const void* GetPixels() const;

void Save(const char* Path, Format Fmt = Format::GL_PNG);

void Flip();
void FlipTo(void* Data);
void Transpose();
void TransposeTo(void* Data);
static void Flip(void* In, void* &Out, int width, int height, uint32_t Bpp = 32);
};




/********************************************//**
* @brief A class representing a texture in video memory. Upon destruction, the texture is deleted.
***********************************************/
class Texture
{
private:
unsigned int ID;
unsigned int Target;
unsigned int Width, Height;
unsigned int Format;

public:
/********************************************//**
* @brief Texture Constructor. Initialises a texture in video memory.
*
* @param Target unsigned int - Can be GL_TEXTURE_RECTANGLE OR GL_TEXTURE_2D
* @param Width unsigned int - Width of the texture to create.
* @param Height unsigned int - Height of the texture to create.
* @param unsigned char* Pixels = nullptr - Pixels are optional. If specified, must be in a 32-bit format (ARGB, BGRA, ABGR, etc).
* @param unsigned int Format = GL_BGRA - Format of the 32-bit layout. (ARGB, BGRA, ABGR, etc..) CANNOT be 24-bit formats.
*
***********************************************/
Texture(unsigned int Target, unsigned int Width, unsigned int Height, unsigned char* Pixels = nullptr, unsigned int Format = GL_BGRA);


/********************************************//**
* @brief Texture Destructor. Deletes a texture from video memory. Cleanup.
***********************************************/
~Texture();



/********************************************//**
* @brief Sets the pixels of the entire texture.
* Pixels must be Width * Height * 4 OR ((Width * 32 + 31) / 32) * 4 * Height.
*
* @param unsigned char* Pixels - Buffer containing the pixels to be set.
* @return
*
***********************************************/
void SetPixels(unsigned char* Pixels);


/********************************************//**
* @brief Draws this texture to the back-buffer with glColor4ub(255, 255, 255, 255).
*
* @param X1 float - The X-coordinate of the upper-left corner of the rectangle in which to render this texture.
* @param Y1 float - The Y-coordinate of the upper-left corner of the rectangle in which to render this texture.
* @param X2 float - The X-coordinate of the lower-right corner of the rectangle in which to render this texture.
* @param Y2 float - The Y-coordinate of the lower-right corner of the rectangle in which to render this texture.
* @return void
*
***********************************************/
void Draw(float X1, float Y1, float X2, float Y2);


/********************************************//**
* @brief Returns the ID of the texture generated by this class.
*
* @return unsigned int - ID of the texture in video memory.
*
***********************************************/
unsigned int GetID() const {return ID;}


/********************************************//**
* @brief Returns the PixelFormat of the texture generated by this class. Always returns a 32-bit format.
*
* @return unsigned int - Pixel Format: GL_RGBA, GL_BGRA, etc..
*
***********************************************/
unsigned int GetPixelFormat() const {return Format;}


/********************************************//**
* @brief Returns the Width of this texture as specified upon creation.
*
* @return int
*
***********************************************/
int GetWidth() const {return Width;}


/********************************************//**
* @brief Returns the Height of this texture as specified upon creation.
*
* @return int
*
***********************************************/
int GetHeight() const {return Height;}


/********************************************//**
* @brief Returns the Target of this texture as specified upon creation. GL_TEXTURE_RECTANGLE OR GL_TEXTURE_2D
*
* @return unsigned int
*
***********************************************/
unsigned int GetTarget() const {return Target;}
};




/********************************************//**
* @brief A class representing a Font in Graphics Memory (DeviceContext). Upon destruction, the font is deleted.
***********************************************/
class Font
{
private:
HDC DC;
unsigned int Base;
unsigned int Size;
const char* Name;


/********************************************//**
* @brief Determines if two types are the exact same when decayed at compile time.
*
* @param T - Type to compare to.
* @param U - Type that is decayed first and compared to T.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T, typename U>
struct is_same_decay : public std::integral_constant<bool, std::is_same<T, typename std::decay<U>::type>::value> {};


/********************************************//**
* @brief Compares a type to a char, char*, or const char* when decayed at compile time.
*
* @param T - The type to decay and compare.
* @return std::integral_constant<bool, true> if the types matched, std::integral_constant<bool, false> otherwise.
*
***********************************************/
template<typename T>
struct is_char_type : public std::integral_constant<bool, is_same_decay<char, T>::value || is_same_decay<char*, T>::value || is_same_decay<const char*, T>::value> {};


/********************************************//**
* @brief Overrides std::to_string via ADL but only if the parameter is a char, char* or const char* when decayed.
*
* @param value T to be convert to a string. Must be a char, char* or const char* for this function to be triggered.
* @return An STL string containing the contents of the parameter.
*
***********************************************/
template<typename T>
std::string to_string(T value)
{
static_assert(is_char_type<T>::value, "Argument: Value Must be of literal type.");
std::string Result;
Result += value;
return Result;
}

public:
/********************************************//**
* @brief Constructor for constructing a BitmapFont in video memory.
*
* @param Name const char* - Name of the font to be used. Arial, TimesNewRoman, etc..
* @param DC HDC - Device Context in which to select the new font into.
* @param Size unsigned int - Size of the font.
*
***********************************************/
Font(const char* Name, HDC DC, unsigned int Size);


/********************************************//**
* @brief Destructor deleted the font from video memory.
***********************************************/
~Font();



/********************************************//**
* @brief Variadic template version of PrintF for OpenGL. Draws a string in white.
*
* @param X float - X position on the screen where the top left of the string is to be drawn.
* @param Y float - Y position on the screen where the top left of the string is to be drawn.
* @param Text const char* - Text containing the string as well as the format if necessary.
* @param args Args&&... - Variadic parameter pack containing arguments deduced by the format string if any.
* @return void
*
* Draw(X, Y, "This is a non-formated string");
* Draw(X, Y, "This is a formated string with % number(s), 1);
*
***********************************************/
template<typename... Args>
void Draw(float X, float Y, const char* Text, Args&&... args);


/********************************************//**
* @brief Variadic template version of PrintF for OpenGL. Draws a string in any colour.
*
* @param X float - X position on the screen where the top left of the string is to be drawn.
* @param Y float - Y position on the screen where the top left of the string is to be drawn.
* @param R float - R component in the RGB model of the colour to be used. 0.0f <= R <= 1.0f.
* @param G float - G component in the RGB model of the colour to be used. 0.0f <= G <= 1.0f.
* @param B float - B component in the RGB model of the colour to be used. 0.0f <= B <= 1.0f.
* @param Text const char* - Text containing the string as well as the format if necessary.
* @param args Args&&... - Variadic parameter pack containing arguments deduced by the format string if any.
* @return void
*
* Draw(X, Y, 0.5f, 0.5f, 0.5f, "This is a non-formated string");
* Draw(X, Y, 1.0f, 0.0f, 0.0f, "This is a formated string with % number(s), 1);
***********************************************/
template<typename... Args>
void Draw(float X, float Y, float R, float G, float B, const char* Text, Args&&... args);
};

#endif // GRAPHICS_HXX_INCLUDED



The documentation takes the longest and wastes the most time.. So all in all, I have NOT been working on animated textures or patching the current plugin. I've instead been getting rid of the old code and slowly replacing it with faster and better new code with proper documentation.. That includes the hooking API so that things will be EASIER for me to hook. Otherwise, there's not really a way for me to just shove in a new texture API without headaches..

Also been trying to make it as cross-platform as I can.. The reason for the re-write is simply.. It's impossible to hook model vertices with the current code.. This is something I keep getting asked to implement.. With the new code-base, I can port most of my Direct-X code to OpenGL for model hooks (We'll see if it works).

Things like this: https://github.com/Brandon-T/SRL-GLX/blob/master/GLXCore.simba#L981 NEEDS to be updated.. It was written when Lape was in its earliest release stage and it's extremely nasty. I don't think I even remember how it works -__-..


If there is something I can do please tell me :D

riwu

2015-02-08 08:45:52

From: Brandon
I did not think of a solution yet but I am leaning on doing exactly that. I've been trying really HARD to keep the new code-base understandable for all and not just me.. Then I've been working on optimising & micro-optimising (because this is low level graphics) stuff but trying to keep it readable as well..

Thanks for the great work, looking forward to the revamped source!

I've read your tutorial https://villavu.com/forum/showthread.php?t=89645, now reading through the plugin source to learn more about hooking :) there's still plenty of things that i dont understand though….especially since my knowledge of c++ is only limited to http://greenteapress.com/thinkcpp/thinkCScpp.pdf lol

https://github.com/Brandon-T/GLX/blob/master/GLX/src/Exports.cpp#L236
What's line 235-237 (and 250-252) for? The next 3 lines does the exact same thing except adding in a boolean comparison?

Clarity

2015-02-09 10:40:53

From: PatriqDesigns
Well why dont you release what you have done to the community? Why wont you make a repo for it where all could contribute. That would be awesome, and would let OpenGL development be more "accepted" and used.


Fear not :)
I'm sure @riwu, like myself, has not released much OGL work to the community simply because it is so powerful in terms of profit potential, and the things he has likely made are not really public material (e.g. fishers, choppers, miners focused on XP not GP).

However, the tutorial and library @Obscurity and I are working on will give everyone the tools to do these things themselves. As a result, your profits will be merit based, as I believe they should be. However, I do plan on releasing my dungeoneering script fully free and to the public when it is eventually finished (been forever I know!).

I only release scripts when I am totally done using them for my own purposes, else I end up bringing in a ton of competition against myself, and nobody wants to do that. Idk about others' mentalities.

So, with the OGL release I plan on releasing to higher boards some mid-level money makers like frost dragons, since I've stopped using them entirely in favor of higher level profit scripts (GWD, etc.)

I'm sure Obscurity has similar plans.

Obscurity

2015-02-09 12:40:38

I don't plan on releasing ones like Tormented Demons or Ascension, but I'd be happy to give the Bandos/etc to members. :-).

Also, sorry for ditching you last night, Clarity. My PC is in pieces in front of me here at work. Gonna take some fixing before I can get back online (phone ATM).

riwu

2015-02-25 01:54:29

@Brandon;
Simba's memory usage is rising proportional to time running
it got over 1GB after 20hr+ of running

Are u already aware of this and is waiting for simba changes to fix it?
https://github.com/MerlijnWajer/Simba/issues/340

Brandon

2015-02-25 02:24:18

From: riwu
@Brandon;
Simba's memory usage is rising proportional to time running
it got over 1GB after 20hr+ of running

Are u already aware of this and is waiting for simba changes to fix it?
https://github.com/MerlijnWajer/Simba/issues/340




That request on Simba's github is just to make things easier and compatible with future plugins and doesn't have anything to do with the current plugin. It would be extremely nice of the Simba dev team to add it. It will make ANY plugin written in ANY language exponentially more powerful. Hence the reason why I made the request (which I normally never do and instead find work around's for)

As for memory usage increasing, I'd check your script because the Simba plugin doesn't allocate a drop of raw memory. All it does is pass pointers to Simba and read and write data to the SMART plugin. It doesn't require any allocations at all.


https://github.com/riwu/GLX/blob/master/GLX/src/Exports.cpp#L88


For example, take the above function. If you notice, it takes a "size" variable as a reference/pointer. It will set this variable to the amount of models available from the client. This tells Simba how many models to read directly from memory (yes, Simba does all of the reading/writing as well). This way, the plugin doesn't have to allocate anything and instead, allocations are done in Simba itself via SetLength as shown below:

https://github.com/Brandon-T/SRL-GLX/blob/master/GLXCore.simba#L170


Function glGetTextures: glTextureArray;
var
Size, I: Cardinal;
Ptr: Pointer;
Begin
Result := [];
Ptr := GLXTextures(Size); //get a pointer to data from the plugin (directly from the Smart plugin).
SetLength(Result, Size); //Allocate memory for the textures we're going to read (via Simba).

For I := 0 To Size - 1 Do //read this many textures from the client.
Begin
Result[I] := glTexture(Ptr^); //cast the pointer to a texture.
Ptr.Inc(sizeof(glTexture)); //move the pointer to the next texture.
End;
End;

If you notice, all the plugin functions use SetLength on the Simba side and simply read the data into the memory allocated by Simba. This makes it impossible for the plugin to leak because it never allocated anything in the first place. I've purposely done this (made Simba do all the allocations via SetLength) so that I would not have to worry about anyone complaining about plugin leaks.

In fact, if Simba could read from SharedMemory directly, the GLX.dll plugin would never exist (it only exists to give Simba a pointer to the shared memory block and synchronise communications via Event/Mutex). SmartRemote32 might not exist either or any other communication plugins.

Though, I am curious as to what would raise your memory usage that high. It would only be possible to leak memory if you were to use AllocMem, GetMem or CreateBitmap and functions such as those. That's the ONLY way (other than constantly crashing and restarting the script thread.. in which case, add on terminate won't be called to free the one and only bitmap the plugin uses).


However, do note that the include does not use such. It only uses CreateBitmap internal (for Smart's debug of course). I can't see a problem with that as only one bitmap is ever created per smart per script for the duration of the lifetime of the script entirely.

The only way I can see you leaking is if you created a ton of your own bitmaps and freed none (which I doubt as well).

Are you allocating raw memory in Simba anywhere? Are all your images freed?