me.bigteddy98.mcproxy.protocol.packet.PacketDataWrapper.java Source code

Java tutorial

Introduction

Here is the source code for me.bigteddy98.mcproxy.protocol.packet.PacketDataWrapper.java

Source

/* 
 * MCProxy
 * Copyright (C) 2014 Sander Gielisse
 *
 *     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 me.bigteddy98.mcproxy.protocol.packet;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufInputStream;
import io.netty.buffer.ByteBufOutputStream;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Map.Entry;
import java.util.UUID;

import me.bigteddy98.mcproxy.entity.DataWatcher;
import me.bigteddy98.mcproxy.entity.Location;
import me.bigteddy98.mcproxy.inventory.ItemStack;

import org.jnbt.CompoundTag;
import org.jnbt.NBTInputStream;
import org.jnbt.NBTOutputStream;

public class PacketDataWrapper {

    private final ByteBuf buffer;

    public PacketDataWrapper(ByteBuf buffer) {
        this.buffer = buffer;
    }

    public ByteBuf getBuffer() {
        return buffer;
    }

    public int readableBytes() {
        return this.buffer.readableBytes();
    }

    public void markReaderIndex() {
        this.buffer.markReaderIndex();
    }

    public void resetReaderIndex() {
        this.buffer.resetReaderIndex();
    }

    public byte readByte() {
        return this.buffer.readByte();
    }

    public int readVarInt() {
        int out = 0;
        int bytes = 0;
        byte in;
        while (true) {
            in = this.buffer.readByte();

            out |= (in & 0x7F) << (bytes++ * 7);

            if (bytes > 5) {
                throw new RuntimeException("VarInt too big");
            }

            if ((in & 0x80) != 0x80) {
                break;
            }
        }
        return out;
    }

    public void discardSomeReadBytes() {
        this.buffer.discardSomeReadBytes();
    }

    public void readBytes(byte[] compressedPacket) {
        this.buffer.readBytes(compressedPacket);
    }

    public void writeVarInt(int value) {
        int part;
        while (true) {
            part = value & 0x7F;

            value >>>= 7;
            if (value != 0) {
                part |= 0x80;
            }

            this.buffer.writeByte(part);

            if (value == 0) {
                break;
            }
        }
    }

    public void writeBytes(ByteBuf temporarilyBuf) {
        this.buffer.writeBytes(temporarilyBuf);
    }

    public void writeBytes(ByteBuf buffer, int i, int dataSize) {
        this.buffer.writeBytes(buffer, i, dataSize);
    }

    public void writeBytes(byte[] uncompressedPacket) {
        this.buffer.writeBytes(uncompressedPacket);
    }

    public String readString() {
        int len = this.readVarInt();

        byte[] b = new byte[len];
        this.readBytes(b);

        try {
            return new String(b, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new Error("No UTF-8 support? This server platform is not supported!", e);
        }
    }

    public void writeString(String s) {
        byte[] b = null;
        try {
            b = s.getBytes("UTF-8");
        } catch (UnsupportedEncodingException e) {
            throw new Error("No UTF-8 support? This server platform is not supported!", e);
        }
        writeVarInt(b.length);
        this.writeBytes(b);
    }

    public short readShort() {
        return this.buffer.readShort();
    }

    public void writeShort(int value) {
        this.buffer.writeShort(value);
    }

    public void writeBytes(byte[] publicKeyBytes, int i, int length) {
        this.buffer.writeBytes(publicKeyBytes, i, length);
    }

    public float readFloat() {
        float f = this.buffer.readFloat();
        if (Float.isNaN(f)) {
            return 0F;
        }
        return f;
    }

    public Location readLocation() {
        long value = this.readLong();
        long x = value >> 38;
        long y = value << 26 >> 52;
        long z = value << 38 >> 38;
        return new Location(x, y, z, 0F, 0F);
    }

    public long readLong() {
        return this.buffer.readLong();
    }

    public int writerIndex() {
        return this.buffer.writerIndex();
    }

    public void ensureWritable(int i) {
        this.buffer.ensureWritable(i);
    }

    public ItemStack readItemStack() {
        short blockId = this.readShort();
        if (blockId == -1) {
            return null;
        }

        ItemStack stack = new ItemStack(blockId, (byte) -1, (short) -1);

        stack.setAmount(this.readByte());
        stack.setDamage(this.readShort());

        int index = this.readerIndex();
        if (this.readByte() == 0) {
            return stack;
        }
        this.readerIndex(index);

        try (NBTInputStream nbtInStream = new NBTInputStream(
                new DataInputStream(new ByteBufInputStream(this.buffer)))) {
            stack.setCompoundTag((CompoundTag) nbtInStream.readTag());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stack;
    }

    private void readerIndex(int index) {
        this.buffer.readerIndex(index);
    }

    private int readerIndex() {
        return this.buffer.readerIndex();
    }

    public boolean readBoolean() {
        return this.buffer.readBoolean();
    }

    public int readUnsignedByte() {
        return this.buffer.readUnsignedByte();
    }

    public double readDouble() {
        double value = this.buffer.readDouble();
        if (Double.isNaN(value)) {
            return 0.0D;
        }
        return value;
    }

    public void readBytes(byte[] data, int i, int length) {
        this.buffer.readBytes(data, i, length);
    }

    public void writeByte(int value) {
        this.buffer.writeByte(value);
    }

    public void writeLocation(Location loc) {
        this.writeLong(((long) loc.getBlockX() & 0x3FFFFFF) << 38 | ((long) loc.getBlockY() & 0xFFF) << 26
                | (loc.getBlockZ() & 0x3FFFFFF));
    }

    public void writeLong(long l) {
        this.buffer.writeLong(l);
    }

    public void writeInt(int i) {
        this.buffer.writeInt(i);
    }

    public void writeBoolean(boolean bool) {
        this.buffer.writeBoolean(bool);
    }

    public void writeDataWatcher(DataWatcher watcher) throws UnsupportedEncodingException {
        for (Entry<Integer, Object> watch : watcher.getWatchedCopy().entrySet()) {
            if (watch.getValue() instanceof Byte) {
                // byte, index
                int i = (0 << 5 | watch.getKey() & 0x1F) & 0xFF;
                this.writeByte(i);
                this.writeByte((byte) watch.getValue());
            } else if (watch.getValue() instanceof Short) {
                int i = (1 << 5 | watch.getKey() & 0x1F) & 0xFF;
                this.writeByte(i);
                this.writeShort((short) watch.getValue());
            } else if (watch.getValue() instanceof Integer) {
                int i = (2 << 5 | watch.getKey() & 0x1F) & 0xFF;
                this.writeByte(i);
                this.writeInt((int) watch.getValue());
            } else if (watch.getValue() instanceof Float) {
                int i = (3 << 5 | watch.getKey() & 0x1F) & 0xFF;
                this.writeByte(i);
                this.writeFloat((float) watch.getValue());
            } else if (watch.getValue() instanceof String) {
                int i = (4 << 5 | watch.getKey() & 0x1F) & 0xFF;
                this.writeByte(i);
                writeString((String) watch.getValue());
            } else if (watch.getValue() instanceof ItemStack) {
                int i = (5 << 5 | watch.getKey() & 0x1F) & 0xFF;
                this.writeByte(i);
                this.writeItemStack((ItemStack) watch.getValue());
                // } else if (watch.getValue() instanceof Vector) { currently
                // not implemented

            } else {
                throw new UnsupportedEncodingException(
                        "Type " + watch.getValue().getClass() + " cannot be part of a datawatcher.");
            }
        }
        this.writeByte(127);
    }

    public void writeItemStack(ItemStack stack) {
        if (stack == null) {
            this.writeShort(-1);
            return;
        }
        this.writeShort(stack.getBlockId());
        this.writeByte(stack.getAmount());
        this.writeShort(stack.getDamage());

        if (stack.getCompoundTag() == null) {
            this.writeByte(0);
            return;
        }
        try (NBTOutputStream outStream = new NBTOutputStream(
                new DataOutputStream(new ByteBufOutputStream(this.buffer)))) {
            outStream.writeTag(stack.getCompoundTag());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void writeFloat(float value) {
        this.buffer.writeFloat(value);
    }

    public void writeUUID(UUID uuid) {
        this.writeLong(uuid.getMostSignificantBits());
        this.writeLong(uuid.getLeastSignificantBits());
    }

    public UUID readUUID() {
        return new UUID(this.readLong(), this.readLong());
    }

    public void writeDouble(double value) {
        this.buffer.writeDouble(value);
    }

    public int readUnsignedShort() {
        return this.buffer.readUnsignedShort();
    }

    public int readInt() {
        return this.buffer.readInt();
    }
}