From e3fe9e5e93fbf8ce26a61719fdb4ccd9a627d37a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 15 Mar 2021 17:06:58 +0000 Subject: Deduplicate WriteBlockEntity --- src/Protocol/Protocol_1_8.cpp | 279 +++++++++++++++++++----------------------- 1 file changed, 125 insertions(+), 154 deletions(-) (limited to 'src/Protocol/Protocol_1_8.cpp') diff --git a/src/Protocol/Protocol_1_8.cpp b/src/Protocol/Protocol_1_8.cpp index 1a1229f05..654146e14 100644 --- a/src/Protocol/Protocol_1_8.cpp +++ b/src/Protocol/Protocol_1_8.cpp @@ -1598,28 +1598,31 @@ void cProtocol_1_8_0::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { ASSERT(m_State == 3); // In game mode? - cPacketizer Pkt(*this, pktUpdateBlockEntity); - Pkt.WriteXYZPosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ()); - - Byte Action = 0; + Byte Action; switch (a_BlockEntity.GetBlockType()) { - case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing - case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text - case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity - case E_BLOCK_HEAD: Action = 4; break; // Update Mobhead entity - case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot + case E_BLOCK_ENCHANTMENT_TABLE: Action = 0; break; // The ones with a action of 0 is just a workaround to send the block entities to a client. + case E_BLOCK_END_PORTAL: Action = 0; break; // Todo: 18.09.2020 - remove this when block entities are transmitted in the ChunkData packet - 12xx12 + + case E_BLOCK_MOB_SPAWNER: Action = 1; break; // Update mob spawner spinny mob thing + case E_BLOCK_COMMAND_BLOCK: Action = 2; break; // Update command block text + case E_BLOCK_BEACON: Action = 3; break; // Update beacon entity + case E_BLOCK_HEAD: Action = 4; break; // Update mobhead entity + case E_BLOCK_FLOWER_POT: Action = 5; break; // Update flower pot case E_BLOCK_WALL_BANNER: - case E_BLOCK_STANDING_BANNER: Action = 6; break; // Update Banner - case E_BLOCK_BED: Action = 11; break; // Update bed color - case E_BLOCK_ENCHANTMENT_TABLE: Action = 0; break; // The ones with a action of 0 is just a workaround to send the block entities to a client. - case E_BLOCK_END_PORTAL: Action = 0; break; // Todo: 18.09.2020 - remove this when block entities are transmitted in the ChunkData packet - 12xx12 + case E_BLOCK_STANDING_BANNER: Action = 6; break; // Update banner - default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break; + default: return; // Block entities change between versions } + + cPacketizer Pkt(*this, pktUpdateBlockEntity); + Pkt.WriteXYZPosition64(a_BlockEntity.GetPosX(), a_BlockEntity.GetPosY(), a_BlockEntity.GetPosZ()); Pkt.WriteBEUInt8(Action); - WriteBlockEntity(Pkt, a_BlockEntity); + cFastNBTWriter Writer; + WriteBlockEntity(Writer, a_BlockEntity); + Writer.Finish(); + Pkt.WriteBuf(Writer.GetResult()); } @@ -3131,6 +3134,113 @@ void cProtocol_1_8_0::SendEntitySpawn(const cEntity & a_Entity, const UInt8 a_Ob +void cProtocol_1_8_0::WriteBlockEntity(cFastNBTWriter & a_Writer, const cBlockEntity & a_BlockEntity) +{ + a_Writer.AddInt("x", a_BlockEntity.GetPosX()); + a_Writer.AddInt("y", a_BlockEntity.GetPosY()); + a_Writer.AddInt("z", a_BlockEntity.GetPosZ()); + + switch (a_BlockEntity.GetBlockType()) + { + case E_BLOCK_WALL_BANNER: + case E_BLOCK_STANDING_BANNER: + { + auto & BannerEntity = static_cast(a_BlockEntity); + a_Writer.AddInt("Base", static_cast(BannerEntity.GetBaseColor())); + break; + } + + case E_BLOCK_BEACON: + { + auto & BeaconEntity = static_cast(a_BlockEntity); + a_Writer.AddInt("Primary", BeaconEntity.GetPrimaryEffect()); + a_Writer.AddInt("Secondary", BeaconEntity.GetSecondaryEffect()); + a_Writer.AddInt("Levels", BeaconEntity.GetBeaconLevel()); + break; + } + + case E_BLOCK_COMMAND_BLOCK: + { + auto & CommandBlockEntity = static_cast(a_BlockEntity); + a_Writer.AddByte("TrackOutput", 1); // Neither I nor the MC wiki has any idea about this + a_Writer.AddInt("SuccessCount", CommandBlockEntity.GetResult()); + a_Writer.AddString("Command", CommandBlockEntity.GetCommand()); + // You can set custom names for windows in Vanilla + // For a command block, this would be the 'name' prepended to anything it outputs into global chat + // MCS doesn't have this, so just leave it @ '@'. (geddit?) + a_Writer.AddString("CustomName", "@"); + if (!CommandBlockEntity.GetLastOutput().empty()) + { + a_Writer.AddString("LastOutput", Printf("{\"text\":\"%s\"}", CommandBlockEntity.GetLastOutput().c_str())); + } + break; + } + + case E_BLOCK_ENCHANTMENT_TABLE: + { + auto & EnchantingTableEntity = static_cast(a_BlockEntity); + if (!EnchantingTableEntity.GetCustomName().empty()) + { + a_Writer.AddString("CustomName", EnchantingTableEntity.GetCustomName()); + } + break; + } + + case E_BLOCK_END_PORTAL: + { + // Nothing! + break; + } + + case E_BLOCK_HEAD: + { + auto & MobHeadEntity = static_cast(a_BlockEntity); + a_Writer.AddByte("SkullType", MobHeadEntity.GetType() & 0xFF); + a_Writer.AddByte("Rot", MobHeadEntity.GetRotation() & 0xFF); + + // The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity + a_Writer.BeginCompound("Owner"); + a_Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString()); + a_Writer.AddString("Name", MobHeadEntity.GetOwnerName()); + a_Writer.BeginCompound("Properties"); + a_Writer.BeginList("textures", TAG_Compound); + a_Writer.BeginCompound(""); + a_Writer.AddString("Signature", MobHeadEntity.GetOwnerTextureSignature()); + a_Writer.AddString("Value", MobHeadEntity.GetOwnerTexture()); + a_Writer.EndCompound(); + a_Writer.EndList(); + a_Writer.EndCompound(); + a_Writer.EndCompound(); + break; + } + + case E_BLOCK_FLOWER_POT: + { + auto & FlowerPotEntity = static_cast(a_BlockEntity); + a_Writer.AddInt("Item", static_cast(FlowerPotEntity.GetItem().m_ItemType)); + a_Writer.AddInt("Data", static_cast(FlowerPotEntity.GetItem().m_ItemDamage)); + break; + } + + case E_BLOCK_MOB_SPAWNER: + { + auto & MobSpawnerEntity = static_cast(a_BlockEntity); + a_Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(MobSpawnerEntity.GetEntity())); + a_Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay()); + break; + } + + default: + { + break; + } + } +} + + + + + void cProtocol_1_8_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) { short ItemType = a_Item.m_ItemType; @@ -3213,145 +3323,6 @@ void cProtocol_1_8_0::WriteItem(cPacketizer & a_Pkt, const cItem & a_Item) -void cProtocol_1_8_0::WriteBlockEntity(cPacketizer & a_Pkt, const cBlockEntity & a_BlockEntity) -{ - cFastNBTWriter Writer; - - switch (a_BlockEntity.GetBlockType()) - { - case E_BLOCK_WALL_BANNER: - case E_BLOCK_STANDING_BANNER: - { - auto & BannerEntity = static_cast(a_BlockEntity); - Writer.AddInt("x", BannerEntity.GetPosX()); - Writer.AddInt("y", BannerEntity.GetPosY()); - Writer.AddInt("z", BannerEntity.GetPosZ()); - Writer.AddString("id", "Banner"); - Writer.AddInt("Base", static_cast(BannerEntity.GetBaseColor())); - break; - } - - case E_BLOCK_BEACON: - { - auto & BeaconEntity = static_cast(a_BlockEntity); - Writer.AddInt("x", BeaconEntity.GetPosX()); - Writer.AddInt("y", BeaconEntity.GetPosY()); - Writer.AddInt("z", BeaconEntity.GetPosZ()); - Writer.AddInt("Primary", BeaconEntity.GetPrimaryEffect()); - Writer.AddInt("Secondary", BeaconEntity.GetSecondaryEffect()); - Writer.AddInt("Levels", BeaconEntity.GetBeaconLevel()); - Writer.AddString("id", "Beacon"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though - break; - } - - case E_BLOCK_COMMAND_BLOCK: - { - auto & CommandBlockEntity = static_cast(a_BlockEntity); - Writer.AddByte("TrackOutput", 1); // Neither I nor the MC wiki has any idea about this - Writer.AddInt("SuccessCount", CommandBlockEntity.GetResult()); - Writer.AddInt("x", CommandBlockEntity.GetPosX()); - Writer.AddInt("y", CommandBlockEntity.GetPosY()); - Writer.AddInt("z", CommandBlockEntity.GetPosZ()); - Writer.AddString("Command", CommandBlockEntity.GetCommand()); - // You can set custom names for windows in Vanilla - // For a command block, this would be the 'name' prepended to anything it outputs into global chat - // MCS doesn't have this, so just leave it @ '@'. (geddit?) - Writer.AddString("CustomName", "@"); - Writer.AddString("id", "Control"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though - if (!CommandBlockEntity.GetLastOutput().empty()) - { - Writer.AddString("LastOutput", Printf("{\"text\":\"%s\"}", CommandBlockEntity.GetLastOutput().c_str())); - } - break; - } - - case E_BLOCK_ENCHANTMENT_TABLE: - { - auto & EnchantingTableEntity = static_cast(a_BlockEntity); - Writer.AddInt("x", EnchantingTableEntity.GetPosX()); - Writer.AddInt("y", EnchantingTableEntity.GetPosY()); - Writer.AddInt("z", EnchantingTableEntity.GetPosZ()); - if (!EnchantingTableEntity.GetCustomName().empty()) - { - Writer.AddString("CustomName", EnchantingTableEntity.GetCustomName()); - } - Writer.AddString("id", "EnchantingTable"); - break; - } - - case E_BLOCK_END_PORTAL: - { - Writer.AddInt("x", a_BlockEntity.GetPosX()); - Writer.AddInt("y", a_BlockEntity.GetPosY()); - Writer.AddInt("z", a_BlockEntity.GetPosZ()); - Writer.AddString("id", "EndPortal"); - break; - } - - case E_BLOCK_HEAD: - { - auto & MobHeadEntity = static_cast(a_BlockEntity); - Writer.AddInt("x", MobHeadEntity.GetPosX()); - Writer.AddInt("y", MobHeadEntity.GetPosY()); - Writer.AddInt("z", MobHeadEntity.GetPosZ()); - Writer.AddByte("SkullType", MobHeadEntity.GetType() & 0xFF); - Writer.AddByte("Rot", MobHeadEntity.GetRotation() & 0xFF); - Writer.AddString("id", "Skull"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though - - // The new Block Entity format for a Mob Head. See: https://minecraft.gamepedia.com/Head#Block_entity - Writer.BeginCompound("Owner"); - Writer.AddString("Id", MobHeadEntity.GetOwnerUUID().ToShortString()); - Writer.AddString("Name", MobHeadEntity.GetOwnerName()); - Writer.BeginCompound("Properties"); - Writer.BeginList("textures", TAG_Compound); - Writer.BeginCompound(""); - Writer.AddString("Signature", MobHeadEntity.GetOwnerTextureSignature()); - Writer.AddString("Value", MobHeadEntity.GetOwnerTexture()); - Writer.EndCompound(); - Writer.EndList(); - Writer.EndCompound(); - Writer.EndCompound(); - break; - } - - case E_BLOCK_FLOWER_POT: - { - auto & FlowerPotEntity = static_cast(a_BlockEntity); - Writer.AddInt("x", FlowerPotEntity.GetPosX()); - Writer.AddInt("y", FlowerPotEntity.GetPosY()); - Writer.AddInt("z", FlowerPotEntity.GetPosZ()); - Writer.AddInt("Item", static_cast(FlowerPotEntity.GetItem().m_ItemType)); - Writer.AddInt("Data", static_cast(FlowerPotEntity.GetItem().m_ItemDamage)); - Writer.AddString("id", "FlowerPot"); // "Tile Entity ID" - MC wiki; vanilla server always seems to send this though - break; - } - - case E_BLOCK_MOB_SPAWNER: - { - auto & MobSpawnerEntity = static_cast(a_BlockEntity); - Writer.AddInt("x", MobSpawnerEntity.GetPosX()); - Writer.AddInt("y", MobSpawnerEntity.GetPosY()); - Writer.AddInt("z", MobSpawnerEntity.GetPosZ()); - Writer.AddString("EntityId", cMonster::MobTypeToVanillaName(MobSpawnerEntity.GetEntity())); - Writer.AddShort("Delay", MobSpawnerEntity.GetSpawnDelay()); - Writer.AddString("id", "MobSpawner"); - break; - } - - default: - { - break; - } - } - - Writer.Finish(); - a_Pkt.WriteBuf(Writer.GetResult()); -} - - - - - void cProtocol_1_8_0::WriteEntityMetadata(cPacketizer & a_Pkt, const cEntity & a_Entity) { // Common metadata: -- cgit v1.2.3