Refactor network events for cleaner buffer management.

Naming some previously unnamed events.
This commit is contained in:
HikikoMarmy
2025-07-01 14:00:14 +01:00
parent e15570ceec
commit d2cd5f55c6
102 changed files with 1739 additions and 889 deletions

View File

@@ -1,20 +1,17 @@
#include "NotifyClientDiscovered.h"
#include "../../Game/RealmUser.h"
#include "../../Common/Constant.h"
NotifyClientDiscovered::NotifyClientDiscovered( std::string clientIp, int32_t clientPort ) : GenericMessage( 0x40 )
NotifyClientDiscovered::NotifyClientDiscovered( sptr_user user ) : GenericMessage( 0x40 )
{
this->m_clientIp = std::move( clientIp );
this->m_clientPort = clientPort;
this->m_clientIp = user->m_discoveryAddr;
this->m_clientPort = user->m_discoveryPort;
}
ByteBuffer &NotifyClientDiscovered::Serialize()
void NotifyClientDiscovered::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( 0 );
m_stream.write_sz_utf8( m_clientIp );
m_stream.write_u32( m_clientPort );
return m_stream;
out.write_sz_utf8( m_clientIp );
out.write_u32( m_clientPort );
}

View File

@@ -3,7 +3,7 @@
#include <string>
#include "../GenericNetMessage.h"
#include "../../Common/Constant.h"
#include "../../Common/ForwardDecl.h"
class NotifyClientDiscovered : public GenericMessage {
private:
@@ -11,6 +11,6 @@ private:
int32_t m_clientPort;
public:
NotifyClientDiscovered( std::string clientIp, int32_t clientPort );
ByteBuffer &Serialize() override;
NotifyClientDiscovered( sptr_user user );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -1,20 +1,19 @@
#include "NotifyClientDiscovered_RTA.h"
#include "../../Common/Constant.h"
#include "../../Game/RealmUser.h"
NotifyClientDiscovered_RTA::NotifyClientDiscovered_RTA( std::string clientIp, int32_t clientPort ) : GenericMessage( 0x40 )
NotifyClientDiscovered_RTA::NotifyClientDiscovered_RTA( sptr_user user ) : GenericMessage( 0x40 )
{
this->m_clientIp = std::move( clientIp );
this->m_clientPort = clientPort;
this->m_clientIp = user->m_discoveryAddr;
this->m_clientPort = user->m_discoveryPort;
}
ByteBuffer & NotifyClientDiscovered_RTA::Serialize()
void NotifyClientDiscovered_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( 0 );
m_stream.write_utf8( m_clientIp );
m_stream.write_u32( m_clientPort );
return m_stream;
out.write_utf8( m_clientIp );
out.write_u32( m_clientPort );
}

View File

@@ -4,6 +4,7 @@
#include "../GenericNetMessage.h"
#include "../../Common/Constant.h"
#include "../../Common/ForwardDecl.h"
class NotifyClientDiscovered_RTA : public GenericMessage {
private:
@@ -11,6 +12,6 @@ private:
int32_t m_clientPort;
public:
NotifyClientDiscovered_RTA( std::string clientIp, int32_t clientPort );
ByteBuffer &Serialize() override;
NotifyClientDiscovered_RTA( sptr_user user );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -0,0 +1,18 @@
#include "NotifyClientReqConnect.h"
NotifyClientRequestConnect::NotifyClientRequestConnect( std::string clientIp, int32_t clientPort ) : GenericMessage( 0x3F )
{
this->m_clientIp = std::move( clientIp );
this->m_clientPort = clientPort;
}
ByteBuffer &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,16 @@
#pragma once
#include <string>
#include "../GenericNetMessage.h"
class NotifyClientRequestConnect : public GenericMessage
{
private:
std::string m_clientIp;
int32_t m_clientPort;
public:
NotifyClientRequestConnect( std::string clientIp, int32_t clientPort );
ByteBuffer &Serialize() override;
};

View File

@@ -1,18 +1,18 @@
#include "NotifyClientRequestConnect.h"
NotifyClientRequestConnect::NotifyClientRequestConnect( std::string clientIp, int32_t clientPort ) : GenericMessage( 0x3F )
#include "../../Game/RealmUser.h"
NotifyClientRequestConnect::NotifyClientRequestConnect( sptr_user user ) : GenericMessage( 0x3F )
{
this->m_clientIp = std::move( clientIp );
this->m_clientPort = clientPort;
this->m_clientIp = user->m_discoveryAddr;
this->m_clientPort = user->m_discoveryPort;
}
ByteBuffer &NotifyClientRequestConnect::Serialize()
void NotifyClientRequestConnect::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( 0 );
m_stream.write_sz_utf8( m_clientIp );
m_stream.write_u32( m_clientPort );
return m_stream;
out.write_sz_utf8( m_clientIp );
out.write_u32( m_clientPort );
}

View File

@@ -3,14 +3,14 @@
#include <string>
#include "../GenericNetMessage.h"
#include "../../Common/ForwardDecl.h"
class NotifyClientRequestConnect : public GenericMessage
{
class NotifyClientRequestConnect : public GenericMessage {
private:
std::string m_clientIp;
int32_t m_clientPort;
public:
NotifyClientRequestConnect( std::string clientIp, int32_t clientPort );
ByteBuffer &Serialize() override;
NotifyClientRequestConnect( sptr_user user );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -1,22 +1,25 @@
#include "NotifyClientRequestConnect_RTA.h"
NotifyClientRequestConnect_RTA::NotifyClientRequestConnect_RTA( std::string localAddr, std::string remoteAddr, int32_t port ) : GenericMessage( 0x65 )
#include "../../Game/RealmUser.h"
NotifyClientRequestConnect_RTA::NotifyClientRequestConnect_RTA( sptr_user user ) : GenericMessage( 0x65 )
{
this->m_localAddr = localAddr;
this->m_remoteAddr = remoteAddr;
this->m_port = port;
this->m_remoteAddr = user->m_discoveryAddr;
this->m_remotePort = user->m_discoveryPort;
this->m_localAddr = user->m_localAddr;
this->m_localPort = user->m_localPort;
}
ByteBuffer &NotifyClientRequestConnect_RTA::Serialize()
void NotifyClientRequestConnect_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( 0 );
m_stream.write_utf8( this->m_localAddr);
m_stream.write_u32( this->m_port );
out.write_utf8( this->m_remoteAddr );
out.write_u32( this->m_remotePort );
m_stream.write_utf8( this->m_localAddr );
m_stream.write_u32( this->m_port );
return m_stream;
out.write_utf8( this->m_localAddr );
out.write_u32( this->m_localPort );
}

View File

@@ -4,14 +4,16 @@
#include <string>
#include "../GenericNetMessage.h"
#include "../../Common/ForwardDecl.h"
class NotifyClientRequestConnect_RTA : public GenericMessage {
private:
std::string m_localAddr;
std::string m_remoteAddr;
int32_t m_port;
int32_t m_localPort;
int32_t m_remotePort;
public:
NotifyClientRequestConnect_RTA( std::string localAddr, std::string remoteAddr, int32_t port );
ByteBuffer &Serialize() override;
NotifyClientRequestConnect_RTA( sptr_user user );
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -4,12 +4,9 @@ NotifyForcedLogout::NotifyForcedLogout() : GenericMessage( 0x41 )
{
}
ByteBuffer &NotifyForcedLogout::Serialize()
void NotifyForcedLogout::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
m_stream.write_u32( 0 );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( 0 );
out.write_u32( 0 );
}

View File

@@ -7,5 +7,5 @@ private:
public:
NotifyForcedLogout();
ByteBuffer &Serialize() override;
void Serialize( ByteBuffer &out ) const override;
};

View File

@@ -7,17 +7,15 @@ NotifyGameDiscovered::NotifyGameDiscovered( std::string clientIp, int32_t client
this->m_clientType = clientType;
}
ByteBuffer &NotifyGameDiscovered::Serialize()
void NotifyGameDiscovered::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( 0 );
if( m_clientType == RealmGameType::RETURN_TO_ARMS )
m_stream.write_utf8( m_clientIp );
out.write_utf8( m_clientIp );
else
m_stream.write_sz_utf8( m_clientIp );
out.write_sz_utf8( m_clientIp );
m_stream.write_u32( m_clientPort );
return m_stream;
out.write_u32( m_clientPort );
}

View File

@@ -14,5 +14,5 @@ private:
public:
NotifyGameDiscovered( std::string clientIp, int32_t clientPort, RealmGameType clientType );
ByteBuffer &Serialize() override;
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -1,19 +1,19 @@
#include "NotifyReserveUserSlot_RTA.h"
NotifyReserveUserSlot_RTA::NotifyReserveUserSlot_RTA( std::string discoveryAddr, int32_t discoveryPort ) : GenericMessage( 0x51 )
NotifyReserveUserSlot_RTA::NotifyReserveUserSlot_RTA( int32_t memberId, std::string discoveryAddr, int32_t discoveryPort ) : GenericMessage( 0x51 )
{
this->m_discoveryAddr = discoveryAddr;
this->m_port = discoveryPort;
this->m_memberId = memberId;
}
ByteBuffer &NotifyReserveUserSlot_RTA::Serialize()
// This notification is nullsub.
void NotifyReserveUserSlot_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( 0 );
m_stream.write_u32( 0 ); // Maybe slot or character ID?
m_stream.write_utf8(""); // Probably IP
m_stream.write_u32( 0 ); // Probably Port
return m_stream;
out.write_u32( 0 );
out.write_utf8( "" );
out.write_u32( 0 );
}

View File

@@ -6,8 +6,9 @@ class NotifyReserveUserSlot_RTA : public GenericMessage {
private:
std::string m_discoveryAddr;
int32_t m_port;
int32_t m_memberId;
public:
NotifyReserveUserSlot_RTA( std::string discoveryAddr, int32_t discoveryPort );
ByteBuffer &Serialize() override;
NotifyReserveUserSlot_RTA( int32_t memberId, std::string discoveryAddr, int32_t discoveryPort );
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -0,0 +1,18 @@
#include "NotifyRoomMessage.h"
NotifyRoomMessage::NotifyRoomMessage( std::wstring roomName, std::wstring chatHandle, std::wstring message ) : GenericMessage( 0x3D )
{
m_roomName = roomName;
m_chatHandle = chatHandle;
m_message = message;
}
void NotifyRoomMessage::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( 0 );
out.write_utf16( m_roomName );
out.write_utf16( m_chatHandle );
out.write_utf16( m_message );
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "../GenericNetMessage.h"
class NotifyRoomMessage : public GenericMessage {
private:
std::wstring m_message;
std::wstring m_chatHandle;
std::wstring m_roomName;
public:
NotifyRoomMessage( std::wstring roomName, std::wstring chatHandle, std::wstring message );
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -4,48 +4,46 @@ Notify_4C::Notify_4C() : GenericMessage( 0x4C )
{
}
ByteBuffer &Notify_4C::Serialize()
void Notify_4C::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( 0 );
m_stream.write_u32( 0 ); // Unknown
out.write_u32( 0 ); // Unknown
m_stream.write_u32( 1 ); // Unknown
out.write_u32( 1 ); // Unknown
{
m_stream.write_utf16( L"Dummy 1" );
out.write_utf16( L"Dummy 1" );
}
m_stream.write_u32( 1 ); // Unknown
out.write_u32( 1 ); // Unknown
{
m_stream.write_u32( 0 );
out.write_u32( 0 );
// Blob
}
m_stream.write_u32( 1 ); // Unknown
out.write_u32( 1 ); // Unknown
{
m_stream.write_u32( 0 );
out.write_u32( 0 );
}
m_stream.write_u16( 0 ); // Unknown
out.write_u16( 0 ); // Unknown
m_stream.write_u32( 1 ); // Unknown
out.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 );
out.write_u16( 0 );
out.write_u32( 0 );
out.write_utf16( L"Dummy 2" );
out.write_u32( 0 );
out.write_u32( 0 );
out.write_u32( 0 );
out.write_u16( 1 );
}
m_stream.write_u32( 0 ); // Unknown
out.write_u32( 0 ); // Unknown
m_stream.write_utf8( "127.0.0.1" );
out.write_utf8( "127.0.0.1" );
m_stream.write_u32( 0 ); // Unknown
m_stream.write_u32( 0 ); // Unknown
return m_stream;
out.write_u32( 0 ); // Unknown
out.write_u32( 0 ); // Unknown
}

View File

@@ -7,5 +7,5 @@ private:
public:
Notify_4C();
ByteBuffer &Serialize() override;
void Serialize(ByteBuffer &out) const override;
};

View File

@@ -0,0 +1,22 @@
#include "Notify_65.h"
NotifyClientRequestsConnect2::NotifyClientRequestsConnect2( std::string discoveryAddr, std::string localAddr, int32_t port ) : GenericMessage( 0x65 )
{
m_discoveryAddr = std::move( discoveryAddr );
m_localAddr = std::move( localAddr );
m_port = port;
}
ByteBuffer &NotifyClientRequestsConnect2::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
m_stream.write_utf8( m_discoveryAddr );
m_stream.write_u32( m_port );
m_stream.write_utf8( m_localAddr );
m_stream.write_u32( m_port );
return m_stream;
}

