RuneHive-Tarnish
Neural OSRS Enhancement Framework
Loading...
Searching...
No Matches
PacketBuilder.java
1package com.osroyale.net.packet;
2
3import com.osroyale.net.codec.AccessType;
4import com.osroyale.net.codec.ByteModification;
5import com.osroyale.net.codec.ByteOrder;
6import io.netty.buffer.ByteBuf;
7import io.netty.buffer.DefaultByteBufHolder;
8import io.netty.buffer.PooledByteBufAllocator;
9
10import static com.google.common.base.Preconditions.checkState;
11
52
53public final class PacketBuilder extends DefaultByteBufHolder {
54
55 private static final int[] BIT_MASK = new int[32];
56
57 static {
58 for (int i = 0; i < BIT_MASK.length; i++) {
59 BIT_MASK[i] = (1 << i) - 1;
60 }
61 }
62
63 private static final int DEFAULT_CAPACITY = 128;
64 private int bitPosition;
65
66 private PacketBuilder(ByteBuf buffer) {
67 super(buffer);
68 }
69
70 public static PacketBuilder alloc(int initialCapacity, int maxCapacity) {
71 return new PacketBuilder(PooledByteBufAllocator.DEFAULT.buffer(initialCapacity, maxCapacity));
72 }
73
74 public static PacketBuilder alloc(int capacity) {
75 return new PacketBuilder(PooledByteBufAllocator.DEFAULT.buffer(capacity));
76 }
77
78 public static PacketBuilder alloc() {
79 return alloc(DEFAULT_CAPACITY);
80 }
81 public static PacketBuilder wrap(ByteBuf buf) {
82 return new PacketBuilder(buf);
83 }
84
85 public PacketBuilder initializeAccess(AccessType type) {
86 switch (type) {
87 case BIT:
88 bitPosition = content().writerIndex() * 8;
89 break;
90 case BYTE:
91 content().writerIndex((bitPosition + 7) / 8);
92 bitPosition = -1;
93 break;
94 }
95 return this;
96 }
97
98 public PacketBuilder writeByte(int value) {
99 writeByte(value, ByteModification.NONE);
100 return this;
101 }
102
103 public PacketBuilder writeByte(int value, ByteModification type) {
104 switch (type) {
105 case ADD:
106 value += 128;
107 break;
108 case NEG:
109 value = -value;
110 break;
111 case SUB:
112 value = 128 - value;
113 break;
114 case NONE:
115 break;
116 }
117 content().writeByte((byte) value);
118 return this;
119 }
120
121 public PacketBuilder writeBit(boolean flag) {
122 writeBits(1, flag ? 1 : 0);
123 return this;
124 }
125
126 public PacketBuilder writeBits(int amount, int value) {
127 checkState(amount >= 1 && amount <= 32, "Number of bits must be between 1 and 32 inclusive.");
128
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);
136 }
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);
142 amount -= bitOffset;
143 }
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);
149 } else {
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);
154 }
155 return this;
156 }
157
158 public PacketBuilder writeBytes(byte[] from, int size) {
159 content().writeBytes(from, 0, size);
160 return this;
161 }
162
163 public PacketBuilder writeBytes(ByteBuf from) {
164 for (int i = 0; i < from.writerIndex(); i++) {
165 writeByte(from.getByte(i));
166 }
167 return this;
168 }
169
170 public PacketBuilder writeBytesReverse(byte[] data) {
171 for (int i = data.length - 1; i >= 0; i--) {
172 writeByte(data[i]);
173 }
174 return this;
175 }
176
177 public PacketBuilder writeInt(int value) {
178 writeInt(value, ByteModification.NONE, ByteOrder.BE);
179 return this;
180 }
181
182 public PacketBuilder writeInt(int value, ByteOrder order) {
183 writeInt(value, ByteModification.NONE, order);
184 return this;
185 }
186
187 public PacketBuilder writeInt(int value, ByteModification type) {
188 writeInt(value, type, ByteOrder.BE);
189 return this;
190 }
191
192 public PacketBuilder writeInt(int value, ByteModification type, ByteOrder order) {
193 switch (order) {
194 case BE:
195 writeByte(value >> 24);
196 writeByte(value >> 16);
197 writeByte(value >> 8);
198 writeByte(value, type);
199 break;
200 case ME:
201 writeByte(value >> 8);
202 writeByte(value, type);
203 writeByte(value >> 24);
204 writeByte(value >> 16);
205 break;
206 case IME:
207 writeByte(value >> 16);
208 writeByte(value >> 24);
209 writeByte(value, type);
210 writeByte(value >> 8);
211 break;
212 case LE:
213 writeByte(value, type);
214 writeByte(value >> 8);
215 writeByte(value >> 16);
216 writeByte(value >> 24);
217 break;
218 }
219 return this;
220 }
221
222 public PacketBuilder writeLong(long value) {
223 writeLong(value, ByteModification.NONE, ByteOrder.BE);
224 return this;
225 }
226
227 public PacketBuilder writeLong(long value, ByteOrder order) {
228 writeLong(value, ByteModification.NONE, order);
229 return this;
230 }
231
232 public PacketBuilder writeLong(long value, ByteModification type) {
233 writeLong(value, type, ByteOrder.BE);
234 return this;
235 }
236
237 public PacketBuilder writeLong(long value, ByteModification type, ByteOrder order) {
238 switch (order) {
239 case BE:
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);
248 break;
249
250 case ME:
251 throw new UnsupportedOperationException("Middle-endian long " + "is not implemented!");
252
253 case IME:
254 throw new UnsupportedOperationException("Inverse-middle-endian long is not implemented!");
255
256 case LE:
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));
265 break;
266
267 }
268 return this;
269 }
270
271 public PacketBuilder writeShort(int value) {
272 writeShort(value, ByteModification.NONE, ByteOrder.BE);
273 return this;
274 }
275
276 public PacketBuilder writeShort(int value, ByteOrder order) {
277 writeShort(value, ByteModification.NONE, order);
278 return this;
279 }
280
281 public PacketBuilder writeShort(int value, ByteModification type) {
282 writeShort(value, type, ByteOrder.BE);
283 return this;
284 }
285
286 public PacketBuilder writeShort(int value, ByteModification type, ByteOrder order) {
287 switch (order) {
288 case BE:
289 writeByte(value >> 8);
290 writeByte(value, type);
291 break;
292 case ME:
293 throw new IllegalArgumentException("Middle-endian short is " + "impossible!");
294 case IME:
295 throw new IllegalArgumentException("Inverse-middle-endian " + "short is impossible!");
296 case LE:
297 writeByte(value, type);
298 writeByte(value >> 8);
299 break;
300 default:
301 break;
302 }
303 return this;
304 }
305
306 public PacketBuilder writeString(String string) {
307 for (final byte value : string.getBytes()) {
308 writeByte(value);
309 }
310 writeByte(10);
311 return this;
312 }
313
314 public GamePacket toPacket(int opcode) {
315 return new GamePacket(opcode, PacketType.FIXED, content());
316 }
317
318 public GamePacket toPacket(int opcode, PacketType type) {
319 return new GamePacket(opcode, type, content());
320 }
321
322 public String getString() {
323 byte temp;
324 StringBuilder builder = new StringBuilder();
325 while (content().isReadable() && (temp = content().readByte()) != 10) {
326 builder.append((char) temp);
327 }
328 return builder.toString();
329 }
330
331 public PacketBuilder writeBuffer(ByteBuf buffer) {
332 this.content().writeBytes(buffer);
333 return this;
334 }
335
336 public PacketBuilder writeByteArray(byte[] bytes) {
337 content().writeBytes(bytes);
338 return this;
339 }
340
341 public PacketBuilder writeByteArray(byte[] bytes, int offset, int length) {
342 content().writeBytes(bytes, offset, length);
343 return this;
344 }
345}