Got DCC Send and Recieve working (without having to use threads)
This commit is contained in:
@@ -12,27 +12,26 @@
|
||||
static char THIS_FILE[] = __FILE__;
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSendFileDialog port management data
|
||||
std::vector<unsigned short> CSendFileDialog::m_usedPorts;
|
||||
std::vector<HANDLE> CSendFileDialog::m_hThread;
|
||||
std::vector<CSendFileDialog *> CSendFileDialog::m_transferDialogs;
|
||||
|
||||
const unsigned short CSendFileDialog::kFirstPort = 1024;
|
||||
const unsigned short CSendFileDialog::kLastPort = 5000;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSendFileDialog dialog
|
||||
|
||||
|
||||
CSendFileDialog::CSendFileDialog(CWnd* pParent /*=NULL*/)
|
||||
CSendFileDialog::CSendFileDialog(DCCTransferInfo dccinfo, CWnd* pParent)
|
||||
: CDialog(CSendFileDialog::IDD, pParent)
|
||||
{
|
||||
//{{AFX_DATA_INIT(CSendFileDialog)
|
||||
m_BytesSent = _T("");
|
||||
m_Filesize = _T("");
|
||||
m_FolderName = _T("");
|
||||
m_FileName = _T("");
|
||||
m_RecvrName = _T("");
|
||||
m_TimeLeft = _T("");
|
||||
m_XferRate = _T("");
|
||||
m_XferStatus = _T("");
|
||||
m_SentRecvd = _T("");
|
||||
m_ToFrom = _T("");
|
||||
//}}AFX_DATA_INIT
|
||||
|
||||
m_bIsCanceled = false;
|
||||
m_dccInfo = dccinfo;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,33 +39,410 @@ void CSendFileDialog::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CSendFileDialog)
|
||||
DDX_Control(pDX, IDC_XFERSTATUS, m_XferStatus);
|
||||
DDX_Control(pDX, IDC_XFERRATE, m_XferRate);
|
||||
DDX_Control(pDX, IDC_TOFROM, m_ToFrom);
|
||||
DDX_Control(pDX, IDC_TIMELEFT, m_TimeLeft);
|
||||
DDX_Control(pDX, IDC_SENTRECVD, m_SentRecvd);
|
||||
DDX_Control(pDX, IDC_RECVRNAME, m_RecvrName);
|
||||
DDX_Control(pDX, IDC_FOLDERNAME, m_FolderName);
|
||||
DDX_Control(pDX, IDC_FILESIZE, m_Filesize);
|
||||
DDX_Control(pDX, IDC_FILENAME, m_FileName);
|
||||
DDX_Control(pDX, IDC_BYTESSENT, m_BytesSent);
|
||||
DDX_Control(pDX, IDC_PROGRESS1, m_ProgressFile);
|
||||
DDX_Text(pDX, IDC_BYTESSENT, m_BytesSent);
|
||||
DDX_Text(pDX, IDC_FILESIZE, m_Filesize);
|
||||
DDX_Text(pDX, IDC_FOLDERNAME, m_FolderName);
|
||||
DDX_Text(pDX, IDC_FILENAME, m_FileName);
|
||||
DDX_Text(pDX, IDC_RECVRNAME, m_RecvrName);
|
||||
DDX_Text(pDX, IDC_TIMELEFT, m_TimeLeft);
|
||||
DDX_Text(pDX, IDC_XFERRATE, m_XferRate);
|
||||
DDX_Text(pDX, IDC_XFERSTATUS, m_XferStatus);
|
||||
DDX_Text(pDX, IDC_SENTRECVD, m_SentRecvd);
|
||||
DDX_Text(pDX, IDC_TOFROM, m_ToFrom);
|
||||
//}}AFX_DATA_MAP
|
||||
}
|
||||
|
||||
|
||||
BEGIN_MESSAGE_MAP(CSendFileDialog, CDialog)
|
||||
//{{AFX_MSG_MAP(CSendFileDialog)
|
||||
ON_WM_TIMER()
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSendFileDialog shared data management functions
|
||||
unsigned short CSendFileDialog::MakePortReservation()
|
||||
{
|
||||
//Assume the first port number is open
|
||||
unsigned short uiPort = kFirstPort;
|
||||
|
||||
//if there are no used ports in the list use the first one
|
||||
if (m_usedPorts.size() <= 0)
|
||||
m_usedPorts.push_back(kFirstPort);
|
||||
|
||||
//next see if the port range is saturated (pigeon hole principal)
|
||||
else if ((*m_usedPorts.end() - kFirstPort + 1) >= m_usedPorts.size())
|
||||
m_usedPorts.push_back(*m_usedPorts.end() + 1);
|
||||
|
||||
//there must be a find a gap in the used port list
|
||||
//since the list is always sorted
|
||||
else
|
||||
{
|
||||
std::vector<unsigned short>::iterator iter;
|
||||
for (iter = m_usedPorts.begin(); iter < m_usedPorts.end(); iter++)
|
||||
{
|
||||
//oops, this port is being used, let's try the next one over
|
||||
if (*iter == uiPort) uiPort++;
|
||||
//looks like we found a gap, stop here
|
||||
else break;
|
||||
}
|
||||
|
||||
//Insert our port number into the gap we just found
|
||||
m_usedPorts.insert(iter, uiPort);
|
||||
}
|
||||
|
||||
return uiPort;
|
||||
}
|
||||
|
||||
void CSendFileDialog::FreePort(unsigned short port)
|
||||
{
|
||||
//Tell used port list that this port is now open
|
||||
std::vector<unsigned short>::iterator iter;
|
||||
for (iter = m_usedPorts.begin(); iter < m_usedPorts.end(); iter++)
|
||||
{
|
||||
//Find the port number, remove it
|
||||
if (*iter == port)
|
||||
{
|
||||
m_usedPorts.erase(iter);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CSendFileDialog::AddTransferDialog(CSendFileDialog *ptr)
|
||||
{
|
||||
if (ptr == NULL) return;
|
||||
|
||||
m_transferDialogs.push_back(ptr);
|
||||
}
|
||||
|
||||
void CSendFileDialog::FreeAnyCompletedTransfers()
|
||||
{
|
||||
//remove all file transfer dialogs that are completed
|
||||
std::vector<CSendFileDialog *>::iterator iter;
|
||||
CSendFileDialog *dlg;
|
||||
DCCTransferInfo info;
|
||||
while (iter < m_transferDialogs.end())
|
||||
{
|
||||
dlg = *iter;
|
||||
info = dlg->m_dccInfo;
|
||||
if (info.m_ulBytesSent >= info.m_ulFileSize &&
|
||||
info.m_bIsConnected == false)
|
||||
{
|
||||
delete dlg;
|
||||
iter = m_transferDialogs.erase(iter);
|
||||
}
|
||||
else
|
||||
{
|
||||
iter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSendFileDialog message handlers
|
||||
|
||||
void CSendFileDialog::OnTimer(UINT nIDEvent)
|
||||
{
|
||||
if (m_dccInfo.m_bIsSender) SendSomeData();
|
||||
else RecvSomeData();
|
||||
|
||||
CDialog::OnTimer(nIDEvent);
|
||||
}
|
||||
|
||||
void CSendFileDialog::OnCancel()
|
||||
{
|
||||
//Thread is going to check up on us to see if it's time to bail
|
||||
m_bIsCanceled = true;
|
||||
const unsigned int kTimerID = 1000;
|
||||
|
||||
//See if a file pointer got left open
|
||||
if (m_dccInfo.m_fp != NULL)
|
||||
fclose(m_dccInfo.m_fp);
|
||||
|
||||
//See if a socket got left open
|
||||
if (m_dccInfo.m_sock == true)
|
||||
m_dccInfo.m_sock.Close();
|
||||
|
||||
//See if we need to free a port reservation
|
||||
if (m_dccInfo.m_bIsSender == true && m_dccInfo.m_uiPort >= kFirstPort)
|
||||
FreePort(m_dccInfo.m_uiPort);
|
||||
|
||||
//Now we are no longer connected
|
||||
m_dccInfo.m_bIsConnected = false;
|
||||
|
||||
//kill the timer
|
||||
KillTimer(kTimerID);
|
||||
|
||||
CDialog::OnCancel();
|
||||
}
|
||||
|
||||
int CSendFileDialog::Setup()
|
||||
{
|
||||
//Wait 50 ms between checking for data
|
||||
const unsigned int kPortCheckDelay = 50;
|
||||
const unsigned int kTimerID = 1000;
|
||||
|
||||
//Depending on whether we are sending or recieving
|
||||
// we have to set up differently
|
||||
int ret;
|
||||
if (m_dccInfo.m_bIsSender) ret = SetupSend();
|
||||
else ret = SetupRecv();
|
||||
|
||||
//See if we were able to set up a connection
|
||||
if (-1 == ret)
|
||||
{
|
||||
if (m_dccInfo.m_sock == true) m_dccInfo.m_sock.Close();
|
||||
if (m_dccInfo.m_fp != NULL) fclose(m_dccInfo.m_fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//Setup a timer which routinely checks up on the data
|
||||
if ( SetTimer(kTimerID, kPortCheckDelay, NULL) < 0 )
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// CSendFileDialog dcc file transfer functions
|
||||
int CSendFileDialog::SetupSend()
|
||||
{
|
||||
const unsigned long k_ulTimeout = 30000; //30 second timeout
|
||||
|
||||
//Make sure we are sending...
|
||||
ASSERT (m_dccInfo.m_bIsSender);
|
||||
|
||||
//Remember when we started
|
||||
m_dccInfo.m_ulStartTime = GetTickCount();
|
||||
|
||||
//Setup the status info on the dialog
|
||||
m_BytesSent.SetWindowText("0 bytes");
|
||||
m_ProgressFile.SetRange(0, 100);
|
||||
m_ProgressFile.SetPos(0);
|
||||
m_FolderName.SetWindowText(LPCTSTR(m_dccInfo.m_directory));
|
||||
m_FileName.SetWindowText(LPCTSTR(m_dccInfo.m_fileName));
|
||||
m_RecvrName.SetWindowText(LPCTSTR(m_dccInfo.m_partnerName));
|
||||
m_TimeLeft.SetWindowText("Infinite");
|
||||
m_XferRate.SetWindowText("0 bytes/sec");
|
||||
m_XferStatus.SetWindowText("Waiting to Connect...");
|
||||
m_SentRecvd.SetWindowText("Sent:");
|
||||
m_ToFrom.SetWindowText("To:");
|
||||
|
||||
char filesize[32];
|
||||
sprintf(filesize, "%lu bytes", m_dccInfo.m_ulFileSize);
|
||||
m_Filesize.SetWindowText(filesize);
|
||||
|
||||
//Show the dialog and tell it about this server
|
||||
ShowWindow(SW_SHOW);
|
||||
|
||||
//Tell user file transfer has started
|
||||
m_XferStatus.SetWindowText("Sending File...");
|
||||
|
||||
//Create a file to write incoming data to
|
||||
CString filename = m_dccInfo.m_directory+m_dccInfo.m_fileName;
|
||||
m_dccInfo.m_fp = fopen(filename, "rb");
|
||||
|
||||
//bail if we can't open the file
|
||||
if ( !m_dccInfo.m_fp ) return -1;
|
||||
|
||||
//Create a port to listen on
|
||||
IPaddress ip;
|
||||
TCPsocket waitSock, newSock;
|
||||
SDLNet_ResolveHost(&ip, NULL, m_dccInfo.m_uiPort);
|
||||
waitSock = SDLNet_TCP_Open(&ip);
|
||||
if ( !waitSock ) return -1;
|
||||
|
||||
//Wait for someone to connect to us
|
||||
unsigned long ulTime;
|
||||
do
|
||||
{
|
||||
ulTime = GetTickCount() - m_dccInfo.m_ulStartTime;
|
||||
newSock = SDLNet_TCP_Accept(waitSock);
|
||||
} while ( !newSock && ulTime < k_ulTimeout);
|
||||
|
||||
//Make sure the socket is valid
|
||||
if ( !newSock ) return -1;
|
||||
|
||||
//Now data can be sent on this socket
|
||||
m_dccInfo.m_sock = Socket(newSock);
|
||||
m_dccInfo.m_bIsConnected = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CSendFileDialog::SetupRecv()
|
||||
{
|
||||
//Make sure we are not sending...
|
||||
ASSERT(!m_dccInfo.m_bIsSender);
|
||||
|
||||
//Remember when we started
|
||||
m_dccInfo.m_ulStartTime = GetTickCount();
|
||||
|
||||
//Setup the status info on the dialog
|
||||
m_BytesSent.SetWindowText("0 bytes");
|
||||
m_ProgressFile.SetRange(0, 100);
|
||||
m_ProgressFile.SetPos(0);
|
||||
m_FolderName.SetWindowText(LPCTSTR(m_dccInfo.m_directory));
|
||||
m_FileName.SetWindowText(LPCTSTR(m_dccInfo.m_fileName));
|
||||
m_RecvrName.SetWindowText(LPCTSTR(m_dccInfo.m_partnerName));
|
||||
m_TimeLeft.SetWindowText("Infinite");
|
||||
m_XferRate.SetWindowText("0 bytes/sec");
|
||||
m_XferStatus.SetWindowText("Waiting to Connect...");
|
||||
m_SentRecvd.SetWindowText("Recv'd:");
|
||||
m_ToFrom.SetWindowText("From:");
|
||||
|
||||
char filesize[32];
|
||||
sprintf(filesize, "%lu bytes", m_dccInfo.m_ulFileSize);
|
||||
m_Filesize.SetWindowText(filesize);
|
||||
|
||||
//Show the dialog and tell it about this server
|
||||
ShowWindow(SW_SHOW);
|
||||
|
||||
//Create an active socket to retrieve data from (close listening socket)
|
||||
InetAddr addr;
|
||||
addr.host = htonl(m_dccInfo.m_ulPartnerIP);
|
||||
addr.port = htons(m_dccInfo.m_uiPort);
|
||||
m_dccInfo.m_sock.Connect(addr);
|
||||
|
||||
//bail if we can't open the socket
|
||||
if ( !m_dccInfo.m_sock ) return -1;
|
||||
else m_dccInfo.m_bIsConnected = true;
|
||||
|
||||
//Tell user file transfer has started
|
||||
m_XferStatus.SetWindowText("Recieving File...");
|
||||
|
||||
//Create a file to write incoming data to
|
||||
CString filename = m_dccInfo.m_directory+m_dccInfo.m_fileName;
|
||||
m_dccInfo.m_fp = fopen(filename, "wb");
|
||||
|
||||
//bail if we can't open the file
|
||||
if ( !m_dccInfo.m_fp ) return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CSendFileDialog::SendSomeData()
|
||||
{
|
||||
//Make sure the socket and the file descriptor are valid
|
||||
if (m_dccInfo.m_fp == NULL || m_dccInfo.m_sock != true) return;
|
||||
|
||||
//Make sure we're sending
|
||||
ASSERT (m_dccInfo.m_bIsSender);
|
||||
|
||||
char szBuf[8193];
|
||||
unsigned long cbSend, cbRead, numAck;
|
||||
float fracSent;
|
||||
unsigned long seconds, minutes, hours, rate;
|
||||
|
||||
|
||||
//See if the file is done transfering
|
||||
if (m_dccInfo.m_ulBytesSent < m_dccInfo.m_ulFileSize)
|
||||
{
|
||||
//Pull a data block from the file
|
||||
cbRead = fread(szBuf, sizeof(char), m_dccInfo.m_uiXferRate, m_dccInfo.m_fp);
|
||||
|
||||
//Send the next chunk out
|
||||
cbSend = 0;
|
||||
while (cbSend <= 0)
|
||||
cbSend = m_dccInfo.m_sock.Send((unsigned char *)szBuf, cbRead);
|
||||
|
||||
//Update sent byte count
|
||||
m_dccInfo.m_ulBytesSent += cbSend;
|
||||
|
||||
//Make sure chunk gets acknowledged
|
||||
cbRead = 0;
|
||||
while( cbRead <= 0)
|
||||
cbRead = m_dccInfo.m_sock.Receive((unsigned char*)&numAck, 4);
|
||||
|
||||
//Make sure numAck matches current amount of data sent
|
||||
if (m_dccInfo.m_ulBytesSent != ntohl(numAck))
|
||||
{
|
||||
OnCancel();
|
||||
return;
|
||||
}
|
||||
|
||||
//Update that statistics
|
||||
fracSent = float(m_dccInfo.m_ulBytesSent)/float(m_dccInfo.m_ulFileSize);
|
||||
seconds = seconds = (GetTickCount() - m_dccInfo.m_ulStartTime)/1000;
|
||||
rate = (seconds > 0) ? m_dccInfo.m_ulBytesSent / seconds : 0;
|
||||
seconds = (unsigned long)(float(seconds)/fracSent);
|
||||
minutes = (seconds/60) % 60;
|
||||
hours = (seconds/3600);
|
||||
seconds = seconds % 60;
|
||||
|
||||
//Update the file transfer window
|
||||
sprintf(szBuf, "%lu bytes", m_dccInfo.m_ulBytesSent);
|
||||
m_BytesSent.SetWindowText(szBuf);
|
||||
sprintf(szBuf, "%luh %lum %lus", hours, minutes, seconds);
|
||||
m_TimeLeft.SetWindowText(szBuf);
|
||||
sprintf(szBuf, "%lu bytes/sec", rate);
|
||||
m_XferRate.SetWindowText(szBuf);
|
||||
m_ProgressFile.SetPos(int(fracSent*100.F));
|
||||
}
|
||||
else
|
||||
{
|
||||
//OK, we're all done. Close up shop.
|
||||
OnCancel();
|
||||
}
|
||||
}
|
||||
|
||||
void CSendFileDialog::RecvSomeData()
|
||||
{
|
||||
//Make sure socket and file descriptor are valid
|
||||
if (m_dccInfo.m_sock != true || m_dccInfo.m_fp == NULL) return;
|
||||
|
||||
//Make sure were not sending
|
||||
ASSERT (!m_dccInfo.m_bIsSender);
|
||||
|
||||
char szBuf[8193];
|
||||
unsigned long cbRead, cbSent, replyTotal;
|
||||
float fracSent;
|
||||
unsigned long seconds, minutes, hours, rate;
|
||||
|
||||
|
||||
//Start grabbing data blocks
|
||||
if (m_dccInfo.m_ulBytesSent < m_dccInfo.m_ulFileSize)
|
||||
{
|
||||
//Grab the next buffer
|
||||
cbRead = m_dccInfo.m_sock.Receive((unsigned char*)szBuf, sizeof(szBuf)-1);
|
||||
|
||||
//Bail if there is nothing to read
|
||||
if( cbRead <= 0 ) return;
|
||||
else szBuf[cbRead] = '\0';
|
||||
|
||||
//Write it to file
|
||||
fwrite(szBuf, cbRead, 1, m_dccInfo.m_fp);
|
||||
|
||||
//update byte count
|
||||
m_dccInfo.m_ulBytesSent += cbRead;
|
||||
|
||||
//Update the file transfer statistics
|
||||
fracSent = float(m_dccInfo.m_ulBytesSent)/float(m_dccInfo.m_ulFileSize);
|
||||
seconds = (GetTickCount() - m_dccInfo.m_ulStartTime)/1000;
|
||||
rate = (seconds > 0) ? m_dccInfo.m_ulBytesSent / seconds : 0;
|
||||
seconds = (unsigned long)(float(seconds)/fracSent);
|
||||
minutes = (seconds/60) % 60;
|
||||
hours = (seconds/3600);
|
||||
seconds = seconds % 60;
|
||||
|
||||
//Update the file transfer window
|
||||
sprintf(szBuf, "%lu bytes", m_dccInfo.m_ulBytesSent);
|
||||
m_BytesSent.SetWindowText(szBuf);
|
||||
sprintf(szBuf, "%luh %lum %lus", hours, minutes, seconds);
|
||||
m_TimeLeft.SetWindowText(szBuf);
|
||||
sprintf(szBuf, "%lu bytes/sec", rate);
|
||||
m_XferRate.SetWindowText(szBuf);
|
||||
m_ProgressFile.SetPos(int(fracSent*100.F));
|
||||
|
||||
//Tell the sender how many bytes we received
|
||||
replyTotal = htonl(m_dccInfo.m_ulBytesSent);
|
||||
|
||||
//Send out response
|
||||
cbSent = m_dccInfo.m_sock.Send((unsigned char *)&replyTotal, 4);
|
||||
}
|
||||
else
|
||||
{
|
||||
OnCancel();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,26 +14,60 @@
|
||||
|
||||
class CSendFileDialog : public CDialog
|
||||
{
|
||||
// Public data types
|
||||
public:
|
||||
// DCC Info
|
||||
struct DCCTransferInfo
|
||||
{
|
||||
bool m_bIsSender;
|
||||
bool m_bIsConnected;
|
||||
CString m_fileName;
|
||||
CString m_directory;
|
||||
CString m_partnerName;
|
||||
unsigned long m_ulPartnerIP;
|
||||
unsigned int m_uiPort;
|
||||
unsigned long m_ulFileSize;
|
||||
unsigned long m_ulBytesSent;
|
||||
unsigned long m_ulStartTime;
|
||||
unsigned int m_uiXferRate;
|
||||
Socket m_sock;
|
||||
FILE* m_fp;
|
||||
|
||||
DCCTransferInfo() :
|
||||
m_bIsSender(false),
|
||||
m_bIsConnected(false),
|
||||
m_ulPartnerIP(0L),
|
||||
m_uiPort(0),
|
||||
m_ulFileSize(0L),
|
||||
m_ulBytesSent(0L),
|
||||
m_ulStartTime(0L),
|
||||
m_uiXferRate(0),
|
||||
m_fp(NULL)
|
||||
{}
|
||||
};
|
||||
|
||||
// Construction
|
||||
public:
|
||||
CSendFileDialog(CWnd* pParent = NULL); // standard constructor
|
||||
// standard constructor
|
||||
CSendFileDialog(DCCTransferInfo dccinfo, CWnd* pParent = NULL);
|
||||
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CSendFileDialog)
|
||||
enum { IDD = IDD_FILEXFER };
|
||||
CStatic m_XferStatus;
|
||||
CStatic m_XferRate;
|
||||
CStatic m_ToFrom;
|
||||
CStatic m_TimeLeft;
|
||||
CStatic m_SentRecvd;
|
||||
CStatic m_RecvrName;
|
||||
CStatic m_FolderName;
|
||||
CStatic m_Filesize;
|
||||
CStatic m_FileName;
|
||||
CStatic m_BytesSent;
|
||||
CProgressCtrl m_ProgressFile;
|
||||
CString m_BytesSent;
|
||||
CString m_Filesize;
|
||||
CString m_FolderName;
|
||||
CString m_FileName;
|
||||
CString m_RecvrName;
|
||||
CString m_TimeLeft;
|
||||
CString m_XferRate;
|
||||
CString m_XferStatus;
|
||||
CString m_SentRecvd;
|
||||
CString m_ToFrom;
|
||||
//}}AFX_DATA
|
||||
|
||||
DCCTransferInfo m_dccInfo;
|
||||
|
||||
// Overrides
|
||||
// ClassWizard generated virtual function overrides
|
||||
@@ -44,16 +78,32 @@ public:
|
||||
|
||||
// Implementation
|
||||
public:
|
||||
bool isCanceled() { return m_bIsCanceled; }
|
||||
int Setup();
|
||||
static unsigned short MakePortReservation();
|
||||
static void AddTransferDialog(CSendFileDialog *ptr);
|
||||
static void FreeAnyCompletedTransfers();
|
||||
|
||||
protected:
|
||||
void FreePort(unsigned short port);
|
||||
int SetupSend();
|
||||
int SetupRecv();
|
||||
void SendSomeData();
|
||||
void RecvSomeData();
|
||||
|
||||
protected:
|
||||
bool m_bIsCanceled;
|
||||
static std::vector<HANDLE> m_hThread;
|
||||
static std::vector<unsigned short> m_usedPorts;
|
||||
static std::vector<CSendFileDialog *> m_transferDialogs;
|
||||
|
||||
static const unsigned short kFirstPort;
|
||||
static const unsigned short kLastPort;
|
||||
|
||||
protected:
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CSendFileDialog)
|
||||
virtual void OnCancel();
|
||||
afx_msg void OnTimer(UINT nIDEvent);
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
@@ -195,6 +195,7 @@ bool CIrcSession::Connect(const CIrcSessionInfo& info)
|
||||
|
||||
m_socket.Send("USER %s %s %s :%s\r\n",
|
||||
info.sUserID.c_str(), szHostName, "server", info.sFullName.c_str());
|
||||
|
||||
}
|
||||
catch( const char* )
|
||||
{
|
||||
@@ -339,7 +340,7 @@ void CIrcSession::RemoveMonitor(IIrcSessionMonitor* pMonitor)
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
CIrcSessionInfo::CIrcSessionInfo()
|
||||
: iPort(0), bIdentServer(false), iIdentServerPort(0)
|
||||
: iPort(0), bIdentServer(false), iIdentServerPort(0), bIsGameHost(false), luSongHash(0L)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -353,7 +354,12 @@ CIrcSessionInfo::CIrcSessionInfo(const CIrcSessionInfo& si)
|
||||
sPassword(si.sPassword),
|
||||
bIdentServer(si.bIdentServer),
|
||||
sIdentServerType(si.sIdentServerType),
|
||||
iIdentServerPort(si.iIdentServerPort)
|
||||
iIdentServerPort(si.iIdentServerPort),
|
||||
bIsGameHost(si.bIsGameHost),
|
||||
sSongPath(si.sSongPath),
|
||||
luSongHash(si.luSongHash),
|
||||
sHostName(si.sHostName),
|
||||
sHostIP(si.sHostIP)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -369,6 +375,14 @@ void CIrcSessionInfo::Reset()
|
||||
bIdentServer = false;
|
||||
sIdentServerType = "";
|
||||
iIdentServerPort = 0;
|
||||
|
||||
bIsGameHost = false;
|
||||
sSongPath = "";
|
||||
luSongHash = 0L;
|
||||
sHostName = "";
|
||||
sHostIP = "";
|
||||
|
||||
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@@ -469,7 +483,7 @@ DWORD WINAPI CIrcIdentServer::ListenProc(LPVOID pparam)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
std::vector<unsigned short> CIrcDCCServer::m_usedPorts;
|
||||
/*std::vector<unsigned short> CIrcDCCServer::m_usedPorts;
|
||||
std::vector<HANDLE> CIrcDCCServer::m_hThread;
|
||||
const unsigned short CIrcDCCServer::kFirstPort = 1024;
|
||||
const unsigned short CIrcDCCServer::kLastPort = 5000;
|
||||
@@ -558,7 +572,7 @@ bool CIrcDCCServer::Start(DCCTransferInfo dccinfo)
|
||||
dccinfo.m_pDCCSever = this;
|
||||
|
||||
//Create the appropriate thread, but don't start it just yet
|
||||
/*if (dccinfo.m_bIsSender)
|
||||
if (dccinfo.m_bIsSender)
|
||||
dccinfo.m_pThread = CreateThread(NULL, 0, DoThreadSend, (void *)&dccinfo,
|
||||
CREATE_SUSPENDED, NULL);
|
||||
else
|
||||
@@ -570,12 +584,7 @@ bool CIrcDCCServer::Start(DCCTransferInfo dccinfo)
|
||||
|
||||
//Now we can fire off the thread
|
||||
if (-1 == ResumeThread(dccinfo.m_pThread)) return false;
|
||||
Sleep(100);*/
|
||||
|
||||
if (dccinfo.m_bIsSender)
|
||||
DoThreadSend((void *)&dccinfo);
|
||||
else
|
||||
DoThreadRecv((void *)&dccinfo);
|
||||
Sleep(100);
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -896,7 +905,7 @@ DWORD WINAPI CIrcDCCServer::DoThreadSend(void* dccInfo)
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include "CrossThreadsMessagingDevice.h"
|
||||
#include "SendFileDialog.h"
|
||||
//#include "SendFileDialog.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
namespace irc {
|
||||
@@ -76,6 +76,12 @@ struct CIrcSessionInfo
|
||||
String sIdentServerType;
|
||||
unsigned int iIdentServerPort;
|
||||
|
||||
bool bIsGameHost;
|
||||
String sSongPath;
|
||||
unsigned long luSongHash;
|
||||
String sHostName;
|
||||
String sHostIP;
|
||||
|
||||
CIrcSessionInfo();
|
||||
CIrcSessionInfo(const CIrcSessionInfo& si);
|
||||
|
||||
@@ -103,6 +109,15 @@ public :
|
||||
CIrcSessionInfo& GetInfo() const
|
||||
{ return (CIrcSessionInfo&)m_info; }
|
||||
|
||||
void SetGameInfo(bool isHost, String sPath, unsigned long luHash, String sHost, String sIP)
|
||||
{
|
||||
m_info.bIsGameHost = isHost;
|
||||
m_info.sSongPath = sPath;
|
||||
m_info.luSongHash = luHash;
|
||||
m_info.sHostName = sHost;
|
||||
m_info.sHostIP = sIP;
|
||||
}
|
||||
|
||||
operator bool() const { return (bool)m_socket; }
|
||||
|
||||
// send-to-stream operators
|
||||
@@ -166,7 +181,7 @@ private :
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CIrcDCCServer
|
||||
/*class CIrcDCCServer
|
||||
{
|
||||
public:
|
||||
struct DCCTransferInfo
|
||||
@@ -218,7 +233,7 @@ protected:
|
||||
|
||||
static DWORD WINAPI DoThreadSend(void* dccinfo);
|
||||
static DWORD WINAPI DoThreadRecv(void* dccinfo);
|
||||
};
|
||||
};*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -38,6 +38,10 @@
|
||||
#define IDC_TOFROM 1023
|
||||
#define IDC_SENTRECVD 1024
|
||||
#define IDC_COMBO1 1030
|
||||
#define IDC_NEWGAMEFRAME 1031
|
||||
#define IDC_SELECT_MUSIC_STATIC 1032
|
||||
#define IDC_GAME_NAME_STATIC 1033
|
||||
#define IDC_REFRESH_GAME_LIST 1034
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
@@ -45,7 +49,7 @@
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 136
|
||||
#define _APS_NEXT_COMMAND_VALUE 32771
|
||||
#define _APS_NEXT_CONTROL_VALUE 1031
|
||||
#define _APS_NEXT_CONTROL_VALUE 1035
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Binary file not shown.
+87
-1341
File diff suppressed because it is too large
Load Diff
@@ -188,6 +188,10 @@ SOURCE=.\res\smlobby.ico
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\smlobby.rc
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\res\smlobby.rc2
|
||||
# End Source File
|
||||
# End Group
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,42 @@
|
||||
<html>
|
||||
<body>
|
||||
<pre>
|
||||
<h1>Build Log</h1>
|
||||
<h3>
|
||||
--------------------Configuration: smlobby - Win32 Debug--------------------
|
||||
</h3>
|
||||
<h3>Command Lines</h3>
|
||||
Creating temporary file "C:\DOCUME~1\BRENDA~1\LOCALS~1\Temp\RSP1BA.tmp" with contents
|
||||
[
|
||||
/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR"Debug/" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c
|
||||
"C:\eclipse\workspace\stepmania\src\smlobby\smlobbyDlg.cpp"
|
||||
]
|
||||
Creating command line "cl.exe @C:\DOCUME~1\BRENDA~1\LOCALS~1\Temp\RSP1BA.tmp"
|
||||
Creating temporary file "C:\DOCUME~1\BRENDA~1\LOCALS~1\Temp\RSP1BB.tmp" with contents
|
||||
[
|
||||
ws2_32.lib /nologo /subsystem:windows /incremental:yes /pdb:"../../smlobby.pdb" /debug /machine:I386 /out:"../../smlobby.exe" /pdbtype:sept
|
||||
.\Debug\ConnectDlg.obj
|
||||
.\Debug\CrossThreadsMessagingDevice.obj
|
||||
.\Debug\EditChat.obj
|
||||
.\Debug\irc.obj
|
||||
.\Debug\RageUtil.obj
|
||||
.\Debug\SendFileDialog.obj
|
||||
.\Debug\smlobby.obj
|
||||
.\Debug\smlobbyDlg.obj
|
||||
.\Debug\socket.obj
|
||||
.\Debug\StdAfx.obj
|
||||
.\Debug\smlobby.res
|
||||
]
|
||||
Creating command line "link.exe @C:\DOCUME~1\BRENDA~1\LOCALS~1\Temp\RSP1BB.tmp"
|
||||
<h3>Output Window</h3>
|
||||
Compiling...
|
||||
smlobbyDlg.cpp
|
||||
Linking...
|
||||
|
||||
|
||||
|
||||
<h3>Results</h3>
|
||||
smlobby.exe - 0 error(s), 0 warning(s)
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
@@ -92,23 +92,25 @@ FONT 8, "MS Sans Serif", 0, 0, 0x1
|
||||
BEGIN
|
||||
EDITTEXT IDC_EDIT_ENTRY,105,281,347,12,ES_AUTOHSCROLL
|
||||
GROUPBOX "Chat",IDC_STATIC,5,140,453,160
|
||||
GROUPBOX "Waiting Games",IDC_STATIC,5,5,117,130
|
||||
LISTBOX IDC_LIST_GAMES,15,20,100,105,LBS_SORT |
|
||||
GROUPBOX "Waiting Games",IDC_STATIC,5,22,117,113
|
||||
LISTBOX IDC_LIST_GAMES,15,42,100,84,LBS_SORT |
|
||||
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
GROUPBOX "Game Information",IDC_STATIC,143,5,107,130
|
||||
EDITTEXT IDC_EDIT_GAME_INFO,153,20,90,105,ES_MULTILINE
|
||||
GROUPBOX "Create New Game",IDC_STATIC,271,5,185,130
|
||||
EDITTEXT IDC_EDIT_GAME_INFO,153,20,90,105,ES_MULTILINE |
|
||||
ES_READONLY
|
||||
GROUPBOX "Create New Game",IDC_NEWGAMEFRAME,271,5,185,130
|
||||
COMBOBOX IDC_COMBO_MUSIC,278,35,170,88,CBS_DROPDOWNLIST |
|
||||
CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Select Music:",IDC_STATIC,278,25,44,10
|
||||
LTEXT "Select Music:",IDC_SELECT_MUSIC_STATIC,278,25,44,10
|
||||
PUSHBUTTON "Create Game",IDC_BUTTON_CREATE_GAME,338,100,56,20
|
||||
LISTBOX IDC_LIST_USERS,10,155,85,140,LBS_SORT |
|
||||
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||
EDITTEXT IDC_EDIT_GAME_NAME,277,70,171,15,ES_AUTOHSCROLL
|
||||
LTEXT "Game Name:",IDC_STATIC,278,60,87,10
|
||||
LTEXT "Game Name:",IDC_GAME_NAME_STATIC,278,60,87,10
|
||||
PUSHBUTTON "Begin Game",IDC_BUTTON_BEGIN_GAME,213,305,49,20
|
||||
EDITTEXT IDC_EDIT_CHAT_MESSAGES,105,155,347,120,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | WS_VSCROLL
|
||||
PUSHBUTTON "Refresh Game List",IDC_REFRESH_GAME_LIST,32,6,63,13
|
||||
END
|
||||
|
||||
IDD_FILEXFER DIALOG DISCARDABLE 0, 0, 186, 173
|
||||
@@ -123,7 +125,7 @@ BEGIN
|
||||
LTEXT "To:",IDC_TOFROM,7,49,33,8
|
||||
CONTROL "Progress1",IDC_PROGRESS1,"msctls_progress32",WS_BORDER,
|
||||
7,70,172,13
|
||||
LTEXT "Sent:",IDC_SENTRECVD,7,89,21,9
|
||||
LTEXT "Sent:",IDC_SENTRECVD,7,89,28,9
|
||||
LTEXT "Time left:",IDC_STATIC,7,98,33,8
|
||||
LTEXT "Rate:",IDC_STATIC,7,107,33,8
|
||||
LTEXT "Status:",IDC_STATIC,7,117,33,8
|
||||
|
||||
@@ -14,7 +14,8 @@ static char THIS_FILE[] = __FILE__;
|
||||
|
||||
|
||||
#include "ConnectDlg.h"
|
||||
|
||||
#include "SendFileDialog.h"
|
||||
#include <process.h>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// global objects
|
||||
@@ -22,7 +23,7 @@ static const NetworkInit g_wsInit;
|
||||
static const unsigned short FILE_XFER_RATE = 4096;
|
||||
|
||||
irc::CIrcSession g_ircSession;
|
||||
irc::CIrcDCCServer g_DCCServer;
|
||||
//irc::CIrcDCCServer g_DCCServer;
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
@@ -80,12 +81,20 @@ CSmlobbyDlg::CSmlobbyDlg(CWnd* pParent /*=NULL*/)
|
||||
//}}AFX_DATA_INIT
|
||||
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
|
||||
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
|
||||
|
||||
//We aren't trying to join any games just yet
|
||||
m_bWantToJoin = false;
|
||||
}
|
||||
|
||||
void CSmlobbyDlg::DoDataExchange(CDataExchange* pDX)
|
||||
{
|
||||
CDialog::DoDataExchange(pDX);
|
||||
//{{AFX_DATA_MAP(CSmlobbyDlg)
|
||||
DDX_Control(pDX, IDC_BUTTON_BEGIN_GAME, m_buttonStartGame);
|
||||
DDX_Control(pDX, IDC_GAME_NAME_STATIC, m_staticGameName);
|
||||
DDX_Control(pDX, IDC_SELECT_MUSIC_STATIC, m_staticSelectMusic);
|
||||
DDX_Control(pDX, IDC_NEWGAMEFRAME, m_frameNewGame);
|
||||
DDX_Control(pDX, IDC_BUTTON_CREATE_GAME, m_buttonCreateGame);
|
||||
DDX_Control(pDX, IDC_COMBO_MUSIC, m_comboMusic);
|
||||
DDX_Control(pDX, IDC_EDIT_GAME_NAME, m_editGameName);
|
||||
DDX_Control(pDX, IDC_EDIT_GAME_INFO, m_editGameInfo);
|
||||
@@ -103,8 +112,10 @@ BEGIN_MESSAGE_MAP(CSmlobbyDlg, CDialog)
|
||||
ON_WM_PAINT()
|
||||
ON_WM_DESTROY()
|
||||
ON_LBN_DBLCLK(IDC_LIST_GAMES, OnDblclkListGames)
|
||||
ON_LBN_SELCHANGE(IDC_LIST_GAMES, OnSelchangeListGames)
|
||||
ON_BN_CLICKED(IDC_BUTTON_CREATE_GAME, OnButtonCreateGame)
|
||||
ON_LBN_SELCHANGE(IDC_LIST_GAMES, OnSelchangeListGames)
|
||||
ON_BN_CLICKED(IDC_BUTTON_BEGIN_GAME, OnButtonBeginGame)
|
||||
ON_BN_CLICKED(IDC_REFRESH_GAME_LIST, OnRefreshGameList)
|
||||
//}}AFX_MSG_MAP
|
||||
END_MESSAGE_MAP()
|
||||
|
||||
@@ -148,6 +159,7 @@ BOOL CSmlobbyDlg::OnInitDialog()
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "MODE", OnIrc_MODE)
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "NICK", OnIrc_NICK)
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "PART", OnIrc_PART)
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "QUIT", OnIrc_QUIT)
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "PRIVMSG", OnIrc_PRIVMSG)
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "DCC", OnIrc_DCC_SEND)
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "002", OnIrc_YOURHOST)
|
||||
@@ -158,7 +170,7 @@ BOOL CSmlobbyDlg::OnInitDialog()
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "332", OnIrc_RPL_TOPIC)
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "353", OnIrc_RPL_NAMREPLY)
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "366", OnIrc_IgnoreMesg) //RPL_ENDOFNAMES
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "376", OnIrc_IgnoreMesg) //RPL_ENDOFMOTD
|
||||
IRC_MAP_ENTRY(CSmlobbyDlg, "376", OnIrc_RPL_ENDOFMOTD)
|
||||
|
||||
|
||||
//Initialize IRC Server connection dialog
|
||||
@@ -203,6 +215,8 @@ BOOL CSmlobbyDlg::OnInitDialog()
|
||||
GetDirListing( sDir+"\\*.*", arrayGroupDirs, true );
|
||||
SortCStringArray( arrayGroupDirs );
|
||||
|
||||
//FILE *fp = fopen("SongHashes.txt","wt");
|
||||
//int k=1000;
|
||||
for( unsigned i=0; i< arrayGroupDirs.GetSize(); i++ ) // for each dir in /Songs/
|
||||
{
|
||||
CString sGroupDirName = arrayGroupDirs[i];
|
||||
@@ -223,11 +237,19 @@ BOOL CSmlobbyDlg::OnInitDialog()
|
||||
continue; // ignore it
|
||||
|
||||
CString sSongDir = ssprintf("%s\\%s\\%s", sDir, sGroupDirName, sSongDirName);
|
||||
unsigned long ulSongHash = GetHashForDirectory( sSongDir );
|
||||
|
||||
m_comboMusic.AddString( sSongDir );
|
||||
m_comboMusic.SetItemData( m_comboMusic.GetCount()-1, ulSongHash );
|
||||
//fprintf(fp, "%d,%s,%lu\n", k, LPCSTR(sSongDir), ulSongHash);
|
||||
//k++;
|
||||
}
|
||||
}
|
||||
|
||||
//fclose(fp);
|
||||
//Make sure start game button is invisible
|
||||
m_buttonStartGame.ShowWindow(FALSE);
|
||||
|
||||
return TRUE; // return TRUE unless you set the focus to a control
|
||||
}
|
||||
|
||||
@@ -304,21 +326,69 @@ bool CSmlobbyDlg::OnIrc_NICK(const CIrcMessage* pmsg)
|
||||
|
||||
bool CSmlobbyDlg::OnIrc_PRIVMSG(const CIrcMessage* pmsg)
|
||||
{
|
||||
//See if were being sent a DCC command
|
||||
//See if were being sent a DCC comand
|
||||
if (OnIrc_DCC_RECV(pmsg))
|
||||
return true;
|
||||
|
||||
|
||||
//see if someone is starting a game
|
||||
if (OnIrc_DDR_GAME_START(pmsg))
|
||||
return true;
|
||||
|
||||
UpdateChatMessages( pmsg );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSmlobbyDlg::OnIrc_RPL_ENDOFMOTD(const CIrcMessage *pmsg)
|
||||
{
|
||||
g_ircSession << irc::CIrcMessage(CString("join #mainlobby"));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSmlobbyDlg::OnIrc_DDR_GAME_START(const CIrcMessage *pmsg)
|
||||
{
|
||||
//incoming::
|
||||
// PRIVMSG <recipient> :<0x01>DDR START
|
||||
|
||||
//Make sure we have a parameter
|
||||
if ( pmsg->parameters.size() < 1 )
|
||||
return false;
|
||||
|
||||
//Make sure it's a DDR start
|
||||
if ( std::string::npos == pmsg->parameters[1].find("\001DDR START") )
|
||||
return false;
|
||||
|
||||
//Get the info for this chat room
|
||||
String sSongPath = g_ircSession.GetInfo().sSongPath;
|
||||
String sIP = g_ircSession.GetInfo().sHostIP;
|
||||
String sMyUserName = g_ircSession.GetInfo().sNick;
|
||||
|
||||
//Are we the one who stated the game
|
||||
if (m_buttonStartGame.IsWindowVisible() == TRUE)
|
||||
{
|
||||
m_buttonStartGame.ShowWindow(FALSE);
|
||||
if ( !WinExec("smserver.exe") )
|
||||
AfxMessageBox("Lobby unable to start Stepmania game server!");
|
||||
}
|
||||
|
||||
//Start up the game
|
||||
if ( !WinExec("stepmania.exe " + sSongPath + " " + sIP.c_str() + " " + sMyUserName.c_str()) )
|
||||
AfxMessageBox("Lobby unable to start Stepmania!");
|
||||
|
||||
//Bail from this lobby
|
||||
g_ircSession << irc::CIrcMessage(CString("part ") + CString(g_ircSession.GetInfo().sCurrentChatRoom.c_str()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSmlobbyDlg::OnIrc_DCC_SEND(const CIrcMessage *pmsg)
|
||||
{
|
||||
//incoming:
|
||||
// /DCC SEND <recipient>
|
||||
//outgoing:
|
||||
// PRIVMSG <recipient> :<0x01>DCC SEND <filename> <ipaddress> <port> <filesize><0x01>
|
||||
// PRIVMSG <recipient> :<0x01>DCC SEND <filename> <ipaddress> <port> <filesize> <0x01>
|
||||
|
||||
const kRecptParm = 1;
|
||||
|
||||
//Make sure we have a parameter
|
||||
@@ -352,29 +422,41 @@ bool CSmlobbyDlg::OnIrc_DCC_SEND(const CIrcMessage *pmsg)
|
||||
CString dirname = fullpath.Left(fullpath.GetLength() - filename.GetLength());
|
||||
|
||||
//Place all of the connection info into a dcc info structure
|
||||
irc::CIrcDCCServer::DCCTransferInfo dccInfo;
|
||||
//irc::CIrcDCCServer::DCCTransferInfo dccInfo;
|
||||
CSendFileDialog::DCCTransferInfo dccInfo;
|
||||
dccInfo.m_bIsSender = true;
|
||||
dccInfo.m_fileName = filename;
|
||||
dccInfo.m_directory = dirname;
|
||||
dccInfo.m_partnerName = partnerName;
|
||||
dccInfo.m_uiPort = g_DCCServer.MakePortReservation();
|
||||
dccInfo.m_uiPort = CSendFileDialog::MakePortReservation();
|
||||
dccInfo.m_uiXferRate = FILE_XFER_RATE;
|
||||
dccInfo.m_ulFileSize = GetFileSizeInBytes(fullpath);
|
||||
dccInfo.m_ulPartnerIP = ipaddr.host;
|
||||
|
||||
//Create a dcc command to send to the user to which our file is going
|
||||
// make sure data is in network byte order
|
||||
char szDCCString[512];
|
||||
sprintf(szDCCString, "PRIVMSG %s :\001DCC SEND %s %ul %u %ul\001",
|
||||
dccInfo.m_partnerName, dccInfo.m_fileName, ipaddr.host,
|
||||
dccInfo.m_uiPort, dccInfo.m_ulFileSize);
|
||||
unsigned long ip = ntohl(ipaddr.host);
|
||||
unsigned short port = dccInfo.m_uiPort;//htons(dccInfo.m_uiPort);
|
||||
unsigned long filesize = dccInfo.m_ulFileSize;//htonl(dccInfo.m_ulFileSize);
|
||||
sprintf(szDCCString, "PRIVMSG %s :\001DCC SEND %s %lu %u %lu \001",
|
||||
dccInfo.m_partnerName, dccInfo.m_fileName, ip, port, filesize);
|
||||
|
||||
//Send of the dcc command to the other party
|
||||
g_ircSession << irc::CIrcMessage(szDCCString);
|
||||
|
||||
//We now have enough info to fire off a thread that will
|
||||
//We now have enough info to open a window that will
|
||||
//wait for the other party to connect to us and then
|
||||
//transfer the file to them
|
||||
g_DCCServer.Start(dccInfo);
|
||||
//g_DCCServer.Start(dccInfo);
|
||||
CSendFileDialog *dlg = new CSendFileDialog(dccInfo);
|
||||
|
||||
//Remember this dialog so that when we exit the app
|
||||
//CSendFileDialog::FreeAnyCompletedTransfers() can release it
|
||||
CSendFileDialog::AddTransferDialog(dlg);
|
||||
|
||||
//Now let's try and open the window
|
||||
if ( !dlg->Create(IDD_FILEXFER, NULL) || !dlg->Setup() ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -383,6 +465,7 @@ bool CSmlobbyDlg::OnIrc_DCC_RECV(const CIrcMessage *pmsg)
|
||||
{
|
||||
//incoming::
|
||||
// PRIVMSG <recipient> :<0x01>DCC SEND <filename> <ipaddress> <port> <filesize><0x01>
|
||||
// filesize, ipaddress, and port are in network byte order
|
||||
|
||||
//Make sure we have a parameter
|
||||
if ( pmsg->parameters.size() < 1 )
|
||||
@@ -395,13 +478,28 @@ bool CSmlobbyDlg::OnIrc_DCC_RECV(const CIrcMessage *pmsg)
|
||||
//Make sure we can read out the dcc send fields
|
||||
const char* pszRawString = pmsg->parameters[1].c_str();
|
||||
char szFilename[256];
|
||||
unsigned long ulPartnerIP;
|
||||
unsigned short uiPartnerPort;
|
||||
unsigned long ulFileSize;
|
||||
unsigned long ulPartnerIP = 0L;
|
||||
unsigned short uiPartnerPort = 0;
|
||||
unsigned long ulFileSize = 0L;
|
||||
|
||||
//Snag the dcc info fields from the message string
|
||||
if ( 4 != sscanf(pszRawString, "\001DCC SEND %255s %lu %u %lu",
|
||||
&szFilename, &ulPartnerIP, &uiPartnerPort, &ulFileSize) )
|
||||
int ret = sscanf(pszRawString, "\001DCC SEND %255s %lu %u %lu \001",
|
||||
&szFilename, &ulPartnerIP, &uiPartnerPort, &ulFileSize);
|
||||
if ( 4 != ret )
|
||||
return false;
|
||||
|
||||
//Transform data from network byte order to host byte order
|
||||
//ulFileSize = ntohl(ulFileSize);
|
||||
//uiPartnerPort = ntohs(uiPartnerPort);
|
||||
//ulPartnerIP = ntohl(ulPartnerIP);
|
||||
|
||||
//See if this is an echo of a connection I already sent
|
||||
IPaddress ipaddr;
|
||||
char szHostName[256];
|
||||
gethostname(szHostName, 256);
|
||||
SDLNet_ResolveHost(&ipaddr, szHostName, 0);
|
||||
|
||||
if (ulPartnerIP == ntohl(ipaddr.host))
|
||||
return false;
|
||||
|
||||
//Open a dialog box so user can decide where to save file
|
||||
@@ -410,7 +508,8 @@ bool CSmlobbyDlg::OnIrc_DCC_RECV(const CIrcMessage *pmsg)
|
||||
return false;
|
||||
|
||||
//Assemble all of this info into a dcc info structure
|
||||
irc::CIrcDCCServer::DCCTransferInfo dccInfo;
|
||||
//irc::CIrcDCCServer::DCCTransferInfo dccInfo;
|
||||
CSendFileDialog::DCCTransferInfo dccInfo;
|
||||
dccInfo.m_bIsSender = false;
|
||||
dccInfo.m_directory = pathname;
|
||||
dccInfo.m_fileName = szFilename;
|
||||
@@ -420,8 +519,16 @@ bool CSmlobbyDlg::OnIrc_DCC_RECV(const CIrcMessage *pmsg)
|
||||
dccInfo.m_ulFileSize = ulFileSize;
|
||||
dccInfo.m_ulPartnerIP = ulPartnerIP;
|
||||
|
||||
//We now have enough info to fire off a thread that downloads the file
|
||||
g_DCCServer.Start(dccInfo);
|
||||
//We now have enough info to create a window to deal with file xfer
|
||||
//g_DCCServer.Start(dccInfo);
|
||||
CSendFileDialog *dlg = new CSendFileDialog(dccInfo);
|
||||
|
||||
//Remember this dialog so that when we exit the app
|
||||
//CSendFileDialog::FreeAnyCompletedTransfers() can release it
|
||||
CSendFileDialog::AddTransferDialog(dlg);
|
||||
|
||||
//Now let's try and open the window
|
||||
if ( !dlg->Create(IDD_FILEXFER, NULL) || !dlg->Setup() ) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -446,29 +553,50 @@ bool CSmlobbyDlg::OnIrc_JOIN(const CIrcMessage* pmsg)
|
||||
|
||||
bool CSmlobbyDlg::OnIrc_PART(const CIrcMessage* pmsg)
|
||||
{
|
||||
if( !pmsg->prefix.sNick.length() || pmsg->prefix.sNick == m_session.GetInfo().sNick )
|
||||
return false;
|
||||
|
||||
//make sure to reset the names lists since were leaving current room
|
||||
m_listUsers.ResetContent();
|
||||
char szName[256];
|
||||
|
||||
//forget which chat room we joined
|
||||
g_ircSession.GetInfo().sCurrentChatRoom = "";
|
||||
|
||||
//if we are the host kick everyone else out
|
||||
if ( g_ircSession.GetInfo().bIsGameHost )
|
||||
{
|
||||
for (int i = 0; i < m_listUsers.GetCount(); i++)
|
||||
{
|
||||
m_listUsers.GetDlgItemText(i, szName, 256);
|
||||
if (szName[0] != '@')
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//make sure to reset the names lists since were leaving current room
|
||||
m_listUsers.ResetContent();
|
||||
|
||||
//query the server for a list of chat rooms
|
||||
g_ircSession << irc::CIrcMessage(CString("list"));
|
||||
|
||||
UpdateChatMessages( pmsg );
|
||||
|
||||
//Now that we've left a game, we can allow user to create a game
|
||||
m_frameNewGame.ShowWindow(TRUE);
|
||||
m_buttonCreateGame.ShowWindow(TRUE);
|
||||
m_comboMusic.ShowWindow(TRUE);
|
||||
m_editGameName.ShowWindow(TRUE);
|
||||
m_staticGameName.ShowWindow(TRUE);
|
||||
m_staticSelectMusic.ShowWindow(TRUE);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSmlobbyDlg::OnIrc_KICK(const CIrcMessage* pmsg)
|
||||
{
|
||||
if( !pmsg->prefix.sNick.length() )
|
||||
/*if( !pmsg->prefix.sNick.length() )
|
||||
return false;
|
||||
|
||||
UpdateChatMessages( pmsg );
|
||||
UpdateChatMessages( pmsg );*/
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -485,6 +613,20 @@ bool CSmlobbyDlg::OnIrc_MODE(const CIrcMessage* pmsg)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool CSmlobbyDlg::OnIrc_QUIT(const CIrcMessage *pmsg)
|
||||
{
|
||||
//leave a game if we are currently in one
|
||||
if (g_ircSession.GetInfo().sCurrentChatRoom != "")
|
||||
{
|
||||
g_ircSession << irc::CIrcMessage(CString("part ") + CString(g_ircSession.GetInfo().sCurrentChatRoom.c_str()));
|
||||
}
|
||||
|
||||
PostQuitMessage(0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CSmlobbyDlg::OnIrc_RPL_LISTSTART(const CIrcMessage *pmsg)
|
||||
{
|
||||
//Were going to be getting a new list of rooms
|
||||
@@ -512,7 +654,7 @@ bool CSmlobbyDlg::OnIrc_RPL_TOPIC(const CIrcMessage *pmsg)
|
||||
|
||||
//Put the info for a game up in the game info box
|
||||
//msg Format: "<channel> :<topic>"
|
||||
//topic format: "GameName\nserverIP\nServerIRCName\nSongHash"
|
||||
//topic format: "GameName serverIP ServerIRCName SongHash SongPath"
|
||||
std::vector<String> vecGameParams;
|
||||
const char* p1 = pmsg->parameters[2].c_str();
|
||||
const char* p2 = p1;
|
||||
@@ -532,14 +674,54 @@ bool CSmlobbyDlg::OnIrc_RPL_TOPIC(const CIrcMessage *pmsg)
|
||||
}
|
||||
|
||||
//somehow we lost some game info
|
||||
if (vecGameParams.size() != 4) return false;
|
||||
if (vecGameParams.size() != 5) return false;
|
||||
|
||||
//Display game info
|
||||
m_editGameInfo.SetSel(-1, 0);
|
||||
m_editGameInfo.ReplaceSel(("Game Name: " + vecGameParams[0] + "\n").c_str());
|
||||
m_editGameInfo.ReplaceSel(("Server IP: " + vecGameParams[1] + "\n").c_str());
|
||||
m_editGameInfo.ReplaceSel(("Host IRC Name: " + vecGameParams[2] + "\n").c_str());
|
||||
m_editGameInfo.ReplaceSel(("Song Hash: " + vecGameParams[3] + "\n").c_str());
|
||||
m_editGameInfo.ReplaceSel(("Song: " + vecGameParams[4] + "\n").c_str());
|
||||
|
||||
//Get the hash value
|
||||
unsigned long hash;
|
||||
sscanf(vecGameParams[3].c_str(), "%ul", &hash);
|
||||
|
||||
//Remember the game info for later
|
||||
g_ircSession.SetGameInfo((m_buttonStartGame.IsWindowVisible() == TRUE) ? true: false,
|
||||
vecGameParams[4], hash, vecGameParams[2], vecGameParams[1]);
|
||||
|
||||
//See if we wanted to join a game
|
||||
if (m_bWantToJoin == true)
|
||||
{
|
||||
m_bWantToJoin = false;
|
||||
|
||||
//See if we have a song that matches that hash
|
||||
if (FindSongNameFromHash(hash) >= 0)
|
||||
{
|
||||
//Tell the server that we join this a chat room
|
||||
g_ircSession << irc::CIrcMessage(CString("join #") +
|
||||
CString(vecGameParams[0].c_str()));
|
||||
|
||||
return true;
|
||||
}
|
||||
//Otherwise ask if we want to send a song download request
|
||||
else
|
||||
{
|
||||
int ret = AfxMessageBox("I'm sorry, you don't have the song their using.\nWould you like me to send a message into that room asking\nsomeone to send you a copy so that you can join?", MB_YESNO);
|
||||
if (ret == IDYES)
|
||||
{
|
||||
String msg;
|
||||
msg = "PRIVMSG #" + vecGameParams[0] + " "
|
||||
+ g_ircSession.GetInfo().sNick
|
||||
+ " would like to join you, but they need a copy of "
|
||||
+ vecGameParams[4];
|
||||
|
||||
g_ircSession << irc::CIrcMessage(CString(msg.c_str()));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -594,6 +776,9 @@ void CSmlobbyDlg::OnDestroy()
|
||||
g_ircSession.Disconnect();
|
||||
g_ircSession.RemoveMonitor(this);
|
||||
|
||||
//Free any left over file transfer dialogs
|
||||
CSendFileDialog::FreeAnyCompletedTransfers();
|
||||
|
||||
//Close the parent application
|
||||
AfxGetApp()->ExitInstance();
|
||||
}
|
||||
@@ -634,17 +819,25 @@ void CSmlobbyDlg::UpdateChatMessages( const CIrcMessage* p )
|
||||
|
||||
void CSmlobbyDlg::OnDblclkListGames()
|
||||
{
|
||||
//make sure we're not in the room we are already trying to join
|
||||
//Get the game name that was currently selected
|
||||
int nIndex = m_listGames.GetCurSel();
|
||||
CString strGameName;
|
||||
char szGameName[128];
|
||||
int nDummy;
|
||||
|
||||
if (nIndex != LB_ERR)
|
||||
{
|
||||
m_listGames.GetText(nIndex, strGameName);
|
||||
|
||||
//Tell the server that we wanted to join a chat room
|
||||
g_ircSession << irc::CIrcMessage(CString("join ") + strGameName);
|
||||
}
|
||||
int nIndex = m_listGames.GetCurSel();
|
||||
if (nIndex == LB_ERR) return;
|
||||
|
||||
m_listGames.GetText(nIndex, szGameName);
|
||||
sscanf(szGameName, "%s (%d)", &szGameName, &nDummy);
|
||||
|
||||
if (g_ircSession.GetInfo().sCurrentChatRoom == szGameName) return;
|
||||
|
||||
//other wise, tell server we want to part this channel
|
||||
if (g_ircSession.GetInfo().sCurrentChatRoom != "")
|
||||
g_ircSession << irc::CIrcMessage(CString("part ") + CString(szGameName));
|
||||
|
||||
m_bWantToJoin = true;
|
||||
OnSelchangeListGames();
|
||||
}
|
||||
|
||||
void CSmlobbyDlg::OnSelchangeListGames()
|
||||
@@ -692,9 +885,16 @@ void CSmlobbyDlg::OnButtonCreateGame()
|
||||
return;
|
||||
}
|
||||
|
||||
//Make sure we have some songs
|
||||
if(m_comboMusic.GetCount() <= 0)
|
||||
{
|
||||
MessageBox("You don't have any songs!");
|
||||
return;
|
||||
}
|
||||
|
||||
//Make sure a song is selected
|
||||
int iIndex = m_comboMusic.GetCurSel();
|
||||
if( iIndex <= 0 )
|
||||
if( iIndex == CB_ERR )
|
||||
{
|
||||
MessageBox("Need to select a song to play!");
|
||||
return;
|
||||
@@ -718,14 +918,48 @@ void CSmlobbyDlg::OnButtonCreateGame()
|
||||
unsigned long hash = GetHashForDirectory( sSongDir );
|
||||
|
||||
//Now tell the server our game info
|
||||
CString sIrcMessage = ssprintf( "topic #%s :%s %s %s %u",
|
||||
CString sIrcMessage = ssprintf( "topic #%s :%s %s %s %u ",
|
||||
gameName,
|
||||
gameName,
|
||||
host_ip_str,
|
||||
g_ircSession.GetInfo().sNick.c_str(),
|
||||
hash );
|
||||
|
||||
//Tack on the song name
|
||||
sIrcMessage += sSongDir;
|
||||
|
||||
//make sure to clean out the values you put in the fields
|
||||
m_comboMusic.SetCurSel(-1);
|
||||
m_editGameName.SetSel(0, -1);
|
||||
m_editGameName.Clear();
|
||||
|
||||
//Make sure we can't create another game until we part this lobby
|
||||
m_frameNewGame.ShowWindow(FALSE);
|
||||
m_buttonCreateGame.ShowWindow(FALSE);
|
||||
m_comboMusic.ShowWindow(FALSE);
|
||||
m_editGameName.ShowWindow(FALSE);
|
||||
m_staticGameName.ShowWindow(FALSE);
|
||||
m_staticSelectMusic.ShowWindow(FALSE);
|
||||
|
||||
//Show the start game button
|
||||
m_buttonStartGame.ShowWindow(TRUE);
|
||||
|
||||
//Send off topic and request update now
|
||||
g_ircSession << irc::CIrcMessage(sIrcMessage);
|
||||
g_ircSession << irc::CIrcMessage(CString("topic #") + gameName);
|
||||
}
|
||||
|
||||
int CSmlobbyDlg::FindSongNameFromHash(unsigned long hash)
|
||||
{
|
||||
unsigned long comboHash;
|
||||
for (int i = 0; i < m_comboMusic.GetCount(); i++)
|
||||
{
|
||||
comboHash = m_comboMusic.GetItemData(i);
|
||||
if (hash == comboHash)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool CSmlobbyDlg::IsUniqueGameName(const CString GameName)
|
||||
@@ -780,3 +1014,50 @@ CString CSmlobbyDlg::SelectFolder()
|
||||
|
||||
return CString(szPath);
|
||||
}
|
||||
|
||||
void CSmlobbyDlg::OnButtonBeginGame()
|
||||
{
|
||||
//Create a dcc command to send to the user to which our file is going
|
||||
char szString[64];
|
||||
sprintf(szString, "PRIVMSG %s :\001DDR START", g_ircSession.GetInfo().sCurrentChatRoom.c_str());
|
||||
|
||||
//Send of the dcc command to the other party
|
||||
g_ircSession << irc::CIrcMessage(szString);
|
||||
}
|
||||
|
||||
|
||||
bool CSmlobbyDlg::WinExec(String sCmdLine)
|
||||
{
|
||||
STARTUPINFO si;
|
||||
PROCESS_INFORMATION pi;
|
||||
|
||||
memset(&si,0,sizeof(si));
|
||||
memset(&pi,0,sizeof(pi));
|
||||
si.cb = sizeof(si);
|
||||
si.wShowWindow=SW_SHOW;
|
||||
|
||||
char szCmdLine[256];
|
||||
strncpy(szCmdLine, sCmdLine.c_str(), 255);
|
||||
|
||||
int ret = CreateProcess(
|
||||
NULL, // pointer to name of executable module
|
||||
szCmdLine, // pointer to command line string
|
||||
NULL, // pointer to process security attributes
|
||||
NULL, // pointer to thread security attributes
|
||||
FALSE, // handle inheritance flag
|
||||
NULL, // creation flags
|
||||
NULL, // pointer to new environment block
|
||||
NULL, // pointer to current directory name
|
||||
&si, // pointer to STARTUPINFO
|
||||
&pi // pointer to PROCESS_INFORMATION
|
||||
);
|
||||
|
||||
if (FAILED(ret)) return false;
|
||||
else return true;
|
||||
}
|
||||
|
||||
void CSmlobbyDlg::OnRefreshGameList()
|
||||
{
|
||||
//Ask for a refresh of the games
|
||||
g_ircSession << irc::CIrcMessage("list");
|
||||
}
|
||||
|
||||
@@ -26,6 +26,11 @@ public:
|
||||
// Dialog Data
|
||||
//{{AFX_DATA(CSmlobbyDlg)
|
||||
enum { IDD = IDD_SMLOBBY_DIALOG };
|
||||
CButton m_buttonStartGame;
|
||||
CStatic m_staticGameName;
|
||||
CStatic m_staticSelectMusic;
|
||||
CButton m_frameNewGame;
|
||||
CButton m_buttonCreateGame;
|
||||
CComboBox m_comboMusic;
|
||||
CEdit m_editGameName;
|
||||
CEdit m_editGameInfo;
|
||||
@@ -44,6 +49,7 @@ public:
|
||||
// Implementation
|
||||
protected:
|
||||
HICON m_hIcon;
|
||||
bool m_bWantToJoin;
|
||||
|
||||
// Generated message map functions
|
||||
//{{AFX_MSG(CSmlobbyDlg)
|
||||
@@ -53,8 +59,10 @@ protected:
|
||||
virtual void OnPaint();
|
||||
virtual void OnDestroy();
|
||||
afx_msg void OnDblclkListGames();
|
||||
afx_msg void OnSelchangeListGames();
|
||||
afx_msg void OnButtonCreateGame();
|
||||
afx_msg void OnSelchangeListGames();
|
||||
afx_msg void OnButtonBeginGame();
|
||||
afx_msg void OnRefreshGameList();
|
||||
//}}AFX_MSG
|
||||
DECLARE_MESSAGE_MAP()
|
||||
|
||||
@@ -66,12 +74,15 @@ protected:
|
||||
bool OnIrc_PART(const CIrcMessage* pmsg);
|
||||
bool OnIrc_KICK(const CIrcMessage* pmsg);
|
||||
bool OnIrc_MODE(const CIrcMessage* pmsg);
|
||||
bool OnIrc_QUIT(const CIrcMessage *pmsg);
|
||||
bool OnIrc_RPL_LISTSTART(const CIrcMessage *pmsg);
|
||||
bool OnIrc_RPL_LIST(const CIrcMessage *pmsg);
|
||||
bool OnIrc_RPL_TOPIC(const CIrcMessage *pmsg);
|
||||
bool OnIrc_RPL_NAMREPLY(const CIrcMessage *pmsg);
|
||||
bool OnIrc_DCC_SEND(const CIrcMessage *pmsg);
|
||||
bool OnIrc_DCC_RECV(const CIrcMessage *pmsg);
|
||||
bool OnIrc_DDR_GAME_START(const CIrcMessage *pmsg);
|
||||
bool OnIrc_RPL_ENDOFMOTD(const CIrcMessage *pmsg);
|
||||
bool OnIrc_IgnoreMesg(const CIrcMessage *pmsg) { return true; }
|
||||
|
||||
virtual void OnIrcDefault(const CIrcMessage* pmsg);
|
||||
@@ -79,7 +90,9 @@ protected:
|
||||
|
||||
void UpdateChatMessages( const CIrcMessage* p );
|
||||
bool IsUniqueGameName(const CString GameName);
|
||||
int FindSongNameFromHash(unsigned long hash);
|
||||
CString SelectFolder();
|
||||
bool WinExec(String sCmdLine);
|
||||
};
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
|
||||
@@ -106,7 +106,16 @@ bool Socket::Listen()
|
||||
|
||||
Socket Socket::Accept()
|
||||
{
|
||||
return Socket(SDLNet_TCP_Accept(m_sock));
|
||||
const int kMaxRetry = 10;
|
||||
TCPsocket new_sock;
|
||||
|
||||
for (int i = 0; i < kMaxRetry; i++)
|
||||
{
|
||||
new_sock = SDLNet_TCP_Accept(m_sock);
|
||||
if ( new_sock ) break;
|
||||
}
|
||||
|
||||
return Socket(new_sock);
|
||||
}
|
||||
|
||||
int Socket::Send(const unsigned char* buf, int cbBuf)
|
||||
|
||||
Reference in New Issue
Block a user