14
Network/Event/Notify_65.h Normal file
View File

@@ -0,0 +1,14 @@
#pragma once
#include "../GenericNetMessage.h"
class NotifyClientRequestsConnect2 : public GenericMessage {
private:
std::string m_discoveryAddr;
std::string m_localAddr;
int32_t m_port;
public:
NotifyClientRequestsConnect2( std::string discoveryAddr, std::string localAddr, int32_t port );
ByteBuffer &Serialize() override;
};

View File

@@ -0,0 +1,45 @@
#include "RequestAppendCharacterData.h"
#include "../../Game/CharacterSaveManager.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Database/Database.h"
#include "../../logging.h"
void RequestAppendCharacterData::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId = stream->read_encrypted_utf16();
auto length = stream->read_u32();
m_data = stream->read_bytes( length );
m_endOfData = stream->read_u32();
}
sptr_generic_response RequestAppendCharacterData::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultAppendCharacterData >( this, FATAL_ERROR );
}
CharacterSaveManager::Get().AppendSaveData( user->m_sessionId, m_data, m_endOfData );
return std::make_shared< ResultAppendCharacterData >( this, SUCCESS );
}
ResultAppendCharacterData::ResultAppendCharacterData( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
{
m_reply = reply;
}
void ResultAppendCharacterData::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
}

View File

@@ -6,10 +6,11 @@
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class Request_5D : public GenericRequest
class RequestAppendCharacterData : public GenericRequest
{
private:
std::vector< uint8_t > m_data;
int32_t m_endOfData;
enum CREATE_REPLY {
SUCCESS = 0,
@@ -17,20 +18,20 @@ private:
GENERAL_ERROR,
};
public:
static std::unique_ptr< Request_5D > Create()
static std::unique_ptr< RequestAppendCharacterData > Create()
{
return std::make_unique< Request_5D >();
return std::make_unique< RequestAppendCharacterData >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class Result_5D : public GenericResponse {
class ResultAppendCharacterData : public GenericResponse {
private:
int32_t m_reply;
public:
Result_5D( GenericRequest *request, int32_t reply );
ByteBuffer &Serialize();
ResultAppendCharacterData( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -15,27 +15,21 @@ sptr_generic_response RequestCancelGame::ProcessRequest( sptr_socket socket, spt
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultCancelGame >( this );
}
if (user->m_isHost)
if( user->m_gameType != RealmGameType::CHAMPIONS_OF_NORRATH )
{
auto result = GameSessionManager::Get().RequestCancel(user);
if( false == result )
{
Log::Error( "Failed to cancel game session for user [%S]", user->m_sessionId.c_str() );
}
return std::make_shared< ResultCancelGame >( this );
}
else
if( !GameSessionManager::Get().RequestCancel( user ) )
{
user->m_isHost = false;
user->m_gameId = -1;
Log::Error( "Failed to cancel game session for user [{}]", user->m_sessionId );
}
return std::make_shared< ResultCancelGame >( this );
@@ -43,14 +37,12 @@ sptr_generic_response RequestCancelGame::ProcessRequest( sptr_socket socket, spt
ResultCancelGame::ResultCancelGame( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteBuffer &ResultCancelGame::Serialize()
void ResultCancelGame::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
}

View File

@@ -24,5 +24,5 @@ public:
class ResultCancelGame : public GenericResponse {
public:
ResultCancelGame( GenericRequest *request );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -2,6 +2,7 @@
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../Game/ChatRoomManager.h"
#include "../../logging.h"
void RequestCancelGame_RTA::Deserialize( sptr_byte_stream stream )
@@ -15,15 +16,34 @@ sptr_generic_response RequestCancelGame_RTA::ProcessRequest( sptr_socket socket,
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultCancelGame_RTA >( this );
}
GameSessionManager::Get().RequestCancel( user );
if( user->m_gameType != RealmGameType::RETURN_TO_ARMS )
{
return std::make_shared< ResultCancelGame_RTA >( this );
}
const auto &gameSession = GameSessionManager::Get().FindGame( user->m_gameId, user->m_gameType );
if( gameSession == nullptr )
{
Log::Error( "Game session not found for user [{}]", user->m_sessionId );
return std::make_shared< ResultCancelGame_RTA >( this );
}
if( !GameSessionManager::Get().RequestCancel( user ) )
{
Log::Error( "Failed to cancel game session for user [{}]", user->m_sessionId );
}
if( !ChatRoomManager::Get().LeaveRoom( user, user->m_privateRoomId ) )
{
Log::Error( "Failed to leave private chat room for user [{}]", user->m_username );
}
return std::make_shared< ResultCancelGame_RTA >( this );
}
@@ -33,11 +53,9 @@ ResultCancelGame_RTA::ResultCancelGame_RTA( GenericRequest *request ) : GenericR
}
ByteBuffer &ResultCancelGame_RTA::Serialize()
void ResultCancelGame_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
}

View File

@@ -24,5 +24,5 @@ public:
class ResultCancelGame_RTA : public GenericResponse {
public:
ResultCancelGame_RTA( GenericRequest *request );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -11,11 +11,11 @@ void RequestCreateAccount::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_username = Util::WideToUTF8( stream->read_encrypted_utf16() );
m_password = Util::WideToUTF8( stream->read_encrypted_utf16() );
m_emailAddress = Util::WideToUTF8( stream->read_encrypted_utf16() );
m_dateOfBirth = Util::WideToUTF8( stream->read_encrypted_utf16() );
m_chatHandle = Util::WideToUTF8( stream->read_encrypted_utf16() );
m_username = stream->read_encrypted_utf16();
m_password = stream->read_encrypted_utf16();
m_emailAddress = stream->read_encrypted_utf16();
m_dateOfBirth = stream->read_encrypted_utf16();
m_chatHandle = stream->read_encrypted_utf16();
}
bool RequestCreateAccount::VerifyUserData()
@@ -45,34 +45,40 @@ sptr_generic_response RequestCreateAccount::ProcessRequest( sptr_socket socket,
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( nullptr == user || user->m_gameType != RealmGameType::RETURN_TO_ARMS )
{
return std::make_shared< ResultCreateAccount >( this, CREATE_ACCOUNT_REPLY::ERROR_FATAL, L"" );
return std::make_shared< ResultCreateAccount >( this, ERROR_FATAL, L"" );
}
if( m_username.empty() || m_password.empty() || m_emailAddress.empty() || m_dateOfBirth.empty() || m_chatHandle.empty() )
{
Log::Error( "RequestCreateAccount::ProcessRequest() - Missing required fields for account creation." );
return std::make_shared< ResultCreateAccount >( this, CREATE_ACCOUNT_REPLY::ERROR_FATAL, L"" );
return std::make_shared< ResultCreateAccount >( this, ERROR_FATAL, L"" );
}
auto result = Database::Get().CreateNewAccount
(
m_username,
m_password,
m_emailAddress,
m_dateOfBirth,
m_chatHandle
Util::WideToUTF8( m_username ),
Util::WideToUTF8( m_password ),
Util::WideToUTF8( m_emailAddress ),
Util::WideToUTF8( m_dateOfBirth ),
Util::WideToUTF8( m_chatHandle )
);
if( !result )
{
Log::Error( "RequestCreateAccount::ProcessRequest() - Failed to create account for user: %s", m_username.c_str() );
return std::make_shared< ResultCreateAccount >( this, CREATE_ACCOUNT_REPLY::ERROR_FATAL, L"" );
Log::Error( "RequestCreateAccount::ProcessRequest() - Failed to create account for user: {}", m_username );
return std::make_shared< ResultCreateAccount >( this, ERROR_FATAL, L"" );
}
return std::make_shared< ResultCreateAccount >( this, CREATE_ACCOUNT_REPLY::SUCCESS, user->m_sessionId );
user->m_isLoggedIn = true;
user->m_sessionId = UserManager::Get().GenerateSessionId();
user->m_accountId = result;
user->m_username = m_username;
user->m_chatHandle = m_chatHandle;
return std::make_shared< ResultCreateAccount >( this, SUCCESS, user->m_sessionId );
}
ResultCreateAccount::ResultCreateAccount( GenericRequest *request, int32_t reply, std::wstring sessionId ) : GenericResponse( *request )
@@ -81,13 +87,11 @@ ResultCreateAccount::ResultCreateAccount( GenericRequest *request, int32_t reply
m_sessionId = sessionId;
}
ByteBuffer &ResultCreateAccount::Serialize()
void ResultCreateAccount::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
m_stream.write_encrypted_utf16( m_sessionId );
return m_stream;
out.write_encrypted_utf16( m_sessionId );
}

View File

@@ -8,17 +8,18 @@
class RequestCreateAccount : public GenericRequest
{
private:
enum CREATE_ACCOUNT_REPLY {
SUCCESS = 0,
ERROR_FATAL,
ERROR_NOT_EXIST
};
std::string m_username;
std::string m_password;
std::string m_emailAddress;
std::string m_dateOfBirth;
std::string m_chatHandle;
std::wstring m_username;
std::wstring m_password;
std::wstring m_emailAddress;
std::wstring m_dateOfBirth;
std::wstring m_chatHandle;
bool VerifyUserData();
@@ -41,5 +42,5 @@ private:
public:
ResultCreateAccount( GenericRequest *request, int32_t reply, std::wstring sessionId );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -1,6 +1,7 @@
#include "RequestCreateNewCharacter_RTA.h"
#include "../../Database/Database.h"
#include "../../Game/CharacterSaveManager.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Game/RealmCharacter.h"
@@ -12,37 +13,40 @@ void RequestCreateNewCharacter_RTA::Deserialize( sptr_byte_stream stream )
m_sessionId = stream->read_encrypted_utf16();
auto a = stream->read_u32();
auto a = stream->read_u32();
auto b = stream->read_u32();
m_newCharacterData = std::make_shared< RealmCharacter >( stream );
m_metaData.Deserialize( stream );
auto characterDataSize = stream->read_u32();
m_characterData = stream->read_bytes( characterDataSize );
}
sptr_generic_response RequestCreateNewCharacter_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultCreateNewCharacter_RTA >( this, FATAL_ERROR );
}
auto unpacked = m_newCharacterData->Unpack();
//Log::PacketToFile( "new_character", unpacked, unpacked.size());
auto characterId = Database::Get().CreateNewCharacter( user->m_accountId, m_newCharacterData->GetMetaData().Serialize(), m_newCharacterData->GetCharacterData() );
if( characterId < 0 )
if( user->m_gameType != RealmGameType::RETURN_TO_ARMS )
{
Log::Error( "Invalid game type for CreateNewCharacter_RTA request! [{}]", m_sessionId );
return std::make_shared< ResultCreateNewCharacter_RTA >( this, FATAL_ERROR );
}
Log::Info( "New character created for user: " + std::to_string( user->m_accountId ) + ", Character ID: " + std::to_string( characterId ) );
user->m_characterId = characterId;
user->m_character = m_newCharacterData;
auto &saveManager = CharacterSaveManager::Get();
if( !saveManager.BeginSaveTask( user, user, 0, m_metaData, CharacterSaveType::NEW_CHARACTER ) )
{
Log::Error( "Failed to begin save task for new character! [{}]", m_sessionId );
return std::make_shared< ResultCreateNewCharacter_RTA >( this, FATAL_ERROR );
}
saveManager.AppendSaveData( user->m_sessionId, m_characterData, false );
return std::make_shared< ResultCreateNewCharacter_RTA >( this, SUCCESS );
}
@@ -52,11 +56,9 @@ ResultCreateNewCharacter_RTA::ResultCreateNewCharacter_RTA( GenericRequest *requ
m_reply = reply;
}
ByteBuffer& ResultCreateNewCharacter_RTA::Serialize()
void ResultCreateNewCharacter_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
}

View File

@@ -9,13 +9,15 @@ class RequestCreateNewCharacter_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
sptr_realm_character m_newCharacterData;
CharacterSlotData m_metaData;
std::vector< uint8_t > m_characterData;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestCreateNewCharacter_RTA > Create()
{
@@ -32,5 +34,5 @@ private:
public:
ResultCreateNewCharacter_RTA( GenericRequest *request, int32_t reply );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -10,31 +10,37 @@ void RequestCreatePrivateGame::Deserialize( sptr_byte_stream stream )
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameInfo = stream->read_utf16();
m_gameName = stream->read_utf16();
}
sptr_generic_response RequestCreatePrivateGame::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultCreatePrivateGame >( this, CREATE_REPLY::FATAL_ERROR, "", 0 );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultCreatePrivateGame >( this, FATAL_ERROR, "", 0 );
}
auto result = GameSessionManager::Get().CreatePrivateGameSession( user, m_gameInfo, user->m_gameType );
if( nullptr != GameSessionManager::Get().FindGame( m_gameName, user->m_gameType ) )
{
Log::Error( "Game name is already in use! [{}]", m_gameName );
return std::make_shared< ResultCreatePrivateGame >( this, GAME_NAME_IN_USE, "", 0 );
}
auto result = GameSessionManager::Get().CreateGameSession_CON( user, L"", m_gameName, L"", true);
if( !result )
{
Log::Error( "RequestCreatePrivateGame::ProcessRequest() - Failed to create private game session!" );
return std::make_shared< ResultCreatePrivateGame >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
return std::make_shared< ResultCreatePrivateGame >( this, GENERAL_ERROR, "", 0 );
}
Log::Info( "[%S] Create Private Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
Log::Info( "[{}] Create Private Game: {}", m_sessionId, m_gameName );
return std::make_shared< ResultCreatePrivateGame >( this, CREATE_REPLY::SUCCESS, Config::service_ip, Config::discovery_port );
return std::make_shared< ResultCreatePrivateGame >( this, SUCCESS, Config::service_ip, Config::discovery_port );
}
ResultCreatePrivateGame::ResultCreatePrivateGame( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
@@ -44,14 +50,12 @@ ResultCreatePrivateGame::ResultCreatePrivateGame( GenericRequest *request, int32
m_discoveryPort = discoveryPort;
}
ByteBuffer &ResultCreatePrivateGame::Serialize()
void ResultCreatePrivateGame::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIp );
m_stream.write( m_discoveryPort );
return m_stream;
out.write_sz_utf8( m_discoveryIp );
out.write( m_discoveryPort );
}

