PDA

View Full Version : how to log into osrs with aerolib?



SimbaOp
11-23-2017, 12:09 PM
program new;
{$DEFINE SMART}
{$I AeroLib/AeroLib.Simba}

procedure declarePlayer();
begin
Me.Name := 'fsdfds';
Me.Pass := 'dsfsdfsd';
Me.Pin := '';
Me.Nick := '';
Me.Member := False;
Me.Active := True;
end;

begin
inital;
declareplayer;
loginPlayer(true);
end.
Anyone know why this just keeps clicking on the username and password areas and doesnt type anything? Anyone know a better way to login with aerolib?


My script also types in game, sometimes it gets disconnected while typing. Is there any way to prevent that from messing up a login bot?

Lipcot
11-23-2017, 07:58 PM
Update this two files

login.simba:


{
=====
Login
=====
}

Var

BOX_EU : TBox = [389,271,535,311]; // Existing user box
BOX_CW : TBox = [5,464,102,493]; // Current world box
BOX_UB : TBox = [313,240,515,257]; // Username box
BOX_PB : TBox = [345,258,515,270]; // Password box
BOX_GB : TBox = [235,305,369,336]; // Click to login box
BOX_CB : TBox = [395,305,529,336]; // Cancel box
BOX_WD : TBox = [276,298,499,381]; // Click to play box (splash screen)
BOX_LO : TBox = [573,406,707,433]; // Logout box

// Login states
LS_LOGGEDOUT = 0;
LS_LOGGEDIN = 1;
LS_SPLASHSCREEN = 2;
LS_WORLDSCREEN = 3;


const
SM_Color = 8115338;
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

LOGIN_TA_X1 = 210; //Text check area
LOGIN_TA_Y1 = 54;
LOGIN_TA_X2 = 556;
LOGIN_TA_Y2 = 228;

LOGIN_TEXTCOLOUR = 16777215; //Color of text
LOGIN_STATUSCOLOUR = 65535; //Color of text


(*
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 not result then
mouse(Point(742,481), 10, 10, MOUSE_LEFT);
end;

function getLoginState(): Integer;
var
tCol : TColEx;
begin
if (getColor(427,489) = 16777215) then
Exit(LS_LOGGEDIN);
tCol.create(12899548, 5);
if tCol.findIn(toBox(555,13,569,28)) then
Exit(LS_LOGGEDIN);
if (getColor(400,335) = 16777215) then
Exit(LS_SPLASHSCREEN);
if (getcolor(115,14) = 1800605) then
Exit(LS_WORLDSCREEN);
Result := LS_LOGGEDOUT;
end;

function connectionLost(): Boolean;
var
X,Y : Integer;
begin
result := (findText(X, Y, 'attem', 'SmallChars07', toBox(0,0,230,35)) or
findText(X, Y, 'lease', 'SmallChars07', toBox(0,0,230,35)));
end;

function isLoggedIn(): Boolean;
var
T : Timer;
begin
if connectionLost() then
begin
T.start();
while (connectionLost() and (T.timeElapsed() < 60000)) do
wait(1);
end;

result := getLoginState() = LS_LOGGEDIN;
end;

function isSplashScreen(): Boolean;
begin
result := getLoginState() = LS_SPLASHSCREEN;
end;

function isWorldScreen(): Boolean;
begin
result := getLoginState() = LS_WORLDSCREEN;
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 05/12/2013 by Flight

Example:

.. code-block:: pascal

while not RSReady() do
SleepAndMoveMouse(100 + Random(500));

*)

function RSReady(): boolean;
var
T : Timer;
begin
if isLoggedIn() then
exit(true);

T.start();
while (T.timeElapsed < 120000) do
begin
if (getColor(31,488) = 16777215) then
begin
setAudioOff();
exit(true);
end;
wait(20+random(10));
end;

warn('Could not start up OSRS or RSReady was not detected!', WT_CORE);
terminateScript();
end;

function WS_enabled(): Boolean; forward;
function WS_logout(): Boolean; forward;
function logoutPlayer(): Boolean;
var
T : Timer;
label
start;
begin
if not isLoggedIn() then
exit(true);

start:
if not gametab(TAB_LOGOUT) then
exit(false);

if WS_enabled() then
if WS_logout() then exit(true);
T.start();
while (Me.inCombat() and (T.timeElapsed() < 5000)) do
wait(60+random(25));

