#pragma warning (disable:4949)
#include "NetBridge_Base.h"

#pragma unmanaged


CNetBridge_Base::CNetBridge_Base(void)
{
	m_hMsgEvent			= CreateEvent( NULL, FALSE, FALSE, NULL ); // auto-reset

	m_dwHost			= 0;
	m_dwNetIDCounter	= 0;
	m_pfError			= NULL;

	m_bytesSend			= 0;
	m_bytesRecv			= 0;

	m_pfOutPut			= NULL;
	m_bShutdown			= false;
	
	//m_CompletionPort	= NULL;


	//ZeroMemory( m_EventHostArray, sizeof( m_EventHostArray ) );
}

CNetBridge_Base::~CNetBridge_Base(void)
{

}

int	CNetBridge_Base::Init ()
{
	// 初始化  Winsock 2.2
	WSADATA          wsd;

	// Load Winsock
	if ( WSAStartup( MAKEWORD(2,2), &wsd ) != 0 )
	{
		return NB_ERR_UNABLE_LOAD_WINSOCK;
	}

	return NB_OK;
}



void CNetBridge_Base::GetPacketInfo	( PVOID pData, DWORD dwDataSize, DWORD *pFlag, DWORD *pSize )
{
	// 檢查是否已滿足檢查封包大小的量 ( 暫時先以 DWORD 4 Bytes 訂, 之後可能是用動態或者是其它方式傳送 )

	DWORD dwBaseSize = 0;
	if( dwDataSize >= sizeof( DWORD ) )
	{
		// 檢查封裝資料有無壓縮 or 打包

		//dwSize = ( dwSize | 0x80000000 ) ^ 0x80000000;
		//return dwSize;
		if( pFlag )
		{
			//*pFlag = (*((DWORD*)pData) | (!DF_PTAG_MASK) ) ^ (!DF_PTAG_MASK);
			*pFlag = (*((DWORD*)pData) | (DF_PTAG_SIZEMASK) ) ^ (DF_PTAG_SIZEMASK);
			
			if( *pFlag & DF_PTAG_PACKETLOG_RQUEST )
			{
				//dwBaseSize += 4;
			}
		}


		if( pSize )
		{
			*pSize = ((*((DWORD*)pData) | DF_PTAG_MASK) ^ DF_PTAG_MASK ) + dwBaseSize;

			if( *pSize > 100000 )
			{
				//MessageBox( NULL , "封包Size過大","錯誤", MB_OK );
			}
		}
	}
}

DWORD	CNetBridge_Base::ConvertIP( const char* pszIP )
{
	u_long IP_ADDRESS;

	if( pszIP != NULL )
	{
		if( strlen( pszIP ) != 0 )
		{

			//測試輸入的IP是IP Address 或是 DNS

			//轉換 IP
			IP_ADDRESS = inet_addr( pszIP ); 

			//測試轉出結果, 若傳回 INADDR_NONE 的話, 表該 IP 可能是 DNS
			if ( IP_ADDRESS == INADDR_NONE ) 
			{
				// Host isn't an IP address, try using DNS
				hostent* HE = gethostbyname( pszIP );

				if ( HE == 0 )
				{
					//Error can't check DNS
					return 0;
				}

				IP_ADDRESS = *((u_long*)HE->h_addr_list[0]);
			}
		}
	}

	return IP_ADDRESS;
}


CNetSocket*	CNetBridge_Base::CreateSocket		( bool bManage, CNetSocket* t_pSocket, DWORD* pdwNetID )
{
	DWORD dwNetID			= 0;
	CNetSocket* pSocket		= NULL;

	if( t_pSocket == NULL )
	{
		pSocket							= new CNetSocket;
		pSocket->m_pvecMsg				= &m_vecAuthorize;	
		pSocket->m_pNetBridge			= this;
		pSocket->m_pBufferIncomplete	= CreateBuffer( ( DF_NB_PACKETBUFFERSIZE * 2 ) );
	}
	else
	{
		pSocket = t_pSocket;
	}

	if( bManage )
	{
		m_cs_Socket.Enter();
		{
			if( m_vecRecycleNetID.empty() == true )
			{
				dwNetID = ++m_dwNetIDCounter;
			}
			else
			{
				dwNetID = m_vecRecycleNetID.back();
				m_vecRecycleNetID.pop_back();
			}

			// 之後這裡應該改成自己分派預建好的記憶體
			
			pSocket->m_dwNetID		= dwNetID;

			m_mapSocket[ dwNetID ]	= pSocket;		
		}
		m_cs_Socket.Leave();

		if( pdwNetID != NULL ) 
			*pdwNetID = dwNetID;
	}

	return pSocket;
}

