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 module sul.protocol.pocket101.types;
10 
11 import std.bitmanip : write, peek;
12 static import std.conv;
13 import std.system : Endian;
14 import std.typecons : Tuple;
15 import std.uuid : UUID;
16 
17 import sul.utils.buffer;
18 import sul.utils.var;
19 
20 static if(__traits(compiles, { import sul.metadata.pocket101; })) import sul.metadata.pocket101;
21 
22 struct PackWithSize {
23 
24 	public enum string[] FIELDS = ["id", "vers", "size"];
25 
26 	public string id;
27 	public string vers;
28 	public ulong size;
29 
30 	public pure nothrow @safe void encode(Buffer buffer) {
31 		with(buffer) {
32 			writeBytes(varuint.encode(cast(uint)id.length)); writeString(id);
33 			writeBytes(varuint.encode(cast(uint)vers.length)); writeString(vers);
34 			writeLittleEndianUlong(size);
35 		}
36 	}
37 
38 	public pure nothrow @safe void decode(Buffer buffer) {
39 		with(buffer) {
40 			uint aq=varuint.decode(_buffer, &_index); id=readString(aq);
41 			uint dvc=varuint.decode(_buffer, &_index); vers=readString(dvc);
42 			size=readLittleEndianUlong();
43 		}
44 	}
45 
46 	public string toString() {
47 		return "PackWithSize(id: " ~ std.conv.to!string(this.id) ~ ", vers: " ~ std.conv.to!string(this.vers) ~ ", size: " ~ std.conv.to!string(this.size) ~ ")";
48 	}
49 
50 }
51 
52 struct Pack {
53 
54 	public enum string[] FIELDS = ["id", "vers"];
55 
56 	public string id;
57 	public string vers;
58 
59 	public pure nothrow @safe void encode(Buffer buffer) {
60 		with(buffer) {
61 			writeBytes(varuint.encode(cast(uint)id.length)); writeString(id);
62 			writeBytes(varuint.encode(cast(uint)vers.length)); writeString(vers);
63 		}
64 	}
65 
66 	public pure nothrow @safe void decode(Buffer buffer) {
67 		with(buffer) {
68 			uint aq=varuint.decode(_buffer, &_index); id=readString(aq);
69 			uint dvc=varuint.decode(_buffer, &_index); vers=readString(dvc);
70 		}
71 	}
72 
73 	public string toString() {
74 		return "Pack(id: " ~ std.conv.to!string(this.id) ~ ", vers: " ~ std.conv.to!string(this.vers) ~ ")";
75 	}
76 
77 }
78 
79 /**
80  * Informations about a slot, that, if not empty, contains an item id and meta, the
81  * count (0-255) and, optionally, an nbt tag for enchantments, custom name, colours
82  * and more.
83  */
84 struct Slot {
85 
86 	public enum string[] FIELDS = ["id", "metaAndCount", "nbt"];
87 
88 	/**
89 	 * Item's id or 0 if the slot is empty.
90 	 */
91 	public int id;
92 
93 	/**
94 	 * Item's meta or uses (unsigned short) left-shifted 8 times and the count (unisgned
95 	 * byte).
96 	 * Examples:
97 	 * ---
98 	 * var encoded = item.meta << 8 | item.count
99 	 * var meta = encoded >> 8
100 	 * var count = count & 255
101 	 * ---
102 	 */
103 	public int metaAndCount;
104 
105 	/**
106 	 * Optional nbt data encoded as a nameless little-endian compound tag.
107 	 */
108 	public ubyte[] nbt;
109 
110 	public pure nothrow @safe void encode(Buffer buffer) {
111 		with(buffer) {
112 			writeBytes(varint.encode(id));
113 			if(id>0){ writeBytes(varint.encode(metaAndCount)); }
114 			if(id>0){ writeLittleEndianUshort(cast(ushort)nbt.length); writeBytes(nbt); }
115 		}
116 	}
117 
118 	public pure nothrow @safe void decode(Buffer buffer) {
119 		with(buffer) {
120 			id=varint.decode(_buffer, &_index);
121 			if(id>0){ metaAndCount=varint.decode(_buffer, &_index); }
122 			if(id>0){ nbt.length=readLittleEndianUshort(); if(_buffer.length>=_index+nbt.length){ nbt=_buffer[_index.._index+nbt.length].dup; _index+=nbt.length; } }
123 		}
124 	}
125 
126 	public string toString() {
127 		return "Slot(id: " ~ std.conv.to!string(this.id) ~ ", metaAndCount: " ~ std.conv.to!string(this.metaAndCount) ~ ", nbt: " ~ std.conv.to!string(this.nbt) ~ ")";
128 	}
129 
130 }
131 
132 struct Attribute {
133 
134 	public enum string[] FIELDS = ["min", "max", "value", "def", "name"];
135 
136 	public float min;
137 	public float max;
138 	public float value;
139 	public float def;
140 	public string name;
141 
142 	public pure nothrow @safe void encode(Buffer buffer) {
143 		with(buffer) {
144 			writeLittleEndianFloat(min);
145 			writeLittleEndianFloat(max);
146 			writeLittleEndianFloat(value);
147 			writeLittleEndianFloat(def);
148 			writeBytes(varuint.encode(cast(uint)name.length)); writeString(name);
149 		}
150 	}
151 
152 	public pure nothrow @safe void decode(Buffer buffer) {
153 		with(buffer) {
154 			min=readLittleEndianFloat();
155 			max=readLittleEndianFloat();
156 			value=readLittleEndianFloat();
157 			def=readLittleEndianFloat();
158 			uint bfz=varuint.decode(_buffer, &_index); name=readString(bfz);
159 		}
160 	}
161 
162 	public string toString() {
163 		return "Attribute(min: " ~ std.conv.to!string(this.min) ~ ", max: " ~ std.conv.to!string(this.max) ~ ", value: " ~ std.conv.to!string(this.value) ~ ", def: " ~ std.conv.to!string(this.def) ~ ", name: " ~ std.conv.to!string(this.name) ~ ")";
164 	}
165 
166 }
167 
168 /**
169  * Position of a block, where x and z are signed and y is always positive (as blocks
170  * cannot be placed under 0).
171  */
172 struct BlockPosition {
173 
174 	public enum string[] FIELDS = ["x", "y", "z"];
175 
176 	public int x;
177 	public uint y;
178 	public int z;
179 
180 	public pure nothrow @safe void encode(Buffer buffer) {
181 		with(buffer) {
182 			writeBytes(varint.encode(x));
183 			writeBytes(varuint.encode(y));
184 			writeBytes(varint.encode(z));
185 		}
186 	}
187 
188 	public pure nothrow @safe void decode(Buffer buffer) {
189 		with(buffer) {
190 			x=varint.decode(_buffer, &_index);
191 			y=varuint.decode(_buffer, &_index);
192 			z=varint.decode(_buffer, &_index);
193 		}
194 	}
195 
196 	public string toString() {
197 		return "BlockPosition(x: " ~ std.conv.to!string(this.x) ~ ", y: " ~ std.conv.to!string(this.y) ~ ", z: " ~ std.conv.to!string(this.z) ~ ")";
198 	}
199 
200 }
201 
202 /**
203  * Player's skin.
204  */
205 struct Skin {
206 
207 	public enum string[] FIELDS = ["name", "data"];
208 
209 	/**
210 	 * Name of the skin. It's used to render the shape of the skin correctly.
211 	 */
212 	public string name;
213 
214 	/**
215 	 * Bytes of the skin in format RGBA. The length should be 8192 or 16382.
216 	 */
217 	public ubyte[] data;
218 
219 	public pure nothrow @safe void encode(Buffer buffer) {
220 		with(buffer) {
221 			writeBytes(varuint.encode(cast(uint)name.length)); writeString(name);
222 			writeBytes(varuint.encode(cast(uint)data.length)); writeBytes(data);
223 		}
224 	}
225 
226 	public pure nothrow @safe void decode(Buffer buffer) {
227 		with(buffer) {
228 			uint bfz=varuint.decode(_buffer, &_index); name=readString(bfz);
229 			data.length=varuint.decode(_buffer, &_index); if(_buffer.length>=_index+data.length){ data=_buffer[_index.._index+data.length].dup; _index+=data.length; }
230 		}
231 	}
232 
233 	public string toString() {
234 		return "Skin(name: " ~ std.conv.to!string(this.name) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
235 	}
236 
237 }
238 
239 /**
240  * Informations about a player that will be added to the player's list in the pause
241  * menu.
242  */
243 struct PlayerList {
244 
245 	public enum string[] FIELDS = ["uuid", "entityId", "displayName", "skin"];
246 
247 	/**
248 	 * UUID of the player. If it's associated with an XBOX Live account the player's profile
249 	 * will also be available in pause menu.
250 	 */
251 	public UUID uuid;
252 
253 	/**
254 	 * Player's id, used to associate the skin with the game's entity spawned with AddPlayer.
255 	 */
256 	public long entityId;
257 
258 	/**
259 	 * Player's display name, that can contain Minecraft's formatting codes. It shouldn't
260 	 * contain suffixes nor prefixes.
261 	 */
262 	public string displayName;
263 
264 	/**
265 	 * Player's skin usually given in the Login's packet body.
266 	 */
267 	public sul.protocol.pocket101.types.Skin skin;
268 
269 	public pure nothrow @safe void encode(Buffer buffer) {
270 		with(buffer) {
271 			writeBytes(uuid.data);
272 			writeBytes(varlong.encode(entityId));
273 			writeBytes(varuint.encode(cast(uint)displayName.length)); writeString(displayName);
274 			skin.encode(bufferInstance);
275 		}
276 	}
277 
278 	public pure nothrow @safe void decode(Buffer buffer) {
279 		with(buffer) {
280 			if(_buffer.length>=_index+16){ ubyte[16] dvz=_buffer[_index.._index+16].dup; _index+=16; uuid=UUID(dvz); }
281 			entityId=varlong.decode(_buffer, &_index);
282 			uint zlcxe5bu=varuint.decode(_buffer, &_index); displayName=readString(zlcxe5bu);
283 			skin.decode(bufferInstance);
284 		}
285 	}
286 
287 	public string toString() {
288 		return "PlayerList(uuid: " ~ std.conv.to!string(this.uuid) ~ ", entityId: " ~ std.conv.to!string(this.entityId) ~ ", displayName: " ~ std.conv.to!string(this.displayName) ~ ", skin: " ~ std.conv.to!string(this.skin) ~ ")";
289 	}
290 
291 }
292 
293 struct Link {
294 
295 	// action
296 	public enum ubyte ADD = 0;
297 	public enum ubyte RIDE = 1;
298 	public enum ubyte REMOVE = 2;
299 
300 	public enum string[] FIELDS = ["from", "to", "action"];
301 
302 	public long from;
303 	public long to;
304 	public ubyte action;
305 
306 	public pure nothrow @safe void encode(Buffer buffer) {
307 		with(buffer) {
308 			writeBytes(varlong.encode(from));
309 			writeBytes(varlong.encode(to));
310 			writeBigEndianUbyte(action);
311 		}
312 	}
313 
314 	public pure nothrow @safe void decode(Buffer buffer) {
315 		with(buffer) {
316 			from=varlong.decode(_buffer, &_index);
317 			to=varlong.decode(_buffer, &_index);
318 			action=readBigEndianUbyte();
319 		}
320 	}
321 
322 	public string toString() {
323 		return "Link(from: " ~ std.conv.to!string(this.from) ~ ", to: " ~ std.conv.to!string(this.to) ~ ", action: " ~ std.conv.to!string(this.action) ~ ")";
324 	}
325 
326 }
327 
328 struct Recipe {
329 
330 	// type
331 	public enum int SHAPELESS = 0;
332 	public enum int SHAPED = 1;
333 	public enum int FURNACE = 2;
334 	public enum int FURNACE_DATA = 3;
335 	public enum int MULTI = 4;
336 
337 	public enum string[] FIELDS = ["type", "data"];
338 
339 	public int type;
340 	public ubyte[] data;
341 
342 	public pure nothrow @safe void encode(Buffer buffer) {
343 		with(buffer) {
344 			writeBytes(varint.encode(type));
345 			writeBytes(data);
346 		}
347 	}
348 
349 	public pure nothrow @safe void decode(Buffer buffer) {
350 		with(buffer) {
351 			type=varint.decode(_buffer, &_index);
352 			data=_buffer[_index..$].dup; _index=_buffer.length;
353 		}
354 	}
355 
356 	public string toString() {
357 		return "Recipe(type: " ~ std.conv.to!string(this.type) ~ ", data: " ~ std.conv.to!string(this.data) ~ ")";
358 	}
359 
360 }
361 
362 /**
363  * Chunk's blocks, lights and other immutable data.
364  */
365 struct ChunkData {
366 
367 	public enum string[] FIELDS = ["sections", "heights", "biomes", "borders", "extraData", "blockEntities"];
368 
369 	/**
370 	 * 16x16x16 section of the chunk. The array's keys also indicate the section's height
371 	 * (the 3rd element of the array will be the 3rd section from bottom, starting at `y=24`).
372 	 * The amount of sections should be in a range from 0 (empty chunk) to 16.
373 	 */
374 	public sul.protocol.pocket101.types.Section[] sections;
375 
376 	/**
377 	 * Coordinates of the highest block in the column that receives sky light (order `xz`).
378 	 * It is used to increase the speed when calculating the block's light level.
379 	 */
380 	public ushort[256] heights;
381 
382 	/**
383 	 * Biomes in order `xz`.
384 	 */
385 	public ubyte[256] biomes;
386 
387 	/**
388 	 * Colums where there are world borders (in format `xz`). This feature hasn't been
389 	 * implemented in the game yet and crashes the client.
390 	 */
391 	public ubyte[] borders;
392 	public sul.protocol.pocket101.types.ExtraData[] extraData;
393 
394 	/**
395 	 * Additional data for the chunk's block entities (tiles), encoded in the same way
396 	 * as BlockEntityData.nbt is. The position is given by the `Int` tags `x`, `y`, `z`
397 	 * which are added to the block's compound tag together with the `String` tag `id`
398 	 * that contains the name of the tile in pascal case.
399 	 * Wrong encoding or missing tags may result in the block becoming invisible.
400 	 */
401 	public ubyte[] blockEntities;
402 
403 	public pure nothrow @safe void encode(Buffer o_buffer) {
404 		Buffer buffer = new Buffer();
405 		with(buffer) {
406 			writeBytes(varuint.encode(cast(uint)sections.length)); foreach(cvdlbm;sections){ cvdlbm.encode(bufferInstance); }
407 			foreach(avzhc;heights){ writeBigEndianUshort(avzhc); }
408 			writeBytes(biomes);
409 			writeBytes(varuint.encode(cast(uint)borders.length)); writeBytes(borders);
410 			writeBytes(varuint.encode(cast(uint)extraData.length)); foreach(zhcfyr;extraData){ zhcfyr.encode(bufferInstance); }
411 			writeBytes(blockEntities);
412 		}
413 		with(o_buffer){ writeBytes(varuint.encode(cast(uint)buffer._buffer.length)); }
414 		o_buffer.writeBytes(buffer._buffer);
415 	}
416 
417 	public pure nothrow @safe void decode(Buffer o_buffer) {
418 		Buffer buffer = new Buffer();
419 		with(o_buffer) {
420 			immutable _length=varuint.decode(_buffer, &_index);
421 			buffer._buffer = readBytes(_length);
422 		}
423 		with(buffer) {
424 			sections.length=varuint.decode(_buffer, &_index); foreach(ref cvdlbm;sections){ cvdlbm.decode(bufferInstance); }
425 			foreach(ref avzhc;heights){ avzhc=readBigEndianUshort(); }
426 			if(_buffer.length>=_index+biomes.length){ biomes=_buffer[_index.._index+biomes.length].dup; _index+=biomes.length; }
427 			borders.length=varuint.decode(_buffer, &_index); if(_buffer.length>=_index+borders.length){ borders=_buffer[_index.._index+borders.length].dup; _index+=borders.length; }
428 			extraData.length=varuint.decode(_buffer, &_index); foreach(ref zhcfyr;extraData){ zhcfyr.decode(bufferInstance); }
429 			blockEntities=_buffer[_index..$].dup; _index=_buffer.length;
430 		}
431 	}
432 
433 	public string toString() {
434 		return "ChunkData(sections: " ~ std.conv.to!string(this.sections) ~ ", heights: " ~ std.conv.to!string(this.heights) ~ ", biomes: " ~ std.conv.to!string(this.biomes) ~ ", borders: " ~ std.conv.to!string(this.borders) ~ ", extraData: " ~ std.conv.to!string(this.extraData) ~ ", blockEntities: " ~ std.conv.to!string(this.blockEntities) ~ ")";
435 	}
436 
437 }
438 
439 /**
440  * Section of a chunk with informations about blocks and lights. The array of bytes
441  * are always ordered `xzy`.
442  */
443 struct Section {
444 
445 	public enum string[] FIELDS = ["storageVersion", "blockIds", "blockMetas", "skyLight", "blockLight"];
446 
447 	public ubyte storageVersion = 0;
448 	public ubyte[4096] blockIds;
449 	public ubyte[2048] blockMetas;
450 	public ubyte[2048] skyLight;
451 	public ubyte[2048] blockLight;
452 
453 	public pure nothrow @safe void encode(Buffer buffer) {
454 		with(buffer) {
455 			writeBigEndianUbyte(storageVersion);
456 			writeBytes(blockIds);
457 			writeBytes(blockMetas);
458 			writeBytes(skyLight);
459 			writeBytes(blockLight);
460 		}
461 	}
462 
463 	public pure nothrow @safe void decode(Buffer buffer) {
464 		with(buffer) {
465 			storageVersion=readBigEndianUbyte();
466 			if(_buffer.length>=_index+blockIds.length){ blockIds=_buffer[_index.._index+blockIds.length].dup; _index+=blockIds.length; }
467 			if(_buffer.length>=_index+blockMetas.length){ blockMetas=_buffer[_index.._index+blockMetas.length].dup; _index+=blockMetas.length; }
468 			if(_buffer.length>=_index+skyLight.length){ skyLight=_buffer[_index.._index+skyLight.length].dup; _index+=skyLight.length; }
469 			if(_buffer.length>=_index+blockLight.length){ blockLight=_buffer[_index.._index+blockLight.length].dup; _index+=blockLight.length; }
470 		}
471 	}
472 
473 	public string toString() {
474 		return "Section(storageVersion: " ~ std.conv.to!string(this.storageVersion) ~ ", blockIds: " ~ std.conv.to!string(this.blockIds) ~ ", blockMetas: " ~ std.conv.to!string(this.blockMetas) ~ ", skyLight: " ~ std.conv.to!string(this.skyLight) ~ ", blockLight: " ~ std.conv.to!string(this.blockLight) ~ ")";
475 	}
476 
477 }
478 
479 struct ExtraData {
480 
481 	public enum string[] FIELDS = ["key", "value"];
482 
483 	public uint key;
484 	public ushort value;
485 
486 	public pure nothrow @safe void encode(Buffer buffer) {
487 		with(buffer) {
488 			writeBytes(varuint.encode(key));
489 			writeLittleEndianUshort(value);
490 		}
491 	}
492 
493 	public pure nothrow @safe void decode(Buffer buffer) {
494 		with(buffer) {
495 			key=varuint.decode(_buffer, &_index);
496 			value=readLittleEndianUshort();
497 		}
498 	}
499 
500 	public string toString() {
501 		return "ExtraData(key: " ~ std.conv.to!string(this.key) ~ ", value: " ~ std.conv.to!string(this.value) ~ ")";
502 	}
503 
504 }
505 
506 struct Decoration {
507 
508 	public enum string[] FIELDS = ["rotationAndIcon", "position", "label", "color"];
509 
510 	public int rotationAndIcon;
511 	public Tuple!(ubyte, "x", ubyte, "z") position;
512 	public string label;
513 
514 	/**
515 	 * ARGB colour.
516 	 */
517 	public uint color;
518 
519 	public pure nothrow @safe void encode(Buffer buffer) {
520 		with(buffer) {
521 			writeBytes(varint.encode(rotationAndIcon));
522 			writeBigEndianUbyte(position.x); writeBigEndianUbyte(position.z);
523 			writeBytes(varuint.encode(cast(uint)label.length)); writeString(label);
524 			writeLittleEndianUint(color);
525 		}
526 	}
527 
528 	public pure nothrow @safe void decode(Buffer buffer) {
529 		with(buffer) {
530 			rotationAndIcon=varint.decode(_buffer, &_index);
531 			position.x=readBigEndianUbyte(); position.z=readBigEndianUbyte();
532 			uint bfzw=varuint.decode(_buffer, &_index); label=readString(bfzw);
533 			color=readLittleEndianUint();
534 		}
535 	}
536 
537 	public string toString() {
538 		return "Decoration(rotationAndIcon: " ~ std.conv.to!string(this.rotationAndIcon) ~ ", position: " ~ std.conv.to!string(this.position) ~ ", label: " ~ std.conv.to!string(this.label) ~ ", color: " ~ std.conv.to!string(this.color) ~ ")";
539 	}
540 
541 }
542 
543 /**
544  * A game rule that prevents the client from doing client-side actions and animations.
545  */
546 struct Rule {
547 
548 	// name
549 	public enum string DROWNING_DAMAGE = "drowningdamage";
550 	public enum string FALL_DAMAGE = "falldamage";
551 	public enum string FIRE_DAMAGE = "firedamage";
552 	public enum string IMMUTABLE_WORLD = "immutableworld";
553 	public enum string PVP = "pvp";
554 
555 	public enum string[] FIELDS = ["name", "value", "unknown2"];
556 
557 	/**
558 	 * Name of the rule. Same of the `gamerule` command's field in Minecraft: Education
559 	 * Edition.
560 	 * The behaviours indicated in the following constants' descriptions is enabled or
561 	 * disabled.
562 	 */
563 	public string name;
564 
565 	/**
566 	 * Indicates whether the game rule is enabled.
567 	 */
568 	public bool value;
569 	public bool unknown2;
570 
571 	public pure nothrow @safe void encode(Buffer buffer) {
572 		with(buffer) {
573 			writeBytes(varuint.encode(cast(uint)name.length)); writeString(name);
574 			writeBigEndianBool(value);
575 			writeBigEndianBool(unknown2);
576 		}
577 	}
578 
579 	public pure nothrow @safe void decode(Buffer buffer) {
580 		with(buffer) {
581 			uint bfz=varuint.decode(_buffer, &_index); name=readString(bfz);
582 			value=readBigEndianBool();
583 			unknown2=readBigEndianBool();
584 		}
585 	}
586 
587 	public string toString() {
588 		return "Rule(name: " ~ std.conv.to!string(this.name) ~ ", value: " ~ std.conv.to!string(this.value) ~ ", unknown2: " ~ std.conv.to!string(this.unknown2) ~ ")";
589 	}
590 
591 }
592