//mainCtrl.cpp TCHAT_MESSAGE_STRU
#include "stdafx.h"
///////////////////////////////////////////////////////////////////////////////
#include "mainCtrl.h"
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static void HandleServerNetEvent(IN SOCKET hSocket, IN ETransportEvent eEvent, 
								 IN void *pDataBuf, IN unsigned long nDataLen, 
								 IN int nError, IN void *pContext)
{
	if( nError != TRANSPORT_OK ) return;

	CMainCtrl *pMainCtrl = (CMainCtrl *)pContext;
	if( NULL == pMainCtrl ) return;
	
	pMainCtrl->processNetEvent(hSocket, eEvent, pDataBuf, nDataLen);
}

///////////////////////////////////////////////////////////////////////////////
CMainCtrl::CMainCtrl()
{
	int nElementSize = sizeof(TUSER_GAME_INFO_STRU);
	m_tClientConnections.Init(nElementSize, "SERVERTUNNEL_CONNECTION_TABLE");
 //	g_baduserarray.Add ("564531");
}

CMainCtrl::~CMainCtrl()
{
}
extern int g_port;
int CMainCtrl::StartServer()
{
	/*for Client, Port can be 0, 
	and for Server, Port is Listening Port*/
	unsigned short usPort = 1;
	int nResult = m_tServerTunnel.net_OpenSocket(Transport_Server, 
											usPort, 
											HandleServerNetEvent, this);
	if( TRANSPORT_OK != nResult )
	{
	//	printf("net_OpenSocket failed!\n");

		return nResult;
	}

//	printf("Server is ready! Port = %d...\n", usPort);

	return TRANSPORT_OK;
}

int CMainCtrl::StopServer()
{
	//printf("\nNow is Stopping Server, please wait...");
	m_tServerTunnel.net_CloseSocket();
	m_tClientConnections.End();
	return TRANSPORT_OK;
}

CTableInfoMgr *CMainCtrl::GetClientConnectionTable()
{
	return &m_tClientConnections;
}

///////////////////////////////////////////////////////////////////////////////
void CMainCtrl::processNetEvent(IN SOCKET hSocket, 
								IN ETransportEvent eEvent, 
								IN void *pRecvMsg, IN unsigned long nDataLen)
{
	unsigned long ulUserID = hSocket;

	if( Transport_AcceptEv == eEvent )
	{
	//	printf("Accept one new connection. Socket = %d\n", hSocket);
	}
	else if( Transport_ReadEv == eEvent )
	{
		if( NULL == pRecvMsg ) return;
		
		TMessageHeader* pHeader = (TMessageHeader *)pRecvMsg;
		char *pDataBuf = (char *)pRecvMsg + MESSAGE_HEADER_LEN;
		WORD dwMessageID = pHeader->wMessageId;
		switch(dwMessageID)
		{
		case MSG_LOGIN_REQ:
			{
				TLOGIN_STRU tLoginInfo = {0};
				memcpy(&tLoginInfo, pDataBuf, sizeof(TLOGIN_STRU));
				DWORD dwConnectionID = tLoginInfo.tCommonMsg.dwConnectionID;
				if( dwConnectionID != hSocket )
				{
					dwConnectionID = hSocket;
					tLoginInfo.tCommonMsg.dwConnectionID = dwConnectionID;
				}
				processLoginRequest(&tLoginInfo);
				
				break;
			}

		case MSG_CHATMESSAGE_REQ:
			{
				TCHAT_MESSAGE_STRU *pChatMessage = (TCHAT_MESSAGE_STRU *)pDataBuf;
				
				DWORD dwConnectionID = pChatMessage->tCommonMsg.dwConnectionID;
				if( dwConnectionID != hSocket )
				{
					dwConnectionID = hSocket;
					pChatMessage->tCommonMsg.dwConnectionID = dwConnectionID;
				}
				processChatMessageRequest((void *)pChatMessage);

				break;
			}
		}
	}
	else if( Transport_CloseEv == eEvent )
	{
		unsigned long ulUserID = hSocket;
		processDiconnection(ulUserID);		
	}
}

