use of org.dragonet.raknet.protocol.EncapsulatedPacket in project Dragonet-Legacy by DragonetMC.
the class Session method addEncapsulatedToQueue.
public void addEncapsulatedToQueue(EncapsulatedPacket packet, int flags) throws Exception {
if ((packet.needACK = (flags & RakNet.FLAG_NEED_ACK) > 0)) {
this.needACK.put(packet.identifierACK, new HashMap<Integer, Integer>());
}
if (packet.reliability == 2 || packet.reliability == 3 || packet.reliability == 4 || packet.reliability == 6 || packet.reliability == 7) {
packet.messageIndex = this.messageIndex++;
if (packet.reliability == 3) {
int index = this.channelIndex.get(packet.orderChannel) + 1;
packet.orderIndex = index;
channelIndex.put(packet.orderChannel, index);
}
}
if (packet.getTotalLength() + 4 > this.mtuSize) {
byte[][] buffers = Binary.splitBytes(packet.buffer, this.mtuSize - 34);
int splitID = ++this.splitID % 65536;
for (int count = 0; count < buffers.length; count++) {
byte[] buffer = buffers[count];
EncapsulatedPacket pk = new EncapsulatedPacket();
pk.splitID = splitID;
pk.hasSplit = true;
pk.splitCount = buffers.length;
pk.reliability = packet.reliability;
pk.splitIndex = count;
pk.buffer = buffer;
if (count > 0) {
pk.messageIndex = this.messageIndex++;
} else {
pk.messageIndex = packet.messageIndex;
}
if (pk.reliability == 3) {
pk.orderChannel = packet.orderChannel;
pk.orderIndex = packet.orderIndex;
}
this.addToQueue(pk, flags | RakNet.PRIORITY_IMMEDIATE);
}
} else {
this.addToQueue(packet, flags);
}
}
use of org.dragonet.raknet.protocol.EncapsulatedPacket in project Dragonet-Legacy by DragonetMC.
the class RakNetInterface method sendPacket.
public void sendPacket(String identifier, PEPacket packet, boolean needACK, boolean immediate) {
packet.encode();
byte[] buffer = packet.getData();
if (buffer.length > 1024 && !BatchPacket.class.isAssignableFrom(packet.getClass())) {
BatchPacket batch = new BatchPacket();
batch.packets.add(packet);
sendPacket(identifier, batch, needACK, immediate);
return;
}
EncapsulatedPacket encapsulated = new EncapsulatedPacket();
encapsulated.buffer = buffer;
encapsulated.needACK = needACK;
encapsulated.reliability = needACK ? (byte) 2 : (byte) 3;
encapsulated.messageIndex = 0;
this.handler.sendEncapsulated(identifier, encapsulated, (needACK ? RakNet.FLAG_NEED_ACK : 0) | (immediate ? RakNet.PRIORITY_IMMEDIATE : RakNet.PRIORITY_NORMAL));
}
use of org.dragonet.raknet.protocol.EncapsulatedPacket in project Dragonet-Legacy by DragonetMC.
the class Session method handleEncapsulatedPacket.
private void handleEncapsulatedPacket(EncapsulatedPacket packet) throws Exception {
if (packet.messageIndex == null) {
this.handleEncapsulatedPacketRoute(packet);
} else {
if (packet.messageIndex < this.reliableWindowStart || packet.messageIndex > this.reliableWindowEnd) {
return;
}
if ((packet.messageIndex - this.lastReliableIndex) == 1) {
this.lastReliableIndex++;
this.reliableWindowStart++;
this.reliableWindowEnd++;
this.handleEncapsulatedPacketRoute(packet);
if (!this.reliableWindow.isEmpty()) {
TreeMap<Integer, EncapsulatedPacket> sortedMap = new TreeMap<>(this.reliableWindow);
for (int index : sortedMap.keySet()) {
EncapsulatedPacket pk = this.reliableWindow.get(index);
if ((index - this.lastReliableIndex) != 1) {
break;
}
this.lastReliableIndex++;
this.reliableWindowStart++;
this.reliableWindowEnd++;
this.handleEncapsulatedPacketRoute(pk);
this.reliableWindow.remove(index);
}
}
} else {
this.reliableWindow.put(packet.messageIndex, packet);
}
}
}
use of org.dragonet.raknet.protocol.EncapsulatedPacket in project Dragonet-Legacy by DragonetMC.
the class Session method handleEncapsulatedPacketRoute.
private void handleEncapsulatedPacketRoute(EncapsulatedPacket packet) throws Exception {
if (this.sessionManager == null) {
return;
}
if (packet.hasSplit) {
if (this.state == STATE_CONNECTED) {
this.handleSplit(packet);
}
return;
}
byte id = packet.buffer[0];
if ((id & 0xff) < 0x80) {
//internal data packet
if (state == STATE_CONNECTING_2) {
if (id == CLIENT_CONNECT_DataPacket.ID) {
CLIENT_CONNECT_DataPacket dataPacket = new CLIENT_CONNECT_DataPacket();
dataPacket.buffer = packet.buffer;
dataPacket.decode();
SERVER_HANDSHAKE_DataPacket pk = new SERVER_HANDSHAKE_DataPacket();
pk.address = this.address;
pk.port = this.port;
pk.sendPing = dataPacket.sendPing;
pk.sendPong = dataPacket.sendPing + 1000L;
pk.encode();
EncapsulatedPacket sendPacket = new EncapsulatedPacket();
sendPacket.reliability = 0;
sendPacket.buffer = pk.buffer;
this.addToQueue(sendPacket, RakNet.PRIORITY_IMMEDIATE);
} else if (id == CLIENT_HANDSHAKE_DataPacket.ID) {
CLIENT_HANDSHAKE_DataPacket dataPacket = new CLIENT_HANDSHAKE_DataPacket();
dataPacket.buffer = packet.buffer;
dataPacket.decode();
if (dataPacket.port == this.sessionManager.getPort() || !this.sessionManager.portChecking) {
//FINALLY!
this.state = STATE_CONNECTED;
this.isTemporal = false;
this.sessionManager.openSession(this);
}
}
} else if (id == CLIENT_DISCONNECT_DataPacket.ID) {
disconnect("client disconnect");
} else if (id == PING_DataPacket.ID) {
PING_DataPacket dataPacket = new PING_DataPacket();
dataPacket.buffer = packet.buffer;
dataPacket.decode();
PONG_DataPacket pk = new PONG_DataPacket();
pk.pingID = dataPacket.pingID;
pk.encode();
EncapsulatedPacket sendPacket = new EncapsulatedPacket();
sendPacket.reliability = 0;
sendPacket.buffer = pk.buffer;
this.addToQueue(sendPacket);
//TODO: add PING/PONG (0x00/0x03) automatic latency measure
}
} else if (state == STATE_CONNECTED) {
this.sessionManager.streamEncapsulated(this, packet);
//TODO: stream channels
} else {
//this.sessionManager.getLogger().notice("Received packet before connection: "+Binary.bytesToHexString(packet.buffer));
}
}
use of org.dragonet.raknet.protocol.EncapsulatedPacket in project Dragonet-Legacy by DragonetMC.
the class Session method handlePacket.
public void handlePacket(Packet packet) throws Exception {
this.isActive = true;
this.lastUpdate = System.currentTimeMillis();
if (this.state == STATE_CONNECTED || this.state == STATE_CONNECTING_2) {
if (((packet.buffer[0] & 0xff) >= 0x80 || (packet.buffer[0] & 0xff) <= 0x8f) && packet instanceof DataPacket) {
DataPacket dp = (DataPacket) packet;
dp.decode();
if (dp.seqNumber < this.windowStart || dp.seqNumber > this.windowEnd || this.receivedWindow.containsKey(dp.seqNumber)) {
return;
}
int diff = dp.seqNumber - this.lastSeqNumber;
this.NACKQueue.remove(dp.seqNumber);
this.ACKQueue.put(dp.seqNumber, dp.seqNumber);
this.receivedWindow.put(dp.seqNumber, dp.seqNumber);
if (diff != 1) {
for (int i = this.lastSeqNumber + 1; i < dp.seqNumber; i++) {
if (!this.receivedWindow.containsKey(i)) {
this.NACKQueue.put(i, i);
}
}
}
if (diff >= 1) {
this.lastSeqNumber = dp.seqNumber;
this.windowStart += diff;
this.windowEnd += diff;
}
for (Object pk : dp.packets) {
if (pk instanceof EncapsulatedPacket) {
this.handleEncapsulatedPacket((EncapsulatedPacket) pk);
}
}
} else {
if (packet instanceof ACK) {
packet.decode();
for (int seq : new ArrayList<>(((ACK) packet).packets.values())) {
if (this.recoveryQueue.containsKey(seq)) {
for (Object pk : this.recoveryQueue.get(seq).packets) {
if (pk instanceof EncapsulatedPacket && ((EncapsulatedPacket) pk).needACK && ((EncapsulatedPacket) pk).messageIndex != null) {
if (this.needACK.containsKey(((EncapsulatedPacket) pk).identifierACK)) {
this.needACK.get(((EncapsulatedPacket) pk).identifierACK).remove(((EncapsulatedPacket) pk).messageIndex);
}
}
}
this.recoveryQueue.remove(seq);
}
}
} else if (packet instanceof NACK) {
packet.decode();
for (int seq : new ArrayList<>(((NACK) packet).packets.values())) {
if (this.recoveryQueue.containsKey(seq)) {
DataPacket pk = this.recoveryQueue.get(seq);
pk.seqNumber = this.sendSeqNumber++;
this.packetToSend.add(pk);
this.recoveryQueue.remove(seq);
}
}
}
}
} else if ((packet.buffer[0] & 0xff) > 0x00 || (packet.buffer[0] & 0xff) < (byte) 0x80) {
//Not Data packet :)
packet.decode();
if (packet instanceof OPEN_CONNECTION_REQUEST_1) {
//TODO: check protocol number and refuse connections
OPEN_CONNECTION_REPLY_1 pk = new OPEN_CONNECTION_REPLY_1();
pk.mtuSize = ((OPEN_CONNECTION_REQUEST_1) packet).mtuSize;
pk.serverID = sessionManager.getID();
this.sendPacket(pk);
this.state = STATE_CONNECTING_1;
} else if (this.state == STATE_CONNECTING_1 && packet instanceof OPEN_CONNECTION_REQUEST_2) {
this.id = ((OPEN_CONNECTION_REQUEST_2) packet).clientID;
if (((OPEN_CONNECTION_REQUEST_2) packet).serverPort == this.sessionManager.getPort() || !this.sessionManager.portChecking) {
//Max size, do not allow creating large buffers to fill server memory
this.mtuSize = Math.min(Math.abs(((OPEN_CONNECTION_REQUEST_2) packet).mtuSize), 1464);
OPEN_CONNECTION_REPLY_2 pk = new OPEN_CONNECTION_REPLY_2();
pk.mtuSize = (short) this.mtuSize;
pk.serverID = this.sessionManager.getID();
pk.clientAddress = this.address;
pk.clientPort = this.port;
this.sendPacket(pk);
this.state = STATE_CONNECTING_2;
}
}
}
}
Aggregations