void	CNetBridge_Base::DeleteSocket	( DWORD dwNetID )
{
	// DeleteSocket 有義務將所有資料結構中有關該 Socket 的資料刪除

	CNetSocket* pSocket = NULL;
	m_cs_Socket.Enter();
	{
		
		map< DWORD, CNetSocket* >::iterator it = m_mapSocket.find( dwNetID );
		if( it == m_mapSocket.end() )
			return;

		// 檢查有無在等待刪除清單中
		multimap< DWORD, CNetSocket* >::iterator itclose = m_mapClosingSocket.begin();
		if( itclose != m_mapClosingSocket.end() )
		{
			while( 1 )
			{
				if( itclose->second == it->second )
				{
					itclose = m_mapClosingSocket.erase( itclose );
					break;
				}
				else
					itclose++;

				if( itclose == m_mapClosingSocket.end() )
					break;
			}
		}

		/*
		// 檢查 WaitSendSocket
		vector< DWORD >::iterator itWait = m_vecWaitSendSocket.begin();
		while(1)
		{
			if( *itWait == dwNetID )
			{
				itWait = m_vecWaitSendSocket.erase( dwNetID );
			}
		}
		*/

		m_vecRecycleNetID.push_back( dwNetID );

		pSocket = it->second;

		if( pSocket->m_tcp_socket != INVALID_SOCKET )
		{
			closesocket( pSocket->m_tcp_socket );
			pSocket->m_tcp_socket = INVALID_SOCKET;
		}

		if( pSocket != NULL )
		{
			// 釋放 Incomplete Buffer 
				DeleteBuffer( pSocket->m_pBufferIncomplete );
				delete pSocket;

			// 檢查 Accpet Buffer

			// 檢查 Recv Buffer

			// 檢查 Send Buffer



		}


		m_mapSocket.erase( it );
	}
	m_cs_Socket.Leave();
}

CEventMsg*		CNetBridge_Base::CreateMsg ( EM_MSG_TYPE emMsgType, CNetSocket* pSocket )
{
	//之後要擴充成 POOL 管理
	CEventMsg* pMsg = new CEventMsg;
	pMsg->emMsg		= emMsgType;
	pMsg->pSocket	= pSocket;

	return pMsg;
}

void			CNetBridge_Base::DeleteMsg ( CEventMsg* pMsg )
{
	//之後要擴充成 POOL 管理
	delete pMsg;
}

inline DWORD CNetBridge_Base::Wait					( DWORD dwTime )
{	
	return WaitForSingleObject( m_hMsgEvent, dwTime );
}

void	CNetBridge_Base::Flush ()
{
	vector< CEventMsg* >		vecMsg;
	vector< CEventMsg* >		vecAuthorize;
	//SleepEx( 0, true );


	// 將所有訊息一口氣取出, 避免多次呼叫浪費系統時間
	m_cs_MessageAndEvent.Enter();
		
		vecMsg			= m_vecMsg;
		vecAuthorize	= m_vecAuthorize;

		m_vecMsg.clear();
		m_vecAuthorize.clear();

	m_cs_MessageAndEvent.Leave();

	CheckAuthorize( &vecAuthorize );

	CheckMsg( &vecMsg );


	// 檢查有無 ClosingSocket 到時間了
		CheckSocket();

	// 檢查有無封包待送
		CheckPacket();	
}


