void CGateInfo::ProcSelectServer(SOCKET s, WORD wServerIndex) { _TDEFAULTMESSAGE DefMsg; char szEncodePacket[128]; char szEncodeAllPacket[256]; char szEncodeMsg[24]; char *pServerIP; GAMESERVERINFO *pServerInfo; PLISTNODE pListNode = xUserInfoList.GetHead(); while (pListNode) { CUserInfo *pUserInfo = xUserInfoList.GetData(pListNode); if (pUserInfo->sock == s) { if (!pUserInfo->fSelServerOk) { fnMakeDefMessageA(&DefMsg, SM_SELECTSERVER_OK, 0, pUserInfo->nCertification, 0, 0); int nPos = fnEncodeMessageA(&DefMsg, szEncodeMsg, sizeof(szEncodePacket)); szEncodeMsg[nPos] = '\0'; for ( PLISTNODE pNode = g_xGameServerList.GetHead(); pNode; pNode = g_xGameServerList.GetNext( pNode ) ) { pServerInfo = g_xGameServerList.GetData( pNode ); if ( pServerInfo->index == wServerIndex ) { pServerIP = pServerInfo->ip; pServerInfo->connCnt++; break; } } if ( !pServerIP ) break; pUserInfo->nServerID = wServerIndex; int nPos2 = fnEncode6BitBufA((unsigned char *)pServerIP, szEncodePacket, memlen(pServerIP), sizeof(szEncodePacket)); szEncodePacket[nPos2] = '\0'; memmove(szEncodeAllPacket, szEncodeMsg, nPos); memmove(&szEncodeAllPacket[nPos], szEncodePacket, nPos2); szEncodeAllPacket[nPos + nPos2] = '\0'; SendToGate(s, szEncodeAllPacket); pUserInfo->fSelServerOk = TRUE; pListNode = xUserInfoList.RemoveNode(pListNode); } } else pListNode = xUserInfoList.GetNext(pListNode); } }
UINT WINAPI LoadAccountRecords(LPVOID lpParameter) { //InsertLogMsg(IDS_LOADACCOUNTRECORDS); //下面这一段是获取服务器相关消息的,暂时屏蔽掉 //CRecordset *pRec = GetDBManager()->CreateRecordset(); //pRec->Execute( "UPDATE TBL_ACCOUNT SET FLD_CERTIFICATION=0 WHERE FLD_CERTIFICATION >= 30" ); //GetDBManager()->DestroyRecordset( pRec ); //// ---------------------------------------------------------------------------------------- //GAMESERVERINFO *pServerInfo; //pRec = GetDBManager()->CreateRecordset(); //if ( pRec->Execute( "SELECT * FROM TBL_SERVERINFO" ) ) //{ // while ( pRec->Fetch() ) // { // pServerInfo = new GAMESERVERINFO; // if ( !pServerInfo ) // break; // pServerInfo->index = atoi( pRec->Get( "FLD_SERVERIDX" ) ); // strcpy( pServerInfo->name, pRec->Get( "FLD_SERVERNAME" ) ); // strcpy( pServerInfo->ip, pRec->Get( "FLD_SERVERIP" ) ); // pServerInfo->connCnt = 0; // g_xGameServerList.AddNewNode( pServerInfo ); // } //} //GetDBManager()->DestroyRecordset( pRec ); GAMESERVERINFO *pServerInfo; char szTmp[64]; for ( PLISTNODE pNode = g_xGameServerList.GetHead(); pNode; pNode = g_xGameServerList.GetNext( pNode ) ) { pServerInfo = g_xGameServerList.GetData( pNode ); sprintf( szTmp, "%d,%s,", pServerInfo->index, pServerInfo->name ); strcat( g_szServerList, szTmp ); } // ---------------------------------------------------------------------------------------- InitServerThreadForMsg(); if (InitServerSocket(g_gcSock, &g_gcAddr, _IDM_GATECOMMSOCK_MSG, 5500, 1)) SwitchMenuItem(TRUE); return 0L; }
void LoadCharacterRecords() { InsertLogMsg(IDS_LOADACCOUNTRECORDS); CRecordset *pRec = GetDBManager()->CreateRecordset(); if ( pRec->Execute( "SELECT * FROM TBL_GAMEGATEINFO" ) ) { GAMESERVERINFO *pServerInfo; while ( pRec->Fetch() ) { pServerInfo = new GAMESERVERINFO; if ( !pServerInfo ) break; pServerInfo->index = atoi( pRec->Get( "FLD_SERVERIDX" ) ); strcpy( pServerInfo->name, pRec->Get( "FLD_SERVERNAME" ) ); strcpy( pServerInfo->ip, pRec->Get( "FLD_SERVERIP" ) ); pServerInfo->connCnt = 0; g_xGameServerList.AddNewNode( pServerInfo ); } } GetDBManager()->DestroyRecordset( pRec ); }
//UINT WINAPI AcceptThread(LPVOID lpParameter) DWORD WINAPI AcceptThread(LPVOID lpParameter) { int nLen = sizeof(SOCKADDR_IN); char szMsg[64]; SOCKET Accept; SOCKADDR_IN Address; while (TRUE) { Accept = accept(g_ssock, (struct sockaddr FAR *)&Address, &nLen); if (g_fTerminated) return 0; CSessionInfo* pNewUserInfo = (CSessionInfo*)GlobalAlloc(GPTR, sizeof(CSessionInfo)); if (pNewUserInfo) { pNewUserInfo->sock = Accept; CreateIoCompletionPort((HANDLE)pNewUserInfo->sock, g_hIOCP, (DWORD)pNewUserInfo, 0); if (g_xSessionList.AddNewNode(pNewUserInfo)) { int zero = 0; setsockopt(pNewUserInfo->sock, SOL_SOCKET, SO_SNDBUF, (char *)&zero, sizeof(zero) ); // ORZ: pNewUserInfo->Recv(); UpdateStatusBar(TRUE); szMsg[0] = '%'; szMsg[1] = 'O'; char *pszPos = ValToAnsiStr((int)Accept, &szMsg[2]); *pszPos++ = '/'; pszPos = ValToAnsiStr((int)Address.sin_addr.s_net, pszPos); *pszPos++ = '.'; pszPos = ValToAnsiStr((int)Address.sin_addr.s_host, pszPos); *pszPos++ = '.'; pszPos = ValToAnsiStr((int)Address.sin_addr.s_lh, pszPos); *pszPos++ = '.'; pszPos = ValToAnsiStr((int)Address.sin_addr.s_impno, pszPos); *pszPos++ = '$'; *pszPos = '\0'; SendExToServer(szMsg); } } } return 0; }
DWORD WINAPI AcceptThread(LPVOID lpParameter) { int nLen = sizeof(SOCKADDR_IN); SOCKET Accept; SOCKADDR_IN Address; DWORD dwRecvBytes; DWORD dwFlags; TCHAR szGateIP[16]; while (TRUE) { Accept = accept(g_ssock, (struct sockaddr FAR *)&Address, &nLen); if (g_fTerminated) return 0L; CServerInfo* pServerInfo = (CServerInfo*)GlobalAlloc(GPTR, sizeof(CServerInfo)); if (pServerInfo) { pServerInfo->m_sock = Accept; CreateIoCompletionPort((HANDLE)pServerInfo->m_sock, g_hIOCP, (DWORD)pServerInfo, 0); if (g_xServerList.AddNewNode(pServerInfo)) { int zero = 0; setsockopt(pServerInfo->m_sock, SOL_SOCKET, SO_SNDBUF, (char *)&zero, sizeof(zero)); ZeroMemory(&(pServerInfo->Overlapped), sizeof(OVERLAPPED)); pServerInfo->DataBuf.len = DATA_BUFSIZE; pServerInfo->DataBuf.buf = pServerInfo->Buffer; pServerInfo->nOvFlag = OVERLAPPED_RECV; dwFlags = 0; WSARecv(pServerInfo->m_sock, &(pServerInfo->DataBuf), 1, &dwRecvBytes, &dwFlags, &(pServerInfo->Overlapped), NULL); UpdateStatusBarSession(TRUE); _stprintf(szGateIP, _T("%d.%d.%d.%d"), Address.sin_addr.s_net, Address.sin_addr.s_host, Address.sin_addr.s_lh, Address.sin_addr.s_impno); InsertLogMsgParam(IDS_ACCEPT_GATESERVER, szGateIP, LOGPARAM_STR); } } } return 0; }
UINT WINAPI LoadAccountRecords(LPVOID lpParameter) { //获取服务器列表的 GAMESERVERINFO *pServerInfo; char szTmp[64]; for ( PLISTNODE pNode = g_xGameServerList.GetHead(); pNode; pNode = g_xGameServerList.GetNext( pNode ) ) { pServerInfo = g_xGameServerList.GetData( pNode ); sprintf( szTmp, "%d,%s,", pServerInfo->index, pServerInfo->name ); strcat( g_szServerList, szTmp ); } // ---------------------------------------------------------------------------------------- //服务器线程 InitServerThreadForMsg(); ENGINE_COMPONENT_INFO info = g_SeverConfig.getLoginSrvInfo(); if (InitServerSocket(g_gcSock, &g_gcAddr, _IDM_GATECOMMSOCK_MSG, info.intport?info.intport:5500, 1)) SwitchMenuItem(TRUE); return 0L; }
DWORD WINAPI AcceptThread(LPVOID lpParameter) { int nLen = sizeof(SOCKADDR_IN); SOCKET Accept; SOCKADDR_IN Address; while (TRUE) { Accept = accept(g_gcSock, (struct sockaddr FAR *)&Address, &nLen); if (g_fTerminated) return 0; CGateInfo* pGateInfo = new CGateInfo; if (pGateInfo) { pGateInfo->sock = Accept; CreateIoCompletionPort((HANDLE)pGateInfo->sock, g_hIOCP, (DWORD)pGateInfo, 0); if (g_xGateList.AddNewNode(pGateInfo)) { int zero = 0; setsockopt(pGateInfo->sock, SOL_SOCKET, SO_SNDBUF, (char *)&zero, sizeof(zero) ); pGateInfo->Recv(); UpdateStatusBar(TRUE); #ifdef _DEBUG TCHAR szGateIP[256]; wsprintf(szGateIP, _T("%d.%d.%d.%d"), Address.sin_addr.s_net, Address.sin_addr.s_host, Address.sin_addr.s_lh, Address.sin_addr.s_impno); InsertLogMsgParam(IDS_ACCEPT_GATESERVER, szGateIP); #endif } } } return 0; }
UINT WINAPI ThreadFuncForMsg(LPVOID lpParameter) { _TDEFAULTMESSAGE DefaultMsg; char *pszBegin, *pszEnd; int nCount; PLISTNODE pListNode; CGateInfo* pGateInfo; while (TRUE) { if (g_xGateList.GetCount()) { pListNode = g_xGateList.GetHead(); while (pListNode) { pGateInfo = g_xGateList.GetData(pListNode); if (pGateInfo) { nCount = pGateInfo->g_SendToGateQ.GetCount(); if (nCount) { for (int nLoop = 0; nLoop < nCount; nLoop++) { _LPTSENDBUFF pSendBuff = (_LPTSENDBUFF)pGateInfo->g_SendToGateQ.PopQ(); if (pSendBuff) { int nLen = memlen(pSendBuff->szData); if ((pszBegin = (char *)memchr(pSendBuff->szData, '#', nLen)) &&(pszEnd = (char *)memchr(pSendBuff->szData, '!', nLen))) { *pszEnd = '\0'; fnDecodeMessageA(&DefaultMsg, (pszBegin + 2)); // 2 = "#?" ? = Check Code switch (DefaultMsg.wIdent) { case CM_PROTOCOL: break; case CM_IDPASSWORD: pGateInfo->ProcLogin(pSendBuff->sock, pszBegin + DEFBLOCKSIZE + 2); break; case CM_SELECTSERVER: pGateInfo->ProcSelectServer(pSendBuff->sock, DefaultMsg.wParam); break; case CM_ADDNEWUSER: pGateInfo->ProcAddUser(pSendBuff->sock, pszBegin + DEFBLOCKSIZE + 2); break; case CM_UPDATEUSER: break; case CM_CHANGEPASSWORD: break; } } delete pSendBuff; pSendBuff = NULL; } } } } pListNode = g_xGateList.GetNext(pListNode); } } SleepEx(1, TRUE); } return 0; }
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID) { DWORD dwBytesTransferred = 0; CSessionInfo* pSessionInfo = NULL; _LPTCOMPLETIONPORT lpPerIoData = NULL; char szPacket[DATA_BUFSIZE * 2]; char szMsg[32]; char *pszPos; while (TRUE) { if ( GetQueuedCompletionStatus( (HANDLE)CompletionPortID, &dwBytesTransferred, (LPDWORD)&pSessionInfo, (LPOVERLAPPED *)&lpPerIoData, INFINITE) == 0) { if (g_fTerminated) return 0; if (pSessionInfo) { szMsg[0] = '%'; szMsg[1] = 'X'; char *pszPos = ValToAnsiStr((int)pSessionInfo->sock, &szMsg[2]); *pszPos++ = '$'; *pszPos = '\0'; SendExToServer(szMsg); g_xSessionList.RemoveNodeByData(pSessionInfo); closesocket(pSessionInfo->sock); pSessionInfo->sock = INVALID_SOCKET; UpdateStatusBar(FALSE); GlobalFree(pSessionInfo); } continue; } if (g_fTerminated) return 0; if (dwBytesTransferred == 0) { szMsg[0] = '%'; szMsg[1] = 'X'; char *pszPos = ValToAnsiStr((int)pSessionInfo->sock, &szMsg[2]); *pszPos++ = '$'; *pszPos = '\0'; SendExToServer(szMsg); g_xSessionList.RemoveNodeByData(pSessionInfo); closesocket(pSessionInfo->sock); pSessionInfo->sock = INVALID_SOCKET; UpdateStatusBar(FALSE); GlobalFree(pSessionInfo); continue; } // ORZ: pSessionInfo->bufLen += dwBytesTransferred; while ( pSessionInfo->HasCompletionPacket() ) { szPacket[0] = '%'; szPacket[1] = 'A'; pszPos = ValToAnsiStr( (int) pSessionInfo->sock, &szPacket[2] ); *pszPos++ = '/'; pszPos = pSessionInfo->ExtractPacket( pszPos ); *pszPos++ = '$'; *pszPos = '\0'; SendExToServer( szPacket ); } // ORZ: if ( pSessionInfo->Recv() == SOCKET_ERROR && WSAGetLastError() != ERROR_IO_PENDING ) { InsertLogMsg(_TEXT("WSARecv() failed")); CloseSession(pSessionInfo->sock); continue; } } return 0; }
DWORD WINAPI ServerWorkerThread(LPVOID CompletionPortID) { DWORD dwBytesTransferred = 0; CGateInfo* pGateInfo = NULL; LPOVERLAPPED lpOverlapped = NULL; char szTmp[DATA_BUFSIZE]; while (TRUE) { if ( GetQueuedCompletionStatus( (HANDLE)CompletionPortID, &dwBytesTransferred, (LPDWORD)&pGateInfo, (LPOVERLAPPED *)&lpOverlapped, INFINITE) == 0 ) { return 0; } if (g_fTerminated) { PLISTNODE pListNode; if (g_xGateList.GetCount()) { pListNode = g_xGateList.GetHead(); while (pListNode) { pGateInfo = g_xGateList.GetData(pListNode); if (pGateInfo) pGateInfo->Close(); delete pGateInfo; pGateInfo = NULL; pListNode = g_xGateList.RemoveNode(pListNode); } } return 0; } if ( dwBytesTransferred == 0 ) { pGateInfo->Close(); continue; } pGateInfo->bufLen += dwBytesTransferred; while ( pGateInfo->HasCompletionPacket() ) { *(pGateInfo->ExtractPacket( szTmp ) - 1) = '\0'; switch ( szTmp[1] ) { case '-': pGateInfo->SendKeepAlivePacket(); break; case 'A': pGateInfo->ReceiveSendUser(&szTmp[2]); break; case 'O': pGateInfo->ReceiveOpenUser(&szTmp[2]); break; case 'X': pGateInfo->ReceiveCloseUser(&szTmp[2]); break; case 'S': pGateInfo->ReceiveServerMsg(&szTmp[2]); break; case 'M': pGateInfo->MakeNewUser(&szTmp[2]); break; } } if ( pGateInfo->Recv() == SOCKET_ERROR && WSAGetLastError() != ERROR_IO_PENDING ) { InsertLogMsg(_TEXT("WSARecv() failed")); continue; } } return 0; }
//处理操作 UINT WINAPI ThreadFuncForMsg(LPVOID lpParameter) { _TDEFAULTMESSAGE DefaultMsg; char *pszBegin, *pszEnd; int nCount; PLISTNODE pListNode; CGateInfo* pGateInfo; while (TRUE) { if (g_xGateList.GetCount()) { pListNode = g_xGateList.GetHead(); while (pListNode) { pGateInfo = g_xGateList.GetData(pListNode); if (pGateInfo) { nCount = pGateInfo->g_SendToGateQ.GetCount(); if (nCount) { for (int nLoop = 0; nLoop < nCount; nLoop++) { _LPTSENDBUFF pSendBuff = (_LPTSENDBUFF)pGateInfo->g_SendToGateQ.PopQ(); //先解密 if (pSendBuff) { int nLen = pSendBuff->nLen; pSendBuff->szData[nLen] = '\0'; pszBegin = pSendBuff->szData; { //解密 Packet *pPacket = (Packet*)pSendBuff->szData; /*pPacket->dlen = pPacket->crc^ pPacket->dlen;*/ switch(pPacket->Category) { case ACCOUNT: pGateInfo->AccountProcess(pSendBuff->sock,pPacket); break; default: break; } //switch (DefaultMsg.wIdent) //{ // case CM_PROTOCOL: // break; // case CM_IDPASSWORD: // pGateInfo->ProcLogin(pSendBuff->sock, pszBegin + DEFBLOCKSIZE + 2); // break; // case CM_SELECTSERVER: // pGateInfo->ProcSelectServer(pSendBuff->sock, DefaultMsg.wParam); // break; // case CM_ADDNEWUSER: // pGateInfo->ProcAddUser(pSendBuff->sock, pszBegin + DEFBLOCKSIZE + 2); // break; // case CM_UPDATEUSER: // break; // case CM_CHANGEPASSWORD: // break; //} } delete pSendBuff; pSendBuff = NULL; } } } } pListNode = g_xGateList.GetNext(pListNode); } } SleepEx(1, TRUE); } return 0; }
void CGateInfo::GetSelectCharacter(SOCKET s, char *pszPacket) { char szDecodeMsg[128]; char szServerIP[32]; char szEncodeMsg[32]; char szEncodeData[64]; char szEncodePacket[256]; _TDEFAULTMESSAGE DefaultMsg; // ORZ: Load Balancing, 접속수가 가장 적은 게이트 서버 IP 선택 GAMESERVERINFO *pBestServer = NULL; GAMESERVERINFO *pTemp; // EnterCriticalSection( &g_xGameServerList.m_cs ); for ( PLISTNODE pNode = g_xGameServerList.GetHead();pNode; pNode = g_xGameServerList.GetNext( pNode ) ) { pTemp = g_xGameServerList.GetData( pNode ); if ( !pBestServer || pTemp->connCnt < pBestServer->connCnt ) { pBestServer = pTemp; continue; } } pBestServer->connCnt++; // LeaveCriticalSection( &g_xGameServerList.m_cs ); strcpy( szServerIP, pBestServer->ip ); // ORZ: from here int nPos = fnDecode6BitBufA(pszPacket, szDecodeMsg, sizeof(szDecodeMsg)); szDecodeMsg[nPos] = '\0'; char *pszDevide = (char *)memchr(szDecodeMsg, '/', nPos); if (pszDevide) { *pszDevide++ = '\0'; // 서버 선택이 가능하도록 수정 _TLOADHUMAN tLoadHuman; CServerInfo* pServerInfo; memcpy(tLoadHuman.szUserID, szDecodeMsg, memlen(szDecodeMsg)); memcpy(tLoadHuman.szCharName, pszDevide, memlen(pszDevide)); ZeroMemory(tLoadHuman.szUserAddr, sizeof(tLoadHuman.szUserAddr)); tLoadHuman.nCertification = 0; PLISTNODE pListNode = g_xServerList.GetHead(); if (pListNode) pServerInfo = g_xServerList.GetData(pListNode); GetLoadHumanRcd(pServerInfo, &tLoadHuman, 0); fnMakeDefMessageA(&DefaultMsg, SM_STARTPLAY, 0, 0, 0, 0); nPos = fnEncodeMessageA(&DefaultMsg, szEncodeMsg, sizeof(szEncodeMsg)); int nPos2 = fnEncode6BitBufA((unsigned char *)szServerIP, szEncodeData, memlen(szServerIP) -1, sizeof(szEncodeData)); memmove(szEncodePacket, szEncodeMsg, nPos); memmove(&szEncodePacket[nPos], szEncodeData, nPos2); szEncodePacket[nPos + nPos2] = '\0'; // ORZ: 전체 리스트에 추가한다. // 같은 아이디가 이미 존재하거나 메모리 부족등의 이유로 실패할 수 있다. // if ( GetGlobalUserList()->Insert( tLoadHuman.szCharName, szServerIP ) ) SendToGate(s, szEncodePacket); // else // { // fnMakeDefMessageA(&DefaultMsg, SM_STARTFAIL, 0, 0, 0, 0); // nPos = fnEncodeMessageA(&DefaultMsg, szEncodeMsg, sizeof(szEncodeMsg)); // szEncodeMsg[nPos] = '\0'; // SendToGate(pGateInfo->sock, s, szEncodeMsg); // } } }
//UINT WINAPI AcceptThread(LPVOID lpParameter) //logingate接受线程 DWORD WINAPI AcceptThread(LPVOID lpParameter) { int nLen = sizeof(SOCKADDR_IN); char szMsg[128] = {0}; SOCKET Accept; SOCKADDR_IN Address; while (TRUE) { Accept = accept(g_ssock, (struct sockaddr FAR *)&Address, &nLen); if (g_fTerminated) return 0; CSessionInfo* pNewUserInfo = CSessionInfo::ObjPool().createObject();//(CSessionInfo*)GlobalAlloc(GPTR, sizeof(CSessionInfo)); if (pNewUserInfo) { pNewUserInfo->sock = Accept; CreateIoCompletionPort((HANDLE)pNewUserInfo->sock, g_hIOCP, (DWORD)pNewUserInfo, 0); if (g_xSessionList.AddNewNode(pNewUserInfo)) { int zero = 0; setsockopt(pNewUserInfo->sock, SOL_SOCKET, SO_SNDBUF, (char *)&zero, sizeof(zero) ); zero = 0; setsockopt( pNewUserInfo->sock, SOL_SOCKET, SO_RCVBUF, (char*)&zero, sizeof(zero)); int nodelay = 1; setsockopt( pNewUserInfo->sock, IPPROTO_TCP, TCP_NODELAY, (char*)&nodelay, sizeof(nodelay) ); // ORZ:接受数据 int retcode = pNewUserInfo->Recv(); if ( (retcode == SOCKET_ERROR) && (WSAGetLastError() != WSA_IO_PENDING) ) { continue; } UpdateStatusBar(TRUE); szMsg[0] = '%'; szMsg[1] = 'O'; char *pszPos = ValToAnsiStr((int)Accept, &szMsg[2]); *pszPos++ = '/'; pszPos = ValToAnsiStr((int)Address.sin_addr.s_net, pszPos); *pszPos++ = '.'; pszPos = ValToAnsiStr((int)Address.sin_addr.s_host, pszPos); *pszPos++ = '.'; pszPos = ValToAnsiStr((int)Address.sin_addr.s_lh, pszPos); *pszPos++ = '.'; pszPos = ValToAnsiStr((int)Address.sin_addr.s_impno, pszPos); *pszPos++ = '$'; *pszPos = '\0'; //发送给loginsrv更新 SendExToServer(szMsg); } } } return 0; }