Clean up Network Events

Beginning support for RTA
This commit is contained in:
HikikoMarmy
2025-04-24 11:16:32 +01:00
parent b4dfb0666c
commit d81261581d
74 changed files with 1379 additions and 241 deletions

View File

@@ -0,0 +1,24 @@
#include "../../global_define.h"
#include "NotifyClientDiscovered.h"
NotifyClientDiscovered::NotifyClientDiscovered( std::string clientIp, int32_t clientPort, RealmClientType clientType ) : GenericMessage( 0x40 )
{
this->m_clientIp = std::move( clientIp );
this->m_clientPort = clientPort;
this->m_clientType = clientType;
}
ByteStream &NotifyClientDiscovered::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
if( m_clientType == RealmClientType::RETURN_TO_ARMS )
m_stream.write_utf8( m_clientIp );
else
m_stream.write_sz_utf8( m_clientIp );
m_stream.write_u32( m_clientPort );
return m_stream;
}

View File

@@ -0,0 +1,12 @@
#pragma once
class NotifyClientDiscovered : public GenericMessage {
private:
std::string m_clientIp;
int32_t m_clientPort;
RealmClientType m_clientType;
public:
NotifyClientDiscovered( std::string clientIp, int32_t clientPort, RealmClientType clientType );
ByteStream &Serialize() override;
};

View File

@@ -0,0 +1,19 @@
#include "../../global_define.h"
#include "NotifyClientReqConnect.h"
NotifyClientRequestConnect::NotifyClientRequestConnect( std::string clientIp, int32_t clientPort ) : GenericMessage( 0x3F )
{
this->m_clientIp = std::move( clientIp );
this->m_clientPort = clientPort;
}
ByteStream &NotifyClientRequestConnect::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
m_stream.write_sz_utf8( m_clientIp );
m_stream.write_u32( m_clientPort );
return m_stream;
}

View File

@@ -0,0 +1,12 @@
#pragma once
class NotifyClientRequestConnect : public GenericMessage
{
private:
std::string m_clientIp;
int32_t m_clientPort;
public:
NotifyClientRequestConnect( std::string clientIp, int32_t clientPort );
ByteStream &Serialize() override;
};

View File

@@ -0,0 +1,23 @@
#include "../../global_define.h"
#include "NotifyClientRequestConnect_RTA.h"
NotifyClientRequestConnect_RTA::NotifyClientRequestConnect_RTA( std::string localAddr, std::string remoteAddr, int32_t port ) : GenericMessage( 0x65 )
{
this->m_localAddr = localAddr;
this->m_remoteAddr = remoteAddr;
this->m_port = port;
}
ByteStream &NotifyClientRequestConnect_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
m_stream.write_utf8( this->m_remoteAddr );
m_stream.write_u32( this->m_port );
m_stream.write_utf8( this->m_localAddr );
m_stream.write_u32( this->m_port );
return m_stream;
}

View File

@@ -0,0 +1,12 @@
#pragma once
class NotifyClientRequestConnect_RTA : public GenericMessage {
private:
std::string m_localAddr;
std::string m_remoteAddr;
int32_t m_port;
public:
NotifyClientRequestConnect_RTA( std::string localAddr, std::string remoteAddr, int32_t port );
ByteStream &Serialize() override;
};

View File

@@ -0,0 +1,14 @@
#include "../../global_define.h"
#include "NotifyForcedLogout.h"
NotifyForcedLogout::NotifyForcedLogout() : GenericMessage( 0x41 )
{
}
ByteStream &NotifyForcedLogout::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,9 @@
#pragma once
class NotifyForcedLogout : public GenericMessage {
private:
public:
NotifyForcedLogout();
ByteStream &Serialize() override;
};

View File

@@ -0,0 +1,24 @@
#include "../../global_define.h"
#include "NotifyGameDiscovered.h"
NotifyGameDiscovered::NotifyGameDiscovered( std::string clientIp, int32_t clientPort, RealmClientType clientType ) : GenericMessage( 0x3E )
{
this->m_clientIp = std::move( clientIp );
this->m_clientPort = clientPort;
this->m_clientType = clientType;
}
ByteStream &NotifyGameDiscovered::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
if( m_clientType == RealmClientType::RETURN_TO_ARMS )
m_stream.write_utf8( m_clientIp );
else
m_stream.write_sz_utf8( m_clientIp );
m_stream.write_u32( m_clientPort );
return m_stream;
}

View File

@@ -0,0 +1,12 @@
#pragma once
class NotifyGameDiscovered : public GenericMessage {
private:
std::string m_clientIp;
int32_t m_clientPort;
RealmClientType m_clientType;
public:
NotifyGameDiscovered( std::string clientIp, int32_t clientPort, RealmClientType clientType );
ByteStream &Serialize() override;
};

View File