void CNetBridge_Base::CheckAuthorize		( vector< CEventMsg* >* pvecMsg )
{
	CEventMsg*				pMsg		= NULL;
	CEventObj*				pEvent		= NULL;
	DWORD					dwNetID		= 0;
	BOOL					IsDelMsg	= true;


	// 檢查有無等待授權 or 授權回應的部份
	do 
	{
		pMsg		= NULL;
		pEvent		= NULL;
		IsDelMsg	= true;

		if( pvecMsg->empty() == FALSE )
		{
			pMsg = *(pvecMsg->begin());
			pvecMsg->erase( pvecMsg->begin() );
		}
		else
		{
			// 沒有訊息並跳開迴圈
			break;
		}

		//int a = pMsg->MsgConnect.m_dwNetID;		

		// 執行事件
		switch( pMsg->emMsg )
		{
		case MSG_RECV:
			{
				// 這裡應該還要做解壓縮 or 其它處理
				CBuffer*	pRecvBuf	= pMsg->MsgRecv.pBuffer;
				PVOID		ptr			= pRecvBuf->m_pData + sizeof( DWORD );
				DWORD		dwBufSize	= pRecvBuf->m_dwSize - sizeof( DWORD );
				CNetSocket* pSocket		= pMsg->pSocket;

				pSocket->m_cs_SocketIO.Enter();
					pSocket->m_MsgRecvCount--;
				pSocket->m_cs_SocketIO.Leave();

				dwNetID				= pSocket->m_dwNetID;

				switch( pMsg->pSocket->m_emAuthorize )
				{
				case EM_AUTHORIZE_WAIT_AUTHORIZE:
					{
						// 本地端為連出端, 收到連入端送來的驗證資料
						// 設定本地端解碼資料					

						Struct_PacketAuthorize* pPacket = (Struct_PacketAuthorize*)ptr;

						pSocket->m_IsCompress		= pPacket->IsCompress;
						pSocket->m_IsEncryption		= pPacket->IsEncryption;
						pSocket->m_AuthorizeIndex	= pPacket->AuthorizeIndex;

						// 整理回覆資料, 並送出
						// 回覆資料目前 Key 值的前一個 Key, 並打包時用目前 Key 值的下一個 Key

						if( pSocket->m_IsEncryption == FALSE )
						{
							BYTE Key = 0;
							_Send( pSocket->m_dwNetID, sizeof( BYTE ), &Key );
						}
						else
						{
							// 尚未實做
							BYTE Key = 0;
							_Send( pSocket->m_dwNetID, sizeof( BYTE ), &Key );
						}
				
						pSocket->m_emAuthorize = EM_AUTHORIZE_WAIT_PASS;
						//pSocket->m_emStatus = EM_SOCKET_WAIT_PASS;

					} break;
				case EM_AUTHORIZE_WAIT_PASS:
					{
						BYTE Key = *(BYTE*)ptr;
						
						// 驗證 該筆資料
						if( Key == 0 )
						{
							// 認證都 okay 了, 正式連線
						
							if( pSocket->m_pEvent )
								pSocket->m_pEvent->OnConnect( pSocket->m_dwNetID );						
							
							//pSocket->m_emStatus = EM_SOCKET_CONNECTED;
							pSocket->m_emAuthorize = EM_AUTHORIZE_OKAY;

							// 將該 Socket 的 Queue  設成正常的 Queue, 此後正常工作
							pSocket->m_pvecMsg	= &m_vecMsg;
						}
						else
						{
							// Host 端傳回來的資料有誤, 斷線處置
							// 將之斷線
							On_Error( "Flush:CheckQueueAuthorize: Host 端傳回來的資料有誤" );
							Close( pSocket->m_dwNetID );
						}
					} break;
				//case EM_SOCKET_CHECK_AUTHORIZE:
				case EM_AUTHORIZE_CHECK_AUTHORIZE:
					{
						//CClientEventObj* pClientEvent	= NULL;

						// 本地端為連入端, 收到連出端送來的驗證資料
						BYTE Key = *(BYTE*)ptr;

						// 驗證 該筆資料
						if( Key == 0 )
						{
							//pMsg->MsgAccept.pAcceptSocket
							//pSocket->m_emStatus = EM_SOCKET_CONNECTED;
							pSocket->m_emAuthorize = EM_AUTHORIZE_OKAY;

							// 驗證 okay 後發出連線訊息
							//if( pEvent = GetEvent( dwNetID ) )

								// 送出確認 Okay 的封包, 並送出一個確認 Key

								BYTE Key = 0;
								_Send( pSocket->m_dwNetID, sizeof( BYTE ), &Key );

								// 呼叫 Accept 取得新連線的事件
								if( pSocket->m_pEvent )
									pSocket->m_pEvent = pSocket->m_pEvent->OnAccept( pSocket->m_dwNetID );

								// 將該 Socket 的 Queue  設成正常的 Queue, 此後正常工作
								pSocket->m_pvecMsg = &m_vecMsg;

								// 呼叫 新連線的 Connect
								if( pSocket->m_pEvent )
									pSocket->m_pEvent->OnConnect( pSocket->m_dwNetID );
							
						}
						else
						{
							// 將之斷線
							On_Error( "Flush:CheckQueueAuthorize: 認証失敗" );
							Close( pSocket->m_dwNetID );
						}			
					} break;
				case EM_AUTHORIZE_OKAY:
					{
						// 因為 Queue 才剛切換成 正常 Queue, 但確已收到封包, 代表網路速度極快, 這裡收到訊息後轉給正常 Queue 處理
						MsgRecv( pMsg->pSocket, pMsg->MsgRecv.pBuffer );

						// 將訊息設法保存下來
						IsDelMsg = false;
					} break;
				}
				
				if( IsDelMsg )
				{
					DeleteBuffer( pMsg->MsgRecv.pBuffer );
					pMsg->MsgRecv.pBuffer = NULL;
				}

			} break;

			// 因為還沒有做持續連線的動作. 故暫時先不做
			/*
			case MSG_CONNECT_FAILED:
			{
			//((CClientEventObj*)pEvent)->OnConnectFailed( pMsg->m_dwFailID );
			if( GetEvent( dwNetID ) )
			((CClientEventObj*)pEvent)->OnConnectFailed( pMsg->MsgConnectFailed.dwFailID );
			} break;
			*/
		case MSG_DISCONNECT:
			{
				CNetSocket* pSocket = pMsg->pSocket;

				if( 
					pSocket->m_emAuthorize == EM_AUTHORIZE_WAIT_AUTHORIZE || 
					pSocket->m_emAuthorize == EM_AUTHORIZE_WAIT_PASS		
				  )
				{
					// 給予與 Winsock 相同的 Error Code
					if( pSocket->m_pEvent )
						pSocket->m_pEvent->OnConnectFailed( WSAECONNREFUSED );					
				}
				else
				{
					if( pSocket->m_emAuthorize == EM_AUTHORIZE_OKAY )
					{
						if( pSocket->m_pEvent )
							pSocket->m_pEvent->OnDisconnect( pSocket->m_dwNetID );
					}
				}

				pSocket->m_emStatus = EM_SOCKET_UNCONNECT;

				//CNetSocket* pSocket		= pMsg->pSocket;

				//pSocket->m_pEvent->OnDisconnect( pSocket->m_dwNetID );

				//DelEvent( pSocket->m_dwNetID );

				// 之後應該不會再收到任何訊息了
				// 將該 Socket 相關資料全部刪除
				//DeleteSocket( pSocket->m_dwNetID );
			} break;
		}


		// 釋放訊息
		DeleteMsg( pMsg );

	} while( 1 );
}