View File

@@ -10,7 +10,7 @@ class RequestCreatePrivateGame : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
std::wstring m_gameName;
enum CREATE_REPLY {
SUCCESS = 0,
@@ -38,5 +38,5 @@ private:
public:
ResultCreatePrivateGame( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -10,48 +10,52 @@ void RequestCreatePrivateGame_RTA::Deserialize( sptr_byte_stream stream )
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameInfo = stream->read_utf16();
m_gameName = stream->read_utf16();
m_localAddr = Util::WideToUTF8( stream->read_utf16() );
m_localPort = stream->read_u32();
}
sptr_generic_response RequestCreatePrivateGame_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
Log::Packet( stream->get_buffer(), stream->get_length(), false );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultCreatePrivateGame2 >( this, CREATE_REPLY::FATAL_ERROR, "", 0 );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultCreatePrivateGame_RTA >( this, CREATE_REPLY::FATAL_ERROR, "", 0 );
}
auto result = GameSessionManager::Get().CreatePrivateGameSession( user, m_gameInfo, user->m_gameType );
auto result = GameSessionManager::Get().CreateGameSession_RTA( user, L"", m_gameName, {}, true);
if( !result )
{
Log::Error( "RequestCreatePrivateGame2::ProcessRequest() - Failed to create private game session!" );
return std::make_shared< ResultCreatePrivateGame2 >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
return std::make_shared< ResultCreatePrivateGame_RTA >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
}
Log::Info( "[%S] Create Private Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
user->m_localAddr = m_localAddr;
user->m_localPort = m_localPort;
return std::make_shared< ResultCreatePrivateGame2 >( this, CREATE_REPLY::SUCCESS, Config::service_ip, Config::discovery_port );
Log::Info( "[{}] Create Private Game: {}", m_sessionId, m_gameName );
return std::make_shared< ResultCreatePrivateGame_RTA >( 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 )
ResultCreatePrivateGame_RTA::ResultCreatePrivateGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIp = discoveryIp;
m_discoveryPort = discoveryPort;
}
ByteBuffer &ResultCreatePrivateGame2::Serialize()
void ResultCreatePrivateGame_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIp );
m_stream.write( m_discoveryPort );
return m_stream;
out.write_utf8( m_discoveryIp );
out.write( m_discoveryPort );
}

View File

@@ -2,6 +2,7 @@
#include <memory>
#include <string>
#include <array>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
@@ -10,7 +11,9 @@ class RequestCreatePrivateGame_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
std::wstring m_gameName;
std::string m_localAddr;
int32_t m_localPort;
enum CREATE_REPLY {
SUCCESS = 0,
@@ -30,13 +33,13 @@ public:
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCreatePrivateGame2 : public GenericResponse {
class ResultCreatePrivateGame_RTA : 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 );
ByteBuffer &Serialize();
ResultCreatePrivateGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -7,22 +7,22 @@
void RequestCreatePrivateRoom::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_roomName = stream->read_utf16();
}
sptr_generic_response RequestCreatePrivateRoom::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultCreatePrivateRoom >( this );
}
auto sessionId = stream->read_encrypted_utf16();
auto roomName = stream->read_utf16();
auto result = ChatRoomManager::Get().CreatePrivateChatSession( user, roomName );
auto result = ChatRoomManager::Get().CreateGameChatSession( user, m_roomName );
if( !result )
{
@@ -37,11 +37,9 @@ ResultCreatePrivateRoom::ResultCreatePrivateRoom( GenericRequest *request ) : Ge
{
}
ByteBuffer&ResultCreatePrivateRoom::Serialize()
void ResultCreatePrivateRoom::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
}

View File

@@ -8,6 +8,10 @@
class RequestCreatePrivateRoom : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_roomName;
public:
static std::unique_ptr< RequestCreatePrivateRoom > Create()
{
@@ -21,5 +25,5 @@ public:
class ResultCreatePrivateRoom : public GenericResponse {
public:
ResultCreatePrivateRoom( GenericRequest *request );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -19,30 +19,64 @@ void RequestCreatePublicGame::Deserialize( sptr_byte_stream stream )
auto unknown_d = stream->read_u32();
m_gameInfo = stream->read_utf16();
auto [name, stage] = ParseNameAndStage( m_gameInfo );
m_gameName = name;
m_stageName = stage;
}
std::tuple<std::wstring, std::wstring> RequestCreatePublicGame::ParseNameAndStage( const std::wstring &gameInfo )
{
const size_t open = gameInfo.find( L'[' );
const size_t close = gameInfo.find( L']' );
if( open == std::wstring::npos || close == std::wstring::npos || close < open )
return { L"", L"" };
std::wstring name = gameInfo.substr( 0, open );
std::wstring stage = gameInfo.substr( open + 1, close - open - 1 );
if( !name.empty() && iswspace( name.back() ) )
name.pop_back();
return { name, stage };
}
sptr_generic_response RequestCreatePublicGame::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
Log::Packet( stream->get_buffer(), stream->get_length(), false );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultCreatePublicGame >( this, CREATE_REPLY::FATAL_ERROR, "", 0 );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultCreatePublicGame >( this, FATAL_ERROR, "", 0 );
}
auto result = GameSessionManager::Get().CreatePublicGameSession( user, m_gameInfo, user->m_gameType );
if( nullptr != GameSessionManager::Get().FindGame( m_gameName, user->m_gameType ) )
{
Log::Error( "Game name is already in use! [{}]", m_gameName );
return std::make_shared< ResultCreatePublicGame >( this, GAME_NAME_IN_USE, "", 0 );
}
auto result = GameSessionManager::Get().CreateGameSession_CON( user, m_gameInfo, m_gameName, m_stageName, false );
if( !result )
{
Log::Error( "RequestCreatePublicGame::ProcessRequest() - Failed to create public game session!" );
return std::make_shared< ResultCreatePublicGame >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
return std::make_shared< ResultCreatePublicGame >( this, GENERAL_ERROR, "", 0 );
}
Log::Info( "[%S] Create Public Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
Log::Info( "[{}] Create Public Game: {}", m_sessionId, m_gameInfo );
return std::make_shared< ResultCreatePublicGame >(this, CREATE_REPLY::SUCCESS, Config::service_ip, Config::discovery_port);
user->m_isHost = true;
user->m_discoveryAddr = "";
user->m_discoveryPort = 0;
return std::make_shared< ResultCreatePublicGame >( this, SUCCESS, Config::service_ip, Config::discovery_port );
}
// Result
@@ -53,14 +87,12 @@ ResultCreatePublicGame::ResultCreatePublicGame( GenericRequest *request, int32_t
m_discoveryPort = discoveryPort;
}
ByteBuffer &ResultCreatePublicGame::Serialize()
void ResultCreatePublicGame::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIp );
m_stream.write( m_discoveryPort );
return m_stream;
out.write_sz_utf8( m_discoveryIp );
out.write( m_discoveryPort );
}

View File

@@ -11,6 +11,8 @@ class RequestCreatePublicGame : public GenericRequest
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
std::wstring m_gameName;
std::wstring m_stageName;
int32_t m_minimumLevel;
int32_t m_maximumLevel;
@@ -22,6 +24,7 @@ private:
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePublicGame > Create()
{
@@ -29,6 +32,8 @@ public:
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
std::tuple< std::wstring, std::wstring > ParseNameAndStage( const std::wstring &gameInfo );
};
class ResultCreatePublicGame : public GenericResponse {
@@ -39,5 +44,5 @@ private:
public:
ResultCreatePublicGame( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -2,10 +2,10 @@
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../Game/ChatRoomManager.h"
#include "../../configuration.h"
#include "../../logging.h"
// Request
void RequestCreatePublicGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
@@ -22,22 +22,65 @@ void RequestCreatePublicGame_RTA::Deserialize( sptr_byte_stream stream )
auto unknown_e = stream->read_u32();
auto unknown_f = stream->read_u32();
m_localAddr = Util::WideToUTF8(stream->read_utf16());
m_localAddr = Util::WideToUTF8( stream->read_utf16() );
m_localPort = stream->read_u32();
if( !ParseGameInfo() )
{
Log::Error( "Failed to parse game info: {}", m_gameInfo );
}
}
bool RequestCreatePublicGame_RTA::ParseGameInfo()
{
if( m_gameInfo.empty() )
{
Log::Error( "Game info is empty!" );
return false;
}
size_t pipePos = m_gameInfo.find( L'|' );
if( pipePos == std::wstring::npos )
{
Log::Error( "Invalid game info format!" );
return false;
}
std::wstring numbersPart = m_gameInfo.substr( 0, pipePos );
m_gameName = m_gameInfo.substr( pipePos + 1 );
std::wstringstream ss( numbersPart );
std::wstring numStr;
std::array<int8_t, 5> fields = { 0, 0, 0, 0, 0 };
for( size_t i = 0; i < fields.size(); ++i )
{
if( !std::getline( ss, numStr, L',' ) )
return false;
try
{
fields[ i ] = std::stoi( numStr );
}
catch( ... )
{
return false;
}
}
return true;
}
sptr_generic_response RequestCreatePublicGame_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultCreatePublicGame_RTA >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
}
auto result = GameSessionManager::Get().CreatePublicGameSession( user, m_gameInfo, user->m_gameType );
auto result = GameSessionManager::Get().CreateGameSession_RTA( user, m_gameInfo, m_gameName, m_attributes, false );
if( !result )
{
Log::Error( "RequestCreatePublicGame::ProcessRequest() - Failed to create public game session!" );
@@ -45,8 +88,9 @@ sptr_generic_response RequestCreatePublicGame_RTA::ProcessRequest( sptr_socket s
}
user->m_localAddr = m_localAddr;
user->m_localPort = m_localPort;
Log::Info( "[%S] Create Public Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
Log::Info( "[{}] Create Public Game: {}", user->m_username, m_gameInfo );
return std::make_shared< ResultCreatePublicGame_RTA >( this, CREATE_REPLY::SUCCESS, Config::service_ip, Config::discovery_port );
}
@@ -59,14 +103,12 @@ ResultCreatePublicGame_RTA::ResultCreatePublicGame_RTA( GenericRequest *request,
m_discoveryPort = discoveryPort;
}
ByteBuffer &ResultCreatePublicGame_RTA::Serialize()
void ResultCreatePublicGame_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
m_stream.write_utf8( m_discoveryIp );
m_stream.write( m_discoveryPort );
return m_stream;
out.write_utf8( m_discoveryIp );
out.write( m_discoveryPort );
}

View File