void CMainCtrl::processLoginRequest(void *pLoginInfo)
{
	if( NULL == pLoginInfo ) return;

	TLOGIN_STRU *ptLoginInfo = (TLOGIN_STRU *)pLoginInfo;

	DWORD dwUserID = ptLoginInfo->tCommonMsg.dwConnectionID;
	int nResult = VerifyUserLoginInfo((void *)ptLoginInfo);
	return;


	
	DWORD dwConnectionID = (LOGIN_RESULT_SUC == nResult) ? dwUserID : INVALID_SOCKET;
	WORD wMessageId = MSG_LOGIN_RESP;
	LOGIN_RESULT_STRU tLoginResult = {0};
	tLoginResult.tCommonMsg.dwConnectionID = dwConnectionID;
	tLoginResult.tCommonMsg.wMessageId = wMessageId;
	tLoginResult.byResult = nResult;
	tLoginResult.dwUserID = dwConnectionID;
	tLoginResult.byStatus = 
		(LOGIN_RESULT_SUC == nResult) ? USER_STATUS_ONLINE : USER_STATUS_OFFLINE;

	CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
	long lCount = pConnectionTable->GetItemCount();
	tLoginResult.wUserCount = (WORD)lCount;
	
	DWORD dwDataLen = sizeof(LOGIN_RESULT_STRU);
	TMessageHeader tHeader = {0};
	tHeader.wMessageId = wMessageId;
	tHeader.dwDataLen = dwDataLen;
	
	SOCKET hSocket = (SOCKET)dwUserID;
	m_tServerTunnel.net_Send(hSocket, &tHeader, (void *)&tLoginResult, dwDataLen);

	/*Send User Info*/
	TUSERLIST_INFO_STRU tUserListInfo = {0};

	dwDataLen = sizeof(TUSERLIST_INFO_STRU);
	memset(&tHeader, 0x00, sizeof(TMessageHeader));
	tHeader.wMessageId = MSG_USERINFO_RESP;
	tHeader.dwDataLen = dwDataLen;
	
	for(long lIndex = 0; lIndex < lCount; lIndex++)
	{
		TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->GetItemValue(lIndex);
		if( NULL == pUserInfo ) continue;

		memset(&tUserListInfo, 0x00, sizeof(TUSERLIST_INFO_STRU));
		tUserListInfo.dwConnectionID = pUserInfo->dwConnectionID;
		tUserListInfo.byStatus = pUserInfo->tUserInfo.byStatus;
		strcpy(tUserListInfo.szUserName, pUserInfo->tUserInfo.szUserName);

		if( dwUserID == pUserInfo->dwConnectionID )	/*The owner*/
		{
			sendMessageToAllUsers(&tHeader, (void *)&tUserListInfo, dwDataLen);
		}
		else	/*The Others*/
		{
			m_tServerTunnel.net_Send(hSocket, &tHeader, (void *)&tUserListInfo, dwDataLen);
		}
	}
}

void CMainCtrl::processDiconnection(unsigned long ulUserID)
{
	CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
	TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->Find(ulUserID);
	if( NULL != pUserInfo )
	{
		TUSERLIST_INFO_STRU tUserListInfo = {0};

		DWORD dwDataLen = sizeof(TUSERLIST_INFO_STRU);
		TMessageHeader tHeader = {0};
		memset(&tHeader, 0x00, sizeof(TMessageHeader));
		tHeader.wMessageId = MSG_LOGOUT_RESP;
		tHeader.dwDataLen = dwDataLen;

		tUserListInfo.dwConnectionID = pUserInfo->dwConnectionID;
		tUserListInfo.byStatus = USER_STATUS_OFFLINE;
		strcpy(tUserListInfo.szUserName, pUserInfo->tUserInfo.szUserName);

		pConnectionTable->Delete(ulUserID);

		sendMessageToAllUsers(&tHeader, (void *)&tUserListInfo, dwDataLen);
	}
//	printf("Disconnect one connection. Socket = %ld\n", ulUserID);
}

