package org.rsbot.script.methods;
import org.rsbot.Configuration;
import org.rsbot.script.util.Filter;
import org.rsbot.script.wrappers.RSComponent;
import org.rsbot.script.wrappers.RSInterface;
import org.rsbot.util.io.HttpClient;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* Methods for lobby interface
*
* @author Debauchery
*/
public class Lobby extends MethodProvider {
public static final int INTERFACE_LOBBY = 906;
public static final int TAB_WORLDS = 22;
public static final int TAB_FRIENDS = 21;
public static final int TAB_CLAN = 20;
public static final int TAB_OPTIONS = 19;
public static final int TAB_FRIENDS_CHAT = 265;
public static final int TAB_PLAYERS = 215;
public static final int INTERFACE_LOBBY_BUTTON_PLAY = 171;
public static final int INTERFACE_LOBBY_ALERT_TEXT = 235;
public static final int INTERFACE_LOBBY_ALERT_CLOSE = 242;
public static final int INTERFACE_LOBBY_BUTTON_LOGOUT = 195;
public final static int INTERFACE_LOBBY_WORLD_SELECT = 910;
public final static int INTERFACE_WORLD_SELECT_CURRENT_WORLD = 11;
public final static int INTERFACE_WORLD_SELECT_WORLD_LIST = 77;
public final static int INTERFACE_WORLD_SELECT_WORLD_NAME = 69;
public final static int INTERFACE_WORLD_SELECT_AMOUNT_OF_PLAYERS = 71;
public final static int INTERFACE_WORLD_SELECT_WORLD_ACTIVITY = 72;
public final static int INTERFACE_WORLD_SELECT_WORLD_TYPE = 74;
public final static int INTERFACE_WORLD_SELECT_WORLD_PING = 76;
public final static int INTERFACE_WORLD_SELECT_SCROLL_AREA = 86;
public final static int INTERFACE_WORLD_SELECT_SCROLL_BAR = 1;
public static final Filter<World> ALL_FILTER = new Filter<World>() {
public boolean accept(final World w) {
return true;
}
};
public Lobby(final MethodContext ctx) {
super(ctx);
}
/**
* Checks that current game is in lobby.
*
* @return <tt>true</tt> if the tab is opened.
*/
public boolean inLobby() {
return methods.game.getClientState() == Game.INDEX_LOBBY_SCREEN;
}
public class World {
private final String world;
private final String players;
private final String activity;
private final String lootShare;
private final String type;
public World(String world, String players, String activity, String lootShare, String type) {
this.world = world;
this.players = players;
this.activity = activity;
this.lootShare = lootShare;
this.type = type;
}
public int getWorldID() {
return Integer.parseInt(this.world);
}
public int getAmountOfPlayers() {
return Integer.parseInt(this.players);
}
public String getActivity() {
return this.activity;
}
public boolean isLootShare() {
return (this.lootShare.equals("Yes"));
}
public boolean isOnline() {
return (!this.players.equals("OFFLINE"));
}
public boolean isMembers() {
return (this.type.equals("Members"));
}
}
public Object[][] getWorldObjects() {
String HTML = null;
try {
HTML = HttpClient.downloadAsString((new URL("http://www." + Configuration.Paths.URLs.GAME + "/slu.ws?order=WPMLA")));
} catch (IOException ignored) {
}
try {
HTML = HTML.split("Type[^<]</td>[^<]</tr>")[1];
HTML = HTML.split("</table>")[0].trim();
} catch (Exception e) {
return new Object[0][0];
}
ArrayList<Object[]> worldData = new ArrayList<Object[]>();
try {
Pattern regex = Pattern.compile("[^ ]World ([0-9[^ |^<|^\n|^ (]]*)[^0-9|^OF]*([0-9|A-Z]*)[^=]*[^>]*>([^<]*)"
+ "[^Y|^N]*(Y|N)[^F|^M]*(Members|Free)", Pattern.UNICODE_CASE);
Matcher regexMatcher = regex.matcher(HTML);
while (regexMatcher.find()) {
worldData.add(new Object[]{regexMatcher.group(1), regexMatcher.group(2), regexMatcher.group(3),
(regexMatcher.group(4).equals("Y") ? "Yes" : "No"), regexMatcher.group(5)});
}
} catch (Exception ignored) {
}
Object[][] result = new Object[worldData.size()][5];
for (int i = 0; i < result.length; i++) {
result[i] = worldData.get(i);
}
return result;
}
public World[] getAll(final Filter<World> filter) {
List<World> worlds = new ArrayList<World>();
for (Object[] worldData : getWorldObjects()) {
if (worldData.length == 5) {
World world = (new World((String) worldData[0], (String) worldData[1], (String) worldData[2],
(String) worldData[3], (String) worldData[4]));
if (world != null && filter.accept(world)) {
worlds.add(world);
}
}
}
return (World[]) worlds.toArray();
}
public World[] getAllMembersIncluded(final boolean members) {
return getAll(new Filter<World>() {
public boolean accept(final World world) {
return world != null && (world.isMembers() == members);
}
});
}
public RSInterface getInterface() {
return methods.interfaces.get(INTERFACE_LOBBY);
}
public RSComponent getComponent(int index) {
RSInterface face = getInterface();
if (face != null && face.isValid()) {
return face.getComponent(index);
}
return null;
}
public boolean clickPlay() {
RSComponent playComp = getComponent(INTERFACE_LOBBY_BUTTON_PLAY);
return playComp != null && playComp.isValid() && playComp.doClick();
}
public int getSelectedTab() {
int[] ids = new int[]{TAB_PLAYERS, TAB_WORLDS, TAB_FRIENDS, TAB_CLAN, TAB_OPTIONS, TAB_FRIENDS_CHAT};
for (int id : ids) {
final RSComponent c = getComponent(id);
if (c != null && c.isValid() && c.getTextureID() == 4671) {
return id;
}
}
return -1;
}
public boolean open(final int tab) {
if (getSelectedTab() == tab) {
return true;
}
final RSComponent c = getComponent(tab);
if (c != null && c.isValid()) {
c.doClick();
}
return getSelectedTab() == tab;
}
public int getSelectedWorld() {
if (!inLobby()) {
return -1;
}
open(TAB_WORLDS);
if (methods.interfaces.getComponent(INTERFACE_LOBBY_WORLD_SELECT, INTERFACE_WORLD_SELECT_CURRENT_WORLD).isValid()) {
final String worldText = methods.interfaces.getComponent(INTERFACE_LOBBY_WORLD_SELECT,
INTERFACE_WORLD_SELECT_CURRENT_WORLD).getText().trim().substring(methods.interfaces.getComponent(
INTERFACE_LOBBY_WORLD_SELECT, INTERFACE_WORLD_SELECT_CURRENT_WORLD).getText().trim().indexOf("World ") + 6);
return Integer.parseInt(worldText);
}
return -1;
}
/**
* Enters a world from the lobby.
*
* @param world The world to switch to.
* @param enter To enter the world or not.
* @return <tt>true</tt> If correctly entered the world else <tt>false</tt>
* @see org.rsbot.script.methods.Game switchWorld(int world)
*/
public boolean switchWorlds(final int world, final boolean enter) {
if (!inLobby() || methods.game.getClientState() == 9 || methods.game.getClientState() == 11) {
return false;
}
if (!methods.interfaces.get(INTERFACE_LOBBY_WORLD_SELECT).isValid() || getSelectedTab() != TAB_WORLDS) {
open(TAB_WORLDS);
sleep(random(600, 800));
}
if (getSelectedWorld() == world) {
if (enter) {
methods.interfaces.getComponent(INTERFACE_LOBBY, INTERFACE_LOBBY_BUTTON_PLAY).doClick();
}
return true;
}
final RSComponent comp = getWorldComponent(world);
if (comp != null) {
methods.interfaces.scrollTo(comp, methods.interfaces.getComponent(INTERFACE_LOBBY_WORLD_SELECT, INTERFACE_WORLD_SELECT_SCROLL_AREA));
comp.doClick();
sleep(random(500, 800));
if (getSelectedWorld() == world) {
if (enter) {
methods.interfaces.getComponent(INTERFACE_LOBBY, INTERFACE_LOBBY_BUTTON_PLAY).doClick();
}
return true;
}
}
return false;
}
/**
* Enters a world from the lobby.
*
* @param world The world to switch to.
* @return <tt>true</tt> If correctly entered the world else <tt>false</tt>
* @see org.rsbot.script.methods.Game switchWorld(int world)
*/
public boolean switchWorlds(final int world) {
return switchWorlds(world, true);
}
/**
* Gets the component of any world on the lobby interface
*
* @param world The world to get the component of.
* @return The component corresponding to the world.
*/
public RSComponent getWorldComponent(final int world) {
if (!inLobby()) {
return null;
}
if (!methods.interfaces.get(INTERFACE_LOBBY_WORLD_SELECT).isValid()) {
open(TAB_WORLDS);
}
for (int i = 0; i < methods.interfaces.getComponent(INTERFACE_LOBBY_WORLD_SELECT, INTERFACE_WORLD_SELECT_WORLD_NAME).getComponents().length; i++) {
final RSComponent comp = methods.interfaces.getComponent(INTERFACE_LOBBY_WORLD_SELECT, INTERFACE_WORLD_SELECT_WORLD_NAME).getComponents()[i];
if (comp != null) {
final String number = comp.getText();
if (Integer.parseInt(number) == world) {
return methods.interfaces.getComponent(INTERFACE_LOBBY_WORLD_SELECT, INTERFACE_WORLD_SELECT_WORLD_LIST).getComponents()[i];
}
}
}
return null;
}
/**
* Used for logging out if in lobby
*
* @return <tt>true</tt> if correctly logged out else false
*/
public boolean logout() {
if (inLobby()) {
methods.interfaces.getComponent(INTERFACE_LOBBY, INTERFACE_LOBBY_BUTTON_LOGOUT).doClick();
}
return !methods.game.isLoggedIn();
}
}