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 `<sender> 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