Support for Return To Arms Events and Notifications.

This commit is contained in:
HikikoMarmy
2025-06-15 00:16:45 +01:00
parent f82fc49594
commit 38d08dc7de
35 changed files with 785 additions and 222 deletions

View File

@@ -0,0 +1,20 @@
#include "NotifyClientDiscovered_RTA.h"
#include "../../Common/Constant.h"
NotifyClientDiscovered_RTA::NotifyClientDiscovered_RTA( std::string clientIp, int32_t clientPort ) : GenericMessage( 0x40 )
{
this->m_clientIp = std::move( clientIp );
this->m_clientPort = clientPort;
}
ByteBuffer & NotifyClientDiscovered_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( 0 );
m_stream.write_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"
#include "../../Common/Constant.h"
class NotifyClientDiscovered_RTA : public GenericMessage {
private:
std::string m_clientIp;
int32_t m_clientPort;
public:
NotifyClientDiscovered_RTA( std::string clientIp, int32_t clientPort );
ByteBuffer &Serialize() override;
};

View File

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

View File

@@ -1,5 +1,10 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetMessage.h"
class NotifyClientRequestConnect_RTA : public GenericMessage {
private:
std::string m_localAddr;
@@ -8,5 +13,5 @@ private:
public:
NotifyClientRequestConnect_RTA( std::string localAddr, std::string remoteAddr, int32_t port );
ByteStream &Serialize() override;
ByteBuffer &Serialize() override;
};

View File

@@ -0,0 +1,19 @@
#include "NotifyReserveUserSlot_RTA.h"
NotifyReserveUserSlot_RTA::NotifyReserveUserSlot_RTA( std::string discoveryAddr, int32_t discoveryPort ) : GenericMessage( 0x51 )
{
this->m_discoveryAddr = discoveryAddr;
this->m_port = discoveryPort;
}
ByteBuffer &NotifyReserveUserSlot_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.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;
}

View File

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

View File

@@ -1,6 +1,9 @@
#include "../../global_define.h"
#include "RequestCancelGame_RTA.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../logging.h"
void RequestCancelGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
@@ -8,10 +11,12 @@ void RequestCancelGame_RTA::Deserialize( sptr_byte_stream stream )
m_sessionId = stream->read_encrypted_utf16();
}
sptr_generic_response RequestCancelGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
sptr_generic_response RequestCancelGame_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
@@ -28,10 +33,10 @@ ResultCancelGame_RTA::ResultCancelGame_RTA( GenericRequest *request ) : GenericR
}
ByteStream &ResultCancelGame_RTA::Serialize()
ByteBuffer &ResultCancelGame_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
return m_stream;

View File

@@ -1,5 +1,11 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestCancelGame_RTA : public GenericRequest
{
private:
@@ -11,12 +17,12 @@ public:
return std::make_unique< RequestCancelGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultCancelGame_RTA : public GenericResponse {
public:
ResultCancelGame_RTA( GenericRequest *request );
ByteStream &Serialize();
ByteBuffer &Serialize();
};

View File

@@ -0,0 +1,62 @@
#include "RequestCreateNewCharacter_RTA.h"
#include "../../Database/Database.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Game/RealmCharacter.h"
#include "../../logging.h"
void RequestCreateNewCharacter_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
auto a = stream->read_u32();
auto b = stream->read_u32();
m_newCharacterData = std::make_shared< RealmCharacter >( stream );
}
sptr_generic_response RequestCreateNewCharacter_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
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 )
{
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;
return std::make_shared< ResultCreateNewCharacter_RTA >( this, SUCCESS );
}
ResultCreateNewCharacter_RTA::ResultCreateNewCharacter_RTA( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
{
m_reply = reply;
}
ByteBuffer& ResultCreateNewCharacter_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
return m_stream;
}

View File

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

View File