T.start();
repeat
mousebox(BOX_LO, MOUSE_LEFT);
wait(randomRange(400,1100));
if (not isLoggedIn()) then
exit(true);
until(T.timeElapsed > 11000);

if isSplashScreen() then
begin
mouseBox(BOX_WD, MOUSE_LEFT);
while not isLoggedIn() do
wait(60+random(25));
GoTo start;
end;
end;

var
IgnoreWorlds : TIntegerArray;

function selectWorld(W: integer): boolean; forward;
function randomWorld(Member: Boolean): Integer; forward;
function getCurrentWorldLS(): integer; forward;

function loginPlayer(Safe: Boolean=False): Boolean;
var
Box : TBox;
T : Timer;
p : TPoint;
wTxtCol,lCol,
rCol : TColEx;
c,w,typtmp,uL,
uH,pL,pH,uLen,
pLen,i,j,
Attempts,rw : Integer;
foundLogin,
retryLogin,
doSwitch : Boolean;
TPA : TPointArray;
MemWorlds,
FreeWorlds : TIntegerArray;
Actions : TVariantArray;
label
EnterName,EnterGame,SplashScreen;
begin
//{$IFNDEF SMART}
//activateClient();
//{$ENDIF}
if isLoggedIn() then
exit(true);
if ((length(Me.Name) < 1) or (length(Me.Pass) < 1)) then
begin
warn('No username / password, deactivating player...', WT_CORE);
Me.Active := false;
Exit(false);
end;

if isSplashScreen() then
goto SplashScreen;

if not Me.Active then
begin
warn('Player inactive...', WT_CORE);
Exit(false);
end;

if (length(Me.Name) < 1) then
Exit(false);

T.start();
repeat
if (T.timeElapsed > 180000) then
begin
warn('It has been 3 minutes and OSRS is not yet ready, terminating script.', WT_CORE);
terminateScript();
end;
Wait(RandomRange(1000,2000));
until (RSReady);

MemWorlds :=
[ 320,343,369,+
302,321,344,370,+
303,322,345,373,+
304, 346,374,+
305, 349,375,+
306,327,350,376,+
328,351,377,+
309,329,354,378,+
310,330,358, +
311,333,359, +
312,334,360, +
313, 361, +
314,336,362, +
365,386,+
317,338,366, +
318,341,367, +
319,342,368];

FreeWorlds :=
[301,308,316,335,381, +
382,383,384,385,393,394];

EnterName:
if inIntArray(IgnoreWorlds, getCurrentWorldLS()) then
begin
warn('Ignore world detected, choosing another world', WT_CORE);
selectWorld(randomWorld(Me.Member));
end;

if not Me.Member then
if inIntArray(MemWorlds, getCurrentWorldLS()) then
begin
warn('Switching to a F2P world', WT_CORE);
selectWorld(randomWorld(Me.Member));
end;

warn('Logging player in...', WT_CORE);

if isLoggedIn() then
exit(true);

if isSplashScreen() then
goto SplashScreen;

//if Length(Me.WorldList) > 0 then
//selectWorld(Me.WorldList[0]);

wTxtCol.create(WHITE_TEXT, 1);
if not wTxtCol.findAllIn(toBox(439,313,484,327), TPA) then
begin
mouseBox(BOX_EU, MOUSE_LEFT);
rCol.create(clRed, 5);
T.start();
while (T.timeElapsed() < 60000) do
begin
if rCol.findIn(toBox(405,220,430,240)) then
begin
mouseBox(toBox(236,306,367,337), MOUSE_LEFT);
wait(500 + random(500));
end;

c := countColor(65535, 238, 215, 526, 230);
if ((c > 1) and (not rCol.findIn(toBox(405,220,430,240)))) then
begin
foundLogin := true;
break;
end;
wait(500 + random(500));
end;
if not FoundLogin then
begin
warn('Unable to detect login interface...', WT_CORE);
exit(false);
end;
end;

for W:=0 to 1 do
begin
if W = 0 then
Box := BOX_PB
else
Box := BOX_UB;

lCol.create(LOGIN_TEXTCOLOUR, 1);
lCol.findAllIn(Box, TPA);

