Got DCC Send and Recieve working (without having to use threads)

This commit is contained in:
Brendan Walker
2002-12-19 23:59:12 +00:00
parent f512af6daf
commit fa3572a33e
16 changed files with 996 additions and 1445 deletions
+400 -24
View File
@@ -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;
}
}
+63 -13
View File
@@ -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:
bool m_bIsCanceled;
void FreePort(unsigned short port);
int SetupSend();
int SetupRecv();
void SendSomeData();
void RecvSomeData();
protected:
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()
};
+20 -11
View File
@@ -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;
}
}*/
////////////////////////////////////////////////////////////////////
+18 -3
View File
@@ -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

+5 -1
View File
@@ -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.
File diff suppressed because it is too large Load Diff
+4
View File
@@ -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.
+42
View File
@@ -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>
+9 -7
View File
@@ -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
+321 -40
View File
@@ -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
char szGameName[128];
int nDummy;
int nIndex = m_listGames.GetCurSel();
CString strGameName;
if (nIndex == LB_ERR) return;
if (nIndex != LB_ERR)
{
m_listGames.GetText(nIndex, strGameName);
m_listGames.GetText(nIndex, szGameName);
sscanf(szGameName, "%s (%d)", &szGameName, &nDummy);
//Tell the server that we wanted to join a chat room
g_ircSession << irc::CIrcMessage(CString("join ") + strGameName);
}
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");
}
+14 -1
View File
@@ -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}}
+10 -1
View File
@@ -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)