@@ -2,6 +2,7 @@
#include <memory>
#include <string>
#include <array>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
@@ -11,8 +12,11 @@ class RequestCreatePublicGame_RTA : public GenericRequest
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
std::wstring m_gameName;
std::string m_localAddr;
int32_t m_localPort;
std::array< int8_t, 5 > m_attributes;
enum CREATE_REPLY {
SUCCESS = 0,
@@ -21,6 +25,7 @@ private:
GAME_NAME_IN_USE = 38,
GAME_PENDING = 40,
};
public:
static std::unique_ptr< RequestCreatePublicGame_RTA > Create()
{
@@ -28,6 +33,7 @@ public:
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
bool ParseGameInfo();
};
class ResultCreatePublicGame_RTA : public GenericResponse {
@@ -38,5 +44,5 @@ private:
public:
ResultCreatePublicGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -3,6 +3,7 @@
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../configuration.h"
#include "../../logging.h"
void RequestDoClientDiscovery::Deserialize( sptr_byte_stream stream )
{
@@ -16,7 +17,9 @@ sptr_generic_response RequestDoClientDiscovery::ProcessRequest( sptr_socket sock
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
Log::Packet( stream->get_buffer(), stream->get_length(), false );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultDoClientDiscovery >( this, DISCOVERY_REPLY::FATAL_ERROR, "", 0 );
@@ -28,7 +31,7 @@ sptr_generic_response RequestDoClientDiscovery::ProcessRequest( sptr_socket sock
return std::make_shared< ResultDoClientDiscovery >( this, DISCOVERY_REPLY::FATAL_ERROR, "", 0 );
}
if( session->m_currentPlayers >= session->m_maximumPlayers )
if( !session->IsJoinable( user ) )
{
return std::make_shared< ResultDoClientDiscovery >( this, DISCOVERY_REPLY::GAME_FULL, "", 0 );
}
@@ -46,14 +49,12 @@ ResultDoClientDiscovery::ResultDoClientDiscovery( GenericRequest *request, int32
m_discoveryPort = port;
}
ByteBuffer &ResultDoClientDiscovery::Serialize()
void ResultDoClientDiscovery::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIP );
m_stream.write( m_discoveryPort );
return m_stream;
out.write_sz_utf8( m_discoveryIP );
out.write( m_discoveryPort );
}

View File

@@ -36,5 +36,5 @@ private:
public:
ResultDoClientDiscovery( GenericRequest *request, int32_t reply, std::string ip = "", int32_t port = 0);
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,61 @@
#include "RequestDoClientDiscovery_RTA.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../configuration.h"
#include "../../logging.h"
void RequestDoClientDiscovery_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameId = stream->read_u32();
m_localAddr = stream->read_utf16();
m_localPort = stream->read_u32();
}
sptr_generic_response RequestDoClientDiscovery_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Packet( stream->get_buffer(), stream->get_length(), false );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultDoClientDiscovery_RTA >( this, TIMEOUT );
}
auto session = GameSessionManager::Get().FindGame( m_gameId, user->m_gameType );
if( session == nullptr )
{
Log::Error( "Game session not found! [{}]", m_gameId );
return std::make_shared< ResultDoClientDiscovery_RTA >( this, NOT_FOUND );
}
user->m_isHost = false;
user->m_gameId = session->m_gameId;
user->m_localAddr = Util::WideToUTF8(m_localAddr);
user->m_localPort = m_localPort;
return std::make_shared< ResultDoClientDiscovery_RTA >( this, SUCCESS, Config::service_ip, Config::discovery_port );
}
ResultDoClientDiscovery_RTA::ResultDoClientDiscovery_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIp = discoveryIp;
m_discoveryPort = discoveryPort;
}
void ResultDoClientDiscovery_RTA::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
out.write_utf8( m_discoveryIp );
out.write_u32( m_discoveryPort );
}

View File

@@ -0,0 +1,41 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestDoClientDiscovery_RTA : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_localAddr;
int32_t m_localPort;
uint32_t m_gameId;
enum REPLY {
SUCCESS = 0,
TIMEOUT,
NOT_FOUND
};
public:
static std::unique_ptr< RequestDoClientDiscovery_RTA > Create()
{
return std::make_unique< RequestDoClientDiscovery_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultDoClientDiscovery_RTA : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
public:
ResultDoClientDiscovery_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0);
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -1,44 +1,85 @@
#include "RequestEnterRoom.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/ChatRoomManager.h"
#include "../../logging.h"
void RequestEnterRoom::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId = stream->read_encrypted_utf16();
m_roomName = stream->read_utf16();
}
sptr_generic_response RequestEnterRoom::ProcessRequest( sptr_socket socket, 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 )
{
}
ByteBuffer& ResultEnterRoom::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
m_stream.write_utf16( L"Room Name" );
m_stream.write_utf16( L"Room Banner" );
m_stream.write_u32( 3 );
const auto user = UserManager::Get().FindUserBySocket( socket );
if( !user )
{
m_stream.write_utf16( L"Name1" );
m_stream.write_utf16( L"Name2" );
m_stream.write_utf16( L"Name3" );
Log::Error( "User not found for socket!" );
return std::make_shared< ResultEnterRoom >( this, GENERAL_ERROR, nullptr );
}
m_stream.write_u32( 1 );
if( !ChatRoomManager::Get().JoinRoom( user, m_roomName ) )
{
m_stream.write_utf16( L"Name1" );
Log::Error( "Failed to join room [{}] for user [{}]", m_roomName, user->m_username );
return std::make_shared< ResultEnterRoom >( this, GENERAL_ERROR, nullptr );
}
return m_stream;
const auto room = ChatRoomManager::Get().FindRoom( m_roomName );
if( !room )
{
Log::Error( "Chat room [{}] not found after joining", m_roomName );
return std::make_shared< ResultEnterRoom >( this, GENERAL_ERROR, nullptr );
}
return std::make_shared< ResultEnterRoom >( this, SUCCESS, room );
}
ResultEnterRoom::ResultEnterRoom( GenericRequest *request, int32_t reply, sptr_chat_room_session room ) : GenericResponse( *request )
{
m_reply = reply;
m_room = room;
}
void ResultEnterRoom::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
if( m_room )
{
out.write_utf16( m_room->m_name );
out.write_utf16( m_room->m_banner );
out.write_u32( static_cast< uint32_t >( m_room->m_members.size() ) );
for( const auto &m : m_room->m_members )
{
if( auto member = m.lock() )
{
out.write_utf16( member->m_chatHandle );
}
else
{
out.write_utf16( L"Unknown" );
}
}
out.write_u32( static_cast< uint32_t >( m_room->m_moderators.size() ) );
for( const auto &m : m_room->m_moderators )
{
if( auto member = m.lock() )
{
out.write_utf16( member->m_chatHandle );
}
else
{
out.write_utf16( L"" );
}
}
}
}

View File

@@ -6,8 +6,18 @@
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
#include "../../Game/ChatRoomSession.h"
class RequestEnterRoom : public GenericRequest
{
private:
std::wstring m_roomName;
enum REPLY {
SUCCESS = 0,
GENERAL_ERROR
};
public:
static std::unique_ptr< RequestEnterRoom > Create()
{
@@ -19,7 +29,11 @@ public:
};
class ResultEnterRoom : public GenericResponse {
private:
int32_t m_reply;
sptr_chat_room_session m_room;
public:
ResultEnterRoom( GenericRequest *request );
ByteBuffer &Serialize();
ResultEnterRoom( GenericRequest *request, int32_t reply, sptr_chat_room_session room );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -5,8 +5,6 @@
#include "../../Database/Database.h"
#include "../../logging.h"
#include "../../Common/RLEZ.hpp"
void RequestGetNetCharacterData_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
@@ -17,12 +15,12 @@ void RequestGetNetCharacterData_RTA::Deserialize( sptr_byte_stream stream )
sptr_generic_response RequestGetNetCharacterData_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize(stream);
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultGetNetCharacterData_RTA >( this, FATAL_ERROR, nullptr );
return std::make_shared< ResultGetNetCharacterData_RTA >( this, FATAL_ERROR );
}
auto result = Database::Get().LoadCharacterData( user->m_accountId, m_characterId );
@@ -30,79 +28,81 @@ sptr_generic_response RequestGetNetCharacterData_RTA::ProcessRequest( sptr_socke
if( !result )
{
Log::Error( "Failed to load character data for account ID: " + std::to_string( user->m_accountId ) + ", character ID: " + std::to_string( m_characterId ) );
return std::make_shared< ResultGetNetCharacterData_RTA >( this, FATAL_ERROR, nullptr );
return std::make_shared< ResultGetNetCharacterData_RTA >( this, FATAL_ERROR );
}
user->m_characterId = m_characterId;
user->m_characterId = result->m_characterId;
user->m_character = result;
auto characterName = result->GetMetaData().GetValue( L"name" );
Log::Debug( "Character data loaded for account ID: %lld, character ID: %d, name: %ls", user->m_accountId, m_characterId, characterName.c_str() );
return std::make_shared< ResultGetNetCharacterData_RTA >( this, SUCCESS, result );
return SendCharacterData( socket, result );
}
ResultGetNetCharacterData_RTA::ResultGetNetCharacterData_RTA( GenericRequest *request, int32_t reply, sptr_realm_character data ) : GenericResponse( *request )
sptr_generic_response RequestGetNetCharacterData_RTA::SendCharacterData( sptr_socket socket, sptr_realm_character character )
{
const auto &data = character->m_data;
const auto data_size = data.size();
size_t position = 0;
sptr_generic_response finalChunk = nullptr;
while( position < data_size )
{
const size_t chunk_size = std::min<size_t>( 1024, data_size - position );
std::vector<uint8_t> chunk_data( data.begin() + position, data.begin() + position + chunk_size );
const int32_t isFinalChunk = ( position + chunk_size >= data_size );
auto response = std::make_shared<ResultGetNetCharacterData_RTA>( this, SUCCESS, std::move( chunk_data ), isFinalChunk );
if( isFinalChunk )
{
finalChunk = response;
}
else
{
socket->send( response );
}
position += chunk_size;
}
return finalChunk;
}
ResultGetNetCharacterData_RTA::ResultGetNetCharacterData_RTA( GenericRequest *request, int32_t reply, std::optional<std::vector<uint8_t>> data, std::optional<int32_t> endOfData ) : GenericResponse( *request )
{
m_reply = reply;
m_data = data;
if( !data.has_value() )
{
m_chunk.clear();
}
else
{
m_chunk = data.value();
}
if( !endOfData.has_value() )
{
m_endOfData = 0;
}
else
{
m_endOfData = endOfData.value();
}
}
ByteBuffer& ResultGetNetCharacterData_RTA::Serialize()
void ResultGetNetCharacterData_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
if( !m_reply )
{
const auto &characterData = m_data->m_characterData;
// Erase first 4 bytes
//characterData.erase(characterData.begin(), characterData.begin() + 4);
//const auto unpacked = RLEZ::Decompress(characterData);
//const auto repacked = RLEZ::Compress(unpacked);
//Log::PacketToFile( "characterData_1", characterData, characterData.size() );
//Log::PacketToFile( "characterData_2", unpacked, unpacked.size() );
//Log::PacketToFile( "characterData_3", repacked, repacked.size() );
m_stream.write_u32( characterData.size());
m_stream.write_bytes( characterData );
for (int i = 0; i < 136; i++)
{
m_stream.write_u8(0xFF);
}
for (int i = 0; i < 5; i++)
{
m_stream.write_u32(0);
m_stream.write_u32(3);
m_stream.write_u32(0);
m_stream.write_u8(0);
}
m_stream.write_u32(0);
m_stream.write_u32(0);
m_stream.write_u32(0);
m_stream.write_u32(0);
m_stream.write_u8(0);
m_stream.write_u8(5);
m_stream.write_u8(3);
m_stream.write_u8(0);
m_stream.write_u8(0);
m_stream.write_u8(3);
m_stream.write_u8(1);
m_stream.write_u32(1); // End Of Stream
out.write_u32( static_cast< uint32_t >( m_chunk.size() ) );
out.write_bytes( m_chunk );
out.write_u32( m_endOfData );
}
//Log::Packet( m_stream.get_buffer(), m_stream.get_length(), false);
return m_stream;
}

View File

@@ -27,14 +27,20 @@ public:
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
sptr_generic_response SendCharacterData(sptr_socket socket, sptr_realm_character data);
};
class ResultGetNetCharacterData_RTA : public GenericResponse {
private:
int32_t m_reply;
sptr_realm_character m_data;
int32_t m_endOfData;
std::vector< uint8_t > m_chunk;
public:
ResultGetNetCharacterData_RTA( GenericRequest *request, int32_t reply, sptr_realm_character data );
ByteBuffer &Serialize();
ResultGetNetCharacterData_RTA( GenericRequest *request, int32_t reply,
std::optional< std::vector< uint8_t > > data = std::nullopt,
std::optional < int32_t > endOfData = std::nullopt );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -20,17 +20,15 @@ ResultGetEncryptionKey::ResultGetEncryptionKey( GenericRequest *request ) : Gene
m_symKey = RealmCrypt::getSymmetricKey();
}
ByteBuffer& ResultGetEncryptionKey::Serialize()
void ResultGetEncryptionKey::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.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;
out.write_u32( encrypted.size() + 4 );
out.write_u32( m_symKey.size() );
out.write_bytes( encrypted );
}

View File

@@ -23,5 +23,5 @@ public:
std::vector< uint8_t > m_symKey;
ResultGetEncryptionKey( GenericRequest *request );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,38 @@
#include "RequestGetFriendList.h"
void RequestGetFriendList::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestGetFriendList::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto publicKey = stream->read_utf8();
auto unknown = stream->read_u32();
return std::make_shared< ResultGetFriendList >( this );
}
ResultGetFriendList::ResultGetFriendList( GenericRequest *request ) : GenericResponse( *request )
{
}
void ResultGetFriendList::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
// Friends
out.write_u32(1);
out.write_utf16(L"String_1");
out.write_u32(1);
out.write_utf16(L"String_2");
// Ignore
out.write_u32(1);
out.write_utf16(L"String_3");
}

View File

