INT KNetConnectPlayer::OnClientLogin2( DWORD dwRoleId, const GUID& rConnGuid, INT nConnectId, BOOL bHidden /*= FALSE*/,BOOL bTinyTerminal) { INT nRetCode = FALSE; KPlayer* pPlayer = NULL; INT nPlayerIndex = 0; pPlayer = g_cPlayerMgr.GetById(dwRoleId); LOG_PROCESS_ERROR(pPlayer); LOG_PROCESS_ERROR(pPlayer->GetGameState() == gsWaitForConnect); LOG_PROCESS_ERROR(pPlayer->m_cPlayerServer.m_Guid == rConnGuid); pPlayer->SetTinyTerminal(bTinyTerminal); nPlayerIndex = pPlayer->GetPlayerIndex(); m_pnConnId2PlayerIndex[nConnectId] = nPlayerIndex; m_pnPlayerIndex2ConnId[nPlayerIndex] = nConnectId; m_mpAccount2Player[pPlayer->m_cPlayerServer.m_strAccount] = nPlayerIndex; g_RelayClient.DoConfirmPlayerLoginRequest(dwRoleId); pPlayer->SetGameState(gsWaitForPermit); pPlayer->m_nTimer = 0; nRetCode = TRUE; EXIT0: if (!nRetCode) { QLogPrintf(LOG_INFO, "Invalid Client: %d\n", nConnectId); if (pPlayer) QLogPrintf(LOG_INFO, "Player %d state %d\n", dwRoleId, pPlayer->GetGameState()); } return nRetCode; }
INT KPlayerMgr::GetAllPlayers(std::vector<KPlayer*>& rvPlayers) { INT nResult = 0; INT nPlayerIndex = 0; while ((nPlayerIndex = m_cObjMgr.NextUsedIndex(nPlayerIndex)) > 0) { KPlayer* pPlayer = m_cObjMgr.GetByIndex(nPlayerIndex); if (pPlayer->GetGameState() == gsPlaying) { LOG_PROCESS_ERROR(pPlayer); rvPlayers.push_back(pPlayer); } else { //QLogPrintf(LOG_INFO, "KPlayerMgr::GetAllPlayers Cull %d %d", pPlayer->GetPlayerId(), pPlayer->GetGameState()); } } nResult = 1; EXIT0: return nResult; }
BOOL KNetConnectPlayer::ProcessPacket( INT nConnectId, LPCBYTE pData, UINT uDataLen ) { QCONFIRM_RET_FALSE(nConnectId > 0 && nConnectId <= m_nMaxConnId); QCONFIRM_RET_FALSE(pData); RxStat(pData, uDataLen); INT nPlayerIndex = m_pnConnId2PlayerIndex[nConnectId]; if (nPlayerIndex == 0) { // Process Login KC2S_LOGIN *pLL = (KC2S_LOGIN* )pData; QCONFIRM_RET_FALSE(pLL->byProtocol == emKPLBASE_PTC_C2S_LOGIN && uDataLen == sizeof(KC2S_LOGIN)); //Q_Printl("pLL->byProtocol="<<pLL->byProtocol <<" uDataLen=" <<uDataLen); DWORD dwClientIp = 0; USHORT uClientPort = 0; g_piSocketServer->GetRemoteAddress(nConnectId, dwClientIp, uClientPort); Q_Printl("[ClientLogin] from [" << inet_ntoa(*(struct in_addr*)&dwClientIp) << ":" << uClientPort << "] ConnectionToken" << KGuidHelper::GuidToString(pLL->guid) << " pLL->dwTinyTerminal=" << pLL->dwTinyTerminal); // 玩家已连接上,未发Login协议前应为0 QCONFIRM(m_pnConnId2PlayerIndex[nConnectId] == 0); QCONFIRM_RET_FALSE(pLL->byGameServerVersion <= KD_PROTOCOL_VERSION && pLL->byGameServerVersion >= KD_PROTOCOL_VERSION_LOWER_LIMIT); return OnClientLogin2(pLL->dwRoleId, pLL->guid, nConnectId, pLL->nHidden,pLL->dwTinyTerminal); } QCONFIRM_RET_FALSE(uDataLen >= sizeof(BYTE) * 2); // Check Protocol Size INT nPtcSize = KPTC_SIZE::GetSizeC2S(*pData, *(pData + 1)); if (nPtcSize > 0) { QCONFIRM_RET_FALSE((UINT)nPtcSize == uDataLen); } else // 变长 { QCONFIRM_RET_FALSE(uDataLen >= sizeof(BYTE) * 3 && *(LPWORD)(pData + 2) == uDataLen); } KPlayer* pPlayer = g_cPlayerMgr.GetByIndex(nPlayerIndex); QCONFIRM_RET_FALSE(pPlayer); // Doing 协议过滤 if ( KNSBASE_EXT::DoingProtocolFilter[pPlayer->GetMoveState()] && ! (*KNSBASE_EXT::DoingProtocolFilter[pPlayer->GetMoveState()])(*pPlayer, pData, uDataLen) ) { QLogPrintf(LOG_ERR, "[%s] Doing为[%d]时禁止发送[PF %u, P %u] 协议被屏蔽", pPlayer->GetName(), pPlayer->GetMoveState(), LPCBYTE(pData)[0], LPCBYTE(pData)[1]); return TRUE; } // base协议处理 if (*pData == 0) return g_cPlayerBaseProcess.ProcessProtocol(nPlayerIndex, pData, uDataLen); PLAYER_GAME_STATE eGameState = pPlayer->GetGameState(); if (eGameState != gsPlaying) { KPTC_HEADER_BASE* pHeader = (KPTC_HEADER_BASE*)pData; QLogPrintf(LOG_ERR, "Protocol[%u, %u] blocked, Player[%d][%s] GameState[%d] is not 'gsPlaying'", pHeader->byProtocolFamily, pHeader->byProtocol, pPlayer->m_dwId, pPlayer->GetName(), eGameState); // 其他状态不接受扩展协议 return TRUE; } // 子模块协议处理 IKModuleInterface* piModule = g_cModuleManager.GetModule(BYTE(*pData) - KD_MAX_BASE_PROTOCOL_HEADER); if (!piModule) { Q_Error("Unrecognized Protocol " << BYTE(*pData) << " " << BYTE(*(pData+ 1)) << " Size " << uDataLen); return FALSE; } piModule->ProcessProtocol(nPlayerIndex, pData, uDataLen); return TRUE; }
BOOL KPlayerMgr::Activate() { static INT nPlayerIndex = 0; m_timeActivate = KSysService::GameTime(NULL); for (INT i = 0; i < KD_BATCH_PROCESS_PLAYER_MAX; ++i) { if (nPlayerIndex > m_cObjMgr.GetMaxCount()) { nPlayerIndex = 0; break; } nPlayerIndex = m_cObjMgr.NextUsedIndex(nPlayerIndex); if (nPlayerIndex <= 0) break; KPlayer* pPlayer = m_cObjMgr.GetByIndex(nPlayerIndex); QCONFIRM_RET_FALSE(pPlayer); PLAYER_GAME_STATE eGameState = pPlayer->GetGameState(); switch (eGameState) { case emPLAYERSTATE_BEGIN: // kick out break; case gsPlaying: OnRegularProcess(pPlayer); break; case gsWaitForConnect: // 等待登陆倒计时 if (pPlayer->m_nTimer++ >= LOGIN_TIMEOUT) { QLogPrintf( LOG_INFO, "Login timeout: acc = %s, role = %s\n", pPlayer->m_cPlayerServer.GetAccount(), pPlayer->GetName() ); g_cNetConnectPlayer.KickOutPlayer(pPlayer->GetPlayerIndex()); } break; case gsWaitForPermit: case gsWaitForRoleData: // 等待登陆倒计时 if (pPlayer->m_nTimer++ >= LOGIN_TIMEOUT) { QLogPrintf( LOG_INFO, "Relay permission or query role data, kicking (%s, %d)\n", pPlayer->GetName(), pPlayer->GetPlayerIndex() ); g_cNetConnectPlayer.KickOutPlayer(pPlayer->GetPlayerIndex()); } break; case gsWaitForLoginLoading: case gsWaitForNewMapLoading: break; case gsDeleting: // 掉线倒计时 if (pPlayer->m_nTimer++ >= LOGOUT_WAITING_TIME/* || !pPlayer->m_bFightState*/) { //pPlayer->SavePosition(); //// 这里之所以调RemovePlayer是为了在Save之前触发Trap(如果有的话),Trap可能会涉及存盘角色数据 //g_pWorld->RemovePlayer(pPlayer); //g_RelayClient.SaveRoleData(pPlayer); //g_pWorld->m_FellowshipMgr.UnloadPlayerFellowship(pPlayer->m_dwID); g_cNetConnectPlayer.KickOutPlayer(pPlayer->GetPlayerIndex()); } break; default: break; } } return TRUE; }