From 45794ab15c1c4769887ecc6c8afb3b64273c70e9 Mon Sep 17 00:00:00 2001 From: Josh Larson Date: Wed, 2 Mar 2016 10:31:26 -0600 Subject: [PATCH] Added fragmented processing to ClientReceiver --- src/com/projectswg/ClientReceiver.java | 43 +++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/com/projectswg/ClientReceiver.java b/src/com/projectswg/ClientReceiver.java index 180b223..12e4bdd 100644 --- a/src/com/projectswg/ClientReceiver.java +++ b/src/com/projectswg/ClientReceiver.java @@ -2,18 +2,21 @@ package com.projectswg; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicLong; import com.projectswg.networking.NetInterceptor; +import com.projectswg.networking.Packet; import com.projectswg.networking.UDPServer.UDPPacket; import com.projectswg.networking.encryption.Encryption; import com.projectswg.networking.soe.Acknowledge; import com.projectswg.networking.soe.ClientNetworkStatusUpdate; import com.projectswg.networking.soe.DataChannelA; import com.projectswg.networking.soe.Disconnect; +import com.projectswg.networking.soe.Fragmented; import com.projectswg.networking.soe.KeepAlive; import com.projectswg.networking.soe.MultiPacket; import com.projectswg.networking.soe.OutOfOrder; @@ -29,6 +32,7 @@ public class ClientReceiver { private final NetInterceptor interceptor; private final AtomicLong lastPacket; + private final List fragmentedBuffer; private ExecutorService executor; private ClientSender sender; private ClientReceiverCallback callback; @@ -40,6 +44,7 @@ public class ClientReceiver { public ClientReceiver(NetInterceptor interceptor) { this.interceptor = interceptor; this.lastPacket = new AtomicLong(0); + this.fragmentedBuffer = new ArrayList<>(); setConnectionState(ConnectionState.DISCONNECTED); sender = null; callback = null; @@ -138,6 +143,9 @@ public class ClientReceiver { case 9: onDataChannel(new DataChannelA(data)); break; + case 0x0D: + onFragmented(new Fragmented(data)); + break; case 17: onOutOfOrder(new OutOfOrder(data)); break; @@ -210,6 +218,39 @@ public class ClientReceiver { } } + private void onFragmented(Fragmented frag) { + if (frag.getSequence() != rxSequence+1) { + if (frag.getSequence() > rxSequence) + sender.send(new OutOfOrder(frag.getSequence())); + System.err.println("Invalid Sequence! Expected: " + (rxSequence+1) + " Actual: " + frag.getSequence()); + return; + } + rxSequence = frag.getSequence(); + sender.send(new Acknowledge(rxSequence)); + fragmentedBuffer.add(frag); + frag = fragmentedBuffer.get(0); + ByteBuffer data = frag.getPacketData(); + data.position(4); + int size = Packet.getNetInt(data); + int index = data.remaining(); + for (int i = 1; i < fragmentedBuffer.size() && index < size; i++) + index += fragmentedBuffer.get(i).getPacketData().limit()-4; + if (index == size) + processFragmentedReady(size); + } + + private void processFragmentedReady(int size) { + ByteBuffer combined = ByteBuffer.allocate(size); + while (combined.hasRemaining()) { + ByteBuffer packet = fragmentedBuffer.get(0).getPacketData(); + packet.position(combined.position() == 0 ? 8 : 4); + combined.put(packet); + fragmentedBuffer.remove(0); + } + combined.flip(); + process(combined); + } + private void onOutOfOrder(OutOfOrder ooo) { sender.onOutOfOrder(ooo.getSequence()); }