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/pocket101.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.pocket101.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.pocket101.types;
27 
28 static if(__traits(compiles, { import sul.metadata.pocket101; })) import sul.metadata.pocket101;
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, 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.pocket101.types.PackWithSize[] behaviourPacks;
377 	public sul.protocol.pocket101.types.PackWithSize[] resourcePacks;
378 
379 	public pure nothrow @safe @nogc this() {}
380 
381 	public pure nothrow @safe @nogc this(bool mustAccept, sul.protocol.pocket101.types.PackWithSize[] behaviourPacks=(sul.protocol.pocket101.types.PackWithSize[]).init, sul.protocol.pocket101.types.PackWithSize[] resourcePacks=(sul.protocol.pocket101.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.pocket101.types.Pack[] behaviourPacks;
427 	public sul.protocol.pocket101.types.Pack[] resourcePacks;
428 
429 	public pure nothrow @safe @nogc this() {}
430 
431 	public pure nothrow @safe @nogc this(bool mustAccept, sul.protocol.pocket101.types.Pack[] behaviourPacks=(sul.protocol.pocket101.types.Pack[]).init, sul.protocol.pocket101.types.Pack[] resourcePacks=(sul.protocol.pocket101.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.pocket101.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.pocket101.types.Slot heldItem=sul.protocol.pocket101.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.pocket101.types.Attribute[] attributes;
1218 	public Metadata metadata;
1219 	public sul.protocol.pocket101.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.pocket101.types.Attribute[] attributes=(sul.protocol.pocket101.types.Attribute[]).init, Metadata metadata=Metadata.init, sul.protocol.pocket101.types.Link[] links=(sul.protocol.pocket101.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.pocket101.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.pocket101.types.Slot item=sul.protocol.pocket101.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.pocket101.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.pocket101.types.BlockPosition position=sul.protocol.pocket101.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.pocket101.types.BlockPosition position;
1681 
1682 	public pure nothrow @safe @nogc this() {}
1683 
1684 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.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.pocket101.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.pocket101.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.pocket101.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.pocket101.types.BlockPosition position=sul.protocol.pocket101.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.pocket101.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.pocket101.types.BlockPosition[] destroyedBlocks=(sul.protocol.pocket101.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 DEFAULT = 90;
1982 	public enum ubyte UNDEFINED = 91;
1983 
1984 	public enum string[] FIELDS = ["sound", "position", "volume", "pitch", "unknown4"];
1985 
1986 	public ubyte sound;
1987 
1988 	/**
1989 	 * Position where the sound was generated. The closer to the player the more intense
1990 	 * will be on the client.
1991 	 */
1992 	public Tuple!(float, "x", float, "y", float, "z") position;
1993 	public uint volume;
1994 	public int pitch;
1995 	public bool unknown4;
1996 
1997 	public pure nothrow @safe @nogc this() {}
1998 
1999 	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) {
2000 		this.sound = sound;
2001 		this.position = position;
2002 		this.volume = volume;
2003 		this.pitch = pitch;
2004 		this.unknown4 = unknown4;
2005 	}
2006 
2007 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2008 		_buffer.length = 0;
2009 		static if(writeId){ writeBigEndianUbyte(ID); }
2010 		writeBigEndianUbyte(sound);
2011 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
2012 		writeBytes(varuint.encode(volume));
2013 		writeBytes(varint.encode(pitch));
2014 		writeBigEndianBool(unknown4);
2015 		return _buffer;
2016 	}
2017 
2018 	public pure nothrow @safe void decode(bool readId=true)() {
2019 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2020 		sound=readBigEndianUbyte();
2021 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
2022 		volume=varuint.decode(_buffer, &_index);
2023 		pitch=varint.decode(_buffer, &_index);
2024 		unknown4=readBigEndianBool();
2025 	}
2026 
2027 	public static pure nothrow @safe LevelSoundEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
2028 		LevelSoundEvent ret = new LevelSoundEvent();
2029 		ret._buffer = buffer;
2030 		ret.decode!readId();
2031 		return ret;
2032 	}
2033 
2034 	public override string toString() {
2035 		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) ~ ")";
2036 	}
2037 
2038 }
2039 
2040 class LevelEvent : Buffer {
2041 
2042 	public enum ubyte ID = 27;
2043 
2044 	public enum bool CLIENTBOUND = true;
2045 	public enum bool SERVERBOUND = false;
2046 
2047 	// event id
2048 	public enum int START_RAIN = 3001;
2049 	public enum int START_THUNDER = 3002;
2050 	public enum int STOP_RAIN = 3003;
2051 	public enum int STOP_THUNDER = 3004;
2052 	public enum int SET_DATA = 4000;
2053 	public enum int PLAYERS_SLEEPING = 9800;
2054 	public enum int BUBBLE = 16385;
2055 	public enum int CRITICAL = 16386;
2056 	public enum int BLOCK_FORCE_FIELD = 16387;
2057 	public enum int SMOKE = 16388;
2058 	public enum int EXPLODE = 16389;
2059 	public enum int EVAPORATION = 16390;
2060 	public enum int FLAME = 16391;
2061 	public enum int LAVA = 16392;
2062 	public enum int LARGE_SMOKE = 16393;
2063 	public enum int REDSTONE = 16394;
2064 	public enum int RISING_RED_DUST = 16395;
2065 	public enum int ITEM_BREAK = 16396;
2066 	public enum int SNOWBALL_POOF = 16397;
2067 	public enum int HUGE_EXPLODE = 16398;
2068 	public enum int HUGE_EXPLODE_SEED = 16399;
2069 	public enum int MOB_FLAME = 16400;
2070 	public enum int HEART = 16401;
2071 	public enum int TERRAIN = 16402;
2072 	public enum int TOWN_AURA = 16403;
2073 	public enum int PORTAL = 16404;
2074 	public enum int WATER_SPLASH = 16405;
2075 	public enum int WATER_WAKE = 16406;
2076 	public enum int DRIP_WATER = 16407;
2077 	public enum int DRIP_LAVA = 16408;
2078 	public enum int FALLING_DUST = 16409;
2079 	public enum int MOB_SPELL = 16410;
2080 	public enum int MOB_SPELL_AMBIENT = 16411;
2081 	public enum int MOB_SPELL_INSTANTANEOUS = 16412;
2082 	public enum int INK = 16413;
2083 	public enum int SLIME = 16414;
2084 	public enum int RAIN_SPLASH = 16415;
2085 	public enum int VILLAGER_ANGRY = 16416;
2086 	public enum int VILLAGER_HAPPY = 16417;
2087 	public enum int ENCHANTMENT_TABLE = 16418;
2088 	public enum int TRACKING_EMITTER = 16419;
2089 	public enum int NOTE = 16420;
2090 	public enum int WITCH_SPELL = 16421;
2091 	public enum int CARROT = 16422;
2092 	public enum int END_ROD = 16424;
2093 	public enum int DRAGON_BREATH = 16425;
2094 	public enum int SHOOT = 2000;
2095 	public enum int DESTROY = 2001;
2096 
2097 	public enum string[] FIELDS = ["eventId", "position", "data"];
2098 
2099 	public int eventId;
2100 	public Tuple!(float, "x", float, "y", float, "z") position;
2101 	public int data;
2102 
2103 	public pure nothrow @safe @nogc this() {}
2104 
2105 	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) {
2106 		this.eventId = eventId;
2107 		this.position = position;
2108 		this.data = data;
2109 	}
2110 
2111 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2112 		_buffer.length = 0;
2113 		static if(writeId){ writeBigEndianUbyte(ID); }
2114 		writeBytes(varint.encode(eventId));
2115 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
2116 		writeBytes(varint.encode(data));
2117 		return _buffer;
2118 	}
2119 
2120 	public pure nothrow @safe void decode(bool readId=true)() {
2121 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2122 		eventId=varint.decode(_buffer, &_index);
2123 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
2124 		data=varint.decode(_buffer, &_index);
2125 	}
2126 
2127 	public static pure nothrow @safe LevelEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
2128 		LevelEvent ret = new LevelEvent();
2129 		ret._buffer = buffer;
2130 		ret.decode!readId();
2131 		return ret;
2132 	}
2133 
2134 	public override string toString() {
2135 		return "LevelEvent(eventId: " ~ std.conv.to!string(this.eventId) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
2136 	}
2137 
2138 }
2139 
2140 class BlockEvent : Buffer {
2141 
2142 	public enum ubyte ID = 28;
2143 
2144 	public enum bool CLIENTBOUND = true;
2145 	public enum bool SERVERBOUND = false;
2146 
2147 	public enum string[] FIELDS = ["position", "data"];
2148 
2149 	public sul.protocol.pocket101.types.BlockPosition position;
2150 	public int[2] data;
2151 
2152 	public pure nothrow @safe @nogc this() {}
2153 
2154 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.types.BlockPosition position, int[2] data=(int[2]).init) {
2155 		this.position = position;
2156 		this.data = data;
2157 	}
2158 
2159 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2160 		_buffer.length = 0;
2161 		static if(writeId){ writeBigEndianUbyte(ID); }
2162 		position.encode(bufferInstance);
2163 		foreach(zfy;data){ writeBytes(varint.encode(zfy)); }
2164 		return _buffer;
2165 	}
2166 
2167 	public pure nothrow @safe void decode(bool readId=true)() {
2168 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2169 		position.decode(bufferInstance);
2170 		foreach(ref zfy;data){ zfy=varint.decode(_buffer, &_index); }
2171 	}
2172 
2173 	public static pure nothrow @safe BlockEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
2174 		BlockEvent ret = new BlockEvent();
2175 		ret._buffer = buffer;
2176 		ret.decode!readId();
2177 		return ret;
2178 	}
2179 
2180 	public override string toString() {
2181 		return "BlockEvent(position: " ~ std.conv.to!string(this.position) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
2182 	}
2183 
2184 }
2185 
2186 class EntityEvent : Buffer {
2187 
2188 	public enum ubyte ID = 29;
2189 
2190 	public enum bool CLIENTBOUND = true;
2191 	public enum bool SERVERBOUND = true;
2192 
2193 	// event id
2194 	public enum ubyte HURT_ANIMATION = 2;
2195 	public enum ubyte DEATH_ANIMATION = 3;
2196 	public enum ubyte TAME_FAIL = 6;
2197 	public enum ubyte TAME_SUCCESS = 7;
2198 	public enum ubyte SHAKE_WET = 8;
2199 	public enum ubyte USE_ITEM = 9;
2200 	public enum ubyte EAT_GRASS_ANIMATION = 10;
2201 	public enum ubyte FISH_HOOK_BUBBLES = 11;
2202 	public enum ubyte FISH_HOOK_POSITION = 12;
2203 	public enum ubyte FISH_HOOK_HOOK = 13;
2204 	public enum ubyte FISH_HOOK_TEASE = 14;
2205 	public enum ubyte SQUID_INK_CLOUD = 15;
2206 	public enum ubyte AMBIENT_SOUND = 16;
2207 	public enum ubyte RESPAWN = 17;
2208 
2209 	public enum string[] FIELDS = ["entityId", "eventId", "unknown2"];
2210 
2211 	public long entityId;
2212 	public ubyte eventId;
2213 	public int unknown2;
2214 
2215 	public pure nothrow @safe @nogc this() {}
2216 
2217 	public pure nothrow @safe @nogc this(long entityId, ubyte eventId=ubyte.init, int unknown2=int.init) {
2218 		this.entityId = entityId;
2219 		this.eventId = eventId;
2220 		this.unknown2 = unknown2;
2221 	}
2222 
2223 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2224 		_buffer.length = 0;
2225 		static if(writeId){ writeBigEndianUbyte(ID); }
2226 		writeBytes(varlong.encode(entityId));
2227 		writeBigEndianUbyte(eventId);
2228 		writeBytes(varint.encode(unknown2));
2229 		return _buffer;
2230 	}
2231 
2232 	public pure nothrow @safe void decode(bool readId=true)() {
2233 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2234 		entityId=varlong.decode(_buffer, &_index);
2235 		eventId=readBigEndianUbyte();
2236 		unknown2=varint.decode(_buffer, &_index);
2237 	}
2238 
2239 	public static pure nothrow @safe EntityEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
2240 		EntityEvent ret = new EntityEvent();
2241 		ret._buffer = buffer;
2242 		ret.decode!readId();
2243 		return ret;
2244 	}
2245 
2246 	public override string toString() {
2247 		return "EntityEvent(entityId: " ~ std.conv.to!string(this.entityId) ~ ", eventId: " ~ std.conv.to!string(this.eventId) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
2248 	}
2249 
2250 }
2251 
2252 class MobEffect : Buffer {
2253 
2254 	public enum ubyte ID = 30;
2255 
2256 	public enum bool CLIENTBOUND = true;
2257 	public enum bool SERVERBOUND = false;
2258 
2259 	// event id
2260 	public enum ubyte ADD = 1;
2261 	public enum ubyte MODIFY = 2;
2262 	public enum ubyte REMOVE = 3;
2263 
2264 	public enum string[] FIELDS = ["entityId", "eventId", "effect", "amplifier", "particles", "duration"];
2265 
2266 	public long entityId;
2267 	public ubyte eventId;
2268 	public int effect;
2269 	public int amplifier;
2270 	public bool particles;
2271 	public int duration;
2272 
2273 	public pure nothrow @safe @nogc this() {}
2274 
2275 	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) {
2276 		this.entityId = entityId;
2277 		this.eventId = eventId;
2278 		this.effect = effect;
2279 		this.amplifier = amplifier;
2280 		this.particles = particles;
2281 		this.duration = duration;
2282 	}
2283 
2284 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2285 		_buffer.length = 0;
2286 		static if(writeId){ writeBigEndianUbyte(ID); }
2287 		writeBytes(varlong.encode(entityId));
2288 		writeBigEndianUbyte(eventId);
2289 		writeBytes(varint.encode(effect));
2290 		writeBytes(varint.encode(amplifier));
2291 		writeBigEndianBool(particles);
2292 		writeBytes(varint.encode(duration));
2293 		return _buffer;
2294 	}
2295 
2296 	public pure nothrow @safe void decode(bool readId=true)() {
2297 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2298 		entityId=varlong.decode(_buffer, &_index);
2299 		eventId=readBigEndianUbyte();
2300 		effect=varint.decode(_buffer, &_index);
2301 		amplifier=varint.decode(_buffer, &_index);
2302 		particles=readBigEndianBool();
2303 		duration=varint.decode(_buffer, &_index);
2304 	}
2305 
2306 	public static pure nothrow @safe MobEffect fromBuffer(bool readId=true)(ubyte[] buffer) {
2307 		MobEffect ret = new MobEffect();
2308 		ret._buffer = buffer;
2309 		ret.decode!readId();
2310 		return ret;
2311 	}
2312 
2313 	public override string toString() {
2314 		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) ~ ")";
2315 	}
2316 
2317 }
2318 
2319 /**
2320  * Updates an entity's attributes. This packet should be used when a value must be
2321  * modified but it cannot be done using another packet (for example controlling the
2322  * player's experience and level).
2323  */
2324 class UpdateAttributes : Buffer {
2325 
2326 	public enum ubyte ID = 31;
2327 
2328 	public enum bool CLIENTBOUND = true;
2329 	public enum bool SERVERBOUND = false;
2330 
2331 	public enum string[] FIELDS = ["entityId", "attributes"];
2332 
2333 	public long entityId;
2334 	public sul.protocol.pocket101.types.Attribute[] attributes;
2335 
2336 	public pure nothrow @safe @nogc this() {}
2337 
2338 	public pure nothrow @safe @nogc this(long entityId, sul.protocol.pocket101.types.Attribute[] attributes=(sul.protocol.pocket101.types.Attribute[]).init) {
2339 		this.entityId = entityId;
2340 		this.attributes = attributes;
2341 	}
2342 
2343 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2344 		_buffer.length = 0;
2345 		static if(writeId){ writeBigEndianUbyte(ID); }
2346 		writeBytes(varlong.encode(entityId));
2347 		writeBytes(varuint.encode(cast(uint)attributes.length)); foreach(yrcldrc;attributes){ yrcldrc.encode(bufferInstance); }
2348 		return _buffer;
2349 	}
2350 
2351 	public pure nothrow @safe void decode(bool readId=true)() {
2352 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2353 		entityId=varlong.decode(_buffer, &_index);
2354 		attributes.length=varuint.decode(_buffer, &_index); foreach(ref yrcldrc;attributes){ yrcldrc.decode(bufferInstance); }
2355 	}
2356 
2357 	public static pure nothrow @safe UpdateAttributes fromBuffer(bool readId=true)(ubyte[] buffer) {
2358 		UpdateAttributes ret = new UpdateAttributes();
2359 		ret._buffer = buffer;
2360 		ret.decode!readId();
2361 		return ret;
2362 	}
2363 
2364 	public override string toString() {
2365 		return "UpdateAttributes(entityId: " ~ std.conv.to!string(this.entityId) ~ ", attributes: " ~ std.conv.to!string(this.attributes) ~ ")";
2366 	}
2367 
2368 }
2369 
2370 /**
2371  * Sent when the client puts an item in its hotbar or selects a new hotbar slot.
2372  */
2373 class MobEquipment : Buffer {
2374 
2375 	public enum ubyte ID = 32;
2376 
2377 	public enum bool CLIENTBOUND = true;
2378 	public enum bool SERVERBOUND = true;
2379 
2380 	public enum string[] FIELDS = ["entityId", "item", "inventorySlot", "hotbarSlot", "unknown4"];
2381 
2382 	public long entityId;
2383 	public sul.protocol.pocket101.types.Slot item;
2384 
2385 	/**
2386 	 * Slot of the inventory where the item is. The hotbat slots (0-8) are not counted.
2387 	 * 255 means that a generic empty slot has been selected.
2388 	 */
2389 	public ubyte inventorySlot;
2390 
2391 	/**
2392 	 * Slot of the hotbar where the item is being moved.
2393 	 */
2394 	public ubyte hotbarSlot;
2395 	public ubyte unknown4;
2396 
2397 	public pure nothrow @safe @nogc this() {}
2398 
2399 	public pure nothrow @safe @nogc this(long entityId, sul.protocol.pocket101.types.Slot item=sul.protocol.pocket101.types.Slot.init, ubyte inventorySlot=ubyte.init, ubyte hotbarSlot=ubyte.init, ubyte unknown4=ubyte.init) {
2400 		this.entityId = entityId;
2401 		this.item = item;
2402 		this.inventorySlot = inventorySlot;
2403 		this.hotbarSlot = hotbarSlot;
2404 		this.unknown4 = unknown4;
2405 	}
2406 
2407 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2408 		_buffer.length = 0;
2409 		static if(writeId){ writeBigEndianUbyte(ID); }
2410 		writeBytes(varlong.encode(entityId));
2411 		item.encode(bufferInstance);
2412 		writeBigEndianUbyte(inventorySlot);
2413 		writeBigEndianUbyte(hotbarSlot);
2414 		writeBigEndianUbyte(unknown4);
2415 		return _buffer;
2416 	}
2417 
2418 	public pure nothrow @safe void decode(bool readId=true)() {
2419 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2420 		entityId=varlong.decode(_buffer, &_index);
2421 		item.decode(bufferInstance);
2422 		inventorySlot=readBigEndianUbyte();
2423 		hotbarSlot=readBigEndianUbyte();
2424 		unknown4=readBigEndianUbyte();
2425 	}
2426 
2427 	public static pure nothrow @safe MobEquipment fromBuffer(bool readId=true)(ubyte[] buffer) {
2428 		MobEquipment ret = new MobEquipment();
2429 		ret._buffer = buffer;
2430 		ret.decode!readId();
2431 		return ret;
2432 	}
2433 
2434 	public override string toString() {
2435 		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) ~ ")";
2436 	}
2437 
2438 }
2439 
2440 class MobArmorEquipment : Buffer {
2441 
2442 	public enum ubyte ID = 33;
2443 
2444 	public enum bool CLIENTBOUND = true;
2445 	public enum bool SERVERBOUND = true;
2446 
2447 	public enum string[] FIELDS = ["entityId", "armor"];
2448 
2449 	public long entityId;
2450 	public sul.protocol.pocket101.types.Slot[4] armor;
2451 
2452 	public pure nothrow @safe @nogc this() {}
2453 
2454 	public pure nothrow @safe @nogc this(long entityId, sul.protocol.pocket101.types.Slot[4] armor=(sul.protocol.pocket101.types.Slot[4]).init) {
2455 		this.entityId = entityId;
2456 		this.armor = armor;
2457 	}
2458 
2459 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2460 		_buffer.length = 0;
2461 		static if(writeId){ writeBigEndianUbyte(ID); }
2462 		writeBytes(varlong.encode(entityId));
2463 		foreach(yjbi;armor){ yjbi.encode(bufferInstance); }
2464 		return _buffer;
2465 	}
2466 
2467 	public pure nothrow @safe void decode(bool readId=true)() {
2468 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2469 		entityId=varlong.decode(_buffer, &_index);
2470 		foreach(ref yjbi;armor){ yjbi.decode(bufferInstance); }
2471 	}
2472 
2473 	public static pure nothrow @safe MobArmorEquipment fromBuffer(bool readId=true)(ubyte[] buffer) {
2474 		MobArmorEquipment ret = new MobArmorEquipment();
2475 		ret._buffer = buffer;
2476 		ret.decode!readId();
2477 		return ret;
2478 	}
2479 
2480 	public override string toString() {
2481 		return "MobArmorEquipment(entityId: " ~ std.conv.to!string(this.entityId) ~ ", armor: " ~ std.conv.to!string(this.armor) ~ ")";
2482 	}
2483 
2484 }
2485 
2486 class Interact : Buffer {
2487 
2488 	public enum ubyte ID = 34;
2489 
2490 	public enum bool CLIENTBOUND = false;
2491 	public enum bool SERVERBOUND = true;
2492 
2493 	// action
2494 	public enum ubyte ATTACK = 1;
2495 	public enum ubyte INTERACT = 2;
2496 	public enum ubyte LEAVE_VEHICLE = 3;
2497 	public enum ubyte HOVER = 4;
2498 
2499 	public enum string[] FIELDS = ["action", "target"];
2500 
2501 	public ubyte action;
2502 	public long target;
2503 
2504 	public pure nothrow @safe @nogc this() {}
2505 
2506 	public pure nothrow @safe @nogc this(ubyte action, long target=long.init) {
2507 		this.action = action;
2508 		this.target = target;
2509 	}
2510 
2511 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2512 		_buffer.length = 0;
2513 		static if(writeId){ writeBigEndianUbyte(ID); }
2514 		writeBigEndianUbyte(action);
2515 		writeBytes(varlong.encode(target));
2516 		return _buffer;
2517 	}
2518 
2519 	public pure nothrow @safe void decode(bool readId=true)() {
2520 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2521 		action=readBigEndianUbyte();
2522 		target=varlong.decode(_buffer, &_index);
2523 	}
2524 
2525 	public static pure nothrow @safe Interact fromBuffer(bool readId=true)(ubyte[] buffer) {
2526 		Interact ret = new Interact();
2527 		ret._buffer = buffer;
2528 		ret.decode!readId();
2529 		return ret;
2530 	}
2531 
2532 	public override string toString() {
2533 		return "Interact(action: " ~ std.conv.to!string(this.action) ~ ", target: " ~ std.conv.to!string(this.target) ~ ")";
2534 	}
2535 
2536 }
2537 
2538 class UseItem : Buffer {
2539 
2540 	public enum ubyte ID = 35;
2541 
2542 	public enum bool CLIENTBOUND = false;
2543 	public enum bool SERVERBOUND = true;
2544 
2545 	public enum string[] FIELDS = ["blockPosition", "hotbarSlot", "face", "facePosition", "position", "slot", "item"];
2546 
2547 	public sul.protocol.pocket101.types.BlockPosition blockPosition;
2548 	public uint hotbarSlot;
2549 	public int face;
2550 	public Tuple!(float, "x", float, "y", float, "z") facePosition;
2551 	public Tuple!(float, "x", float, "y", float, "z") position;
2552 	public int slot;
2553 	public sul.protocol.pocket101.types.Slot item;
2554 
2555 	public pure nothrow @safe @nogc this() {}
2556 
2557 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.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.pocket101.types.Slot item=sul.protocol.pocket101.types.Slot.init) {
2558 		this.blockPosition = blockPosition;
2559 		this.hotbarSlot = hotbarSlot;
2560 		this.face = face;
2561 		this.facePosition = facePosition;
2562 		this.position = position;
2563 		this.slot = slot;
2564 		this.item = item;
2565 	}
2566 
2567 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2568 		_buffer.length = 0;
2569 		static if(writeId){ writeBigEndianUbyte(ID); }
2570 		blockPosition.encode(bufferInstance);
2571 		writeBytes(varuint.encode(hotbarSlot));
2572 		writeBytes(varint.encode(face));
2573 		writeLittleEndianFloat(facePosition.x); writeLittleEndianFloat(facePosition.y); writeLittleEndianFloat(facePosition.z);
2574 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
2575 		writeBytes(varint.encode(slot));
2576 		item.encode(bufferInstance);
2577 		return _buffer;
2578 	}
2579 
2580 	public pure nothrow @safe void decode(bool readId=true)() {
2581 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2582 		blockPosition.decode(bufferInstance);
2583 		hotbarSlot=varuint.decode(_buffer, &_index);
2584 		face=varint.decode(_buffer, &_index);
2585 		facePosition.x=readLittleEndianFloat(); facePosition.y=readLittleEndianFloat(); facePosition.z=readLittleEndianFloat();
2586 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
2587 		slot=varint.decode(_buffer, &_index);
2588 		item.decode(bufferInstance);
2589 	}
2590 
2591 	public static pure nothrow @safe UseItem fromBuffer(bool readId=true)(ubyte[] buffer) {
2592 		UseItem ret = new UseItem();
2593 		ret._buffer = buffer;
2594 		ret.decode!readId();
2595 		return ret;
2596 	}
2597 
2598 	public override string toString() {
2599 		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) ~ ")";
2600 	}
2601 
2602 }
2603 
2604 class PlayerAction : Buffer {
2605 
2606 	public enum ubyte ID = 36;
2607 
2608 	public enum bool CLIENTBOUND = false;
2609 	public enum bool SERVERBOUND = true;
2610 
2611 	// action
2612 	public enum int START_BREAK = 0;
2613 	public enum int ABORT_BREAK = 1;
2614 	public enum int STOP_BREAK = 2;
2615 	public enum int RELEASE_ITEM = 5;
2616 	public enum int STOP_SLEEPING = 6;
2617 	public enum int RESPAWN = 7;
2618 	public enum int JUMP = 8;
2619 	public enum int START_SPRINT = 9;
2620 	public enum int STOP_SPRINT = 10;
2621 	public enum int START_SNEAK = 11;
2622 	public enum int STOP_SNEAK = 12;
2623 	public enum int START_GLIDING = 15;
2624 	public enum int STOP_GLIDING = 16;
2625 
2626 	public enum string[] FIELDS = ["entityId", "action", "position", "face"];
2627 
2628 	public long entityId;
2629 	public int action;
2630 	public sul.protocol.pocket101.types.BlockPosition position;
2631 	public int face;
2632 
2633 	public pure nothrow @safe @nogc this() {}
2634 
2635 	public pure nothrow @safe @nogc this(long entityId, int action=int.init, sul.protocol.pocket101.types.BlockPosition position=sul.protocol.pocket101.types.BlockPosition.init, int face=int.init) {
2636 		this.entityId = entityId;
2637 		this.action = action;
2638 		this.position = position;
2639 		this.face = face;
2640 	}
2641 
2642 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2643 		_buffer.length = 0;
2644 		static if(writeId){ writeBigEndianUbyte(ID); }
2645 		writeBytes(varlong.encode(entityId));
2646 		writeBytes(varint.encode(action));
2647 		position.encode(bufferInstance);
2648 		writeBytes(varint.encode(face));
2649 		return _buffer;
2650 	}
2651 
2652 	public pure nothrow @safe void decode(bool readId=true)() {
2653 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2654 		entityId=varlong.decode(_buffer, &_index);
2655 		action=varint.decode(_buffer, &_index);
2656 		position.decode(bufferInstance);
2657 		face=varint.decode(_buffer, &_index);
2658 	}
2659 
2660 	public static pure nothrow @safe PlayerAction fromBuffer(bool readId=true)(ubyte[] buffer) {
2661 		PlayerAction ret = new PlayerAction();
2662 		ret._buffer = buffer;
2663 		ret.decode!readId();
2664 		return ret;
2665 	}
2666 
2667 	public override string toString() {
2668 		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) ~ ")";
2669 	}
2670 
2671 }
2672 
2673 /**
2674  * Sent by the player when it falls from a distance that causes damage, that can be
2675  * influenced by its armour and its effects.
2676  */
2677 class PlayerFall : Buffer {
2678 
2679 	public enum ubyte ID = 37;
2680 
2681 	public enum bool CLIENTBOUND = false;
2682 	public enum bool SERVERBOUND = true;
2683 
2684 	public enum string[] FIELDS = ["distance"];
2685 
2686 	/**
2687 	 * Number of blocks the player has been in free falling before hitting the ground.
2688 	 */
2689 	public float distance;
2690 
2691 	public pure nothrow @safe @nogc this() {}
2692 
2693 	public pure nothrow @safe @nogc this(float distance) {
2694 		this.distance = distance;
2695 	}
2696 
2697 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2698 		_buffer.length = 0;
2699 		static if(writeId){ writeBigEndianUbyte(ID); }
2700 		writeLittleEndianFloat(distance);
2701 		return _buffer;
2702 	}
2703 
2704 	public pure nothrow @safe void decode(bool readId=true)() {
2705 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2706 		distance=readLittleEndianFloat();
2707 	}
2708 
2709 	public static pure nothrow @safe PlayerFall fromBuffer(bool readId=true)(ubyte[] buffer) {
2710 		PlayerFall ret = new PlayerFall();
2711 		ret._buffer = buffer;
2712 		ret.decode!readId();
2713 		return ret;
2714 	}
2715 
2716 	public override string toString() {
2717 		return "PlayerFall(distance: " ~ std.conv.to!string(this.distance) ~ ")";
2718 	}
2719 
2720 }
2721 
2722 class HurtArmor : Buffer {
2723 
2724 	public enum ubyte ID = 38;
2725 
2726 	public enum bool CLIENTBOUND = true;
2727 	public enum bool SERVERBOUND = false;
2728 
2729 	public enum string[] FIELDS = ["unknown0"];
2730 
2731 	public int unknown0;
2732 
2733 	public pure nothrow @safe @nogc this() {}
2734 
2735 	public pure nothrow @safe @nogc this(int unknown0) {
2736 		this.unknown0 = unknown0;
2737 	}
2738 
2739 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2740 		_buffer.length = 0;
2741 		static if(writeId){ writeBigEndianUbyte(ID); }
2742 		writeBytes(varint.encode(unknown0));
2743 		return _buffer;
2744 	}
2745 
2746 	public pure nothrow @safe void decode(bool readId=true)() {
2747 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2748 		unknown0=varint.decode(_buffer, &_index);
2749 	}
2750 
2751 	public static pure nothrow @safe HurtArmor fromBuffer(bool readId=true)(ubyte[] buffer) {
2752 		HurtArmor ret = new HurtArmor();
2753 		ret._buffer = buffer;
2754 		ret.decode!readId();
2755 		return ret;
2756 	}
2757 
2758 	public override string toString() {
2759 		return "HurtArmor(unknown0: " ~ std.conv.to!string(this.unknown0) ~ ")";
2760 	}
2761 
2762 }
2763 
2764 /**
2765  * Updates an entity's metadata.
2766  */
2767 class SetEntityData : Buffer {
2768 
2769 	public enum ubyte ID = 39;
2770 
2771 	public enum bool CLIENTBOUND = true;
2772 	public enum bool SERVERBOUND = false;
2773 
2774 	public enum string[] FIELDS = ["entityId", "metadata"];
2775 
2776 	public long entityId;
2777 	public Metadata metadata;
2778 
2779 	public pure nothrow @safe @nogc this() {}
2780 
2781 	public pure nothrow @safe @nogc this(long entityId, Metadata metadata=Metadata.init) {
2782 		this.entityId = entityId;
2783 		this.metadata = metadata;
2784 	}
2785 
2786 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2787 		_buffer.length = 0;
2788 		static if(writeId){ writeBigEndianUbyte(ID); }
2789 		writeBytes(varlong.encode(entityId));
2790 		metadata.encode(bufferInstance);
2791 		return _buffer;
2792 	}
2793 
2794 	public pure nothrow @safe void decode(bool readId=true)() {
2795 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2796 		entityId=varlong.decode(_buffer, &_index);
2797 		metadata=Metadata.decode(bufferInstance);
2798 	}
2799 
2800 	public static pure nothrow @safe SetEntityData fromBuffer(bool readId=true)(ubyte[] buffer) {
2801 		SetEntityData ret = new SetEntityData();
2802 		ret._buffer = buffer;
2803 		ret.decode!readId();
2804 		return ret;
2805 	}
2806 
2807 	public override string toString() {
2808 		return "SetEntityData(entityId: " ~ std.conv.to!string(this.entityId) ~ ", metadata: " ~ std.conv.to!string(this.metadata) ~ ")";
2809 	}
2810 
2811 }
2812 
2813 /**
2814  * Updates an entity's motion.
2815  */
2816 class SetEntityMotion : Buffer {
2817 
2818 	public enum ubyte ID = 40;
2819 
2820 	public enum bool CLIENTBOUND = true;
2821 	public enum bool SERVERBOUND = false;
2822 
2823 	public enum string[] FIELDS = ["entityId", "motion"];
2824 
2825 	/**
2826 	 * Entity which motion is updated. If the entity id is the player's, its motion is
2827 	 * updated client-side and the player will send movement packets to the server (meaning
2828 	 * that the server has no physical calculations to do). If not an animation will be
2829 	 * done client-side but the server will have to calculate the new position applying
2830 	 * the item's movement rules.
2831 	 */
2832 	public long entityId;
2833 
2834 	/**
2835 	 * New motion for the entity that will influence its movement.
2836 	 */
2837 	public Tuple!(float, "x", float, "y", float, "z") motion;
2838 
2839 	public pure nothrow @safe @nogc this() {}
2840 
2841 	public pure nothrow @safe @nogc this(long entityId, Tuple!(float, "x", float, "y", float, "z") motion=Tuple!(float, "x", float, "y", float, "z").init) {
2842 		this.entityId = entityId;
2843 		this.motion = motion;
2844 	}
2845 
2846 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2847 		_buffer.length = 0;
2848 		static if(writeId){ writeBigEndianUbyte(ID); }
2849 		writeBytes(varlong.encode(entityId));
2850 		writeLittleEndianFloat(motion.x); writeLittleEndianFloat(motion.y); writeLittleEndianFloat(motion.z);
2851 		return _buffer;
2852 	}
2853 
2854 	public pure nothrow @safe void decode(bool readId=true)() {
2855 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2856 		entityId=varlong.decode(_buffer, &_index);
2857 		motion.x=readLittleEndianFloat(); motion.y=readLittleEndianFloat(); motion.z=readLittleEndianFloat();
2858 	}
2859 
2860 	public static pure nothrow @safe SetEntityMotion fromBuffer(bool readId=true)(ubyte[] buffer) {
2861 		SetEntityMotion ret = new SetEntityMotion();
2862 		ret._buffer = buffer;
2863 		ret.decode!readId();
2864 		return ret;
2865 	}
2866 
2867 	public override string toString() {
2868 		return "SetEntityMotion(entityId: " ~ std.conv.to!string(this.entityId) ~ ", motion: " ~ std.conv.to!string(this.motion) ~ ")";
2869 	}
2870 
2871 }
2872 
2873 class SetEntityLink : Buffer {
2874 
2875 	public enum ubyte ID = 41;
2876 
2877 	public enum bool CLIENTBOUND = true;
2878 	public enum bool SERVERBOUND = false;
2879 
2880 	// action
2881 	public enum ubyte ADD = 0;
2882 	public enum ubyte RIDE = 1;
2883 	public enum ubyte REMOVE = 2;
2884 
2885 	public enum string[] FIELDS = ["from", "to", "action"];
2886 
2887 	public long from;
2888 	public long to;
2889 	public ubyte action;
2890 
2891 	public pure nothrow @safe @nogc this() {}
2892 
2893 	public pure nothrow @safe @nogc this(long from, long to=long.init, ubyte action=ubyte.init) {
2894 		this.from = from;
2895 		this.to = to;
2896 		this.action = action;
2897 	}
2898 
2899 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2900 		_buffer.length = 0;
2901 		static if(writeId){ writeBigEndianUbyte(ID); }
2902 		writeBytes(varlong.encode(from));
2903 		writeBytes(varlong.encode(to));
2904 		writeBigEndianUbyte(action);
2905 		return _buffer;
2906 	}
2907 
2908 	public pure nothrow @safe void decode(bool readId=true)() {
2909 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2910 		from=varlong.decode(_buffer, &_index);
2911 		to=varlong.decode(_buffer, &_index);
2912 		action=readBigEndianUbyte();
2913 	}
2914 
2915 	public static pure nothrow @safe SetEntityLink fromBuffer(bool readId=true)(ubyte[] buffer) {
2916 		SetEntityLink ret = new SetEntityLink();
2917 		ret._buffer = buffer;
2918 		ret.decode!readId();
2919 		return ret;
2920 	}
2921 
2922 	public override string toString() {
2923 		return "SetEntityLink(from: " ~ std.conv.to!string(this.from) ~ ", to: " ~ std.conv.to!string(this.to) ~ ", action: " ~ std.conv.to!string(this.action) ~ ")";
2924 	}
2925 
2926 }
2927 
2928 class SetHealth : Buffer {
2929 
2930 	public enum ubyte ID = 42;
2931 
2932 	public enum bool CLIENTBOUND = true;
2933 	public enum bool SERVERBOUND = false;
2934 
2935 	public enum string[] FIELDS = ["health"];
2936 
2937 	public int health;
2938 
2939 	public pure nothrow @safe @nogc this() {}
2940 
2941 	public pure nothrow @safe @nogc this(int health) {
2942 		this.health = health;
2943 	}
2944 
2945 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2946 		_buffer.length = 0;
2947 		static if(writeId){ writeBigEndianUbyte(ID); }
2948 		writeBytes(varint.encode(health));
2949 		return _buffer;
2950 	}
2951 
2952 	public pure nothrow @safe void decode(bool readId=true)() {
2953 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
2954 		health=varint.decode(_buffer, &_index);
2955 	}
2956 
2957 	public static pure nothrow @safe SetHealth fromBuffer(bool readId=true)(ubyte[] buffer) {
2958 		SetHealth ret = new SetHealth();
2959 		ret._buffer = buffer;
2960 		ret.decode!readId();
2961 		return ret;
2962 	}
2963 
2964 	public override string toString() {
2965 		return "SetHealth(health: " ~ std.conv.to!string(this.health) ~ ")";
2966 	}
2967 
2968 }
2969 
2970 class SetSpawnPosition : Buffer {
2971 
2972 	public enum ubyte ID = 43;
2973 
2974 	public enum bool CLIENTBOUND = true;
2975 	public enum bool SERVERBOUND = false;
2976 
2977 	public enum string[] FIELDS = ["unknown0", "position", "unknown2"];
2978 
2979 	public int unknown0;
2980 	public sul.protocol.pocket101.types.BlockPosition position;
2981 	public bool unknown2;
2982 
2983 	public pure nothrow @safe @nogc this() {}
2984 
2985 	public pure nothrow @safe @nogc this(int unknown0, sul.protocol.pocket101.types.BlockPosition position=sul.protocol.pocket101.types.BlockPosition.init, bool unknown2=bool.init) {
2986 		this.unknown0 = unknown0;
2987 		this.position = position;
2988 		this.unknown2 = unknown2;
2989 	}
2990 
2991 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
2992 		_buffer.length = 0;
2993 		static if(writeId){ writeBigEndianUbyte(ID); }
2994 		writeBytes(varint.encode(unknown0));
2995 		position.encode(bufferInstance);
2996 		writeBigEndianBool(unknown2);
2997 		return _buffer;
2998 	}
2999 
3000 	public pure nothrow @safe void decode(bool readId=true)() {
3001 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3002 		unknown0=varint.decode(_buffer, &_index);
3003 		position.decode(bufferInstance);
3004 		unknown2=readBigEndianBool();
3005 	}
3006 
3007 	public static pure nothrow @safe SetSpawnPosition fromBuffer(bool readId=true)(ubyte[] buffer) {
3008 		SetSpawnPosition ret = new SetSpawnPosition();
3009 		ret._buffer = buffer;
3010 		ret.decode!readId();
3011 		return ret;
3012 	}
3013 
3014 	public override string toString() {
3015 		return "SetSpawnPosition(unknown0: " ~ std.conv.to!string(this.unknown0) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
3016 	}
3017 
3018 }
3019 
3020 class Animate : Buffer {
3021 
3022 	public enum ubyte ID = 44;
3023 
3024 	public enum bool CLIENTBOUND = true;
3025 	public enum bool SERVERBOUND = true;
3026 
3027 	// action
3028 	public enum int BREAKING = 1;
3029 	public enum int WAKE_UP = 3;
3030 
3031 	public enum string[] FIELDS = ["action", "entityId"];
3032 
3033 	public int action;
3034 	public long entityId;
3035 
3036 	public pure nothrow @safe @nogc this() {}
3037 
3038 	public pure nothrow @safe @nogc this(int action, long entityId=long.init) {
3039 		this.action = action;
3040 		this.entityId = entityId;
3041 	}
3042 
3043 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3044 		_buffer.length = 0;
3045 		static if(writeId){ writeBigEndianUbyte(ID); }
3046 		writeBytes(varint.encode(action));
3047 		writeBytes(varlong.encode(entityId));
3048 		return _buffer;
3049 	}
3050 
3051 	public pure nothrow @safe void decode(bool readId=true)() {
3052 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3053 		action=varint.decode(_buffer, &_index);
3054 		entityId=varlong.decode(_buffer, &_index);
3055 	}
3056 
3057 	public static pure nothrow @safe Animate fromBuffer(bool readId=true)(ubyte[] buffer) {
3058 		Animate ret = new Animate();
3059 		ret._buffer = buffer;
3060 		ret.decode!readId();
3061 		return ret;
3062 	}
3063 
3064 	public override string toString() {
3065 		return "Animate(action: " ~ std.conv.to!string(this.action) ~ ", entityId: " ~ std.conv.to!string(this.entityId) ~ ")";
3066 	}
3067 
3068 }
3069 
3070 class Respawn : Buffer {
3071 
3072 	public enum ubyte ID = 45;
3073 
3074 	public enum bool CLIENTBOUND = true;
3075 	public enum bool SERVERBOUND = false;
3076 
3077 	public enum string[] FIELDS = ["position"];
3078 
3079 	public Tuple!(float, "x", float, "y", float, "z") position;
3080 
3081 	public pure nothrow @safe @nogc this() {}
3082 
3083 	public pure nothrow @safe @nogc this(Tuple!(float, "x", float, "y", float, "z") position) {
3084 		this.position = position;
3085 	}
3086 
3087 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3088 		_buffer.length = 0;
3089 		static if(writeId){ writeBigEndianUbyte(ID); }
3090 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
3091 		return _buffer;
3092 	}
3093 
3094 	public pure nothrow @safe void decode(bool readId=true)() {
3095 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3096 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
3097 	}
3098 
3099 	public static pure nothrow @safe Respawn fromBuffer(bool readId=true)(ubyte[] buffer) {
3100 		Respawn ret = new Respawn();
3101 		ret._buffer = buffer;
3102 		ret.decode!readId();
3103 		return ret;
3104 	}
3105 
3106 	public override string toString() {
3107 		return "Respawn(position: " ~ std.conv.to!string(this.position) ~ ")";
3108 	}
3109 
3110 }
3111 
3112 class DropItem : Buffer {
3113 
3114 	public enum ubyte ID = 46;
3115 
3116 	public enum bool CLIENTBOUND = false;
3117 	public enum bool SERVERBOUND = true;
3118 
3119 	// action
3120 	public enum ubyte DROP = 0;
3121 
3122 	public enum string[] FIELDS = ["action", "item"];
3123 
3124 	public ubyte action;
3125 	public sul.protocol.pocket101.types.Slot item;
3126 
3127 	public pure nothrow @safe @nogc this() {}
3128 
3129 	public pure nothrow @safe @nogc this(ubyte action, sul.protocol.pocket101.types.Slot item=sul.protocol.pocket101.types.Slot.init) {
3130 		this.action = action;
3131 		this.item = item;
3132 	}
3133 
3134 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3135 		_buffer.length = 0;
3136 		static if(writeId){ writeBigEndianUbyte(ID); }
3137 		writeBigEndianUbyte(action);
3138 		item.encode(bufferInstance);
3139 		return _buffer;
3140 	}
3141 
3142 	public pure nothrow @safe void decode(bool readId=true)() {
3143 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3144 		action=readBigEndianUbyte();
3145 		item.decode(bufferInstance);
3146 	}
3147 
3148 	public static pure nothrow @safe DropItem fromBuffer(bool readId=true)(ubyte[] buffer) {
3149 		DropItem ret = new DropItem();
3150 		ret._buffer = buffer;
3151 		ret.decode!readId();
3152 		return ret;
3153 	}
3154 
3155 	public override string toString() {
3156 		return "DropItem(action: " ~ std.conv.to!string(this.action) ~ ", item: " ~ std.conv.to!string(this.item) ~ ")";
3157 	}
3158 
3159 }
3160 
3161 class InventoryAction : Buffer {
3162 
3163 	public enum ubyte ID = 47;
3164 
3165 	public enum bool CLIENTBOUND = false;
3166 	public enum bool SERVERBOUND = true;
3167 
3168 	public enum string[] FIELDS = ["action", "item"];
3169 
3170 	public int action;
3171 	public sul.protocol.pocket101.types.Slot item;
3172 
3173 	public pure nothrow @safe @nogc this() {}
3174 
3175 	public pure nothrow @safe @nogc this(int action, sul.protocol.pocket101.types.Slot item=sul.protocol.pocket101.types.Slot.init) {
3176 		this.action = action;
3177 		this.item = item;
3178 	}
3179 
3180 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3181 		_buffer.length = 0;
3182 		static if(writeId){ writeBigEndianUbyte(ID); }
3183 		writeBytes(varint.encode(action));
3184 		item.encode(bufferInstance);
3185 		return _buffer;
3186 	}
3187 
3188 	public pure nothrow @safe void decode(bool readId=true)() {
3189 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3190 		action=varint.decode(_buffer, &_index);
3191 		item.decode(bufferInstance);
3192 	}
3193 
3194 	public static pure nothrow @safe InventoryAction fromBuffer(bool readId=true)(ubyte[] buffer) {
3195 		InventoryAction ret = new InventoryAction();
3196 		ret._buffer = buffer;
3197 		ret.decode!readId();
3198 		return ret;
3199 	}
3200 
3201 	public override string toString() {
3202 		return "InventoryAction(action: " ~ std.conv.to!string(this.action) ~ ", item: " ~ std.conv.to!string(this.item) ~ ")";
3203 	}
3204 
3205 }
3206 
3207 class ContainerOpen : Buffer {
3208 
3209 	public enum ubyte ID = 48;
3210 
3211 	public enum bool CLIENTBOUND = true;
3212 	public enum bool SERVERBOUND = false;
3213 
3214 	public enum string[] FIELDS = ["window", "type", "slotCount", "position", "entityId"];
3215 
3216 	public ubyte window;
3217 	public ubyte type;
3218 	public int slotCount;
3219 	public sul.protocol.pocket101.types.BlockPosition position;
3220 	public long entityId;
3221 
3222 	public pure nothrow @safe @nogc this() {}
3223 
3224 	public pure nothrow @safe @nogc this(ubyte window, ubyte type=ubyte.init, int slotCount=int.init, sul.protocol.pocket101.types.BlockPosition position=sul.protocol.pocket101.types.BlockPosition.init, long entityId=long.init) {
3225 		this.window = window;
3226 		this.type = type;
3227 		this.slotCount = slotCount;
3228 		this.position = position;
3229 		this.entityId = entityId;
3230 	}
3231 
3232 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3233 		_buffer.length = 0;
3234 		static if(writeId){ writeBigEndianUbyte(ID); }
3235 		writeBigEndianUbyte(window);
3236 		writeBigEndianUbyte(type);
3237 		writeBytes(varint.encode(slotCount));
3238 		position.encode(bufferInstance);
3239 		writeBytes(varlong.encode(entityId));
3240 		return _buffer;
3241 	}
3242 
3243 	public pure nothrow @safe void decode(bool readId=true)() {
3244 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3245 		window=readBigEndianUbyte();
3246 		type=readBigEndianUbyte();
3247 		slotCount=varint.decode(_buffer, &_index);
3248 		position.decode(bufferInstance);
3249 		entityId=varlong.decode(_buffer, &_index);
3250 	}
3251 
3252 	public static pure nothrow @safe ContainerOpen fromBuffer(bool readId=true)(ubyte[] buffer) {
3253 		ContainerOpen ret = new ContainerOpen();
3254 		ret._buffer = buffer;
3255 		ret.decode!readId();
3256 		return ret;
3257 	}
3258 
3259 	public override string toString() {
3260 		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) ~ ")";
3261 	}
3262 
3263 }
3264 
3265 class ContainerClose : Buffer {
3266 
3267 	public enum ubyte ID = 49;
3268 
3269 	public enum bool CLIENTBOUND = true;
3270 	public enum bool SERVERBOUND = true;
3271 
3272 	public enum string[] FIELDS = ["window"];
3273 
3274 	public ubyte window;
3275 
3276 	public pure nothrow @safe @nogc this() {}
3277 
3278 	public pure nothrow @safe @nogc this(ubyte window) {
3279 		this.window = window;
3280 	}
3281 
3282 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3283 		_buffer.length = 0;
3284 		static if(writeId){ writeBigEndianUbyte(ID); }
3285 		writeBigEndianUbyte(window);
3286 		return _buffer;
3287 	}
3288 
3289 	public pure nothrow @safe void decode(bool readId=true)() {
3290 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3291 		window=readBigEndianUbyte();
3292 	}
3293 
3294 	public static pure nothrow @safe ContainerClose fromBuffer(bool readId=true)(ubyte[] buffer) {
3295 		ContainerClose ret = new ContainerClose();
3296 		ret._buffer = buffer;
3297 		ret.decode!readId();
3298 		return ret;
3299 	}
3300 
3301 	public override string toString() {
3302 		return "ContainerClose(window: " ~ std.conv.to!string(this.window) ~ ")";
3303 	}
3304 
3305 }
3306 
3307 class ContainerSetSlot : Buffer {
3308 
3309 	public enum ubyte ID = 50;
3310 
3311 	public enum bool CLIENTBOUND = true;
3312 	public enum bool SERVERBOUND = true;
3313 
3314 	public enum string[] FIELDS = ["window", "slot", "hotbarSlot", "item", "unknown4"];
3315 
3316 	public ubyte window;
3317 	public int slot;
3318 	public int hotbarSlot;
3319 	public sul.protocol.pocket101.types.Slot item;
3320 	public ubyte unknown4;
3321 
3322 	public pure nothrow @safe @nogc this() {}
3323 
3324 	public pure nothrow @safe @nogc this(ubyte window, int slot=int.init, int hotbarSlot=int.init, sul.protocol.pocket101.types.Slot item=sul.protocol.pocket101.types.Slot.init, ubyte unknown4=ubyte.init) {
3325 		this.window = window;
3326 		this.slot = slot;
3327 		this.hotbarSlot = hotbarSlot;
3328 		this.item = item;
3329 		this.unknown4 = unknown4;
3330 	}
3331 
3332 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3333 		_buffer.length = 0;
3334 		static if(writeId){ writeBigEndianUbyte(ID); }
3335 		writeBigEndianUbyte(window);
3336 		writeBytes(varint.encode(slot));
3337 		writeBytes(varint.encode(hotbarSlot));
3338 		item.encode(bufferInstance);
3339 		writeBigEndianUbyte(unknown4);
3340 		return _buffer;
3341 	}
3342 
3343 	public pure nothrow @safe void decode(bool readId=true)() {
3344 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3345 		window=readBigEndianUbyte();
3346 		slot=varint.decode(_buffer, &_index);
3347 		hotbarSlot=varint.decode(_buffer, &_index);
3348 		item.decode(bufferInstance);
3349 		unknown4=readBigEndianUbyte();
3350 	}
3351 
3352 	public static pure nothrow @safe ContainerSetSlot fromBuffer(bool readId=true)(ubyte[] buffer) {
3353 		ContainerSetSlot ret = new ContainerSetSlot();
3354 		ret._buffer = buffer;
3355 		ret.decode!readId();
3356 		return ret;
3357 	}
3358 
3359 	public override string toString() {
3360 		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) ~ ")";
3361 	}
3362 
3363 }
3364 
3365 class ContainerSetData : Buffer {
3366 
3367 	public enum ubyte ID = 51;
3368 
3369 	public enum bool CLIENTBOUND = true;
3370 	public enum bool SERVERBOUND = false;
3371 
3372 	public enum string[] FIELDS = ["window", "property", "value"];
3373 
3374 	public ubyte window;
3375 	public int property;
3376 	public int value;
3377 
3378 	public pure nothrow @safe @nogc this() {}
3379 
3380 	public pure nothrow @safe @nogc this(ubyte window, int property=int.init, int value=int.init) {
3381 		this.window = window;
3382 		this.property = property;
3383 		this.value = value;
3384 	}
3385 
3386 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3387 		_buffer.length = 0;
3388 		static if(writeId){ writeBigEndianUbyte(ID); }
3389 		writeBigEndianUbyte(window);
3390 		writeBytes(varint.encode(property));
3391 		writeBytes(varint.encode(value));
3392 		return _buffer;
3393 	}
3394 
3395 	public pure nothrow @safe void decode(bool readId=true)() {
3396 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3397 		window=readBigEndianUbyte();
3398 		property=varint.decode(_buffer, &_index);
3399 		value=varint.decode(_buffer, &_index);
3400 	}
3401 
3402 	public static pure nothrow @safe ContainerSetData fromBuffer(bool readId=true)(ubyte[] buffer) {
3403 		ContainerSetData ret = new ContainerSetData();
3404 		ret._buffer = buffer;
3405 		ret.decode!readId();
3406 		return ret;
3407 	}
3408 
3409 	public override string toString() {
3410 		return "ContainerSetData(window: " ~ std.conv.to!string(this.window) ~ ", property: " ~ std.conv.to!string(this.property) ~ ", value: " ~ std.conv.to!string(this.value) ~ ")";
3411 	}
3412 
3413 }
3414 
3415 class ContainerSetContent : Buffer {
3416 
3417 	public enum ubyte ID = 52;
3418 
3419 	public enum bool CLIENTBOUND = true;
3420 	public enum bool SERVERBOUND = false;
3421 
3422 	public enum string[] FIELDS = ["window", "slots", "hotbar"];
3423 
3424 	public ubyte window;
3425 	public sul.protocol.pocket101.types.Slot[] slots;
3426 	public int[] hotbar;
3427 
3428 	public pure nothrow @safe @nogc this() {}
3429 
3430 	public pure nothrow @safe @nogc this(ubyte window, sul.protocol.pocket101.types.Slot[] slots=(sul.protocol.pocket101.types.Slot[]).init, int[] hotbar=(int[]).init) {
3431 		this.window = window;
3432 		this.slots = slots;
3433 		this.hotbar = hotbar;
3434 	}
3435 
3436 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3437 		_buffer.length = 0;
3438 		static if(writeId){ writeBigEndianUbyte(ID); }
3439 		writeBigEndianUbyte(window);
3440 		writeBytes(varuint.encode(cast(uint)slots.length)); foreach(cxdm;slots){ cxdm.encode(bufferInstance); }
3441 		writeBytes(varuint.encode(cast(uint)hotbar.length)); foreach(a9yf;hotbar){ writeBytes(varint.encode(a9yf)); }
3442 		return _buffer;
3443 	}
3444 
3445 	public pure nothrow @safe void decode(bool readId=true)() {
3446 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3447 		window=readBigEndianUbyte();
3448 		slots.length=varuint.decode(_buffer, &_index); foreach(ref cxdm;slots){ cxdm.decode(bufferInstance); }
3449 		hotbar.length=varuint.decode(_buffer, &_index); foreach(ref a9yf;hotbar){ a9yf=varint.decode(_buffer, &_index); }
3450 	}
3451 
3452 	public static pure nothrow @safe ContainerSetContent fromBuffer(bool readId=true)(ubyte[] buffer) {
3453 		ContainerSetContent ret = new ContainerSetContent();
3454 		ret._buffer = buffer;
3455 		ret.decode!readId();
3456 		return ret;
3457 	}
3458 
3459 	public override string toString() {
3460 		return "ContainerSetContent(window: " ~ std.conv.to!string(this.window) ~ ", slots: " ~ std.conv.to!string(this.slots) ~ ", hotbar: " ~ std.conv.to!string(this.hotbar) ~ ")";
3461 	}
3462 
3463 }
3464 
3465 class CraftingData : Buffer {
3466 
3467 	public enum ubyte ID = 53;
3468 
3469 	public enum bool CLIENTBOUND = true;
3470 	public enum bool SERVERBOUND = false;
3471 
3472 	public enum string[] FIELDS = ["recipes"];
3473 
3474 	public sul.protocol.pocket101.types.Recipe[] recipes;
3475 
3476 	public pure nothrow @safe @nogc this() {}
3477 
3478 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.types.Recipe[] recipes) {
3479 		this.recipes = recipes;
3480 	}
3481 
3482 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3483 		_buffer.length = 0;
3484 		static if(writeId){ writeBigEndianUbyte(ID); }
3485 		writeBytes(varuint.encode(cast(uint)recipes.length)); foreach(cvabc;recipes){ cvabc.encode(bufferInstance); }
3486 		return _buffer;
3487 	}
3488 
3489 	public pure nothrow @safe void decode(bool readId=true)() {
3490 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3491 		recipes.length=varuint.decode(_buffer, &_index); foreach(ref cvabc;recipes){ cvabc.decode(bufferInstance); }
3492 	}
3493 
3494 	public static pure nothrow @safe CraftingData fromBuffer(bool readId=true)(ubyte[] buffer) {
3495 		CraftingData ret = new CraftingData();
3496 		ret._buffer = buffer;
3497 		ret.decode!readId();
3498 		return ret;
3499 	}
3500 
3501 	public override string toString() {
3502 		return "CraftingData(recipes: " ~ std.conv.to!string(this.recipes) ~ ")";
3503 	}
3504 
3505 }
3506 
3507 class CraftingEvent : Buffer {
3508 
3509 	public enum ubyte ID = 54;
3510 
3511 	public enum bool CLIENTBOUND = false;
3512 	public enum bool SERVERBOUND = true;
3513 
3514 	public enum string[] FIELDS = ["window", "type", "uuid", "input", "output"];
3515 
3516 	public ubyte window;
3517 	public int type;
3518 	public UUID uuid;
3519 	public sul.protocol.pocket101.types.Slot[] input;
3520 	public sul.protocol.pocket101.types.Slot[] output;
3521 
3522 	public pure nothrow @safe @nogc this() {}
3523 
3524 	public pure nothrow @safe @nogc this(ubyte window, int type=int.init, UUID uuid=UUID.init, sul.protocol.pocket101.types.Slot[] input=(sul.protocol.pocket101.types.Slot[]).init, sul.protocol.pocket101.types.Slot[] output=(sul.protocol.pocket101.types.Slot[]).init) {
3525 		this.window = window;
3526 		this.type = type;
3527 		this.uuid = uuid;
3528 		this.input = input;
3529 		this.output = output;
3530 	}
3531 
3532 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3533 		_buffer.length = 0;
3534 		static if(writeId){ writeBigEndianUbyte(ID); }
3535 		writeBigEndianUbyte(window);
3536 		writeBytes(varint.encode(type));
3537 		writeBytes(uuid.data);
3538 		writeBytes(varuint.encode(cast(uint)input.length)); foreach(a5dq;input){ a5dq.encode(bufferInstance); }
3539 		writeBytes(varuint.encode(cast(uint)output.length)); foreach(bvcv;output){ bvcv.encode(bufferInstance); }
3540 		return _buffer;
3541 	}
3542 
3543 	public pure nothrow @safe void decode(bool readId=true)() {
3544 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3545 		window=readBigEndianUbyte();
3546 		type=varint.decode(_buffer, &_index);
3547 		if(_buffer.length>=_index+16){ ubyte[16] dvz=_buffer[_index.._index+16].dup; _index+=16; uuid=UUID(dvz); }
3548 		input.length=varuint.decode(_buffer, &_index); foreach(ref a5dq;input){ a5dq.decode(bufferInstance); }
3549 		output.length=varuint.decode(_buffer, &_index); foreach(ref bvcv;output){ bvcv.decode(bufferInstance); }
3550 	}
3551 
3552 	public static pure nothrow @safe CraftingEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
3553 		CraftingEvent ret = new CraftingEvent();
3554 		ret._buffer = buffer;
3555 		ret.decode!readId();
3556 		return ret;
3557 	}
3558 
3559 	public override string toString() {
3560 		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) ~ ")";
3561 	}
3562 
3563 }
3564 
3565 /**
3566  * Updates the world's settings and client's permissions.
3567  */
3568 class AdventureSettings : Buffer {
3569 
3570 	public enum ubyte ID = 55;
3571 
3572 	public enum bool CLIENTBOUND = true;
3573 	public enum bool SERVERBOUND = true;
3574 
3575 	// flags
3576 	public enum uint IMMUTABLE_WORLD = 1;
3577 	public enum uint PVP_DISABLED = 2;
3578 	public enum uint PVM_DISABLED = 4;
3579 	public enum uint MVP_DISBALED = 8;
3580 	public enum uint EVP_DISABLED = 16;
3581 	public enum uint AUTO_JUMP = 32;
3582 	public enum uint ALLOW_FLIGHT = 64;
3583 	public enum uint NO_CLIP = 128;
3584 	public enum uint FLYING = 512;
3585 
3586 	// permissions
3587 	public enum uint USER = 0;
3588 	public enum uint OPERATOR = 1;
3589 	public enum uint HOST = 2;
3590 	public enum uint AUTOMATION = 3;
3591 	public enum uint ADMIN = 4;
3592 
3593 	public enum string[] FIELDS = ["flags", "permissions"];
3594 
3595 	public uint flags;
3596 	public uint permissions;
3597 
3598 	public pure nothrow @safe @nogc this() {}
3599 
3600 	public pure nothrow @safe @nogc this(uint flags, uint permissions=uint.init) {
3601 		this.flags = flags;
3602 		this.permissions = permissions;
3603 	}
3604 
3605 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3606 		_buffer.length = 0;
3607 		static if(writeId){ writeBigEndianUbyte(ID); }
3608 		writeBytes(varuint.encode(flags));
3609 		writeBytes(varuint.encode(permissions));
3610 		return _buffer;
3611 	}
3612 
3613 	public pure nothrow @safe void decode(bool readId=true)() {
3614 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3615 		flags=varuint.decode(_buffer, &_index);
3616 		permissions=varuint.decode(_buffer, &_index);
3617 	}
3618 
3619 	public static pure nothrow @safe AdventureSettings fromBuffer(bool readId=true)(ubyte[] buffer) {
3620 		AdventureSettings ret = new AdventureSettings();
3621 		ret._buffer = buffer;
3622 		ret.decode!readId();
3623 		return ret;
3624 	}
3625 
3626 	public override string toString() {
3627 		return "AdventureSettings(flags: " ~ std.conv.to!string(this.flags) ~ ", permissions: " ~ std.conv.to!string(this.permissions) ~ ")";
3628 	}
3629 
3630 }
3631 
3632 /**
3633  * Sets a block entity's nbt tag, block's additional data that cannot be indicated
3634  * in the block's meta. More informations about block entities and their tag format
3635  * can be found on Minecraft Wiki.
3636  */
3637 class BlockEntityData : Buffer {
3638 
3639 	public enum ubyte ID = 56;
3640 
3641 	public enum bool CLIENTBOUND = true;
3642 	public enum bool SERVERBOUND = false;
3643 
3644 	public enum string[] FIELDS = ["position", "nbt"];
3645 
3646 	/**
3647 	 * Position of the block that will be associated with tag.
3648 	 */
3649 	public sul.protocol.pocket101.types.BlockPosition position;
3650 
3651 	/**
3652 	 * Named binary tag of the block. The format varies from the classic format of Minecraft:
3653 	 * Pocket Edition (which is like Minecraft's but little endian) introducing the use
3654 	 * of varints for some types:
3655 	 * + The tag `Int` is encoded as a signed varint instead of a simple signed 32-bits
3656 	 * integer
3657 	 * + The length of the `ByteArray` and the `IntArray` is encoded as an unsigned varint
3658 	 * instead of a 32-bits integer
3659 	 * + The length of the `String` tag and the named tag's name length are encoded as
3660 	 * an unisgned varint instead of a 16-bits integer
3661 	 */
3662 	public ubyte[] nbt;
3663 
3664 	public pure nothrow @safe @nogc this() {}
3665 
3666 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.types.BlockPosition position, ubyte[] nbt=(ubyte[]).init) {
3667 		this.position = position;
3668 		this.nbt = nbt;
3669 	}
3670 
3671 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3672 		_buffer.length = 0;
3673 		static if(writeId){ writeBigEndianUbyte(ID); }
3674 		position.encode(bufferInstance);
3675 		writeBytes(nbt);
3676 		return _buffer;
3677 	}
3678 
3679 	public pure nothrow @safe void decode(bool readId=true)() {
3680 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3681 		position.decode(bufferInstance);
3682 		nbt=_buffer[_index..$].dup; _index=_buffer.length;
3683 	}
3684 
3685 	public static pure nothrow @safe BlockEntityData fromBuffer(bool readId=true)(ubyte[] buffer) {
3686 		BlockEntityData ret = new BlockEntityData();
3687 		ret._buffer = buffer;
3688 		ret.decode!readId();
3689 		return ret;
3690 	}
3691 
3692 	public override string toString() {
3693 		return "BlockEntityData(position: " ~ std.conv.to!string(this.position) ~ ", nbt: " ~ std.conv.to!string(this.nbt) ~ ")";
3694 	}
3695 
3696 }
3697 
3698 class PlayerInput : Buffer {
3699 
3700 	public enum ubyte ID = 57;
3701 
3702 	public enum bool CLIENTBOUND = false;
3703 	public enum bool SERVERBOUND = true;
3704 
3705 	public enum string[] FIELDS = ["motion", "flags", "unknown2"];
3706 
3707 	public Tuple!(float, "x", float, "y", float, "z") motion;
3708 	public ubyte flags;
3709 	public bool unknown2;
3710 
3711 	public pure nothrow @safe @nogc this() {}
3712 
3713 	public pure nothrow @safe @nogc this(Tuple!(float, "x", float, "y", float, "z") motion, ubyte flags=ubyte.init, bool unknown2=bool.init) {
3714 		this.motion = motion;
3715 		this.flags = flags;
3716 		this.unknown2 = unknown2;
3717 	}
3718 
3719 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3720 		_buffer.length = 0;
3721 		static if(writeId){ writeBigEndianUbyte(ID); }
3722 		writeLittleEndianFloat(motion.x); writeLittleEndianFloat(motion.y); writeLittleEndianFloat(motion.z);
3723 		writeBigEndianUbyte(flags);
3724 		writeBigEndianBool(unknown2);
3725 		return _buffer;
3726 	}
3727 
3728 	public pure nothrow @safe void decode(bool readId=true)() {
3729 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3730 		motion.x=readLittleEndianFloat(); motion.y=readLittleEndianFloat(); motion.z=readLittleEndianFloat();
3731 		flags=readBigEndianUbyte();
3732 		unknown2=readBigEndianBool();
3733 	}
3734 
3735 	public static pure nothrow @safe PlayerInput fromBuffer(bool readId=true)(ubyte[] buffer) {
3736 		PlayerInput ret = new PlayerInput();
3737 		ret._buffer = buffer;
3738 		ret.decode!readId();
3739 		return ret;
3740 	}
3741 
3742 	public override string toString() {
3743 		return "PlayerInput(motion: " ~ std.conv.to!string(this.motion) ~ ", flags: " ~ std.conv.to!string(this.flags) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
3744 	}
3745 
3746 }
3747 
3748 /**
3749  * Sends a 16x16 chunk to the client with its blocks, lights and block entities (tiles).
3750  */
3751 class FullChunkData : Buffer {
3752 
3753 	public enum ubyte ID = 58;
3754 
3755 	public enum bool CLIENTBOUND = true;
3756 	public enum bool SERVERBOUND = false;
3757 
3758 	public enum string[] FIELDS = ["position", "data"];
3759 
3760 	/**
3761 	 * Coordinates of the chunk.
3762 	 */
3763 	public Tuple!(int, "x", int, "z") position;
3764 	public sul.protocol.pocket101.types.ChunkData data;
3765 
3766 	public pure nothrow @safe @nogc this() {}
3767 
3768 	public pure nothrow @safe @nogc this(Tuple!(int, "x", int, "z") position, sul.protocol.pocket101.types.ChunkData data=sul.protocol.pocket101.types.ChunkData.init) {
3769 		this.position = position;
3770 		this.data = data;
3771 	}
3772 
3773 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3774 		_buffer.length = 0;
3775 		static if(writeId){ writeBigEndianUbyte(ID); }
3776 		writeBytes(varint.encode(position.x)); writeBytes(varint.encode(position.z));
3777 		data.encode(bufferInstance);
3778 		return _buffer;
3779 	}
3780 
3781 	public pure nothrow @safe void decode(bool readId=true)() {
3782 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3783 		position.x=varint.decode(_buffer, &_index); position.z=varint.decode(_buffer, &_index);
3784 		data.decode(bufferInstance);
3785 	}
3786 
3787 	public static pure nothrow @safe FullChunkData fromBuffer(bool readId=true)(ubyte[] buffer) {
3788 		FullChunkData ret = new FullChunkData();
3789 		ret._buffer = buffer;
3790 		ret.decode!readId();
3791 		return ret;
3792 	}
3793 
3794 	public override string toString() {
3795 		return "FullChunkData(position: " ~ std.conv.to!string(this.position) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
3796 	}
3797 
3798 }
3799 
3800 /**
3801  * Indicates whether the cheats are enabled. If not the client cannot send commands.
3802  */
3803 class SetCommandsEnabled : Buffer {
3804 
3805 	public enum ubyte ID = 59;
3806 
3807 	public enum bool CLIENTBOUND = true;
3808 	public enum bool SERVERBOUND = false;
3809 
3810 	public enum string[] FIELDS = ["enabled"];
3811 
3812 	public bool enabled;
3813 
3814 	public pure nothrow @safe @nogc this() {}
3815 
3816 	public pure nothrow @safe @nogc this(bool enabled) {
3817 		this.enabled = enabled;
3818 	}
3819 
3820 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3821 		_buffer.length = 0;
3822 		static if(writeId){ writeBigEndianUbyte(ID); }
3823 		writeBigEndianBool(enabled);
3824 		return _buffer;
3825 	}
3826 
3827 	public pure nothrow @safe void decode(bool readId=true)() {
3828 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3829 		enabled=readBigEndianBool();
3830 	}
3831 
3832 	public static pure nothrow @safe SetCommandsEnabled fromBuffer(bool readId=true)(ubyte[] buffer) {
3833 		SetCommandsEnabled ret = new SetCommandsEnabled();
3834 		ret._buffer = buffer;
3835 		ret.decode!readId();
3836 		return ret;
3837 	}
3838 
3839 	public override string toString() {
3840 		return "SetCommandsEnabled(enabled: " ~ std.conv.to!string(this.enabled) ~ ")";
3841 	}
3842 
3843 }
3844 
3845 /**
3846  * Sets the world's difficulty.
3847  */
3848 class SetDifficulty : Buffer {
3849 
3850 	public enum ubyte ID = 60;
3851 
3852 	public enum bool CLIENTBOUND = true;
3853 	public enum bool SERVERBOUND = false;
3854 
3855 	// difficulty
3856 	public enum uint PEACEFUL = 0;
3857 	public enum uint EASY = 1;
3858 	public enum uint NORMAL = 2;
3859 	public enum uint HARD = 3;
3860 
3861 	public enum string[] FIELDS = ["difficulty"];
3862 
3863 	public uint difficulty;
3864 
3865 	public pure nothrow @safe @nogc this() {}
3866 
3867 	public pure nothrow @safe @nogc this(uint difficulty) {
3868 		this.difficulty = difficulty;
3869 	}
3870 
3871 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3872 		_buffer.length = 0;
3873 		static if(writeId){ writeBigEndianUbyte(ID); }
3874 		writeBytes(varuint.encode(difficulty));
3875 		return _buffer;
3876 	}
3877 
3878 	public pure nothrow @safe void decode(bool readId=true)() {
3879 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3880 		difficulty=varuint.decode(_buffer, &_index);
3881 	}
3882 
3883 	public static pure nothrow @safe SetDifficulty fromBuffer(bool readId=true)(ubyte[] buffer) {
3884 		SetDifficulty ret = new SetDifficulty();
3885 		ret._buffer = buffer;
3886 		ret.decode!readId();
3887 		return ret;
3888 	}
3889 
3890 	public override string toString() {
3891 		return "SetDifficulty(difficulty: " ~ std.conv.to!string(this.difficulty) ~ ")";
3892 	}
3893 
3894 }
3895 
3896 class ChangeDimension : Buffer {
3897 
3898 	public enum ubyte ID = 61;
3899 
3900 	public enum bool CLIENTBOUND = true;
3901 	public enum bool SERVERBOUND = false;
3902 
3903 	// dimension
3904 	public enum int OVERWORLD = 0;
3905 	public enum int NETHER = 1;
3906 	public enum int END = 2;
3907 
3908 	public enum string[] FIELDS = ["dimension", "position", "unknown2"];
3909 
3910 	public int dimension;
3911 	public Tuple!(float, "x", float, "y", float, "z") position;
3912 	public bool unknown2;
3913 
3914 	public pure nothrow @safe @nogc this() {}
3915 
3916 	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) {
3917 		this.dimension = dimension;
3918 		this.position = position;
3919 		this.unknown2 = unknown2;
3920 	}
3921 
3922 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3923 		_buffer.length = 0;
3924 		static if(writeId){ writeBigEndianUbyte(ID); }
3925 		writeBytes(varint.encode(dimension));
3926 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
3927 		writeBigEndianBool(unknown2);
3928 		return _buffer;
3929 	}
3930 
3931 	public pure nothrow @safe void decode(bool readId=true)() {
3932 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3933 		dimension=varint.decode(_buffer, &_index);
3934 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
3935 		unknown2=readBigEndianBool();
3936 	}
3937 
3938 	public static pure nothrow @safe ChangeDimension fromBuffer(bool readId=true)(ubyte[] buffer) {
3939 		ChangeDimension ret = new ChangeDimension();
3940 		ret._buffer = buffer;
3941 		ret.decode!readId();
3942 		return ret;
3943 	}
3944 
3945 	public override string toString() {
3946 		return "ChangeDimension(dimension: " ~ std.conv.to!string(this.dimension) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
3947 	}
3948 
3949 }
3950 
3951 /**
3952  * Sets the player's gamemode. This packet is sent by the player when it has the operator
3953  * status (set in AdventureSettings.permissions) and it changes the gamemode in the
3954  * settings screen.
3955  */
3956 class SetPlayerGameType : Buffer {
3957 
3958 	public enum ubyte ID = 62;
3959 
3960 	public enum bool CLIENTBOUND = true;
3961 	public enum bool SERVERBOUND = true;
3962 
3963 	// gamemode
3964 	public enum int SURVIVAL = 0;
3965 	public enum int CREATIVE = 1;
3966 
3967 	public enum string[] FIELDS = ["gamemode"];
3968 
3969 	public int gamemode;
3970 
3971 	public pure nothrow @safe @nogc this() {}
3972 
3973 	public pure nothrow @safe @nogc this(int gamemode) {
3974 		this.gamemode = gamemode;
3975 	}
3976 
3977 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
3978 		_buffer.length = 0;
3979 		static if(writeId){ writeBigEndianUbyte(ID); }
3980 		writeBytes(varint.encode(gamemode));
3981 		return _buffer;
3982 	}
3983 
3984 	public pure nothrow @safe void decode(bool readId=true)() {
3985 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
3986 		gamemode=varint.decode(_buffer, &_index);
3987 	}
3988 
3989 	public static pure nothrow @safe SetPlayerGameType fromBuffer(bool readId=true)(ubyte[] buffer) {
3990 		SetPlayerGameType ret = new SetPlayerGameType();
3991 		ret._buffer = buffer;
3992 		ret.decode!readId();
3993 		return ret;
3994 	}
3995 
3996 	public override string toString() {
3997 		return "SetPlayerGameType(gamemode: " ~ std.conv.to!string(this.gamemode) ~ ")";
3998 	}
3999 
4000 }
4001 
4002 /**
4003  * Adds or removes a player from the player's list displayed in the pause menu. This
4004  * packet should be sent before spawning a player with AddPlayer, otherwise the skin
4005  * is not applied.
4006  */
4007 class PlayerList : Buffer {
4008 
4009 	public enum ubyte ID = 63;
4010 
4011 	public enum bool CLIENTBOUND = true;
4012 	public enum bool SERVERBOUND = false;
4013 
4014 	public enum string[] FIELDS = ["action"];
4015 
4016 	public ubyte action;
4017 
4018 	public pure nothrow @safe @nogc this() {}
4019 
4020 	public pure nothrow @safe @nogc this(ubyte action) {
4021 		this.action = action;
4022 	}
4023 
4024 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4025 		_buffer.length = 0;
4026 		static if(writeId){ writeBigEndianUbyte(ID); }
4027 		writeBigEndianUbyte(action);
4028 		return _buffer;
4029 	}
4030 
4031 	public pure nothrow @safe void decode(bool readId=true)() {
4032 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4033 		action=readBigEndianUbyte();
4034 	}
4035 
4036 	public static pure nothrow @safe PlayerList fromBuffer(bool readId=true)(ubyte[] buffer) {
4037 		PlayerList ret = new PlayerList();
4038 		ret._buffer = buffer;
4039 		ret.decode!readId();
4040 		return ret;
4041 	}
4042 
4043 	public override string toString() {
4044 		return "PlayerList(action: " ~ std.conv.to!string(this.action) ~ ")";
4045 	}
4046 
4047 	alias _encode = encode;
4048 
4049 	enum string variantField = "action";
4050 
4051 	alias Variants = TypeTuple!(Add, Remove);
4052 
4053 	public class Add {
4054 
4055 		public enum typeof(action) ACTION = 0;
4056 
4057 		public enum string[] FIELDS = ["players"];
4058 
4059 		public sul.protocol.pocket101.types.PlayerList[] players;
4060 
4061 		public pure nothrow @safe @nogc this() {}
4062 
4063 		public pure nothrow @safe @nogc this(sul.protocol.pocket101.types.PlayerList[] players) {
4064 			this.players = players;
4065 		}
4066 
4067 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4068 			action = 0;
4069 			_encode!writeId();
4070 			writeBytes(varuint.encode(cast(uint)players.length)); foreach(cxevc;players){ cxevc.encode(bufferInstance); }
4071 			return _buffer;
4072 		}
4073 
4074 		public pure nothrow @safe void decode() {
4075 			players.length=varuint.decode(_buffer, &_index); foreach(ref cxevc;players){ cxevc.decode(bufferInstance); }
4076 		}
4077 
4078 		public override string toString() {
4079 			return "PlayerList.Add(players: " ~ std.conv.to!string(this.players) ~ ")";
4080 		}
4081 
4082 	}
4083 
4084 	public class Remove {
4085 
4086 		public enum typeof(action) ACTION = 1;
4087 
4088 		public enum string[] FIELDS = ["players"];
4089 
4090 		public UUID[] players;
4091 
4092 		public pure nothrow @safe @nogc this() {}
4093 
4094 		public pure nothrow @safe @nogc this(UUID[] players) {
4095 			this.players = players;
4096 		}
4097 
4098 		public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4099 			action = 1;
4100 			_encode!writeId();
4101 			writeBytes(varuint.encode(cast(uint)players.length)); foreach(cxevc;players){ writeBytes(cxevc.data); }
4102 			return _buffer;
4103 		}
4104 
4105 		public pure nothrow @safe void decode() {
4106 			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); } }
4107 		}
4108 
4109 		public override string toString() {
4110 			return "PlayerList.Remove(players: " ~ std.conv.to!string(this.players) ~ ")";
4111 		}
4112 
4113 	}
4114 
4115 }
4116 
4117 class TelemetryEvent : Buffer {
4118 
4119 	public enum ubyte ID = 64;
4120 
4121 	public enum bool CLIENTBOUND = true;
4122 	public enum bool SERVERBOUND = false;
4123 
4124 	public enum string[] FIELDS = ["entityId", "eventId"];
4125 
4126 	public long entityId;
4127 	public int eventId;
4128 
4129 	public pure nothrow @safe @nogc this() {}
4130 
4131 	public pure nothrow @safe @nogc this(long entityId, int eventId=int.init) {
4132 		this.entityId = entityId;
4133 		this.eventId = eventId;
4134 	}
4135 
4136 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4137 		_buffer.length = 0;
4138 		static if(writeId){ writeBigEndianUbyte(ID); }
4139 		writeBytes(varlong.encode(entityId));
4140 		writeBytes(varint.encode(eventId));
4141 		return _buffer;
4142 	}
4143 
4144 	public pure nothrow @safe void decode(bool readId=true)() {
4145 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4146 		entityId=varlong.decode(_buffer, &_index);
4147 		eventId=varint.decode(_buffer, &_index);
4148 	}
4149 
4150 	public static pure nothrow @safe TelemetryEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
4151 		TelemetryEvent ret = new TelemetryEvent();
4152 		ret._buffer = buffer;
4153 		ret.decode!readId();
4154 		return ret;
4155 	}
4156 
4157 	public override string toString() {
4158 		return "TelemetryEvent(entityId: " ~ std.conv.to!string(this.entityId) ~ ", eventId: " ~ std.conv.to!string(this.eventId) ~ ")";
4159 	}
4160 
4161 }
4162 
4163 class SpawnExperienceOrb : Buffer {
4164 
4165 	public enum ubyte ID = 65;
4166 
4167 	public enum bool CLIENTBOUND = true;
4168 	public enum bool SERVERBOUND = false;
4169 
4170 	public enum string[] FIELDS = ["position", "count"];
4171 
4172 	public Tuple!(float, "x", float, "y", float, "z") position;
4173 	public int count;
4174 
4175 	public pure nothrow @safe @nogc this() {}
4176 
4177 	public pure nothrow @safe @nogc this(Tuple!(float, "x", float, "y", float, "z") position, int count=int.init) {
4178 		this.position = position;
4179 		this.count = count;
4180 	}
4181 
4182 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4183 		_buffer.length = 0;
4184 		static if(writeId){ writeBigEndianUbyte(ID); }
4185 		writeLittleEndianFloat(position.x); writeLittleEndianFloat(position.y); writeLittleEndianFloat(position.z);
4186 		writeBytes(varint.encode(count));
4187 		return _buffer;
4188 	}
4189 
4190 	public pure nothrow @safe void decode(bool readId=true)() {
4191 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4192 		position.x=readLittleEndianFloat(); position.y=readLittleEndianFloat(); position.z=readLittleEndianFloat();
4193 		count=varint.decode(_buffer, &_index);
4194 	}
4195 
4196 	public static pure nothrow @safe SpawnExperienceOrb fromBuffer(bool readId=true)(ubyte[] buffer) {
4197 		SpawnExperienceOrb ret = new SpawnExperienceOrb();
4198 		ret._buffer = buffer;
4199 		ret.decode!readId();
4200 		return ret;
4201 	}
4202 
4203 	public override string toString() {
4204 		return "SpawnExperienceOrb(position: " ~ std.conv.to!string(this.position) ~ ", count: " ~ std.conv.to!string(this.count) ~ ")";
4205 	}
4206 
4207 }
4208 
4209 class ClientboundMapItemData : Buffer {
4210 
4211 	public enum ubyte ID = 66;
4212 
4213 	public enum bool CLIENTBOUND = true;
4214 	public enum bool SERVERBOUND = false;
4215 
4216 	// update
4217 	public enum uint TEXTURE = 2;
4218 	public enum uint DECORATIONS = 4;
4219 	public enum uint ENTITIES = 8;
4220 
4221 	public enum string[] FIELDS = ["mapId", "update", "scale", "size", "offset", "data", "decorations"];
4222 
4223 	public long mapId;
4224 	public uint update;
4225 	public ubyte scale;
4226 
4227 	/**
4228 	 * Colums and rows.
4229 	 */
4230 	public Tuple!(int, "x", int, "z") size;
4231 	public Tuple!(int, "x", int, "z") offset;
4232 
4233 	/**
4234 	 * ARGB colours encoded as unsigned varints.
4235 	 */
4236 	public ubyte[] data;
4237 	public sul.protocol.pocket101.types.Decoration[] decorations;
4238 
4239 	public pure nothrow @safe @nogc this() {}
4240 
4241 	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.pocket101.types.Decoration[] decorations=(sul.protocol.pocket101.types.Decoration[]).init) {
4242 		this.mapId = mapId;
4243 		this.update = update;
4244 		this.scale = scale;
4245 		this.size = size;
4246 		this.offset = offset;
4247 		this.data = data;
4248 		this.decorations = decorations;
4249 	}
4250 
4251 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4252 		_buffer.length = 0;
4253 		static if(writeId){ writeBigEndianUbyte(ID); }
4254 		writeBytes(varlong.encode(mapId));
4255 		writeBytes(varuint.encode(update));
4256 		if(update==2||update==4){ writeBigEndianUbyte(scale); }
4257 		if(update==2){ writeBytes(varint.encode(size.x)); writeBytes(varint.encode(size.z)); }
4258 		if(update==2){ writeBytes(varint.encode(offset.x)); writeBytes(varint.encode(offset.z)); }
4259 		if(update==2){ writeBytes(data); }
4260 		if(update==4){ writeBytes(varuint.encode(cast(uint)decorations.length)); foreach(zvbjdlbm;decorations){ zvbjdlbm.encode(bufferInstance); } }
4261 		return _buffer;
4262 	}
4263 
4264 	public pure nothrow @safe void decode(bool readId=true)() {
4265 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4266 		mapId=varlong.decode(_buffer, &_index);
4267 		update=varuint.decode(_buffer, &_index);
4268 		if(update==2||update==4){ scale=readBigEndianUbyte(); }
4269 		if(update==2){ size.x=varint.decode(_buffer, &_index); size.z=varint.decode(_buffer, &_index); }
4270 		if(update==2){ offset.x=varint.decode(_buffer, &_index); offset.z=varint.decode(_buffer, &_index); }
4271 		if(update==2){ data=_buffer[_index..$].dup; _index=_buffer.length; }
4272 		if(update==4){ decorations.length=varuint.decode(_buffer, &_index); foreach(ref zvbjdlbm;decorations){ zvbjdlbm.decode(bufferInstance); } }
4273 	}
4274 
4275 	public static pure nothrow @safe ClientboundMapItemData fromBuffer(bool readId=true)(ubyte[] buffer) {
4276 		ClientboundMapItemData ret = new ClientboundMapItemData();
4277 		ret._buffer = buffer;
4278 		ret.decode!readId();
4279 		return ret;
4280 	}
4281 
4282 	public override string toString() {
4283 		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) ~ ")";
4284 	}
4285 
4286 }
4287 
4288 class MapInfoRequest : Buffer {
4289 
4290 	public enum ubyte ID = 67;
4291 
4292 	public enum bool CLIENTBOUND = false;
4293 	public enum bool SERVERBOUND = true;
4294 
4295 	public enum string[] FIELDS = ["mapId"];
4296 
4297 	public long mapId;
4298 
4299 	public pure nothrow @safe @nogc this() {}
4300 
4301 	public pure nothrow @safe @nogc this(long mapId) {
4302 		this.mapId = mapId;
4303 	}
4304 
4305 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4306 		_buffer.length = 0;
4307 		static if(writeId){ writeBigEndianUbyte(ID); }
4308 		writeBytes(varlong.encode(mapId));
4309 		return _buffer;
4310 	}
4311 
4312 	public pure nothrow @safe void decode(bool readId=true)() {
4313 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4314 		mapId=varlong.decode(_buffer, &_index);
4315 	}
4316 
4317 	public static pure nothrow @safe MapInfoRequest fromBuffer(bool readId=true)(ubyte[] buffer) {
4318 		MapInfoRequest ret = new MapInfoRequest();
4319 		ret._buffer = buffer;
4320 		ret.decode!readId();
4321 		return ret;
4322 	}
4323 
4324 	public override string toString() {
4325 		return "MapInfoRequest(mapId: " ~ std.conv.to!string(this.mapId) ~ ")";
4326 	}
4327 
4328 }
4329 
4330 /**
4331  * Packet sent by the client when its view-distance is updated and when it spawns for
4332  * the first time a world. A ChunkRadiusUpdate should always be sent in response, otherwise
4333  * the player will not update its view distance.
4334  */
4335 class RequestChunkRadius : Buffer {
4336 
4337 	public enum ubyte ID = 68;
4338 
4339 	public enum bool CLIENTBOUND = false;
4340 	public enum bool SERVERBOUND = true;
4341 
4342 	public enum string[] FIELDS = ["radius"];
4343 
4344 	/**
4345 	 * Number of chunks before the fog starts to appear in the client's view. The value
4346 	 * of this field is usually between 8 and 14.
4347 	 */
4348 	public int radius;
4349 
4350 	public pure nothrow @safe @nogc this() {}
4351 
4352 	public pure nothrow @safe @nogc this(int radius) {
4353 		this.radius = radius;
4354 	}
4355 
4356 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4357 		_buffer.length = 0;
4358 		static if(writeId){ writeBigEndianUbyte(ID); }
4359 		writeBytes(varint.encode(radius));
4360 		return _buffer;
4361 	}
4362 
4363 	public pure nothrow @safe void decode(bool readId=true)() {
4364 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4365 		radius=varint.decode(_buffer, &_index);
4366 	}
4367 
4368 	public static pure nothrow @safe RequestChunkRadius fromBuffer(bool readId=true)(ubyte[] buffer) {
4369 		RequestChunkRadius ret = new RequestChunkRadius();
4370 		ret._buffer = buffer;
4371 		ret.decode!readId();
4372 		return ret;
4373 	}
4374 
4375 	public override string toString() {
4376 		return "RequestChunkRadius(radius: " ~ std.conv.to!string(this.radius) ~ ")";
4377 	}
4378 
4379 }
4380 
4381 /**
4382  * Packet sent always and only in response to RequestChunkRadius to change the client's
4383  * view distance.
4384  */
4385 class ChunkRadiusUpdated : Buffer {
4386 
4387 	public enum ubyte ID = 69;
4388 
4389 	public enum bool CLIENTBOUND = true;
4390 	public enum bool SERVERBOUND = false;
4391 
4392 	public enum string[] FIELDS = ["radius"];
4393 
4394 	/**
4395 	 * View distance that may be different from the client's one if the server sets a limit
4396 	 * on the view distance.
4397 	 */
4398 	public int radius;
4399 
4400 	public pure nothrow @safe @nogc this() {}
4401 
4402 	public pure nothrow @safe @nogc this(int radius) {
4403 		this.radius = radius;
4404 	}
4405 
4406 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4407 		_buffer.length = 0;
4408 		static if(writeId){ writeBigEndianUbyte(ID); }
4409 		writeBytes(varint.encode(radius));
4410 		return _buffer;
4411 	}
4412 
4413 	public pure nothrow @safe void decode(bool readId=true)() {
4414 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4415 		radius=varint.decode(_buffer, &_index);
4416 	}
4417 
4418 	public static pure nothrow @safe ChunkRadiusUpdated fromBuffer(bool readId=true)(ubyte[] buffer) {
4419 		ChunkRadiusUpdated ret = new ChunkRadiusUpdated();
4420 		ret._buffer = buffer;
4421 		ret.decode!readId();
4422 		return ret;
4423 	}
4424 
4425 	public override string toString() {
4426 		return "ChunkRadiusUpdated(radius: " ~ std.conv.to!string(this.radius) ~ ")";
4427 	}
4428 
4429 }
4430 
4431 class ItemFrameDropItem : Buffer {
4432 
4433 	public enum ubyte ID = 70;
4434 
4435 	public enum bool CLIENTBOUND = true;
4436 	public enum bool SERVERBOUND = false;
4437 
4438 	public enum string[] FIELDS = ["position", "item"];
4439 
4440 	public sul.protocol.pocket101.types.BlockPosition position;
4441 	public sul.protocol.pocket101.types.Slot item;
4442 
4443 	public pure nothrow @safe @nogc this() {}
4444 
4445 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.types.BlockPosition position, sul.protocol.pocket101.types.Slot item=sul.protocol.pocket101.types.Slot.init) {
4446 		this.position = position;
4447 		this.item = item;
4448 	}
4449 
4450 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4451 		_buffer.length = 0;
4452 		static if(writeId){ writeBigEndianUbyte(ID); }
4453 		position.encode(bufferInstance);
4454 		item.encode(bufferInstance);
4455 		return _buffer;
4456 	}
4457 
4458 	public pure nothrow @safe void decode(bool readId=true)() {
4459 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4460 		position.decode(bufferInstance);
4461 		item.decode(bufferInstance);
4462 	}
4463 
4464 	public static pure nothrow @safe ItemFrameDropItem fromBuffer(bool readId=true)(ubyte[] buffer) {
4465 		ItemFrameDropItem ret = new ItemFrameDropItem();
4466 		ret._buffer = buffer;
4467 		ret.decode!readId();
4468 		return ret;
4469 	}
4470 
4471 	public override string toString() {
4472 		return "ItemFrameDropItem(position: " ~ std.conv.to!string(this.position) ~ ", item: " ~ std.conv.to!string(this.item) ~ ")";
4473 	}
4474 
4475 }
4476 
4477 class ReplaceSelectedItem : Buffer {
4478 
4479 	public enum ubyte ID = 71;
4480 
4481 	public enum bool CLIENTBOUND = false;
4482 	public enum bool SERVERBOUND = true;
4483 
4484 	public enum string[] FIELDS = ["item"];
4485 
4486 	public sul.protocol.pocket101.types.Slot item;
4487 
4488 	public pure nothrow @safe @nogc this() {}
4489 
4490 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.types.Slot item) {
4491 		this.item = item;
4492 	}
4493 
4494 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4495 		_buffer.length = 0;
4496 		static if(writeId){ writeBigEndianUbyte(ID); }
4497 		item.encode(bufferInstance);
4498 		return _buffer;
4499 	}
4500 
4501 	public pure nothrow @safe void decode(bool readId=true)() {
4502 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4503 		item.decode(bufferInstance);
4504 	}
4505 
4506 	public static pure nothrow @safe ReplaceSelectedItem fromBuffer(bool readId=true)(ubyte[] buffer) {
4507 		ReplaceSelectedItem ret = new ReplaceSelectedItem();
4508 		ret._buffer = buffer;
4509 		ret.decode!readId();
4510 		return ret;
4511 	}
4512 
4513 	public override string toString() {
4514 		return "ReplaceSelectedItem(item: " ~ std.conv.to!string(this.item) ~ ")";
4515 	}
4516 
4517 }
4518 
4519 /**
4520  * Updates client's game rules. This packet is ignored if the game is not launched
4521  * as Education Edition and should be avoid in favour of AdventureSettings, with which
4522  * the same result can be obtained with less data.
4523  */
4524 class GameRulesChanged : Buffer {
4525 
4526 	public enum ubyte ID = 72;
4527 
4528 	public enum bool CLIENTBOUND = true;
4529 	public enum bool SERVERBOUND = false;
4530 
4531 	public enum string[] FIELDS = ["rules"];
4532 
4533 	public sul.protocol.pocket101.types.Rule[] rules;
4534 
4535 	public pure nothrow @safe @nogc this() {}
4536 
4537 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.types.Rule[] rules) {
4538 		this.rules = rules;
4539 	}
4540 
4541 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4542 		_buffer.length = 0;
4543 		static if(writeId){ writeBigEndianUbyte(ID); }
4544 		writeBigEndianUint(cast(uint)rules.length); foreach(cvzm;rules){ cvzm.encode(bufferInstance); }
4545 		return _buffer;
4546 	}
4547 
4548 	public pure nothrow @safe void decode(bool readId=true)() {
4549 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4550 		rules.length=readBigEndianUint(); foreach(ref cvzm;rules){ cvzm.decode(bufferInstance); }
4551 	}
4552 
4553 	public static pure nothrow @safe GameRulesChanged fromBuffer(bool readId=true)(ubyte[] buffer) {
4554 		GameRulesChanged ret = new GameRulesChanged();
4555 		ret._buffer = buffer;
4556 		ret.decode!readId();
4557 		return ret;
4558 	}
4559 
4560 	public override string toString() {
4561 		return "GameRulesChanged(rules: " ~ std.conv.to!string(this.rules) ~ ")";
4562 	}
4563 
4564 }
4565 
4566 class Camera : Buffer {
4567 
4568 	public enum ubyte ID = 73;
4569 
4570 	public enum bool CLIENTBOUND = true;
4571 	public enum bool SERVERBOUND = false;
4572 
4573 	public enum string[] FIELDS = ["unknown0", "unknown1"];
4574 
4575 	public long unknown0;
4576 	public long unknown1;
4577 
4578 	public pure nothrow @safe @nogc this() {}
4579 
4580 	public pure nothrow @safe @nogc this(long unknown0, long unknown1=long.init) {
4581 		this.unknown0 = unknown0;
4582 		this.unknown1 = unknown1;
4583 	}
4584 
4585 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4586 		_buffer.length = 0;
4587 		static if(writeId){ writeBigEndianUbyte(ID); }
4588 		writeBytes(varlong.encode(unknown0));
4589 		writeBytes(varlong.encode(unknown1));
4590 		return _buffer;
4591 	}
4592 
4593 	public pure nothrow @safe void decode(bool readId=true)() {
4594 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4595 		unknown0=varlong.decode(_buffer, &_index);
4596 		unknown1=varlong.decode(_buffer, &_index);
4597 	}
4598 
4599 	public static pure nothrow @safe Camera fromBuffer(bool readId=true)(ubyte[] buffer) {
4600 		Camera ret = new Camera();
4601 		ret._buffer = buffer;
4602 		ret.decode!readId();
4603 		return ret;
4604 	}
4605 
4606 	public override string toString() {
4607 		return "Camera(unknown0: " ~ std.conv.to!string(this.unknown0) ~ ", unknown1: " ~ std.conv.to!string(this.unknown1) ~ ")";
4608 	}
4609 
4610 }
4611 
4612 class AddItem : Buffer {
4613 
4614 	public enum ubyte ID = 74;
4615 
4616 	public enum bool CLIENTBOUND = true;
4617 	public enum bool SERVERBOUND = false;
4618 
4619 	public enum string[] FIELDS = ["item"];
4620 
4621 	public sul.protocol.pocket101.types.Slot item;
4622 
4623 	public pure nothrow @safe @nogc this() {}
4624 
4625 	public pure nothrow @safe @nogc this(sul.protocol.pocket101.types.Slot item) {
4626 		this.item = item;
4627 	}
4628 
4629 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4630 		_buffer.length = 0;
4631 		static if(writeId){ writeBigEndianUbyte(ID); }
4632 		item.encode(bufferInstance);
4633 		return _buffer;
4634 	}
4635 
4636 	public pure nothrow @safe void decode(bool readId=true)() {
4637 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4638 		item.decode(bufferInstance);
4639 	}
4640 
4641 	public static pure nothrow @safe AddItem fromBuffer(bool readId=true)(ubyte[] buffer) {
4642 		AddItem ret = new AddItem();
4643 		ret._buffer = buffer;
4644 		ret.decode!readId();
4645 		return ret;
4646 	}
4647 
4648 	public override string toString() {
4649 		return "AddItem(item: " ~ std.conv.to!string(this.item) ~ ")";
4650 	}
4651 
4652 }
4653 
4654 /**
4655  * Adds, removes or modifies an entity's boss bar. The percentage of the bar is calculated
4656  * using the entity's attributes for the health and the max health, updated with UpdateAttributes.
4657  */
4658 class BossEvent : Buffer {
4659 
4660 	public enum ubyte ID = 75;
4661 
4662 	public enum bool CLIENTBOUND = true;
4663 	public enum bool SERVERBOUND = false;
4664 
4665 	// event id
4666 	public enum uint ADD = 0;
4667 	public enum uint UPDATE = 1;
4668 	public enum uint REMOVE = 2;
4669 
4670 	public enum string[] FIELDS = ["entityId", "eventId"];
4671 
4672 	public long entityId;
4673 	public uint eventId;
4674 
4675 	public pure nothrow @safe @nogc this() {}
4676 
4677 	public pure nothrow @safe @nogc this(long entityId, uint eventId=uint.init) {
4678 		this.entityId = entityId;
4679 		this.eventId = eventId;
4680 	}
4681 
4682 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4683 		_buffer.length = 0;
4684 		static if(writeId){ writeBigEndianUbyte(ID); }
4685 		writeBytes(varlong.encode(entityId));
4686 		writeBytes(varuint.encode(eventId));
4687 		return _buffer;
4688 	}
4689 
4690 	public pure nothrow @safe void decode(bool readId=true)() {
4691 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4692 		entityId=varlong.decode(_buffer, &_index);
4693 		eventId=varuint.decode(_buffer, &_index);
4694 	}
4695 
4696 	public static pure nothrow @safe BossEvent fromBuffer(bool readId=true)(ubyte[] buffer) {
4697 		BossEvent ret = new BossEvent();
4698 		ret._buffer = buffer;
4699 		ret.decode!readId();
4700 		return ret;
4701 	}
4702 
4703 	public override string toString() {
4704 		return "BossEvent(entityId: " ~ std.conv.to!string(this.entityId) ~ ", eventId: " ~ std.conv.to!string(this.eventId) ~ ")";
4705 	}
4706 
4707 }
4708 
4709 class ShowCredits : Buffer {
4710 
4711 	public enum ubyte ID = 76;
4712 
4713 	public enum bool CLIENTBOUND = true;
4714 	public enum bool SERVERBOUND = true;
4715 
4716 	// status
4717 	public enum int START = 0;
4718 	public enum int END = 1;
4719 
4720 	public enum string[] FIELDS = ["entityId", "status"];
4721 
4722 	public long entityId;
4723 	public int status;
4724 
4725 	public pure nothrow @safe @nogc this() {}
4726 
4727 	public pure nothrow @safe @nogc this(long entityId, int status=int.init) {
4728 		this.entityId = entityId;
4729 		this.status = status;
4730 	}
4731 
4732 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4733 		_buffer.length = 0;
4734 		static if(writeId){ writeBigEndianUbyte(ID); }
4735 		writeBytes(varlong.encode(entityId));
4736 		writeBytes(varint.encode(status));
4737 		return _buffer;
4738 	}
4739 
4740 	public pure nothrow @safe void decode(bool readId=true)() {
4741 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4742 		entityId=varlong.decode(_buffer, &_index);
4743 		status=varint.decode(_buffer, &_index);
4744 	}
4745 
4746 	public static pure nothrow @safe ShowCredits fromBuffer(bool readId=true)(ubyte[] buffer) {
4747 		ShowCredits ret = new ShowCredits();
4748 		ret._buffer = buffer;
4749 		ret.decode!readId();
4750 		return ret;
4751 	}
4752 
4753 	public override string toString() {
4754 		return "ShowCredits(entityId: " ~ std.conv.to!string(this.entityId) ~ ", status: " ~ std.conv.to!string(this.status) ~ ")";
4755 	}
4756 
4757 }
4758 
4759 /**
4760  * Sends a list of the commands that the player can use through the CommandStep packet.
4761  */
4762 class AvailableCommands : Buffer {
4763 
4764 	public enum ubyte ID = 77;
4765 
4766 	public enum bool CLIENTBOUND = true;
4767 	public enum bool SERVERBOUND = false;
4768 
4769 	public enum string[] FIELDS = ["commands", "unknown1"];
4770 
4771 	/**
4772 	 * JSON object with the commands.
4773 	 */
4774 	public string commands;
4775 	public string unknown1;
4776 
4777 	public pure nothrow @safe @nogc this() {}
4778 
4779 	public pure nothrow @safe @nogc this(string commands, string unknown1=string.init) {
4780 		this.commands = commands;
4781 		this.unknown1 = unknown1;
4782 	}
4783 
4784 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4785 		_buffer.length = 0;
4786 		static if(writeId){ writeBigEndianUbyte(ID); }
4787 		writeBytes(varuint.encode(cast(uint)commands.length)); writeString(commands);
4788 		writeBytes(varuint.encode(cast(uint)unknown1.length)); writeString(unknown1);
4789 		return _buffer;
4790 	}
4791 
4792 	public pure nothrow @safe void decode(bool readId=true)() {
4793 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4794 		uint y9bfzm=varuint.decode(_buffer, &_index); commands=readString(y9bfzm);
4795 		uint d5b9be=varuint.decode(_buffer, &_index); unknown1=readString(d5b9be);
4796 	}
4797 
4798 	public static pure nothrow @safe AvailableCommands fromBuffer(bool readId=true)(ubyte[] buffer) {
4799 		AvailableCommands ret = new AvailableCommands();
4800 		ret._buffer = buffer;
4801 		ret.decode!readId();
4802 		return ret;
4803 	}
4804 
4805 	public override string toString() {
4806 		return "AvailableCommands(commands: " ~ std.conv.to!string(this.commands) ~ ", unknown1: " ~ std.conv.to!string(this.unknown1) ~ ")";
4807 	}
4808 
4809 }
4810 
4811 class CommandStep : Buffer {
4812 
4813 	public enum ubyte ID = 78;
4814 
4815 	public enum bool CLIENTBOUND = false;
4816 	public enum bool SERVERBOUND = true;
4817 
4818 	public enum string[] FIELDS = ["command", "overload", "unknown2", "currentStep", "done", "clientId", "input", "output"];
4819 
4820 	public string command;
4821 	public string overload;
4822 	public uint unknown2;
4823 	public uint currentStep;
4824 	public bool done;
4825 	public ulong clientId;
4826 	public string input;
4827 	public string output;
4828 
4829 	public pure nothrow @safe @nogc this() {}
4830 
4831 	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) {
4832 		this.command = command;
4833 		this.overload = overload;
4834 		this.unknown2 = unknown2;
4835 		this.currentStep = currentStep;
4836 		this.done = done;
4837 		this.clientId = clientId;
4838 		this.input = input;
4839 		this.output = output;
4840 	}
4841 
4842 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4843 		_buffer.length = 0;
4844 		static if(writeId){ writeBigEndianUbyte(ID); }
4845 		writeBytes(varuint.encode(cast(uint)command.length)); writeString(command);
4846 		writeBytes(varuint.encode(cast(uint)overload.length)); writeString(overload);
4847 		writeBytes(varuint.encode(unknown2));
4848 		writeBytes(varuint.encode(currentStep));
4849 		writeBigEndianBool(done);
4850 		writeBytes(varulong.encode(clientId));
4851 		writeBytes(varuint.encode(cast(uint)input.length)); writeString(input);
4852 		writeBytes(varuint.encode(cast(uint)output.length)); writeString(output);
4853 		return _buffer;
4854 	}
4855 
4856 	public pure nothrow @safe void decode(bool readId=true)() {
4857 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4858 		uint y9bfz=varuint.decode(_buffer, &_index); command=readString(y9bfz);
4859 		uint bzcxyq=varuint.decode(_buffer, &_index); overload=readString(bzcxyq);
4860 		unknown2=varuint.decode(_buffer, &_index);
4861 		currentStep=varuint.decode(_buffer, &_index);
4862 		done=readBigEndianBool();
4863 		clientId=varulong.decode(_buffer, &_index);
4864 		uint a5dq=varuint.decode(_buffer, &_index); input=readString(a5dq);
4865 		uint bvcv=varuint.decode(_buffer, &_index); output=readString(bvcv);
4866 	}
4867 
4868 	public static pure nothrow @safe CommandStep fromBuffer(bool readId=true)(ubyte[] buffer) {
4869 		CommandStep ret = new CommandStep();
4870 		ret._buffer = buffer;
4871 		ret.decode!readId();
4872 		return ret;
4873 	}
4874 
4875 	public override string toString() {
4876 		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) ~ ")";
4877 	}
4878 
4879 }
4880 
4881 class ResourcePackDataInfo : Buffer {
4882 
4883 	public enum ubyte ID = 79;
4884 
4885 	public enum bool CLIENTBOUND = true;
4886 	public enum bool SERVERBOUND = false;
4887 
4888 	public enum string[] FIELDS = ["id", "maxChunkSize", "chunkCount", "compressedPackSize", "sha256"];
4889 
4890 	public string id;
4891 	public uint maxChunkSize;
4892 	public uint chunkCount;
4893 	public ulong compressedPackSize;
4894 	public string sha256;
4895 
4896 	public pure nothrow @safe @nogc this() {}
4897 
4898 	public pure nothrow @safe @nogc this(string id, uint maxChunkSize=uint.init, uint chunkCount=uint.init, ulong compressedPackSize=ulong.init, string sha256=string.init) {
4899 		this.id = id;
4900 		this.maxChunkSize = maxChunkSize;
4901 		this.chunkCount = chunkCount;
4902 		this.compressedPackSize = compressedPackSize;
4903 		this.sha256 = sha256;
4904 	}
4905 
4906 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4907 		_buffer.length = 0;
4908 		static if(writeId){ writeBigEndianUbyte(ID); }
4909 		writeBytes(varuint.encode(cast(uint)id.length)); writeString(id);
4910 		writeLittleEndianUint(maxChunkSize);
4911 		writeLittleEndianUint(chunkCount);
4912 		writeLittleEndianUlong(compressedPackSize);
4913 		writeBytes(varuint.encode(cast(uint)sha256.length)); writeString(sha256);
4914 		return _buffer;
4915 	}
4916 
4917 	public pure nothrow @safe void decode(bool readId=true)() {
4918 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4919 		uint aq=varuint.decode(_buffer, &_index); id=readString(aq);
4920 		maxChunkSize=readLittleEndianUint();
4921 		chunkCount=readLittleEndianUint();
4922 		compressedPackSize=readLittleEndianUlong();
4923 		uint chmu=varuint.decode(_buffer, &_index); sha256=readString(chmu);
4924 	}
4925 
4926 	public static pure nothrow @safe ResourcePackDataInfo fromBuffer(bool readId=true)(ubyte[] buffer) {
4927 		ResourcePackDataInfo ret = new ResourcePackDataInfo();
4928 		ret._buffer = buffer;
4929 		ret.decode!readId();
4930 		return ret;
4931 	}
4932 
4933 	public override string toString() {
4934 		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) ~ ")";
4935 	}
4936 
4937 }
4938 
4939 class ResourcePackChunkData : Buffer {
4940 
4941 	public enum ubyte ID = 80;
4942 
4943 	public enum bool CLIENTBOUND = true;
4944 	public enum bool SERVERBOUND = false;
4945 
4946 	public enum string[] FIELDS = ["id", "chunkIndex", "progress", "data"];
4947 
4948 	public string id;
4949 	public uint chunkIndex;
4950 	public ulong progress;
4951 	public ubyte[] data;
4952 
4953 	public pure nothrow @safe @nogc this() {}
4954 
4955 	public pure nothrow @safe @nogc this(string id, uint chunkIndex=uint.init, ulong progress=ulong.init, ubyte[] data=(ubyte[]).init) {
4956 		this.id = id;
4957 		this.chunkIndex = chunkIndex;
4958 		this.progress = progress;
4959 		this.data = data;
4960 	}
4961 
4962 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
4963 		_buffer.length = 0;
4964 		static if(writeId){ writeBigEndianUbyte(ID); }
4965 		writeBytes(varuint.encode(cast(uint)id.length)); writeString(id);
4966 		writeLittleEndianUint(chunkIndex);
4967 		writeLittleEndianUlong(progress);
4968 		writeBytes(varuint.encode(cast(uint)data.length)); writeBytes(data);
4969 		return _buffer;
4970 	}
4971 
4972 	public pure nothrow @safe void decode(bool readId=true)() {
4973 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
4974 		uint aq=varuint.decode(_buffer, &_index); id=readString(aq);
4975 		chunkIndex=readLittleEndianUint();
4976 		progress=readLittleEndianUlong();
4977 		data.length=varuint.decode(_buffer, &_index); if(_buffer.length>=_index+data.length){ data=_buffer[_index.._index+data.length].dup; _index+=data.length; }
4978 	}
4979 
4980 	public static pure nothrow @safe ResourcePackChunkData fromBuffer(bool readId=true)(ubyte[] buffer) {
4981 		ResourcePackChunkData ret = new ResourcePackChunkData();
4982 		ret._buffer = buffer;
4983 		ret.decode!readId();
4984 		return ret;
4985 	}
4986 
4987 	public override string toString() {
4988 		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) ~ ")";
4989 	}
4990 
4991 }
4992 
4993 class ResourcePackChunkRequest : Buffer {
4994 
4995 	public enum ubyte ID = 81;
4996 
4997 	public enum bool CLIENTBOUND = false;
4998 	public enum bool SERVERBOUND = true;
4999 
5000 	public enum string[] FIELDS = ["id", "chunkIndex"];
5001 
5002 	public string id;
5003 	public uint chunkIndex;
5004 
5005 	public pure nothrow @safe @nogc this() {}
5006 
5007 	public pure nothrow @safe @nogc this(string id, uint chunkIndex=uint.init) {
5008 		this.id = id;
5009 		this.chunkIndex = chunkIndex;
5010 	}
5011 
5012 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
5013 		_buffer.length = 0;
5014 		static if(writeId){ writeBigEndianUbyte(ID); }
5015 		writeBytes(varuint.encode(cast(uint)id.length)); writeString(id);
5016 		writeLittleEndianUint(chunkIndex);
5017 		return _buffer;
5018 	}
5019 
5020 	public pure nothrow @safe void decode(bool readId=true)() {
5021 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
5022 		uint aq=varuint.decode(_buffer, &_index); id=readString(aq);
5023 		chunkIndex=readLittleEndianUint();
5024 	}
5025 
5026 	public static pure nothrow @safe ResourcePackChunkRequest fromBuffer(bool readId=true)(ubyte[] buffer) {
5027 		ResourcePackChunkRequest ret = new ResourcePackChunkRequest();
5028 		ret._buffer = buffer;
5029 		ret.decode!readId();
5030 		return ret;
5031 	}
5032 
5033 	public override string toString() {
5034 		return "ResourcePackChunkRequest(id: " ~ std.conv.to!string(this.id) ~ ", chunkIndex: " ~ std.conv.to!string(this.chunkIndex) ~ ")";
5035 	}
5036 
5037 }
5038 
5039 /**
5040  * Transfers the player to another server. Once transferred the player will immediately
5041  * close the connection with the transferring server, try to resolve the ip and join
5042  * the new server starting a new raknet session.
5043  */
5044 class Transfer : Buffer {
5045 
5046 	public enum ubyte ID = 82;
5047 
5048 	public enum bool CLIENTBOUND = true;
5049 	public enum bool SERVERBOUND = false;
5050 
5051 	public enum string[] FIELDS = ["ip", "port"];
5052 
5053 	/**
5054 	 * Address of the new server. It can be an dotted ip (for example `127.0.0.1`) or an
5055 	 * URI (for example `localhost` or `play.example.com`). Only IP of version 4 are currently
5056 	 * allowed.
5057 	 */
5058 	public string ip;
5059 
5060 	/**
5061 	 * Port of the new server. If 0 the server will try to connect to the default port.
5062 	 */
5063 	public ushort port = 19132;
5064 
5065 	public pure nothrow @safe @nogc this() {}
5066 
5067 	public pure nothrow @safe @nogc this(string ip, ushort port=19132) {
5068 		this.ip = ip;
5069 		this.port = port;
5070 	}
5071 
5072 	public pure nothrow @safe ubyte[] encode(bool writeId=true)() {
5073 		_buffer.length = 0;
5074 		static if(writeId){ writeBigEndianUbyte(ID); }
5075 		writeBytes(varuint.encode(cast(uint)ip.length)); writeString(ip);
5076 		writeLittleEndianUshort(port);
5077 		return _buffer;
5078 	}
5079 
5080 	public pure nothrow @safe void decode(bool readId=true)() {
5081 		static if(readId){ ubyte _id; _id=readBigEndianUbyte(); }
5082 		uint aa=varuint.decode(_buffer, &_index); ip=readString(aa);
5083 		port=readLittleEndianUshort();
5084 	}
5085 
5086 	public static pure nothrow @safe Transfer fromBuffer(bool readId=true)(ubyte[] buffer) {
5087 		Transfer ret = new Transfer();
5088 		ret._buffer = buffer;
5089 		ret.decode!readId();
5090 		return ret;
5091 	}
5092 
5093 	public override string toString() {
5094 		return "Transfer(ip: " ~ std.conv.to!string(this.ip) ~ ", port: " ~ std.conv.to!string(this.port) ~ ")";
5095 	}
5096 
5097 }
5098