Beispiel #1
0
int KBishopClient::login_state_wait_delete_respond()
{
    int                     nResult             = false;
    int                     nRetCode            = false;
    tagNewDelRoleResponse  *pDeleteRoleRespond  = NULL;
    IKG_Buffer             *piBuffer            = NULL;
    unsigned                uBufferSize         = 0;
    timeval                 TimeoutValue        = {0, 100 * 1000};

    ASSERT(m_piSocketStream);
    nRetCode = m_piSocketStream->CheckCanRecv(&TimeoutValue);
    KGLOG_PROCESS_ERROR(nRetCode != -1);
    KG_PROCESS_SUCCESS(!nRetCode);

    nRetCode = m_piSocketStream->Recv(&piBuffer);
    KGLOG_PROCESS_ERROR(nRetCode == 1);

    uBufferSize = piBuffer->GetSize();
    KGLOG_PROCESS_ERROR(uBufferSize == sizeof(tagNewDelRoleResponse));
    pDeleteRoleRespond = (tagNewDelRoleResponse *)piBuffer->GetData();
    ASSERT(pDeleteRoleRespond);
    KGLOG_PROCESS_ERROR(pDeleteRoleRespond->cProtocol == B2C_CREATE_OR_DELETE_ROLE_RESULT);
    pDeleteRoleRespond->szRoleName[sizeof(pDeleteRoleRespond->szRoleName) - 1] = '\0';
    
    if (pDeleteRoleRespond->bSucceeded)
    {
        ROLE_LIST::iterator it;

        for (it = m_RoleList.begin(); it != m_RoleList.end(); ++it) 
        {
            nRetCode = strcmp(it->szRoleName, pDeleteRoleRespond->szRoleName);
            if (!nRetCode)
            {
                m_RoleList.erase(it);
                break;
            }
        }
    }
    else
    {        
        goto Exit0;
    }

    m_CurrentState = LOGIN_STATE_WAIT_PLAYER_OPERATE;
    
Exit1:    
    nResult = true;
Exit0:
    if (!nResult) 
    {  
        m_nLoginResult = Login_DeleteRole;
        m_CurrentState = LOGIN_STATE_NONE;
        KG_COM_RELEASE(m_piSocketStream);
    }
    KG_COM_RELEASE(piBuffer);
    return nResult;
}
Beispiel #2
0
const void *KClient::GetPackFromServer(unsigned int uLinkId, unsigned int &uLen)
{
	void* pRet = NULL;
	uLen = 0;
	do 
	{
		if (uLinkId >= (unsigned int)m_nMaxConnCount)
		{
			ASSERT(FALSE);
			break;
		}
		IKG_SocketStream* pConnection = m_ppConnections[uLinkId];
		//ASSERT(pConnection);
		if (!pConnection)
			return NULL;
		timeval sTimeOut = {0, 0};
		INT nResult = pConnection->CheckCanRecv(&sTimeOut);
		if (nResult == 0)
		{
			break;
		}
		else if (nResult == -1)
		{
			// 断线
			OnConnectionClose(uLinkId);
			pConnection->Release();
			break;
		}
		IKG_Buffer *pBuffer = NULL;
		nResult = pConnection->Recv(&pBuffer);
		if (nResult <= 0)
		{
			// 断线
			OnConnectionClose(uLinkId);
			pConnection->Release();
			break;
		}
		LPVOID pData = pBuffer->GetData();
		size_t nLen = pBuffer->GetSize();
		if (nLen > sizeof(m_szBuffer))
		{
			ASSERT(FALSE);
			pBuffer->Release();
			break;
		}
		memcpy(m_szBuffer, pData, nLen);
		uLen = nLen;
		pBuffer->Release();
		pRet = m_szBuffer;
	}
	while(0);
	return pRet;
}
Beispiel #3
0
int KBishopClient::login_state_wait_create_respond()
{
    int                     nResult             = false;
    int                     nRetCode            = false;
    tagNewDelRoleResponse  *pCreateRoleRespond  = NULL;
    IKG_Buffer             *piBuffer            = NULL;
    unsigned                uBufferSize         = 0;
    timeval                 TimeoutValue        = {0, 100 * 1000};

    ASSERT(m_piSocketStream);
    nRetCode = m_piSocketStream->CheckCanRecv(&TimeoutValue);
    KGLOG_PROCESS_ERROR(nRetCode != -1);
    KG_PROCESS_SUCCESS(!nRetCode);

    nRetCode = m_piSocketStream->Recv(&piBuffer);
    KGLOG_PROCESS_ERROR(nRetCode == 1);

    uBufferSize = piBuffer->GetSize();
    KGLOG_PROCESS_ERROR(uBufferSize == sizeof(tagNewDelRoleResponse));
    pCreateRoleRespond = (tagNewDelRoleResponse *)piBuffer->GetData();
    ASSERT(pCreateRoleRespond);
    KGLOG_PROCESS_ERROR(pCreateRoleRespond->cProtocol == B2C_CREATE_OR_DELETE_ROLE_RESULT);
    
    KGLOG_CHECK_ERROR(pCreateRoleRespond->bSucceeded);
    if (pCreateRoleRespond->bSucceeded)
    {
        strncpy(m_szLoginRole, m_RoleCreateParam.szRoleName, sizeof(m_szLoginRole));
        m_szLoginRole[sizeof(m_szLoginRole) - 1] = '\0';

		m_CurrentState = LOGIN_STATE_REQUEST_LOGIN_GAME;
    }
    else
    {        
		//m_CurrentState = LOGIN_STATE_WAIT_PLAYER_OPERATE;
        goto Exit0;
    }

Exit1:    
    nResult = true;
Exit0:
    if (!nResult) 
    {  
        m_nLoginResult = Login_CreateRole;
        m_CurrentState = LOGIN_STATE_NONE;
        KG_COM_RELEASE(m_piSocketStream);
    }
    KG_COM_RELEASE(piBuffer);
    return nResult;
}
Beispiel #4
0
int KBishopClient::login_state_wait_game_login_info()
{
    int                    nResult             = false;
    int                    nRetCode            = false;
    tagNotifyPlayerLogin  *pGameLoginInfo      = NULL;
    IKG_Buffer            *piBuffer            = NULL;
    unsigned               uBufferSize         = 0;
    timeval                TimeoutValue        = {0, 100 * 1000};
    struct in_addr         GameServerAddress;
    const char            *pcszGameServerIP    = NULL;

    ASSERT(m_piSocketStream);
    nRetCode = m_piSocketStream->CheckCanRecv(&TimeoutValue);
    KGLOG_PROCESS_ERROR(nRetCode != -1);
    KG_PROCESS_SUCCESS(!nRetCode);

    nRetCode = m_piSocketStream->Recv(&piBuffer);
    m_CurrentState = LOGIN_STATE_NONE;
    KG_COM_RELEASE(m_piSocketStream);
    KGLOG_PROCESS_ERROR(nRetCode == 1);

    uBufferSize = piBuffer->GetSize();
    KGLOG_PROCESS_ERROR(uBufferSize == sizeof(tagNotifyPlayerLogin));
    pGameLoginInfo = (tagNotifyPlayerLogin *)piBuffer->GetData();
    ASSERT(pGameLoginInfo);
    KGLOG_PROCESS_ERROR(pGameLoginInfo->cProtocol == B2C_NOTIFY_PLAYER_LOGIN_GAMESVR);

    KGLOG_CHECK_ERROR(pGameLoginInfo->nResult == ROLE_LOGIN_RESULT_SUCCESS);
    switch (pGameLoginInfo->nResult) 
    {
    case ROLE_LOGIN_RESULT_SUCCESS:
        // 启动游戏世界状态机 ...
        m_nLoginResult = Login_Sucess;

        GameServerAddress.s_addr = pGameLoginInfo->nIPAddr;
        pcszGameServerIP = inet_ntoa(GameServerAddress);
        ASSERT(pcszGameServerIP);
        KGLOG_PROCESS_ERROR(m_pOwner);
        nRetCode = m_pOwner->m_PlayerClient.Connect(pcszGameServerIP, pGameLoginInfo->wPort);
        if (nRetCode)
        {
            nRetCode = m_pOwner->m_PlayerClient.DoApplyPlayerData(pGameLoginInfo->szRoleName, pGameLoginInfo->guid);            
        }
        
    	break;
    case ROLE_LOGIN_RESULT_MAINTENANCE:
    case ROLE_LOGIN_RESULT_IS_FULL:
    case ROLE_LOGIN_RESULT_UNKNOWN:
    default:
        goto Exit0;
        break;
    }
    
Exit1:    
    nResult = true;
Exit0:
    if (!nResult) 
    {
        m_nLoginResult = Login_RequestLoginGameserver;
        m_CurrentState = LOGIN_STATE_NONE;
        KG_COM_RELEASE(m_piSocketStream);
    }

    KG_COM_RELEASE(piBuffer);    
    return nResult;
}
Beispiel #5
0
int KBishopClient::login_state_wait_role_list()
{
    int             nResult         = false;
    int             nRetCode        = false;
    TProcessData   *pTProcessData   = NULL;
    IKG_Buffer     *piBuffer        = NULL;
    unsigned        uBufferSize     = 0;
    timeval         TimeoutValue    = {0, 100 * 1000};
    int             nRoleCount      = 0;
    KBaseData      *pRoleBaseInfo   = NULL;
    int             nRoleIndex      = 0;

    ASSERT(m_piSocketStream);
    nRetCode = m_piSocketStream->CheckCanRecv(&TimeoutValue);
    KGLOG_PROCESS_ERROR(nRetCode != -1);
    KG_PROCESS_SUCCESS(!nRetCode);

    nRetCode = m_piSocketStream->Recv(&piBuffer);
    KGLOG_PROCESS_ERROR(nRetCode == 1);

    uBufferSize = piBuffer->GetSize();
    KGLOG_PROCESS_ERROR(uBufferSize >= sizeof(TProcessData));
    pTProcessData = (TProcessData *)piBuffer->GetData();
    ASSERT(pTProcessData);
    KGLOG_PROCESS_ERROR(pTProcessData->nProtoId == B2C_RETURN_ROLE_LIST);
    nRoleCount = pTProcessData->pDataBuffer[0];
    KGLOG_PROCESS_ERROR(uBufferSize == sizeof(TProcessData) + nRoleCount * sizeof(KBaseData));
    pRoleBaseInfo = (KBaseData *)(pTProcessData->pDataBuffer + 1);

    m_RoleList.clear();

    for (nRoleIndex = 0; nRoleIndex < nRoleCount; ++nRoleIndex) 
    {
        UI_ROLE_LIST_ITEM RoleListItem;

        pRoleBaseInfo[nRoleIndex].szAccount[sizeof(pRoleBaseInfo[nRoleIndex].szAccount) - 1] = 0;
        pRoleBaseInfo[nRoleIndex].szRoleName[sizeof(pRoleBaseInfo[nRoleIndex].szRoleName) - 1] = 0;
        
        strncpy(RoleListItem.szAccountName, pRoleBaseInfo[nRoleIndex].szAccount, sizeof(RoleListItem.szAccountName));
        RoleListItem.szAccountName[sizeof(RoleListItem.szAccountName) - 1] = '\0';

        strncpy(RoleListItem.szRoleName, pRoleBaseInfo[nRoleIndex].szRoleName, sizeof(RoleListItem.szRoleName));
        RoleListItem.szRoleName[sizeof(RoleListItem.szRoleName) - 1] = '\0';

        RoleListItem.nRoleType = pRoleBaseInfo[nRoleIndex].cRoleType;
        RoleListItem.nLevel    = (int)(pRoleBaseInfo[nRoleIndex].byLevel);

        memcpy(RoleListItem.wRepresentID, pRoleBaseInfo->wRepresentID, sizeof(RoleListItem.wRepresentID));

        m_RoleList.push_back(RoleListItem);
    }
    
    m_CurrentState = LOGIN_STATE_WAIT_PLAYER_OPERATE;
    
Exit1:    
    nResult = true;
Exit0:
    if (!nResult) 
    {  
        m_nLoginResult = Login_GetRolelist;
        m_CurrentState = LOGIN_STATE_NONE;
        KG_COM_RELEASE(m_piSocketStream);
    }
    KG_COM_RELEASE(piBuffer);
    return nResult;
}
Beispiel #6
0
int KBishopClient::login_state_wait_login_verify_respond()
{
    int                             nResult         = false;
    int                             nRetCode        = false;
    timeval                         TimeoutValue    = {0, 100 * 1000};
    unsigned                        uBufferSize     = 0;
    IKG_Buffer                     *piRespondBuffer = NULL;
    PLAYER_LOGIN_GATEWAY_RESPOND   *pVerifyRespond  = NULL;

    ASSERT(m_piSocketStream);
    nRetCode = m_piSocketStream->CheckCanRecv(&TimeoutValue);
    KGLOG_PROCESS_ERROR(nRetCode != -1);
    KG_PROCESS_SUCCESS(!nRetCode);

    nRetCode = m_piSocketStream->Recv(&piRespondBuffer);
    KGLOG_PROCESS_ERROR(nRetCode == 1);
    ASSERT(piRespondBuffer);

    uBufferSize = piRespondBuffer->GetSize();
    KGLOG_PROCESS_ERROR(uBufferSize == sizeof(PLAYER_LOGIN_GATEWAY_RESPOND));
    
    pVerifyRespond = (PLAYER_LOGIN_GATEWAY_RESPOND *)piRespondBuffer->GetData();
    ASSERT(pVerifyRespond);
    KGLOG_PROCESS_ERROR(pVerifyRespond->cProtocol == B2C_ACCOUNT_VERIFY_RESULT);

    switch (pVerifyRespond->nRespondCode) 
    {
    case LOGIN_R_SUCCESS:        
        if (m_nAutoLoginFlag)
        {
            // 自动选择角色登陆(断线重连)
            m_CurrentState   = LOGIN_STATE_REQUEST_LOGIN_GAME;
            m_nAutoLoginFlag = false;
        }
        else
        {
            // 手动选择角色登陆时,需要等待角色列表
            m_CurrentState = LOGIN_STATE_WAIT_ROLE_LIST;
        }
    	break;
    case LOGIN_R_ACCOUNT_OR_PASSWORD_ERROR:
    case LOGIN_R_ACTIVE:
    case LOGIN_R_CDKEY:
    case LOGIN_R_SUCCESS_AND_IN_GAME:
    case LOGIN_R_TIMEOUT:
    case LOGIN_R_SYSTEM_MAINTENANCE:
    case LOGIN_R_INVALID_PROTOCOLVERSION:
    case LOGIN_R_INVALID_PROTO:
    case LOGIN_R_ACCOUNT_EXIST:
    case LOGIN_R_FREEZE:
    case LOGIN_R_BLACK_LIST:
    case LOGIN_R_ACC_IN_GATEWAY:        
    default:
        goto Exit0;
        break;  
    }

Exit1:
    nResult = true;
Exit0:
    if (!nResult) 
    {         
        m_nLoginResult = Login_VerifyAccount;
        m_CurrentState = LOGIN_STATE_NONE;
        KG_COM_RELEASE(m_piSocketStream);
    }
    KG_COM_RELEASE(piRespondBuffer);
    return nResult;
}
Beispiel #7
0
BOOL KLogClient::ProcessPackage()
{
    BOOL                    bResult             = false;
    int                     nRetCode            = false;
    IKG_Buffer*             piBuffer            = NULL;

    KG_PROCESS_ERROR(m_piSocketStream);

    while (true)
    {
        const struct timeval        TimeVal     = {0, 0};
        INTERNAL_PROTOCOL_HEADER*   pHeader     = NULL;
        size_t                      uPakSize    = 0;
        PROCESS_PROTOCOL_FUNC       pFunc       = NULL;

        if (g_pSO3World->m_nCurrentTime - m_nLastSendPacketTime > m_nPingCycle)
        {
            DoPingSignal();
        }

        nRetCode = m_piSocketStream->CheckCanRecv(&TimeVal);
        if (nRetCode == -1)
        {
            m_bSocketError = true;
            goto Exit0;
        }
        if (nRetCode == 0)
        {
            break;
        }

        KGLOG_PROCESS_ERROR(nRetCode == 1);

        KG_COM_RELEASE(piBuffer);

        nRetCode = m_piSocketStream->Recv(&piBuffer);
        if (nRetCode == -1)
        {
            m_bSocketError = true;
            goto Exit0;
        }
        KGLOG_PROCESS_ERROR(nRetCode == 1);

        pHeader = (INTERNAL_PROTOCOL_HEADER*)piBuffer->GetData();
        KGLOG_PROCESS_ERROR(pHeader);

        KGLOG_PROCESS_ERROR(pHeader->wProtocolID < l2g_protocol_end);

        uPakSize = piBuffer->GetSize();
        KGLOG_PROCESS_ERROR(uPakSize >= m_uProtocolSize[pHeader->wProtocolID]);

        pFunc = m_ProcessProtocolFuns[pHeader->wProtocolID];
        if (pFunc == NULL)
        {
            KGLogPrintf(KGLOG_INFO, "Protocol %d not process!", pHeader->wProtocolID);
            goto Exit0;
        }

        (this->*pFunc)((BYTE*)pHeader, uPakSize);
    }

    bResult = true;
Exit0:
    if (m_piSocketStream && m_bSocketError)
    {
        KGLogPrintf(KGLOG_ERR, "Log server connection lost!\n");
        KG_COM_RELEASE(m_piSocketStream);
    }
    KG_COM_RELEASE(piBuffer);
    return bResult;
}
Beispiel #8
0
int KSimulateRelay::ProcessPackage()
{
    int                     nResult             = false;
    int                     nRetCode            = false;
    int                     nConnectionAlive    = false;
    IKG_Buffer*             piPackage           = NULL;
    PROTOCOL_FUNCTION       ProtocolFunc        = NULL;
    BYTE*                   pbyData             = NULL;
    size_t                  uDataLen            = 0;
    KGR_PROTOCOL_HEADER*    pHeader             = NULL;

    KG_PROCESS_ERROR(m_piSocket);

    nConnectionAlive = m_piSocket->IsAlive();
    KGLOG_PROCESS_ERROR(nConnectionAlive);

    while (true)
    {
        timeval TimeoutValue = {0, 0};

        nRetCode = m_piSocket->CheckCanRecv(&TimeoutValue);
        if (nRetCode == -1)
        {
            nConnectionAlive = false;
            goto Exit0;
        }

        if (nRetCode == 0)
            break;

        KG_COM_RELEASE(piPackage);

        nRetCode = m_piSocket->Recv(&piPackage);
        if (nRetCode != 1)
        {
            nConnectionAlive = false;
            goto Exit0;
        }

        KGLOG_PROCESS_ERROR(piPackage);

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

        uDataLen = piPackage->GetSize();
        KGLOG_PROCESS_ERROR(uDataLen >= sizeof(KGR_PROTOCOL_HEADER));

        pHeader = (KGR_PROTOCOL_HEADER*)pbyData;
        KGLOG_PROCESS_ERROR(pHeader->byProtocol > g2r_protocol_begin);
        KGLOG_PROCESS_ERROR(pHeader->byProtocol < g2r_protocol_total);

        ProtocolFunc = m_ProtocolFunctions[pHeader->byProtocol];
        if (ProtocolFunc == NULL)
            continue;
        if (pHeader->byProtocol != m_nDoNotRespondProtocol)
        {
            (this->*ProtocolFunc)(pbyData, uDataLen);
        }       
    }

    nResult = true;
Exit0:
    if (m_piSocket && !nConnectionAlive)
    {
        KGLogPrintf(KGLOG_INFO, "[Gateway] Connection lost !\n");
        KG_COM_RELEASE(m_piSocket);
    }
    KG_COM_RELEASE(piPackage);
    return nResult;
}
Beispiel #9
0
BOOL KApexProxy::Breathe()
{
    BOOL        bResult            = false;
    int         nRetCode           = false;
    IKG_Buffer* piBuffer           = NULL;
    BOOL        bConnectionAlive   = true;
    BYTE*       pbyRecvData        = NULL;
    size_t      uRecvDataLen       = 0;

    // if (m_piSocketStream == NULL) // Try Connect
    // {
    //     nRetCode = Connect(
    //         g_pSO3GameCenter->m_Settings.m_szApexServerIP,
    //         g_pSO3GameCenter->m_Settings.m_nApexServerPort
    //     );
    //     KG_PROCESS_ERROR(nRetCode);
    // }

    KG_PROCESS_ERROR(m_piSocketStream);

    // assert(m_piSocketStream);

    if (m_bSendErrorFlag)
    {
        bConnectionAlive = false;
        m_bSendErrorFlag = false;
        goto Exit0;
    }

    while (true)
    {
        timeval TimeVal = {0, 0};

        if (g_pSO3GameCenter->m_nTimeNow - m_nLastPingTime > g_pSO3GameCenter->m_Settings.m_nApexPingCycle)
        {
            DoPingSignal();
            m_nLastPingTime = g_pSO3GameCenter->m_nTimeNow;
        }

        nRetCode = m_piSocketStream->CheckCanRecv(&TimeVal);
        if (nRetCode == -1)
        {
            bConnectionAlive = false;
            goto Exit0;
        }
        if (nRetCode == 0)
        {
            break;
        }

        KGLOG_PROCESS_ERROR(nRetCode == 1);

        KG_COM_RELEASE(piBuffer);

        nRetCode = m_piSocketStream->Recv(&piBuffer);
        if (nRetCode == -1)
        {
            bConnectionAlive = false;
            goto Exit0;
        }
        KGLOG_PROCESS_ERROR(nRetCode == 1);

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

        uRecvDataLen = piBuffer->GetSize();

        ProcessRecvData(pbyRecvData, uRecvDataLen);
    }

    ClearTimeoutKickNode();

    bResult = true;
Exit0:
    if (m_piSocketStream && !bConnectionAlive)
    {
        KGLogPrintf(KGLOG_INFO, "[ApexProxy] Connection lost.");
        KG_COM_RELEASE(m_piSocketStream);
    }

    KG_COM_RELEASE(piBuffer);
    return bResult;
}
Beispiel #10
0
BOOL KPlayerManager::ProcessPackage(IKG_SocketStream* piSocket)
{
    BOOL                    bResult         = false;
    int                     nRetCode        = 0;
    int                     nPlayerIndex    = 0;
    KPlayerAgency*          pPlayer         = NULL;
    IKG_Buffer*             piBuffer        = NULL;
    BYTE*                   pbyData         = NULL;
    size_t                  uDataLen        = 0;
    KGC_PROTOCOL_HEADER*    pHeader         = NULL;
    PC2G_PROTOCOL_FUNC      ProtocolFunc    = NULL;

    assert(piSocket);

    nPlayerIndex = (int)(ptrdiff_t)(piSocket->GetUserData());

    pPlayer = GetPlayer(nPlayerIndex);
    KGLOG_PROCESS_ERROR(pPlayer);

    while (true)
    {
        KG_COM_RELEASE(piBuffer);

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

        if (nRetCode == -1)
        {
            KGLogPrintf(KGLOG_INFO, "Connection lost: %d(%s, %d)\n", nPlayerIndex, pPlayer->szAccount, pPlayer->nState);
            OnDisconnect(pPlayer);
            break;
        }

        KGLOG_PROCESS_ERROR(piBuffer);

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

        uDataLen = piBuffer->GetSize();
        KGLOG_PROCESS_ERROR(uDataLen >= sizeof(KGC_PROTOCOL_HEADER));

        pHeader = (KGC_PROTOCOL_HEADER*)pbyData;
        KGLOG_PROCESS_ERROR(pHeader->byProtocol > c2g_protocol_begin);
        KGLOG_PROCESS_ERROR(pHeader->byProtocol < c2g_protocol_total);

        ProtocolFunc = m_PakProcessor[pHeader->byProtocol];
        KGLOG_PROCESS_ERROR(ProtocolFunc);

        KGLOG_PROCESS_ERROR(uDataLen >= m_uPakSize[pHeader->byProtocol]);

	    (this->*ProtocolFunc)(pPlayer, pbyData, uDataLen);
    }

    bResult = true;
Exit0:
    KG_COM_RELEASE(piBuffer);
    return bResult;
}
Beispiel #11
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;
}