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