T.start();
repeat
if (Length(TPA) > 0) then
begin
sortTPAFrom(TPA, Point(Box.X2, Box.Y1 + (Box.Y2 - Box.X2) div 2));
p := point(TPA[0].X + 20, TPA[0].Y);
if (not pointInBox(p, Box)) then
p := point(BOX_UB.X2 - (10 + random(10)), p.y);
mouse(p, 5, 5, MOUSE_LEFT);
end else
mouseBox(Box, MOUSE_LEFT);

typtmp := 0;
if (countColor(LOGIN_TEXTCOLOUR, Box.X1, Box.Y1, Box.X2, Box.Y2) > 0) then
begin
keyDown(VK_BACK);
while (countColor(LOGIN_TEXTCOLOUR, Box.X1, Box.Y1, Box.X2, Box.Y2) > 0) do
begin
Inc(typtmp);
Wait(50+Random(50));
if (typtmp >= RandomRange(20, 24)) then
Break;
end;
keyUp(VK_BACK);
end;
until(not lCol.findAllIn(Box, TPA) or (T.timeElapsed > 120000));
end;

Wait(100 + Random(200));

if (not Safe) then
begin
mouseBox(BOX_UB, MOUSE_LEFT);
typeSend(Me.Name);
mouseBox(BOX_PB, MOUSE_LEFT);
typeSend(Me.Pass, false);
end else
begin
uL := 1;
pL := 1;
uLen := length(Me.Name);
pLen := length(Me.Pass);

repeat
if (not (uH = uLen)) then
begin
mouseBox(BOX_UB, MOUSE_LEFT);
// prevents "Out of string range" errors
uH := (uL + randomRange(1, 3));
if (uH > uLen) then
uH := uLen;

for i := uL to uH do
begin
wait(100 + random(100));
typeSend(Me.Name[i], false);
end;

uL := (uH + 1);
end;

if (not (pH = pLen)) then
begin
mouseBox(BOX_PB, MOUSE_LEFT);
// prevents "Out of string range" errors
pH := (pL + randomRange(1, 3));
if (pH > pLen) then
pH := pLen;

for j := pL to pH do
begin
wait(100 + random(100));
typeSend(Me.Pass[j], false);
end;

pL := (pH + 1);
end;

until((uH = uLen) and (pH = pLen));
end;

EnterGame:
mouseBox(BOX_GB, MOUSE_LEFT);

T.start();
repeat
if (isSplashScreen() or isLoggedIn()) then
break;

SetLength(Actions, 0);

if (T.timeElapsed() > 60000) then
Actions := ['One minute has passed... Debug: ' + toStr(CountColor(LOGIN_STATUSCOLOUR, 224, 190, 532, 250)), 0, 5, 'Terminate']
else
case (CountColor(LOGIN_STATUSCOLOUR, 224, 190, 532, 250)) of
// WriteLn Error Wait for Retrys Action
863 : Actions := ['Invalid Username / Password', 0, 0, 'Terminate'];
1539: Actions := ['Your account has been disabled', 0, 0, 'Terminate'];
1073: Actions := ['Your account is already logged in', 1700, 5, 'Retry'];
492: Actions := ['Error Connecting.', 20000, 10, 'Retry'];
1437: Actions := ['Too many incorrect logins.', 5 * 60000, 2, 'Switch'];
906: Actions := ['This world is full.', 2000, 3, 'Switch'];
1227: Actions := ['Login limit exceeded.', 5000, 5, 'Switch'];
1231: Actions := ['No reply from login server', 5000, 2, 'Switch'];
1136: Actions := ['Runescape has been updated.', 0, 0, 'RSUpdate'];
777: Actions := ['Login limit exceeded.', 0, 2, 'Switch'];
1700: Actions := ['Members world', 0, 2, 'Switch'];
774 : Actions := ['Login server offline', 1500, 10, 'Retry'];
end;
{Respond}

if (Length(Actions) > 0) then
begin
warn(Actions[0], WT_CORE);
Wait(1000 + Random(500));
Wait(Actions[1] + Random(100));

if (Actions[2] > 0) then
begin
if (Attempts < Actions[2])then
begin
RetryLogin := True;
Wait(2000 + Random(1000));
end else
terminateScript();
end;

case Actions[3] of
'Terminate': terminateScript();

'Retry':
begin
RetryLogin := True;
break;
end;

'Switch':
begin
doSwitch := True;
break;
end;

