Big Refactor.

General support for encryption and decryption.
Game Session creation.
Discovery Server.

Still broken as hell, but less so?
This commit is contained in:
HikikoMarmy
2024-12-25 01:20:12 +00:00
parent 8b154e614f
commit a0a363b7d0
88 changed files with 4595 additions and 1600 deletions

0
Game/GameSession.cpp Normal file
View File

51
Game/GameSession.h Normal file
View File

@@ -0,0 +1,51 @@
#pragma once
#include <string>
#include <array>
class GameSession {
public:
GameSession()
{
m_gameIndex = 0;
m_minimumLevel = 0;
m_maximumLevel = 0;
m_hostSessionId = L"";
m_gameName = L"";
m_userList.fill( nullptr );
}
~GameSession()
{
}
sptr_user GetOwner()
{
return m_userList[ 0 ];
}
sptr_user GetUser( const size_t index )
{
if( index < 0 || index >= m_userList.size() )
{
return nullptr;
}
return m_userList[ index ];
}
int32_t m_gameIndex;
std::wstring m_hostSessionId;
std::wstring m_gameName;
int32_t m_minimumLevel;
int32_t m_maximumLevel;
// User Information
std::array< sptr_user, 4 > m_userList;
};
typedef std::shared_ptr< GameSession > sptr_game_session;

165
Game/GameSessionManager.cpp Normal file
View File

