Search in sources :

Example 1 with EncapsulatedPacket

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);
    }
}
Also used : EncapsulatedPacket(org.dragonet.raknet.protocol.EncapsulatedPacket)

Example 2 with EncapsulatedPacket

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));
}
Also used : BatchPacket(org.dragonet.net.packet.minecraft.BatchPacket) EncapsulatedPacket(org.dragonet.raknet.protocol.EncapsulatedPacket)

Example 3 with EncapsulatedPacket

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);
        }
    }
}
Also used : EncapsulatedPacket(org.dragonet.raknet.protocol.EncapsulatedPacket)

Example 4 with EncapsulatedPacket

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));
    }
}
Also used : CLIENT_CONNECT_DataPacket(org.dragonet.raknet.protocol.packet.CLIENT_CONNECT_DataPacket) PING_DataPacket(org.dragonet.raknet.protocol.packet.PING_DataPacket) PONG_DataPacket(org.dragonet.raknet.protocol.packet.PONG_DataPacket) CLIENT_HANDSHAKE_DataPacket(org.dragonet.raknet.protocol.packet.CLIENT_HANDSHAKE_DataPacket) SERVER_HANDSHAKE_DataPacket(org.dragonet.raknet.protocol.packet.SERVER_HANDSHAKE_DataPacket) EncapsulatedPacket(org.dragonet.raknet.protocol.EncapsulatedPacket)

Example 5 with EncapsulatedPacket

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;
            }
        }
    }
}
Also used : OPEN_CONNECTION_REPLY_2(org.dragonet.raknet.protocol.packet.OPEN_CONNECTION_REPLY_2) OPEN_CONNECTION_REPLY_1(org.dragonet.raknet.protocol.packet.OPEN_CONNECTION_REPLY_1) ACK(org.dragonet.raknet.protocol.packet.ACK) NACK(org.dragonet.raknet.protocol.packet.NACK) OPEN_CONNECTION_REQUEST_2(org.dragonet.raknet.protocol.packet.OPEN_CONNECTION_REQUEST_2) OPEN_CONNECTION_REQUEST_1(org.dragonet.raknet.protocol.packet.OPEN_CONNECTION_REQUEST_1) EncapsulatedPacket(org.dragonet.raknet.protocol.EncapsulatedPacket) CLIENT_DISCONNECT_DataPacket(org.dragonet.raknet.protocol.packet.CLIENT_DISCONNECT_DataPacket) DataPacket(org.dragonet.raknet.protocol.DataPacket) PONG_DataPacket(org.dragonet.raknet.protocol.packet.PONG_DataPacket) SERVER_HANDSHAKE_DataPacket(org.dragonet.raknet.protocol.packet.SERVER_HANDSHAKE_DataPacket) CLIENT_CONNECT_DataPacket(org.dragonet.raknet.protocol.packet.CLIENT_CONNECT_DataPacket) CLIENT_HANDSHAKE_DataPacket(org.dragonet.raknet.protocol.packet.CLIENT_HANDSHAKE_DataPacket) PING_DataPacket(org.dragonet.raknet.protocol.packet.PING_DataPacket) NACK(org.dragonet.raknet.protocol.packet.NACK)

Aggregations

EncapsulatedPacket (org.dragonet.raknet.protocol.EncapsulatedPacket)6 CLIENT_CONNECT_DataPacket (org.dragonet.raknet.protocol.packet.CLIENT_CONNECT_DataPacket)2 CLIENT_HANDSHAKE_DataPacket (org.dragonet.raknet.protocol.packet.CLIENT_HANDSHAKE_DataPacket)2 PING_DataPacket (org.dragonet.raknet.protocol.packet.PING_DataPacket)2 PONG_DataPacket (org.dragonet.raknet.protocol.packet.PONG_DataPacket)2 SERVER_HANDSHAKE_DataPacket (org.dragonet.raknet.protocol.packet.SERVER_HANDSHAKE_DataPacket)2 BatchPacket (org.dragonet.net.packet.minecraft.BatchPacket)1 DataPacket (org.dragonet.raknet.protocol.DataPacket)1 ACK (org.dragonet.raknet.protocol.packet.ACK)1 CLIENT_DISCONNECT_DataPacket (org.dragonet.raknet.protocol.packet.CLIENT_DISCONNECT_DataPacket)1 NACK (org.dragonet.raknet.protocol.packet.NACK)1 OPEN_CONNECTION_REPLY_1 (org.dragonet.raknet.protocol.packet.OPEN_CONNECTION_REPLY_1)1 OPEN_CONNECTION_REPLY_2 (org.dragonet.raknet.protocol.packet.OPEN_CONNECTION_REPLY_2)1 OPEN_CONNECTION_REQUEST_1 (org.dragonet.raknet.protocol.packet.OPEN_CONNECTION_REQUEST_1)1 OPEN_CONNECTION_REQUEST_2 (org.dragonet.raknet.protocol.packet.OPEN_CONNECTION_REQUEST_2)1 BinaryStream (org.dragonet.utilities.BinaryStream)1