@@ -1,7 +1,10 @@
#include "../../global_define.h"
#include "RequestCreatePrivateGame_RTA.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../configuration.h"
#include "../../logging.h"
void RequestCreatePrivateGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
@@ -10,11 +13,18 @@ void RequestCreatePrivateGame_RTA::Deserialize( sptr_byte_stream stream )
m_gameInfo = stream->read_utf16();
}
sptr_generic_response RequestCreatePrivateGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
sptr_generic_response RequestCreatePrivateGame_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto result = GameSessionManager::Get().CreatePrivateGameSession( user, m_gameInfo, user->m_clientType );
auto user = RealmUserManager::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 );
}
auto result = GameSessionManager::Get().CreatePrivateGameSession( user, m_gameInfo, user->m_gameType );
if( !result )
{
@@ -34,10 +44,10 @@ ResultCreatePrivateGame2::ResultCreatePrivateGame2( GenericRequest *request, int
m_discoveryPort = discoveryPort;
}
ByteStream &ResultCreatePrivateGame2::Serialize()
ByteBuffer &ResultCreatePrivateGame2::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
m_stream.write_sz_utf8( m_discoveryIp );

View File

@@ -1,5 +1,11 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestCreatePrivateGame_RTA : public GenericRequest
{
private:
@@ -20,7 +26,7 @@ public:
return std::make_unique< RequestCreatePrivateGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
@@ -32,5 +38,5 @@ private:
public:
ResultCreatePrivateGame2( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteStream &Serialize();
ByteBuffer &Serialize();
};

View File

@@ -1,7 +1,10 @@
#include "../../global_define.h"
#include "RequestCreatePublicGame_RTA.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../configuration.h"
#include "../../logging.h"
// Request
void RequestCreatePublicGame_RTA::Deserialize( sptr_byte_stream stream )
{
@@ -19,16 +22,21 @@ void RequestCreatePublicGame_RTA::Deserialize( sptr_byte_stream stream )
auto unknown_e = stream->read_u32();
auto unknown_f = stream->read_u32();
m_localAddr = stream->read_utf16();
m_localAddr = Util::WideToUTF8(stream->read_utf16());
}
sptr_generic_response RequestCreatePublicGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
sptr_generic_response RequestCreatePublicGame_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Packet( stream->data, stream->data.size(), false );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultCreatePublicGame_RTA >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
}
auto result = GameSessionManager::Get().CreatePublicGameSession( user, m_gameInfo, user->m_clientType );
auto result = GameSessionManager::Get().CreatePublicGameSession( user, m_gameInfo, user->m_gameType );
if( !result )
{
@@ -36,7 +44,7 @@ sptr_generic_response RequestCreatePublicGame_RTA::ProcessRequest( sptr_user use
return std::make_shared< ResultCreatePublicGame_RTA >( this, CREATE_REPLY::GENERAL_ERROR, "", 0 );
}
user->m_localAddr = Utility::WideToUTF8( m_localAddr );
user->m_localAddr = m_localAddr;
Log::Info( "[%S] Create Public Game: %S", m_sessionId.c_str(), m_gameInfo.c_str() );
@@ -51,10 +59,10 @@ ResultCreatePublicGame_RTA::ResultCreatePublicGame_RTA( GenericRequest *request,
m_discoveryPort = discoveryPort;
}
ByteStream &ResultCreatePublicGame_RTA::Serialize()
ByteBuffer &ResultCreatePublicGame_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
m_stream.write_utf8( m_discoveryIp );

View File

@@ -1,12 +1,18 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestCreatePublicGame_RTA : public GenericRequest
{
private:
std::wstring m_sessionId;
std::wstring m_gameInfo;
std::wstring m_localAddr;
std::string m_localAddr;
enum CREATE_REPLY {
SUCCESS = 0,
@@ -20,7 +26,7 @@ public:
{
return std::make_unique< RequestCreatePublicGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
@@ -32,5 +38,5 @@ private:
public:
ResultCreatePublicGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0 );
ByteStream &Serialize();
ByteBuffer &Serialize();
};

View File

@@ -0,0 +1,108 @@
#include "RequestGetCharacterData_RTA.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Database/Database.h"
#include "../../logging.h"
#include "../../Common/RLEZ.hpp"
void RequestGetNetCharacterData_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
auto sessionId = stream->read_encrypted_utf16();
m_characterId = stream->read_u32();
}
sptr_generic_response RequestGetNetCharacterData_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize(stream);
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultGetNetCharacterData_RTA >( this, FATAL_ERROR, nullptr );
}
auto result = Database::Get().LoadCharacterData( user->m_accountId, m_characterId );
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 );
}
user->m_characterId = 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 );
}
ResultGetNetCharacterData_RTA::ResultGetNetCharacterData_RTA( GenericRequest *request, int32_t reply, sptr_realm_character data ) : GenericResponse( *request )
{
m_reply = reply;
m_data = data;
}
ByteBuffer& ResultGetNetCharacterData_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.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
}
//Log::Packet( m_stream.get_buffer(), m_stream.get_length(), false);
return m_stream;
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
#include "../../Game/RealmCharacter.h"
class RequestGetNetCharacterData_RTA : public GenericRequest
{
private:
int32_t m_characterId;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestGetNetCharacterData_RTA > Create()
{
return std::make_unique< RequestGetNetCharacterData_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetNetCharacterData_RTA : public GenericResponse {
private:
int32_t m_reply;
sptr_realm_character m_data;
public:
ResultGetNetCharacterData_RTA( GenericRequest *request, int32_t reply, sptr_realm_character data );
ByteBuffer &Serialize();
};

View File

@@ -1,28 +1,31 @@
#include "../../global_define.h"
#include "RequestGetGame_RTA.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../configuration.h"
#include "../../logging.h"
void RequestGetGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
m_sessionId = stream->read_encrypted_utf16();
m_gameId = stream->read_u32();
m_localAddr = stream->read_utf16();
m_localAddr = Util::WideToUTF8(stream->read_utf16());
}
sptr_generic_response RequestGetGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
sptr_generic_response RequestGetGame_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
Log::Packet( stream->data, stream->data.size(), false );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId.c_str() );
return std::make_shared< ResultGetGame_RTA >( this, TIMEOUT );
}
auto session = GameSessionManager::Get().FindGame( m_gameId );
auto session = GameSessionManager::Get().FindGame( m_gameId, user->m_gameType );
if( session == nullptr )
{
@@ -46,6 +49,7 @@ sptr_generic_response RequestGetGame_RTA::ProcessRequest( sptr_user user, sptr_b
user->m_isHost = false;
user->m_gameId = session->m_gameIndex;
user->m_localAddr = m_localAddr;
return std::make_shared< ResultGetGame_RTA >( this, SUCCESS, Config::service_ip, Config::discovery_port );
}
@@ -57,10 +61,10 @@ ResultGetGame_RTA::ResultGetGame_RTA( GenericRequest *request, int32_t reply, st
m_discoveryPort = discoveryPort;
}
ByteStream &ResultGetGame_RTA::Serialize()
ByteBuffer &ResultGetGame_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
m_stream.write_utf8( m_discoveryIp );

View File

@@ -1,9 +1,16 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestGetGame_RTA : public GenericRequest {
private:
std::wstring m_sessionId;
std::wstring m_localAddr;
std::string m_localAddr;
uint32_t m_gameId;
enum REPLY {
@@ -17,7 +24,7 @@ public:
{
return std::make_unique< RequestGetGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
@@ -29,5 +36,5 @@ private:
public:
ResultGetGame_RTA( GenericRequest *request, int32_t reply, std::string discoveryIp = "", int32_t discoveryPort = 0);
ByteStream &Serialize();
ByteBuffer &Serialize();
};

View File

@@ -0,0 +1,65 @@
#include "RequestGetNetCharacterList_RTA.h"
#include "../../Game/RealmUser.h"
#include "../../Game/RealmCharacterMetaKV.h"
#include "../../Database/Database.h"
#include "../../logging.h"
void RequestGetNetCharacterList_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestGetNetCharacterList_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
//auto result = Database::Get().LoadCharacterList( user->m_accountId );
auto result = std::map< int32_t, RealmCharacterMetaData >();
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 )
{
m_reply = reply;
m_characterList = std::move( list );
}
ByteBuffer &ResultGetNetCharacterList_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
if( 0 == m_reply )
{
// Character Count
m_stream.write_u32( static_cast< int >( m_characterList.size() ) );
// Character List
for( auto &character : m_characterList )
{
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 );
}
}
}
else
{
m_stream.write_u32( 0 ); // No characters
}
return m_stream;
}

