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 index c47c145..c8956bd 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/NormalProxyProvider.java @@ -101,7 +101,6 @@ public class NormalProxyProvider extends ProxyProvider { 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"); 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 index 283ea1c..1aa5f39 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/ProxyProvider.java @@ -1,5 +1,6 @@ package gearth.protocol.connection.proxy; +import com.sun.corba.se.impl.orbutil.concurrent.Mutex; import gearth.protocol.HConnection; import gearth.protocol.connection.HProxy; import gearth.protocol.connection.HProxySetter; @@ -8,12 +9,13 @@ import gearth.protocol.connection.HStateSetter; import gearth.protocol.memory.Rc4Obtainer; import gearth.protocol.packethandler.IncomingPacketHandler; import gearth.protocol.packethandler.OutgoingPacketHandler; +import gearth.protocol.packethandler.PacketHandler; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.net.Socket; import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.concurrent.Semaphore; public abstract class ProxyProvider { @@ -30,19 +32,13 @@ public abstract class ProxyProvider { 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(); + client.setTcpNoDelay(true); 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()); + OutgoingPacketHandler outgoingHandler = new OutgoingPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables()); + IncomingPacketHandler incomingHandler = new IncomingPacketHandler(client.getOutputStream(), hConnection.getTrafficObservables()); rc4Obtainer.setPacketHandlers(outgoingHandler, incomingHandler); outgoingHandler.addOnDatastreamConfirmedListener(hotelVersion -> { @@ -53,82 +49,44 @@ public abstract class ProxyProvider { 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); + Semaphore abort = new Semaphore(0); - } - } - 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(); + handleInputStream(client, outgoingHandler, abort); + handleInputStream(server, incomingHandler, abort); - while(!aborted[0]) { - Thread.sleep(50); - } + // abort can be acquired as soon as one of the sockets is closed + abort.acquire(); try { if (!server.isClosed()) server.close(); if (!client.isClosed()) client.close(); if (HConnection.DEBUG) System.out.println("STOP"); + if (datastream[0]) { + onConnectEnd(); + }; } catch (IOException e) { e.printStackTrace(); } } + private void handleInputStream(Socket socket, PacketHandler packetHandler, Semaphore abort) { + new Thread(() -> { + try { + int readLength; + byte[] buffer = new byte[10000]; + while (!socket.isClosed() && + (hConnection.getState() == HState.WAITING_FOR_CLIENT || hConnection.getState() == HState.CONNECTED) && + (readLength = socket.getInputStream().read(buffer)) != -1) { + packetHandler.act(Arrays.copyOf(buffer, readLength)); + } + } + catch (IOException ignore) {} finally { + abort.release(); + } + }).start(); + } + public abstract void start() throws IOException; public abstract void abort(); 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 index d4ce2cd..c00320d 100644 --- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/RawIpProxyProvider.java +++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/RawIpProxyProvider.java @@ -87,7 +87,6 @@ public class RawIpProxyProvider extends ProxyProvider { 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"); diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/PayloadBuffer.java b/G-Earth/src/main/java/gearth/protocol/packethandler/PayloadBuffer.java index 55c3993..ceb1d92 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/PayloadBuffer.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/PayloadBuffer.java @@ -14,7 +14,7 @@ public class PayloadBuffer { return receive(); } public void push(byte[] tcpData) { - buffer = buffer.length == 0 ? tcpData : combineByteArrays(buffer, tcpData); + buffer = buffer.length == 0 ? tcpData.clone() : combineByteArrays(buffer, tcpData); } public HPacket[] receive() { if (buffer.length < 6) return new HPacket[0];