2013-07-29 12:13:03 +01:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "Protocol.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Adjust these if a new protocol is added or an old one is removed:
|
2020-07-17 18:46:50 +01:00
|
|
|
#define MCS_CLIENT_VERSIONS "1.8.x-1.12.x"
|
2020-02-24 00:07:28 +02:00
|
|
|
#define MCS_PROTOCOL_VERSIONS "47, 107, 108, 109, 110, 210, 315, 316, 335, 338, 340"
|
|
|
|
|
#define MCS_LATEST_PROTOCOL_VERSION 340
|
2013-07-29 12:13:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2020-01-03 14:30:51 +01:00
|
|
|
/** Meta-protocol that recognizes multiple protocol versions, creates the specific
|
|
|
|
|
protocol version instance and redirects everything to it. */
|
2020-07-17 18:46:50 +01:00
|
|
|
class cMultiVersionProtocol
|
2013-07-29 12:13:03 +01:00
|
|
|
{
|
|
|
|
|
public:
|
2020-07-17 18:46:50 +01:00
|
|
|
|
2013-07-29 12:13:03 +01:00
|
|
|
enum
|
|
|
|
|
{
|
2016-09-02 19:22:06 +02:00
|
|
|
PROTO_VERSION_1_8_0 = 47,
|
|
|
|
|
PROTO_VERSION_1_9_0 = 107,
|
|
|
|
|
PROTO_VERSION_1_9_1 = 108,
|
|
|
|
|
PROTO_VERSION_1_9_2 = 109,
|
|
|
|
|
PROTO_VERSION_1_9_4 = 110,
|
|
|
|
|
PROTO_VERSION_1_10_0 = 210,
|
2016-12-15 20:21:43 +01:00
|
|
|
PROTO_VERSION_1_11_0 = 315,
|
2017-02-21 17:11:28 +02:00
|
|
|
PROTO_VERSION_1_11_1 = 316,
|
2017-06-14 11:22:51 +02:00
|
|
|
PROTO_VERSION_1_12 = 335,
|
2017-08-17 16:25:53 +02:00
|
|
|
PROTO_VERSION_1_12_1 = 338,
|
2017-09-21 14:12:43 +01:00
|
|
|
PROTO_VERSION_1_12_2 = 340,
|
2018-08-01 00:21:44 +01:00
|
|
|
PROTO_VERSION_1_13 = 393
|
2017-09-21 14:12:43 +01:00
|
|
|
};
|
2013-07-29 12:13:03 +01:00
|
|
|
|
2020-07-17 18:46:50 +01:00
|
|
|
cMultiVersionProtocol();
|
2016-02-05 23:45:45 +02:00
|
|
|
|
2015-07-31 16:49:10 +02:00
|
|
|
/** Translates protocol version number into protocol version text: 49 -> "1.4.4" */
|
2013-07-29 12:13:03 +01:00
|
|
|
static AString GetVersionTextFromInt(int a_ProtocolVersion);
|
2016-02-05 23:45:45 +02:00
|
|
|
|
2020-07-17 18:46:50 +01:00
|
|
|
/** Returns if we contain a concrete protocol corresponding to the client's protocol version. */
|
|
|
|
|
bool VersionRecognitionSuccessful()
|
|
|
|
|
{
|
|
|
|
|
return m_Protocol != nullptr;
|
|
|
|
|
}
|
2015-07-31 16:49:10 +02:00
|
|
|
|
2020-07-17 18:46:50 +01:00
|
|
|
/** Convenience overload to enable redirecting sends to the underlying implementation. */
|
|
|
|
|
auto & operator->()
|
|
|
|
|
{
|
|
|
|
|
return m_Protocol;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/** The function that's responsible for processing incoming protocol data. */
|
|
|
|
|
std::function<void(cClientHandle &, std::string_view)> HandleIncomingData;
|
|
|
|
|
|
|
|
|
|
/** Sends a disconnect to the client as a result of a recognition error.
|
|
|
|
|
This function can be used to disconnect before any protocol has been recognised. */
|
|
|
|
|
void SendDisconnect(cClientHandle & a_Client, const AString & a_Reason);
|
2016-02-05 23:45:45 +02:00
|
|
|
|
2020-07-17 18:46:50 +01:00
|
|
|
private:
|
|
|
|
|
|
|
|
|
|
/** Handles data reception in a newly-created client handle that doesn't yet have known protocol.
|
|
|
|
|
a_Data contains a view of data that were just received.
|
|
|
|
|
Calls TryRecognizeProtocol to populate m_Protocol, and transitions to another mode depending on success. */
|
|
|
|
|
void HandleIncomingDataInRecognitionStage(cClientHandle & a_Client, std::string_view a_Data);
|
|
|
|
|
|
|
|
|
|
/** Handles and responds to unsupported clients sending pings. */
|
|
|
|
|
void HandleIncomingDataInOldPingResponseStage(cClientHandle & a_Client, const std::string_view a_Data);
|
|
|
|
|
|
|
|
|
|
/* Tries to recognize a protocol based on a_Data and m_Buffer contents.
|
|
|
|
|
a_Data is replaced with a sub-view, with handshake packet removed. */
|
|
|
|
|
void TryRecognizeProtocol(cClientHandle & a_Client, std::string_view & a_Data);
|
|
|
|
|
|
|
|
|
|
/** Tries to recognize a protocol in the lengthed family (1.7+), based on m_Buffer.
|
|
|
|
|
The packet length and type have already been read, type is 0.
|
|
|
|
|
Returns a cProtocol_XXX instance if recognized. */
|
|
|
|
|
std::unique_ptr<cProtocol> TryRecognizeLengthedProtocol(cClientHandle & a_Client, std::string_view & a_Data);
|
|
|
|
|
|
|
|
|
|
/** Sends one packet inside a cByteBuffer.
|
|
|
|
|
This is used only when handling an outdated server ping. */
|
|
|
|
|
static void SendPacket(cClientHandle & a_Client, cByteBuffer & a_OutPacketBuffer);
|
2016-05-14 12:12:42 -07:00
|
|
|
|
2019-09-09 18:22:37 +02:00
|
|
|
/** Returns the protocol-specific packet ID given the protocol-agnostic packet enum. */
|
2020-07-17 18:46:50 +01:00
|
|
|
static UInt32 GetPacketID(cProtocol::ePacketType a_PacketType);
|
|
|
|
|
|
|
|
|
|
/* Status handler for unrecognised versions. */
|
|
|
|
|
void HandlePacketStatusRequest(cClientHandle & a_Client, cByteBuffer & a_Out);
|
2017-09-04 10:58:38 -05:00
|
|
|
|
2020-07-17 18:46:50 +01:00
|
|
|
/* Ping handler for unrecognised versions. */
|
|
|
|
|
void HandlePacketStatusPing(cClientHandle & a_Client, cByteBuffer & a_Out);
|
2015-07-31 16:49:10 +02:00
|
|
|
|
2020-07-17 18:46:50 +01:00
|
|
|
/** The actual protocol implementation.
|
|
|
|
|
Created when recognition of the client version succeeds with a version we support. */
|
|
|
|
|
std::unique_ptr<cProtocol> m_Protocol;
|
2016-02-05 23:45:45 +02:00
|
|
|
|
2020-07-17 18:46:50 +01:00
|
|
|
/** Buffer for received protocol data. */
|
|
|
|
|
cByteBuffer m_Buffer;
|
2015-03-22 19:46:08 +01:00
|
|
|
|
2013-07-29 12:13:03 +01:00
|
|
|
} ;
|