@@ -0,0 +1,25 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestGetFriendList : public GenericRequest
{
public:
static std::unique_ptr< RequestGetFriendList > Create()
{
return std::make_unique< RequestGetFriendList >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetFriendList : public GenericResponse {
public:
ResultGetFriendList( GenericRequest *request );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -17,10 +17,10 @@ sptr_generic_response RequestGetGame::ProcessRequest( sptr_socket socket, sptr_b
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultGetGame >( this, TIMEOUT );
}
@@ -28,28 +28,28 @@ sptr_generic_response RequestGetGame::ProcessRequest( sptr_socket socket, sptr_b
if( session == nullptr )
{
Log::Error( "Game session not found! [%S]", m_gameName.c_str() );
Log::Error( "Game session not found! [{}]", m_gameName );
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() );
Log::Error( "Game session is full! [{}]", m_gameName );
return std::make_shared< ResultGetGame >( this, TIMEOUT );
}
auto host_user = session->m_owner.lock();
auto host_user = session->GetOwner();
if( host_user == nullptr )
{
Log::Error( "Game session owner not found! [%S]", m_gameName.c_str() );
Log::Error( "Game session owner not found! [{}]", m_gameName );
return std::make_shared< ResultGetGame >( this, TIMEOUT );
}
user->m_isHost = false;
user->m_gameId = session->m_gameIndex;
user->m_gameId = session->m_gameId;
return std::make_shared< ResultGetGame >( this, SUCCESS, session->m_gameIndex );
return std::make_shared< ResultGetGame >( this, SUCCESS, session->m_gameId );
}
ResultGetGame::ResultGetGame( GenericRequest *request, int32_t reply, int32_t gameId ) : GenericResponse( *request )
@@ -58,17 +58,15 @@ ResultGetGame::ResultGetGame( GenericRequest *request, int32_t reply, int32_t ga
m_gameId = gameId;
}
ByteBuffer &ResultGetGame::Serialize()
void ResultGetGame::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.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" );
out.write_utf16( L"Kelethin" );
out.write_utf16( L"OwnerName" );
m_stream.write_u32( m_gameId );
return m_stream;
out.write_u32( m_gameId );
}

View File

@@ -33,5 +33,5 @@ private:
public:
ResultGetGame( GenericRequest *request, int32_t reply, int32_t gameId = 0 );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -2,7 +2,7 @@
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../configuration.h"
#include "../../Game/RealmUser.h"
#include "../../logging.h"
void RequestGetGame_RTA::Deserialize( sptr_byte_stream stream )
@@ -10,65 +10,71 @@ void RequestGetGame_RTA::Deserialize( sptr_byte_stream stream )
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameId = stream->read_u32();
m_localAddr = Util::WideToUTF8(stream->read_utf16());
m_gameName = stream->read_utf16();
}
sptr_generic_response RequestGetGame_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Log::Packet( stream->get_buffer(), stream->get_length(), false );
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultGetGame_RTA >( this, TIMEOUT );
}
auto session = GameSessionManager::Get().FindGame( m_gameId, user->m_gameType );
auto session = GameSessionManager::Get().FindGame( m_gameName, user->m_gameType );
if( session == nullptr )
{
Log::Error( "Game session not found! [%d]", m_gameId );
Log::Error( "Game session not found! [{}]", m_gameName );
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 );
Log::Error( "Game session is full! [{}]", m_gameName );
return std::make_shared< ResultGetGame_RTA >( this, TIMEOUT );
}
auto host_user = session->m_owner.lock();
auto host_user = session->GetOwner();
if( host_user == nullptr )
{
Log::Error( "Game session owner not found! [%d]", m_gameId );
Log::Error( "Game session owner not found! [{}]", m_gameName );
return std::make_shared< ResultGetGame_RTA >( this, TIMEOUT );
}
user->m_isHost = false;
user->m_gameId = session->m_gameIndex;
user->m_localAddr = m_localAddr;
user->m_gameId = session->m_gameId;
return std::make_shared< ResultGetGame_RTA >( this, SUCCESS, Config::service_ip, Config::discovery_port );
return std::make_shared< ResultGetGame_RTA >( this, SUCCESS, session->m_gameId, host_user->m_discoveryAddr, host_user->m_localAddr, host_user->m_discoveryPort );
}
ResultGetGame_RTA::ResultGetGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp, int32_t discoveryPort ) : GenericResponse( *request )
ResultGetGame_RTA::ResultGetGame_RTA( GenericRequest *request, int32_t reply, int32_t gameId, std::string discoveryAddr, std::string localAddr, int32_t discoveryPort ) : GenericResponse( *request )
{
m_reply = reply;
m_discoveryIp = discoveryIp;
m_discoveryPort = discoveryPort;
m_gameId = gameId;
m_discoveryAddr = Util::UTF8ToWide( discoveryAddr );
m_localAddr = Util::UTF8ToWide( localAddr );
m_port = discoveryPort;
}
ByteBuffer &ResultGetGame_RTA::Serialize()
void ResultGetGame_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
m_stream.write_utf8( m_discoveryIp );
m_stream.write_u32( m_discoveryPort );
out.write_utf16( L"Test" );
out.write_u32( m_gameId );
return m_stream;
out.write_utf16( m_discoveryAddr );
out.write_u32( m_port );
out.write_utf16( m_localAddr );
out.write_u32( m_port );
}

View File

@@ -9,9 +9,7 @@
class RequestGetGame_RTA : public GenericRequest {
private:
std::wstring m_sessionId;
std::string m_localAddr;
uint32_t m_gameId;
std::wstring m_gameName;
enum REPLY {
SUCCESS = 0,
@@ -31,10 +29,13 @@ public:
class ResultGetGame_RTA : public GenericResponse {
private:
int32_t m_reply;
std::string m_discoveryIp;
int32_t m_discoveryPort;
int32_t m_gameId;
std::wstring m_discoveryAddr;
std::wstring m_localAddr;
int32_t m_port;
public:
ResultGetGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0);
ByteBuffer &Serialize();
ResultGetGame_RTA( GenericRequest *request, int32_t reply, int32_t gameId = -1, std::string discoveryAddr = "", std::string localAddr = "", int32_t discoveryPort = 0 );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -1,6 +1,7 @@
#include "RequestGetNetCharacterList_RTA.h"
#include "../../Game/RealmUser.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmCharacterMetaKV.h"
#include "../../Database/Database.h"
#include "../../logging.h"
@@ -14,52 +15,51 @@ sptr_generic_response RequestGetNetCharacterList_RTA::ProcessRequest( sptr_socke
{
Deserialize( stream );
//auto result = Database::Get().LoadCharacterList( user->m_accountId );
auto user = UserManager::Get().FindUserBySocket( socket );
if( !user )
{
return std::make_shared< ResultGetNetCharacterList_RTA >( this, FATAL_ERROR, std::nullopt );
}
auto result = std::map< int32_t, RealmCharacterMetaData >();
auto result = Database::Get().LoadCharacterSlots( user->m_accountId );
return std::make_shared< ResultGetNetCharacterList_RTA >( this, SUCCESS, result );
}
ResultGetNetCharacterList_RTA::ResultGetNetCharacterList_RTA( GenericRequest *request, int32_t reply, std::map< int32_t, RealmCharacterMetaData > list ) : GenericResponse( *request )
ResultGetNetCharacterList_RTA::ResultGetNetCharacterList_RTA( GenericRequest *request, int32_t reply, std::optional< std::map< uint32_t, CharacterSlotData > > list ) : GenericResponse( *request )
{
m_reply = reply;
m_characterList = std::move( list );
if( list != std::nullopt )
{
m_characterList = list.value();
}
}
ByteBuffer &ResultGetNetCharacterList_RTA::Serialize()
void ResultGetNetCharacterList_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
if( 0 == m_reply )
// Character Count
out.write_u32( static_cast< int >( m_characterList.size() ) );
// Character List
for( auto &character : m_characterList )
{
// Character Count
m_stream.write_u32( static_cast< int >( m_characterList.size() ) );
const auto &KV = character.second.GetMetaData();
// Character List
for( auto &character : m_characterList )
// Character ID
out.write_u32( character.first );
// Number of Key-Value pairs
out.write_u32( static_cast< uint32_t >( KV.size() ) );
for( auto &pair : KV )
{
const auto &KV = character.second.GetMetaData();
// Character ID
m_stream.write_u32( character.first );
// Number of Key-Value pairs
m_stream.write_u32( static_cast< uint32_t >( KV.size() ) );
for( auto &pair : KV )
{
m_stream.write_utf16( pair.first );
m_stream.write_utf16( pair.second );
}
out.write_utf16( pair.first );
out.write_utf16( pair.second );
}
}
else
{
m_stream.write_u32( 0 ); // No characters
}
return m_stream;
}

View File

@@ -31,9 +31,9 @@ public:
class ResultGetNetCharacterList_RTA : public GenericResponse {
private:
int32_t m_reply;
std::map< int32_t, RealmCharacterMetaData > m_characterList;
std::map< uint32_t, CharacterSlotData > m_characterList;
public:
ResultGetNetCharacterList_RTA( GenericRequest *request, int32_t reply, std::map< int32_t, RealmCharacterMetaData > list );
ByteBuffer &Serialize();
ResultGetNetCharacterList_RTA( GenericRequest *request, int32_t reply, std::optional< std::map< uint32_t, CharacterSlotData > > list );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -1,5 +1,7 @@
#include "RequestGetPublicRooms.h"
#include "../../Game/ChatRoomManager.h"
void RequestGetPublicRooms::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
@@ -9,39 +11,45 @@ sptr_generic_response RequestGetPublicRooms::ProcessRequest( sptr_socket socket,
{
Deserialize( stream );
auto publicKey = stream->read_utf8();
const auto publicRooms = ChatRoomManager::Get().GetPublicRoomList();
return std::make_shared< ResultGetPublicRooms >( this );
return std::make_shared< ResultGetPublicRooms >( this, publicRooms );
}
ResultGetPublicRooms::ResultGetPublicRooms( GenericRequest *request ) : GenericResponse( *request )
ResultGetPublicRooms::ResultGetPublicRooms( GenericRequest *request, std::vector< sptr_chat_room_session > rooms ) : GenericResponse( *request )
{
m_rooms = std::move( rooms );
}
ByteBuffer& ResultGetPublicRooms::Serialize()
void ResultGetPublicRooms::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
m_stream.write_u32( 0);
for( int i = 0; i < 0; i++ )
const auto numRoom = static_cast< uint32_t >( m_rooms.size() );
out.write_u32( numRoom );
for( const auto &room : m_rooms )
{
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" );
}
out.write_utf16( room->m_name );
}
return m_stream;
out.write_u32( numRoom );
for( const auto &room : m_rooms )
{
out.write_utf16( L"UNKNOWN" );
}
out.write_u32( numRoom );
for( const auto &room : m_rooms )
{
out.write_u32( 88 );
}
out.write_u32( numRoom );
for( const auto &room : m_rooms )
{
out.write_u32( 99 );
}
}

View File

@@ -6,6 +6,8 @@
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
#include "../../Game/ChatRoomSession.h"
class RequestGetPublicRooms : public GenericRequest
{
public:
@@ -19,7 +21,10 @@ public:
};
class ResultGetPublicRooms : public GenericResponse {
private:
std::vector< sptr_chat_room_session > m_rooms;
public:
ResultGetPublicRooms( GenericRequest *request );
ByteBuffer &Serialize();
ResultGetPublicRooms( GenericRequest *request, std::vector< sptr_chat_room_session > rooms );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -19,22 +19,21 @@ ResultGetRealmStats::ResultGetRealmStats( GenericRequest *request ) : GenericRes
}
ByteBuffer &ResultGetRealmStats::Serialize()
void ResultGetRealmStats::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
// Player count on the game page.
m_stream.write_u32( RealmUserManager::Get().GetUserCount() ); // Users Logged In Game
out.write_u32( UserManager::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;
out.write_u32( 0 ); // Users Logged In Realm
out.write_u32( 0 ); // Users Running Game
out.write_u32( 0 ); // Users Running Realm
out.write_u32( 0 ); // Users Playing Game
out.write_u32( 0 ); // Users Playing Realm
out.write_u32( 0 ); // unmatchedGamesGame
out.write_u32( 0 ); // unmatchedGamesRealm
}

View File

@@ -20,5 +20,5 @@ public:
class ResultGetRealmStats : public GenericResponse {
public:
ResultGetRealmStats( GenericRequest *request );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -1,43 +1,88 @@
#include "RequestGetRoom.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/ChatRoomManager.h"
#include "../../logging.h"
void RequestGetRoom::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId = stream->read_encrypted_utf16();
m_sessionId = stream->read_encrypted_utf16();
m_roomName = stream->read_utf16();
}
sptr_generic_response RequestGetRoom::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultGetRoom >( this );
}
Log::Packet( stream->get_buffer(), stream->get_length(), false );
ResultGetRoom::ResultGetRoom( GenericRequest *request ) : GenericResponse( *request )
{
}
ByteBuffer &ResultGetRoom::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
m_stream.write_utf16( L"Room Name" );
m_stream.write_utf16( L"Room Banner" );
m_stream.write_u32( 3 );
const auto user = UserManager::Get().FindUserBySocket( socket );
if( !user )
{
m_stream.write_utf16( L"Name1" );
m_stream.write_utf16( L"Name2" );
m_stream.write_utf16( L"Name3" );
return std::make_shared< ResultGetRoom >( this, GENERAL_ERROR );
}
m_stream.write_u32( 1 );
sptr_chat_room_session targetRoom = nullptr;
if( m_roomName.empty() )
{
m_stream.write_utf16( L"Name1" );
targetRoom = ChatRoomManager::Get().FindRoom( user->m_privateRoomId );
}
else
{
targetRoom = ChatRoomManager::Get().FindRoom( user->m_publicRoomId );
}
return m_stream;
return std::make_shared< ResultGetRoom >( this, SUCCESS, targetRoom );
}
ResultGetRoom::ResultGetRoom( GenericRequest *request, int32_t reply, sptr_chat_room_session room ) : GenericResponse( *request )
{
m_reply = reply;
m_room = room;
}
void ResultGetRoom::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
if( m_room )
{
out.write_utf16( m_room->m_name );
out.write_utf16( m_room->m_banner );
out.write_u32( static_cast< uint32_t >( m_room->m_members.size() ) );
for( const auto &m : m_room->m_members )
{
const auto &member = m.lock();
if( member )
{
out.write_utf16( member->m_chatHandle );
}
else
{
out.write_utf16( L"" );
}
}
out.write_u32( static_cast< uint32_t >( m_room->m_moderators.size() ) );
for( const auto &m : m_room->m_moderators )
{
if( auto member = m.lock() )
{
out.write_utf16( member->m_chatHandle );
}
else
{
out.write_utf16( L"" );
}
}
}
}

