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/ChunkDataSerializer.cpp4
-rw-r--r--src/Protocol/MojangAPI.cpp52
-rw-r--r--src/Protocol/MojangAPI.h4
-rw-r--r--src/Protocol/Protocol.h3
-rw-r--r--src/Protocol/Protocol17x.cpp18
-rw-r--r--src/Protocol/Protocol17x.h1
-rw-r--r--src/Protocol/Protocol18x.cpp58
-rw-r--r--src/Protocol/Protocol18x.h1
-rw-r--r--src/Protocol/ProtocolRecognizer.cpp11
-rw-r--r--src/Protocol/ProtocolRecognizer.h3
12 files changed, 142 insertions, 39 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/ChunkDataSerializer.cpp b/src/Protocol/ChunkDataSerializer.cpp
index 60fd5f935..2b9c06779 100644
--- a/src/Protocol/ChunkDataSerializer.cpp
+++ b/src/Protocol/ChunkDataSerializer.cpp
@@ -68,7 +68,7 @@ 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)
+ // 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);
@@ -126,7 +126,7 @@ void cChunkDataSerializer::Serialize29(AString & a_Data)
void cChunkDataSerializer::Serialize39(AString & a_Data)
{
- // TODO: Do not copy data and then compress it; rather, compress partial blocks of data (zlib *can* stream)
+ // 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);
diff --git a/src/Protocol/MojangAPI.cpp b/src/Protocol/MojangAPI.cpp
index 570754204..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;
}
@@ -659,7 +683,7 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
a_NamesToQuery.erase(a_NamesToQuery.begin(), itr);
Json::FastWriter Writer;
AString RequestBody = Writer.write(root);
-
+
// Create the HTTP request:
AString Request;
Request += "POST " + m_NameToUUIDAddress + " HTTP/1.0\r\n"; // We need to use HTTP 1.0 because we don't handle Chunked transfer encoding
@@ -667,7 +691,7 @@ void cMojangAPI::QueryNamesToUUIDs(AStringVector & a_NamesToQuery)
Request += "User-Agent: MCServer\r\n";
Request += "Connection: close\r\n";
Request += "Content-Type: application/json\r\n";
- Request += Printf("Content-Length: %u\r\n", (unsigned)RequestBody.length());
+ Request += Printf("Content-Length: %u\r\n", static_cast<unsigned>(RequestBody.length()));
Request += "\r\n";
Request += RequestBody;
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/Protocol.h b/src/Protocol/Protocol.h
index 95adc23e9..7be72014a 100644
--- a/src/Protocol/Protocol.h
+++ b/src/Protocol/Protocol.h
@@ -16,6 +16,8 @@
#include "../Map.h"
#include "../ByteBuffer.h"
+#include <array>
+
@@ -99,6 +101,7 @@ public:
virtual void SendPlayerAbilities (void) = 0;
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) = 0;
virtual void SendParticleEffect (const AString & a_SoundName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) = 0;
+ virtual void SendParticleEffect (const AString & a_SoundName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) = 0;
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) = 0;
virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) = 0;
virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) = 0;
diff --git a/src/Protocol/Protocol17x.cpp b/src/Protocol/Protocol17x.cpp
index e1e48e43f..0bd219fb1 100644
--- a/src/Protocol/Protocol17x.cpp
+++ b/src/Protocol/Protocol17x.cpp
@@ -492,7 +492,7 @@ void cProtocol172::SendEntityVelocity(const cEntity & a_Entity)
cPacketizer Pkt(*this, 0x12); // Entity Velocity packet
Pkt.WriteBEUInt32(a_Entity.GetUniqueID());
- // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick
+ // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick
Pkt.WriteBEInt16(static_cast<short>(a_Entity.GetSpeedX() * 400));
Pkt.WriteBEInt16(static_cast<short>(a_Entity.GetSpeedY() * 400));
Pkt.WriteBEInt16(static_cast<short>(a_Entity.GetSpeedZ() * 400));
@@ -813,6 +813,16 @@ void cProtocol172::SendParticleEffect(const AString & a_ParticleName, float a_Sr
+void cProtocol172::SendParticleEffect(const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data)
+{
+ // 1.72 doesn't support extra data
+ this->SendParticleEffect(a_ParticleName, a_Src.x, a_Src.y, a_Src.z, a_Offset.x, a_Offset.y, a_Offset.z, a_ParticleData, a_ParticleAmount);
+}
+
+
+
+
+
void cProtocol172::SendPlayerListAddPlayer(const cPlayer & a_Player)
{
ASSERT(m_State == 3); // In game mode?
@@ -1791,7 +1801,7 @@ void cProtocol172::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
// Version:
Json::Value Version;
- Version["name"] = "1.7.2";
+ Version["name"] = "MCServer 1.7.2";
Version["protocol"] = 4;
// Players:
@@ -2567,7 +2577,7 @@ void cProtocol172::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings
{
- AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent/backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;)
+ AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent / backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;)
}
a_Item.m_Lore = Lore;
@@ -3233,7 +3243,7 @@ void cProtocol176::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
// Version:
Json::Value Version;
- Version["name"] = "1.7.6";
+ Version["name"] = "MCServer 1.7.6";
Version["protocol"] = 5;
// Players:
diff --git a/src/Protocol/Protocol17x.h b/src/Protocol/Protocol17x.h
index 553856eaa..ead2935b0 100644
--- a/src/Protocol/Protocol17x.h
+++ b/src/Protocol/Protocol17x.h
@@ -100,6 +100,7 @@ public:
virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override;
virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override;
+ virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
virtual void SendPlayerAbilities (void) override;
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override;
diff --git a/src/Protocol/Protocol18x.cpp b/src/Protocol/Protocol18x.cpp
index 20b55f461..d06022ce0 100644
--- a/src/Protocol/Protocol18x.cpp
+++ b/src/Protocol/Protocol18x.cpp
@@ -479,7 +479,7 @@ void cProtocol180::SendEntityVelocity(const cEntity & a_Entity)
cPacketizer Pkt(*this, 0x12); // Entity Velocity packet
Pkt.WriteVarInt32(a_Entity.GetUniqueID());
- // 400 = 8000 / 20 ... Conversion from our speed in m/s to 8000 m/tick
+ // 400 = 8000 / 20 ... Conversion from our speed in m / s to 8000 m / tick
Pkt.WriteBEInt16((short)(a_Entity.GetSpeedX() * 400));
Pkt.WriteBEInt16((short)(a_Entity.GetSpeedY() * 400));
Pkt.WriteBEInt16((short)(a_Entity.GetSpeedZ() * 400));
@@ -814,6 +814,50 @@ void cProtocol180::SendParticleEffect(const AString & a_ParticleName, float a_Sr
+void cProtocol180::SendParticleEffect(const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data)
+{
+ ASSERT(m_State == 3); // In game mode?
+ int ParticleID = GetParticleID(a_ParticleName);
+
+ cPacketizer Pkt(*this, 0x2A);
+ Pkt.WriteBEInt32(ParticleID);
+ Pkt.WriteBool(false);
+ Pkt.WriteBEFloat(a_Src.x);
+ Pkt.WriteBEFloat(a_Src.y);
+ Pkt.WriteBEFloat(a_Src.z);
+ Pkt.WriteBEFloat(a_Offset.x);
+ Pkt.WriteBEFloat(a_Offset.y);
+ Pkt.WriteBEFloat(a_Offset.z);
+ Pkt.WriteBEFloat(a_ParticleData);
+ Pkt.WriteBEInt32(a_ParticleAmount);
+ switch (ParticleID)
+ {
+ // iconcrack
+ case 36:
+ {
+ Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[0]));
+ Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[1]));
+ break;
+ }
+ // blockcrack
+ // blockdust
+ case 37:
+ case 38:
+ {
+ Pkt.WriteVarInt32(static_cast<UInt32>(a_Data[0]));
+ break;
+ }
+ default:
+ {
+ break;
+ }
+ }
+}
+
+
+
+
+
void cProtocol180::SendPlayerListAddPlayer(const cPlayer & a_Player)
{
ASSERT(m_State == 3); // In game mode?
@@ -2056,7 +2100,7 @@ void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
// Version:
Json::Value Version;
- Version["name"] = "1.8";
+ Version["name"] = "MCServer 1.8";
Version["protocol"] = 47;
// Players:
@@ -2192,7 +2236,7 @@ void cProtocol180::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
void cProtocol180::HandlePacketAnimation(cByteBuffer & a_ByteBuffer)
{
- m_Client->HandleAnimation(1); // Packet exists solely for arm-swing notification
+ m_Client->HandleAnimation(0); // Packet exists solely for arm-swing notification
}
@@ -2307,7 +2351,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);
}
@@ -2396,7 +2440,7 @@ void cProtocol180::HandlePacketPlayerPos(cByteBuffer & a_ByteBuffer)
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosY);
HANDLE_READ(a_ByteBuffer, ReadBEDouble, double, PosZ);
HANDLE_READ(a_ByteBuffer, ReadBool, bool, IsOnGround);
- m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + 1.62, IsOnGround);
+ m_Client->HandlePlayerPos(PosX, PosY, PosZ, PosY + (m_Client->GetPlayer()->IsCrouched() ? 1.54 : 1.62), IsOnGround);
}
@@ -2761,7 +2805,7 @@ void cProtocol180::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
if (!NBT.IsValid())
{
AString HexDump;
- CreateHexDump(HexDump, a_Metadata.data(), a_Metadata.size(), 16);
+ CreateHexDump(HexDump, a_Metadata.data(), std::max<size_t>(a_Metadata.size(), 1024), 16);
LOGWARNING("Cannot parse NBT item metadata: (" SIZE_T_FMT " bytes)\n%s", a_Metadata.size(), HexDump.c_str());
return;
}
@@ -2796,7 +2840,7 @@ void cProtocol180::ParseItemMetadata(cItem & a_Item, const AString & a_Metadata)
for (int loretag = NBT.GetFirstChild(displaytag); loretag >= 0; loretag = NBT.GetNextSibling(loretag)) // Loop through array of strings
{
- AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent/backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;)
+ AppendPrintf(Lore, "%s`", NBT.GetString(loretag).c_str()); // Append the lore with a grave accent / backtick, used internally by MCS to display a new line in the client; don't forget to c_str ;)
}
a_Item.m_Lore = Lore;
diff --git a/src/Protocol/Protocol18x.h b/src/Protocol/Protocol18x.h
index 06a57b216..6143e8b4e 100644
--- a/src/Protocol/Protocol18x.h
+++ b/src/Protocol/Protocol18x.h
@@ -98,6 +98,7 @@ public:
virtual void SendPlayerAbilities (void) override;
virtual void SendEntityAnimation (const cEntity & a_Entity, char a_Animation) override;
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override;
+ virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override;
virtual void SendPlayerListAddPlayer (const cPlayer & a_Player) override;
virtual void SendPlayerListRemovePlayer (const cPlayer & a_Player) override;
virtual void SendPlayerListUpdateGameMode (const cPlayer & a_Player) override;
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp
index 6c599dedc..477f2d71e 100644
--- a/src/Protocol/ProtocolRecognizer.cpp
+++ b/src/Protocol/ProtocolRecognizer.cpp
@@ -449,6 +449,17 @@ void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, flo
+
+void cProtocolRecognizer::SendParticleEffect(const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data)
+{
+ ASSERT(m_Protocol != nullptr);
+ m_Protocol->SendParticleEffect(a_ParticleName, a_Src, a_Offset, a_ParticleData, a_ParticleAmount, a_Data);
+}
+
+
+
+
+
void cProtocolRecognizer::SendPaintingSpawn(const cPainting & a_Painting)
{
m_Protocol->SendPaintingSpawn(a_Painting);
diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h
index 8454549e3..956b5dcc0 100644
--- a/src/Protocol/ProtocolRecognizer.h
+++ b/src/Protocol/ProtocolRecognizer.h
@@ -18,7 +18,7 @@
// Adjust these if a new protocol is added or an old one is removed:
-#define MCS_CLIENT_VERSIONS "1.7.x, 1.8"
+#define MCS_CLIENT_VERSIONS "1.7.x, 1.8.x"
#define MCS_PROTOCOL_VERSIONS "4, 5, 47"
@@ -82,6 +82,7 @@ public:
virtual void SendMapDecorators (int a_ID, const cMapDecoratorList & a_Decorators, unsigned int m_Scale) override;
virtual void SendMapInfo (int a_ID, unsigned int a_Scale) override;
virtual void SendParticleEffect (const AString & a_ParticleName, float a_SrcX, float a_SrcY, float a_SrcZ, float a_OffsetX, float a_OffsetY, float a_OffsetZ, float a_ParticleData, int a_ParticleAmount) override;
+ virtual void SendParticleEffect (const AString & a_ParticleName, Vector3f a_Src, Vector3f a_Offset, float a_ParticleData, int a_ParticleAmount, std::array<int, 2> a_Data) override;
virtual void SendPaintingSpawn (const cPainting & a_Painting) override;
virtual void SendPickupSpawn (const cPickup & a_Pickup) override;
virtual void SendPlayerAbilities (void) override;