@@ -0,0 +1,165 @@
#include "../global_define.h"
#include "GameSessionManager.h"
GameSessionManager::GameSessionManager()
{
m_gameIndex = 0;
m_publicGameSessionList.clear();
m_privateGameSessionList.clear();
}
GameSessionManager::~GameSessionManager()
{
}
bool GameSessionManager::CreatePublicGameSession( sptr_user owner, std::wstring gameName, int32_t minimumLevel, int32_t maximumLevel )
{
auto &hostSessionId = owner->m_sessionId;
// Check if the host session id is already in use
for( auto &gameSession : m_publicGameSessionList )
{
if( gameSession->m_hostSessionId == hostSessionId )
{
Log::Error( "Host session id is already in use! [%S]", hostSessionId.c_str() );
return false;
}
}
auto new_session = std::make_shared< GameSession >();
new_session->m_gameIndex = m_gameIndex++;
new_session->m_hostSessionId = hostSessionId;
new_session->m_gameName = gameName;
new_session->m_minimumLevel = minimumLevel;
new_session->m_maximumLevel = maximumLevel;
new_session->m_userList[ 0 ] = owner;
m_publicGameSessionList.push_back( new_session );
return true;
}
bool GameSessionManager::CreatePrivateGameSession( sptr_user owner, std::wstring gameName, int32_t minimumLevel, int32_t maximumLevel )
{
auto &hostSessionId = owner->m_sessionId;
// Check if the game name or host session id is already in use
for( auto &gameSession : m_privateGameSessionList )
{
if( gameSession->m_hostSessionId == hostSessionId )
{
Log::Error( "Host session id is already in use! [%S]", hostSessionId.c_str() );
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 >();
new_session->m_gameIndex = -1;
new_session->m_hostSessionId = hostSessionId;
new_session->m_gameName = gameName;
new_session->m_minimumLevel = minimumLevel;
new_session->m_maximumLevel = maximumLevel;
m_privateGameSessionList.push_back( new_session );
return false;
}
bool GameSessionManager::UpdateGameSessionDiscovery( sptr_user owner, std::string hostIp, int32_t hostPort )
{
auto &hostSessionId = owner->m_sessionId;
for( auto &gameSession : m_publicGameSessionList )
{
if( gameSession->m_hostSessionId == hostSessionId )
{
//gameSession->m_hostIp = hostIp;
//gameSession->m_hostPort = hostPort;
return true;
}
}
for( auto &gameSession : m_privateGameSessionList )
{
if( gameSession->m_hostSessionId == hostSessionId )
{
//gameSession->m_hostIp = hostIp;
//gameSession->m_hostPort = hostPort;
return true;
}
}
Log::Error( "Failed to update game session discovery information! [%S]", hostSessionId.c_str() );
return false;
}
sptr_game_session GameSessionManager::FindGame( const std::wstring sessionId )
{
for( auto &gameSession : m_publicGameSessionList )
{
if( gameSession->m_hostSessionId == sessionId )
{
return gameSession;
}
}
for( auto &gameSession : m_privateGameSessionList )
{
if( gameSession->m_hostSessionId == sessionId )
{
return gameSession;
}
}
return nullptr;
}
sptr_game_session GameSessionManager::FindGame( const int32_t gameId )
{
for( auto &gameSession : m_publicGameSessionList )
{
if( gameSession->m_gameIndex == gameId )
{
return gameSession;
}
}
return nullptr;
}
bool GameSessionManager::UserJoinGame( const int32_t gameId, sptr_user joiningUser )
{
auto gameSession = FindGame( gameId );
if( gameSession == nullptr )
{
Log::Error( "Game session not found! [%d]", gameId );
return false;
}
for( auto &user : gameSession->m_userList )
{
if( user == nullptr )
{
user = joiningUser;
user->m_state = RealmUser::UserState::JoinPending;
return true;
}
}
Log::Error( "Game session is full! [%d]", gameId );
return false;
}

41
Game/GameSessionManager.h Normal file
View File

@@ -0,0 +1,41 @@
#pragma once
#include "GameSession.h"
class GameSessionManager {
private:
static inline std::unique_ptr< GameSessionManager > m_instance;
static inline std::mutex m_mutex;
int32_t m_gameIndex;
std::vector< sptr_game_session > m_publicGameSessionList;
std::vector< sptr_game_session > m_privateGameSessionList;
public:
GameSessionManager();
~GameSessionManager();
GameSessionManager( const GameSessionManager & ) = delete;
GameSessionManager &operator=( const GameSessionManager & ) = delete;
static GameSessionManager& Get()
{
std::lock_guard< std::mutex > lock( m_mutex );
if( m_instance == nullptr )
{
m_instance.reset( new GameSessionManager() );
}
return *m_instance;
}
public:
bool CreatePublicGameSession( sptr_user owner, std::wstring gameName, int32_t minimumLevel, int32_t maximumLevel );
bool CreatePrivateGameSession( sptr_user owner, std::wstring gameName, int32_t minimumLevel, int32_t maximumLevel );
bool UpdateGameSessionDiscovery( sptr_user owner, std::string hostIp, int32_t hostPort );
sptr_game_session FindGame( const std::wstring sessionId );
sptr_game_session FindGame( const int32_t gameId );
bool UserJoinGame( const int32_t gameId, sptr_user joiningUser );
};

28
Game/RealmUser.cpp Normal file
View File

@@ -0,0 +1,28 @@
#include "../global_define.h"
RealmUser::RealmUser()
{
m_state = UserState::MainMenu;
m_realmSocket = nullptr;
m_discoverySocket = nullptr;
m_sessionId = L"";
}
RealmUser::~RealmUser()
{
m_state = UserState::MainMenu;
if( m_realmSocket )
{
m_realmSocket->flag.disconnected = true;
m_realmSocket.reset();
}
if( m_discoverySocket )
{
m_discoverySocket->flag.disconnected = true;
m_discoverySocket.reset();
}
m_sessionId = L"";
}

20
Game/RealmUser.h Normal file
View File

@@ -0,0 +1,20 @@
#pragma once
class RealmUser {
public:
RealmUser();
~RealmUser();
enum class UserState {
MainMenu,
JoinPending,
InGameLobby,
InGameSession,
} m_state;
sptr_tcp_socket m_realmSocket;
sptr_udp_socket m_discoverySocket;
std::wstring m_sessionId;
};
typedef std::shared_ptr< RealmUser > sptr_user;

105
Game/RealmUserManager.cpp Normal file
View File

@@ -0,0 +1,105 @@
#include "../global_define.h"
RealmUserManager::RealmUserManager()
{
m_users.clear();
}
RealmUserManager::~RealmUserManager()
{
}
std::wstring RealmUserManager::GenerateSessionId()
{
// TODO : Use something better than rand()
std::wstring sessionId;
for( int i = 0; i < MAX_SESSION_ID_LENGTH; i++ )
{
sessionId += L"0123456789ABCDEF"[ rand() % 16 ];
}
return sessionId;
}
sptr_user RealmUserManager::CreateUser( sptr_tcp_socket socket, std::wstring userId, std::wstring userPw )
{
Log::Debug( "ClientManager::CreateUser() - Created new user" );
auto user = std::make_shared< RealmUser >();
user->m_sessionId = GenerateSessionId();
user->m_realmSocket = socket;
m_users.push_back( user );
return user;
}
void RealmUserManager::RemoveUser( sptr_user user )
{
auto it = std::find( m_users.begin(), m_users.end(), user );
if( it == m_users.end() )
{
Log::Error( "RemoveUser : [%S] not found", user->m_sessionId.c_str() );
return;
}
Log::Debug( "RemoveUser : [%S]", user->m_sessionId.c_str() );
m_users.erase( it );
}
void RealmUserManager::RemoveUser( const std::wstring &sessionId )
{
auto it = std::find_if( m_users.begin(), m_users.end(), [ &sessionId ]( sptr_user user )
{
return user->m_sessionId == sessionId;
} );
if( it == m_users.end() )
{
Log::Error( "RemoveUser : [%S] not found", sessionId.c_str() );
return;
}
Log::Debug( "RemoveUser : [%S]", sessionId.c_str() );
m_users.erase( it );
}
sptr_user RealmUserManager::GetUser( const std::wstring &sessionId )
{
for( auto &user : m_users )
{
if( user->m_sessionId == sessionId )
{
return user;
}
}
return nullptr;
}
sptr_user RealmUserManager::GetUser( sptr_tcp_socket socket )
{
for( auto &user : m_users )
{
if( user->m_realmSocket == socket )
{
return user;
}
}
return nullptr;
}
sptr_user RealmUserManager::GetUser( sptr_udp_socket socket )
{
for( auto &user : m_users )
{
if( user->m_discoverySocket == socket )
{
return user;
}
}
return nullptr;
}

40
Game/RealmUserManager.h Normal file
View File

@@ -0,0 +1,40 @@
#pragma once
#include "RealmUser.h"
class RealmUserManager {
private:
static const int MAX_SESSION_ID_LENGTH = 16;
static inline std::unique_ptr< RealmUserManager > m_instance;
static inline std::mutex m_mutex;
std::vector< sptr_user > m_users;
public:
static RealmUserManager& Get()
{
std::lock_guard< std::mutex > lock( m_mutex );
if( m_instance == nullptr )
{
m_instance.reset( new RealmUserManager() );
}
return *m_instance;
}
RealmUserManager( const RealmUserManager & ) = delete;
RealmUserManager &operator=( const RealmUserManager & ) = delete;
RealmUserManager();
~RealmUserManager();
public:
static std::wstring GenerateSessionId();
sptr_user CreateUser( sptr_tcp_socket socket, std::wstring userId, std::wstring userPw );
void RemoveUser( sptr_user user );
void RemoveUser( const std::wstring &sessionId );
sptr_user GetUser( const std::wstring &sessionId );
sptr_user GetUser( sptr_tcp_socket socket );
sptr_user GetUser( sptr_udp_socket socket );
private:
};