summaryrefslogtreecommitdiffstats
path: root/src/Protocol
diff options
context:
space:
mode:
Diffstat (limited to 'src/Protocol')
-rw-r--r--src/Protocol/Authenticator.cpp20
-rw-r--r--src/Protocol/Authenticator.h6
-rw-r--r--src/Protocol/CMakeLists.txt9
-rw-r--r--src/Protocol/ChunkDataSerializer.cpp60
-rw-r--r--src/Protocol/ChunkDataSerializer.h2
-rw-r--r--src/Protocol/MojangAPI.cpp48
-rw-r--r--src/Protocol/MojangAPI.h4
-rw-r--r--src/Protocol/Packetizer.h2
-rw-r--r--src/Protocol/Protocol.h13
-rw-r--r--src/Protocol/Protocol17x.cpp137
-rw-r--r--src/Protocol/Protocol17x.h13
-rw-r--r--src/Protocol/Protocol18x.cpp232
-rw-r--r--src/Protocol/Protocol18x.h13
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp130
-rw-r--r--src/Protocol/ProtocolRecognizer.h13
15 files changed, 581 insertions, 121 deletions
diff --git a/src/Protocol/Authenticator.cpp b/src/Protocol/Authenticator.cpp
index c9e4296a2..bfbe5028d 100644
--- a/src/Protocol/Authenticator.cpp
+++ b/src/Protocol/Authenticator.cpp
@@ -19,6 +19,10 @@
#define DEFAULT_AUTH_SERVER "sessionserver.mojang.com"
#define DEFAULT_AUTH_ADDRESS "/session/minecraft/hasJoined?username=%USERNAME%&serverId=%SERVERID%"
+
+
+
+
cAuthenticator::cAuthenticator(void) :
super("cAuthenticator"),
m_Server(DEFAULT_AUTH_SERVER),
@@ -40,11 +44,11 @@ cAuthenticator::~cAuthenticator()
-void cAuthenticator::ReadINI(cIniFile & IniFile)
+void cAuthenticator::ReadSettings(cSettingsRepositoryInterface & a_Settings)
{
- m_Server = IniFile.GetValueSet ("Authentication", "Server", DEFAULT_AUTH_SERVER);
- m_Address = IniFile.GetValueSet ("Authentication", "Address", DEFAULT_AUTH_ADDRESS);
- m_ShouldAuthenticate = IniFile.GetValueSetB("Authentication", "Authenticate", true);
+ m_Server = a_Settings.GetValueSet ("Authentication", "Server", DEFAULT_AUTH_SERVER);
+ m_Address = a_Settings.GetValueSet ("Authentication", "Address", DEFAULT_AUTH_ADDRESS);
+ m_ShouldAuthenticate = a_Settings.GetValueSetB("Authentication", "Authenticate", true);
}
@@ -69,9 +73,9 @@ void cAuthenticator::Authenticate(int a_ClientID, const AString & a_UserName, co
-void cAuthenticator::Start(cIniFile & IniFile)
+void cAuthenticator::Start(cSettingsRepositoryInterface & a_Settings)
{
- ReadINI(IniFile);
+ ReadSettings(a_Settings);
m_ShouldTerminate = false;
super::Start();
}
@@ -267,3 +271,7 @@ bool cAuthenticator::GetPlayerProperties(const AString & a_UUID, Json::Value & a
return true;
}
*/
+
+
+
+
diff --git a/src/Protocol/Authenticator.h b/src/Protocol/Authenticator.h
index 853eff535..02b349256 100644
--- a/src/Protocol/Authenticator.h
+++ b/src/Protocol/Authenticator.h
@@ -14,7 +14,7 @@
#include "../OSSupport/IsThread.h"
-
+class cSettingsRepositoryInterface;
@@ -40,13 +40,13 @@ public:
~cAuthenticator();
/** (Re-)read server and address from INI: */
- void ReadINI(cIniFile & IniFile);
+ void ReadSettings(cSettingsRepositoryInterface & a_Settings);
/** Queues a request for authenticating a user. If the auth fails, the user will be kicked */
void Authenticate(int a_ClientID, const AString & a_UserName, const AString & a_ServerHash);
/** Starts the authenticator thread. The thread may be started and stopped repeatedly */
- void Start(cIniFile & IniFile);
+ void Start(cSettingsRepositoryInterface & a_Settings);
/** Stops the authenticator thread. The thread may be started and stopped repeatedly */
void Stop(void);
diff --git a/src/Protocol/CMakeLists.txt b/src/Protocol/CMakeLists.txt
index c3a45ca47..42a7d5a9d 100644
--- a/src/Protocol/CMakeLists.txt
+++ b/src/Protocol/CMakeLists.txt
@@ -25,6 +25,15 @@ SET (HDRS
ProtocolRecognizer.h
)
+if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+ set_source_files_properties(ChunkDataSerializer.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=old-style-cast")
+ set_source_files_properties(MojangAPI.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=old-style-cast")
+ set_source_files_properties(Packetizer.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=old-style-cast")
+ set_source_files_properties(Protocol18x.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=old-style-cast -Wno-error=sign-conversion -Wno-error=conversion -Wno-error=switch-enum -Wno-error=switch")
+ set_source_files_properties(Protocol17x.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=switch-enum -Wno-error=old-style-cast")
+ set_source_files_properties(ProtocolRecognizer.cpp PROPERTIES COMPILE_FLAGS "-Wno-error=old-style-cast")
+endif()
+
if (NOT MSVC)
add_library(Protocol ${SRCS} ${HDRS})
endif()
diff --git a/src/Protocol/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp
index 2b9c06779..37fbae0e5 100644
--- a/src/Protocol/ChunkDataSerializer.cpp
+++ b/src/Protocol/ChunkDataSerializer.cpp
@@ -43,7 +43,6 @@ const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int
AString data;
switch (a_Version)
{
- case RELEASE_1_2_5: Serialize29(data); break;
case RELEASE_1_3_2: Serialize39(data); break;
case RELEASE_1_8_0: Serialize47(data, a_ChunkX, a_ChunkZ); break;
// TODO: Other protocol versions may serialize the data differently; implement here
@@ -65,65 +64,6 @@ const AString & cChunkDataSerializer::Serialize(int a_Version, int a_ChunkX, int
-
-void cChunkDataSerializer::Serialize29(AString & a_Data)
-{
- // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib can stream)
-
- const int BiomeDataSize = cChunkDef::Width * cChunkDef::Width;
- const int MetadataOffset = sizeof(m_BlockTypes);
- const int BlockLightOffset = MetadataOffset + sizeof(m_BlockMetas);
- const int SkyLightOffset = BlockLightOffset + sizeof(m_BlockLight);
- const int BiomeOffset = SkyLightOffset + sizeof(m_BlockSkyLight);
- const int DataSize = BiomeOffset + BiomeDataSize;
-
- // Temporary buffer for the composed data:
- char AllData [DataSize];
-
- memcpy(AllData, m_BlockTypes, sizeof(m_BlockTypes));
- memcpy(AllData + MetadataOffset, m_BlockMetas, sizeof(m_BlockMetas));
- memcpy(AllData + BlockLightOffset, m_BlockLight, sizeof(m_BlockLight));
- memcpy(AllData + SkyLightOffset, m_BlockSkyLight, sizeof(m_BlockSkyLight));
- memcpy(AllData + BiomeOffset, m_BiomeData, BiomeDataSize);
-
- // Compress the data:
- // In order not to use allocation, use a fixed-size buffer, with the size
- // that uses the same calculation as compressBound():
- const uLongf CompressedMaxSize = DataSize + (DataSize >> 12) + (DataSize >> 14) + (DataSize >> 25) + 16;
- char CompressedBlockData[CompressedMaxSize];
-
- uLongf CompressedSize = compressBound(DataSize);
-
- // Run-time check that our compile-time guess about CompressedMaxSize was enough:
- ASSERT(CompressedSize <= CompressedMaxSize);
-
- compress2((Bytef*)CompressedBlockData, &CompressedSize, (const Bytef*)AllData, sizeof(AllData), Z_DEFAULT_COMPRESSION);
-
- // Now put all those data into a_Data:
-
- // "Ground-up continuous", or rather, "biome data present" flag:
- a_Data.push_back('\x01');
-
- // Two bitmaps; we're aways sending the full chunk with no additional data, so the bitmaps are 0xffff and 0, respectively
- // Also, no endian flipping is needed because of the const values
- unsigned short BitMap1 = 0xffff;
- unsigned short BitMap2 = 0;
- a_Data.append((const char *)&BitMap1, sizeof(short));
- a_Data.append((const char *)&BitMap2, sizeof(short));
-
- UInt32 CompressedSizeBE = htonl((UInt32)CompressedSize);
- a_Data.append((const char *)&CompressedSizeBE, sizeof(CompressedSizeBE));
-
- Int32 UnusedInt32 = 0;
- a_Data.append((const char *)&UnusedInt32, sizeof(UnusedInt32));
-
- a_Data.append(CompressedBlockData, CompressedSize);
-}
-
-
-
-
-
void cChunkDataSerializer::Serialize39(AString & a_Data)
{
// TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib can stream)
diff --git a/src/Protocol/ChunkDataSerializer.h b/src/Protocol/ChunkDataSerializer.h
index a082ef3d8..6acc1544b 100644
--- a/src/Protocol/ChunkDataSerializer.h
+++ b/src/Protocol/ChunkDataSerializer.h
@@ -22,14 +22,12 @@ protected:
Serializations m_Serializations;
- void Serialize29(AString & a_Data); // Release 1.2.4 and 1.2.5
void Serialize39(AString & a_Data); // Release 1.3.1 to 1.7.10
void Serialize47(AString & a_Data, int a_ChunkX, int a_ChunkZ); // Release 1.8
public:
enum
{
- RELEASE_1_2_5 = 29,
RELEASE_1_3_2 = 39,
RELEASE_1_8_0 = 47,
} ;
diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp
index 0d1441500..110590359 100644
--- a/src/Protocol/MojangAPI.cpp
+++ b/src/Protocol/MojangAPI.cpp
@@ -38,12 +38,36 @@ const int MAX_PER_QUERY = 100;
-/** This is the data of the root certs for Starfield Technologies, the CA that signed sessionserver.mojang.com's cert:
-Downloaded from http://certs.starfieldtech.com/repository/ */
-static const AString & StarfieldCACert(void)
+/** Returns the CA certificates that should be trusted for Mojang-related connections. */
+static const AString & GetCACerts(void)
{
static const AString Cert(
- // G2 cert
+ // Equifax root CA cert
+ // Currently used for signing *.mojang.com's cert
+ // Exported from Mozilla Firefox's built-in CA repository
+ "-----BEGIN CERTIFICATE-----\n"
+ "MIIDIDCCAomgAwIBAgIENd70zzANBgkqhkiG9w0BAQUFADBOMQswCQYDVQQGEwJV\n"
+ "UzEQMA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2Vy\n"
+ "dGlmaWNhdGUgQXV0aG9yaXR5MB4XDTk4MDgyMjE2NDE1MVoXDTE4MDgyMjE2NDE1\n"
+ "MVowTjELMAkGA1UEBhMCVVMxEDAOBgNVBAoTB0VxdWlmYXgxLTArBgNVBAsTJEVx\n"
+ "dWlmYXggU2VjdXJlIENlcnRpZmljYXRlIEF1dGhvcml0eTCBnzANBgkqhkiG9w0B\n"
+ "AQEFAAOBjQAwgYkCgYEAwV2xWGcIYu6gmi0fCG2RFGiYCh7+2gRvE4RiIcPRfM6f\n"
+ "BeC4AfBONOziipUEZKzxa1NfBbPLZ4C/QgKO/t0BCezhABRP/PvwDN1Dulsr4R+A\n"
+ "cJkVV5MW8Q+XarfCaCMczE1ZMKxRHjuvK9buY0V7xdlfUNLjUA86iOe/FP3gx7kC\n"
+ "AwEAAaOCAQkwggEFMHAGA1UdHwRpMGcwZaBjoGGkXzBdMQswCQYDVQQGEwJVUzEQ\n"
+ "MA4GA1UEChMHRXF1aWZheDEtMCsGA1UECxMkRXF1aWZheCBTZWN1cmUgQ2VydGlm\n"
+ "aWNhdGUgQXV0aG9yaXR5MQ0wCwYDVQQDEwRDUkwxMBoGA1UdEAQTMBGBDzIwMTgw\n"
+ "ODIyMTY0MTUxWjALBgNVHQ8EBAMCAQYwHwYDVR0jBBgwFoAUSOZo+SvSspXXR9gj\n"
+ "IBBPM5iQn9QwHQYDVR0OBBYEFEjmaPkr0rKV10fYIyAQTzOYkJ/UMAwGA1UdEwQF\n"
+ "MAMBAf8wGgYJKoZIhvZ9B0EABA0wCxsFVjMuMGMDAgbAMA0GCSqGSIb3DQEBBQUA\n"
+ "A4GBAFjOKer89961zgK5F7WF0bnj4JXMJTENAKaSbn+2kmOeUJXRmm/kEd5jhW6Y\n"
+ "7qj/WsjTVbJmcVfewCHrPSqnI0kBBIZCe/zuf6IWUrVnZ9NA2zsmWLIodz2uFHdh\n"
+ "1voqZiegDfqnc1zqcPGUIWVEX/r87yloqaKHee9570+sB3c4\n"
+ "-----END CERTIFICATE-----\n\n"
+
+ // Starfield G2 cert
+ // This is the data of the root certs for Starfield Technologies, the CA that used to sign sessionserver.mojang.com's cert
+ // Downloaded from http://certs.starfieldtech.com/repository/
"-----BEGIN CERTIFICATE-----\n"
"MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMx\n"
"EDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoT\n"
@@ -67,7 +91,8 @@ static const AString & StarfieldCACert(void)
"pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1\n"
"mMpYjn0q7pBZc2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0\n"
"-----END CERTIFICATE-----\n\n"
- // Original (G1) cert:
+
+ // Starfield original (G1) cert:
"-----BEGIN CERTIFICATE-----\n"
"MIIEDzCCAvegAwIBAgIBADANBgkqhkiG9w0BAQUFADBoMQswCQYDVQQGEwJVUzEl\n"
"MCMGA1UEChMcU3RhcmZpZWxkIFRlY2hub2xvZ2llcywgSW5jLjEyMDAGA1UECxMp\n"
@@ -226,12 +251,12 @@ cMojangAPI::~cMojangAPI()
-void cMojangAPI::Start(cIniFile & a_SettingsIni, bool a_ShouldAuth)
+void cMojangAPI::Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth)
{
- m_NameToUUIDServer = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER);
- m_NameToUUIDAddress = a_SettingsIni.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS);
- m_UUIDToProfileServer = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER);
- m_UUIDToProfileAddress = a_SettingsIni.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS);
+ m_NameToUUIDServer = a_Settings.GetValueSet("MojangAPI", "NameToUUIDServer", DEFAULT_NAME_TO_UUID_SERVER);
+ m_NameToUUIDAddress = a_Settings.GetValueSet("MojangAPI", "NameToUUIDAddress", DEFAULT_NAME_TO_UUID_ADDRESS);
+ m_UUIDToProfileServer = a_Settings.GetValueSet("MojangAPI", "UUIDToProfileServer", DEFAULT_UUID_TO_PROFILE_SERVER);
+ m_UUIDToProfileAddress = a_Settings.GetValueSet("MojangAPI", "UUIDToProfileAddress", DEFAULT_UUID_TO_PROFILE_ADDRESS);
LoadCachesFromDisk();
if (a_ShouldAuth)
{
@@ -390,7 +415,7 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
{
// Connect the socket:
cBlockingSslClientSocket Socket;
- Socket.SetTrustedRootCertsFromString(StarfieldCACert(), a_ServerName);
+ Socket.SetTrustedRootCertsFromString(GetCACerts(), a_ServerName);
if (!Socket.Connect(a_ServerName, 443))
{
LOGWARNING("%s: Can't connect to %s: %s", __FUNCTION__, a_ServerName.c_str(), Socket.GetLastErrorText().c_str());
@@ -434,7 +459,6 @@ bool cMojangAPI::SecureRequest(const AString & a_ServerName, const AString & a_R
a_Response.append((const char *)buf, (size_t)ret);
}
- Socket.Disconnect();
return true;
}
diff --git a/src/Protocol/MojangAPI.h b/src/Protocol/MojangAPI.h
index 0dc2617b6..bea950740 100644
--- a/src/Protocol/MojangAPI.h
+++ b/src/Protocol/MojangAPI.h
@@ -25,7 +25,7 @@ namespace Json
-
+class cSettingsRepositoryInterface;
// tolua_begin
class cMojangAPI
@@ -38,7 +38,7 @@ public:
/** Initializes the API; reads the settings from the specified ini file.
Loads cached results from disk. */
- void Start(cIniFile & a_SettingsIni, bool a_ShouldAuth);
+ void Start(cSettingsRepositoryInterface & a_Settings, bool a_ShouldAuth);
/** Connects to the specified server using SSL, sends the given request and receives the response.
Checks Mojang certificates using the hard-coded Starfield root CA certificate.
diff --git a/src/Protocol/Packetizer.h b/src/Protocol/Packetizer.h
index 7f5e9c2c3..efed9c7a9 100644
--- a/src/Protocol/Packetizer.h
+++ b/src/Protocol/Packetizer.h
@@ -58,7 +58,7 @@ public:
}
- inline void WriteBEUInt16(short a_Value)
+ inline void WriteBEUInt16(UInt16 a_Value)
{
VERIFY(m_Out.WriteBEUInt16(a_Value));
}
diff --git a/src/Protocol/Protocol.h b/src/Protocol/Protocol.h
index 3bca7551b..1a19249bf 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -70,6 +70,12 @@ public:
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) = 0;
virtual void SendChat (const AString & a_Message) = 0;
virtual void SendChat (const cCompositeChat & a_Message) = 0;
+ virtual void SendChatAboveActionBar (const AString & a_Message) = 0;
+ virtual void SendChatAboveActionBar (const cCompositeChat & a_Message) = 0;
+ virtual void SendChatSystem (const AString & a_Message) = 0;
+ virtual void SendChatSystem (const cCompositeChat & a_Message) = 0;
+ virtual void SendChatType (const AString & a_Message, eChatType type) = 0;
+ virtual void SendChatType (const cCompositeChat & a_Message, eChatType type) = 0;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) = 0;
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) = 0;
virtual void SendDestroyEntity (const cEntity & a_Entity) = 0;
@@ -88,6 +94,7 @@ public:
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) = 0;
virtual void SendGameMode (eGameMode a_GameMode) = 0;
virtual void SendHealth (void) = 0;
+ virtual void SendHideTitle (void) = 0;
virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) = 0;
virtual void SendKeepAlive (int a_PingID) = 0;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) = 0;
@@ -112,12 +119,17 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) = 0;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) = 0;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) = 0;
+ virtual void SendResetTitle (void) = 0;
virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) = 0;
virtual void SendExperience (void) = 0;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) = 0;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) = 0;
virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) = 0;
virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) = 0;
+ virtual void SendSetSubTitle (const cCompositeChat & a_SubTitle) = 0;
+ virtual void SendSetRawSubTitle (const AString & a_SubTitle) = 0;
+ virtual void SendSetTitle (const cCompositeChat & a_Title) = 0;
+ virtual void SendSetRawTitle (const AString & a_Title) = 0;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) = 0;
virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) = 0;
virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) = 0;
@@ -128,6 +140,7 @@ public:
virtual void SendTabCompletionResults (const AStringVector & a_Results) = 0;
virtual void SendTeleportEntity (const cEntity & a_Entity) = 0;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) = 0;
+ virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) = 0;
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) = 0;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) = 0;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) = 0;
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index 799c021f3..c5c0f4a03 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -247,8 +247,67 @@ void cProtocol172::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
void cProtocol172::SendChat(const AString & a_Message)
{
+ this->SendChatType(a_Message, ctChatBox);
+}
+
+
+
+
+
+void cProtocol172::SendChat(const cCompositeChat & a_Message)
+{
+ this->SendChatType(a_Message, ctChatBox);
+}
+
+
+
+
+
+void cProtocol172::SendChatSystem(const AString & a_Message)
+{
+ this->SendChatType(a_Message, ctSystem);
+}
+
+
+
+
+
+void cProtocol172::SendChatSystem(const cCompositeChat & a_Message)
+{
+ this->SendChatType(a_Message, ctSystem);
+}
+
+
+
+
+
+void cProtocol172::SendChatAboveActionBar(const AString & a_Message)
+{
+ this->SendChatType(a_Message, ctAboveActionBar);
+}
+
+
+
+
+
+void cProtocol172::SendChatAboveActionBar(const cCompositeChat & a_Message)
+{
+ this->SendChatType(a_Message, ctAboveActionBar);
+}
+
+
+
+
+
+void cProtocol172::SendChatType(const AString & a_Message, eChatType type)
+{
ASSERT(m_State == 3); // In game mode?
-
+
+ if (type != ctChatBox) // 1.7.2 doesn't support anything else
+ {
+ return;
+ }
+
cPacketizer Pkt(*this, 0x02); // Chat Message packet
Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str()));
}
@@ -257,10 +316,15 @@ void cProtocol172::SendChat(const AString & a_Message)
-void cProtocol172::SendChat(const cCompositeChat & a_Message)
+void cProtocol172::SendChatType(const cCompositeChat & a_Message, eChatType type)
{
ASSERT(m_State == 3); // In game mode?
+ if (type != ctChatBox) // 1.7.2 doesn't support anything else
+ {
+ return;
+ }
+
cWorld * World = m_Client->GetPlayer()->GetWorld();
bool ShouldUseChatPrefixes = (World == nullptr) ? false : World->ShouldUseChatPrefixes();
@@ -555,6 +619,15 @@ void cProtocol172::SendHealth(void)
+void cProtocol172::SendHideTitle(void)
+{
+ // Not implemented in this protocol version
+}
+
+
+
+
+
void cProtocol172::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item)
{
ASSERT(m_State == 3); // In game mode?
@@ -995,6 +1068,15 @@ void cProtocol172::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
+void cProtocol172::SendResetTitle(void)
+{
+ // Not implemented in this protocol version
+}
+
+
+
+
+
void cProtocol172::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks)
{
if ((m_LastSentDimension == a_Dimension) && !a_ShouldIgnoreDimensionChecks)
@@ -1023,8 +1105,8 @@ void cProtocol172::SendExperience (void)
cPacketizer Pkt(*this, 0x1f); // Experience Packet
cPlayer * Player = m_Client->GetPlayer();
Pkt.WriteBEFloat(Player->GetXpPercentage());
- Pkt.WriteBEInt16(static_cast<UInt16>(std::max<int>(Player->GetXpLevel(), std::numeric_limits<UInt16>::max())));
- Pkt.WriteBEInt16(static_cast<UInt16>(std::max<int>(Player->GetCurrentXp(), std::numeric_limits<UInt16>::max())));
+ Pkt.WriteBEInt16(static_cast<Int16>(std::min<int>(Player->GetXpLevel(), std::numeric_limits<Int16>::max())));
+ Pkt.WriteBEInt16(static_cast<Int16>(std::min<int>(Player->GetCurrentXp(), std::numeric_limits<Int16>::max())));
}
@@ -1094,6 +1176,42 @@ void cProtocol172::SendDisplayObjective(const AString & a_Objective, cScoreboard
+void cProtocol172::SendSetSubTitle(const cCompositeChat & a_SubTitle)
+{
+ // Not implemented in this protocol version
+}
+
+
+
+
+
+void cProtocol172::SendSetRawSubTitle(const AString & a_SubTitle)
+{
+ // Not implemented in this protocol version
+}
+
+
+
+
+
+void cProtocol172::SendSetTitle(const cCompositeChat & a_Title)
+{
+ // Not implemented in this protocol version
+}
+
+
+
+
+
+void cProtocol172::SendSetRawTitle(const AString & a_Title)
+{
+ // Not implemented in this protocol version
+}
+
+
+
+
+
void cProtocol172::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
{
ASSERT(m_State == 3); // In game mode?
@@ -1296,6 +1414,15 @@ void cProtocol172::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cProtocol172::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks)
+{
+ // Not implemented in this protocol version
+}
+
+
+
+
+
void cProtocol172::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle)
{
ASSERT(m_State == 3); // In game mode?
@@ -2247,7 +2374,7 @@ void cProtocol172::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
case 0x0206: Action = caNumber7; break;
case 0x0207: Action = caNumber8; break;
case 0x0208: Action = caNumber9; break;
- case 0x0300: Action = caMiddleClick; break;
+ case 0x0302: Action = caMiddleClick; break;
case 0x0400: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftClickOutsideHoldNothing : caDropKey; break;
case 0x0401: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caRightClickOutsideHoldNothing : caCtrlDropKey; break;
case 0x0500: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftPaintBegin : caUnknown; break;
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 773c39f87..b07fa9ed9 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -68,6 +68,12 @@ public:
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override;
virtual void SendChat (const cCompositeChat & a_Message) override;
+ virtual void SendChatAboveActionBar (const AString & a_Message) override;
+ virtual void SendChatAboveActionBar (const cCompositeChat & a_Message) override;
+ virtual void SendChatSystem (const AString & a_Message) override;
+ virtual void SendChatSystem (const cCompositeChat & a_Message) override;
+ virtual void SendChatType (const AString & a_Message, eChatType type) override;
+ virtual void SendChatType (const cCompositeChat & a_Message, eChatType type) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
@@ -90,6 +96,7 @@ public:
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override;
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHealth (void) override;
+ virtual void SendHideTitle (void) override;
virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override;
virtual void SendKeepAlive (int a_PingID) override;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
@@ -113,9 +120,14 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
+ virtual void SendResetTitle (void) override;
virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override;
virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
+ virtual void SendSetSubTitle (const cCompositeChat & a_SubTitle) override;
+ virtual void SendSetRawSubTitle (const AString & a_SubTitle) override;
+ virtual void SendSetTitle (const cCompositeChat & a_Title) override;
+ virtual void SendSetRawTitle (const AString & a_Title) override;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override;
virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override;
@@ -126,6 +138,7 @@ public:
virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
+ virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override;
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override;
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 17faca27e..4708d67c9 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -51,7 +51,7 @@ Implements the 1.8.x protocol classes:
/** The slot number that the client uses to indicate "outside the window". */
-static const Int16 SLOT_NUM_OUTSIDE = -1;
+static const Int16 SLOT_NUM_OUTSIDE = -999;
@@ -234,18 +234,72 @@ void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockV
void cProtocol180::SendChat(const AString & a_Message)
{
+ this->SendChatType(a_Message, ctChatBox);
+}
+
+
+
+
+
+void cProtocol180::SendChat(const cCompositeChat & a_Message)
+{
+ this->SendChatType(a_Message, ctChatBox);
+}
+
+
+
+
+
+void cProtocol180::SendChatSystem(const AString & a_Message)
+{
+ this->SendChatType(a_Message, ctSystem);
+}
+
+
+
+
+
+void cProtocol180::SendChatSystem(const cCompositeChat & a_Message)
+{
+ this->SendChatType(a_Message, ctSystem);
+}
+
+
+
+
+
+void cProtocol180::SendChatAboveActionBar(const AString & a_Message)
+{
+ this->SendChatType(a_Message, ctAboveActionBar);
+}
+
+
+
+
+
+void cProtocol180::SendChatAboveActionBar(const cCompositeChat & a_Message)
+{
+ this->SendChatType(a_Message, ctAboveActionBar);
+}
+
+
+
+
+
+void cProtocol180::SendChatType(const AString & a_Message, eChatType type)
+{
ASSERT(m_State == 3); // In game mode?
cPacketizer Pkt(*this, 0x02); // Chat Message packet
Pkt.WriteString(Printf("{\"text\":\"%s\"}", EscapeString(a_Message).c_str()));
- Pkt.WriteBEInt8(0);
+ Pkt.WriteBEInt8(type);
}
-void cProtocol180::SendChat(const cCompositeChat & a_Message)
+void cProtocol180::SendChatType(const cCompositeChat & a_Message, eChatType type)
{
ASSERT(m_State == 3); // In game mode?
@@ -255,7 +309,7 @@ void cProtocol180::SendChat(const cCompositeChat & a_Message)
// Send the message to the client:
cPacketizer Pkt(*this, 0x02);
Pkt.WriteString(a_Message.CreateJsonString(ShouldUseChatPrefixes));
- Pkt.WriteBEInt8(0);
+ Pkt.WriteBEInt8(type);
}
@@ -542,6 +596,18 @@ void cProtocol180::SendHealth(void)
+void cProtocol180::SendHideTitle(void)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x45); // Title packet
+ Pkt.WriteVarInt32(3); // Hide title
+}
+
+
+
+
+
void cProtocol180::SendInventorySlot(char a_WindowID, short a_SlotNum, const cItem & a_Item)
{
ASSERT(m_State == 3); // In game mode?
@@ -681,7 +747,7 @@ void cProtocol180::SendMapDecorators(int a_ID, const cMapDecoratorList & a_Decor
cPacketizer Pkt(*this, 0x34);
Pkt.WriteVarInt32(a_ID);
Pkt.WriteBEUInt8(m_Scale);
- Pkt.WriteVarInt32(a_Decorators.size());
+ Pkt.WriteVarInt32(static_cast<UInt32>(a_Decorators.size()));
for (cMapDecoratorList::const_iterator it = a_Decorators.begin(); it != a_Decorators.end(); ++it)
{
@@ -1065,6 +1131,18 @@ void cProtocol180::SendRemoveEntityEffect(const cEntity & a_Entity, int a_Effect
+void cProtocol180::SendResetTitle(void)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x45); // Title packet
+ Pkt.WriteVarInt32(4); // Reset title
+}
+
+
+
+
+
void cProtocol180::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks)
{
if ((m_LastSentDimension == a_Dimension) && !a_ShouldIgnoreDimensionChecks)
@@ -1167,6 +1245,52 @@ void cProtocol180::SendDisplayObjective(const AString & a_Objective, cScoreboard
+void cProtocol180::SendSetSubTitle(const cCompositeChat & a_SubTitle)
+{
+ SendSetRawSubTitle(a_SubTitle.CreateJsonString(false));
+}
+
+
+
+
+
+void cProtocol180::SendSetRawSubTitle(const AString & a_SubTitle)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x45); // Title packet
+ Pkt.WriteVarInt32(1); // Set subtitle
+
+ Pkt.WriteString(a_SubTitle);
+}
+
+
+
+
+
+void cProtocol180::SendSetTitle(const cCompositeChat & a_Title)
+{
+ SendSetRawTitle(a_Title.CreateJsonString(false));
+}
+
+
+
+
+
+void cProtocol180::SendSetRawTitle(const AString & a_Title)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x45); // Title packet
+ Pkt.WriteVarInt32(0); // Set title
+
+ Pkt.WriteString(a_Title);
+}
+
+
+
+
+
void cProtocol180::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
{
ASSERT(m_State == 3); // In game mode?
@@ -1374,6 +1498,22 @@ void cProtocol180::SendThunderbolt(int a_BlockX, int a_BlockY, int a_BlockZ)
+void cProtocol180::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks)
+{
+ ASSERT(m_State == 3); // In game mode?
+
+ cPacketizer Pkt(*this, 0x45); // Title packet
+ Pkt.WriteVarInt32(2); // Set title display times
+
+ Pkt.WriteBEInt32(a_FadeInTicks);
+ Pkt.WriteBEInt32(a_DisplayTicks);
+ Pkt.WriteBEInt32(a_FadeOutTicks);
+}
+
+
+
+
+
void cProtocol180::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle)
{
ASSERT(m_State == 3); // In game mode?
@@ -1575,7 +1715,7 @@ bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_Compress
// Compress the data:
char CompressedData[MAX_COMPRESSED_PACKET_LEN];
- uLongf CompressedSize = compressBound(a_Packet.size());
+ uLongf CompressedSize = compressBound(static_cast<uLongf>(a_Packet.size()));
if (CompressedSize >= MAX_COMPRESSED_PACKET_LEN)
{
ASSERT(!"Too high packet size.");
@@ -1584,7 +1724,7 @@ bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_Compress
int Status = compress2(
reinterpret_cast<Bytef *>(CompressedData), &CompressedSize,
- reinterpret_cast<const Bytef *>(a_Packet.data()), a_Packet.size(), Z_DEFAULT_COMPRESSION
+ reinterpret_cast<const Bytef *>(a_Packet.data()), static_cast<uLongf>(a_Packet.size()), Z_DEFAULT_COMPRESSION
);
if (Status != Z_OK)
{
@@ -1597,7 +1737,7 @@ bool cProtocol180::CompressPacket(const AString & a_Packet, AString & a_Compress
Buffer.ReadAll(LengthData);
Buffer.CommitRead();
- Buffer.WriteVarInt32(CompressedSize + LengthData.size());
+ Buffer.WriteVarInt32(static_cast<UInt32>(CompressedSize + LengthData.size()));
Buffer.WriteVarInt32(static_cast<UInt32>(a_Packet.size()));
Buffer.ReadAll(LengthData);
Buffer.CommitRead();
@@ -1770,7 +1910,7 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size)
AString UncompressedData;
if (m_State == 3)
{
- UInt32 NumBytesRead = m_ReceivedData.GetReadableSpace();
+ UInt32 NumBytesRead = static_cast<UInt32>(m_ReceivedData.GetReadableSpace());
m_ReceivedData.ReadVarInt(CompressedSize);
if (CompressedSize > PacketLen)
{
@@ -1781,17 +1921,16 @@ void cProtocol180::AddReceivedData(const char * a_Data, size_t a_Size)
{
// Decompress the data:
AString CompressedData;
- if (!m_ReceivedData.ReadString(CompressedData, CompressedSize))
+ if (!m_ReceivedData.ReadString(CompressedData, CompressedSize) || (InflateString(CompressedData.data(), CompressedSize, UncompressedData) != Z_OK))
{
m_Client->Kick("Compression failure");
return;
}
- InflateString(CompressedData.data(), CompressedSize, UncompressedData);
- PacketLen = UncompressedData.size();
+ PacketLen = static_cast<UInt32>(UncompressedData.size());
}
else
{
- NumBytesRead -= m_ReceivedData.GetReadableSpace(); // How many bytes has the CompressedSize taken up?
+ NumBytesRead -= static_cast<UInt32>(m_ReceivedData.GetReadableSpace()); // How many bytes has the CompressedSize taken up?
ASSERT(PacketLen > NumBytesRead);
PacketLen -= NumBytesRead;
}
@@ -2265,7 +2404,7 @@ void cProtocol180::HandlePacketCreativeInventoryAction(cByteBuffer & a_ByteBuffe
{
return;
}
- m_Client->HandleCreativeInventory(SlotNum, Item, (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftClickOutside : caLeftClick);
+ m_Client->HandleCreativeInventory(SlotNum, Item, (SlotNum == -1) ? caLeftClickOutside : caLeftClick);
}
@@ -2553,7 +2692,7 @@ void cProtocol180::HandlePacketWindowClick(cByteBuffer & a_ByteBuffer)
case 0x0206: Action = caNumber7; break;
case 0x0207: Action = caNumber8; break;
case 0x0208: Action = caNumber9; break;
- case 0x0300: Action = caMiddleClick; break;
+ case 0x0302: Action = caMiddleClick; break;
case 0x0400: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftClickOutsideHoldNothing : caDropKey; break;
case 0x0401: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caRightClickOutsideHoldNothing : caCtrlDropKey; break;
case 0x0500: Action = (SlotNum == SLOT_NUM_OUTSIDE) ? caLeftPaintBegin : caUnknown; break;
@@ -3202,7 +3341,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Bat.IsHanging() ? 1 : 0);
break;
} // case mtBat
-
+
case mtCreeper:
{
auto & Creeper = reinterpret_cast<const cCreeper &>(a_Mob);
@@ -3212,7 +3351,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Creeper.IsCharged() ? 1 : 0);
break;
} // case mtCreeper
-
+
case mtEnderman:
{
auto & Enderman = reinterpret_cast<const cEnderman &>(a_Mob);
@@ -3224,7 +3363,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Enderman.IsScreaming() ? 1 : 0);
break;
} // case mtEnderman
-
+
case mtGhast:
{
auto & Ghast = reinterpret_cast<const cGhast &>(a_Mob);
@@ -3232,7 +3371,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Ghast.IsCharging());
break;
} // case mtGhast
-
+
case mtHorse:
{
auto & Horse = reinterpret_cast<const cHorse &>(a_Mob);
@@ -3249,10 +3388,6 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
{
Flags |= 0x08;
}
- if (Horse.IsBaby())
- {
- Flags |= 0x10;
- }
if (Horse.IsEating())
{
Flags |= 0x20;
@@ -3276,6 +3411,9 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEInt32(Appearance);
a_Pkt.WriteBEUInt8(0x56); // Int at index 22
a_Pkt.WriteBEInt32(Horse.GetHorseArmour());
+
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Horse.GetAge());
break;
} // case mtHorse
@@ -3287,17 +3425,38 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
break;
} // case mtMagmaCube
+ case mtOcelot:
+ {
+ auto & Ocelot = reinterpret_cast<const cOcelot &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Ocelot.GetAge());
+ break;
+ } // case mtOcelot
+
case mtPig:
{
auto & Pig = reinterpret_cast<const cPig &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Pig.GetAge());
a_Pkt.WriteBEUInt8(0x10);
a_Pkt.WriteBEUInt8(Pig.IsSaddled() ? 1 : 0);
break;
} // case mtPig
-
+
+ case mtRabbit:
+ {
+ auto & Rabbit = reinterpret_cast<const cRabbit &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Rabbit.GetAge());
+ break;
+ } // case mtRabbit
+
case mtSheep:
{
auto & Sheep = reinterpret_cast<const cSheep &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Sheep.GetAge());
+
a_Pkt.WriteBEUInt8(0x10);
Byte SheepMetadata = 0;
SheepMetadata = Sheep.GetFurColor();
@@ -3308,7 +3467,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(SheepMetadata);
break;
} // case mtSheep
-
+
case mtSkeleton:
{
auto & Skeleton = reinterpret_cast<const cSkeleton &>(a_Mob);
@@ -3316,7 +3475,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Skeleton.IsWither() ? 1 : 0);
break;
} // case mtSkeleton
-
+
case mtSlime:
{
auto & Slime = reinterpret_cast<const cSlime &>(a_Mob);
@@ -3330,9 +3489,11 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
auto & Villager = reinterpret_cast<const cVillager &>(a_Mob);
a_Pkt.WriteBEUInt8(0x50);
a_Pkt.WriteBEInt32(Villager.GetVilType());
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Villager.GetAge());
break;
} // case mtVillager
-
+
case mtWitch:
{
auto & Witch = reinterpret_cast<const cWitch &>(a_Mob);
@@ -3350,7 +3511,7 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEFloat(static_cast<float>(a_Mob.GetHealth()));
break;
} // case mtWither
-
+
case mtWolf:
{
auto & Wolf = reinterpret_cast<const cWolf &>(a_Mob);
@@ -3376,20 +3537,31 @@ void cProtocol180::WriteMobMetadata(cPacketizer & a_Pkt, const cMonster & a_Mob)
a_Pkt.WriteBEUInt8(Wolf.IsBegging() ? 1 : 0);
a_Pkt.WriteBEUInt8(0x14);
a_Pkt.WriteBEUInt8(Wolf.GetCollarColor());
+
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(Wolf.GetAge());
break;
} // case mtWolf
-
+
case mtZombie:
{
auto & Zombie = reinterpret_cast<const cZombie &>(a_Mob);
a_Pkt.WriteBEUInt8(0x0c);
- a_Pkt.WriteBEUInt8(Zombie.IsBaby() ? 1 : 0);
+ a_Pkt.WriteBEInt8(Zombie.IsBaby() ? 1 : -1);
a_Pkt.WriteBEUInt8(0x0d);
a_Pkt.WriteBEUInt8(Zombie.IsVillagerZombie() ? 1 : 0);
a_Pkt.WriteBEUInt8(0x0e);
a_Pkt.WriteBEUInt8(Zombie.IsConverting() ? 1 : 0);
break;
} // case mtZombie
+
+ case mtZombiePigman:
+ {
+ auto & ZombiePigman = reinterpret_cast<const cZombiePigman &>(a_Mob);
+ a_Pkt.WriteBEUInt8(0x0c);
+ a_Pkt.WriteBEInt8(ZombiePigman.IsBaby() ? 1 : -1);
+ break;
+ } // case mtZombiePigman
} // switch (a_Mob.GetType())
}
diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h
index 21024d702..36ed251fe 100644
--- a/src/Protocol/Protocol18x.h
+++ b/src/Protocol/Protocol18x.h
@@ -67,6 +67,12 @@ public:
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override;
virtual void SendChat (const cCompositeChat & a_Message) override;
+ virtual void SendChatAboveActionBar (const AString & a_Message) override;
+ virtual void SendChatAboveActionBar (const cCompositeChat & a_Message) override;
+ virtual void SendChatSystem (const AString & a_Message) override;
+ virtual void SendChatSystem (const cCompositeChat & a_Message) override;
+ virtual void SendChatType (const AString & a_Message, eChatType type) override;
+ virtual void SendChatType (const cCompositeChat & a_Message, eChatType type) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
@@ -85,6 +91,7 @@ public:
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override;
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHealth (void) override;
+ virtual void SendHideTitle (void) override;
virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override;
virtual void SendKeepAlive (int a_PingID) override;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
@@ -109,6 +116,7 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
+ virtual void SendResetTitle (void) override;
virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
virtual void SendExperience (void) override;
@@ -116,6 +124,10 @@ public:
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override;
virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override;
+ virtual void SendSetSubTitle (const cCompositeChat & a_SubTitle) override;
+ virtual void SendSetRawSubTitle (const AString & a_SubTitle) override;
+ virtual void SendSetTitle (const cCompositeChat & a_Title) override;
+ virtual void SendSetRawTitle (const AString & a_Title) override;
virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override;
virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override;
virtual void SendSpawnMob (const cMonster & a_Mob) override;
@@ -125,6 +137,7 @@ public:
virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
+ virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override;
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override;
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index e7f7a4526..c89c745a4 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -158,6 +158,66 @@ void cProtocolRecognizer::SendChat(const cCompositeChat & a_Message)
+void cProtocolRecognizer::SendChatAboveActionBar(const AString & a_Message)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendChatAboveActionBar(a_Message);
+}
+
+
+
+
+
+void cProtocolRecognizer::SendChatAboveActionBar(const cCompositeChat & a_Message)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendChatAboveActionBar(a_Message);
+}
+
+
+
+
+
+void cProtocolRecognizer::SendChatSystem(const AString & a_Message)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendChatSystem(a_Message);
+}
+
+
+
+
+
+void cProtocolRecognizer::SendChatSystem(const cCompositeChat & a_Message)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendChatSystem(a_Message);
+}
+
+
+
+
+
+void cProtocolRecognizer::SendChatType(const AString & a_Message, eChatType type)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendChatType(a_Message, type);
+}
+
+
+
+
+
+void cProtocolRecognizer::SendChatType(const cCompositeChat & a_Message, eChatType type)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendChatType(a_Message, type);
+}
+
+
+
+
+
void cProtocolRecognizer::SendChunkData(int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer)
{
ASSERT(m_Protocol != nullptr);
@@ -350,6 +410,16 @@ void cProtocolRecognizer::SendHealth(void)
+void cProtocolRecognizer::SendHideTitle(void)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendHideTitle();
+}
+
+
+
+
+
void cProtocolRecognizer::SendWindowProperty(const cWindow & a_Window, short a_Property, short a_Value)
{
ASSERT(m_Protocol != nullptr);
@@ -599,6 +669,16 @@ void cProtocolRecognizer::SendRemoveEntityEffect(const cEntity & a_Entity, int a
+void cProtocolRecognizer::SendResetTitle(void)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendResetTitle();
+}
+
+
+
+
+
void cProtocolRecognizer::SendRespawn(eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks)
{
ASSERT(m_Protocol != nullptr);
@@ -659,6 +739,46 @@ void cProtocolRecognizer::SendDisplayObjective(const AString & a_Objective, cSco
+void cProtocolRecognizer::SendSetSubTitle(const cCompositeChat & a_SubTitle)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendSetSubTitle(a_SubTitle);
+}
+
+
+
+
+
+void cProtocolRecognizer::SendSetRawSubTitle(const AString & a_SubTitle)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendSetRawSubTitle(a_SubTitle);
+}
+
+
+
+
+
+void cProtocolRecognizer::SendSetTitle(const cCompositeChat & a_Title)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendSetTitle(a_Title);
+}
+
+
+
+
+
+void cProtocolRecognizer::SendSetRawTitle(const AString & a_Title)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendSetRawTitle(a_Title);
+}
+
+
+
+
+
void cProtocolRecognizer::SendSoundEffect(const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch)
{
ASSERT(m_Protocol != nullptr);
@@ -759,6 +879,16 @@ void cProtocolRecognizer::SendThunderbolt(int a_BlockX, int a_BlockY, int a_Bloc
+void cProtocolRecognizer::SendTitleTimes(int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendTitleTimes(a_FadeInTicks, a_DisplayTicks, a_FadeOutTicks);
+}
+
+
+
+
+
void cProtocolRecognizer::SendTimeUpdate(Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle)
{
ASSERT(m_Protocol != nullptr);
diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h
index 6c2185d6d..29eddcbc9 100644
--- a/src/Protocol/ProtocolRecognizer.h
+++ b/src/Protocol/ProtocolRecognizer.h
@@ -55,6 +55,12 @@ public:
virtual void SendBlockChanges (int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes) override;
virtual void SendChat (const AString & a_Message) override;
virtual void SendChat (const cCompositeChat & a_Message) override;
+ virtual void SendChatAboveActionBar (const AString & a_Message) override;
+ virtual void SendChatAboveActionBar (const cCompositeChat & a_Message) override;
+ virtual void SendChatSystem (const AString & a_Message) override;
+ virtual void SendChatSystem (const cCompositeChat & a_Message) override;
+ virtual void SendChatType (const AString & a_Message, eChatType type) override;
+ virtual void SendChatType (const cCompositeChat & a_Message, eChatType type) override;
virtual void SendChunkData (int a_ChunkX, int a_ChunkZ, cChunkDataSerializer & a_Serializer) override;
virtual void SendCollectEntity (const cEntity & a_Entity, const cPlayer & a_Player) override;
virtual void SendDestroyEntity (const cEntity & a_Entity) override;
@@ -73,6 +79,7 @@ public:
virtual void SendExplosion (double a_BlockX, double a_BlockY, double a_BlockZ, float a_Radius, const cVector3iArray & a_BlocksAffected, const Vector3d & a_PlayerMotion) override;
virtual void SendGameMode (eGameMode a_GameMode) override;
virtual void SendHealth (void) override;
+ virtual void SendHideTitle (void) override;
virtual void SendInventorySlot (char a_WindowID, short a_SlotNum, const cItem & a_Item) override;
virtual void SendKeepAlive (int a_PingID) override;
virtual void SendLogin (const cPlayer & a_Player, const cWorld & a_World) override;
@@ -97,12 +104,17 @@ public:
virtual void SendPlayerSpawn (const cPlayer & a_Player) override;
virtual void SendPluginMessage (const AString & a_Channel, const AString & a_Message) override;
virtual void SendRemoveEntityEffect (const cEntity & a_Entity, int a_EffectID) override;
+ virtual void SendResetTitle (void) override;
virtual void SendRespawn (eDimension a_Dimension, bool a_ShouldIgnoreDimensionChecks) override;
virtual void SendExperience (void) override;
virtual void SendExperienceOrb (const cExpOrb & a_ExpOrb) override;
virtual void SendScoreboardObjective (const AString & a_Name, const AString & a_DisplayName, Byte a_Mode) override;
virtual void SendScoreUpdate (const AString & a_Objective, const AString & a_Player, cObjective::Score a_Score, Byte a_Mode) override;
virtual void SendDisplayObjective (const AString & a_Objective, cScoreboard::eDisplaySlot a_Display) override;
+ virtual void SendSetSubTitle (const cCompositeChat & a_SubTitle) override;
+ virtual void SendSetRawSubTitle (const AString & a_SubTitle) override;
+ virtual void SendSetTitle (const cCompositeChat & a_Title) override;
+ virtual void SendSetRawTitle (const AString & a_Title) override;
virtual void SendSoundEffect (const AString & a_SoundName, double a_X, double a_Y, double a_Z, float a_Volume, float a_Pitch) override;
virtual void SendSoundParticleEffect (int a_EffectID, int a_SrcX, int a_SrcY, int a_SrcZ, int a_Data) override;
virtual void SendSpawnFallingBlock (const cFallingBlock & a_FallingBlock) override;
@@ -113,6 +125,7 @@ public:
virtual void SendTabCompletionResults (const AStringVector & a_Results) override;
virtual void SendTeleportEntity (const cEntity & a_Entity) override;
virtual void SendThunderbolt (int a_BlockX, int a_BlockY, int a_BlockZ) override;
+ virtual void SendTitleTimes (int a_FadeInTicks, int a_DisplayTicks, int a_FadeOutTicks) override;
virtual void SendTimeUpdate (Int64 a_WorldAge, Int64 a_TimeOfDay, bool a_DoDaylightCycle) override;
virtual void SendUnloadChunk (int a_ChunkX, int a_ChunkZ) override;
virtual void SendUpdateBlockEntity (cBlockEntity & a_BlockEntity) override;