Refactor FlashPacketHandler into EncryptedPacketHandler for Rc4Obtainer

This commit is contained in:
UnfamiliarLegacy 2024-06-24 07:19:52 +02:00
parent c7fcc596da
commit 0df906144e
10 changed files with 227 additions and 175 deletions

View File

@ -2,6 +2,10 @@ package gearth.protocol;
public interface TrafficListener { public interface TrafficListener {
int BEFORE_MODIFICATION = 0;
int MODIFICATION = 1;
int AFTER_MODIFICATION = 2;
void onCapture(HMessage message); void onCapture(HMessage message);
} }

View File

@ -6,9 +6,9 @@ import gearth.protocol.HMessage;
import gearth.protocol.crypto.RC4; import gearth.protocol.crypto.RC4;
import gearth.protocol.memory.habboclient.HabboClient; import gearth.protocol.memory.habboclient.HabboClient;
import gearth.protocol.memory.habboclient.HabboClientFactory; import gearth.protocol.memory.habboclient.HabboClientFactory;
import gearth.protocol.packethandler.EncryptedPacketHandler;
import gearth.protocol.packethandler.PayloadBuffer; import gearth.protocol.packethandler.PayloadBuffer;
import gearth.protocol.packethandler.flash.BufferChangeListener; import gearth.protocol.packethandler.flash.BufferChangeListener;
import gearth.protocol.packethandler.flash.FlashPacketHandler;
import gearth.ui.titlebar.TitleBarController; import gearth.ui.titlebar.TitleBarController;
import gearth.ui.translations.LanguageBundle; import gearth.ui.translations.LanguageBundle;
import javafx.application.Platform; import javafx.application.Platform;
@ -28,32 +28,32 @@ public class Rc4Obtainer {
public static final boolean DEBUG = false; public static final boolean DEBUG = false;
private final HabboClient client; private final HabboClient client;
private List<FlashPacketHandler> flashPacketHandlers; private List<EncryptedPacketHandler> flashPacketHandlers;
public Rc4Obtainer(HConnection hConnection) { public Rc4Obtainer(HConnection hConnection) {
client = HabboClientFactory.get(hConnection); client = HabboClientFactory.get(hConnection);
} }
public void setFlashPacketHandlers(FlashPacketHandler... flashPacketHandlers) { public void setFlashPacketHandlers(EncryptedPacketHandler... flashPacketHandlers) {
this.flashPacketHandlers = Arrays.asList(flashPacketHandlers); this.flashPacketHandlers = Arrays.asList(flashPacketHandlers);
for (FlashPacketHandler handler : flashPacketHandlers) { for (EncryptedPacketHandler handler : flashPacketHandlers) {
BufferChangeListener bufferChangeListener = new BufferChangeListener() { BufferChangeListener bufferChangeListener = new BufferChangeListener() {
@Override @Override
public void act() { public void onPacket() {
if (handler.isEncryptedStream()) { if (handler.isEncryptedStream()) {
onSendFirstEncryptedMessage(handler); onSendFirstEncryptedMessage(handler);
handler.getBufferChangeObservable().removeListener(this); handler.getPacketReceivedObservable().removeListener(this);
} }
} }
}; };
handler.getBufferChangeObservable().addListener(bufferChangeListener); handler.getPacketReceivedObservable().addListener(bufferChangeListener);
} }
} }
private void onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler) { private void onSendFirstEncryptedMessage(EncryptedPacketHandler flashPacketHandler) {
if (!HConnection.DECRYPTPACKETS) return; if (!HConnection.DECRYPTPACKETS) return;
flashPacketHandlers.forEach(FlashPacketHandler::block); flashPacketHandlers.forEach(EncryptedPacketHandler::block);
new Thread(() -> { new Thread(() -> {
@ -99,11 +99,11 @@ public class Rc4Obtainer {
if (DEBUG) if (DEBUG)
System.out.println("Cracked RC4 in " + (endTime - startTime) + "ms"); System.out.println("Cracked RC4 in " + (endTime - startTime) + "ms");
flashPacketHandlers.forEach(FlashPacketHandler::unblock); flashPacketHandlers.forEach(EncryptedPacketHandler::unblock);
}).start(); }).start();
} }
private boolean onSendFirstEncryptedMessage(FlashPacketHandler flashPacketHandler, List<byte[]> potentialRC4tables) { private boolean onSendFirstEncryptedMessage(EncryptedPacketHandler flashPacketHandler, List<byte[]> potentialRC4tables) {
for (byte[] possible : potentialRC4tables) for (byte[] possible : potentialRC4tables)
if (isCorrectRC4Table(flashPacketHandler, possible)) if (isCorrectRC4Table(flashPacketHandler, possible))
@ -112,7 +112,7 @@ public class Rc4Obtainer {
return false; return false;
} }
private boolean isCorrectRC4Table(FlashPacketHandler flashPacketHandler, byte[] possible) { private boolean isCorrectRC4Table(EncryptedPacketHandler flashPacketHandler, byte[] possible) {
try { try {
@ -127,7 +127,7 @@ public class Rc4Obtainer {
final byte[] keycpy = Arrays.copyOf(possible, possible.length); final byte[] keycpy = Arrays.copyOf(possible, possible.length);
final RC4 rc4Tryout = new RC4(keycpy, i, j); final RC4 rc4Tryout = new RC4(keycpy, i, j);
if (flashPacketHandler.getMessageSide() == HMessage.Direction.TOSERVER) if (flashPacketHandler.getDirection() == HMessage.Direction.TOSERVER)
rc4Tryout.undoRc4(encBuffer); rc4Tryout.undoRc4(encBuffer);
if (rc4Tryout.couldBeFresh()) { if (rc4Tryout.couldBeFresh()) {

View File

@ -0,0 +1,133 @@
package gearth.protocol.packethandler;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage;
import gearth.protocol.TrafficListener;
import gearth.protocol.crypto.RC4;
import gearth.protocol.packethandler.flash.BufferChangeListener;
import gearth.services.extension_handler.ExtensionHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public abstract class EncryptedPacketHandler extends PacketHandler {
private static final Logger logger = LoggerFactory.getLogger(EncryptedPacketHandler.class);
/**
* Fires when a packet is received.
*/
private final Observable<BufferChangeListener> packetReceivedObservable;
private final HMessage.Direction direction;
private volatile boolean isTempBlocked;
private volatile boolean isEncryptedStream;
private volatile List<Byte> tempEncryptedBuffer;
private RC4 encryptCipher;
private RC4 decryptCipher;
protected EncryptedPacketHandler(ExtensionHandler extensionHandler, Observable<TrafficListener>[] trafficObservables, HMessage.Direction direction) {
super(extensionHandler, trafficObservables);
this.packetReceivedObservable = new Observable<>(BufferChangeListener::onPacket);
this.direction = direction;
this.isTempBlocked = false;
this.isEncryptedStream = false;
this.tempEncryptedBuffer = new ArrayList<>();
}
public boolean isBlocked() {
return isTempBlocked;
}
public void setEncryptedStream() {
isEncryptedStream = true;
}
public boolean isEncryptedStream() {
return isEncryptedStream;
}
public HMessage.Direction getDirection() {
return direction;
}
public Observable<BufferChangeListener> getPacketReceivedObservable() {
return packetReceivedObservable;
}
@Override
public void act(byte[] buffer) throws IOException {
packetReceivedObservable.fireEvent();
if (!isEncryptedStream()) {
writeBuffer(buffer);
} else if (!HConnection.DECRYPTPACKETS) {
writeOut(buffer);
} else if (decryptCipher == null) {
for (int i = 0; i < buffer.length; i++) {
tempEncryptedBuffer.add(buffer[i]);
}
} else {
writeBuffer(decryptCipher.rc4(buffer));
}
}
protected byte[] encrypt(byte[] buffer) {
return encryptCipher.rc4(buffer);
}
protected byte[] decrypt(byte[] buffer) {
return decryptCipher.rc4(buffer);
}
protected abstract void writeOut(byte[] buffer) throws IOException;
protected abstract void writeBuffer(byte[] buffer) throws IOException;
protected abstract void flush() throws IOException;
public void block() {
isTempBlocked = true;
}
public void unblock() {
try {
flush();
} catch (IOException e) {
logger.error("Failed to flush buffer after unblocking packet handler", e);
}
isTempBlocked = false;
}
public void setRc4(RC4 rc4) {
this.decryptCipher = rc4.deepCopy();
this.encryptCipher = rc4.deepCopy();
final byte[] buffer = new byte[tempEncryptedBuffer.size()];
for (int i = 0; i < tempEncryptedBuffer.size(); i++) {
buffer[i] = tempEncryptedBuffer.get(i);
}
try {
// Write out all captured packets.
act(buffer);
} catch (IOException e) {
logger.error("Failed to write out captured encrypted buffer", e);
}
this.tempEncryptedBuffer.clear();
this.tempEncryptedBuffer = null;
}
public List<Byte> getEncryptedBuffer() {
return tempEncryptedBuffer;
}
}

View File

@ -9,23 +9,23 @@ import java.io.IOException;
public abstract class PacketHandler { public abstract class PacketHandler {
protected final ExtensionHandler extensionHandler; private final ExtensionHandler extensionHandler;
private final Object[] trafficObservables; //get notified on packet send private final Observable<TrafficListener>[] trafficObservables; //get notified on packet send
protected volatile int currentIndex = 0; protected volatile int currentIndex = 0;
protected final Object sendLock = new Object(); protected final Object sendLock = new Object();
protected final Object flushLock = new Object();
protected PacketHandler(ExtensionHandler extensionHandler, Object[] trafficObservables) { protected PacketHandler(ExtensionHandler extensionHandler, Observable<TrafficListener>[] trafficObservables) {
this.extensionHandler = extensionHandler; this.extensionHandler = extensionHandler;
this.trafficObservables = trafficObservables; this.trafficObservables = trafficObservables;
} }
public abstract boolean sendToStream(byte[] buffer); public abstract boolean sendToStream(byte[] buffer);
public abstract void act(byte[] buffer) throws IOException; public abstract void act(byte[] buffer) throws IOException;
protected void notifyListeners(int i, HMessage message) { protected void notifyListeners(int i, HMessage message) {
((Observable<TrafficListener>) trafficObservables[i]).fireEvent(trafficListener -> { trafficObservables[i].fireEvent(trafficListener -> {
message.getPacket().resetReadIndex(); message.getPacket().resetReadIndex();
trafficListener.onCapture(message); trafficListener.onCapture(message);
}); });
@ -33,10 +33,10 @@ public abstract class PacketHandler {
} }
protected void awaitListeners(HMessage message, PacketSender packetSender) { protected void awaitListeners(HMessage message, PacketSender packetSender) {
notifyListeners(0, message); notifyListeners(TrafficListener.BEFORE_MODIFICATION, message);
notifyListeners(1, message); notifyListeners(TrafficListener.MODIFICATION, message);
extensionHandler.handle(message, message2 -> { extensionHandler.handle(message, message2 -> {
notifyListeners(2, message2); notifyListeners(TrafficListener.AFTER_MODIFICATION, message2);
if (!message2.isBlocked()) { if (!message2.isBlocked()) {
packetSender.send(message2); packetSender.send(message2);
} }

View File

@ -3,6 +3,6 @@ package gearth.protocol.packethandler.flash;
public interface BufferChangeListener { public interface BufferChangeListener {
void act(); void onPacket();
} }

View File

@ -1,53 +1,37 @@
package gearth.protocol.packethandler.flash; package gearth.protocol.packethandler.flash;
import gearth.misc.listenerpattern.Observable; import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HConnection;
import gearth.protocol.HMessage; import gearth.protocol.HMessage;
import gearth.protocol.HPacket; import gearth.protocol.HPacket;
import gearth.protocol.crypto.RC4; import gearth.protocol.TrafficListener;
import gearth.protocol.packethandler.PacketHandler; import gearth.protocol.packethandler.EncryptedPacketHandler;
import gearth.protocol.packethandler.PayloadBuffer; import gearth.protocol.packethandler.PayloadBuffer;
import gearth.services.extension_handler.ExtensionHandler; import gearth.services.extension_handler.ExtensionHandler;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
public abstract class FlashPacketHandler extends PacketHandler { public abstract class FlashPacketHandler extends EncryptedPacketHandler {
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<Byte> tempEncryptedBuffer = new ArrayList<>();
volatile boolean isEncryptedStream = false;
private final OutputStream out;
private final PayloadBuffer payloadBuffer; private final PayloadBuffer payloadBuffer;
private volatile boolean isDataStream;
FlashPacketHandler(HMessage.Direction direction, OutputStream outputStream, Observable<TrafficListener>[] trafficObservables, ExtensionHandler extensionHandler) {
FlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) { super(extensionHandler, trafficObservables, direction);
super(extensionHandler, trafficObservables); this.out = outputStream;
out = outputStream;
this.payloadBuffer = new PayloadBuffer(); this.payloadBuffer = new PayloadBuffer();
this.isDataStream = false;
}
public boolean isDataStream() {
return isDataStream;
} }
public boolean isDataStream() {return isDataStream;}
public void setAsDataStream() { public void setAsDataStream() {
isDataStream = true; isDataStream = true;
} }
public boolean isEncryptedStream() {
return isEncryptedStream;
}
public void act(byte[] buffer) throws IOException { public void act(byte[] buffer) throws IOException {
if (!isDataStream) { if (!isDataStream) {
synchronized (sendLock) { synchronized (sendLock) {
@ -56,76 +40,33 @@ public abstract class FlashPacketHandler extends PacketHandler {
return; return;
} }
bufferChangeObservable.fireEvent(); super.act(buffer);
if (!isEncryptedStream) { if (!isBlocked()) {
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(); flush();
} }
} }
@Override
public void setRc4(RC4 rc4) { protected void writeOut(byte[] buffer) throws IOException {
this.decryptcipher = rc4.deepCopy(); synchronized (sendLock) {
this.encryptcipher = rc4.deepCopy(); out.write(buffer);
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() { @Override
isTempBlocked = true; protected void writeBuffer(byte[] buffer) {
} payloadBuffer.push(buffer);
public void unblock() {
try {
flush();
} catch (IOException e) {
e.printStackTrace();
}
isTempBlocked = false;
} }
public boolean sendToStream(byte[] buffer) { public boolean sendToStream(byte[] buffer) {
return sendToStream(buffer, isEncryptedStream); return sendToStream(buffer, isEncryptedStream());
} }
private boolean sendToStream(byte[] buffer, boolean isEncrypted) { private boolean sendToStream(byte[] buffer, boolean isEncrypted) {
synchronized (sendLock) { synchronized (sendLock) {
try { try {
out.write( out.write(isEncrypted ? encrypt(buffer) : buffer);
(!isEncrypted)
? buffer
: encryptcipher.rc4(buffer)
);
return true; return true;
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); e.printStackTrace();
@ -135,12 +76,12 @@ public abstract class FlashPacketHandler extends PacketHandler {
} }
public void flush() throws IOException { public void flush() throws IOException {
synchronized (manipulationLock) { synchronized (flushLock) {
HPacket[] hpackets = payloadBuffer.receive(); HPacket[] hpackets = payloadBuffer.receive();
for (HPacket hpacket : hpackets){ for (HPacket hpacket : hpackets){
HMessage hMessage = new HMessage(hpacket, getMessageSide(), currentIndex); HMessage hMessage = new HMessage(hpacket, getDirection(), currentIndex);
boolean isencrypted = isEncryptedStream; boolean isencrypted = isEncryptedStream();
if (isDataStream) { if (isDataStream) {
awaitListeners(hMessage, hMessage1 -> sendToStream(hMessage1.getPacket().toBytes(), isencrypted)); awaitListeners(hMessage, hMessage1 -> sendToStream(hMessage1.getPacket().toBytes(), isencrypted));
@ -153,21 +94,4 @@ public abstract class FlashPacketHandler extends PacketHandler {
} }
} }
} }
public abstract HMessage.Direction getMessageSide();
public List<Byte> getEncryptedBuffer() {
return tempEncryptedBuffer;
}
protected abstract void printForDebugging(byte[] bytes);
private Observable<BufferChangeListener> bufferChangeObservable = new Observable<>(BufferChangeListener::act);
public Observable<BufferChangeListener> getBufferChangeObservable() {
return bufferChangeObservable;
}
public int getCurrentIndex() {
return currentIndex;
}
} }

View File

@ -10,39 +10,29 @@ import java.io.OutputStream;
public class IncomingFlashPacketHandler extends FlashPacketHandler { public class IncomingFlashPacketHandler extends FlashPacketHandler {
public IncomingFlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, OutgoingFlashPacketHandler outgoingHandler, ExtensionHandler extensionHandler) { public IncomingFlashPacketHandler(OutputStream outputStream, Observable<TrafficListener>[] trafficObservables, OutgoingFlashPacketHandler outgoingHandler, ExtensionHandler extensionHandler) {
super(outputStream, trafficObservables, extensionHandler); super(HMessage.Direction.TOCLIENT, outputStream, trafficObservables, extensionHandler);
TrafficListener listener = new TrafficListener() { TrafficListener listener = new TrafficListener() {
@Override @Override
public void onCapture(HMessage message) { public void onCapture(HMessage message) {
if (isDataStream && message.getPacket().structureEquals("sb") && message.getPacket().length() > 500) { if (isDataStream() && message.getPacket().structureEquals("sb") && message.getPacket().length() > 500) {
((Observable<TrafficListener>)trafficObservables[0]).removeListener(this); trafficObservables[TrafficListener.BEFORE_MODIFICATION].removeListener(this);
HPacket packet = message.getPacket(); HPacket packet = message.getPacket();
packet.readString(); packet.readString();
isEncryptedStream = packet.readBoolean(); if (packet.readBoolean()) {
outgoingHandler.isEncryptedStream = true; setEncryptedStream();
} }
else if (isDataStream && message.getPacket().structureEquals("s") && message.getPacket().length() > 200) { outgoingHandler.setEncryptedStream();
((Observable<TrafficListener>)trafficObservables[0]).removeListener(this); } else if (isDataStream() && message.getPacket().structureEquals("s") && message.getPacket().length() > 200) {
outgoingHandler.isEncryptedStream = true; trafficObservables[TrafficListener.BEFORE_MODIFICATION].removeListener(this);
} outgoingHandler.setEncryptedStream();
else if (message.getIndex() > 1) { } else if (message.getIndex() > 1) {
((Observable<TrafficListener>)trafficObservables[0]).removeListener(this); trafficObservables[TrafficListener.BEFORE_MODIFICATION].removeListener(this);
} }
} }
}; };
((Observable<TrafficListener>)trafficObservables[0]).addListener(listener); trafficObservables[TrafficListener.BEFORE_MODIFICATION].addListener(listener);
}
@Override
public HMessage.Direction getMessageSide() {
return HMessage.Direction.TOCLIENT;
}
@Override
protected void printForDebugging(byte[] bytes) {
System.out.println("-- DEBUG INCOMING -- " + new HPacket(bytes).toString() + " -- DEBUG --");
} }
} }

View File

@ -3,6 +3,7 @@ package gearth.protocol.packethandler.flash;
import gearth.misc.listenerpattern.Observable; import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HMessage; import gearth.protocol.HMessage;
import gearth.protocol.HPacket; import gearth.protocol.HPacket;
import gearth.protocol.TrafficListener;
import gearth.services.extension_handler.ExtensionHandler; import gearth.services.extension_handler.ExtensionHandler;
import java.io.IOException; import java.io.IOException;
@ -10,27 +11,34 @@ import java.io.OutputStream;
public class OutgoingFlashPacketHandler extends FlashPacketHandler { public class OutgoingFlashPacketHandler extends FlashPacketHandler {
public OutgoingFlashPacketHandler(OutputStream outputStream, Object[] trafficObservables, ExtensionHandler extensionHandler) { private final Observable<OnDatastreamConfirmedListener> datastreamConfirmedObservable;
super(outputStream, trafficObservables, extensionHandler);
public OutgoingFlashPacketHandler(OutputStream outputStream, Observable<TrafficListener>[] trafficObservables, ExtensionHandler extensionHandler) {
super(HMessage.Direction.TOSERVER, outputStream, trafficObservables, extensionHandler);
this.datastreamConfirmedObservable = new Observable<>();
} }
private Observable<OnDatastreamConfirmedListener> datastreamConfirmedObservable = new Observable<>();
public void addOnDatastreamConfirmedListener(OnDatastreamConfirmedListener listener) { public void addOnDatastreamConfirmedListener(OnDatastreamConfirmedListener listener) {
datastreamConfirmedObservable.addListener(listener); datastreamConfirmedObservable.addListener(listener);
} }
private void dataStreamCheck(byte[] buffer) { private void dataStreamCheck(byte[] buffer) {
if (!isDataStream) { if (isDataStream()) {
HPacket hpacket = new HPacket(buffer); return;
isDataStream = (hpacket.getBytesLength() > 6 && hpacket.length() < 100);
if (isDataStream) {
String hotelVersion = hpacket.readString();
String clientIdentifier = hpacket.readString();
datastreamConfirmedObservable.fireEvent(l -> l.confirm(hotelVersion, clientIdentifier));
}
} }
final HPacket hpacket = new HPacket(buffer);
final boolean isValid = (hpacket.getBytesLength() > 6 && hpacket.length() < 100);
if (!isValid) return;
setAsDataStream();
final String hotelVersion = hpacket.readString();
final String clientIdentifier = hpacket.readString();
datastreamConfirmedObservable.fireEvent(l -> l.confirm(hotelVersion, clientIdentifier));
} }
@Override @Override
@ -38,15 +46,4 @@ public class OutgoingFlashPacketHandler extends FlashPacketHandler {
dataStreamCheck(buffer); dataStreamCheck(buffer);
super.act(buffer); super.act(buffer);
} }
@Override
public HMessage.Direction getMessageSide() {
return HMessage.Direction.TOSERVER;
}
@Override
protected void printForDebugging(byte[] bytes) {
System.out.println("-- DEBUG OUTGOING -- " + new HPacket(bytes).toString() + " -- DEBUG --");
}
} }

View File

@ -1,7 +1,9 @@
package gearth.protocol.packethandler.nitro; package gearth.protocol.packethandler.nitro;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HMessage; import gearth.protocol.HMessage;
import gearth.protocol.HPacket; import gearth.protocol.HPacket;
import gearth.protocol.TrafficListener;
import gearth.protocol.connection.proxy.nitro.websocket.NitroSession; import gearth.protocol.connection.proxy.nitro.websocket.NitroSession;
import gearth.protocol.packethandler.PacketHandler; import gearth.protocol.packethandler.PacketHandler;
import gearth.protocol.packethandler.PayloadBuffer; import gearth.protocol.packethandler.PayloadBuffer;
@ -22,7 +24,7 @@ public class NitroPacketHandler extends PacketHandler {
private final PayloadBuffer payloadBuffer; private final PayloadBuffer payloadBuffer;
private final Object payloadLock; private final Object payloadLock;
public NitroPacketHandler(HMessage.Direction direction, NitroSession session, ExtensionHandler extensionHandler, Object[] trafficObservables) { public NitroPacketHandler(HMessage.Direction direction, NitroSession session, ExtensionHandler extensionHandler, Observable<TrafficListener>[] trafficObservables) {
super(extensionHandler, trafficObservables); super(extensionHandler, trafficObservables);
this.direction = direction; this.direction = direction;
this.session = session; this.session = session;

View File

@ -1,7 +1,9 @@
package gearth.protocol.packethandler.unity; package gearth.protocol.packethandler.unity;
import gearth.misc.listenerpattern.Observable;
import gearth.protocol.HMessage; import gearth.protocol.HMessage;
import gearth.protocol.HPacket; import gearth.protocol.HPacket;
import gearth.protocol.TrafficListener;
import gearth.protocol.packethandler.ByteArrayUtils; import gearth.protocol.packethandler.ByteArrayUtils;
import gearth.protocol.packethandler.PacketHandler; import gearth.protocol.packethandler.PacketHandler;
import gearth.services.extension_handler.ExtensionHandler; import gearth.services.extension_handler.ExtensionHandler;
@ -15,7 +17,7 @@ public class UnityPacketHandler extends PacketHandler {
private final Session session; private final Session session;
private final HMessage.Direction direction; private final HMessage.Direction direction;
public UnityPacketHandler(ExtensionHandler extensionHandler, Object[] trafficObservables, Session session, HMessage.Direction direction) { public UnityPacketHandler(ExtensionHandler extensionHandler, Observable<TrafficListener>[] trafficObservables, Session session, HMessage.Direction direction) {
super(extensionHandler, trafficObservables); super(extensionHandler, trafficObservables);
this.session = session; this.session = session;
this.direction = direction; this.direction = direction;