@@ -0,0 +1,52 @@
#include "../../global_define.h"
#include "Notify_4C.h"
Notify_4C::Notify_4C() : GenericMessage( 0x4C )
{
}
ByteStream &Notify_4C::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
m_stream.write_u32( 0 ); // Unknown
m_stream.write_u32( 1 ); // Unknown
{
m_stream.write_utf16( L"Dummy 1" );
}
m_stream.write_u32( 1 ); // Unknown
{
m_stream.write_u32( 0 );
// Blob
}
m_stream.write_u32( 1 ); // Unknown
{
m_stream.write_u32( 0 );
}
m_stream.write_u16( 0 ); // Unknown
m_stream.write_u32( 1 ); // Unknown
{
m_stream.write_u16( 0 );
m_stream.write_u32( 0 );
m_stream.write_utf16( L"Dummy 2" );
m_stream.write_u32( 0 );
m_stream.write_u32( 0 );
m_stream.write_u32( 0 );
m_stream.write_u16( 1 );
}
m_stream.write_u32( 0 ); // Unknown
m_stream.write_utf8( "127.0.0.1" );
m_stream.write_u32( 0 ); // Unknown
m_stream.write_u32( 0 ); // Unknown
return m_stream;
}

View File

@@ -0,0 +1,9 @@
#pragma once
class Notify_4C : public GenericMessage {
private:
public:
Notify_4C();
ByteStream &Serialize() override;
};

View File

@@ -0,0 +1,38 @@
#include "../../global_define.h"
#include "RequestCancelGame.h"
void RequestCancelGame::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
}
sptr_generic_response RequestCancelGame::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultCancelGame >( this );
}
GameSessionManager::Get().RequestCancel( user );
return std::make_shared< ResultCancelGame >( this );
}
ResultCancelGame::ResultCancelGame( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream &ResultCancelGame::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,22 @@
#pragma once
class RequestCancelGame : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestCancelGame > Create()
{
return std::make_unique< RequestCancelGame >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCancelGame : public GenericResponse {
public:
ResultCancelGame( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,38 @@
#include "../../global_define.h"
#include "RequestCancelGame_RTA.h"
void RequestCancelGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
}
sptr_generic_response RequestCancelGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultCancelGame_RTA >( this );
}
GameSessionManager::Get().RequestCancel( user );
return std::make_shared< ResultCancelGame_RTA >( this );
}
ResultCancelGame_RTA::ResultCancelGame_RTA( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream &ResultCancelGame_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,22 @@
#pragma once
class RequestCancelGame_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestCancelGame_RTA > Create()
{
return std::make_unique< RequestCancelGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCancelGame_RTA : public GenericResponse {
public:
ResultCancelGame_RTA( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,48 @@
#include "../../global_define.h"
#include "RequestCreateAccount.h"
void RequestCreateAccount::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto username = stream->read_encrypted_utf16();
auto password = stream->read_encrypted_utf16();
auto emailAddress = stream->read_encrypted_utf16();
auto dateOfBirth = stream->read_encrypted_utf16();
auto chatHandle = stream->read_encrypted_utf16();
int dbg = 0;
}
sptr_generic_response RequestCreateAccount::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Debug( "Account creation isn't supported. Random SessionID generated." );
if( nullptr == user )
{
Log::Error( "RequestCreateAccount::ProcessRequest() - User not found!" );
return std::make_shared< ResultCreateAccount >( this, CREATE_ACCOUNT_REPLY::ERROR_FATAL, L"" );
}
return std::make_shared< ResultCreateAccount >( this, CREATE_ACCOUNT_REPLY::SUCCESS, user->m_sessionId );
}
ResultCreateAccount::ResultCreateAccount( GenericRequest *request, int32_t reply, std::wstring sessionId ) : GenericResponse( *request )
{
m_reply = reply;
m_sessionId = sessionId;
}
ByteStream &ResultCreateAccount::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
m_stream.write_u32( 0 );
//m_stream.write_encrypted_utf16( m_sessionId );
return m_stream;
}

View File

@@ -0,0 +1,34 @@
#pragma once
// Account Creation is used in the Network Beta for CoN
// but it isn't used or supported here because retail
// uses "foo" and "bar" to login without user data.
class RequestCreateAccount : public GenericRequest
{
enum CREATE_ACCOUNT_REPLY {
SUCCESS = 0,
ERROR_FATAL,
ERROR_NOT_EXIST
};
public:
static std::unique_ptr< RequestCreateAccount > Create()
{
return std::make_unique< RequestCreateAccount >();
}
CREATE_ACCOUNT_REPLY m_reply;
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreateAccount : public GenericResponse {
private:
std::wstring m_sessionId;
int32_t m_reply;
public:
ResultCreateAccount( GenericRequest *request, int32_t reply, std::wstring sessionId );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,47 @@
#include "../../global_define.h"
#include "RequestCreatePrivateGame.h"
void RequestCreatePrivateGame::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameInfo = stream->read_utf16();
}
sptr_generic_response RequestCreatePrivateGame::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto result = GameSessionManager::Get().CreatePrivateGameSession( user, m_gameInfo, user->m_clientType );
if( !result )
{
Log::Error( "RequestCreatePrivateGame::ProcessRequest() - Failed to create private game session!" );
return std::make_shared< ResultCreatePrivateGame >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
}
Log::Info( "[%S] Create Private Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
return std::make_shared< ResultCreatePrivateGame >( this, CREATE_REPLY::SUCCESS, Config::service_ip, Config::discovery_port );
}
ResultCreatePrivateGame::ResultCreatePrivateGame( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIp = discoveryIp;
m_discoveryPort = discoveryPort;
}
ByteStream &ResultCreatePrivateGame::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIp );
m_stream.write( m_discoveryPort );
return m_stream;
}

View File

@@ -0,0 +1,36 @@
#pragma once
class RequestCreatePrivateGame : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePrivateGame > Create()
{
return std::make_unique< RequestCreatePrivateGame >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePrivateGame : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultCreatePrivateGame( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,47 @@
#include "../../global_define.h"
#include "RequestCreatePrivateGame_RTA.h"
void RequestCreatePrivateGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameInfo = stream->read_utf16();
}
sptr_generic_response RequestCreatePrivateGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto result = GameSessionManager::Get().CreatePrivateGameSession( user, m_gameInfo, user->m_clientType );
if( !result )
{
Log::Error( "RequestCreatePrivateGame2::ProcessRequest() - Failed to create private game session!" );
return std::make_shared< ResultCreatePrivateGame2 >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
}
Log::Info( "[%S] Create Private Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
return std::make_shared< ResultCreatePrivateGame2 >( this, CREATE_REPLY::SUCCESS, Config::service_ip, Config::discovery_port );
}
ResultCreatePrivateGame2::ResultCreatePrivateGame2( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIp = discoveryIp;
m_discoveryPort = discoveryPort;
}
ByteStream &ResultCreatePrivateGame2::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIp );
m_stream.write( m_discoveryPort );
return m_stream;
}

