mirror of
https://github.com/sirjonasxx/G-Earth.git
synced 2024-11-27 02:40:51 +01:00
refactor HConnection and finally have it kind of readable
This commit is contained in:
parent
bb1bd567b3
commit
5ce9a8ea02
629
G-Earth/src/main/java/gearth/protocol/HConnection_temp.java
Normal file
629
G-Earth/src/main/java/gearth/protocol/HConnection_temp.java
Normal file
@ -0,0 +1,629 @@
|
||||
package gearth.protocol;
|
||||
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.misc.OSValidator;
|
||||
import gearth.misc.listenerpattern.Observable;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.protocol.hostreplacer.hostsfile.HostReplacer;
|
||||
import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory;
|
||||
import gearth.protocol.hostreplacer.ipmapping.IpMapper;
|
||||
import gearth.protocol.hostreplacer.ipmapping.IpMapperFactory;
|
||||
import gearth.protocol.memory.Rc4Obtainer;
|
||||
import gearth.protocol.packethandler.IncomingPacketHandler;
|
||||
import gearth.protocol.packethandler.OutgoingPacketHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
|
||||
public class HConnection_temp {
|
||||
|
||||
// public static final String HOTELS_CACHE_KEY = "hotelsConnectionInfo";
|
||||
//
|
||||
// private final Queue<HPacket> sendToClientAsyncQueue = new LinkedList<>();
|
||||
// private final Queue<HPacket> sendToServerAsyncQueue = new LinkedList<>();
|
||||
// public HConnection_temp() {
|
||||
// new Thread(() -> {
|
||||
// while (true) {
|
||||
// HPacket packet;
|
||||
// synchronized (sendToClientAsyncQueue) {
|
||||
// while ((packet = sendToClientAsyncQueue.poll()) != null) {
|
||||
// sendToClient(packet);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// Thread.sleep(1);
|
||||
// } catch (InterruptedException e) { //java........................................
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }).start();
|
||||
// new Thread(() -> {
|
||||
// while (true) {
|
||||
// HPacket packet;
|
||||
// synchronized (sendToServerAsyncQueue) {
|
||||
// while ((packet = sendToServerAsyncQueue.poll()) != null) {
|
||||
// sendToServer(packet);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// Thread.sleep(1);
|
||||
// } catch (InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }).start();
|
||||
// }
|
||||
// // checks if host is a raw IP instead of a domain
|
||||
// private static boolean hostIsIpAddress(String host){
|
||||
// for (char c : host.toCharArray()) {
|
||||
// if (c != '.' && (c < '0' || c > '9')) {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public static List<String> autoDetectHosts;
|
||||
// static {
|
||||
// autoDetectHosts = new ArrayList<>();
|
||||
// autoDetectHosts.add("game-br.habbo.com:30000");
|
||||
// autoDetectHosts.add("game-de.habbo.com:30000");
|
||||
// autoDetectHosts.add("game-es.habbo.com:30000");
|
||||
// autoDetectHosts.add("game-fi.habbo.com:30000");
|
||||
// autoDetectHosts.add("game-fr.habbo.com:30000");
|
||||
// autoDetectHosts.add("game-it.habbo.com:30000");
|
||||
// autoDetectHosts.add("game-nl.habbo.com:30000");
|
||||
// autoDetectHosts.add("game-tr.habbo.com:30000");
|
||||
// autoDetectHosts.add("game-us.habbo.com:38101");
|
||||
//
|
||||
// List<Object> additionalCachedHotels = Cacher.getList(HOTELS_CACHE_KEY);
|
||||
// if (additionalCachedHotels != null) {
|
||||
// for (Object additionalHotel : additionalCachedHotels) {
|
||||
// if (!autoDetectHosts.contains(additionalHotel)) {
|
||||
// autoDetectHosts.add((String)additionalHotel);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (OSValidator.isMac()) {
|
||||
// for (int i = 2; i <= autoDetectHosts.size(); i++) {
|
||||
// ProcessBuilder allowLocalHost = new ProcessBuilder("ifconfig", "lo0", "alias", ("127.0.0." + i), "up");
|
||||
// try {
|
||||
// allowLocalHost.start();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public static volatile boolean DECRYPTPACKETS = true;
|
||||
// public static volatile boolean DEBUG = false;
|
||||
// private static final HostReplacer hostsReplacer = HostReplacerFactory.get();
|
||||
//
|
||||
// private volatile boolean hostRedirected = false;
|
||||
// private volatile Object[] trafficObservables = {new Observable<TrafficListener>(), new Observable<TrafficListener>(), new Observable<TrafficListener>()};
|
||||
// private volatile Observable<StateChangeListener> stateObservable = new Observable<>();
|
||||
//
|
||||
// private volatile State state = State.NOT_CONNECTED;
|
||||
//
|
||||
// private volatile List<Proxy> potentialProxies = new ArrayList<>();
|
||||
// private volatile Proxy actual_proxy = null;
|
||||
// private volatile String hotelVersion = "";
|
||||
//
|
||||
// private volatile boolean rawIpMode = false;
|
||||
//
|
||||
//
|
||||
// public HState getState() {
|
||||
// return state;
|
||||
// }
|
||||
//
|
||||
// // autodetect method
|
||||
// public void prepare() {
|
||||
// prepare(autoDetectHosts);
|
||||
// }
|
||||
//
|
||||
// // manual method
|
||||
// public void prepare(String domain, int port) {
|
||||
// List<Object> additionalCachedHotels = Cacher.getList(HOTELS_CACHE_KEY);
|
||||
// if (additionalCachedHotels == null) {
|
||||
// additionalCachedHotels = new ArrayList<>();
|
||||
// }
|
||||
// if (!additionalCachedHotels.contains(domain +":"+port)) {
|
||||
// additionalCachedHotels.add(domain+":"+port);
|
||||
// Cacher.put(HOTELS_CACHE_KEY, additionalCachedHotels);
|
||||
// }
|
||||
//
|
||||
// List<String> potentialHost = new ArrayList<>();
|
||||
// potentialHost.add(domain+":"+port);
|
||||
//
|
||||
// if (hostIsIpAddress(domain)) {
|
||||
// setState(State.PREPARING); // state will not be prepared until the server-connection is initialized
|
||||
// rawIpMode = true;
|
||||
// potentialProxies.clear();
|
||||
// potentialProxies.add(new Proxy(domain, domain, port, port, "0.0.0.0"));
|
||||
// }
|
||||
// else {
|
||||
// prepare(potentialHost);
|
||||
// }
|
||||
//
|
||||
// actual_proxy = null;
|
||||
// }
|
||||
//
|
||||
// public Object[] getTrafficObservables() {
|
||||
// return trafficObservables;
|
||||
// }
|
||||
//
|
||||
// private void prepare(List<String> allPotentialHosts) {
|
||||
// rawIpMode = false;
|
||||
// setState(State.PREPARING);
|
||||
// clearAllProxies();
|
||||
// actual_proxy = null;
|
||||
//
|
||||
// if (hostRedirected) {
|
||||
// removeFromHosts();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// List<String> willremove = new ArrayList<>();
|
||||
// int c = 0;
|
||||
// for (String host : allPotentialHosts) {
|
||||
// String[] split = host.split(":");
|
||||
// String input_dom = split[0];
|
||||
// if (!hostIsIpAddress(input_dom)) {
|
||||
// int port = Integer.parseInt(split[1]);
|
||||
// String actual_dom;
|
||||
//
|
||||
// InetAddress address = null;
|
||||
// try {
|
||||
// address = InetAddress.getByName(input_dom);
|
||||
// actual_dom = address.getHostAddress();
|
||||
// }
|
||||
// catch (UnknownHostException e) {
|
||||
// willremove.add(host);
|
||||
// continue;
|
||||
// }
|
||||
//
|
||||
// int intercept_port = port;
|
||||
// String intercept_host = "127.0." + (c / 254) + "." + (1 + c % 254);
|
||||
// potentialProxies.add(new Proxy(input_dom, actual_dom, port, intercept_port, intercept_host));
|
||||
// c++;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// List<Object> additionalCachedHotels = Cacher.getList(HOTELS_CACHE_KEY);
|
||||
// if (additionalCachedHotels != null) {
|
||||
// for (String host : willremove) {
|
||||
// additionalCachedHotels.remove(host);
|
||||
// }
|
||||
// Cacher.put(HOTELS_CACHE_KEY, additionalCachedHotels);
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// setState(State.PREPARED);
|
||||
// }
|
||||
//
|
||||
// private void startForRawIp() {
|
||||
//
|
||||
// new Thread(() -> {
|
||||
// try {
|
||||
//
|
||||
// Proxy proxy = potentialProxies.get(0);
|
||||
// IpMapper ipMapper = IpMapperFactory.get();
|
||||
//// ipMapper.deleteMapping(proxy.actual_domain); // just making sure -> actually, dont
|
||||
//
|
||||
// Queue<Socket> preConnectedServerConnections = new LinkedList<>();
|
||||
// for (int i = 0; i < 3; i++) {
|
||||
// preConnectedServerConnections.add(new Socket(proxy.actual_domain, proxy.actual_port));
|
||||
// Thread.sleep(50);
|
||||
// }
|
||||
//
|
||||
// ipMapper.enable();
|
||||
// ipMapper.addMapping(proxy.actual_domain);
|
||||
//
|
||||
// if (DEBUG) System.out.println("Added mapping for raw IP");
|
||||
//
|
||||
// ServerSocket proxy_server = new ServerSocket(proxy.getIntercept_port(), 10, InetAddress.getByName(proxy.getIntercept_host()));
|
||||
// proxy.initProxy(proxy_server);
|
||||
// if (DEBUG) System.out.println("");
|
||||
//
|
||||
//
|
||||
// Thread.sleep(30);
|
||||
// setState(State.WAITING_FOR_CLIENT);
|
||||
//
|
||||
// while ((state == State.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
||||
// try {
|
||||
// if (DEBUG) System.out.println("try accept proxy");
|
||||
// Socket client = proxy_server.accept();
|
||||
// client.setTcpNoDelay(true);
|
||||
// actual_proxy = proxy;
|
||||
// if (DEBUG) System.out.println("accepted a proxy");
|
||||
//
|
||||
// new Thread(() -> {
|
||||
// try {
|
||||
// if (preConnectedServerConnections.isEmpty()) {
|
||||
// if (DEBUG) System.out.println("pre-made server connections ran out of stock");
|
||||
// }
|
||||
// else {
|
||||
//// System.out.println("hi");
|
||||
//// SocketAddress proxyAddr = new InetSocketAddress("80.248.225.58", 31431);
|
||||
//// System.out.println("hi2");
|
||||
//// java.net.Proxy pr = new java.net.Proxy(java.net.Proxy.Type.SOCKS, proxyAddr);
|
||||
//// System.out.println("hi3");
|
||||
//// Socket server = new Socket(pr);
|
||||
//// System.out.println("hi4");
|
||||
//// server.connect(new InetSocketAddress(proxy.actual_domain, proxy.actual_port));
|
||||
//// System.out.println("hi5");
|
||||
// startProxyThread(client, preConnectedServerConnections.poll(), actual_proxy);
|
||||
//// startProxyThread(client, server, actual_proxy);
|
||||
// }
|
||||
// } catch (InterruptedException | IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }).start();
|
||||
//
|
||||
// } catch (IOException e1) {
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//// if (proxy_server.isClosed()) {
|
||||
//// if (rawIpMode) {
|
||||
//// IpMapperFactory.get().deleteMapping(proxy.actual_domain);
|
||||
//// }
|
||||
//// }
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }).start();
|
||||
// }
|
||||
//
|
||||
// public void start() throws IOException {
|
||||
// if (state == State.PREPARING && rawIpMode) {
|
||||
// startForRawIp();
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (state == State.PREPARED && !rawIpMode) {
|
||||
//
|
||||
// setState(State.WAITING_FOR_CLIENT);
|
||||
//
|
||||
// if (!hostRedirected) {
|
||||
// addToHosts();
|
||||
// }
|
||||
//
|
||||
// for (int c = 0; c < potentialProxies.size(); c++) {
|
||||
// Proxy potentialProxy = potentialProxies.get(c);
|
||||
//
|
||||
// ServerSocket proxy_server = new ServerSocket(potentialProxy.getIntercept_port(), 10, InetAddress.getByName(potentialProxy.getIntercept_host()));
|
||||
// potentialProxy.initProxy(proxy_server);
|
||||
//
|
||||
// new Thread(() -> {
|
||||
// try {
|
||||
// Thread.sleep(30);
|
||||
// while ((state == State.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
||||
// try {
|
||||
// Socket client = proxy_server.accept();
|
||||
// client.setTcpNoDelay(true);
|
||||
// actual_proxy = potentialProxy;
|
||||
// closeAllProxies(actual_proxy);
|
||||
// if (DEBUG) System.out.println("accepted a proxy");
|
||||
//
|
||||
// new Thread(() -> {
|
||||
// try {
|
||||
// Socket server = new Socket(actual_proxy.actual_domain, actual_proxy.actual_port);
|
||||
// startProxyThread(client, server, actual_proxy);
|
||||
// } catch (InterruptedException | IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }).start();
|
||||
//
|
||||
//
|
||||
// } catch (IOException e1) {
|
||||
// // TODO Auto-generated catch block
|
||||
//// e1.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }).start();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// if (DEBUG) System.out.println("done waiting for clients with: " + this.state );
|
||||
// }
|
||||
// }
|
||||
// private void startProxyThread(Socket client, Socket server, Proxy proxy) throws InterruptedException, UnknownHostException, IOException {
|
||||
// final boolean[] datastream = new boolean[1];
|
||||
// server.setTcpNoDelay(true);
|
||||
//
|
||||
// OutputStream client_out = client.getOutputStream();
|
||||
// InputStream client_in = client.getInputStream();
|
||||
// OutputStream habbo_server_out = server.getOutputStream();
|
||||
// InputStream habbo_server_in = server.getInputStream();
|
||||
//
|
||||
// if (DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort());
|
||||
//
|
||||
// final boolean[] aborted = new boolean[1];
|
||||
// Rc4Obtainer rc4Obtainer = new Rc4Obtainer(this);
|
||||
//
|
||||
// OutgoingPacketHandler outgoingHandler = new OutgoingPacketHandler(habbo_server_out, trafficObservables);
|
||||
// IncomingPacketHandler incomingHandler = new IncomingPacketHandler(client_out, trafficObservables);
|
||||
// rc4Obtainer.setPacketHandlers(outgoingHandler, incomingHandler);
|
||||
//
|
||||
// outgoingHandler.addOnDatastreamConfirmedListener(hotelVersion -> {
|
||||
// incomingHandler.setAsDataStream();
|
||||
// this.hotelVersion = hotelVersion;
|
||||
// onConnect();
|
||||
//
|
||||
// setState(State.CONNECTED);
|
||||
// proxy.verifyProxy(incomingHandler, outgoingHandler);
|
||||
// });
|
||||
//
|
||||
// // wachten op data van client
|
||||
// new Thread(() -> {
|
||||
// try {
|
||||
// while (!client.isClosed() && (state == State.WAITING_FOR_CLIENT || state == State.CONNECTED)) {
|
||||
// byte[] buffer;
|
||||
// while (client_in.available() > 0) {
|
||||
// client_in.read(buffer = new byte[client_in.available()]);
|
||||
// outgoingHandler.act(buffer);
|
||||
// }
|
||||
// Thread.sleep(1);
|
||||
//
|
||||
// }
|
||||
// }
|
||||
// catch (IOException | InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// finally {
|
||||
// if (DEBUG) System.out.println("abortclient");
|
||||
// try {
|
||||
// if (habbo_server_out != null) habbo_server_out.close();
|
||||
// if (habbo_server_in != null) habbo_server_in.close();
|
||||
// if (client_in != null) client_in.close();
|
||||
// if (client_out != null) client_out.close();
|
||||
// if (server != null && !server.isClosed()) server.close();
|
||||
// if (client != null && !client.isClosed()) client.close();
|
||||
// aborted[0] = true;
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// if (datastream[0]) {
|
||||
// setState(State.NOT_CONNECTED);
|
||||
// proxy.verifyProxy(null, null);
|
||||
// if (rawIpMode) {
|
||||
// IpMapperFactory.get().deleteMapping(proxy.actual_domain);
|
||||
// }
|
||||
// actual_proxy = null;
|
||||
// };
|
||||
// }
|
||||
// }).start();
|
||||
// // wachten op data van server
|
||||
// new Thread(() -> {
|
||||
// try {
|
||||
// while (!server.isClosed() && (state == State.CONNECTED || state == State.WAITING_FOR_CLIENT)) {
|
||||
// byte[] buffer;
|
||||
// while (habbo_server_in.available() > 0) {
|
||||
// habbo_server_in.read(buffer = new byte[habbo_server_in.available()]);
|
||||
// incomingHandler.act(buffer);
|
||||
// }
|
||||
// Thread.sleep(1);
|
||||
// }
|
||||
// } catch (IOException | InterruptedException e) {
|
||||
// e.printStackTrace();
|
||||
// } finally {
|
||||
// try {
|
||||
// if (habbo_server_out != null) habbo_server_out.close();
|
||||
// if (habbo_server_in != null) habbo_server_in.close();
|
||||
// if (client_in != null) client_in.close();
|
||||
// if (client_out != null) client_out.close();
|
||||
// if (!server.isClosed()) server.close();
|
||||
// if (!client.isClosed()) client.close();
|
||||
// aborted[0] = true;
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }).start();
|
||||
//
|
||||
// while(!aborted[0]) {
|
||||
// Thread.sleep(50);
|
||||
// }
|
||||
//
|
||||
// try {
|
||||
// if (!server.isClosed()) server.close();
|
||||
// if (!client.isClosed()) client.close();
|
||||
// if (DEBUG) System.out.println("STOP");
|
||||
// }
|
||||
// catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
//
|
||||
// private void onConnect() {
|
||||
// if (hostRedirected) {
|
||||
// removeFromHosts();
|
||||
// }
|
||||
//
|
||||
// clearAllProxies();
|
||||
//
|
||||
// }
|
||||
// public void abort() {
|
||||
// setState(State.ABORTING);
|
||||
// if (hostRedirected) {
|
||||
// removeFromHosts();
|
||||
// }
|
||||
//
|
||||
// if (rawIpMode && potentialProxies.size() == 1) {
|
||||
// IpMapperFactory.get().deleteMapping(potentialProxies.get(0).actual_domain);
|
||||
// }
|
||||
// if (rawIpMode && actual_proxy != null) {
|
||||
// IpMapperFactory.get().deleteMapping(actual_proxy.actual_domain);
|
||||
// }
|
||||
//
|
||||
// actual_proxy = null;
|
||||
//
|
||||
// clearAllProxies();
|
||||
// setState(State.NOT_CONNECTED);
|
||||
// }
|
||||
//
|
||||
// private void clearAllProxies() {
|
||||
// closeAllProxies(null);
|
||||
// potentialProxies = new ArrayList<>();
|
||||
// }
|
||||
// private void closeAllProxies(Proxy except) {
|
||||
// for (Proxy proxy : potentialProxies) {
|
||||
// if (except != proxy) {
|
||||
// if (proxy.getProxy_server() != null && !proxy.getProxy_server().isClosed()) {
|
||||
// try {
|
||||
// proxy.getProxy_server().close();
|
||||
// } catch (IOException e) {
|
||||
// // TODO Auto-generated catch block
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void addToHosts() {
|
||||
// List<String> linesTemp = new ArrayList<>();
|
||||
// for (Proxy proxy : potentialProxies) {
|
||||
// linesTemp.add(proxy.getIntercept_host() + " " + proxy.getInput_domain());
|
||||
// }
|
||||
//
|
||||
// String[] lines = new String[linesTemp.size()];
|
||||
// for (int i = 0; i < linesTemp.size(); i++) {
|
||||
// lines[i] = linesTemp.get(i);
|
||||
// }
|
||||
// hostsReplacer.addRedirect(lines);
|
||||
// hostRedirected = true;
|
||||
// }
|
||||
// private void removeFromHosts(){
|
||||
// List<String> linesTemp = new ArrayList<>();
|
||||
// for (Proxy proxy : potentialProxies) {
|
||||
// linesTemp.add(proxy.getIntercept_host() + " " + proxy.getInput_domain());
|
||||
// }
|
||||
//
|
||||
// String[] lines = new String[linesTemp.size()];
|
||||
// for (int i = 0; i < linesTemp.size(); i++) {
|
||||
// lines[i] = linesTemp.get(i);
|
||||
// }
|
||||
// hostsReplacer.removeRedirect(lines);
|
||||
// hostRedirected = false;
|
||||
// }
|
||||
//
|
||||
// private void setState(State state) {
|
||||
// if (state == State.CONNECTED) {
|
||||
// sendToClientAsyncQueue.clear();
|
||||
// sendToServerAsyncQueue.clear();
|
||||
// }
|
||||
// if (state != this.state) {
|
||||
// if (state != State.CONNECTED) {
|
||||
// hotelVersion = "";
|
||||
// }
|
||||
//
|
||||
// State buffer = this.state;
|
||||
// this.state = state;
|
||||
// stateObservable.fireEvent(l -> l.stateChanged(buffer, state));
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// public Observable<StateChangeListener> getStateObservable() {
|
||||
// return stateObservable;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * 3 orders:
|
||||
// * 0 = before modification ¹
|
||||
// * 1 = modification
|
||||
// * 2 = after modification ¹
|
||||
// *
|
||||
// * ¹don't edit the packet (block, replace)
|
||||
// */
|
||||
// public void addTrafficListener(int order, TrafficListener listener) {
|
||||
// ((Observable<TrafficListener>) trafficObservables[order]).addListener(listener);
|
||||
// }
|
||||
// public void removeTrafficListener(TrafficListener listener) {
|
||||
// ((Observable<TrafficListener>) trafficObservables[0]).removeListener(listener);
|
||||
// ((Observable<TrafficListener>) trafficObservables[1]).removeListener(listener);
|
||||
// ((Observable<TrafficListener>) trafficObservables[2]).removeListener(listener);
|
||||
// }
|
||||
//
|
||||
// public int getServerPort() {
|
||||
// if (actual_proxy == null) return -1;
|
||||
// return actual_proxy.getIntercept_port();
|
||||
// }
|
||||
// public String getServerHost() {
|
||||
// if (actual_proxy == null) return "<auto-detect>";
|
||||
// return actual_proxy.getActual_domain();
|
||||
// }
|
||||
// public String getDomain() {
|
||||
// if (actual_proxy == null) return "<auto-detect>";
|
||||
// return actual_proxy.getInput_domain();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private boolean sendToClient(HPacket message) {
|
||||
// if (actual_proxy == null || actual_proxy.getInHandler() == null) return false;
|
||||
// actual_proxy.getInHandler().sendToStream(message.toBytes());
|
||||
// return true;
|
||||
// }
|
||||
// private boolean sendToServer(HPacket message) {
|
||||
// if (actual_proxy == null || actual_proxy.getOutHandler() == null) return false;
|
||||
// actual_proxy.getOutHandler().sendToStream(message.toBytes());
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// public void sendToClientAsync(HPacket message) {
|
||||
// synchronized (sendToClientAsyncQueue) {
|
||||
// sendToClientAsyncQueue.add(message);
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// public void sendToServerAsync(HPacket message) {
|
||||
// synchronized (sendToServerAsyncQueue) {
|
||||
// sendToServerAsyncQueue.add(message);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public String getClientHost() {
|
||||
// if (actual_proxy == null) {
|
||||
// return "";
|
||||
// }
|
||||
// return actual_proxy.getIntercept_host();
|
||||
// }
|
||||
//
|
||||
// public int getClientPort() {
|
||||
// if (actual_proxy == null) {
|
||||
// return -1;
|
||||
// }
|
||||
// return actual_proxy.getIntercept_port();
|
||||
// }
|
||||
//
|
||||
// public String getHotelVersion() {
|
||||
// return hotelVersion;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public boolean isRawIpMode() {
|
||||
// return rawIpMode;
|
||||
// }
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package gearth.protocol;
|
||||
|
||||
import gearth.protocol.connection.HState;
|
||||
|
||||
public interface StateChangeListener {
|
||||
|
||||
void stateChanged(HConnection.State oldState, HConnection.State newState);
|
||||
void stateChanged(HState oldState, HState newState);
|
||||
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
package gearth.protocol.connection;
|
||||
|
||||
import gearth.protocol.HPacket;
|
||||
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class AsyncPacketSender {
|
||||
|
||||
private final HProxy proxy;
|
||||
private final Queue<HPacket> sendToClientAsyncQueue = new LinkedList<>();
|
||||
private final Queue<HPacket> sendToServerAsyncQueue = new LinkedList<>();
|
||||
|
||||
AsyncPacketSender(HProxy proxy) {
|
||||
this.proxy = proxy;
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
HPacket packet;
|
||||
synchronized (sendToClientAsyncQueue) {
|
||||
while ((packet = sendToClientAsyncQueue.poll()) != null) {
|
||||
sendToClient(packet);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
HPacket packet;
|
||||
synchronized (sendToServerAsyncQueue) {
|
||||
while ((packet = sendToServerAsyncQueue.poll()) != null) {
|
||||
sendToServer(packet);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
private void sendToClient(HPacket message) {
|
||||
proxy.getInHandler().sendToStream(message.toBytes());
|
||||
}
|
||||
private void sendToServer(HPacket message) {
|
||||
proxy.getOutHandler().sendToStream(message.toBytes());
|
||||
}
|
||||
|
||||
public void sendToClientAsync(HPacket message) {
|
||||
synchronized (sendToClientAsyncQueue) {
|
||||
sendToClientAsyncQueue.add(message);
|
||||
}
|
||||
|
||||
}
|
||||
public void sendToServerAsync(HPacket message) {
|
||||
synchronized (sendToServerAsyncQueue) {
|
||||
sendToServerAsyncQueue.add(message);
|
||||
}
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
synchronized (sendToClientAsyncQueue) {
|
||||
sendToClientAsyncQueue.clear();
|
||||
}
|
||||
synchronized (sendToServerAsyncQueue) {
|
||||
sendToServerAsyncQueue.clear();
|
||||
}
|
||||
}
|
||||
}
|
82
G-Earth/src/main/java/gearth/protocol/connection/HProxy.java
Normal file
82
G-Earth/src/main/java/gearth/protocol/connection/HProxy.java
Normal file
@ -0,0 +1,82 @@
|
||||
package gearth.protocol.connection;
|
||||
|
||||
import gearth.protocol.packethandler.IncomingPacketHandler;
|
||||
import gearth.protocol.packethandler.OutgoingPacketHandler;
|
||||
|
||||
import java.net.ServerSocket;
|
||||
|
||||
public class HProxy {
|
||||
private volatile String input_domain; //string representation of the domain to intercept
|
||||
private volatile String actual_domain; //dns resolved domain (ignoring hosts file)
|
||||
private volatile int actual_port; //port of the server
|
||||
|
||||
private volatile int intercept_port; //port used to intercept connection (with the current implementation, must equal actual_port)
|
||||
private volatile String intercept_host; //local ip used to intercept host, example 127.0.0.1
|
||||
|
||||
private volatile ServerSocket proxy_server = null; //listener for the client
|
||||
|
||||
private volatile IncomingPacketHandler inHandler = null; //connection with client (only initialized when verified habbo connection)
|
||||
private volatile OutgoingPacketHandler outHandler = null; //connection with server (only initialized when verified habbo connection)
|
||||
|
||||
private volatile String hotelVersion = "";
|
||||
private volatile AsyncPacketSender asyncPacketSender = null;
|
||||
|
||||
public HProxy(String input_domain, String actual_domain, int actual_port, int intercept_port, String intercept_host) {
|
||||
this.input_domain = input_domain;
|
||||
this.actual_domain = actual_domain;
|
||||
this.actual_port = actual_port;
|
||||
this.intercept_host = intercept_host;
|
||||
this.intercept_port = intercept_port;
|
||||
}
|
||||
|
||||
public void initProxy(ServerSocket socket) {
|
||||
this.proxy_server = socket;
|
||||
}
|
||||
|
||||
public void verifyProxy(IncomingPacketHandler incomingHandler, OutgoingPacketHandler outgoingHandler, String hotelVersion) {
|
||||
this.inHandler = incomingHandler;
|
||||
this.outHandler = outgoingHandler;
|
||||
this.hotelVersion = hotelVersion;
|
||||
this.asyncPacketSender = new AsyncPacketSender(this);
|
||||
}
|
||||
|
||||
public int getActual_port() {
|
||||
return actual_port;
|
||||
}
|
||||
|
||||
public int getIntercept_port() {
|
||||
return intercept_port;
|
||||
}
|
||||
|
||||
public ServerSocket getProxy_server() {
|
||||
return proxy_server;
|
||||
}
|
||||
|
||||
public String getActual_domain() {
|
||||
return actual_domain;
|
||||
}
|
||||
|
||||
public String getInput_domain() {
|
||||
return input_domain;
|
||||
}
|
||||
|
||||
public String getIntercept_host() {
|
||||
return intercept_host;
|
||||
}
|
||||
|
||||
public IncomingPacketHandler getInHandler() {
|
||||
return inHandler;
|
||||
}
|
||||
|
||||
public OutgoingPacketHandler getOutHandler() {
|
||||
return outHandler;
|
||||
}
|
||||
|
||||
public String getHotelVersion() {
|
||||
return hotelVersion;
|
||||
}
|
||||
|
||||
public AsyncPacketSender getAsyncPacketSender() {
|
||||
return asyncPacketSender;
|
||||
}
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package gearth.protocol.connection;
|
||||
|
||||
public interface HProxySetter {
|
||||
void setProxy(HProxy proxy);
|
||||
}
|
10
G-Earth/src/main/java/gearth/protocol/connection/HState.java
Normal file
10
G-Earth/src/main/java/gearth/protocol/connection/HState.java
Normal file
@ -0,0 +1,10 @@
|
||||
package gearth.protocol.connection;
|
||||
|
||||
public enum HState {
|
||||
NOT_CONNECTED,
|
||||
PREPARING, // DOMAIN AND PORT BEEN PASSED
|
||||
PREPARED, // FOUND IP ADDRESS OF DOMAIN
|
||||
WAITING_FOR_CLIENT, // WAITING FOR CORRECT TCP CONNECTION TO BE SET UP
|
||||
CONNECTED, // CONNECTED
|
||||
ABORTING
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package gearth.protocol.connection;
|
||||
|
||||
public interface HStateSetter {
|
||||
void setState(HState state);
|
||||
}
|
@ -0,0 +1,203 @@
|
||||
package gearth.protocol.connection.proxy;
|
||||
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.connection.HProxy;
|
||||
import gearth.protocol.connection.HProxySetter;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.protocol.connection.HStateSetter;
|
||||
import gearth.protocol.hostreplacer.hostsfile.HostReplacer;
|
||||
import gearth.protocol.hostreplacer.hostsfile.HostReplacerFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class NormalProxyProvider extends ProxyProvider {
|
||||
|
||||
private List<String> potentialHosts;
|
||||
|
||||
|
||||
private static final HostReplacer hostsReplacer = HostReplacerFactory.get();
|
||||
private volatile boolean hostRedirected = false;
|
||||
|
||||
private volatile List<HProxy> potentialProxies = new ArrayList<>();
|
||||
private volatile HProxy proxy = null;
|
||||
|
||||
|
||||
|
||||
public NormalProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, List<String> potentialHosts) {
|
||||
super(proxySetter, stateSetter, hConnection);
|
||||
this.potentialHosts = potentialHosts;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void start() throws IOException {
|
||||
if (hConnection.getState() != HState.NOT_CONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
prepare();
|
||||
addToHosts();
|
||||
launchProxy();
|
||||
|
||||
}
|
||||
|
||||
private void prepare() {
|
||||
stateSetter.setState(HState.PREPARING);
|
||||
|
||||
List<String> willremove = new ArrayList<>();
|
||||
int c = 0;
|
||||
for (String host : potentialHosts) {
|
||||
String[] split = host.split(":");
|
||||
String input_dom = split[0];
|
||||
if (!ProxyProviderFactory.hostIsIpAddress(input_dom)) {
|
||||
int port = Integer.parseInt(split[1]);
|
||||
String actual_dom;
|
||||
|
||||
InetAddress address;
|
||||
try {
|
||||
address = InetAddress.getByName(input_dom);
|
||||
actual_dom = address.getHostAddress();
|
||||
}
|
||||
catch (UnknownHostException e) {
|
||||
willremove.add(host);
|
||||
continue;
|
||||
}
|
||||
|
||||
int intercept_port = port;
|
||||
String intercept_host = "127.0." + (c / 254) + "." + (1 + c % 254);
|
||||
potentialProxies.add(new HProxy(input_dom, actual_dom, port, intercept_port, intercept_host));
|
||||
c++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Object> additionalCachedHotels = Cacher.getList(ProxyProviderFactory.HOTELS_CACHE_KEY);
|
||||
if (additionalCachedHotels != null) {
|
||||
for (String host : willremove) {
|
||||
additionalCachedHotels.remove(host);
|
||||
}
|
||||
Cacher.put(ProxyProviderFactory.HOTELS_CACHE_KEY, additionalCachedHotels);
|
||||
}
|
||||
|
||||
stateSetter.setState(HState.PREPARED);
|
||||
}
|
||||
|
||||
private void launchProxy() throws IOException {
|
||||
stateSetter.setState(HState.WAITING_FOR_CLIENT);
|
||||
|
||||
for (int c = 0; c < potentialProxies.size(); c++) {
|
||||
HProxy potentialProxy = potentialProxies.get(c);
|
||||
|
||||
ServerSocket proxy_server = new ServerSocket(potentialProxy.getIntercept_port(), 10, InetAddress.getByName(potentialProxy.getIntercept_host()));
|
||||
potentialProxy.initProxy(proxy_server);
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Thread.sleep(30);
|
||||
while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
||||
try {
|
||||
Socket client = proxy_server.accept();
|
||||
client.setTcpNoDelay(true);
|
||||
proxy = potentialProxy;
|
||||
closeAllProxies(proxy);
|
||||
if (HConnection.DEBUG) System.out.println("accepted a proxy");
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Socket server = new Socket(proxy.getActual_domain(), proxy.getActual_port());
|
||||
startProxyThread(client, server, proxy);
|
||||
} catch (InterruptedException | IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
} catch (IOException e1) {
|
||||
// TODO Auto-generated catch block
|
||||
// e1.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
|
||||
if (HConnection.DEBUG) System.out.println("done waiting for clients with: " + hConnection.getState() );
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
stateSetter.setState(HState.ABORTING);
|
||||
if (hostRedirected) {
|
||||
removeFromHosts();
|
||||
}
|
||||
|
||||
clearAllProxies();
|
||||
stateSetter.setState(HState.NOT_CONNECTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConnect() {
|
||||
super.onConnect();
|
||||
|
||||
if (hostRedirected) {
|
||||
removeFromHosts();
|
||||
}
|
||||
clearAllProxies();
|
||||
}
|
||||
|
||||
private void addToHosts() {
|
||||
List<String> linesTemp = new ArrayList<>();
|
||||
for (HProxy proxy : potentialProxies) {
|
||||
linesTemp.add(proxy.getIntercept_host() + " " + proxy.getInput_domain());
|
||||
}
|
||||
|
||||
String[] lines = new String[linesTemp.size()];
|
||||
for (int i = 0; i < linesTemp.size(); i++) {
|
||||
lines[i] = linesTemp.get(i);
|
||||
}
|
||||
hostsReplacer.addRedirect(lines);
|
||||
hostRedirected = true;
|
||||
}
|
||||
private void removeFromHosts(){
|
||||
List<String> linesTemp = new ArrayList<>();
|
||||
for (HProxy proxy : potentialProxies) {
|
||||
linesTemp.add(proxy.getIntercept_host() + " " + proxy.getInput_domain());
|
||||
}
|
||||
|
||||
String[] lines = new String[linesTemp.size()];
|
||||
for (int i = 0; i < linesTemp.size(); i++) {
|
||||
lines[i] = linesTemp.get(i);
|
||||
}
|
||||
hostsReplacer.removeRedirect(lines);
|
||||
hostRedirected = false;
|
||||
}
|
||||
|
||||
private void clearAllProxies() {
|
||||
closeAllProxies(null);
|
||||
potentialProxies = new ArrayList<>();
|
||||
}
|
||||
private void closeAllProxies(HProxy except) {
|
||||
for (HProxy proxy : potentialProxies) {
|
||||
if (except != proxy) {
|
||||
if (proxy.getProxy_server() != null && !proxy.getProxy_server().isClosed()) {
|
||||
try {
|
||||
proxy.getProxy_server().close();
|
||||
} catch (IOException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
potentialProxies = Collections.singletonList(except);
|
||||
}
|
||||
}
|
@ -0,0 +1,145 @@
|
||||
package gearth.protocol.connection.proxy;
|
||||
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.connection.HProxy;
|
||||
import gearth.protocol.connection.HProxySetter;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.protocol.connection.HStateSetter;
|
||||
import gearth.protocol.memory.Rc4Obtainer;
|
||||
import gearth.protocol.packethandler.IncomingPacketHandler;
|
||||
import gearth.protocol.packethandler.OutgoingPacketHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.Socket;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
public abstract class ProxyProvider {
|
||||
|
||||
protected final HProxySetter proxySetter;
|
||||
protected final HStateSetter stateSetter;
|
||||
protected final HConnection hConnection;
|
||||
|
||||
public ProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection){
|
||||
this.proxySetter = proxySetter;
|
||||
this.stateSetter = stateSetter;
|
||||
this.hConnection = hConnection;
|
||||
}
|
||||
|
||||
protected void startProxyThread(Socket client, Socket server, HProxy proxy) throws InterruptedException, UnknownHostException, IOException {
|
||||
final boolean[] datastream = new boolean[1];
|
||||
server.setTcpNoDelay(true);
|
||||
|
||||
OutputStream client_out = client.getOutputStream();
|
||||
InputStream client_in = client.getInputStream();
|
||||
OutputStream habbo_server_out = server.getOutputStream();
|
||||
InputStream habbo_server_in = server.getInputStream();
|
||||
|
||||
if (HConnection.DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort());
|
||||
|
||||
final boolean[] aborted = new boolean[1];
|
||||
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection);
|
||||
|
||||
OutgoingPacketHandler outgoingHandler = new OutgoingPacketHandler(habbo_server_out, hConnection.getTrafficObservables());
|
||||
IncomingPacketHandler incomingHandler = new IncomingPacketHandler(client_out, hConnection.getTrafficObservables());
|
||||
rc4Obtainer.setPacketHandlers(outgoingHandler, incomingHandler);
|
||||
|
||||
outgoingHandler.addOnDatastreamConfirmedListener(hotelVersion -> {
|
||||
incomingHandler.setAsDataStream();
|
||||
proxy.verifyProxy(incomingHandler, outgoingHandler, hotelVersion);
|
||||
proxySetter.setProxy(proxy);
|
||||
datastream[0] = true;
|
||||
onConnect();
|
||||
});
|
||||
|
||||
// wachten op data van client
|
||||
new Thread(() -> {
|
||||
try {
|
||||
while (!client.isClosed() && (hConnection.getState() == HState.WAITING_FOR_CLIENT || hConnection.getState() == HState.CONNECTED)) {
|
||||
byte[] buffer;
|
||||
while (client_in.available() > 0) {
|
||||
client_in.read(buffer = new byte[client_in.available()]);
|
||||
outgoingHandler.act(buffer);
|
||||
}
|
||||
Thread.sleep(1);
|
||||
|
||||
}
|
||||
}
|
||||
catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally {
|
||||
if (HConnection.DEBUG) System.out.println("abortclient");
|
||||
try {
|
||||
if (habbo_server_out != null) habbo_server_out.close();
|
||||
if (habbo_server_in != null) habbo_server_in.close();
|
||||
if (client_in != null) client_in.close();
|
||||
if (client_out != null) client_out.close();
|
||||
if (server != null && !server.isClosed()) server.close();
|
||||
if (client != null && !client.isClosed()) client.close();
|
||||
aborted[0] = true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (datastream[0]) {
|
||||
onConnectEnd();
|
||||
};
|
||||
}
|
||||
}).start();
|
||||
// wachten op data van server
|
||||
new Thread(() -> {
|
||||
try {
|
||||
while (!server.isClosed() && (hConnection.getState() == HState.WAITING_FOR_CLIENT || hConnection.getState() == HState.CONNECTED)) {
|
||||
byte[] buffer;
|
||||
while (habbo_server_in.available() > 0) {
|
||||
habbo_server_in.read(buffer = new byte[habbo_server_in.available()]);
|
||||
incomingHandler.act(buffer);
|
||||
}
|
||||
Thread.sleep(1);
|
||||
}
|
||||
} catch (IOException | InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
if (habbo_server_out != null) habbo_server_out.close();
|
||||
if (habbo_server_in != null) habbo_server_in.close();
|
||||
if (client_in != null) client_in.close();
|
||||
if (client_out != null) client_out.close();
|
||||
if (!server.isClosed()) server.close();
|
||||
if (!client.isClosed()) client.close();
|
||||
aborted[0] = true;
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
|
||||
while(!aborted[0]) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
try {
|
||||
if (!server.isClosed()) server.close();
|
||||
if (!client.isClosed()) client.close();
|
||||
if (HConnection.DEBUG) System.out.println("STOP");
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract void start() throws IOException;
|
||||
public abstract void abort();
|
||||
|
||||
protected void onConnect() {
|
||||
stateSetter.setState(HState.CONNECTED);
|
||||
}
|
||||
protected void onConnectEnd() {
|
||||
proxySetter.setProxy(null);
|
||||
stateSetter.setState(HState.NOT_CONNECTED);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
package gearth.protocol.connection.proxy;
|
||||
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.misc.OSValidator;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.connection.HProxySetter;
|
||||
import gearth.protocol.connection.HStateSetter;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ProxyProviderFactory {
|
||||
|
||||
public static final String HOTELS_CACHE_KEY = "hotelsConnectionInfo";
|
||||
|
||||
public static List<String> autoDetectHosts;
|
||||
static {
|
||||
autoDetectHosts = new ArrayList<>();
|
||||
autoDetectHosts.add("game-br.habbo.com:30000");
|
||||
autoDetectHosts.add("game-de.habbo.com:30000");
|
||||
autoDetectHosts.add("game-es.habbo.com:30000");
|
||||
autoDetectHosts.add("game-fi.habbo.com:30000");
|
||||
autoDetectHosts.add("game-fr.habbo.com:30000");
|
||||
autoDetectHosts.add("game-it.habbo.com:30000");
|
||||
autoDetectHosts.add("game-nl.habbo.com:30000");
|
||||
autoDetectHosts.add("game-tr.habbo.com:30000");
|
||||
autoDetectHosts.add("game-us.habbo.com:38101");
|
||||
|
||||
List<Object> additionalCachedHotels = Cacher.getList(HOTELS_CACHE_KEY);
|
||||
if (additionalCachedHotels != null) {
|
||||
for (Object additionalHotel : additionalCachedHotels) {
|
||||
if (!autoDetectHosts.contains(additionalHotel)) {
|
||||
autoDetectHosts.add((String)additionalHotel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (OSValidator.isMac()) {
|
||||
for (int i = 2; i <= autoDetectHosts.size() + 5; i++) {
|
||||
ProcessBuilder allowLocalHost = new ProcessBuilder("ifconfig", "lo0", "alias", ("127.0.0." + i), "up");
|
||||
try {
|
||||
allowLocalHost.start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final HProxySetter proxySetter;
|
||||
private final HStateSetter stateSetter;
|
||||
private final HConnection hConnection;
|
||||
|
||||
public ProxyProviderFactory(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection){
|
||||
this.proxySetter = proxySetter;
|
||||
this.stateSetter = stateSetter;
|
||||
this.hConnection = hConnection;
|
||||
}
|
||||
|
||||
// checks if host is a raw IP instead of a domain
|
||||
// TODO support ipv6 (not only here, also in IPmapper)
|
||||
static boolean hostIsIpAddress(String host){
|
||||
for (char c : host.toCharArray()) {
|
||||
if (c != '.' && (c < '0' || c > '9')) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public ProxyProvider provide() {
|
||||
return provide(autoDetectHosts);
|
||||
}
|
||||
|
||||
public ProxyProvider provide(String domain, int port) {
|
||||
List<Object> additionalCachedHotels = Cacher.getList(HOTELS_CACHE_KEY);
|
||||
if (additionalCachedHotels == null) {
|
||||
additionalCachedHotels = new ArrayList<>();
|
||||
}
|
||||
if (!additionalCachedHotels.contains(domain +":"+port)) {
|
||||
additionalCachedHotels.add(domain+":"+port);
|
||||
Cacher.put(HOTELS_CACHE_KEY, additionalCachedHotels);
|
||||
}
|
||||
|
||||
if (hostIsIpAddress(domain)) {
|
||||
return new RawIpProxyProvider(proxySetter, stateSetter, hConnection, domain, port);
|
||||
}
|
||||
else {
|
||||
List<String> potentialHost = new ArrayList<>();
|
||||
potentialHost.add(domain+":"+port);
|
||||
return provide(potentialHost);
|
||||
}
|
||||
}
|
||||
|
||||
private ProxyProvider provide(List<String> potentialHosts) {
|
||||
return new NormalProxyProvider(proxySetter, stateSetter, hConnection, potentialHosts);
|
||||
}
|
||||
}
|
@ -0,0 +1,131 @@
|
||||
package gearth.protocol.connection.proxy;
|
||||
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.connection.HProxy;
|
||||
import gearth.protocol.connection.HProxySetter;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.protocol.connection.HStateSetter;
|
||||
import gearth.protocol.hostreplacer.ipmapping.IpMapper;
|
||||
import gearth.protocol.hostreplacer.ipmapping.IpMapperFactory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.Socket;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class RawIpProxyProvider extends ProxyProvider {
|
||||
|
||||
private volatile String input_host;
|
||||
private volatile int input_port;
|
||||
|
||||
private IpMapper ipMapper = IpMapperFactory.get();
|
||||
private boolean hasMapped = false;
|
||||
|
||||
private HProxy proxy = null;
|
||||
|
||||
public RawIpProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, String input_host, int input_port) {
|
||||
super(proxySetter, stateSetter, hConnection);
|
||||
this.input_host = input_host;
|
||||
this.input_port = input_port;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (hConnection.getState() != HState.NOT_CONNECTED) {
|
||||
return;
|
||||
}
|
||||
|
||||
launchMITM();
|
||||
}
|
||||
|
||||
private void launchMITM() {
|
||||
new Thread(() -> {
|
||||
try {
|
||||
stateSetter.setState(HState.PREPARING);
|
||||
proxy = new HProxy(input_host, input_host, input_port, input_port, "0.0.0.0");
|
||||
|
||||
Queue<Socket> preConnectedServerConnections = new LinkedList<>();
|
||||
for (int i = 0; i < 3; i++) {
|
||||
preConnectedServerConnections.add(new Socket(proxy.getActual_domain(), proxy.getActual_port()));
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
ipMapper.enable();
|
||||
ipMapper.addMapping(proxy.getActual_domain());
|
||||
hasMapped = true;
|
||||
|
||||
if (HConnection.DEBUG) System.out.println("Added mapping for raw IP");
|
||||
|
||||
ServerSocket proxy_server = new ServerSocket(proxy.getIntercept_port(), 10, InetAddress.getByName(proxy.getIntercept_host()));
|
||||
proxy.initProxy(proxy_server);
|
||||
|
||||
stateSetter.setState(HState.WAITING_FOR_CLIENT);
|
||||
|
||||
|
||||
|
||||
while ((hConnection.getState() == HState.WAITING_FOR_CLIENT) && !proxy_server.isClosed()) {
|
||||
try {
|
||||
if (HConnection.DEBUG) System.out.println("try accept proxy");
|
||||
Socket client = proxy_server.accept();
|
||||
client.setTcpNoDelay(true);
|
||||
|
||||
if (HConnection.DEBUG) System.out.println("accepted a proxy");
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
if (preConnectedServerConnections.isEmpty()) {
|
||||
if (HConnection.DEBUG) System.out.println("pre-made server connections ran out of stock");
|
||||
}
|
||||
else {
|
||||
startProxyThread(client, preConnectedServerConnections.poll(), proxy);
|
||||
}
|
||||
} catch (InterruptedException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
|
||||
} catch (IOException e1) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort() {
|
||||
stateSetter.setState(HState.ABORTING);
|
||||
if (hasMapped) {
|
||||
ipMapper.deleteMapping(proxy.getActual_domain());
|
||||
hasMapped = false;
|
||||
}
|
||||
tryCloseProxy();
|
||||
stateSetter.setState(HState.NOT_CONNECTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onConnectEnd() {
|
||||
if (hasMapped) {
|
||||
ipMapper.deleteMapping(proxy.getActual_domain());
|
||||
hasMapped = false;
|
||||
}
|
||||
tryCloseProxy();
|
||||
super.onConnectEnd();
|
||||
}
|
||||
|
||||
private void tryCloseProxy() {
|
||||
if (proxy.getProxy_server() != null && !proxy.getProxy_server().isClosed()) {
|
||||
try {
|
||||
proxy.getProxy_server().close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package gearth.protocol.misc;
|
||||
|
||||
import gearth.protocol.HConnection;
|
||||
|
||||
/**
|
||||
* Created by Jeunez on 30/01/2019.
|
||||
*/
|
||||
public interface ConnectionInfoOverrider {
|
||||
|
||||
boolean mustOverrideConnection();
|
||||
HConnection.Proxy getOverrideProxy();
|
||||
}
|
@ -6,6 +6,7 @@ import gearth.misc.listenerpattern.Observable;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.HMessage;
|
||||
import gearth.protocol.HPacket;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.services.extensionhandler.extensions.ExtensionListener;
|
||||
import gearth.services.extensionhandler.extensions.extensionproducers.ExtensionProducer;
|
||||
import gearth.services.extensionhandler.extensions.extensionproducers.ExtensionProducerFactory;
|
||||
@ -39,7 +40,7 @@ public class ExtensionHandler {
|
||||
private void initialize() {
|
||||
|
||||
hConnection.getStateObservable().addListener((oldState, newState) -> {
|
||||
if (newState == HConnection.State.CONNECTED) {
|
||||
if (newState == HState.CONNECTED) {
|
||||
HarbleAPIFetcher.fetch(hConnection.getHotelVersion());
|
||||
synchronized (gEarthExtensions) {
|
||||
for (GEarthExtension extension : gEarthExtensions) {
|
||||
@ -52,7 +53,7 @@ public class ExtensionHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (oldState == HConnection.State.CONNECTED) {
|
||||
if (oldState == HState.CONNECTED) {
|
||||
synchronized (hConnection) {
|
||||
for (GEarthExtension extension : gEarthExtensions) {
|
||||
extension.connectionEnd();
|
||||
@ -180,7 +181,7 @@ public class ExtensionHandler {
|
||||
extension.getExtensionObservable().addListener(listener);
|
||||
extension.init();
|
||||
|
||||
if (hConnection.getState() == HConnection.State.CONNECTED) {
|
||||
if (hConnection.getState() == HState.CONNECTED) {
|
||||
extension.connectionStart(
|
||||
hConnection.getDomain(),
|
||||
hConnection.getServerPort(),
|
||||
|
@ -1,6 +1,8 @@
|
||||
package gearth.ui.connection;
|
||||
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.protocol.connection.proxy.ProxyProviderFactory;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.*;
|
||||
@ -52,7 +54,7 @@ public class ConnectionController extends SubForm {
|
||||
updateInputUI();
|
||||
});
|
||||
|
||||
List<String> knownHosts = HConnection.autoDetectHosts;
|
||||
List<String> knownHosts = ProxyProviderFactory.autoDetectHosts;
|
||||
Set<String> hosts = new HashSet<>();
|
||||
Set<String> ports = new HashSet<>();
|
||||
|
||||
@ -95,7 +97,7 @@ public class ConnectionController extends SubForm {
|
||||
private void updateInputUI() {
|
||||
txtfield_hotelversion.setText(getHConnection().getHotelVersion());
|
||||
|
||||
btnConnect.setDisable(getHConnection().getState() == HConnection.State.PREPARING || getHConnection().getState() == HConnection.State.ABORTING);
|
||||
btnConnect.setDisable(getHConnection().getState() == HState.PREPARING || getHConnection().getState() == HState.ABORTING);
|
||||
if (!cbx_autodetect.isSelected() && !btnConnect.isDisable()) {
|
||||
try {
|
||||
int i = Integer.parseInt(inpPort.getEditor().getText());
|
||||
@ -106,8 +108,8 @@ public class ConnectionController extends SubForm {
|
||||
}
|
||||
}
|
||||
|
||||
inpHost.setDisable(getHConnection().getState() != HConnection.State.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpPort.setDisable(getHConnection().getState() != HConnection.State.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpHost.setDisable(getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
inpPort.setDisable(getHConnection().getState() != HState.NOT_CONNECTED || cbx_autodetect.isSelected());
|
||||
}
|
||||
|
||||
public void onParentSet(){
|
||||
@ -120,26 +122,26 @@ public class ConnectionController extends SubForm {
|
||||
|
||||
getHConnection().getStateObservable().addListener((oldState, newState) -> Platform.runLater(() -> {
|
||||
updateInputUI();
|
||||
if (newState == HConnection.State.NOT_CONNECTED) {
|
||||
if (newState == HState.NOT_CONNECTED) {
|
||||
lblState.setText("Not connected");
|
||||
btnConnect.setText("Connect");
|
||||
outHost.setText("");
|
||||
outPort.setText("");
|
||||
}
|
||||
else if (oldState == HConnection.State.NOT_CONNECTED) {
|
||||
else if (oldState == HState.NOT_CONNECTED) {
|
||||
btnConnect.setText("Abort");
|
||||
}
|
||||
|
||||
if (newState == HConnection.State.CONNECTED) {
|
||||
if (newState == HState.CONNECTED) {
|
||||
lblState.setText("Connected");
|
||||
outHost.setText(getHConnection().getDomain());
|
||||
outPort.setText(getHConnection().getServerPort()+"");
|
||||
}
|
||||
if (newState == HConnection.State.WAITING_FOR_CLIENT) {
|
||||
if (newState == HState.WAITING_FOR_CLIENT) {
|
||||
lblState.setText("Waiting for connection");
|
||||
}
|
||||
|
||||
if (newState == HConnection.State.CONNECTED) {
|
||||
if (newState == HState.CONNECTED) {
|
||||
JSONObject connectionSettings = new JSONObject();
|
||||
connectionSettings.put(AUTODETECT_CACHE, cbx_autodetect.isSelected());
|
||||
connectionSettings.put(HOST_CACHE, inpHost.getEditor().getText());
|
||||
@ -152,22 +154,17 @@ public class ConnectionController extends SubForm {
|
||||
}
|
||||
|
||||
public void btnConnect_clicked(ActionEvent actionEvent) {
|
||||
if (getHConnection().getState() == HConnection.State.NOT_CONNECTED) {
|
||||
if (getHConnection().getState() == HState.NOT_CONNECTED) {
|
||||
|
||||
btnConnect.setDisable(true);
|
||||
new Thread(() -> {
|
||||
if (cbx_autodetect.isSelected()) {
|
||||
getHConnection().prepare();
|
||||
getHConnection().start();
|
||||
}
|
||||
else {
|
||||
getHConnection().prepare(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText()));
|
||||
getHConnection().start(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText()));
|
||||
}
|
||||
if (HConnection.DEBUG) System.out.println("connecting");
|
||||
try {
|
||||
getHConnection().start();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}).start();
|
||||
|
||||
|
||||
|
@ -2,7 +2,8 @@ package gearth.ui.extra;
|
||||
|
||||
import gearth.misc.Cacher;
|
||||
import gearth.protocol.HConnection;
|
||||
import gearth.protocol.misc.ConnectionInfoOverrider;
|
||||
import gearth.protocol.connection.HProxy;
|
||||
import gearth.protocol.connection.HState;
|
||||
import gearth.ui.SubForm;
|
||||
import gearth.ui.info.InfoController;
|
||||
import javafx.scene.control.*;
|
||||
@ -11,7 +12,7 @@ import javafx.scene.layout.GridPane;
|
||||
/**
|
||||
* Created by Jonas on 06/04/18.
|
||||
*/
|
||||
public class ExtraController extends SubForm implements ConnectionInfoOverrider {
|
||||
public class ExtraController extends SubForm {
|
||||
|
||||
public static final String NOTEPAD_CACHE_KEY = "notepad_text";
|
||||
|
||||
@ -35,7 +36,6 @@ public class ExtraController extends SubForm implements ConnectionInfoOverrider
|
||||
public CheckBox cbx_debug;
|
||||
|
||||
public void initialize() {
|
||||
HConnection.setConnectionInfoOverrider(this);
|
||||
|
||||
url_troubleshooting.setTooltip(new Tooltip("https://github.com/sirjonasxx/G-Earth/wiki/Troubleshooting"));
|
||||
InfoController.activateHyperlink(url_troubleshooting);
|
||||
@ -58,7 +58,7 @@ public class ExtraController extends SubForm implements ConnectionInfoOverrider
|
||||
|
||||
cbx_advanced.selectedProperty().addListener(observable -> updateAdvancedUI());
|
||||
getHConnection().getStateObservable().addListener((oldState, newState) -> {
|
||||
if (oldState == HConnection.State.NOT_CONNECTED || newState == HConnection.State.NOT_CONNECTED) {
|
||||
if (oldState == HState.NOT_CONNECTED || newState == HState.NOT_CONNECTED) {
|
||||
updateAdvancedUI();
|
||||
}
|
||||
});
|
||||
@ -75,28 +75,12 @@ public class ExtraController extends SubForm implements ConnectionInfoOverrider
|
||||
if (!cbx_advanced.isSelected()) {
|
||||
cbx_debug.setSelected(false);
|
||||
cbx_ovcinfo.setSelected(false);
|
||||
if (getHConnection().getState() == HConnection.State.NOT_CONNECTED) {
|
||||
if (getHConnection().getState() == HState.NOT_CONNECTED) {
|
||||
cbx_disableDecryption.setSelected(false);
|
||||
}
|
||||
}
|
||||
grd_advanced.setDisable(!cbx_advanced.isSelected());
|
||||
|
||||
cbx_disableDecryption.setDisable(getHConnection().getState() != HConnection.State.NOT_CONNECTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean mustOverrideConnection() {
|
||||
return cbx_ovcinfo.isSelected();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HConnection.Proxy getOverrideProxy() {
|
||||
return new HConnection.Proxy(
|
||||
txt_realIp.getText(),
|
||||
txt_realIp.getText(),
|
||||
Integer.parseInt(txt_realPort.getText()),
|
||||
Integer.parseInt(txt_mitmPort.getText()),
|
||||
txt_mitmIP.getText()
|
||||
);
|
||||
cbx_disableDecryption.setDisable(getHConnection().getState() != HState.NOT_CONNECTED);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package gearth.ui.injection;
|
||||
|
||||
import gearth.protocol.connection.HState;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.Button;
|
||||
@ -81,8 +82,8 @@ public class InjectionController extends SubForm {
|
||||
}
|
||||
|
||||
if (!dirty) {
|
||||
btn_sendToClient.setDisable(getHConnection().getState() != HConnection.State.CONNECTED);
|
||||
btn_sendToServer.setDisable(getHConnection().getState() != HConnection.State.CONNECTED);
|
||||
btn_sendToClient.setDisable(getHConnection().getState() != HState.CONNECTED);
|
||||
btn_sendToServer.setDisable(getHConnection().getState() != HState.CONNECTED);
|
||||
if (packets.length == 1) {
|
||||
lbl_pcktInfo.setText("header (id:" + packets[0].headerId() + ", length:" +
|
||||
packets[0].length() + ")");
|
||||
|
@ -1,5 +1,6 @@
|
||||
package gearth.ui.logger;
|
||||
|
||||
import gearth.protocol.connection.HState;
|
||||
import javafx.application.Platform;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.scene.control.Button;
|
||||
@ -36,14 +37,14 @@ public class LoggerController extends SubForm {
|
||||
|
||||
public void onParentSet(){
|
||||
getHConnection().getStateObservable().addListener((oldState, newState) -> Platform.runLater(() -> {
|
||||
if (newState == HConnection.State.PREPARING) {
|
||||
if (newState == HState.PREPARING) {
|
||||
miniLogText(Color.ORANGE, "Connecting to "+getHConnection().getDomain() + ":" + getHConnection().getServerPort());
|
||||
}
|
||||
if (newState == HConnection.State.CONNECTED) {
|
||||
if (newState == HState.CONNECTED) {
|
||||
miniLogText(Color.GREEN, "Connected to "+getHConnection().getDomain() + ":" + getHConnection().getServerPort());
|
||||
packetLogger.start();
|
||||
}
|
||||
if (newState == HConnection.State.NOT_CONNECTED) {
|
||||
if (newState == HState.NOT_CONNECTED) {
|
||||
miniLogText(Color.RED, "End of connection");
|
||||
packetLogger.stop();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user