1 /*
2  * This file was automatically generated by sel-utils and
3  * released under the MIT License.
4  * 
5  * License: https://github.com/sel-project/sel-utils/blob/master/LICENSE
6  * Repository: https://github.com/sel-project/sel-utils
7  * Generated from https://github.com/sel-project/sel-utils/blob/master/xml/protocol/pocket102.xml
8  */
9 /**
10  * Packets related to the gameplay. Network-related packets (encapsulation, acks, nacks)
11  * are managed by RakNet and every packet in this section is encapsualted in an Encapsualted
12  * packet.
13  */
14 module sul.protocol.pocket102.play;
15 
16 import std.bitmanip : write, peek;
17 static import std.conv;
18 import std.system : Endian;
19 import std.typetuple : TypeTuple;
20 import std.typecons : Tuple;
21 import std.uuid : UUID;
22 
23 import sul.utils.buffer;
24 import sul.utils.var;
25 
26 static import sul.protocol.pocket102.types;
27 
28 static if(__traits(compiles, { import sul.metadata.pocket102; })) import sul.metadata.pocket102;
29 
30 alias Packets = TypeTuple!(Login, PlayStatus, ServerToClientHandshake, ClientToServerHandshake, Disconnect, Batch, ResourcePacksInfo, ResourcePacksStackPacket, ResourcePackClientResponse, Text, SetTime, StartGame, AddPlayer, AddEntity, RemoveEntity, AddItemEntity, AddHangingEntity, TakeItemEntity, MoveEntity, MovePlayer, RiderJump, RemoveBlock, UpdateBlock, AddPainting, Explode, LevelSoundEvent, LevelEvent, BlockEvent, EntityEvent, MobEffect, UpdateAttributes, MobEquipment, MobArmorEquipment, Interact, UseItem, PlayerAction, PlayerFall, HurtArmor, SetEntityData, SetEntityMotion, SetEntityLink, SetHealth, SetSpawnPosition, Animate, Respawn, DropItem, InventoryAction, ContainerOpen, ContainerClose, ContainerSetSlot, ContainerSetData, ContainerSetContent, CraftingData, CraftingEvent, AdventureSettings, BlockEntityData, PlayerInput, FullChunkData, SetCommandsEnabled, SetDifficulty, ChangeDimension, SetPlayerGameType, PlayerList, TelemetryEvent, SpawnExperienceOrb, ClientboundMapItemData, MapInfoRequest, RequestChunkRadius, ChunkRadiusUpdated, ItemFrameDropItem, ReplaceSelectedItem, GameRulesChanged, Camera, AddItem, BossEvent, ShowCredits, AvailableCommands, CommandStep, UpdateTrade, ResourcePackDataInfo, ResourcePackChunkData, ResourcePackChunkRequest, Transfer);
31 
32 /**
33  * First MCPE packet sent after the establishment of the connection through raknet.
34  * It contains informations about the player.
35  */
36 class Login : Buffer {
37 
38 	public enum ubyte ID = 1;
39 
40 	public enum bool CLIENTBOUND = false;
41 	public enum bool SERVERBOUND = true;
42 
43 	// edition
44 	public enum ubyte CLASSIC = 0;
45 	public enum ubyte EDUCATION = 1;
46 
47 	public enum string[] FIELDS = ["protocol", "edition", "body_"];
48 
49 	/**
50 	 * Version of the protocol used by the player.
51 	 */
52 	public uint protocol;
53 
54 	/**
55 	 * Edition that the player is using to join the server. The different editions may
56 	 * have different features and servers may block the access from unaccepted editions
57 	 * of the game.
58 	 */
59 	public ubyte edition;
60 
61 	/**
62 	 * Zlib-compressed bytes that contains 2 JWTs with more informations about the player
63 	 * and its account. Once uncompressed the resulting payload will contain 2 JWTs which
64 	 * length is indicated by a little-endian unsigned integer each.
65 	 */
66 	public ubyte[] body_;
67 
68 	public pure nothrow @safe @nogc this() {}
69 
70 	public pure nothrow @safe @nogc this(uint protocol, ubyte edition=ubyte.init, ubyte[] body_=(ubyte[]).init) {
71 		this.protocol = protocol;
72 		this.edition = edition;
73 		this.body_ = body_;
74 	}
75 
76 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
77 		_buffer.length = 0;
78 		static if(writeId){ writeBigEndianUbyte(ID); }
79 		writeBigEndianUint(protocol);
80 		writeBigEndianUbyte(edition);
81 		writeBytes(varuint.encode(cast(uint)body_.length)); writeBytes(body_);
82 		return _buffer;
83 	}
84 
85 	public pure nothrow @safe void decode(bool readId=true)() {
86 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
87 		protocol=readBigEndianUint();
88 		edition=readBigEndianUbyte();
89 		body_.length=varuint.decode(_buffer, &_index); if(_buffer.length>=_index+body_.length){ body_=_buffer[_index.._index+body_.length].dup; _index+=body_.length; }
90 	}
91 
92 	public static pure nothrow @safe Login fromBuffer(bool readId=true)(ubyte[] buffer) {
93 		Login ret = new Login();
94 		ret._buffer = buffer;
95 		ret.decode!readId();
96 		return ret;
97 	}
98 
99 	public override string toString() {
100 		return "Login(protocol: " ~ std.conv.to!string(this.protocol) ~ ", edition: " ~ std.conv.to!string(this.edition) ~ ", body_: " ~ std.conv.to!string(this.body_) ~ ")";
101 	}
102 
103 }
104 
105 /**
106  * Packet sent as response to Login to indicate whether the connection has been accepted
107  * and when the player is ready to spawn in the world.
108  */
109 class PlayStatus : Buffer {
110 
111 	public enum ubyte ID = 2;
112 
113 	public enum bool CLIENTBOUND = true;
114 	public enum bool SERVERBOUND = false;
115 
116 	// status
117 	public enum uint OK = 0;
118 	public enum uint OUTDATED_CLIENT = 1;
119 	public enum uint OUTDATED_SERVER = 2;
120 	public enum uint SPAWNED = 3;
121 	public enum uint INVALID_TENANT = 4;
122 	public enum uint EDITION_MISMATCH = 5;
123 
124 	public enum string[] FIELDS = ["status"];
125 
126 	public uint status;
127 
128 	public pure nothrow @safe @nogc this() {}
129 
130 	public pure nothrow @safe @nogc this(uint status) {
131 		this.status = status;
132 	}
133 
134 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
135 		_buffer.length = 0;
136 		static if(writeId){ writeBigEndianUbyte(ID); }
137 		writeBigEndianUint(status);
138 		return _buffer;
139 	}
140 
141 	public pure nothrow @safe void decode(bool readId=true)() {
142 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
143 		status=readBigEndianUint();
144 	}
145 
146 	public static pure nothrow @safe PlayStatus fromBuffer(bool readId=true)(ubyte[] buffer) {
147 		PlayStatus ret = new PlayStatus();
148 		ret._buffer = buffer;
149 		ret.decode!readId();
150 		return ret;
151 	}
152 
153 	public override string toString() {
154 		return "PlayStatus(status: " ~ std.conv.to!string(this.status) ~ ")";
155 	}
156 
157 }
158 
159 class ServerToClientHandshake : Buffer {
160 
161 	public enum ubyte ID = 3;
162 
163 	public enum bool CLIENTBOUND = true;
164 	public enum bool SERVERBOUND = false;
165 
166 	public enum string[] FIELDS = ["serverPublicKey", "token"];
167 
168 	public string serverPublicKey;
169 	public ubyte[] token;
170 
171 	public pure nothrow @safe @nogc this() {}
172 
173 	public pure nothrow @safe @nogc this(string serverPublicKey, ubyte[] token=(ubyte[]).init) {
174 		this.serverPublicKey = serverPublicKey;
175 		this.token = token;
176 	}
177 
178 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
179 		_buffer.length = 0;
180 		static if(writeId){ writeBigEndianUbyte(ID); }
181 		writeBytes(varuint.encode(cast(uint)serverPublicKey.length)); writeString(serverPublicKey);
182 		writeBytes(varuint.encode(cast(uint)token.length)); writeBytes(token);
183 		return _buffer;
184 	}
185 
186 	public pure nothrow @safe void decode(bool readId=true)() {
187 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
188 		uint cvdvuvbl=varuint.decode(_buffer, &_index); serverPublicKey=readString(cvdvuvbl);
189 		token.length=varuint.decode(_buffer, &_index); if(_buffer.length>=_index+token.length){ token=_buffer[_index.._index+token.length].dup; _index+=token.length; }
190 	}
191 
192 	public static pure nothrow @safe ServerToClientHandshake fromBuffer(bool readId=true)(ubyte[] buffer) {
193 		ServerToClientHandshake ret = new ServerToClientHandshake();
194 		ret._buffer = buffer;
195 		ret.decode!readId();
196 		return ret;
197 	}
198 
199 	public override string toString() {
200 		return "ServerToClientHandshake(serverPublicKey: " ~ std.conv.to!string(this.serverPublicKey) ~ ", token: " ~ std.conv.to!string(this.token) ~ ")";
201 	}
202 
203 }
204 
205 class ClientToServerHandshake : Buffer {
206 
207 	public enum ubyte ID = 4;
208 
209 	public enum bool CLIENTBOUND = false;
210 	public enum bool SERVERBOUND = true;
211 
212 	public enum string[] FIELDS = [];
213 
214 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
215 		_buffer.length = 0;
216 		static if(writeId){ writeBigEndianUbyte(ID); }
217 		return _buffer;
218 	}
219 
220 	public pure nothrow @safe void decode(bool readId=true)() {
221 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
222 	}
223 
224 	public static pure nothrow @safe ClientToServerHandshake fromBuffer(bool readId=true)(ubyte[] buffer) {
225 		ClientToServerHandshake ret = new ClientToServerHandshake();
226 		ret._buffer = buffer;
227 		ret.decode!readId();
228 		return ret;
229 	}
230 
231 	public override string toString() {
232 		return "ClientToServerHandshake()";
233 	}
234 
235 }
236 
237 /**
238  * Disconnects the player from the server.
239  */
240 class Disconnect : Buffer {
241 
242 	public enum ubyte ID = 5;
243 
244 	public enum bool CLIENTBOUND = true;
245 	public enum bool SERVERBOUND = false;
246 
247 	public enum string[] FIELDS = ["hideDisconnectionScreen", "message"];
248 
249 	/**
250 	 * Indicates whether to display the main menu screen or a disconnection message.
251 	 */
252 	public bool hideDisconnectionScreen;
253 
254 	/**
255 	 * The message to display in the disconnection screen. If the message is in the game's
256 	 * language file it will be translated client-side.
257 	 */
258 	public string message;
259 
260 	public pure nothrow @safe @nogc this() {}
261 
262 	public pure nothrow @safe @nogc this(bool hideDisconnectionScreen, string message=string.init) {
263 		this.hideDisconnectionScreen = hideDisconnectionScreen;
264 		this.message = message;
265 	}
266 
267 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
268 		_buffer.length = 0;
269 		static if(writeId){ writeBigEndianUbyte(ID); }
270 		writeBigEndianBool(hideDisconnectionScreen);
271 		if(hideDisconnectionScreen==false){ writeBytes(varuint.encode(cast(uint)message.length)); writeString(message); }
272 		return _buffer;
273 	}
274 
275 	public pure nothrow @safe void decode(bool readId=true)() {
276 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
277 		hideDisconnectionScreen=readBigEndianBool();
278 		if(hideDisconnectionScreen==false){ uint bvcfz=varuint.decode(_buffer, &_index); message=readString(bvcfz); }
279 	}
280 
281 	public static pure nothrow @safe Disconnect fromBuffer(bool readId=true)(ubyte[] buffer) {
282 		Disconnect ret = new Disconnect();
283 		ret._buffer = buffer;
284 		ret.decode!readId();
285 		return ret;
286 	}
287 
288 	public override string toString() {
289 		return "Disconnect(hideDisconnectionScreen: " ~ std.conv.to!string(this.hideDisconnectionScreen) ~ ", message: " ~ std.conv.to!string(this.message) ~ ")";
290 	}
291 
292 }
293 
294 /**
295  * One ore more packet, each prefixed with their varuint-encoded length, compressed
296  * with zlib's deflate algorithm.
297  */
298 class Batch : Buffer {
299 
300 	public enum ubyte ID = 6;
301 
302 	public enum bool CLIENTBOUND = true;
303 	public enum bool SERVERBOUND = true;
304 
305 	public enum string[] FIELDS = ["data"];
306 
307 	/**
308 	 * Compressed data.
309 	 * 
310 	 * Pseudo-code for decompression:
311 	 * ---
312 	 * ubyte[] uncompressed = uncompress(batch.payload);
313 	 * int index = 0;
314 	 * while(index < uncompressed.length) {
315 	 *    int length = varuint.decode(uncompressed, &index);
316 	 *    if(length < uncompressed.length - index) {}
317 	 *       ubyte[] packet = uncompressed[0..length];
318 	 *       index += length;
319 	 *    }
320 	 * }
321 	 * ---
322 	 * 
323 	 * Pseudo-code for compression:
324 	 * ---
325 	 * ubyte[] payload;
326 	 * foreach(ubyte[] packet ; packets) {
327 	 *    payload.concat(varuint.encode(packet.length));
328 	 *    payload.concat(packet);
329 	 * }
330 	 * Batch batch = new Batch(compress(payload, Zlib.DEFLATE));
331 	 * ---
332 	 */
333 	public ubyte[] data;
334 
335 	public pure nothrow @safe @nogc this() {}
336 
337 	public pure nothrow @safe @nogc this(ubyte[] data) {
338 		this.data = data;
339 	}
340 
341 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
342 		_buffer.length = 0;
343 		static if(writeId){ writeBigEndianUbyte(ID); }
344 		writeBytes(varuint.encode(cast(uint)data.length)); writeBytes(data);
345 		return _buffer;
346 	}
347 
348 	public pure nothrow @safe void decode(bool readId=true)() {
349 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
350 		data.length=varuint.decode(_buffer, &_index); if(_buffer.length>=_index+data.length){ data=_buffer[_index.._index+data.length].dup; _index+=data.length; }
351 	}
352 
353 	public static pure nothrow @safe Batch fromBuffer(bool readId=true)(ubyte[] buffer) {
354 		Batch ret = new Batch();
355 		ret._buffer = buffer;
356 		ret.decode!readId();
357 		return ret;
358 	}
359 
360 	public override string toString() {
361 		return "Batch(data: " ~ std.conv.to!string(this.data) ~ ")";
362 	}
363 
364 }
365 
366 class ResourcePacksInfo : Buffer {
367 
368 	public enum ubyte ID = 7;
369 
370 	public enum bool CLIENTBOUND = true;
371 	public enum bool SERVERBOUND = false;
372 
373 	public enum string[] FIELDS = ["mustAccept", "behaviourPacks", "resourcePacks"];
374 
375 	public bool mustAccept;
376 	public sul.protocol.pocket102.types.PackWithSize[] behaviourPacks;
377 	public sul.protocol.pocket102.types.PackWithSize[] resourcePacks;
378 
379 	public pure nothrow @safe @nogc this() {}
380 
381 	public pure nothrow @safe @nogc this(bool mustAccept, sul.protocol.pocket102.types.PackWithSize[] behaviourPacks=(sul.protocol.pocket102.types.PackWithSize[]).init, sul.protocol.pocket102.types.PackWithSize[] resourcePacks=(sul.protocol.pocket102.types.PackWithSize[]).init) {
382 		this.mustAccept = mustAccept;
383 		this.behaviourPacks = behaviourPacks;
384 		this.resourcePacks = resourcePacks;
385 	}
386 
387 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
388 		_buffer.length = 0;
389 		static if(writeId){ writeBigEndianUbyte(ID); }
390 		writeBigEndianBool(mustAccept);
391 		writeLittleEndianUshort(cast(ushort)behaviourPacks.length); foreach(yvyzbvuf;behaviourPacks){ yvyzbvuf.encode(bufferInstance); }
392 		writeLittleEndianUshort(cast(ushort)resourcePacks.length); foreach(cvbvyvyn;resourcePacks){ cvbvyvyn.encode(bufferInstance); }
393 		return _buffer;
394 	}
395 
396 	public pure nothrow @safe void decode(bool readId=true)() {
397 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
398 		mustAccept=readBigEndianBool();
399 		behaviourPacks.length=readLittleEndianUshort(); foreach(ref yvyzbvuf;behaviourPacks){ yvyzbvuf.decode(bufferInstance); }
400 		resourcePacks.length=readLittleEndianUshort(); foreach(ref cvbvyvyn;resourcePacks){ cvbvyvyn.decode(bufferInstance); }
401 	}
402 
403 	public static pure nothrow @safe ResourcePacksInfo fromBuffer(bool readId=true)(ubyte[] buffer) {
404 		ResourcePacksInfo ret = new ResourcePacksInfo();
405 		ret._buffer = buffer;
406 		ret.decode!readId();
407 		return ret;
408 	}
409 
410 	public override string toString() {
411 		return "ResourcePacksInfo(mustAccept: " ~ std.conv.to!string(this.mustAccept) ~ ", behaviourPacks: " ~ std.conv.to!string(this.behaviourPacks) ~ ", resourcePacks: " ~ std.conv.to!string(this.resourcePacks) ~ ")";
412 	}
413 
414 }
415 
416 class ResourcePacksStackPacket : Buffer {
417 
418 	public enum ubyte ID = 8;
419 
420 	public enum bool CLIENTBOUND = true;
421 	public enum bool SERVERBOUND = false;
422 
423 	public enum string[] FIELDS = ["mustAccept", "behaviourPacks", "resourcePacks"];
424 
425 	public bool mustAccept;
426 	public sul.protocol.pocket102.types.Pack[] behaviourPacks;
427 	public sul.protocol.pocket102.types.Pack[] resourcePacks;
428 
429 	public pure nothrow @safe @nogc this() {}
430 
431 	public pure nothrow @safe @nogc this(bool mustAccept, sul.protocol.pocket102.types.Pack[] behaviourPacks=(sul.protocol.pocket102.types.Pack[]).init, sul.protocol.pocket102.types.Pack[] resourcePacks=(sul.protocol.pocket102.types.Pack[]).init) {
432 		this.mustAccept = mustAccept;
433 		this.behaviourPacks = behaviourPacks;
434 		this.resourcePacks = resourcePacks;
435 	}
436 
437 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
438 		_buffer.length = 0;
439 		static if(writeId){ writeBigEndianUbyte(ID); }
440 		writeBigEndianBool(mustAccept);
441 		writeLittleEndianUshort(cast(ushort)behaviourPacks.length); foreach(yvyzbvuf;behaviourPacks){ yvyzbvuf.encode(bufferInstance); }
442 		writeLittleEndianUshort(cast(ushort)resourcePacks.length); foreach(cvbvyvyn;resourcePacks){ cvbvyvyn.encode(bufferInstance); }
443 		return _buffer;
444 	}
445 
446 	public pure nothrow @safe void decode(bool readId=true)() {
447 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
448 		mustAccept=readBigEndianBool();
449 		behaviourPacks.length=readLittleEndianUshort(); foreach(ref yvyzbvuf;behaviourPacks){ yvyzbvuf.decode(bufferInstance); }
450 		resourcePacks.length=readLittleEndianUshort(); foreach(ref cvbvyvyn;resourcePacks){ cvbvyvyn.decode(bufferInstance); }
451 	}
452 
453 	public static pure nothrow @safe ResourcePacksStackPacket fromBuffer(bool readId=true)(ubyte[] buffer) {
454 		ResourcePacksStackPacket ret = new ResourcePacksStackPacket();
455 		ret._buffer = buffer;
456 		ret.decode!readId();
457 		return ret;
458 	}
459 
460 	public override string toString() {
461 		return "ResourcePacksStackPacket(mustAccept: " ~ std.conv.to!string(this.mustAccept) ~ ", behaviourPacks: " ~ std.conv.to!string(this.behaviourPacks) ~ ", resourcePacks: " ~ std.conv.to!string(this.resourcePacks) ~ ")";
462 	}
463 
464 }
465 
466 class ResourcePackClientResponse : Buffer {
467 
468 	public enum ubyte ID = 9;
469 
470 	public enum bool CLIENTBOUND = false;
471 	public enum bool SERVERBOUND = true;
472 
473 	// status
474 	public enum ubyte REFUSED = 1;
475 	public enum ubyte SEND_PACKS = 2;
476 	public enum ubyte HAVE_ALL_PACKS = 3;
477 	public enum ubyte COMPLETED = 4;
478 
479 	public enum string[] FIELDS = ["status", "packIds"];
480 
481 	public ubyte status;
482 	public string[] packIds;
483 
484 	public pure nothrow @safe @nogc this() {}
485 
486 	public pure nothrow @safe @nogc this(ubyte status, string[] packIds=(string[]).init) {
487 		this.status = status;
488 		this.packIds = packIds;
489 	}
490 
491 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
492 		_buffer.length = 0;
493 		static if(writeId){ writeBigEndianUbyte(ID); }
494 		writeBigEndianUbyte(status);
495 		writeLittleEndianUshort(cast(ushort)packIds.length); foreach(cfalc;packIds){ writeBytes(varuint.encode(cast(uint)cfalc.length)); writeString(cfalc); }
496 		return _buffer;
497 	}
498 
499 	public pure nothrow @safe void decode(bool readId=true)() {
500 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
501 		status=readBigEndianUbyte();
502 		packIds.length=readLittleEndianUshort(); foreach(ref cfalc;packIds){ uint yzbm=varuint.decode(_buffer, &_index); cfalc=readString(yzbm); }
503 	}
504 
505 	public static pure nothrow @safe ResourcePackClientResponse fromBuffer(bool readId=true)(ubyte[] buffer) {
506 		ResourcePackClientResponse ret = new ResourcePackClientResponse();
507 		ret._buffer = buffer;
508 		ret.decode!readId();
509 		return ret;
510 	}
511 
512 	public override string toString() {
513 		return "ResourcePackClientResponse(status: " ~ std.conv.to!string(this.status) ~ ", packIds: " ~ std.conv.to!string(this.packIds) ~ ")";
514 	}
515 
516 }
517 
518 /**
519  * Sends or receives a message from the player. Every variant's field can contain Minecraft's
520  * formatting codes.
521  * Every packet sent in the same game tick should be joined together with `\n§r` (line
522  * break and reset formatting), otherwise the messages will be displayed multiple times
523  * on the client's chat (see [MCPE-17631](https://bugs.mojang.com/browse/MCPE-17631)).
524  */
525 class Text : Buffer {
526 
527 	public enum ubyte ID = 10;
528 
529 	public enum bool CLIENTBOUND = true;
530 	public enum bool SERVERBOUND = true;
531 
532 	public enum string[] FIELDS = ["type"];
533 
534 	public ubyte type;
535 
536 	public pure nothrow @safe @nogc this() {}
537 
538 	public pure nothrow @safe @nogc this(ubyte type) {
539 		this.type = type;
540 	}
541 
542 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
543 		_buffer.length = 0;
544 		static if(writeId){ writeBigEndianUbyte(ID); }
545 		writeBigEndianUbyte(type);
546 		return _buffer;
547 	}
548 
549 	public pure nothrow @safe void decode(bool readId=true)() {
550 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
551 		type=readBigEndianUbyte();
552 	}
553 
554 	public static pure nothrow @safe Text fromBuffer(bool readId=true)(ubyte[] buffer) {
555 		Text ret = new Text();
556 		ret._buffer = buffer;
557 		ret.decode!readId();
558 		return ret;
559 	}
560 
561 	public override string toString() {
562 		return "Text(type: " ~ std.conv.to!string(this.type) ~ ")";
563 	}
564 
565 	alias _encode = encode;
566 
567 	enum string variantField = "type";
568 
569 	alias Variants = TypeTuple!(Raw, Chat, Translation, Popup, Tip, System, Whisper);
570 
571 	/**
572 	 * Raw message that will be printed in the chat as it is.
573 	 */
574 	public class Raw {
575 
576 		public enum typeof(type) TYPE = 0;
577 
578 		public enum string[] FIELDS = ["message"];
579 
580 		public string message;
581 
582 		public pure nothrow @safe @nogc this() {}
583 
584 		public pure nothrow @safe @nogc this(string message) {
585 			this.message = message;
586 		}
587 
588 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
589 			type = 0;
590 			_encode!writeId();
591 			writeBytes(varuint.encode(cast(uint)message.length)); writeString(message);
592 			return _buffer;
593 		}
594 
595 		public pure nothrow @safe void decode() {
596 			uint bvcfz=varuint.decode(_buffer, &_index); message=readString(bvcfz);
597 		}
598 
599 		public override string toString() {
600 			return "Text.Raw(message: " ~ std.conv.to!string(this.message) ~ ")";
601 		}
602 
603 	}
604 
605 	/**
606 	 * Chat message sent by the player to the server. If sent from the server it will display
607 	 * as `&lt;sender&gt; message`.
608 	 */
609 	public class Chat {
610 
611 		public enum typeof(type) TYPE = 1;
612 
613 		public enum string[] FIELDS = ["sender", "message"];
614 
615 		/**
616 		 * Case sensitive name of the player that has sent the message.
617 		 */
618 		public string sender;
619 
620 		/**
621 		 * Message sent by the player. It should be unformatted (regular expression: `§[a-fA-F0-9k-or]`)
622 		 * before being processed as chat message by the server.
623 		 */
624 		public string message;
625 
626 		public pure nothrow @safe @nogc this() {}
627 
628 		public pure nothrow @safe @nogc this(string sender, string message=string.init) {
629 			this.sender = sender;
630 			this.message = message;
631 		}
632 
633 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
634 			type = 1;
635 			_encode!writeId();
636 			writeBytes(varuint.encode(cast(uint)sender.length)); writeString(sender);
637 			writeBytes(varuint.encode(cast(uint)message.length)); writeString(message);
638 			return _buffer;
639 		}
640 
641 		public pure nothrow @safe void decode() {
642 			uint cvzv=varuint.decode(_buffer, &_index); sender=readString(cvzv);
643 			uint bvcfz=varuint.decode(_buffer, &_index); message=readString(bvcfz);
644 		}
645 
646 		public override string toString() {
647 			return "Text.Chat(sender: " ~ std.conv.to!string(this.sender) ~ ", message: " ~ std.conv.to!string(this.message) ~ ")";
648 		}
649 
650 	}
651 
652 	/**
653 	 * Sends a message that will be translated client-side using the player's language.
654 	 */
655 	public class Translation {
656 
657 		public enum typeof(type) TYPE = 2;
658 
659 		public enum string[] FIELDS = ["message", "parameters"];
660 
661 		/**
662 		 * A message in the game's language file.
663 		 */
664 		public string message;
665 
666 		/**
667 		 * Parameters that will be placed instead of the replacement symbols (%1, %2, etc...).
668 		 */
669 		public string[] parameters;
670 
671 		public pure nothrow @safe @nogc this() {}
672 
673 		public pure nothrow @safe @nogc this(string message, string[] parameters=(string[]).init) {
674 			this.message = message;
675 			this.parameters = parameters;
676 		}
677 
678 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
679 			type = 2;
680 			_encode!writeId();
681 			writeBytes(varuint.encode(cast(uint)message.length)); writeString(message);
682 			writeBytes(varuint.encode(cast(uint)parameters.length)); foreach(cfy1dvc;parameters){ writeBytes(varuint.encode(cast(uint)cfy1dvc.length)); writeString(cfy1dvc); }
683 			return _buffer;
684 		}
685 
686 		public pure nothrow @safe void decode() {
687 			uint bvcfz=varuint.decode(_buffer, &_index); message=readString(bvcfz);
688 			parameters.length=varuint.decode(_buffer, &_index); foreach(ref cfy1dvc;parameters){ uint yzmry=varuint.decode(_buffer, &_index); cfy1dvc=readString(yzmry); }
689 		}
690 
691 		public override string toString() {
692 			return "Text.Translation(message: " ~ std.conv.to!string(this.message) ~ ", parameters: " ~ std.conv.to!string(this.parameters) ~ ")";
693 		}
694 
695 	}
696 
697 	/**
698 	 * Displays popups messages for one tick before fading out. The popup messages are
699 	 * displayed at the centre of the screen and are not automatically aligned horizontally.
700 	 */
701 	public class Popup {
702 
703 		public enum typeof(type) TYPE = 3;
704 
705 		public enum string[] FIELDS = ["title", "subtitle"];
706 
707 		public string title;
708 		public string subtitle;
709 
710 		public pure nothrow @safe @nogc this() {}
711 
712 		public pure nothrow @safe @nogc this(string title, string subtitle=string.init) {
713 			this.title = title;
714 			this.subtitle = subtitle;
715 		}
716 
717 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
718 			type = 3;
719 			_encode!writeId();
720 			writeBytes(varuint.encode(cast(uint)title.length)); writeString(title);
721 			writeBytes(varuint.encode(cast(uint)subtitle.length)); writeString(subtitle);
722 			return _buffer;
723 		}
724 
725 		public pure nothrow @safe void decode() {
726 			uint dlbu=varuint.decode(_buffer, &_index); title=readString(dlbu);
727 			uint cvdlbu=varuint.decode(_buffer, &_index); subtitle=readString(cvdlbu);
728 		}
729 
730 		public override string toString() {
731 			return "Text.Popup(title: " ~ std.conv.to!string(this.title) ~ ", subtitle: " ~ std.conv.to!string(this.subtitle) ~ ")";
732 		}
733 
734 	}
735 
736 	/**
737 	 * Displays a tip message for one tick before fading out. The tip message is displayed
738 	 * on top of the inventory bar and can contain multiple lines separated with `\n`.
739 	 */
740 	public class Tip {
741 
742 		public enum typeof(type) TYPE = 4;
743 
744 		public enum string[] FIELDS = ["message"];
745 
746 		public string message;
747 
748 		public pure nothrow @safe @nogc this() {}
749 
750 		public pure nothrow @safe @nogc this(string message) {
751 			this.message = message;
752 		}
753 
754 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
755 			type = 4;
756 			_encode!writeId();
757 			writeBytes(varuint.encode(cast(uint)message.length)); writeString(message);
758 			return _buffer;
759 		}
760 
761 		public pure nothrow @safe void decode() {
762 			uint bvcfz=varuint.decode(_buffer, &_index); message=readString(bvcfz);
763 		}
764 
765 		public override string toString() {
766 			return "Text.Tip(message: " ~ std.conv.to!string(this.message) ~ ")";
767 		}
768 
769 	}
770 
771 	public class System {
772 
773 		public enum typeof(type) TYPE = 5;
774 
775 		public enum string[] FIELDS = ["message"];
776 
777 		public string message;
778 
779 		public pure nothrow @safe @nogc this() {}
780 
781 		public pure nothrow @safe @nogc this(string message) {
782 			this.message = message;
783 		}
784 
785 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
786 			type = 5;
787 			_encode!writeId();
788 			writeBytes(varuint.encode(cast(uint)message.length)); writeString(message);
789 			return _buffer;
790 		}
791 
792 		public pure nothrow @safe void decode() {
793 			uint bvcfz=varuint.decode(_buffer, &_index); message=readString(bvcfz);
794 		}
795 
796 		public override string toString() {
797 			return "Text.System(message: " ~ std.conv.to!string(this.message) ~ ")";
798 		}
799 
800 	}
801 
802 	/**
803 	 * Sends a whisper message to the client that will be displayed in the format `<i>sender
804 	 * has whispered to you:</i> message`.
805 	 */
806 	public class Whisper {
807 
808 		public enum typeof(type) TYPE = 6;
809 
810 		public enum string[] FIELDS = ["sender", "message"];
811 
812 		public string sender;
813 		public string message;
814 
815 		public pure nothrow @safe @nogc this() {}
816 
817 		public pure nothrow @safe @nogc this(string sender, string message=string.init) {
818 			this.sender = sender;
819 			this.message = message;
820 		}
821 
822 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
823 			type = 6;
824 			_encode!writeId();
825 			writeBytes(varuint.encode(cast(uint)sender.length)); writeString(sender);
826 			writeBytes(varuint.encode(cast(uint)message.length)); writeString(message);
827 			return _buffer;
828 		}
829 
830 		public pure nothrow @safe void decode() {
831 			uint cvzv=varuint.decode(_buffer, &_index); sender=readString(cvzv);
832 			uint bvcfz=varuint.decode(_buffer, &_index); message=readString(bvcfz);
833 		}
834 
835 		public override string toString() {
836 			return "Text.Whisper(sender: " ~ std.conv.to!string(this.sender) ~ ", message: " ~ std.conv.to!string(this.message) ~ ")";
837 		}
838 
839 	}
840 
841 }
842 
843 /**
844  * Sets the time.
845  */
846 class SetTime : Buffer {
847 
848 	public enum ubyte ID = 11;
849 
850 	public enum bool CLIENTBOUND = true;
851 	public enum bool SERVERBOUND = false;
852 
853 	public enum string[] FIELDS = ["time", "daylightCycle"];
854 
855 	/**
856 	 * Time of the day in a range from 0 to 24000. If higher or lower it will be moduled
857 	 * to 24000.
858 	 */
859 	public int time;
860 
861 	/**
862 	 * Indicates whether the daylight cycle is active. If not, the time will be stopped
863 	 * at the value given in the previous field.
864 	 */
865 	public bool daylightCycle;
866 
867 	public pure nothrow @safe @nogc this() {}
868 
869 	public pure nothrow @safe @nogc this(int time, bool daylightCycle=bool.init) {
870 		this.time = time;
871 		this.daylightCycle = daylightCycle;
872 	}
873 
874 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
875 		_buffer.length = 0;
876 		static if(writeId){ writeBigEndianUbyte(ID); }
877 		writeBytes(varint.encode(time));
878 		writeBigEndianBool(daylightCycle);
879 		return _buffer;
880 	}
881 
882 	public pure nothrow @safe void decode(bool readId=true)() {
883 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
884 		time=varint.decode(_buffer, &_index);
885 		daylightCycle=readBigEndianBool();
886 	}
887 
888 	public static pure nothrow @safe SetTime fromBuffer(bool readId=true)(ubyte[] buffer) {
889 		SetTime ret = new SetTime();
890 		ret._buffer = buffer;
891 		ret.decode!readId();
892 		return ret;
893 	}
894 
895 	public override string toString() {
896 		return "SetTime(time: " ~ std.conv.to!string(this.time) ~ ", daylightCycle: " ~ std.conv.to!string(this.daylightCycle) ~ ")";
897 	}
898 
899 }
900 
901 class StartGame : Buffer {
902 
903 	public enum ubyte ID = 12;
904 
905 	public enum bool CLIENTBOUND = true;
906 	public enum bool SERVERBOUND = false;
907 
908 	// dimension
909 	public enum int OVERWORLD = 0;
910 	public enum int NETHER = 1;
911 	public enum int END = 2;
912 
913 	// generator
914 	public enum int OLD = 0;
915 	public enum int INFINITE = 1;
916 	public enum int FLAT = 2;
917 
918 	// world gamemode
919 	public enum int SURVIVAL = 0;
920 	public enum int CREATIVE = 1;
921 
922 	// difficulty
923 	public enum int PEACEFUL = 0;
924 	public enum int EASY = 1;
925 	public enum int NORMAL = 2;
926 	public enum int HARD = 3;
927 
928 	// edition
929 	public enum ubyte CLASSIC = 0;
930 	public enum ubyte EDUCATION = 1;
931 
932 	public enum string[] FIELDS = ["entityId", "runtimeId", "position", "yaw", "pitch", "seed", "dimension", "generator", "worldGamemode", "difficulty", "spawnPosition", "loadedInCreative", "time", "edition", "rainLevel", "lightingLevel", "commandsEnabled", "textureRequired", "levelId", "worldName"];
933 
934 	/**
935 	 * Player's entity id that uniquely identifies the entity of the server.
936 	 */
937 	public long entityId;
938 	public long runtimeId;
939 
940 	/**
941 	 * Position where the player will spawn.
942 	 */
943 	public Tuple!(float, "x", float, "y", float, "z") position;
944 	public float yaw;
945 	public float pitch;
946 
947 	/**
948 	 * World's seed. It's displayed in the game's world settings and in beta's debug informations
949 	 * on top of the screen.
950 	 */
951 	public int seed;
952 
953 	/**
954 	 * World's dimension. Different dimensions have different sky colours and render distances.
955 	 */
956 	public int dimension = 0;
957 
958 	/**
959 	 * World's type. It's displayed in the game's world settings.
960 	 * In old and infinite world the sky becomes darker at 32 blocks of altitude and in
961 	 * flat worlds it only becomes darker under 0.
962 	 */
963 	public int generator = 1;
964 
965 	/**
966 	 * Default's world gamemode. If the player's gamemode is different from the default's
967 	 * one a SetPlayerGameType should be sent after this.
968 	 */
969 	public int worldGamemode;
970 
971 	/**
972 	 * World's difficulty. The value is visible in the client's world settings.
973 	 */
974 	public int difficulty;
975 
976 	/**
977 	 * Position where the client's compass will point to.
978 	 */
979 	public Tuple!(int, "x", int, "y", int, "z") spawnPosition;
980 	public bool loadedInCreative;
981 
982 	/**
983 	 * Time of the day that should be in a range from 0 to 24000. If not the absolute value
984 	 * is moduled per 24000.
985 	 * If the world's time is stopped a SetTime packet should be sent after this.
986 	 */
987 	public int time;
988 
989 	/**
990 	 * Game's edition. Some behaviours (some entities for example) may only work in a version
991 	 * and not in the other.
992 	 */
993 	public ubyte edition;
994 
995 	/**
996 	 * Intensity of the rain or the snow. Any value lower than or equals to 0 means no
997 	 * rain.
998 	 */
999 	public float rainLevel;
1000 	public float lightingLevel;
1001 
1002 	/**
1003 	 * Indicates whether the cheats are enabled. If the cheats are disabled the player
1004 	 * cannot send commands.
1005 	 */
1006 	public bool commandsEnabled;
1007 	public bool textureRequired;
1008 	public string levelId;
1009 
1010 	/**
1011 	 * World's name that will be displayed in the game's world settings. It can contain
1012 	 * formatting codes.
1013 	 */
1014 	public string worldName;
1015 
1016 	public pure nothrow @safe @nogc this() {}
1017 
1018 	public pure nothrow @safe @nogc this(long entityId, long runtimeId=long.init, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, float yaw=float.init, float pitch=float.init, int seed=int.init, int dimension=0, int generator=1, int worldGamemode=int.init, int difficulty=int.init, Tuple!(int, "x", int, "y", int, "z") spawnPosition=Tuple!(int, "x", int, "y", int, "z").init, bool loadedInCreative=bool.init, int time=int.init, ubyte edition=ubyte.init, float rainLevel=float.init, float lightingLevel=float.init, bool commandsEnabled=bool.init, bool textureRequired=bool.init, string levelId=string.init, string worldName=string.init) {
1019 		this.entityId = entityId;
1020 		this.runtimeId = runtimeId;
1021 		this.position = position;
1022 		this.yaw = yaw;
1023 		this.pitch = pitch;
1024 		this.seed = seed;
1025 		this.dimension = dimension;
1026 		this.generator = generator;
1027 		this.worldGamemode = worldGamemode;
1028 		this.difficulty = difficulty;
1029 		this.spawnPosition = spawnPosition;
1030 		this.loadedInCreative = loadedInCreative;
1031 		this.time = time;
1032 		this.edition = edition;
1033 		this.rainLevel = rainLevel;
1034 		this.lightingLevel = lightingLevel;
1035 		this.commandsEnabled = commandsEnabled;
1036 		this.textureRequired = textureRequired;
1037 		this.levelId = levelId;
1038 		this.worldName = worldName;
1039 	}
1040 
1041 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1042 		_buffer.length = 0;
1043 		static if(writeId){ writeBigEndianUbyte(ID); }
1044 		writeBytes(varlong.encode(entityId));
1045 		writeBytes(varlong.encode(runtimeId));
1046 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
1047 		writeLittleEndianFloat(yaw);
1048 		writeLittleEndianFloat(pitch);
1049 		writeBytes(varint.encode(seed));
1050 		writeBytes(varint.encode(dimension));
1051 		writeBytes(varint.encode(generator));
1052 		writeBytes(varint.encode(worldGamemode));
1053 		writeBytes(varint.encode(difficulty));
1054 		writeBytes(varint.encode(spawnPosition.x)); writeBytes(varint.encode(spawnPosition.y)); writeBytes(varint.encode(spawnPosition.z));
1055 		writeBigEndianBool(loadedInCreative);
1056 		writeBytes(varint.encode(time));
1057 		writeBigEndianUbyte(edition);
1058 		writeLittleEndianFloat(rainLevel);
1059 		writeLittleEndianFloat(lightingLevel);
1060 		writeBigEndianBool(commandsEnabled);
1061 		writeBigEndianBool(textureRequired);
1062 		writeBytes(varuint.encode(cast(uint)levelId.length)); writeString(levelId);
1063 		writeBytes(varuint.encode(cast(uint)worldName.length)); writeString(worldName);
1064 		return _buffer;
1065 	}
1066 
1067 	public pure nothrow @safe void decode(bool readId=true)() {
1068 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1069 		entityId=varlong.decode(_buffer, &_index);
1070 		runtimeId=varlong.decode(_buffer, &_index);
1071 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
1072 		yaw=readLittleEndianFloat();
1073 		pitch=readLittleEndianFloat();
1074 		seed=varint.decode(_buffer, &_index);
1075 		dimension=varint.decode(_buffer, &_index);
1076 		generator=varint.decode(_buffer, &_index);
1077 		worldGamemode=varint.decode(_buffer, &_index);
1078 		difficulty=varint.decode(_buffer, &_index);
1079 		spawnPosition.x=varint.decode(_buffer, &_index); spawnPosition.y=varint.decode(_buffer, &_index); spawnPosition.z=varint.decode(_buffer, &_index);
1080 		loadedInCreative=readBigEndianBool();
1081 		time=varint.decode(_buffer, &_index);
1082 		edition=readBigEndianUbyte();
1083 		rainLevel=readLittleEndianFloat();
1084 		lightingLevel=readLittleEndianFloat();
1085 		commandsEnabled=readBigEndianBool();
1086 		textureRequired=readBigEndianBool();
1087 		uint bvzxz=varuint.decode(_buffer, &_index); levelId=readString(bvzxz);
1088 		uint d9bry1=varuint.decode(_buffer, &_index); worldName=readString(d9bry1);
1089 	}
1090 
1091 	public static pure nothrow @safe StartGame fromBuffer(bool readId=true)(ubyte[] buffer) {
1092 		StartGame ret = new StartGame();
1093 		ret._buffer = buffer;
1094 		ret.decode!readId();
1095 		return ret;
1096 	}
1097 
1098 	public override string toString() {
1099 		return "StartGame(entityId: " ~ std.conv.to!string(this.entityId) ~ ", runtimeId: " ~ std.conv.to!string(this.runtimeId) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", yaw: " ~ std.conv.to!string(this.yaw) ~ ", pitch: " ~ std.conv.to!string(this.pitch) ~ ", seed: " ~ std.conv.to!string(this.seed) ~ ", dimension: " ~ std.conv.to!string(this.dimension) ~ ", generator: " ~ std.conv.to!string(this.generator) ~ ", worldGamemode: " ~ std.conv.to!string(this.worldGamemode) ~ ", difficulty: " ~ std.conv.to!string(this.difficulty) ~ ", spawnPosition: " ~ std.conv.to!string(this.spawnPosition) ~ ", loadedInCreative: " ~ std.conv.to!string(this.loadedInCreative) ~ ", time: " ~ std.conv.to!string(this.time) ~ ", edition: " ~ std.conv.to!string(this.edition) ~ ", rainLevel: " ~ std.conv.to!string(this.rainLevel) ~ ", lightingLevel: " ~ std.conv.to!string(this.lightingLevel) ~ ", commandsEnabled: " ~ std.conv.to!string(this.commandsEnabled) ~ ", textureRequired: " ~ std.conv.to!string(this.textureRequired) ~ ", levelId: " ~ std.conv.to!string(this.levelId) ~ ", worldName: " ~ std.conv.to!string(this.worldName) ~ ")";
1100 	}
1101 
1102 }
1103 
1104 /**
1105  * Spawns a player after adding it to the player's list using PlayerList. If PlayerList
1106  * is sent after this packet the player will appear to have the same skin as the player
1107  * who receives this packet.
1108  * Spawning a player to itself (using the same entity id given in the StartGame packet)
1109  * will crash the client's game.
1110  */
1111 class AddPlayer : Buffer {
1112 
1113 	public enum ubyte ID = 13;
1114 
1115 	public enum bool CLIENTBOUND = true;
1116 	public enum bool SERVERBOUND = false;
1117 
1118 	public enum string[] FIELDS = ["uuid", "username", "entityId", "runtimeId", "position", "motion", "pitch", "headYaw", "yaw", "heldItem", "metadata"];
1119 
1120 	/**
1121 	 * Player's UUID, should match an UUID of a player in the list added through PlayerList.
1122 	 */
1123 	public UUID uuid;
1124 
1125 	/**
1126 	 * Player's username and text displayed on the nametag if something else is not specified
1127 	 * in the metadata.
1128 	 */
1129 	public string username;
1130 	public long entityId;
1131 	public long runtimeId;
1132 	public Tuple!(float, "x", float, "y", float, "z") position;
1133 	public Tuple!(float, "x", float, "y", float, "z") motion;
1134 	public float pitch;
1135 	public float headYaw;
1136 	public float yaw;
1137 	public sul.protocol.pocket102.types.Slot heldItem;
1138 	public Metadata metadata;
1139 
1140 	public pure nothrow @safe @nogc this() {}
1141 
1142 	public pure nothrow @safe @nogc this(UUID uuid, string username=string.init, long entityId=long.init, long runtimeId=long.init, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, Tuple!(float, "x", float, "y", float, "z") motion=Tuple!(float, "x", float, "y", float, "z").init, float pitch=float.init, float headYaw=float.init, float yaw=float.init, sul.protocol.pocket102.types.Slot heldItem=sul.protocol.pocket102.types.Slot.init, Metadata metadata=Metadata.init) {
1143 		this.uuid = uuid;
1144 		this.username = username;
1145 		this.entityId = entityId;
1146 		this.runtimeId = runtimeId;
1147 		this.position = position;
1148 		this.motion = motion;
1149 		this.pitch = pitch;
1150 		this.headYaw = headYaw;
1151 		this.yaw = yaw;
1152 		this.heldItem = heldItem;
1153 		this.metadata = metadata;
1154 	}
1155 
1156 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1157 		_buffer.length = 0;
1158 		static if(writeId){ writeBigEndianUbyte(ID); }
1159 		writeBytes(uuid.data);
1160 		writeBytes(varuint.encode(cast(uint)username.length)); writeString(username);
1161 		writeBytes(varlong.encode(entityId));
1162 		writeBytes(varlong.encode(runtimeId));
1163 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
1164 		writeLittleEndianFloat(motion.x); writeLittleEndianFloat(motion.y); writeLittleEndianFloat(motion.z);
1165 		writeLittleEndianFloat(pitch);
1166 		writeLittleEndianFloat(headYaw);
1167 		writeLittleEndianFloat(yaw);
1168 		heldItem.encode(bufferInstance);
1169 		metadata.encode(bufferInstance);
1170 		return _buffer;
1171 	}
1172 
1173 	public pure nothrow @safe void decode(bool readId=true)() {
1174 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1175 		if(_buffer.length>=_index+16){ ubyte[16] dvz=_buffer[_index.._index+16].dup; _index+=16; uuid=UUID(dvz); }
1176 		uint dnc5bu=varuint.decode(_buffer, &_index); username=readString(dnc5bu);
1177 		entityId=varlong.decode(_buffer, &_index);
1178 		runtimeId=varlong.decode(_buffer, &_index);
1179 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
1180 		motion.x=readLittleEndianFloat(); motion.y=readLittleEndianFloat(); motion.z=readLittleEndianFloat();
1181 		pitch=readLittleEndianFloat();
1182 		headYaw=readLittleEndianFloat();
1183 		yaw=readLittleEndianFloat();
1184 		heldItem.decode(bufferInstance);
1185 		metadata=Metadata.decode(bufferInstance);
1186 	}
1187 
1188 	public static pure nothrow @safe AddPlayer fromBuffer(bool readId=true)(ubyte[] buffer) {
1189 		AddPlayer ret = new AddPlayer();
1190 		ret._buffer = buffer;
1191 		ret.decode!readId();
1192 		return ret;
1193 	}
1194 
1195 	public override string toString() {
1196 		return "AddPlayer(uuid: " ~ std.conv.to!string(this.uuid) ~ ", username: " ~ std.conv.to!string(this.username) ~ ", entityId: " ~ std.conv.to!string(this.entityId) ~ ", runtimeId: " ~ std.conv.to!string(this.runtimeId) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", motion: " ~ std.conv.to!string(this.motion) ~ ", pitch: " ~ std.conv.to!string(this.pitch) ~ ", headYaw: " ~ std.conv.to!string(this.headYaw) ~ ", yaw: " ~ std.conv.to!string(this.yaw) ~ ", heldItem: " ~ std.conv.to!string(this.heldItem) ~ ", metadata: " ~ std.conv.to!string(this.metadata) ~ ")";
1197 	}
1198 
1199 }
1200 
1201 class AddEntity : Buffer {
1202 
1203 	public enum ubyte ID = 14;
1204 
1205 	public enum bool CLIENTBOUND = true;
1206 	public enum bool SERVERBOUND = false;
1207 
1208 	public enum string[] FIELDS = ["entityId", "runtimeId", "type", "position", "motion", "pitch", "yaw", "attributes", "metadata", "links"];
1209 
1210 	public long entityId;
1211 	public long runtimeId;
1212 	public uint type;
1213 	public Tuple!(float, "x", float, "y", float, "z") position;
1214 	public Tuple!(float, "x", float, "y", float, "z") motion;
1215 	public float pitch;
1216 	public float yaw;
1217 	public sul.protocol.pocket102.types.Attribute[] attributes;
1218 	public Metadata metadata;
1219 	public sul.protocol.pocket102.types.Link[] links;
1220 
1221 	public pure nothrow @safe @nogc this() {}
1222 
1223 	public pure nothrow @safe @nogc this(long entityId, long runtimeId=long.init, uint type=uint.init, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, Tuple!(float, "x", float, "y", float, "z") motion=Tuple!(float, "x", float, "y", float, "z").init, float pitch=float.init, float yaw=float.init, sul.protocol.pocket102.types.Attribute[] attributes=(sul.protocol.pocket102.types.Attribute[]).init, Metadata metadata=Metadata.init, sul.protocol.pocket102.types.Link[] links=(sul.protocol.pocket102.types.Link[]).init) {
1224 		this.entityId = entityId;
1225 		this.runtimeId = runtimeId;
1226 		this.type = type;
1227 		this.position = position;
1228 		this.motion = motion;
1229 		this.pitch = pitch;
1230 		this.yaw = yaw;
1231 		this.attributes = attributes;
1232 		this.metadata = metadata;
1233 		this.links = links;
1234 	}
1235 
1236 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1237 		_buffer.length = 0;
1238 		static if(writeId){ writeBigEndianUbyte(ID); }
1239 		writeBytes(varlong.encode(entityId));
1240 		writeBytes(varlong.encode(runtimeId));
1241 		writeBytes(varuint.encode(type));
1242 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
1243 		writeLittleEndianFloat(motion.x); writeLittleEndianFloat(motion.y); writeLittleEndianFloat(motion.z);
1244 		writeLittleEndianFloat(pitch);
1245 		writeLittleEndianFloat(yaw);
1246 		writeBytes(varuint.encode(cast(uint)attributes.length)); foreach(yrcldrc;attributes){ yrcldrc.encode(bufferInstance); }
1247 		metadata.encode(bufferInstance);
1248 		writeBytes(varuint.encode(cast(uint)links.length)); foreach(blam;links){ blam.encode(bufferInstance); }
1249 		return _buffer;
1250 	}
1251 
1252 	public pure nothrow @safe void decode(bool readId=true)() {
1253 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1254 		entityId=varlong.decode(_buffer, &_index);
1255 		runtimeId=varlong.decode(_buffer, &_index);
1256 		type=varuint.decode(_buffer, &_index);
1257 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
1258 		motion.x=readLittleEndianFloat(); motion.y=readLittleEndianFloat(); motion.z=readLittleEndianFloat();
1259 		pitch=readLittleEndianFloat();
1260 		yaw=readLittleEndianFloat();
1261 		attributes.length=varuint.decode(_buffer, &_index); foreach(ref yrcldrc;attributes){ yrcldrc.decode(bufferInstance); }
1262 		metadata=Metadata.decode(bufferInstance);
1263 		links.length=varuint.decode(_buffer, &_index); foreach(ref blam;links){ blam.decode(bufferInstance); }
1264 	}
1265 
1266 	public static pure nothrow @safe AddEntity fromBuffer(bool readId=true)(ubyte[] buffer) {
1267 		AddEntity ret = new AddEntity();
1268 		ret._buffer = buffer;
1269 		ret.decode!readId();
1270 		return ret;
1271 	}
1272 
1273 	public override string toString() {
1274 		return "AddEntity(entityId: " ~ std.conv.to!string(this.entityId) ~ ", runtimeId: " ~ std.conv.to!string(this.runtimeId) ~ ", type: " ~ std.conv.to!string(this.type) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", motion: " ~ std.conv.to!string(this.motion) ~ ", pitch: " ~ std.conv.to!string(this.pitch) ~ ", yaw: " ~ std.conv.to!string(this.yaw) ~ ", attributes: " ~ std.conv.to!string(this.attributes) ~ ", metadata: " ~ std.conv.to!string(this.metadata) ~ ", links: " ~ std.conv.to!string(this.links) ~ ")";
1275 	}
1276 
1277 }
1278 
1279 /**
1280  * Despawns an entity or a player.
1281  */
1282 class RemoveEntity : Buffer {
1283 
1284 	public enum ubyte ID = 15;
1285 
1286 	public enum bool CLIENTBOUND = true;
1287 	public enum bool SERVERBOUND = false;
1288 
1289 	public enum string[] FIELDS = ["entityId"];
1290 
1291 	public long entityId;
1292 
1293 	public pure nothrow @safe @nogc this() {}
1294 
1295 	public pure nothrow @safe @nogc this(long entityId) {
1296 		this.entityId = entityId;
1297 	}
1298 
1299 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1300 		_buffer.length = 0;
1301 		static if(writeId){ writeBigEndianUbyte(ID); }
1302 		writeBytes(varlong.encode(entityId));
1303 		return _buffer;
1304 	}
1305 
1306 	public pure nothrow @safe void decode(bool readId=true)() {
1307 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1308 		entityId=varlong.decode(_buffer, &_index);
1309 	}
1310 
1311 	public static pure nothrow @safe RemoveEntity fromBuffer(bool readId=true)(ubyte[] buffer) {
1312 		RemoveEntity ret = new RemoveEntity();
1313 		ret._buffer = buffer;
1314 		ret.decode!readId();
1315 		return ret;
1316 	}
1317 
1318 	public override string toString() {
1319 		return "RemoveEntity(entityId: " ~ std.conv.to!string(this.entityId) ~ ")";
1320 	}
1321 
1322 }
1323 
1324 /**
1325  * Spawns a dropped item.
1326  */
1327 class AddItemEntity : Buffer {
1328 
1329 	public enum ubyte ID = 16;
1330 
1331 	public enum bool CLIENTBOUND = true;
1332 	public enum bool SERVERBOUND = false;
1333 
1334 	public enum string[] FIELDS = ["entityId", "runtimeId", "item", "position", "motion"];
1335 
1336 	public long entityId;
1337 	public long runtimeId;
1338 	public sul.protocol.pocket102.types.Slot item;
1339 	public Tuple!(float, "x", float, "y", float, "z") position;
1340 	public Tuple!(float, "x", float, "y", float, "z") motion;
1341 
1342 	public pure nothrow @safe @nogc this() {}
1343 
1344 	public pure nothrow @safe @nogc this(long entityId, long runtimeId=long.init, sul.protocol.pocket102.types.Slot item=sul.protocol.pocket102.types.Slot.init, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, Tuple!(float, "x", float, "y", float, "z") motion=Tuple!(float, "x", float, "y", float, "z").init) {
1345 		this.entityId = entityId;
1346 		this.runtimeId = runtimeId;
1347 		this.item = item;
1348 		this.position = position;
1349 		this.motion = motion;
1350 	}
1351 
1352 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1353 		_buffer.length = 0;
1354 		static if(writeId){ writeBigEndianUbyte(ID); }
1355 		writeBytes(varlong.encode(entityId));
1356 		writeBytes(varlong.encode(runtimeId));
1357 		item.encode(bufferInstance);
1358 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
1359 		writeLittleEndianFloat(motion.x); writeLittleEndianFloat(motion.y); writeLittleEndianFloat(motion.z);
1360 		return _buffer;
1361 	}
1362 
1363 	public pure nothrow @safe void decode(bool readId=true)() {
1364 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1365 		entityId=varlong.decode(_buffer, &_index);
1366 		runtimeId=varlong.decode(_buffer, &_index);
1367 		item.decode(bufferInstance);
1368 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
1369 		motion.x=readLittleEndianFloat(); motion.y=readLittleEndianFloat(); motion.z=readLittleEndianFloat();
1370 	}
1371 
1372 	public static pure nothrow @safe AddItemEntity fromBuffer(bool readId=true)(ubyte[] buffer) {
1373 		AddItemEntity ret = new AddItemEntity();
1374 		ret._buffer = buffer;
1375 		ret.decode!readId();
1376 		return ret;
1377 	}
1378 
1379 	public override string toString() {
1380 		return "AddItemEntity(entityId: " ~ std.conv.to!string(this.entityId) ~ ", runtimeId: " ~ std.conv.to!string(this.runtimeId) ~ ", item: " ~ std.conv.to!string(this.item) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", motion: " ~ std.conv.to!string(this.motion) ~ ")";
1381 	}
1382 
1383 }
1384 
1385 class AddHangingEntity : Buffer {
1386 
1387 	public enum ubyte ID = 17;
1388 
1389 	public enum bool CLIENTBOUND = true;
1390 	public enum bool SERVERBOUND = false;
1391 
1392 	public enum string[] FIELDS = ["entityId", "runtimeId", "position", "unknown3"];
1393 
1394 	public long entityId;
1395 	public long runtimeId;
1396 	public sul.protocol.pocket102.types.BlockPosition position;
1397 	public int unknown3;
1398 
1399 	public pure nothrow @safe @nogc this() {}
1400 
1401 	public pure nothrow @safe @nogc this(long entityId, long runtimeId=long.init, sul.protocol.pocket102.types.BlockPosition position=sul.protocol.pocket102.types.BlockPosition.init, int unknown3=int.init) {
1402 		this.entityId = entityId;
1403 		this.runtimeId = runtimeId;
1404 		this.position = position;
1405 		this.unknown3 = unknown3;
1406 	}
1407 
1408 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1409 		_buffer.length = 0;
1410 		static if(writeId){ writeBigEndianUbyte(ID); }
1411 		writeBytes(varlong.encode(entityId));
1412 		writeBytes(varlong.encode(runtimeId));
1413 		position.encode(bufferInstance);
1414 		writeBytes(varint.encode(unknown3));
1415 		return _buffer;
1416 	}
1417 
1418 	public pure nothrow @safe void decode(bool readId=true)() {
1419 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1420 		entityId=varlong.decode(_buffer, &_index);
1421 		runtimeId=varlong.decode(_buffer, &_index);
1422 		position.decode(bufferInstance);
1423 		unknown3=varint.decode(_buffer, &_index);
1424 	}
1425 
1426 	public static pure nothrow @safe AddHangingEntity fromBuffer(bool readId=true)(ubyte[] buffer) {
1427 		AddHangingEntity ret = new AddHangingEntity();
1428 		ret._buffer = buffer;
1429 		ret.decode!readId();
1430 		return ret;
1431 	}
1432 
1433 	public override string toString() {
1434 		return "AddHangingEntity(entityId: " ~ std.conv.to!string(this.entityId) ~ ", runtimeId: " ~ std.conv.to!string(this.runtimeId) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", unknown3: " ~ std.conv.to!string(this.unknown3) ~ ")";
1435 	}
1436 
1437 }
1438 
1439 /**
1440  * Plays the collection animation and despawns the entity that has been collected.
1441  */
1442 class TakeItemEntity : Buffer {
1443 
1444 	public enum ubyte ID = 18;
1445 
1446 	public enum bool CLIENTBOUND = true;
1447 	public enum bool SERVERBOUND = false;
1448 
1449 	public enum string[] FIELDS = ["collected", "collector"];
1450 
1451 	/**
1452 	 * Collected entity, usually an item entity or an arrow, that will float toward the
1453 	 * collector and despawn.
1454 	 */
1455 	public long collected;
1456 
1457 	/**
1458 	 * Entity that collects, usually a player or another entity with an inventory.
1459 	 */
1460 	public long collector;
1461 
1462 	public pure nothrow @safe @nogc this() {}
1463 
1464 	public pure nothrow @safe @nogc this(long collected, long collector=long.init) {
1465 		this.collected = collected;
1466 		this.collector = collector;
1467 	}
1468 
1469 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1470 		_buffer.length = 0;
1471 		static if(writeId){ writeBigEndianUbyte(ID); }
1472 		writeBytes(varlong.encode(collected));
1473 		writeBytes(varlong.encode(collector));
1474 		return _buffer;
1475 	}
1476 
1477 	public pure nothrow @safe void decode(bool readId=true)() {
1478 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1479 		collected=varlong.decode(_buffer, &_index);
1480 		collector=varlong.decode(_buffer, &_index);
1481 	}
1482 
1483 	public static pure nothrow @safe TakeItemEntity fromBuffer(bool readId=true)(ubyte[] buffer) {
1484 		TakeItemEntity ret = new TakeItemEntity();
1485 		ret._buffer = buffer;
1486 		ret.decode!readId();
1487 		return ret;
1488 	}
1489 
1490 	public override string toString() {
1491 		return "TakeItemEntity(collected: " ~ std.conv.to!string(this.collected) ~ ", collector: " ~ std.conv.to!string(this.collector) ~ ")";
1492 	}
1493 
1494 }
1495 
1496 class MoveEntity : Buffer {
1497 
1498 	public enum ubyte ID = 19;
1499 
1500 	public enum bool CLIENTBOUND = true;
1501 	public enum bool SERVERBOUND = false;
1502 
1503 	public enum string[] FIELDS = ["entityId", "position", "pitch", "headYaw", "yaw"];
1504 
1505 	public long entityId;
1506 	public Tuple!(float, "x", float, "y", float, "z") position;
1507 	public ubyte pitch;
1508 	public ubyte headYaw;
1509 	public ubyte yaw;
1510 
1511 	public pure nothrow @safe @nogc this() {}
1512 
1513 	public pure nothrow @safe @nogc this(long entityId, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, ubyte pitch=ubyte.init, ubyte headYaw=ubyte.init, ubyte yaw=ubyte.init) {
1514 		this.entityId = entityId;
1515 		this.position = position;
1516 		this.pitch = pitch;
1517 		this.headYaw = headYaw;
1518 		this.yaw = yaw;
1519 	}
1520 
1521 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1522 		_buffer.length = 0;
1523 		static if(writeId){ writeBigEndianUbyte(ID); }
1524 		writeBytes(varlong.encode(entityId));
1525 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
1526 		writeBigEndianUbyte(pitch);
1527 		writeBigEndianUbyte(headYaw);
1528 		writeBigEndianUbyte(yaw);
1529 		return _buffer;
1530 	}
1531 
1532 	public pure nothrow @safe void decode(bool readId=true)() {
1533 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1534 		entityId=varlong.decode(_buffer, &_index);
1535 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
1536 		pitch=readBigEndianUbyte();
1537 		headYaw=readBigEndianUbyte();
1538 		yaw=readBigEndianUbyte();
1539 	}
1540 
1541 	public static pure nothrow @safe MoveEntity fromBuffer(bool readId=true)(ubyte[] buffer) {
1542 		MoveEntity ret = new MoveEntity();
1543 		ret._buffer = buffer;
1544 		ret.decode!readId();
1545 		return ret;
1546 	}
1547 
1548 	public override string toString() {
1549 		return "MoveEntity(entityId: " ~ std.conv.to!string(this.entityId) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", pitch: " ~ std.conv.to!string(this.pitch) ~ ", headYaw: " ~ std.conv.to!string(this.headYaw) ~ ", yaw: " ~ std.conv.to!string(this.yaw) ~ ")";
1550 	}
1551 
1552 }
1553 
1554 class MovePlayer : Buffer {
1555 
1556 	public enum ubyte ID = 20;
1557 
1558 	public enum bool CLIENTBOUND = true;
1559 	public enum bool SERVERBOUND = true;
1560 
1561 	// animation
1562 	public enum ubyte FULL = 0;
1563 	public enum ubyte NONE = 1;
1564 	public enum ubyte ROTATION = 2;
1565 
1566 	public enum string[] FIELDS = ["entityId", "position", "pitch", "headYaw", "yaw", "animation", "onGround"];
1567 
1568 	public long entityId;
1569 	public Tuple!(float, "x", float, "y", float, "z") position;
1570 	public float pitch;
1571 	public float headYaw;
1572 	public float yaw;
1573 	public ubyte animation;
1574 	public bool onGround;
1575 
1576 	public pure nothrow @safe @nogc this() {}
1577 
1578 	public pure nothrow @safe @nogc this(long entityId, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, float pitch=float.init, float headYaw=float.init, float yaw=float.init, ubyte animation=ubyte.init, bool onGround=bool.init) {
1579 		this.entityId = entityId;
1580 		this.position = position;
1581 		this.pitch = pitch;
1582 		this.headYaw = headYaw;
1583 		this.yaw = yaw;
1584 		this.animation = animation;
1585 		this.onGround = onGround;
1586 	}
1587 
1588 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1589 		_buffer.length = 0;
1590 		static if(writeId){ writeBigEndianUbyte(ID); }
1591 		writeBytes(varlong.encode(entityId));
1592 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
1593 		writeLittleEndianFloat(pitch);
1594 		writeLittleEndianFloat(headYaw);
1595 		writeLittleEndianFloat(yaw);
1596 		writeBigEndianUbyte(animation);
1597 		writeBigEndianBool(onGround);
1598 		return _buffer;
1599 	}
1600 
1601 	public pure nothrow @safe void decode(bool readId=true)() {
1602 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1603 		entityId=varlong.decode(_buffer, &_index);
1604 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
1605 		pitch=readLittleEndianFloat();
1606 		headYaw=readLittleEndianFloat();
1607 		yaw=readLittleEndianFloat();
1608 		animation=readBigEndianUbyte();
1609 		onGround=readBigEndianBool();
1610 	}
1611 
1612 	public static pure nothrow @safe MovePlayer fromBuffer(bool readId=true)(ubyte[] buffer) {
1613 		MovePlayer ret = new MovePlayer();
1614 		ret._buffer = buffer;
1615 		ret.decode!readId();
1616 		return ret;
1617 	}
1618 
1619 	public override string toString() {
1620 		return "MovePlayer(entityId: " ~ std.conv.to!string(this.entityId) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", pitch: " ~ std.conv.to!string(this.pitch) ~ ", headYaw: " ~ std.conv.to!string(this.headYaw) ~ ", yaw: " ~ std.conv.to!string(this.yaw) ~ ", animation: " ~ std.conv.to!string(this.animation) ~ ", onGround: " ~ std.conv.to!string(this.onGround) ~ ")";
1621 	}
1622 
1623 }
1624 
1625 class RiderJump : Buffer {
1626 
1627 	public enum ubyte ID = 21;
1628 
1629 	public enum bool CLIENTBOUND = true;
1630 	public enum bool SERVERBOUND = true;
1631 
1632 	public enum string[] FIELDS = ["rider"];
1633 
1634 	public long rider;
1635 
1636 	public pure nothrow @safe @nogc this() {}
1637 
1638 	public pure nothrow @safe @nogc this(long rider) {
1639 		this.rider = rider;
1640 	}
1641 
1642 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1643 		_buffer.length = 0;
1644 		static if(writeId){ writeBigEndianUbyte(ID); }
1645 		writeBytes(varlong.encode(rider));
1646 		return _buffer;
1647 	}
1648 
1649 	public pure nothrow @safe void decode(bool readId=true)() {
1650 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1651 		rider=varlong.decode(_buffer, &_index);
1652 	}
1653 
1654 	public static pure nothrow @safe RiderJump fromBuffer(bool readId=true)(ubyte[] buffer) {
1655 		RiderJump ret = new RiderJump();
1656 		ret._buffer = buffer;
1657 		ret.decode!readId();
1658 		return ret;
1659 	}
1660 
1661 	public override string toString() {
1662 		return "RiderJump(rider: " ~ std.conv.to!string(this.rider) ~ ")";
1663 	}
1664 
1665 }
1666 
1667 /**
1668  * Instantly removes a block, either because the player is in creative mode or because
1669  * the target block's hardness is 0 or lower (after all enchantments are applied).
1670  */
1671 class RemoveBlock : Buffer {
1672 
1673 	public enum ubyte ID = 22;
1674 
1675 	public enum bool CLIENTBOUND = false;
1676 	public enum bool SERVERBOUND = true;
1677 
1678 	public enum string[] FIELDS = ["position"];
1679 
1680 	public sul.protocol.pocket102.types.BlockPosition position;
1681 
1682 	public pure nothrow @safe @nogc this() {}
1683 
1684 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.BlockPosition position) {
1685 		this.position = position;
1686 	}
1687 
1688 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1689 		_buffer.length = 0;
1690 		static if(writeId){ writeBigEndianUbyte(ID); }
1691 		position.encode(bufferInstance);
1692 		return _buffer;
1693 	}
1694 
1695 	public pure nothrow @safe void decode(bool readId=true)() {
1696 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1697 		position.decode(bufferInstance);
1698 	}
1699 
1700 	public static pure nothrow @safe RemoveBlock fromBuffer(bool readId=true)(ubyte[] buffer) {
1701 		RemoveBlock ret = new RemoveBlock();
1702 		ret._buffer = buffer;
1703 		ret.decode!readId();
1704 		return ret;
1705 	}
1706 
1707 	public override string toString() {
1708 		return "RemoveBlock(position: " ~ std.conv.to!string(this.position) ~ ")";
1709 	}
1710 
1711 }
1712 
1713 class UpdateBlock : Buffer {
1714 
1715 	public enum ubyte ID = 23;
1716 
1717 	public enum bool CLIENTBOUND = true;
1718 	public enum bool SERVERBOUND = false;
1719 
1720 	// flags and meta
1721 	public enum uint NEIGHBORS = 1;
1722 	public enum uint NETWORK = 2;
1723 	public enum uint NO_GRAPHIC = 4;
1724 	public enum uint PRIORITY = 8;
1725 
1726 	public enum string[] FIELDS = ["position", "block", "flagsAndMeta"];
1727 
1728 	public sul.protocol.pocket102.types.BlockPosition position;
1729 	public uint block;
1730 	public uint flagsAndMeta;
1731 
1732 	public pure nothrow @safe @nogc this() {}
1733 
1734 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.BlockPosition position, uint block=uint.init, uint flagsAndMeta=uint.init) {
1735 		this.position = position;
1736 		this.block = block;
1737 		this.flagsAndMeta = flagsAndMeta;
1738 	}
1739 
1740 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1741 		_buffer.length = 0;
1742 		static if(writeId){ writeBigEndianUbyte(ID); }
1743 		position.encode(bufferInstance);
1744 		writeBytes(varuint.encode(block));
1745 		writeBytes(varuint.encode(flagsAndMeta));
1746 		return _buffer;
1747 	}
1748 
1749 	public pure nothrow @safe void decode(bool readId=true)() {
1750 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1751 		position.decode(bufferInstance);
1752 		block=varuint.decode(_buffer, &_index);
1753 		flagsAndMeta=varuint.decode(_buffer, &_index);
1754 	}
1755 
1756 	public static pure nothrow @safe UpdateBlock fromBuffer(bool readId=true)(ubyte[] buffer) {
1757 		UpdateBlock ret = new UpdateBlock();
1758 		ret._buffer = buffer;
1759 		ret.decode!readId();
1760 		return ret;
1761 	}
1762 
1763 	public override string toString() {
1764 		return "UpdateBlock(position: " ~ std.conv.to!string(this.position) ~ ", block: " ~ std.conv.to!string(this.block) ~ ", flagsAndMeta: " ~ std.conv.to!string(this.flagsAndMeta) ~ ")";
1765 	}
1766 
1767 }
1768 
1769 /**
1770  * Spawns a painting entity in the world.
1771  */
1772 class AddPainting : Buffer {
1773 
1774 	public enum ubyte ID = 24;
1775 
1776 	public enum bool CLIENTBOUND = true;
1777 	public enum bool SERVERBOUND = false;
1778 
1779 	public enum string[] FIELDS = ["entityId", "runtimeId", "position", "direction", "title"];
1780 
1781 	public long entityId;
1782 	public long runtimeId;
1783 	public sul.protocol.pocket102.types.BlockPosition position;
1784 	public int direction;
1785 	public string title;
1786 
1787 	public pure nothrow @safe @nogc this() {}
1788 
1789 	public pure nothrow @safe @nogc this(long entityId, long runtimeId=long.init, sul.protocol.pocket102.types.BlockPosition position=sul.protocol.pocket102.types.BlockPosition.init, int direction=int.init, string title=string.init) {
1790 		this.entityId = entityId;
1791 		this.runtimeId = runtimeId;
1792 		this.position = position;
1793 		this.direction = direction;
1794 		this.title = title;
1795 	}
1796 
1797 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1798 		_buffer.length = 0;
1799 		static if(writeId){ writeBigEndianUbyte(ID); }
1800 		writeBytes(varlong.encode(entityId));
1801 		writeBytes(varlong.encode(runtimeId));
1802 		position.encode(bufferInstance);
1803 		writeBytes(varint.encode(direction));
1804 		writeBytes(varuint.encode(cast(uint)title.length)); writeString(title);
1805 		return _buffer;
1806 	}
1807 
1808 	public pure nothrow @safe void decode(bool readId=true)() {
1809 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1810 		entityId=varlong.decode(_buffer, &_index);
1811 		runtimeId=varlong.decode(_buffer, &_index);
1812 		position.decode(bufferInstance);
1813 		direction=varint.decode(_buffer, &_index);
1814 		uint dlbu=varuint.decode(_buffer, &_index); title=readString(dlbu);
1815 	}
1816 
1817 	public static pure nothrow @safe AddPainting fromBuffer(bool readId=true)(ubyte[] buffer) {
1818 		AddPainting ret = new AddPainting();
1819 		ret._buffer = buffer;
1820 		ret.decode!readId();
1821 		return ret;
1822 	}
1823 
1824 	public override string toString() {
1825 		return "AddPainting(entityId: " ~ std.conv.to!string(this.entityId) ~ ", runtimeId: " ~ std.conv.to!string(this.runtimeId) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", direction: " ~ std.conv.to!string(this.direction) ~ ", title: " ~ std.conv.to!string(this.title) ~ ")";
1826 	}
1827 
1828 }
1829 
1830 class Explode : Buffer {
1831 
1832 	public enum ubyte ID = 25;
1833 
1834 	public enum bool CLIENTBOUND = true;
1835 	public enum bool SERVERBOUND = false;
1836 
1837 	public enum string[] FIELDS = ["position", "radius", "destroyedBlocks"];
1838 
1839 	public Tuple!(float, "x", float, "y", float, "z") position;
1840 	public float radius;
1841 	public sul.protocol.pocket102.types.BlockPosition[] destroyedBlocks;
1842 
1843 	public pure nothrow @safe @nogc this() {}
1844 
1845 	public pure nothrow @safe @nogc this(Tuple!(float, "x", float, "y", float, "z") position, float radius=float.init, sul.protocol.pocket102.types.BlockPosition[] destroyedBlocks=(sul.protocol.pocket102.types.BlockPosition[]).init) {
1846 		this.position = position;
1847 		this.radius = radius;
1848 		this.destroyedBlocks = destroyedBlocks;
1849 	}
1850 
1851 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
1852 		_buffer.length = 0;
1853 		static if(writeId){ writeBigEndianUbyte(ID); }
1854 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
1855 		writeLittleEndianFloat(radius);
1856 		writeBytes(varuint.encode(cast(uint)destroyedBlocks.length)); foreach(zvdjevqx;destroyedBlocks){ zvdjevqx.encode(bufferInstance); }
1857 		return _buffer;
1858 	}
1859 
1860 	public pure nothrow @safe void decode(bool readId=true)() {
1861 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
1862 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
1863 		radius=readLittleEndianFloat();
1864 		destroyedBlocks.length=varuint.decode(_buffer, &_index); foreach(ref zvdjevqx;destroyedBlocks){ zvdjevqx.decode(bufferInstance); }
1865 	}
1866 
1867 	public static pure nothrow @safe Explode fromBuffer(bool readId=true)(ubyte[] buffer) {
1868 		Explode ret = new Explode();
1869 		ret._buffer = buffer;
1870 		ret.decode!readId();
1871 		return ret;
1872 	}
1873 
1874 	public override string toString() {
1875 		return "Explode(position: " ~ std.conv.to!string(this.position) ~ ", radius: " ~ std.conv.to!string(this.radius) ~ ", destroyedBlocks: " ~ std.conv.to!string(this.destroyedBlocks) ~ ")";
1876 	}
1877 
1878 }
1879 
1880 /**
1881  * Plays a sound at a certain position.
1882  */
1883 class LevelSoundEvent : Buffer {
1884 
1885 	public enum ubyte ID = 26;
1886 
1887 	public enum bool CLIENTBOUND = true;
1888 	public enum bool SERVERBOUND = true;
1889 
1890 	// sound
1891 	public enum ubyte ITEM_USE_ON = 0;
1892 	public enum ubyte HIT = 1;
1893 	public enum ubyte STEP = 2;
1894 	public enum ubyte JUMP = 3;
1895 	public enum ubyte BREAK = 4;
1896 	public enum ubyte PLACE = 5;
1897 	public enum ubyte HEAVY_STEP = 6;
1898 	public enum ubyte GALLOP = 7;
1899 	public enum ubyte FALL = 8;
1900 	public enum ubyte AMBIENT = 9;
1901 	public enum ubyte AMBIENT_BABY = 10;
1902 	public enum ubyte AMBIENT_IN_WATER = 11;
1903 	public enum ubyte BREATHE = 12;
1904 	public enum ubyte DEATH = 13;
1905 	public enum ubyte DEATH_IN_WATER = 14;
1906 	public enum ubyte DEATH_TO_ZOMBIE = 15;
1907 	public enum ubyte HURT = 16;
1908 	public enum ubyte HURT_IN_WATER = 17;
1909 	public enum ubyte MAD = 18;
1910 	public enum ubyte BOOST = 19;
1911 	public enum ubyte BOW = 20;
1912 	public enum ubyte SQUISH_BIG = 21;
1913 	public enum ubyte SQUISH_SMALL = 22;
1914 	public enum ubyte FALL_BIG = 23;
1915 	public enum ubyte FALL_SMALL = 24;
1916 	public enum ubyte SPLASH = 25;
1917 	public enum ubyte FIZZ = 26;
1918 	public enum ubyte FLAP = 27;
1919 	public enum ubyte SWIM = 28;
1920 	public enum ubyte DRINK = 29;
1921 	public enum ubyte EAT = 30;
1922 	public enum ubyte TAKEOFF = 31;
1923 	public enum ubyte SHAKE = 32;
1924 	public enum ubyte PLOP = 33;
1925 	public enum ubyte LAND = 34;
1926 	public enum ubyte SADDLE = 35;
1927 	public enum ubyte ARMOR = 36;
1928 	public enum ubyte ADD_CHEST = 37;
1929 	public enum ubyte THROW = 38;
1930 	public enum ubyte ATTACK = 39;
1931 	public enum ubyte ATTACK_NODAMAGE = 40;
1932 	public enum ubyte WARN = 41;
1933 	public enum ubyte SHEAR = 42;
1934 	public enum ubyte MILK = 43;
1935 	public enum ubyte THUNDER = 44;
1936 	public enum ubyte EXPLODE = 45;
1937 	public enum ubyte FIRE = 46;
1938 	public enum ubyte IGNITE = 47;
1939 	public enum ubyte FUSE = 48;
1940 	public enum ubyte STARE = 49;
1941 	public enum ubyte SPAWN = 50;
1942 	public enum ubyte SHOOT = 51;
1943 	public enum ubyte BREAK_BLOCK = 52;
1944 	public enum ubyte REMEDY = 53;
1945 	public enum ubyte UNFECT = 54;
1946 	public enum ubyte LEVELUP = 55;
1947 	public enum ubyte BOW_HIT = 56;
1948 	public enum ubyte BULLET_HIT = 57;
1949 	public enum ubyte EXTINGUISH_FIRE = 58;
1950 	public enum ubyte ITEM_FIZZ = 59;
1951 	public enum ubyte CHEST_OPEN = 60;
1952 	public enum ubyte CHEST_CLOSED = 61;
1953 	public enum ubyte POWER_ON = 62;
1954 	public enum ubyte POWER_OFF = 63;
1955 	public enum ubyte ATTACH = 64;
1956 	public enum ubyte DETACH = 65;
1957 	public enum ubyte DENY = 66;
1958 	public enum ubyte TRIPOD = 67;
1959 	public enum ubyte POP = 68;
1960 	public enum ubyte DROP_SLOT = 69;
1961 	public enum ubyte NOTE = 70;
1962 	public enum ubyte THORNS = 71;
1963 	public enum ubyte PISTON_IN = 72;
1964 	public enum ubyte PISTON_OUT = 73;
1965 	public enum ubyte PORTAL = 74;
1966 	public enum ubyte WATER = 75;
1967 	public enum ubyte LAVA_POP = 76;
1968 	public enum ubyte LAVA = 77;
1969 	public enum ubyte BURP = 78;
1970 	public enum ubyte BUCKET_FILL_WATER = 79;
1971 	public enum ubyte BUCKET_FILL_LAVA = 80;
1972 	public enum ubyte BUCKET_EMPTY_WATER = 81;
1973 	public enum ubyte BUCKET_EMPTY_LAVA = 82;
1974 	public enum ubyte GUARDIAN_FLOP = 83;
1975 	public enum ubyte ELDERGUARDIAN_CURSE = 84;
1976 	public enum ubyte MOB_WARNING = 85;
1977 	public enum ubyte MOB_WARNING_BABY = 86;
1978 	public enum ubyte TELEPORT = 87;
1979 	public enum ubyte SHULKER_OPEN = 88;
1980 	public enum ubyte SHULKER_CLOSE = 89;
1981 	public enum ubyte HAGGLE = 90;
1982 	public enum ubyte HAGGLE_YES = 91;
1983 	public enum ubyte HAGGLE_NO = 92;
1984 	public enum ubyte HAGGLE_IDLE = 93;
1985 	public enum ubyte DEFAULT = 94;
1986 	public enum ubyte UNDEFINED = 95;
1987 
1988 	public enum string[] FIELDS = ["sound", "position", "volume", "pitch", "unknown4"];
1989 
1990 	public ubyte sound;
1991 
1992 	/**
1993 	 * Position where the sound was generated. The closer to the player the more intense
1994 	 * will be on the client.
1995 	 */
1996 	public Tuple!(float, "x", float, "y", float, "z") position;
1997 	public uint volume;
1998 	public int pitch;
1999 	public bool unknown4;
2000 
2001 	public pure nothrow @safe @nogc this() {}
2002 
2003 	public pure nothrow @safe @nogc this(ubyte sound, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, uint volume=uint.init, int pitch=int.init, bool unknown4=bool.init) {
2004 		this.sound = sound;
2005 		this.position = position;
2006 		this.volume = volume;
2007 		this.pitch = pitch;
2008 		this.unknown4 = unknown4;
2009 	}
2010 
2011 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2012 		_buffer.length = 0;
2013 		static if(writeId){ writeBigEndianUbyte(ID); }
2014 		writeBigEndianUbyte(sound);
2015 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
2016 		writeBytes(varuint.encode(volume));
2017 		writeBytes(varint.encode(pitch));
2018 		writeBigEndianBool(unknown4);
2019 		return _buffer;
2020 	}
2021 
2022 	public pure nothrow @safe void decode(bool readId=true)() {
2023 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2024 		sound=readBigEndianUbyte();
2025 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
2026 		volume=varuint.decode(_buffer, &_index);
2027 		pitch=varint.decode(_buffer, &_index);
2028 		unknown4=readBigEndianBool();
2029 	}
2030 
2031 	public static pure nothrow @safe LevelSoundEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
2032 		LevelSoundEvent ret = new LevelSoundEvent();
2033 		ret._buffer = buffer;
2034 		ret.decode!readId();
2035 		return ret;
2036 	}
2037 
2038 	public override string toString() {
2039 		return "LevelSoundEvent(sound: " ~ std.conv.to!string(this.sound) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", volume: " ~ std.conv.to!string(this.volume) ~ ", pitch: " ~ std.conv.to!string(this.pitch) ~ ", unknown4: " ~ std.conv.to!string(this.unknown4) ~ ")";
2040 	}
2041 
2042 }
2043 
2044 class LevelEvent : Buffer {
2045 
2046 	public enum ubyte ID = 27;
2047 
2048 	public enum bool CLIENTBOUND = true;
2049 	public enum bool SERVERBOUND = false;
2050 
2051 	// event id
2052 	public enum int START_RAIN = 3001;
2053 	public enum int START_THUNDER = 3002;
2054 	public enum int STOP_RAIN = 3003;
2055 	public enum int STOP_THUNDER = 3004;
2056 	public enum int SET_DATA = 4000;
2057 	public enum int PLAYERS_SLEEPING = 9800;
2058 	public enum int BUBBLE = 16385;
2059 	public enum int CRITICAL = 16386;
2060 	public enum int BLOCK_FORCE_FIELD = 16387;
2061 	public enum int SMOKE = 16388;
2062 	public enum int EXPLODE = 16389;
2063 	public enum int EVAPORATION = 16390;
2064 	public enum int FLAME = 16391;
2065 	public enum int LAVA = 16392;
2066 	public enum int LARGE_SMOKE = 16393;
2067 	public enum int REDSTONE = 16394;
2068 	public enum int RISING_RED_DUST = 16395;
2069 	public enum int ITEM_BREAK = 16396;
2070 	public enum int SNOWBALL_POOF = 16397;
2071 	public enum int HUGE_EXPLODE = 16398;
2072 	public enum int HUGE_EXPLODE_SEED = 16399;
2073 	public enum int MOB_FLAME = 16400;
2074 	public enum int HEART = 16401;
2075 	public enum int TERRAIN = 16402;
2076 	public enum int TOWN_AURA = 16403;
2077 	public enum int PORTAL = 16404;
2078 	public enum int WATER_SPLASH = 16405;
2079 	public enum int WATER_WAKE = 16406;
2080 	public enum int DRIP_WATER = 16407;
2081 	public enum int DRIP_LAVA = 16408;
2082 	public enum int FALLING_DUST = 16409;
2083 	public enum int MOB_SPELL = 16410;
2084 	public enum int MOB_SPELL_AMBIENT = 16411;
2085 	public enum int MOB_SPELL_INSTANTANEOUS = 16412;
2086 	public enum int INK = 16413;
2087 	public enum int SLIME = 16414;
2088 	public enum int RAIN_SPLASH = 16415;
2089 	public enum int VILLAGER_ANGRY = 16416;
2090 	public enum int VILLAGER_HAPPY = 16417;
2091 	public enum int ENCHANTMENT_TABLE = 16418;
2092 	public enum int TRACKING_EMITTER = 16419;
2093 	public enum int NOTE = 16420;
2094 	public enum int WITCH_SPELL = 16421;
2095 	public enum int CARROT = 16422;
2096 	public enum int END_ROD = 16424;
2097 	public enum int DRAGON_BREATH = 16425;
2098 	public enum int SHOOT = 2000;
2099 	public enum int DESTROY = 2001;
2100 
2101 	public enum string[] FIELDS = ["eventId", "position", "data"];
2102 
2103 	public int eventId;
2104 	public Tuple!(float, "x", float, "y", float, "z") position;
2105 	public int data;
2106 
2107 	public pure nothrow @safe @nogc this() {}
2108 
2109 	public pure nothrow @safe @nogc this(int eventId, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, int data=int.init) {
2110 		this.eventId = eventId;
2111 		this.position = position;
2112 		this.data = data;
2113 	}
2114 
2115 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2116 		_buffer.length = 0;
2117 		static if(writeId){ writeBigEndianUbyte(ID); }
2118 		writeBytes(varint.encode(eventId));
2119 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
2120 		writeBytes(varint.encode(data));
2121 		return _buffer;
2122 	}
2123 
2124 	public pure nothrow @safe void decode(bool readId=true)() {
2125 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2126 		eventId=varint.decode(_buffer, &_index);
2127 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
2128 		data=varint.decode(_buffer, &_index);
2129 	}
2130 
2131 	public static pure nothrow @safe LevelEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
2132 		LevelEvent ret = new LevelEvent();
2133 		ret._buffer = buffer;
2134 		ret.decode!readId();
2135 		return ret;
2136 	}
2137 
2138 	public override string toString() {
2139 		return "LevelEvent(eventId: " ~ std.conv.to!string(this.eventId) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
2140 	}
2141 
2142 }
2143 
2144 class BlockEvent : Buffer {
2145 
2146 	public enum ubyte ID = 28;
2147 
2148 	public enum bool CLIENTBOUND = true;
2149 	public enum bool SERVERBOUND = false;
2150 
2151 	public enum string[] FIELDS = ["position", "data"];
2152 
2153 	public sul.protocol.pocket102.types.BlockPosition position;
2154 	public int[2] data;
2155 
2156 	public pure nothrow @safe @nogc this() {}
2157 
2158 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.BlockPosition position, int[2] data=(int[2]).init) {
2159 		this.position = position;
2160 		this.data = data;
2161 	}
2162 
2163 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2164 		_buffer.length = 0;
2165 		static if(writeId){ writeBigEndianUbyte(ID); }
2166 		position.encode(bufferInstance);
2167 		foreach(zfy;data){ writeBytes(varint.encode(zfy)); }
2168 		return _buffer;
2169 	}
2170 
2171 	public pure nothrow @safe void decode(bool readId=true)() {
2172 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2173 		position.decode(bufferInstance);
2174 		foreach(ref zfy;data){ zfy=varint.decode(_buffer, &_index); }
2175 	}
2176 
2177 	public static pure nothrow @safe BlockEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
2178 		BlockEvent ret = new BlockEvent();
2179 		ret._buffer = buffer;
2180 		ret.decode!readId();
2181 		return ret;
2182 	}
2183 
2184 	public override string toString() {
2185 		return "BlockEvent(position: " ~ std.conv.to!string(this.position) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
2186 	}
2187 
2188 }
2189 
2190 class EntityEvent : Buffer {
2191 
2192 	public enum ubyte ID = 29;
2193 
2194 	public enum bool CLIENTBOUND = true;
2195 	public enum bool SERVERBOUND = true;
2196 
2197 	// event id
2198 	public enum ubyte HURT_ANIMATION = 2;
2199 	public enum ubyte DEATH_ANIMATION = 3;
2200 	public enum ubyte TAME_FAIL = 6;
2201 	public enum ubyte TAME_SUCCESS = 7;
2202 	public enum ubyte SHAKE_WET = 8;
2203 	public enum ubyte USE_ITEM = 9;
2204 	public enum ubyte EAT_GRASS_ANIMATION = 10;
2205 	public enum ubyte FISH_HOOK_BUBBLES = 11;
2206 	public enum ubyte FISH_HOOK_POSITION = 12;
2207 	public enum ubyte FISH_HOOK_HOOK = 13;
2208 	public enum ubyte FISH_HOOK_TEASE = 14;
2209 	public enum ubyte SQUID_INK_CLOUD = 15;
2210 	public enum ubyte AMBIENT_SOUND = 16;
2211 	public enum ubyte RESPAWN = 17;
2212 
2213 	public enum string[] FIELDS = ["entityId", "eventId", "unknown2"];
2214 
2215 	public long entityId;
2216 	public ubyte eventId;
2217 	public int unknown2;
2218 
2219 	public pure nothrow @safe @nogc this() {}
2220 
2221 	public pure nothrow @safe @nogc this(long entityId, ubyte eventId=ubyte.init, int unknown2=int.init) {
2222 		this.entityId = entityId;
2223 		this.eventId = eventId;
2224 		this.unknown2 = unknown2;
2225 	}
2226 
2227 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2228 		_buffer.length = 0;
2229 		static if(writeId){ writeBigEndianUbyte(ID); }
2230 		writeBytes(varlong.encode(entityId));
2231 		writeBigEndianUbyte(eventId);
2232 		writeBytes(varint.encode(unknown2));
2233 		return _buffer;
2234 	}
2235 
2236 	public pure nothrow @safe void decode(bool readId=true)() {
2237 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2238 		entityId=varlong.decode(_buffer, &_index);
2239 		eventId=readBigEndianUbyte();
2240 		unknown2=varint.decode(_buffer, &_index);
2241 	}
2242 
2243 	public static pure nothrow @safe EntityEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
2244 		EntityEvent ret = new EntityEvent();
2245 		ret._buffer = buffer;
2246 		ret.decode!readId();
2247 		return ret;
2248 	}
2249 
2250 	public override string toString() {
2251 		return "EntityEvent(entityId: " ~ std.conv.to!string(this.entityId) ~ ", eventId: " ~ std.conv.to!string(this.eventId) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
2252 	}
2253 
2254 }
2255 
2256 class MobEffect : Buffer {
2257 
2258 	public enum ubyte ID = 30;
2259 
2260 	public enum bool CLIENTBOUND = true;
2261 	public enum bool SERVERBOUND = false;
2262 
2263 	// event id
2264 	public enum ubyte ADD = 1;
2265 	public enum ubyte MODIFY = 2;
2266 	public enum ubyte REMOVE = 3;
2267 
2268 	public enum string[] FIELDS = ["entityId", "eventId", "effect", "amplifier", "particles", "duration"];
2269 
2270 	public long entityId;
2271 	public ubyte eventId;
2272 	public int effect;
2273 	public int amplifier;
2274 	public bool particles;
2275 	public int duration;
2276 
2277 	public pure nothrow @safe @nogc this() {}
2278 
2279 	public pure nothrow @safe @nogc this(long entityId, ubyte eventId=ubyte.init, int effect=int.init, int amplifier=int.init, bool particles=bool.init, int duration=int.init) {
2280 		this.entityId = entityId;
2281 		this.eventId = eventId;
2282 		this.effect = effect;
2283 		this.amplifier = amplifier;
2284 		this.particles = particles;
2285 		this.duration = duration;
2286 	}
2287 
2288 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2289 		_buffer.length = 0;
2290 		static if(writeId){ writeBigEndianUbyte(ID); }
2291 		writeBytes(varlong.encode(entityId));
2292 		writeBigEndianUbyte(eventId);
2293 		writeBytes(varint.encode(effect));
2294 		writeBytes(varint.encode(amplifier));
2295 		writeBigEndianBool(particles);
2296 		writeBytes(varint.encode(duration));
2297 		return _buffer;
2298 	}
2299 
2300 	public pure nothrow @safe void decode(bool readId=true)() {
2301 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2302 		entityId=varlong.decode(_buffer, &_index);
2303 		eventId=readBigEndianUbyte();
2304 		effect=varint.decode(_buffer, &_index);
2305 		amplifier=varint.decode(_buffer, &_index);
2306 		particles=readBigEndianBool();
2307 		duration=varint.decode(_buffer, &_index);
2308 	}
2309 
2310 	public static pure nothrow @safe MobEffect fromBuffer(bool readId=true)(ubyte[] buffer) {
2311 		MobEffect ret = new MobEffect();
2312 		ret._buffer = buffer;
2313 		ret.decode!readId();
2314 		return ret;
2315 	}
2316 
2317 	public override string toString() {
2318 		return "MobEffect(entityId: " ~ std.conv.to!string(this.entityId) ~ ", eventId: " ~ std.conv.to!string(this.eventId) ~ ", effect: " ~ std.conv.to!string(this.effect) ~ ", amplifier: " ~ std.conv.to!string(this.amplifier) ~ ", particles: " ~ std.conv.to!string(this.particles) ~ ", duration: " ~ std.conv.to!string(this.duration) ~ ")";
2319 	}
2320 
2321 }
2322 
2323 /**
2324  * Updates an entity's attributes. This packet should be used when a value must be
2325  * modified but it cannot be done using another packet (for example controlling the
2326  * player's experience and level).
2327  */
2328 class UpdateAttributes : Buffer {
2329 
2330 	public enum ubyte ID = 31;
2331 
2332 	public enum bool CLIENTBOUND = true;
2333 	public enum bool SERVERBOUND = false;
2334 
2335 	public enum string[] FIELDS = ["entityId", "attributes"];
2336 
2337 	public long entityId;
2338 	public sul.protocol.pocket102.types.Attribute[] attributes;
2339 
2340 	public pure nothrow @safe @nogc this() {}
2341 
2342 	public pure nothrow @safe @nogc this(long entityId, sul.protocol.pocket102.types.Attribute[] attributes=(sul.protocol.pocket102.types.Attribute[]).init) {
2343 		this.entityId = entityId;
2344 		this.attributes = attributes;
2345 	}
2346 
2347 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2348 		_buffer.length = 0;
2349 		static if(writeId){ writeBigEndianUbyte(ID); }
2350 		writeBytes(varlong.encode(entityId));
2351 		writeBytes(varuint.encode(cast(uint)attributes.length)); foreach(yrcldrc;attributes){ yrcldrc.encode(bufferInstance); }
2352 		return _buffer;
2353 	}
2354 
2355 	public pure nothrow @safe void decode(bool readId=true)() {
2356 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2357 		entityId=varlong.decode(_buffer, &_index);
2358 		attributes.length=varuint.decode(_buffer, &_index); foreach(ref yrcldrc;attributes){ yrcldrc.decode(bufferInstance); }
2359 	}
2360 
2361 	public static pure nothrow @safe UpdateAttributes fromBuffer(bool readId=true)(ubyte[] buffer) {
2362 		UpdateAttributes ret = new UpdateAttributes();
2363 		ret._buffer = buffer;
2364 		ret.decode!readId();
2365 		return ret;
2366 	}
2367 
2368 	public override string toString() {
2369 		return "UpdateAttributes(entityId: " ~ std.conv.to!string(this.entityId) ~ ", attributes: " ~ std.conv.to!string(this.attributes) ~ ")";
2370 	}
2371 
2372 }
2373 
2374 /**
2375  * Sent when the client puts an item in its hotbar or selects a new hotbar slot.
2376  */
2377 class MobEquipment : Buffer {
2378 
2379 	public enum ubyte ID = 32;
2380 
2381 	public enum bool CLIENTBOUND = true;
2382 	public enum bool SERVERBOUND = true;
2383 
2384 	public enum string[] FIELDS = ["entityId", "item", "inventorySlot", "hotbarSlot", "unknown4"];
2385 
2386 	public long entityId;
2387 	public sul.protocol.pocket102.types.Slot item;
2388 
2389 	/**
2390 	 * Slot of the inventory where the item is. The hotbat slots (0-8) are not counted.
2391 	 * 255 means that a generic empty slot has been selected.
2392 	 */
2393 	public ubyte inventorySlot;
2394 
2395 	/**
2396 	 * Slot of the hotbar where the item is being moved.
2397 	 */
2398 	public ubyte hotbarSlot;
2399 	public ubyte unknown4;
2400 
2401 	public pure nothrow @safe @nogc this() {}
2402 
2403 	public pure nothrow @safe @nogc this(long entityId, sul.protocol.pocket102.types.Slot item=sul.protocol.pocket102.types.Slot.init, ubyte inventorySlot=ubyte.init, ubyte hotbarSlot=ubyte.init, ubyte unknown4=ubyte.init) {
2404 		this.entityId = entityId;
2405 		this.item = item;
2406 		this.inventorySlot = inventorySlot;
2407 		this.hotbarSlot = hotbarSlot;
2408 		this.unknown4 = unknown4;
2409 	}
2410 
2411 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2412 		_buffer.length = 0;
2413 		static if(writeId){ writeBigEndianUbyte(ID); }
2414 		writeBytes(varlong.encode(entityId));
2415 		item.encode(bufferInstance);
2416 		writeBigEndianUbyte(inventorySlot);
2417 		writeBigEndianUbyte(hotbarSlot);
2418 		writeBigEndianUbyte(unknown4);
2419 		return _buffer;
2420 	}
2421 
2422 	public pure nothrow @safe void decode(bool readId=true)() {
2423 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2424 		entityId=varlong.decode(_buffer, &_index);
2425 		item.decode(bufferInstance);
2426 		inventorySlot=readBigEndianUbyte();
2427 		hotbarSlot=readBigEndianUbyte();
2428 		unknown4=readBigEndianUbyte();
2429 	}
2430 
2431 	public static pure nothrow @safe MobEquipment fromBuffer(bool readId=true)(ubyte[] buffer) {
2432 		MobEquipment ret = new MobEquipment();
2433 		ret._buffer = buffer;
2434 		ret.decode!readId();
2435 		return ret;
2436 	}
2437 
2438 	public override string toString() {
2439 		return "MobEquipment(entityId: " ~ std.conv.to!string(this.entityId) ~ ", item: " ~ std.conv.to!string(this.item) ~ ", inventorySlot: " ~ std.conv.to!string(this.inventorySlot) ~ ", hotbarSlot: " ~ std.conv.to!string(this.hotbarSlot) ~ ", unknown4: " ~ std.conv.to!string(this.unknown4) ~ ")";
2440 	}
2441 
2442 }
2443 
2444 class MobArmorEquipment : Buffer {
2445 
2446 	public enum ubyte ID = 33;
2447 
2448 	public enum bool CLIENTBOUND = true;
2449 	public enum bool SERVERBOUND = true;
2450 
2451 	public enum string[] FIELDS = ["entityId", "armor"];
2452 
2453 	public long entityId;
2454 	public sul.protocol.pocket102.types.Slot[4] armor;
2455 
2456 	public pure nothrow @safe @nogc this() {}
2457 
2458 	public pure nothrow @safe @nogc this(long entityId, sul.protocol.pocket102.types.Slot[4] armor=(sul.protocol.pocket102.types.Slot[4]).init) {
2459 		this.entityId = entityId;
2460 		this.armor = armor;
2461 	}
2462 
2463 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2464 		_buffer.length = 0;
2465 		static if(writeId){ writeBigEndianUbyte(ID); }
2466 		writeBytes(varlong.encode(entityId));
2467 		foreach(yjbi;armor){ yjbi.encode(bufferInstance); }
2468 		return _buffer;
2469 	}
2470 
2471 	public pure nothrow @safe void decode(bool readId=true)() {
2472 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2473 		entityId=varlong.decode(_buffer, &_index);
2474 		foreach(ref yjbi;armor){ yjbi.decode(bufferInstance); }
2475 	}
2476 
2477 	public static pure nothrow @safe MobArmorEquipment fromBuffer(bool readId=true)(ubyte[] buffer) {
2478 		MobArmorEquipment ret = new MobArmorEquipment();
2479 		ret._buffer = buffer;
2480 		ret.decode!readId();
2481 		return ret;
2482 	}
2483 
2484 	public override string toString() {
2485 		return "MobArmorEquipment(entityId: " ~ std.conv.to!string(this.entityId) ~ ", armor: " ~ std.conv.to!string(this.armor) ~ ")";
2486 	}
2487 
2488 }
2489 
2490 class Interact : Buffer {
2491 
2492 	public enum ubyte ID = 34;
2493 
2494 	public enum bool CLIENTBOUND = false;
2495 	public enum bool SERVERBOUND = true;
2496 
2497 	// action
2498 	public enum ubyte ATTACK = 1;
2499 	public enum ubyte INTERACT = 2;
2500 	public enum ubyte LEAVE_VEHICLE = 3;
2501 	public enum ubyte HOVER = 4;
2502 
2503 	public enum string[] FIELDS = ["action", "target"];
2504 
2505 	public ubyte action;
2506 	public long target;
2507 
2508 	public pure nothrow @safe @nogc this() {}
2509 
2510 	public pure nothrow @safe @nogc this(ubyte action, long target=long.init) {
2511 		this.action = action;
2512 		this.target = target;
2513 	}
2514 
2515 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2516 		_buffer.length = 0;
2517 		static if(writeId){ writeBigEndianUbyte(ID); }
2518 		writeBigEndianUbyte(action);
2519 		writeBytes(varlong.encode(target));
2520 		return _buffer;
2521 	}
2522 
2523 	public pure nothrow @safe void decode(bool readId=true)() {
2524 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2525 		action=readBigEndianUbyte();
2526 		target=varlong.decode(_buffer, &_index);
2527 	}
2528 
2529 	public static pure nothrow @safe Interact fromBuffer(bool readId=true)(ubyte[] buffer) {
2530 		Interact ret = new Interact();
2531 		ret._buffer = buffer;
2532 		ret.decode!readId();
2533 		return ret;
2534 	}
2535 
2536 	public override string toString() {
2537 		return "Interact(action: " ~ std.conv.to!string(this.action) ~ ", target: " ~ std.conv.to!string(this.target) ~ ")";
2538 	}
2539 
2540 }
2541 
2542 class UseItem : Buffer {
2543 
2544 	public enum ubyte ID = 35;
2545 
2546 	public enum bool CLIENTBOUND = false;
2547 	public enum bool SERVERBOUND = true;
2548 
2549 	public enum string[] FIELDS = ["blockPosition", "hotbarSlot", "face", "facePosition", "position", "slot", "item"];
2550 
2551 	public sul.protocol.pocket102.types.BlockPosition blockPosition;
2552 	public uint hotbarSlot;
2553 	public int face;
2554 	public Tuple!(float, "x", float, "y", float, "z") facePosition;
2555 	public Tuple!(float, "x", float, "y", float, "z") position;
2556 	public int slot;
2557 	public sul.protocol.pocket102.types.Slot item;
2558 
2559 	public pure nothrow @safe @nogc this() {}
2560 
2561 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.BlockPosition blockPosition, uint hotbarSlot=uint.init, int face=int.init, Tuple!(float, "x", float, "y", float, "z") facePosition=Tuple!(float, "x", float, "y", float, "z").init, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, int slot=int.init, sul.protocol.pocket102.types.Slot item=sul.protocol.pocket102.types.Slot.init) {
2562 		this.blockPosition = blockPosition;
2563 		this.hotbarSlot = hotbarSlot;
2564 		this.face = face;
2565 		this.facePosition = facePosition;
2566 		this.position = position;
2567 		this.slot = slot;
2568 		this.item = item;
2569 	}
2570 
2571 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2572 		_buffer.length = 0;
2573 		static if(writeId){ writeBigEndianUbyte(ID); }
2574 		blockPosition.encode(bufferInstance);
2575 		writeBytes(varuint.encode(hotbarSlot));
2576 		writeBytes(varint.encode(face));
2577 		writeLittleEndianFloat(facePosition.x); writeLittleEndianFloat(facePosition.y); writeLittleEndianFloat(facePosition.z);
2578 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
2579 		writeBytes(varint.encode(slot));
2580 		item.encode(bufferInstance);
2581 		return _buffer;
2582 	}
2583 
2584 	public pure nothrow @safe void decode(bool readId=true)() {
2585 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2586 		blockPosition.decode(bufferInstance);
2587 		hotbarSlot=varuint.decode(_buffer, &_index);
2588 		face=varint.decode(_buffer, &_index);
2589 		facePosition.x=readLittleEndianFloat(); facePosition.y=readLittleEndianFloat(); facePosition.z=readLittleEndianFloat();
2590 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
2591 		slot=varint.decode(_buffer, &_index);
2592 		item.decode(bufferInstance);
2593 	}
2594 
2595 	public static pure nothrow @safe UseItem fromBuffer(bool readId=true)(ubyte[] buffer) {
2596 		UseItem ret = new UseItem();
2597 		ret._buffer = buffer;
2598 		ret.decode!readId();
2599 		return ret;
2600 	}
2601 
2602 	public override string toString() {
2603 		return "UseItem(blockPosition: " ~ std.conv.to!string(this.blockPosition) ~ ", hotbarSlot: " ~ std.conv.to!string(this.hotbarSlot) ~ ", face: " ~ std.conv.to!string(this.face) ~ ", facePosition: " ~ std.conv.to!string(this.facePosition) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", slot: " ~ std.conv.to!string(this.slot) ~ ", item: " ~ std.conv.to!string(this.item) ~ ")";
2604 	}
2605 
2606 }
2607 
2608 class PlayerAction : Buffer {
2609 
2610 	public enum ubyte ID = 36;
2611 
2612 	public enum bool CLIENTBOUND = false;
2613 	public enum bool SERVERBOUND = true;
2614 
2615 	// action
2616 	public enum int START_BREAK = 0;
2617 	public enum int ABORT_BREAK = 1;
2618 	public enum int STOP_BREAK = 2;
2619 	public enum int RELEASE_ITEM = 5;
2620 	public enum int STOP_SLEEPING = 6;
2621 	public enum int RESPAWN = 7;
2622 	public enum int JUMP = 8;
2623 	public enum int START_SPRINT = 9;
2624 	public enum int STOP_SPRINT = 10;
2625 	public enum int START_SNEAK = 11;
2626 	public enum int STOP_SNEAK = 12;
2627 	public enum int START_GLIDING = 15;
2628 	public enum int STOP_GLIDING = 16;
2629 
2630 	public enum string[] FIELDS = ["entityId", "action", "position", "face"];
2631 
2632 	public long entityId;
2633 	public int action;
2634 	public sul.protocol.pocket102.types.BlockPosition position;
2635 	public int face;
2636 
2637 	public pure nothrow @safe @nogc this() {}
2638 
2639 	public pure nothrow @safe @nogc this(long entityId, int action=int.init, sul.protocol.pocket102.types.BlockPosition position=sul.protocol.pocket102.types.BlockPosition.init, int face=int.init) {
2640 		this.entityId = entityId;
2641 		this.action = action;
2642 		this.position = position;
2643 		this.face = face;
2644 	}
2645 
2646 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2647 		_buffer.length = 0;
2648 		static if(writeId){ writeBigEndianUbyte(ID); }
2649 		writeBytes(varlong.encode(entityId));
2650 		writeBytes(varint.encode(action));
2651 		position.encode(bufferInstance);
2652 		writeBytes(varint.encode(face));
2653 		return _buffer;
2654 	}
2655 
2656 	public pure nothrow @safe void decode(bool readId=true)() {
2657 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2658 		entityId=varlong.decode(_buffer, &_index);
2659 		action=varint.decode(_buffer, &_index);
2660 		position.decode(bufferInstance);
2661 		face=varint.decode(_buffer, &_index);
2662 	}
2663 
2664 	public static pure nothrow @safe PlayerAction fromBuffer(bool readId=true)(ubyte[] buffer) {
2665 		PlayerAction ret = new PlayerAction();
2666 		ret._buffer = buffer;
2667 		ret.decode!readId();
2668 		return ret;
2669 	}
2670 
2671 	public override string toString() {
2672 		return "PlayerAction(entityId: " ~ std.conv.to!string(this.entityId) ~ ", action: " ~ std.conv.to!string(this.action) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", face: " ~ std.conv.to!string(this.face) ~ ")";
2673 	}
2674 
2675 }
2676 
2677 /**
2678  * Sent by the player when it falls from a distance that causes damage, that can be
2679  * influenced by its armour and its effects.
2680  */
2681 class PlayerFall : Buffer {
2682 
2683 	public enum ubyte ID = 37;
2684 
2685 	public enum bool CLIENTBOUND = false;
2686 	public enum bool SERVERBOUND = true;
2687 
2688 	public enum string[] FIELDS = ["distance"];
2689 
2690 	/**
2691 	 * Number of blocks the player has been in free falling before hitting the ground.
2692 	 */
2693 	public float distance;
2694 
2695 	public pure nothrow @safe @nogc this() {}
2696 
2697 	public pure nothrow @safe @nogc this(float distance) {
2698 		this.distance = distance;
2699 	}
2700 
2701 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2702 		_buffer.length = 0;
2703 		static if(writeId){ writeBigEndianUbyte(ID); }
2704 		writeLittleEndianFloat(distance);
2705 		return _buffer;
2706 	}
2707 
2708 	public pure nothrow @safe void decode(bool readId=true)() {
2709 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2710 		distance=readLittleEndianFloat();
2711 	}
2712 
2713 	public static pure nothrow @safe PlayerFall fromBuffer(bool readId=true)(ubyte[] buffer) {
2714 		PlayerFall ret = new PlayerFall();
2715 		ret._buffer = buffer;
2716 		ret.decode!readId();
2717 		return ret;
2718 	}
2719 
2720 	public override string toString() {
2721 		return "PlayerFall(distance: " ~ std.conv.to!string(this.distance) ~ ")";
2722 	}
2723 
2724 }
2725 
2726 class HurtArmor : Buffer {
2727 
2728 	public enum ubyte ID = 38;
2729 
2730 	public enum bool CLIENTBOUND = true;
2731 	public enum bool SERVERBOUND = false;
2732 
2733 	public enum string[] FIELDS = ["unknown0"];
2734 
2735 	public int unknown0;
2736 
2737 	public pure nothrow @safe @nogc this() {}
2738 
2739 	public pure nothrow @safe @nogc this(int unknown0) {
2740 		this.unknown0 = unknown0;
2741 	}
2742 
2743 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2744 		_buffer.length = 0;
2745 		static if(writeId){ writeBigEndianUbyte(ID); }
2746 		writeBytes(varint.encode(unknown0));
2747 		return _buffer;
2748 	}
2749 
2750 	public pure nothrow @safe void decode(bool readId=true)() {
2751 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2752 		unknown0=varint.decode(_buffer, &_index);
2753 	}
2754 
2755 	public static pure nothrow @safe HurtArmor fromBuffer(bool readId=true)(ubyte[] buffer) {
2756 		HurtArmor ret = new HurtArmor();
2757 		ret._buffer = buffer;
2758 		ret.decode!readId();
2759 		return ret;
2760 	}
2761 
2762 	public override string toString() {
2763 		return "HurtArmor(unknown0: " ~ std.conv.to!string(this.unknown0) ~ ")";
2764 	}
2765 
2766 }
2767 
2768 /**
2769  * Updates an entity's metadata.
2770  */
2771 class SetEntityData : Buffer {
2772 
2773 	public enum ubyte ID = 39;
2774 
2775 	public enum bool CLIENTBOUND = true;
2776 	public enum bool SERVERBOUND = false;
2777 
2778 	public enum string[] FIELDS = ["entityId", "metadata"];
2779 
2780 	public long entityId;
2781 	public Metadata metadata;
2782 
2783 	public pure nothrow @safe @nogc this() {}
2784 
2785 	public pure nothrow @safe @nogc this(long entityId, Metadata metadata=Metadata.init) {
2786 		this.entityId = entityId;
2787 		this.metadata = metadata;
2788 	}
2789 
2790 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2791 		_buffer.length = 0;
2792 		static if(writeId){ writeBigEndianUbyte(ID); }
2793 		writeBytes(varlong.encode(entityId));
2794 		metadata.encode(bufferInstance);
2795 		return _buffer;
2796 	}
2797 
2798 	public pure nothrow @safe void decode(bool readId=true)() {
2799 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2800 		entityId=varlong.decode(_buffer, &_index);
2801 		metadata=Metadata.decode(bufferInstance);
2802 	}
2803 
2804 	public static pure nothrow @safe SetEntityData fromBuffer(bool readId=true)(ubyte[] buffer) {
2805 		SetEntityData ret = new SetEntityData();
2806 		ret._buffer = buffer;
2807 		ret.decode!readId();
2808 		return ret;
2809 	}
2810 
2811 	public override string toString() {
2812 		return "SetEntityData(entityId: " ~ std.conv.to!string(this.entityId) ~ ", metadata: " ~ std.conv.to!string(this.metadata) ~ ")";
2813 	}
2814 
2815 }
2816 
2817 /**
2818  * Updates an entity's motion.
2819  */
2820 class SetEntityMotion : Buffer {
2821 
2822 	public enum ubyte ID = 40;
2823 
2824 	public enum bool CLIENTBOUND = true;
2825 	public enum bool SERVERBOUND = false;
2826 
2827 	public enum string[] FIELDS = ["entityId", "motion"];
2828 
2829 	/**
2830 	 * Entity which motion is updated. If the entity id is the player's, its motion is
2831 	 * updated client-side and the player will send movement packets to the server (meaning
2832 	 * that the server has no physical calculations to do). If not an animation will be
2833 	 * done client-side but the server will have to calculate the new position applying
2834 	 * the item's movement rules.
2835 	 */
2836 	public long entityId;
2837 
2838 	/**
2839 	 * New motion for the entity that will influence its movement.
2840 	 */
2841 	public Tuple!(float, "x", float, "y", float, "z") motion;
2842 
2843 	public pure nothrow @safe @nogc this() {}
2844 
2845 	public pure nothrow @safe @nogc this(long entityId, Tuple!(float, "x", float, "y", float, "z") motion=Tuple!(float, "x", float, "y", float, "z").init) {
2846 		this.entityId = entityId;
2847 		this.motion = motion;
2848 	}
2849 
2850 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2851 		_buffer.length = 0;
2852 		static if(writeId){ writeBigEndianUbyte(ID); }
2853 		writeBytes(varlong.encode(entityId));
2854 		writeLittleEndianFloat(motion.x); writeLittleEndianFloat(motion.y); writeLittleEndianFloat(motion.z);
2855 		return _buffer;
2856 	}
2857 
2858 	public pure nothrow @safe void decode(bool readId=true)() {
2859 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2860 		entityId=varlong.decode(_buffer, &_index);
2861 		motion.x=readLittleEndianFloat(); motion.y=readLittleEndianFloat(); motion.z=readLittleEndianFloat();
2862 	}
2863 
2864 	public static pure nothrow @safe SetEntityMotion fromBuffer(bool readId=true)(ubyte[] buffer) {
2865 		SetEntityMotion ret = new SetEntityMotion();
2866 		ret._buffer = buffer;
2867 		ret.decode!readId();
2868 		return ret;
2869 	}
2870 
2871 	public override string toString() {
2872 		return "SetEntityMotion(entityId: " ~ std.conv.to!string(this.entityId) ~ ", motion: " ~ std.conv.to!string(this.motion) ~ ")";
2873 	}
2874 
2875 }
2876 
2877 class SetEntityLink : Buffer {
2878 
2879 	public enum ubyte ID = 41;
2880 
2881 	public enum bool CLIENTBOUND = true;
2882 	public enum bool SERVERBOUND = false;
2883 
2884 	// action
2885 	public enum ubyte ADD = 0;
2886 	public enum ubyte RIDE = 1;
2887 	public enum ubyte REMOVE = 2;
2888 
2889 	public enum string[] FIELDS = ["from", "to", "action"];
2890 
2891 	public long from;
2892 	public long to;
2893 	public ubyte action;
2894 
2895 	public pure nothrow @safe @nogc this() {}
2896 
2897 	public pure nothrow @safe @nogc this(long from, long to=long.init, ubyte action=ubyte.init) {
2898 		this.from = from;
2899 		this.to = to;
2900 		this.action = action;
2901 	}
2902 
2903 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2904 		_buffer.length = 0;
2905 		static if(writeId){ writeBigEndianUbyte(ID); }
2906 		writeBytes(varlong.encode(from));
2907 		writeBytes(varlong.encode(to));
2908 		writeBigEndianUbyte(action);
2909 		return _buffer;
2910 	}
2911 
2912 	public pure nothrow @safe void decode(bool readId=true)() {
2913 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2914 		from=varlong.decode(_buffer, &_index);
2915 		to=varlong.decode(_buffer, &_index);
2916 		action=readBigEndianUbyte();
2917 	}
2918 
2919 	public static pure nothrow @safe SetEntityLink fromBuffer(bool readId=true)(ubyte[] buffer) {
2920 		SetEntityLink ret = new SetEntityLink();
2921 		ret._buffer = buffer;
2922 		ret.decode!readId();
2923 		return ret;
2924 	}
2925 
2926 	public override string toString() {
2927 		return "SetEntityLink(from: " ~ std.conv.to!string(this.from) ~ ", to: " ~ std.conv.to!string(this.to) ~ ", action: " ~ std.conv.to!string(this.action) ~ ")";
2928 	}
2929 
2930 }
2931 
2932 class SetHealth : Buffer {
2933 
2934 	public enum ubyte ID = 42;
2935 
2936 	public enum bool CLIENTBOUND = true;
2937 	public enum bool SERVERBOUND = false;
2938 
2939 	public enum string[] FIELDS = ["health"];
2940 
2941 	public int health;
2942 
2943 	public pure nothrow @safe @nogc this() {}
2944 
2945 	public pure nothrow @safe @nogc this(int health) {
2946 		this.health = health;
2947 	}
2948 
2949 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2950 		_buffer.length = 0;
2951 		static if(writeId){ writeBigEndianUbyte(ID); }
2952 		writeBytes(varint.encode(health));
2953 		return _buffer;
2954 	}
2955 
2956 	public pure nothrow @safe void decode(bool readId=true)() {
2957 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2958 		health=varint.decode(_buffer, &_index);
2959 	}
2960 
2961 	public static pure nothrow @safe SetHealth fromBuffer(bool readId=true)(ubyte[] buffer) {
2962 		SetHealth ret = new SetHealth();
2963 		ret._buffer = buffer;
2964 		ret.decode!readId();
2965 		return ret;
2966 	}
2967 
2968 	public override string toString() {
2969 		return "SetHealth(health: " ~ std.conv.to!string(this.health) ~ ")";
2970 	}
2971 
2972 }
2973 
2974 class SetSpawnPosition : Buffer {
2975 
2976 	public enum ubyte ID = 43;
2977 
2978 	public enum bool CLIENTBOUND = true;
2979 	public enum bool SERVERBOUND = false;
2980 
2981 	public enum string[] FIELDS = ["unknown0", "position", "unknown2"];
2982 
2983 	public int unknown0;
2984 	public sul.protocol.pocket102.types.BlockPosition position;
2985 	public bool unknown2;
2986 
2987 	public pure nothrow @safe @nogc this() {}
2988 
2989 	public pure nothrow @safe @nogc this(int unknown0, sul.protocol.pocket102.types.BlockPosition position=sul.protocol.pocket102.types.BlockPosition.init, bool unknown2=bool.init) {
2990 		this.unknown0 = unknown0;
2991 		this.position = position;
2992 		this.unknown2 = unknown2;
2993 	}
2994 
2995 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2996 		_buffer.length = 0;
2997 		static if(writeId){ writeBigEndianUbyte(ID); }
2998 		writeBytes(varint.encode(unknown0));
2999 		position.encode(bufferInstance);
3000 		writeBigEndianBool(unknown2);
3001 		return _buffer;
3002 	}
3003 
3004 	public pure nothrow @safe void decode(bool readId=true)() {
3005 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3006 		unknown0=varint.decode(_buffer, &_index);
3007 		position.decode(bufferInstance);
3008 		unknown2=readBigEndianBool();
3009 	}
3010 
3011 	public static pure nothrow @safe SetSpawnPosition fromBuffer(bool readId=true)(ubyte[] buffer) {
3012 		SetSpawnPosition ret = new SetSpawnPosition();
3013 		ret._buffer = buffer;
3014 		ret.decode!readId();
3015 		return ret;
3016 	}
3017 
3018 	public override string toString() {
3019 		return "SetSpawnPosition(unknown0: " ~ std.conv.to!string(this.unknown0) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
3020 	}
3021 
3022 }
3023 
3024 class Animate : Buffer {
3025 
3026 	public enum ubyte ID = 44;
3027 
3028 	public enum bool CLIENTBOUND = true;
3029 	public enum bool SERVERBOUND = true;
3030 
3031 	// action
3032 	public enum int BREAKING = 1;
3033 	public enum int WAKE_UP = 3;
3034 
3035 	public enum string[] FIELDS = ["action", "entityId"];
3036 
3037 	public int action;
3038 	public long entityId;
3039 
3040 	public pure nothrow @safe @nogc this() {}
3041 
3042 	public pure nothrow @safe @nogc this(int action, long entityId=long.init) {
3043 		this.action = action;
3044 		this.entityId = entityId;
3045 	}
3046 
3047 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3048 		_buffer.length = 0;
3049 		static if(writeId){ writeBigEndianUbyte(ID); }
3050 		writeBytes(varint.encode(action));
3051 		writeBytes(varlong.encode(entityId));
3052 		return _buffer;
3053 	}
3054 
3055 	public pure nothrow @safe void decode(bool readId=true)() {
3056 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3057 		action=varint.decode(_buffer, &_index);
3058 		entityId=varlong.decode(_buffer, &_index);
3059 	}
3060 
3061 	public static pure nothrow @safe Animate fromBuffer(bool readId=true)(ubyte[] buffer) {
3062 		Animate ret = new Animate();
3063 		ret._buffer = buffer;
3064 		ret.decode!readId();
3065 		return ret;
3066 	}
3067 
3068 	public override string toString() {
3069 		return "Animate(action: " ~ std.conv.to!string(this.action) ~ ", entityId: " ~ std.conv.to!string(this.entityId) ~ ")";
3070 	}
3071 
3072 }
3073 
3074 class Respawn : Buffer {
3075 
3076 	public enum ubyte ID = 45;
3077 
3078 	public enum bool CLIENTBOUND = true;
3079 	public enum bool SERVERBOUND = false;
3080 
3081 	public enum string[] FIELDS = ["position"];
3082 
3083 	public Tuple!(float, "x", float, "y", float, "z") position;
3084 
3085 	public pure nothrow @safe @nogc this() {}
3086 
3087 	public pure nothrow @safe @nogc this(Tuple!(float, "x", float, "y", float, "z") position) {
3088 		this.position = position;
3089 	}
3090 
3091 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3092 		_buffer.length = 0;
3093 		static if(writeId){ writeBigEndianUbyte(ID); }
3094 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
3095 		return _buffer;
3096 	}
3097 
3098 	public pure nothrow @safe void decode(bool readId=true)() {
3099 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3100 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
3101 	}
3102 
3103 	public static pure nothrow @safe Respawn fromBuffer(bool readId=true)(ubyte[] buffer) {
3104 		Respawn ret = new Respawn();
3105 		ret._buffer = buffer;
3106 		ret.decode!readId();
3107 		return ret;
3108 	}
3109 
3110 	public override string toString() {
3111 		return "Respawn(position: " ~ std.conv.to!string(this.position) ~ ")";
3112 	}
3113 
3114 }
3115 
3116 class DropItem : Buffer {
3117 
3118 	public enum ubyte ID = 46;
3119 
3120 	public enum bool CLIENTBOUND = false;
3121 	public enum bool SERVERBOUND = true;
3122 
3123 	// action
3124 	public enum ubyte DROP = 0;
3125 
3126 	public enum string[] FIELDS = ["action", "item"];
3127 
3128 	public ubyte action;
3129 	public sul.protocol.pocket102.types.Slot item;
3130 
3131 	public pure nothrow @safe @nogc this() {}
3132 
3133 	public pure nothrow @safe @nogc this(ubyte action, sul.protocol.pocket102.types.Slot item=sul.protocol.pocket102.types.Slot.init) {
3134 		this.action = action;
3135 		this.item = item;
3136 	}
3137 
3138 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3139 		_buffer.length = 0;
3140 		static if(writeId){ writeBigEndianUbyte(ID); }
3141 		writeBigEndianUbyte(action);
3142 		item.encode(bufferInstance);
3143 		return _buffer;
3144 	}
3145 
3146 	public pure nothrow @safe void decode(bool readId=true)() {
3147 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3148 		action=readBigEndianUbyte();
3149 		item.decode(bufferInstance);
3150 	}
3151 
3152 	public static pure nothrow @safe DropItem fromBuffer(bool readId=true)(ubyte[] buffer) {
3153 		DropItem ret = new DropItem();
3154 		ret._buffer = buffer;
3155 		ret.decode!readId();
3156 		return ret;
3157 	}
3158 
3159 	public override string toString() {
3160 		return "DropItem(action: " ~ std.conv.to!string(this.action) ~ ", item: " ~ std.conv.to!string(this.item) ~ ")";
3161 	}
3162 
3163 }
3164 
3165 class InventoryAction : Buffer {
3166 
3167 	public enum ubyte ID = 47;
3168 
3169 	public enum bool CLIENTBOUND = false;
3170 	public enum bool SERVERBOUND = true;
3171 
3172 	public enum string[] FIELDS = ["action", "item"];
3173 
3174 	public int action;
3175 	public sul.protocol.pocket102.types.Slot item;
3176 
3177 	public pure nothrow @safe @nogc this() {}
3178 
3179 	public pure nothrow @safe @nogc this(int action, sul.protocol.pocket102.types.Slot item=sul.protocol.pocket102.types.Slot.init) {
3180 		this.action = action;
3181 		this.item = item;
3182 	}
3183 
3184 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3185 		_buffer.length = 0;
3186 		static if(writeId){ writeBigEndianUbyte(ID); }
3187 		writeBytes(varint.encode(action));
3188 		item.encode(bufferInstance);
3189 		return _buffer;
3190 	}
3191 
3192 	public pure nothrow @safe void decode(bool readId=true)() {
3193 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3194 		action=varint.decode(_buffer, &_index);
3195 		item.decode(bufferInstance);
3196 	}
3197 
3198 	public static pure nothrow @safe InventoryAction fromBuffer(bool readId=true)(ubyte[] buffer) {
3199 		InventoryAction ret = new InventoryAction();
3200 		ret._buffer = buffer;
3201 		ret.decode!readId();
3202 		return ret;
3203 	}
3204 
3205 	public override string toString() {
3206 		return "InventoryAction(action: " ~ std.conv.to!string(this.action) ~ ", item: " ~ std.conv.to!string(this.item) ~ ")";
3207 	}
3208 
3209 }
3210 
3211 class ContainerOpen : Buffer {
3212 
3213 	public enum ubyte ID = 48;
3214 
3215 	public enum bool CLIENTBOUND = true;
3216 	public enum bool SERVERBOUND = false;
3217 
3218 	public enum string[] FIELDS = ["window", "type", "slotCount", "position", "entityId"];
3219 
3220 	public ubyte window;
3221 	public ubyte type;
3222 	public int slotCount;
3223 	public sul.protocol.pocket102.types.BlockPosition position;
3224 	public long entityId;
3225 
3226 	public pure nothrow @safe @nogc this() {}
3227 
3228 	public pure nothrow @safe @nogc this(ubyte window, ubyte type=ubyte.init, int slotCount=int.init, sul.protocol.pocket102.types.BlockPosition position=sul.protocol.pocket102.types.BlockPosition.init, long entityId=long.init) {
3229 		this.window = window;
3230 		this.type = type;
3231 		this.slotCount = slotCount;
3232 		this.position = position;
3233 		this.entityId = entityId;
3234 	}
3235 
3236 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3237 		_buffer.length = 0;
3238 		static if(writeId){ writeBigEndianUbyte(ID); }
3239 		writeBigEndianUbyte(window);
3240 		writeBigEndianUbyte(type);
3241 		writeBytes(varint.encode(slotCount));
3242 		position.encode(bufferInstance);
3243 		writeBytes(varlong.encode(entityId));
3244 		return _buffer;
3245 	}
3246 
3247 	public pure nothrow @safe void decode(bool readId=true)() {
3248 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3249 		window=readBigEndianUbyte();
3250 		type=readBigEndianUbyte();
3251 		slotCount=varint.decode(_buffer, &_index);
3252 		position.decode(bufferInstance);
3253 		entityId=varlong.decode(_buffer, &_index);
3254 	}
3255 
3256 	public static pure nothrow @safe ContainerOpen fromBuffer(bool readId=true)(ubyte[] buffer) {
3257 		ContainerOpen ret = new ContainerOpen();
3258 		ret._buffer = buffer;
3259 		ret.decode!readId();
3260 		return ret;
3261 	}
3262 
3263 	public override string toString() {
3264 		return "ContainerOpen(window: " ~ std.conv.to!string(this.window) ~ ", type: " ~ std.conv.to!string(this.type) ~ ", slotCount: " ~ std.conv.to!string(this.slotCount) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", entityId: " ~ std.conv.to!string(this.entityId) ~ ")";
3265 	}
3266 
3267 }
3268 
3269 class ContainerClose : Buffer {
3270 
3271 	public enum ubyte ID = 49;
3272 
3273 	public enum bool CLIENTBOUND = true;
3274 	public enum bool SERVERBOUND = true;
3275 
3276 	public enum string[] FIELDS = ["window"];
3277 
3278 	public ubyte window;
3279 
3280 	public pure nothrow @safe @nogc this() {}
3281 
3282 	public pure nothrow @safe @nogc this(ubyte window) {
3283 		this.window = window;
3284 	}
3285 
3286 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3287 		_buffer.length = 0;
3288 		static if(writeId){ writeBigEndianUbyte(ID); }
3289 		writeBigEndianUbyte(window);
3290 		return _buffer;
3291 	}
3292 
3293 	public pure nothrow @safe void decode(bool readId=true)() {
3294 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3295 		window=readBigEndianUbyte();
3296 	}
3297 
3298 	public static pure nothrow @safe ContainerClose fromBuffer(bool readId=true)(ubyte[] buffer) {
3299 		ContainerClose ret = new ContainerClose();
3300 		ret._buffer = buffer;
3301 		ret.decode!readId();
3302 		return ret;
3303 	}
3304 
3305 	public override string toString() {
3306 		return "ContainerClose(window: " ~ std.conv.to!string(this.window) ~ ")";
3307 	}
3308 
3309 }
3310 
3311 class ContainerSetSlot : Buffer {
3312 
3313 	public enum ubyte ID = 50;
3314 
3315 	public enum bool CLIENTBOUND = true;
3316 	public enum bool SERVERBOUND = true;
3317 
3318 	public enum string[] FIELDS = ["window", "slot", "hotbarSlot", "item", "unknown4"];
3319 
3320 	public ubyte window;
3321 	public int slot;
3322 	public int hotbarSlot;
3323 	public sul.protocol.pocket102.types.Slot item;
3324 	public ubyte unknown4;
3325 
3326 	public pure nothrow @safe @nogc this() {}
3327 
3328 	public pure nothrow @safe @nogc this(ubyte window, int slot=int.init, int hotbarSlot=int.init, sul.protocol.pocket102.types.Slot item=sul.protocol.pocket102.types.Slot.init, ubyte unknown4=ubyte.init) {
3329 		this.window = window;
3330 		this.slot = slot;
3331 		this.hotbarSlot = hotbarSlot;
3332 		this.item = item;
3333 		this.unknown4 = unknown4;
3334 	}
3335 
3336 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3337 		_buffer.length = 0;
3338 		static if(writeId){ writeBigEndianUbyte(ID); }
3339 		writeBigEndianUbyte(window);
3340 		writeBytes(varint.encode(slot));
3341 		writeBytes(varint.encode(hotbarSlot));
3342 		item.encode(bufferInstance);
3343 		writeBigEndianUbyte(unknown4);
3344 		return _buffer;
3345 	}
3346 
3347 	public pure nothrow @safe void decode(bool readId=true)() {
3348 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3349 		window=readBigEndianUbyte();
3350 		slot=varint.decode(_buffer, &_index);
3351 		hotbarSlot=varint.decode(_buffer, &_index);
3352 		item.decode(bufferInstance);
3353 		unknown4=readBigEndianUbyte();
3354 	}
3355 
3356 	public static pure nothrow @safe ContainerSetSlot fromBuffer(bool readId=true)(ubyte[] buffer) {
3357 		ContainerSetSlot ret = new ContainerSetSlot();
3358 		ret._buffer = buffer;
3359 		ret.decode!readId();
3360 		return ret;
3361 	}
3362 
3363 	public override string toString() {
3364 		return "ContainerSetSlot(window: " ~ std.conv.to!string(this.window) ~ ", slot: " ~ std.conv.to!string(this.slot) ~ ", hotbarSlot: " ~ std.conv.to!string(this.hotbarSlot) ~ ", item: " ~ std.conv.to!string(this.item) ~ ", unknown4: " ~ std.conv.to!string(this.unknown4) ~ ")";
3365 	}
3366 
3367 }
3368 
3369 class ContainerSetData : Buffer {
3370 
3371 	public enum ubyte ID = 51;
3372 
3373 	public enum bool CLIENTBOUND = true;
3374 	public enum bool SERVERBOUND = false;
3375 
3376 	public enum string[] FIELDS = ["window", "property", "value"];
3377 
3378 	public ubyte window;
3379 	public int property;
3380 	public int value;
3381 
3382 	public pure nothrow @safe @nogc this() {}
3383 
3384 	public pure nothrow @safe @nogc this(ubyte window, int property=int.init, int value=int.init) {
3385 		this.window = window;
3386 		this.property = property;
3387 		this.value = value;
3388 	}
3389 
3390 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3391 		_buffer.length = 0;
3392 		static if(writeId){ writeBigEndianUbyte(ID); }
3393 		writeBigEndianUbyte(window);
3394 		writeBytes(varint.encode(property));
3395 		writeBytes(varint.encode(value));
3396 		return _buffer;
3397 	}
3398 
3399 	public pure nothrow @safe void decode(bool readId=true)() {
3400 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3401 		window=readBigEndianUbyte();
3402 		property=varint.decode(_buffer, &_index);
3403 		value=varint.decode(_buffer, &_index);
3404 	}
3405 
3406 	public static pure nothrow @safe ContainerSetData fromBuffer(bool readId=true)(ubyte[] buffer) {
3407 		ContainerSetData ret = new ContainerSetData();
3408 		ret._buffer = buffer;
3409 		ret.decode!readId();
3410 		return ret;
3411 	}
3412 
3413 	public override string toString() {
3414 		return "ContainerSetData(window: " ~ std.conv.to!string(this.window) ~ ", property: " ~ std.conv.to!string(this.property) ~ ", value: " ~ std.conv.to!string(this.value) ~ ")";
3415 	}
3416 
3417 }
3418 
3419 class ContainerSetContent : Buffer {
3420 
3421 	public enum ubyte ID = 52;
3422 
3423 	public enum bool CLIENTBOUND = true;
3424 	public enum bool SERVERBOUND = false;
3425 
3426 	public enum string[] FIELDS = ["window", "slots", "hotbar"];
3427 
3428 	public ubyte window;
3429 	public sul.protocol.pocket102.types.Slot[] slots;
3430 	public int[] hotbar;
3431 
3432 	public pure nothrow @safe @nogc this() {}
3433 
3434 	public pure nothrow @safe @nogc this(ubyte window, sul.protocol.pocket102.types.Slot[] slots=(sul.protocol.pocket102.types.Slot[]).init, int[] hotbar=(int[]).init) {
3435 		this.window = window;
3436 		this.slots = slots;
3437 		this.hotbar = hotbar;
3438 	}
3439 
3440 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3441 		_buffer.length = 0;
3442 		static if(writeId){ writeBigEndianUbyte(ID); }
3443 		writeBigEndianUbyte(window);
3444 		writeBytes(varuint.encode(cast(uint)slots.length)); foreach(cxdm;slots){ cxdm.encode(bufferInstance); }
3445 		writeBytes(varuint.encode(cast(uint)hotbar.length)); foreach(a9yf;hotbar){ writeBytes(varint.encode(a9yf)); }
3446 		return _buffer;
3447 	}
3448 
3449 	public pure nothrow @safe void decode(bool readId=true)() {
3450 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3451 		window=readBigEndianUbyte();
3452 		slots.length=varuint.decode(_buffer, &_index); foreach(ref cxdm;slots){ cxdm.decode(bufferInstance); }
3453 		hotbar.length=varuint.decode(_buffer, &_index); foreach(ref a9yf;hotbar){ a9yf=varint.decode(_buffer, &_index); }
3454 	}
3455 
3456 	public static pure nothrow @safe ContainerSetContent fromBuffer(bool readId=true)(ubyte[] buffer) {
3457 		ContainerSetContent ret = new ContainerSetContent();
3458 		ret._buffer = buffer;
3459 		ret.decode!readId();
3460 		return ret;
3461 	}
3462 
3463 	public override string toString() {
3464 		return "ContainerSetContent(window: " ~ std.conv.to!string(this.window) ~ ", slots: " ~ std.conv.to!string(this.slots) ~ ", hotbar: " ~ std.conv.to!string(this.hotbar) ~ ")";
3465 	}
3466 
3467 }
3468 
3469 class CraftingData : Buffer {
3470 
3471 	public enum ubyte ID = 53;
3472 
3473 	public enum bool CLIENTBOUND = true;
3474 	public enum bool SERVERBOUND = false;
3475 
3476 	public enum string[] FIELDS = ["recipes"];
3477 
3478 	public sul.protocol.pocket102.types.Recipe[] recipes;
3479 
3480 	public pure nothrow @safe @nogc this() {}
3481 
3482 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.Recipe[] recipes) {
3483 		this.recipes = recipes;
3484 	}
3485 
3486 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3487 		_buffer.length = 0;
3488 		static if(writeId){ writeBigEndianUbyte(ID); }
3489 		writeBytes(varuint.encode(cast(uint)recipes.length)); foreach(cvabc;recipes){ cvabc.encode(bufferInstance); }
3490 		return _buffer;
3491 	}
3492 
3493 	public pure nothrow @safe void decode(bool readId=true)() {
3494 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3495 		recipes.length=varuint.decode(_buffer, &_index); foreach(ref cvabc;recipes){ cvabc.decode(bufferInstance); }
3496 	}
3497 
3498 	public static pure nothrow @safe CraftingData fromBuffer(bool readId=true)(ubyte[] buffer) {
3499 		CraftingData ret = new CraftingData();
3500 		ret._buffer = buffer;
3501 		ret.decode!readId();
3502 		return ret;
3503 	}
3504 
3505 	public override string toString() {
3506 		return "CraftingData(recipes: " ~ std.conv.to!string(this.recipes) ~ ")";
3507 	}
3508 
3509 }
3510 
3511 class CraftingEvent : Buffer {
3512 
3513 	public enum ubyte ID = 54;
3514 
3515 	public enum bool CLIENTBOUND = false;
3516 	public enum bool SERVERBOUND = true;
3517 
3518 	public enum string[] FIELDS = ["window", "type", "uuid", "input", "output"];
3519 
3520 	public ubyte window;
3521 	public int type;
3522 	public UUID uuid;
3523 	public sul.protocol.pocket102.types.Slot[] input;
3524 	public sul.protocol.pocket102.types.Slot[] output;
3525 
3526 	public pure nothrow @safe @nogc this() {}
3527 
3528 	public pure nothrow @safe @nogc this(ubyte window, int type=int.init, UUID uuid=UUID.init, sul.protocol.pocket102.types.Slot[] input=(sul.protocol.pocket102.types.Slot[]).init, sul.protocol.pocket102.types.Slot[] output=(sul.protocol.pocket102.types.Slot[]).init) {
3529 		this.window = window;
3530 		this.type = type;
3531 		this.uuid = uuid;
3532 		this.input = input;
3533 		this.output = output;
3534 	}
3535 
3536 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3537 		_buffer.length = 0;
3538 		static if(writeId){ writeBigEndianUbyte(ID); }
3539 		writeBigEndianUbyte(window);
3540 		writeBytes(varint.encode(type));
3541 		writeBytes(uuid.data);
3542 		writeBytes(varuint.encode(cast(uint)input.length)); foreach(a5dq;input){ a5dq.encode(bufferInstance); }
3543 		writeBytes(varuint.encode(cast(uint)output.length)); foreach(bvcv;output){ bvcv.encode(bufferInstance); }
3544 		return _buffer;
3545 	}
3546 
3547 	public pure nothrow @safe void decode(bool readId=true)() {
3548 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3549 		window=readBigEndianUbyte();
3550 		type=varint.decode(_buffer, &_index);
3551 		if(_buffer.length>=_index+16){ ubyte[16] dvz=_buffer[_index.._index+16].dup; _index+=16; uuid=UUID(dvz); }
3552 		input.length=varuint.decode(_buffer, &_index); foreach(ref a5dq;input){ a5dq.decode(bufferInstance); }
3553 		output.length=varuint.decode(_buffer, &_index); foreach(ref bvcv;output){ bvcv.decode(bufferInstance); }
3554 	}
3555 
3556 	public static pure nothrow @safe CraftingEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
3557 		CraftingEvent ret = new CraftingEvent();
3558 		ret._buffer = buffer;
3559 		ret.decode!readId();
3560 		return ret;
3561 	}
3562 
3563 	public override string toString() {
3564 		return "CraftingEvent(window: " ~ std.conv.to!string(this.window) ~ ", type: " ~ std.conv.to!string(this.type) ~ ", uuid: " ~ std.conv.to!string(this.uuid) ~ ", input: " ~ std.conv.to!string(this.input) ~ ", output: " ~ std.conv.to!string(this.output) ~ ")";
3565 	}
3566 
3567 }
3568 
3569 /**
3570  * Updates the world's settings and client's permissions.
3571  */
3572 class AdventureSettings : Buffer {
3573 
3574 	public enum ubyte ID = 55;
3575 
3576 	public enum bool CLIENTBOUND = true;
3577 	public enum bool SERVERBOUND = true;
3578 
3579 	// flags
3580 	public enum uint IMMUTABLE_WORLD = 1;
3581 	public enum uint PVP_DISABLED = 2;
3582 	public enum uint PVM_DISABLED = 4;
3583 	public enum uint MVP_DISBALED = 8;
3584 	public enum uint EVP_DISABLED = 16;
3585 	public enum uint AUTO_JUMP = 32;
3586 	public enum uint ALLOW_FLIGHT = 64;
3587 	public enum uint NO_CLIP = 128;
3588 	public enum uint FLYING = 512;
3589 
3590 	// permissions
3591 	public enum uint USER = 0;
3592 	public enum uint OPERATOR = 1;
3593 	public enum uint HOST = 2;
3594 	public enum uint AUTOMATION = 3;
3595 	public enum uint ADMIN = 4;
3596 
3597 	public enum string[] FIELDS = ["flags", "permissions"];
3598 
3599 	public uint flags;
3600 	public uint permissions;
3601 
3602 	public pure nothrow @safe @nogc this() {}
3603 
3604 	public pure nothrow @safe @nogc this(uint flags, uint permissions=uint.init) {
3605 		this.flags = flags;
3606 		this.permissions = permissions;
3607 	}
3608 
3609 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3610 		_buffer.length = 0;
3611 		static if(writeId){ writeBigEndianUbyte(ID); }
3612 		writeBytes(varuint.encode(flags));
3613 		writeBytes(varuint.encode(permissions));
3614 		return _buffer;
3615 	}
3616 
3617 	public pure nothrow @safe void decode(bool readId=true)() {
3618 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3619 		flags=varuint.decode(_buffer, &_index);
3620 		permissions=varuint.decode(_buffer, &_index);
3621 	}
3622 
3623 	public static pure nothrow @safe AdventureSettings fromBuffer(bool readId=true)(ubyte[] buffer) {
3624 		AdventureSettings ret = new AdventureSettings();
3625 		ret._buffer = buffer;
3626 		ret.decode!readId();
3627 		return ret;
3628 	}
3629 
3630 	public override string toString() {
3631 		return "AdventureSettings(flags: " ~ std.conv.to!string(this.flags) ~ ", permissions: " ~ std.conv.to!string(this.permissions) ~ ")";
3632 	}
3633 
3634 }
3635 
3636 /**
3637  * Sets a block entity's nbt tag, block's additional data that cannot be indicated
3638  * in the block's meta. More informations about block entities and their tag format
3639  * can be found on Minecraft Wiki.
3640  */
3641 class BlockEntityData : Buffer {
3642 
3643 	public enum ubyte ID = 56;
3644 
3645 	public enum bool CLIENTBOUND = true;
3646 	public enum bool SERVERBOUND = false;
3647 
3648 	public enum string[] FIELDS = ["position", "nbt"];
3649 
3650 	/**
3651 	 * Position of the block that will be associated with tag.
3652 	 */
3653 	public sul.protocol.pocket102.types.BlockPosition position;
3654 
3655 	/**
3656 	 * Named binary tag of the block. The format varies from the classic format of Minecraft:
3657 	 * Pocket Edition (which is like Minecraft's but little endian) introducing the use
3658 	 * of varints for some types:
3659 	 * + The tag `Int` is encoded as a signed varint instead of a simple signed 32-bits
3660 	 * integer
3661 	 * + The length of the `ByteArray` and the `IntArray` is encoded as an unsigned varint
3662 	 * instead of a 32-bits integer
3663 	 * + The length of the `String` tag and the named tag's name length are encoded as
3664 	 * an unisgned varint instead of a 16-bits integer
3665 	 */
3666 	public ubyte[] nbt;
3667 
3668 	public pure nothrow @safe @nogc this() {}
3669 
3670 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.BlockPosition position, ubyte[] nbt=(ubyte[]).init) {
3671 		this.position = position;
3672 		this.nbt = nbt;
3673 	}
3674 
3675 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3676 		_buffer.length = 0;
3677 		static if(writeId){ writeBigEndianUbyte(ID); }
3678 		position.encode(bufferInstance);
3679 		writeBytes(nbt);
3680 		return _buffer;
3681 	}
3682 
3683 	public pure nothrow @safe void decode(bool readId=true)() {
3684 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3685 		position.decode(bufferInstance);
3686 		nbt=_buffer[_index..$].dup; _index=_buffer.length;
3687 	}
3688 
3689 	public static pure nothrow @safe BlockEntityData fromBuffer(bool readId=true)(ubyte[] buffer) {
3690 		BlockEntityData ret = new BlockEntityData();
3691 		ret._buffer = buffer;
3692 		ret.decode!readId();
3693 		return ret;
3694 	}
3695 
3696 	public override string toString() {
3697 		return "BlockEntityData(position: " ~ std.conv.to!string(this.position) ~ ", nbt: " ~ std.conv.to!string(this.nbt) ~ ")";
3698 	}
3699 
3700 }
3701 
3702 class PlayerInput : Buffer {
3703 
3704 	public enum ubyte ID = 57;
3705 
3706 	public enum bool CLIENTBOUND = false;
3707 	public enum bool SERVERBOUND = true;
3708 
3709 	public enum string[] FIELDS = ["motion", "flags", "unknown2"];
3710 
3711 	public Tuple!(float, "x", float, "y", float, "z") motion;
3712 	public ubyte flags;
3713 	public bool unknown2;
3714 
3715 	public pure nothrow @safe @nogc this() {}
3716 
3717 	public pure nothrow @safe @nogc this(Tuple!(float, "x", float, "y", float, "z") motion, ubyte flags=ubyte.init, bool unknown2=bool.init) {
3718 		this.motion = motion;
3719 		this.flags = flags;
3720 		this.unknown2 = unknown2;
3721 	}
3722 
3723 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3724 		_buffer.length = 0;
3725 		static if(writeId){ writeBigEndianUbyte(ID); }
3726 		writeLittleEndianFloat(motion.x); writeLittleEndianFloat(motion.y); writeLittleEndianFloat(motion.z);
3727 		writeBigEndianUbyte(flags);
3728 		writeBigEndianBool(unknown2);
3729 		return _buffer;
3730 	}
3731 
3732 	public pure nothrow @safe void decode(bool readId=true)() {
3733 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3734 		motion.x=readLittleEndianFloat(); motion.y=readLittleEndianFloat(); motion.z=readLittleEndianFloat();
3735 		flags=readBigEndianUbyte();
3736 		unknown2=readBigEndianBool();
3737 	}
3738 
3739 	public static pure nothrow @safe PlayerInput fromBuffer(bool readId=true)(ubyte[] buffer) {
3740 		PlayerInput ret = new PlayerInput();
3741 		ret._buffer = buffer;
3742 		ret.decode!readId();
3743 		return ret;
3744 	}
3745 
3746 	public override string toString() {
3747 		return "PlayerInput(motion: " ~ std.conv.to!string(this.motion) ~ ", flags: " ~ std.conv.to!string(this.flags) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
3748 	}
3749 
3750 }
3751 
3752 /**
3753  * Sends a 16x16 chunk to the client with its blocks, lights and block entities (tiles).
3754  */
3755 class FullChunkData : Buffer {
3756 
3757 	public enum ubyte ID = 58;
3758 
3759 	public enum bool CLIENTBOUND = true;
3760 	public enum bool SERVERBOUND = false;
3761 
3762 	public enum string[] FIELDS = ["position", "data"];
3763 
3764 	/**
3765 	 * Coordinates of the chunk.
3766 	 */
3767 	public Tuple!(int, "x", int, "z") position;
3768 	public sul.protocol.pocket102.types.ChunkData data;
3769 
3770 	public pure nothrow @safe @nogc this() {}
3771 
3772 	public pure nothrow @safe @nogc this(Tuple!(int, "x", int, "z") position, sul.protocol.pocket102.types.ChunkData data=sul.protocol.pocket102.types.ChunkData.init) {
3773 		this.position = position;
3774 		this.data = data;
3775 	}
3776 
3777 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3778 		_buffer.length = 0;
3779 		static if(writeId){ writeBigEndianUbyte(ID); }
3780 		writeBytes(varint.encode(position.x)); writeBytes(varint.encode(position.z));
3781 		data.encode(bufferInstance);
3782 		return _buffer;
3783 	}
3784 
3785 	public pure nothrow @safe void decode(bool readId=true)() {
3786 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3787 		position.x=varint.decode(_buffer, &_index); position.z=varint.decode(_buffer, &_index);
3788 		data.decode(bufferInstance);
3789 	}
3790 
3791 	public static pure nothrow @safe FullChunkData fromBuffer(bool readId=true)(ubyte[] buffer) {
3792 		FullChunkData ret = new FullChunkData();
3793 		ret._buffer = buffer;
3794 		ret.decode!readId();
3795 		return ret;
3796 	}
3797 
3798 	public override string toString() {
3799 		return "FullChunkData(position: " ~ std.conv.to!string(this.position) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
3800 	}
3801 
3802 }
3803 
3804 /**
3805  * Indicates whether the cheats are enabled. If not the client cannot send commands.
3806  */
3807 class SetCommandsEnabled : Buffer {
3808 
3809 	public enum ubyte ID = 59;
3810 
3811 	public enum bool CLIENTBOUND = true;
3812 	public enum bool SERVERBOUND = false;
3813 
3814 	public enum string[] FIELDS = ["enabled"];
3815 
3816 	public bool enabled;
3817 
3818 	public pure nothrow @safe @nogc this() {}
3819 
3820 	public pure nothrow @safe @nogc this(bool enabled) {
3821 		this.enabled = enabled;
3822 	}
3823 
3824 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3825 		_buffer.length = 0;
3826 		static if(writeId){ writeBigEndianUbyte(ID); }
3827 		writeBigEndianBool(enabled);
3828 		return _buffer;
3829 	}
3830 
3831 	public pure nothrow @safe void decode(bool readId=true)() {
3832 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3833 		enabled=readBigEndianBool();
3834 	}
3835 
3836 	public static pure nothrow @safe SetCommandsEnabled fromBuffer(bool readId=true)(ubyte[] buffer) {
3837 		SetCommandsEnabled ret = new SetCommandsEnabled();
3838 		ret._buffer = buffer;
3839 		ret.decode!readId();
3840 		return ret;
3841 	}
3842 
3843 	public override string toString() {
3844 		return "SetCommandsEnabled(enabled: " ~ std.conv.to!string(this.enabled) ~ ")";
3845 	}
3846 
3847 }
3848 
3849 /**
3850  * Sets the world's difficulty.
3851  */
3852 class SetDifficulty : Buffer {
3853 
3854 	public enum ubyte ID = 60;
3855 
3856 	public enum bool CLIENTBOUND = true;
3857 	public enum bool SERVERBOUND = false;
3858 
3859 	// difficulty
3860 	public enum uint PEACEFUL = 0;
3861 	public enum uint EASY = 1;
3862 	public enum uint NORMAL = 2;
3863 	public enum uint HARD = 3;
3864 
3865 	public enum string[] FIELDS = ["difficulty"];
3866 
3867 	public uint difficulty;
3868 
3869 	public pure nothrow @safe @nogc this() {}
3870 
3871 	public pure nothrow @safe @nogc this(uint difficulty) {
3872 		this.difficulty = difficulty;
3873 	}
3874 
3875 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3876 		_buffer.length = 0;
3877 		static if(writeId){ writeBigEndianUbyte(ID); }
3878 		writeBytes(varuint.encode(difficulty));
3879 		return _buffer;
3880 	}
3881 
3882 	public pure nothrow @safe void decode(bool readId=true)() {
3883 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3884 		difficulty=varuint.decode(_buffer, &_index);
3885 	}
3886 
3887 	public static pure nothrow @safe SetDifficulty fromBuffer(bool readId=true)(ubyte[] buffer) {
3888 		SetDifficulty ret = new SetDifficulty();
3889 		ret._buffer = buffer;
3890 		ret.decode!readId();
3891 		return ret;
3892 	}
3893 
3894 	public override string toString() {
3895 		return "SetDifficulty(difficulty: " ~ std.conv.to!string(this.difficulty) ~ ")";
3896 	}
3897 
3898 }
3899 
3900 class ChangeDimension : Buffer {
3901 
3902 	public enum ubyte ID = 61;
3903 
3904 	public enum bool CLIENTBOUND = true;
3905 	public enum bool SERVERBOUND = false;
3906 
3907 	// dimension
3908 	public enum int OVERWORLD = 0;
3909 	public enum int NETHER = 1;
3910 	public enum int END = 2;
3911 
3912 	public enum string[] FIELDS = ["dimension", "position", "unknown2"];
3913 
3914 	public int dimension;
3915 	public Tuple!(float, "x", float, "y", float, "z") position;
3916 	public bool unknown2;
3917 
3918 	public pure nothrow @safe @nogc this() {}
3919 
3920 	public pure nothrow @safe @nogc this(int dimension, Tuple!(float, "x", float, "y", float, "z") position=Tuple!(float, "x", float, "y", float, "z").init, bool unknown2=bool.init) {
3921 		this.dimension = dimension;
3922 		this.position = position;
3923 		this.unknown2 = unknown2;
3924 	}
3925 
3926 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3927 		_buffer.length = 0;
3928 		static if(writeId){ writeBigEndianUbyte(ID); }
3929 		writeBytes(varint.encode(dimension));
3930 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
3931 		writeBigEndianBool(unknown2);
3932 		return _buffer;
3933 	}
3934 
3935 	public pure nothrow @safe void decode(bool readId=true)() {
3936 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3937 		dimension=varint.decode(_buffer, &_index);
3938 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
3939 		unknown2=readBigEndianBool();
3940 	}
3941 
3942 	public static pure nothrow @safe ChangeDimension fromBuffer(bool readId=true)(ubyte[] buffer) {
3943 		ChangeDimension ret = new ChangeDimension();
3944 		ret._buffer = buffer;
3945 		ret.decode!readId();
3946 		return ret;
3947 	}
3948 
3949 	public override string toString() {
3950 		return "ChangeDimension(dimension: " ~ std.conv.to!string(this.dimension) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
3951 	}
3952 
3953 }
3954 
3955 /**
3956  * Sets the player's gamemode. This packet is sent by the player when it has the operator
3957  * status (set in AdventureSettings.permissions) and it changes the gamemode in the
3958  * settings screen.
3959  */
3960 class SetPlayerGameType : Buffer {
3961 
3962 	public enum ubyte ID = 62;
3963 
3964 	public enum bool CLIENTBOUND = true;
3965 	public enum bool SERVERBOUND = true;
3966 
3967 	// gamemode
3968 	public enum int SURVIVAL = 0;
3969 	public enum int CREATIVE = 1;
3970 
3971 	public enum string[] FIELDS = ["gamemode"];
3972 
3973 	public int gamemode;
3974 
3975 	public pure nothrow @safe @nogc this() {}
3976 
3977 	public pure nothrow @safe @nogc this(int gamemode) {
3978 		this.gamemode = gamemode;
3979 	}
3980 
3981 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3982 		_buffer.length = 0;
3983 		static if(writeId){ writeBigEndianUbyte(ID); }
3984 		writeBytes(varint.encode(gamemode));
3985 		return _buffer;
3986 	}
3987 
3988 	public pure nothrow @safe void decode(bool readId=true)() {
3989 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3990 		gamemode=varint.decode(_buffer, &_index);
3991 	}
3992 
3993 	public static pure nothrow @safe SetPlayerGameType fromBuffer(bool readId=true)(ubyte[] buffer) {
3994 		SetPlayerGameType ret = new SetPlayerGameType();
3995 		ret._buffer = buffer;
3996 		ret.decode!readId();
3997 		return ret;
3998 	}
3999 
4000 	public override string toString() {
4001 		return "SetPlayerGameType(gamemode: " ~ std.conv.to!string(this.gamemode) ~ ")";
4002 	}
4003 
4004 }
4005 
4006 /**
4007  * Adds or removes a player from the player's list displayed in the pause menu. This
4008  * packet should be sent before spawning a player with AddPlayer, otherwise the skin
4009  * is not applied.
4010  */
4011 class PlayerList : Buffer {
4012 
4013 	public enum ubyte ID = 63;
4014 
4015 	public enum bool CLIENTBOUND = true;
4016 	public enum bool SERVERBOUND = false;
4017 
4018 	public enum string[] FIELDS = ["action"];
4019 
4020 	public ubyte action;
4021 
4022 	public pure nothrow @safe @nogc this() {}
4023 
4024 	public pure nothrow @safe @nogc this(ubyte action) {
4025 		this.action = action;
4026 	}
4027 
4028 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4029 		_buffer.length = 0;
4030 		static if(writeId){ writeBigEndianUbyte(ID); }
4031 		writeBigEndianUbyte(action);
4032 		return _buffer;
4033 	}
4034 
4035 	public pure nothrow @safe void decode(bool readId=true)() {
4036 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4037 		action=readBigEndianUbyte();
4038 	}
4039 
4040 	public static pure nothrow @safe PlayerList fromBuffer(bool readId=true)(ubyte[] buffer) {
4041 		PlayerList ret = new PlayerList();
4042 		ret._buffer = buffer;
4043 		ret.decode!readId();
4044 		return ret;
4045 	}
4046 
4047 	public override string toString() {
4048 		return "PlayerList(action: " ~ std.conv.to!string(this.action) ~ ")";
4049 	}
4050 
4051 	alias _encode = encode;
4052 
4053 	enum string variantField = "action";
4054 
4055 	alias Variants = TypeTuple!(Add, Remove);
4056 
4057 	public class Add {
4058 
4059 		public enum typeof(action) ACTION = 0;
4060 
4061 		public enum string[] FIELDS = ["players"];
4062 
4063 		public sul.protocol.pocket102.types.PlayerList[] players;
4064 
4065 		public pure nothrow @safe @nogc this() {}
4066 
4067 		public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.PlayerList[] players) {
4068 			this.players = players;
4069 		}
4070 
4071 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4072 			action = 0;
4073 			_encode!writeId();
4074 			writeBytes(varuint.encode(cast(uint)players.length)); foreach(cxevc;players){ cxevc.encode(bufferInstance); }
4075 			return _buffer;
4076 		}
4077 
4078 		public pure nothrow @safe void decode() {
4079 			players.length=varuint.decode(_buffer, &_index); foreach(ref cxevc;players){ cxevc.decode(bufferInstance); }
4080 		}
4081 
4082 		public override string toString() {
4083 			return "PlayerList.Add(players: " ~ std.conv.to!string(this.players) ~ ")";
4084 		}
4085 
4086 	}
4087 
4088 	public class Remove {
4089 
4090 		public enum typeof(action) ACTION = 1;
4091 
4092 		public enum string[] FIELDS = ["players"];
4093 
4094 		public UUID[] players;
4095 
4096 		public pure nothrow @safe @nogc this() {}
4097 
4098 		public pure nothrow @safe @nogc this(UUID[] players) {
4099 			this.players = players;
4100 		}
4101 
4102 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4103 			action = 1;
4104 			_encode!writeId();
4105 			writeBytes(varuint.encode(cast(uint)players.length)); foreach(cxevc;players){ writeBytes(cxevc.data); }
4106 			return _buffer;
4107 		}
4108 
4109 		public pure nothrow @safe void decode() {
4110 			players.length=varuint.decode(_buffer, &_index); foreach(ref cxevc;players){ if(_buffer.length>=_index+16){ ubyte[16] yhdm=_buffer[_index.._index+16].dup; _index+=16; cxevc=UUID(yhdm); } }
4111 		}
4112 
4113 		public override string toString() {
4114 			return "PlayerList.Remove(players: " ~ std.conv.to!string(this.players) ~ ")";
4115 		}
4116 
4117 	}
4118 
4119 }
4120 
4121 class TelemetryEvent : Buffer {
4122 
4123 	public enum ubyte ID = 64;
4124 
4125 	public enum bool CLIENTBOUND = true;
4126 	public enum bool SERVERBOUND = false;
4127 
4128 	public enum string[] FIELDS = ["entityId", "eventId"];
4129 
4130 	public long entityId;
4131 	public int eventId;
4132 
4133 	public pure nothrow @safe @nogc this() {}
4134 
4135 	public pure nothrow @safe @nogc this(long entityId, int eventId=int.init) {
4136 		this.entityId = entityId;
4137 		this.eventId = eventId;
4138 	}
4139 
4140 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4141 		_buffer.length = 0;
4142 		static if(writeId){ writeBigEndianUbyte(ID); }
4143 		writeBytes(varlong.encode(entityId));
4144 		writeBytes(varint.encode(eventId));
4145 		return _buffer;
4146 	}
4147 
4148 	public pure nothrow @safe void decode(bool readId=true)() {
4149 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4150 		entityId=varlong.decode(_buffer, &_index);
4151 		eventId=varint.decode(_buffer, &_index);
4152 	}
4153 
4154 	public static pure nothrow @safe TelemetryEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
4155 		TelemetryEvent ret = new TelemetryEvent();
4156 		ret._buffer = buffer;
4157 		ret.decode!readId();
4158 		return ret;
4159 	}
4160 
4161 	public override string toString() {
4162 		return "TelemetryEvent(entityId: " ~ std.conv.to!string(this.entityId) ~ ", eventId: " ~ std.conv.to!string(this.eventId) ~ ")";
4163 	}
4164 
4165 }
4166 
4167 class SpawnExperienceOrb : Buffer {
4168 
4169 	public enum ubyte ID = 65;
4170 
4171 	public enum bool CLIENTBOUND = true;
4172 	public enum bool SERVERBOUND = false;
4173 
4174 	public enum string[] FIELDS = ["position", "count"];
4175 
4176 	public Tuple!(float, "x", float, "y", float, "z") position;
4177 	public int count;
4178 
4179 	public pure nothrow @safe @nogc this() {}
4180 
4181 	public pure nothrow @safe @nogc this(Tuple!(float, "x", float, "y", float, "z") position, int count=int.init) {
4182 		this.position = position;
4183 		this.count = count;
4184 	}
4185 
4186 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4187 		_buffer.length = 0;
4188 		static if(writeId){ writeBigEndianUbyte(ID); }
4189 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
4190 		writeBytes(varint.encode(count));
4191 		return _buffer;
4192 	}
4193 
4194 	public pure nothrow @safe void decode(bool readId=true)() {
4195 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4196 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
4197 		count=varint.decode(_buffer, &_index);
4198 	}
4199 
4200 	public static pure nothrow @safe SpawnExperienceOrb fromBuffer(bool readId=true)(ubyte[] buffer) {
4201 		SpawnExperienceOrb ret = new SpawnExperienceOrb();
4202 		ret._buffer = buffer;
4203 		ret.decode!readId();
4204 		return ret;
4205 	}
4206 
4207 	public override string toString() {
4208 		return "SpawnExperienceOrb(position: " ~ std.conv.to!string(this.position) ~ ", count: " ~ std.conv.to!string(this.count) ~ ")";
4209 	}
4210 
4211 }
4212 
4213 class ClientboundMapItemData : Buffer {
4214 
4215 	public enum ubyte ID = 66;
4216 
4217 	public enum bool CLIENTBOUND = true;
4218 	public enum bool SERVERBOUND = false;
4219 
4220 	// update
4221 	public enum uint TEXTURE = 2;
4222 	public enum uint DECORATIONS = 4;
4223 	public enum uint ENTITIES = 8;
4224 
4225 	public enum string[] FIELDS = ["mapId", "update", "scale", "size", "offset", "data", "decorations"];
4226 
4227 	public long mapId;
4228 	public uint update;
4229 	public ubyte scale;
4230 
4231 	/**
4232 	 * Colums and rows.
4233 	 */
4234 	public Tuple!(int, "x", int, "z") size;
4235 	public Tuple!(int, "x", int, "z") offset;
4236 
4237 	/**
4238 	 * ARGB colours encoded as unsigned varints.
4239 	 */
4240 	public ubyte[] data;
4241 	public sul.protocol.pocket102.types.Decoration[] decorations;
4242 
4243 	public pure nothrow @safe @nogc this() {}
4244 
4245 	public pure nothrow @safe @nogc this(long mapId, uint update=uint.init, ubyte scale=ubyte.init, Tuple!(int, "x", int, "z") size=Tuple!(int, "x", int, "z").init, Tuple!(int, "x", int, "z") offset=Tuple!(int, "x", int, "z").init, ubyte[] data=(ubyte[]).init, sul.protocol.pocket102.types.Decoration[] decorations=(sul.protocol.pocket102.types.Decoration[]).init) {
4246 		this.mapId = mapId;
4247 		this.update = update;
4248 		this.scale = scale;
4249 		this.size = size;
4250 		this.offset = offset;
4251 		this.data = data;
4252 		this.decorations = decorations;
4253 	}
4254 
4255 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4256 		_buffer.length = 0;
4257 		static if(writeId){ writeBigEndianUbyte(ID); }
4258 		writeBytes(varlong.encode(mapId));
4259 		writeBytes(varuint.encode(update));
4260 		if(update==2||update==4){ writeBigEndianUbyte(scale); }
4261 		if(update==2){ writeBytes(varint.encode(size.x)); writeBytes(varint.encode(size.z)); }
4262 		if(update==2){ writeBytes(varint.encode(offset.x)); writeBytes(varint.encode(offset.z)); }
4263 		if(update==2){ writeBytes(data); }
4264 		if(update==4){ writeBytes(varuint.encode(cast(uint)decorations.length)); foreach(zvbjdlbm;decorations){ zvbjdlbm.encode(bufferInstance); } }
4265 		return _buffer;
4266 	}
4267 
4268 	public pure nothrow @safe void decode(bool readId=true)() {
4269 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4270 		mapId=varlong.decode(_buffer, &_index);
4271 		update=varuint.decode(_buffer, &_index);
4272 		if(update==2||update==4){ scale=readBigEndianUbyte(); }
4273 		if(update==2){ size.x=varint.decode(_buffer, &_index); size.z=varint.decode(_buffer, &_index); }
4274 		if(update==2){ offset.x=varint.decode(_buffer, &_index); offset.z=varint.decode(_buffer, &_index); }
4275 		if(update==2){ data=_buffer[_index..$].dup; _index=_buffer.length; }
4276 		if(update==4){ decorations.length=varuint.decode(_buffer, &_index); foreach(ref zvbjdlbm;decorations){ zvbjdlbm.decode(bufferInstance); } }
4277 	}
4278 
4279 	public static pure nothrow @safe ClientboundMapItemData fromBuffer(bool readId=true)(ubyte[] buffer) {
4280 		ClientboundMapItemData ret = new ClientboundMapItemData();
4281 		ret._buffer = buffer;
4282 		ret.decode!readId();
4283 		return ret;
4284 	}
4285 
4286 	public override string toString() {
4287 		return "ClientboundMapItemData(mapId: " ~ std.conv.to!string(this.mapId) ~ ", update: " ~ std.conv.to!string(this.update) ~ ", scale: " ~ std.conv.to!string(this.scale) ~ ", size: " ~ std.conv.to!string(this.size) ~ ", offset: " ~ std.conv.to!string(this.offset) ~ ", data: " ~ std.conv.to!string(this.data) ~ ", decorations: " ~ std.conv.to!string(this.decorations) ~ ")";
4288 	}
4289 
4290 }
4291 
4292 class MapInfoRequest : Buffer {
4293 
4294 	public enum ubyte ID = 67;
4295 
4296 	public enum bool CLIENTBOUND = false;
4297 	public enum bool SERVERBOUND = true;
4298 
4299 	public enum string[] FIELDS = ["mapId"];
4300 
4301 	public long mapId;
4302 
4303 	public pure nothrow @safe @nogc this() {}
4304 
4305 	public pure nothrow @safe @nogc this(long mapId) {
4306 		this.mapId = mapId;
4307 	}
4308 
4309 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4310 		_buffer.length = 0;
4311 		static if(writeId){ writeBigEndianUbyte(ID); }
4312 		writeBytes(varlong.encode(mapId));
4313 		return _buffer;
4314 	}
4315 
4316 	public pure nothrow @safe void decode(bool readId=true)() {
4317 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4318 		mapId=varlong.decode(_buffer, &_index);
4319 	}
4320 
4321 	public static pure nothrow @safe MapInfoRequest fromBuffer(bool readId=true)(ubyte[] buffer) {
4322 		MapInfoRequest ret = new MapInfoRequest();
4323 		ret._buffer = buffer;
4324 		ret.decode!readId();
4325 		return ret;
4326 	}
4327 
4328 	public override string toString() {
4329 		return "MapInfoRequest(mapId: " ~ std.conv.to!string(this.mapId) ~ ")";
4330 	}
4331 
4332 }
4333 
4334 /**
4335  * Packet sent by the client when its view-distance is updated and when it spawns for
4336  * the first time a world. A ChunkRadiusUpdate should always be sent in response, otherwise
4337  * the player will not update its view distance.
4338  */
4339 class RequestChunkRadius : Buffer {
4340 
4341 	public enum ubyte ID = 68;
4342 
4343 	public enum bool CLIENTBOUND = false;
4344 	public enum bool SERVERBOUND = true;
4345 
4346 	public enum string[] FIELDS = ["radius"];
4347 
4348 	/**
4349 	 * Number of chunks before the fog starts to appear in the client's view. The value
4350 	 * of this field is usually between 8 and 14.
4351 	 */
4352 	public int radius;
4353 
4354 	public pure nothrow @safe @nogc this() {}
4355 
4356 	public pure nothrow @safe @nogc this(int radius) {
4357 		this.radius = radius;
4358 	}
4359 
4360 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4361 		_buffer.length = 0;
4362 		static if(writeId){ writeBigEndianUbyte(ID); }
4363 		writeBytes(varint.encode(radius));
4364 		return _buffer;
4365 	}
4366 
4367 	public pure nothrow @safe void decode(bool readId=true)() {
4368 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4369 		radius=varint.decode(_buffer, &_index);
4370 	}
4371 
4372 	public static pure nothrow @safe RequestChunkRadius fromBuffer(bool readId=true)(ubyte[] buffer) {
4373 		RequestChunkRadius ret = new RequestChunkRadius();
4374 		ret._buffer = buffer;
4375 		ret.decode!readId();
4376 		return ret;
4377 	}
4378 
4379 	public override string toString() {
4380 		return "RequestChunkRadius(radius: " ~ std.conv.to!string(this.radius) ~ ")";
4381 	}
4382 
4383 }
4384 
4385 /**
4386  * Packet sent always and only in response to RequestChunkRadius to change the client's
4387  * view distance.
4388  */
4389 class ChunkRadiusUpdated : Buffer {
4390 
4391 	public enum ubyte ID = 69;
4392 
4393 	public enum bool CLIENTBOUND = true;
4394 	public enum bool SERVERBOUND = false;
4395 
4396 	public enum string[] FIELDS = ["radius"];
4397 
4398 	/**
4399 	 * View distance that may be different from the client's one if the server sets a limit
4400 	 * on the view distance.
4401 	 */
4402 	public int radius;
4403 
4404 	public pure nothrow @safe @nogc this() {}
4405 
4406 	public pure nothrow @safe @nogc this(int radius) {
4407 		this.radius = radius;
4408 	}
4409 
4410 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4411 		_buffer.length = 0;
4412 		static if(writeId){ writeBigEndianUbyte(ID); }
4413 		writeBytes(varint.encode(radius));
4414 		return _buffer;
4415 	}
4416 
4417 	public pure nothrow @safe void decode(bool readId=true)() {
4418 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4419 		radius=varint.decode(_buffer, &_index);
4420 	}
4421 
4422 	public static pure nothrow @safe ChunkRadiusUpdated fromBuffer(bool readId=true)(ubyte[] buffer) {
4423 		ChunkRadiusUpdated ret = new ChunkRadiusUpdated();
4424 		ret._buffer = buffer;
4425 		ret.decode!readId();
4426 		return ret;
4427 	}
4428 
4429 	public override string toString() {
4430 		return "ChunkRadiusUpdated(radius: " ~ std.conv.to!string(this.radius) ~ ")";
4431 	}
4432 
4433 }
4434 
4435 class ItemFrameDropItem : Buffer {
4436 
4437 	public enum ubyte ID = 70;
4438 
4439 	public enum bool CLIENTBOUND = true;
4440 	public enum bool SERVERBOUND = false;
4441 
4442 	public enum string[] FIELDS = ["position", "item"];
4443 
4444 	public sul.protocol.pocket102.types.BlockPosition position;
4445 	public sul.protocol.pocket102.types.Slot item;
4446 
4447 	public pure nothrow @safe @nogc this() {}
4448 
4449 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.BlockPosition position, sul.protocol.pocket102.types.Slot item=sul.protocol.pocket102.types.Slot.init) {
4450 		this.position = position;
4451 		this.item = item;
4452 	}
4453 
4454 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4455 		_buffer.length = 0;
4456 		static if(writeId){ writeBigEndianUbyte(ID); }
4457 		position.encode(bufferInstance);
4458 		item.encode(bufferInstance);
4459 		return _buffer;
4460 	}
4461 
4462 	public pure nothrow @safe void decode(bool readId=true)() {
4463 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4464 		position.decode(bufferInstance);
4465 		item.decode(bufferInstance);
4466 	}
4467 
4468 	public static pure nothrow @safe ItemFrameDropItem fromBuffer(bool readId=true)(ubyte[] buffer) {
4469 		ItemFrameDropItem ret = new ItemFrameDropItem();
4470 		ret._buffer = buffer;
4471 		ret.decode!readId();
4472 		return ret;
4473 	}
4474 
4475 	public override string toString() {
4476 		return "ItemFrameDropItem(position: " ~ std.conv.to!string(this.position) ~ ", item: " ~ std.conv.to!string(this.item) ~ ")";
4477 	}
4478 
4479 }
4480 
4481 class ReplaceSelectedItem : Buffer {
4482 
4483 	public enum ubyte ID = 71;
4484 
4485 	public enum bool CLIENTBOUND = false;
4486 	public enum bool SERVERBOUND = true;
4487 
4488 	public enum string[] FIELDS = ["item"];
4489 
4490 	public sul.protocol.pocket102.types.Slot item;
4491 
4492 	public pure nothrow @safe @nogc this() {}
4493 
4494 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.Slot item) {
4495 		this.item = item;
4496 	}
4497 
4498 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4499 		_buffer.length = 0;
4500 		static if(writeId){ writeBigEndianUbyte(ID); }
4501 		item.encode(bufferInstance);
4502 		return _buffer;
4503 	}
4504 
4505 	public pure nothrow @safe void decode(bool readId=true)() {
4506 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4507 		item.decode(bufferInstance);
4508 	}
4509 
4510 	public static pure nothrow @safe ReplaceSelectedItem fromBuffer(bool readId=true)(ubyte[] buffer) {
4511 		ReplaceSelectedItem ret = new ReplaceSelectedItem();
4512 		ret._buffer = buffer;
4513 		ret.decode!readId();
4514 		return ret;
4515 	}
4516 
4517 	public override string toString() {
4518 		return "ReplaceSelectedItem(item: " ~ std.conv.to!string(this.item) ~ ")";
4519 	}
4520 
4521 }
4522 
4523 /**
4524  * Updates client's game rules. This packet is ignored if the game is not launched
4525  * as Education Edition and should be avoid in favour of AdventureSettings, with which
4526  * the same result can be obtained with less data.
4527  */
4528 class GameRulesChanged : Buffer {
4529 
4530 	public enum ubyte ID = 72;
4531 
4532 	public enum bool CLIENTBOUND = true;
4533 	public enum bool SERVERBOUND = false;
4534 
4535 	public enum string[] FIELDS = ["rules"];
4536 
4537 	public sul.protocol.pocket102.types.Rule[] rules;
4538 
4539 	public pure nothrow @safe @nogc this() {}
4540 
4541 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.Rule[] rules) {
4542 		this.rules = rules;
4543 	}
4544 
4545 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4546 		_buffer.length = 0;
4547 		static if(writeId){ writeBigEndianUbyte(ID); }
4548 		writeBigEndianUint(cast(uint)rules.length); foreach(cvzm;rules){ cvzm.encode(bufferInstance); }
4549 		return _buffer;
4550 	}
4551 
4552 	public pure nothrow @safe void decode(bool readId=true)() {
4553 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4554 		rules.length=readBigEndianUint(); foreach(ref cvzm;rules){ cvzm.decode(bufferInstance); }
4555 	}
4556 
4557 	public static pure nothrow @safe GameRulesChanged fromBuffer(bool readId=true)(ubyte[] buffer) {
4558 		GameRulesChanged ret = new GameRulesChanged();
4559 		ret._buffer = buffer;
4560 		ret.decode!readId();
4561 		return ret;
4562 	}
4563 
4564 	public override string toString() {
4565 		return "GameRulesChanged(rules: " ~ std.conv.to!string(this.rules) ~ ")";
4566 	}
4567 
4568 }
4569 
4570 class Camera : Buffer {
4571 
4572 	public enum ubyte ID = 73;
4573 
4574 	public enum bool CLIENTBOUND = true;
4575 	public enum bool SERVERBOUND = false;
4576 
4577 	public enum string[] FIELDS = ["unknown0", "unknown1"];
4578 
4579 	public long unknown0;
4580 	public long unknown1;
4581 
4582 	public pure nothrow @safe @nogc this() {}
4583 
4584 	public pure nothrow @safe @nogc this(long unknown0, long unknown1=long.init) {
4585 		this.unknown0 = unknown0;
4586 		this.unknown1 = unknown1;
4587 	}
4588 
4589 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4590 		_buffer.length = 0;
4591 		static if(writeId){ writeBigEndianUbyte(ID); }
4592 		writeBytes(varlong.encode(unknown0));
4593 		writeBytes(varlong.encode(unknown1));
4594 		return _buffer;
4595 	}
4596 
4597 	public pure nothrow @safe void decode(bool readId=true)() {
4598 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4599 		unknown0=varlong.decode(_buffer, &_index);
4600 		unknown1=varlong.decode(_buffer, &_index);
4601 	}
4602 
4603 	public static pure nothrow @safe Camera fromBuffer(bool readId=true)(ubyte[] buffer) {
4604 		Camera ret = new Camera();
4605 		ret._buffer = buffer;
4606 		ret.decode!readId();
4607 		return ret;
4608 	}
4609 
4610 	public override string toString() {
4611 		return "Camera(unknown0: " ~ std.conv.to!string(this.unknown0) ~ ", unknown1: " ~ std.conv.to!string(this.unknown1) ~ ")";
4612 	}
4613 
4614 }
4615 
4616 class AddItem : Buffer {
4617 
4618 	public enum ubyte ID = 74;
4619 
4620 	public enum bool CLIENTBOUND = true;
4621 	public enum bool SERVERBOUND = false;
4622 
4623 	public enum string[] FIELDS = ["item"];
4624 
4625 	public sul.protocol.pocket102.types.Slot item;
4626 
4627 	public pure nothrow @safe @nogc this() {}
4628 
4629 	public pure nothrow @safe @nogc this(sul.protocol.pocket102.types.Slot item) {
4630 		this.item = item;
4631 	}
4632 
4633 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4634 		_buffer.length = 0;
4635 		static if(writeId){ writeBigEndianUbyte(ID); }
4636 		item.encode(bufferInstance);
4637 		return _buffer;
4638 	}
4639 
4640 	public pure nothrow @safe void decode(bool readId=true)() {
4641 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4642 		item.decode(bufferInstance);
4643 	}
4644 
4645 	public static pure nothrow @safe AddItem fromBuffer(bool readId=true)(ubyte[] buffer) {
4646 		AddItem ret = new AddItem();
4647 		ret._buffer = buffer;
4648 		ret.decode!readId();
4649 		return ret;
4650 	}
4651 
4652 	public override string toString() {
4653 		return "AddItem(item: " ~ std.conv.to!string(this.item) ~ ")";
4654 	}
4655 
4656 }
4657 
4658 /**
4659  * Adds, removes or modifies an entity's boss bar. The percentage of the bar is calculated
4660  * using the entity's attributes for the health and the max health, updated with UpdateAttributes.
4661  */
4662 class BossEvent : Buffer {
4663 
4664 	public enum ubyte ID = 75;
4665 
4666 	public enum bool CLIENTBOUND = true;
4667 	public enum bool SERVERBOUND = false;
4668 
4669 	// event id
4670 	public enum uint ADD = 0;
4671 	public enum uint UPDATE = 1;
4672 	public enum uint REMOVE = 2;
4673 
4674 	public enum string[] FIELDS = ["entityId", "eventId"];
4675 
4676 	public long entityId;
4677 	public uint eventId;
4678 
4679 	public pure nothrow @safe @nogc this() {}
4680 
4681 	public pure nothrow @safe @nogc this(long entityId, uint eventId=uint.init) {
4682 		this.entityId = entityId;
4683 		this.eventId = eventId;
4684 	}
4685 
4686 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4687 		_buffer.length = 0;
4688 		static if(writeId){ writeBigEndianUbyte(ID); }
4689 		writeBytes(varlong.encode(entityId));
4690 		writeBytes(varuint.encode(eventId));
4691 		return _buffer;
4692 	}
4693 
4694 	public pure nothrow @safe void decode(bool readId=true)() {
4695 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4696 		entityId=varlong.decode(_buffer, &_index);
4697 		eventId=varuint.decode(_buffer, &_index);
4698 	}
4699 
4700 	public static pure nothrow @safe BossEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
4701 		BossEvent ret = new BossEvent();
4702 		ret._buffer = buffer;
4703 		ret.decode!readId();
4704 		return ret;
4705 	}
4706 
4707 	public override string toString() {
4708 		return "BossEvent(entityId: " ~ std.conv.to!string(this.entityId) ~ ", eventId: " ~ std.conv.to!string(this.eventId) ~ ")";
4709 	}
4710 
4711 }
4712 
4713 class ShowCredits : Buffer {
4714 
4715 	public enum ubyte ID = 76;
4716 
4717 	public enum bool CLIENTBOUND = true;
4718 	public enum bool SERVERBOUND = true;
4719 
4720 	// status
4721 	public enum int START = 0;
4722 	public enum int END = 1;
4723 
4724 	public enum string[] FIELDS = ["entityId", "status"];
4725 
4726 	public long entityId;
4727 	public int status;
4728 
4729 	public pure nothrow @safe @nogc this() {}
4730 
4731 	public pure nothrow @safe @nogc this(long entityId, int status=int.init) {
4732 		this.entityId = entityId;
4733 		this.status = status;
4734 	}
4735 
4736 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4737 		_buffer.length = 0;
4738 		static if(writeId){ writeBigEndianUbyte(ID); }
4739 		writeBytes(varlong.encode(entityId));
4740 		writeBytes(varint.encode(status));
4741 		return _buffer;
4742 	}
4743 
4744 	public pure nothrow @safe void decode(bool readId=true)() {
4745 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4746 		entityId=varlong.decode(_buffer, &_index);
4747 		status=varint.decode(_buffer, &_index);
4748 	}
4749 
4750 	public static pure nothrow @safe ShowCredits fromBuffer(bool readId=true)(ubyte[] buffer) {
4751 		ShowCredits ret = new ShowCredits();
4752 		ret._buffer = buffer;
4753 		ret.decode!readId();
4754 		return ret;
4755 	}
4756 
4757 	public override string toString() {
4758 		return "ShowCredits(entityId: " ~ std.conv.to!string(this.entityId) ~ ", status: " ~ std.conv.to!string(this.status) ~ ")";
4759 	}
4760 
4761 }
4762 
4763 /**
4764  * Sends a list of the commands that the player can use through the CommandStep packet.
4765  */
4766 class AvailableCommands : Buffer {
4767 
4768 	public enum ubyte ID = 77;
4769 
4770 	public enum bool CLIENTBOUND = true;
4771 	public enum bool SERVERBOUND = false;
4772 
4773 	public enum string[] FIELDS = ["commands", "unknown1"];
4774 
4775 	/**
4776 	 * JSON object with the commands.
4777 	 */
4778 	public string commands;
4779 	public string unknown1;
4780 
4781 	public pure nothrow @safe @nogc this() {}
4782 
4783 	public pure nothrow @safe @nogc this(string commands, string unknown1=string.init) {
4784 		this.commands = commands;
4785 		this.unknown1 = unknown1;
4786 	}
4787 
4788 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4789 		_buffer.length = 0;
4790 		static if(writeId){ writeBigEndianUbyte(ID); }
4791 		writeBytes(varuint.encode(cast(uint)commands.length)); writeString(commands);
4792 		writeBytes(varuint.encode(cast(uint)unknown1.length)); writeString(unknown1);
4793 		return _buffer;
4794 	}
4795 
4796 	public pure nothrow @safe void decode(bool readId=true)() {
4797 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4798 		uint y9bfzm=varuint.decode(_buffer, &_index); commands=readString(y9bfzm);
4799 		uint d5b9be=varuint.decode(_buffer, &_index); unknown1=readString(d5b9be);
4800 	}
4801 
4802 	public static pure nothrow @safe AvailableCommands fromBuffer(bool readId=true)(ubyte[] buffer) {
4803 		AvailableCommands ret = new AvailableCommands();
4804 		ret._buffer = buffer;
4805 		ret.decode!readId();
4806 		return ret;
4807 	}
4808 
4809 	public override string toString() {
4810 		return "AvailableCommands(commands: " ~ std.conv.to!string(this.commands) ~ ", unknown1: " ~ std.conv.to!string(this.unknown1) ~ ")";
4811 	}
4812 
4813 }
4814 
4815 class CommandStep : Buffer {
4816 
4817 	public enum ubyte ID = 78;
4818 
4819 	public enum bool CLIENTBOUND = false;
4820 	public enum bool SERVERBOUND = true;
4821 
4822 	public enum string[] FIELDS = ["command", "overload", "unknown2", "currentStep", "done", "clientId", "input", "output"];
4823 
4824 	public string command;
4825 	public string overload;
4826 	public uint unknown2;
4827 	public uint currentStep;
4828 	public bool done;
4829 	public ulong clientId;
4830 	public string input;
4831 	public string output;
4832 
4833 	public pure nothrow @safe @nogc this() {}
4834 
4835 	public pure nothrow @safe @nogc this(string command, string overload=string.init, uint unknown2=uint.init, uint currentStep=uint.init, bool done=bool.init, ulong clientId=ulong.init, string input=string.init, string output=string.init) {
4836 		this.command = command;
4837 		this.overload = overload;
4838 		this.unknown2 = unknown2;
4839 		this.currentStep = currentStep;
4840 		this.done = done;
4841 		this.clientId = clientId;
4842 		this.input = input;
4843 		this.output = output;
4844 	}
4845 
4846 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4847 		_buffer.length = 0;
4848 		static if(writeId){ writeBigEndianUbyte(ID); }
4849 		writeBytes(varuint.encode(cast(uint)command.length)); writeString(command);
4850 		writeBytes(varuint.encode(cast(uint)overload.length)); writeString(overload);
4851 		writeBytes(varuint.encode(unknown2));
4852 		writeBytes(varuint.encode(currentStep));
4853 		writeBigEndianBool(done);
4854 		writeBytes(varulong.encode(clientId));
4855 		writeBytes(varuint.encode(cast(uint)input.length)); writeString(input);
4856 		writeBytes(varuint.encode(cast(uint)output.length)); writeString(output);
4857 		return _buffer;
4858 	}
4859 
4860 	public pure nothrow @safe void decode(bool readId=true)() {
4861 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4862 		uint y9bfz=varuint.decode(_buffer, &_index); command=readString(y9bfz);
4863 		uint bzcxyq=varuint.decode(_buffer, &_index); overload=readString(bzcxyq);
4864 		unknown2=varuint.decode(_buffer, &_index);
4865 		currentStep=varuint.decode(_buffer, &_index);
4866 		done=readBigEndianBool();
4867 		clientId=varulong.decode(_buffer, &_index);
4868 		uint a5dq=varuint.decode(_buffer, &_index); input=readString(a5dq);
4869 		uint bvcv=varuint.decode(_buffer, &_index); output=readString(bvcv);
4870 	}
4871 
4872 	public static pure nothrow @safe CommandStep fromBuffer(bool readId=true)(ubyte[] buffer) {
4873 		CommandStep ret = new CommandStep();
4874 		ret._buffer = buffer;
4875 		ret.decode!readId();
4876 		return ret;
4877 	}
4878 
4879 	public override string toString() {
4880 		return "CommandStep(command: " ~ std.conv.to!string(this.command) ~ ", overload: " ~ std.conv.to!string(this.overload) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ", currentStep: " ~ std.conv.to!string(this.currentStep) ~ ", done: " ~ std.conv.to!string(this.done) ~ ", clientId: " ~ std.conv.to!string(this.clientId) ~ ", input: " ~ std.conv.to!string(this.input) ~ ", output: " ~ std.conv.to!string(this.output) ~ ")";
4881 	}
4882 
4883 }
4884 
4885 class UpdateTrade : Buffer {
4886 
4887 	public enum ubyte ID = 79;
4888 
4889 	public enum bool CLIENTBOUND = true;
4890 	public enum bool SERVERBOUND = false;
4891 
4892 	public enum string[] FIELDS = ["unknown0", "unknown1", "unknown2", "unknown3", "unknown4", "trader", "player", "unknown7", "offers"];
4893 
4894 	public ubyte unknown0;
4895 	public ubyte unknown1;
4896 	public int unknown2;
4897 	public int unknown3;
4898 	public bool unknown4;
4899 	public long trader;
4900 	public long player;
4901 	public string unknown7;
4902 	public ubyte[] offers;
4903 
4904 	public pure nothrow @safe @nogc this() {}
4905 
4906 	public pure nothrow @safe @nogc this(ubyte unknown0, ubyte unknown1=ubyte.init, int unknown2=int.init, int unknown3=int.init, bool unknown4=bool.init, long trader=long.init, long player=long.init, string unknown7=string.init, ubyte[] offers=(ubyte[]).init) {
4907 		this.unknown0 = unknown0;
4908 		this.unknown1 = unknown1;
4909 		this.unknown2 = unknown2;
4910 		this.unknown3 = unknown3;
4911 		this.unknown4 = unknown4;
4912 		this.trader = trader;
4913 		this.player = player;
4914 		this.unknown7 = unknown7;
4915 		this.offers = offers;
4916 	}
4917 
4918 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4919 		_buffer.length = 0;
4920 		static if(writeId){ writeBigEndianUbyte(ID); }
4921 		writeBigEndianUbyte(unknown0);
4922 		writeBigEndianUbyte(unknown1);
4923 		writeBytes(varint.encode(unknown2));
4924 		writeBytes(varint.encode(unknown3));
4925 		writeBigEndianBool(unknown4);
4926 		writeBytes(varlong.encode(trader));
4927 		writeBytes(varlong.encode(player));
4928 		writeBytes(varuint.encode(cast(uint)unknown7.length)); writeString(unknown7);
4929 		writeBytes(offers);
4930 		return _buffer;
4931 	}
4932 
4933 	public pure nothrow @safe void decode(bool readId=true)() {
4934 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4935 		unknown0=readBigEndianUbyte();
4936 		unknown1=readBigEndianUbyte();
4937 		unknown2=varint.decode(_buffer, &_index);
4938 		unknown3=varint.decode(_buffer, &_index);
4939 		unknown4=readBigEndianBool();
4940 		trader=varlong.decode(_buffer, &_index);
4941 		player=varlong.decode(_buffer, &_index);
4942 		uint d5b9bc=varuint.decode(_buffer, &_index); unknown7=readString(d5b9bc);
4943 		offers=_buffer[_index..$].dup; _index=_buffer.length;
4944 	}
4945 
4946 	public static pure nothrow @safe UpdateTrade fromBuffer(bool readId=true)(ubyte[] buffer) {
4947 		UpdateTrade ret = new UpdateTrade();
4948 		ret._buffer = buffer;
4949 		ret.decode!readId();
4950 		return ret;
4951 	}
4952 
4953 	public override string toString() {
4954 		return "UpdateTrade(unknown0: " ~ std.conv.to!string(this.unknown0) ~ ", unknown1: " ~ std.conv.to!string(this.unknown1) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ", unknown3: " ~ std.conv.to!string(this.unknown3) ~ ", unknown4: " ~ std.conv.to!string(this.unknown4) ~ ", trader: " ~ std.conv.to!string(this.trader) ~ ", player: " ~ std.conv.to!string(this.player) ~ ", unknown7: " ~ std.conv.to!string(this.unknown7) ~ ", offers: " ~ std.conv.to!string(this.offers) ~ ")";
4955 	}
4956 
4957 }
4958 
4959 class ResourcePackDataInfo : Buffer {
4960 
4961 	public enum ubyte ID = 80;
4962 
4963 	public enum bool CLIENTBOUND = true;
4964 	public enum bool SERVERBOUND = false;
4965 
4966 	public enum string[] FIELDS = ["id", "maxChunkSize", "chunkCount", "compressedPackSize", "sha256"];
4967 
4968 	public string id;
4969 	public uint maxChunkSize;
4970 	public uint chunkCount;
4971 	public ulong compressedPackSize;
4972 	public string sha256;
4973 
4974 	public pure nothrow @safe @nogc this() {}
4975 
4976 	public pure nothrow @safe @nogc this(string id, uint maxChunkSize=uint.init, uint chunkCount=uint.init, ulong compressedPackSize=ulong.init, string sha256=string.init) {
4977 		this.id = id;
4978 		this.maxChunkSize = maxChunkSize;
4979 		this.chunkCount = chunkCount;
4980 		this.compressedPackSize = compressedPackSize;
4981 		this.sha256 = sha256;
4982 	}
4983 
4984 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4985 		_buffer.length = 0;
4986 		static if(writeId){ writeBigEndianUbyte(ID); }
4987 		writeBytes(varuint.encode(cast(uint)id.length)); writeString(id);
4988 		writeLittleEndianUint(maxChunkSize);
4989 		writeLittleEndianUint(chunkCount);
4990 		writeLittleEndianUlong(compressedPackSize);
4991 		writeBytes(varuint.encode(cast(uint)sha256.length)); writeString(sha256);
4992 		return _buffer;
4993 	}
4994 
4995 	public pure nothrow @safe void decode(bool readId=true)() {
4996 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4997 		uint aq=varuint.decode(_buffer, &_index); id=readString(aq);
4998 		maxChunkSize=readLittleEndianUint();
4999 		chunkCount=readLittleEndianUint();
5000 		compressedPackSize=readLittleEndianUlong();
5001 		uint chmu=varuint.decode(_buffer, &_index); sha256=readString(chmu);
5002 	}
5003 
5004 	public static pure nothrow @safe ResourcePackDataInfo fromBuffer(bool readId=true)(ubyte[] buffer) {
5005 		ResourcePackDataInfo ret = new ResourcePackDataInfo();
5006 		ret._buffer = buffer;
5007 		ret.decode!readId();
5008 		return ret;
5009 	}
5010 
5011 	public override string toString() {
5012 		return "ResourcePackDataInfo(id: " ~ std.conv.to!string(this.id) ~ ", maxChunkSize: " ~ std.conv.to!string(this.maxChunkSize) ~ ", chunkCount: " ~ std.conv.to!string(this.chunkCount) ~ ", compressedPackSize: " ~ std.conv.to!string(this.compressedPackSize) ~ ", sha256: " ~ std.conv.to!string(this.sha256) ~ ")";
5013 	}
5014 
5015 }
5016 
5017 class ResourcePackChunkData : Buffer {
5018 
5019 	public enum ubyte ID = 81;
5020 
5021 	public enum bool CLIENTBOUND = true;
5022 	public enum bool SERVERBOUND = false;
5023 
5024 	public enum string[] FIELDS = ["id", "chunkIndex", "progress", "data"];
5025 
5026 	public string id;
5027 	public uint chunkIndex;
5028 	public ulong progress;
5029 	public ubyte[] data;
5030 
5031 	public pure nothrow @safe @nogc this() {}
5032 
5033 	public pure nothrow @safe @nogc this(string id, uint chunkIndex=uint.init, ulong progress=ulong.init, ubyte[] data=(ubyte[]).init) {
5034 		this.id = id;
5035 		this.chunkIndex = chunkIndex;
5036 		this.progress = progress;
5037 		this.data = data;
5038 	}
5039 
5040 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
5041 		_buffer.length = 0;
5042 		static if(writeId){ writeBigEndianUbyte(ID); }
5043 		writeBytes(varuint.encode(cast(uint)id.length)); writeString(id);
5044 		writeLittleEndianUint(chunkIndex);
5045 		writeLittleEndianUlong(progress);
5046 		writeBytes(varuint.encode(cast(uint)data.length)); writeBytes(data);
5047 		return _buffer;
5048 	}
5049 
5050 	public pure nothrow @safe void decode(bool readId=true)() {
5051 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
5052 		uint aq=varuint.decode(_buffer, &_index); id=readString(aq);
5053 		chunkIndex=readLittleEndianUint();
5054 		progress=readLittleEndianUlong();
5055 		data.length=varuint.decode(_buffer, &_index); if(_buffer.length>=_index+data.length){ data=_buffer[_index.._index+data.length].dup; _index+=data.length; }
5056 	}
5057 
5058 	public static pure nothrow @safe ResourcePackChunkData fromBuffer(bool readId=true)(ubyte[] buffer) {
5059 		ResourcePackChunkData ret = new ResourcePackChunkData();
5060 		ret._buffer = buffer;
5061 		ret.decode!readId();
5062 		return ret;
5063 	}
5064 
5065 	public override string toString() {
5066 		return "ResourcePackChunkData(id: " ~ std.conv.to!string(this.id) ~ ", chunkIndex: " ~ std.conv.to!string(this.chunkIndex) ~ ", progress: " ~ std.conv.to!string(this.progress) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
5067 	}
5068 
5069 }
5070 
5071 class ResourcePackChunkRequest : Buffer {
5072 
5073 	public enum ubyte ID = 82;
5074 
5075 	public enum bool CLIENTBOUND = false;
5076 	public enum bool SERVERBOUND = true;
5077 
5078 	public enum string[] FIELDS = ["id", "chunkIndex"];
5079 
5080 	public string id;
5081 	public uint chunkIndex;
5082 
5083 	public pure nothrow @safe @nogc this() {}
5084 
5085 	public pure nothrow @safe @nogc this(string id, uint chunkIndex=uint.init) {
5086 		this.id = id;
5087 		this.chunkIndex = chunkIndex;
5088 	}
5089 
5090 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
5091 		_buffer.length = 0;
5092 		static if(writeId){ writeBigEndianUbyte(ID); }
5093 		writeBytes(varuint.encode(cast(uint)id.length)); writeString(id);
5094 		writeLittleEndianUint(chunkIndex);
5095 		return _buffer;
5096 	}
5097 
5098 	public pure nothrow @safe void decode(bool readId=true)() {
5099 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
5100 		uint aq=varuint.decode(_buffer, &_index); id=readString(aq);
5101 		chunkIndex=readLittleEndianUint();
5102 	}
5103 
5104 	public static pure nothrow @safe ResourcePackChunkRequest fromBuffer(bool readId=true)(ubyte[] buffer) {
5105 		ResourcePackChunkRequest ret = new ResourcePackChunkRequest();
5106 		ret._buffer = buffer;
5107 		ret.decode!readId();
5108 		return ret;
5109 	}
5110 
5111 	public override string toString() {
5112 		return "ResourcePackChunkRequest(id: " ~ std.conv.to!string(this.id) ~ ", chunkIndex: " ~ std.conv.to!string(this.chunkIndex) ~ ")";
5113 	}
5114 
5115 }
5116 
5117 /**
5118  * Transfers the player to another server. Once transferred the player will immediately
5119  * close the connection with the transferring server, try to resolve the ip and join
5120  * the new server starting a new raknet session.
5121  */
5122 class Transfer : Buffer {
5123 
5124 	public enum ubyte ID = 83;
5125 
5126 	public enum bool CLIENTBOUND = true;
5127 	public enum bool SERVERBOUND = false;
5128 
5129 	public enum string[] FIELDS = ["ip", "port"];
5130 
5131 	/**
5132 	 * Address of the new server. It can be an dotted ip (for example `127.0.0.1`) or an
5133 	 * URI (for example `localhost` or `play.example.com`). Only IP of version 4 are currently
5134 	 * allowed.
5135 	 */
5136 	public string ip;
5137 
5138 	/**
5139 	 * Port of the new server. If 0 the server will try to connect to the default port.
5140 	 */
5141 	public ushort port = 19132;
5142 
5143 	public pure nothrow @safe @nogc this() {}
5144 
5145 	public pure nothrow @safe @nogc this(string ip, ushort port=19132) {
5146 		this.ip = ip;
5147 		this.port = port;
5148 	}
5149 
5150 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
5151 		_buffer.length = 0;
5152 		static if(writeId){ writeBigEndianUbyte(ID); }
5153 		writeBytes(varuint.encode(cast(uint)ip.length)); writeString(ip);
5154 		writeLittleEndianUshort(port);
5155 		return _buffer;
5156 	}
5157 
5158 	public pure nothrow @safe void decode(bool readId=true)() {
5159 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
5160 		uint aa=varuint.decode(_buffer, &_index); ip=readString(aa);
5161 		port=readLittleEndianUshort();
5162 	}
5163 
5164 	public static pure nothrow @safe Transfer fromBuffer(bool readId=true)(ubyte[] buffer) {
5165 		Transfer ret = new Transfer();
5166 		ret._buffer = buffer;
5167 		ret.decode!readId();
5168 		return ret;
5169 	}
5170 
5171 	public override string toString() {
5172 		return "Transfer(ip: " ~ std.conv.to!string(this.ip) ~ ", port: " ~ std.conv.to!string(this.port) ~ ")";
5173 	}
5174 
5175 }
5176