View File

@@ -0,0 +1,36 @@
#pragma once
class RequestCreatePrivateGame_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePrivateGame_RTA > Create()
{
return std::make_unique< RequestCreatePrivateGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePrivateGame2 : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultCreatePrivateGame2( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,38 @@
#include "../../global_define.h"
#include "RequestCreatePrivateRoom.h"
void RequestCreatePrivateRoom::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestCreatePrivateRoom::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto sessionId = stream->read_encrypted_utf16();
auto roomName = stream->read_utf16();
auto result = ChatRoomManager::Get().CreatePrivateChatSession( user, roomName );
if( !result )
{
Log::Error( "RequestCreatePrivateRoom::ProcessRequest() - Failed to create private room!" );
return std::make_shared< ResultCreatePrivateRoom >( this );
}
return std::make_shared< ResultCreatePrivateRoom >( this );
}
ResultCreatePrivateRoom::ResultCreatePrivateRoom( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream&ResultCreatePrivateRoom::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,19 @@
#pragma once
class RequestCreatePrivateRoom : public GenericRequest
{
public:
static std::unique_ptr< RequestCreatePrivateRoom > Create()
{
return std::make_unique< RequestCreatePrivateRoom >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePrivateRoom : public GenericResponse {
public:
ResultCreatePrivateRoom( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,56 @@
#include "../../global_define.h"
#include "RequestCreatePublicGame.h"
// Request
void RequestCreatePublicGame::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
// Some kind of match attributes
auto unknown_a = stream->read_u16();
auto unknown_b = stream->read_u32();
auto unknown_c = stream->read_u32();
auto unknown_d = stream->read_u32();
m_gameInfo = stream->read_utf16();
}
sptr_generic_response RequestCreatePublicGame::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto result = GameSessionManager::Get().CreatePublicGameSession( user, m_gameInfo, user->m_clientType );
if( !result )
{
Log::Error( "RequestCreatePublicGame::ProcessRequest() - Failed to create public game session!" );
return std::make_shared< ResultCreatePublicGame >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
}
Log::Info( "[%S] Create Public Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
return std::make_shared< ResultCreatePublicGame >(this, CREATE_REPLY::SUCCESS, Config::service_ip, Config::discovery_port);
}
// Result
ResultCreatePublicGame::ResultCreatePublicGame( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIp = discoveryIp;
m_discoveryPort = discoveryPort;
}
ByteStream &ResultCreatePublicGame::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIp );
m_stream.write( m_discoveryPort );
return m_stream;
}

View File

@@ -0,0 +1,37 @@
#pragma once
class RequestCreatePublicGame : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
int32_t m_minimumLevel;
int32_t m_maximumLevel;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePublicGame > Create()
{
return std::make_unique< RequestCreatePublicGame >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePublicGame : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultCreatePublicGame( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,64 @@
#include "../../global_define.h"
#include "RequestCreatePublicGame_RTA.h"
// Request
void RequestCreatePublicGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
auto unknown_a = stream->read_u16();
auto unknown_b = stream->read_u32();
auto unknown_c = stream->read_u32();
auto unknown_d = stream->read_u32();
m_gameInfo = stream->read_utf16();
auto unknown_e = stream->read_u32();
auto unknown_f = stream->read_u32();
m_localAddr = stream->read_utf16();
}
sptr_generic_response RequestCreatePublicGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Packet( stream->data, stream->data.size(), false );
auto result = GameSessionManager::Get().CreatePublicGameSession( user, m_gameInfo, user->m_clientType );
if( !result )
{
Log::Error( "RequestCreatePublicGame::ProcessRequest() - Failed to create public game session!" );
return std::make_shared< ResultCreatePublicGame_RTA >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
}
user->m_localAddr = Utility::WideToUTF8( m_localAddr );
Log::Info( "[%S] Create Public Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
return std::make_shared< ResultCreatePublicGame_RTA >( this, CREATE_REPLY::SUCCESS, Config::service_ip, Config::discovery_port );
}
// Result
ResultCreatePublicGame_RTA::ResultCreatePublicGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIp = discoveryIp;
m_discoveryPort = discoveryPort;
}
ByteStream &ResultCreatePublicGame_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
m_stream.write_utf8( m_discoveryIp );
m_stream.write( m_discoveryPort );
return m_stream;
}

View File

@@ -0,0 +1,36 @@
#pragma once
class RequestCreatePublicGame_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
std::wstring m_localAddr;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePublicGame_RTA > Create()
{
return std::make_unique< RequestCreatePublicGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePublicGame_RTA : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultCreatePublicGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,50 @@
#include "../../global_define.h"
#include "RequestDoClientDiscovery.h"
void RequestDoClientDiscovery::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameId = stream->read_u32();
}
sptr_generic_response RequestDoClientDiscovery::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto session = GameSessionManager::Get().FindGame( m_gameId );
if( session == nullptr )
{
return std::make_shared< ResultDoClientDiscovery >( this, DISCOVERY_REPLY::FATAL_ERROR, "", 0 );
}
if( session->m_currentPlayers >= session->m_maximumPlayers )
{
return std::make_shared< ResultDoClientDiscovery >( this, DISCOVERY_REPLY::GAME_FULL, "", 0 );
}
user->m_gameId = m_gameId;
user->m_isHost = false;
return std::make_shared< ResultDoClientDiscovery >( this, DISCOVERY_REPLY::SUCCESS, Config::service_ip, Config::discovery_port );
}
ResultDoClientDiscovery::ResultDoClientDiscovery( GenericRequest *request, int32_t reply, std::string ip, int32_t port ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIP = ip;
m_discoveryPort = port;
}
ByteStream &ResultDoClientDiscovery::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIP );
m_stream.write( m_discoveryPort );
return m_stream;
}

