/** * @file PacketBuild.h * @brief 组包模块头文件 * Copyright(c) 2007,上海第九城市游戏研发部 * All rights reserved * 文件名称: PacketBuild.h * 摘 要: 根据通信协议(类型,命令字,协议结构)进行组包 * 作 者: dzj * 完成日期: 2007.11.30 * */ #pragma once #include "MsgToPut.h" #include "SrvProtocol.h" #include "RelationServiceProtocol.h" #include "LoginServiceProtocol.h" #include "ShopSvrProtocol.h" #include "LogSvcProtocol.h" using namespace RelationServiceNS; using namespace ShopServer; class CPacketBuild { public: //组包函数; // template < typename T_Msg > //#ifdef USE_DSIOCP // static MsgToPut* CreatePkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, T_Msg* pPkg ) //#else //USE_DSIOCP // static MsgToPut* CreatePkg( int nHandleID, int nSessionID, T_Msg* pPkg ) //#endif //USE_DSIOCP // { //#ifdef USE_DSIOCP // if ( NULL == pUniqueSocket ) // { // return NULL;//对应的句柄已无效,放弃发送; // } //#endif //USE_DSIOCP // MsgToPut* pMsg = NULL; // unsigned short wPkgLen = 0; // unsigned char byPkgType = 0; // unsigned short wCmd = 0; // TRY_BEGIN; // if ( pPkg->wCmd != T_Msg::wCmd ) // { // D_ERROR( "CPacketBuild::CreatePkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); // return NULL; // } // pMsg = g_poolMsgToPut->RetrieveOrCreate(); // if ( NULL == pMsg ) // { // D_ERROR( "CPacketBuild::CreatePkg,取不到MsgToPut,包类型:%x", T_Msg::wCmd ); // return NULL; // } // TRY_END; // // TRY_BEGIN; // pMsg->nHandleID = nHandleID; // pMsg->nSessionID = nSessionID; // wPkgLen = sizeof(T_Msg) + 5; // if ( wPkgLen > sizeof(pMsg->pMsg) ) // { // D_ERROR( "CPacketBuild::CreatePkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); // return NULL; // } // byPkgType = T_Msg::byPkgType; // wCmd = pPkg->wCmd; // pMsg->nMsgLen = (int)wPkgLen;//包头字段长度为sizeof(WORD)(wPkgLen)+sizeof(BYTE)(byPkgType)+sizeof(WORD)(wCmd); // TRY_END; // // TRY_BEGIN; // memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; // memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; // memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; // memcpy( &(pMsg->pMsg[5]), pPkg, sizeof(T_Msg) );//包内容; // //#ifdef USE_DSIOCP // pMsg->pUniqueSocket = pUniqueSocket; // //for debug, pMsg->msgcmd = wCmd; //#endif //USE_DSIOCP // // return pMsg; // TRY_END; // return NULL; // }; //组建向所有连入连接广播的广播包; template < typename T_Msg > static MsgToPut* CreateInconnBrocastPkg( T_Msg* pPkg ) { TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreateInconnBrocastPkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if ( sizeof(T_Msg) > (MsgToPut::MSG_MAX_SIZE - 5) ) { D_ERROR( "CPacketBuild::CreateInconnBrocastPkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreateInconnBrocastPkg,取不到MsgToPut,内存分配失败,包类型:%x", T_Msg::wCmd ); return NULL; } unsigned short wPkgLen = 0; // encode #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable:4267 ) int iEnLen = m_clipro.EnCode( (int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5) ); #pragma warning( pop ) #else //ACE_WIN32 int iEnLen = m_clipro.EnCode( (int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5) ); #endif //ACE_WIN32 if( iEnLen < 0 ) { D_ERROR("CPacketBuild::CreateInconnBrocastPkg, encode出错,包类型%x\n", pPkg->wCmd); return NULL; } wPkgLen = iEnLen + 5; pMsg->nHandleID = GATE_PLAYER_BROCASTSID;//向本gate的所有玩家群发消息 pMsg->nSessionID = GATE_PLAYER_BROCASTSID;//向本gate的所有玩家群发消息 #ifdef USE_DSIOCP pMsg->pUniqueSocket = NULL;//广播消息,没有特定的socket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; return pMsg; TRY_END; return NULL; }; template < typename T_Msg > #ifdef USE_DSIOCP static MsgToPut* CreateClientPkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, T_Msg* pPkg ) #else //USE_DSIOCP static MsgToPut* CreateClientPkg( int nHandleID, int nSessionID, T_Msg* pPkg ) #endif //USE_DSIOCP { #ifdef USE_DSIOCP if ( NULL == pUniqueSocket ) { return NULL;//对应的句柄已无效,放弃发送; } #endif //USE_DSIOCP TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreatePkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if (sizeof(T_Msg) > (MsgToPut::MSG_MAX_SIZE - 5)) { D_ERROR( "CPacketBuild::CreatePkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreatePkg,取不到MsgToPut,内存分配失败, 包类型:%x", T_Msg::wCmd ); return NULL; } unsigned short wPkgLen = 0; // encode #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable:4267 ) int iEnLen = m_clipro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #pragma warning( pop ) #else //ACE_WIN32 int iEnLen = m_clipro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #endif //ACE_WIN32 if( iEnLen < 0 ) { D_ERROR("CPacketBuild::CreatePkg, encode出错,包类型%x\n", pPkg->wCmd); return NULL; } wPkgLen = iEnLen + 5; pMsg->nHandleID = nHandleID; pMsg->nSessionID = nSessionID; pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = pUniqueSocket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; }; template < typename T_Msg > #ifdef USE_DSIOCP static MsgToPut* CreateGatePkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, T_Msg* pPkg, MsgToPut* pOldToSendMsg, bool& isNewMsg ) #else //USE_DSIOCP static MsgToPut* CreateGatePkg( int nHandleID, int nSessionID, T_Msg* pPkg, MsgToPut* pOldToSendMsg, bool& isNewMsg ) #endif //USE_DSIOCP { isNewMsg = false; #ifdef USE_DSIOCP if ( NULL == pUniqueSocket ) { return NULL;//对应的句柄已无效,放弃发送; } #endif //USE_DSIOCP TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreatePkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if ( (sizeof(T_Msg)+5) > MsgToPut::MSG_MAX_SIZE ) { D_ERROR( "CPacketBuild::CreatePkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = NULL; int stpos = 0;//消息体中的存放起始位置; if ( ( NULL == pOldToSendMsg ) || ( (sizeof(T_Msg) + 5 + pOldToSendMsg->nMsgLen) > MsgToPut::MSG_MAX_SIZE ) ) { //旧MsgToPut体放不下; pMsg = g_poolMsgToPut->RetrieveOrCreate(); stpos = 0; if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreatePkg,取不到MsgToPut,内存分配失败,包类型:%x", T_Msg::wCmd ); return NULL; } isNewMsg = true; } else { pMsg = pOldToSendMsg; stpos = pOldToSendMsg->nMsgLen;//存放至旧消息体时使用; } unsigned short wPkgLen = sizeof(T_Msg) + 5; memcpy( &(pMsg->pMsg[5+stpos]), pPkg, sizeof(T_Msg) );//包内容; pMsg->nHandleID = nHandleID; pMsg->nSessionID = nSessionID; pMsg->nMsgLen = wPkgLen + stpos; unsigned char byPkgType = T_Msg::byPkgType; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0+stpos]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2+stpos]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3+stpos]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = pUniqueSocket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; }; template < typename T_Msg > #ifdef USE_DSIOCP static MsgToPut* CreateServerPkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, T_Msg* pPkg ) #else //USE_DSIOCP static MsgToPut* CreateServerPkg( int nHandleID, int nSessionID, T_Msg* pPkg ) #endif //USE_DSIOCP { #ifdef USE_DSIOCP if ( NULL == pUniqueSocket ) { return NULL;//对应的句柄已无效,放弃发送; } #endif //USE_DSIOCP if ( NULL == pPkg ) { D_ERROR( "CreateServerPkg,传入消息空!\n" ); return NULL; } TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreatePkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if (sizeof(T_Msg) > (MsgToPut::MSG_MAX_SIZE - 5)) { D_ERROR( "CPacketBuild::CreatePkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreatePkg,取不到MsgToPut,内存分配失败,包类型:%x", T_Msg::wCmd ); return NULL; } unsigned short wPkgLen = 0; memcpy( &(pMsg->pMsg[5]), pPkg, sizeof(T_Msg) );//包内容; wPkgLen = sizeof(T_Msg) + 5; pMsg->nHandleID = nHandleID; pMsg->nSessionID = nSessionID; pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = T_Msg::byPkgType; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = pUniqueSocket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; }; // template<> //#ifdef USE_DSIOCP // static MsgToPut* CPacketBuild::CreateServerPkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, MGBroadCast* pPkg ) //#else //USE_DSIOCP // static MsgToPut* CPacketBuild::CreateServerPkg( int nHandleID, int nSessionID, MGBroadCast* pPkg ) //#endif //USE_DSIOCP #ifdef USE_DSIOCP static MsgToPut* CreateMGTPkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, MGBroadCast* pPkg ) #else //USE_DSIOCP static MsgToPut* CreateMGTPkg( int nHandleID, int nSessionID, MGBroadCast* pPkg ) #endif //USE_DSIOCP { #ifdef USE_DSIOCP if ( NULL == pUniqueSocket ) { return NULL;//对应的句柄已无效,放弃发送; } #endif //USE_DSIOCP if ( NULL == pPkg ) { D_ERROR( "CreateServerPkg,传入消息空!\n" ); return NULL; } TRY_BEGIN; if (sizeof(MGBroadCast) > (MsgToPut::MSG_MAX_SIZE - 5)) { D_ERROR( "CreateServerPkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", MGBroadCast::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CreateServerPkg,取不到MsgToPut,内存分配失败,包类型:%x", MGBroadCast::wCmd ); return NULL; } /* int nCurNum; //此次有效的人数 unsigned long arrPlayerPID[MAX_NOTIPLAYER_NUM_PERGATE]; */ //根据广播包中的目标玩家个数计算有效内容的长度; int tocpysize = sizeof(int) + ( sizeof(pPkg->arrPlayerPID[0]) * (pPkg->nCurNum) ); unsigned short wPkgLen = 0; memcpy( &(pMsg->pMsg[5]), pPkg, tocpysize );//包内容; wPkgLen = tocpysize + 5; pMsg->nHandleID = nHandleID; pMsg->nSessionID = nSessionID; pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = MGBroadCast::byPkgType; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = pUniqueSocket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; }; template < typename T_Msg > static MsgToPut* CreateSrvBrocastPkg( T_Msg* pPkg ) { #ifdef USE_DSIOCP //if ( NULL == pUniqueSocket ) //{ // return NULL;//对应的句柄已无效,放弃发送; //} #endif //USE_DSIOCP TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreatePkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if (sizeof(T_Msg) > (MsgToPut::MSG_MAX_SIZE - 5)) { D_ERROR( "CPacketBuild::CreatePkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreatePkg,取不到MsgToPut,内存分配失败,包类型:%x", T_Msg::wCmd ); return NULL; } unsigned short wPkgLen = 0; memcpy( &(pMsg->pMsg[5]), pPkg, sizeof(T_Msg) );//包内容; wPkgLen = sizeof(T_Msg) + 5; pMsg->nHandleID = GATE_PLAYER_BROCASTSID; pMsg->nSessionID = GATE_PLAYER_BROCASTSID; pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = T_Msg::byPkgType; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = NULL; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; } //关系服务器的解析 template < typename T_Msg > #ifdef USE_DSIOCP static MsgToPut* CreateRelationPkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, T_Msg* pPkg ) #else //USE_DSIOCP static MsgToPut* CreateRelationPkg( int nHandleID, int nSessionID, T_Msg* pPkg ) #endif //USE_DSIOCP { #ifdef USE_DSIOCP if ( NULL == pUniqueSocket ) { return NULL;//对应的句柄已无效,放弃发送; } #endif //USE_DSIOCP TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreateRelationPkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if (sizeof(T_Msg) > (MsgToPut::MSG_MAX_SIZE - 5)) { D_ERROR( "CPacketBuild::CreateRelationPkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreateRelationPkg,取不到MsgToPut,内存分配失败,包类型:%x", T_Msg::wCmd ); return NULL; } unsigned short wPkgLen = 0; // encode #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable:4267 ) int iEnLen = m_relationpro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #pragma warning( pop ) #else //ACE_WIN32 int iEnLen = m_relationpro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #endif //ACE_WIN32 if( iEnLen < 0 ) { D_ERROR("CPacketBuild::CreateRelationPkg, encode出错,包类型%x\n", pPkg->wCmd); return NULL; } wPkgLen = iEnLen + 5; if ( wPkgLen >= sizeof(pMsg->pMsg) ) { D_ERROR("CPacketBuild::CreateRelationPkg, encode too large:%d\n", iEnLen ); } pMsg->nHandleID = nHandleID; pMsg->nSessionID = nSessionID; pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = pUniqueSocket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; }; //关系服务器的解析 template < typename T_Msg > #ifdef USE_DSIOCP static MsgToPut* CreateNewLoginPkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, T_Msg* pPkg ) #else //USE_DSIOCP static MsgToPut* CreateNewLoginPkg( int nHandleID, int nSessionID, T_Msg* pPkg ) #endif //USE_DSIOCP { #ifdef USE_DSIOCP if ( NULL == pUniqueSocket ) { return NULL;//对应的句柄已无效,放弃发送; } #endif //USE_DSIOCP TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreateNewLoginPkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if (sizeof(T_Msg) > (MsgToPut::MSG_MAX_SIZE - 5)) { D_ERROR( "CPacketBuild::CreateNewLoginPkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreateNewLoginPkg,取不到MsgToPut,内存分配失败,包类型:%x", T_Msg::wCmd ); return NULL; } unsigned short wPkgLen = 0; // encode #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable:4267 ) int iEnLen = m_loginpro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #pragma warning( pop ) #else //ACE_WIN32 int iEnLen = m_loginpro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #endif //ACE_WIN32 if( iEnLen < 0 ) { D_ERROR("CPacketBuild::CreateNewLoginPkg, encode出错,包类型%x\n", pPkg->wCmd); return NULL; } wPkgLen = iEnLen + 5; pMsg->nHandleID = nHandleID; pMsg->nSessionID = nSessionID; pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = pUniqueSocket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; }; //商城服务器的解析 template < typename T_Msg > #ifdef USE_DSIOCP static MsgToPut* CreateShopPkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, T_Msg* pPkg ) #else //USE_DSIOCP static MsgToPut* CreateShopPkg( int nHandleID, int nSessionID, T_Msg* pPkg ) #endif //USE_DSIOCP { #ifdef USE_DSIOCP if ( NULL == pUniqueSocket ) { return NULL;//对应的句柄已无效,放弃发送; } #endif //USE_DSIOCP TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreateShopPkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if (sizeof(T_Msg) > (MsgToPut::MSG_MAX_SIZE - 5)) { D_ERROR( "CPacketBuild::CreateShopPkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreateShopPkg,取不到MsgToPut,内存分配失败,包类型:%x", T_Msg::wCmd ); return NULL; } unsigned short wPkgLen = 0; // encode #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable:4267 ) int iEnLen = m_shopPro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #pragma warning( pop ) #else //ACE_WIN32 int iEnLen = m_shopPro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #endif //ACE_WIN32 if( iEnLen < 0 ) { D_ERROR("CPacketBuild::CreateShopPkg, encode出错,包类型%x\n", pPkg->wCmd); return NULL; } wPkgLen = iEnLen + 5; if ( wPkgLen >= sizeof(pMsg->pMsg) ) { D_ERROR("CPacketBuild::CreateShopPkg, encode too large:%d\n", iEnLen ); } pMsg->nHandleID = nHandleID; pMsg->nSessionID = nSessionID; pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = pUniqueSocket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; }; //日志服务器的解析 template < typename T_Msg > #ifdef USE_DSIOCP static MsgToPut* CreateLogPkg( int nHandleID, int nSessionID, UniqueObj< CDsSocket >* pUniqueSocket, T_Msg* pPkg ) #else //USE_DSIOCP static MsgToPut* CreateLogPkg( int nHandleID, int nSessionID, T_Msg* pPkg ) #endif //USE_DSIOCP { #ifdef USE_DSIOCP if ( NULL == pUniqueSocket ) { return NULL;//对应的句柄已无效,放弃发送; } #endif //USE_DSIOCP TRY_BEGIN; if ( pPkg->wCmd != T_Msg::wCmd ) { D_ERROR( "CPacketBuild::CreateLogPkg,传入类型%x与待发送包类型%x不一致", T_Msg::wCmd, pPkg->wCmd ); return NULL; } if (sizeof(T_Msg) > (MsgToPut::MSG_MAX_SIZE - 5)) { D_ERROR( "CPacketBuild::CreateLogPkg,欲发包的包长超过了MsgToPut的内部缓存大小,包类型%x", T_Msg::wCmd ); return NULL; } // 填写MsgToPut MsgToPut* pMsg = g_poolMsgToPut->RetrieveOrCreate(); if ( NULL == pMsg ) { D_ERROR( "CPacketBuild::CreateLogPkg,取不到MsgToPut,内存分配失败,包类型:%x", T_Msg::wCmd ); return NULL; } unsigned short wPkgLen = 0; // encode #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable:4267 ) int iEnLen = m_logPro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #pragma warning( pop ) #else //ACE_WIN32 int iEnLen = m_logPro.EnCode((int)pPkg->wCmd, pPkg, &pMsg->pMsg[5], (int)(sizeof(pMsg->pMsg) - 5)); #endif //ACE_WIN32 if( iEnLen < 0 ) { D_ERROR("CPacketBuild::CreateLogPkg, encode出错,包类型%x\n", pPkg->wCmd); return NULL; } wPkgLen = iEnLen + 5; if ( wPkgLen >= sizeof(pMsg->pMsg) ) { D_ERROR("CPacketBuild::CreateLogPkg, encode too large:%d\n", iEnLen ); } pMsg->nHandleID = nHandleID; pMsg->nSessionID = nSessionID; pMsg->nMsgLen = wPkgLen; unsigned char byPkgType = 0; unsigned short wCmd = pPkg->wCmd; memcpy( &(pMsg->pMsg[0]), &wPkgLen, 2 );//包长:wPkgLen; memcpy( &(pMsg->pMsg[2]), &byPkgType, 1 );//包类型:byPkgType; memcpy( &(pMsg->pMsg[3]), &wCmd, 2 );//命令字:wCmd; #ifdef USE_DSIOCP pMsg->pUniqueSocket = pUniqueSocket; //for debug, pMsg->msgcmd = wCmd; #endif //USE_DSIOCP return pMsg; TRY_END; return NULL; }; private: // 使用协议工具2008.7.15 static CliProtocol m_clipro; //客户端的 static RelationServiceProtocol m_relationpro; //关系服务器的解析 static LoginServiceProtocol m_loginpro; //新登录服务器的解析 static ShopSrvProtocol m_shopPro;//商城服务器的解析 static LOG_SVC_NS::LogSvcProtocol m_logPro;//日至服务器的解析 };