Bionicle
2010-03-04 20:17:28
Needs testing to see if they are broken or not (they shouldn't be):
- UpdateWorlds
- LoadWorldArray
- ChangeWorld + RandomWorld(probably works, but untested)
- ChooseWorldBy
I fixed:
- WorldScreen
- FindWorld
- SelectWorld
- OrderWorlds
I rewrote:
- OpenWorldScreen
I added:
- GetLobbyTab
- LobbyTab
I changed;
- GetWorldInfo
- WorldScreen
- FindWorld
- SelectWorld
- OrderWorlds
- OpenWorldScreen
In WorldScreen I changed:
- The mouse coords
- SmallChars to StatChars
In FindWorld I changed:
- Added to take into account members world text (yellow instead of white)
- Mouse coords that were off, such as the order world one and the box of the world numbers
- Added if the World screen is not open, try to open it before it exits the function
In SelectWorld I changed:
- Added to take into account members world text (yellow instead of white)
- Mouse coords that were off
- When it moves the mouse over the world to click it, to look for the highlighted grey color before it clicks
- when it clicks instead of the timer, i changed it to if it finds the highlighted orange color (world switching is hella faster now ;), no need for timer)
In OrderWorlds I changed:
- The coords of the box that surounded the ordering button thingys
- The array of the TStringArray, lootshare was in the wrong place.
In GetWorldInfo I changed:
- Added to take into account members world text (yellow instead of white)
- changed SmallChars to StatChars so it would at least run the other functions ^.^ not to sure how to fix it
New WorldSwitcher.scar:
//-----------------------------------------------------------------//
//-- Scar Standard Resource Library --//
//-- ยป WorldSwitch routines --//
//-----------------------------------------------------------------//
// * function WorldScreen: Boolean; // by Narcle
// * function GetLobbyTab: Boolean; // by Bionicle1800
// * function LobbyTab: Boolean; // by Bionicle1800
// * function OpenWorldScreen: Boolean; // by Nava2
// * 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 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;
{ const LobbyTab Constants;
Description: Constants representing lobbytab numbers. }
const
PlayerInfo = 1;
WorldSelect = 2;
FriendsList = 3;
ClanChat = 4;
Options = 5;
{*******************************************************************************
function WorldScreen: Boolean;
by: Narcle, edit by NaumanAkhlaQ, edit by Bionicle1800
Description: Returns true if the World screen is open.
*******************************************************************************}
function WorldScreen: Boolean;
begin
Result := FindTextTPA(16777215, 0, 672, 62, 695, 74, 'orld ', StatChars, Nothing);
end;
{*******************************************************************************
function GetLobbyTab: Integer;
By: Bionicle1800
Description: Gets current lobby tab.
*******************************************************************************}
function GetLobbyTab: Integer;
begin
for result := 1 to 5 do
if GetColor(97 + (result-1)*123, 31) = 7375258 then
Exit;
end;
{*******************************************************************************
function LobbyTab(Tab: Integer): Boolean;
By: Bionicle1800
Description: Goes to the lobby tab specified by the integer 'Tab'.
Valid arguments are 1 through 5, as well as PlayerInfo,
WorldSelect, FriendsList, ClanChat and Options.
*******************************************************************************}
function LobbyTab(Tab: Integer): Boolean;
begin
if not InRange(Tab, PlayerInfo, Options) then
begin
Srl_Warn('LobbyTab', 'Tab ' + IntToStr(Tab) + ' is not valid.', warn_AllVersions);
Exit;
end;
result := GetLobbyTab = Tab;
if result then
Exit;
if GetColor(97 + (Tab-1)*123, 31) = 4410194 then
begin
Mouse(97 + (Tab-1)*123, 31, 6, 6, true);
result := true;
end;
end;
{*******************************************************************************
function OpenWorldScreen: Boolean;
by: Bionicle1800
Description: Opens the world screen. Returns true if world screen is opened.
*******************************************************************************}
function OpenWorldScreen: Boolean;
begin
if LobbyTab(2) then
if WorldScreen then
result := true;
end;
const
SRL_LG_ENGLISH = 0;
SRL_LG_GERMAN = 1;
SRL_LG_FRENCH = 2;
SRL_LG_PORTUGUESE = 3;
SRL_WORLDPARSE_LANG = SRL_LG_ENGLISH;
{*******************************************************************************
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;
Path := IncludePath + 'SRL\SRL\misc\Worlds.INI';
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;
begin
try
H := StrToInt(ReadINI('Worlds', 'High', IncludePath + 'SRL\SRL\misc\Worlds.ini'));
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', IncludePath + 'SRL\SRL\misc\Worlds.ini') = '') then
begin
WorldArray[Hw].Number := i;
WorldArray[Hw].Prefix := ReadINI('World' + IntToStr(i), 'Prefix', IncludePath + 'SRL\SRL\misc\worlds.ini');
WorldArray[Hw].Members := (ReadINI('World' + IntToStr(i), 'Type', IncludePath + 'SRL\SRL\misc\worlds.ini') = 'Members');
WorldArray[Hw].LootShare := StrToBool(ReadINI('World' + IntToStr(i), 'Lootshare', IncludePath + 'SRL\SRL\misc\worlds.ini'));
WorldArray[Hw].QuickChat := StrToBool(ReadINI('World' + IntToStr(i), 'Quickchat', IncludePath + 'SRL\SRL\misc\worlds.ini'));
WorldArray[Hw].PVP := StrToBool(ReadINI('World' + IntToStr(i), 'PvP', IncludePath + 'SRL\SRL\misc\worlds.ini'));
WorldArray[Hw].Language := ReadINI('World' + IntToStr(i), 'ServLang', IncludePath + 'SRL\SRL\misc\worlds.ini');
Inc(Hw);
end;
SetArrayLength(WorldArray, Hw);
end;
{*******************************************************************************
function FindWorld(W: integer): Boolean;
by: Narcle, edit by Bionicle1800
Description: Scrolls to area and returns true if world was found
*******************************************************************************}
function FindWorld(W: integer): Boolean;
Var
WPos, SPos, i, x, y, H: integer;
begin
if not WorldScreen then
if not OpenWorldScreen then
Exit;
Result := FindTextTpaEx(16579836, 0, 103, 135, 122, 438, x, y, IntToStr(W), StatChars, Nothing);
if Result then
Exit;
Result := FindTextTpaEx(6618364, 0, 103, 135, 122, 438, x, y, IntToStr(W), StatChars, Nothing);
if Result then
Exit;
if Length(WorldArray) < 1 then
LoadWorldArrays;
H := High(WorldArray);
for i := 0 to H do
if (WorldArray[i].Number = W) then
begin
WPos := i+1;
Break;
end;
SPos := Round(WPos / (H+1)*100);
if not WorldsOrdered then
begin
Mouse(103, 129, 3, 3, true);//makes them drop down
WorldsOrdered := true;
wait(500+random(500));
end;
if (W < 16) then SPos := 0;
if (W > H-9) then SPos := 101;//101 compensate for randomness
Mouse(698, Round(SPos/100.0*262.0+152), 3, 3, true);
wait(500+Random(100));
Result := FindTextTpaEx(16579836, 0, 103, 135, 122, 438, x, y, IntToStr(W), StatChars, Nothing);
if Result then
Exit;
Result := FindTextTpaEx(6618364, 0, 103, 135, 122, 438, x, y, IntToStr(W), StatChars, Nothing);
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;
begin
if (WorldScreen) then
begin
Color := 16579836;//white
if not FindTextTpaEx(Color, 0, 84, 134, 134, 440, x, y, ' '+inttostr(World)+' ', StatChars, Nothing) then
begin
Color := 6618364;//yellow
if FindTextTpaEx(Color, 0, 84, 134, 134, 440, x, y, ' '+inttostr(World)+' ', StatChars, Nothing) then
WorldRec.Members := true
else
Exit;
end;
WorldRec.Number := World;
WorldRec.PlayerNo := StrToIntDef(Trim(GetTextAtEx(138, y-1, 0, StatChars, False, False, 0, 3, Color, 4, False, tr_Digits)), -1);
WorldRec.Activity := Trim(GetTextAtEx(240, y - 1, 0, StatChars, False, False, 0, 3, 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('ounty', WorldRec.Activity) > 0;
Result := (WorldRec.PlayerNo > 0);
end;
end;
{*******************************************************************************
Function SelectWorld(W: Integer): Boolean;
by: Narcle & ZephyrsFury, edit by Bionicle1800
Description: Switches to the specified world. Returns true if successful.
*******************************************************************************}
function SelectWorld(W: integer): boolean;
var
x, y, xx, yy: integer;
WRec: TWorld;
begin
if OpenWorldScreen then
begin
wait(400+random(200));
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 not FindTextTpaEx(16579836, 0, 103, 135, 122, 438, x, y, IntToStr(W), StatChars, nothing) then
if not FindTextTpaEx(6618364, 0, 103, 135, 122, 438, x, y, IntToStr(W), StatChars, Nothing) then
Exit;
MMouse(x, y, 500, 4);
GetMousePos(x, y);
wait(300);
if FindColor(xx, yy, 6316128, x-20, y-2, x+20, y+2) then
begin
Mouse(x, y, 0, 0, true);//Final click
Wait(300);
if FindColor(xx, yy, 19890, x-20, y-2, x+20, y+2) then
Result := true;
end;
end else
WriteLn('World ' + IntToStr(W) + ' is either OFFLINE or FULL.');
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;
begin
if High(WorldArray) < 0 then
LoadWorldArrays;
H := High(WorldArray);
SetLength(wArray, H + 1);
for i := 0 to H do
if (WorldArray[i].Members = Members) and (WorldArray[i].PvP = PvP) 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
while LoggedIn do LogOut;
Result := SelectWorld(W);
LoginPlayer;
end;
{*******************************************************************************
Procedure OrderWorlds(by: string; Descending: boolean);
by: NaumanAkhlaQ, edit by Bionicle1800
Description: Orders worlds by 'by' in order 'Descending'
Check function for valid params of 'by'
Descending = true means the left button
*******************************************************************************}
Procedure OrderWorlds(by: string; Descending: 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(['type', 't']), TStringArray(['ls', 'lootshare']), TStringArray(['ping', 'pi'])];
For I := 0 To High(Arr) Do
If InStrArr(Lowercase(By), Arr[i], False) Then
Break;
FindColorsTolerance(TPA, 1074576, 82, 103, 683, 136, 1);
ATPA := SplitTPA(TPA, 2);
SortATPAFromFirstPoint(ATPA, Point(91, 124));
TB := GetTPABounds(ATPA[(I * 2) + Integer(Descending)]);
MouseBox(TB.x1, TB.y1, TB.x2, TB.y2, 1);
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;