void CNetBridge_Base::CheckMsg				( vector< CEventMsg* >* pvecMsg )
{

	CEventMsg*				pMsg	= NULL;
	CEventObj*				pEvent	= NULL;
	DWORD					dwNetID = 0;

	do 
	{
		pMsg		= NULL;
		pEvent		= NULL;

		if( pvecMsg->empty() == FALSE )
		{
			pMsg = *(pvecMsg->begin());
			pvecMsg->erase( pvecMsg->begin() );
		}
		else
		{
			// 沒有訊息並跳開迴圈
			break;
		}

		//int a = pMsg->MsgConnect.m_dwNetID;		

		// 執行事件
		switch( pMsg->emMsg )
		{
#ifndef DF_PACKET_LOG
		case MSG_RECV:
			{
				// 這裡應該還要做解壓縮 or 其它處理
				CBuffer*	pRecvBuf	= pMsg->MsgRecv.pBuffer;
				PVOID		ptr			= pRecvBuf->m_pData + sizeof( DWORD );
				DWORD		dwBufSize	= pRecvBuf->m_dwSize - sizeof( DWORD );
				CNetSocket* pSocket		= pMsg->pSocket;

				pSocket->m_cs_SocketIO.Enter();
					pSocket->m_MsgRecvCount--;
				pSocket->m_cs_SocketIO.Leave();

				dwNetID					= pMsg->pSocket->m_dwNetID;

				if( pSocket->m_pEvent )
					pSocket->m_pEvent->OnRecv( dwNetID, dwBufSize, ptr );

				DeleteBuffer( pMsg->MsgRecv.pBuffer );
				pMsg->MsgRecv.pBuffer = NULL;
			

			} break;

#else
		case MSG_RECV:
			{
				// 這裡應該還要做解壓縮 or 其它處理
				CBuffer*	pRecvBuf	= pMsg->MsgRecv.pBuffer;
				PVOID		ptr			= pRecvBuf->m_pData + sizeof( DWORD );
				DWORD		dwBufSize	= pRecvBuf->m_dwSize - sizeof( DWORD );
				CNetSocket* pSocket		= pMsg->pSocket;
				DWORD		dwNetID		= pMsg->pSocket->m_dwNetID;

				pSocket->m_cs_SocketIO.Enter();
				pSocket->m_MsgRecvCount--;
				pSocket->m_cs_SocketIO.Leave();
		
				//-----------------------------------------------------------------------
				Struct_PacketLog* pLog = (Struct_PacketLog*)ptr;
				if( pLog->dwID == 0x12345678 )
				{
					// 收到要求, 發送回去
					pLog->dwID = 0x87654321;
					_Send( dwNetID, sizeof( Struct_PacketLog ), pLog );

					char szOut[255];

					DWORD dwTime	= GetTickCount();
					DWORD dwSpend	= dwTime - pLog->dwTime;

					sprintf( szOut, "\nNB: RECV ECHO REQUEST ( %d ), spend( %d )ms", pLog->dwPacketID, dwSpend );

					//MsgOutPut( szOut );
				}
				else
					if( pLog->dwID == 0x87654321 )
					{
						// Echo Packet
						DWORD dwTime	= GetTickCount();
						DWORD dwSpend	= dwTime - pLog->dwTime;

						char szOut[255];

						sprintf( szOut, "\nNB: RECV ECHO ANSWER ( %d ), spend( %d )ms", pLog->dwPacketID, dwSpend );
						m_dwPacketLog--;
						//MsgOutPut( szOut );
					}
					else
					{
						//m_pEventObj->OnRecv( NetID, (Size-1), pData );
						if( pSocket->m_pEvent )
							pSocket->m_pEvent->OnRecv( dwNetID, dwBufSize, ptr );
					}
				//-----------------------------------------------------------------------

				DeleteBuffer( pMsg->MsgRecv.pBuffer );
				pMsg->MsgRecv.pBuffer = NULL;


			} break;


#endif
				// 因為還沒有做持續連線的動作. 故暫時先不做
				/*
				case MSG_CONNECT_FAILED:
				{
				//((CClientEventObj*)pEvent)->OnConnectFailed( pMsg->m_dwFailID );
				if( GetEvent( dwNetID ) )
				((CClientEventObj*)pEvent)->OnConnectFailed( pMsg->MsgConnectFailed.dwFailID );
				} break;
				*/
		/*
		case MSG_CONNECT:
			{
				CNetSocket* pSocket		= pMsg->pSocket;
				dwNetID					= pMsg->pSocket->m_dwNetID;

				pSocket->m_pEvent->OnConnect( pSocket->m_dwNetID );

			} break;
		case MSG_ACCEPT:
			{
				CClientEventObj* pClientEvent	= NULL;
				dwNetID							= pMsg->pSocket->m_dwNetID;
				// 接收使用者定義的新事件
				//CClientEventObj* pNewEvent = ((CHostEventObj*)pEvent)->OnNewConnection( pMsg->m_dwNewConnectionNetID );

				if( pEvent = GetEvent( dwNetID ) )
					pClientEvent	= ((CHostEventObj*)pEvent)->OnAccept( pMsg->MsgAccept.pAcceptSocket->m_dwNetID );

				m_mapEvent[ pMsg->MsgAccept.pAcceptSocket->m_dwNetID ] = pClientEvent;


			} break;
		*/
		case MSG_DISCONNECT:
			{
				CNetSocket* pSocket		= pMsg->pSocket;

				if( pSocket->m_pEvent )
					pSocket->m_pEvent->OnDisconnect( pSocket->m_dwNetID );

				pSocket->m_emStatus = EM_SOCKET_UNCONNECT;

				//pSocket->m_emStatus		= EM_SOCKET_UNCONNECT;

				//DelEvent( pSocket->m_dwNetID );

				// 之後應該不會再收到任何訊息了
				// 將該 Socket 相關資料全部刪除
				//DeleteSocket( pSocket->m_dwNetID );
			} break;
		}

			// 釋放訊息
			DeleteMsg( pMsg );

		} while( 1 );
}