View File

@@ -0,0 +1,34 @@
#pragma once
class RequestDoClientDiscovery : public GenericRequest
{
private:
enum DISCOVERY_REPLY {
SUCCESS = 0,
FATAL_ERROR = 1,
GAME_FULL = 2,
};
std::wstring m_sessionId;
int32_t m_gameId;
public:
static std::unique_ptr< RequestDoClientDiscovery > Create()
{
return std::make_unique< RequestDoClientDiscovery >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultDoClientDiscovery : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIP;
int32_t m_discoveryPort;
public:
ResultDoClientDiscovery( GenericRequest *request, int32_t reply, std::string ip = "", int32_t port = 0);
ByteStream &Serialize();
};

View File

@@ -0,0 +1,45 @@
#include "../../global_define.h"
#include "RequestEnterRoom.h"
void RequestEnterRoom::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestEnterRoom::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto publicKey = stream->read_utf8();
auto unknown = stream->read_u32();
return std::make_shared< ResultEnterRoom >( this );
}
ResultEnterRoom::ResultEnterRoom( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream& ResultEnterRoom::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
m_stream.write_utf16( L"Room Name" );
m_stream.write_utf16( L"Room Banner" );
m_stream.write_u32( 3 );
{
m_stream.write_utf16( L"Name1" );
m_stream.write_utf16( L"Name2" );
m_stream.write_utf16( L"Name3" );
}
m_stream.write_u32( 1 );
{
m_stream.write_utf16( L"Name1" );
}
return m_stream;
}

View File

