Package org.spout.vanilla.protocol

Source Code of org.spout.vanilla.protocol.VanillaByteBufUtils

/*
* This file is part of Vanilla.
*
* Copyright (c) 2011 Spout LLC <http://www.spout.org/>
* Vanilla is licensed under the Spout License Version 1.
*
* Vanilla is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option)
* any later version.
*
* In addition, 180 days after any changes are published, you can use the
* software, incorporating those changes, under the terms of the MIT license,
* as described in the Spout License Version 1.
*
* Vanilla 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 Lesser General Public License for
* more details.
*
* You should have received a copy of the GNU Lesser General Public License,
* the MIT license and the Spout License Version 1 along with this program.
* If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
* License and see <http://spout.in/licensev1> for the full license, including
* the MIT license.
*/
package org.spout.vanilla.protocol;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import io.netty.buffer.ByteBuf;

import org.spout.api.inventory.ItemStack;
import org.spout.api.material.Material;
import org.spout.api.material.block.BlockFace;
import org.spout.api.util.Parameter;

import org.spout.math.GenericMath;
import org.spout.nbt.CompoundMap;
import org.spout.vanilla.material.VanillaMaterials;

import static org.spout.api.util.ByteBufUtils.readCompound;
import static org.spout.api.util.ByteBufUtils.writeCompound;

public final class VanillaByteBufUtils {
  /**
   * Writes a list of parameters (e.g. mob metadata) to the buffer.
   *
   * @param buf The buffer.
   * @param parameters The parameters.
   */
  @SuppressWarnings ("unchecked")
  public static void writeParameters(ByteBuf buf, List<Parameter<?>> parameters) {
    for (Parameter<?> parameter : parameters) {
      int type = parameter.getType();
      int index = parameter.getIndex();
      if (index > 0x1F) {
        throw new IllegalArgumentException("Index has a maximum of 0x1F!");
      }

      buf.writeByte(type << 5 | index & 0x1F);

      switch (type) {
        case Parameter.TYPE_BYTE:
          buf.writeByte(((Parameter<Byte>) parameter).getValue());
          break;
        case Parameter.TYPE_SHORT:
          buf.writeShort(((Parameter<Short>) parameter).getValue());
          break;
        case Parameter.TYPE_INT:
          buf.writeInt(((Parameter<Integer>) parameter).getValue());
          break;
        case Parameter.TYPE_FLOAT:
          buf.writeFloat(((Parameter<Float>) parameter).getValue());
          break;
        case Parameter.TYPE_STRING:
          writeString(buf, ((Parameter<String>) parameter).getValue());
          break;
        case Parameter.TYPE_ITEM:
          ItemStack item = ((Parameter<ItemStack>) parameter).getValue();
          writeItemStack(buf, item);
          break;
      }
    }

    buf.writeByte(127);
  }

  /**
   * Reads a list of parameters from the buffer.
   *
   * @param buf The buffer.
   * @return The parameters.
   */
  public static List<Parameter<?>> readParameters(ByteBuf buf) throws IOException {
    List<Parameter<?>> parameters = new ArrayList<Parameter<?>>();

    for (int b = buf.readUnsignedByte(); b != 127; b = buf.readUnsignedByte()) {
      int type = (b & 0xE0) >> 5;
      int index = b & 0x1F;

      switch (type) {
        case Parameter.TYPE_BYTE:
          parameters.add(new Parameter<Byte>(type, index, buf.readByte()));
          break;
        case Parameter.TYPE_SHORT:
          parameters.add(new Parameter<Short>(type, index, buf.readShort()));
          break;
        case Parameter.TYPE_INT:
          parameters.add(new Parameter<Integer>(type, index, buf.readInt()));
          break;
        case Parameter.TYPE_FLOAT:
          parameters.add(new Parameter<Float>(type, index, buf.readFloat()));
          break;
        case Parameter.TYPE_STRING:
          parameters.add(new Parameter<String>(type, index, readString(buf)));
          break;
        case Parameter.TYPE_ITEM:
          parameters.add(new Parameter<ItemStack>(type, index, readItemStack(buf)));
          break;
      }
    }

    return parameters;
  }

  /**
   * Writes a string to the buffer.
   *
   * @param buf The buffer.
   * @param str The string.
   * @throws IllegalArgumentException if the string is too long <em>after</em> it is encoded.
   */
  public static void writeString(ByteBuf buf, String str) {
    int len = str.length();
    if (len >= 65536) {
      throw new IllegalArgumentException("String too long.");
    }
    buf.writeShort(len);
    for (int i = 0; i < len; ++i) {
      buf.writeChar(str.charAt(i));
    }
  }

  /**
   * Reads a string from the buffer.
   *
   * @param buf The buffer.
   * @return The string.
   */
  public static String readString(ByteBuf buf) {
    int len = buf.readUnsignedShort();

    char[] characters = new char[len];
    for (int i = 0; i < len; i++) {
      characters[i] = buf.readChar();
    }

    return new String(characters);
  }

  /**
   * Gets the size of a String represented in the formats read and written by
   * {@link #writeString(ByteBuf, String)} and {@link #readString(ByteBuf)}.
   *
   * @param str to get the written length of
   * @return String length
   */
  public static int getStringLength(String str) {
    return str.length() * 2 + 2;
  }

  public static ItemStack readItemStack(ByteBuf buffer) throws IOException {
    short id = buffer.readShort();
    if (id < 0) {
      return null;
    } else {
      Material material = VanillaMaterials.getMaterial(id);
      if (material == null) {
        throw new IOException("Unknown material with id of " + id);
      }
      int count = buffer.readUnsignedByte();
      int damage = buffer.readUnsignedShort();
      CompoundMap nbtData = readCompound(buffer);
      return new ItemStack(material, damage, count).setNBTData(nbtData);
    }
  }

  public static void writeItemStack(ByteBuf buffer, ItemStack item) {
    short id = item == null ? (short) -1 : VanillaMaterials.getMinecraftId(item.getMaterial());
    buffer.writeShort(id);
    if (id != -1) {
      buffer.writeByte(item.getAmount());
      buffer.writeShort(item.getData());
      writeCompound(buffer, item.getNBTData());
    }
  }

  public static byte getNativeDirection(BlockFace face) {
    switch (face) {
      case SOUTH:
        return 3;
      case WEST:
        return 0;
      case NORTH:
        return 1;
      case EAST:
        return 2;
      default:
        return -1;
    }
  }

  public static int protocolifyPosition(float pos) {
    return GenericMath.floor(pos * 32);
  }

  public static float deProtocolifyPosition(int pos) {
    return pos / 32F;
  }

  public static int protocolifyPitch(float pitch) {
    return GenericMath.wrapByte(GenericMath.floor((pitch / 360) * 256));
  }

  public static float deProtocolifyPitch(int pitch) {
    return 360f * (pitch / 256f);
  }

  public static int protocolifyYaw(float yaw) {
    return protocolifyPitch(-yaw);
  }

  public static float deProtocolifyYaw(int yaw) {
    return -deProtocolifyPitch(yaw);
  }

  private VanillaByteBufUtils() {
  }

}
TOP

Related Classes of org.spout.vanilla.protocol.VanillaByteBufUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.