53public final class PacketBuilder
extends DefaultByteBufHolder {
55 private static final int[] BIT_MASK =
new int[32];
58 for (
int i = 0; i < BIT_MASK.length; i++) {
59 BIT_MASK[i] = (1 << i) - 1;
63 private static final int DEFAULT_CAPACITY = 128;
64 private int bitPosition;
66 private PacketBuilder(ByteBuf buffer) {
70 public static PacketBuilder alloc(
int initialCapacity,
int maxCapacity) {
71 return new PacketBuilder(PooledByteBufAllocator.DEFAULT.buffer(initialCapacity, maxCapacity));
74 public static PacketBuilder alloc(
int capacity) {
75 return new PacketBuilder(PooledByteBufAllocator.DEFAULT.buffer(capacity));
78 public static PacketBuilder alloc() {
79 return alloc(DEFAULT_CAPACITY);
81 public static PacketBuilder wrap(ByteBuf buf) {
82 return new PacketBuilder(buf);
85 public PacketBuilder initializeAccess(
AccessType type) {
88 bitPosition = content().writerIndex() * 8;
91 content().writerIndex((bitPosition + 7) / 8);
98 public PacketBuilder writeByte(
int value) {
117 content().writeByte((
byte) value);
121 public PacketBuilder writeBit(
boolean flag) {
122 writeBits(1, flag ? 1 : 0);
126 public PacketBuilder writeBits(
int amount,
int value) {
127 checkState(amount >= 1 && amount <= 32,
"Number of bits must be between 1 and 32 inclusive.");
129 int bytePos = bitPosition >> 3;
130 int bitOffset = 8 - (bitPosition & 7);
131 bitPosition = bitPosition + amount;
132 int requiredSpace = bytePos - content().writerIndex() + 1;
133 requiredSpace += (amount + 7) / 8;
134 if (content().writableBytes() < requiredSpace) {
135 content().capacity(content().capacity() + requiredSpace);
137 for (; amount > bitOffset; bitOffset = 8) {
138 byte tmp = content().getByte(bytePos);
139 tmp &= ~BIT_MASK[bitOffset];
140 tmp |= (value >> (amount - bitOffset)) & BIT_MASK[bitOffset];
141 content().setByte(bytePos++, tmp);
144 if (amount == bitOffset) {
145 byte tmp = content().getByte(bytePos);
146 tmp &= ~BIT_MASK[bitOffset];
147 tmp |= value & BIT_MASK[bitOffset];
148 content().setByte(bytePos, tmp);
150 byte tmp = content().getByte(bytePos);
151 tmp &= ~(BIT_MASK[amount] << (bitOffset - amount));
152 tmp |= (value & BIT_MASK[amount]) << (bitOffset - amount);
153 content().setByte(bytePos, tmp);
158 public PacketBuilder writeBytes(
byte[] from,
int size) {
159 content().writeBytes(from, 0, size);
163 public PacketBuilder writeBytes(ByteBuf from) {
164 for (
int i = 0; i < from.writerIndex(); i++) {
165 writeByte(from.getByte(i));
170 public PacketBuilder writeBytesReverse(
byte[] data) {
171 for (
int i = data.length - 1; i >= 0; i--) {
177 public PacketBuilder writeInt(
int value) {
182 public PacketBuilder writeInt(
int value,
ByteOrder order) {
195 writeByte(value >> 24);
196 writeByte(value >> 16);
197 writeByte(value >> 8);
198 writeByte(value, type);
201 writeByte(value >> 8);
202 writeByte(value, type);
203 writeByte(value >> 24);
204 writeByte(value >> 16);
207 writeByte(value >> 16);
208 writeByte(value >> 24);
209 writeByte(value, type);
210 writeByte(value >> 8);
213 writeByte(value, type);
214 writeByte(value >> 8);
215 writeByte(value >> 16);
216 writeByte(value >> 24);
222 public PacketBuilder writeLong(
long value) {
227 public PacketBuilder writeLong(
long value,
ByteOrder order) {
240 writeByte((
int) (value >> 56));
241 writeByte((
int) (value >> 48));
242 writeByte((
int) (value >> 40));
243 writeByte((
int) (value >> 32));
244 writeByte((
int) (value >> 24));
245 writeByte((
int) (value >> 16));
246 writeByte((
int) (value >> 8));
247 writeByte((
int) value, type);
251 throw new UnsupportedOperationException(
"Middle-endian long " +
"is not implemented!");
254 throw new UnsupportedOperationException(
"Inverse-middle-endian long is not implemented!");
257 writeByte((
int) value, type);
258 writeByte((
int) (value >> 8));
259 writeByte((
int) (value >> 16));
260 writeByte((
int) (value >> 24));
261 writeByte((
int) (value >> 32));
262 writeByte((
int) (value >> 40));
263 writeByte((
int) (value >> 48));
264 writeByte((
int) (value >> 56));
271 public PacketBuilder writeShort(
int value) {
276 public PacketBuilder writeShort(
int value,
ByteOrder order) {
289 writeByte(value >> 8);
290 writeByte(value, type);
293 throw new IllegalArgumentException(
"Middle-endian short is " +
"impossible!");
295 throw new IllegalArgumentException(
"Inverse-middle-endian " +
"short is impossible!");
297 writeByte(value, type);
298 writeByte(value >> 8);
306 public PacketBuilder writeString(String
string) {
307 for (
final byte value :
string.getBytes()) {
319 return new GamePacket(opcode, type, content());
322 public String getString() {
324 StringBuilder builder =
new StringBuilder();
325 while (content().isReadable() && (temp = content().readByte()) != 10) {
326 builder.append((
char) temp);
328 return builder.toString();
331 public PacketBuilder writeBuffer(ByteBuf buffer) {
332 this.content().writeBytes(buffer);
336 public PacketBuilder writeByteArray(
byte[] bytes) {
337 content().writeBytes(bytes);
341 public PacketBuilder writeByteArray(
byte[] bytes,
int offset,
int length) {
342 content().writeBytes(bytes, offset, length);