void CNetBridge_Base::CheckPacket				()
{
	CNetSocket* pSocket = NULL;
	DWORD		dwNetID = 0;
	CBuffer*	pBuffer	= NULL;

	while( m_vecWaitSendSocket.empty() != true )
	{
		dwNetID = m_vecWaitSendSocket.front();
		m_vecWaitSendSocket.erase( m_vecWaitSendSocket.begin() );

		pSocket = GetSocket( dwNetID );
		if( pSocket == NULL )
			continue;

		DWORD dwTotalSize		= 0;
		DWORD dwBufferCounter	= (DWORD)pSocket->m_vecWaitToSend.size();

		vector< CBuffer* >::iterator it;
		for( it = pSocket->m_vecWaitToSend.begin(); it != pSocket->m_vecWaitToSend.end(); it++ )
		{
			dwTotalSize += ((CBuffer*)*it)->m_dwTotalSize;
		}

		//if( dwBufferCounter > 2 || dwTotalSize > 128 )
		if( false )
		{
			// 資料量大於 128 bytes 進行壓縮 or 
			BYTE* ptr	= NULL;
			//pBuffer		= CreateBuffer( dwTotalSize );//, NULL, &ptr );
			pBuffer		= CreatePacketBuffer( dwTotalSize , NULL, &ptr );

			// 加註該封包是打包封
			*((DWORD*)pBuffer->m_pData) |= DF_PTAG_COLLECT;

			ptr = pBuffer->m_pData + sizeof( DWORD );

			// 複製資料進一個 Buffer
			it = pSocket->m_vecWaitToSend.begin();
			
			while( it != pSocket->m_vecWaitToSend.end() )
			{
				memcpy( ptr, ((CBuffer*)*it)->m_pData, ((CBuffer*)*it)->m_dwTotalSize );
				ptr += ((CBuffer*)*it)->m_dwTotalSize;
				DeleteBuffer( *it );
				it = pSocket->m_vecWaitToSend.erase( it );
				
				pSocket->m_dwSendBuf--;
			}

			pSocket->m_dwSendBuf++;


		
			// 資料量大於 128 bytes 進行壓縮
			
			//if( dwTotalSize > 128 )
			if( false )
			{
				// 推入待壓縮佇列後, 再由 Thread 發出封包
				Post_Compress( pSocket, pBuffer );
			}
			else
			{
				// 發出封包
				Post_Send( pSocket, pBuffer );
			}
		}
		else
		{
			// 小封包, 且數量不大於二
			//ocket->m_vecSend.push_back( pBuffer );
			// 複製資料進一個 Buffer
			it = pSocket->m_vecWaitToSend.begin();
			while( it != pSocket->m_vecWaitToSend.end() )
			{
				// 發出封包
				//pSocket->m_vecSend.push_back( *it );
				Post_Send( pSocket, *it );
				it = pSocket->m_vecWaitToSend.erase( it );				
			}
		}

	}
	//m_vecWaitSendSocket.push_back( pSocket->m_dwNetID );

}