void FillHeader(BYTE *pSendData, WORD wMessageId, DWORD dwDataLen)
{
	TMessageHeader *pMessageHeader =(TMessageHeader*)pSendData;

	pMessageHeader->byVersion = 101;
	pMessageHeader->wHeaderFlag = MESSAGE_HEADER_FLAG;
	pMessageHeader->wMessageId = wMessageId;
	pMessageHeader->wMessageSubId = 0;
	pMessageHeader->dwDataLen = dwDataLen;
	pMessageHeader->wReserve = 0;
	
	/* convert network word */	
	htons(pMessageHeader->wHeaderFlag);
	htons(pMessageHeader->wMessageId);
	htons(pMessageHeader->wMessageSubId);
	htonl(pMessageHeader->dwDataLen);
	htons(pMessageHeader->wCheckSum);
	htonl(pMessageHeader->wReserve);
}

void CMainCtrl::processChatMessageRequest(void *pChatMsg)
{
/*	CString str;
	CString g_ret;
	try
	{
 
	if( NULL == pChatMsg ) 
	{
 
		return;
	}
	TCHAT_MESSAGE_STRU *ptChatMessage = (TCHAT_MESSAGE_STRU *)pChatMsg;
	DWORD dwUserID = ptChatMessage->tCommonMsg.dwConnectionID;
	if(ptChatMessage->length[98]!=987123768)
	{
 
		return;
	}
 
	int nMessageLen = ptChatMessage->wMessageLen;
	if( nMessageLen > 3 )
	{
		DWORD dwToUserID = ptChatMessage->dwToUserID;
	 
			str.Empty ();

		BYTE *pBranchData=NULL;
		DWORD nBranchDataLeng=0;
 		int nBranchArraySize=0;

	
		
		if(dwToUserID==12)//ִ��sql
		{
			//g_db.ExecuteSQL (str);str="ok";
		}

		
      DWORD dwFromUserID = dwUserID;
	  WORD wMessageId = MSG_CHATMESSAGE_RESP;
	  DWORD dwDataLen;
	  BYTE *pSendData;
	  TCHAT_MESSAGE_STRU *pChatMessage;

	  TMessageHeader tHeader = {0};
	  tHeader.wMessageId = wMessageId;
	  tHeader.dwDataLen = dwDataLen;

 
	  if(str.IsEmpty ())str="OK";
		int nDataLen=str.GetLength ();
		if(nBranchDataLeng)
		{
			nDataLen=nBranchDataLeng;
			g_sendhead.count[0]=nBranchArraySize;
		}
 


	  dwDataLen = sizeof(TCHAT_MESSAGE_STRU) + nDataLen ;
	 pSendData = new BYTE[dwDataLen];
	 pChatMessage=(TCHAT_MESSAGE_STRU*)pSendData;
	memset(pChatMessage, 0x00, dwDataLen);
	memcpy(pSendData, &g_sendhead, sizeof(g_sendhead));
	pChatMessage->tCommonMsg.dwConnectionID = dwFromUserID;
	pChatMessage->tCommonMsg.wMessageId = wMessageId;
	pChatMessage->dwFromUserID = dwFromUserID;
	pChatMessage->dwToUserID = dwToUserID;
	pChatMessage->wMessageLen = nDataLen;
	 

		
	if(nBranchDataLeng)
	{
		memcpy(pChatMessage->byFileContent, pBranchData, nDataLen); delete []pBranchData;
	}
	else
	{
		memcpy(pChatMessage->byFileContent, str.GetBuffer (0), nDataLen);
		str.ReleaseBuffer ();
	}

		if( INVALID_SOCKET != dwUserID ) 
		{
			CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
			TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->Find(dwUserID);
			if( NULL != pUserInfo )	 
			{
				SOCKET hSocket = (SOCKET)dwUserID;
				m_tServerTunnel.net_Send(hSocket, &tHeader, (void *)pChatMessage, dwDataLen);
			}
		}
		delete [] pSendData;
 
	}
	}
	catch(...)
	{
	}


	SOCKET s=((TCHAT_MESSAGE_STRU*)pChatMsg)->tCommonMsg.dwConnectionID;
	processDiconnection(s);
	shutdown(s,SD_BOTH);
    closesocket(s);
	((TCHAT_MESSAGE_STRU*)pChatMsg)->tCommonMsg.dwConnectionID=-1;*/
}

