Example #1
0
void __stdcall ShowServerStatusDetail(DWORD dwValue)//020511 lsw
{
	DWORD dwCount = 0;

	if( g_pServerTable )
	{
		LP_SERVER_DATA pDummyServerData = g_pServerTable->GetServerListHead();
		while( pDummyServerData )
		{
			dwCount++;
			MyLog( LOG_NORMAL, "<< %2d / %12s / %4d >> UsingDB: %4d(%6d), NumOfUsers: %4d, Status: %c >>"
				, dwCount
				, GetTypedServerText(pDummyServerData->dwServerType)
				, pDummyServerData->wPort
				, (pDummyServerData->pUsingDBDemon?pDummyServerData->pUsingDBDemon->wPort:0)
				, (pDummyServerData->pUsingDBDemon?g_pServerTable->GetDBLoad( pDummyServerData->pUsingDBDemon ):0)
				, pDummyServerData->dwNumOfUsers
				, ServerStatusSymbols[pDummyServerData->dwStatus] );

			pDummyServerData = pDummyServerData->pNextServerData;
		}
		MyLog( LOG_NORMAL, "-- Total %d Servers are listed", dwCount );
	}
	else
	{
		MyLog( LOG_JUST_DISPLAY, "<< g_pServerTable Is not available >>" );
	}
}
Example #2
0
// ==========================================================================================
void __stdcall RecvMsgFromServer( DWORD dwConnectionIndex, char *pMsg, DWORD dwLength )
{
	BYTE bID;
	bID = (BYTE)pMsg[0];
	USERINFO *pUser;

	if (dwConnectionIndex == 0)
	{
#ifdef __ON_DEBUG
//		_asm int 3;
#endif
		return;
	}

	if( bID == (BYTE)PTCL_NOTIFY_SERVER_UP )
	{
		if( g_pServerTable->OnRecvServerUpMsg(dwConnectionIndex, *(WORD*)(pMsg+1)) )
		{
#ifdef __ON_DEBUG
//			_asm int 3;
#endif
		}
		return;
	}

	LP_SERVER_DATA pSender = g_pServerTable->GetConnectedServerData( dwConnectionIndex );

	if( !pSender ) return;

	switch (bID)
	{
	// -------------
	// 기본패킷 
	// -------------
	// 전용
	case PTCL_ORDER_SET_SERVER_LIST:
	case PTCL_ORDER_CONNECT_TO_SERVERS:
	case PTCL_ORDER_SET_DB_DEMON:
	case PTCL_ORDER_TO_REPORT_SERVER_DATAS:
	case PTCL_NOTIFY_YOU_ARE_CERTIFIED:

	//공통
	case PTCL_ORDER_DESTROY_SERVER:
	case PTCL_NOTIFY_SERVER_STATUS:
 	case PTCL_SERVER_TRY_TO_CHECK_CONNECTION:
	case PTCL_SERVER_CONNECTION_OK:
	case PTCL_ORDER_TO_REPORT_SERVER_STATUS:
		{	
			if( !g_pServerTable->OnRecvNegotiationMsgs( pSender, bID, pMsg+1, dwLength-1 ) )
			{
				MyLog( LOG_FATAL, "OnRecvNegotiationMsg() Failed :: (pSender(%d), bId(%d), MsgLength(%d))", pSender->wPort, bID, dwLength );
#ifdef __ON_DEBUG
//				_asm int 3;
#endif
			}
		}	
		break;
	// ---------------
	// AGENT 전용 패킷
	// ---------------
	case PTCL_MAP_TO_AGENT_CHECK_IS_USER_GHOST:
		{	//< CSD-030515
			char szAnswer[64+1];
			LP_REQUEST_REMOVE_GHOST_USER_PACKET pAnswer = (LP_REQUEST_REMOVE_GHOST_USER_PACKET)(szAnswer + 1);
			LP_CHECK_IS_USER_GHOST_PACKET pPacket = (LP_CHECK_IS_USER_GHOST_PACKET)(pMsg + 1);
			
			if (pPacket->dwID <= 0)
			{
				MyLog( LOG_FATAL, "PTCL_MAP_TO_AGENT_CHECK_IS_USER_GHOST :: dwID < 0 !!! (From %d/%d)", dwConnectionIndex, pSender->wPort );
				break;
			}

			pUser = g_pUserTable->GetUserInfo(pPacket->dwID);

			if (pUser == NULL)
			{	//  없다. 이건 GHOST!
				szAnswer[0] = PTCL_AGENT_TO_MAP_REQUEST_REMOVE_GHOST_USER;
				pAnswer->dwID = pPacket->dwID;

				if( !g_pServerTable->Send(dwConnectionIndex, szAnswer, sizeof(BYTE)+sizeof(REQUEST_REMOVE_GHOST_USER_PACKET)))
				{
					MyLog(LOG_FATAL, "PTCL_MAP_TO_AGENT_CHECK_IS_USER_GHOST :: Failed To Answer!!! (From %d/%d)", dwConnectionIndex, pSender->wPort);
				}
				// Proxy에서 로그아웃을 하도록 함
				static char szDummy[1 + ID_LENGTH];
				memset(szDummy, 0, sizeof(szDummy));
				szDummy[0] = BYTE(PTCL_PROXY_TO_LOGOUT);
				memcpy(szDummy + 1, pPacket->szID, ID_LENGTH);

				if (!g_pServerTable->SendToProxyServer(szDummy, 1 + ID_LENGTH))
				{
					MyLog(LOG_IMPORTANT, "Failed To send 'PTCL_PROXY_TO_LOGOUT' to Proxy");
				}

				MyLog(LOG_FATAL, "PTCL_MAP_TO_AGENT_CHECK_IS_USER_GHOST :: User Name : %s!!! (From %d/%d)", pPacket->szID, dwConnectionIndex, pSender->wPort);
			}

			break;
		}	//> CSD-030515
	case PTCL_BROADCAST_TO_SERVERS:
		{	
			t_packet raja_packet;
			memset(&raja_packet,0,sizeof(t_packet));
			memcpy(raja_packet.h.data, pMsg+1, 5);
			memcpy(raja_packet.u.data, pMsg+1+5, raja_packet.h.header.size);
			char szName[21];
			// 패킷안의 이름 정보를 카피하고 널스트링을 넣는다 
			memcpy(szName,raja_packet.u.login_close_login_id.id,20);
			szName[20] = NULL;
			
			if (raja_packet.h.header.type == CMD_CLOSE_LOGIN_ID)
			{
				USERINFO* cur = NULL;
				USERINFO* next = NULL;
				USERINFO** pTable = g_pUserTable->GetUserInfoTable();
				for (DWORD i=0; i<g_pUserTable->GetBucketNum(); i++)
				{
					cur = pTable[i];
					while (cur)
					{
						next = cur->pNextUserInfo;
						if (strcmp(cur->szName,szName ) == 0)
						{
							// 해당 유저에게 끊도록 권고한다.
							g_pUserTable->DisconnectUserBySuggest( cur, CMD_CLOSE_CONNECTION_SAME_ID_LOGON );
						}
						cur = next;
					}
				}
			}
			break;
		}
		

	case PTCL_DB_TO_AGENT_REQUEST_DISCONNECT_USER_BY_ID:
	case PTCL_MAP_TO_AGENT_REQUEST_DISCONNECT_USER:
		{
			DWORD *dwUniqID;

			dwUniqID = (DWORD *)(pMsg+1);
			pUser = g_pUserTable->GetUserInfo(*dwUniqID);
			
			if (pUser != NULL) 
			{	//< CSD-030322		
				static char szDummy[1 + ID_LENGTH];
				memset(szDummy, 0, sizeof(szDummy));
				szDummy[0] = BYTE(PTCL_PROXY_TO_LOGOUT);
				memcpy(szDummy + 1, pUser->szName, ID_LENGTH);

				if (!g_pServerTable->SendToProxyServer(szDummy, 1 + ID_LENGTH))
				{
					MyLog(LOG_IMPORTANT, "Failed To send 'PTCL_PROXY_TO_LOGOUT' to Proxy");
				}
				
				// 접속을 끊도록 권고한다.
				g_pUserTable->DisconnectUserBySuggest( pUser, CMD_CLOSE_CONNECTION_NORMAL );
				MyLog( LOG_NORMAL, "User(%d) SUGGESTED to DISCONNECT by %s(%d)", pUser->dwConnectionIndex, GetTypedServerText(pSender->dwServerType), dwConnectionIndex );
			}	//> CSD-030322

			break;
		}
	case PTCL_DB_ANSWER:
		{
			DWORD *dwUniqID;
			bool redirect_to_client = true;		// default must be true

			dwUniqID = (DWORD *)(pMsg+1);

			t_packet *p = (t_packet *)(pMsg + 1 + 4);

			pUser = g_pUserTable->GetUserInfo(*dwUniqID);
			if (pUser) 
			{
				switch( p->h.header.type ) {
				// ---------------------------
				// Client에게 보내지 않을 패킷
				// ---------------------------
				// Modified by chan78 at 2000/12/09 :: 동일 ID 동시접속
				case CMD_CLOSE_LOGIN_ID:
					{
						char szName[21];

						// 패킷안의 이름 정보를 카피하고 널스트링을 넣는다 
						memcpy( szName, p->u.login_close_login_id. id, 20 );
						szName[20] = 0;
							
						if( !strcmp( szName, pUser->szName ) )
						{	
							// 해당 유저를 끊는다.
							g_pUserTable->DisconnectUserBySuggest( pUser, CMD_CLOSE_CONNECTION_SAME_ID_LOGON );
							//g_pINet->CompulsiveDisconnectUser(pUser->dwConnectionIndex);
						}	
						else
						{	
							MyLog( LOG_IMPORTANT, "CMD_CLOSE_LOGIN_ID: Name is not match!!! '%s', '%s'", szName, pUser->szName );
						}	
					}		
					redirect_to_client = false;
					break;
				// ---------------------------------
				// 여기서부터는 Client에게 보낼 패킷
				// ---------------------------------
				case CMD_CONNECT_INFO:
					{
						// Setting Server informations
						WORD port = p->u.server_connect_info.port;
						if( g_pUserTable->GetUserInfo( *dwUniqID ) && g_pServerTable->GetConnectedServerData(port) ) {
							g_pUserTable->GetUserInfo( *dwUniqID )->dwMapServerConnectionIndex = g_pServerTable->GetConnectedServerData(port)->dwConnectionIndex;
						} else {
							MyLog( LOG_FATAL, "Invalid dwUniqID(%d) or ServerID(%d)", *dwUniqID, port );
						}
						//MyLog( LOG_IGNORE, "User %d took map Server %d(%d)", *dwUniqID, p->u.server_connect_info.port, g_pUserTable->GetUserInfo( *dwUniqID )->dwMapServerConnectionIndex );

						// LOGIN 과정에서 DB에 기록된 사용자 정보의 제거를 요청한다.
						szMsg[0] = (BYTE)PTCL_AGENT_TO_DB_REQUEST_REMOVE_USER;
						memcpy(szMsg+1,dwUniqID,4);		// (dwUniqID == &(*dwUniqID) 해깔리지 마세요.

						if( pUser->dwDBDemonConnectionIndex )
						{
							if( !g_pServerTable->Send( pUser->dwDBDemonConnectionIndex, szMsg, 5) )
							{
								g_pUserTable->DisconnectUserBySuggest( pUser, CMD_CLOSE_CONNECTION_ABNORMAL );
								MyLog( LOG_IMPORTANT, "Failed To send 'PTCL_AGENT_TO_DB_REQUEST_REMOVE_USER' to (%d)", pUser->dwDBDemonConnectionIndex );
							}
						}
						else
						{
							if( !g_pServerTable->SendToDBDemon( szMsg, 5 ) )
							{
								g_pUserTable->DisconnectUserBySuggest( pUser, CMD_CLOSE_CONNECTION_ABNORMAL );
								MyLog( LOG_IMPORTANT, "Failed To send 'PTCL_AGENT_TO_DB_REQUEST_REMOVE_USER' to (%d)", pUser->dwDBDemonConnectionIndex );
							}
						}
					}
					break;
				case CMD_ACCEPT_LOGIN:
					{	//< CSD-030322 
						pMsg[0] = BYTE(PTCL_PROXY_TO_ACCESS);

						if(LocalMgr.IsAbleNation(JAPAN))
						{
							t_packet packet;
							::memcpy(packet.h.data, pMsg+1+4,5);
							::memcpy(packet.u.data, pMsg+1+4+5, packet.h.header.size);
							
							DWORD pUniqID = *(DWORD*)(pMsg + 1);
							USERINFO *pUserInfo = g_pUserTable->GetUserInfo(pUniqID);

							if(!pUserInfo)
							{
								MyLog(LOG_IMPORTANT, "RecvMsgFromServer(CMD_ACCEPT_LOGIN) Can Not Take UserInfo (%d)", pUniqID);
								break;
							}

							::memcpy(pUserInfo->szName, packet.u.server_accept_login.id,20);
							MyLog(LOG_IMPORTANT, "RecvMsgFromServer(CMD_ACCEPT_LOGIN) User ID Copy: '%s'",pUserInfo->szName);
						}

						if (!g_pServerTable->SendToProxyServer(pMsg, dwLength))
						{
							MyLog(LOG_IMPORTANT, "Failed To send 'PTCL_PROXY_TO_ACCESS' to Proxy");
							break;
						}
						return;
					}//> CSD-030322

					case CMD_INVALID_ID		:
					case CMD_INVALID_PW		:
					case CMD_INVALID_DB		:
					case CMD_INVALID_PAY		:
					case CMD_INVALID_VERSION	:
					case CMD_INVALID_AGE		: // 030923 kyo
						{
							//010925 lsw
							//if( !g_pUserTable->SendToUserNoEncode( pUser, (pMsg+1+4), (dwLength-1-4) ) )
							if( !g_pUserTable->SendToUser( pUser, (pMsg+1+4), (dwLength-1-4) ) )
							{
								MyLog( LOG_FATAL, "WARNNING:: Failed To Redirect DB Demon's Packet to User(%d)", pUser->dwConnectionIndex );
							}
							return;
						}
						break;
				default:
					break;
				}

				if( redirect_to_client )
				{
					if( !g_pUserTable->SendToUser( pUser, (pMsg+1+4), (dwLength-1-4) ) )
					{
						MyLog( LOG_FATAL, "WARNNING:: Failed To Redirect DB Demon's Packet to User(%d)", pUser->dwConnectionIndex );
					} else {
						//MyLog( LOG_FATAL, "Got Message From DB Demon(id:%d UniqID:%d dwLength:%d)(type:%d)", bID, *dwUniqID, dwLength, p->h.header.type );
					}
				}
			}
			else	// pUser Is NULL
			{
				// Added by chan78 at 2001/02/09
				if( p->h.header.type == CMD_ACCEPT_LOGIN )
				{	
					// Request Remove From '[TotalDB].LoginTable' to DB DEMON
					szMsg[0] = (BYTE)PTCL_AGENT_TO_DB_REMOVE_USER_FROM_LOGIN_TABLE;

					memcpy(szMsg+1, &(*dwUniqID),4);
					memcpy(szMsg+1+4, p->u.server_accept_login.id, ID_LENGTH );
					memcpy(szMsg+1+4+ID_LENGTH, &g_pServerTable->GetOwnServerData()->wPort, 2 );
					if( !g_pServerTable->Send(dwConnectionIndex, szMsg, 1+4+ID_LENGTH+2) )
					{
						MyLog( LOG_FATAL, "--- Warnning!!! Failed to Send PTCL_USER_LIST_CONNECTION!!!" );
					}
				}
				else if( p->h.header.type == CMD_CLOSE_LOGIN_ID )
				{
					// CMD_CLOSE_LOGIN_ID를 받았지만 유저가 USERLIST에 존재하지 않는 경우.
					// 이경우는 로그할 필요가 있다.
					szMsg[0] = (BYTE)PTCL_AGENT_TO_DB_REMOVE_USER_FROM_LOGIN_TABLE;

					memcpy(szMsg+1, &(*dwUniqID),4);
					memcpy(szMsg+1+4, p->u.login_close_login_id.id, ID_LENGTH );
					memcpy(szMsg+1+4+ID_LENGTH, &g_pServerTable->GetOwnServerData()->wPort, 2 );
					
					if( !g_pServerTable->Send(dwConnectionIndex, szMsg, 1+4+ID_LENGTH+2) )
					{
						MyLog( LOG_FATAL, "--- Warnning!!! Failed to Send PTCL_USER_LIST_CONNECTION!!!" );
					}
					MyLog( LOG_IMPORTANT, "CMD_CLOSE_LOGIN_ID received illegal pUser!!!" );
				}
//				else MyLog( LOG_FATAL, "DB Demon Sent Illegal dwUniqID(%d)", *dwUniqID );
			}		
		}			
		break;
	case PTCL_MAP_TO_AGENT_PACKED_MSG:
		{
			t_packet *packet;
			// bSend 는 Agent가 가로채 처리한 후 client에게 전송 할것인가 말것인가를 결정한다. 기본값 참.
			bool bSend = true;

			CPackedMsg*	pPackedMsg = (CPackedMsg*)pMsg;
			DWORD dwUserNum = pPackedMsg->GetUserNum();
			//USERINFO_CLIENT_RECV* pInfo = (USERINFO_CLIENT_RECV*)pMsg->GetMsg();

			// 받은 패킷을 클라이언트로 보내준다.
			packet = (t_packet*)(pPackedMsg->GetMsg());
			if( (sizeof(t_header) + packet->h.header.size) != pPackedMsg->GetMsgLength() )
			{
				MyLog( LOG_IGNORE, "MapServer(%d) Send Illegal PackedMsg, Ignore It!", dwConnectionIndex);
				return;
			}

			for (DWORD i=0; i<dwUserNum; i++)
			{
				DWORD dwUserID = pPackedMsg->GetUser(i);
				USERINFO *pUser = g_pUserTable->GetUserInfo(dwUserID);
				if( !pUser )
				{
					//MyLog( LOG_FATAL, "PTCL_PACKED_USER :: User %d Not Found from MAP(%d)", dwUserID, dwConnectionIndex );

					// Modified by chan78 at 2000/12/16 :: 걔 없다 끊어달라고 요청.
					szMsg[0] = (BYTE)PTCL_AGENT_TO_MAP_REQUEST_REMOVE_USER;
					memcpy(szMsg+1,&dwUserID,4);

					if( !g_pServerTable->Send( dwConnectionIndex, szMsg, 5 ) ) {
						MyLog( LOG_IMPORTANT, "-- Requst Remove that Player(dwUniqID:%d) to Map Server(dwConnectionIndex:%d)", dwUserID, dwConnectionIndex );
						LP_SERVER_DATA pServerData = g_pServerTable->GetServerData( dwConnectionIndex );
						if( pServerData == NULL )
						{
							MyLog( LOG_IMPORTANT, "-- PSList(%d) is NULL!" );
						}
						else
						{
							MyLog( LOG_IMPORTANT, "-- %s(%s:%d)", GetTypedServerText(pServerData->dwServerType), pServerData->szIP, pServerData->wPort );
						}
					}
					continue;
				}

				switch(packet->h.header.type)
				{
				//-----------------------------------------------------------------------------
				// Map Change의 처리 :: Agent는 이 Packet을 hooking해 Map Server의 ID를 바꾼다.
				//-----------------------------------------------------------------------------
				case CMD_CHANGE_MAP:
					{
						char szAnswer[16+1];
						t_packet *pAnswer;
						pAnswer = (t_packet *)(szAnswer+1+4);

						LP_SERVER_DATA pServerData = g_pServerTable->GetConnectedServerData((WORD)packet->u.server_change_map.port);
						if( !pServerData || !pServerData->dwConnectionIndex ) {
							// 서버 ID(port)로 dwConnectionIndex를 구할 수 없으면 접속을 끊어버린다.
							// 알림 패킷을 보내려면 여기서 보내야한다.
							MyLog( LOG_FATAL, "User %s Failed to CHANGE MAP :: Server(port:%d) Is Not Connected", pUser->szName, packet->u.server_change_map.port );
							g_pINet->CompulsiveDisconnectUser( pUser->dwConnectionIndex );
						}

						// Change Map Server
						pUser->dwMapServerConnectionIndex = pServerData->dwConnectionIndex;
						//MyLog( LOG_FATAL, "User %d CHANGE map Server to %d(%d)", dwUserID, pServerData->wPort, pServerData->dwConnectionIndex );

						// Added by chan78 at 2001/02/22 :: Answer To Map
						szAnswer[0] = (BYTE)PTCL_AGENT_TO_MAP;
						memcpy( szAnswer+1, &dwUserID, sizeof(DWORD) );

						pAnswer->h.header.type = CMD_CHANGE_MAP_DETECTED;
						pAnswer->h.header.size = 0;

						if( !g_pServerTable->Send( dwConnectionIndex, szAnswer, 1+4+sizeof(t_header) ) )
						{
							//MyLog( LOG_IMPORTANT, "Fail to Send 'CMD_CHANGE_MAP_DETECTED' to MAP(%d)", dwConnectionIndex );
						}
					
						// FOR DEBUG by chan78 2001/02/21
						dwMapChangeCounter++;
						//MyLog( LOG_NORMAL, "CMD_CHANGE_MAP (%d) (uID:%d, MapdwID:%d port:%d )", dwMapChangeCounter, dwUserID, pServerData->dwConnectionIndex, packet->u.server_change_map.port );

						bSend = true;
					}
					break;

				default:
					// Do nothing.
					break;
				}
				// 전송한다.
				if( bSend ) {
					if (pUser)
					{
						//패킷 키 인코딩 할 자리 
						if( !g_pUserTable->SendToUser(pUser, pPackedMsg->GetMsg(), pPackedMsg->GetMsgLength() ) )
						{
							// 끊는다.
						}
					} else {
						MyLog( LOG_FATAL, "PTCL_PACKED_USER :: User %d Not Found", i );
					}
				}
			}
		}
		break;
	// Added by chan78 at 2001/03/16
	// -----------------------------
	case PTCL_MANAGER_QUERY:
		{
			if( !OnRecvMsgFromManager( (LP_MANAGER_PACKET)pMsg, dwLength ) )
			{
				MyLog( LOG_FATAL, "PTCL_MANAGER_ANSWER :: OnRecvMsgFromManager() has return false(%d)", pSender->wPort );
				break;
			}
		}
		break;
	// Added by chan78 at 2001/03/16
	case PTCL_MANAGER_ANSWER:
		{
			// 있을 수 없다.
			MyLog( LOG_FATAL, "PTCL_MANAGER_ANSWER :: has received!!!(%d)", pSender->wPort );
			g_pServerTable->DestroyServer( FINISH_TYPE_UNKNOWN_ERROR);
		}
		break;
	// -----------------------------

	// Added by KBS 011012
	case PTCL_RM_FROM_PROXY:
		{
			RMProc(dwConnectionIndex, pMsg, dwLength);
		}
		break;
	//
	case PTCL_AGENT_TO_COMMIT:
		{	//< CSD-030322
			// When A User Connaction Accepted
			DWORD* pUniqID = (DWORD*)(pMsg + 1);
			pUser = g_pUserTable->GetUserInfo(*pUniqID);

			if (pUser == NULL)
			{
				break;
			}

			pUser->bAmILogon = true;
			//2001/01/29 zhh
			time_t Login;
			struct tm *now;
			time( &Login );
			now = localtime(&Login);
			int year = now->tm_year + 1900;
			int mon  = now->tm_mon+1;
			int day  = now->tm_mday;
			int hour = now->tm_hour;
			int min  = now->tm_min;
			int sec  = now->tm_sec;

			char logintime[15];
			memset(logintime,0,15);
			sprintf(logintime,"%4d%2d%2d%2d%2d%2d", year, mon, day, hour, min, sec );
			memcpy(pUser->logintime, logintime, 15);
			
			if (!g_pUserTable->SendToUser(pUser, (pMsg + 1 + 4), dwLength - 4 - 1))
			{
				MyLog( LOG_FATAL, "WARNNING:: Failed To Redirect DB Demon's Packet to User(%d)", pUser->dwConnectionIndex );
			}
						
			break;
		}	//> CSD-030322
	default:
		{
			MyLog( LOG_FATAL, "Unknown SERVER PACKET(%d, %d)!", bID, dwConnectionIndex );
//			_asm int 3;
			break;
		}
		break;
	}
	return;
}
Example #3
0
void __stdcall OnDisconnectUser( DWORD dwConnectionIndex )
{
	// 사용자가 다른 Server에 Entry를 갖고 있는 경우 제거해주는 처리를 한다.
	USERINFO *pUserInfo = (USERINFO*)g_pINet->GetUserInfo(dwConnectionIndex);

	// pUserInfo 검증.
#ifdef __ON_DEBUG
	ASSERT( pUserInfo );
#endif
	if( !pUserInfo )
	{
		MyLog(LOG_IGNORE, "Connection Closed Not Authed User Index %d", dwConnectionIndex );
		return;
	}
	// Map Server에 연결된 경우.
	if( pUserInfo->dwMapServerConnectionIndex )
	{
		szMsg[0] = (BYTE)PTCL_AGENT_TO_MAP_REQUEST_REMOVE_USER;
		memcpy(szMsg+1,&pUserInfo->dwID,4);

		if( !g_pServerTable->Send(pUserInfo->dwMapServerConnectionIndex,szMsg, 1+4) )
		{
			MyLog( LOG_IMPORTANT, "OnDisconnectUser() :: Failed to Send Notify Packet that User Lost connection to Map(%d)", pUserInfo->dwMapServerConnectionIndex );
			LP_SERVER_DATA pServerData = g_pServerTable->GetServerData( pUserInfo->dwMapServerConnectionIndex );
			if( pServerData == NULL )
			{
				MyLog( LOG_IMPORTANT, "-- PServerData(%d) is NULL!" );
			}
			else
			{
				MyLog( LOG_IMPORTANT, "-- %s(%s:%d)", GetTypedServerText(pServerData->dwServerType), pServerData->szIP, pServerData->wPort );
			}
		}
	}
	else if( pUserInfo->dwDBDemonConnectionIndex )
	{
		szMsg[0] = (BYTE)PTCL_AGENT_TO_DB_REQUEST_REMOVE_USER;
		memcpy(szMsg+1,&pUserInfo->dwID,4);

		if( !g_pServerTable->Send( pUserInfo->dwDBDemonConnectionIndex, szMsg, 5) )
		{
			g_pINet->CompulsiveDisconnectUser( pUserInfo->dwConnectionIndex );
			MyLog( LOG_NORMAL, "Can't send request to remove User %d from DB DEMON -- Close this connection", pUserInfo->dwID );
		}
	}
#ifdef __ON_DEBUG
	// DB Demon과 Map SERVER에 동시에 Entry를 갖고 있는 경우. 발생하면 안되는 예외상황.
	else if( pUserInfo->dwDBDemonConnectionIndex && pUserInfo->dwMapServerConnectionIndex )
	{
//		_asm int 3;
	}
#endif

	// DB의 Log-in Table Entry에서 제거한다.
	if( pUserInfo->bAmILogon )
	{
		// --------------
		// 2001/01/29, zhh
		time_t Logout;
		struct tm *now;												
		time( &Logout );
		now = localtime(&Logout);
		int year = now->tm_year + 1900;
		int mon  = now->tm_mon+1;
		int day  = now->tm_mday;
		int hour = now->tm_hour;
		int min  = now->tm_min;						
		int sec  = now->tm_sec;
		char logouttime[15];
		memset(logouttime,0,15);
		sprintf(logouttime,"%4d%2d%2d%2d%2d%2d", year, mon, day, hour, min, sec);
		// --------------

		szMsg[0] = (BYTE)PTCL_AGENT_TO_DB_REMOVE_USER_FROM_LOGIN_TABLE;
		memcpy(szMsg+1,&pUserInfo->dwID,4);
		memcpy(szMsg+1+4, &pUserInfo->szName, ID_LENGTH);
		memcpy(szMsg+1+4+ID_LENGTH, &g_pServerTable->GetOwnServerData()->wPort, 2 );

		//2001/01/29 zhh
		memcpy(szMsg+1+4+ID_LENGTH+2, logouttime,15);
		memcpy(szMsg+1+4+ID_LENGTH+2+15, pUserInfo->logintime,15);

		//2001/08/30 zhh
		memcpy(szMsg+1+4+ID_LENGTH+2+15+15, pUserInfo->szIP,20);

		if( pUserInfo->dwDBDemonConnectionIndex )
		{
			//2001/08/30 zhh
			if( !g_pServerTable->Send(pUserInfo->dwDBDemonConnectionIndex, szMsg, 1+4+ID_LENGTH+2+30+20) )
			{
				MyLog( LOG_IMPORTANT, "Failed To send 'PTCL_AGENT_TO_DB_REMOVE_USER_FROM_LOGIN_TABLE' to (%d)", pUserInfo->dwDBDemonConnectionIndex );
			}
		}
		else 
		{
			//2001/08/30 zhh
			if( !g_pServerTable->SendToDBDemon( szMsg, 1+4+ID_LENGTH+2+30+20) )
			{
				MyLog( LOG_IMPORTANT, "Failed To send 'PTCL_AGENT_TO_DB_REMOVE_USER_FROM_LOGIN_TABLE' to DBDemon", pUserInfo->dwDBDemonConnectionIndex );
			}
		}
	}
	//< CSD-030322
	static char szDummy[1 + ID_LENGTH];
	memset(szDummy, 0, sizeof(szDummy));
	szDummy[0] = BYTE(PTCL_PROXY_TO_LOGOUT);
	memcpy(szDummy + 1, pUserInfo->szName, ID_LENGTH);

	if (!g_pServerTable->SendToProxyServer(szDummy, 1 + ID_LENGTH))
	{
		MyLog(LOG_IMPORTANT, "Failed To send 'PTCL_PROXY_TO_LOGOUT' to Proxy");
	}
	//> CSD-030322

	// 030206 kyo
	//g_cAsyncPay.LogoutUser( pUserInfo );
	g_cAsyncPay.LogoutUser( dwConnectionIndex, pUserInfo->szName );

	// 실제로 Clear.
	g_pUserTable->RemoveUser(dwConnectionIndex);
	return;
}
Example #4
0
void __stdcall ReceivedMsgServer(DWORD dwConnectionIndex,char* pMsg,DWORD dwLength)
{
	EXCEPTION_POINTERS* pException = NULL;//020508 lsw
	__try	//020508 lsw
	{

		BYTE bID;
		bID = (BYTE)pMsg[0];

		if (dwConnectionIndex == 0)
		{
	#ifdef __ON_DEBUG
	//		_asm int 3;
	#endif
			return;
		}

		if( bID == (BYTE)PTCL_NOTIFY_SERVER_UP )
		{
			if( g_pServerTable->OnRecvServerUpMsg(dwConnectionIndex, *(WORD*)(pMsg+1)) )
			{
	#ifdef __ON_DEBUG
	//			_asm int 3;
	#endif
			}
			return;
		}

		LP_SERVER_DATA pSender = g_pServerTable->GetConnectedServerData( dwConnectionIndex );

		if( !pSender ) return;

		switch (bID)
		{
		// -------------
		// 기본패킷 
		// -------------
		// 전용
		case PTCL_ORDER_SET_SERVER_LIST:
		case PTCL_ORDER_CONNECT_TO_SERVERS:
		case PTCL_ORDER_SET_DB_DEMON:
		case PTCL_ORDER_TO_REPORT_SERVER_DATAS:
		case PTCL_NOTIFY_YOU_ARE_CERTIFIED:

		//공통
		case PTCL_ORDER_DESTROY_SERVER:
		case PTCL_NOTIFY_SERVER_STATUS:
		case PTCL_SERVER_TRY_TO_CHECK_CONNECTION:
		case PTCL_SERVER_CONNECTION_OK:
		case PTCL_ORDER_TO_REPORT_SERVER_STATUS:
			{
				if( !g_pServerTable->OnRecvNegotiationMsgs( pSender, bID, pMsg+1, dwLength-1 ) )
				{
					MyLog( LOG_FATAL, "OnRecvNegotiationMsg() Failed :: (pSender(%d), bId(%d), MsgLength(%d))", pSender->wPort, bID, dwLength );
	#ifdef __ON_DEBUG
	//				_asm int 3;
	#endif
				}
			}
			break;
		case PTCL_AGENT_TO_DB_REMOVE_USER_FROM_LOGIN_TABLE:
			{
				char id[20];
				memset(id,0,20);
				memcpy(id,pMsg+4+1,20);
				if(LocalMgr.IsAbleNation(TAIWAN|CHINA|HONGKONG))//021007 lsw
				{
					//2001/02/24 zhh
					if(dwLength>1+4+ID_LENGTH+2+15)
					{
					char in[15],out[15];
					memset(in,0,15);
					memset(out,0,15);
					memcpy(out,pMsg+1+4+ID_LENGTH+2, 15);
					memcpy(in ,pMsg+1+4+ID_LENGTH+2+15, 15);

					//2001/08/30 zhh
					char IP[20]={0,};
					memcpy(IP ,pMsg+1+4+ID_LENGTH+2+15+15, 20);


					//2001/02/19 zhh
					for(int i=0;i<14;i++)
					{
						if(out[i]==' ')	out[i]='0';
						if( in[i]==' ')	 in[i]='0';
					}
					// acer5
					if(ConQ && out[0]!=0 && in[0]!=0)
						ConQ->AskCheckLogoutWithIP(id,in,out,IP);
					}
				}

				//001218 zhh
				int ret = onepass.DeleteUsedID_SQL_ForPay(NULL,id,0);
				if( ret != 1 )
				{
					MyLog( LOG_NORMAL, "<zoung>%d %s close ret = %d(1 = success)", dwConnectionIndex, id, ret);
				}
			}
			break;
		case PTCL_AGENT_TO_DB_REQUEST_REMOVE_USER:
			{
				ClearUserCN(dwConnectionIndex,pMsg,dwLength);
			}
			break;
		case PTCL_AGENT_TO_DB:
		case PTCL_MAP_TO_DB:
			{
				DWORD dwUniqID;
				t_packet raja_packet;
				memset(&raja_packet,0,sizeof(t_packet));
				memcpy(&dwUniqID, pMsg+1, 4);
				memcpy(raja_packet.h.data, pMsg+1+4, HEADER_SIZE);
				memcpy(raja_packet.u.data, pMsg+1+4+HEADER_SIZE, raja_packet.h.header.size);
			
				DWORD cn = GetUserCN( pSender, dwUniqID, raja_packet.h.header.type );
				//if( cn == -1 ) break;
				///////////////////////////////////////////////////////////////////////////
				
				connections[cn].dwUserID = dwUniqID;
				connections[cn].dwConIndex = dwConnectionIndex;

				//sprintf(txt,"cn: %d USERID %d Index %d",cn, dwUniqID,dwConnectionIndex);
				//WriteText(txt);

				HandleCommand( connections, dwConnectionIndex, &raja_packet ,dwUniqID,cn );
			}
			break;





		// Added by chan78 at 2000/12/17
		case PTCL_ORDER_TO_CLEAR_PAY_TABLE:
			{
				onepass.DeleteUsedID_SQL_ForPay(NULL," ", (int)*(WORD*)(pMsg+1));
			}
			break;
		// Added by chan78 at 2001/03/16
		// -----------------------------
		case PTCL_MANAGER_QUERY:
			{
				if( !OnRecvMsgFromManager( (LP_MANAGER_PACKET)pMsg, dwLength ) )
				{
					MyLog( LOG_FATAL, "PTCL_MANAGER_ANSWER :: OnRecvMsgFromManager() has return false(%d)", pSender->wPort );
					break;
				}
			}
			break;
		// Added by chan78 at 2001/03/16
		case PTCL_MANAGER_ANSWER:
			{
				// 있을 수 없다.
				MyLog( LOG_FATAL, "PTCL_MANAGER_ANSWER :: has received!!!(%d)", pSender->wPort );
				g_pServerTable->DestroyServer( FINISH_TYPE_UNKNOWN_ERROR);
			}
			break;
		// -----------------------------

		// Added by KBS 011012
		case PTCL_RM_FROM_PROXY:
			{
				RMProc(dwConnectionIndex, pMsg, dwLength);
			}
			break;
		//

		default:
			{
				MyLog( LOG_FATAL, "Unknown bID(%d) Received. From %s(wPort:%d) Size(%d) ConnectionID(%d)", bID, GetTypedServerText(pSender->dwServerType), pSender->wPort, dwLength, dwConnectionIndex);
	#ifdef __ON_DEBUG
	//			_asm int 3;
	#endif
			}
			break;
			
		}
	}
	__except(pException = GetExceptionInformation())//020508 lsw
	{
		//acer7
		DumpException( pException, "Exception Raised on HadleCommand()", pMsg, dwLength );
		ProcessEnd(FINISH_TYPE_UNKNOWN_ERROR);
	}