Example #1
0
BOOL KPlayerServer::ProcessPackage(IKG_SocketStream* piSocket)
{
    BOOL                bResult         = false;
    int                 nRetCode        = 0;
    int                 nConnIndex      = -1;
    IKG_Buffer*         piBuffer        = NULL;
    BYTE*               pbyData         = NULL;
    unsigned            uDataLen        = 0;
    int                 nPackCount      = 0;
    BOOL                bShutDownFlag   = false;

    assert(piSocket);

    nConnIndex = (int)(ptrdiff_t)(piSocket->GetUserData());
    KGLOG_PROCESS_ERROR(nConnIndex >= 0 && nConnIndex < m_nMaxConnection);

    while (true)
    {
        KG_COM_RELEASE(piBuffer);

       /* if (nPackCount++ >= m_nMaxClientPackPerFrame)
        {
            KGLogPrintf(KGLOG_INFO, "Client send too many packs, connection: %d\n", nConnIndex);

            bShutDownFlag = true;
            break;
        }*/

        nRetCode = piSocket->Recv(&piBuffer);
        if (nRetCode == -2)
        {
            break;
        }

        if (nRetCode == -1)
        {
            KPlayer* pPlayer = GetPlayerByConnection(nConnIndex);
            int r = piSocket->GetLastError();

            if (pPlayer)
                KGLogPrintf(KGLOG_INFO, "Connection lost: %d, err:%d, player:%d\n", nConnIndex, r, pPlayer->m_dwID);
            else
                KGLogPrintf(KGLOG_INFO, "Connection lost: %d, err:%d\n", nConnIndex, r);

            bShutDownFlag = true;
            break;
        }

        KGLOG_PROCESS_ERROR(piBuffer);

        pbyData   = (BYTE*)piBuffer->GetData();
        KGLOG_PROCESS_ERROR(pbyData);

        uDataLen = piBuffer->GetSize();

        nRetCode  = CheckPackage(pbyData, uDataLen);
        if (!nRetCode)
        {
		    KGLogPrintf(KGLOG_INFO, "Pak error, connection: %d\n", nConnIndex);

            bShutDownFlag = true;
            break;
        }

        KPlayer*        pPlayer = GetPlayerByConnection(nConnIndex);
	    KC2S_Header*    pHeader = (KC2S_Header*)pbyData;

        if (m_bCloseFlag[pHeader->protocolID] != 0)
            continue;

        m_nC2STraffic += (int)uDataLen;

        m_C2SPakStat[pHeader->protocolID].dwPackCount++;
        m_C2SPakStat[pHeader->protocolID].uTotalSize += uDataLen;

        m_ConnectionDataList[nConnIndex].dwLastPingTime = m_dwTimeNow;

        if (pPlayer)
        {
            if (pPlayer->m_eGameStatus == gsPlaying)
            {
                // 帧数不可能比前面的还低, 帧数不可能超过服务端一定范围(客户端帧平衡算法决定的)
                if (
                    (pHeader->frame < pPlayer->m_nLastClientFrame) //|| 
                    //(pHeader->nFrame > g_pSO3World->m_nGameLoop + GAME_FPS / 2)
                )
                {
                    KGLogPrintf(
                        KGLOG_ERR, "Frame error(%d): last frame = %d, pak frame = %d , server frame = %d\n", 
                        nConnIndex, pPlayer->m_nLastClientFrame, pHeader->frame, g_pSO3World->m_nGameLoop
                    );

                    bShutDownFlag = true;
                    break;
                }

                KHero* pFightingHero = pPlayer->GetFightingHero();
                if (!pFightingHero)
                    continue;

                if (!pFightingHero->m_pScene)
                    continue;

                BOOL bShouldSkip = false;

                switch (pFightingHero->m_pScene->m_eSceneState)
                {
                case ssWaitingClientLoading:
                    if (pHeader->protocolID != c2s_ping_signal && pHeader->protocolID != c2s_loading_complete)
                        bShouldSkip = true;
                    break;
                case ssCountDown:
                    if (pHeader->protocolID != c2s_ping_signal && pHeader->protocolID != c2s_apply_leave_mission)
                        bShouldSkip = true;
                    break;
                case ssFighting:
                    break;
                default:
                    bShouldSkip = true;
                    break;
                }
                
                if (bShouldSkip)
                    continue;
                
            }
        }
        else
        {
            // 玩家指针为空,这时候只允许极少数几个协议上来
            if (pHeader->protocolID != c2s_handshake_request && pHeader->protocolID != c2s_ping_signal)
            {
                continue;
            }
        }

	    (this->*m_ProcessProtocolFuns[pHeader->protocolID])(
            (char*)pbyData, (int)uDataLen, nConnIndex, pHeader->frame
        );

        if (pPlayer && (pPlayer->m_nLastClientFrame < pHeader->frame))
        {
            nPackCount = 0;
            pPlayer->m_nLastClientFrame = pHeader->frame;
        }
    }

    bResult = true;
Exit0:
    if (bShutDownFlag)
    {
        Detach(nConnIndex);
        Shutdown(nConnIndex);
        bShutDownFlag = false;
    }
    KG_COM_RELEASE(piBuffer);
    return bResult;
}