View File

@@ -6,7 +6,18 @@
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
#include "../../Game/ChatRoomSession.h"
class RequestGetRoom : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_roomName;
enum CREATE_ACCOUNT_REPLY {
SUCCESS = 0,
GENERAL_ERROR = 1,
};
public:
static std::unique_ptr< RequestGetRoom > Create()
{
@@ -18,7 +29,11 @@ public:
};
class ResultGetRoom : public GenericResponse {
private:
int32_t m_reply;
sptr_chat_room_session m_room;
public:
ResultGetRoom( GenericRequest *request );
ByteBuffer &Serialize();
ResultGetRoom( GenericRequest *request, int32_t reply, sptr_chat_room_session room = nullptr );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -16,7 +16,7 @@ sptr_generic_response RequestGetRules::ProcessRequest( sptr_socket socket, sptr_
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultGetRules >( this, L"" );
@@ -25,24 +25,24 @@ sptr_generic_response RequestGetRules::ProcessRequest( sptr_socket socket, sptr_
// TODO: Get rules/eula based on language
// and move it info a MOTD file.
std::wstring rules;
if (user->m_gameType == RealmGameType::RETURN_TO_ARMS)
if( user->m_gameType == RealmGameType::RETURN_TO_ARMS )
{
rules = L"Welcome to the Norrath Emulated Server!\n\n"
rules = L"Welcome to the Champions Emulated Server!\n\n"
L"RETURN TO ARMS network support is currently a\n"
L"work in progress and can not guarantee stability.\n\n"
L"[IMPORTANT]:\n"
L"Please note that ONLINE character data will not be saved.\n"
L"You must import an offline save file for now.\n";
L"Please note that ONLINE character saves may be unstable.\n"
L"Use them at your own risk.\n";
}
else
{
rules = L"Welcome to the Norrath Emulated Server!\n\n"
rules = L"Welcome to the Champions 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 );
return std::make_shared< ResultGetRules >( this, rules );
}
ResultGetRules::ResultGetRules( GenericRequest *request, std::wstring rules ) : GenericResponse( *request )
@@ -50,13 +50,13 @@ ResultGetRules::ResultGetRules( GenericRequest *request, std::wstring rules ) :
m_rules = rules;
}
ByteBuffer &ResultGetRules::Serialize()
void ResultGetRules::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
out.write_utf16( m_rules );
m_stream.write_utf16( m_rules );
return m_stream;
}

View File

@@ -27,5 +27,5 @@ private:
public:
ResultGetRules( GenericRequest *request, std::wstring rules );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -32,18 +32,16 @@ ResultGetServerAddress::ResultGetServerAddress( GenericRequest *request, std::st
m_gameType = gameType;
}
ByteBuffer &ResultGetServerAddress::Serialize()
void ResultGetServerAddress::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
if( m_gameType == RealmGameType::RETURN_TO_ARMS )
m_stream.write_utf8( m_ip );
out.write_utf8( m_ip );
else
m_stream.write_sz_utf8( m_ip );
out.write_sz_utf8( m_ip );
m_stream.write( m_port );
return m_stream;
out.write( m_port );
}

View File

@@ -25,5 +25,5 @@ public:
RealmGameType m_gameType;
ResultGetServerAddress( GenericRequest *request, std::string ip, int32_t port, RealmGameType clientType );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,45 @@
#include "RequestLeaveRoom.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/ChatRoomManager.h"
#include "../../logging.h"
void RequestLeaveRoom::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId = stream->read_encrypted_utf16();
m_roomName = stream->read_utf16();
}
sptr_generic_response RequestLeaveRoom::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
const auto user = UserManager::Get().FindUserBySocket( socket );
if( !user )
{
Log::Error( "User not found for socket!" );
return std::make_shared< ResultLeaveRoom >( this, GENERAL_ERROR );
}
if( !ChatRoomManager::Get().LeaveRoom( user, m_roomName ) )
{
Log::Error( "Could not remove user [{}] from room [{}]", user->m_username, m_roomName );
return std::make_shared< ResultLeaveRoom >( this, GENERAL_ERROR );
}
return std::make_shared< ResultLeaveRoom >( this, SUCCESS );
}
ResultLeaveRoom::ResultLeaveRoom( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
{
m_reply = reply;
}
void ResultLeaveRoom::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
}

View File

@@ -0,0 +1,36 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestLeaveRoom : public GenericRequest
{
private:
std::wstring m_roomName;
enum REPLY {
SUCCESS = 0,
GENERAL_ERROR
};
public:
static std::unique_ptr< RequestLeaveRoom > Create()
{
return std::make_unique< RequestLeaveRoom >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultLeaveRoom : public GenericResponse {
private:
int32_t m_reply;
public:
ResultLeaveRoom( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -10,58 +10,77 @@ void RequestLogin::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_username = Util::WideToUTF8( stream->read_encrypted_utf16() );
m_password = Util::WideToUTF8( stream->read_encrypted_utf16() );
m_username = stream->read_encrypted_utf16();
m_password = stream->read_encrypted_utf16();
}
sptr_generic_response RequestLogin::ProcessLoginCON(sptr_user user)
sptr_generic_response RequestLogin::ProcessLoginCON( sptr_user user )
{
if (m_username != "foo" && m_password != "bar")
if( m_username != L"foo" && m_password != L"bar" )
{
// Network Beta CoN uses login information, but it's invalid because of version 2.0
// which used "foo" and "bar" as the login credentials.
Log::Debug("RequestLogin : Champions of Norrath v1.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::ACCOUNT_INVALID, L"");
return std::make_shared< ResultLogin >( this, LOGIN_REPLY::ACCOUNT_INVALID, L"" );
}
user->m_isLoggedIn = true;
user->m_accountId = -1;
user->m_sessionId = RealmUserManager::Get().GenerateSessionId();
user->m_sessionId = UserManager::Get().GenerateSessionId();
return std::make_shared< ResultLogin >(this, SUCCESS, user->m_sessionId);
return std::make_shared< ResultLogin >( this, SUCCESS, user->m_sessionId );
}
sptr_generic_response RequestLogin::ProcessLoginRTA(sptr_user user)
sptr_generic_response RequestLogin::ProcessLoginRTA( sptr_user user )
{
// Return to Arms uses login information.
Log::Debug("RequestLogin : Return to Arms");
Log::Debug( "RequestLogin : Return to Arms" );
auto &UserManager = UserManager::Get();
auto &Database = Database::Get();
// Verify the account exists
auto accountId = Database::Get().VerifyAccount(m_username, m_password);
auto accountId = Database.VerifyAccount( m_username, m_password );
if (accountId < 0)
if( accountId < 0 )
{
Log::Error("RequestLogin::ProcessRequest() - Invalid account ID: " + std::to_string(accountId));
return std::make_shared< ResultLogin >(this, ACCOUNT_INVALID, L"");
Log::Error( "RequestLogin::ProcessRequest() - Invalid account ID: " + std::to_string( accountId ) );
return std::make_shared< ResultLogin >( this, ACCOUNT_INVALID, L"" );
}
user->m_accountId = accountId;
user->m_sessionId = RealmUserManager::Get().GenerateSessionId();
// Check if the user is already logged in
for( const auto &existingUser : UserManager.GetUserList() )
{
if( existingUser->m_username == m_username || existingUser->m_accountId == accountId )
{
return std::make_shared< ResultLogin >( this, FATAL_ERROR, L"" );
}
}
Database::Get().CreateSession(
auto [result, chatHandle] = Database.LoadAccount( accountId );
// Login Success
user->m_isLoggedIn = true;
user->m_username = m_username;
user->m_accountId = accountId;
user->m_chatHandle = chatHandle;
user->m_sessionId = UserManager.GenerateSessionId();
Database.CreateSession(
user->m_accountId,
user->m_sessionId,
user->sock->remote_ip);
user->sock->remote_ip );
return std::make_shared< ResultLogin >(this, SUCCESS, user->m_sessionId);
return std::make_shared< ResultLogin >( this, SUCCESS, user->m_sessionId );
}
sptr_generic_response RequestLogin::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "RequestLogin::ProcessRequest() - User not found" );
@@ -90,14 +109,12 @@ ResultLogin::ResultLogin( GenericRequest *request, int32_t reply, std::wstring s
m_sessionId = sessionId;
}
ByteBuffer &ResultLogin::Serialize()
void ResultLogin::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
m_stream.write_encrypted_utf16( m_sessionId );
m_stream.write_encrypted_utf16( L"UNKNOWN DUMMY STRING" );
return m_stream;
out.write_encrypted_utf16( m_sessionId );
out.write_encrypted_utf16( L"UNKNOWN DUMMY STRING" );
}

View File

@@ -15,8 +15,8 @@ private:
ACCOUNT_INVALID = 4,
};
std::string m_username;
std::string m_password;
std::wstring m_username;
std::wstring m_password;
std::wstring m_sessionId;
public:
@@ -39,5 +39,5 @@ private:
public:
ResultLogin( GenericRequest *request, int32_t reply, std::wstring sessionId );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -13,9 +13,9 @@ sptr_generic_response RequestLogout::ProcessRequest( sptr_socket socket, sptr_by
{
Deserialize( stream );
RealmUserManager::Get().RemoveUser( socket );
UserManager::Get().RemoveUser( socket );
Log::Debug( "[%S] Logout", m_sessionId.c_str() );
Log::Debug( "[{}] Logout", m_sessionId );
return std::make_shared< ResultLogout >( this, 0 );
}
@@ -25,11 +25,9 @@ ResultLogout::ResultLogout( GenericRequest *request, int32_t reply ) : GenericRe
m_reply = reply;
}
ByteBuffer &ResultLogout::Serialize()
void ResultLogout::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
}

View File

@@ -25,5 +25,5 @@ private:
int32_t m_reply;
public:
ResultLogout( GenericRequest *request, int32_t reply );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -51,49 +51,47 @@ ResultMatchGame::ResultMatchGame( GenericRequest *request, std::string userIp )
m_userIp = userIp;
}
ByteBuffer &ResultMatchGame::Serialize()
void ResultMatchGame::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
const auto publicGameList = GameSessionManager::Get().GetAvailableGameSessionList( RealmGameType::CHAMPIONS_OF_NORRATH );
const auto publicGameCount = static_cast< uint32_t >( publicGameList.size() );
m_stream.write_u32( publicGameCount );
out.write_u32( publicGameCount );
{
for( const auto &game : publicGameList )
{
if( m_userIp == game->m_hostExternalAddr )
m_stream.write_utf16( std::format( L"{}:{}", Util::UTF8ToWide( game->m_hostLocalAddr ), game->m_hostPort ) );
out.write_utf16( std::format( L"{}:{}", Util::UTF8ToWide( game->m_hostLocalAddr ), game->m_hostNatPort ) );
else
m_stream.write_utf16( std::format( L"{}:{}", Util::UTF8ToWide( game->m_hostExternalAddr ), game->m_hostPort ) );
out.write_utf16( std::format( L"{}:{}", Util::UTF8ToWide( game->m_hostExternalAddr ), game->m_hostNatPort ) );
}
}
m_stream.write_u32( publicGameCount );
out.write_u32( publicGameCount );
{
for( const auto &game : publicGameList )
m_stream.write_utf16( game->m_gameName );
out.write_utf16( game->m_gameName );
}
m_stream.write_u32( publicGameCount );
out.write_u32( publicGameCount );
{
for( const auto &game : publicGameList )
m_stream.write_utf16( game->m_ownerName );
out.write_utf16( game->m_ownerName );
}
m_stream.write_u32( publicGameCount );
out.write_u32( publicGameCount );
{
for( const auto &game : publicGameList )
m_stream.write_u32( game->m_gameIndex );
out.write_u32( game->m_gameId );
}
m_stream.write_u32( publicGameCount );
out.write_u32( publicGameCount );
{
for( const auto &game : publicGameList )
m_stream.write_utf8( game->m_gameData );
out.write_utf8( game->m_gameData );
}
return m_stream;
}

View File

