Refactoring game sessions for better RTA support

This commit is contained in:
HikikoMarmy
2025-07-01 13:58:11 +01:00
parent 57c256b008
commit b4ab6cd31b
4 changed files with 322 additions and 150 deletions

View File

@@ -1,17 +1,24 @@
#include "GameSession.h" #include "GameSession.h"
GameSession::GameSession() #include "RealmUser.h"
{ #include "../../logging.h"
m_owner.reset();
GameSession::GameSession( uint32_t index ) : m_gameId( index )
{
m_members.fill( std::weak_ptr< RealmUser >() );
m_gameIndex = 0;
m_type = GameType::Public;
m_state = GameState::NotReady; m_state = GameState::NotReady;
m_currentPlayers = 0; m_currentPlayers = 0;
m_maximumPlayers = 0; m_maximumPlayers = 4;
m_hostPort = 0; m_difficulty = 0;
m_gameMode = 0;
m_mission = 0;
m_unknown = 0;
m_networkSave = 0;
m_hostNatPort = 0;
m_hostLocalAddr.clear(); m_hostLocalAddr.clear();
m_hostExternalAddr.clear(); m_hostExternalAddr.clear();
m_gameName.clear(); m_gameName.clear();
@@ -22,19 +29,167 @@ GameSession::GameSession()
GameSession::~GameSession() GameSession::~GameSession()
{ {
m_owner.reset(); m_members.fill( std::weak_ptr< RealmUser >() );
m_gameIndex = 0; m_gameId = 0;
m_type = GameType::Public; m_type = GameType::Public;
m_state = GameState::NotReady; m_state = GameState::NotReady;
m_currentPlayers = 0; m_currentPlayers = 0;
m_maximumPlayers = 0; m_maximumPlayers = 0;
m_hostPort = 0; m_difficulty = 0;
m_gameMode = 0;
m_mission = 0;
m_unknown = 0;
m_networkSave = 0;
m_hostNatPort = 0;
m_hostLocalAddr.clear(); m_hostLocalAddr.clear();
m_hostExternalAddr.clear(); m_hostExternalAddr.clear();
m_gameName.clear(); m_gameName.clear();
m_ownerName.clear(); m_ownerName.clear();
m_gameData.clear(); m_gameData.clear();
m_description.clear(); m_description.clear();
} }
bool GameSession::IsJoinable( sptr_user user ) const
{
if( user )
{
if( user->m_memberId >= 0 )
return false;
for( const auto &m : m_members )
{
if( m.expired() )
continue;
const auto &member = m.lock();
if( member->m_sessionId == user->m_sessionId )
{
return false;
}
}
}
return ( m_state == GameState::Open && m_currentPlayers < m_maximumPlayers );
}
sptr_user GameSession::GetOwner() const
{
if( !m_members[ 0 ].expired() )
{
return m_members[ 0 ].lock();
}
return nullptr;
}
sptr_user GameSession::GetMember( int32_t index ) const
{
if( index < 0 || index >= static_cast< int32_t >( m_members.size() ) )
return nullptr;
if( !m_members[ index ].expired() )
{
return m_members[ index ].lock();
}
return nullptr;
}
sptr_user GameSession::GetMemberBySessionId( const std::wstring &sessionId ) const
{
for( const auto &m : m_members )
{
if( m.expired() )
continue;
const auto &member = m.lock();
if( member->m_sessionId == sessionId )
{
return member;
}
}
return nullptr;
}
std::vector<sptr_user> GameSession::GetMembers() const
{
std::vector< sptr_user > members;
for( const auto &m : m_members )
{
if( !m.expired() )
{
members.push_back( m.lock() );
}
}
return members;
}
bool GameSession::AddMember( sptr_user user )
{
if( !user || user->m_memberId >= 0 )
return false;
int8_t freeIndex = -1;
for( int8_t i = 0; i < static_cast< int8_t >( m_members.size() ); ++i )
{
auto memberPtr = m_members[ i ].lock();
if( memberPtr )
{
if( memberPtr->m_sessionId == user->m_sessionId )
return false;
}
else if( freeIndex == -1 )
{
freeIndex = i;
}
}
if( freeIndex == -1 )
{
Log::Error( "Game session is full! [{}]", m_gameName );
return false;
}
user->m_memberId = freeIndex;
user->m_gameId = m_gameId;
m_members[ freeIndex ] = user;
m_currentPlayers++;
Log::Info( "Added user [{}] to game session [{}] at index {}",
user->m_username, m_gameName, freeIndex );
return true;
}
bool GameSession::RemoveMember( sptr_user user )
{
if( !user || user->m_memberId < 0 || user->m_memberId >= static_cast< int8_t >( m_members.size() ) )
return false;
int8_t index = static_cast< int8_t >( user->m_memberId );
auto memberPtr = m_members[ index ].lock();
if( !memberPtr || memberPtr->m_sessionId != user->m_sessionId )
{
Log::Error( "User [{}] not found in game session [{}] at index {}",
user->m_username, m_gameName, index );
return false;
}
user->m_memberId = -1;
user->m_gameId = -1;
m_members[ index ].reset();
m_currentPlayers--;
Log::Info( "Removed user [{}] from game session [{}] at index {}",
user->m_username, m_gameName, index );
return true;
}

View File

@@ -1,5 +1,7 @@
#pragma once #pragma once
#include <array>
#include <vector>
#include <string> #include <string>
#include <memory> #include <memory>
@@ -7,42 +9,57 @@
class GameSession { class GameSession {
public: public:
GameSession(); enum class GameType {
~GameSession();
enum class GameType
{
Public, Public,
Private Private
}; };
enum class GameState enum class GameState {
{
NotReady, NotReady,
Open, Open,
Started Started
}; };
GameSession( uint32_t index );
~GameSession();
bool IsJoinable( sptr_user user = nullptr ) const;
sptr_user GetOwner() const;
sptr_user GetMember( int32_t index ) const;
sptr_user GetMemberBySessionId( const std::wstring &sessionId ) const;
std::vector< sptr_user > GetMembers() const;
bool AddMember( sptr_user user );
bool RemoveMember( sptr_user user );
public:
GameType m_type; GameType m_type;
GameState m_state; GameState m_state;
std::weak_ptr< RealmUser > m_owner; std::array< wptr_user, 4 > m_members;
int32_t m_gameIndex; int32_t m_gameId;
std::wstring m_gameName; std::wstring m_gameName;
std::wstring m_ownerName; std::wstring m_ownerName;
std::wstring m_playerCount; std::wstring m_playerCount;
std::string m_gameData; std::string m_gameData;
std::string m_description; std::string m_description;
std::string m_hostLocalAddr; std::string m_hostLocalAddr;
std::string m_hostExternalAddr; std::string m_hostExternalAddr;
int32_t m_hostPort; int32_t m_hostLocalPort;
int32_t m_hostNatPort;
int8_t m_currentPlayers; int8_t m_currentPlayers;
int8_t m_maximumPlayers; int8_t m_maximumPlayers;
int8_t m_difficulty;
int8_t m_gameMode;
int8_t m_mission;
int8_t m_unknown;
int8_t m_networkSave;
}; };
typedef std::shared_ptr< GameSession > sptr_game_session; typedef std::shared_ptr< GameSession > sptr_game_session;

View File

@@ -1,17 +1,16 @@
#include "GameSessionManager.h" #include "GameSessionManager.h"
#include "RealmUser.h" #include "RealmUser.h"
#include "../Network/Event/NotifyGameDiscovered.h"
#include "../Network/Event/NotifyClientDiscovered.h" #include "../Network/Event/NotifyClientDiscovered.h"
#include "../Network/Event/NotifyClientDiscovered_RTA.h" #include "../Network/Event/NotifyClientDiscovered_RTA.h"
#include "../Network/Event/NotifyClientRequestConnect.h" #include "../Network/Event/NotifyClientRequestConnect.h"
#include "../Network/Event/NotifyClientRequestConnect_RTA.h" #include "../Network/Event/NotifyClientRequestConnect_RTA.h"
#include "../Network/Event/NotifyGameDiscovered.h"
#include "../Network/Event/NotifyReserveUserSlot_RTA.h"
#include "../../logging.h" #include "../../logging.h"
GameSessionManager::GameSessionManager() GameSessionManager::GameSessionManager()
{ {
m_gameIndex = 0; m_uniqueGameIndex = 0;
m_gameSessionList[ 0 ].clear(); m_gameSessionList[ 0 ].clear();
m_gameSessionList[ 1 ].clear(); m_gameSessionList[ 1 ].clear();
} }
@@ -32,86 +31,101 @@ void GameSessionManager::OnDisconnectUser( sptr_user user )
if( !session ) if( !session )
return; return;
auto owner = session->m_owner.lock(); const auto owner = session->GetOwner();
if( !owner ) if( !owner )
{ {
Log::Error( "Game session owner not found! [%d]", gameId ); Log::Error( "Game session owner not found! [{}]", gameId );
ForceTerminateGame( gameId, gameType ); ForceTerminateGame( gameId, gameType );
return; return;
} }
if( owner->m_sessionId == user->m_sessionId ) if( owner->m_sessionId == user->m_sessionId )
{ {
Log::Info( "Game session owner disconnected! [%d]", gameId ); Log::Info( "Game session owner disconnected! [{}]", gameId );
ForceTerminateGame( gameId, gameType ); ForceTerminateGame( gameId, gameType );
} }
} }
bool GameSessionManager::CreatePublicGameSession( sptr_user owner, std::wstring gameName, RealmGameType clientType ) bool GameSessionManager::CreateGameSession_CON( sptr_user user,
const std::wstring gameInfo,
const std::wstring name,
const std::wstring stage,
bool isPrivateGame )
{ {
auto new_session = std::make_shared< GameSession >(); if( name.empty() )
{
Log::Error( "Invalid parameters for creating game session!" );
return false;
}
new_session->m_type = GameSession::GameType::Public; auto new_session = std::make_shared< GameSession >( m_uniqueGameIndex++ );
new_session->m_gameIndex = m_gameIndex;
new_session->m_hostLocalAddr.clear();
new_session->m_hostExternalAddr.clear();
new_session->m_gameName = gameName;
new_session->m_currentPlayers = 1;
new_session->m_maximumPlayers = 4;
new_session->m_gameData.resize( 256 ); if( isPrivateGame )
{
new_session->m_type = GameSession::GameType::Private;
new_session->m_gameName = name;
}
else
{
new_session->m_type = GameSession::GameType::Public;
new_session->m_gameName = name + L" [" + stage + L"]";
}
owner->m_isHost = true; user->m_isHost = true;
owner->m_discoveryAddr = ""; user->m_gameId = new_session->m_gameId;
user->m_discoveryAddr = "";
user->m_discoveryPort = 0;
owner->m_gameId = m_gameIndex; new_session->AddMember( user );
new_session->m_owner = owner;
std::lock_guard< std::mutex > lock( m_dataMutex ); std::lock_guard< std::mutex > lock( m_dataMutex );
m_gameSessionList[ clientType ].push_back( new_session ); m_gameSessionList[ RealmGameType::CHAMPIONS_OF_NORRATH ].push_back( new_session );
m_gameIndex++;
return true; return true;
} }
bool GameSessionManager::CreatePrivateGameSession( sptr_user owner, std::wstring gameName, RealmGameType clientType ) bool GameSessionManager::CreateGameSession_RTA(
sptr_user user,
const std::wstring gameInfo,
const std::wstring name,
const std::array< int8_t, 5 > &attributes,
const bool isPrivateGame )
{ {
// Check if the game name or host session id is already in use if( nullptr != FindGame( name, RealmGameType::RETURN_TO_ARMS ) )
for( const auto &gameSession : m_gameSessionList[ clientType ] )
{ {
if( gameSession->m_type != GameSession::GameType::Private ) Log::Error( "Game name is already in use! [{}]", name );
continue; return false;
if( gameSession->m_gameName == gameName )
{
Log::Error( "Game name is already in use! [%S]", gameName.c_str() );
return false;
}
} }
auto new_session = std::make_shared< GameSession >(); auto new_session = std::make_shared< GameSession >( m_uniqueGameIndex++ );
new_session->m_type = GameSession::GameType::Private; if( isPrivateGame )
new_session->m_gameIndex = m_gameIndex; {
new_session->m_hostLocalAddr.clear(); new_session->m_type = GameSession::GameType::Private;
new_session->m_hostExternalAddr.clear(); }
new_session->m_gameName = gameName; else
new_session->m_currentPlayers = 1; {
new_session->m_maximumPlayers = 4; new_session->m_type = GameSession::GameType::Public;
new_session->m_gameData.resize( 256 ); new_session->m_gameData = Util::WideToUTF8( gameInfo );
new_session->m_difficulty = attributes[ 0 ];
new_session->m_gameMode = attributes[ 1 ];
new_session->m_unknown = attributes[ 2 ];
new_session->m_mission = attributes[ 3 ];
new_session->m_networkSave = attributes[ 4 ];
}
owner->m_isHost = true; new_session->m_gameName = name;
owner->m_discoveryAddr = "";
owner->m_gameId = m_gameIndex; user->m_isHost = true;
new_session->m_owner = owner; user->m_gameId = new_session->m_gameId;
user->m_discoveryAddr = "";
user->m_discoveryPort = 0;
new_session->AddMember( user );
std::lock_guard< std::mutex > lock( m_dataMutex ); std::lock_guard< std::mutex > lock( m_dataMutex );
m_gameSessionList[ clientType ].push_back( new_session ); m_gameSessionList[ RealmGameType::RETURN_TO_ARMS ].push_back( new_session );
m_gameIndex++;
return true; return true;
} }
@@ -128,7 +142,7 @@ bool GameSessionManager::ForceTerminateGame( int32_t gameId, RealmGameType clien
const auto &gameList = m_gameSessionList[ clientType ]; const auto &gameList = m_gameSessionList[ clientType ];
const auto it = std::find_if( gameList.begin(), gameList.end(), [ &gameId ]( sptr_game_session gameSession ) const auto it = std::find_if( gameList.begin(), gameList.end(), [ &gameId ]( sptr_game_session gameSession )
{ {
return gameSession->m_gameIndex == gameId; return gameSession->m_gameId == gameId;
} ); } );
if( it != m_gameSessionList[ clientType ].end() ) if( it != m_gameSessionList[ clientType ].end() )
@@ -148,7 +162,7 @@ sptr_game_session GameSessionManager::FindGame( const int32_t gameId, const Real
for( auto &gameSession : m_gameSessionList[ gameType ] ) for( auto &gameSession : m_gameSessionList[ gameType ] )
{ {
if( gameSession->m_gameIndex == gameId ) if( gameSession->m_gameId == gameId )
{ {
return gameSession; return gameSession;
} }
@@ -182,7 +196,7 @@ bool GameSessionManager::RequestOpen( sptr_user user )
if( session == nullptr ) if( session == nullptr )
{ {
Log::Error( "Game session not found! [%d]", gameId ); Log::Error( "Game session not found! [{}]", gameId );
return false; return false;
} }
@@ -193,13 +207,15 @@ bool GameSessionManager::RequestOpen( sptr_user user )
if( user->m_discoveryAddr.empty() ) if( user->m_discoveryAddr.empty() )
{ {
Log::Error( "User discovery address is empty! [%d]", gameId ); Log::Error( "User discovery address is empty! [{}]", gameId );
return false; return false;
} }
session->m_hostExternalAddr = user->m_discoveryAddr;
session->m_hostLocalAddr = user->m_localAddr; session->m_hostLocalAddr = user->m_localAddr;
session->m_hostPort = user->m_discoveryPort; session->m_hostLocalPort = user->m_localPort;
session->m_hostExternalAddr = user->m_discoveryAddr;
session->m_hostNatPort = user->m_discoveryPort;
session->m_state = GameSession::GameState::Open; session->m_state = GameSession::GameState::Open;
@@ -207,14 +223,11 @@ bool GameSessionManager::RequestOpen( sptr_user user )
NotifyGameDiscovered msg( user->m_discoveryAddr, user->m_discoveryPort, user->m_gameType ); NotifyGameDiscovered msg( user->m_discoveryAddr, user->m_discoveryPort, user->m_gameType );
user->sock->send( msg ); user->sock->send( msg );
Log::Info( "Game Session [%d] Discoverable on %s", gameId, user->m_discoveryAddr.c_str() ); Log::Info( "Game Session [{}] Discoverable on {}", gameId, user->m_discoveryAddr );
return true; return true;
} }
// NOTE:
// This might solely be for a user that is LEAVING the game (I.E "CancelJoining")
// instead of a game being cancelled overall. RTA has a dedicated endgame event.
bool GameSessionManager::RequestCancel( sptr_user user ) bool GameSessionManager::RequestCancel( sptr_user user )
{ {
if( !user || user->m_gameId < 0 ) if( !user || user->m_gameId < 0 )
@@ -229,7 +242,7 @@ bool GameSessionManager::RequestCancel( sptr_user user )
const auto it = std::find_if( gameList.begin(), gameList.end(), const auto it = std::find_if( gameList.begin(), gameList.end(),
[ gameId ]( const sptr_game_session &gameSession ) [ gameId ]( const sptr_game_session &gameSession )
{ {
return gameSession->m_gameIndex == gameId; return gameSession->m_gameId == gameId;
} ); } );
if( it == gameList.end() ) if( it == gameList.end() )
@@ -237,21 +250,22 @@ bool GameSessionManager::RequestCancel( sptr_user user )
const auto &session = *it; const auto &session = *it;
auto owner = session->m_owner.lock(); if( false == session->RemoveMember( user ) )
if( !owner )
{ {
Log::Error( "Game session owner not found! [%d]", gameId ); Log::Error( "Failed to remove user [{}] from game session [{}]", user->m_username, gameId );
ForceTerminateGame( gameId, gameType );
return false;
} }
if( owner->m_sessionId != user->m_sessionId ) if( session->m_currentPlayers <= 0 )
{ {
Log::Error( "User is not the host! [%d]", gameId ); Log::Info( "Game session [{}] is empty, removing it", gameId );
return false; gameList.erase( it );
}
else
{
Log::Info( "User [{}] left game session [{}], remaining players: {}",
user->m_username, gameId, session->m_currentPlayers );
} }
gameList.erase( it );
return true; return true;
} }
@@ -263,28 +277,28 @@ bool GameSessionManager::RequestJoin( sptr_user join_user )
if( session == nullptr ) if( session == nullptr )
{ {
Log::Error( "Game session not found! [%d]", gameId ); Log::Error( "Game session not found! [{}]", gameId );
return false; return false;
} }
if( session->m_state != GameSession::GameState::Open ) if( session->m_state != GameSession::GameState::Open )
{ {
Log::Error( "Game session not open! [%d]", gameId ); Log::Error( "Game session not open! [{}]", gameId );
return false; return false;
} }
auto host_user = session->m_owner.lock(); auto host_user = session->GetOwner();
if( host_user == nullptr ) if( host_user == nullptr )
{ {
Log::Error( "Host not found! [%d]", gameId ); Log::Error( "Host not found! [{}]", gameId );
ForceTerminateGame( gameId, gameType ); ForceTerminateGame( gameId, gameType );
return false; return false;
} }
if( host_user->m_discoveryAddr.empty() ) if( host_user->m_discoveryAddr.empty() )
{ {
Log::Error( "User discovery address is empty! [%d]", gameId ); Log::Error( "User discovery address is empty! [{}]", gameId );
ForceTerminateGame( gameId, gameType ); ForceTerminateGame( gameId, gameType );
return false; return false;
} }
@@ -300,7 +314,7 @@ bool GameSessionManager::RequestJoin( sptr_user join_user )
ProcessJoinArms( join_user, host_user ); ProcessJoinArms( join_user, host_user );
} }
Log::Info( "User [%S] Joining game session... [%d]", join_user->m_sessionId.c_str(), gameId ); Log::Info( "User [{}] Joining game session... [{}]", join_user->m_sessionId, gameId );
return true; return true;
} }
@@ -308,16 +322,16 @@ bool GameSessionManager::RequestJoin( sptr_user join_user )
// NOTE: // NOTE:
// Request Start seems to be for RTA only. // Request Start seems to be for RTA only.
// CON will disconnect from the server at start time. // CON will disconnect from the server at start time.
bool GameSessionManager::RequestStart(sptr_user user) bool GameSessionManager::RequestStart( sptr_user user )
{ {
const auto gameId = user->m_gameId; const auto gameId = user->m_gameId;
const auto gameType = user->m_gameType; const auto gameType = user->m_gameType;
auto session = FindGame( gameId, gameType ); auto session = FindGame( gameId, gameType );
if( session == nullptr ) if( session == nullptr )
{ {
Log::Error( "Game session not found! [%d]", gameId ); Log::Error( "Game session not found! [{}]", gameId );
return false; return false;
} }
@@ -325,13 +339,13 @@ bool GameSessionManager::RequestStart(sptr_user user)
session->m_state = GameSession::GameState::Started; session->m_state = GameSession::GameState::Started;
// Temp (or permanent) remove the game from the list. // Remove the game from the list.
auto &gameList = m_gameSessionList[ gameType ]; auto &gameList = m_gameSessionList[ gameType ];
const auto it = std::find_if( gameList.begin(), gameList.end(), const auto it = std::find_if( gameList.begin(), gameList.end(),
[ gameId ]( const sptr_game_session &gameSession ) [ gameId ]( const sptr_game_session &gameSession )
{ {
return gameSession->m_gameIndex == gameId; return gameSession->m_gameId == gameId;
} ); } );
if( it != gameList.end() ) if( it != gameList.end() )
@@ -339,7 +353,7 @@ bool GameSessionManager::RequestStart(sptr_user user)
gameList.erase( it ); gameList.erase( it );
} }
Log::Info( "Game session [%d] started", gameId ); Log::Info( "Game session [{}] started", gameId );
return true; return true;
} }
@@ -386,56 +400,30 @@ std::vector<sptr_game_session> GameSessionManager::GetPrivateGameSessionList( co
return list; return list;
} }
void GameSessionManager::ProcessJoinNorrath(sptr_user join, sptr_user host) void GameSessionManager::ProcessJoinNorrath( sptr_user join, sptr_user host )
{ {
std::string hostAddr = host->m_discoveryAddr; // Tell the joining user its own address
std::string joinAddr = join->m_discoveryAddr; NotifyClientDiscovered msgClientDiscovered( join );
join->sock->send( msgClientDiscovered );
if (hostAddr == joinAddr)
{
hostAddr = host->m_localAddr;
// I don't think the joiner ever reports its local address for CON.
// At best, we can report the hosts local IP and hope communication works.
}
// Tell the joining user the hosts address.
NotifyClientDiscovered msgClientDiscovered( hostAddr, host->m_discoveryPort );
join->sock->send(msgClientDiscovered);
// Tell the host the joining user's address. // Tell the host the joining user's address.
NotifyClientRequestConnect msgNotifyReqConnect( NotifyClientRequestConnect msgNotifyReqConnect( join );
joinAddr, host->sock->send( msgNotifyReqConnect );
join->m_discoveryPort
);
host->sock->send(msgNotifyReqConnect);
} }
void GameSessionManager::ProcessJoinArms(sptr_user join, sptr_user host) void GameSessionManager::ProcessJoinArms( sptr_user join, sptr_user host )
{ {
std::string hostAddr = host->m_discoveryAddr; Log::Debug("Join User IPs : [{}:{}] -> [{}:{}]",
std::string joinAddr = join->m_discoveryAddr; join->m_localAddr, join->m_localPort, join->m_discoveryAddr, join->m_discoveryPort );
if (hostAddr == joinAddr) Log::Debug("Host User IPs : [{}:{}] -> [{}:{}]",
{ host->m_localAddr, host->m_localPort, host->m_discoveryAddr, host->m_discoveryPort );
hostAddr = host->m_localAddr;
joinAddr = join->m_localAddr;
}
// Tell the joining user the hosts address. // Tell the joining user its own address
NotifyClientDiscovered_RTA msgClientDiscovered(hostAddr, host->m_discoveryPort); NotifyClientDiscovered_RTA msgClientDiscovered( join );
join->sock->send(msgClientDiscovered); join->sock->send( msgClientDiscovered );
// Reserve a slot for the joining user.
NotifyReserveUserSlot_RTA msgNotifyReserveUser(joinAddr, join->m_discoveryPort);
host->sock->send(msgNotifyReserveUser);
// Tell the host the joining user's address. // Tell the host the joining user's address.
NotifyClientRequestConnect_RTA msgNotifyReqConnect( NotifyClientRequestConnect_RTA msgNotifyReqConnect( join );
joinAddr, host->sock->send( msgNotifyReqConnect );
join->m_discoveryAddr,
join->m_discoveryPort
);
host->sock->send(msgNotifyReqConnect);
} }

