From 5ce9a8ea025410c8b8ae8cbbcf8c0faf1773b568 Mon Sep 17 00:00:00 2001 From: sirjonasxx <36828922+sirjonasxx@users.noreply.github.com> Date: Wed, 29 Apr 2020 05:11:38 +0200 Subject: [PATCH] refactor HConnection and finally have it kind of readable --- .../gearth/protocol/HConnection_temp.java | 629 ++++++++++++++++++ .../gearth/protocol/StateChangeListener.java | 4 +- .../connection/AsyncPacketSender.java | 78 +++ .../gearth/protocol/connection/HProxy.java | 82 +++ .../protocol/connection/HProxySetter.java | 5 + .../gearth/protocol/connection/HState.java | 10 + .../protocol/connection/HStateSetter.java | 5 + .../connection/proxy/NormalProxyProvider.java | 203 ++++++ .../connection/proxy/ProxyProvider.java | 145 ++++ .../proxy/ProxyProviderFactory.java | 99 +++ .../connection/proxy/RawIpProxyProvider.java | 131 ++++ .../misc/ConnectionInfoOverrider.java | 12 - .../extensionhandler/ExtensionHandler.java | 7 +- .../ui/connection/ConnectionController.java | 31 +- .../java/gearth/ui/extra/ExtraController.java | 28 +- .../ui/injection/InjectionController.java | 5 +- .../gearth/ui/logger/LoggerController.java | 7 +- 17 files changed, 1421 insertions(+), 60 deletions(-) create mode 100644 G-Earth/src/main/java/gearth/protocol/HConnection_temp.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/AsyncPacketSender.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/HProxy.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/HProxySetter.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/HState.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/HStateSetter.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProviderFactory.java create mode 100644 G-Earth/src/main/java/gearth/protocol/connection/proxy/RawIpProxyProvider.java delete mode 100644 G-Earth/src/main/java/gearth/protocol/misc/ConnectionInfoOverrider.java diff --git a/G-Earth/src/main/java/gearth/protocol/HConnection_temp.java b/G-Earth/src/main/java/gearth/protocol/HConnection_temp.java new file mode 100644 index 0000000..d7817d9 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/HConnection_temp.java @@ -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 sendToClientAsyncQueue = new LinkedList<>(); +// private final Queue 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 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 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(), new Observable(), new Observable()}; +// private volatile Observable stateObservable = new Observable<>(); +// +// private volatile State state = State.NOT_CONNECTED; +// +// private volatile List 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 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 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 allPotentialHosts) { +// rawIpMode = false; +// setState(State.PREPARING); +// clearAllProxies(); +// actual_proxy = null; +// +// if (hostRedirected) { +// removeFromHosts(); +// } +// +// +// List 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 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 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 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 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 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) trafficObservables[order]).addListener(listener); +// } +// public void removeTrafficListener(TrafficListener listener) { +// ((Observable) trafficObservables[0]).removeListener(listener); +// ((Observable) trafficObservables[1]).removeListener(listener); +// ((Observable) 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 ""; +// return actual_proxy.getActual_domain(); +// } +// public String getDomain() { +// if (actual_proxy == null) return ""; +// 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; +// } +} diff --git a/G-Earth/src/main/java/gearth/protocol/StateChangeListener.java b/G-Earth/src/main/java/gearth/protocol/StateChangeListener.java index 3fed137..3b6893c 100644 --- a/G-Earth/src/main/java/gearth/protocol/StateChangeListener.java +++ b/G-Earth/src/main/java/gearth/protocol/StateChangeListener.java @@ -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); } diff --git a/G-Earth/src/main/java/gearth/protocol/connection/AsyncPacketSender.java b/G-Earth/src/main/java/gearth/protocol/connection/AsyncPacketSender.java new file mode 100644 index 0000000..8c54e87 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/AsyncPacketSender.java @@ -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 sendToClientAsyncQueue = new LinkedList<>(); + private final Queue 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(); + } + } +} diff --git a/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java b/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java new file mode 100644 index 0000000..b49fd5e --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java @@ -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; + } +} diff --git a/G-Earth/src/main/java/gearth/protocol/connection/HProxySetter.java b/G-Earth/src/main/java/gearth/protocol/connection/HProxySetter.java new file mode 100644 index 0000000..cc5ef52 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/HProxySetter.java @@ -0,0 +1,5 @@ +package gearth.protocol.connection; + +public interface HProxySetter { + void setProxy(HProxy proxy); +} diff --git a/G-Earth/src/main/java/gearth/protocol/connection/HState.java b/G-Earth/src/main/java/gearth/protocol/connection/HState.java new file mode 100644 index 0000000..d9ceedb --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/HState.java @@ -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 +} \ No newline at end of file diff --git a/G-Earth/src/main/java/gearth/protocol/connection/HStateSetter.java b/G-Earth/src/main/java/gearth/protocol/connection/HStateSetter.java new file mode 100644 index 0000000..048cc8f --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/HStateSetter.java @@ -0,0 +1,5 @@ +package gearth.protocol.connection; + +public interface HStateSetter { + void setState(HState state); +} diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java new file mode 100644 index 0000000..c47c145 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java @@ -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 potentialHosts; + + + private static final HostReplacer hostsReplacer = HostReplacerFactory.get(); + private volatile boolean hostRedirected = false; + + private volatile List potentialProxies = new ArrayList<>(); + private volatile HProxy proxy = null; + + + + public NormalProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, List 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 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 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 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 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); + } +} diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java new file mode 100644 index 0000000..283ea1c --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java @@ -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); + } + + +} diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProviderFactory.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProviderFactory.java new file mode 100644 index 0000000..7159240 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProviderFactory.java @@ -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 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 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 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 potentialHost = new ArrayList<>(); + potentialHost.add(domain+":"+port); + return provide(potentialHost); + } + } + + private ProxyProvider provide(List potentialHosts) { + return new NormalProxyProvider(proxySetter, stateSetter, hConnection, potentialHosts); + } +} diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/RawIpProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/RawIpProxyProvider.java new file mode 100644 index 0000000..8487472 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/RawIpProxyProvider.java @@ -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 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(); + } + } + } +} diff --git a/G-Earth/src/main/java/gearth/protocol/misc/ConnectionInfoOverrider.java b/G-Earth/src/main/java/gearth/protocol/misc/ConnectionInfoOverrider.java deleted file mode 100644 index f02f20d..0000000 --- a/G-Earth/src/main/java/gearth/protocol/misc/ConnectionInfoOverrider.java +++ /dev/null @@ -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(); -} diff --git a/G-Earth/src/main/java/gearth/services/extensionhandler/ExtensionHandler.java b/G-Earth/src/main/java/gearth/services/extensionhandler/ExtensionHandler.java index 0b5dd38..b383199 100644 --- a/G-Earth/src/main/java/gearth/services/extensionhandler/ExtensionHandler.java +++ b/G-Earth/src/main/java/gearth/services/extensionhandler/ExtensionHandler.java @@ -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(), diff --git a/G-Earth/src/main/java/gearth/ui/connection/ConnectionController.java b/G-Earth/src/main/java/gearth/ui/connection/ConnectionController.java index e12c95e..ba45b56 100644 --- a/G-Earth/src/main/java/gearth/ui/connection/ConnectionController.java +++ b/G-Earth/src/main/java/gearth/ui/connection/ConnectionController.java @@ -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 knownHosts = HConnection.autoDetectHosts; + List knownHosts = ProxyProviderFactory.autoDetectHosts; Set hosts = new HashSet<>(); Set 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(); diff --git a/G-Earth/src/main/java/gearth/ui/extra/ExtraController.java b/G-Earth/src/main/java/gearth/ui/extra/ExtraController.java index 1fc3e91..f489610 100644 --- a/G-Earth/src/main/java/gearth/ui/extra/ExtraController.java +++ b/G-Earth/src/main/java/gearth/ui/extra/ExtraController.java @@ -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); } } diff --git a/G-Earth/src/main/java/gearth/ui/injection/InjectionController.java b/G-Earth/src/main/java/gearth/ui/injection/InjectionController.java index 5a87c0d..323adf4 100644 --- a/G-Earth/src/main/java/gearth/ui/injection/InjectionController.java +++ b/G-Earth/src/main/java/gearth/ui/injection/InjectionController.java @@ -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() + ")"); diff --git a/G-Earth/src/main/java/gearth/ui/logger/LoggerController.java b/G-Earth/src/main/java/gearth/ui/logger/LoggerController.java index 9a87cc1..1f76d32 100644 --- a/G-Earth/src/main/java/gearth/ui/logger/LoggerController.java +++ b/G-Earth/src/main/java/gearth/ui/logger/LoggerController.java @@ -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(); }