@@ -0,0 +1,19 @@
#pragma once
class RequestEnterRoom : public GenericRequest
{
public:
static std::unique_ptr< RequestEnterRoom > Create()
{
return std::make_unique< RequestEnterRoom >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultEnterRoom : public GenericResponse {
public:
ResultEnterRoom( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,37 @@
#include "../../global_define.h"
#include "RequestGetEncryptionKey.h"
void RequestGetEncryptionKey::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestGetEncryptionKey::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto publicKey = stream->read_utf8();
auto unknown = stream->read_u32();
return std::make_shared< ResultGetEncryptionKey >( this );
}
ResultGetEncryptionKey::ResultGetEncryptionKey( GenericRequest *request ) : GenericResponse( *request )
{
m_symKey = RealmCrypt::getSymmetricKey();
}
ByteStream& ResultGetEncryptionKey::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
auto encrypted = RealmCrypt::encryptSymmetric( m_symKey );
m_stream.write_u32( encrypted.size() + 4 );
m_stream.write_u32( m_symKey.size() );
m_stream.write_bytes( encrypted );
return m_stream;
}

View File

@@ -0,0 +1,21 @@
#pragma once
class RequestGetEncryptionKey : public GenericRequest
{
public:
static std::unique_ptr< RequestGetEncryptionKey > Create()
{
return std::make_unique< RequestGetEncryptionKey >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetEncryptionKey : public GenericResponse {
public:
std::vector< uint8_t > m_symKey;
ResultGetEncryptionKey( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,69 @@
#include "../../global_define.h"
#include "RequestGetGame.h"
void RequestGetGame::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameName = stream->read_utf16();
}
sptr_generic_response RequestGetGame::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultGetGame >( this, TIMEOUT );
}
auto session = GameSessionManager::Get().FindGame( m_gameName );
if( session == nullptr )
{
Log::Error( "Game session not found! [%S]", m_gameName.c_str() );
return std::make_shared< ResultGetGame >( this, NOT_FOUND );
}
if( session->m_currentPlayers >= session->m_maximumPlayers )
{
Log::Error( "Game session is full! [%S]", m_gameName.c_str() );
return std::make_shared< ResultGetGame >( this, TIMEOUT );
}
auto host_user = session->m_owner.lock();
if( host_user == nullptr )
{
Log::Error( "Game session owner not found! [%S]", m_gameName.c_str() );
return std::make_shared< ResultGetGame >( this, TIMEOUT );
}
user->m_isHost = false;
user->m_gameId = session->m_gameIndex;
return std::make_shared< ResultGetGame >( this, SUCCESS, session->m_gameIndex );
}
ResultGetGame::ResultGetGame( GenericRequest *request, int32_t reply, int32_t gameId ) : GenericResponse( *request )
{
m_reply = reply;
m_gameId = gameId;
}
ByteStream &ResultGetGame::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
// TODO: These may come in from the UpdateGameData event
m_stream.write_utf16( L"Kelethin" );
m_stream.write_utf16( L"OwnerName" );
m_stream.write_u32( m_gameId );
return m_stream;
}

View File

@@ -0,0 +1,31 @@
#pragma once
class RequestGetGame : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_gameName;
enum REPLY {
SUCCESS = 0,
TIMEOUT,
NOT_FOUND
};
public:
static std::unique_ptr< RequestGetGame > Create()
{
return std::make_unique< RequestGetGame >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetGame : public GenericResponse {
private:
int32_t m_reply;
int32_t m_gameId;
public:
ResultGetGame( GenericRequest *request, int32_t reply, int32_t gameId = 0 );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,70 @@
#include "../../global_define.h"
#include "RequestGetGame_RTA.h"
void RequestGetGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameId = stream->read_u32();
m_localAddr = stream->read_utf16();
}
sptr_generic_response RequestGetGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Packet( stream->data, stream->data.size(), false );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultGetGame_RTA >( this, TIMEOUT );
}
auto session = GameSessionManager::Get().FindGame( m_gameId );
if( session == nullptr )
{
Log::Error( "Game session not found! [%d]", m_gameId );
return std::make_shared< ResultGetGame_RTA >( this, NOT_FOUND );
}
if( session->m_currentPlayers >= session->m_maximumPlayers )
{
Log::Error( "Game session is full! [%d]", m_gameId );
return std::make_shared< ResultGetGame_RTA >( this, TIMEOUT );
}
auto host_user = session->m_owner.lock();
if( host_user == nullptr )
{
Log::Error( "Game session owner not found! [%d]", m_gameId );
return std::make_shared< ResultGetGame_RTA >( this, TIMEOUT );
}
user->m_isHost = false;
user->m_gameId = session->m_gameIndex;
return std::make_shared< ResultGetGame_RTA >( this, SUCCESS, Config::service_ip, Config::discovery_port );
}
ResultGetGame_RTA::ResultGetGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIp = discoveryIp;
m_discoveryPort = discoveryPort;
}
ByteStream &ResultGetGame_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
m_stream.write_utf8( m_discoveryIp );
m_stream.write_u32( m_discoveryPort );
return m_stream;
}

View File

@@ -0,0 +1,33 @@
#pragma once
class RequestGetGame_RTA : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_localAddr;
uint32_t m_gameId;
enum REPLY {
SUCCESS = 0,
TIMEOUT,
NOT_FOUND
};
public:
static std::unique_ptr< RequestGetGame_RTA > Create()
{
return std::make_unique< RequestGetGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetGame_RTA : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultGetGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0);
ByteStream &Serialize();
};

View File

@@ -0,0 +1,48 @@
#include "../../global_define.h"
#include "RequestGetPublicRooms.h"
void RequestGetPublicRooms::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestGetPublicRooms::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto publicKey = stream->read_utf8();
return std::make_shared< ResultGetPublicRooms >( this );
}
ResultGetPublicRooms::ResultGetPublicRooms( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream& ResultGetPublicRooms::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
m_stream.write_u32( 0);
for( int i = 0; i < 0; i++ )
{
m_stream.write_utf16( L"Room Name" );
m_stream.write_utf16( L"Room Banner" );
m_stream.write_u32( 3 );
{
m_stream.write_utf16( L"Name1" );
m_stream.write_utf16( L"Name2" );
m_stream.write_utf16( L"Name3" );
}
m_stream.write_u32( 1 );
{
m_stream.write_utf16( L"Name1" );
}
}
return m_stream;
}

View File

