Narcle
2011-09-08 22:16:19
Need some testing done. I've ran it multiple times but real use would be best.
This update will allow you too have favorite worlds and still work.
Note: worlds.ini needs to be updated, world21 for me was set to a free world but is in fact members so it failed to find it.
Small change in OrderWorlds to sort correctly.
Most of the redone was in FindWorld as you can imagine.
This update will allow you too have favorite worlds and still work.
Note: worlds.ini needs to be updated, world21 for me was set to a free world but is in fact members so it failed to find it.
Small change in OrderWorlds to sort correctly.
Most of the redone was in FindWorld as you can imagine.
//-----------------------------------------------------------------//
//-- Scar Standard Resource Library --//
//-- ? WorldSwitch routines --//
//-----------------------------------------------------------------//
// * function WorldScreen: Boolean; // by Narcle
// * function OpenWorldScreen: Boolean; // by Bionicle1800
// * function UpdateWorlds: Boolean; // by mixster & Nava2
// * procedure LoadWorldArrays; // by Narcle
// * function FindWorld(W: integer): Boolean; // by Narcle
// * function GetWorldInfo(World: Integer; var WorldRec: TWorld): Boolean; // by Narcle
// * function WS_CurrentWorld(var World: Integer): Boolean; // by IceFire908
// * function GetWorldInfo(World: Integer; var WorldRec: TWorld): Boolean; // by Narcle
// * function FindWorld(W: integer): Boolean; // by Narcle fixed by Shuttleu
// * function SelectWorld(WorldNumber: Integer): Boolean; // by Narcle & ZephyrsFury
// * function RandomWorld(Members, PvP: Boolean): Integer; // by Narcle & mixster
// * function ChangeWorld(W: Integer): Boolean; // by Nava2
// * Procedure OrderWorlds(by: string; Descending: boolean); // by NaumanAkhlaQ
// * Function ChooseWorldBy(SettingsNames:TStringArray; SettingsDescending: TBooleanArray; Members, PVP: boolean): boolean; // by Rasta Magician
type
TWorld = record
Number, PlayerNo: Integer;
Members: Boolean;
Prefix, Location, Activity, Language: String;
LootShare, QuickChat, PVP: Boolean;
end;
TWorldArray = array of TWorld;
var
WorldArray: TWorldArray;
WorldsOrdered: Boolean;
function ExitToLobby: Boolean; forward;
function LogInPlayer: Boolean; forward;
{*******************************************************************************
function WorldScreen: Boolean;
by: IceFire908
Description: Returns true if the World screen is open.
*******************************************************************************}
function WorldScreen: Boolean;
begin
Result := (GetLobbyTab = L_WorldSelect);
end;
{*******************************************************************************
function OpenWorldScreen: Boolean;
by: Bionicle1800
Description: Opens the world screen. Returns true if world screen is opened.
*******************************************************************************}
function OpenWorldScreen: Boolean;
begin
Result := LobbyTab(2);
end;
const
SRL_LG_ENGLISH = 0;
SRL_LG_GERMAN = 1;
SRL_LG_FRENCH = 2;
SRL_LG_PORTUGUESE = 3;
SRL_WORLDPARSE_LANG = SRL_LG_ENGLISH;
SRL_WS_ARROWCOLOR = 1008783;//Arrow color that can order the worlds;
SRL_WS_WHITECOLOR = 16579836;//White text color, (f2p);
SRL_WS_YELLOWCOLOR = 6618364;//Yellow text color, (p2p);
SRL_WS_SCROLLCOLOR1 = 1250841;//Black color on the left side of scroll area
SRL_WS_SCROLLCOLOR2 = 592137;//Black color under scroll bar
{*******************************************************************************
procedure UpdateWorlds;
by: mixster
Description: Parses the worlds page into Worlds.INI
*******************************************************************************}
function UpdateWorlds: Boolean;
var
worldList: TWorldArray;
str, Path: string;
tsa, tsb: TStringArray;
W, I, H, Time: Integer;
begin
try
Result := True;
{$IFDEF SIMBA}
Path := IncludePath + 'SRL/SRL/misc/worlds.ini';
{$ELSE}
Path := IncludePath + 'SRL\SRL\misc\worlds.INI';
{$ENDIF}
Writeln('NOTE: Attempting to update the Worlds.INI, please allow the script to access this file.');
Time := GetTimeRunning;
W := RewriteFile(Path, False);
CloseFile(W);
if (SRL_WORLDPARSE_LANG = SRL_LG_ENGLISH) then
str := ''
else
str := 'l=' + IntToStr(SRL_WORLDPARSE_LANG) + '/';
str := GetPage('http://www.runescape.com/' + str + 'slu.ws?order=WMPLA');
Delete(str, 1, Pos('<a href="?order=MWPLA">', str));
Delete(str, 1, Pos('<tr', str) + 3);
tsa := srl_Explode(str, '<tr');
H := High(tsa);
SetLength(worldList, H + 1);
for I := 0 to H do
with worldList[I] do
begin
tsb := srl_Explode(tsa[I], '<td');
if High(tsb) < 5 then
begin
Writeln('Skipping world "' + IntToStr(I + 1) + '" because explosion didn''t return enough values');
Continue;
end;
PlayerNo := StrToIntDef(Between('>', '<', tsb[2]), 2000);
if (Between('"', '"', tsb[3]) = 'a') or (Between('"', '"', tsb[3]) = 'a d') then
begin
Location := 'Activity';
Activity := Between('>', '<', tsb[3]);
end
else
begin
Location := Between('>', '<', tsb[3]);
Activity := '';
end;
Prefix := Between('http://', '.runescape', tsb[1]);
if Prefix = '' then
Prefix := Replace(Lowercase(Between('>' + #10, #10 + #10, tsb[1])), ' ', '');
Number := StrToIntDef(Replace(Prefix, 'world', ''), -1);
if Number = -1 then
begin
Writeln('Invalid world number produced: ' + Prefix);
Writeln('Assuming has suffix, trying again');
str := Replace(Prefix, 'world', '');
Number := StrToIntDef(Copy(str, 1, Length(str) - 1), -1);
if Number = -1 then
Writeln('Failed to gather a world number')
else
Writeln('Succeeded, got ' + IntToStr(Number));
end;
LootShare := Between('"', '"', tsb[4]) = 'd';
QuickChat := Activity = 'Quick Chat';
PvP := Activity = 'PvP World';
Members := Between('"', '"', tsb[5]) = 'm';
end;
//Writeln('Writing to the INI File. T: ' + IntToStr(GetTimeRunning - W));
except
Result := False;
//SRL_Warn('UpdateWorlds', ExceptionToString(ExceptionType, ExceptionParam), Warn_AllVersions);
end;
if not Result then Exit;
WriteINI('Worlds', 'Count', IntToStr(High(worldList) + 1), Path);
WriteINI('Worlds', 'High', IntToStr(worldList[High(worldList)].Number) + #13#10, Path);
H := High(worldList);
for I := 0 to H do
with worldList[I] do
begin
Str := 'World' + IntToStr(Number);
DeleteINI(Str, '', Path);
WriteINI(Str, 'Prefix', Prefix, Path);
WriteINI(Str, 'Activity', Activity, Path);
//WriteINI(Str, 'Type', BoolToStr(Members), Path);
if (Members) then
WriteINI(Str, 'Type', 'Members', Path)
else
WriteINI(Str, 'Type', 'Free', Path);
//WriteINI(Str, 'Flag', fla + 'Flag', Path);
WriteINI(Str, 'Location', Location, Path);
WriteINI(Str, 'LootShare', BoolToStr(LootShare), Path);
WriteINI(Str, 'QuickChat', BoolToStr(QuickChat), Path);
WriteINI(Str, 'PvP', BoolToStr(PvP) + #13#10, Path);
end;
Writeln('Parsed Worlds Page into Worlds.INI. Took ' + IntToStr(GetTimeRunning - Time) + ' ms.');
end;
{*******************************************************************************
procedure LoadWorldArrays;
by: Narcle; Edits by Nava2
Description: Loads the world array into WorldArray from Worlds.ini
*******************************************************************************}
procedure LoadWorldArrays;
var
i, H, Hw: integer;
FilePath: String;
begin
{$IFDEF SIMBA}
FilePath := IncludePath + 'SRL/SRL/misc/worlds.ini';
{$ELSE}
FilePath := IncludePath + 'SRL\SRL\misc\worlds.ini';
{$ENDIF}
try
H := StrToInt(ReadINI('Worlds', 'High', FilePath));
except
Writeln('LoadWorldArrays: Could not load world arrays, attempting to rewrite Worlds.INI');
if not UpdateWorlds then
begin
SRL_Warn('LoadWorldArrays', 'Could not Load World arrays, please download mixster''s world parser, and replace Worlds.ini', Warn_AllVersions);
Exit;
end;
end;
SetArrayLength(WorldArray, H + 1);
for i := 1 to H do
if not (ReadINI('World' + IntToStr(i), 'Prefix', FilePath) = '') then
begin
WorldArray[Hw].Number := i;
WorldArray[Hw].Prefix := ReadINI('World' + IntToStr(i), 'Prefix', FilePath);
WorldArray[Hw].Members := (ReadINI('World' + IntToStr(i), 'Type', FilePath) = 'Members');
WorldArray[Hw].LootShare := StrToBool(ReadINI('World' + IntToStr(i), 'Lootshare', FilePath));
WorldArray[Hw].QuickChat := StrToBool(ReadINI('World' + IntToStr(i), 'Quickchat', FilePath));
WorldArray[Hw].PVP := StrToBool(LowerCase(ReadINI('World' + IntToStr(i), 'PvP', FilePath)));
WorldArray[Hw].Language := ReadINI('World' + IntToStr(i), 'ServLang', FilePath);
Inc(Hw);
end;
SetArrayLength(WorldArray, Hw);
end;
{*******************************************************************************
function WS_CurrentWorld(var World: Integer): Boolean;
by: IceFire908
Description: Results true if the current world is members,returns world number.
World returns -1 if failed. Only works at world screen.
*******************************************************************************}
function WS_CurrentWorld(var World: Integer): Boolean;
var
P: TPoint;
begin
World := -1;
if (not (WorldScreen)) then
Exit;
if (IsTextInAreaEx(618, 74, 705, 96, P.X, P.Y, 'orld', 0, SmallChars, False, False, 0, 1, clWhite)) then
World := StrToIntDef(GetNumbers(Trim(GetTextAtEx(P.X, P.Y, 0, SmallChars, False, False, 0, 1, clWhite, 15, False, tr_AllChars))), -1);
Result := FindColorTolerance(P.X, P.Y, 3141117, 596, 64, 701, 100, 20);
end;
{*******************************************************************************
Procedure OrderWorlds(by: string; Descending: boolean);
by: NaumanAkhlaQ
Description: Orders worlds by 'by' in order 'Descending'
Check function for valid params of 'by'
Descending = true means the left button
*******************************************************************************}
Function OrderWorlds(by: string; Descending: boolean): boolean;
var
ATPA: T2DPointArray;
Arr: array of tstringarray;
TPA: TPointArray;
I: Byte;
TB: TBox;
begin
Arr := [TStringArray(['world', 'w', 'worlds']), TStringArray(['players', 'pl', 'player']), TStringArray(['activity', 'location', 'loc', 'act']),
TStringArray(['ls', 'lootshare']), TStringArray(['type', 't']), TStringArray(['ping', 'pi'])];
for I := 0 To High(Arr) do
if InStrArr(Lowercase(By), Arr[i], False) then
Break;
FindColorsTolerance(TPA, SRL_WS_ARROWCOLOR, 92, 0, 716, 200, 1);
ATPA := SplitTPA(TPA, 2);
SortATPAFromFirstPoint(ATPA, Point(92, 166));
if Length(ATPA) < (I * 2) then
Exit;
TB := GetTPABounds(ATPA[(I * 2) + Integer(Descending)]);
MouseBox(TB.x1, TB.y1, TB.x2, TB.y2, 1);
Result := true;
end;
{*******************************************************************************
function FindWorld(W: integer): Boolean;
by: Narcle
Description: Scrolls to area and returns true if world was found
*******************************************************************************}
function FindWorld(W: integer): Boolean;
Var
WPos, SPos, CurPos, i, H, CurW, TextColor: integer;
p: TPoint;
TPA, TPA2, TPA3: TPointArray;
SP, SB: TBox;
begin
if not WorldScreen then
Exit;
WS_CurrentWorld(CurW);
if (W = CurW) then
begin
Result := True;
WriteLn('Already on world ' + IntToStr(W));
Exit;
end;
if (W = 0) then
begin
srl_Warn('FindWorld', 'World Number cannot be 0', warn_AllVersions);
Exit;
end;
if not WorldsOrdered then
begin
if not OrderWorlds('w', True) then
begin
Writeln('FindWorld: Could not order worlds properly.');
Exit;
end;
WorldsOrdered := true;
wait(400+random(200));
end;
FindColorsTolerance(TPA, SRL_WS_SCROLLCOLOR1, 680, 1, 705, 500, 0);//These coords determine the scroll bars general area, it deviates everything.
SB := GetTPABounds(TPA);
With SB do
begin
FindColorsTolerance(TPA2, SRL_WS_SCROLLCOLOR1, x1+3, y1, x1+3, y2, 0);//SRL_WS_SCROLLCOLOR1
FindColorsTolerance(TPA3, SRL_WS_SCROLLCOLOR2, x1+3, y1, x1+3, y2, 0);//SRL_WS_SCROLLCOLOR2
end;
TPA2 := CombineTPA(TPA2, TPA3);
SP := GetTPABounds(TPA2);
//Writeln('Half Worlds shown:'+IntToStr((SB.y2-SB.y1+32)/42));
if Length(WorldArray) < 1 then
LoadWorldArrays;
WPos := -1;
H := High(WorldArray);
for i := 0 to H do
if (WorldArray[i].Number = W) then
begin
WPos := i;
if i < ((SB.y2-SB.y1+32)/42) then
WPos := 0;
if i > (H+1-((SB.y2-SB.y1+32)/42)) then
WPos := (H+1);
if WorldArray[i].Members then
TextColor := SRL_WS_YELLOWCOLOR
else
TextColor := SRL_WS_WHITECOLOR;
Break;
end;
if WPos = -1 then
begin
srl_Warn('FindWorld', 'World '+IntToStr(W)+' does not exist in worlds.ini ', warn_AllVersions);
Exit;
end;
//Writeln('CurPos: '+ToStr(CurPos)+' WPos: '+ToStr(WPos)+' H+1: '+ToSTr(H+1));
SPos := (SB.y1+(SP.Y2-SP.Y1)/2) + Round( (WPos+0.0)/(H+1.0-((SB.y2-SB.y1+32)/42))*(SB.y2-SB.y1-(SP.Y2-SP.Y1)+0.0) );//need the 0.0 to make it extended inside ()
CurPos := (SP.y2 + (SP.Y2-SP.Y1)/2);
if InRange(SPos, CurPos - (SP.Y2-SP.Y1), CurPos + (SP.Y2-SP.Y1)) then
begin//if its too close the scroll bar won't move to correct position
if (SP.y2 < ((SB.y1+(SP.Y2-SP.Y1))+ (SB.y2-SB.y1-(SP.Y2-SP.Y1))/2)) then//half point
Mouse((SB.x1 + (SB.x2-SB.x1)/2), SB.y2, 0, 0, true)
else
Mouse((SB.x1 + (SB.x2-SB.x1)/2), SB.y1, 0, 0, true);
end;
//Writeln('SPos := '+ToStr(SPos));
Mouse((SB.x1 + (SB.x2-SB.x1)/2), SPos, 0, 0, true);
wait(300+Random(100));
Result := IsTextInAreaEx(84, 134, 134, 440, p.X, p.Y, IntToStr(W) + ' ', 0, StatChars, False, False, -1, 2, TextColor);
end;
{*******************************************************************************
function GetWorldInfo(World: Integer; var WorldRec: TWorld): Boolean;
by: Narcle
Description: Records World info into TWorld record, also Results true if world
was found
*******************************************************************************}
function GetWorldInfo(World: Integer; var WorldRec: TWorld): Boolean;
var
xx, yy, x, y, Color: integer;
Num: String;
begin
if (WorldScreen) then
begin
Color := SRL_WS_WHITECOLOR;//white
if not IsTextInAreaEx(84, 134, 134, 440, X, Y, IntToStr(World) + ' ', 0, StatChars, False, False, 0, 2, Color) then
begin
Color := SRL_WS_YELLOWCOLOR;//yellow
if IsTextInAreaEx(84, 134, 134, 440, X, Y, IntToStr(World) + ' ', 0, StatChars, False, False, 0, 2, Color) then
WorldRec.Members := true
else
Exit;
end;
WorldRec.Number := World;
Num := LowerCase(Trim(GetTextAtEx(137, y, 0, StatChars, False, False, 0, 2, Color, 5, False, tr_AllChars)));
if Num = 'full' then
WorldRec.PlayerNo := -2
else
WorldRec.PlayerNo := StrToIntDef(Num, -1);
WorldRec.Activity := Trim(GetTextAtEx(238, y, 0, StatChars, False, False, 0, 2, Color, 24, False, tr_AllChars));
WorldRec.LootShare := FindColor(xx, yy, 7711612, 600, y-4, 636, y+14);
WorldRec.QuickChat := Pos('uick', WorldRec.Activity) > 0;
WorldRec.PVP := (Pos('ildern', WorldRec.Activity) > 0);
Result := (WorldRec.PlayerNo > 0);
end;
end;
{*******************************************************************************
Function SelectWorld(W: Integer): Boolean;
by: Narcle & ZephyrsFury
Description: Switches to the specified world. Returns true if successful.
*******************************************************************************}
function SelectWorld(W: integer): boolean;
var
x, y, xx, yy, T, CurW: integer;
WRec: TWorld;
begin
if OpenWorldScreen then
begin
T := GetSystemTime + 60000;
Repeat
Wait(100+random(100));
until InRange(CountColorTolerance(SRL_WS_ARROWCOLOR, 0, 0, 716, 240, 1), 550, 650) or (GetSystemTime > T);
if (GetSystemTime > T) then
begin
Writeln('World screen did not load after a minute, please refreash.');
Exit;
end;
WS_CurrentWorld(CurW);
if (W = CurW) then
begin
Result := True;
WriteLn('Already on world ' + IntToStr(W));
Exit;
end;
if FindWorld(W) then
begin
wait(100+random(100));
if GetWorldInfo(W, WRec) then
begin
Writeln('World: '+inttostr(WRec.Number)+', Players: '+inttostr(WRec.PlayerNo)+', Members: '+Booltostr(WRec.Members)+', PvP: '+Booltostr(WRec.PVP));
if FindText(x, y, ' '+inttostr(W)+' ', StatChars, 84, 134, 140, 440) then
begin
MMouse(x, y, 500, 4);
GetMousePos(x, y);
wait(400+random(100));
if FindColor(xx, yy, 6316128, x-20, y-2, x+20, y+2) then
begin
GetMousePos(x, y);
Mouse(x, y, 0, 0, true);
if FindColor(xx, yy, 19890, x-20, y-2, x+20, y+2) then
begin
Writeln('World '+inttostr(W)+' selected.');
Result := true;
end;
end;
end;
end else
if WRec.PlayerNo = -2 then
WriteLn('World ' + IntToStr(W) + ' is FULL.')
else
WriteLn('World ' + IntToStr(W) + ' is OFFLINE.')
end else
WriteLn('Failed to find World ' + IntToStr(W) + '!');
if (not(Result)) then TypeByte(vk_Escape);
end;
end;
{*******************************************************************************
function RandomWorld(Members, PvP: Boolean): Integer;
by: Narcle & mixster
Description: Returns a random world by paramaters.
*******************************************************************************}
function RandomWorld(Members, PvP: Boolean): Integer;
var
i, H, l: integer;
wArray: TWorldArray;
Mems, Pv: Boolean;
begin
if High(WorldArray) < 0 then
LoadWorldArrays;
H := High(WorldArray);
SetLength(wArray, H + 1);
if (Members) then
Mems := True;
if (PvP) then
Pv := True;
for i := 0 to H do
if (WorldArray[i].Members = Mems) and (WorldArray[i].PvP = Pv) and (InStrArr(WorldArray[i].Language, ['English', ''], False)) then
begin
wArray[l] := WorldArray[i];
Inc(l);
end;
Result := wArray[random(l)].Number;
end;
{*******************************************************************************
function ChangeWorld(W: Integer): Boolean;
by: Nava2
Description: Changes to world W. Returns True if successful.
*******************************************************************************}
function ChangeWorld(W: Integer): Boolean;
begin
if LoggedIn then
WaitFunc(@ExitToLobby, 500, 5000);
Result := SelectWorld(W);
LoginPlayer;
end;
{*******************************************************************************
Function ChooseWorldBy(SettingsNames:TStringArray; SettingsDescending: array of boolean; Members, PVP: boolean): boolean;
by: Rasta Magician
Description: Chooses a world by SettingsNames , ordered by SettingsDescending
Takes into account Members and PVP
Check OrderWorlds for valid params for SettingsNames
*******************************************************************************}
function ChooseWorldBy(SettingsNames:TStringArray; SettingsDescending: array of boolean; Members, PVP: boolean): boolean;
var
TPA: TPointArray;
i, C : integer;
begin
if not WorldScreen then
if not OpenWorldScreen then
exit;
if length(SettingsNames) <> length(SettingsDescending) then
begin
srl_warn('ChooseWorldBy', 'Arrays are not the same length', warn_AllVersions);
SelectWorld(RandomWorld(Members, PVP));
exit;
end;
for i:= 0 to High(SettingsNames) do
begin
OrderWorlds(SettingsNames[i], SettingsDescending[i]);
wait(1000+random(200));
end;
wait(1500+random(500));
for i:= 0 to 15 do //16 worlds show up in screen
begin
FindColorsTolerance(TPA, 16777215, 182, 150+18*i, 206, 159+18*i, 0);
C := Length(TPA);
if (C = 0)or(C = 66) then //failed detection or full
Continue;
if (Members)xor(GetColor(620, 157+18*i) <> 11316396) then
Continue;
if (PVP)xor(GetColor(589, 156+18*i) <> 1251528) then
Continue;
MouseBox(79, 148+18*i, 685, 165+18*i, 1);
for c := 0 to 4 do
begin
wait(200);
Result := not WorldScreen;
if Result then exit;
end;
end;
Result := false;
writeln('Failed to sort the worlds. Choosing random world. Members: ' +
BoolToStr(Members) + '; PVP: ' + BoolToStr(PVP) + ';');
SelectWorld(RandomWorld(Members, PVP));
end;