diff --git a/.classpath b/.classpath index 547b7d7..2ebdd55 100644 --- a/.classpath +++ b/.classpath @@ -1,15 +1,7 @@ - - - - - - - - - - + + diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..f55250e --- /dev/null +++ b/.gitmodules @@ -0,0 +1,9 @@ +[submodule "client-holocore"] + path = client-holocore + url = ssh://git@bitbucket.org/projectswg/client-holocore.git +[submodule "PSWGCommon"] + path = PSWGCommon + url = git@bitbucket.org:projectswg/pswgcommon.git +[submodule "Client Holocore"] + path = Client Holocore + url = ssh://git@bitbucket.org/projectswg/client-holocore.git diff --git a/.project b/.project index 2110506..073e59a 100644 --- a/.project +++ b/.project @@ -11,13 +11,13 @@ - edu.umd.cs.findbugs.plugin.eclipse.findbugsBuilder + org.eclipse.buildship.core.gradleprojectbuilder org.eclipse.jdt.core.javanature - edu.umd.cs.findbugs.plugin.eclipse.findbugsNature + org.eclipse.buildship.core.gradleprojectnature diff --git a/Client Holocore b/Client Holocore new file mode 160000 index 0000000..7f4330e --- /dev/null +++ b/Client Holocore @@ -0,0 +1 @@ +Subproject commit 7f4330e534c2ef12e993e73d1396c58fcbd7eda6 diff --git a/Forwarder.jar b/Forwarder.jar index 326be33..d3288c1 100644 Binary files a/Forwarder.jar and b/Forwarder.jar differ diff --git a/PSWGCommon b/PSWGCommon new file mode 160000 index 0000000..f5c9e09 --- /dev/null +++ b/PSWGCommon @@ -0,0 +1 @@ +Subproject commit f5c9e09dd5aa4e408f0d1bd709b6535417dc2c0d diff --git a/lib/ClientHolocore-javadoc.jar b/lib/ClientHolocore-javadoc.jar deleted file mode 100644 index e87ba9b..0000000 Binary files a/lib/ClientHolocore-javadoc.jar and /dev/null differ diff --git a/lib/ClientHolocore.jar b/lib/ClientHolocore.jar deleted file mode 100644 index a89f650..0000000 Binary files a/lib/ClientHolocore.jar and /dev/null differ diff --git a/lib/Holocore.jar b/lib/Holocore.jar index b48400f..fd7e338 100644 Binary files a/lib/Holocore.jar and b/lib/Holocore.jar differ diff --git a/lib/PSWGCommon.jar b/lib/PSWGCommon.jar deleted file mode 100644 index 2b18b1b..0000000 Binary files a/lib/PSWGCommon.jar and /dev/null differ diff --git a/src/com/projectswg/Connections.java b/src/com/projectswg/Connections.java index c1ac0a7..625318e 100644 --- a/src/com/projectswg/Connections.java +++ b/src/com/projectswg/Connections.java @@ -4,8 +4,6 @@ import java.net.InetAddress; import java.net.InetSocketAddress; import java.util.concurrent.atomic.AtomicLong; -import network.packets.swg.ErrorMessage; - import com.projectswg.common.control.IntentManager; import com.projectswg.common.control.Manager; import com.projectswg.common.debug.Log; @@ -22,6 +20,8 @@ import com.projectswg.networking.soe.Disconnect.DisconnectReason; import com.projectswg.services.PacketRecordingService; import com.projectswg.utilities.ThreadUtilities; +import network.packets.swg.ErrorMessage; + public class Connections extends Manager { public static final String VERSION = "0.9.8"; @@ -40,7 +40,7 @@ public class Connections extends Manager { } public Connections(InetAddress remoteAddr, int remotePort, int loginPort, boolean timeout) { - setIntentManager(new IntentManager()); + setIntentManager(new IntentManager(Runtime.getRuntime().availableProcessors())); this.server = new ServerConnectionService(remoteAddr, remotePort); this.client = new ClientConnectionService(loginPort, timeout); this.recording = new PacketRecordingService(); diff --git a/src/com/projectswg/Forwarder.java b/src/com/projectswg/Forwarder.java index 6eb08fe..ceeb2fe 100644 --- a/src/com/projectswg/Forwarder.java +++ b/src/com/projectswg/Forwarder.java @@ -5,6 +5,12 @@ import java.net.UnknownHostException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import com.projectswg.Connections.ConnectionCallback; +import com.projectswg.common.debug.Log; +import com.projectswg.common.debug.Log.LogLevel; +import com.projectswg.common.debug.log_wrapper.ConsoleLogWrapper; +import com.projectswg.connection.ServerConnectionStatus; + import javafx.application.Application; import javafx.application.Platform; import javafx.scene.Scene; @@ -16,12 +22,6 @@ import javafx.scene.paint.Color; import javafx.scene.text.Text; import javafx.stage.Stage; -import com.projectswg.Connections.ConnectionCallback; -import com.projectswg.common.debug.Log; -import com.projectswg.common.debug.Log.LogLevel; -import com.projectswg.common.debug.log_wrapper.ConsoleLogWrapper; -import com.projectswg.connection.ServerConnectionStatus; - public class Forwarder extends Application implements ConnectionCallback { private static final String [] DATA_NAMES = new String[]{"B", "KB", "MB", "GB", "TB"}; diff --git a/src/com/projectswg/networking/NetInterceptor.java b/src/com/projectswg/networking/NetInterceptor.java index 98a3b40..21b6162 100644 --- a/src/com/projectswg/networking/NetInterceptor.java +++ b/src/com/projectswg/networking/NetInterceptor.java @@ -1,13 +1,11 @@ package com.projectswg.networking; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; - +import com.projectswg.common.network.NetBuffer; import com.projectswg.networking.client.ClientData; -import resources.Galaxy; import network.packets.swg.login.LoginClientId; import network.packets.swg.login.LoginClusterStatus; +import resources.Galaxy; public class NetInterceptor { @@ -26,10 +24,11 @@ public class NetInterceptor { public byte [] interceptClient(byte [] data) { if (data.length < 6) return data; - ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); - switch (bb.getInt(2)) { + NetBuffer buffer = NetBuffer.wrap(data); + buffer.getShort(); + switch (buffer.getInt()) { case 0x41131F96: // LoginClientId - return setAutoLogin(bb); + return setAutoLogin(buffer); case 0x43FD1C22: // CmdSceneReady clientData.setZoning(false); return data; @@ -41,16 +40,17 @@ public class NetInterceptor { public byte [] interceptServer(byte [] data) { if (data.length < 6) return data; - ByteBuffer bb = ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN); - switch (bb.getInt(2)) { + NetBuffer buffer = NetBuffer.wrap(data); + buffer.getShort(); + switch (buffer.getInt()) { case 0x3436AEB6: // LoginClusterStatus - return getServerList(bb); + return getServerList(buffer); default: return data; } } - private byte [] setAutoLogin(ByteBuffer data) { + private byte [] setAutoLogin(NetBuffer data) { LoginClientId id = new LoginClientId(data); if (!id.getUsername().equals(properties.getUsername()) || !id.getPassword().isEmpty()) return data.array(); @@ -58,7 +58,7 @@ public class NetInterceptor { return id.encode().array(); } - private byte [] getServerList(ByteBuffer data) { + private byte [] getServerList(NetBuffer data) { LoginClusterStatus cluster = new LoginClusterStatus(); cluster.decode(data); for (Galaxy g : cluster.getGalaxies()) { diff --git a/src/com/projectswg/networking/Packet.java b/src/com/projectswg/networking/Packet.java index 78a20ae..c6c44fe 100644 --- a/src/com/projectswg/networking/Packet.java +++ b/src/com/projectswg/networking/Packet.java @@ -35,8 +35,10 @@ import java.util.List; public class Packet { + public static final Charset ascii = Charset.forName("UTF-8"); public static final Charset unicode = Charset.forName("UTF-16LE"); + private InetAddress address; private ByteBuffer data; private int port = 0; diff --git a/src/com/projectswg/networking/client/ClientConnectionService.java b/src/com/projectswg/networking/client/ClientConnectionService.java index e37b0a9..f7ffe2d 100644 --- a/src/com/projectswg/networking/client/ClientConnectionService.java +++ b/src/com/projectswg/networking/client/ClientConnectionService.java @@ -1,8 +1,5 @@ package com.projectswg.networking.client; -import network.packets.swg.SWGPacket; -import network.packets.swg.zone.HeartBeat; - import com.projectswg.common.concurrency.Delay; import com.projectswg.common.concurrency.PswgBasicScheduledThread; import com.projectswg.common.control.Manager; @@ -18,6 +15,9 @@ import com.projectswg.networking.soe.Disconnect; import com.projectswg.networking.soe.Disconnect.DisconnectReason; import com.projectswg.resources.ClientConnectionStatus; +import network.packets.swg.SWGPacket; +import network.packets.swg.zone.HeartBeat; + public class ClientConnectionService extends Manager implements ClientPacketSender { private final NetInterceptor interceptor; diff --git a/src/com/projectswg/networking/client/ClientData.java b/src/com/projectswg/networking/client/ClientData.java index 695bbcc..f048269 100644 --- a/src/com/projectswg/networking/client/ClientData.java +++ b/src/com/projectswg/networking/client/ClientData.java @@ -20,7 +20,7 @@ public class ClientData { reset(ClientConnectionStatus.DISCONNECTED); } - public void reset(ClientConnectionStatus status) { + public void resetConnectionInfo() { setConnectionId(-1); setCommunicationPort(0); setRxSequence((short) -1); @@ -29,6 +29,10 @@ public class ClientData { setOOOSequence((short) 0); setLastAcknowledgement(0); setZoning(false); + } + + public void reset(ClientConnectionStatus status) { + resetConnectionInfo(); setStatus(status); if (status == ClientConnectionStatus.LOGIN_CONNECTED) setClientServer(ClientServer.LOGIN); diff --git a/src/com/projectswg/networking/client/ClientPacketSender.java b/src/com/projectswg/networking/client/ClientPacketSender.java index df6f476..ee7bf55 100644 --- a/src/com/projectswg/networking/client/ClientPacketSender.java +++ b/src/com/projectswg/networking/client/ClientPacketSender.java @@ -1,9 +1,9 @@ package com.projectswg.networking.client; -import network.packets.swg.SWGPacket; - import com.projectswg.networking.Packet; +import network.packets.swg.SWGPacket; + public interface ClientPacketSender { /** Adds the specified packets to a buffer to guarantee sending in-order */ diff --git a/src/com/projectswg/networking/client/receiver/ClientInboundProcessor.java b/src/com/projectswg/networking/client/receiver/ClientInboundProcessor.java index 4243904..e966dea 100644 --- a/src/com/projectswg/networking/client/receiver/ClientInboundProcessor.java +++ b/src/com/projectswg/networking/client/receiver/ClientInboundProcessor.java @@ -4,9 +4,6 @@ import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.ByteOrder; -import network.packets.swg.login.ServerId; -import network.packets.swg.login.ServerString; - import com.projectswg.common.concurrency.PswgTaskThreadPool; import com.projectswg.common.control.IntentChain; import com.projectswg.common.control.IntentManager; @@ -18,8 +15,21 @@ import com.projectswg.networking.NetInterceptor; import com.projectswg.networking.Packet; import com.projectswg.networking.client.ClientData; import com.projectswg.networking.client.ClientPacketSender; +import com.projectswg.networking.client.ClientServerSocket.ClientServer; import com.projectswg.networking.client.ClientServerSocket.IncomingPacket; -import com.projectswg.networking.soe.*; +import com.projectswg.networking.soe.Acknowledge; +import com.projectswg.networking.soe.ClientNetworkStatusUpdate; +import com.projectswg.networking.soe.DataChannel; +import com.projectswg.networking.soe.Disconnect; +import com.projectswg.networking.soe.Disconnect.DisconnectReason; +import com.projectswg.networking.soe.Fragmented; +import com.projectswg.networking.soe.KeepAlive; +import com.projectswg.networking.soe.MultiPacket; +import com.projectswg.networking.soe.OutOfOrder; +import com.projectswg.networking.soe.SequencedPacket; +import com.projectswg.networking.soe.ServerNetworkStatusUpdate; +import com.projectswg.networking.soe.SessionRequest; +import com.projectswg.networking.soe.SessionResponse; import com.projectswg.resources.ClientConnectionStatus; import com.projectswg.utilities.ByteUtilities; @@ -51,7 +61,7 @@ public class ClientInboundProcessor { } public void stop() { - processorThreadPool.stop(); + processorThreadPool.stop(false); processorThreadPool.awaitTermination(1000); } @@ -64,7 +74,6 @@ public class ClientInboundProcessor { } public void onConnected() { - packetSender.sendPackaged(new ServerString("Holocore"), new ServerId(1)); fragmentedProcessor.reset(); } @@ -129,10 +138,16 @@ public class ClientInboundProcessor { } private void handlePacket(IncomingPacket incoming, Packet p) { - processorIntentChain.broadcastAfter(new ClientSonyPacketIntent(p)); - if (p instanceof SessionRequest) + if (p instanceof SessionRequest) { onSessionRequest(incoming, (SessionRequest) p); - else if (p instanceof MultiPacket) + processorIntentChain.broadcastAfter(new ClientSonyPacketIntent(p)); + return; + } + if (incoming.getServer() != clientData.getClientServer()) { + Log.w("Dropping packet %s with invalid server %s [expected %s]", p, incoming.getServer(), clientData.getClientServer()); + return; + } + if (p instanceof MultiPacket) onMultiPacket(incoming, (MultiPacket) p); else if (p instanceof Disconnect) onDisconnect(incoming, (Disconnect) p); @@ -150,6 +165,7 @@ public class ClientInboundProcessor { onOutOfOrder((OutOfOrder) p); else Log.e("Unhandled SOE packet: %s", p); + processorIntentChain.broadcastAfter(new ClientSonyPacketIntent(p)); } private void onSessionRequest(IncomingPacket incoming, SessionRequest request) { @@ -167,11 +183,14 @@ public class ClientInboundProcessor { Log.i("Unknown server in session request! Server: %s", incoming.getServer()); return; } - setConnectionState(newStatus); - clientData.reset(newStatus); + clientData.resetConnectionInfo(); + clientData.setClientServer(incoming.getServer()); + if (incoming.getServer() == ClientServer.ZONE) + packetSender.sendRaw(new Disconnect(clientData.getConnectionId(), DisconnectReason.NEW_CONNECTION_ATTEMPT)); clientData.setConnectionId(request.getConnectionId()); clientData.setCommunicationPort(incoming.getPort()); packetSender.sendRaw(new SessionResponse(request.getConnectionId(), 0, (byte) 0, (byte) 0, (byte) 0, MAX_PACKET_SIZE)); + setConnectionState(newStatus); } private void onMultiPacket(IncomingPacket incoming, MultiPacket packet) { diff --git a/src/com/projectswg/networking/client/sender/ClientPackager.java b/src/com/projectswg/networking/client/sender/ClientPackager.java index 49b75ca..8688dcb 100644 --- a/src/com/projectswg/networking/client/sender/ClientPackager.java +++ b/src/com/projectswg/networking/client/sender/ClientPackager.java @@ -35,7 +35,6 @@ public class ClientPackager { this.inboundQueue = new SynchronizedQueue<>(new ArrayDeque<>(128)); this.inboundQueueLock = new SmartLock(); this.packagerThread = new PswgBasicThread("packet-packager", () -> packagerRunnable()); - this.packagerThread.setInterruptOnStop(true); this.packetResender = new ClientPacketResender(sender); this.channel = new DataChannel(); reset(); @@ -50,7 +49,7 @@ public class ClientPackager { public void stop() { packetResender.stop(); - packagerThread.stop(); + packagerThread.stop(true); packagerThread.awaitTermination(1000); inboundQueue.clear(); } @@ -66,9 +65,7 @@ public class ClientPackager { } private void handleClientStatusChanged(ClientConnectionStatus status) { - if (status == ClientConnectionStatus.DISCONNECTED) { - clear(); - } + clear(); } private void packagerRunnable() { diff --git a/src/com/projectswg/networking/client/sender/ClientPacketResender.java b/src/com/projectswg/networking/client/sender/ClientPacketResender.java index 8b9138c..e406990 100644 --- a/src/com/projectswg/networking/client/sender/ClientPacketResender.java +++ b/src/com/projectswg/networking/client/sender/ClientPacketResender.java @@ -32,7 +32,6 @@ public class ClientPacketResender { this.sender = sender; this.sentPackets = new ArrayList<>(128); this.resender = new PswgBasicThread("packet-resender", () -> resendRunnable()); - this.resender.setInterruptOnStop(true); this.congAvoidance = new CongestionAvoidance(); this.lastSent = new AtomicLong(0); } @@ -44,7 +43,7 @@ public class ClientPacketResender { } public void stop() { - resender.stop(); + resender.stop(true); resender.awaitTermination(1000); synchronized (sentPackets) { sentPackets.clear(); @@ -73,9 +72,7 @@ public class ClientPacketResender { } private void handleClientStatusChanged(ClientConnectionStatus status) { - if (status == ClientConnectionStatus.DISCONNECTED) { - restart(); - } + restart(); } private void onOutOfOrder(short sequence) { @@ -300,10 +297,12 @@ public class ClientPacketResender { this.data = data; } + @Override public short getSequence() { return (short) sequence; } public int getSequenceInt() { return sequence; } public byte [] getData() { return data; } + @Override public int compareTo(SequencedPacket p) { if (getSequence() < p.getSequence()) return -1; @@ -312,12 +311,14 @@ public class ClientPacketResender { return 1; } + @Override public boolean equals(Object o) { if (!(o instanceof SequencedOutbound)) return super.equals(o); return ((SequencedOutbound) o).getSequence() == sequence; } + @Override public int hashCode() { return sequence; } diff --git a/src/com/projectswg/networking/server/ServerConnectionService.java b/src/com/projectswg/networking/server/ServerConnectionService.java index 351be39..6f85c7d 100644 --- a/src/com/projectswg/networking/server/ServerConnectionService.java +++ b/src/com/projectswg/networking/server/ServerConnectionService.java @@ -7,8 +7,6 @@ import java.util.Queue; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; -import network.packets.swg.zone.HeartBeat; - import com.projectswg.common.concurrency.PswgBasicScheduledThread; import com.projectswg.common.concurrency.PswgBasicThread; import com.projectswg.common.control.IntentChain; @@ -25,6 +23,8 @@ import com.projectswg.intents.ServerConnectionChangedIntent; import com.projectswg.intents.ServerToClientPacketIntent; import com.projectswg.utilities.ThreadUtilities; +import network.packets.swg.zone.HeartBeat; + public class ServerConnectionService extends Service { private static final long HOLOCORE_TIMEOUT = TimeUnit.SECONDS.toNanos(21); @@ -108,7 +108,6 @@ public class ServerConnectionService extends Service { this.lastHeartbeat = new AtomicLong(0); this.thread = new PswgBasicThread("server-connection", () -> run()); this.heartbeatThread = new PswgBasicScheduledThread("server-heartbeat", () -> heartbeat()); - this.thread.setInterruptOnStop(true); this.outQueue = new LinkedList<>(); this.recvIntentChain = null; } @@ -131,7 +130,7 @@ public class ServerConnectionService extends Service { public void stop() { if (!thread.isRunning()) return; - thread.stop(); + thread.stop(true); heartbeatThread.stop(); thread.awaitTermination(5000); heartbeatThread.awaitTermination(1000); @@ -179,7 +178,7 @@ public class ServerConnectionService extends Service { } private boolean tryConnect() { - if (!connection.connect()) + if (!connection.connect(10000)) return false; synchronized (outQueue) { while (!outQueue.isEmpty()) { diff --git a/src/com/projectswg/networking/server/ServerConnectionWrapper.java b/src/com/projectswg/networking/server/ServerConnectionWrapper.java index d4ca799..bd7ec66 100644 --- a/src/com/projectswg/networking/server/ServerConnectionWrapper.java +++ b/src/com/projectswg/networking/server/ServerConnectionWrapper.java @@ -43,7 +43,7 @@ public class ServerConnectionWrapper { } private void setupConnectionIntents() { - intentManager = new IntentManager(); + intentManager = new IntentManager(Runtime.getRuntime().availableProcessors()); connection.setIntentManager(intentManager); intentManager.registerForIntent(ServerConnectionChangedIntent.class, scci -> onServerConnectionChanged(scci)); intentManager.registerForIntent(ServerToClientPacketIntent.class, scpi -> onServerData(scpi)); diff --git a/src/com/projectswg/networking/soe/DataChannel.java b/src/com/projectswg/networking/soe/DataChannel.java index d6610ae..dbe52b4 100644 --- a/src/com/projectswg/networking/soe/DataChannel.java +++ b/src/com/projectswg/networking/soe/DataChannel.java @@ -31,6 +31,7 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; +import com.projectswg.common.network.NetBuffer; import com.projectswg.networking.Packet; public class DataChannel extends Packet implements SequencedPacket { @@ -60,6 +61,7 @@ public class DataChannel extends Packet implements SequencedPacket { } } + @Override public void decode(ByteBuffer data) { super.decode(data); switch (getOpcode()) { @@ -75,7 +77,7 @@ public class DataChannel extends Packet implements SequencedPacket { if (multiPacket == 0x19) { int length = 0; while (data.remaining() > 1) { - length = getByte(data) & 0xFF; + length = data.get() & 0xFF; if (length == 0xFF) length = getNetShort(data); if (length > data.remaining()) { @@ -94,38 +96,38 @@ public class DataChannel extends Packet implements SequencedPacket { } } + @Override public ByteBuffer encode() { return encode(this.sequence); } public ByteBuffer encode(int sequence) { this.sequence = (short) sequence; + NetBuffer data; if (content.size() == 1) { byte[] pData = content.get(0); - ByteBuffer data = ByteBuffer.allocate(4 + pData.length); - addNetShort(data, channel.getOpcode()); - addNetShort(data, sequence); - data.put(pData); - return data; + data = NetBuffer.allocate(4 + pData.length); + data.addNetShort(channel.getOpcode()); + data.addNetShort(sequence); + data.addRawArray(pData); } else if (content.size() > 1) { - int length = getLength(); - ByteBuffer data = ByteBuffer.allocate(length); - addNetShort(data, channel.getOpcode()); - addNetShort(data, sequence); - addNetShort(data, 0x19); + data = NetBuffer.allocate(getLength()); + data.addNetShort(channel.getOpcode()); + data.addNetShort(sequence); + data.addNetShort(0x19); for (byte[] pData : content) { if (pData.length >= 0xFF) { - addByte(data, 0xFF); - addNetShort(data, pData.length); + data.addByte(0xFF); + data.addNetShort(pData.length); } else { - data.put((byte) pData.length); + data.addByte(pData.length); } - data.put(pData); + data.addRawArray(pData); } - return data; } else { - return ByteBuffer.allocate(0); + data = NetBuffer.allocate(0); } + return data.getBuffer(); } public void addPacket(byte[] packet) { @@ -178,6 +180,7 @@ public class DataChannel extends Packet implements SequencedPacket { this.channel = channel; } + @Override public short getSequence() { return sequence; } diff --git a/src/com/projectswg/networking/soe/MultiPacket.java b/src/com/projectswg/networking/soe/MultiPacket.java index dd624f0..88d2f69 100644 --- a/src/com/projectswg/networking/soe/MultiPacket.java +++ b/src/com/projectswg/networking/soe/MultiPacket.java @@ -31,6 +31,7 @@ import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.List; +import com.projectswg.common.network.NetBuffer; import com.projectswg.networking.Packet; @@ -51,6 +52,7 @@ public class MultiPacket extends Packet { this.content = packets; } + @Override public void decode(ByteBuffer data) { data.position(2); int pLength = getNextPacketLength(data); @@ -62,20 +64,20 @@ public class MultiPacket extends Packet { } } + @Override public ByteBuffer encode() { - int length = getLength(); - ByteBuffer data = ByteBuffer.allocate(length); - addNetShort(data, 3); + NetBuffer data = NetBuffer.allocate(getLength()); + data.addNetShort(3); for (byte [] packet : content) { if (packet.length >= 255) { - addByte(data, 255); - addShort(data, packet.length); + data.addByte(255); + data.addShort(packet.length); } else { - addByte(data, packet.length); + data.addByte(packet.length); } - data.put(packet); + data.addRawArray(packet); } - return data; + return data.getBuffer(); } public int getLength() { @@ -103,11 +105,11 @@ public class MultiPacket extends Packet { private int getNextPacketLength(ByteBuffer data) { if (data.remaining() < 1) return 0; - int length = getByte(data) & 0xFF; + int length = data.get() & 0xFF; if (length == 255) { if (data.remaining() < 2) return 0; - return getShort(data) & 0xFFFF; + return data.getShort() & 0xFFFF; } return length; }