@@ -24,5 +24,5 @@ private:
public:
ResultMatchGame( GenericRequest *request, std::string userIp );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -13,9 +13,16 @@ sptr_generic_response RequestMatchGame_RTA::ProcessRequest( sptr_socket socket,
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
UserManager::Get().Disconnect( socket, "User not found!" );
return std::make_shared< ResultMatchGame_RTA >( this, "" );
}
if( !user->m_isLoggedIn )
{
UserManager::Get().Disconnect( user, "User is not logged in!" );
return std::make_shared< ResultMatchGame_RTA >( this, "" );
}
@@ -27,72 +34,60 @@ ResultMatchGame_RTA::ResultMatchGame_RTA( GenericRequest *request, std::string u
m_userIp = userIp;
}
ByteBuffer&ResultMatchGame_RTA::Serialize()
void ResultMatchGame_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
const auto publicGameList = GameSessionManager::Get().GetAvailableGameSessionList( RealmGameType::RETURN_TO_ARMS );
const auto publicGameCount = static_cast< uint32_t >( publicGameList.size() );
m_stream.write_u32( publicGameCount );
out.write_u32( publicGameCount );
{
for( const auto &game : publicGameList )
m_stream.write_utf16( game->m_gameName );
out.write_utf16( Util::UTF8ToWide( game->m_gameData ) );
}
m_stream.write_u32( publicGameCount );
out.write_u32( publicGameCount );
{
for( const auto &game : publicGameList )
m_stream.write_utf16( game->m_playerCount );
out.write_utf16( game->m_playerCount );
}
m_stream.write_u32( publicGameCount );
out.write_u32( publicGameCount );
{
for( const auto &game : publicGameList )
m_stream.write_u32( game->m_gameIndex );
out.write_u32( game->m_gameId );
}
m_stream.write_u32( publicGameCount );
// Something about filtering.
out.write_u32( publicGameCount );
{
m_stream.write_u32( 0 ); // Size
// Blob Data
out.write_u32( 0 ); // Size
}
m_stream.write_u32( publicGameCount );
out.write_u32(publicGameCount);
{
for( const auto &game : publicGameList )
{
if( m_userIp == game->m_hostExternalAddr )
m_stream.write_utf16( Util::UTF8ToWide( game->m_hostLocalAddr ) );
else
m_stream.write_utf16( Util::UTF8ToWide( game->m_hostExternalAddr ) );
}
for (const auto& game : publicGameList)
out.write_utf16(Util::UTF8ToWide(game->m_hostExternalAddr));
}
m_stream.write_u32( publicGameCount );
out.write_u32(publicGameCount);
{
for( const auto &game : publicGameList )
m_stream.write_u32( game->m_hostPort );
for (const auto& game : publicGameList)
out.write_u32(game->m_hostNatPort);
}
m_stream.write_u32( publicGameCount );
out.write_u32(publicGameCount);
{
for( const auto &game : publicGameList )
{
if( m_userIp == game->m_hostExternalAddr )
m_stream.write_utf16( Util::UTF8ToWide( game->m_hostLocalAddr ) );
else
m_stream.write_utf16( Util::UTF8ToWide( game->m_hostExternalAddr ) );
}
for (const auto& game : publicGameList)
out.write_utf16(Util::UTF8ToWide(game->m_hostLocalAddr));
}
m_stream.write_u32( publicGameCount );
out.write_u32(publicGameCount);
{
for( const auto &game : publicGameList )
m_stream.write_u32( game->m_hostPort );
for (const auto& game : publicGameList)
out.write_u32(game->m_hostLocalPort);
}
return m_stream;
}

View File

@@ -24,5 +24,5 @@ private:
public:
ResultMatchGame_RTA( GenericRequest *request, std::string userIp );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -1,6 +1,8 @@
#include "RequestSaveCharacter_RTA.h"
#include "../../Database/Database.h"
#include "../../Game/GameSessionManager.h"
#include "../../Game/CharacterSaveManager.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Game/RealmCharacter.h"
@@ -12,53 +14,59 @@ void RequestSaveCharacter_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId_A = stream->read_encrypted_utf16();
m_sessionId_B = stream->read_encrypted_utf16();
m_characterId = stream->read_u32();
m_sessionId = stream->read_encrypted_utf16();
m_memberSessionId = stream->read_encrypted_utf16();
m_targetCharacterId = stream->read_u32();
auto a = stream->read_u32();
auto b = stream->read_u32();
m_characterData = std::make_shared< RealmCharacter >( stream );
m_metaData.Deserialize( stream );
auto characterDataSize = stream->read_u32();
m_characterData = stream->read_bytes( characterDataSize );
}
sptr_generic_response RequestSaveCharacter_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
auto &userManager = UserManager::Get();
auto user = userManager.FindUserBySocket( socket );
if( user == nullptr || user->m_accountId == -1 )
{
Log::Error( "User not found! [%S]", m_sessionId_A.c_str() );
// Try to recover the user through session records.
user = UserManager::Get().RecoverUserBySession( m_sessionId, socket );
if( user == nullptr )
{
Log::Error( "Failed to recover user by session ID: {}", m_sessionId );
return std::make_shared< ResultSaveCharacter_RTA >( this, FATAL_ERROR );
}
Log::Debug( "Recovered user by session ID: {}", m_sessionId );
}
sptr_user targetUser = user;
if( m_sessionId != m_memberSessionId )
{
targetUser = userManager.FindUserBySessionId( m_memberSessionId );
}
if( targetUser == nullptr || targetUser->m_accountId == -1 )
{
Log::Error( "Target user not found or invalid account ID for session: {}", m_memberSessionId );
return std::make_shared< ResultSaveCharacter_RTA >( this, FATAL_ERROR );
}
//auto unpacked = RLEZ::Decompress( m_characterData->GetCharacterData() );
auto characterId = targetUser->m_characterId;
//Log::PacketToFile( "save_character_comp", stream->get_buffer(), stream->get_length());
//Log::PacketToFile( "save_character_decomp", unpacked, unpacked.size());
Log::Packet(stream->get_buffer(), stream->get_length(), false);
Log::Debug( "Processing RequestSaveCharacter_RTA for user: " + std::to_string( user->m_accountId ) );
Log::Debug( "Session ID A: " + Util::WideToUTF8( m_sessionId_A ) );
Log::Debug( "Session ID B: " + Util::WideToUTF8( m_sessionId_B ) );
Log::Debug( "Character ID: " + std::to_string( m_characterId ) );
//if( m_characterId != user->m_characterId )
//{
// Log::Error( "Character ID mismatch for user: " + Util::WideToUTF8( user->m_sessionId ) + ". Expected: " + std::to_string(user->m_characterId) + ", Received: " + std::to_string(m_characterId));
// return std::make_shared< ResultSaveCharacter_RTA >( this, GENERAL_ERROR );
//}
auto result = Database::Get().SaveCharacter( user->m_accountId, user->m_characterId, m_characterData->GetMetaData().Serialize(), m_characterData->GetCharacterData() );
if( false == result )
auto &saveManager = CharacterSaveManager::Get();
if( saveManager.BeginSaveTask( user, targetUser, characterId, m_metaData, CharacterSaveType::SAVE_CHARACTER ) )
{
return std::make_shared< ResultSaveCharacter_RTA >( this, FATAL_ERROR );
saveManager.AppendSaveData( user->m_sessionId, m_characterData, false );
}
user->m_character = std::move(m_characterData);
return std::make_shared< ResultSaveCharacter_RTA >( this, SUCCESS );
}
@@ -68,11 +76,9 @@ ResultSaveCharacter_RTA::ResultSaveCharacter_RTA( GenericRequest *request, int32
m_reply = reply;
}
ByteBuffer& ResultSaveCharacter_RTA::Serialize()
void ResultSaveCharacter_RTA::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
}

View File

@@ -8,18 +8,19 @@
class RequestSaveCharacter_RTA : public GenericRequest
{
private:
std::wstring m_sessionId_A;
std::wstring m_sessionId_B;
std::vector< uint8_t > m_data;
uint32_t m_characterId;
sptr_realm_character m_characterData;
std::wstring m_sessionId;
std::wstring m_memberSessionId;
uint32_t m_targetCharacterId;
CharacterSlotData m_metaData;
std::vector< uint8_t > m_characterData;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestSaveCharacter_RTA > Create()
{
@@ -36,5 +37,5 @@ private:
public:
ResultSaveCharacter_RTA( GenericRequest *request, int32_t reply );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,69 @@
#include "RequestSendRoomMessage.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/ChatRoomManager.h"
#include "NotifyRoomMessage.h"
#include "../../logging.h"
void RequestSendRoomMessage::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId = stream->read_encrypted_utf16();
m_roomName = stream->read_utf16();
m_message = stream->read_utf16();
}
sptr_generic_response RequestSendRoomMessage::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Packet( stream->get_buffer(), stream->get_length(), false );
const auto user = UserManager::Get().FindUserBySocket( socket );
if( !user )
{
Log::Error( "User not found for socket!" );
return std::make_shared< ResultSendRoomMessage >( this, GENERAL_ERROR );
}
const auto room = ChatRoomManager::Get().FindRoom( m_roomName );
if( !room )
{
Log::Error( "Chat room not found: {}", m_roomName );
return std::make_shared< ResultSendRoomMessage >( this, GENERAL_ERROR );
}
if( !room->IsMember( user ) )
{
Log::Error( "User [{}] is not a member of chat room [{}]", user->m_chatHandle, m_roomName );
return std::make_shared< ResultSendRoomMessage >( this, GENERAL_ERROR );
}
NotifyRoomMessage msg( m_roomName, user->m_chatHandle, m_message );
for( const auto &member : room->m_members )
{
auto memberUser = member.lock();
if( !memberUser )
continue;
memberUser->sock->send( msg );
}
return std::make_shared< ResultSendRoomMessage >( this, SUCCESS );
}
ResultSendRoomMessage::ResultSendRoomMessage( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
{
m_reply = reply;
}
void ResultSendRoomMessage::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestSendRoomMessage : public GenericRequest
{
private:
std::wstring m_roomName;
std::wstring m_message;
enum REPLY {
SUCCESS = 0,
GENERAL_ERROR
};
public:
static std::unique_ptr< RequestSendRoomMessage > Create()
{
return std::make_unique< RequestSendRoomMessage >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultSendRoomMessage : public GenericResponse {
private:
int32_t m_reply;
public:
ResultSendRoomMessage( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -2,6 +2,7 @@
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../Game/ChatRoomManager.h"
#include "../../Game/RealmUser.h"
#include "../../logging.h"
@@ -16,7 +17,7 @@ sptr_generic_response RequestStartGame::ProcessRequest( sptr_socket socket, sptr
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultStartGame >( this, FATAL_ERROR );
@@ -29,7 +30,16 @@ sptr_generic_response RequestStartGame::ProcessRequest( sptr_socket socket, sptr
return std::make_shared< ResultStartGame >( this, FATAL_ERROR );
}
GameSessionManager::Get().RequestStart(user);
if( !GameSessionManager::Get().RequestStart( user ) )
{
Log::Error( "Failed to start game session [{}]", user->m_gameId );
return std::make_shared< ResultStartGame >( this, FATAL_ERROR );
}
if( !ChatRoomManager::Get().CloseGameChatSession( session->m_gameName ) )
{
Log::Error( "Failed to close chat room for game session [{}]", session->m_gameName );
}
return std::make_shared< ResultStartGame >( this, SUCCESS );
}
@@ -39,11 +49,9 @@ ResultStartGame::ResultStartGame( GenericRequest *request, int32_t reply ) : Gen
m_reply = reply;
}
ByteBuffer& ResultStartGame::Serialize()
void ResultStartGame::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
}

View File

@@ -32,5 +32,5 @@ private:
public:
ResultStartGame( GenericRequest *request, int32_t reply );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -14,11 +14,11 @@ sptr_generic_response RequestTouchSession::ProcessRequest( sptr_socket socket, s
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultTouchSession >( this );
}
@@ -30,11 +30,9 @@ ResultTouchSession::ResultTouchSession( GenericRequest *request ) : GenericRespo
}
ByteBuffer &ResultTouchSession::Serialize()
void ResultTouchSession::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
}

View File

@@ -23,5 +23,5 @@ public:
class ResultTouchSession : public GenericResponse {
public:
ResultTouchSession( GenericRequest *request );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -13,54 +13,58 @@ void RequestUpdateGameData::Deserialize( sptr_byte_stream stream )
m_gameData = stream->read_utf8();
}
sptr_generic_response RequestUpdateGameData::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
bool RequestUpdateGameData::ParseGameData( sptr_game_session session )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
if( session == nullptr || m_gameData.size() < 256 )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultUpdateGameData >( this );
Log::Error( "Invalid game session or game data size! [{}]", m_sessionId );
return false;
}
auto gameSession = GameSessionManager::Get().FindGame( user->m_gameId, user->m_gameType );
session->m_gameData = m_gameData;
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;
int8_t currentPlayers = 0;
int8_t 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
session->m_currentPlayers = currentPlayers;
session->m_maximumPlayers = maxPlayers;
session->m_description = ( result == 3 ) ? description : "";
}
else
{
Log::Debug( "Failed to parse game info from: %s", m_gameData.c_str() );
Log::Debug( "Failed to parse game info from: {}", m_gameData );
}
std::string ip = std::string( m_gameData.c_str() + 220, 24 );
user->m_localAddr = ip;
return true;
}
sptr_generic_response RequestUpdateGameData::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [{}]", m_sessionId );
return std::make_shared< ResultUpdateGameData >( this );
}
auto gameSession = GameSessionManager::Get().FindGame( user->m_gameId, user->m_gameType );
if( !ParseGameData( gameSession ) )
{
Log::Error( "Failed to parse game data! [{}]", m_sessionId );
return std::make_shared< ResultUpdateGameData >( this );
}
const auto localAddr = std::string( m_gameData.c_str() + 220, 24 );
user->m_localAddr = localAddr;
return std::make_shared< ResultUpdateGameData >( this );
}
@@ -70,11 +74,9 @@ ResultUpdateGameData::ResultUpdateGameData( GenericRequest *request ) : GenericR
}
ByteBuffer &ResultUpdateGameData::Serialize()
void ResultUpdateGameData::Serialize( ByteBuffer &out ) const
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
return m_stream;
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( 0 );
}