View File

@@ -0,0 +1,39 @@
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <map>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
#include "../../Game/RealmCharacterMetaKV.h"
class RequestGetNetCharacterList_RTA : public GenericRequest
{
private:
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestGetNetCharacterList_RTA > Create()
{
return std::make_unique< RequestGetNetCharacterList_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultGetNetCharacterList_RTA : public GenericResponse {
private:
int32_t m_reply;
std::map< int32_t, RealmCharacterMetaData > m_characterList;
public:
ResultGetNetCharacterList_RTA( GenericRequest *request, int32_t reply, std::map< int32_t, RealmCharacterMetaData > list );
ByteBuffer &Serialize();
};

View File

@@ -1,46 +1,56 @@
#include "../../global_define.h"
#include "RequestMatchGame_RTA.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/GameSessionManager.h"
#include "../../logging.h"
void RequestMatchGame_RTA::Deserialize( sptr_byte_stream stream )
{
DeserializeHeader( stream );
}
sptr_generic_response RequestMatchGame_RTA::ProcessRequest( sptr_user user, sptr_byte_stream stream )
sptr_generic_response RequestMatchGame_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
return std::make_shared< ResultMatchGame_RTA >( this );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
return std::make_shared< ResultMatchGame_RTA >( this, "" );
}
return std::make_shared< ResultMatchGame_RTA >( this, socket->remote_ip );
}
ResultMatchGame_RTA::ResultMatchGame_RTA( GenericRequest *request ) : GenericResponse( *request )
ResultMatchGame_RTA::ResultMatchGame_RTA( GenericRequest *request, std::string userIp ) : GenericResponse( *request )
{
m_userIp = userIp;
}
ByteStream&ResultMatchGame_RTA::Serialize()
ByteBuffer&ResultMatchGame_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_requestId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( 0 );
auto publicGameList = GameSessionManager::Get().GetAvailableGameSessionList( RealmClientType::RETURN_TO_ARMS );
auto publicGameCount = static_cast< uint32_t >( publicGameList.size() );
const auto publicGameList = GameSessionManager::Get().GetAvailableGameSessionList( RealmGameType::RETURN_TO_ARMS );
const auto publicGameCount = static_cast< uint32_t >( publicGameList.size() );
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
for( const auto &game : publicGameList )
m_stream.write_utf16( game->m_gameName );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
for( const auto &game : publicGameList )
m_stream.write_utf16( game->m_playerCount );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
for( const auto &game : publicGameList )
m_stream.write_u32( game->m_gameIndex );
}
@@ -52,25 +62,35 @@ ByteStream&ResultMatchGame_RTA::Serialize()
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( game->m_hostExternalAddr );
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 ) );
}
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
for( const auto &game : publicGameList )
m_stream.write_u32( game->m_hostPort );
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
m_stream.write_utf16( game->m_hostLocalAddr );
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 ) );
}
}
m_stream.write_u32( publicGameCount );
{
for( auto &game : publicGameList )
for( const auto &game : publicGameList )
m_stream.write_u32( game->m_hostPort );
}

