// GCKMSDlg.cpp : implementation file
//

#include "stdafx.h"
#include "GCKMS.h"
#include "GCKMSDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CGCKMSDlg dialog

CGCKMSDlg::CGCKMSDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CGCKMSDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CGCKMSDlg)
	//}}AFX_DATA_INIT
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CGCKMSDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CGCKMSDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CGCKMSDlg, CDialog)
	//{{AFX_MSG_MAP(CGCKMSDlg)
	ON_WM_CLOSE()
	ON_WM_ENDSESSION()
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CGCKMSDlg message handlers

void CGCKMSDlg::OnClose() 
{
	int i;
	if(m_ID_list.empty() == FALSE)
	{
		for(i = 0; i < m_ID_list.size(); i ++)
		{
			KillTimer(m_ID_list[i] + 1000);
		}
	}
	m_ID_list.clear();
	m_IP_list.clear();
	m_port_list.clear();
	m_wsUDPS.Close();
	for(i = 0; i < m_wsTCPS_list.size(); i ++)
	{
		m_wsTCPS_list[i]->m_Data = "";
		m_wsTCPS_list[i]->m_dta.clear();
		m_wsTCPS_list[i]->ShutDown(2);
		m_wsTCPS_list[i]->Close();
		delete m_wsTCPS_list[i];
	}
	m_wsTCPS_list.clear();
	DestroyWindow();
	CDialog::OnClose();
}

void CGCKMSDlg::OnCancel() 
{
	OnClose();
}

void CGCKMSDlg::OnOK() 
{
}

void CGCKMSDlg::OnEndSession(BOOL bEnding) 
{
	OnClose();
}

BOOL CGCKMSDlg::OnInitDialog()
{
	CDialog::OnInitDialog();
	CString txt;
	CWSTCPS *wsTCPS;
	SetIcon(m_hIcon, TRUE);
	if(m_wsUDPS.Create(27900, SOCK_DGRAM, FD_READ) != FALSE)
	{
		txt = " - UDP server running";
	}

//	test.Create(111, SOCK_DGRAM, FD_READ);
//	test.SendTo("\\heartbeat\\8911\\gamename\\giants", 31, 27900, "gckms.no-ip.org");

	m_wsTCPS_list.push_back(wsTCPS);
	m_wsTCPS_list[0] = new CWSTCPS;
	if(m_wsTCPS_list[0]->Create(28900, SOCK_STREAM, FD_ACCEPT | FD_READ | FD_CLOSE) != FALSE)
	{
		if(m_wsTCPS_list[0]->Listen() != FALSE)
		{
			SetTimer(ID_TCPS_TIMER, 30000, NULL);
			if(txt == "")
			{
				txt = " - TCP server running";
			}
			else
			{
				txt = txt + " | TCP server running";
			}
		}
	}
	SetWindowText("GCKMS" + txt);
	return TRUE;
}

void CGCKMSDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this);
		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

HCURSOR CGCKMSDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CGCKMSDlg::OnUDPS_Receive(int nErrorCode) 
{
	if(nErrorCode == 0)
	{
		DWORD rcv;
		int rcv2;
		CString IP;
		UINT port;
		char *dta;
		CString txt;
		m_wsUDPS.IOCtl(FIONREAD, &rcv);
		dta = new char[rcv + 1];
		rcv2 = m_wsUDPS.ReceiveFrom(dta, rcv, IP, port);
		dta[rcv2] = '\0';
		txt = dta;
		delete [] dta;
		if(IP.Left(7) == "192.168")
		{
			IP = inet_ntoa(*((struct in_addr*)gethostbyname("gckms.no-ip.org")->h_addr_list[0]));
		}
		if(m_IP_list.size() < 1000 && (txt.Left(1) == "0" || txt.Left(1) == "1"))
		{
			if(m_ID_list.empty() != FALSE && txt.Left(1) == "0")
			{
				int i;
				m_ID_list.push_back(0);
				m_IP_list.push_back(IP);
				m_port_list.push_back(atoi(txt.Mid(1)));
				SetTimer(1000, 360000, NULL);
				for(i = 1; i < m_wsTCPS_list.size(); i ++)
				{
					m_wsTCPS_list[i]->Send("00¬" + IP + "¬" + txt.Mid(1) + '\0', IP.GetLength() + txt.Mid(1).GetLength() + 5);
				}
			}
			else
			{
				int i;
				BOOL isIPnP;
				isIPnP = FALSE;
				for(i = 0; i < m_ID_list.size(); i ++)
				{
					if(m_IP_list[i] == IP && m_port_list[i] == atoi(txt.Mid(1)))
					{
						KillTimer(m_ID_list[i]);
						SetTimer(m_ID_list[i] + 1000, 360000, NULL);
						if(txt.Left(1) == "1")
						{
							int j;
							CString txt2;
							txt2.Format("%d", m_ID_list[i]);
							for(j = 1; j < m_wsTCPS_list.size(); j ++)
							{
								m_wsTCPS_list[j]->Send("1" + txt2 + '\0', txt2.GetLength() + 2);
							}
						}
						isIPnP = TRUE;
						break;
					}
				}
				if(isIPnP == FALSE && txt.Left(1) == "0")
				{
					int j;
					BOOL isID;
					for(i = 0; i <= 999; i ++)
					{
						isID = FALSE;
						for(j = 0; j < m_ID_list.size(); j ++)
						{
							if(m_ID_list[j] == i)
							{
								isID = TRUE;
								break;
							}
						}
						if(isID == FALSE)
						{
							CString txt2;
							m_ID_list.push_back(i);
							m_IP_list.push_back(IP);
							m_port_list.push_back(atoi(txt.Mid(1)));
							SetTimer(i + 1000, 360000, NULL);
							txt2.Format("%d", i);
							for(j = 1; j < m_wsTCPS_list.size(); j ++)
							{
								m_wsTCPS_list[j]->Send("0" + txt2 + "¬" + IP + "¬" + txt.Mid(1) + '\0', txt2.GetLength() + IP.GetLength() + txt.Mid(1).GetLength() + 4);
							}
							break;
						}
					}
				}
			}
			if(txt.Left(1) == "0")
			{
				m_wsUDPS.SendTo("\\status\\", 8, port, IP);
			}
		}
	}
}

