Code:
(*
Login
=====
The Login include contains all the functions to succesfully log you in and out
of the game.
.. contents::
*)
const
SM_Color = 8115338;
{ var SRL_Logs: Integer;
var RandomPlayer, GraphicsSet: Boolean;
Description: Variables needed for some login functions. }
var
PlayerCurTime, SRL_Logs : integer;
RandomPlayer : Boolean;
procedure NextPlayer(Active: Boolean); forward;
procedure RandomNextPlayer(Active: Boolean); forward;
const
// Existing User - box
EUX1 = 389;
EUY1 = 271;
EUX2 = 535;
EUY2 = 311;
// Current World / click to switch - box
CWX1 = 5;
CWY1 = 463;
CWX2 = 104;
CWY2 = 497;
const
UBx1 = 313; // Username tBox - in use now
UBy1 = 254;
UBx2 = 435;
UBy2 = 260;
PBx1 = 346; // Password tBox - in use now
PBy1 = 271;
PBx2 = 435;
PBy2 = 281;
GBx1 = 229; // Login Box, after entering username / password
GBy1 = 301;
GBx2 = 375;
GBy2 = 341;
WDx1 = 276; // window box (to enter game) "click here to play"
WDy1 = 298;
WDx2 = 499;
WDy2 = 381;
WHITE_TEXT = 16777215; // white text color
MESSAGE_BOX = 11452366; // The "helpful message" box color
INFO_BOX = 7428416; // Blue information box color
LOGIN_COLOR = 6865381; // Login button color
ERROR_BOX = 2044518; // Error box (comes up on incorrect pw/un or banned acc
const //GetScreen
LOGIN_TA_X1 = 210; //Text check area
LOGIN_TA_Y1 = 54;
LOGIN_TA_X2 = 556;
LOGIN_TA_Y2 = 228;
LOGIN_TEXTCOLOUR = 16777215; //Colour of text
LOGIN_STATUSCOLOUR = 65535; //Colour of text
(*
LobbyScreen
~~~~~~~~~~~
.. code-block:: pascal
function LobbyScreen: Boolean;
Returns true if we are at the Lobby Screen
.. note::
by IceFire908 & Bionicle1800
Last modified 28/02/2013 By Ashaman88/Le Jingle
Example:
.. code-block:: pascal
// wait for the Lobby Screen to appear!
while (not LobbyScreen) do
Wait(100 + Random(400));
*)
function LobbyScreen: Boolean;
begin
Result := (GetColor(400, 335) = 16777215); // 'H' click Here to Play
end;
(*
SetAudioOff
~~~~~~~~~~~
.. code-block:: pascal
function SetAudioOff(): boolean;
Turns offs the music on the login screen.
Should default turn off, upon loading old school RS.
.. note::
by Ashaman88/Le Jingle
Example:
.. code-block:: pascal
SetAudioOff;
*)
function SetAudioOff(): boolean;
var
c : integer;
begin
c := CountColor(65536, 725, 463, 760, 498);
// 346 = Turned Off Already
// 284 = Turned On...
result := inrange(c, 340, 350);
if result then
exit
else
Mouse(742, 481, 10, 10, mouse_left);
end;
(*
TakeIPScreen
~~~~~~~~~~~~
.. code-block:: pascal
procedure TakeIPScreen();
Saves a screenshot of the last logged in IP address to the SRL logs folder.
.. note::
by Harry & Coh3n
Example:
.. code-block:: pascal
TakeIPScreen();
*)
procedure TakeIPScreen();
var
tmpPath: string;
begin
if ((not lobbyScreen()) or (SRL_DisableIPLog)) then
exit;
tmpPath := SRL_SavePath;
SRL_SavePath := tmpPath + 'IPLogs/'; // so TakeScreen saves to the right directory
takeScreen('IP Log');
SRL_SavePath := tmpPath; // reset
end;
(*
RSReady
~~~~~~~
.. code-block:: pascal
function RSReady: Boolean;
Returns true if we are ready to auto (on loginscreen or logged in).
Useful for waiting until RS has fully loaded.
.. note::
by ZephyrsFury
Last modified 28/02/2013 By Ashaman88/Le Jingle/Justin
Example:
.. code-block:: pascal
while (not RSReady) do
SleepAndMoveMouse(100 + Random(500));
*)
function RSReady: boolean;
var
t : integer;
begin
Result := (LoggedIn);
if result then
exit;
if not Result then
begin
t := GetSystemTime() + 120000;
while GetSystemTime < t do
begin
Result := (GetColor(31, 488) = 16777215);
if result then
begin
SetAudioOff();
exit;
end;
wait(20+random(10));
end;
end;
Writeln('Could not start up Old School RuneScape or RSReady was not detected!');
TerminateScript;
end;
(*
Logout
~~~~~~
.. code-block:: pascal
function Logout: Boolean;
Logs you all the way out from ingame.
.. note::
by Ashaman88/Justin/Le Jingle
Example:
.. code-block:: pascal
if (not FindTree()) then
Logout();
*)
function Logout: Boolean;
var
t: integer;
begin
result := not loggedin;
if result then
exit;
if not gametab(tab_logout) then
exit;
mousebox(596,367,689,386,mouse_left);
marktime(t);
repeat
wait(RandomRange(400,500));
if timefrommark(t)>5000 then
exit;
until not loggedin;
result := true;
end;
(*
LoginPlayerToLob
~~~~~~~~~~~~~~~~
.. code-block:: pascal
function LoginPlayerToLob: Boolean;
Like LoginPlayer but only to the lobbyscreen.
.. note::
by SRL Dev Team
Example:
.. code-block:: pascal
LoginPlayerToLob();
if (not LobbyScreen()) then
LoginPlayerToLob(); // try again!
*)
function LoginPlayerToLob: Boolean; //TODO: Make this function check for "Error Messages" (Acc Disabled/Error connecting)
var
c, t, w, typtmp : integer;
foundLogin : boolean;
p : TPoint;
TPA: TPointArray;
Boxes : TIntegerArray;
begin
ActivateClient;
Result := ((LobbyScreen) or (LoggedIn));
if (Result) then
Exit;
if (not (Players[CurrentPlayer].Active)) then
begin
WriteLn('Player is not Active...');
if (AllPlayersInActive) then
begin
WriteLn('All players not active!');
Exit;
end;
NextPlayer(False);
Exit;
end;
T := GetSystemTime;
repeat
if (RSReady) then
Break;
if ((GetSystemTime - T) > 180000) then
begin
WriteLn('It has been 3 minutes and Runescape is not yet ready... Terminating.');
TerminateScript;
end;
Wait(RandomRange(1000, 2000));
until (False);
WriteLn('Welcome to Runescape.');
if (loggedIn) then
exit;
if Length(Players[CurrentPlayer].WorldInfo) > 0 then
SelectWorld(Players[CurrentPlayer].WorldInfo[0]);
// click 'Existing User'
MouseBox(EUX1, EUY1, EUX2, EUY2, mouse_left);
t := GetSystemTime() + 60000;
while GetSystemTime < t do
begin
c := CountColor(65535, 238, 215, 526, 230);
if c > 1 then
begin
foundLogin := true;
break;
end;
wait(500 + random(500));
end;
if not FoundLogin then
begin
writeln('Unable to detect login interface!');
exit;
end;
for W := 0 to 1 do
begin
if W = 0 then
Boxes := [UBX1, UBY1, UBX2, UBY2]
else
Boxes := [PBX1, PBY1, PBX2, PBY2];
t := (getSystemTime + (60000 * 2));
FindColors(TPA, LOGIN_TEXTCOLOUR, Boxes[0], Boxes[1], Boxes[2], Boxes[3]);
repeat
if (Length(TPA) > 0) then
begin
SortTPAFrom(TPA, Point(Boxes[2], Boxes[1] + (Boxes[3] - Boxes[2]) div 2));
p := point(TPA[0].X + 20, TPA[0].Y);
if (not pointInBox(p, intToBox(Boxes[0], Boxes[1], Boxes[2], Boxes[3]))) then
p := point(UBX2 - (10 + random(10)), p.y);
Mouse(p.x, p.y, 5, 5, mouse_left);
end else
MouseBox(Boxes[0], Boxes[1], Boxes[2], Boxes[3], mouse_left);
typtmp := 0;
while (CountColor(LOGIN_TEXTCOLOUR, Boxes[0], Boxes[1], Boxes[2], Boxes[3]) > 0) do
begin
Inc(typtmp);
TypeByte(VK_BACK);
Wait(50+Random(50));
if (typtmp >= RandomRange(20, 24)) then
Break;
end;
until(not FindColors(TPA, LOGIN_TEXTCOLOUR, Boxes[0], Boxes[1], Boxes[2], Boxes[3]) or (getSystemTime > t));
Wait(100 + Random(200));
if W = 0 then
begin
WriteLn(Capitalize(Players[CurrentPlayer].Name));
TypeSend(Players[CurrentPlayer].Name);
end else
TypeSendEx(Players[CurrentPlayer].Pass, False);
end;
MouseBox(GBx1, GBy1, GBx2, GBy2, mouse_left);
{Check responses}
T := GetSystemTime;
repeat
result := lobbyScreen or loggedin;
if result then
break;
if (GetSystemTime - t > 60000) then
begin
result := false;
writeln('failed logging into lobby');
exit;
end;
// so the lobby appears (gets rid of black screen)
if not lobbyScreen then
begin
wait(1000+random(1000));
continue;
end;
until (Result);
TakeIPScreen();
end;
(*
LoginPlayer
~~~~~~~~~~~
.. code-block:: pascal
function LoginPlayer: Boolean;
Logs in the Player[CurrentPlayer].
.. note::
by SRL Dev Team
Example:
.. code-block:: pascal
if (not LoggedIn()) then
begin
WriteLn('Error: Not Logged In! Fixing');
LoginPlayer();
end;
*)
function LoginPlayer: Boolean;
var
RetryLogin: Boolean;
typtmp, t, w, i: integer;
Actions: TVariantArray;
Attempts: LongInt;
p: TPoint;
//ATPA: T2dPointArray;
TPA: TPointArray;
Boxes : TIntegerArray;
//B: TBox;
label
ProcStart;
begin
ActivateClient;
if (LoggedIn) then Exit;
Wait(100 + Random(200));
TypeByte(vk_Escape);
Wait(200 + Random(200));
{Check for lobby screen already open/ already logged in}
Result := ((LobbyScreen) or (LoggedIn));
if (Result) then Exit;
{Check for active player.}
if (not (Players[CurrentPlayer].Active)) then
begin
WriteLn('Player is not Active...');
if (AllPlayersInActive) then
begin
WriteLn('All players not active!');
Exit;
end;
NextPlayer(False);
Exit;
end;
{Wait for the client to finish loading.}
T := GetSystemTime;
repeat
if (RSReady) then
Break;
if ((GetSystemTime - T) > 180000) then
begin
WriteLn('It has been 3 minutes and Runescape is not yet ready... Terminating.');
TerminateScript;
end;
Wait(RandomRange(1000, 2000));
until (False);
if (CountColor(16777215, 408, 279, 518, 299) = 281) then //Existing User text
begin
WriteLn('Welcome to Runescape.');
MouseBox(395, 275, 529, 307, mouse_Left); //Existing User
end;
if Length(Players[CurrentPlayer].WorldInfo) > 0 then
SelectWorld(Players[CurrentPlayer].WorldInfo[0]);
ProcStart:
{Type in username and pass}
if (loggedIn) then
exit;
for W:= 0 to 1 do
begin
if W = 0 then
Boxes:= [UBX1, UBY1, UBX2, UBY2]
else
Boxes:= [PBX1, PBY1, PBX2, PBY2];
t := (getSystemTime + (60000 * 2));
FindColors(TPA, LOGIN_TEXTCOLOUR, Boxes[0], Boxes[1], Boxes[2], Boxes[3]);
repeat
if (Length(TPA) > 0) then
begin
SortTPAFrom(TPA, Point(Boxes[2], Boxes[1] + (Boxes[3] - Boxes[2]) div 2));
p := point(TPA[0].X + 20, TPA[0].Y);
if (not pointInBox(p, intToBox(Boxes[0], Boxes[1], Boxes[2], Boxes[3]))) then
p := point(UBX2 - (10 + random(10)), p.y);
Mouse(p.x, p.y, 2, 2, mouse_left);
end else
MouseBox(Boxes[0], Boxes[1], Boxes[2], Boxes[3], mouse_left);
typtmp := 0;
while (CountColor(LOGIN_TEXTCOLOUR, Boxes[0], Boxes[1], Boxes[2], Boxes[3]) > 0) do
begin
Inc(typtmp);
TypeByte(VK_BACK);
Wait(50+Random(50));
if (typtmp >= RandomRange(30, 35)) then
Break;
end;
until(not FindColors(TPA, LOGIN_TEXTCOLOUR, Boxes[0], Boxes[1], Boxes[2], Boxes[3]) or (getSystemTime > t));
Wait(100 + Random(200));
if W = 0 then
begin
WriteLn(Capitalize(Players[CurrentPlayer].Name));
TypeSend(Players[CurrentPlayer].Name);
end else
begin
TypeSendEx(Players[CurrentPlayer].Pass, False);
MouseBox(234, 304, 369, 338, mouse_Left); //Login
end;
end;
{Check responses}
T := GetSystemTime;
repeat
// so the lobby appears (gets rid of black screen)
if (countColorTolerance(clBlack, 0, 0, 500, 500, 20) > 245000) then
begin
wait(2000 + random(1500));
mouseBox(0, 0, 750, 490, mouse_Move);
end;
SetLength(Actions, 0);
if ((GetSystemTime - T) > 60000) then
Actions := ['One minute has passed... Debug: ' + ToStr(CountColor(LOGIN_STATUSCOLOUR, 224, 190, 532, 250)), 0, 5, 'PlayerFalse', 'Login Failed']
else
// writeln(CountColor(LOGIN_STATUSCOLOUR, 224, 190, 532, 250));
case (CountColor(LOGIN_STATUSCOLOUR, 224, 190, 532, 250)) of //text colour points
// WriteLn Error Wait for Retrys Action Player[CurrentPlayer].Loc
738: Actions := ['Invalid Username / Password', 0, 2, 'PlayerFalse', 'Wrong User/Pass']; //Updated
1539: Actions := ['Your account has been disabled', 0, 0, 'PlayerFalse', 'Acc Disabled']; //Updated
1073: Actions := ['Your account is already logged in', 5000, 5, 'PlayerTrue', 'Already logged in']; //Updated
1573: Actions := ['Not a Members Account', 0, 1, 'PlayerTrue', '']; //Updated
492: Actions := ['Error Connecting.', 20000, 9, 'Terminate', 'Error Connecting']; //Updated
1721: Actions := ['Too many incorrect logins.', 5 * 60000, 2, 'PlayerFalse', 'Too many logins']; //Updated
906: Actions := ['This world is full.', 5000, 10, 'PlayerFalse', 'World is full']; //Updated
1136: Actions := ['Runescape has been updated.', 0, 0, 'RSUpdate', 'RS Updated'];
777: Actions := ['Login limit exceeded.', 20000, 10, '', 'Waiting for login.'];
1700: Actions := ['You will need a members account to login to this world. Please subscribe, or use a different world.', 0, 0, 'PlayerFalse', 'Acc Disabled']; //Updated
end;
{Respond}
if (Length(Actions) > 0) then
begin
WriteLn(Actions[0]);
if (Actions[0] <> 'Not a Members Account') then
begin
Wait(1000 + Random(500));
TypeByte(vk_Escape);
end;
Wait(Actions[1] + Random(100));
if (Actions[2] <> 0) then
if (Attempts < Actions[2]) or (Actions[2] = -1) then
begin
if (Actions[0] = 'Not a Members Account') then
begin
Players[CurrentPlayer].Member := False;
if (Length(Players[CurrentPlayer].WorldInfo) > 0) then
Players[CurrentPlayer].WorldInfo[0] := False;
MouseBox(267, 321, 496, 350, mouse_left); //Play free game instead button TODO:Check if this is needed
Wait(3000 + Random(2000));
Result := True;
Exit;
end;
RetryLogin := True;
Wait(2000 + Random(1000));
Break;
end;
if (Actions[4] <> '') then
Players[CurrentPlayer].Loc := Actions[4];
case Actions[3] of
'PlayerFalse': NextPlayer(False);
'PlayerTrue':
begin
//LeaveLobby();
NextPlayer(True);
end;
'Terminate': TerminateScript;
'RSUpdate':
begin
if SRL_HasProc(srl_OnRSUpdate) then
begin
case actions[0] of
'Runescape has been updated.':
begin
Writeln('Runescape has been updated! Waiting 5 minutes to restart SMART!');
Wait(300000);
end;
end;
SRL_Procs[srl_OnRSUpdate]();
Exit;
end;
Writeln('Runescape has been updated! Please restart Simba.');
TerminateScript;
end;
end;
Exit;
end;
Wait(100);
Result := (LobbyScreen) or (LoggedIn);
until (Result);
TakeIPScreen();
if (LobbyScreen) then
begin
MouseBox(WDx1, WDy1, WDx2, WDy2, mouse_Left); //Click To Play
i := 0;
repeat
i := i+1;
Wait(100 + Random(100));
until (LoggedIn) or (i > 30);
end;
Wait(100 + Random(100));
{Back to main screen if needed}
if (RetryLogin) then
begin
RetryLogin := False;
Inc(Attempts);
goto ProcStart;
end;
end;
(*
NextPlayerIndex
~~~~~~~~~~~~~~~
.. code-block:: pascal
function NextPlayerIndex: Integer;
Returns the player number of the next active player.
.. note::
by Dankness, Ron, Raymond & ZephyrsFury
Example:
.. code-block:: pascal
if (NextPlayerIndex() != -1) then
WriteLn('We still have active players!');
*)
function NextPlayerIndex: Integer;
begin
if (AllPlayersInactive) then
begin
Result := -1;
Exit;
end;
Result := (CurrentPlayer + 1) mod Length(Players);
while (Players[Result].Active = False) do
Result := (Result + 1) mod Length(Players);
end;
(*
RandomPlayerIndex
~~~~~~~~~~~~~~~~~
.. code-block:: pascal
function RandomPlayerIndex: Integer;
Returns the player number of a random active player.
.. note::
by Dankness, Ron, Raymond & ZephyrsFury
Example:
.. code-block:: pascal
procedure NextPlayerRandom(Active: Boolean);
begin
Players[CurrentPlayer].Active := Active;
CurrentPlayer := RandomPlayerIndex();
if (CurrentPlayer = -1) then
begin
WriteLn('All players inactive..');
TerminateScript();
end;
end;
*)
function RandomPlayerIndex: Integer;
var
N: Integer;
begin
if (AllPlayersInactive) then
begin
Result := -1;
Exit;
end;
N := Random(Length(Players));
while (Players[N].Active = False) or (N = CurrentPlayer) do
begin
if (PlayersActive = 1) and (N = CurrentPlayer) then Break;
N := Random(Length(Players));
end;
Result := N;
end;
(*
SwitchToPlayer
~~~~~~~~~~~~~~
.. code-block:: pascal
function SwitchToPlayer(PlayerNo: Integer; Active: Boolean): Boolean;
Switches to a specific player, setting the current player's activity to True or False.
.. note::
by Dankness, Ron, Raymond & ZephyrsFury
Example:
.. code-block:: pascal
SwitchToPlayer(1, True);
*)
function SwitchToPlayer(PlayerNo: Integer; Active: Boolean): Boolean;
begin
WriteLn('SwitchToPlayer(PlayerNo: ' + IntToStr(PlayerNo) + ', Active: ' + BoolToStr(Active)+ ');');
Players[CurrentPlayer].Active := Active;
Logout;
if SRL_HasProc(srl_OnNextPlayer) then
SRL_Procs[srl_OnNextPlayer]();
PlayerCurTime := GetSystemTime;
Players[CurrentPlayer].Worked := Players[CurrentPlayer].Worked + (PlayerCurTime - PlayerStartTime);
CurrentPlayer := PlayerNo;
SRL_Logs := SRL_Logs + 1;
LoginPlayer;
SetScreenName(Players[CurrentPlayer].Nick);
Result := LoggedIn;
end;
(*
NextPlayer
~~~~~~~~~~
.. code-block:: pascal
procedure NextPlayer(Active: Boolean);
Logs in the next player that isn't inactive.
Boolean: True - Current player is ok. False - Current player is false.
.. note::
by ZephyrsFury
Example:
.. code-block:: pascal
NextPlayer(True);
*)
procedure NextPlayer(Active: Boolean);
var
srl_PlayerIndexFunc: function: Integer;
cP: Integer;
begin
if (RandomPlayer) then
srl_PlayerIndexFunc := @RandomPlayerIndex
else
srl_PlayerIndexFunc := @NextPlayerIndex;
WriteLn('NextPlayer(' + BoolToStr(Active) + ')');
LogOut;
cP := srl_PlayerIndexFunc();
while (cP = -1) do
begin
cP := srl_PlayerIndexFunc();
if SRL_HasProc(srl_InNextPlayerLoop) then
SRL_Procs[srl_InNextPlayerLoop]();
Wait(5000); //Endless loop
end;
SwitchToPlayer(cP, Active);
end;
(*
RandomNextPlayer
~~~~~~~~~~~~~~~~
.. code-block:: pascal
procedure RandomNextPlayer(Active: Boolean);
Logs in a random player that isn't inactive.
Boolean: True - Current player is ok. False - Current player is false.
.. note::
by ZephyrsFury
Example:
.. code-block:: pascal
RandomNextPlayer(True);
*)
procedure RandomNextPlayer(Active: Boolean);
var
tmpBool: Boolean;
begin
tmpBool := RandomPlayer;
RandomPlayer := True;
NextPlayer(Active);
RandomPlayer := tmpBool;
end;
(*
CheckUserNicks
~~~~~~~~~~~~~~
.. code-block:: pascal
procedure CheckUserNicks;
Checks if all nicks are set correct.
.. note::
by Sumilion, Raymond, and Nava2
Example:
.. code-block:: pascal
// make sure the user setup their nicks right..
CheckUserNicks();
*)
procedure CheckUserNicks;
var
I, II: Integer;
Wrong, FWrong: Boolean;
WarnStrings: TStringArray;
begin
WarnStrings := ['Please fill in your nickname.',
'Your nickname isn'' found in the players name'];
for i := 0 to HowManyPlayers - 1 do
for II := 0 to 1 do
begin
case II of
0: Wrong := (Players[i].Nick = '');
1: Wrong := (Pos(Players[i].nick, Capitalize(Players[i].name))<1);
end;
if Wrong then
begin;
Writeln('--');
Writeln('WARNING: ' + WarnStrings[II] + ' with player: ' + Players[i].Name);
FWrong := True;
end;
end;
if FWrong then
begin
Writeln('');
Writeln('For more information, visit http://www.villavu.com/forum/showthread.php?t=5410');
end;
end;
replace that with your current login.simba for SLR-OSR