View File

@@ -6,6 +6,8 @@
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
#include "../../Game/GameSession.h"
class RequestUpdateGameData : public GenericRequest
{
private:
@@ -19,10 +21,11 @@ public:
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
bool ParseGameData( sptr_game_session session );
};
class ResultUpdateGameData : public GenericResponse {
public:
ResultUpdateGameData( GenericRequest *request );
ByteBuffer &Serialize();
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -0,0 +1,61 @@
#include "RequestUserJoinSuccess.h"
#include "../../Game/GameSessionManager.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Database/Database.h"
#include "../../logging.h"
void RequestUserJoinSuccess::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_ownerSessionId = stream->read_encrypted_utf16();
}
sptr_generic_response RequestUserJoinSuccess::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Packet( stream->get_buffer(), stream->get_length(), false );
auto user = UserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultUserJoinSuccess >( this, FATAL_ERROR );
}
auto gameSession = GameSessionManager::Get().FindGame( user->m_gameId, user->m_gameType );
if( gameSession == nullptr )
{
Log::Error( "Game session not found for user: {}", user->m_username );
return std::make_shared< ResultUserJoinSuccess >( this, FATAL_ERROR );
}
if( !gameSession->IsJoinable() )
{
Log::Error( "Game session is not open for user: {}", user->m_username );
return std::make_shared< ResultUserJoinSuccess >( this, FATAL_ERROR );
}
if( !gameSession->AddMember( user ) )
{
Log::Error( "Failed to add user {} to game session {}", user->m_username, gameSession->m_gameId );
return std::make_shared< ResultUserJoinSuccess >( this, FATAL_ERROR );
}
return std::make_shared< ResultUserJoinSuccess >( this, SUCCESS );
}
ResultUserJoinSuccess::ResultUserJoinSuccess( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
{
m_reply = reply;
}
void ResultUserJoinSuccess::Serialize( ByteBuffer &out ) const
{
out.write_u16( m_packetId );
out.write_u32( m_trackId );
out.write_u32( m_reply );
}

View File

@@ -0,0 +1,37 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestUserJoinSuccess : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_ownerSessionId;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestUserJoinSuccess > Create()
{
return std::make_unique< RequestUserJoinSuccess >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultUserJoinSuccess : public GenericResponse {
private:
int32_t m_reply;
public:
ResultUserJoinSuccess( GenericRequest *request, int32_t reply );
void Serialize( ByteBuffer &out ) const;
};

View File

@@ -1,67 +0,0 @@
#include "Request_5D.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Database/Database.h"
#include "../../logging.h"
#include "../../Common/RLEZ.hpp"
void Request_5D::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId = stream->read_encrypted_utf16();
auto length = stream->read_u32();
m_data = stream->read_bytes( length );
auto unknown = stream->read_u32();
}
sptr_generic_response Request_5D::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< Result_5D >( this, FATAL_ERROR );
}
//auto unpacked = RLEZ::Decompress( m_data );
//Log::PacketToFile( "5D_data_comp", m_data, m_data.size());
//Log::PacketToFile( "5D_data_decomp", unpacked, unpacked.size());
//auto &myCharacter = user->m_character;
//if( nullptr == myCharacter )
//{
// return std::make_shared< Result_5D >( this, FATAL_ERROR );
//}
//myCharacter->SetInventoryData( m_data );
//auto result = Database::Get().SaveInventory( user->m_accountId, user->m_characterId, m_data );
//if( !result )
//{
// Log::Error( "Failed to save inventory for account ID: " + std::to_string( user->m_accountId ) + ", character ID: " + std::to_string( user->m_characterId ) );
// return std::make_shared< Result_5D >( this, FATAL_ERROR );
//}
return std::make_shared< Result_5D >( this, SUCCESS );
}
Result_5D::Result_5D( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
{
m_reply = reply;
}
ByteBuffer& Result_5D::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
return m_stream;
}

View File

@@ -1,5 +1,6 @@
#include "Request_5F.h"
#include "../../Game/GameSessionManager.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Database/Database.h"
@@ -9,21 +10,49 @@ void Request_5F::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId_a = stream->read_encrypted_utf16();
auto sessionId_b = stream->read_encrypted_utf16();
m_sessionId = stream->read_encrypted_utf16();
m_memberSessionId = stream->read_encrypted_utf16();
}
sptr_generic_response Request_5F::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< Result_5F >( this, FATAL_ERROR );
}
Log::Packet( stream->get_buffer(), stream->get_length(), false );
Log::Debug( "Request_5F From user ID : %d", user->m_accountId );
//auto user = UserManager::Get().FindUserBySocket( socket );
//if( user == nullptr )
//{
// return std::make_shared< Result_5F >( this, FATAL_ERROR );
//}
//
//auto targetUser = UserManager::Get().FindUserBySessionId( m_memberSessionId );
//if( targetUser == nullptr || targetUser->m_accountId == -1 )
//{
// Log::Error( "Target user not found or invalid account ID for session: %S", m_memberSessionId.c_str() );
// return std::make_shared< Result_5F >( this, FATAL_ERROR );
//}
//
//auto gameSession = GameSessionManager::Get().FindGame( user->m_gameId, user->m_gameType );
//if( gameSession == nullptr )
//{
// Log::Error( "Game session not found for user: %S", user->m_sessionId.c_str() );
// return std::make_shared< Result_5F >( this, FATAL_ERROR );
//}
//
//if( !gameSession->IsJoinable() )
//{
// Log::Error( "Game session is not open for user: %S", user->m_sessionId.c_str() );
// return std::make_shared< Result_5F >( this, FATAL_ERROR );
//}
//
//if( !gameSession->AddMember( targetUser ) )
//{
// Log::Error( "Failed to add user %S to game session %d", targetUser->m_sessionId.c_str(), gameSession->m_gameIndex );
// return std::make_shared< Result_5F >( this, FATAL_ERROR );
//}
// TODO: Here is more like finalize/confirm joined
return std::make_shared< Result_5F >( this, SUCCESS );
}

View File

@@ -9,7 +9,8 @@
class Request_5F : public GenericRequest
{
private:
std::vector< uint8_t > m_data;
std::wstring m_sessionId;
std::wstring m_memberSessionId;
enum CREATE_REPLY {
SUCCESS = 0,

View File

@@ -17,11 +17,12 @@
/* 000F */ #include "Event/RequestGetRealmStats.h"
/* 0011 */ #include "Event/RequestGetRoom.h"
/* 0015 */ #include "Event/RequestLeaveRoom.h"
/* 0016 */ #include "Event/RequestLogin.h"
/* 0017 */ #include "Event/RequestLogout.h"
/* 0018 */ #include "Event/RequestMatchGame.h"
/* 0022 */ #include "Event/RequestSendRoomMessage.h"
/* 0023 */ #include "Event/RequestStartGame.h"
/* 0024 */ #include "Event/RequestTouchSession.h"
/* 0025 */ #include "Event/RequestDoClientDiscovery.h"
@@ -35,17 +36,18 @@
/* 0054 */ #include "Event/RequestCreatePublicGame_RTA.h"
/* 0055 */ #include "Event/RequestMatchGame_RTA.h"
/* 0056 */ #include "Event/RequestCreatePrivateGame_RTA.h"
/* 0057 */ #include "Event/RequestGetGame_RTA.h"
/* 0058 */ #include "Event/RequestCreateNewCharacter_RTA.h"
/* 005B */ #include "Event/RequestGetNetCharacterList_RTA.h"
/* 005C */ #include "Event/RequestGetCharacterData_RTA.h"
/* 005D */ #include "Event/Request_5D.h"
/* 005D */ #include "Event/RequestAppendCharacterData.h"
/* 005E */ #include "Event/RequestSaveCharacter_RTA.h"
/* 005F */ #include "Event/Request_5F.h"
/* 005F */ #include "Event/RequestUserJoinSuccess.h"
/* 0060 */ #include "Event/RequestCancelGame_RTA.h"
/* 0061 */ #include "Event/Request_61.h"
/* 0061 */ #include "Event/RequestGetFriendList.h"
/* 0066 */ #include "Event/RequestGetGame_RTA.h"
/* 0066 */ #include "Event/RequestDoClientDiscovery_RTA.h"
const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > > REQUEST_EVENT =
@@ -100,6 +102,11 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
return std::make_unique< RequestGetRoom >();
}
},
{ 0x0015, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestLeaveRoom >();
}
},
{ 0x0016, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestLogin >();
@@ -115,6 +122,11 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
return std::make_unique< RequestMatchGame >();
}
},
{ 0x0022, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestSendRoomMessage >();
}
},
{ 0x0023, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestStartGame >();
@@ -165,6 +177,11 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
return std::make_unique< RequestCreatePrivateGame_RTA >();
}
},
{ 0x0057, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetGame_RTA >();
}
},
{ 0x0058, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreateNewCharacter_RTA >();
@@ -182,7 +199,7 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
},
{ 0x005D, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< Request_5D >();
return std::make_unique< RequestAppendCharacterData >();
}
},
{ 0x005E, []() -> std::unique_ptr< GenericRequest >
@@ -192,7 +209,7 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
},
{ 0x005F, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< Request_5F >();
return std::make_unique< RequestUserJoinSuccess >();
}
},
{ 0x0060, []() -> std::unique_ptr< GenericRequest >
@@ -202,12 +219,12 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
},
{ 0x0061, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< Request_61 >();
return std::make_unique< RequestGetFriendList >();
}
},
{ 0x0066, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetGame_RTA >();
return std::make_unique< RequestDoClientDiscovery_RTA >();
}
},
};

View File

@@ -13,7 +13,7 @@ public:
}
virtual ~GenericMessage() = default;
virtual ByteBuffer& Serialize() = 0;
virtual void Serialize( ByteBuffer &out ) const = 0;
};
typedef std::shared_ptr< GenericMessage > sptr_generic_message;

View File

@@ -1,18 +1 @@
#include "GenericNetRequest.h"
sptr_generic_response GenericRequest::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
throw std::runtime_error( "ProcessRequest not implemented for GenericRequest" );
}
sptr_generic_response GenericRequest::ProcessRequest( sptr_byte_stream stream )
{
throw std::runtime_error( "ProcessRequest not implemented for GenericRequest" );
}
void GenericRequest::DeserializeHeader( sptr_byte_stream stream )
{
m_packetId = stream->read_u16();
m_trackId = stream->read_u32();
auto version = stream->read_u32(); // 2 for CON and 6 for RTA
};
#include "GenericNetRequest.h"

View File

@@ -1,6 +1,7 @@
#pragma once
#include <memory>
#include "../Common/ByteStream.h"
class GenericResponse;
@@ -12,18 +13,30 @@ using sptr_user = std::shared_ptr< RealmUser >;
class RealmSocket;
using sptr_socket = std::shared_ptr< RealmSocket >;
class GenericRequest
{
class GenericRequest {
public:
int16_t m_packetId;
uint32_t m_trackId;
virtual ~GenericRequest() = default;
virtual sptr_generic_response ProcessRequest( sptr_socket user, sptr_byte_stream stream );
virtual sptr_generic_response ProcessRequest( sptr_byte_stream stream );
virtual sptr_generic_response ProcessRequest( sptr_socket user, sptr_byte_stream stream )
{
throw std::runtime_error( "ProcessRequest not implemented for GenericRequest" );
}
virtual sptr_generic_response ProcessRequest( sptr_byte_stream stream )
{
throw std::runtime_error( "ProcessRequest not implemented for GenericRequest" );
}
void DeserializeHeader( sptr_byte_stream stream )
{
m_packetId = stream->read_u16();
m_trackId = stream->read_u32();
auto version = stream->read_u32(); // 2 for CON and 6 for RTA
};
void DeserializeHeader( sptr_byte_stream stream );
virtual void Deserialize( sptr_byte_stream stream ) = 0;
};

View File

@@ -17,7 +17,7 @@ public:
}
virtual ~GenericResponse() = default;
virtual ByteBuffer& Serialize() = 0;
virtual void Serialize( ByteBuffer& out ) const = 0;
};
typedef std::shared_ptr< GenericResponse > sptr_generic_response;
using sptr_generic_response = std::shared_ptr< GenericResponse >;

Some files were not shown because too many files have changed in this diff Show More