Rewrote DCC server to allow for multiple threads, also added DCC recv.
(DCC recv still broken, threading buggy)
This commit is contained in:
@@ -32,7 +32,7 @@ CSendFileDialog::CSendFileDialog(CWnd* pParent /*=NULL*/)
|
|||||||
m_ToFrom = _T("");
|
m_ToFrom = _T("");
|
||||||
//}}AFX_DATA_INIT
|
//}}AFX_DATA_INIT
|
||||||
|
|
||||||
m_pDCCServer = NULL;
|
m_bIsCanceled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -65,13 +65,8 @@ END_MESSAGE_MAP()
|
|||||||
|
|
||||||
void CSendFileDialog::OnCancel()
|
void CSendFileDialog::OnCancel()
|
||||||
{
|
{
|
||||||
//Tell the DCC Server to abort as the file isn't transfering
|
//Thread is going to check up on us to see if it's time to bail
|
||||||
// or the user has beome impatient :)
|
m_bIsCanceled = true;
|
||||||
if (m_pDCCServer)
|
|
||||||
{
|
|
||||||
CIrcDCCServer* pServer = (CIrcDCCServer *)m_pDCCServer;
|
|
||||||
pServer->Stop(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
CDialog::OnCancel();
|
CDialog::OnCancel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,10 +44,10 @@ public:
|
|||||||
|
|
||||||
// Implementation
|
// Implementation
|
||||||
public:
|
public:
|
||||||
void AssignDCCServer(void* pServer) { m_pDCCServer = pServer; }
|
bool isCanceled() { return m_bIsCanceled; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void* m_pDCCServer;
|
bool m_bIsCanceled;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
|||||||
+356
-176
@@ -469,231 +469,267 @@ DWORD WINAPI CIrcIdentServer::ListenProc(LPVOID pparam)
|
|||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
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;
|
||||||
|
|
||||||
CIrcDCCServer::CIrcDCCServer()
|
////////////////////////////////////////////////////////////////////
|
||||||
: m_uiPort(0), m_hThread(NULL), m_bIsSender(false),
|
|
||||||
m_ulPartnerIP(0L), m_ulFileSize(0L),
|
|
||||||
m_pSendFileDialog(NULL), m_ulStartTime(0L),
|
|
||||||
m_ulBytesSent(0L), m_uiXferRate(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CIrcDCCServer::~CIrcDCCServer()
|
CIrcDCCServer::~CIrcDCCServer()
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CIrcDCCServer::Start(
|
unsigned short CIrcDCCServer::MakePortReservation()
|
||||||
const CString fileName,
|
|
||||||
const CString directory,
|
|
||||||
const CString partner,
|
|
||||||
unsigned long ulPartnerIP,
|
|
||||||
unsigned short uiPort,
|
|
||||||
unsigned long ulFileSize,
|
|
||||||
unsigned short uiXferRate,
|
|
||||||
const bool bIsSender
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
//Clean up old send file dialog
|
//Assume the first port number is open
|
||||||
if (m_pSendFileDialog)
|
unsigned short uiPort = kFirstPort;
|
||||||
{
|
|
||||||
delete m_pSendFileDialog;
|
|
||||||
m_pSendFileDialog = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( m_socket )
|
//if there are no used ports in the list use the first one
|
||||||
return false;
|
if (m_usedPorts.size() <= 0)
|
||||||
|
m_usedPorts.push_back(kFirstPort);
|
||||||
|
|
||||||
//Setup the connection info vars
|
//next see if the port range is saturated (pigeon hole principal)
|
||||||
m_fileName = fileName;
|
else if ((*m_usedPorts.end() - kFirstPort + 1) >= m_usedPorts.size())
|
||||||
m_directory = directory;
|
m_usedPorts.push_back(*m_usedPorts.end() + 1);
|
||||||
m_partnerName = partner;
|
|
||||||
m_ulPartnerIP = ulPartnerIP;
|
|
||||||
m_uiPort = uiPort;
|
|
||||||
m_ulFileSize = ulFileSize;
|
|
||||||
m_bIsSender = bIsSender;
|
|
||||||
m_ulBytesSent = 0L;
|
|
||||||
m_uiXferRate = uiXferRate;
|
|
||||||
|
|
||||||
//Remember when we started
|
//there must be a find a gap in the used port list
|
||||||
m_ulStartTime = GetTickCount();
|
//since the list is always sorted
|
||||||
|
|
||||||
//Create a file transfer dialog
|
|
||||||
m_pSendFileDialog = new CSendFileDialog(AfxGetMainWnd());
|
|
||||||
if ( !m_pSendFileDialog->Create(IDD_FILEXFER, AfxGetMainWnd()) )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
m_pSendFileDialog->m_BytesSent = "0 bytes";
|
|
||||||
m_pSendFileDialog->m_ProgressFile.SetRange(0, 100);
|
|
||||||
m_pSendFileDialog->m_ProgressFile.SetPos(0);
|
|
||||||
sprintf(m_pSendFileDialog->m_Filesize.GetBuffer(32), "%lu bytes", m_ulFileSize);
|
|
||||||
m_pSendFileDialog->m_FolderName = m_directory;
|
|
||||||
m_pSendFileDialog->m_FileName = m_fileName;
|
|
||||||
m_pSendFileDialog->m_RecvrName = m_partnerName;
|
|
||||||
m_pSendFileDialog->m_TimeLeft = "Infinite";
|
|
||||||
m_pSendFileDialog->m_XferRate = "0 bytes/sec";
|
|
||||||
m_pSendFileDialog->m_XferStatus = "Waiting to Connect...";
|
|
||||||
|
|
||||||
//Some fields in the
|
|
||||||
if (m_bIsSender)
|
|
||||||
{
|
|
||||||
m_pSendFileDialog->m_SentRecvd = "Sent:";
|
|
||||||
m_pSendFileDialog->m_ToFrom = "To:";
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_pSendFileDialog->m_SentRecvd = "Recv'd:";
|
std::vector<unsigned short>::iterator iter;
|
||||||
m_pSendFileDialog->m_ToFrom = "From:";
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
//Show the dialog and tell it about this server
|
//Insert our port number into the gap we just found
|
||||||
m_pSendFileDialog->AssignDCCServer(this);
|
m_usedPorts.insert(iter, uiPort);
|
||||||
m_pSendFileDialog->ShowWindow(SW_SHOW);
|
}
|
||||||
|
|
||||||
//Fire off the thread
|
return uiPort;
|
||||||
m_hThread = CreateThread(NULL, 0, ListenProc, this, 0, NULL);
|
}
|
||||||
Sleep(100);
|
|
||||||
|
void CIrcDCCServer::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 CIrcDCCServer::FreeThread(HANDLE pThread)
|
||||||
|
{
|
||||||
|
//If thread list is empty, bail
|
||||||
|
if (m_hThread.size() <= 0) return;
|
||||||
|
|
||||||
|
//Tell thread ptr list that this thread is done
|
||||||
|
std::vector<HANDLE>::iterator iter;
|
||||||
|
for (iter = m_hThread.begin(); iter < m_hThread.end(); iter++)
|
||||||
|
{
|
||||||
|
//is this the the thread were looking for?
|
||||||
|
if ( *iter == pThread )
|
||||||
|
{
|
||||||
|
//Now we can forget about the thread
|
||||||
|
CloseHandle(*iter);
|
||||||
|
m_hThread.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CIrcDCCServer::Start(DCCTransferInfo dccinfo)
|
||||||
|
{
|
||||||
|
//Make sure we have a port reservation made if were hosting a file
|
||||||
|
if (dccinfo.m_bIsSender && dccinfo.m_uiPort < kFirstPort)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Remember when we started and who spawned us
|
||||||
|
dccinfo.m_ulStartTime = GetTickCount();
|
||||||
|
dccinfo.m_pDCCSever = this;
|
||||||
|
|
||||||
|
//Create the appropriate thread, but don't start it just yet
|
||||||
|
/*if (dccinfo.m_bIsSender)
|
||||||
|
dccinfo.m_pThread = CreateThread(NULL, 0, DoThreadSend, (void *)&dccinfo,
|
||||||
|
CREATE_SUSPENDED, NULL);
|
||||||
|
else
|
||||||
|
dccinfo.m_pThread = CreateThread(NULL, 0, DoThreadRecv, (void *)&dccinfo,
|
||||||
|
CREATE_SUSPENDED, NULL);
|
||||||
|
|
||||||
|
//Rememeber who what threads we spawned
|
||||||
|
m_hThread.push_back(dccinfo.m_pThread);
|
||||||
|
|
||||||
|
//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);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIrcDCCServer::Stop(DWORD timeout)
|
void CIrcDCCServer::Stop(DWORD timeout, HANDLE hThread)
|
||||||
{
|
{
|
||||||
if( m_hThread )
|
//make sure we have a threads running
|
||||||
|
if (m_hThread.size() <= 0) return;
|
||||||
|
|
||||||
|
//Generate an iterator for the thread list
|
||||||
|
std::vector<HANDLE>::iterator iter;
|
||||||
|
|
||||||
|
//if the thread specified is NULL, kill all of the threads in the list
|
||||||
|
if (hThread == NULL)
|
||||||
{
|
{
|
||||||
m_socket.Close();
|
//Start at the beginning
|
||||||
if( WaitForSingleObject(m_hThread, timeout) != WAIT_OBJECT_0 && m_hThread )
|
iter = m_hThread.begin();
|
||||||
|
while(m_hThread.size() > 0)
|
||||||
{
|
{
|
||||||
TerminateThread(m_hThread, 1);
|
//wait for each thread to finish
|
||||||
CloseHandle(m_hThread);
|
if( *iter && WaitForSingleObject(*iter, timeout) != WAIT_OBJECT_0 )
|
||||||
m_hThread = NULL;
|
{
|
||||||
|
TerminateThread(*iter, 1);
|
||||||
|
CloseHandle(*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
//now we can forget about the thread
|
||||||
|
iter = m_hThread.erase(iter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//otherwise, find all a specific thread to close
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (iter = m_hThread.begin(); iter < m_hThread.end(); iter++)
|
||||||
|
{
|
||||||
|
//is this the the thread were looking for?
|
||||||
|
if ( *iter == hThread )
|
||||||
|
{
|
||||||
|
//wait for each thread to finish
|
||||||
|
if( *iter && WaitForSingleObject(*iter, timeout) != WAIT_OBJECT_0 )
|
||||||
|
{
|
||||||
|
TerminateThread(*iter, 1);
|
||||||
|
CloseHandle(*iter);
|
||||||
|
}
|
||||||
|
|
||||||
|
//now we can forget about the thread
|
||||||
|
m_hThread.erase(iter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CIrcDCCServer::DoThreadRecv()
|
DWORD WINAPI CIrcDCCServer::DoThreadRecv(void* dccInfo)
|
||||||
{
|
{
|
||||||
char szBuf[8193];
|
char szBuf[8193];
|
||||||
unsigned long cbRead, cbSent;
|
unsigned long cbRead, cbSent, replyTotal;
|
||||||
float fracSent;
|
float fracSent;
|
||||||
unsigned long seconds, minutes, hours, rate;
|
unsigned long seconds, minutes, hours, rate;
|
||||||
|
|
||||||
|
//Make a local copy of the dcc info
|
||||||
|
DCCTransferInfo info = *((DCCTransferInfo*)dccInfo);
|
||||||
|
|
||||||
|
//Create a file transfer dialog
|
||||||
|
CSendFileDialog* pSendFileDialog = new CSendFileDialog(NULL);
|
||||||
|
CWnd* pParent= pSendFileDialog->FromHandle( AfxGetMainWnd()->m_hWnd );
|
||||||
|
if (!pParent || !pSendFileDialog || !pSendFileDialog->Create(IDD_FILEXFER, pParent) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Setup the status info on the dialog
|
||||||
|
pSendFileDialog->m_BytesSent = "0 bytes";
|
||||||
|
pSendFileDialog->m_ProgressFile.SetRange(0, 100);
|
||||||
|
pSendFileDialog->m_ProgressFile.SetPos(0);
|
||||||
|
pSendFileDialog->m_FolderName = info.m_directory;
|
||||||
|
pSendFileDialog->m_FileName = info.m_fileName;
|
||||||
|
pSendFileDialog->m_RecvrName = info.m_partnerName;
|
||||||
|
pSendFileDialog->m_TimeLeft = "Infinite";
|
||||||
|
pSendFileDialog->m_XferRate = "0 bytes/sec";
|
||||||
|
pSendFileDialog->m_XferStatus = "Waiting to Connect...";
|
||||||
|
pSendFileDialog->m_SentRecvd = "Recv'd:";
|
||||||
|
pSendFileDialog->m_ToFrom = "From:";
|
||||||
|
sprintf(pSendFileDialog->m_Filesize.GetBuffer(32), "%lu bytes",
|
||||||
|
info.m_ulFileSize);
|
||||||
|
|
||||||
|
//Show the dialog and tell it about this server
|
||||||
|
pSendFileDialog->ShowWindow(SW_SHOW);
|
||||||
|
|
||||||
//Create an active socket to retrieve data from (close listening socket)
|
//Create an active socket to retrieve data from (close listening socket)
|
||||||
InetAddr addr;
|
InetAddr addr;
|
||||||
addr.host = m_ulPartnerIP;
|
Socket sock;
|
||||||
addr.port = m_uiPort;
|
addr.host = htonl(info.m_ulPartnerIP);
|
||||||
m_socket.Connect(addr);
|
addr.port = htons(info.m_uiPort);
|
||||||
if ( !m_socket ) return;
|
sock.Connect(addr);
|
||||||
|
|
||||||
|
//bail if we can't open the socket
|
||||||
|
if ( !sock )
|
||||||
|
{
|
||||||
|
pSendFileDialog->ShowWindow(SW_HIDE);
|
||||||
|
delete pSendFileDialog;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//Tell user file transfer has started
|
//Tell user file transfer has started
|
||||||
m_pSendFileDialog->m_XferStatus = "Recieving File...";
|
pSendFileDialog->m_XferStatus = "Recieving File...";
|
||||||
|
|
||||||
//Create a file to write incoming data to
|
//Create a file to write incoming data to
|
||||||
CString filename = m_directory+m_fileName;
|
CString filename = info.m_directory+info.m_fileName;
|
||||||
FILE* fp = fopen(filename, "wb");
|
FILE* fp = fopen(filename, "wb");
|
||||||
if ( !fp ) return;
|
|
||||||
|
//bail if we can't open the file
|
||||||
|
if ( !sock )
|
||||||
|
{
|
||||||
|
pSendFileDialog->ShowWindow(SW_HIDE);
|
||||||
|
delete pSendFileDialog;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
//Start grabbing data blocks
|
//Start grabbing data blocks
|
||||||
while(m_ulBytesSent < m_ulFileSize)
|
while(info.m_ulBytesSent < info.m_ulFileSize && !pSendFileDialog->isCanceled())
|
||||||
{
|
{
|
||||||
//Grab the next buffer
|
//Grab the next buffer
|
||||||
cbRead = m_socket.Receive((unsigned char*)szBuf, sizeof(szBuf)-1);
|
cbRead = sock.Receive((unsigned char*)szBuf, sizeof(szBuf)-1);
|
||||||
|
|
||||||
if( cbRead <= 0 ) continue;
|
if( cbRead <= 0 ) continue;
|
||||||
else szBuf[cbRead] = '\0';
|
else szBuf[cbRead] = '\0';
|
||||||
|
|
||||||
//Update the file transfer statistics
|
|
||||||
m_ulBytesSent += cbRead;
|
|
||||||
fracSent = float(m_ulBytesSent)/float(m_ulFileSize);
|
|
||||||
seconds = (GetTickCount() - m_ulStartTime)/1000;
|
|
||||||
rate = m_ulBytesSent / seconds;
|
|
||||||
seconds = (unsigned long)(float(seconds)/fracSent);
|
|
||||||
minutes = (seconds/60) % 60;
|
|
||||||
hours = (seconds/3600);
|
|
||||||
seconds = seconds % 60;
|
|
||||||
|
|
||||||
//Update the file transfer window
|
|
||||||
sprintf(m_pSendFileDialog->m_BytesSent.GetBuffer(64), "%lu bytes", m_ulBytesSent);
|
|
||||||
sprintf(m_pSendFileDialog->m_TimeLeft.GetBuffer(32), "%luh%lum%lus",
|
|
||||||
hours, minutes, seconds);
|
|
||||||
sprintf(m_pSendFileDialog->m_XferRate.GetBuffer(64), "%lubytes/sec", rate);
|
|
||||||
m_pSendFileDialog->m_ProgressFile.SetPos(int(fracSent*100.F));
|
|
||||||
|
|
||||||
//Write it to file
|
//Write it to file
|
||||||
fwrite(szBuf, cbRead, 1, fp);
|
fwrite(szBuf, cbRead, 1, fp);
|
||||||
|
|
||||||
//Tell the sender how many bytes we received
|
//update byte count
|
||||||
cbRead = htonl(cbRead);
|
info.m_ulBytesSent += cbRead;
|
||||||
cbSent = 0;
|
|
||||||
while ( cbSent <= 0 )
|
|
||||||
cbSent = m_socket.Send((unsigned char *)&cbRead, 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Close our data transfer socket
|
//Update the file transfer statistics
|
||||||
m_socket.Close();
|
fracSent = float(info.m_ulBytesSent)/float(info.m_ulFileSize);
|
||||||
|
seconds = (GetTickCount() - info.m_ulStartTime)/1000;
|
||||||
//Close our file
|
rate = (seconds > 0) ? info.m_ulBytesSent / seconds : 0;
|
||||||
fclose(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
void CIrcDCCServer::DoThreadSend()
|
|
||||||
{
|
|
||||||
char szBuf[8193];
|
|
||||||
unsigned long cbSend, cbRead, numAck;
|
|
||||||
float fracSent;
|
|
||||||
unsigned long seconds, minutes, hours, rate;
|
|
||||||
|
|
||||||
//Wait for someone to connect to us
|
|
||||||
//on a pre-arranged port
|
|
||||||
m_socket.Bind(InetAddr(m_uiPort));
|
|
||||||
m_socket.Listen();
|
|
||||||
|
|
||||||
//Create an active socket to write data from (close listening socket)
|
|
||||||
Socket sock = m_socket.Accept();
|
|
||||||
if ( !sock ) return;
|
|
||||||
m_socket.Close();
|
|
||||||
|
|
||||||
//Tell user file transfer has started
|
|
||||||
m_pSendFileDialog->m_XferStatus = "Sending File...";
|
|
||||||
|
|
||||||
//Create a file to read incoming data from
|
|
||||||
CString filename = m_directory+"\\"+m_fileName;
|
|
||||||
FILE* fp = fopen(filename, "rb");
|
|
||||||
if ( !fp ) return;
|
|
||||||
|
|
||||||
|
|
||||||
//Start grapping data blocks
|
|
||||||
while( m_ulBytesSent < m_ulFileSize )
|
|
||||||
{
|
|
||||||
//Pull a data block from the file
|
|
||||||
fread(szBuf, m_uiXferRate, 1, fp);
|
|
||||||
|
|
||||||
//Send the next chunk out
|
|
||||||
cbSend = 0;
|
|
||||||
while (cbSend <= 0)
|
|
||||||
cbSend = sock.Send((unsigned char *)szBuf, m_uiXferRate);
|
|
||||||
|
|
||||||
//Make sure chunk gets acknowledged
|
|
||||||
cbRead = 0;
|
|
||||||
while( cbRead <= 0)
|
|
||||||
cbRead = m_socket.Receive((unsigned char*)&numAck, 4);
|
|
||||||
|
|
||||||
//Update that statistics
|
|
||||||
m_ulBytesSent += ntohl(numAck);
|
|
||||||
fracSent = float(m_ulBytesSent)/float(m_ulFileSize);
|
|
||||||
seconds = (GetTickCount() - m_ulStartTime)/1000;
|
|
||||||
rate = m_ulBytesSent / seconds;
|
|
||||||
seconds = (unsigned long)(float(seconds)/fracSent);
|
seconds = (unsigned long)(float(seconds)/fracSent);
|
||||||
minutes = (seconds/60) % 60;
|
minutes = (seconds/60) % 60;
|
||||||
hours = (seconds/3600);
|
hours = (seconds/3600);
|
||||||
seconds = seconds % 60;
|
seconds = seconds % 60;
|
||||||
|
|
||||||
//Update the file transfer window
|
//Update the file transfer window
|
||||||
sprintf(m_pSendFileDialog->m_BytesSent.GetBuffer(64), "%lu bytes", m_ulBytesSent);
|
sprintf(pSendFileDialog->m_BytesSent.GetBuffer(64), "%lu bytes",
|
||||||
sprintf(m_pSendFileDialog->m_TimeLeft.GetBuffer(32), "%luh%lum%lus",
|
info.m_ulBytesSent);
|
||||||
|
sprintf(pSendFileDialog->m_TimeLeft.GetBuffer(32), "%luh%lum%lus",
|
||||||
hours, minutes, seconds);
|
hours, minutes, seconds);
|
||||||
sprintf(m_pSendFileDialog->m_XferRate.GetBuffer(64), "%lubytes/sec", rate);
|
sprintf(pSendFileDialog->m_XferRate.GetBuffer(64), "%lubytes/sec", rate);
|
||||||
m_pSendFileDialog->m_ProgressFile.SetPos(int(fracSent*100.F));
|
pSendFileDialog->m_ProgressFile.SetPos(int(fracSent*100.F));
|
||||||
|
|
||||||
|
//Tell the sender how many bytes we received
|
||||||
|
replyTotal = htonl(info.m_ulBytesSent);
|
||||||
|
|
||||||
|
//Send out response
|
||||||
|
cbSent = sock.Send((unsigned char *)&replyTotal, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Close our data transfer socket
|
//Close our data transfer socket
|
||||||
@@ -701,19 +737,163 @@ void CIrcDCCServer::DoThreadSend()
|
|||||||
|
|
||||||
//Close our file
|
//Close our file
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
|
||||||
|
//Clean up file dialog
|
||||||
|
pSendFileDialog->ShowWindow(SW_HIDE);
|
||||||
|
delete pSendFileDialog;
|
||||||
|
|
||||||
|
//Free this thread from the system
|
||||||
|
if (info.m_pDCCSever)
|
||||||
|
info.m_pDCCSever->FreeThread(info.m_pThread);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD WINAPI CIrcDCCServer::ListenProc(LPVOID pparam)
|
DWORD WINAPI CIrcDCCServer::DoThreadSend(void* dccInfo)
|
||||||
{
|
{
|
||||||
CIrcDCCServer* pThis = (CIrcDCCServer*)pparam;
|
char szBuf[8193];
|
||||||
|
unsigned long cbSend, cbRead, numAck;
|
||||||
|
float fracSent;
|
||||||
|
unsigned long seconds, minutes, hours, rate;
|
||||||
|
const k_ulTimeout = 10000; //30 second timeout
|
||||||
|
|
||||||
if (pThis->IsSender())
|
//Make a local copy of the dcc info
|
||||||
try { pThis->DoThreadSend(); } catch( ... ) {}
|
DCCTransferInfo info = *((DCCTransferInfo*)dccInfo);
|
||||||
else
|
|
||||||
try { pThis->DoThreadRecv(); } catch( ... ) {}
|
|
||||||
|
|
||||||
CloseHandle(pThis->m_hThread);
|
//Create a file transfer dialog
|
||||||
pThis->m_hThread = NULL;
|
CSendFileDialog* pSendFileDialog = new CSendFileDialog(NULL);
|
||||||
|
ASSERT (pSendFileDialog);
|
||||||
|
|
||||||
|
CWnd* pParent= pSendFileDialog->FromHandle( AfxGetMainWnd()->m_hWnd );
|
||||||
|
ASSERT (pParent);
|
||||||
|
|
||||||
|
ASSERT (pSendFileDialog->Create(IDD_FILEXFER, pParent) == TRUE);
|
||||||
|
//if (!pParent || !pSendFileDialog || !pSendFileDialog->Create(IDD_FILEXFER, pParent) )
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
//Setup the status info on the dialog
|
||||||
|
pSendFileDialog->m_BytesSent = "0 bytes";
|
||||||
|
pSendFileDialog->m_ProgressFile.SetRange(0, 100);
|
||||||
|
pSendFileDialog->m_ProgressFile.SetPos(0);
|
||||||
|
pSendFileDialog->m_FolderName = info.m_directory;
|
||||||
|
pSendFileDialog->m_FileName = info.m_fileName;
|
||||||
|
pSendFileDialog->m_RecvrName = info.m_partnerName;
|
||||||
|
pSendFileDialog->m_TimeLeft = "Infinite";
|
||||||
|
pSendFileDialog->m_XferRate = "0 bytes/sec";
|
||||||
|
pSendFileDialog->m_XferStatus = "Waiting to Connect...";
|
||||||
|
pSendFileDialog->m_SentRecvd = "Sent:";
|
||||||
|
pSendFileDialog->m_ToFrom = "To:";
|
||||||
|
sprintf(pSendFileDialog->m_Filesize.GetBuffer(32), "%lu bytes",
|
||||||
|
info.m_ulFileSize);
|
||||||
|
|
||||||
|
//Show the dialog and tell it about this server
|
||||||
|
pSendFileDialog->ShowWindow(SW_SHOW);
|
||||||
|
|
||||||
|
//Wait for someone to connect to us
|
||||||
|
//on a pre-arranged port
|
||||||
|
Socket sockListen;
|
||||||
|
sockListen.Bind(InetAddr(INADDR_ANY, htons(info.m_uiPort)));
|
||||||
|
if (!sockListen.Listen())
|
||||||
|
{
|
||||||
|
pSendFileDialog->ShowWindow(SW_HIDE);
|
||||||
|
delete pSendFileDialog;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Wait for partner to connect to us
|
||||||
|
Socket sock;
|
||||||
|
while(!sock && (GetTickCount() - info.m_ulStartTime) < k_ulTimeout)
|
||||||
|
sock = sockListen.Accept();
|
||||||
|
|
||||||
|
//Make sure socket is valid (we didn't timeout)
|
||||||
|
if ( !sock )
|
||||||
|
{
|
||||||
|
pSendFileDialog->ShowWindow(SW_HIDE);
|
||||||
|
delete pSendFileDialog;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Close the socket we were listening on
|
||||||
|
sockListen.Close();
|
||||||
|
|
||||||
|
//Tell user file transfer has started
|
||||||
|
pSendFileDialog->m_XferStatus = "Sending File...";
|
||||||
|
|
||||||
|
//Create a file to read incoming data from
|
||||||
|
CString filename = info.m_directory+info.m_fileName;
|
||||||
|
FILE* fp = fopen(filename, "rb");
|
||||||
|
ASSERT( fp != NULL );
|
||||||
|
if ( !fp )
|
||||||
|
{
|
||||||
|
pSendFileDialog->ShowWindow(SW_HIDE);
|
||||||
|
delete pSendFileDialog;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Start grabbing data blocks
|
||||||
|
while( info.m_ulBytesSent < info.m_ulFileSize && !pSendFileDialog->isCanceled() )
|
||||||
|
{
|
||||||
|
//Pull a data block from the file
|
||||||
|
cbRead = fread(szBuf, info.m_uiXferRate, 1, fp);
|
||||||
|
|
||||||
|
//Send the next chunk out
|
||||||
|
cbSend = 0;
|
||||||
|
while (cbSend <= 0)
|
||||||
|
cbSend = sock.Send((unsigned char *)szBuf, cbRead);
|
||||||
|
|
||||||
|
//Update sent byte count
|
||||||
|
info.m_ulBytesSent += cbSend;
|
||||||
|
|
||||||
|
//Make sure chunk gets acknowledged
|
||||||
|
cbRead = 0;
|
||||||
|
while( cbRead <= 0)
|
||||||
|
cbRead = sock.Receive((unsigned char*)&numAck, 4);
|
||||||
|
|
||||||
|
//Make sure numAck matches current amount of data seny
|
||||||
|
//Update that statistics
|
||||||
|
if (info.m_ulBytesSent != ntohl(numAck))
|
||||||
|
{
|
||||||
|
pSendFileDialog->ShowWindow(SW_HIDE);
|
||||||
|
delete pSendFileDialog;
|
||||||
|
sock.Close();
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fracSent = float(info.m_ulBytesSent)/float(info.m_ulFileSize);
|
||||||
|
seconds = (GetTickCount() - info.m_ulStartTime)/1000;
|
||||||
|
rate = info.m_ulBytesSent / seconds;
|
||||||
|
seconds = (unsigned long)(float(seconds)/fracSent);
|
||||||
|
minutes = (seconds/60) % 60;
|
||||||
|
hours = (seconds/3600);
|
||||||
|
seconds = seconds % 60;
|
||||||
|
|
||||||
|
//Update the file transfer window
|
||||||
|
sprintf(pSendFileDialog->m_BytesSent.GetBuffer(64), "%lu bytes",
|
||||||
|
info.m_ulBytesSent);
|
||||||
|
sprintf(pSendFileDialog->m_TimeLeft.GetBuffer(32), "%luh%lum%lus",
|
||||||
|
hours, minutes, seconds);
|
||||||
|
sprintf(pSendFileDialog->m_XferRate.GetBuffer(64), "%lubytes/sec", rate);
|
||||||
|
pSendFileDialog->m_ProgressFile.SetPos(int(fracSent*100.F));
|
||||||
|
}
|
||||||
|
|
||||||
|
//Close our data transfer socket
|
||||||
|
sock.Close();
|
||||||
|
|
||||||
|
//Close our file
|
||||||
|
fclose(fp);
|
||||||
|
|
||||||
|
//Clean up file dialog
|
||||||
|
pSendFileDialog->ShowWindow(SW_HIDE);
|
||||||
|
delete pSendFileDialog;
|
||||||
|
|
||||||
|
//Free this thread and port from the system
|
||||||
|
if (info.m_pDCCSever)
|
||||||
|
{
|
||||||
|
info.m_pDCCSever->FreeThread(info.m_pThread);
|
||||||
|
info.m_pDCCSever->FreePort(info.m_uiPort);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+37
-27
@@ -168,26 +168,9 @@ private :
|
|||||||
|
|
||||||
class CIrcDCCServer
|
class CIrcDCCServer
|
||||||
{
|
{
|
||||||
public :
|
public:
|
||||||
CIrcDCCServer();
|
struct DCCTransferInfo
|
||||||
virtual ~CIrcDCCServer();
|
{
|
||||||
|
|
||||||
bool Start(
|
|
||||||
const CString fileName,
|
|
||||||
const CString directory,
|
|
||||||
const CString partner,
|
|
||||||
unsigned long ulPartnerIP,
|
|
||||||
unsigned short uiPort,
|
|
||||||
unsigned long ulFileSize,
|
|
||||||
unsigned short uiXferRate,
|
|
||||||
const bool bIsSender = false
|
|
||||||
);
|
|
||||||
|
|
||||||
void Stop(DWORD timeout = 5000L);
|
|
||||||
|
|
||||||
bool IsSender() { return m_bIsSender; }
|
|
||||||
|
|
||||||
protected :
|
|
||||||
bool m_bIsSender;
|
bool m_bIsSender;
|
||||||
CString m_fileName;
|
CString m_fileName;
|
||||||
CString m_directory;
|
CString m_directory;
|
||||||
@@ -198,16 +181,43 @@ protected :
|
|||||||
unsigned long m_ulBytesSent;
|
unsigned long m_ulBytesSent;
|
||||||
unsigned long m_ulStartTime;
|
unsigned long m_ulStartTime;
|
||||||
unsigned int m_uiXferRate;
|
unsigned int m_uiXferRate;
|
||||||
CSendFileDialog* m_pSendFileDialog;
|
CIrcDCCServer* m_pDCCSever;
|
||||||
|
HANDLE m_pThread;
|
||||||
|
|
||||||
void DoThreadSend();
|
DCCTransferInfo() :
|
||||||
void DoThreadRecv();
|
m_bIsSender(false),
|
||||||
|
m_ulPartnerIP(0L),
|
||||||
|
m_uiPort(0),
|
||||||
|
m_ulFileSize(0L),
|
||||||
|
m_ulBytesSent(0L),
|
||||||
|
m_ulStartTime(0L),
|
||||||
|
m_uiXferRate(0),
|
||||||
|
m_pDCCSever(NULL),
|
||||||
|
m_pThread(NULL)
|
||||||
|
{}
|
||||||
|
};
|
||||||
|
|
||||||
private :
|
public :
|
||||||
Socket m_socket;
|
virtual ~CIrcDCCServer();
|
||||||
HANDLE m_hThread;
|
|
||||||
|
|
||||||
static DWORD WINAPI ListenProc(LPVOID pparam);
|
bool Start(DCCTransferInfo dccinfo);
|
||||||
|
void Stop(DWORD timeout = 0, HANDLE hThread = NULL);
|
||||||
|
|
||||||
|
unsigned short MakePortReservation();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void FreePort(unsigned short port);
|
||||||
|
void FreeThread(HANDLE pThread);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static std::vector<HANDLE> m_hThread;
|
||||||
|
static std::vector<unsigned short> m_usedPorts;
|
||||||
|
|
||||||
|
static const unsigned short kFirstPort;
|
||||||
|
static const unsigned short kLastPort;
|
||||||
|
|
||||||
|
static DWORD WINAPI DoThreadSend(void* dccinfo);
|
||||||
|
static DWORD WINAPI DoThreadRecv(void* dccinfo);
|
||||||
};
|
};
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
Binary file not shown.
+1001
-20
File diff suppressed because it is too large
Load Diff
@@ -68,7 +68,7 @@ LINK32=link.exe
|
|||||||
# PROP Ignore_Export_Lib 0
|
# PROP Ignore_Export_Lib 0
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
|
# ADD BASE CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||||
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FD /GZ /c
|
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_MBCS" /FR /FD /GZ /c
|
||||||
# SUBTRACT CPP /YX /Yc /Yu
|
# SUBTRACT CPP /YX /Yc /Yu
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -88,7 +88,7 @@ IDD_SMLOBBY_DIALOG DIALOGEX 0, 0, 464, 330
|
|||||||
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_APPWINDOW
|
EXSTYLE WS_EX_APPWINDOW
|
||||||
CAPTION "StepMania Lobby"
|
CAPTION "StepMania Lobby"
|
||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif", 0, 0, 0x1
|
||||||
BEGIN
|
BEGIN
|
||||||
EDITTEXT IDC_EDIT_ENTRY,105,281,347,12,ES_AUTOHSCROLL
|
EDITTEXT IDC_EDIT_ENTRY,105,281,347,12,ES_AUTOHSCROLL
|
||||||
GROUPBOX "Chat",IDC_STATIC,5,140,453,160
|
GROUPBOX "Chat",IDC_STATIC,5,140,453,160
|
||||||
@@ -117,7 +117,6 @@ CAPTION "File Transfer"
|
|||||||
FONT 8, "MS Sans Serif"
|
FONT 8, "MS Sans Serif"
|
||||||
BEGIN
|
BEGIN
|
||||||
PUSHBUTTON "Cancel",IDCANCEL,129,152,50,14
|
PUSHBUTTON "Cancel",IDCANCEL,129,152,50,14
|
||||||
LTEXT "Sending File",IDC_STATIC,7,7,41,9
|
|
||||||
LTEXT "File:",IDC_STATIC,7,21,33,8
|
LTEXT "File:",IDC_STATIC,7,21,33,8
|
||||||
LTEXT "Size:",IDC_STATIC,7,30,33,8
|
LTEXT "Size:",IDC_STATIC,7,30,33,8
|
||||||
LTEXT "Folder:",IDC_STATIC,7,40,33,8
|
LTEXT "Folder:",IDC_STATIC,7,40,33,8
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ static const NetworkInit g_wsInit;
|
|||||||
static const unsigned short FILE_XFER_RATE = 4096;
|
static const unsigned short FILE_XFER_RATE = 4096;
|
||||||
|
|
||||||
irc::CIrcSession g_ircSession;
|
irc::CIrcSession g_ircSession;
|
||||||
|
irc::CIrcDCCServer g_DCCServer;
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
@@ -148,6 +149,7 @@ BOOL CSmlobbyDlg::OnInitDialog()
|
|||||||
IRC_MAP_ENTRY(CSmlobbyDlg, "NICK", OnIrc_NICK)
|
IRC_MAP_ENTRY(CSmlobbyDlg, "NICK", OnIrc_NICK)
|
||||||
IRC_MAP_ENTRY(CSmlobbyDlg, "PART", OnIrc_PART)
|
IRC_MAP_ENTRY(CSmlobbyDlg, "PART", OnIrc_PART)
|
||||||
IRC_MAP_ENTRY(CSmlobbyDlg, "PRIVMSG", OnIrc_PRIVMSG)
|
IRC_MAP_ENTRY(CSmlobbyDlg, "PRIVMSG", OnIrc_PRIVMSG)
|
||||||
|
IRC_MAP_ENTRY(CSmlobbyDlg, "DCC", OnIrc_DCC_SEND)
|
||||||
IRC_MAP_ENTRY(CSmlobbyDlg, "002", OnIrc_YOURHOST)
|
IRC_MAP_ENTRY(CSmlobbyDlg, "002", OnIrc_YOURHOST)
|
||||||
IRC_MAP_ENTRY(CSmlobbyDlg, "321", OnIrc_RPL_LISTSTART)
|
IRC_MAP_ENTRY(CSmlobbyDlg, "321", OnIrc_RPL_LISTSTART)
|
||||||
IRC_MAP_ENTRY(CSmlobbyDlg, "322", OnIrc_RPL_LIST)
|
IRC_MAP_ENTRY(CSmlobbyDlg, "322", OnIrc_RPL_LIST)
|
||||||
@@ -311,8 +313,77 @@ bool CSmlobbyDlg::OnIrc_PRIVMSG(const CIrcMessage* pmsg)
|
|||||||
return true;
|
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>
|
||||||
|
const kRecptParm = 1;
|
||||||
|
|
||||||
|
//Make sure we have a parameter
|
||||||
|
if ( pmsg->parameters.size() < (kRecptParm + 1) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Make sure we're not trying to send a file to ourselves (people can be silly :p)
|
||||||
|
CString partnerName = pmsg->parameters[kRecptParm].c_str();
|
||||||
|
if ( partnerName == g_ircSession.GetInfo().sNick.c_str())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Make sure partner is currently in the room
|
||||||
|
if (LB_ERR == m_listUsers.FindString(-1, partnerName))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//open a file dialog box to get the file the user wants to send
|
||||||
|
CFileDialog fileDialog(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_EXPLORER,
|
||||||
|
NULL, AfxGetMainWnd());
|
||||||
|
if (IDOK != fileDialog.DoModal())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
//Setup retrieval params
|
||||||
|
IPaddress ipaddr;
|
||||||
|
char szHostName[256];
|
||||||
|
gethostname(szHostName, 256);
|
||||||
|
SDLNet_ResolveHost(&ipaddr, szHostName, 0);
|
||||||
|
|
||||||
|
//Get filename and directory
|
||||||
|
CString filename = fileDialog.GetFileName();
|
||||||
|
CString fullpath = fileDialog.GetPathName();
|
||||||
|
CString dirname = fullpath.Left(fullpath.GetLength() - filename.GetLength());
|
||||||
|
|
||||||
|
//Place all of the connection info into a dcc info structure
|
||||||
|
irc::CIrcDCCServer::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_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
|
||||||
|
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);
|
||||||
|
|
||||||
|
//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
|
||||||
|
//wait for the other party to connect to us and then
|
||||||
|
//transfer the file to them
|
||||||
|
g_DCCServer.Start(dccInfo);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool CSmlobbyDlg::OnIrc_DCC_RECV(const CIrcMessage *pmsg)
|
bool CSmlobbyDlg::OnIrc_DCC_RECV(const CIrcMessage *pmsg)
|
||||||
{
|
{
|
||||||
|
//incoming::
|
||||||
|
// PRIVMSG <recipient> :<0x01>DCC SEND <filename> <ipaddress> <port> <filesize><0x01>
|
||||||
|
|
||||||
//Make sure we have a parameter
|
//Make sure we have a parameter
|
||||||
if ( pmsg->parameters.size() < 1 )
|
if ( pmsg->parameters.size() < 1 )
|
||||||
return false;
|
return false;
|
||||||
@@ -328,20 +399,29 @@ bool CSmlobbyDlg::OnIrc_DCC_RECV(const CIrcMessage *pmsg)
|
|||||||
unsigned short uiPartnerPort;
|
unsigned short uiPartnerPort;
|
||||||
unsigned long ulFileSize;
|
unsigned long ulFileSize;
|
||||||
|
|
||||||
|
//Snag the dcc info fields from the message string
|
||||||
if ( 4 != sscanf(pszRawString, "\001DCC SEND %255s %lu %u %lu",
|
if ( 4 != sscanf(pszRawString, "\001DCC SEND %255s %lu %u %lu",
|
||||||
&szFilename, &ulPartnerIP, &uiPartnerPort, &ulFileSize) )
|
&szFilename, &ulPartnerIP, &uiPartnerPort, &ulFileSize) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//Open a dialog box so user can decide where to save file
|
//Open a dialog box so user can decide where to save file
|
||||||
CString pathname = SelectFolder();
|
CString pathname = SelectFolder();
|
||||||
|
if (pathname.GetLength() <= 1)
|
||||||
|
return false;
|
||||||
|
|
||||||
//We now have enough info to fire off a thread which downloads the file
|
//Assemble all of this info into a dcc info structure
|
||||||
CIrcDCCServer DCCServer;
|
irc::CIrcDCCServer::DCCTransferInfo dccInfo;
|
||||||
CString filename(szFilename);
|
dccInfo.m_bIsSender = false;
|
||||||
CString partner(pmsg->prefix.sNick.c_str());
|
dccInfo.m_directory = pathname;
|
||||||
|
dccInfo.m_fileName = szFilename;
|
||||||
|
dccInfo.m_partnerName = pmsg->prefix.sNick.c_str();
|
||||||
|
dccInfo.m_uiPort = uiPartnerPort;
|
||||||
|
dccInfo.m_uiXferRate = FILE_XFER_RATE;
|
||||||
|
dccInfo.m_ulFileSize = ulFileSize;
|
||||||
|
dccInfo.m_ulPartnerIP = ulPartnerIP;
|
||||||
|
|
||||||
DCCServer.Start(filename, pathname, partner, ulPartnerIP, uiPartnerPort,
|
//We now have enough info to fire off a thread that downloads the file
|
||||||
ulFileSize, FILE_XFER_RATE);
|
g_DCCServer.Start(dccInfo);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -612,10 +692,18 @@ void CSmlobbyDlg::OnButtonCreateGame()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Make sure a song is selected
|
||||||
|
int iIndex = m_comboMusic.GetCurSel();
|
||||||
|
if( iIndex <= 0 )
|
||||||
|
{
|
||||||
|
MessageBox("Need to select a song to play!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
//Tell the server that we wanted to create a chat room
|
//Tell the server that we wanted to create a chat room
|
||||||
g_ircSession << irc::CIrcMessage(CString("join ") + "#" + gameName);
|
g_ircSession << irc::CIrcMessage(CString("join ") + "#" + gameName);
|
||||||
|
|
||||||
//Get the IP address of our machine
|
//Get the IP address of our machine in network byte order
|
||||||
IPaddress ipaddr;
|
IPaddress ipaddr;
|
||||||
char szHostName[256];
|
char szHostName[256];
|
||||||
gethostname(szHostName, 256);
|
gethostname(szHostName, 256);
|
||||||
@@ -625,15 +713,10 @@ void CSmlobbyDlg::OnButtonCreateGame()
|
|||||||
sprintf(host_ip_str, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
sprintf(host_ip_str, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
|
||||||
|
|
||||||
//Insert song name/hash code here
|
//Insert song name/hash code here
|
||||||
|
|
||||||
int iIndex = m_comboMusic.GetCurSel();
|
|
||||||
if( iIndex <= 0 )
|
|
||||||
ASSERT(0); // what do we do here?
|
|
||||||
CString sSongDir;
|
CString sSongDir;
|
||||||
m_comboMusic.GetLBText( iIndex, sSongDir );
|
m_comboMusic.GetLBText( iIndex, sSongDir );
|
||||||
unsigned long hash = GetHashForDirectory( sSongDir );
|
unsigned long hash = GetHashForDirectory( sSongDir );
|
||||||
|
|
||||||
|
|
||||||
//Now tell the server our game info
|
//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,
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ protected:
|
|||||||
bool OnIrc_RPL_LIST(const CIrcMessage *pmsg);
|
bool OnIrc_RPL_LIST(const CIrcMessage *pmsg);
|
||||||
bool OnIrc_RPL_TOPIC(const CIrcMessage *pmsg);
|
bool OnIrc_RPL_TOPIC(const CIrcMessage *pmsg);
|
||||||
bool OnIrc_RPL_NAMREPLY(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_DCC_RECV(const CIrcMessage *pmsg);
|
||||||
bool OnIrc_IgnoreMesg(const CIrcMessage *pmsg) { return true; }
|
bool OnIrc_IgnoreMesg(const CIrcMessage *pmsg) { return true; }
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,12 @@ InetAddr::InetAddr(short wPort)
|
|||||||
port = wPort;
|
port = wPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InetAddr::InetAddr(long dwIP, short wPort)
|
||||||
|
{
|
||||||
|
host = dwIP;
|
||||||
|
port = wPort;
|
||||||
|
}
|
||||||
|
|
||||||
InetAddr::InetAddr(const char* lpszAddress, short wPort)
|
InetAddr::InetAddr(const char* lpszAddress, short wPort)
|
||||||
{
|
{
|
||||||
Resolve(lpszAddress, wPort);
|
Resolve(lpszAddress, wPort);
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ class InetAddr : public IPaddress
|
|||||||
{
|
{
|
||||||
public :
|
public :
|
||||||
InetAddr(short wPort = 0);
|
InetAddr(short wPort = 0);
|
||||||
|
InetAddr(long dwIP, short wPort);
|
||||||
InetAddr(const char* lpszAddress, short wPort = 0);
|
InetAddr(const char* lpszAddress, short wPort = 0);
|
||||||
InetAddr& operator = (char* lpszAddress);
|
InetAddr& operator = (char* lpszAddress);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user