View File

@@ -6,13 +6,15 @@
#include "GameSession.h" #include "GameSession.h"
#include "../Common/Constant.h"
class GameSessionManager { class GameSessionManager {
private: private:
static inline std::unique_ptr< GameSessionManager > m_instance; static inline std::unique_ptr< GameSessionManager > m_instance;
static inline std::mutex m_mutex; static inline std::mutex m_mutex;
static inline std::mutex m_dataMutex; static inline std::mutex m_dataMutex;
int32_t m_gameIndex; int32_t m_uniqueGameIndex;
std::vector< sptr_game_session > m_gameSessionList[ 2 ]; std::vector< sptr_game_session > m_gameSessionList[ 2 ];
public: public:
@@ -34,8 +36,18 @@ public:
void OnDisconnectUser( sptr_user user ); void OnDisconnectUser( sptr_user user );
bool CreatePublicGameSession( sptr_user user, const std::wstring gameName, const RealmGameType clientType ); bool CreateGameSession_CON( sptr_user user,
bool CreatePrivateGameSession( sptr_user user, const std::wstring gameName, const RealmGameType clientType ); const std::wstring gameInfo,
const std::wstring name,
const std::wstring stage,
const bool isPrivateGame );
bool CreateGameSession_RTA( sptr_user user,
const std::wstring gameInfo,
const std::wstring name,
const std::array< int8_t, 5 > &attributes,
const bool isPrivateGame );
bool ForceTerminateGame( const int32_t gameId, RealmGameType clientType ); bool ForceTerminateGame( const int32_t gameId, RealmGameType clientType );
sptr_game_session FindGame( const int32_t gameId, RealmGameType clientType ); sptr_game_session FindGame( const int32_t gameId, RealmGameType clientType );
sptr_game_session FindGame( const std::wstring &gameName, RealmGameType clientType ); sptr_game_session FindGame( const std::wstring &gameName, RealmGameType clientType );