SRL Archive - First Scripts

Grand exchange


Wardancer

2012-09-10 21:24:43

Hello,

First, I want to say a big thank you to everyone that helped me writing this script. NKN gave a lot of his time to help me out at the very start to tutor me and explain the difference between a string and an integer. Also note (and I can't stress that enough) that the general frame (declare player and such) of the script and the custom object functions were written by him. I only filled the skeleton. I also want to thank everyone that were helpful on the help section of the forum, namely riwu, litoris, masterBB, Runaway and certainly a few more that I've forgotten. I also can't forget Rasta Magician and ProphesyOfWolf for their original work on grandexchange.simba. Even though I basically rewrote all the commands, the work they've done was an inspiration for me and helped me work around a few issues.

EDIT: I've just been told I should credit ReadySteadyGo for the object finding function, so here it is.

I decided as my first scripting task to rewrite a bunch of functions related to the grand exchange. It goes from opening the GE to recovering items while also buying any item and selling any item (no slot restriction). I didn't bother explaining in details what each functions do and how to use them (let's pretend that's my antileech), but I'll just say that you have to type the full name of items that you want to buy or sell. That one is less obvious if you don't work with the text commands often.

For any question, comment, bug report, request for an extra function or insult, feel free to post.

EDIT 2: Just thought I should say that I learned what a variable is on september 3rd (1 week ago). That's what I came up with one week after starting to learn about coding.

program new;
{$DEFINE SMART}
{$i srl/srl.simba}
{$i srl/srl/misc/SmartGraphics.simba}

procedure DeclarePlayers;
begin
HowManyPlayers := 1; // This is set to the total amount of players (more on multiplayer later ;)), for now, just keep it set as 1
NumberOfPlayers(HowManyPlayers); // This is a procedure in SRL which sets up player arrays (also, more on that later), this will always be the same
CurrentPlayer := 0; // This is the player to start with; the first player will always be 0 (you'll find out when you learn all about arrays)

Players[0].Name := ''; // Username
Players[0].Pass := ''; // Password
Players[0].Nick := ''; // 3-4 lowercase letters from username; used for random event detection
Players[0].Active := True; // Set to true if you want to use Player 0
Players[0].Pin := ''; // Leave blank if the player doesn't have a bank pin
Players[0].BoxRewards := ['Xp', 'mote', 'ostume', 'oins', 'aphire', 'ssence'];
end;
procedure Antiban;
begin
FindNormalRandoms;
case Random(80) of
0: RandomRClick;
2: PickUpMouse;
3: RandomMovement;
4: BoredHuman;
5: ExamineInv;
7: SetAngle(SRL_ANGLE_HIGH);
8: Wait(5000)
end;
end;
type //Credit goes to NKN for the custom object finding functions. I only put the values in there, but the frame is all his. //Been told I have to credit ReadySteadyGo for it too
MSObject = record
Col, Tol, TPADist, MinCount: Integer;
Hue, Sat: Extended;
Uptext: String;
MMDot: String;
end;
var
GE, BuyButton, SellButton, CancelButton, ExitGEMenuButton : MSObject;
procedure LoadObjects;
begin
with GE do
begin
Col := 2891040;
Tol := 20;
Hue := 0.18;
Sat := 0.30;
UpText := 'Exch'
end;
with BuyButton do
begin
Col := 247218;
Tol := 4;
Hue := 0.25;
Sat := 1.29;
UpText := 'Buy O'
end;
with SellButton do
begin
Col := 224454;
Tol := 4;
Hue := 0.34;
Sat := 0.03;
UpText := 'Sell O'
end;
with CancelButton do
begin
Col := 791918;
Tol := 20;
Hue := 0.04;
Sat := 0.47;
UpText := 'bort'
end;
with ExitGEMenuButton do
begin
Col := 11975110;
Tol := 10;
Hue := 0.80;
Sat := 0.31;
UpText := 'ack'
end;
end;
function FindObject(var x,y : Integer; Obj: MSObject; X1,Y1,X2,Y2:integer) : Boolean;
var
a : Integer;
TPA : TPointArray;
ATPA : T2DPointArray;
MP : TPoint;
tmpCTS : Integer;
Box : TBox;
begin
if not LoggedIn then Exit;
tmpCTS := GetColorToleranceSpeed;
ColorToleranceSpeed(2);
SetColorSpeed2Modifiers(Obj.Hue,Obj.Sat);
FindColorsSpiralTolerance(MSCX,MSCY,TPA,Obj.Col,X1,Y1,X2,Y2,Obj.Tol);
SortTPAFrom(TPA,point(MSCX,MSCY));
ATPA := TPAtoATPAEx(TPA,15,15);
for a := 0 to High(ATPA) do
begin
MP := MiddleTPA(ATPA[a]);
Box := IntToBox((MP.x - 20),(MP.y - 20),(MP.x + 20),(MP.y + 20));
SMART_DrawBoxEx(True,False,Box,clYellow);
MMouse(MP.x,MP.y,4,4);
if(WaitUpText(Obj.UpText,400))then
begin
x := MP.x; y := MP.y;
Result := True
SMART_ClearCanvas;
Break;
end;
end;

ColorToleranceSpeed(tmpCTS);
SetColorSpeed2Modifiers(0.2,0.2);
end;
function InGEE: Boolean; //From now on it's my work
begin
result := findTextTPA(39116, 20, 204, 27, 248, 49, 'Grand', upCharsEx, nothing);
end;
function GEESellMenu: Boolean;
begin
result := findTextTPA(39116, 20, 87, 68, 155, 86, 'Sell O', upCharsEx, nothing);
end;
function GEEBuyMenu: Boolean;
begin
result := findTextTPA(39116, 20, 87, 68, 155, 86, 'Buy O', upCharsEx, nothing);
end;
function GEEBuyOrSellMenu: Boolean;
begin
result := GEEBuyMenu or GEESellMenu;
end;
function GEEIsSpotFree(spot : Integer): Boolean;
var
a : TBox;
begin
a := GridBox(spot, 3, 2, 50, 30, 157, 121, point(105,95))
result := findTextTPA(39372, 20, a.x1, a.y1, a.x2, a.y2, 'Empty', upCharsEx, nothing);
if result = true then
writeln('This spot is free!');
if result = false then
writeln('This spot is not free!');
end;
function GEEReadyToCollect: Boolean;
var
x, y : Integer;
begin
result := FindColorTolerance(x, y, 1048714, 175, 310, 275, 310, 50) or FindColorTolerance(x, y, 1999423, 175, 310, 275, 310, 50)
end;
function GEECanTypeAmount: Boolean;
begin
result := findTextTPA(0, 150, 125, 387, 166, 412, 'nter', upCharsEx, nothing);
end;
function GEECanTypePrice: Boolean;
begin
result := findTextTPA(0, 150, 140, 392, 182, 411, 'nter', upCharsEx, nothing);
end;
function GEECanTypeItem: Boolean;
begin
result := findTextTPA(23200, 50, 196, 355, 228, 373, 'rand', upCharsEx, nothing);
end;
procedure OpenGE;
var
x,y:integer;
begin
if InGEE or GEESellMenu or GEEBuyMenu then
Exit;
if(FindObject(x,y,GE,MSX1,MSY1,MSX2,MSY2)) then
begin
Clickmouse2(false);
WaitOption('Exchange G',500);
WaitFunc(@InGEE,10,6000);
end else
Exit;
end;
procedure GEEMenuExit;
var
x, y : Integer;
begin
if not InGEE then
Exit;
if not GEESellMenu and not GEEBuyMenu then
Exit;
if(FindObject(x,y,ExitGEMenuButton,MSX1,MSY1,MSX2,MSY2)) then
begin
ClickMouse2(true);
WaitUptext('ack',5000);
Wait(750 + Random(200));
end else
Exit;
end;
procedure GEERecoverAt(spot : integer; abort : Boolean);
var
i, x, y : Integer;
b, c : TBox;
begin
if not InGEE then
Exit;
if GEESellMenu or GEEBuyMenu then
GEEMenuExit;
begin
if not GEEIsSpotFree(spot) then
begin
b := GridBox(spot, 3, 2, 100, 70, 155, 120, point(100,136));
MouseTBox(b, 1);
WaitFunc(@GEEBuyOrSellMenu, 10, 6000);
if abort then
begin
if (FindObject(x,y,CancelButton,MSX1,MSY1,MSX2,MSY2)) then
ClickMouse2(true);
WaitUptext('bort',500);
WaitFunc(@GEEReadyToCollect, 10, 6000);
end;
for i := 1 to 2 do
begin
c := GridBox(i, 2, 1, 15, 12, 60, 0, point(417, 295));
writeln('test');
MouseTBox(c, 3);
Wait(500 + random(100));
if IsUptext('ollect') then
begin
ClickMouse2(true);
Wait(500 + random(100));
end;
end;
end;
end;
end;
procedure GEERecoverAll(abort : Boolean);
var
i : Integer;
begin
for i := 1 to 6 do
if abort then
begin
GEERecoverAt(i, true);
end else
GEERecoverAt(i, false);
end;
function GEEIsFinishedAt(spot: Integer): Boolean;
var
x, y : Integer;
a : TBox;
begin
if not InGEE then
Exit;
if GEESellMenu or GEEBuyMenu then
GEEMenuExit;
a := GridBox(spot, 3, 2, 100, 70, 155, 120, point(100,136));
result := FindColorTolerance(x, y, 1999423, a.x1, a.y1, a.x2, a.y2, 50);
end;
procedure GEEIsFinishedAny;
var
i : Integer;
begin
for i := 1 to 6 do
GEEIsFinishedAt(i);
end;
procedure GEERecoverFinishedAt(spot : Integer);
begin
if not InGEE then
Exit;
if GEESellMenu or GEEBuyMenu then
GEEMenuExit;
if GEEIsFinishedAt(spot) then
GEERecoverAt(spot, false);
end;
procedure GEERecoverAllFinished;
var
i : Integer;
begin
for i := 1 to 6 do
GEERecoverFinishedAt(i);
end;
function GEEBuyAt(spot: integer): Boolean;
var
x, y : Integer;
b : TBox;
begin
Result := False;
if not InGEE then
Exit;
if GEESellMenu or GEEBuyMenu then
Exit;
case spot of
0:
if not (FindObject(x,y,BuyButton,MSX1,MSY1,MSX2,MSY2)) then
begin
writeln('No spot is free')
Exit;
end;
1..6:
begin
b:= GridBox(spot, 3, 2, 155, 120, 155, 120, point(100,136));
if not FindObject(x,y,BuyButton,b.x1,b.y1,b.x2,b.y2) then
begin
writeln('This spot is not free')
Exit;
end;
end;
else
begin
writeln('Invalid spot entered');
Exit;
end;
end;
ClickMouse2(true);
WaitUptext('Buy O',500);
Wait(500+Random(250));
WaitFunc(@GEEBuyMenu,10,6000);
end;
function GEESellAt(spot: integer): Boolean;
var
x, y : Integer;
b: TBox;
begin
Result := False;
if not InGEE then
Exit;
if GEESellMenu or GEEBuyMenu then
GEEMenuExit;
case spot of
0:
if not (FindObject(x,y,SellButton,MSX1,MSY1,MSX2,MSY2)) then
begin
writeln('No spot is free')
Exit;
end;
1..6:
begin
b:= GridBox(spot, 3, 2, 155, 120, 155, 120, point(100,136));
if not FindObject(x,y,SellButton,b.x1,b.y1,b.x2,b.y2) then
begin
writeln('This spot is not free')
Exit;
end;
end;
else
begin
writeln('Invalid spot entered');
Exit;
end;
end;
ClickMouse2(true);
if WaitUptext('Sell O',500) then
WaitFunc(@GEEBuyMenu,10,6000);
Wait(1250+Random(250));
end;
procedure GEESetQuantity(Q : String);
var
x, y, numberOfFailures : integer;
searchBox: TBox;
begin
for numberofFailures := 0 to 5 do
if not InGEE then
Exit;
if not GEESellMenu and not GEEBuyMenu then
Exit;
case lowercase(Q) of
'1':
searchBox := IntToBox(56, 211, 87, 231);
'10':
searchBox := IntToBox(97, 211, 129, 231);
'100':
searchBox := IntToBox(138, 211, 170, 231);
'all':
if not GEESellMenu then
begin
writeln('Invalid parameter');
Exit;
end else
searchBox := IntToBox(180, 211, 210, 231);
else
begin
if (FindColorTolerance(x, y, 39116, 222, 211, 252, 231, 100)) then
begin
MMouse(x, y, 4, 4);
ClickMouse2(true);
WaitFunc(@GEECanTypeAmount, 10, 16000);
TypeSendEx(Q, true);
Wait(1500 + Random(250));
end;
end;
end;
case lowercase(Q) of
'1', '10', '100', 'all':
if (FindColorTolerance(x, y, 39116, searchBox.x1, searchBox.y1, searchBox.x2, searchBox.y2, 100)) then
begin
MMouse(x, y, 4, 4);
ClickMouse2(true);
Wait(1000 + Random(500));
end;
end;
if (ExtractFromStr(GetTextAtExWrap(86, 184, 227, 198, 0, 10, 1, 6400255, 50, UpCharsEx), Numbers)) = Q then
Exit;
begin
writeln('Something went wrong!')
Inc(numberOfFailures);
if numberofFailures = 5 then
begin
writeln('Failed too many times. Terminating script.');
TerminateScript;
end;
end;
end;
procedure GEESetPrice(Value : String; numberOfClicks : Integer);
var
x, y, numberOfFailures, numberOfClickz : integer;
searchBox: TBox;
begin
for numberOfFailures := 0 to 5 do
if not InGEE then
Exit;
if not GEESellMenu and not GEEBuyMenu then
Exit;
case lowercase(Value) of
'min':
searchBox := IntToBox(274, 211, 304, 231);
'mid':
Exit;
'max':
searchBox := IntToBox(427, 211, 460, 231);
else
begin
if (FindColorTolerance(x, y, 39167, 371, 211, 403, 231, 100)) then
begin
MMouse(x, y, 4, 4);
ClickMouse2(true);
WaitFunc(@GEECanTypePrice, 10, 6000);
TypeSendEx(Value, true);
Wait(1500 + Random(250));
if (ExtractFromStr(GetTextAtExWrap(296, 184, 438, 198, 0, 10, 1, 6400255, 50, UpCharsEx), Numbers)) = Value then
Exit;
begin
writeln('Something went wrong!')
Inc(numberOfFailures);
if numberOfFailures = 5 then
begin
writeln('Failed too many times. Terminating script.');
TerminateScript;
end;
end;
end;
end;
end;
case lowercase(Value) of
'min', 'max':
if (FindColorTolerance(x, y, 39167, searchBox.x1, searchBox.y1, searchBox.x2, searchBox.y2, 100)) then
begin
repeat
MMouse(x, y, 4, 4);
ClickMouse2(true);
Inc(numberOfClickz);
Wait(200 + Random(50));
until (numberOfClickz = numberOfClicks);
Wait(500 + Random(200));
end;
end;
end;
procedure GEEConfirmOffer;
begin
MouseBoxEx(215, 286, 310, 325, 10, 1);
Wait(1500 + Random(500));
end;
procedure GEEBuy(What, Quantity, Value: String; numberOfClicks, spot : Integer);
var
x, y : Integer;
begin
if not InGEE then
Exit;
if GEESellMenu or GEEBuyMenu then
GEEMenuExit;
GEEBuyAt(spot);
WaitFunc(@GEECanTypeItem, 10, 6000);
TypeSendEx(What, true);
WaitFindColor(x, y, 23200, 67, 343, 119, 359, 30, 6000);
MouseBoxEx(200, 350, 228, 368, 5, 1);
WaitColorGone(39372, 394, 81, 40, 6000);
Wait(500 + Random(250));
if lowercase(GetTextAtExWrap(590, 236, 705, 257, 0, 10, 1, 39423, 50, StatChars)) = lowercase(ExtractFromStr(What, Letters)) then
begin
GEESetQuantity(Quantity);
GEESetPrice(value, numberOfClicks);
GEEConfirmOffer;
Exit;
end else
Writeln('A problem occurred. Trying again.');
GEEBuy(What, Quantity, Value, numberOfClicks, spot);
end;
procedure GEESell(What, Quantity, Value : String; numberOfClicks, spot : Integer);
var
i, numberOfFails : Integer;
begin
if not InGEE then
Exit;
if GEESellMenu or GEEBuyMenu then
GEEMenuExit;
GEESellAt(spot);
repeat
for i := 1 to 28 do
begin
MouseSpeed := randomrange(8, 15);
MouseTBox(InvBox(i), 3);
if lowercase(GetTextAtExWrap(46, 7, 147, 23, 0, 10, 1, 2658536, 50, UpChars)) = lowercase(ExtractFromStr(What, Letters)) then
begin
writeln('Found the item at slot ' + IntToStr(i));
ClickMouse2(true);
Wait(2000 + Random(500));
Break;
end else
Inc(numberOfFails);
if (numberOfFails) = 100 then
begin
writeln('Item not found. Terminating script.');
TerminateScript;
end;
end;
until(lowercase(GetTextAtExWrap(46, 7, 147, 23, 0, 10, 1, 2658536, 50, UpChars)) = lowercase(ExtractFromStr(What, Letters)));
begin
if lowercase(GetTextAtExWrap(212, 68, 386, 89, 0, 10, 1, 39372, 50, UpCharsEx)) = lowercase(ExtractFromStr(What, Letters)) then
begin
GEESetQuantity(Quantity);
GEESetPrice(value, numberOfClicks);
GEEConfirmOffer;
end else
GEESell(What, Quantity, Value, numberOfClicks, spot);
end;
end;



procedure Test;
begin
OpenGE;
GEEBuy('clean ranarr', '5', 'max', 4, 0);
Wait(120000);
GEERecoverAllFinished;
Wait(120000);
GEESell('clean ranarr', 'all', '9999', 1, 0);
end;



procedure Mainloop;
begin
//OpenGE;
Test;



end;

begin
{$IFDEF SMART}
SRL_SIXHOURFIX := TRUE;
SMART_FIXSPEED := TRUE;
{$ENDIF}

ClearDebug;
SetupSRL;
DeclarePlayers; // Calls the procedure, you can't forget this!
LoginPlayer;
ClickNorth(SRL_ANGLE_HIGH);
LoadObjects;
repeat
Mainloop;
until(allPlayersInactive);
end.

Thank you for your comments.

Rezozo

2012-09-10 21:27:38

First! And Sweeeeeeeeet. Definitely gonna check this out later.

NKN

2012-09-10 21:32:40

Nice release. :D

mormonman

2012-09-10 22:33:10

<Wardancer> My grand exchange functions. Please comment: http://villavu.com/forum/showthread.php?t=89709


Comment.

NKN

2012-09-10 22:34:09

From: mormonman
Comment.


Well that was literal.

Wardancer

2012-09-11 16:13:34

Known bug:
- GetTextAtExWrap reads every "i" as ".!", making it impossible to sell any item containing an "i" with the current built. If there is a demand for it, I'll code a second function that will work slot based instead of by name.

Known possible problem:
- If you're typing the full name of an item and it's still not the one on top, the script won't pick it. It'll only pick the first one. A failsafe is in place to prevent you from buying unwanted items. You might end up in an endless loop though. I won't bother patching this unless it comes up as a major issue for some players.

Austin

2012-09-11 18:40:55

Looks great! Just did a quick run through/test of it. Only thing I noticed is that it doesn't do the pin for me. I put the pin into the script, waited about 30 seconds (yes i know not long) and it didn't work. It was a quick run through so not sure if it can easily be fixed or not. But everything else worked great! Good release :)

