Files
Champions-Reborn-Server-Mirror/Source/Game/RealmUserManager.cpp
2026-03-02 12:37:07 +00:00

181 lines
4.1 KiB
C++

#include "Game/RealmUserManager.hpp"
#include "Game/GameSessionManager.hpp"
#include "Game/ChatRoomManager.hpp"
#include "Network/Event/NotifyForcedLogout.hpp"
#include "Network/Event/NotifyFriendStatus.hpp"
#include "Database/Database.hpp"
#include "Common/Constant.hpp"
#include "logging.hpp"
UserManager::UserManager()
{
std::random_device rd;
rng.seed( rd() );
m_users.clear();
}
UserManager::~UserManager()
{
}
std::wstring UserManager::GenerateSessionId()
{
static const wchar_t charset[] = L"0123456789ABCDEF";
std::uniform_int_distribution<int> dist( 0, 15 );
std::wstring sessionId;
sessionId.reserve( MAX_SESSION_ID_LENGTH );
for( int i = 0; i < MAX_SESSION_ID_LENGTH; ++i )
{
sessionId += charset[ dist( rng ) ];
}
return sessionId;
}
sptr_user UserManager::CreateUser( sptr_socket socket, RealmGameType clientType )
{
Log::Debug( "ClientManager::CreateUser() - Created new user" );
auto user = std::make_shared< RealmUser >();
user->sock = socket;
user->m_gameType = clientType;
std::lock_guard< std::mutex > lock( m_mutex );
m_users.push_back( user );
return user;
}
void UserManager::RemoveUser( sptr_user user )
{
auto it = std::find( m_users.begin(), m_users.end(), user );
if( it == m_users.end() )
{
Log::Error( "RemoveUser : [{}] not found", user->m_sessionId );
return;
}
GameSessionManager::Get().OnDisconnectUser( user );
ChatRoomManager::Get().OnDisconnectUser( user );
NotifyFriendsOnlineStatus( user, false );
Log::Debug( "RemoveUser : [{}][{}]", user->m_username, user->m_sessionId );
std::lock_guard< std::mutex > lock( m_mutex );
m_users.erase( it );
}
void UserManager::RemoveUser( const std::wstring &sessionId )
{
if( auto user = FindUserBySessionId( sessionId ) )
{
RemoveUser( user );
}
}
void UserManager::RemoveUser( const sptr_socket socket )
{
if( auto user = FindUserBySocket( socket ) )
{
RemoveUser( user );
}
}
void UserManager::Disconnect( sptr_socket socket, const std::string reason )
{
if( nullptr == socket )
{
return;
}
Log::Debug( "DisconnectSocket : [{}]. Reason: {}", socket->remote_ip, reason );
socket->send( NotifyForcedLogout() );
socket->flag.disconnected_wait = true;
RemoveUser( socket );
}
void UserManager::Disconnect( sptr_user user, const std::string reason )
{
if( nullptr == user )
{
return;
}
if( user->sock != nullptr )
{
user->sock->send( NotifyForcedLogout() );
user->sock->flag.disconnected_wait = true;
}
Log::Debug( "DisconnectUser : [{}]. Reason: {}", user->m_sessionId, reason );
RemoveUser( user );
}
sptr_user UserManager::FindUserBySessionId( const std::wstring &sessionId )
{
std::lock_guard<std::mutex> lock( m_mutex );
auto it = std::find_if( m_users.begin(), m_users.end(), [ & ]( const sptr_user &user )
{
return user->m_sessionId == sessionId;
} );
return ( it != m_users.end() ) ? *it : nullptr;
}
sptr_user UserManager::FindUserBySocket( const sptr_socket &socket )
{
std::lock_guard<std::mutex> lock( m_mutex );
auto it = std::find_if( m_users.begin(), m_users.end(), [ & ]( const sptr_user &user )
{
return user->sock == socket;
} );
return ( it != m_users.end() ) ? *it : nullptr;
}
sptr_user UserManager::FindUserByChatHandle( const std::wstring &handle )
{
std::lock_guard<std::mutex> lock( m_mutex );
auto it = std::find_if( m_users.begin(), m_users.end(), [ & ]( const sptr_user &user )
{
return user->m_chatHandle == handle;
} );
return ( it != m_users.end() ) ? *it : nullptr;
}
int32_t UserManager::GetUserCount() const
{
return static_cast< int32_t >( m_users.size() );
}
std::vector<sptr_user> UserManager::GetUserList()
{
std::lock_guard<std::mutex> lock( m_mutex );
return m_users;
}
void UserManager::NotifyFriendsOnlineStatus( const sptr_user &user, bool onlineStatus )
{
if( !user || user->m_friendList.empty() )
{
return;
}
const auto notifyFriend = NotifyFriendStatus( user->m_chatHandle, onlineStatus );
for( const auto &friendHandle : user->m_friendList )
{
auto friendUser = FindUserByChatHandle( friendHandle );
if( friendUser && friendUser->sock )
{
friendUser->sock->send( notifyFriend );
}
}
}