View File

@@ -1,5 +1,11 @@
#pragma once
#include <memory>
#include <string>
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
class RequestMatchGame_RTA : public GenericRequest
{
public:
@@ -8,12 +14,15 @@ public:
return std::make_unique< RequestMatchGame_RTA >();
}
sptr_generic_response ProcessRequest( sptr_user user, sptr_byte_stream stream ) override;
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultMatchGame_RTA : public GenericResponse {
private:
std::string m_userIp;
public:
ResultMatchGame_RTA( GenericRequest *request );
ByteStream &Serialize();
ResultMatchGame_RTA( GenericRequest *request, std::string userIp );
ByteBuffer &Serialize();
};

View File

@@ -0,0 +1,78 @@
#include "RequestSaveCharacter_RTA.h"
#include "../../Database/Database.h"
#include "../../Game/RealmUserManager.h"
#include "../../Game/RealmUser.h"
#include "../../Game/RealmCharacter.h"
#include "../../logging.h"
#include "../../Common/RLEZ.hpp"
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();
auto a = stream->read_u32();
auto b = stream->read_u32();
m_characterData = std::make_shared< RealmCharacter >( stream );
}
sptr_generic_response RequestSaveCharacter_RTA::ProcessRequest( sptr_socket socket, sptr_byte_stream stream )
{
Deserialize( stream );
auto user = RealmUserManager::Get().FindUserBySocket( socket );
if( user == nullptr )
{
Log::Error( "User not found! [%S]", m_sessionId_A.c_str() );
return std::make_shared< ResultSaveCharacter_RTA >( this, FATAL_ERROR );
}
//auto unpacked = RLEZ::Decompress( m_characterData->GetCharacterData() );
//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 )
{
return std::make_shared< ResultSaveCharacter_RTA >( this, FATAL_ERROR );
}
user->m_character = std::move(m_characterData);
return std::make_shared< ResultSaveCharacter_RTA >( this, SUCCESS );
}
ResultSaveCharacter_RTA::ResultSaveCharacter_RTA( GenericRequest *request, int32_t reply ) : GenericResponse( *request )
{
m_reply = reply;
}
ByteBuffer& ResultSaveCharacter_RTA::Serialize()
{
m_stream.write_u16( m_packetId );
m_stream.write_u32( m_trackId );
m_stream.write_u32( m_reply );
return m_stream;
}

