summaryrefslogtreecommitdiffstats
path: root/src/Protocol
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2014-09-30 20:48:40 +0200
committerMattes D <github@xoft.cz>2014-09-30 20:48:40 +0200
commit5de27e7edf29b2f79e647ad35d4a665900b83ac8 (patch)
tree6d19e415f5c7cacab867c5dff2855627fa6169fd /src/Protocol
parentMerge pull request #1427 from mc-server/chestcarts (diff)
parentFixed a missing semicolon. (diff)
downloadcuberite-5de27e7edf29b2f79e647ad35d4a665900b83ac8.tar
cuberite-5de27e7edf29b2f79e647ad35d4a665900b83ac8.tar.gz
cuberite-5de27e7edf29b2f79e647ad35d4a665900b83ac8.tar.bz2
cuberite-5de27e7edf29b2f79e647ad35d4a665900b83ac8.tar.lz
cuberite-5de27e7edf29b2f79e647ad35d4a665900b83ac8.tar.xz
cuberite-5de27e7edf29b2f79e647ad35d4a665900b83ac8.tar.zst
cuberite-5de27e7edf29b2f79e647ad35d4a665900b83ac8.zip
Diffstat (limited to '')
-rw-r--r--src/Protocol/Protocol17x.cpp92
-rw-r--r--src/Protocol/Protocol17x.h3
-rw-r--r--src/Protocol/Protocol18x.cpp86
-rw-r--r--src/Protocol/Protocol18x.h4
4 files changed, 172 insertions, 13 deletions
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index e4c33908a..a7abd240f 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -2064,6 +2064,22 @@ void cProtocol172::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
HANDLE_READ(a_ByteBuffer, ReadBEShort, short, Length);
+ if (Length + 1 != (int)a_ByteBuffer.GetReadableSpace())
+ {
+ LOGD("Invalid plugin message packet, payload length doesn't match packet length (exp %d, got %d)",
+ (int)a_ByteBuffer.GetReadableSpace() - 1, Length
+ );
+ return;
+ }
+
+ // If the plugin channel is recognized vanilla, handle it directly:
+ if (Channel.substr(0, 3) == "MC|")
+ {
+ HandleVanillaPluginMessage(a_ByteBuffer, Channel, Length);
+ return;
+ }
+
+ // Read the plugin message and relay to clienthandle:
AString Data;
if (!a_ByteBuffer.ReadString(Data, Length))
{
@@ -2217,6 +2233,82 @@ void cProtocol172::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer)
+void cProtocol172::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel, short a_PayloadLength)
+{
+ if (a_Channel == "MC|AdvCdm")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode);
+ switch (Mode)
+ {
+ case 0x00:
+ {
+ // Block-based commandblock update:
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockY);
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
+ HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Command);
+ m_Client->HandleCommandBlockBlockChange(BlockX, BlockY, BlockZ, Command);
+ break;
+ }
+
+ // TODO: Entity-based commandblock update
+
+ default:
+ {
+ m_Client->SendChat(Printf("Failure setting command block command; unhandled mode %d", Mode), mtFailure);
+ LOG("Unhandled MC|AdvCdm packet mode.");
+ return;
+ }
+ } // switch (Mode)
+ return;
+ }
+ else if (a_Channel == "MC|Brand")
+ {
+ // Read the client's brand:
+ AString Brand;
+ if (a_ByteBuffer.ReadString(Brand, a_PayloadLength))
+ {
+ m_Client->SetClientBrand(Brand);
+ }
+
+ // Send back our brand:
+ SendPluginMessage("MC|Brand", "MCServer");
+ return;
+ }
+ else if (a_Channel == "MC|Beacon")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, Effect1);
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, Effect2);
+ m_Client->HandleBeaconSelection(Effect1, Effect2);
+ return;
+ }
+ else if (a_Channel == "MC|ItemName")
+ {
+ AString ItemName;
+ if (a_ByteBuffer.ReadString(ItemName, a_PayloadLength))
+ {
+ m_Client->HandleAnvilItemName(ItemName);
+ }
+ return;
+ }
+ else if (a_Channel == "MC|TrSel")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, SlotNum);
+ m_Client->HandleNPCTrade(SlotNum);
+ return;
+ }
+ LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str());
+
+ // Read the payload and send it through to the clienthandle:
+ AString Message;
+ VERIFY(a_ByteBuffer.ReadString(Message, a_PayloadLength));
+ m_Client->HandlePluginMessage(a_Channel, Message);
+}
+
+
+
+
+
void cProtocol172::SendData(const char * a_Data, size_t a_Size)
{
if (m_IsEncrypted)
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 0bc86a72a..7709df59d 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -295,6 +295,9 @@ protected:
void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
+ /** Parses Vanilla plugin messages into specific ClientHandle calls.
+ The message payload is still in the bytebuffer, to be read by this function. */
+ void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel, short a_PayloadLength);
/** Sends the data to the client, encrypting them if needed. */
virtual void SendData(const char * a_Data, size_t a_Size) override;
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 1070a8434..acdb48cf7 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -989,10 +989,6 @@ void cProtocol180::SendPluginMessage(const AString & a_Channel, const AString &
cPacketizer Pkt(*this, 0x3f);
Pkt.WriteString(a_Channel);
- if (a_Channel.substr(0, 3) == "MC|")
- {
- Pkt.WriteVarInt((UInt32)a_Message.size());
- }
Pkt.WriteBuf(a_Message.data(), a_Message.size());
}
@@ -2324,18 +2320,17 @@ void cProtocol180::HandlePacketPlayerPosLook(cByteBuffer & a_ByteBuffer)
void cProtocol180::HandlePacketPluginMessage(cByteBuffer & a_ByteBuffer)
{
HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Channel);
- AString Data;
+
+ // If the plugin channel is recognized vanilla, handle it directly:
if (Channel.substr(0, 3) == "MC|")
{
- // Vanilla sends the payload length within the payload itself, so skip it:
- HANDLE_READ(a_ByteBuffer, ReadVarInt, UInt32, DataLen);
- if (DataLen != a_ByteBuffer.GetReadableSpace() - 1)
- {
- ASSERT(!"Bad plugin message payload length");
- return;
- }
+ HandleVanillaPluginMessage(a_ByteBuffer, Channel);
+ return;
}
- a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1); // Always succeeds
+
+ // Read the plugin message and relay to clienthandle:
+ AString Data;
+ VERIFY(a_ByteBuffer.ReadString(Data, a_ByteBuffer.GetReadableSpace() - 1)); // Always succeeds
m_Client->HandlePluginMessage(Channel, Data);
}
@@ -2524,6 +2519,71 @@ void cProtocol180::HandlePacketWindowClose(cByteBuffer & a_ByteBuffer)
+void cProtocol180::HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel)
+{
+ if (a_Channel == "MC|AdvCdm")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadByte, Byte, Mode)
+ switch (Mode)
+ {
+ case 0x00:
+ {
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockX);
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockY);
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, BlockZ);
+ HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Command);
+ m_Client->HandleCommandBlockBlockChange(BlockX, BlockY, BlockZ, Command);
+ break;
+ }
+
+ default:
+ {
+ m_Client->SendChat(Printf("Failure setting command block command; unhandled mode %d", Mode), mtFailure);
+ LOG("Unhandled MC|AdvCdm packet mode.");
+ return;
+ }
+ } // switch (Mode)
+ return;
+ }
+ else if (a_Channel == "MC|Brand")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, Brand);
+ m_Client->SetClientBrand(Brand);
+ // Send back our brand, including the length:
+ SendPluginMessage("MC|Brand", "\x08MCServer");
+ return;
+ }
+ else if (a_Channel == "MC|Beacon")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, Effect1);
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, Effect2);
+ m_Client->HandleBeaconSelection(Effect1, Effect2);
+ return;
+ }
+ else if (a_Channel == "MC|ItemName")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadVarUTF8String, AString, ItemName);
+ m_Client->HandleAnvilItemName(ItemName);
+ return;
+ }
+ else if (a_Channel == "MC|TrSel")
+ {
+ HANDLE_READ(a_ByteBuffer, ReadBEInt, int, SlotNum);
+ m_Client->HandleNPCTrade(SlotNum);
+ return;
+ }
+ LOG("Unhandled vanilla plugin channel: \"%s\".", a_Channel.c_str());
+
+ // Read the payload and send it through to the clienthandle:
+ AString Message;
+ VERIFY(a_ByteBuffer.ReadString(Message, a_ByteBuffer.GetReadableSpace() - 1));
+ m_Client->HandlePluginMessage(a_Channel, Message);
+}
+
+
+
+
+
void cProtocol180::SendData(const char * a_Data, size_t a_Size)
{
if (m_IsEncrypted)
diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h
index acc167a6d..8c0b77a21 100644
--- a/src/Protocol/Protocol18x.h
+++ b/src/Protocol/Protocol18x.h
@@ -312,6 +312,10 @@ protected:
void HandlePacketWindowClick (cByteBuffer & a_ByteBuffer);
void HandlePacketWindowClose (cByteBuffer & a_ByteBuffer);
+ /** Parses Vanilla plugin messages into specific ClientHandle calls.
+ The message payload is still in the bytebuffer, the handler reads it specifically for each handled channel */
+ void HandleVanillaPluginMessage(cByteBuffer & a_ByteBuffer, const AString & a_Channel);
+
/** Sends the data to the client, encrypting them if needed. */
virtual void SendData(const char * a_Data, size_t a_Size) override;