mirror of
https://github.com/HikikoMarmy/Champions-Reborn-Server.git
synced 2026-04-05 00:49:48 -03:00
Reorganized and cleaned up the solution.
This commit is contained in:
203
Source/Game/CharacterSaveManager.cpp
Normal file
203
Source/Game/CharacterSaveManager.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* CharacterSaveManager is responsible for managing character saves while online.
|
||||
* Because Return To Arms can have any user in the party initiate a save for any
|
||||
* other user in the party, we need to keep track of these tasks.
|
||||
*
|
||||
* Tasks keep track of the user that initiated the save (the owner),
|
||||
* and the target user whose character is being saved.
|
||||
*/
|
||||
|
||||
#include "Game/CharacterSaveManager.hpp"
|
||||
|
||||
#include "Game/RealmUser.hpp"
|
||||
#include "Game/RealmUserManager.hpp"
|
||||
#include "Database/Database.hpp"
|
||||
#include "logging.hpp"
|
||||
|
||||
CharacterSaveManager::CharacterSaveManager()
|
||||
{
|
||||
m_tasks.clear();
|
||||
}
|
||||
|
||||
CharacterSaveManager::~CharacterSaveManager()
|
||||
{
|
||||
m_tasks.clear();
|
||||
}
|
||||
|
||||
bool CharacterSaveManager::BeginSaveTask(
|
||||
const sptr_user user,
|
||||
const uint32_t characterId,
|
||||
const CharacterSlotData &metaData,
|
||||
const CharacterSaveType saveType )
|
||||
{
|
||||
return BeginSaveTask( user, user, characterId, metaData, saveType );
|
||||
}
|
||||
|
||||
bool CharacterSaveManager::BeginSaveTask(
|
||||
const sptr_user m_owner,
|
||||
const sptr_user m_target,
|
||||
const uint32_t characterId,
|
||||
const CharacterSlotData &metaData,
|
||||
const CharacterSaveType saveType )
|
||||
{
|
||||
if( !m_owner || !m_target )
|
||||
{
|
||||
Log::Error( "CreateSaveTask called with empty session IDs!" );
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto &sessionId = m_owner->m_sessionId;
|
||||
|
||||
if( m_tasks.find( sessionId ) != m_tasks.end() )
|
||||
{
|
||||
m_tasks.erase( sessionId );
|
||||
}
|
||||
|
||||
auto task = std::make_shared< CharacterSaveTask >( saveType, characterId );
|
||||
|
||||
task->m_ownerUser = m_owner;
|
||||
task->m_targetUser = m_target;
|
||||
task->m_meta = metaData;
|
||||
m_tasks[ sessionId ] = task;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void CharacterSaveManager::AppendSaveData( const std::wstring &sessionId, const std::vector<uint8_t> &data, bool endOfData )
|
||||
{
|
||||
try
|
||||
{
|
||||
auto it = m_tasks.find( sessionId );
|
||||
if( it == m_tasks.end() )
|
||||
{
|
||||
Log::Error( "AddDataToSaveTask: No task found for session ID [{}].", sessionId );
|
||||
return;
|
||||
}
|
||||
|
||||
auto &task = it->second;
|
||||
|
||||
if( !task->AppendData( data ) )
|
||||
{
|
||||
Log::Error( "AddDataToSaveTask: Append failed for session ID [{}].", sessionId );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !endOfData )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if( !task->Validate() )
|
||||
{
|
||||
Log::Error( "AddDataToSaveTask: Validation failed for session ID [{}].", sessionId );
|
||||
return;
|
||||
}
|
||||
|
||||
if( !CommitSaveTask( sessionId ) )
|
||||
{
|
||||
Log::Error( "AddDataToSaveTask: Commit failed for session ID [{}].", sessionId );
|
||||
return;
|
||||
}
|
||||
|
||||
Log::Debug( "AddDataToSaveTask: Final chunk committed for session ID [{}].", sessionId );
|
||||
}
|
||||
catch( const std::exception &e )
|
||||
{
|
||||
Log::Error( "AddDataToSaveTask: Exception for session ID [{}]: {}", sessionId, e.what() );
|
||||
}
|
||||
}
|
||||
|
||||
bool CharacterSaveManager::CommitSaveTask( const std::wstring &sessionId )
|
||||
{
|
||||
try
|
||||
{
|
||||
auto node = m_tasks.extract( sessionId );
|
||||
if( !node )
|
||||
{
|
||||
Log::Error( "CommitSaveTask: Task for session ID [{}] not found.", sessionId );
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto &saveTask = node.mapped();
|
||||
|
||||
if( !saveTask->Validate() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
auto &targetUser = saveTask->m_targetUser;
|
||||
|
||||
if( !targetUser )
|
||||
{
|
||||
Log::Error( "CommitSaveTask: Target user not found." );
|
||||
return false;
|
||||
}
|
||||
|
||||
if( saveTask->m_saveType == CharacterSaveType::NEW_CHARACTER )
|
||||
{
|
||||
auto result = Database::Get().CreateNewCharacter( targetUser->m_accountId, saveTask->m_meta, saveTask->m_data );
|
||||
if( !result )
|
||||
{
|
||||
Log::Error( "CommitSaveTask: Failed to create new character for account ID: {}", targetUser->m_accountId );
|
||||
return false;
|
||||
}
|
||||
|
||||
Log::Debug( "CommitSaveTask: New character created with ID {} for account ID: {}", result, targetUser->m_accountId );
|
||||
|
||||
targetUser->m_characterId = result;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( 0 == saveTask->m_characterId )
|
||||
{
|
||||
Log::Error( "CommitSaveTask: Invalid character ID for save task." );
|
||||
return false;
|
||||
}
|
||||
|
||||
auto result = Database::Get().SaveCharacter( targetUser->m_accountId, targetUser->m_characterId, saveTask->m_meta, saveTask->m_data );
|
||||
if( !result )
|
||||
{
|
||||
Log::Error( "CommitSaveTask: Failed to save character for account ID: {}", targetUser->m_accountId );
|
||||
return false;
|
||||
}
|
||||
|
||||
Log::Debug( "CommitSaveTask: Character saved for account ID: {}", targetUser->m_accountId );
|
||||
}
|
||||
}
|
||||
catch( const std::exception &e )
|
||||
{
|
||||
Log::Error( "CommitSaveTask: Exception occurred while committing task for session ID [{}]: {}", sessionId, e.what() );
|
||||
return false;
|
||||
}
|
||||
|
||||
Log::Debug( "CommitSaveTask: Task for session ID [{}] committed successfully.", sessionId );
|
||||
return true;
|
||||
}
|
||||
|
||||
void CharacterSaveManager::RemoveSaveTask( const std::wstring &sessionId )
|
||||
{
|
||||
auto it = m_tasks.find( sessionId );
|
||||
if( it != m_tasks.end() )
|
||||
{
|
||||
m_tasks.erase( it );
|
||||
Log::Debug( "RemoveSaveTask: Task for session ID [{}] removed.", sessionId );
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Error( "RemoveSaveTask: Task for session ID [{}] not found.", sessionId );
|
||||
}
|
||||
}
|
||||
|
||||
sptr_character_save_task CharacterSaveManager::FindSaveTask( const std::wstring &sessionId )
|
||||
{
|
||||
auto it = m_tasks.find( sessionId );
|
||||
if( it != m_tasks.end() )
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
Log::Error( "FindSaveTask: Task for session ID [{}] not found.", sessionId );
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user