'RSUpdate':
begin
if AL_HasProc(al_OnRSUpdate) then
begin
case actions[0] of
'Runescape has been updated.':
begin
warn('OSRS has updated, waiting 5 minutes to restart SMART.', WT_CORE);
Wait(300000);
end;
end;
AL_Procs[al_OnRSUpdate]();
RetryLogin;
end;
warn('OSRS has been updated, please restart Simba.', WT_CORE);
terminateScript();
end;
end;
end;
wait(randomRange(90,130));
until(Result);

SplashScreen:
if isSplashScreen() then
begin
mouseBox(BOX_WD, MOUSE_LEFT);
i := 0;
repeat
i := i+1;
Wait(100 + Random(100));
until (isLoggedIn() or (i > 30));
end;

{Back to main screen if needed}
if doSwitch then
begin
mouseBox(BOX_CB, MOUSE_LEFT);
warn('Changing worlds; current world:'+toStr(getCurrentWorldLS()), WT_CORE);
while (not (rw = getCurrentWorldLS())) do
rw := randomWorld(Me.Member);

selectWorld(rw);
warn('W'+toStr(rw)+' selected', WT_CORE);
RetryLogin := False;
DoSwitch := False;
Inc(Attempts);
goto EnterName;
end;

Wait(100 + Random(100));

if RetryLogin then
begin
RetryLogin := False;
Inc(Attempts);
goto EnterGame;
end;

Result := isLoggedIn();
if Result then inc(count_Login);
end;



worldhandler.simba

{
============
WorldHandler
============
}

(*
ExitWorldScreen
~~~~~~~~~~~~~~~

.. code-block:: pascal

function exitWorldscreen(): boolean;

Closes the world screen, results true if successfully closed

.. note::

by Ashaman88

Example:

.. code-block:: pascal

*)
function exitWorldScreen(): Boolean;
begin
if not (getLoginState() = LS_WORLDSCREEN) then
Exit(True);

mousebox(toBox(719,6,750,15), MOUSE_LEFT);
result := not (getLoginState() = LS_WORLDSCREEN);
end;

(*
getCurrentWorldLS
~~~~~~~~~~~~~~

.. code-block:: pascal

function getCurrentWorldLS(): integer;

Returns the current world at the login screen

.. note::

by Ashaman88

Example:

.. code-block:: pascal

*)
function getCurrentWorldLS(): integer;
var
txt : String;
begin
if not (getLoginState() = LS_LOGGEDOUT) then
exit(-1);
txt := getTextAtEx(BOX_CW.X1, BOX_CW.Y1, BOX_CW.X2, BOX_CW.Y2, 0, 5, 2, 16777215, 2, 'UpChars07');
result := strToIntDef(txt, 0);
end;

(*
OpenWorldScreen
~~~~~~~~~~~~~~~

.. code-block:: pascal

function: openWorldScreen(): Boolean;

Opens the world screen, returns true if it is succesfully opened.

.. note::

by Ashaman88

Example:

.. code-block::pascal

*)
function openWorldScreen(): Boolean;
var
T : Timer;
begin
if (getLoginState() = LS_WORLDSCREEN) then
exit(true);
mousebox(toBox(13,468,98,491), MOUSE_LEFT);

T.start();
repeat
wait(100);
if (getLoginState() = LS_WORLDSCREEN) then
break;
until(T.timeElapsed() >= 6000);

result := (getLoginState() = LS_WORLDSCREEN);
end;

(*
WorldIndexToMSPoint
~~~~~~~~~~~~~~~~~~~

.. code-block:: pascal

function worldIndexToMSPoint(Index: Integer): TPoint;

Converts the World Index (spot in World) to a Mainscreen TPoint of the Index. (Top Left)

.. note::

Author: Ashaman88

Example:

.. code-block:: pascal

msPoint := WorldIndexToMSPoint(index);
*)
function worldIndexToMSPoint(Index: Integer): TPoint;
begin
Index := Index ;
Result := Point(200 + (Index mod 4) * 94, 86 + Floor(Index div 4) * 24);
end;

// by Flight
function rsWorldToMS(Index: Integer): TPoint;
begin
if inRange(Index, 301, 319) then
Result.X := 152
else if inRange(Index, 320, 338) then
Result.X := 246
else if inRange(Index, 339, 357) then
Result.X := 338
else if inRange(Index, 358, 382) then
Result.X := 430
else if inRange(Index, 383, 412) then
Result.X := 522;

