From f8c8dcc7f36366dc6b59e6741d466e739322d5d1 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 00:54:38 +0000 Subject: [PATCH 1/5] Improved command blocks * Their command and previous output are displayed on the client * They have a BlockHandler implementation, so you can't place blocks on them anymore + As a side effect, implemented UpdateBlockEntity --- src/BlockEntities/CommandBlockEntity.cpp | 42 +++++++++++++++++++++--- src/Blocks/BlockCommandBlock.h | 32 ++++++++++++++++++ src/Blocks/BlockHandler.cpp | 2 ++ src/ClientHandle.cpp | 9 +++++ src/ClientHandle.h | 2 ++ src/Protocol/Protocol.h | 2 ++ src/Protocol/Protocol125.h | 1 + src/Protocol/Protocol17x.cpp | 25 ++++++++++++++ src/Protocol/Protocol17x.h | 2 ++ src/Protocol/ProtocolRecognizer.cpp | 10 ++++++ src/Protocol/ProtocolRecognizer.h | 2 ++ 11 files changed, 124 insertions(+), 5 deletions(-) create mode 100644 src/Blocks/BlockCommandBlock.h diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 543d47b7a..6e5c8087e 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -7,10 +7,11 @@ #include "json/json.h" #include "CommandBlockEntity.h" #include "../Entities/Player.h" +#include "../WorldStorage/FastNBT.h" -#include "CommandOutput.h" -#include "Root.h" -#include "Server.h" // ExecuteConsoleCommand() +#include "../CommandOutput.h" +#include "../Root.h" +#include "../Server.h" // ExecuteConsoleCommand() @@ -40,6 +41,15 @@ void cCommandBlockEntity::UsedBy(cPlayer * a_Player) void cCommandBlockEntity::SetCommand(const AString & a_Cmd) { m_Command = a_Cmd; + + /* + Vanilla requires that the server send a Block Entity Update after a command has been set + Therefore, command blocks don't support on-the-fly (when window is open) updating of a command and therefore... + ...the following code can't be put in UsedBy just before the window opens + + Just documenting my experience in getting this to work :P + */ + m_World->BroadcastBlockEntity(GetPosX(), GetPosY(), GetPosZ()); } @@ -131,8 +141,30 @@ bool cCommandBlockEntity::Tick(float a_Dt, cChunk & a_Chunk) void cCommandBlockEntity::SendTo(cClientHandle & a_Client) { - // Nothing needs to be sent - UNUSED(a_Client); + cFastNBTWriter Writer; + Writer.AddByte("TrackOutput", 1); // Neither I nor the MC wiki has any idea about this + Writer.AddInt("SuccessCount", GetResult()); + Writer.AddInt("x", GetPosX()); + Writer.AddInt("y", GetPosY()); + Writer.AddInt("z", GetPosZ()); + Writer.AddString("Command", GetCommand().c_str()); + // 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 (!GetLastOutput().empty()) + { + AString Output; + Printf(Output, "{\"text\":\"%s\"}", GetLastOutput().c_str()); + + Writer.AddString("LastOutput", Output.c_str()); + } + + Writer.Finish(); + + a_Client.SendUpdateBlockEntity(GetPosX(), GetPosY(), GetPosZ(), 2, Writer); } diff --git a/src/Blocks/BlockCommandBlock.h b/src/Blocks/BlockCommandBlock.h new file mode 100644 index 000000000..cf0103765 --- /dev/null +++ b/src/Blocks/BlockCommandBlock.h @@ -0,0 +1,32 @@ + +#pragma once + +#include "BlockEntity.h" + + + + + +class cBlockCommandBlockHandler : + public cBlockEntityHandler +{ +public: + cBlockCommandBlockHandler(BLOCKTYPE a_BlockType) + : cBlockEntityHandler(a_BlockType) + { + } + + virtual void ConvertToPickups(cItems & a_Pickups, NIBBLETYPE a_BlockMeta) override + { + a_Pickups.push_back(cItem(E_BLOCK_AIR, 8, 0)); + } + + virtual const char * GetStepSound(void) override + { + return "step.stone"; + } +} ; + + + + diff --git a/src/Blocks/BlockHandler.cpp b/src/Blocks/BlockHandler.cpp index ff1022e12..b9c0887ce 100644 --- a/src/Blocks/BlockHandler.cpp +++ b/src/Blocks/BlockHandler.cpp @@ -14,6 +14,7 @@ #include "BlockChest.h" #include "BlockCloth.h" #include "BlockCobWeb.h" +#include "BlockCommandBlock.h" #include "BlockComparator.h" #include "BlockCrops.h" #include "BlockDeadBush.h" @@ -116,6 +117,7 @@ cBlockHandler * cBlockHandler::CreateBlockHandler(BLOCKTYPE a_BlockType) case E_BLOCK_CAULDRON: return new cBlockCauldronHandler (a_BlockType); case E_BLOCK_CHEST: return new cBlockChestHandler (a_BlockType); case E_BLOCK_COAL_ORE: return new cBlockOreHandler (a_BlockType); + case E_BLOCK_COMMAND_BLOCK: return new cBlockCommandBlockHandler (a_BlockType); case E_BLOCK_ACTIVE_COMPARATOR: return new cBlockComparatorHandler (a_BlockType); case E_BLOCK_COBBLESTONE: return new cBlockStoneHandler (a_BlockType); case E_BLOCK_COBBLESTONE_STAIRS: return new cBlockStairsHandler (a_BlockType); diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index faf583fbb..93dc78642 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -20,6 +20,7 @@ #include "Items/ItemHandler.h" #include "Blocks/BlockHandler.h" #include "Blocks/BlockSlab.h" +#include "WorldStorage/FastNBT.h" #include "Vector3f.h" #include "Vector3d.h" @@ -2203,6 +2204,14 @@ void cClientHandle::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) +void cClientHandle::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) +{ + m_Protocol->SendUpdateBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Action, a_NBT); +} + + + + void cClientHandle::SendUpdateSign( int a_BlockX, int a_BlockY, int a_BlockZ, diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 373ca9e2e..2ac240b17 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -16,6 +16,7 @@ #include "OSSupport/SocketThreads.h" #include "ChunkDef.h" #include "ByteBuffer.h" +#include "WorldStorage/FastNBT.h" @@ -136,6 +137,7 @@ public: void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay); void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); + void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT); void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); void SendWeather (eWeather a_Weather); diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 3293da32c..6af0af25d 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -12,6 +12,7 @@ #include "../Defines.h" #include "../Endianness.h" +#include "../WorldStorage/FastNBT.h" @@ -103,6 +104,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) = 0; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; + virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) = 0; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; virtual void SendWeather (eWeather a_Weather) = 0; diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index d0e5c9428..97b194d76 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -79,6 +79,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; + virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) override {}; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 5b3a79555..01a6b0bde 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -892,6 +892,20 @@ void cProtocol172::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) +void cProtocol172::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) +{ + cPacketizer Pkt(*this, 0x35); // Update tile entity packet + Pkt.WriteInt(a_BlockX); + Pkt.WriteShort(a_BlockY); + Pkt.WriteInt(a_BlockZ); + Pkt.WriteByte(a_Action); + + Pkt.WriteBlockEntity(a_NBT); +} + + + + void cProtocol172::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) { @@ -1819,6 +1833,17 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) +void cProtocol172::cPacketizer::WriteBlockEntity(const cFastNBTWriter & a_NBT) +{ + AString Compressed; + CompressStringGZIP(a_NBT.GetResult().data(), a_NBT.GetResult().size(), Compressed); + WriteShort(Compressed.size()); + WriteBuf(Compressed.data(), Compressed.size()); +} + + + + void cProtocol172::cPacketizer::WriteByteAngle(double a_Angle) { diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 07dba834b..6e04a0ffb 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -102,6 +102,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; + virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; @@ -189,6 +190,7 @@ protected: void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f void WriteMobMetadata(const cMonster & a_Mob); // Writes the mob-specific metadata for the specified mob void WriteEntityProperties(const cEntity & a_Entity); // Writes the entity properties for the specified entity, including the Count field + void WriteBlockEntity(const cFastNBTWriter & a_NBT); protected: cProtocol172 & m_Protocol; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index a21f4f042..579469fb4 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -636,6 +636,16 @@ void cProtocolRecognizer::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) +void cProtocolRecognizer::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) +{ + ASSERT(m_Protocol != NULL); + m_Protocol->SendUpdateBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Action, a_NBT); +} + + + + + void cProtocolRecognizer::SendUpdateSign(int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) { ASSERT(m_Protocol != NULL); diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index e94f4cde8..410ba556e 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -12,6 +12,7 @@ #include "Protocol.h" #include "../ByteBuffer.h" +#include "../WorldStorage/FastNBT.h" @@ -114,6 +115,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; + virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; From 71b01234a2eadbf3512e8efcdd28b2728d720628 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 00:55:08 +0000 Subject: [PATCH 2/5] ProtoProxy: UpdateBlockEntity NBT is written --- Tools/ProtoProxy/Connection.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/Tools/ProtoProxy/Connection.cpp b/Tools/ProtoProxy/Connection.cpp index 34da9b700..cd66e2dfd 100644 --- a/Tools/ProtoProxy/Connection.cpp +++ b/Tools/ProtoProxy/Connection.cpp @@ -2496,7 +2496,8 @@ bool cConnection::HandleServerUpdateTileEntity(void) HANDLE_SERVER_PACKET_READ(ReadBEShort, short, BlockY); HANDLE_SERVER_PACKET_READ(ReadBEInt, int, BlockZ); HANDLE_SERVER_PACKET_READ(ReadByte, Byte, Action); - HANDLE_SERVER_PACKET_READ(ReadBEShort, short, DataLength); + HANDLE_SERVER_PACKET_READ(ReadBEShort, short, DataLength); + AString Data; if ((DataLength > 0) && !m_ServerBuffer.ReadString(Data, DataLength)) { @@ -2506,6 +2507,18 @@ bool cConnection::HandleServerUpdateTileEntity(void) Log(" Block = {%d, %d, %d}", BlockX, BlockY, BlockZ); Log(" Action = %d", Action); DataLog(Data.data(), Data.size(), " Data (%u bytes)", Data.size()); + + // Save metadata to a file: + AString fnam; + Printf(fnam, "%s_item_%08x.nbt", m_LogNameBase.c_str(), m_ItemIdx++); + FILE * f = fopen(fnam.c_str(), "wb"); + if (f != NULL) + { + fwrite(Data.data(), 1, Data.size(), f); + fclose(f); + Log("(saved to file \"%s\")", fnam.c_str()); + } + COPY_TO_CLIENT(); return true; } From a85b2897e0e9563be69ed2fde944573459103d56 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 01:06:19 +0000 Subject: [PATCH 3/5] Implemented MC|Brand response --- src/ClientHandle.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 93dc78642..8f95212e1 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -547,12 +547,18 @@ void cClientHandle::HandlePlayerPos(double a_PosX, double a_PosY, double a_PosZ, void cClientHandle::HandlePluginMessage(const AString & a_Channel, const AString & a_Message) { - if (a_Channel == "MC|AdvCdm") // Command block + if (a_Channel == "MC|AdvCdm") // Command block, set text, Client -> Server { const char* Data = a_Message.c_str(); - HandleCommandBlockMessage(Data, a_Message.size()); - + return; + } + else if (a_Channel == "MC|Brand") // Client <-> Server branding exchange + { + // We are custom, + // We are awesome, + // We are MCServer. + SendPluginMessage("MC|Brand", "MCServer"); return; } From 1af89a8b50a382ef0f5c137a84ab2816c45cc73c Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 13:25:35 +0000 Subject: [PATCH 4/5] Changed SendBlockEntity format slightly * Writing NBT is now in Protocol, not BlockEntity files * Fixed a last output bug --- src/BlockEntities/CommandBlockEntity.cpp | 26 ++------------ src/ClientHandle.cpp | 9 +++-- src/ClientHandle.h | 3 +- src/Protocol/Protocol.h | 3 +- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol17x.cpp | 43 +++++++++++++++++++++--- src/Protocol/Protocol17x.h | 4 +-- src/Protocol/ProtocolRecognizer.cpp | 4 +-- src/Protocol/ProtocolRecognizer.h | 3 +- 9 files changed, 55 insertions(+), 42 deletions(-) diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 6e5c8087e..38737d619 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -58,6 +58,7 @@ void cCommandBlockEntity::SetCommand(const AString & a_Cmd) void cCommandBlockEntity::SetLastOutput(const AString & a_LastOut) { + m_World->BroadcastBlockEntity(GetPosX(), GetPosY(), GetPosZ()); m_LastOutput = a_LastOut; } @@ -141,30 +142,7 @@ bool cCommandBlockEntity::Tick(float a_Dt, cChunk & a_Chunk) void cCommandBlockEntity::SendTo(cClientHandle & a_Client) { - cFastNBTWriter Writer; - Writer.AddByte("TrackOutput", 1); // Neither I nor the MC wiki has any idea about this - Writer.AddInt("SuccessCount", GetResult()); - Writer.AddInt("x", GetPosX()); - Writer.AddInt("y", GetPosY()); - Writer.AddInt("z", GetPosZ()); - Writer.AddString("Command", GetCommand().c_str()); - // 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 (!GetLastOutput().empty()) - { - AString Output; - Printf(Output, "{\"text\":\"%s\"}", GetLastOutput().c_str()); - - Writer.AddString("LastOutput", Output.c_str()); - } - - Writer.Finish(); - - a_Client.SendUpdateBlockEntity(GetPosX(), GetPosY(), GetPosZ(), 2, Writer); + a_Client.SendUpdateBlockEntity(GetPosX(), GetPosY(), GetPosZ(), 2, *this); } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 8f95212e1..327fc0358 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -20,7 +20,6 @@ #include "Items/ItemHandler.h" #include "Blocks/BlockHandler.h" #include "Blocks/BlockSlab.h" -#include "WorldStorage/FastNBT.h" #include "Vector3f.h" #include "Vector3d.h" @@ -573,6 +572,7 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a { if (a_Length < 14) { + SendChat(Printf("%s[INFO]%s Failure setting command block command; bad request", cChatColor::Red.c_str(), cChatColor::White.c_str())); LOGD("Malformed MC|AdvCdm packet."); return; } @@ -602,6 +602,7 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a default: { + SendChat(Printf("%s[INFO]%s Failure setting command block command; unhandled mode", cChatColor::Red.c_str(), cChatColor::White.c_str())); LOGD("Unhandled MC|AdvCdm packet mode."); return; } @@ -624,6 +625,8 @@ void cClientHandle::HandleCommandBlockMessage(const char* a_Data, unsigned int a cWorld * World = m_Player->GetWorld(); World->DoWithCommandBlockAt(BlockX, BlockY, BlockZ, CmdBlockCB); + + SendChat(Printf("%s[INFO]%s Successfully set command block command", cChatColor::Green.c_str(), cChatColor::White.c_str())); } @@ -2210,9 +2213,9 @@ void cClientHandle::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) -void cClientHandle::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) +void cClientHandle::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) { - m_Protocol->SendUpdateBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Action, a_NBT); + m_Protocol->SendUpdateBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Action, a_BlockEntity); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index 2ac240b17..daa185ca0 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -16,7 +16,6 @@ #include "OSSupport/SocketThreads.h" #include "ChunkDef.h" #include "ByteBuffer.h" -#include "WorldStorage/FastNBT.h" @@ -137,7 +136,7 @@ public: void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay); void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); - void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT); + void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity); void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); void SendWeather (eWeather a_Weather); diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index 6af0af25d..ac925e382 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -12,7 +12,6 @@ #include "../Defines.h" #include "../Endianness.h" -#include "../WorldStorage/FastNBT.h" @@ -104,7 +103,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) = 0; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; - virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) = 0; + virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) = 0; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; virtual void SendWeather (eWeather a_Weather) = 0; diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index 97b194d76..ec72ddd01 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -79,7 +79,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) override {}; + virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) override {}; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index 01a6b0bde..c85641ca8 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -24,6 +24,7 @@ Implements the 1.7.x protocol classes: #include "../Entities/Player.h" #include "../Mobs/IncludeAllMonsters.h" #include "../UI/Window.h" +#include "../BlockEntities/CommandBlockEntity.h" @@ -892,7 +893,7 @@ void cProtocol172::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) -void cProtocol172::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) +void cProtocol172::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) { cPacketizer Pkt(*this, 0x35); // Update tile entity packet Pkt.WriteInt(a_BlockX); @@ -900,7 +901,7 @@ void cProtocol172::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_Block Pkt.WriteInt(a_BlockZ); Pkt.WriteByte(a_Action); - Pkt.WriteBlockEntity(a_NBT); + Pkt.WriteBlockEntity(a_BlockEntity); } @@ -1833,10 +1834,44 @@ void cProtocol172::cPacketizer::WriteItem(const cItem & a_Item) -void cProtocol172::cPacketizer::WriteBlockEntity(const cFastNBTWriter & a_NBT) +void cProtocol172::cPacketizer::WriteBlockEntity(const cBlockEntity & a_BlockEntity) { + cFastNBTWriter Writer; + + switch (a_BlockEntity.GetBlockType()) + { + case E_BLOCK_COMMAND_BLOCK: + { + cCommandBlockEntity & CommandBlockEntity = (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().c_str()); + // 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()) + { + AString Output; + Printf(Output, "{\"text\":\"%s\"}", CommandBlockEntity.GetLastOutput().c_str()); + + Writer.AddString("LastOutput", Output.c_str()); + } + break; + } + default: break; + } + + Writer.Finish(); + AString Compressed; - CompressStringGZIP(a_NBT.GetResult().data(), a_NBT.GetResult().size(), Compressed); + CompressStringGZIP(Writer.GetResult().data(), Writer.GetResult().size(), Compressed); WriteShort(Compressed.size()); WriteBuf(Compressed.data(), Compressed.size()); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index 6e04a0ffb..b1d902507 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -102,7 +102,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) override; + virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; @@ -190,7 +190,7 @@ protected: void WriteEntityMetadata(const cEntity & a_Entity); // Writes the metadata for the specified entity, not including the terminating 0x7f void WriteMobMetadata(const cMonster & a_Mob); // Writes the mob-specific metadata for the specified mob void WriteEntityProperties(const cEntity & a_Entity); // Writes the entity properties for the specified entity, including the Count field - void WriteBlockEntity(const cFastNBTWriter & a_NBT); + void WriteBlockEntity(const cBlockEntity & a_BlockEntity); protected: cProtocol172 & m_Protocol; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 579469fb4..86f46f02f 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -636,10 +636,10 @@ void cProtocolRecognizer::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) -void cProtocolRecognizer::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) +void cProtocolRecognizer::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) { ASSERT(m_Protocol != NULL); - m_Protocol->SendUpdateBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Action, a_NBT); + m_Protocol->SendUpdateBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Action, a_BlockEntity); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 410ba556e..c1c8abdd5 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -12,7 +12,6 @@ #include "Protocol.h" #include "../ByteBuffer.h" -#include "../WorldStorage/FastNBT.h" @@ -115,7 +114,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cFastNBTWriter & a_NBT) override; + virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; From e4c3d799ffddb93c658062f9663ec027fc2f1d5a Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Sun, 19 Jan 2014 19:42:25 +0000 Subject: [PATCH 5/5] Removed unneeded paramters --- src/BlockEntities/CommandBlockEntity.cpp | 2 +- src/ClientHandle.cpp | 4 ++-- src/ClientHandle.h | 2 +- src/Protocol/Protocol.h | 2 +- src/Protocol/Protocol125.h | 2 +- src/Protocol/Protocol17x.cpp | 18 +++++++++++++----- src/Protocol/Protocol17x.h | 2 +- src/Protocol/ProtocolRecognizer.cpp | 4 ++-- src/Protocol/ProtocolRecognizer.h | 2 +- 9 files changed, 23 insertions(+), 15 deletions(-) diff --git a/src/BlockEntities/CommandBlockEntity.cpp b/src/BlockEntities/CommandBlockEntity.cpp index 38737d619..7e9015d33 100644 --- a/src/BlockEntities/CommandBlockEntity.cpp +++ b/src/BlockEntities/CommandBlockEntity.cpp @@ -142,7 +142,7 @@ bool cCommandBlockEntity::Tick(float a_Dt, cChunk & a_Chunk) void cCommandBlockEntity::SendTo(cClientHandle & a_Client) { - a_Client.SendUpdateBlockEntity(GetPosX(), GetPosY(), GetPosZ(), 2, *this); + a_Client.SendUpdateBlockEntity(*this); } diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index 327fc0358..ec71f8fe8 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -2213,9 +2213,9 @@ void cClientHandle::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) -void cClientHandle::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) +void cClientHandle::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { - m_Protocol->SendUpdateBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Action, a_BlockEntity); + m_Protocol->SendUpdateBlockEntity(a_BlockEntity); } diff --git a/src/ClientHandle.h b/src/ClientHandle.h index daa185ca0..4add022a6 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -136,7 +136,7 @@ public: void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ); void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay); void SendUnloadChunk (int a_ChunkX, int a_ChunkZ); - void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity); + void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity); void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4); void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ); void SendWeather (eWeather a_Weather); diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h index ac925e382..1bc5d528e 100644 --- a/src/Protocol/Protocol.h +++ b/src/Protocol/Protocol.h @@ -103,7 +103,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) = 0; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0; - virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) = 0; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) = 0; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) = 0; virtual void SendWeather (eWeather a_Weather) = 0; diff --git a/src/Protocol/Protocol125.h b/src/Protocol/Protocol125.h index ec72ddd01..310f9dd78 100644 --- a/src/Protocol/Protocol125.h +++ b/src/Protocol/Protocol125.h @@ -79,7 +79,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) override {}; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override {}; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp index c85641ca8..293f96186 100644 --- a/src/Protocol/Protocol17x.cpp +++ b/src/Protocol/Protocol17x.cpp @@ -893,13 +893,21 @@ void cProtocol172::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) -void cProtocol172::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) +void cProtocol172::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { cPacketizer Pkt(*this, 0x35); // Update tile entity packet - Pkt.WriteInt(a_BlockX); - Pkt.WriteShort(a_BlockY); - Pkt.WriteInt(a_BlockZ); - Pkt.WriteByte(a_Action); + Pkt.WriteInt(a_BlockEntity.GetPosX()); + Pkt.WriteShort(a_BlockEntity.GetPosY()); + Pkt.WriteInt(a_BlockEntity.GetPosZ()); + + Byte Action = 0; + 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 + default: ASSERT(!"Unhandled or unimplemented BlockEntity update request!"); break; + } + Pkt.WriteByte(Action); Pkt.WriteBlockEntity(a_BlockEntity); } diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h index b1d902507..3ae774c18 100644 --- a/src/Protocol/Protocol17x.h +++ b/src/Protocol/Protocol17x.h @@ -102,7 +102,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) override; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override; diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index 86f46f02f..5524af136 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -636,10 +636,10 @@ void cProtocolRecognizer::SendUnloadChunk(int a_ChunkX, int a_ChunkZ) -void cProtocolRecognizer::SendUpdateBlockEntity(int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) +void cProtocolRecognizer::SendUpdateBlockEntity(cBlockEntity & a_BlockEntity) { ASSERT(m_Protocol != NULL); - m_Protocol->SendUpdateBlockEntity(a_BlockX, a_BlockY, a_BlockZ, a_Action, a_BlockEntity); + m_Protocol->SendUpdateBlockEntity(a_BlockEntity); } diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index c1c8abdd5..2dccace6e 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -114,7 +114,7 @@ public: virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override; virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay) override; virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override; - virtual void SendUpdateBlockEntity (int a_BlockX, int a_BlockY, int a_BlockZ, Byte a_Action, cBlockEntity & a_BlockEntity) override; + virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override; virtual void SendUpdateSign (int a_BlockX, int a_BlockY, int a_BlockZ, const AString & a_Line1, const AString & a_Line2, const AString & a_Line3, const AString & a_Line4) override; virtual void SendUseBed (const cEntity & a_Entity, int a_BlockX, int a_BlockY, int a_BlockZ ) override; virtual void SendWeather (eWeather a_Weather) override;