/** * @file Player.cpp * @brief 定义玩家类 * Copyright(c) 2007,上海第九城市游戏研发部 * All rights reserved * 文件名称: Player.cpp * 摘 要: 定义玩家类; * 作 者: dzj * 完成日期: 2007.11.29 * */ #include "Player.h" map CManPlayer::m_mapPlayers;//所有其它srv; ///置玩家的句柄信息,每次新建时必须调用; void CPlayer::SetHandleInfo( int nHandleID, int nSessionID ) { if ( nSessionID <=1000 ) { //连其它srv成功; //D_WARNING( "错误的nSessionID:%d, 玩家的sessionID应该大于1000\n", nSessionID ); D_WARNING( "mapserver连接成功:%d\n\n", nSessionID ); } memset( m_strAccount, 0, sizeof(m_strAccount) );//初始帐号与密码清0; memset( m_strPwd, 0, sizeof(m_strPwd) ); m_nHandleID = nHandleID; m_nSessionID = nSessionID; CManPlayer::AddOnePlayer( this ); if ( nSessionID > 1000 ) { D_WARNING( "有新的客户端连入:%d\n", nSessionID ); //普通玩家上线; //通知客户端其自身的ID号; GCPlayerSelfInfo playerSelfInfo; #ifdef ACE_WIN32 #pragma warning( push ) #pragma warning( disable: 4311 ) //"type cast" pointer truncation from ??* to ?? playerSelfInfo.lPlayerID = (unsigned long) this; #pragma warning( pop ) #else //ACE_WIN32 playerSelfInfo.lPlayerID = (unsigned long) this; #endif //ACE_WIN32 MsgToPut* pNewMsg = CreatePlayerPkg( GCPlayerSelfInfo, this, playerSelfInfo ); this->SendPkgToPlayer( pNewMsg );//通知玩家其自身的ID号; D_WARNING( "向客户端%d返回其自身ID号\n", this->GetSessionID() ); //通知mapsrv玩家上线 GMPlayerAppear mapMsg; mapMsg.lPlayerID = (DWORD)((DWORD_PTR)this);//填入玩家在本GateSrv上的ID号; mapMsg.lMapCode = 0;//目前固定填0; mapMsg.nPosX = 0;//初始时出生在(0,0)位置; mapMsg.nPosY = 0; CPlayer* pMapsrv = CManPlayer::GetMapserver( 700 );//找到mapserver,将相应包转发出去; if ( NULL != pMapsrv ) { pNewMsg = CreatePlayerPkg( GMPlayerAppear, pMapsrv, mapMsg ); pMapsrv->SendPkgToPlayer( pNewMsg ); D_WARNING( "向mapserver%d发送玩家在地图上出现消息\n\n", pMapsrv->GetSessionID() ); } else { D_WARNING( "玩家上线时,找不到mapsrv:%d进行通知\n\n", 700 ); } } return; } ///销毁时的处理(连接断开) ///注意:在新建连接之前也会调用这里; void CPlayer::OnDestoryed() { if ( m_nHandleID != 0 ) { //确实为断开,区别于新建连接时的回调; //以下断开处理; CManPlayer::RemovePlayer( this ); if ( m_nSessionID > 1000 ) { //普通玩家下线; //通知mapsrv玩家下线 GMPlayerLeave mapMsg; mapMsg.lPlayerID = (DWORD)((DWORD_PTR)this);//填入玩家在本GateSrv上的ID号; mapMsg.lMapCode = 0;//目前固定填0; CPlayer* pMapsrv = CManPlayer::GetMapserver( 700 );//找到mapserver,将相应包转发出去; if ( NULL != pMapsrv ) { MsgToPut* pNewMsg = CreatePlayerPkg( GMPlayerLeave, pMapsrv, mapMsg ); pMapsrv->SendPkgToPlayer( pNewMsg ); } else { D_WARNING( "玩家断开时,找不到对应的mapsrv:%d进行通知\n\n", 700 ); } } else if ( m_nSessionID == 700 ) { D_WARNING( "到mapserver断开,删去所有在线玩家\n", 700 ); g_bKickAllPlay = true; D_WARNING( "到mapserver断开,断开在线玩家请求都已发出\n\n", 700 ); } } ResetInfo(); return; } //收包处理; void CPlayer::OnPkgRcved( unsigned short wCmd, const char* pBuf, unsigned short wPkgLen ) { //目前简单使用if else处理,以后修改 if ( C_G_LOGIN == wCmd ) { D_WARNING( "收到客户端:%d登录消息\n\n", GetSessionID() ); if ( wPkgLen != sizeof(CGLogin) ) { //收包大小错误,可能是通信两端消息结构不一致; return; } //玩家登录命令; CGLogin* tmpLogin = (CGLogin*) pBuf; //保存帐号与密码; #ifdef ACE_WIN32 if ( strlen(tmpLogin->strUserAccount)+1 <= sizeof(m_strAccount) ) { strcpy_s( m_strAccount, sizeof(m_strAccount), tmpLogin->strUserAccount ); } if ( strlen(tmpLogin->strUserPassword)+1 <= sizeof(m_strPwd) ) { strcpy_s( m_strPwd, sizeof(m_strPwd), tmpLogin->strUserPassword ); } #else //ACE_WIN32 if ( strlen(tmpLogin->strUserAccount)+1 <= sizeof(m_strAccount) ) { strcpy( m_strAccount, tmpLogin->strUserAccount ); } if ( strlen(tmpLogin->strUserPassword)+1 <= sizeof(m_strPwd) ) { strcpy( m_strPwd, tmpLogin->strUserPassword ); } #endif //ACE_WIN32 } else if ( C_G_RUN == wCmd ) { //检验收包大小是否正确; if ( wPkgLen != sizeof(CGRun) ) { //收包大小错误,可能是通信两端消息结构不一致; return; } //结构校验通过 CGRun* pRun = (CGRun*)pBuf; //消息转发mapsrv; GMRun returnMsg; returnMsg.lPlayerID = (DWORD)((DWORD_PTR)this);//填入玩家在本GateSrv上的ID号; returnMsg.lCurOffset = pRun->lCurOffset; returnMsg.nOrgX = pRun->nOrgX; returnMsg.nOrgY = pRun->nOrgY; returnMsg.fOrgCroodX = pRun->fOrgCroodX; returnMsg.fOrgCroodY = pRun->fOrgCroodY; returnMsg.nNewX = pRun->nNewX; returnMsg.nNewY = pRun->nNewY; returnMsg.fNewCroodX = pRun->fNewCroodX; returnMsg.fNewCroodY = pRun->fNewCroodY; CPlayer* pMapsrv = CManPlayer::GetMapserver( 700 );//找到mapserver,将相应包转发出去; if ( NULL != pMapsrv ) { MsgToPut* pNewMsg = CreatePlayerPkg( GMRun, pMapsrv, returnMsg ); pMapsrv->SendPkgToPlayer( pNewMsg ); D_WARNING( "收到玩家%d跑动消息,目标点(%d,%d),目标点坐标(%f,%f)\n\n" , returnMsg.lPlayerID, returnMsg.nNewX, returnMsg.nNewY, returnMsg.fNewCroodX, returnMsg.fNewCroodX ); } else { D_WARNING( "收到玩家跑动消息时,找不到玩家所在的mapsrv:%d\n\n", 700 ); } } else if ( M_G_RUN == wCmd ) { //检验收包大小是否正确; if ( wPkgLen != sizeof(MGRun) ) { //收包大小错误,可能是通信两端消息结构不一致; return; } //结构校验通过 MGRun* pRun = (MGRun*)pBuf; //消息转发mapsrv; GCRun returnMsg; returnMsg.lPlayerID = pRun->lPlayerID; returnMsg.lCurOffset = pRun->lCurOffset; returnMsg.nOrgX = pRun->nOrgX; returnMsg.nOrgY = pRun->nOrgY; returnMsg.fOrgCroodX = pRun->fOrgCroodX; returnMsg.fOrgCroodY = pRun->fOrgCroodY; returnMsg.nNewX = pRun->nNewX; returnMsg.nNewY = pRun->nNewY; returnMsg.fNewCroodX = pRun->fNewCroodX; returnMsg.fNewCroodY = pRun->fNewCroodY; CPlayer* pNotiPlayer = CManPlayer::FindPlayer( pRun->lNotiPlayerID );//通知此玩家; if ( NULL != pNotiPlayer ) { MsgToPut* pNewMsg = CreatePlayerPkg( GCRun, pNotiPlayer, returnMsg ); pNotiPlayer->SendPkgToPlayer( pNewMsg ); D_WARNING( "通知玩家%d:玩家%d跑动,目标点(%d,%d),目标点坐标(%f,%f)\n\n" , pRun->lNotiPlayerID, returnMsg.lPlayerID, returnMsg.nNewX, returnMsg.nNewY, returnMsg.fNewCroodX, returnMsg.fNewCroodX ); } else { D_WARNING( "收到MapServer跑动包,但找不到对应玩家%x\n\n", pRun->lNotiPlayerID ); } } else if ( M_G_PLAYER_APPEAR == wCmd ){ //检验收包大小是否正确; if ( wPkgLen != sizeof(MGPlayerAppear) ) { //收包大小错误,可能是通信两端消息结构不一致; return; } //结构校验通过 MGPlayerAppear* pPlayerAppear = (MGPlayerAppear*)pBuf; //消息转发mapsrv; GCPlayerAppear returnMsg; returnMsg.lPlayerID = pPlayerAppear->lPlayerID; returnMsg.nPosX = pPlayerAppear->nPosX; returnMsg.nPosY = pPlayerAppear->nPosY; returnMsg.fPosCroodX = pPlayerAppear->fPosCroodX; returnMsg.fPosCroodY = pPlayerAppear->fPosCroodY; CPlayer* pNotiPlayer = CManPlayer::FindPlayer( pPlayerAppear->lNotiPlayerID ); if ( NULL != pNotiPlayer ) { MsgToPut* pNewMsg = CreatePlayerPkg( GCPlayerAppear, pNotiPlayer, returnMsg ); pNotiPlayer->SendPkgToPlayer( pNewMsg );//通知客户端其它玩家出现; D_WARNING( "通知玩家%x,新玩家%x在地图上出现\n\n", pPlayerAppear->lNotiPlayerID, returnMsg.lPlayerID ); } else { D_WARNING( "收到MapServer玩家出现包,但找不到欲通知玩家%x\n\n", pPlayerAppear->lNotiPlayerID ); } } else if ( M_G_PLAYER_LEAVE == wCmd ){ //检验收包大小是否正确; if ( wPkgLen != sizeof(MGPlayerLeave) ) { //收包大小错误,可能是通信两端消息结构不一致; return; } //结构校验通过 MGPlayerLeave* pPlayerleave = (MGPlayerLeave*)pBuf; //消息转发mapsrv; GCPlayerLeave climsg; climsg.lPlayerID = pPlayerleave->lPlayerID; climsg.lMapCode = pPlayerleave->lMapCode; CPlayer* pNotiPlayer = CManPlayer::FindPlayer( pPlayerleave->lNotiPlayerID ); if ( NULL != pNotiPlayer ) { MsgToPut* pNewMsg = CreatePlayerPkg( GCPlayerLeave, pNotiPlayer, climsg ); pNotiPlayer->SendPkgToPlayer( pNewMsg );//通知客户端其它玩家离开; } else { D_WARNING( "收到MapServer玩家离开包,但找不到欲通知玩家%x\n\n", pPlayerleave->lNotiPlayerID ); } } else { D_WARNING( "收到不可识别包,命令字:%d,nSessionID:%d\n\n", wCmd, GetSessionID() ); } return; };