if ((Index=301)or(Index=320)or(Index=339)or(Index=358 )or(Index=383)) then
Result.Y := 39
else if ((Index=302)or(Index=321)or(Index=340)or(Index=359 )or(Index=384)) then
Result.Y := 63
else if ((Index=303)or(Index=322)or(Index=341)or(Index=360 )or(Index=385)) then
Result.Y := 87
else if ((Index=304)or(Index=323)or(Index=342)or(Index=361 )or(Index=386)) then
Result.Y := 111
else if ((Index=305)or(Index=324)or(Index=343)or(Index=362 )or(Index=387)) then
Result.Y := 135
else if ((Index=306)or(Index=325)or(Index=344)or(Index=365 )or(Index=388)) then
Result.Y := 159
else if ((Index=307)or(Index=326)or(Index=345)or(Index=366 )or(Index=389)) then
Result.Y := 183
else if ((Index=308)or(Index=327)or(Index=346)or(Index=367 )or(Index=390)) then
Result.Y := 207
else if ((Index=309)or(Index=328)or(Index=347)or(Index=368 )or(Index=391)) then
Result.Y := 231
else if ((Index=310)or(Index=329)or(Index=348)or(Index=369 )or(Index=392)) then
Result.Y := 255
else if ((Index=311)or(Index=330)or(Index=349)or(Index=370 )or(Index=393)) then
Result.Y := 279
else if ((Index=312)or(Index=331)or(Index=350)or(Index=373 )or(Index=394)) then
Result.Y := 303
else if ((Index=313)or(Index=332)or(Index=351)or(Index=374 )or(Index=400)) then
Result.Y := 327
else if ((Index=314)or(Index=333)or(Index=352)or(Index=375 )or(Index=404)) then
Result.Y := 351
else if ((Index=315)or(Index=334)or(Index=353)or(Index=376 )or(Index=406)) then
Result.Y := 375
else if ((Index=316)or(Index=335)or(Index=354)or(Index=377 )or(Index=407)) then
Result.Y := 399
else if ((Index=317)or(Index=336)or(Index=355)or(Index=378 )or(Index=408)) then
Result.Y := 423
else if ((Index=318)or(Index=337)or(Index=356)or(Index=381 )or(Index=410)) then
Result.Y := 447
else if ((Index=319)or(Index=338)or(Index=357)or(Index=382 )or(Index=412)) then
Result.Y := 471

end;

(*
WorldIndexToMSBox
~~~~~~~~~~~~~~~~~

.. code-block:: pascal

function worldIndexToMSBox(Ind: Integer): TBox;

Converts the World Index (spot in World) to a Mainscreen TBox of the Index.

.. note::

Author: Ashaman88, fixed by Flight

Example:

.. code-block:: pascal

msBox := worldIndexToMSBox(index);
*)
function worldIndexToMSBox(Index: Integer): TBox;
var
P: TPoint;
begin
P := rsWorldToMS(Index);
Result.X1 := P.X;
Result.Y1 := P.Y;
Result.X2 := Result.X1 + 73;
Result.Y2 := Result.Y1 + 15;
end;

(*
WorldsOrdered
~~~~~~~~~~~~~

.. code-block:: pascal

function worldsOrdered(): boolean;

Returns true if worlds are already ordered

.. note::

by Ashaman88

Example:

.. code-block:: pascal

*)
function worldsOrdered(): Boolean;
begin
Result := getcolor(300,8)=2851375;
end;


(*
OrderWorlds
~~~~~~~~~~~

.. code-block:: pascal

Procedure orderWorlds();

Orders worlds by their number

..note::

by Ashaman88

Example:

.. code-block:: pascal

*)
Function orderWorlds(): boolean;
begin
if not (getLoginState() = LS_WORLDSCREEN)then
exit;

mousebox(toBox(297,8,306,13), MOUSE_LEFT);
result := true;
end;

(*
FullWorld
~~~~~~~~~

.. code-block:: pascal

function fullWorld(W: integer): Boolean;

returns true if world is full

..note::

by Ashaman88

Example:

.. code-block:: pascal

*)
function fullWorld(World: Integer): boolean;
var
txt: string;
checkbox: tbox;
begin
if not (getLoginState() = LS_WORLDSCREEN) then
exit(false);
checkbox := worldIndexToMSBox(World);
txt := getTextAtEx((checkbox.x1+44), checkbox.y1, (checkbox.x2-10), checkbox.y2, 0, 4, 2, 16777215, 0, 'StatChars07');
result:= arrinstr(['FULL','ENLL','FNLL','EULL'],txt);
end;


(*
getWorldBox
~~~~~~~~~

.. code-block:: pascal

function getWorldBox(W: integer): Boolean;

Gets the box of the given world.

..note::

by Ashaman88 & Flight

Example:

.. code-block:: pascal

*)
function getWorldBox(W: integer): TBox;
begin
result:=tobox(0,0,0,0);
if not (getLoginState() = LS_WORLDSCREEN) then
Exit;

if not worldsOrdered() then
begin
if not orderWorlds() then
begin
warn('Could not order worlds properly.', WT_CORE);
exitWorldScreen();
Exit;
end;
wait(400+random(200));
end;

if fullworld(W) then
begin
warn('World selected is currently full.', WT_CORE);
exitWorldScreen();
exit;
end;

result := worldIndexToMSBox(W);
end;

(*
SelectWorld
~~~~~~~~~~~

.. code-block:: pascal

Function selectWorld(W: Integer): Boolean;

Switches to the specified world. Returns true if successful.

..note::

by Narcle / ZephyrsFury & Flight

Example:

.. code-block:: pascal

*)
function selectWorld(W: integer): boolean;
var
T : Timer;
wb : tbox;
begin
if (getCurrentWorldLS() = w) then
exit(true);

if (not inRange(W,301,386)) and (not inRange(W,393,394)) then
begin
warn('Invalid world', WT_CORE);
exitWorldScreen();
Exit(false);
end;

if not openWorldScreen() then
exitWorldScreen();

if openWorldScreen() then
begin
wb:= getWorldBox(W);
if wb.x1 = 0 then
begin
exitWorldScreen();
exit(false);
end;
mousebox(wb, MOUSE_LEFT);
result:=true;
end;

T.start();
repeat
wait(randomrange(400,500));
if not (getLoginState() = LS_WORLDSCREEN) then
break;
until(T.timeElapsed() > 6000);

if (getLoginState() = LS_WORLDSCREEN) then
exitWorldScreen();

wait(randomrange(400,500));
if (not(Result)) then typeByte(vk_Escape);
end;


(*
RandomWorld
~~~~~~~~~~~

.. code-block:: pascal

function randomWorld(): Integer;

Returns a random world

..note::

by Ashaman88

Example:

.. code-block:: pascal

*)
function randomWorld(Member: Boolean): Integer;
var
MemWorlds,
FreeWorlds : TIntegerArray;
begin
MemWorlds :=
[318,352,373,
302,319,336,353,374,
303,320,354,375,
304,321,338,355,376,
305,322,339,356,377,
306,323,340,357,378,
307,324,341,358,
342,359,
309,343,360,
310,327,344,361,
311,328,362,
312,329,346,365,386,
313,330,347,366,
314,331,348,367,
315,332,349,368,
333,350,369,
317,334,351,370];

FreeWorlds :=
[301,308,316,326,335,381,382,
383,384,385,393,394];

if Member then
Result := MemWorlds[Random(High(MemWorlds))]
else
Result := FreeWorlds[Random(High(FreeWorlds))];
end;

(*
ChangeWorld
~~~~~~~~~~~

.. code-block:: pascal

function changeWorld(W: Integer): Boolean;

Changes to world W, returns True if successful.

..note::

by Ashaman88

Example:

.. code-block:: pascal

*)
function changeWorld(W: Integer; Safe: Boolean): Boolean;
begin
if isLoggedIn() then
waitFunc(@logoutPlayer, 500, 5000);
result := getCurrentWorldLS = w;
if not result then
Result := selectWorld(W);
//if Length(Me.WorldList) > 0 then
//Me.WorldList[0]:=W;
loginPlayer(Safe);
end;

procedure switchRandomWorld();
var
W : Integer;
begin
if isLoggedIn() then
logoutPlayer();
W := randomWorld(Me.Member);
warn('World '+toStr(W)+' chosen.', WT_SCRIPT);
changeWorld(W, false);
if not isLoggedIn() then
loginPlayer(false);
end;