Wardancer

2012-09-11 20:03:37

Oh, I didn't bother adding a line for the pin as I don't have one on the account I was testing it with. Simply add the following line at the line (gosh I'm using a different version)… well add it after the first Exit of the OpenGE function:

if PinScreen then Inpin('xxxx')    //Replace xxxx with your pin

Easier way to solve this small issue. I might release another version of the script later. I added quite a few functions in the version that I now use so I'm not sure it would be very smart to release those publicly for obvious reasons (once you know what those functions do =)).

BGXD

2012-09-11 20:29:23

Oh nice script..

mase

2012-09-22 04:24:19

Interesting, might have a look at this if it could help me out with my 300 note withdrawal limit when selling high amounts of stuff to GE. :duh:

Mister Snow

2012-11-18 16:24:53

Oh lovely.

This is a very nice one. Some of the stuff is a bit in need of fixing, but this is quite nice! Far superior to what I have myself.

I learned the proper way to wait for things like "enter price" and when to start typing item name. In the past, I just put a decent wait time to allow for lag. Nope, make a function for that too! Thanks for sharing.
:spot:

edit: Also, regarding the i being swapped with !, you can do replace to replace all the ! with i.

This happens with z and 2 sometimes too, if you're reading prices.

Chris Reborn

2012-11-18 16:31:55

looks good nice release!

euphemism

2012-11-18 20:09:21

From: Wardancer
Known bug:
- GetTextAtExWrap reads every "i" as ".!", making it impossible to sell any item containing an "i" with the current built.


You might look into adding a function that parses the grabbed text to check for any instances of ".!" and replace them with "i".

Mister Snow

2012-11-21 11:28:20

if replace(lowercase(GetTextAtExWrap(46, 7, 185, 23, 0, 10, 1, 2658536, 50, UpChars)),'.!','i') = lowercase(ExtractFromStr(What, Letters))


Dunno if OP is around anymore, but this is a much needed fix to use if you plan to use this script.

You should know where to place it if you're not leeching.

The coordinate box is too short for many items, and then every 'i' is messed up.

Again though, I am very thankful for you to have shared this!

Anyone have any idea why it cant seem to find b/s slots? It locates them, then thinks they are in use. I keep looking through it and cannot figure out why it keeps failing there.

I ended up removing the 2nd check and just did Mouse x y true to click, since it never fails at finding the right box… but still wouldnt mind knowing what goes wrong.

At first I thought maybe the color change when mouse hovers was doing it, but using even 5 colors didn't seem to help.

Wardancer

2012-11-24 16:25:43

From: Mister Snow
if replace(lowercase(GetTextAtExWrap(46, 7, 185, 23, 0, 10, 1, 2658536, 50, UpChars)),'.!','i') = lowercase(ExtractFromStr(What, Letters))


Dunno if OP is around anymore, but this is a much needed fix to use if you plan to use this script.

You should know where to place it if you're not leeching.

The coordinate box is too short for many items, and then every 'i' is messed up.

Again though, I am very thankful for you to have shared this!

Anyone have any idea why it cant seem to find b/s slots? It locates them, then thinks they are in use. I keep looking through it and cannot figure out why it keeps failing there.

I ended up removing the 2nd check and just did Mouse x y true to click, since it never fails at finding the right box… but still wouldnt mind knowing what goes wrong.

At first I thought maybe the color change when mouse hovers was doing it, but using even 5 colors didn't seem to help.


I'd consider what I shared to be a very rough draft. I fixed the issues that you mentioned on the version I use. However, I never published another version since I'm still not satisfied with the end result and didn't bother (mostly the form is awful). Also, it's currently a working flipper and I'm not all that comfortable with making it completely open source (added many functions and procedures, obviously). I had already found the "i" solution with the used line posted on http://villavu.com/forum/showthread.php?t=89811.

Here it is:
if (ExtractFromStr((replace((lowercase(GetTextAtExWrap(212, 68, 386, 89, 0, 10, 1, 39372, 50, UpCharsEx))), '.!', 'i')), Letters)) = (lowercase(ExtractFromStr(What, Letters)))

As for the issue with the buy and sell slots, it took me a long time to find out what the problem was. Yet, it was such a simple one. I'm using the colour of the Buy and Sell box arrows to find out if it's free. However, when the mouse is over the box, it changes of shade and that led to a few problems. The simple fix is to make a second "BuyButton" and "SellButton" with the new shade and put them one after the other. For me, this solution worked pretty well. Could the problem you were having with this fix might be the actual order you put in the different colours? They can't be simultaneous. I had to do quite a bit of tweaking with "if…then" to get it to work and I realized just now that I can't find the actual working version, gah.

I had put this project to the side because of the market instability caused my double xp weekend as well as eoc release. I'll get back into it and post the fix for the buy and sell button either later today or tomorrow.

Thank you for your interest in this.

Mister Snow

2012-11-24 19:47:27

Ah okay, if then should work.

I've also now grown the number of necessary replacers:

You'll need replacers for anything with parenthesis (and the numbers in there that do not count as chars, but are still being searched for), dashes, and items starting with I…and maybe a couple more that I just can't remember yet.

Anyway, even though it's mainly a growth on the previously made functions, it was necessary and encouraged me to update an outdated and old script (was still simba from before the game bar update that I just edited to make it work, lol).

Good luck with that flipper :)

Albi

2012-11-25 09:01:11

This is pretty well done ^_^ I love it <3