diff --git a/G-Earth/pom.xml b/G-Earth/pom.xml
index ef8d76c..207afac 100644
--- a/G-Earth/pom.xml
+++ b/G-Earth/pom.xml
@@ -12,6 +12,7 @@
1.8
+ 9.2.14.v20151106
@@ -123,6 +124,7 @@
+
@@ -172,6 +174,24 @@
+
+ javax.websocket
+ javax.websocket-api
+ 1.1
+
+
+
+ org.eclipse.jetty
+ jetty-server
+ ${jettyVersion}
+
+
+ org.eclipse.jetty.websocket
+ javax-websocket-server-impl
+ ${jettyVersion}
+
+
+
diff --git a/G-Earth/src/main/java/gearth/protocol/HConnection.java b/G-Earth/src/main/java/gearth/protocol/HConnection.java
index 041e3dc..97ed7d4 100644
--- a/G-Earth/src/main/java/gearth/protocol/HConnection.java
+++ b/G-Earth/src/main/java/gearth/protocol/HConnection.java
@@ -7,6 +7,7 @@ import gearth.protocol.connection.proxy.ProxyProvider;
import gearth.protocol.connection.proxy.flash.FlashProxyProvider;
import gearth.protocol.connection.proxy.ProxyProviderFactory;
import gearth.protocol.connection.proxy.flash.unix.LinuxRawIpFlashProxyProvider;
+import gearth.protocol.connection.proxy.unity.UnityProxyProvider;
import gearth.services.extensionhandler.ExtensionHandler;
import java.io.IOException;
@@ -60,6 +61,12 @@ public class HConnection {
startMITM();
}
+ public void startUnity() {
+ HConnection selff = this;
+ proxyProvider = new UnityProxyProvider(proxy -> selff.proxy = proxy, selff::setState, this);
+ startMITM();
+ }
+
private void startMITM() {
try {
if (proxyProvider != null) {
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java b/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java
index b49fd5e..67f7b71 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/HProxy.java
@@ -1,7 +1,8 @@
package gearth.protocol.connection;
-import gearth.protocol.packethandler.IncomingPacketHandler;
-import gearth.protocol.packethandler.OutgoingPacketHandler;
+import gearth.protocol.packethandler.PacketHandler;
+import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
+import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
import java.net.ServerSocket;
@@ -15,8 +16,8 @@ public class HProxy {
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 PacketHandler inHandler = null; //connection with client (only initialized when verified habbo connection)
+ private volatile PacketHandler outHandler = null; //connection with server (only initialized when verified habbo connection)
private volatile String hotelVersion = "";
private volatile AsyncPacketSender asyncPacketSender = null;
@@ -33,7 +34,7 @@ public class HProxy {
this.proxy_server = socket;
}
- public void verifyProxy(IncomingPacketHandler incomingHandler, OutgoingPacketHandler outgoingHandler, String hotelVersion) {
+ public void verifyProxy(PacketHandler incomingHandler, PacketHandler outgoingHandler, String hotelVersion) {
this.inHandler = incomingHandler;
this.outHandler = outgoingHandler;
this.hotelVersion = hotelVersion;
@@ -64,11 +65,11 @@ public class HProxy {
return intercept_host;
}
- public IncomingPacketHandler getInHandler() {
+ public PacketHandler getInHandler() {
return inHandler;
}
- public OutgoingPacketHandler getOutHandler() {
+ public PacketHandler getOutHandler() {
return outHandler;
}
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java
index 0c69c33..5e61dd8 100644
--- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/flash/FlashProxyProvider.java
@@ -7,9 +7,9 @@ import gearth.protocol.connection.HState;
import gearth.protocol.connection.HStateSetter;
import gearth.protocol.connection.proxy.ProxyProvider;
import gearth.protocol.memory.Rc4Obtainer;
-import gearth.protocol.packethandler.IncomingPacketHandler;
-import gearth.protocol.packethandler.OutgoingPacketHandler;
-import gearth.protocol.packethandler.PacketHandler;
+import gearth.protocol.packethandler.flash.IncomingFlashPacketHandler;
+import gearth.protocol.packethandler.flash.OutgoingFlashPacketHandler;
+import gearth.protocol.packethandler.flash.FlashPacketHandler;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
@@ -45,9 +45,9 @@ public abstract class FlashProxyProvider implements ProxyProvider {
if (HConnection.DEBUG) System.out.println(server.getLocalAddress().getHostAddress() + ": " + server.getLocalPort());
Rc4Obtainer rc4Obtainer = new Rc4Obtainer(hConnection);
- OutgoingPacketHandler outgoingHandler = new OutgoingPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
- IncomingPacketHandler incomingHandler = new IncomingPacketHandler(client.getOutputStream(), hConnection.getTrafficObservables(), outgoingHandler, hConnection.getExtensionHandler());
- rc4Obtainer.setPacketHandlers(outgoingHandler, incomingHandler);
+ OutgoingFlashPacketHandler outgoingHandler = new OutgoingFlashPacketHandler(server.getOutputStream(), hConnection.getTrafficObservables(), hConnection.getExtensionHandler());
+ IncomingFlashPacketHandler incomingHandler = new IncomingFlashPacketHandler(client.getOutputStream(), hConnection.getTrafficObservables(), outgoingHandler, hConnection.getExtensionHandler());
+ rc4Obtainer.setFlashPacketHandlers(outgoingHandler, incomingHandler);
Semaphore abort = new Semaphore(0);
@@ -78,7 +78,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
}
}
- private void handleInputStream(Socket socket, PacketHandler packetHandler, Semaphore abort) {
+ private void handleInputStream(Socket socket, FlashPacketHandler flashPacketHandler, Semaphore abort) {
new Thread(() -> {
try {
int readLength;
@@ -86,7 +86,7 @@ public abstract class FlashProxyProvider implements ProxyProvider {
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));
+ flashPacketHandler.act(Arrays.copyOf(buffer, readLength));
}
}
catch (IOException ignore) {
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/ProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/ProxyProvider.java
deleted file mode 100644
index 9f3daed..0000000
--- a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/ProxyProvider.java
+++ /dev/null
@@ -1,4 +0,0 @@
-package gearth.protocol.connection.proxy.unity;
-
-public class ProxyProvider {
-}
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicator.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicator.java
new file mode 100644
index 0000000..3d158e1
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicator.java
@@ -0,0 +1,86 @@
+package gearth.protocol.connection.proxy.unity;
+
+import gearth.protocol.HConnection;
+import gearth.protocol.HMessage;
+import gearth.protocol.HPacket;
+import gearth.protocol.connection.HProxy;
+import gearth.protocol.connection.HProxySetter;
+import gearth.protocol.connection.HState;
+import gearth.protocol.connection.HStateSetter;
+import gearth.protocol.connection.proxy.ProxyProvider;
+import gearth.protocol.packethandler.unity.UnityPacketHandler;
+
+import javax.websocket.*;
+import javax.websocket.server.ServerEndpoint;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+
+@ServerEndpoint(value = "/packethandler")
+public class UnityCommunicator {
+
+ private final HProxySetter proxySetter;
+ private final HStateSetter stateSetter;
+ private final HConnection hConnection;
+ private final ProxyProvider proxyProvider;
+
+ HProxy hProxy = null;
+
+ public UnityCommunicator(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, ProxyProvider proxyProvider) {
+ this.proxySetter = proxySetter;
+ this.stateSetter = stateSetter;
+ this.hConnection = hConnection;
+ this.proxyProvider = proxyProvider;
+ }
+
+
+ @OnOpen
+ public void onOpen(Session session) throws IOException {
+
+ }
+
+ @OnMessage
+ public void onMessage(byte[] b, Session session) throws IOException {
+// session.getBasicRemote().sendText(message.toUpperCase());
+// session.getBasicRemote().sendBinary(ByteBuffer.wrap(b));
+// System.out.println("received " + new HPacket(b).toString());
+
+ byte[] packet = Arrays.copyOfRange(b, 1, b.length);
+
+ if (hProxy == null && b[0] == 1) {
+ HPacket maybe = new HPacket(packet);
+ if (maybe.getBytesLength() > 6 && maybe.headerId() == 4000) {
+ String hotelVersion = maybe.readString();
+ hProxy = new HProxy("", "", -1, -1, "");
+ hProxy.verifyProxy(
+ new UnityPacketHandler(hConnection.getExtensionHandler(), hConnection.getTrafficObservables(), session, HMessage.Direction.TOCLIENT),
+ new UnityPacketHandler(hConnection.getExtensionHandler(), hConnection.getTrafficObservables(), session, HMessage.Direction.TOSERVER),
+ hotelVersion
+ );
+ proxySetter.setProxy(hProxy);
+ stateSetter.setState(HState.CONNECTED);
+ }
+ }
+
+
+ if (hProxy != null && b[0] == 0) {
+ hProxy.getInHandler().act(packet);
+ }
+ else if (hProxy != null && b[0] == 1) {
+ hProxy.getOutHandler().act(packet);
+ }
+ else {
+ proxyProvider.abort();
+ }
+ }
+
+ @OnClose
+ public void onClose(Session session) throws IOException {
+ proxyProvider.abort();
+ }
+
+ @OnError
+ public void onError(Session session, Throwable throwable) {
+ proxyProvider.abort();
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicatorConfig.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicatorConfig.java
new file mode 100644
index 0000000..f007fe6
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityCommunicatorConfig.java
@@ -0,0 +1,27 @@
+package gearth.protocol.connection.proxy.unity;
+
+import gearth.protocol.HConnection;
+import gearth.protocol.connection.HProxySetter;
+import gearth.protocol.connection.HStateSetter;
+import gearth.protocol.connection.proxy.ProxyProvider;
+
+import javax.websocket.server.ServerEndpointConfig;
+
+public class UnityCommunicatorConfig extends ServerEndpointConfig.Configurator {
+ private final HProxySetter proxySetter;
+ private final HStateSetter stateSetter;
+ private final HConnection hConnection;
+ private final ProxyProvider proxyProvider;
+
+ public UnityCommunicatorConfig(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection, ProxyProvider proxyProvider) {
+ this.proxySetter = proxySetter;
+ this.stateSetter = stateSetter;
+ this.hConnection = hConnection;
+ this.proxyProvider = proxyProvider;
+ }
+
+
+ public T getEndpointInstance(Class clazz) throws InstantiationException {
+ return (T)new UnityCommunicator(proxySetter, stateSetter, hConnection, proxyProvider);
+ }
+}
\ No newline at end of file
diff --git a/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityProxyProvider.java b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityProxyProvider.java
new file mode 100644
index 0000000..b87d8b3
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/connection/proxy/unity/UnityProxyProvider.java
@@ -0,0 +1,81 @@
+package gearth.protocol.connection.proxy.unity;
+
+import gearth.protocol.HConnection;
+import gearth.protocol.connection.HProxySetter;
+import gearth.protocol.connection.HState;
+import gearth.protocol.connection.HStateSetter;
+import gearth.protocol.connection.proxy.ProxyProvider;
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.handler.HandlerList;
+import org.eclipse.jetty.servlet.ServletContextHandler;
+import org.eclipse.jetty.websocket.jsr356.server.deploy.WebSocketServerContainerInitializer;
+
+import javax.websocket.server.ServerContainer;
+import javax.websocket.server.ServerEndpointConfig;
+import java.io.IOException;
+
+public class UnityProxyProvider implements ProxyProvider {
+
+ private final HProxySetter proxySetter;
+ private final HStateSetter stateSetter;
+ private final HConnection hConnection;
+
+ private Server server;
+
+ public UnityProxyProvider(HProxySetter proxySetter, HStateSetter stateSetter, HConnection hConnection) {
+ this.proxySetter = proxySetter;
+ this.stateSetter = stateSetter;
+ this.hConnection = hConnection;
+ }
+
+
+ @Override
+ public void start() throws IOException {
+
+ // https://happyhyppo.ro/2016/03/21/minimal-websockets-communication-with-javajetty-and-angularjs/
+ server = new Server(8025);
+ ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
+ context.setContextPath("/ws");
+
+ HandlerList handlers = new HandlerList();
+ handlers.setHandlers(new Handler[] { context });
+ server.setHandler(handlers);
+
+ ServerContainer wscontainer = null;
+ try {
+ wscontainer = WebSocketServerContainerInitializer.configureContext(context);
+
+ wscontainer.addEndpoint(ServerEndpointConfig.Builder
+ .create(UnityCommunicator.class, "/packethandler") // the endpoint url
+ .configurator(new UnityCommunicatorConfig(proxySetter, stateSetter, hConnection, this))
+ .build());
+
+ server.start();
+ stateSetter.setState(HState.WAITING_FOR_CLIENT);
+ } catch (Exception e) {
+ stateSetter.setState(HState.NOT_CONNECTED);
+ e.printStackTrace();
+ }
+ }
+
+ @Override
+ public synchronized void abort() {
+ if (server == null) {
+ return;
+ }
+
+ final Server abortThis = server;
+ stateSetter.setState(HState.ABORTING);
+ new Thread(() -> {
+ try {
+ abortThis.stop();
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ stateSetter.setState(HState.NOT_CONNECTED);
+ }
+ }).start();
+ server = null;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/protocol/memory/Rc4Obtainer.java b/G-Earth/src/main/java/gearth/protocol/memory/Rc4Obtainer.java
index d8fa9f1..69f8c3a 100644
--- a/G-Earth/src/main/java/gearth/protocol/memory/Rc4Obtainer.java
+++ b/G-Earth/src/main/java/gearth/protocol/memory/Rc4Obtainer.java
@@ -7,7 +7,9 @@ import gearth.protocol.HPacket;
import gearth.protocol.crypto.RC4;
import gearth.protocol.memory.habboclient.HabboClient;
import gearth.protocol.memory.habboclient.HabboClientFactory;
-import gearth.protocol.packethandler.*;
+import gearth.protocol.packethandler.flash.BufferChangeListener;
+import gearth.protocol.packethandler.flash.FlashPacketHandler;
+import gearth.protocol.packethandler.PayloadBuffer;
import javafx.application.Platform;
import javafx.scene.control.Alert;
import javafx.scene.control.ButtonType;
@@ -25,17 +27,17 @@ public class Rc4Obtainer {
public static final boolean DEBUG = false;
private HabboClient client;
- private List packetHandlers;
+ private List flashPacketHandlers;
public Rc4Obtainer(HConnection hConnection) {
client = HabboClientFactory.get(hConnection);
}
- public void setPacketHandlers(PacketHandler... packetHandlers) {
- this.packetHandlers = Arrays.asList(packetHandlers);
+ public void setFlashPacketHandlers(FlashPacketHandler... flashPacketHandlers) {
+ this.flashPacketHandlers = Arrays.asList(flashPacketHandlers);
- for (PacketHandler handler : packetHandlers) {
+ for (FlashPacketHandler handler : flashPacketHandlers) {
BufferChangeListener bufferChangeListener = new BufferChangeListener() {
@Override
public void act() {
@@ -53,10 +55,10 @@ public class Rc4Obtainer {
- private void onSendFirstEncryptedMessage(PacketHandler packetHandler) {
+ private void onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler) {
if (!HConnection.DECRYPTPACKETS) return;
- packetHandlers.forEach(PacketHandler::block);
+ flashPacketHandlers.forEach(FlashPacketHandler::block);
new Thread(() -> {
@@ -67,8 +69,8 @@ public class Rc4Obtainer {
int i = 0;
while (!worked && i < 4) {
worked = (i % 2 == 0) ?
- onSendFirstEncryptedMessage(packetHandler, client.getRC4cached()) :
- onSendFirstEncryptedMessage(packetHandler, client.getRC4possibilities());
+ onSendFirstEncryptedMessage(flashPacketHandler, client.getRC4cached()) :
+ onSendFirstEncryptedMessage(flashPacketHandler, client.getRC4possibilities());
i++;
}
@@ -107,16 +109,16 @@ public class Rc4Obtainer {
System.out.println("Cracked RC4 in " + (endTime - startTime) + "ms");
}
- packetHandlers.forEach(PacketHandler::unblock);
+ flashPacketHandlers.forEach(FlashPacketHandler::unblock);
}).start();
}
- private boolean onSendFirstEncryptedMessage(PacketHandler packetHandler, List potentialRC4tables) {
+ private boolean onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler, List potentialRC4tables) {
for (byte[] possible : potentialRC4tables) {
- byte[] encBuffer = new byte[packetHandler.getEncryptedBuffer().size()];
+ byte[] encBuffer = new byte[flashPacketHandler.getEncryptedBuffer().size()];
for (int i = 0; i < encBuffer.length; i++) {
- encBuffer[i] = packetHandler.getEncryptedBuffer().get(i);
+ encBuffer[i] = flashPacketHandler.getEncryptedBuffer().get(i);
}
for (int i = 0; i < 256; i++) {
@@ -124,7 +126,7 @@ public class Rc4Obtainer {
byte[] keycpy = Arrays.copyOf(possible, possible.length);
RC4 rc4Tryout = new RC4(keycpy, i, j);
- if (packetHandler.getMessageSide() == HMessage.Direction.TOSERVER) rc4Tryout.undoRc4(encBuffer);
+ if (flashPacketHandler.getMessageSide() == HMessage.Direction.TOSERVER) rc4Tryout.undoRc4(encBuffer);
if (rc4Tryout.couldBeFresh()) {
byte[] encDataCopy = Arrays.copyOf(encBuffer, encBuffer.length);
RC4 rc4TryCopy = rc4Tryout.deepCopy();
@@ -135,7 +137,7 @@ public class Rc4Obtainer {
HPacket[] checker = payloadBuffer.pushAndReceive(decoded);
if (payloadBuffer.peak().length == 0) {
- packetHandler.setRc4(rc4Tryout);
+ flashPacketHandler.setRc4(rc4Tryout);
return true;
}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/ByteArrayUtils.java b/G-Earth/src/main/java/gearth/protocol/packethandler/ByteArrayUtils.java
new file mode 100644
index 0000000..22ea13b
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/ByteArrayUtils.java
@@ -0,0 +1,12 @@
+package gearth.protocol.packethandler;
+
+public class ByteArrayUtils {
+
+ public static byte[] combineByteArrays(byte[] arr1, byte[] arr2) {
+ byte[] combined = new byte[arr1.length + arr2.length];
+ System.arraycopy(arr1,0,combined,0 ,arr1.length);
+ System.arraycopy(arr2,0,combined,arr1.length,arr2.length);
+ return combined;
+ }
+
+}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java
index 6151c3b..01c5552 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java
@@ -1,125 +1,32 @@
package gearth.protocol.packethandler;
import gearth.misc.listenerpattern.Observable;
-import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
-import gearth.protocol.HPacket;
import gearth.protocol.TrafficListener;
-import gearth.protocol.crypto.RC4;
import gearth.services.extensionhandler.ExtensionHandler;
-import gearth.services.extensionhandler.OnHMessageHandled;
import java.io.IOException;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
public abstract class PacketHandler {
- protected static final boolean DEBUG = false;
+ protected final ExtensionHandler extensionHandler;
+ private final Object[] trafficObservables; //get notified on packet send
+ protected final PayloadBuffer payloadBuffer;
+ protected volatile int currentIndex = 0;
+ protected final Object sendLock = new Object();
- private volatile PayloadBuffer payloadBuffer = new PayloadBuffer();
- private volatile OutputStream out;
- private volatile ExtensionHandler extensionHandler;
- private volatile Object[] trafficObservables; //get notified on packet send
- private volatile boolean isTempBlocked = false;
- volatile boolean isDataStream = false;
- private volatile int currentIndex = 0;
-
- private final Object manipulationLock = new Object();
- private final Object sendLock = new Object();
-
- private RC4 decryptcipher = null;
- private RC4 encryptcipher = null;
-
- private volatile List tempEncryptedBuffer = new ArrayList<>();
- volatile boolean isEncryptedStream = false;
-
-
- PacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
- this.trafficObservables = trafficObservables;
+ protected PacketHandler(ExtensionHandler extensionHandler, Object[] trafficObservables) {
this.extensionHandler = extensionHandler;
- out = outputStream;
- }
-
- public boolean isDataStream() {return isDataStream;}
- public void setAsDataStream() {
- isDataStream = true;
- }
-
- public boolean isEncryptedStream() {
- return isEncryptedStream;
- }
-
- public void act(byte[] buffer) throws IOException {
- if (!isDataStream) {
- out.write(buffer);
- return;
- }
-
- bufferChangeObservable.fireEvent();
-
- if (!isEncryptedStream) {
- payloadBuffer.push(buffer);
- }
- else if (!HConnection.DECRYPTPACKETS) {
- synchronized (sendLock) {
- out.write(buffer);
- }
- }
- else if (decryptcipher == null) {
- for (int i = 0; i < buffer.length; i++) {
- tempEncryptedBuffer.add(buffer[i]);
- }
- }
- else {
- byte[] tm = decryptcipher.rc4(buffer);
- if (DEBUG) {
- printForDebugging(tm);
- }
- payloadBuffer.push(tm);
- }
-
- if (!isTempBlocked) {
- flush();
- }
+ this.trafficObservables = trafficObservables;
+ this.payloadBuffer = new PayloadBuffer();
}
- public void setRc4(RC4 rc4) {
- this.decryptcipher = rc4.deepCopy();
- this.encryptcipher = rc4.deepCopy();
+ public abstract void sendToStream(byte[] buffer);
- byte[] encrbuffer = new byte[tempEncryptedBuffer.size()];
- for (int i = 0; i < tempEncryptedBuffer.size(); i++) {
- encrbuffer[i] = tempEncryptedBuffer.get(i);
- }
+ public abstract void act(byte[] buffer) throws IOException;
- try {
- act(encrbuffer);
- } catch (IOException e) {
- e.printStackTrace();
- }
- tempEncryptedBuffer = null;
- }
-
- public void block() {
- isTempBlocked = true;
- }
- public void unblock() {
- try {
- flush();
- } catch (IOException e) {
- e.printStackTrace();
- }
- isTempBlocked = false;
- }
-
- /**
- * LISTENERS CAN EDIT THE MESSAGE BEFORE BEING SENT
- * @param message
- */
- private void notifyListeners(int i, HMessage message) {
+ protected void notifyListeners(int i, HMessage message) {
((Observable) trafficObservables[i]).fireEvent(trafficListener -> {
message.getPacket().resetReadIndex();
trafficListener.onCapture(message);
@@ -127,72 +34,4 @@ public abstract class PacketHandler {
message.getPacket().resetReadIndex();
}
- public void sendToStream(byte[] buffer) {
- synchronized (sendLock) {
- try {
- out.write(
- (!isEncryptedStream)
- ? buffer
- : encryptcipher.rc4(buffer)
- );
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
-
- public void flush() throws IOException {
- synchronized (manipulationLock) {
- HPacket[] hpackets = payloadBuffer.receive();
-
- for (HPacket hpacket : hpackets){
- HMessage hMessage = new HMessage(hpacket, getMessageSide(), currentIndex);
- boolean isencrypted = isEncryptedStream;
-
- OnHMessageHandled afterExtensionIntercept = hMessage1 -> {
- if (isDataStream) {
- notifyListeners(2, hMessage1);
- }
-
- if (!hMessage1.isBlocked()) {
- synchronized (sendLock) {
- out.write(
- (!isencrypted)
- ? hMessage1.getPacket().toBytes()
- : encryptcipher.rc4(hMessage1.getPacket().toBytes())
- );
- }
- }
- };
-
- if (isDataStream) {
- notifyListeners(0, hMessage);
- notifyListeners(1, hMessage);
- extensionHandler.handle(hMessage, afterExtensionIntercept);
- }
- else {
- afterExtensionIntercept.finished(hMessage);
- }
-
- currentIndex++;
- }
- }
- }
-
- public abstract HMessage.Direction getMessageSide();
-
- public List getEncryptedBuffer() {
- return tempEncryptedBuffer;
- }
-
- protected abstract void printForDebugging(byte[] bytes);
-
- private Observable bufferChangeObservable = new Observable<>(BufferChangeListener::act);
- public Observable getBufferChangeObservable() {
- return bufferChangeObservable;
- }
-
- public int getCurrentIndex() {
- return currentIndex;
- }
}
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 ceb1d92..36c7045 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.clone() : combineByteArrays(buffer, tcpData);
+ buffer = buffer.length == 0 ? tcpData.clone() : ByteArrayUtils.combineByteArrays(buffer, tcpData);
}
public HPacket[] receive() {
if (buffer.length < 6) return new HPacket[0];
@@ -30,14 +30,6 @@ public class PayloadBuffer {
}
- private byte[] combineByteArrays(byte[] arr1, byte[] arr2) {
- byte[] combined = new byte[arr1.length + arr2.length];
- System.arraycopy(arr1,0,combined,0 ,arr1.length);
- System.arraycopy(arr2,0,combined,arr1.length,arr2.length);
- return combined;
- }
-
-
public byte[] peak() {
return buffer;
}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/BufferChangeListener.java b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/BufferChangeListener.java
similarity index 57%
rename from G-Earth/src/main/java/gearth/protocol/packethandler/BufferChangeListener.java
rename to G-Earth/src/main/java/gearth/protocol/packethandler/flash/BufferChangeListener.java
index d004cb8..e39d6e7 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/BufferChangeListener.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/BufferChangeListener.java
@@ -1,4 +1,4 @@
-package gearth.protocol.packethandler;
+package gearth.protocol.packethandler.flash;
public interface BufferChangeListener {
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/flash/FlashPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/FlashPacketHandler.java
new file mode 100644
index 0000000..b894343
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/FlashPacketHandler.java
@@ -0,0 +1,182 @@
+package gearth.protocol.packethandler.flash;
+
+import gearth.misc.listenerpattern.Observable;
+import gearth.protocol.HConnection;
+import gearth.protocol.HMessage;
+import gearth.protocol.HPacket;
+import gearth.protocol.TrafficListener;
+import gearth.protocol.crypto.RC4;
+import gearth.protocol.packethandler.PacketHandler;
+import gearth.protocol.packethandler.PayloadBuffer;
+import gearth.services.extensionhandler.ExtensionHandler;
+import gearth.services.extensionhandler.OnHMessageHandled;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class FlashPacketHandler extends PacketHandler {
+
+ protected static final boolean DEBUG = false;
+
+ private volatile OutputStream out;
+ private volatile boolean isTempBlocked = false;
+ volatile boolean isDataStream = false;
+
+ private final Object manipulationLock = new Object();
+
+ private RC4 decryptcipher = null;
+ private RC4 encryptcipher = null;
+
+ private volatile List tempEncryptedBuffer = new ArrayList<>();
+ volatile boolean isEncryptedStream = false;
+
+
+ FlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
+ super(extensionHandler, trafficObservables);
+ out = outputStream;
+ }
+
+ public boolean isDataStream() {return isDataStream;}
+ public void setAsDataStream() {
+ isDataStream = true;
+ }
+
+ public boolean isEncryptedStream() {
+ return isEncryptedStream;
+ }
+
+ public void act(byte[] buffer) throws IOException {
+ if (!isDataStream) {
+ out.write(buffer);
+ return;
+ }
+
+ bufferChangeObservable.fireEvent();
+
+ if (!isEncryptedStream) {
+ payloadBuffer.push(buffer);
+ }
+ else if (!HConnection.DECRYPTPACKETS) {
+ synchronized (sendLock) {
+ out.write(buffer);
+ }
+ }
+ else if (decryptcipher == null) {
+ for (int i = 0; i < buffer.length; i++) {
+ tempEncryptedBuffer.add(buffer[i]);
+ }
+ }
+ else {
+ byte[] tm = decryptcipher.rc4(buffer);
+ if (DEBUG) {
+ printForDebugging(tm);
+ }
+ payloadBuffer.push(tm);
+ }
+
+ if (!isTempBlocked) {
+ flush();
+ }
+ }
+
+
+ public void setRc4(RC4 rc4) {
+ this.decryptcipher = rc4.deepCopy();
+ this.encryptcipher = rc4.deepCopy();
+
+ byte[] encrbuffer = new byte[tempEncryptedBuffer.size()];
+ for (int i = 0; i < tempEncryptedBuffer.size(); i++) {
+ encrbuffer[i] = tempEncryptedBuffer.get(i);
+ }
+
+ try {
+ act(encrbuffer);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ tempEncryptedBuffer = null;
+ }
+
+ public void block() {
+ isTempBlocked = true;
+ }
+ public void unblock() {
+ try {
+ flush();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ isTempBlocked = false;
+ }
+
+ public void sendToStream(byte[] buffer) {
+ synchronized (sendLock) {
+ try {
+ out.write(
+ (!isEncryptedStream)
+ ? buffer
+ : encryptcipher.rc4(buffer)
+ );
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ public void flush() throws IOException {
+ synchronized (manipulationLock) {
+ HPacket[] hpackets = payloadBuffer.receive();
+
+ for (HPacket hpacket : hpackets){
+ HMessage hMessage = new HMessage(hpacket, getMessageSide(), currentIndex);
+ boolean isencrypted = isEncryptedStream;
+
+ OnHMessageHandled afterExtensionIntercept = hMessage1 -> {
+ if (isDataStream) {
+ notifyListeners(2, hMessage1);
+ }
+
+ if (!hMessage1.isBlocked()) {
+ synchronized (sendLock) {
+ out.write(
+ (!isencrypted)
+ ? hMessage1.getPacket().toBytes()
+ : encryptcipher.rc4(hMessage1.getPacket().toBytes())
+ );
+ }
+ }
+ };
+
+ if (isDataStream) {
+ notifyListeners(0, hMessage);
+ notifyListeners(1, hMessage);
+ extensionHandler.handle(hMessage, afterExtensionIntercept);
+ }
+ else {
+ afterExtensionIntercept.finished(hMessage);
+ }
+
+ currentIndex++;
+ }
+ }
+ }
+
+ public abstract HMessage.Direction getMessageSide();
+
+ public List getEncryptedBuffer() {
+ return tempEncryptedBuffer;
+ }
+
+ protected abstract void printForDebugging(byte[] bytes);
+
+ private Observable bufferChangeObservable = new Observable<>(BufferChangeListener::act);
+ public Observable getBufferChangeObservable() {
+ return bufferChangeObservable;
+ }
+
+ public int getCurrentIndex() {
+ return currentIndex;
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/IncomingPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/IncomingFlashPacketHandler.java
similarity index 84%
rename from G-Earth/src/main/java/gearth/protocol/packethandler/IncomingPacketHandler.java
rename to G-Earth/src/main/java/gearth/protocol/packethandler/flash/IncomingFlashPacketHandler.java
index f968241..a7819aa 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/IncomingPacketHandler.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/IncomingFlashPacketHandler.java
@@ -1,4 +1,4 @@
-package gearth.protocol.packethandler;
+package gearth.protocol.packethandler.flash;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HMessage;
@@ -6,13 +6,11 @@ import gearth.protocol.HPacket;
import gearth.protocol.TrafficListener;
import gearth.services.extensionhandler.ExtensionHandler;
-import java.io.IOException;
import java.io.OutputStream;
-import java.util.List;
-public class IncomingPacketHandler extends PacketHandler {
+public class IncomingFlashPacketHandler extends FlashPacketHandler {
- public IncomingPacketHandler(OutputStream outputStream, Object[] trafficObservables, OutgoingPacketHandler outgoingHandler, ExtensionHandler extensionHandler) {
+ public IncomingFlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, OutgoingFlashPacketHandler outgoingHandler, ExtensionHandler extensionHandler) {
super(outputStream, trafficObservables, extensionHandler);
TrafficListener listener = new TrafficListener() {
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/OnDatastreamConfirmedListener.java b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OnDatastreamConfirmedListener.java
similarity index 67%
rename from G-Earth/src/main/java/gearth/protocol/packethandler/OnDatastreamConfirmedListener.java
rename to G-Earth/src/main/java/gearth/protocol/packethandler/flash/OnDatastreamConfirmedListener.java
index fd6dabc..4b09343 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/OnDatastreamConfirmedListener.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OnDatastreamConfirmedListener.java
@@ -1,4 +1,4 @@
-package gearth.protocol.packethandler;
+package gearth.protocol.packethandler.flash;
public interface OnDatastreamConfirmedListener {
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/OutgoingPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OutgoingFlashPacketHandler.java
similarity index 81%
rename from G-Earth/src/main/java/gearth/protocol/packethandler/OutgoingPacketHandler.java
rename to G-Earth/src/main/java/gearth/protocol/packethandler/flash/OutgoingFlashPacketHandler.java
index 156eec6..26467f6 100644
--- a/G-Earth/src/main/java/gearth/protocol/packethandler/OutgoingPacketHandler.java
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/flash/OutgoingFlashPacketHandler.java
@@ -1,4 +1,4 @@
-package gearth.protocol.packethandler;
+package gearth.protocol.packethandler.flash;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HMessage;
@@ -7,13 +7,10 @@ import gearth.services.extensionhandler.ExtensionHandler;
import java.io.IOException;
import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.function.Consumer;
-public class OutgoingPacketHandler extends PacketHandler {
+public class OutgoingFlashPacketHandler extends FlashPacketHandler {
- public OutgoingPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
+ public OutgoingFlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) {
super(outputStream, trafficObservables, extensionHandler);
}
diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/unity/UnityPacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/unity/UnityPacketHandler.java
new file mode 100644
index 0000000..2555e21
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/protocol/packethandler/unity/UnityPacketHandler.java
@@ -0,0 +1,59 @@
+package gearth.protocol.packethandler.unity;
+
+import gearth.protocol.HMessage;
+import gearth.protocol.HPacket;
+import gearth.protocol.packethandler.ByteArrayUtils;
+import gearth.protocol.packethandler.PacketHandler;
+import gearth.protocol.packethandler.PayloadBuffer;
+import gearth.services.extensionhandler.ExtensionHandler;
+import gearth.services.extensionhandler.OnHMessageHandled;
+
+import javax.websocket.Session;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+public class UnityPacketHandler extends PacketHandler {
+
+ private final Session session;
+ private final HMessage.Direction direction;
+
+ public UnityPacketHandler(ExtensionHandler extensionHandler, Object[] trafficObservables, Session session, HMessage.Direction direction) {
+ super(extensionHandler, trafficObservables);
+ this.session = session;
+ this.direction = direction;
+ }
+
+ @Override
+ public void sendToStream(byte[] buffer) {
+ synchronized (sendLock) {
+ try {
+ byte[] prefix = new byte[]{(direction == HMessage.Direction.TOCLIENT ? ((byte)0) : ((byte)1))};
+ byte[] combined = ByteArrayUtils.combineByteArrays(prefix, buffer);
+
+ session.getBasicRemote().sendBinary(ByteBuffer.wrap(combined));
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ }
+
+ @Override
+ public void act(byte[] buffer) throws IOException {
+ HPacket[] packets = payloadBuffer.pushAndReceive(buffer);
+
+ for (HPacket hPacket : packets) {
+ HMessage hMessage = new HMessage(hPacket, direction, currentIndex);
+
+ OnHMessageHandled afterExtensionIntercept = hMessage1 -> {
+ notifyListeners(2, hMessage1);
+ sendToStream(hMessage1.getPacket().toBytes());
+ };
+
+ notifyListeners(0, hMessage);
+ notifyListeners(1, hMessage);
+ extensionHandler.handle(hMessage, afterExtensionIntercept);
+
+ currentIndex++;
+ }
+ }
+}
diff --git a/G-Earth/src/main/java/gearth/services/g_chrome_tools/UnityFileServer.java b/G-Earth/src/main/java/gearth/services/g_chrome_tools/UnityFileServer.java
new file mode 100644
index 0000000..932ed89
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/services/g_chrome_tools/UnityFileServer.java
@@ -0,0 +1,4 @@
+package gearth.services.g_chrome_tools;
+
+public class UnityFileServer {
+}
diff --git a/G-Earth/src/main/java/gearth/services/g_chrome_tools/UnitywebModifyer.java b/G-Earth/src/main/java/gearth/services/g_chrome_tools/UnitywebModifyer.java
new file mode 100644
index 0000000..20ef3e8
--- /dev/null
+++ b/G-Earth/src/main/java/gearth/services/g_chrome_tools/UnitywebModifyer.java
@@ -0,0 +1,4 @@
+package gearth.services.g_chrome_tools;
+
+public class UnitywebModifyer {
+}
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 98fa961..2f9eae2 100644
--- a/G-Earth/src/main/java/gearth/ui/connection/ConnectionController.java
+++ b/G-Earth/src/main/java/gearth/ui/connection/ConnectionController.java
@@ -168,12 +168,19 @@ public class ConnectionController extends SubForm {
btnConnect.setDisable(true);
new Thread(() -> {
- if (cbx_autodetect.isSelected()) {
- getHConnection().start();
+ if (useFlash()) {
+ if (cbx_autodetect.isSelected()) {
+ getHConnection().start();
+ }
+ else {
+ getHConnection().start(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText()));
+ }
}
else {
- getHConnection().start(inpHost.getEditor().getText(), Integer.parseInt(inpPort.getEditor().getText()));
+ getHConnection().startUnity();
}
+
+
if (HConnection.DEBUG) System.out.println("connecting");
}).start();