@@ -0,0 +1,19 @@
#pragma once
class RequestGetPublicRooms : public GenericRequest
{
public:
static std::unique_ptr< RequestGetPublicRooms > Create()
{
return std::make_unique< RequestGetPublicRooms >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetPublicRooms : public GenericResponse {
public:
ResultGetPublicRooms( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,39 @@
#include "../../global_define.h"
#include "RequestGetRealmStats.h"
void RequestGetRealmStats::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestGetRealmStats::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultGetRealmStats >( this );
}
ResultGetRealmStats::ResultGetRealmStats( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream &ResultGetRealmStats::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
// Player count on the game page.
m_stream.write_u32( RealmUserManager::Get().GetUserCount() ); // Users Logged In Game
// I'm not sure this appears anywhere in the game.
m_stream.write_u32( 0 ); // Users Logged In Realm
m_stream.write_u32( 0 ); // Users Running Game
m_stream.write_u32( 0 ); // Users Running Realm
m_stream.write_u32( 0 ); // Users Playing Game
m_stream.write_u32( 0 ); // Users Playing Realm
m_stream.write_u32( 0 ); // unmatchedGamesGame
m_stream.write_u32( 0 ); // unmatchedGamesRealm
return m_stream;
}

View File

@@ -0,0 +1,18 @@
#pragma once
class RequestGetRealmStats : public GenericRequest
{
public:
static std::unique_ptr< RequestGetRealmStats > Create()
{
return std::make_unique< RequestGetRealmStats >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetRealmStats : public GenericResponse {
public:
ResultGetRealmStats( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,44 @@
#include "../../global_define.h"
#include "RequestGetRoom.h"
void RequestGetRoom::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId = stream->read_encrypted_utf16();
}
sptr_generic_response RequestGetRoom::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultGetRoom >( this );
}
ResultGetRoom::ResultGetRoom( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream &ResultGetRoom::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
m_stream.write_utf16( L"Room Name" );
m_stream.write_utf16( L"Room Banner" );
m_stream.write_u32( 3 );
{
m_stream.write_utf16( L"Name1" );
m_stream.write_utf16( L"Name2" );
m_stream.write_utf16( L"Name3" );
}
m_stream.write_u32( 1 );
{
m_stream.write_utf16( L"Name1" );
}
return m_stream;
}

View File

@@ -0,0 +1,18 @@
#pragma once
class RequestGetRoom : public GenericRequest {
public:
static std::unique_ptr< RequestGetRoom > Create()
{
return std::make_unique< RequestGetRoom >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetRoom : public GenericResponse {
public:
ResultGetRoom( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,38 @@
#include "../../global_define.h"
#include "RequestGetRules.h"
void RequestGetRules::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_language = stream->read_sz_utf8();
}
sptr_generic_response RequestGetRules::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
// TODO: Get rules/eula based on language
std::wstring rules =
L"Welcome to the Norrath Emulated Server!\n\n"
L"This server is currently in development\n"
L"and may not be fully functional.\n\n";
return std::make_shared< ResultGetRules >( this, rules );
}
ResultGetRules::ResultGetRules( GenericRequest *request, std::wstring rules ) : GenericResponse( *request )
{
m_rules = rules;
}
ByteStream &ResultGetRules::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
m_stream.write_utf16( m_rules );
return m_stream;
}

View File

@@ -0,0 +1,25 @@
#pragma once
class RequestGetRules : public GenericRequest
{
private:
std::string m_language;
public:
static std::unique_ptr< RequestGetRules > Create()
{
return std::make_unique< RequestGetRules >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetRules : public GenericResponse {
private:
std::wstring m_rules;
public:
ResultGetRules( GenericRequest *request, std::wstring rules );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,37 @@
#include "../../global_define.h"
#include "RequestGetServerAddress.h"
void RequestGetServerAddress::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestGetServerAddress::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultGetServerAddress >( this, Config::service_ip, Config::lobby_port, user->m_clientType );
}
ResultGetServerAddress::ResultGetServerAddress( GenericRequest *request, std::string ip, int32_t port, RealmClientType clientType ) : GenericResponse( *request )
{
m_ip = ip;
m_port = port;
m_clientType = clientType;
}
ByteStream &ResultGetServerAddress::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
if( m_clientType == RealmClientType::RETURN_TO_ARMS )
m_stream.write_utf8( m_ip );
else
m_stream.write_sz_utf8( m_ip );
m_stream.write( m_port );
return m_stream;
}

View File

@@ -0,0 +1,22 @@
#pragma once
class RequestGetServerAddress : public GenericRequest {
public:
static std::unique_ptr< RequestGetServerAddress > Create()
{
return std::make_unique< RequestGetServerAddress >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetServerAddress : public GenericResponse {
public:
std::string m_ip;
int32_t m_port;
RealmClientType m_clientType;
ResultGetServerAddress( GenericRequest *request, std::string ip, int32_t port, RealmClientType clientType );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,65 @@
#include "../../global_define.h"
#include "RequestLogin.h"
void RequestLogin::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_username = stream->read_encrypted_utf16();
m_password = stream->read_encrypted_utf16();
}
sptr_generic_response RequestLogin::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Packet( stream->data, stream->data.size(), false );
if( m_username.empty() || m_password.empty() )
{
Log::Error( "RequestLogin::ProcessRequest() - Username or password is empty" );
return std::make_shared< ResultLogin >( this, LOGIN_REPLY::NOT_EXIST, L"" );
}
if( user->m_clientType == RealmClientType::CHAMPIONS_OF_NORRATH )
{
if( m_username == L"foo" && m_password == L"bar" )
{
// Retail CoN does not use any login information.
Log::Debug( "RequestLogin : Champions of Norrath v2.0" );
}
else
{
// Network Beta CoN uses login information, but it's invalid because of version 2.0.
Log::Debug( "RequestLogin : Champions of Norrath v1.0" );
// TODO: Either block this, or add support for the network beta.
return std::make_shared< ResultLogin >( this, LOGIN_REPLY::NOT_EXIST, L"" );
}
}
else
{
// Return to Arms uses login information.
Log::Debug( "RequestLogin : Return to Arms" );
}
return std::make_shared< ResultLogin >( this, LOGIN_REPLY::SUCCESS, user->m_sessionId );
}
ResultLogin::ResultLogin( GenericRequest *request, int32_t reply, std::wstring sessionId ) : GenericResponse( *request )
{
m_reply = reply;
m_sessionId = sessionId;
}
ByteStream &ResultLogin::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
m_stream.write_encrypted_utf16( m_sessionId );
m_stream.write_encrypted_utf16( L"UNKNOWN DUMMY STRING" );
return m_stream;
}

View File

@@ -0,0 +1,40 @@
#pragma once
// Account Login is used in the Network Beta for CoN.
// In the retail version, the game simply logs in with
// "foo" and "bar" as the username and password.
//
// A unique Session ID is generated and assigned to the player.
class RequestLogin : public GenericRequest
{
private:
enum LOGIN_REPLY {
SUCCESS = 0,
FATAL_ERROR,
NOT_EXIST,
};
std::wstring m_username;
std::wstring m_password;
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestLogin > Create()
{
return std::make_unique< RequestLogin >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultLogin : public GenericResponse {
private:
std::wstring m_sessionId;
int32_t m_reply;
public:
ResultLogin( GenericRequest *request, int32_t reply, std::wstring sessionId );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,31 @@
#include "../../global_define.h"
#include "RequestLogout.h"
void RequestLogout::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
}
sptr_generic_response RequestLogout::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Debug( "[%S] Logout", m_sessionId.c_str() );
return std::make_shared< ResultLogout >( this, 0 );
}
ResultLogout::ResultLogout( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
{
m_reply = reply;
}
ByteStream &ResultLogout::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_reply );
return m_stream;
}

View File

@@ -0,0 +1,23 @@
#pragma once
class RequestLogout : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestLogout > Create()
{
return std::make_unique< RequestLogout >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultLogout : public GenericResponse {
private:
int32_t m_reply;
public:
ResultLogout( GenericRequest *request, int32_t reply );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,88 @@
#include "../../global_define.h"
#include "RequestMatchGame.h"
void RequestMatchGame::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
auto unknown_a = stream->read_u16();
auto unknown_b = stream->read_u32();
auto unknown_c = stream->read_u32();
auto unknown_d = stream->read_u32();
auto unknown_e = stream->read_u32();
// Match Game Node Count
for( uint32_t i = 0; i < unknown_e; i++ )
{
auto node_a = stream->read_u16();
auto node_b = stream->read_u32();
auto node_c = stream->read_utf16();
auto node_d = stream->read_u32();
auto node_e = stream->read_u32();
auto node_f = stream->read_u32();
auto node_g = stream->read_u16();
}
auto unknown_f = stream->read_u8();
auto unknown_g = stream->read_u32();
auto unknown_h = stream->read_u32();
}
sptr_generic_response RequestMatchGame::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultMatchGame >( this );
}
ResultMatchGame::ResultMatchGame( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream &ResultMatchGame::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
auto publicGameList = GameSessionManager::Get().GetAvailableGameSessionList( RealmClientType::CHAMPIONS_OF_NORRATH );
auto publicGameCount = static_cast< uint32_t >( publicGameList.size() );
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( std::format( L"{}:{}", game->m_hostExternalAddr, game->m_hostPort ) );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( game->m_gameName );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( game->m_ownerName );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_u32( game->m_gameIndex );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf8( game->m_gameData );
}
return m_stream;
}

View File

@@ -0,0 +1,21 @@
#pragma once
class RequestMatchGame : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestMatchGame > Create()
{
return std::make_unique< RequestMatchGame >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultMatchGame : public GenericResponse {
public:
ResultMatchGame( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,78 @@
#include "../../global_define.h"
#include "RequestMatchGame_RTA.h"
void RequestMatchGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestMatchGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultMatchGame_RTA >( this );
}
ResultMatchGame_RTA::ResultMatchGame_RTA( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream&ResultMatchGame_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
auto publicGameList = GameSessionManager::Get().GetAvailableGameSessionList( RealmClientType::RETURN_TO_ARMS );
auto publicGameCount = static_cast< uint32_t >( publicGameList.size() );
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( game->m_gameName );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( game->m_playerCount );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_u32( game->m_gameIndex );
}
m_stream.write_u32( publicGameCount );
{
m_stream.write_u32( 0 ); // Size
// Blob Data
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( game->m_hostExternalAddr );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_u32( game->m_hostPort );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( game->m_hostLocalAddr );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_u32( game->m_hostPort );
}
return m_stream;
}

View File

@@ -0,0 +1,19 @@
#pragma once
class RequestMatchGame_RTA : public GenericRequest
{
public:
static std::unique_ptr< RequestMatchGame_RTA > Create()
{
return std::make_unique< RequestMatchGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultMatchGame_RTA : public GenericResponse {
public:
ResultMatchGame_RTA( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,27 @@
#include "../../global_define.h"
#include "RequestSaveNewCharacter_RTA.h"
void RequestSaveNewCharacter::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestSaveNewCharacter::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultSaveNewCharacter >( this );
}
ResultSaveNewCharacter::ResultSaveNewCharacter( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream&ResultSaveNewCharacter::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,19 @@
#pragma once
class RequestSaveNewCharacter : public GenericRequest
{
public:
static std::unique_ptr< RequestSaveNewCharacter > Create()
{
return std::make_unique< RequestSaveNewCharacter >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultSaveNewCharacter : public GenericResponse {
public:
ResultSaveNewCharacter( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,30 @@
#include "../../global_define.h"
#include "RequestTouchSession.h"
void RequestTouchSession::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
}
sptr_generic_response RequestTouchSession::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultTouchSession >( this );
}
ResultTouchSession::ResultTouchSession( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream &ResultTouchSession::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,21 @@
#pragma once
class RequestTouchSession : public GenericRequest
{
private:
std::wstring m_sessionId;
public:
static std::unique_ptr< RequestTouchSession > Create()
{
return std::make_unique< RequestTouchSession >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultTouchSession : public GenericResponse {
public:
ResultTouchSession( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,68 @@
#include "../../global_define.h"
#include "RequestUpdateGameData.h"
void RequestUpdateGameData::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameData = stream->read_utf8();
}
sptr_generic_response RequestUpdateGameData::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto gameSession = GameSessionManager::Get().FindGame( user->m_gameId );
if( gameSession == nullptr )
{
Log::Error( "Game not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultUpdateGameData >( this );
}
if( m_gameData.size() != 256 )
{
Log::Error( "Game data size is not 256 bytes! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultUpdateGameData >( this );
}
gameSession->m_gameData = m_gameData;
// Parse Game Data. Not the most ideal way to do this, but it works.
char currentPlayers = 0;
char maxPlayers = 0;
char description[ 200 ] = { 0 };
int result = sscanf( m_gameData.c_str(), " %hhd / %hhd :%199[^\r\n]", &currentPlayers, &maxPlayers, description );
if( result >= 2 )
{
gameSession->m_currentPlayers = currentPlayers;
gameSession->m_maximumPlayers = maxPlayers;
gameSession->m_description = ( result == 3 ) ? description : ""; // Empty if not parsed
}
else
{
Log::Debug( "Failed to parse game info from: %s", m_gameData.c_str() );
}
std::string ip = std::string( m_gameData.c_str() + 220, 24 );
user->m_localAddr = ip;
return std::make_shared< ResultUpdateGameData >( this );
}
ResultUpdateGameData::ResultUpdateGameData( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream &ResultUpdateGameData::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,22 @@
#pragma once
class RequestUpdateGameData : public GenericRequest
{
private:
std::wstring m_sessionId;
std::string m_gameData;
public:
static std::unique_ptr< RequestUpdateGameData > Create()
{
return std::make_unique< RequestUpdateGameData >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultUpdateGameData : public GenericResponse {
public:
ResultUpdateGameData( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,30 @@
#include "../../global_define.h"
#include "Request_5B.h"
void Request_5B::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response Request_5B::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto publicKey = stream->read_utf8();
auto unknown = stream->read_u32();
return std::make_shared< Result_5B >( this );
}
Result_5B::Result_5B( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream&Result_5B::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,19 @@
#pragma once
class Request_5B : public GenericRequest
{
public:
static std::unique_ptr< Request_5B > Create()
{
return std::make_unique< Request_5B >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class Result_5B : public GenericResponse {
public:
Result_5B( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,27 @@
#include "../../global_define.h"
#include "Request_5D.h"
void Request_5D::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response Request_5D::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< Result_5D >( this );
}
Result_5D::Result_5D( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream&Result_5D::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,19 @@
#pragma once
class Request_5D : public GenericRequest
{
public:
static std::unique_ptr< Request_5D > Create()
{
return std::make_unique< Request_5D >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class Result_5D : public GenericResponse {
public:
Result_5D( GenericRequest *request );
ByteStream &Serialize();
};

View File

@@ -0,0 +1,30 @@
#include "../../global_define.h"
#include "Request_61.h"
void Request_61::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response Request_61::ProcessRequest( sptr_user user, sptr_byte_stream stream )
{
Deserialize( stream );
auto publicKey = stream->read_utf8();
auto unknown = stream->read_u32();
return std::make_shared< Result_61 >( this );
}
Result_61::Result_61( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteStream&Result_61::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( 0 );
return m_stream;
}

View File

@@ -0,0 +1,21 @@
#pragma once
// Potentially character data.
class Request_61 : public GenericRequest
{
public:
static std::unique_ptr< Request_61 > Create()
{
return std::make_unique< Request_61 >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class Result_61 : public GenericResponse {
public:
Result_61( GenericRequest *request );
ByteStream &Serialize();
};