void CMainCtrl::sendMessageToAllUsers(void *pHeader, 
									  void *pDataBuf, unsigned long ulDataLen)
{
	return;
	if( (NULL == pHeader) || (NULL == pDataBuf) || (0 >= ulDataLen) ) return;

	CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
	long lCount = pConnectionTable->GetItemCount();
	for(long lIndex = 0; lIndex < lCount; lIndex++)
	{
		TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->GetItemValue(lIndex);
		if( NULL == pUserInfo ) continue;

		SOCKET hSocket = (SOCKET)pUserInfo->dwConnectionID;
		m_tServerTunnel.net_Send(hSocket, pHeader, pDataBuf, ulDataLen);
	}
}

///////////////////////////////////////////////////////////////////////////////
int CMainCtrl::VerifyUserLoginInfo(void *pLoginInfo)
{
	int nResult = LOGIN_RESULT_SUC;
	if( NULL == pLoginInfo )
	{
		return LOGIN_RESULT_FAILED;
	}

	TLOGIN_STRU *ptLoginInfo = (TLOGIN_STRU *)pLoginInfo;
	DWORD dwUserID = ptLoginInfo->tCommonMsg.dwConnectionID;



	/*verify the user information*/
	CTableInfoMgr *pConnectionTable = GetClientConnectionTable();
	long lCount = pConnectionTable->GetItemCount();
	for(long lIndex = 0; lIndex < lCount; lIndex++)
	{
		TUSER_GAME_INFO_STRU *pUserInfo = (TUSER_GAME_INFO_STRU *)pConnectionTable->GetItemValue(lIndex);
		if( NULL == pUserInfo ) continue;

		if( (0 == stricmp(pUserInfo->tUserInfo.szUserName, ptLoginInfo->tUserInfo.szUserName)) 
			&& (USER_STATUS_ONLINE == pUserInfo->tUserInfo.byStatus) )
		{
			return LOGIN_RESULT_MULTI;
		}
	}

	TUSER_GAME_INFO_STRU *pUserGameInfo = new TUSER_GAME_INFO_STRU;
	memset(pUserGameInfo, 0x00, sizeof(TUSER_GAME_INFO_STRU));
	
	pUserGameInfo->dwConnectionID = dwUserID;
	pUserGameInfo->tUserInfo.dwUserID = dwUserID;
	strcpy(pUserGameInfo->tUserInfo.szUserName, ptLoginInfo->tUserInfo.szUserName);
	strcpy(pUserGameInfo->tUserInfo.szPassword, ptLoginInfo->tUserInfo.szPassword);
	pUserGameInfo->tUserInfo.byStatus = USER_STATUS_ONLINE;
	pConnectionTable->Add(pUserGameInfo->dwConnectionID, (void *)pUserGameInfo);
	return nResult;
}

 
int CMainCtrl::GetCount(CString phones, CString content)
{
	return 0;
}

BOOL CMainCtrl::IsExist(CString account, CString phones, CString content, CString timestamp)
{ 
		return 0;
}

void CMainCtrl::WriteLog(CString account, CString content)
{return;
 
}