View File

@@ -0,0 +1,40 @@
#pragma once
#include "../GenericNetRequest.h"
#include "../GenericNetResponse.h"
#include "../../Game/RealmCharacter.h"
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;
enum CREATE_REPLY {
SUCCESS = 0,
FATAL_ERROR,
GENERAL_ERROR,
};
public:
static std::unique_ptr< RequestSaveCharacter_RTA > Create()
{
return std::make_unique< RequestSaveCharacter_RTA >();
}
sptr_generic_response ProcessRequest( sptr_socket socket, sptr_byte_stream stream ) override;
void Deserialize( sptr_byte_stream stream ) override;
};
class ResultSaveCharacter_RTA : public GenericResponse {
private:
int32_t m_reply;
public:
ResultSaveCharacter_RTA( GenericRequest *request, int32_t reply );
ByteBuffer &Serialize();
};

View File

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

View File

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

View File

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

View File

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

View File

@@ -22,6 +22,7 @@
/* 0017 */ #include "Event/RequestLogout.h"
/* 0018 */ #include "Event/RequestMatchGame.h"
/* 0023 */ #include "Event/RequestStartGame.h"
/* 0024 */ #include "Event/RequestTouchSession.h"
/* 0025 */ #include "Event/RequestDoClientDiscovery.h"
@@ -35,9 +36,12 @@
/* 0055 */ #include "Event/RequestMatchGame_RTA.h"
/* 0056 */ #include "Event/RequestCreatePrivateGame_RTA.h"
/* 0058 */ #include "Event/RequestSaveNewCharacter_RTA.h"
/* 005B */ #include "Event/Request_5B.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"
/* 005E */ #include "Event/RequestSaveCharacter_RTA.h"
/* 005F */ #include "Event/Request_5F.h"
/* 0060 */ #include "Event/RequestCancelGame_RTA.h"
/* 0061 */ #include "Event/Request_61.h"
@@ -111,6 +115,11 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
return std::make_unique< RequestMatchGame >();
}
},
{ 0x0023, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestStartGame >();
}
},
{ 0x0024, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestTouchSession >();
@@ -141,7 +150,6 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
return std::make_unique< RequestUpdateGameData >();
}
},
{ 0x0054, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCreatePublicGame_RTA >();
@@ -159,12 +167,17 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
},
{ 0x0058, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestSaveNewCharacter >();
return std::make_unique< RequestCreateNewCharacter_RTA >();
}
},
{ 0x005B, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< Request_5B >();
return std::make_unique< RequestGetNetCharacterList_RTA >();
}
},
{ 0x005C, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestGetNetCharacterData_RTA >();
}
},
{ 0x005D, []() -> std::unique_ptr< GenericRequest >
@@ -172,6 +185,16 @@ const std::map< int16_t, std::function< std::unique_ptr< GenericRequest >() > >
return std::make_unique< Request_5D >();
}
},
{ 0x005E, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestSaveCharacter_RTA >();
}
},
{ 0x005F, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< Request_5F >();
}
},
{ 0x0060, []() -> std::unique_ptr< GenericRequest >
{
return std::make_unique< RequestCancelGame_RTA >();

View File

@@ -1,19 +1,19 @@
#pragma once
#include "../misc/ByteStream.h"
#include "../Common/ByteStream.h"
class GenericMessage
{
public:
uint16_t m_packetId;
ByteStream m_stream;
ByteBuffer m_stream;
GenericMessage( uint16_t packetId ) : m_packetId( packetId )
{
}
virtual ~GenericMessage() = default;
virtual ByteStream& Serialize() = 0;
virtual ByteBuffer& Serialize() = 0;
};
typedef std::shared_ptr< GenericMessage > sptr_generic_message;

View File

@@ -0,0 +1,18 @@
#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
};

View File

@@ -0,0 +1,31 @@
#pragma once
#include <memory>
#include "../Common/ByteStream.h"
class GenericResponse;
using sptr_generic_response = std::shared_ptr< GenericResponse >;
class RealmUser;
using sptr_user = std::shared_ptr< RealmUser >;
class RealmSocket;
using sptr_socket = std::shared_ptr< RealmSocket >;
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 );
void DeserializeHeader( sptr_byte_stream stream );
virtual void Deserialize( sptr_byte_stream stream ) = 0;
};
using sptr_generic_request = std::shared_ptr< GenericRequest >;