void CNetBridge_Base::CheckSocket				()
{
	// 檢查有無 ClosingSocket 到時間了
	DWORD dwTick		= GetTickCount();
	DWORD dwCloseTime	= 0;

	CNetSocket* pSocket = NULL;

	//multimap< DWORD , CNetSocket* >::iterator it;

	
	m_cs_Socket.Enter();
	
	vector< CNetSocket* >::iterator it;
	// Wait Close Socket
	it = m_vecWaitCloseSocket.begin();

	DWORD dwTime = GetTickCount();
	while( it != m_vecWaitCloseSocket.end() ) 
	{
		pSocket = *it;
				
		if( pSocket->m_dwSendBuf == 0  )
		{
			//shutdown( pSocket->m_tcp_socket, SD_SEND );
			closesocket( pSocket->m_tcp_socket );
			it = m_vecWaitCloseSocket.erase( it );
		}
		else
		{
			if( dwTime > pSocket->m_dwTimer )
			{
				pSocket->m_dwTimer = 0;
				MsgOutPut( "NB: Close() 時間到, 但仍有封包尚未發出. pSocket->m_dwSendBuf" );
				//shutdown( pSocket->m_tcp_socket, SD_SEND );
				closesocket( pSocket->m_tcp_socket );
				it = m_vecWaitCloseSocket.erase( it );
			}
			else
				it++;
		}
		
	}



	DWORD dwCount;
	it = m_vecWaitDeleteSocket.begin();
	while( it != m_vecWaitDeleteSocket.end() ) 
	{

		char szDebugString[1024];
		sprintf( szDebugString, " \n[ Enter ] m_vecWaitDeleteSocket Loop m_vecWaitDeleteSocket.size() == %d", m_vecWaitDeleteSocket.size() );

		OutputDebugString( szDebugString );

		pSocket = *it;
		
		if( m_bShutdown )
		{
			DeleteSocket( pSocket->m_dwNetID );
			it = m_vecWaitDeleteSocket.erase( it );
			OutputDebugString( "\nErase iterator " );
		}
		else
		{
			if( dwTime > pSocket->m_dwTimer )
			{
				DeleteSocket( pSocket->m_dwNetID );
				it = m_vecWaitDeleteSocket.erase( it );
				OutputDebugString( "\nErase iterator" );
			}
			else
				it++;
		}

		if( it == m_vecWaitDeleteSocket.end() )
			OutputDebugString( "\n[ Leave ] m_vecWaitDeleteSocket Loop" );
	}

	

	m_cs_Socket.Leave();
	
}

CBuffer*	CNetBridge_Base::CreateBuffer	( DWORD dwSize )
{
	//return m_buffer.Apply( dwSize );
	//return new CBuffer( dwSize );//BYTE[ dwSize ];
	m_cs_buffer.Enter();
		CBuffer* pBuffer = new CBuffer( dwSize );
		pBuffer->m_pData = m_buffer.Apply( dwSize );
	m_cs_buffer.Leave();

	return pBuffer;
}

void			CNetBridge_Base::DeleteBuffer	( CBuffer* pBuffer )
{
	m_cs_buffer.Enter();
		m_buffer.Delete( pBuffer->m_pData );
	m_cs_buffer.Leave();
		pBuffer->m_pData = NULL;
		delete pBuffer;

	//delete pBuffer;
}




LONG CNetBridge_Base::GetBytesSend	()
{
	return m_bytesSend;
}

LONG CNetBridge_Base::GetBytesRecv	()
{
	return m_bytesRecv;
}

void CNetBridge_Base::ReSetSendCount	()
{
	InterlockedExchange( &m_bytesSend, 0 );
}

void CNetBridge_Base::ReSetRecvCount	()
{
	InterlockedExchange( &m_bytesRecv, 0 );
}

void CNetBridge_Base::On_Error( char *format, ... )
{
	// NOTHING; FUCK 
	va_list vl;
	char dbgbuf[2048];
	va_start(vl, format);
	wvsprintf(dbgbuf, format, vl);
	va_end(vl);
	char szOutput[2048];
	wsprintf( szOutput, "%s\n" );

	OutputDebugString(szOutput);
}

void CNetBridge_Base::PostMsg ( CEventMsg* pMsg )
{
	m_cs_MessageAndEvent.Enter();

		pMsg->pSocket->m_pvecMsg->push_back( pMsg );
		SetEvent( m_hMsgEvent );

	m_cs_MessageAndEvent.Leave();
}

void CNetBridge_Base::MsgAccept ( CNetSocket* pSocket, CNetSocket* pAcceptSocket )
{
	CEventMsg* pMsg = CreateMsg( MSG_ACCEPT, pSocket );
	pMsg->MsgAccept.pAcceptSocket	= pAcceptSocket;
	PostMsg( pMsg );
}


