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

488 lines
13 KiB
C++

#pragma once
#include <SSQ/SSQInfoStruct.h>
#include <PacketStruct_AG.h>
#include <PacketStruct_AW.h>
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//
//
namespace nsSSQ
{
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// <>
//
enum eCTRL_MODE_S2S {
SSQ_S2S_FIELD_CREATE = SCT_S2S,
SSQ_S2S_FIELD_CREATED ,
SSQ_S2S_FIELD_BLOCK , // 종료전 상태 복원 처리 및 더 이상의 서비스 불가 상태 처리
SSQ_S2S_FIELD_DESTORY ,
SSQ_S2S_FIELD_DESTORYED ,
SSQ_S2S_GAMBLE_START ,
SSQ_S2S_GAMBLE_RESULT ,
SSQ_S2S_BATTLE_COUNTDOWN ,
SSQ_S2S_BATTLE_PREPARATION , // A->G 전투 관련 준비 (몬스터생성 등등)
SSQ_S2S_BATTLE_START ,
SSQ_S2S_BATTLE_CANCEL ,
SSQ_S2S_BATTLE_END_REQUEST , // G->A 전투 종료 요청 (시간에 의한 경우가 아닌 상황에서...) SSQ_S2S_BATTLE_END가 돌아올 것이다.
SSQ_S2S_BATTLE_END , // 전투 종료
SSQ_S2S_BATTLE_CLEAR ,
SSQ_S2S_BATTLE_CLEARED , // G->A 종료처리 요청
SSQ_S2S_SET_CHAT_BLOCK_ZONE , // WorldServer에 해당 존은 Chatting이 되지 않도록/되도록 설정 요청
SSQ_S2S_GM_CONTROL_REQ , // GM Control
SSQ_S2S_CMS_UPPERBOUND
};
enum eCTRL_SUB_S2S {
SSQ_S2S_ZONE_SSQ_JOIN_NTF = SSQ_S2S_CMS_UPPERBOUND, // Battle->Agent
SSQ_S2S_OBSERVER_MODE_CTRL ,
SSQ_S2S_OBSERVER_MODE_RESULT ,
SSQ_S2S_OBSERVER_MODE_SELECT_WINDOW ,
SSQ_S2S_CSS_UPPERBOUND
};
BOOST_STATIC_ASSERT( SSQ_S2S_CSS_UPPERBOUND < 256 );
#undef SSQ_MODE_NODE
#define SSQ_S2S_MODE_LIST() \
SSQ_MODE_NODE( SSQ_S2S_FIELD_CREATE ) \
SSQ_MODE_NODE( SSQ_S2S_FIELD_CREATED ) \
SSQ_MODE_NODE( SSQ_S2S_FIELD_DESTORY ) \
SSQ_MODE_NODE( SSQ_S2S_FIELD_DESTORYED ) \
SSQ_MODE_NODE( SSQ_S2S_GAMBLE_START ) \
SSQ_MODE_NODE( SSQ_S2S_BATTLE_COUNTDOWN ) \
SSQ_MODE_NODE( SSQ_S2S_BATTLE_START ) \
SSQ_MODE_NODE( SSQ_S2S_BATTLE_CANCEL ) \
SSQ_MODE_NODE( SSQ_S2S_BATTLE_CLEAR ) \
SSQ_MODE_NODE( SSQ_S2S_ZONE_SSQ_JOIN_NTF )
//////////////////////////////////////////////////////////////////////////
//
struct GM_Spec
{
enum eCategory {
eCategory_SSQ, //ssq관련 gm command
eCategory_upperbound,
};
enum eCmd {
eCmd_open,
eCmd_close,
eCmd_warp,
eCmd_status,
eCmd_jump,
eCmd_summon,
eCmd_observer,
eCmd_upperbound,
};
enum eOption {
eOption_None = 0,
eOption_FastTrack = 1 << 0,
};
typedef TCHAR String[32];
typedef String StringArray[5];
struct Category
{
eCategory Cate;
String CateString;
};
struct SSQ
{
// <FIELDs>
eCmd GM_Cmd;
String CmdString;
// <FORMATs>
struct Open
{
};
struct Close
{
};
};
struct MsgFormat
{
eCategory Cate;
eCmd GM_Cmd;
SSQInfo::SSQCODE CodeOfSSQ;
DWORD GMObjectKey;
eOption Option;
};
};
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// <SSQ_MSG_STRUCTUREs>
// - 서버간 주고 받는 메시지 구조는 여기에 정의한다.
//
SSQ_MSG_DECL( SSQ_S2S_FIELD_CREATE )
{
SSQInfo::SSQCODE CodeOfSSQ; // 모든 패킷의 ZoneKey는 m_dwKey
};
SSQ_MSG_DECL( SSQ_S2S_FIELD_CREATED )
{
SSQInfo::SSQCODE CodeOfSSQ;
KEYTYPE m_ZoneKey;
};
SSQ_MSG_DECL( SSQ_S2S_FIELD_BLOCK )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_FIELD_DESTORY )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_FIELD_DESTORYED )
{
SSQInfo::SSQCODE CodeOfSSQ;
KEYTYPE m_ZoneKey;
};
SSQ_MSG_DECL( SSQ_S2S_GAMBLE_START )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_GAMBLE_RESULT )
{
SSQInfo::SSQCODE CodeOfSSQ;
DWORD RewardHeim; // 갬블로 획득한 하임액
sSTRING_BUFFER_CHAR_NAME CharName; // 전체 공지이므로 캐릭터 이름 전송
};
SSQ_MSG_DECL( SSQ_S2S_BATTLE_COUNTDOWN )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_BATTLE_PREPARATION )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_BATTLE_START )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_BATTLE_CANCEL )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_BATTLE_END_REQUEST )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_BATTLE_END )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_BATTLE_CLEAR )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_BATTLE_CLEARED )
{
SSQInfo::SSQCODE CodeOfSSQ;
};
SSQ_MSG_DECL( SSQ_S2S_SET_CHAT_BLOCK_ZONE )
{
DWORD ZoneKey;
BOOLEAN Enabled;
};
SSQ_MSG_DECL( SSQ_S2S_GM_CONTROL_REQ )
{
GM_Spec::MsgFormat Command;
};
SSQ_MSG_DECL( SSQ_S2S_ZONE_SSQ_JOIN_NTF ) // 동기화 목적으로 빠른 처리를 수행할 수 있어야 한다.
{
DWORD ObjectKey;
SLOTCODE ItemCode;
};
SSQ_MSG_DECL( SSQ_S2S_OBSERVER_MODE_CTRL ) // 동기화 목적으로 빠른 처리를 수행할 수 있어야 한다.
{
typedef nsSSQ::Observer::Info Info;
DWORD ObjectKey; // 요청한 플레이어
Info::eRequest Request;
union {
struct {
Info::eKeyCmd PressedKey;
} ObserverCmd;
};
inline VOID Init()
{
Request = Info::eRequest_None;
ObserverCmd.PressedKey = Info::eKeyCmd_Max;
}
};
SSQ_MSG_DECL( SSQ_S2S_OBSERVER_MODE_RESULT )
{
DWORD ObjectKey;
MSGSUB_SSQ_PROTOCOL_REQUEST_OBSERVER_CTRL_RESULT C2GMsg;
};
SSQ_MSG_DECL( SSQ_S2S_OBSERVER_MODE_SELECT_WINDOW )
{
DWORD ObjectKey;
};
////━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
//// <SSQ_MSG_ROUTER_CLIENT>
//// - Client 지원용 기본 타입
//template< typename _DERIVED_T, typename _STORAGE_T >
//struct SSQMsgRouter : public WarMsgRouter< _DERIVED_T, _STORAGE_T, SSQMsgRouter<_DERIVED_T, _STORAGE_T> >
//{
// typedef _DERIVED_T sub_type;
// typedef _STORAGE_T storage_type;
// typedef SSQMsgRouter< sub_type, storage_type > this_type;
// typedef WarMsgRouter< sub_type, storage_type, this_type > base_type;
// friend struct base_type;
//public:
// inline SSQInfo::COUNT_T AlignNewNode( const DWORD objectKey )
// {
// SSQInfo::COUNT_T regIndex = GetCount();
// if( FlowControl::FCAssert( regIndex < SSQ_MAX_CHARACTERS ) )
// {
// regIndex = m_FreeSlots.back();
// sNODE& rNewNode = m_CharInfos[regIndex];
// rNewNode.SetObjectKey( objectKey );
// rNewNode.SetStorage( storage_info::Allocate() );
// m_MatchTable[objectKey] = regIndex;
// m_FreeSlots.pop_back();
// return regIndex;
// }
// return SSQ_MAX_CHARACTERS; // error
// }
// BOOLEAN Routing( const WAR_TAG_P IN pMsg, const WAR_MSG_HDR IN header );
//};
};
namespace nsSSQ_Util
{
using namespace ::nsSSQ;
#pragma pack(push, 1)
// <MSG_SSQ_CHUNKBLOCK>
// - Server에서 가변 패킷 데이터 스트림 제작시 사용하는 버퍼 블록
// <Format>
// ──────────────────────────────────────────────────
// | MSG_BASE | WAR_MSG_HDR | SSQ_SUB_MESSAGEs
// | dword(key) | byte(cate) | byte(proto) | short(size) | byte stream[xxxx] ...
// ──────────────────────────────────────────────────
struct MSG_SSQ_CHUNKBLOCK : MSG_BASE
{
WAR_MSG_HDR m_Header[1];
BYTE m_Stream[MAX_WAR_MSG_SEQUENCIAL_STREAM_SIZE];
uint16_t GetSize() const {
return static_cast<uint16_t>(sizeof(MSG_BASE) + sizeof(m_Header) + (m_Header->size));
}
};
struct MSG_SSQ_LIGHTBLOCK : MSG_BASE
{
WAR_MSG_HDR m_Header[1];
BYTE m_Stream[128];
uint16_t GetSize() const {
return static_cast<uint16_t>(sizeof(MSG_BASE) + sizeof(m_Header) + (m_Header->size));
}
};
#pragma pack(pop)
template< typename _MSG_CASTER, typename _PACKET_T >
class xxxSender // Broadcaster, Unicaster
{
public:
protected:
typedef _MSG_CASTER derived_type;
typedef _PACKET_T packet_structure;
typedef xxxSender< derived_type, packet_structure > super_type;
public: xxxSender()
: m_pPacket( new (&m_PacketStream) packet_structure )
, MSG_HEADER( m_pPacket->m_Header[0] )
//, m_pMsgHeadPtr( (WAR_TAG_P)&m_pPacket->m_Header[1] )
{
m_pPacket->m_Header->size = 0;
};
public:
inline VOID SetKey( const DWORD userKey ) { m_pPacket->m_dwKey = userKey; }
inline VOID Reset() { new (this) super_type; }
//inline WAR_TAG_P GetEndPointer() { return m_pMsgHeadPtr + MSG_HEADER.size; }
private: MSG_SSQ_CHUNKBLOCK m_PacketStream;
protected: packet_structure* const m_pPacket; // 상속 개체 연속성 목적의 배치구조
public: WAR_MSG_HDR& MSG_HEADER;
//private: WAR_TAG_P m_pMsgHeadPtr;
__DISABLE_COPY(super_type);
};
template< typename _PACKET_T, typename _SUBMSG >
class WAR_MSG_SINGLE_ASSEMBLER
{
protected:
typedef _PACKET_T packet_structure;
typedef _SUBMSG message;
typedef WAR_MSG_SINGLE_ASSEMBLER< packet_structure, message > super_type;
public: WAR_MSG_SINGLE_ASSEMBLER()
: m_pPacket( new (&m_PacketStream) packet_structure )
, MSG( reinterpret_cast<message&>( m_pPacket->m_Header[1] ) )
, m_bProced( FALSE )
{
BOOST_STATIC_ASSERT( sizeof(packet_structure)<=sizeof(MSG_SSQ_LIGHTBLOCK) );
m_pPacket->m_Header->size = 0;
MSG._TAG = MSG.value;
};
public: // m_dwKey는 개별적인 처리에 맏긴다.
inline packet_structure* const GetPacket() { return m_pPacket; }
inline WORD GetSize() const { return m_pPacket->GetSize(); }
inline VOID Completion() { m_pPacket->m_Header->size = MSG.GetSize(); }
inline BOOLEAN SerializeFrom( const message& rSrc )
{
if( m_bProced )
return FALSE;
m_bProced = TRUE;
WAR_MSG_HDR* const pHeader = m_pPacket->m_Header;
return rSrc.SerializeTo( pHeader );
}
protected: packet_structure* const m_pPacket;
public: message& MSG;
protected: BOOLEAN m_bProced;
private: MSG_SSQ_LIGHTBLOCK m_PacketStream;
__DISABLE_COPY(super_type);
};
//#if (0)
// template< typename _DRIVED, typename _PACKET >
// class Broadcaster
// {
// protected:
// typedef _DRIVED sub_type;
// typedef _PACKET packet_structure;
// typedef Broadcaster<sub_type, packet_structure> this_type;
//
// public:
// Broadcaster()
// {
// m_pPacket = new (&m_PacketStream) packet_structure;
// m_pPacket->m_Header->size = sizeof(WAR_MSG_HDR);
// m_PacketSize = m_pPacket->GetSize();
// }
//
// private:
// MSG_SSQ_CHUNKBLOCK m_PacketStream;
//
// protected:
// WORD m_PacketSize;
// packet_structure* m_pPacket;
//
// public:
// inline VOID SetKey( const DWORD key ) { m_pPacket->m_dwKey = key; }
// WAR_TAG_P MakeInit_SSQPacketStream( SSQ_MSG_SCT_HDR*& OUT rpHdr )
// {
// rpHdr = (SSQ_MSG_SCT_HDR*)m_PacketStream.m_Header;
// rpHdr->hdr.size = 0;
// WAR_TAG_P pOffset = (WAR_TAG_P)rpHdr;
// pOffset = SSQ_MSG_SCT_HDR::Serialize( *rpHdr, (WAR_TAG_P)rpHdr );
//
// return pOffset;
// }
// };
//#endif
};
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// <TransactionVTLS>
// - in Process Object Transaction Mechanism
// - _VTLS (Virtual Thread Local Storage) - singleton object
//
template< typename _VTLS >
class TransactionVTLS
{
public:
typedef _VTLS vtls_type;
typedef vtls_type* vtls_pointer;
public: TransactionVTLS() {}
public:
inline VOID Enter( vtls_pointer pvtls ) { ms_bTrans=true; ms_pVTLS=pvtls; }
inline VOID Leave() { ms_bTrans = false; ms_pVTLS = 0; }
inline static bool IsTransaction() { return ms_bTrans; }
inline static vtls_pointer GetStorage() { return ms_pVTLS; }
private:
static bool ms_bTrans;
static vtls_pointer ms_pVTLS;
};
template< typename _VTLS > bool
TransactionVTLS<_VTLS>::ms_bTrans = 0;
template< typename _VTLS > typename TransactionVTLS<_VTLS>::vtls_pointer
TransactionVTLS<_VTLS>::ms_pVTLS = 0;
//━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
// <TransactionObject>
// - in Process Object Transaction Mechanism
// - _LS (Local Storage) - multiple object
//
template< typename _LS >
class TransactionObject
{
public:
typedef _LS ls_type;
typedef ls_type* ls_pointer;
public: TransactionObject() : m_bTrans(false), m_pLS(0) {}
public:
inline VOID Enter( ls_pointer pvtls ) { m_bTrans=true; m_pLS=pvtls; }
inline VOID Leave() { m_bTrans = false; m_pLS = 0; }
inline bool IsTransaction() { return m_bTrans; }
inline ls_pointer GetStorage() { return m_pLS; }
private: bool m_bTrans;
ls_pointer m_pLS;
};
template< typename _VTLS >
class AutoTransactionVTLS : public TransactionVTLS< _VTLS >
{
public: AutoTransactionVTLS( vtls_pointer ptr ) { Enter( ptr ); }
~AutoTransactionVTLS() { Leave(); }
};
template< typename _LS >
class AutoTransactionObject : public TransactionObject< _LS >
{
public: AutoTransactionObject( ls_pointer ptr ) { Enter( ptr ); }
~AutoTransactionObject() { Leave(); }
};