View File

@@ -1,37 +0,0 @@
#pragma once
#include "../Network/RealmSocket.h"
#include "../misc/ByteStream.h"
class GenericResponse;
typedef std::shared_ptr< GenericResponse > sptr_generic_response;
class GenericRequest
{
public:
int16_t m_packetId;
uint32_t m_requestId;
virtual ~GenericRequest() = default;
virtual sptr_generic_response ProcessRequest(sptr_user user, sptr_byte_stream stream)
{
return nullptr;
};
virtual sptr_generic_response ProcessRequest( sptr_byte_stream stream )
{
return nullptr;
};
void DeserializeHeader( sptr_byte_stream stream )
{
m_packetId = stream->read_u16();
m_requestId = stream->read_u32();
auto ver = stream->read_u32(); // Called Version in the game, but is always 2 for CON and RTA
};
virtual void Deserialize( sptr_byte_stream stream ) = 0;
};
typedef std::shared_ptr< GenericRequest > sptr_generic_request;

View File

@@ -0,0 +1,23 @@
#pragma once
#include "GenericNetRequest.h"
#include "../Common/ByteStream.h"
class GenericResponse
{
public:
uint16_t m_packetId;
uint32_t m_trackId;
ByteBuffer m_stream;
GenericResponse( const GenericRequest &request )
{
m_packetId = request.m_packetId;
m_trackId = request.m_trackId;
}
virtual ~GenericResponse() = default;
virtual ByteBuffer& Serialize() = 0;
};
typedef std::shared_ptr< GenericResponse > sptr_generic_response;

View File

@@ -1,21 +0,0 @@
#pragma once
#include "GenericNetRequest.hpp"
#include "../misc/ByteStream.h"
class GenericResponse
{
public:
uint16_t m_packetId;
uint32_t m_requestId;
ByteStream m_stream;
GenericResponse( GenericRequest &request ) : m_packetId( request.m_packetId ), m_requestId( request.m_requestId )
{
}
virtual ~GenericResponse() = default;
virtual ByteStream& Serialize() = 0;
};
typedef std::shared_ptr< GenericResponse > sptr_generic_response;