void CNetBridge_Base::MsgRecv		( CNetSocket* pSocket, CBuffer* pBuffer )
{
#ifdef DF_DEBUG_RECVMSG
	printf("\nMsgRecv(%d)", pSocket->m_dwNetID );
#endif

	CEventMsg* pMsg  = NULL;
	if( CheckCompress( pBuffer ) == false )
	{
		pSocket->m_cs_SocketIO.Enter();
			pSocket->m_MsgRecvCount++;
		pSocket->m_cs_SocketIO.Leave();

		
		pMsg = CreateMsg( MSG_RECV, pSocket );
		
		pMsg->MsgRecv.pBuffer		= pBuffer;
		
		PostMsg( pMsg );
	}
	else
	{
		// 解開打包的封包
		int a = 3;

	}
}

void CNetBridge_Base::MsgError		( CNetSocket* pSocket, DWORD dwErrorID )
{
	CEventMsg* pMsg = CreateMsg( MSG_ERROR, pSocket );

	pMsg->MsgError.dwErrorID	= dwErrorID;

	PostMsg( pMsg );
}

void CNetBridge_Base::MsgConnect	( CNetSocket* pSocket )
{
	CEventMsg* pMsg = CreateMsg( MSG_CONNECT, pSocket );
	
	PostMsg( pMsg );
}

void CNetBridge_Base::MsgDisconnect	( CNetSocket* pSocket )
{
	CEventMsg* pMsg = CreateMsg( MSG_DISCONNECT, pSocket );

	PostMsg( pMsg );
}


int	CNetBridge_Base::Connect ( DWORD dwIP , WORD wPort, CEventObj* pEventObj )
{
	if( pEventObj == NULL )
		return NB_ERR;

	// Create Socket
		CNetSocket* pSocket		= CreateSocket( true, NULL );
		pSocket->m_tcp_socket	= socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
		pSocket->m_emAuthorize	= EM_AUTHORIZE_WAIT_AUTHORIZE;






	// Prepre Socket Address
		SOCKADDR_IN	sa;
		memset( &sa, 0, sizeof( SOCKADDR_IN ) );
		sa.sin_family		= AF_INET;
		sa.sin_addr.s_addr	= dwIP;
		sa.sin_port 		= htons( (WORD)wPort );

	// Tring to connect
		int iReturn			= WSAConnect( pSocket->m_tcp_socket, (SOCKADDR *)&sa, sizeof( SOCKADDR ), NULL, NULL, NULL, NULL );

		if( iReturn == SOCKET_ERROR )
		{
			// 連線失敗
			iReturn = WSAGetLastError();
			pEventObj->OnConnectFailed( iReturn );
			DeleteSocket( pSocket->m_dwNetID );
			return -1;
		}
		
	// Set Keep alive
		SetKeepAlive( pSocket );

		pSocket->m_emStatus	= EM_SOCKET_CONNECTED;
	// Connected!! Create event and msg
		pSocket->m_pEvent = pEventObj;

	// 暫時不發訊息通知 Client, 而等到 Server 發回認證訊息回來後, 才通知 Client 
		//MsgConnect( pSocket );

		return pSocket->m_dwNetID;

	// 連線成功, 準備收發所須要的事件和執行緒

/* OVERLAPPED 用的
	DWORD hID = 0;

	pSocket->m_overlapped_Recv.hEvent	= WSACreateEvent();	// Create 出來的 Event 是 Non-Signaled 狀態
	pSocket->m_overlapped_Send.hEvent	= WSACreateEvent();	// Create 出來的 Event 是 Non-Signaled 狀態

	pSocket->m_thread_Send				= CreateThread( NULL, 0, Thread_Send,	pSocket, 0, &hID );
	pSocket->m_thread_Recv				= CreateThread( NULL, 0, Thread_Recv,	pSocket, 0, &hID );
*/

}

CNetSocket*		CNetBridge_Base::GetSocket		( DWORD dwNetID		)
{
	CNetSocket* pSocket = NULL;

	m_cs_Socket.Enter();
		map< DWORD, CNetSocket* >::iterator it = m_mapSocket.find( dwNetID );

		if( it == m_mapSocket.end() )
		{
			pSocket = NULL;
		}
		else
		{
			pSocket = it->second;
		}
	m_cs_Socket.Leave();

	return pSocket;
}

DWORD	CNetBridge_Base::GetTotalSocket			()
{
	DWORD dwSize = 0;
	m_cs_Socket.Enter();
		dwSize = (DWORD)m_mapSocket.size();
	m_cs_Socket.Leave();
	return dwSize;
}

CBuffer*	CNetBridge_Base::CreatePacketBuffer		( DWORD dwSize, PVOID pData, BYTE** pOffset )
{
	DWORD dwPacketSize = dwSize + ( sizeof( DWORD ) );

	CBuffer* pBuffer	= CreateBuffer( dwPacketSize );
	
	BYTE* ptr			= pBuffer->m_pData;

	memcpy( ptr, &dwPacketSize, sizeof( DWORD ) );

	if( pData != NULL )
	{
		ptr += sizeof( DWORD );
		memcpy( ptr, pData, dwSize );
	}

	if( pOffset != NULL )
	{
		*pOffset = ptr;
	}

	return pBuffer;
}

