diff --git a/G-Earth/src/main/java/gearth/protocol/HMessage.java b/G-Earth/src/main/java/gearth/protocol/HMessage.java index 4c5659d..b1e970f 100644 --- a/G-Earth/src/main/java/gearth/protocol/HMessage.java +++ b/G-Earth/src/main/java/gearth/protocol/HMessage.java @@ -74,7 +74,7 @@ public class HMessage implements StringifyAble { this.isBlocked = message.isBlocked(); this.index = message.getIndex(); this.direction = message.getDestination(); - this.hPacket = new HPacket(message.getPacket()); + this.hPacket = message.getPacket().copy(); } @Override diff --git a/G-Earth/src/main/java/gearth/protocol/HPacket.java b/G-Earth/src/main/java/gearth/protocol/HPacket.java index bceb962..a6c6d5a 100644 --- a/G-Earth/src/main/java/gearth/protocol/HPacket.java +++ b/G-Earth/src/main/java/gearth/protocol/HPacket.java @@ -17,7 +17,7 @@ import java.util.Optional; public class HPacket implements StringifyAble { private boolean isEdited = false; - private byte[] packetInBytes; + protected byte[] packetInBytes; private int readIndex = 6; // if identifier != null, this is a placeholder name for the type of packet, headerId will be "-1" @@ -754,5 +754,8 @@ public class HPacket implements StringifyAble { HPacket packet2 = (HPacket) object; return Arrays.equals(packetInBytes, packet2.packetInBytes) && (isEdited == packet2.isEdited); } - + + public HPacket copy() { + return new HPacket(this); + } } diff --git a/G-Earth/src/main/java/gearth/protocol/TrafficListener.java b/G-Earth/src/main/java/gearth/protocol/TrafficListener.java index f660f8f..da5a11c 100644 --- a/G-Earth/src/main/java/gearth/protocol/TrafficListener.java +++ b/G-Earth/src/main/java/gearth/protocol/TrafficListener.java @@ -1,11 +1,7 @@ package gearth.protocol; -import gearth.protocol.format.shockwave.ShockMessage; - public interface TrafficListener { void onCapture(HMessage message); - void onCapture(ShockMessage message); - } diff --git a/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockMessage.java b/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockMessage.java deleted file mode 100644 index 3a18e95..0000000 --- a/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockMessage.java +++ /dev/null @@ -1,35 +0,0 @@ -package gearth.protocol.format.shockwave; - -import gearth.protocol.HMessage; - -public class ShockMessage { - - private final ShockPacket packet; - private final HMessage.Direction direction; - private final int index; - - private boolean isBlocked; - - public ShockMessage(ShockPacket packet, HMessage.Direction direction, int index) { - this.packet = packet; - this.direction = direction; - this.index = index; - this.isBlocked = false; - } - - public ShockPacket getPacket() { - return packet; - } - - public HMessage.Direction getDirection() { - return direction; - } - - public int getIndex() { - return index; - } - - public boolean isBlocked() { - return isBlocked; - } -} diff --git a/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacket.java b/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacket.java deleted file mode 100644 index 41164f0..0000000 --- a/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacket.java +++ /dev/null @@ -1,15 +0,0 @@ -package gearth.protocol.format.shockwave; - -import gearth.protocol.HMessage; - -public class ShockPacket { - - public ShockPacket(HMessage.Direction direction, byte[] data) { - - } - - public void resetReadIndex() { - - } - -} diff --git a/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacketIn.java b/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacketIn.java deleted file mode 100644 index 8f10c6f..0000000 --- a/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacketIn.java +++ /dev/null @@ -1,4 +0,0 @@ -package gearth.protocol.format.shockwave; - -public class ShockPacketIn { -} diff --git a/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacketOut.java b/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacketOut.java deleted file mode 100644 index 72805b5..0000000 --- a/G-Earth/src/main/java/gearth/protocol/format/shockwave/ShockPacketOut.java +++ /dev/null @@ -1,4 +0,0 @@ -package gearth.protocol.format.shockwave; - -public class ShockPacketOut { -} 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 78bca47..9748dd3 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/PacketHandler.java @@ -3,7 +3,6 @@ package gearth.protocol.packethandler; import gearth.misc.listenerpattern.Observable; import gearth.protocol.HMessage; import gearth.protocol.TrafficListener; -import gearth.protocol.format.shockwave.ShockMessage; import gearth.services.extension_handler.ExtensionHandler; import java.io.IOException; @@ -33,14 +32,6 @@ public abstract class PacketHandler { message.getPacket().resetReadIndex(); } - protected void notifyListeners(int i, ShockMessage message) { - ((Observable) trafficObservables[i]).fireEvent(trafficListener -> { - message.getPacket().resetReadIndex(); - trafficListener.onCapture(message); - }); - message.getPacket().resetReadIndex(); - } - protected void awaitListeners(HMessage message, PacketSender packetSender) { notifyListeners(0, message); notifyListeners(1, message); @@ -52,15 +43,4 @@ public abstract class PacketHandler { }); } - protected void awaitListeners(ShockMessage message, PacketSender packetSender) { - notifyListeners(0, message); - notifyListeners(1, message); - extensionHandler.handle(message, message2 -> { - notifyListeners(2, message2); - if (!message2.isBlocked()) { - packetSender.send(message2); - } - }); - } - } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketHandler.java index 8a29682..ece52b6 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketHandler.java @@ -1,8 +1,7 @@ package gearth.protocol.packethandler.shockwave; import gearth.protocol.HMessage; -import gearth.protocol.format.shockwave.ShockMessage; -import gearth.protocol.format.shockwave.ShockPacket; +import gearth.protocol.HPacket; import gearth.protocol.packethandler.PacketHandler; import gearth.protocol.packethandler.shockwave.buffers.ShockwaveBuffer; import gearth.services.extension_handler.ExtensionHandler; @@ -14,13 +13,14 @@ import java.io.OutputStream; public abstract class ShockwavePacketHandler extends PacketHandler { - private static final Logger logger = LoggerFactory.getLogger(ShockwavePacketHandler.class); + protected static final Logger logger = LoggerFactory.getLogger(ShockwavePacketHandler.class); private final HMessage.Direction direction; private final ShockwaveBuffer payloadBuffer; - private final OutputStream outputStream; private final Object flushLock; + protected final OutputStream outputStream; + ShockwavePacketHandler(HMessage.Direction direction, ShockwaveBuffer payloadBuffer, OutputStream outputStream, ExtensionHandler extensionHandler, Object[] trafficObservables) { super(extensionHandler, trafficObservables); this.direction = direction; @@ -29,21 +29,10 @@ public abstract class ShockwavePacketHandler extends PacketHandler { this.flushLock = new Object(); } - @Override - public boolean sendToStream(byte[] buffer) { - synchronized (sendLock) { - try { - outputStream.write(buffer); - return true; - } catch (IOException e) { - logger.error("Error while sending packet to stream.", e); - return false; - } - } - } - @Override public void act(byte[] buffer) throws IOException { + logger.info("Direction {} Received {} bytes", this.direction, buffer.length); + payloadBuffer.push(buffer); flush(); @@ -51,10 +40,10 @@ public abstract class ShockwavePacketHandler extends PacketHandler { public void flush() throws IOException { synchronized (flushLock) { - final ShockPacket[] packets = payloadBuffer.receive(); + final HPacket[] packets = payloadBuffer.receive(); - for (final ShockPacket packet : packets){ - final ShockMessage message = new ShockMessage(packet, direction, currentIndex); + for (final HPacket packet : packets){ + final HMessage message = new HMessage(packet, direction, currentIndex); awaitListeners(message, x -> sendToStream(x.getPacket().toBytes())); diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketIncomingHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketIncomingHandler.java index 7e9a2da..d4596e9 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketIncomingHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketIncomingHandler.java @@ -4,10 +4,25 @@ import gearth.protocol.HMessage; import gearth.protocol.packethandler.shockwave.buffers.ShockwaveInBuffer; import gearth.services.extension_handler.ExtensionHandler; +import java.io.IOException; import java.io.OutputStream; public class ShockwavePacketIncomingHandler extends ShockwavePacketHandler { public ShockwavePacketIncomingHandler(OutputStream outputStream, ExtensionHandler extensionHandler, Object[] trafficObservables) { super(HMessage.Direction.TOCLIENT, new ShockwaveInBuffer(), outputStream, extensionHandler, trafficObservables); } + + @Override + public boolean sendToStream(byte[] buffer) { + synchronized (sendLock) { + try { + outputStream.write(buffer); + outputStream.write(new byte[] {0x01}); + return true; + } catch (IOException e) { + logger.error("Error while sending packet to stream.", e); + return false; + } + } + } } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketOutgoingHandler.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketOutgoingHandler.java index 7ea0a66..c155b81 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketOutgoingHandler.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/ShockwavePacketOutgoingHandler.java @@ -1,13 +1,31 @@ package gearth.protocol.packethandler.shockwave; +import gearth.encoding.Base64Encoding; import gearth.protocol.HMessage; import gearth.protocol.packethandler.shockwave.buffers.ShockwaveOutBuffer; import gearth.services.extension_handler.ExtensionHandler; +import java.io.IOException; import java.io.OutputStream; public class ShockwavePacketOutgoingHandler extends ShockwavePacketHandler { public ShockwavePacketOutgoingHandler(OutputStream outputStream, ExtensionHandler extensionHandler, Object[] trafficObservables) { super(HMessage.Direction.TOSERVER, new ShockwaveOutBuffer(), outputStream, extensionHandler, trafficObservables); } + + @Override + public boolean sendToStream(byte[] buffer) { + synchronized (sendLock) { + try { + byte[] bufferLen = Base64Encoding.encode(buffer.length, 3); + + outputStream.write(bufferLen); + outputStream.write(buffer); + return true; + } catch (IOException e) { + logger.error("Error while sending packet to stream.", e); + return false; + } + } + } } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveBuffer.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveBuffer.java index 36c0c09..81f6622 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveBuffer.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveBuffer.java @@ -1,11 +1,11 @@ package gearth.protocol.packethandler.shockwave.buffers; -import gearth.protocol.format.shockwave.ShockPacket; +import gearth.protocol.HPacket; public interface ShockwaveBuffer { void push(byte[] data); - ShockPacket[] receive(); + HPacket[] receive(); } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveInBuffer.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveInBuffer.java index 94d43d4..3e9fbc0 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveInBuffer.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveInBuffer.java @@ -1,7 +1,8 @@ package gearth.protocol.packethandler.shockwave.buffers; -import gearth.protocol.format.shockwave.ShockPacket; +import gearth.protocol.HPacket; import gearth.protocol.packethandler.ByteArrayUtils; +import gearth.protocol.packethandler.shockwave.packets.ShockPacket; import java.util.ArrayList; import java.util.Arrays; @@ -16,7 +17,7 @@ public class ShockwaveInBuffer implements ShockwaveBuffer { } @Override - public ShockPacket[] receive() { + public HPacket[] receive() { if (buffer.length < 3) { return new ShockPacket[0]; } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveOutBuffer.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveOutBuffer.java index ef62fc1..c4994c9 100644 --- a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveOutBuffer.java +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/buffers/ShockwaveOutBuffer.java @@ -1,13 +1,20 @@ package gearth.protocol.packethandler.shockwave.buffers; +import gearth.encoding.Base64Encoding; import gearth.protocol.HPacket; -import gearth.protocol.format.shockwave.ShockPacket; import gearth.protocol.packethandler.ByteArrayUtils; +import gearth.protocol.packethandler.shockwave.packets.ShockPacket; import java.util.ArrayList; +import java.util.Arrays; public class ShockwaveOutBuffer implements ShockwaveBuffer { + private static final int PACKET_LENGTH_SIZE = 3; + private static final int PACKET_HEADER_SIZE = 2; + + private static final int PACKET_SIZE_MIN = PACKET_LENGTH_SIZE + PACKET_HEADER_SIZE; + private byte[] buffer = new byte[0]; @Override @@ -16,13 +23,27 @@ public class ShockwaveOutBuffer implements ShockwaveBuffer { } @Override - public ShockPacket[] receive() { - if (buffer.length < 5) { + public HPacket[] receive() { + if (buffer.length < PACKET_SIZE_MIN) { return new ShockPacket[0]; } - ArrayList all = new ArrayList<>(); + ArrayList out = new ArrayList<>(); - return all.toArray(new ShockPacket[all.size()]); + while (buffer.length >= PACKET_SIZE_MIN) { + int length = Base64Encoding.decode(new byte[]{buffer[0], buffer[1], buffer[2]}); + if (buffer.length < length + PACKET_LENGTH_SIZE) { + break; + } + + int endPos = length + PACKET_LENGTH_SIZE; + byte[] packet = Arrays.copyOfRange(buffer, PACKET_LENGTH_SIZE, endPos); + + out.add(new ShockPacket(packet)); + + buffer = Arrays.copyOfRange(buffer, endPos, buffer.length); + } + + return out.toArray(new ShockPacket[0]); } } diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java new file mode 100644 index 0000000..4c43c27 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacket.java @@ -0,0 +1,60 @@ +package gearth.protocol.packethandler.shockwave.packets; + +import gearth.encoding.Base64Encoding; +import gearth.protocol.HMessage; +import gearth.protocol.HPacket; + +import java.nio.charset.StandardCharsets; +import java.security.InvalidParameterException; + +public class ShockPacket extends HPacket { + public ShockPacket(byte[] packet) { + super(packet); + } + + public ShockPacket(HPacket packet) { + super(packet); + } + + public ShockPacket(String packet) { + super(packet); + } + + public ShockPacket(int header) { + super(header); + } + + public ShockPacket(int header, byte[] bytes) { + super(header, bytes); + } + + public ShockPacket(int header, Object... objects) throws InvalidParameterException { + super(header, objects); + } + + public ShockPacket(String identifier, HMessage.Direction direction) throws InvalidParameterException { + super(identifier, direction); + } + + public ShockPacket(String identifier, HMessage.Direction direction, Object... objects) throws InvalidParameterException { + super(identifier, direction, objects); + } + + @Override + public int headerId() { + final String header = new String(this.readBytes(2, 0), StandardCharsets.ISO_8859_1); + final int headerId = Base64Encoding.decode(header.getBytes()); + + return headerId; + } + + @Override + public int length() { + return this.packetInBytes.length; + } + + @Override + public HPacket copy() { + return new ShockPacket(this); + } +} diff --git a/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketUnsupported.java b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketUnsupported.java new file mode 100644 index 0000000..b5c00b8 --- /dev/null +++ b/G-Earth/src/main/java/gearth/protocol/packethandler/shockwave/packets/ShockPacketUnsupported.java @@ -0,0 +1,7 @@ +package gearth.protocol.packethandler.shockwave.packets; + +public class ShockPacketUnsupported extends UnsupportedOperationException { + public ShockPacketUnsupported(String message) { + super(message); + } +} diff --git a/G-Earth/src/main/java/gearth/services/extension_handler/ExtensionHandler.java b/G-Earth/src/main/java/gearth/services/extension_handler/ExtensionHandler.java index a7d1e53..1c42506 100644 --- a/G-Earth/src/main/java/gearth/services/extension_handler/ExtensionHandler.java +++ b/G-Earth/src/main/java/gearth/services/extension_handler/ExtensionHandler.java @@ -7,7 +7,6 @@ import gearth.protocol.HConnection; import gearth.protocol.HMessage; import gearth.protocol.HPacket; import gearth.protocol.connection.HState; -import gearth.protocol.format.shockwave.ShockMessage; import gearth.services.extension_handler.extensions.ExtensionListener; import gearth.services.extension_handler.extensions.GEarthExtension; import gearth.services.extension_handler.extensions.extensionproducers.ExtensionProducer; @@ -182,26 +181,6 @@ public class ExtensionHandler { maybeFinishHmessage(hMessage); } - public void handle(ShockMessage hMessage, OnHMessageHandled callback) { - synchronized (hMessageStuffLock) { - Pair msgDirectionAndId = new Pair<>(hMessage.getDirection(), hMessage.getIndex()); - originalMessages.put(msgDirectionAndId, hMessage); - finishManipulationCallback.put(hMessage, callback); - editedMessages.put(hMessage, null); - allAwaitingMessages.add(hMessage); - - synchronized (gEarthExtensions) { - awaitManipulation.put(hMessage, new HashSet<>(gEarthExtensions)); - - for (GEarthExtension extension : gEarthExtensions) { - extension.packetIntercept(new HMessage(hMessage)); - } - } - } - - maybeFinishHmessage(hMessage); - } - private ExtensionProducerObserver createExtensionProducerObserver() { return new ExtensionProducerObserver() { @Override