Cleanup for Discovery Server and RTA Support

This commit is contained in:
HikikoMarmy
2025-06-15 00:14:02 +01:00
parent a5d810e99a
commit 0e2d4e8d56
2 changed files with 51 additions and 35 deletions

View File

@@ -5,7 +5,13 @@
// ║║║╚═╗║ ║ ║╚╗╔╝║╣ ╠╦╝╚╦╝ ╚═╗║╣ ╠╦╝╚╗╔╝║╣ ╠╦╝ // ║║║╚═╗║ ║ ║╚╗╔╝║╣ ╠╦╝╚╦╝ ╚═╗║╣ ╠╦╝╚╗╔╝║╣ ╠╦╝
// ═╩╝╩╚═╝╚═╝╚═╝ ╚╝ ╚═╝╩╚═ ╩ ╚═╝╚═╝╩╚═ ╚╝ ╚═╝╩╚═ // ═╩╝╩╚═╝╚═╝╚═╝ ╚╝ ╚═╝╩╚═ ╩ ╚═╝╚═╝╩╚═ ╚╝ ╚═╝╩╚═
#include "../global_define.h" #include "DiscoveryServer.h"
#include "../Game/RealmUserManager.h"
#include "../Game/GameSessionManager.h"
#include "../Common/ByteStream.h"
#include "../logging.h"
DiscoveryServer::DiscoveryServer() DiscoveryServer::DiscoveryServer()
{ {
@@ -20,40 +26,45 @@ DiscoveryServer::~DiscoveryServer()
Log::Info( "Discovery Server stopped." ); Log::Info( "Discovery Server stopped." );
} }
void DiscoveryServer::Start( std::string ip, int32_t port ) void DiscoveryServer::Start(std::string ip, int32_t port)
{ {
m_socket = socket( AF_INET, SOCK_DGRAM, 0 ); m_socket = socket(AF_INET, SOCK_DGRAM, 0);
if( m_socket == INVALID_SOCKET ) if (m_socket == INVALID_SOCKET)
{ {
Log::Error( "Failed to create socket." ); Log::Error("Failed to create socket.");
return; return;
} }
sockaddr_in service; sockaddr_in service{};
service.sin_family = AF_INET; service.sin_family = AF_INET;
service.sin_port = htons( port ); service.sin_port = htons(port);
if( ip == "0.0.0.0" ) if (ip == "0.0.0.0")
{ {
service.sin_addr.s_addr = ADDR_ANY; service.sin_addr.s_addr = INADDR_ANY;
} }
else else
{ {
service.sin_addr.s_addr = inet_addr( ip.c_str() ); if (InetPtonA(AF_INET, ip.c_str(), &service.sin_addr) != 1)
{
Log::Error("Invalid IP address format: %s", ip.c_str());
closesocket(m_socket);
return;
}
} }
if( bind( m_socket, ( SOCKADDR * )&service, sizeof( service ) ) == SOCKET_ERROR ) if (bind(m_socket, reinterpret_cast<SOCKADDR*>(&service), sizeof(service)) == SOCKET_ERROR)
{ {
Log::Error( "Failed to bind socket." ); Log::Error("Failed to bind socket.");
closesocket( m_socket ); closesocket(m_socket);
return; return;
} }
m_running = true; m_running = true;
m_thread = std::thread( &DiscoveryServer::Run, this ); m_thread = std::thread(&DiscoveryServer::Run, this);
Log::Info( "Discovery Server started %s:%d", ip.c_str(), port ); Log::Info("Discovery Server started %s:%d", ip.c_str(), port);
} }
void DiscoveryServer::Stop() void DiscoveryServer::Stop()
@@ -81,16 +92,14 @@ void DiscoveryServer::Run()
continue; continue;
} }
ProcessPacket( &clientAddr, std::make_shared< ByteStream >( m_recvBuffer.data(), bytesReceived ) ); ProcessPacket( &clientAddr, std::make_shared< ByteBuffer >( m_recvBuffer.data(), bytesReceived ) );
} }
} }
void DiscoveryServer::ProcessPacket( sockaddr_in *clientAddr, sptr_byte_stream stream ) void DiscoveryServer::ProcessPacket( sockaddr_in *clientAddr, sptr_byte_stream stream )
{ {
if( 0x20 != stream->read_u32() ) if( 0x20 != stream->read_u32() )
{
return; return;
}
auto encryptedBytes = stream->read_bytes( 0x20 ); auto encryptedBytes = stream->read_bytes( 0x20 );
auto decryptedBytes = RealmCrypt::decryptSymmetric( encryptedBytes ); auto decryptedBytes = RealmCrypt::decryptSymmetric( encryptedBytes );
@@ -98,20 +107,23 @@ void DiscoveryServer::ProcessPacket( sockaddr_in *clientAddr, sptr_byte_stream s
std::wstring sessionId( 16, L'\0' ); std::wstring sessionId( 16, L'\0' );
std::memcpy( sessionId.data(), decryptedBytes.data(), 0x20 ); std::memcpy( sessionId.data(), decryptedBytes.data(), 0x20 );
if( sessionId.empty() || sessionId.size() != 16 ) // Validate the session ID is 16 characters long and not all 0's
if (sessionId.size() != 16 || std::all_of(sessionId.begin(), sessionId.end(), [](wchar_t ch) {
return ch == L'\0';
}))
{ {
Log::Error( "Invalid session id." ); Log::Error("Invalid session id.");
return; return;
} }
// Get the users remote IP and Port for discovery. // Get the users remote IP and Port for discovery.
auto remoteIp = inet_ntoa( clientAddr->sin_addr ); char remoteIp[INET_ADDRSTRLEN];
auto remotePort = ntohs( clientAddr->sin_port ); InetNtopA(AF_INET, &clientAddr->sin_addr, remoteIp, INET_ADDRSTRLEN);
Log::Debug( "Discovery Handshake from %s:%d", remoteIp, remotePort ); uint16_t remotePort = ntohs( clientAddr->sin_port );
// Find the user associated with the session ID // Find the user associated with the session ID
auto user = RealmUserManager::Get().GetUser( sessionId ); auto user = RealmUserManager::Get().FindUserBySessionId( sessionId );
if( user == nullptr ) if( user == nullptr )
{ {
Log::Error( "User not found! [%S]", sessionId.c_str() ); Log::Error( "User not found! [%S]", sessionId.c_str() );
@@ -128,6 +140,8 @@ void DiscoveryServer::ProcessPacket( sockaddr_in *clientAddr, sptr_byte_stream s
user->m_discoveryAddr = remoteIp; user->m_discoveryAddr = remoteIp;
user->m_discoveryPort = remotePort; user->m_discoveryPort = remotePort;
Log::Debug("Discovery Handshake from %s:%d", remoteIp, remotePort);
if( user->m_isHost ) if( user->m_isHost )
{ {
GameSessionManager::Get().RequestOpen( user ); GameSessionManager::Get().RequestOpen( user );

View File

@@ -1,20 +1,22 @@
#pragma once #pragma once
class DiscoveryServer { #include <memory>
private: #include <string>
static inline std::unique_ptr< DiscoveryServer > m_instance; #include <thread>
static inline std::mutex m_mutex; #include <mutex>
#include <atomic>
#include <vector>
#include <winsock2.h>
#include <ws2tcpip.h>
#include "../Common/ByteStream.h"
class DiscoveryServer {
public: public:
static DiscoveryServer &Get() static DiscoveryServer &Get()
{ {
std::lock_guard< std::mutex > lock( m_mutex ); static DiscoveryServer instance;
if( m_instance == nullptr ) return instance;
{
m_instance.reset( new DiscoveryServer() );
}
return *m_instance;
} }
DiscoveryServer( const DiscoveryServer & ) = delete; DiscoveryServer( const DiscoveryServer & ) = delete;