bool CNetBridge_Base::CheckCompress			( CBuffer* pBuffer )
{
	return (( *pBuffer->m_pData & 0x80000000 ) != 0 );
}

void CNetBridge_Base::Authorize				( CNetSocket* pSocket, CNetSocket* pAcceptSocket )
{

	Struct_PacketAuthorize Packet;
	
	Packet.AuthorizeIndex	= 0;
	Packet.IsCompress		= FALSE;
	Packet.IsEncryption		= FALSE;
	
	if( pSocket->m_IsEncryption == TRUE )
	{
		// 根據資料發給 Client 一個 Authorize ID
		// 這裡之後應該要改成用 RANDOM 從 Authorize Key List 中挑一個 index 發給 Client , 但為了測試方便暫不實作
		Packet.AuthorizeIndex	= 0;//g_authorize_key[0];
	}

	Packet.IsEncryption	= pSocket->m_IsEncryption;
	Packet.IsCompress		= pSocket->m_IsCompress;

	CBuffer* pBuffer = CreatePacketBuffer( sizeof( Packet ), &Packet, NULL );
	
	Post_Compress( pAcceptSocket, pBuffer );
}

void CNetBridge_Base::GetConnectInfo		( DWORD dwNetID, DWORD* pdwIP, WORD* pwPort )
{
	map< DWORD , CNetSocket* > ::iterator it;
	CNetSocket* pSocket = NULL;

	m_cs_Socket.Enter();		
		it = m_mapSocket.find( dwNetID );
		if( it != m_mapSocket.end() )
		{
			pSocket = it->second;
			if( pSocket->m_emStatus == EM_SOCKET_CONNECTED )
			{
				
				if( pdwIP != NULL )
				{
					*pdwIP = pSocket->m_dwIP;
				}
				
				if( pwPort != NULL )
				{
					*pwPort = pSocket->m_wPort;
				}
			}
		}
	m_cs_Socket.Leave();
}

void CNetBridge_Base::SetKeepAlive		( CNetSocket* pSocket )
{
	// SetKeepAlive
	DWORD			dwBytes;
	tcp_keepalive	_keepalive;

	_keepalive.onoff			 = true;
	_keepalive.keepalivetime	 = 10000;
	_keepalive.keepaliveinterval = 3300;

	int rc = WSAIoctl	(	
							pSocket->m_tcp_socket,
							SIO_KEEPALIVE_VALS,
							&_keepalive,
							sizeof( tcp_keepalive ),
							NULL,
							0,
							&dwBytes,
							NULL,
							NULL
						);

	rc = WSAGetLastError();
}

void CNetBridge_Base::MsgOutPut			( char* format , ... )
{
#ifdef _DEBUG
	char	_Buf[1024];
	va_list marker =(char*)&format + sizeof(format);
	vsprintf( _Buf , format , marker );
	if( m_pfOutPut )
	{
		m_pfOutPut( _Buf );
	}
	else
		OutputDebugStr( _Buf );
#endif
}

void CNetBridge_Base::GetStatusInfo		( char* pszOut )
{
	char szOut[255];
#ifdef DF_PACKET_LOG
	sprintf( szOut, "Connect( %d )s, Disconnecting( %d )s, WaitEcho( %d )p", m_mapSocket.size(), m_mapClosingSocket.size(), m_dwPacketLog );
#else
	sprintf( szOut, "Connect( %d )s, Disconnecting( %d )s", m_mapSocket.size(), m_mapClosingSocket.size() );
#endif

	strcpy( pszOut, szOut );
}

bool CNetBridge_Base::Shutdown ()
{
	bool bReturn = false;
	// 關畢所有連線

		map< DWORD, CNetSocket* >::iterator it;
		CNetSocket*	pSocket = NULL;

		if( m_bShutdown == false )
		{
			// 將所有作用中的 Socket 關畢
			m_cs_Socket.Enter();
			for( it = m_mapSocket.begin(); it!= m_mapSocket.end(); it++ )
			{
				pSocket = it->second;
				pSocket->m_cs_SocketIO.Enter();
				
				pSocket->m_pEvent	= NULL;

				shutdown( pSocket->m_tcp_socket,  SD_SEND );
				//closesocket( pSocket->m_tcp_socket );
				pSocket->m_cs_SocketIO.Leave();
			}
			m_bShutdown = true;
			m_cs_Socket.Leave();
		}

	// 持續 Flush 直到所有連線中斷

			m_cs_Socket.Enter();
			if( m_mapSocket.empty() == true )
				bReturn = true;
			m_cs_Socket.Leave();

	return bReturn;

}

#pragma managed