void CGCKMSDlg::OnTCPS_Accept(int nErrorCode) 
{
	if(m_wsTCPS_list.size() < 1001)
	{
		CWSTCPS *wsTCPS;
		m_wsTCPS_list.push_back(wsTCPS);
		m_wsTCPS_list.back() = new CWSTCPS;
		m_wsTCPS_list[0]->Accept(*m_wsTCPS_list.back());
		if(m_IP_list.empty() == FALSE)
		{
			int i;
			std::string txt;
			CString txt2;
			CString txt3;
			std::vector <char> dta;
			for(i = 0; i < m_ID_list.size(); i ++)
			{
				txt2.Format("%d", m_ID_list[i]);
				txt3.Format("%d", m_port_list[i]);
				txt.append("0" + txt2 + "¬" + m_IP_list[i] + "¬" + txt3);
				dta.insert(dta.end(), txt.begin(), txt.end());
				txt = "";
				dta.push_back('\0');
			}
			m_wsTCPS_list.back()->Send(&dta[0], dta.size());
			dta.clear();
		}
	}
}

void CGCKMSDlg::OnTCPS_Receive(int nErrorCode, CWSTCPS *socket) 
{
	if(nErrorCode == 0)
	{
		DWORD rcv;
		int rcv2;
		int i;
		char *dta;
		((CWSTCPS*)socket)->IOCtl(FIONREAD, &rcv);
		dta = new char[rcv];
		rcv2 = ((CWSTCPS*)socket)->Receive(dta, rcv);
		for(i = 0; i < rcv2; i ++)
		{
			if(dta[i] != '\0')
			{
				int j;
				for(j = 1; j < m_wsTCPS_list.size(); j ++)
				{
					if(m_wsTCPS_list[j] == socket)
					{
						m_wsTCPS_list[j]->m_Data = "";
						m_wsTCPS_list[j]->m_dta.clear();
						m_wsTCPS_list[j]->ShutDown(2);
						m_wsTCPS_list[j]->Close();
						delete m_wsTCPS_list[j];
						m_wsTCPS_list.erase(&m_wsTCPS_list[j]);
						delete [] dta;
						return;
					}
				}
			}
		}
		delete [] dta;
	}
}

void CGCKMSDlg::OnTCPS_Close(int nErrorCode, CWSTCPS *socket) 
{
	int i;
	for(i = 1; i < m_wsTCPS_list.size(); i ++)
	{
		if(m_wsTCPS_list[i] == socket)
		{
			m_wsTCPS_list[i]->m_Data = "";
			m_wsTCPS_list[i]->m_dta.clear();
			m_wsTCPS_list[i]->ShutDown(2);
			m_wsTCPS_list[i]->Close();
			delete m_wsTCPS_list[i];
			m_wsTCPS_list.erase(&m_wsTCPS_list[i]);
			break;
		}
	}
}

void CGCKMSDlg::OnTimer(UINT nIDEvent) 
{
	int i;
	for(i = 0; i < m_ID_list.size(); i ++)
	{
		if(m_ID_list[i] + 1000 == nIDEvent)
		{
			int j;
			CString txt2;
			KillTimer(m_ID_list[i] + 1000);
			txt2.Format("%d", m_ID_list[i]);
			for(j = 1; j < m_wsTCPS_list.size(); j ++)
			{
				m_wsTCPS_list[j]->Send("2" + txt2 + '\0', txt2.GetLength() + 2);
			}
			m_ID_list.erase(&m_ID_list[i]);
			m_IP_list.erase(&m_IP_list[i]);
			m_port_list.erase(&m_port_list[i]);
			break;
		}
	}
	if(nIDEvent == ID_TCPS_TIMER)
	{
		for(i = 1; i < m_wsTCPS_list.size(); i ++)
		{
			char dta[1];
			dta[0] = '\0';
			m_wsTCPS_list[i]->Send(dta, 1);
		}
	}
	CDialog::OnTimer(nIDEvent);
}
