Files
Sun1602/Server/Common/ServerFrame.h
T
2022-10-26 12:25:11 +08:00

241 lines
8.8 KiB
C++

#pragma once
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
/// ServerFrame class
/**
@author Kim Min Wook < taiyo@webzen.com >
@since 2006. 8. 22
@remark
- 서버 프레임 워크의 최상위 클래스
@note
- 하위 클래스에서 구현 해야 한다.
@history
- 2006.10.30~ : (Waverix) 자잘한 기능 및 버그 수정
- 2007.11.05 : (Waverix) 코드 정리 및 Append Assertion Log Handler on Release Mode
*/
//=============================================================================================================================
#include <ServerStruct.h>
#include <IOCPServer.h>
#include <Timer.h>
#include <hash_map>
#include <algorithm>
#include "ReadyState.h"
#ifdef _JP_0_20101123_PMS
#include "pms/PMSManager.h"
#endif
//==================================================================================================
//
class ServerSession;
class NetworkObject;
struct MSG_BASE;
struct MSG_BASE_INTERNAL;
enum eSERVER_MODE
{
eSERVER_DEV = 1, // 개발용으로 서버를 작동
eSERVER_INTRAOFFICE, // 사내용으로 서버를 작동
eSERVER_LIVE, // 실제 서비스용으로 서버를 작동
eSERVER_TESTLIVE,
eSERVER_UPPERBOUND,
};
enum eIOHANDLER
{
SERVER_IOHANDLER = 0x01,
CLIENT_IOHANDLER = 0x02,
};
#define __READ_CONFIG_NUMBER( outValue, szSectionName, keyName, defValue, ini ) \
outValue = GetPrivateProfileInt( szSectionName, keyName, defValue, ini)
#define __READ_CONFIG_STRING( outString, szSectionName, keyName, defValue, ini ) \
GetPrivateProfileString( szSectionName, keyName, defValue, outString, 256, ini)
#define __READ_CONFIG_STRING_IP( outString, szSectionName, keyName, defValue, ini ) \
GetPrivateProfileString( szSectionName, keyName, defValue, outString, 16, ini)
#define P_SUCCESS DISPMSG("냥묘!\n")
#define P_FAILED DISPMSG("呵겨!\n")
//==================================================================================================
namespace util {
;
struct ServerTimeInfoPerFrame : public util::TimeInfoPerFrame
{
void Init();
void Update();
//
ulong aging_counter_; // increasing 1 per second
// (CHANGES) (f100415.1L) (WAVERIX) fix up delta tick error related to degree of accuracy
LARGE_INTEGER time_counter_for_start_;
LARGE_INTEGER time_counter_for_latest_;
LARGE_INTEGER frequency_; // TODO(WAVERIX) change access authorization to private
};
}; //end of namespace
//==================================================================================================
//
class ServerFrame
{
protected: typedef STLX_HASH_MAP<DWORD, ServerSession *> SERVER_MAP;
public: ServerFrame(VOID);
virtual ~ServerFrame(VOID);
public: BOOL DoInit(
const CHAR* Name,
fnCallBackCreateAcceptedObject FnAllocAcceptServer,
fnCallBackDestroyAcceptedObject FnFreeAcceptServer,
fnCallBackDestroyConnectedObject FnFreeConnectServer,
fnCallBackCreateAcceptedObject FnAllocAcceptClient,
fnCallBackDestroyAcceptedObject FnFreeAcceptClient,
fnCallBackDestroyConnectedObject FnFreeConnectClient
);
VOID DoRelease();
VOID DoProcess();
BOOL DoUpdate();
__inline VOID Shutdown() { m_bShutdown = TRUE; }
__inline BOOL IsServerInfoFromFile() { return m_bGetServerInfoFromFile; }
virtual eSERVER_TYPE GetServerType() = 0;
VOID UpdateAppTitle();
__inline ServerSession* FindSession( DWORD idx )
{
SERVER_MAP::iterator it = m_SessionMap.find( idx );
return (it != m_SessionMap.end()) ? it->second : NULL ;
}
// 좋은 방법은 아니나, 이것에 관련해 접근하는 방법이 각 Session*로 시작하는 for_each외에 없는 관계로...-_-;
// 아님 아래 주석과 같은 시작,끝 만을 얻어서 사용할까?
__inline SERVER_MAP& GetSessionList() { return m_SessionMap; }
// connection이 이루어졌을 때
__inline VOID AddSession( DWORD idx, ServerSession* pSession ) { std::pair<SERVER_MAP::iterator,bool> rt = m_SessionMap.insert( SERVER_MAP::value_type(idx, pSession) ); ASSERT(rt.second);
#ifdef _JP_0_20101123_PMS
SetTotalNumberOfConnections();
#endif
}
// connection이 끊어졌을 때
__inline VOID RemoveSession( DWORD idx ) { m_SessionMap.erase(idx);
#ifdef _JP_0_20101123_PMS
SetTotalNumberOfConnections();
#endif
}
VOID AddConnectionlessConnector( ServerSession* pSession );
__inline VOID RemoveConnectionlessConnector( DWORD idx ) { m_ConnectionlessMap.erase(idx); }
BOOL SendToSession( DWORD idx, MSG_BASE_INTERNAL* pMsg, WORD wSize );
VOID SendToSessionType( eSERVER_TYPE type, MSG_BASE_INTERNAL* pMsg, WORD wSize, DWORD dwExceptIndex=0 );
BOOL SendToSession( DWORD idx, MSG_BASE* pMsg, WORD wSize );
VOID SendToSessionType( eSERVER_TYPE type, MSG_BASE* pMsg, WORD wSize, DWORD dwExceptIndex=0 );
virtual VOID SendServerType( ServerSession* pSession );
virtual ServerSession* AllocServerSession( eSERVER_TYPE ) = 0;
virtual VOID FreeServerSession( ServerSession* ) = 0;
BOOL IsListening( DWORD dwKey );
VOID Listen( DWORD dwKey );
VOID SuspendListenThread( DWORD dwKey );
VOID ResumeListenThread( DWORD dwKey );
ReadyState & GetReadyState() { return m_ReadyState; }
ServerSession* InitConnectSession( eSERVER_TYPE type, CHAR* pszIP, WORD wPort );
__inline SERVER_KEY GetKey() { return m_Key; }
__inline DWORD GetGuid() { return m_Guid; }
__inline eSERVER_MODE GetMode() { return (eSERVER_MODE)m_Mode; }
#ifdef _JP_0_20101123_PMS
__inline PMSManager* GetPMSManager() {return &pms_manager_;}
VOID SetTotalNumberOfConnections();
VOID DisplayPMSInfo();
#endif
__inline VOID SetGuid( DWORD guid ) { m_Guid = guid; }
__inline VOID SetKey( SERVER_KEY key ) { m_Key = key;
#ifdef _JP_0_20101123_PMS
pms_manager_.SetCategory(key.m_dwKey);
#endif
}
__inline VOID SetListenIP_s( const CHAR* ip ) { strncpy( m_pszListenIP_s, ip, 16 ); m_pszListenIP_s[15] = '\0'; }
__inline VOID SetListenIP_c( const CHAR* ip ) { strncpy( m_pszListenIP_c, ip, 16 ); m_pszListenIP_c[15] = '\0'; }
__inline VOID SetListenPort_s( const WORD port ) { m_wListenPort_s = port; }
__inline VOID SetListenPort_c( const WORD port ) { m_wListenPort_c = port; }
__inline const WORD GetListenPort_s() { return m_wListenPort_s; }
__inline const WORD GetListenPort_c() { return m_wListenPort_c; }
inline VOID StartNetworkBlock4Closing() { m_bNetworkBlock4Closing = TRUE; }
const util::ServerTimeInfoPerFrame& GetTimeInfoPerFrame() const;
template<typename _OPERATOR>
VOID for_each( _OPERATOR& op );
protected:
VOID FrameCheck();
VOID DisplayAppInfo( BOOL bLog = FALSE );
VOID DisplayServerList();
VOID MaintainConnection();
BOOL ProcessConsole();
VOID Listen( DWORD dwKey, const CHAR* ip, WORD port );
VOID Connect( INT Num );
VOID Connect( ServerSession* pNetObject );
VOID RunUnitTest();
virtual BOOL Init() = 0;
virtual BOOL Update( DWORD tick ) = 0;
virtual VOID Release() = 0;
virtual BOOL KeyEvent(CHAR ch) { ch; return TRUE; }
__inline const CHAR* GetDescFileName() { return m_pszDescFileName; }
__inline const CHAR* GetListenIP_s() { return m_pszListenIP_s; }
__inline const CHAR* GetListenIP_c() { return m_pszListenIP_c; }
__inline IOCPServer* GetIOCPServer() { return m_pIOCPServer; }
private:
BOOL _Update();
private: DWORD m_Guid;
SERVER_KEY m_Key;
INT m_Mode;
INT m_HandlerMask;
BOOL m_bShutdown;
BOOL m_bNetworkBlock4Closing;
protected: util::Timer m_ReconnectTimer;
private: DWORD m_dwFPS;
IOCPServer* m_pIOCPServer;
BOOL m_bGetServerInfoFromFile;
CHAR m_pszListenIP_s[16];
WORD m_wListenPort_s;
CHAR m_pszListenIP_c[16];
WORD m_wListenPort_c;
CHAR m_pszDescFileName[64];
// Connection이 연결된 세션을 가진 리스트
SERVER_MAP m_SessionMap; //< connection이 유지된 세션의 리스트
SERVER_MAP m_ConnectionlessMap;
ReadyState m_ReadyState;
#ifdef _JP_0_20101123_PMS
PMSManager pms_manager_;
#endif
public: //temporary
const LARGE_INTEGER& m_freq; // TODO(WAVERIX) change access authorization to private
private:
// CHANGES: f110805.1L, globally server time information accessability per frame.
util::ServerTimeInfoPerFrame time_info_per_frame_;
//
__DISABLE_COPY(ServerFrame);
};
template<typename _OPERATOR>
VOID ServerFrame::for_each( _OPERATOR& op )
{
std::for_each( m_SessionMap.begin(), m_SessionMap.end(),
compose1( op, select2nd<SERVER_MAP::value_type>() ) );
}
inline const util::ServerTimeInfoPerFrame& ServerFrame::GetTimeInfoPerFrame() const {
return time_info_per_frame_;
};