Started implementing of the 1.8 protocol.
This commit is contained in:
parent
44c1d9c248
commit
157f1c6688
@ -14,6 +14,7 @@ SET (SRCS
|
|||||||
Protocol15x.cpp
|
Protocol15x.cpp
|
||||||
Protocol16x.cpp
|
Protocol16x.cpp
|
||||||
Protocol17x.cpp
|
Protocol17x.cpp
|
||||||
|
Protocol18x.cpp
|
||||||
ProtocolRecognizer.cpp)
|
ProtocolRecognizer.cpp)
|
||||||
|
|
||||||
SET (HDRS
|
SET (HDRS
|
||||||
@ -27,6 +28,7 @@ SET (HDRS
|
|||||||
Protocol15x.h
|
Protocol15x.h
|
||||||
Protocol16x.h
|
Protocol16x.h
|
||||||
Protocol17x.h
|
Protocol17x.h
|
||||||
|
Protocol18x.h
|
||||||
ProtocolRecognizer.h)
|
ProtocolRecognizer.h)
|
||||||
|
|
||||||
if(NOT MSVC)
|
if(NOT MSVC)
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
|
||||||
// Protocol17x.cpp
|
// Protocol17x.cpp
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Implements the 1.7.x protocol classes:
|
Implements the 1.7.x protocol classes:
|
||||||
- cProtocol172
|
- cProtocol172
|
||||||
- release 1.7.2 protocol (#4)
|
- release 1.7.2 protocol (#4)
|
||||||
(others may be added later in the future for the 1.7 release series)
|
- cProtocol176
|
||||||
|
- release 1.7.6 protocol (#5)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
Declares the 1.7.x protocol classes:
|
Declares the 1.7.x protocol classes:
|
||||||
- cProtocol172
|
- cProtocol172
|
||||||
- release 1.7.2 protocol (#4)
|
- release 1.7.2 protocol (#4)
|
||||||
(others may be added later in the future for the 1.7 release series)
|
- cProtocol176
|
||||||
|
- release 1.7.6 protocol (#5)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -199,6 +200,11 @@ protected:
|
|||||||
m_Out.WriteVarUTF8String(a_Value);
|
m_Out.WriteVarUTF8String(a_Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void WritePosition(const Vector3i a_Position)
|
||||||
|
{
|
||||||
|
WriteInt64(((Int64)a_Position.x & 0x3FFFFFF) << 38 | ((Int64)a_Position.y & 0xFFF) << 26 | ((Int64)a_Position.z & 0x3FFFFFF));
|
||||||
|
}
|
||||||
|
|
||||||
void WriteBuf(const char * a_Data, size_t a_Size)
|
void WriteBuf(const char * a_Data, size_t a_Size)
|
||||||
{
|
{
|
||||||
m_Out.Write(a_Data, a_Size);
|
m_Out.Write(a_Data, a_Size);
|
||||||
@ -262,8 +268,8 @@ protected:
|
|||||||
virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer);
|
virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer);
|
||||||
|
|
||||||
// Packet handlers while in the Login state (m_State == 2):
|
// Packet handlers while in the Login state (m_State == 2):
|
||||||
void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer);
|
virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer);
|
||||||
void HandlePacketLoginStart (cByteBuffer & a_ByteBuffer);
|
virtual void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer);
|
||||||
|
|
||||||
// Packet handlers while in the Game state (m_State == 3):
|
// Packet handlers while in the Game state (m_State == 3):
|
||||||
void HandlePacketAnimation (cByteBuffer & a_ByteBuffer);
|
void HandlePacketAnimation (cByteBuffer & a_ByteBuffer);
|
||||||
|
385
src/Protocol/Protocol18x.cpp
Normal file
385
src/Protocol/Protocol18x.cpp
Normal file
@ -0,0 +1,385 @@
|
|||||||
|
|
||||||
|
// Protocol18x.cpp
|
||||||
|
|
||||||
|
/*
|
||||||
|
Implements the 1.8.x protocol classes:
|
||||||
|
- cProtocol180
|
||||||
|
- release 1.8.0 protocol (#47)
|
||||||
|
(others may be added later in the future for the 1.8 release series)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "Globals.h"
|
||||||
|
#include "Bindings/PluginManager.h"
|
||||||
|
#include "json/json.h"
|
||||||
|
#include "Protocol18x.h"
|
||||||
|
|
||||||
|
#include "../ClientHandle.h"
|
||||||
|
#include "../CompositeChat.h"
|
||||||
|
#include "../Root.h"
|
||||||
|
#include "../Server.h"
|
||||||
|
#include "../World.h"
|
||||||
|
|
||||||
|
#include "../Entities/Player.h"
|
||||||
|
|
||||||
|
class cProtocol176;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const int MAX_ENC_LEN = 512; // Maximum size of the encrypted message; should be 128, but who knows...
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cProtocol180:
|
||||||
|
|
||||||
|
cProtocol180::cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State) :
|
||||||
|
super(a_Client, a_ServerAddress, a_ServerPort, a_State)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta)
|
||||||
|
{
|
||||||
|
ASSERT(m_State == 3); // In game mode?
|
||||||
|
|
||||||
|
cPacketizer Pkt(*this, 0x23); // Block Change packet
|
||||||
|
Pkt.WritePosition(Vector3i(a_BlockX, a_BlockY, a_BlockZ));
|
||||||
|
|
||||||
|
UInt32 Block = ((UInt32)a_BlockType << 4) | ((UInt32)a_BlockMeta & 15);
|
||||||
|
Pkt.WriteVarInt(Block);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::SendBlockChanges(int a_ChunkX, int a_ChunkZ, const sSetBlockVector & a_Changes)
|
||||||
|
{
|
||||||
|
ASSERT(m_State == 3); // In game mode?
|
||||||
|
|
||||||
|
cPacketizer Pkt(*this, 0x22); // Multi Block Change packet
|
||||||
|
Pkt.WriteInt(a_ChunkX);
|
||||||
|
Pkt.WriteInt(a_ChunkZ);
|
||||||
|
Pkt.WriteVarInt((UInt32)a_Changes.size());
|
||||||
|
for (sSetBlockVector::const_iterator itr = a_Changes.begin(), end = a_Changes.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
short Coords = itr->y | (itr->z << 8) | (itr->x << 12);
|
||||||
|
Pkt.WriteShort(Coords);
|
||||||
|
|
||||||
|
UInt32 Block = ((UInt32)itr->BlockType << 4) | ((UInt32)itr->BlockMeta & 15);
|
||||||
|
Pkt.WriteVarInt(Block);
|
||||||
|
} // for itr - a_Changes[]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::SendChat(const AString & a_Message)
|
||||||
|
{
|
||||||
|
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.WriteChar(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::SendChat(const cCompositeChat & a_Message)
|
||||||
|
{
|
||||||
|
ASSERT(m_State == 3); // In game mode?
|
||||||
|
|
||||||
|
// Compose the complete Json string to send:
|
||||||
|
Json::Value msg;
|
||||||
|
cWorld * World = m_Client->GetPlayer()->GetWorld();
|
||||||
|
msg["text"] = cClientHandle::FormatMessageType((World == NULL) ? false : World->ShouldUseChatPrefixes(), a_Message.GetMessageType(), a_Message.GetAdditionalMessageTypeData()); // The client crashes without this field being present
|
||||||
|
const cCompositeChat::cParts & Parts = a_Message.GetParts();
|
||||||
|
for (cCompositeChat::cParts::const_iterator itr = Parts.begin(), end = Parts.end(); itr != end; ++itr)
|
||||||
|
{
|
||||||
|
Json::Value Part;
|
||||||
|
switch ((*itr)->m_PartType)
|
||||||
|
{
|
||||||
|
case cCompositeChat::ptText:
|
||||||
|
{
|
||||||
|
Part["text"] = (*itr)->m_Text;
|
||||||
|
AddChatPartStyle(Part, (*itr)->m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case cCompositeChat::ptClientTranslated:
|
||||||
|
{
|
||||||
|
const cCompositeChat::cClientTranslatedPart & p = (const cCompositeChat::cClientTranslatedPart &)**itr;
|
||||||
|
Part["translate"] = p.m_Text;
|
||||||
|
Json::Value With;
|
||||||
|
for (AStringVector::const_iterator itrW = p.m_Parameters.begin(), endW = p.m_Parameters.end(); itrW != endW; ++itr)
|
||||||
|
{
|
||||||
|
With.append(*itrW);
|
||||||
|
}
|
||||||
|
if (!p.m_Parameters.empty())
|
||||||
|
{
|
||||||
|
Part["with"] = With;
|
||||||
|
}
|
||||||
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case cCompositeChat::ptUrl:
|
||||||
|
{
|
||||||
|
const cCompositeChat::cUrlPart & p = (const cCompositeChat::cUrlPart &)**itr;
|
||||||
|
Part["text"] = p.m_Text;
|
||||||
|
Json::Value Url;
|
||||||
|
Url["action"] = "open_url";
|
||||||
|
Url["value"] = p.m_Url;
|
||||||
|
Part["clickEvent"] = Url;
|
||||||
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case cCompositeChat::ptSuggestCommand:
|
||||||
|
case cCompositeChat::ptRunCommand:
|
||||||
|
{
|
||||||
|
const cCompositeChat::cCommandPart & p = (const cCompositeChat::cCommandPart &)**itr;
|
||||||
|
Part["text"] = p.m_Text;
|
||||||
|
Json::Value Cmd;
|
||||||
|
Cmd["action"] = (p.m_PartType == cCompositeChat::ptRunCommand) ? "run_command" : "suggest_command";
|
||||||
|
Cmd["value"] = p.m_Command;
|
||||||
|
Part["clickEvent"] = Cmd;
|
||||||
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case cCompositeChat::ptShowAchievement:
|
||||||
|
{
|
||||||
|
const cCompositeChat::cShowAchievementPart & p = (const cCompositeChat::cShowAchievementPart &)**itr;
|
||||||
|
Part["translate"] = "chat.type.achievement";
|
||||||
|
|
||||||
|
Json::Value Ach;
|
||||||
|
Ach["action"] = "show_achievement";
|
||||||
|
Ach["value"] = p.m_Text;
|
||||||
|
|
||||||
|
Json::Value AchColourAndName;
|
||||||
|
AchColourAndName["color"] = "green";
|
||||||
|
AchColourAndName["translate"] = p.m_Text;
|
||||||
|
AchColourAndName["hoverEvent"] = Ach;
|
||||||
|
|
||||||
|
Json::Value Extra;
|
||||||
|
Extra.append(AchColourAndName);
|
||||||
|
|
||||||
|
Json::Value Name;
|
||||||
|
Name["text"] = p.m_PlayerName;
|
||||||
|
|
||||||
|
Json::Value With;
|
||||||
|
With.append(Name);
|
||||||
|
With.append(Extra);
|
||||||
|
|
||||||
|
Part["with"] = With;
|
||||||
|
AddChatPartStyle(Part, p.m_Style);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
msg["extra"].append(Part);
|
||||||
|
} // for itr - Parts[]
|
||||||
|
|
||||||
|
// Send the message to the client:
|
||||||
|
cPacketizer Pkt(*this, 0x02);
|
||||||
|
Pkt.WriteString(msg.toStyledString());
|
||||||
|
Pkt.WriteChar(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item)
|
||||||
|
{
|
||||||
|
ASSERT(m_State == 3); // In game mode?
|
||||||
|
|
||||||
|
cPacketizer Pkt(*this, 0x04); // Entity Equipment packet
|
||||||
|
Pkt.WriteVarInt((UInt32)a_Entity.GetUniqueID());
|
||||||
|
Pkt.WriteShort(a_SlotNum);
|
||||||
|
Pkt.WriteItem(a_Item);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::SendLogin(const cPlayer & a_Player, const cWorld & a_World)
|
||||||
|
{
|
||||||
|
// Send the Join Game packet:
|
||||||
|
{
|
||||||
|
cServer * Server = cRoot::Get()->GetServer();
|
||||||
|
cPacketizer Pkt(*this, 0x01); // Join Game packet
|
||||||
|
Pkt.WriteInt(a_Player.GetUniqueID());
|
||||||
|
Pkt.WriteByte((Byte)a_Player.GetEffectiveGameMode() | (Server->IsHardcore() ? 0x08 : 0)); // Hardcore flag bit 4
|
||||||
|
Pkt.WriteChar((char)a_World.GetDimension());
|
||||||
|
Pkt.WriteByte(2); // TODO: Difficulty (set to Normal)
|
||||||
|
Pkt.WriteByte(std::min(Server->GetMaxPlayers(), 60));
|
||||||
|
Pkt.WriteString("default"); // Level type - wtf?
|
||||||
|
Pkt.WriteBool(false); // Reduced Debug Info - wtf?
|
||||||
|
}
|
||||||
|
m_LastSentDimension = a_World.GetDimension();
|
||||||
|
|
||||||
|
// Send the spawn position:
|
||||||
|
{
|
||||||
|
cPacketizer Pkt(*this, 0x05); // Spawn Position packet
|
||||||
|
Vector3i Position(a_World.GetSpawnX(), a_World.GetSpawnY(), a_World.GetSpawnZ());
|
||||||
|
Pkt.WritePosition(Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send player abilities:
|
||||||
|
SendPlayerAbilities();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer)
|
||||||
|
{
|
||||||
|
cServer * Server = cRoot::Get()->GetServer();
|
||||||
|
AString ServerDescription = Server->GetDescription();
|
||||||
|
int NumPlayers = Server->GetNumPlayers();
|
||||||
|
int MaxPlayers = Server->GetMaxPlayers();
|
||||||
|
AString Favicon = Server->GetFaviconData();
|
||||||
|
cRoot::Get()->GetPluginManager()->CallHookServerPing(*m_Client, ServerDescription, NumPlayers, MaxPlayers, Favicon);
|
||||||
|
|
||||||
|
// Version:
|
||||||
|
Json::Value Version;
|
||||||
|
Version["name"] = "1.8";
|
||||||
|
Version["protocol"] = 47;
|
||||||
|
|
||||||
|
// Players:
|
||||||
|
Json::Value Players;
|
||||||
|
Players["online"] = NumPlayers;
|
||||||
|
Players["max"] = MaxPlayers;
|
||||||
|
// TODO: Add "sample"
|
||||||
|
|
||||||
|
// Description:
|
||||||
|
Json::Value Description;
|
||||||
|
Description["text"] = ServerDescription.c_str();
|
||||||
|
|
||||||
|
// Create the response:
|
||||||
|
Json::Value ResponseValue;
|
||||||
|
ResponseValue["version"] = Version;
|
||||||
|
ResponseValue["players"] = Players;
|
||||||
|
ResponseValue["description"] = Description;
|
||||||
|
if (!Favicon.empty())
|
||||||
|
{
|
||||||
|
ResponseValue["favicon"] = Printf("data:image/png;base64,%s", Favicon.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
Json::StyledWriter Writer;
|
||||||
|
AString Response = Writer.write(ResponseValue);
|
||||||
|
|
||||||
|
cPacketizer Pkt(*this, 0x00); // Response packet
|
||||||
|
Pkt.WriteString(Response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::HandlePacketLoginStart(cByteBuffer & a_ByteBuffer)
|
||||||
|
{
|
||||||
|
AString Username;
|
||||||
|
if (!a_ByteBuffer.ReadVarUTF8String(Username))
|
||||||
|
{
|
||||||
|
m_Client->Kick("Bad username");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!m_Client->HandleHandshake(Username))
|
||||||
|
{
|
||||||
|
// The client is not welcome here, they have been sent a Kick packet already
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cServer * Server = cRoot::Get()->GetServer();
|
||||||
|
// If auth is required, then send the encryption request:
|
||||||
|
if (Server->ShouldAuthenticate())
|
||||||
|
{
|
||||||
|
cPacketizer Pkt(*this, 0x01);
|
||||||
|
Pkt.WriteString(Server->GetServerID());
|
||||||
|
const AString & PubKeyDer = Server->GetPublicKeyDER();
|
||||||
|
Pkt.WriteVarInt((short)PubKeyDer.size());
|
||||||
|
Pkt.WriteBuf(PubKeyDer.data(), PubKeyDer.size());
|
||||||
|
Pkt.WriteVarInt(4);
|
||||||
|
Pkt.WriteInt((int)(intptr_t)this); // Using 'this' as the cryptographic nonce, so that we don't have to generate one each time :)
|
||||||
|
m_Client->SetUsername(Username);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Client->HandleLogin(4, Username);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cProtocol180::HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer)
|
||||||
|
{
|
||||||
|
UInt32 EncKeyLength, EncNonceLength;
|
||||||
|
a_ByteBuffer.ReadVarInt(EncKeyLength);
|
||||||
|
AString EncKey;
|
||||||
|
if (!a_ByteBuffer.ReadString(EncKey, EncKeyLength))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
a_ByteBuffer.ReadVarInt(EncNonceLength);
|
||||||
|
AString EncNonce;
|
||||||
|
if (!a_ByteBuffer.ReadString(EncNonce, EncNonceLength))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((EncKeyLength > MAX_ENC_LEN) || (EncNonceLength > MAX_ENC_LEN))
|
||||||
|
{
|
||||||
|
LOGD("Too long encryption");
|
||||||
|
m_Client->Kick("Hacked client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt EncNonce using privkey
|
||||||
|
cRsaPrivateKey & rsaDecryptor = cRoot::Get()->GetServer()->GetPrivateKey();
|
||||||
|
Int32 DecryptedNonce[MAX_ENC_LEN / sizeof(Int32)];
|
||||||
|
int res = rsaDecryptor.Decrypt((const Byte *)EncNonce.data(), EncNonce.size(), (Byte *)DecryptedNonce, sizeof(DecryptedNonce));
|
||||||
|
if (res != 4)
|
||||||
|
{
|
||||||
|
LOGD("Bad nonce length: got %d, exp %d", res, 4);
|
||||||
|
m_Client->Kick("Hacked client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ntohl(DecryptedNonce[0]) != (unsigned)(uintptr_t)this)
|
||||||
|
{
|
||||||
|
LOGD("Bad nonce value");
|
||||||
|
m_Client->Kick("Hacked client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt the symmetric encryption key using privkey:
|
||||||
|
Byte DecryptedKey[MAX_ENC_LEN];
|
||||||
|
res = rsaDecryptor.Decrypt((const Byte *)EncKey.data(), EncKey.size(), DecryptedKey, sizeof(DecryptedKey));
|
||||||
|
if (res != 16)
|
||||||
|
{
|
||||||
|
LOGD("Bad key length");
|
||||||
|
m_Client->Kick("Hacked client");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StartEncryption(DecryptedKey);
|
||||||
|
m_Client->HandleLogin(4, m_Client->GetUsername());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
76
src/Protocol/Protocol18x.h
Normal file
76
src/Protocol/Protocol18x.h
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
|
||||||
|
// Protocol18x.h
|
||||||
|
|
||||||
|
/*
|
||||||
|
Declares the 1.8.x protocol classes:
|
||||||
|
- cProtocol180
|
||||||
|
- release 1.8 protocol (#47)
|
||||||
|
(others may be added later in the future for the 1.8 release series)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Protocol.h"
|
||||||
|
#include "Protocol17x.h"
|
||||||
|
#include "../ByteBuffer.h"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable:4127)
|
||||||
|
#pragma warning(disable:4244)
|
||||||
|
#pragma warning(disable:4231)
|
||||||
|
#pragma warning(disable:4189)
|
||||||
|
#pragma warning(disable:4702)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// fwd:
|
||||||
|
namespace Json
|
||||||
|
{
|
||||||
|
class Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class cProtocol180 :
|
||||||
|
public cProtocol176
|
||||||
|
{
|
||||||
|
typedef cProtocol176 super;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
cProtocol180(cClientHandle * a_Client, const AString & a_ServerAddress, UInt16 a_ServerPort, UInt32 a_State);
|
||||||
|
|
||||||
|
virtual void SendBlockChange(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta) override;
|
||||||
|
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 SendPlayerListItem(const cPlayer & a_Player, bool a_IsOnline) override {}
|
||||||
|
virtual void SendEntityEquipment(const cEntity & a_Entity, short a_SlotNum, const cItem & a_Item) override;
|
||||||
|
virtual void SendLogin(const cPlayer & a_Player, const cWorld & a_World) override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void HandlePacketStatusRequest(cByteBuffer & a_ByteBuffer) override;
|
||||||
|
|
||||||
|
// Packet handlers while in the Login state (m_State == 2):
|
||||||
|
virtual void HandlePacketLoginStart(cByteBuffer & a_ByteBuffer) override;
|
||||||
|
virtual void HandlePacketLoginEncryptionResponse(cByteBuffer & a_ByteBuffer) override;
|
||||||
|
} ;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -13,6 +13,7 @@
|
|||||||
#include "Protocol15x.h"
|
#include "Protocol15x.h"
|
||||||
#include "Protocol16x.h"
|
#include "Protocol16x.h"
|
||||||
#include "Protocol17x.h"
|
#include "Protocol17x.h"
|
||||||
|
#include "Protocol18x.h"
|
||||||
#include "../ClientHandle.h"
|
#include "../ClientHandle.h"
|
||||||
#include "../Root.h"
|
#include "../Root.h"
|
||||||
#include "../Server.h"
|
#include "../Server.h"
|
||||||
@ -51,7 +52,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion)
|
|||||||
{
|
{
|
||||||
case PROTO_VERSION_1_2_5: return "1.2.5";
|
case PROTO_VERSION_1_2_5: return "1.2.5";
|
||||||
case PROTO_VERSION_1_3_2: return "1.3.2";
|
case PROTO_VERSION_1_3_2: return "1.3.2";
|
||||||
case PROTO_VERSION_1_4_2: return "1.4.2";
|
// case PROTO_VERSION_1_4_2: return "1.4.2";
|
||||||
case PROTO_VERSION_1_4_4: return "1.4.4";
|
case PROTO_VERSION_1_4_4: return "1.4.4";
|
||||||
case PROTO_VERSION_1_4_6: return "1.4.6";
|
case PROTO_VERSION_1_4_6: return "1.4.6";
|
||||||
case PROTO_VERSION_1_5_0: return "1.5";
|
case PROTO_VERSION_1_5_0: return "1.5";
|
||||||
@ -62,6 +63,7 @@ AString cProtocolRecognizer::GetVersionTextFromInt(int a_ProtocolVersion)
|
|||||||
case PROTO_VERSION_1_6_4: return "1.6.4";
|
case PROTO_VERSION_1_6_4: return "1.6.4";
|
||||||
case PROTO_VERSION_1_7_2: return "1.7.2";
|
case PROTO_VERSION_1_7_2: return "1.7.2";
|
||||||
case PROTO_VERSION_1_7_6: return "1.7.6";
|
case PROTO_VERSION_1_7_6: return "1.7.6";
|
||||||
|
case PROTO_VERSION_1_8_0: return "1.8";
|
||||||
}
|
}
|
||||||
ASSERT(!"Unknown protocol version");
|
ASSERT(!"Unknown protocol version");
|
||||||
return Printf("Unknown protocol (%d)", a_ProtocolVersion);
|
return Printf("Unknown protocol (%d)", a_ProtocolVersion);
|
||||||
@ -1016,6 +1018,27 @@ bool cProtocolRecognizer::TryRecognizeLengthedProtocol(UInt32 a_PacketLengthRema
|
|||||||
m_Protocol = new cProtocol176(m_Client, ServerAddress, (UInt16)ServerPort, NextState);
|
m_Protocol = new cProtocol176(m_Client, ServerAddress, (UInt16)ServerPort, NextState);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
case PROTO_VERSION_1_8_0:
|
||||||
|
{
|
||||||
|
AString ServerAddress;
|
||||||
|
short ServerPort;
|
||||||
|
UInt32 NextState;
|
||||||
|
if (!m_Buffer.ReadVarUTF8String(ServerAddress))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!m_Buffer.ReadBEShort(ServerPort))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!m_Buffer.ReadVarInt(NextState))
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
m_Buffer.CommitRead();
|
||||||
|
m_Protocol = new cProtocol180(m_Client, ServerAddress, (UInt16)ServerPort, NextState);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u)",
|
LOGINFO("Client \"%s\" uses an unsupported protocol (lengthed, version %u)",
|
||||||
m_Client->GetIPString().c_str(), ProtocolVersion
|
m_Client->GetIPString().c_str(), ProtocolVersion
|
||||||
|
@ -51,6 +51,7 @@ public:
|
|||||||
// These will be kept "under" the next / latest, because the next and latest are only needed for previous protocols
|
// These will be kept "under" the next / latest, because the next and latest are only needed for previous protocols
|
||||||
PROTO_VERSION_1_7_2 = 4,
|
PROTO_VERSION_1_7_2 = 4,
|
||||||
PROTO_VERSION_1_7_6 = 5,
|
PROTO_VERSION_1_7_6 = 5,
|
||||||
|
PROTO_VERSION_1_8_0 = 47,
|
||||||
} ;
|
} ;
|
||||||
|
|
||||||
cProtocolRecognizer(cClientHandle * a_Client);
|
cProtocolRecognizer(cClientHandle * a_Client);
|
||||||
|
Loading…
Reference in New Issue
Block a user