net.beaconpe.jraklib.protocol.Packet.java Source code

Java tutorial

Introduction

Here is the source code for net.beaconpe.jraklib.protocol.Packet.java

Source

/*
   JRakLib networking library.
   This software is not affiliated with RakNet or Jenkins Software LLC.
   This software is a port of PocketMine/RakLib <https://github.com/PocketMine/RakLib>.
   All credit goes to the PocketMine Project (http://pocketmine.net)
     
   Copyright (C) 2015 BlockServerProject & PocketMine team
    
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
package net.beaconpe.jraklib.protocol;

import net.beaconpe.jraklib.Binary;

import org.apache.commons.lang3.ArrayUtils;

import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.regex.Pattern;

/**
 * Base class for all Packets.
 */
public abstract class Packet {

    protected int offset = 0;
    protected int length;
    public byte[] buffer;
    protected ByteBuffer sendBuffer;
    public long sendTime;

    public abstract byte getID();

    protected byte[] get(int len) {
        if (len < 0) {
            offset = buffer.length - 1;
            return new byte[] {};
        } else {
            ByteBuffer bb = ByteBuffer.allocate(len);
            while (len > 0) {
                bb.put(buffer[offset]);
                len = len - 1;
                if (len != 0) {
                    offset = offset + 1;
                }
            }
            return bb.array();
        }
    }

    public void setBuffer(byte[] buffer, int offset) {
        this.buffer = buffer;
        this.offset = offset;
    }

    public int getOffset() {
        return offset;
    }

    protected byte[] get() {
        return Binary.subbytes(buffer, offset);
    }

    protected long getLong(boolean signed) {
        if (signed) {
            return Binary.readLong(get(8));
        } else {
            return Binary.readLong(get(8)) & 0xFF;
        }
    }

    protected long getLong() {
        return getLong(true);
    }

    protected int getInt() {
        return Binary.readInt(get(4));
    }

    protected int getShort(boolean signed) {
        if (signed) {
            return Binary.readSignedShort(get(2));
        } else {
            return Binary.readShort(get(2));
        }
    }

    protected short getShort() {
        return (short) getShort(true);
    }

    protected int getLTriad() {
        return Binary.readLTriad(get(3));
    }

    protected int getByte(boolean signed) {
        offset = offset + 1;
        return Binary.readByte(buffer[offset], signed);
    }

    protected byte getByte() {
        return (byte) getByte(true);
    }

    protected String getString() {
        byte[] d = get(getShort());
        return new String(d);
    }

    protected InetSocketAddress getAddress() {
        int version = getByte();
        if (version == 4) {
            String address = ((~getByte()) & 0xff) + "." + ((~getByte()) & 0xff) + "." + ((~getByte()) & 0xff) + "."
                    + ((~getByte()) & 0xff);
            int port = getShort(false);
            return new InetSocketAddress(address, port);
        } else {
            //TODO: IPv6
            return new InetSocketAddress("0.0.0.0", 0);
        }
    }

    protected boolean feof() {
        try {
            @SuppressWarnings("unused")
            byte d = buffer[offset];
            return false;
        } catch (ArrayIndexOutOfBoundsException e) {
            return true;
        }
    }

    protected void put(byte[] bytes) {
        sendBuffer.put(bytes);
    }

    protected void putLong(long l) {
        sendBuffer.put(Binary.writeLong(l));
    }

    protected void putInt(int i) {
        sendBuffer.put(Binary.writeInt(i));
    }

    protected void putShort(short s) {
        sendBuffer.put(Binary.writeShort(s));
    }

    protected void putLTriad(int t) {
        sendBuffer.put(Binary.writeLTriad(t));
    }

    protected void putByte(byte b) {
        sendBuffer.put(b);
    }

    protected void putString(String s) {
        putShort((short) s.getBytes().length);
        put(s.getBytes());
    }

    protected void putAddress(String addr, int port, byte version) {
        putByte(version);
        if (version == 4) {
            for (String section : addr.split(Pattern.quote("."))) {
                putByte((byte) ((byte) ~(Integer.parseInt(section)) & 0xFF));
            }
            putShort((short) port);
        }
    }

    protected abstract void _encode();

    protected abstract void _decode();

    public void encode() {
        sendBuffer = ByteBuffer.allocate(1024 * 1024);
        putByte(getID());
        _encode();
        buffer = ArrayUtils.subarray(sendBuffer.array(), 0, sendBuffer.position());
    }

    public void decode() {
        getByte();
        _decode();
    }

    public void clean() {
        buffer = null;
        sendBuffer = null;
        offset = 0;
        sendTime = -1;
    }
}