diff options
-rw-r--r-- | src/Protocol/ProtocolRecognizer.cpp | 36 | ||||
-rw-r--r-- | src/Protocol/ProtocolRecognizer.h | 3 | ||||
-rw-r--r-- | src/Server.cpp | 1 | ||||
-rw-r--r-- | src/Server.h | 3 |
4 files changed, 43 insertions, 0 deletions
diff --git a/src/Protocol/ProtocolRecognizer.cpp b/src/Protocol/ProtocolRecognizer.cpp index ba179c1bf..9062eb9b5 100644 --- a/src/Protocol/ProtocolRecognizer.cpp +++ b/src/Protocol/ProtocolRecognizer.cpp @@ -90,6 +90,11 @@ void cMultiVersionProtocol::HandleIncomingDataInRecognitionStage(cClientHandle & return; } + if (TryHandleHTTPRequest(a_Client, a_Data)) + { + return; + } + // TODO: recover from git history // Unlengthed protocol, ... @@ -238,6 +243,37 @@ void cMultiVersionProtocol::SendDisconnect(cClientHandle & a_Client, const AStri +bool cMultiVersionProtocol::TryHandleHTTPRequest(cClientHandle & a_Client, ContiguousByteBuffer & a_Data) +{ + const auto RedirectUrl = cRoot::Get()->GetServer()->GetCustomRedirectUrl(); + + if (RedirectUrl.empty()) + { + return false; + } + + ContiguousByteBuffer Buffer; + m_Buffer.ReadSome(Buffer, 10U); + m_Buffer.ResetRead(); + + // The request line, hastily decoded with the hope that it's encoded in US-ASCII. + const std::string_view Value(reinterpret_cast<const char *>(Buffer.data()), Buffer.size()); + + if (Value == u8"GET / HTTP") + { + const auto Response = fmt::format(u8"HTTP/1.0 303 See Other\r\nLocation: {}\r\n\r\n", cRoot::Get()->GetServer()->GetCustomRedirectUrl()); + a_Client.SendData({ reinterpret_cast<const std::byte *>(Response.data()), Response.size() }); + a_Client.Destroy(); + return true; + } + + return false; +} + + + + + std::unique_ptr<cProtocol> cMultiVersionProtocol::TryRecognizeLengthedProtocol(cClientHandle & a_Client) { UInt32 PacketType; diff --git a/src/Protocol/ProtocolRecognizer.h b/src/Protocol/ProtocolRecognizer.h index 0a923e78f..8b7848199 100644 --- a/src/Protocol/ProtocolRecognizer.h +++ b/src/Protocol/ProtocolRecognizer.h @@ -59,6 +59,9 @@ private: /** Handles and responds to unsupported clients sending pings. */ void HandleIncomingDataInOldPingResponseStage(cClientHandle & a_Client, ContiguousByteBufferView a_Data); + /* Checks if incoming data is an HTTP request and handles it if it is. */ + bool TryHandleHTTPRequest(cClientHandle & a_Client, ContiguousByteBuffer & a_Data); + /** Tries to recognize a protocol in the lengthed family (1.7+), based on m_Buffer. Returns a cProtocol_XXX instance if recognized. */ std::unique_ptr<cProtocol> TryRecognizeLengthedProtocol(cClientHandle & a_Client); diff --git a/src/Server.cpp b/src/Server.cpp index 08142b008..d70164316 100644 --- a/src/Server.cpp +++ b/src/Server.cpp @@ -158,6 +158,7 @@ bool cServer::InitServer(cSettingsRepositoryInterface & a_Settings, bool a_Shoul m_bIsHardcore = a_Settings.GetValueSetB("Server", "HardcoreEnabled", false); m_bAllowMultiLogin = a_Settings.GetValueSetB("Server", "AllowMultiLogin", false); m_ResourcePackUrl = a_Settings.GetValueSet("Server", "ResourcePackUrl", ""); + m_CustomRedirectUrl = a_Settings.GetValueSet("Server", "CustomRedirectUrl", "https://youtu.be/dQw4w9WgXcQ"); m_FaviconData = Base64Encode(cFile::ReadWholeFile(AString("favicon.png"))); // Will return empty string if file nonexistant; client doesn't mind diff --git a/src/Server.h b/src/Server.h index 6fa2002e4..479fbb865 100644 --- a/src/Server.h +++ b/src/Server.h @@ -96,6 +96,8 @@ public: const AString & GetResourcePackUrl(void) { return m_ResourcePackUrl; } + std::string_view GetCustomRedirectUrl(void) { return m_CustomRedirectUrl; } + bool Start(void); bool Command(cClientHandle & a_Client, AString & a_Cmd); @@ -222,6 +224,7 @@ private: size_t m_MaxPlayers; bool m_bIsHardcore; AString m_ResourcePackUrl; + AString m_CustomRedirectUrl; /** Map of protocol version to Forge mods (map of ModName -> ModVersionString) */ std::map<UInt32, AStringMap> m_ForgeModsByVersion; |