1
0

Deduplicate WriteBlockEntity

This commit is contained in:
Tiger Wang
2021-03-15 17:06:58 +00:00
parent edf9e39ed7
commit e3fe9e5e93
9 changed files with 251 additions and 542 deletions

View File

@@ -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_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_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
default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break;
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
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<const cBannerEntity &>(a_BlockEntity);
a_Writer.AddInt("Base", static_cast<Int32>(BannerEntity.GetBaseColor()));
break;
}
case E_BLOCK_BEACON:
{
auto & BeaconEntity = static_cast<const cBeaconEntity &>(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<const cCommandBlockEntity &>(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<const cEnchantingTableEntity &>(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<const cMobHeadEntity &>(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<const cFlowerPotEntity &>(a_BlockEntity);
a_Writer.AddInt("Item", static_cast<Int32>(FlowerPotEntity.GetItem().m_ItemType));
a_Writer.AddInt("Data", static_cast<Int32>(FlowerPotEntity.GetItem().m_ItemDamage));
break;
}
case E_BLOCK_MOB_SPAWNER:
{
auto & MobSpawnerEntity = static_cast<const cMobSpawnerEntity &>(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<const cBannerEntity &>(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<Int32>(BannerEntity.GetBaseColor()));
break;
}
case E_BLOCK_BEACON:
{
auto & BeaconEntity = static_cast<const cBeaconEntity &>(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<const cCommandBlockEntity &>(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<const cEnchantingTableEntity &>(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<const cMobHeadEntity &>(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<const cFlowerPotEntity &>(a_BlockEntity);
Writer.AddInt("x", FlowerPotEntity.GetPosX());
Writer.AddInt("y", FlowerPotEntity.GetPosY());
Writer.AddInt("z", FlowerPotEntity.GetPosZ());
Writer.AddInt("Item", static_cast<Int32>(FlowerPotEntity.GetItem().m_ItemType));
Writer.AddInt("Data", static_cast<Int32>(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<const cMobSpawnerEntity &>(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: