moved lobby from separate module to below /src

This commit is contained in:
Chris Danford
2002-12-02 05:44:00 +00:00
parent ca7c1ab78f
commit 840caa7a2c
30 changed files with 6453 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
// ConnectDlg.cpp : implementation file
//
#include "stdafx.h"
#include "resource2.h"
#include "ConnectDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CConnectDlg dialog
CConnectDlg::CConnectDlg(CWnd* pParent /*=NULL*/)
: CDialog(CConnectDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CConnectDlg)
m_sFullName = _T("");
m_sNick = _T("");
m_sPassword = _T("");
m_uiPort = 0;
m_sServer = _T("");
m_sUserID = _T("");
//}}AFX_DATA_INIT
}
void CConnectDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CConnectDlg)
DDX_Text(pDX, IDC_FULLNAME, m_sFullName);
DDX_Text(pDX, IDC_NICK, m_sNick);
DDX_Text(pDX, IDC_PASSWORD, m_sPassword);
DDX_Text(pDX, IDC_PORT, m_uiPort);
DDX_Text(pDX, IDC_SERVER, m_sServer);
DDX_Text(pDX, IDC_USERID, m_sUserID);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CConnectDlg, CDialog)
//{{AFX_MSG_MAP(CConnectDlg)
ON_EN_CHANGE(IDC_FULLNAME, OnChange)
ON_EN_CHANGE(IDC_NICK, OnChange)
ON_EN_CHANGE(IDC_PASSWORD, OnChange)
ON_EN_CHANGE(IDC_PORT, OnChange)
ON_EN_CHANGE(IDC_SERVER, OnChange)
ON_EN_CHANGE(IDC_USERID, OnChange)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CConnectDlg message handlers
void CConnectDlg::OnChange()
{
UpdateButtons();
}
void CConnectDlg::UpdateButtons()
{
GetDlgItem(IDOK)->EnableWindow(
GetDlgItem(IDC_FULLNAME)->GetWindowTextLength() > 0 &&
GetDlgItem(IDC_NICK)->GetWindowTextLength() > 0 &&
GetDlgItem(IDC_SERVER)->GetWindowTextLength() > 0 &&
GetDlgItem(IDC_USERID)->GetWindowTextLength() > 0 &&
GetDlgItemInt(IDC_PORT) != 0
);
}
BOOL CConnectDlg::OnInitDialog()
{
CDialog::OnInitDialog();
UpdateButtons();
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
+53
View File
@@ -0,0 +1,53 @@
#if !defined(AFX_CONNECTDLG_H__04D8BFFC_9C8D_4610_8AFF_4736EB7397BE__INCLUDED_)
#define AFX_CONNECTDLG_H__04D8BFFC_9C8D_4610_8AFF_4736EB7397BE__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ConnectDlg.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CConnectDlg dialog
class CConnectDlg : public CDialog
{
// Construction
public:
CConnectDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CConnectDlg)
enum { IDD = IDD_CONNECT };
CString m_sFullName;
CString m_sNick;
CString m_sPassword;
UINT m_uiPort;
CString m_sServer;
CString m_sUserID;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CConnectDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
void UpdateButtons();
// Generated message map functions
//{{AFX_MSG(CConnectDlg)
afx_msg void OnChange();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_CONNECTDLG_H__04D8BFFC_9C8D_4610_8AFF_4736EB7397BE__INCLUDED_)
@@ -0,0 +1,98 @@
// CrossThreadsMessagingDevice.cpp
#include "stdafx.h"
#include "CrossThreadsMessagingDevice.h"
LPCTSTR CCrossThreadsMessagingDevice::m_lpszClassName = _T("CCrossThreadsMessagingDevice_HiddenWindow");
int CCrossThreadsMessagingDevice::m_iCount = 0;
CCrossThreadsMessagingDevice::CCrossThreadsMessagingDevice()
: m_hWnd(NULL), m_pMonitor(NULL)
{
if( m_iCount++ == 0 )
{
const WNDCLASS wc =
{
0,
HiddenWindowProc,
sizeof(DWORD) * 2,
sizeof(DWORD) * 2,
GetModuleHandle(NULL),
(HICON)NULL,
(HCURSOR)NULL,
(HBRUSH)(COLOR_WINDOW + 1),
(LPCTSTR)NULL,
m_lpszClassName
};
if( !RegisterClass(&wc) )
return;
}
m_hWnd = CreateWindow(
m_lpszClassName,
_T(""),
WS_OVERLAPPED,
0, 0, 0, 0,
(HWND)NULL,
(HMENU)NULL,
GetModuleHandle(NULL),
this
);
}
CCrossThreadsMessagingDevice::~CCrossThreadsMessagingDevice()
{
if( ::IsWindow(m_hWnd) )
DestroyWindow(m_hWnd);
if( --m_iCount == 0 )
{
UnregisterClass(m_lpszClassName, GetModuleHandle(NULL));
}
}
void CCrossThreadsMessagingDevice::Post(WPARAM wParam, LPARAM lParam)
{
ASSERT(::IsWindow(m_hWnd));
PostMessage(m_hWnd, HWM_DATA, wParam, lParam);
}
LRESULT WINAPI CCrossThreadsMessagingDevice::HiddenWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
LRESULT rc = 0;
CCrossThreadsMessagingDevice* pThis =
(CCrossThreadsMessagingDevice*)GetWindowLong(hWnd, GWL_USERDATA);
switch( uMsg )
{
case WM_NCCREATE :
{
LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam;
ASSERT(lpcs->lpCreateParams != NULL);
SetWindowLong(hWnd, GWL_USERDATA, (LONG)lpcs->lpCreateParams);
rc = TRUE;
break;
}
case HWM_DATA :
{
ASSERT(pThis != NULL);
if( pThis->m_pMonitor )
pThis->m_pMonitor->OnCrossThreadsMessage(wParam, lParam);
break;
}
default :
{
rc = DefWindowProc(hWnd, uMsg, wParam, lParam);
break;
}
}
return rc;
}
@@ -0,0 +1,36 @@
// CrossThreadsMessagingDevice.h
#ifndef _CrossThreadsMessagingDevice_H_
#define _CrossThreadsMessagingDevice_H_
class CCrossThreadsMessagingDevice
{
public :
struct ICrossThreadsMessagingDeviceMonitor
{
virtual void OnCrossThreadsMessage(WPARAM wParam, LPARAM lParam) = 0;
};
CCrossThreadsMessagingDevice();
virtual ~CCrossThreadsMessagingDevice();
void SetMonitor(ICrossThreadsMessagingDeviceMonitor* pMonitor) { m_pMonitor = pMonitor; }
void Post(WPARAM wParam, LPARAM lParam);
operator bool() const { return ::IsWindow(m_hWnd)==TRUE; }
private :
enum { HWM_DATA = WM_USER + 1000 };
static LPCTSTR m_lpszClassName;
static int m_iCount;
HWND m_hWnd;
ICrossThreadsMessagingDeviceMonitor* m_pMonitor;
static LRESULT WINAPI HiddenWindowProc(HWND, UINT, WPARAM, LPARAM);
};
#endif // _CrossThreadsMessagingDevice_H_
+88
View File
@@ -0,0 +1,88 @@
// DirectoryDialog.cpp : implementation file
//
#include "stdafx.h"
#include "smlobby.h"
#include "DirectoryDialog.h"
#include "dlgs.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CDirectoryDialog
IMPLEMENT_DYNAMIC(CDirectoryDialog, CFileDialog)
CDirectoryDialog::CDirectoryDialog(BOOL bOpenFileDialog, LPCTSTR lpszDefExt, LPCTSTR lpszFileName,
DWORD dwFlags, LPCTSTR lpszFilter, CWnd* pParentWnd) :
CFileDialog(bOpenFileDialog, lpszDefExt, lpszFileName, dwFlags, lpszFilter, pParentWnd)
{
}
BEGIN_MESSAGE_MAP(CDirectoryDialog, CFileDialog)
//{{AFX_MSG_MAP(CDirectoryDialog)
ON_WM_PAINT()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CDirectoryDialog::OnPaint()
{
CPaintDC dc(this); // device context for painting
// TODO: Add your message handler code here
//This code makes the directory listbox "highlight" an entry when it first
//comes up. W/O this code, the focus is on the directory listbox, but no
//focus rectangle is drawn and no entries are selected. Ho hum.
if (m_bDlgJustCameUp)
{
m_bDlgJustCameUp=FALSE;
SendDlgItemMessage(lst2, LB_SETCURSEL, 0, 0L);
}
// Do not call CFileDialog::OnPaint() for painting messages
}
BOOL CDirectoryDialog::OnInitDialog()
{
CenterWindow();
//Let's hide these windows so the user cannot tab to them. Note that in
//the private template (in cddemo.dlg) the coordinates for these guys are
//*outside* the coordinates of the dlg window itself. Without the following
//ShowWindow()'s you would not see them, but could still tab to them.
GetDlgItem(stc2)->ShowWindow(SW_HIDE);
GetDlgItem(stc3)->ShowWindow(SW_HIDE);
GetDlgItem(edt1)->ShowWindow(SW_HIDE);
GetDlgItem(lst1)->ShowWindow(SW_HIDE);
GetDlgItem(cmb1)->ShowWindow(SW_HIDE);
//We must put something in this field, even though it is hidden. This is
//because if this field is empty, or has something like "*.txt" in it,
//and the user hits OK, the dlg will NOT close. We'll jam something in
//there (like "Junk") so when the user hits OK, the dlg terminates.
//Note that we'll deal with the "Junk" during return processing (see below)
SetDlgItemText(edt1, "Junk");
//Now set the focus to the directories listbox. Due to some painting
//problems, we *must* also process the first WM_PAINT that comes through
//and set the current selection at that point. Setting the selection
//here will NOT work. See comment below in the on paint handler.
GetDlgItem(lst2)->SetFocus();
m_bDlgJustCameUp=TRUE;
CFileDialog::OnInitDialog();
return(FALSE);
}
+41
View File
@@ -0,0 +1,41 @@
#if !defined(AFX_DIRECTORYDIALOG_H__1692F649_A71E_4EA5_9DE0_0A3F2A30B1E6__INCLUDED_)
#define AFX_DIRECTORYDIALOG_H__1692F649_A71E_4EA5_9DE0_0A3F2A30B1E6__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// DirectoryDialog.h : header file
//
#include "resource2.h"
/////////////////////////////////////////////////////////////////////////////
// CDirectoryDialog dialog
class CDirectoryDialog : public CFileDialog
{
DECLARE_DYNAMIC(CDirectoryDialog)
public:
BOOL m_bDlgJustCameUp;
public:
CDirectoryDialog(BOOL bOpenFileDialog, // TRUE for FileOpen, FALSE for FileSaveAs
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL);
protected:
//{{AFX_MSG(CDirectoryDialog)
afx_msg void OnPaint();
virtual BOOL OnInitDialog();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_DIRECTORYDIALOG_H__1692F649_A71E_4EA5_9DE0_0A3F2A30B1E6__INCLUDED_)
+96
View File
@@ -0,0 +1,96 @@
// EditChat.cpp : implementation file
//
#include "stdafx.h"
#include "smlobby.h"
#include "EditChat.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
//external object
extern irc::CIrcSession g_ircSession;
/////////////////////////////////////////////////////////////////////////////
// CEditChat
CEditChat::CEditChat()
{
}
CEditChat::~CEditChat()
{
}
BEGIN_MESSAGE_MAP(CEditChat, CEdit)
//{{AFX_MSG_MAP(CEditChat)
ON_WM_GETDLGCODE()
ON_WM_KEYUP()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CEditChat message handlers
UINT CEditChat::OnGetDlgCode()
{
UINT code = CEdit::OnGetDlgCode();
code |= DLGC_WANTMESSAGE;
return code;
}
void CEditChat::OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags)
{
switch (nChar)
{
//User presses the return key
case VK_RETURN:
SendChatMesg();
break;
}
CEdit::OnKeyUp(nChar, nRepCnt, nFlags);
}
void CEditChat::SendChatMesg()
{
CString s, name;
bool isIncoming = false;
this->GetWindowText(s);
if( s.GetLength() == 0 ) return;
if( s[0] != '/' )
{
//Make sure were in a chat room
if( g_ircSession.GetInfo().sCurrentChatRoom.length() == 0)
{
s = "You are not currently in a chat room";
name = g_ircSession.GetInfo().sNick.c_str();
isIncoming = true;
}
else
{
name = g_ircSession.GetInfo().sCurrentChatRoom.c_str();
}
s = "PRIVMSG " + name + " :" + s;
}
else
{
s = s.Mid(1);
}
if( g_ircSession )
g_ircSession << irc::CIrcMessage(s, isIncoming);
this->SetWindowText(_T(""));
}
+50
View File
@@ -0,0 +1,50 @@
#if !defined(AFX_EDITCHAT_H__68A3B363_25AE_45B1_8519_9FE70839EFC4__INCLUDED_)
#define AFX_EDITCHAT_H__68A3B363_25AE_45B1_8519_9FE70839EFC4__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// EditChat.h : header file
//
/////////////////////////////////////////////////////////////////////////////
// CEditChat window
class CEditChat : public CEdit
{
// Construction
public:
CEditChat();
// Attributes
public:
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CEditChat)
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CEditChat();
void SendChatMesg();
// Generated message map functions
protected:
//{{AFX_MSG(CEditChat)
afx_msg UINT OnGetDlgCode();
afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_EDITCHAT_H__68A3B363_25AE_45B1_8519_9FE70839EFC4__INCLUDED_)
+77
View File
@@ -0,0 +1,77 @@
// SendFileDialog.cpp : implementation file
//
#include "stdafx.h"
#include "smlobby.h"
#include "SendFileDialog.h"
#include "irc.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSendFileDialog dialog
CSendFileDialog::CSendFileDialog(CWnd* pParent /*=NULL*/)
: 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_pDCCServer = NULL;
}
void CSendFileDialog::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSendFileDialog)
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)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSendFileDialog message handlers
void CSendFileDialog::OnCancel()
{
//Tell the DCC Server to abort as the file isn't transfering
// or the user has beome impatient :)
if (m_pDCCServer)
{
CIrcDCCServer* pServer = (CIrcDCCServer *)m_pDCCServer;
pServer->Stop(0);
}
CDialog::OnCancel();
}
+64
View File
@@ -0,0 +1,64 @@
#if !defined(AFX_SENDFILEDIALOG_H__6AA4B205_EDA8_4960_9424_1C5743093120__INCLUDED_)
#define AFX_SENDFILEDIALOG_H__6AA4B205_EDA8_4960_9424_1C5743093120__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// SendFileDialog.h : header file
//
#include "resource2.h"
/////////////////////////////////////////////////////////////////////////////
// CSendFileDialog dialog
class CSendFileDialog : public CDialog
{
// Construction
public:
CSendFileDialog(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CSendFileDialog)
enum { IDD = IDD_FILEXFER };
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
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSendFileDialog)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
public:
void AssignDCCServer(void* pServer) { m_pDCCServer = pServer; }
protected:
void* m_pDCCServer;
protected:
// Generated message map functions
//{{AFX_MSG(CSendFileDialog)
virtual void OnCancel();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SENDFILEDIALOG_H__6AA4B205_EDA8_4960_9424_1C5743093120__INCLUDED_)
+8
View File
@@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// gimplobby.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
+26
View File
@@ -0,0 +1,26 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__FDE20029_172C_49E9_9553_68F48CF8C2BF__INCLUDED_)
#define AFX_STDAFX_H__FDE20029_172C_49E9_9553_68F48CF8C2BF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
#include <afxwin.h> // MFC core and standard components
#include <afxext.h> // MFC extensions
#include <afxdtctl.h> // MFC support for Internet Explorer 4 Common Controls
#ifndef _AFX_NO_AFXCMN_SUPPORT
#include <afxcmn.h> // MFC support for Windows Common Controls
#endif // _AFX_NO_AFXCMN_SUPPORT
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__FDE20029_172C_49E9_9553_68F48CF8C2BF__INCLUDED_)
+830
View File
@@ -0,0 +1,830 @@
// irc.cpp
#include "stdafx.h"
#include "irc.h"
using namespace irc;
////////////////////////////////////////////////////////////////////
CIrcMessage::CIrcMessage(const char* lpszCmdLine, bool bIncoming)
: m_bIncoming(bIncoming)
{
ParseIrcCommand(lpszCmdLine);
}
CIrcMessage::CIrcMessage(const CIrcMessage& m)
: sCommand(m.sCommand),
parameters(m.parameters),
m_bIncoming(m.m_bIncoming)
{
prefix.sNick = m.prefix.sNick;
prefix.sUser = m.prefix.sUser;
prefix.sHost = m.prefix.sHost;
}
void CIrcMessage::Reset()
{
prefix.sNick = prefix.sUser = prefix.sHost = sCommand = "";
m_bIncoming = false;
parameters.clear();
}
CIrcMessage& CIrcMessage::operator = (const CIrcMessage& m)
{
if( &m != this )
{
sCommand = m.sCommand;
parameters = m.parameters;
prefix.sNick = m.prefix.sNick;
prefix.sUser = m.prefix.sUser;
prefix.sHost = m.prefix.sHost;
m_bIncoming = m.m_bIncoming;
}
return *this;
}
CIrcMessage& CIrcMessage::operator = (const char* lpszCmdLine)
{
Reset();
ParseIrcCommand(lpszCmdLine);
return *this;
}
void CIrcMessage::ParseIrcCommand(const char* lpszCmdLine)
{
const char* p1 = lpszCmdLine;
const char* p2 = lpszCmdLine;
ASSERT(lpszCmdLine != NULL);
ASSERT(*lpszCmdLine);
// prefix exists ?
if( *p1 == ':' )
{ // break prefix into its components (nick!user@host)
p2 = ++p1;
while( *p2 && !strchr(" !", *p2) )
++p2;
prefix.sNick.assign(p1, p2 - p1);
if( *p2 != '!' )
goto end_of_prefix;
p1 = ++p2;
while( *p2 && !strchr(" @", *p2) )
++p2;
prefix.sUser.assign(p1, p2 - p1);
if( *p2 != '@' )
goto end_of_prefix;
p1 = ++p2;
while( *p2 && !isspace(*p2) )
++p2;
prefix.sHost.assign(p1, p2 - p1);
end_of_prefix :
while( *p2 && isspace(*p2) )
++p2;
p1 = p2;
}
// get command
ASSERT(*p1 != '\0');
p2 = p1;
while( *p2 && !isspace(*p2) )
++p2;
sCommand.assign(p1, p2 - p1);
_strupr((char*)sCommand.c_str());
while( *p2 && isspace(*p2) )
++p2;
p1 = p2;
// get parameters
while( *p1 )
{
if( *p1 == ':' )
{
++p1;
// seek end-of-message
while( *p2 )
++p2;
parameters.push_back(String(p1, p2 - p1));
break;
}
else
{
// seek end of parameter
while( *p2 && !isspace(*p2) )
++p2;
parameters.push_back(String(p1, p2 - p1));
// see next parameter
while( *p2 && isspace(*p2) )
++p2;
p1 = p2;
}
} // end parameters loop
}
String CIrcMessage::AsString() const
{
String s;
if( prefix.sNick.length() )
{
s += ":" + prefix.sNick;
if( prefix.sUser.length() && prefix.sHost.length() )
s += "!" + prefix.sUser + "@" + prefix.sHost;
s += " ";
}
s += sCommand;
for(int i=0; i < parameters.size(); i++)
{
s += " ";
if( i == parameters.size() - 1 ) // is last parameter ?
s += ":";
s += parameters[i];
}
s += endl;
return s;
}
////////////////////////////////////////////////////////////////////
CIrcSession::CIrcSession(IIrcSessionMonitor* pMonitor)
: m_hThread(NULL)
{
InitializeCriticalSection(&m_cs);
}
CIrcSession::~CIrcSession()
{
Disconnect();
DeleteCriticalSection(&m_cs);
}
bool CIrcSession::Connect(const CIrcSessionInfo& info)
{
ASSERT(m_hThread==NULL && !m_socket);
try
{
// if( !m_socket.Create() )
// throw "Failed to create socket!";
InetAddr addr(info.sServer.c_str(), info.iPort);
if( !m_socket.Connect(addr) )
{
m_socket.Close();
throw "Failed to connect to host!";
}
m_info = info;
// start receiving messages from host
m_hThread = CreateThread(NULL, 0, ThreadProc, this, 0, NULL);
Sleep(100);
if( info.sPassword.length() )
m_socket.Send("PASS %s\r\n", info.sPassword.c_str());
m_socket.Send("NICK %s\r\n", info.sNick.c_str());
TCHAR szHostName[MAX_PATH];
DWORD cbHostName = sizeof(szHostName);
GetComputerName(szHostName, &cbHostName);
m_socket.Send("USER %s %s %s :%s\r\n",
info.sUserID.c_str(), szHostName, "server", info.sFullName.c_str());
}
catch( const char* )
{
Disconnect();
}
catch( ... )
{
Disconnect();
}
return (bool)m_socket;
}
void CIrcSession::Disconnect(const char* lpszMessage)
{
static const DWORD dwServerTimeout = 5 * 1000;
if( !m_hThread )
return;
m_socket.Send("QUIT :%s\r\n", lpszMessage ? lpszMessage : "Bye!");
if( m_hThread && WaitForSingleObject(m_hThread, dwServerTimeout) != WAIT_OBJECT_0 )
{
m_socket.Close();
Sleep(100);
if( m_hThread && WaitForSingleObject(m_hThread, dwServerTimeout) != WAIT_OBJECT_0 )
{
TerminateThread(m_hThread, 1);
CloseHandle(m_hThread);
m_hThread = NULL;
m_info.Reset();
}
}
}
void CIrcSession::Notify(const CIrcMessage* pmsg)
{
// forward message to monitor objects
EnterCriticalSection(&m_cs);
for(std::set<IIrcSessionMonitor*>::iterator it = m_monitors.begin();
it != m_monitors.end();
it++
)
{
(*it)->OnIrcMessage(pmsg);
}
LeaveCriticalSection(&m_cs);
}
void CIrcSession::DoReceive()
{
CIrcIdentServer m_identServer;
char chBuf[1024*4+1];
int cbInBuf = 0;
if( m_info.bIdentServer )
m_identServer.Start(m_info.sUserID.c_str());
while( m_socket )
{
int cbRead;
int nLinesProcessed = 0;
cbRead = m_socket.Receive((unsigned char*)chBuf+cbInBuf, sizeof(chBuf)-cbInBuf-1);
if( cbRead <= 0 )
break;
cbInBuf += cbRead;
chBuf[cbInBuf] = '\0';
char* pStart = chBuf;
while( *pStart )
{
char* pEnd;
// seek end-of-line
for(pEnd=pStart; *pEnd && *pEnd != '\r' && *pEnd != '\n'; ++pEnd)
;
if( *pEnd == '\0' )
break; // uncomplete message. stop parsing.
++nLinesProcessed;
// replace end-of-line with NULLs and skip
while( *pEnd == '\r' || *pEnd == '\n' )
*pEnd++ = '\0';
if( *pStart )
{
// process single message by monitor objects
CIrcMessage msg(pStart, true);
Notify(&msg);
}
cbInBuf -= pEnd - pStart;
ASSERT(cbInBuf >= 0);
pStart = pEnd;
}
// discard processed messages
if( nLinesProcessed != 0 )
memmove(chBuf, pStart, cbInBuf+1);
}
if( m_socket )
m_socket.Close();
if( m_info.bIdentServer )
m_identServer.Stop();
// notify monitor objects that the connection has been closed
Notify(NULL);
}
DWORD WINAPI CIrcSession::ThreadProc(LPVOID pparam)
{
CIrcSession* pThis = (CIrcSession*)pparam;
try { pThis->DoReceive(); } catch( ... ) {}
pThis->m_info.Reset();
CloseHandle(pThis->m_hThread);
pThis->m_hThread = NULL;
return 0;
}
void CIrcSession::AddMonitor(IIrcSessionMonitor* pMonitor)
{
ASSERT(pMonitor != NULL);
EnterCriticalSection(&m_cs);
m_monitors.insert(pMonitor);
LeaveCriticalSection(&m_cs);
}
void CIrcSession::RemoveMonitor(IIrcSessionMonitor* pMonitor)
{
ASSERT(pMonitor != NULL);
EnterCriticalSection(&m_cs);
m_monitors.erase(pMonitor);
LeaveCriticalSection(&m_cs);
}
////////////////////////////////////////////////////////////////////
CIrcSessionInfo::CIrcSessionInfo()
: iPort(0), bIdentServer(false), iIdentServerPort(0)
{
}
CIrcSessionInfo::CIrcSessionInfo(const CIrcSessionInfo& si)
: sServer(si.sServer),
sServerName(si.sServerName),
iPort(si.iPort),
sNick(si.sNick),
sUserID(si.sUserID),
sFullName(si.sFullName),
sPassword(si.sPassword),
bIdentServer(si.bIdentServer),
sIdentServerType(si.sIdentServerType),
iIdentServerPort(si.iIdentServerPort)
{
}
void CIrcSessionInfo::Reset()
{
sServer = "";
sServerName = "";
iPort = 0;
sNick = "";
sUserID = "";
sFullName = "";
sPassword = "";
bIdentServer = false;
sIdentServerType = "";
iIdentServerPort = 0;
}
////////////////////////////////////////////////////////////////////
CIrcIdentServer::CIrcIdentServer()
: m_uiPort(0), m_hThread(NULL)
{
}
CIrcIdentServer::~CIrcIdentServer()
{
Stop();
}
bool CIrcIdentServer::Start(
const char* lpszUserID,
unsigned int uiPort,
const char* lpszResponseType
)
{
if( m_socket )
return false;
if( !m_socket.Bind(InetAddr(uiPort)) )
{
m_socket.Close();
return false;
}
m_sResponseType = lpszResponseType;
m_sUserID = lpszUserID;
m_uiPort = uiPort;
m_hThread = CreateThread(NULL, 0, ListenProc, this, 0, NULL);
Sleep(100);
return true;
}
void CIrcIdentServer::Stop()
{
if( m_hThread )
{
m_socket.Close();
if( WaitForSingleObject(m_hThread, 5000) != WAIT_OBJECT_0 && m_hThread )
{
TerminateThread(m_hThread, 1);
CloseHandle(m_hThread);
m_hThread = NULL;
}
}
}
void CIrcIdentServer::DoThread()
{
m_socket.Listen();
while( (bool)m_socket )
{
Socket s = m_socket.Accept();
if( !s )
break;
char szBuf[1024];
int cbRead = s.Receive((unsigned char*)szBuf, sizeof(szBuf)-1);
if( cbRead <= 0 )
continue;
szBuf[cbRead] = '\0';
// strip CRLF from query
for(char* p = szBuf; *p && *p != '\r' && *p != '\n'; ++p)
;
*p = '\0';
s.Send("%s : USERID : %s : %s\r\n",
szBuf, m_sResponseType.c_str(), m_sUserID.c_str());
Sleep(500);
s.Close();
}
m_socket.Close();
}
DWORD WINAPI CIrcIdentServer::ListenProc(LPVOID pparam)
{
CIrcIdentServer* pThis = (CIrcIdentServer*)pparam;
try { pThis->DoThread(); } catch( ... ) {}
pThis->m_sResponseType = "";
pThis->m_sUserID = "";
pThis->m_uiPort = 0;
CloseHandle(pThis->m_hThread);
pThis->m_hThread = NULL;
return 0;
}
////////////////////////////////////////////////////////////////////
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()
{
Stop();
}
bool CIrcDCCServer::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
)
{
//Clean up old send file dialog
if (m_pSendFileDialog)
{
delete m_pSendFileDialog;
m_pSendFileDialog = NULL;
}
if( m_socket )
return false;
//Setup the connection info vars
m_fileName = fileName;
m_directory = directory;
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
m_ulStartTime = GetTickCount();
//Create a file transfer dialog
m_pSendFileDialog = new CSendFileDialog(AfxGetMainWnd());
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
{
m_pSendFileDialog->m_SentRecvd = "Recv'd:";
m_pSendFileDialog->m_ToFrom = "From:";
}
//Show the dialog and tell it about this server
m_pSendFileDialog->AssignDCCServer(this);
m_pSendFileDialog->ShowWindow(SW_SHOW);
//Fire off the thread
m_hThread = CreateThread(NULL, 0, ListenProc, this, 0, NULL);
Sleep(100);
return true;
}
void CIrcDCCServer::Stop(DWORD timeout)
{
if( m_hThread )
{
m_socket.Close();
if( WaitForSingleObject(m_hThread, timeout) != WAIT_OBJECT_0 && m_hThread )
{
TerminateThread(m_hThread, 1);
CloseHandle(m_hThread);
m_hThread = NULL;
}
}
}
void CIrcDCCServer::DoThreadRecv()
{
char szBuf[8193];
unsigned long cbRead, cbSent;
float fracSent;
unsigned long seconds, minutes, hours, rate;
//Create an active socket to retrieve data from (close listening socket)
InetAddr addr;
addr.host = m_ulPartnerIP;
addr.port = m_uiPort;
m_socket.Connect(addr);
if ( !m_socket ) return;
//Tell user file transfer has started
m_pSendFileDialog->m_XferStatus = "Recieving File...";
//Create a file to write incoming data to
CString filename = m_directory+"\\"+m_fileName;
FILE* fp = fopen(filename, "wb");
if ( !fp ) return;
//Start grabbing data blocks
while(m_ulBytesSent < m_ulFileSize)
{
//Grab the next buffer
cbRead = m_socket.Receive((unsigned char*)szBuf, sizeof(szBuf)-1);
if( cbRead <= 0 ) continue;
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
fwrite(szBuf, cbRead, 1, fp);
//Tell the sender how many bytes we received
cbRead = htonl(cbRead);
cbSent = 0;
while ( cbSent <= 0 )
cbSent = m_socket.Send((unsigned char *)&cbRead, 4);
}
//Close our data transfer socket
m_socket.Close();
//Close our file
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);
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));
}
//Close our data transfer socket
sock.Close();
//Close our file
fclose(fp);
}
DWORD WINAPI CIrcDCCServer::ListenProc(LPVOID pparam)
{
CIrcDCCServer* pThis = (CIrcDCCServer*)pparam;
if (pThis->IsSender())
try { pThis->DoThreadSend(); } catch( ... ) {}
else
try { pThis->DoThreadRecv(); } catch( ... ) {}
CloseHandle(pThis->m_hThread);
pThis->m_hThread = NULL;
return 0;
}
////////////////////////////////////////////////////////////////////
CIrcMonitor::HandlersMap CIrcMonitor::m_handlers;
CIrcMonitor::IrcCommandsMapsListEntry CIrcMonitor::m_handlersMapsListEntry
= { &CIrcMonitor::m_handlers, NULL };
CIrcMonitor::CIrcMonitor(CIrcSession& session)
: m_session(session)
{
m_xPost.SetMonitor(this);
}
CIrcMonitor::~CIrcMonitor()
{
}
void CIrcMonitor::OnIrcMessage(const CIrcMessage* pmsg)
{
CIrcMessage* pMsgCopy = NULL;
if( pmsg )
pMsgCopy = new CIrcMessage(*pmsg);
m_xPost.Post(0, (LPARAM)pMsgCopy);
}
void CIrcMonitor::OnCrossThreadsMessage(WPARAM wParam, LPARAM lParam)
{
CIrcMessage* pmsg = (CIrcMessage*)lParam;
OnIrcAll(pmsg);
if( pmsg )
{
PfnIrcMessageHandler pfn = FindMethod(pmsg->sCommand.c_str());
if( pfn )
{
// call member function. if it returns 'false',
// call the default handling
if( !(this->*pfn)(pmsg) )
OnIrcDefault(pmsg);
}
else // handler not found. call default handler
OnIrcDefault(pmsg);
delete pmsg;
}
else
OnIrcDisconnected();
}
CIrcMonitor::PfnIrcMessageHandler CIrcMonitor::FindMethod(const char* lpszName)
{
// call the recursive version with the most derived map
return FindMethod(GetIrcCommandsMap(), lpszName);
}
CIrcMonitor::PfnIrcMessageHandler CIrcMonitor::FindMethod(IrcCommandsMapsListEntry* pMapsList, const char* lpszName)
{
HandlersMap::iterator it = pMapsList->pHandlersMap->find(lpszName);
if( it != pMapsList->pHandlersMap->end() )
return it->second; // found !
else if( pMapsList->pBaseHandlersMap )
return FindMethod(pMapsList->pBaseHandlersMap, lpszName); // try at base class
return NULL; // not found in any map
}
////////////////////////////////////////////////////////////////////
DECLARE_IRC_MAP(CIrcDefaultMonitor, CIrcMonitor)
CIrcDefaultMonitor::CIrcDefaultMonitor(CIrcSession& session)
: CIrcMonitor(session)
{
IRC_MAP_ENTRY(CIrcDefaultMonitor, "NICK", OnIrc_NICK)
IRC_MAP_ENTRY(CIrcDefaultMonitor, "PING", OnIrc_PING)
IRC_MAP_ENTRY(CIrcDefaultMonitor, "002", OnIrc_YOURHOST)
IRC_MAP_ENTRY(CIrcDefaultMonitor, "005", OnIrc_BOUNCE)
}
bool CIrcDefaultMonitor::OnIrc_NICK(const CIrcMessage* pmsg)
{
if( (m_session.GetInfo().sNick == pmsg->prefix.sNick) && (pmsg->parameters.size() > 0) )
m_session.m_info.sNick = pmsg->parameters[0];
return false;
}
bool CIrcDefaultMonitor::OnIrc_PING(const CIrcMessage* pmsg)
{
char szResponse[100];
sprintf(szResponse, "PONG %s", pmsg->parameters[0].c_str());
m_session << CIrcMessage(szResponse);
return false;
}
bool CIrcDefaultMonitor::OnIrc_YOURHOST(const CIrcMessage* pmsg)
{
static const char* lpszFmt = "Your host is %[^ \x5b,], running version %s";
char szHostName[100], szVersion[100];
if( sscanf(pmsg->parameters[1].c_str(), lpszFmt, &szHostName, &szVersion) > 0 )
m_session.m_info.sServerName = szHostName;
return false;
}
bool CIrcDefaultMonitor::OnIrc_BOUNCE(const CIrcMessage* pmsg)
{
static const char* lpszFmt = "Try server %[^ ,], port %d";
char szAltServer[100];
int iAltPort = 0;
if( sscanf(pmsg->parameters[1].c_str(), lpszFmt, &szAltServer, &iAltPort) == 2 )
{
}
return false;
}
+304
View File
@@ -0,0 +1,304 @@
// irc.h
#ifndef _IRC_H_
#define _IRC_H_
/*
IRC (RFC #1459) Client Implementation
*/
#pragma warning (disable: 4786)
#include "socket.h"
#include <string>
#include <vector>
#include <map>
#include <set>
#include "CrossThreadsMessagingDevice.h"
#include "SendFileDialog.h"
////////////////////////////////////////////////////////////////////
namespace irc {
////////////////////////////////////////////////////////////////////
typedef std::string String;
static const char* endl = "\r\n";
////////////////////////////////////////////////////////////////////
class CIrcMessage
{
public :
struct Prefix
{
String sNick, sUser, sHost;
} prefix;
String sCommand;
std::vector<String> parameters;
bool m_bIncoming;
CIrcMessage() : m_bIncoming(false) {} // default constructor
CIrcMessage(const char* lpszCmdLine, bool bIncoming=false); // parser constructor
CIrcMessage(const CIrcMessage& m); // copy constructor
void Reset();
CIrcMessage& operator = (const CIrcMessage& m);
CIrcMessage& operator = (const char* lpszCmdLine);
String AsString() const;
private :
void ParseIrcCommand(const char* lpszCmdLine);
};
////////////////////////////////////////////////////////////////////
struct IIrcSessionMonitor
{
virtual void OnIrcMessage(const CIrcMessage* pmsg) = 0;
};
////////////////////////////////////////////////////////////////////
struct CIrcSessionInfo
{
String sServer;
String sServerName;
unsigned int iPort;
String sNick;
String sUserID;
String sFullName;
String sPassword;
String sCurrentChatRoom;
bool bIdentServer;
String sIdentServerType;
unsigned int iIdentServerPort;
CIrcSessionInfo();
CIrcSessionInfo(const CIrcSessionInfo& si);
void Reset();
};
////////////////////////////////////////////////////////////////////
class CIrcDefaultMonitor; // foreward
class CIrcSession
{
public :
friend class CIrcDefaultMonitor;
CIrcSession(IIrcSessionMonitor* pMonitor = NULL);
virtual ~CIrcSession();
void AddMonitor(IIrcSessionMonitor* pMonitor);
void RemoveMonitor(IIrcSessionMonitor* pMonitor);
bool Connect(const CIrcSessionInfo& info);
void Disconnect(const char* lpszMessage = "Bye!");
CIrcSessionInfo& GetInfo() const
{ return (CIrcSessionInfo&)m_info; }
operator bool() const { return (bool)m_socket; }
// send-to-stream operators
friend CIrcSession& operator << (CIrcSession& os, const CIrcMessage& m);
protected :
Socket m_socket;
CIrcSessionInfo m_info;
void DoReceive();
private :
std::set<IIrcSessionMonitor*> m_monitors;
HANDLE m_hThread;
CRITICAL_SECTION m_cs; // protect m_monitors
void Notify(const CIrcMessage* pmsg);
static DWORD WINAPI ThreadProc(LPVOID pparam);
};
__inline CIrcSession& operator << (CIrcSession& os, const CIrcMessage& m)
{
if( os )
{
os.m_socket.Send(m.AsString().c_str());
os.Notify(&m);
}
return os;
}
////////////////////////////////////////////////////////////////////
// RFC's Identity Server (RFC #1413)
class CIrcIdentServer
{
public :
CIrcIdentServer();
virtual ~CIrcIdentServer();
bool Start(
const char* lpszUserID,
unsigned int uiPort = 113,
const char* lpszResponseType = "UNIX"
);
void Stop();
protected :
String m_sResponseType;
unsigned int m_uiPort;
String m_sUserID;
void DoThread();
private :
Socket m_socket;
HANDLE m_hThread;
static DWORD WINAPI ListenProc(LPVOID pparam);
};
////////////////////////////////////////////////////////////////////
class CIrcDCCServer
{
public :
CIrcDCCServer();
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;
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;
CSendFileDialog* m_pSendFileDialog;
void DoThreadSend();
void DoThreadRecv();
private :
Socket m_socket;
HANDLE m_hThread;
static DWORD WINAPI ListenProc(LPVOID pparam);
};
////////////////////////////////////////////////////////////////////
class CIrcMonitor :
public IIrcSessionMonitor,
private CCrossThreadsMessagingDevice::ICrossThreadsMessagingDeviceMonitor
{
public :
typedef bool (CIrcMonitor::*PfnIrcMessageHandler)(const CIrcMessage* pmsg);
struct LessString
{
bool operator()(const char* s1, const char* s2) const
{ return stricmp(s1, s2) < 0; }
};
typedef std::map<const char*, PfnIrcMessageHandler, LessString> HandlersMap;
struct IrcCommandsMapsListEntry
{
HandlersMap* pHandlersMap;
IrcCommandsMapsListEntry* pBaseHandlersMap;
};
CIrcMonitor(CIrcSession& session);
virtual ~CIrcMonitor();
virtual void OnIrcMessage(const CIrcMessage* pmsg);
protected :
CIrcSession& m_session;
virtual IrcCommandsMapsListEntry* GetIrcCommandsMap()
{ return &m_handlersMapsListEntry; }
virtual void OnIrcAll(const CIrcMessage* pmsg) {}
virtual void OnIrcDefault(const CIrcMessage* pmsg) {}
virtual void OnIrcDisconnected() {}
private :
CCrossThreadsMessagingDevice m_xPost;
static IrcCommandsMapsListEntry m_handlersMapsListEntry;
static HandlersMap m_handlers;
PfnIrcMessageHandler FindMethod(const char* lpszName);
PfnIrcMessageHandler FindMethod(IrcCommandsMapsListEntry* pMapsList, const char* lpszName);
virtual void OnCrossThreadsMessage(WPARAM wParam, LPARAM lParam);
};
// define an IRC command-to-member map.
// put that macro inside the class definition (.H file)
#define DEFINE_IRC_MAP() \
protected : \
virtual IrcCommandsMapsListEntry* GetIrcCommandsMap() \
{ return &m_handlersMapsListEntry; } \
protected : \
static CIrcMonitor::IrcCommandsMapsListEntry m_handlersMapsListEntry; \
static CIrcMonitor::HandlersMap m_handlers; \
protected :
// IRC command-to-member map's declaration.
// add this macro to the class's .CPP file
#define DECLARE_IRC_MAP(this_class, base_class) \
CIrcMonitor::HandlersMap this_class##::m_handlers; \
CIrcMonitor::IrcCommandsMapsListEntry this_class##::m_handlersMapsListEntry \
= { &this_class##::m_handlers, &base_class##::m_handlersMapsListEntry };
// map actual member functions to their associated IRC command.
// put any number of this macro in the class's constructor.
#define IRC_MAP_ENTRY(class_name, name, member) \
m_handlers[(name)] = (PfnIrcMessageHandler)&class_name##::member;
////////////////////////////////////////////////////////////////////
class CIrcDefaultMonitor : public CIrcMonitor
{
public :
CIrcDefaultMonitor(CIrcSession& session);
DEFINE_IRC_MAP()
protected :
bool OnIrc_NICK(const CIrcMessage* pmsg);
bool OnIrc_PING(const CIrcMessage* pmsg);
bool OnIrc_YOURHOST(const CIrcMessage* pmsg);
bool OnIrc_BOUNCE(const CIrcMessage* pmsg);
};
////////////////////////////////////////////////////////////////////
}; // end of namespace irc
////////////////////////////////////////////////////////////////////
#endif // _IRC_H_
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

+13
View File
@@ -0,0 +1,13 @@
//
// GIMPLOBBY.RC2 - resources Microsoft Visual C++ does not edit directly
//
#ifdef APSTUDIO_INVOKED
#error this file is not editable by Microsoft Visual C++
#endif //APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
// Add manually edited resources here...
/////////////////////////////////////////////////////////////////////////////
+51
View File
@@ -0,0 +1,51 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by smlobby.rc
//
#define IDM_ABOUTBOX 0x0010
#define IDD_ABOUTBOX 100
#define IDS_ABOUTBOX 101
#define IDD_GIMPLOBBY_DIALOG 102
#define IDR_MAINFRAME 128
#define IDD_SMLOBBY_DIALOG 129
#define IDD_CONNECT 130
#define IDD_FILEXFER 131
#define IDC_SERVER 1000
#define IDC_PORT 1001
#define IDC_EDIT_ENTRY 1001
#define IDC_NICK 1002
#define IDC_USERID 1003
#define IDC_LIST_GAMES 1003
#define IDC_FULLNAME 1004
#define IDC_EDIT_GAME_INFO 1004
#define IDC_PASSWORD 1005
#define IDC_COMBO_MUSIC 1005
#define IDC_BUTTON_CREATE_GAME 1006
#define IDC_LIST_USERS 1007
#define IDC_EDIT_GAME_NAME 1008
#define IDC_BUTTON_BEGIN_GAME 1009
#define IDC_EDIT_CHAT_MESSAGES 1012
#define IDC_BUTTON_SEND 1013
#define IDC_PROGRESS1 1014
#define IDC_FILENAME 1015
#define IDC_FILESIZE 1016
#define IDC_FOLDERNAME 1017
#define IDC_RECVRNAME 1018
#define IDC_BYTESSENT 1019
#define IDC_TIMELEFT 1020
#define IDC_XFERRATE 1021
#define IDC_XFERSTATUS 1022
#define IDC_TOFROM 1023
#define IDC_SENTRECVD 1024
#define IDD_DIRECTORY 1536
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 136
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1029
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Binary file not shown.
File diff suppressed because it is too large Load Diff
+67
View File
@@ -0,0 +1,67 @@
// smlobby.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "smlobby.h"
#include "smlobbyDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CSmlobbyApp
BEGIN_MESSAGE_MAP(CSmlobbyApp, CWinApp)
//{{AFX_MSG_MAP(CSmlobbyApp)
// NOTE - the ClassWizard will add and remove mapping macros here.
// DO NOT EDIT what you see in these blocks of generated code!
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSmlobbyApp construction
CSmlobbyApp::CSmlobbyApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CSmlobbyApp object
CSmlobbyApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CSmlobbyApp initialization
BOOL CSmlobbyApp::InitInstance()
{
// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need.
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
m_dlg = new CSmlobbyDlg(NULL);
m_pMainWnd = m_dlg;
m_dlg->DoModal();
m_dlg->DestroyWindow();
delete m_dlg;
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
+186
View File
@@ -0,0 +1,186 @@
# Microsoft Developer Studio Project File - Name="smlobby" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Application" 0x0101
CFG=smlobby - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "smlobby.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "smlobby.mak" CFG="smlobby - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "smlobby - Win32 Release" (based on "Win32 (x86) Application")
!MESSAGE "smlobby - Win32 Debug" (based on "Win32 (x86) Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "smlobby - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /machine:I386
!ELSEIF "$(CFG)" == "smlobby - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /debug /machine:I386 /pdbtype:sept
!ENDIF
# Begin Target
# Name "smlobby - Win32 Release"
# Name "smlobby - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\ConnectDlg.cpp
# End Source File
# Begin Source File
SOURCE=.\CrossThreadsMessagingDevice.cpp
# End Source File
# Begin Source File
SOURCE=.\DirectoryDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\EditChat.cpp
# End Source File
# Begin Source File
SOURCE=.\irc.cpp
# End Source File
# Begin Source File
SOURCE=.\SendFileDialog.cpp
# End Source File
# Begin Source File
SOURCE=.\smlobby.cpp
# End Source File
# Begin Source File
SOURCE=.\smlobby.rc
# End Source File
# Begin Source File
SOURCE=.\smlobbyDlg.cpp
# End Source File
# Begin Source File
SOURCE=.\socket.cpp
# End Source File
# Begin Source File
SOURCE=.\StdAfx.cpp
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\ConnectDlg.h
# End Source File
# Begin Source File
SOURCE=.\CrossThreadsMessagingDevice.h
# End Source File
# Begin Source File
SOURCE=.\DirectoryDialog.h
# End Source File
# Begin Source File
SOURCE=.\EditChat.h
# End Source File
# Begin Source File
SOURCE=.\irc.h
# End Source File
# Begin Source File
SOURCE=.\SendFileDialog.h
# End Source File
# Begin Source File
SOURCE=.\smlobby.h
# End Source File
# Begin Source File
SOURCE=.\smlobbyDlg.h
# End Source File
# Begin Source File
SOURCE=.\socket.h
# End Source File
# Begin Source File
SOURCE=.\StdAfx.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project
+29
View File
@@ -0,0 +1,29 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "smlobby"=.\smlobby.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################
+54
View File
@@ -0,0 +1,54 @@
// smlobby.h : main header file for the Smlobby application
//
#if !defined(AFX_Smlobby_H__0D0E3C89_DD15_4558_AEA0_3711BD2EC0AA__INCLUDED_)
#define AFX_Smlobby_H__0D0E3C89_DD15_4558_AEA0_3711BD2EC0AA__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif
#include "resource2.h" // main symbols
#include "smlobbyDlg.h"
/////////////////////////////////////////////////////////////////////////////
// CSmlobbyApp:
// See smlobby.cpp for the implementation of this class
//
class CSmlobbyApp : public CWinApp
{
private:
CSmlobbyDlg *m_dlg;
public:
CSmlobbyApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSmlobbyApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CSmlobbyApp)
// NOTE - the ClassWizard will add and remove member functions here.
// DO NOT EDIT what you see in these blocks of generated code !
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_Smlobby_H__0D0E3C89_DD15_4558_AEA0_3711BD2EC0AA__INCLUDED_)
+1
View File
@@ -0,0 +1 @@
Microsoft C/C++ program database 2.00
Binary file not shown.
+329
View File
@@ -0,0 +1,329 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource2.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource2.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"#define _AFX_NO_SPLITTER_RESOURCES\r\n"
"#define _AFX_NO_OLE_RESOURCES\r\n"
"#define _AFX_NO_TRACKER_RESOURCES\r\n"
"#define _AFX_NO_PROPERTY_RESOURCES\r\n"
"\r\n"
"#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
"#ifdef _WIN32\r\n"
"LANGUAGE 9, 1\r\n"
"#pragma code_page(1252)\r\n"
"#endif //_WIN32\r\n"
"#include ""res\\smlobby.rc2"" // non-Microsoft Visual C++ edited resources\r\n"
"#include ""afxres.rc"" // Standard components\r\n"
"#endif\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDR_MAINFRAME ICON DISCARDABLE "res\\smlobby.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_ABOUTBOX DIALOG DISCARDABLE 0, 0, 235, 55
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About smlobby"
FONT 8, "MS Sans Serif"
BEGIN
ICON IDR_MAINFRAME,IDC_STATIC,11,17,20,20
LTEXT "smlobby Version 1.0",IDC_STATIC,40,10,119,8,SS_NOPREFIX
LTEXT "Copyright (C) 2002",IDC_STATIC,40,25,119,8
DEFPUSHBUTTON "OK",IDOK,178,7,50,14,WS_GROUP
END
IDD_SMLOBBY_DIALOG DIALOGEX 0, 0, 464, 330
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "StepMania Lobby"
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 |
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
COMBOBOX IDC_COMBO_MUSIC,278,35,170,15,CBS_DROPDOWN | CBS_SORT |
WS_VSCROLL | WS_TABSTOP
LTEXT "Select Music:",IDC_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
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
END
IDD_FILEXFER DIALOG DISCARDABLE 0, 0, 186, 173
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "File Transfer"
FONT 8, "MS Sans Serif"
BEGIN
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 "Size:",IDC_STATIC,7,30,33,8
LTEXT "Folder:",IDC_STATIC,7,40,33,8
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 "Time left:",IDC_STATIC,7,98,33,8
LTEXT "Rate:",IDC_STATIC,7,107,33,8
LTEXT "Status:",IDC_STATIC,7,117,33,8
LTEXT "",IDC_FILENAME,43,21,136,8
LTEXT "",IDC_FILESIZE,43,30,136,8
LTEXT "",IDC_FOLDERNAME,43,40,136,8
LTEXT "",IDC_RECVRNAME,43,49,136,8
LTEXT "",IDC_BYTESSENT,43,89,39,8
LTEXT "",IDC_TIMELEFT,43,98,80,8
LTEXT "",IDC_XFERRATE,43,107,71,8
LTEXT "",IDC_XFERSTATUS,43,117,77,36
END
IDD_DIRECTORY DIALOG DISCARDABLE 109, 35, 165, 134
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Open"
FONT 8, "Helv"
BEGIN
LTEXT "File &Name:",1090,168,0,76,10
EDITTEXT 1152,168,10,90,12,ES_AUTOHSCROLL | ES_OEMCONVERT
LISTBOX 1120,168,26,90,68,LBS_SORT | LBS_OWNERDRAWFIXED |
LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL |
WS_TABSTOP
LTEXT "&Directories:",-1,7,6,92,9
LTEXT "",1088,7,18,92,9,SS_NOPREFIX
LISTBOX 1121,7,32,92,68,LBS_SORT | LBS_OWNERDRAWFIXED |
LBS_HASSTRINGS | LBS_DISABLENOSCROLL | WS_VSCROLL |
WS_TABSTOP
LTEXT "List Files of &Type:",1089,168,98,90,9
COMBOBOX 1136,168,108,90,36,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL |
WS_BORDER | WS_VSCROLL | WS_TABSTOP
LTEXT "Dri&ves:",1091,7,104,92,9
COMBOBOX 1137,7,114,92,68,CBS_DROPDOWNLIST | CBS_OWNERDRAWFIXED |
CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | WS_BORDER |
WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "OK",IDOK,105,6,50,14,WS_GROUP
PUSHBUTTON "Cancel",IDCANCEL,105,24,50,14,WS_GROUP
PUSHBUTTON "&Help",1038,105,46,50,14,WS_GROUP
CONTROL "&Read Only",1040,"Button",BS_AUTOCHECKBOX | WS_GROUP |
WS_TABSTOP,105,68,50,12
END
#ifndef _MAC
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,0,1
PRODUCTVERSION 1,0,0,1
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904B0"
BEGIN
VALUE "CompanyName", "\0"
VALUE "FileDescription", "smlobby MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "smlobby\0"
VALUE "LegalCopyright", "Copyright (C) 2002\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "smlobby.EXE\0"
VALUE "ProductName", "smlobby Application\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
#endif // !_MAC
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_FILEXFER, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 166
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_ABOUTBOX "&About smlobby..."
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
// Unknown language: 0xD, 0x1 resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HEB)
#ifdef _WIN32
LANGUAGE 0xD, 0x1
#pragma code_page(1255)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_CONNECT DIALOG DISCARDABLE 0, 0, 185, 161
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Connect"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "&Server",IDC_STATIC,7,9,22,8
EDITTEXT IDC_SERVER,67,7,92,14,ES_AUTOHSCROLL
LTEXT "&Port",IDC_STATIC,7,26,14,8
EDITTEXT IDC_PORT,67,24,54,14,ES_AUTOHSCROLL | ES_NUMBER
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,46,171,1
LTEXT "&Nick",IDC_STATIC,7,55,16,8
EDITTEXT IDC_NICK,67,53,92,14,ES_AUTOHSCROLL
LTEXT "User &ID",IDC_STATIC,7,74,25,8
EDITTEXT IDC_USERID,67,72,92,14,ES_AUTOHSCROLL
LTEXT "&Full Name",IDC_STATIC,7,92,32,8
EDITTEXT IDC_FULLNAME,67,90,92,14,ES_AUTOHSCROLL
LTEXT "Pass&word",IDC_STATIC,7,111,32,8
EDITTEXT IDC_PASSWORD,67,108,92,14,ES_AUTOHSCROLL
CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,7,131,171,1
DEFPUSHBUTTON "Connect",IDOK,26,140,50,14
PUSHBUTTON "Cancel",IDCANCEL,109,140,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_CONNECT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 178
TOPMARGIN, 7
BOTTOMMARGIN, 154
END
END
#endif // APSTUDIO_INVOKED
#endif // Unknown language: 0xD, 0x1 resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#define _AFX_NO_SPLITTER_RESOURCES
#define _AFX_NO_OLE_RESOURCES
#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE 9, 1
#pragma code_page(1252)
#endif //_WIN32
#include "res\smlobby.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED
+628
View File
@@ -0,0 +1,628 @@
// smlobbyDlg.cpp : implementation file
//
#include "stdafx.h"
#include "smlobby.h"
#include "smlobbyDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#pragma comment(lib, "wsock32.lib")
#include "ConnectDlg.h"
#include "DirectoryDialog.h"
/////////////////////////////////////////////////////////////////////////////
// global objects
static const NetworkInit g_wsInit;
static const unsigned short FILE_XFER_RATE = 4096;
irc::CIrcSession g_ircSession;
/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About
class CAboutDlg : public CDialog
{
public:
CAboutDlg();
// Dialog Data
//{{AFX_DATA(CAboutDlg)
enum { IDD = IDD_ABOUTBOX };
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CAboutDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
//{{AFX_MSG(CAboutDlg)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
//{{AFX_DATA_INIT(CAboutDlg)
//}}AFX_DATA_INIT
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CAboutDlg)
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
//{{AFX_MSG_MAP(CAboutDlg)
// No message handlers
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSmlobbyDlg dialog
CSmlobbyDlg::CSmlobbyDlg(CWnd* pParent /*=NULL*/)
: CDialog(CSmlobbyDlg::IDD, pParent), irc::CIrcDefaultMonitor(g_ircSession)
{
//{{AFX_DATA_INIT(CSmlobbyDlg)
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CSmlobbyDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CSmlobbyDlg)
DDX_Control(pDX, IDC_EDIT_GAME_NAME, m_editGameName);
DDX_Control(pDX, IDC_EDIT_GAME_INFO, m_editGameInfo);
DDX_Control(pDX, IDC_LIST_USERS, m_listUsers);
DDX_Control(pDX, IDC_EDIT_ENTRY, m_editEntry);
DDX_Control(pDX, IDC_EDIT_CHAT_MESSAGES, m_editChatMessages);
DDX_Control(pDX, IDC_LIST_GAMES, m_listGames);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CSmlobbyDlg, CDialog)
//{{AFX_MSG_MAP(CSmlobbyDlg)
ON_WM_SYSCOMMAND()
ON_WM_QUERYDRAGICON()
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)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CSmlobbyDlg message handlers
BOOL CSmlobbyDlg::OnInitDialog()
{
CDialog::OnInitDialog();
//Tell windows we have no default push button
SetDefID(-1);
// Add "About..." menu item to system menu.
// IDM_ABOUTBOX must be in the system command range.
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
//Add IRC reply call backs
IRC_MAP_ENTRY(CSmlobbyDlg, "JOIN", OnIrc_JOIN)
IRC_MAP_ENTRY(CSmlobbyDlg, "KICK", OnIrc_KICK)
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, "PRIVMSG", OnIrc_PRIVMSG)
IRC_MAP_ENTRY(CSmlobbyDlg, "002", OnIrc_YOURHOST)
IRC_MAP_ENTRY(CSmlobbyDlg, "321", OnIrc_RPL_LISTSTART)
IRC_MAP_ENTRY(CSmlobbyDlg, "322", OnIrc_RPL_LIST)
IRC_MAP_ENTRY(CSmlobbyDlg, "323", OnIrc_IgnoreMesg) //RPL_LISTEND
IRC_MAP_ENTRY(CSmlobbyDlg, "331", OnIrc_IgnoreMesg) //RPL_NOTOPIC
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
//Initialize IRC Server connection dialog
CConnectDlg dlg;
dlg.m_sServer = _T("128.208.46.94");
dlg.m_uiPort = 6667;
dlg.m_sNick = _T("smuser");
dlg.m_sUserID = _T("vm");
dlg.m_sFullName = _T("vm");
if( dlg.DoModal() != IDOK )
return TRUE;
// set this document object as the session's monitor
g_ircSession.AddMonitor(this);
CIrcSessionInfo si;
si.sServer = dlg.m_sServer;
si.iPort = dlg.m_uiPort;
si.sNick = dlg.m_sNick;
si.sUserID = dlg.m_sUserID;
si.sFullName = dlg.m_sFullName;
si.sPassword = dlg.m_sPassword;
si.bIdentServer = true;
si.iIdentServerPort = 113;
si.sIdentServerType = "UNIX";
si.sCurrentChatRoom = "";
bool m_bOk = g_ircSession.Connect(si);
if( !m_bOk )
return FALSE;
return TRUE; // return TRUE unless you set the focus to a control
}
void CSmlobbyDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialog::OnSysCommand(nID, lParam);
}
}
// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.
void CSmlobbyDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting
SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}
// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CSmlobbyDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
bool CSmlobbyDlg::OnIrc_YOURHOST(const CIrcMessage* pmsg)
{
CIrcDefaultMonitor::OnIrc_YOURHOST(pmsg);
//query the server for a list of chat rooms
g_ircSession << irc::CIrcMessage(CString("list"));
return false;
}
bool CSmlobbyDlg::OnIrc_NICK(const CIrcMessage* pmsg)
{
CIrcDefaultMonitor::OnIrc_NICK(pmsg);
if( pmsg->prefix.sNick == m_session.GetInfo().sNick && (pmsg->parameters.size() > 0) )
{
}
return false;
}
bool CSmlobbyDlg::OnIrc_PRIVMSG(const CIrcMessage* pmsg)
{
//See if were being sent a DCC command
//STIL UNDER DEVELOPMENT!
//if (OnIrc_DCC_RECV(pmsg))
// return true;
UpdateChatMessages( pmsg );
return true;
}
bool CSmlobbyDlg::OnIrc_DCC_RECV(const CIrcMessage *pmsg)
{
//Make sure we have a parameter
if ( pmsg->parameters.size() < 1 )
return false;
//Make sure it's a DCC send
if ( std::string::npos == pmsg->parameters[1].find("\001DCC SEND") )
return false;
//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;
if ( 4 != sscanf(pszRawString, "\001DCC SEND %255s %lu %u %lu",
&szFilename, &ulPartnerIP, &uiPartnerPort, &ulFileSize) )
return false;
//Open a dialog box so user can decide where to save file
CDirectoryDialog DirDlg(FALSE, NULL, NULL, OFN_SHOWHELP | OFN_HIDEREADONLY |
OFN_OVERWRITEPROMPT | OFN_ENABLETEMPLATE, NULL,
NULL);
DirDlg.m_ofn.hInstance = AfxGetInstanceHandle();
DirDlg.m_ofn.lpTemplateName = MAKEINTRESOURCE(IDD_DIRECTORY);
if ( IDOK != DirDlg.DoModal())
return false;
//We now have enough info to fire off a thread which downloads the file
CIrcDCCServer DCCServer;
CString filename(szFilename);
CString partner(pmsg->prefix.sNick.c_str());
//DCCServer.Start(filename, DirDlg.GetPathName(), partner,
// ulPartnerIP, uiPartnerPort, ulFileSize, FILE_XFER_RATE);
DCCServer.Start(filename, "C:", partner,
ulPartnerIP, uiPartnerPort, ulFileSize, FILE_XFER_RATE);
return true;
}
bool CSmlobbyDlg::OnIrc_JOIN(const CIrcMessage* pmsg)
{
//Put update on message window
UpdateChatMessages( pmsg );
//Remember which chat room we joined
String chatRoomName(pmsg->parameters[0].c_str());
g_ircSession.GetInfo().sCurrentChatRoom = chatRoomName;
//query the server for a list of names in this room
g_ircSession << irc::CIrcMessage(CString("names ") + CString(chatRoomName.c_str()));
//query the server for a list of rooms (could have changed)
g_ircSession << irc::CIrcMessage(CString("list"));
return true;
}
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();
//forget which chat room we joined
g_ircSession.GetInfo().sCurrentChatRoom = "";
//query the server for a list of chat rooms
g_ircSession << irc::CIrcMessage(CString("list"));
UpdateChatMessages( pmsg );
return true;
}
bool CSmlobbyDlg::OnIrc_KICK(const CIrcMessage* pmsg)
{
if( !pmsg->prefix.sNick.length() )
return false;
UpdateChatMessages( pmsg );
return true;
}
bool CSmlobbyDlg::OnIrc_MODE(const CIrcMessage* pmsg)
{
if( !pmsg->prefix.sNick.length() )
return false;
if( pmsg->prefix.sNick == m_session.GetInfo().sNick )
return false;
UpdateChatMessages( pmsg );
return true;
}
bool CSmlobbyDlg::OnIrc_RPL_LISTSTART(const CIrcMessage *pmsg)
{
//Were going to be getting a new list of rooms
//so clear out the old ones
m_listGames.ResetContent();
return true;
}
bool CSmlobbyDlg::OnIrc_RPL_LIST(const CIrcMessage *pmsg)
{
//Add the current game to the list
//msg Format: "<channel> <# visible> :<topic>"
String name = pmsg->parameters[1] + " (" + pmsg->parameters[2] + ")";
m_listGames.AddString(name.c_str());
return true;
}
bool CSmlobbyDlg::OnIrc_RPL_TOPIC(const CIrcMessage *pmsg)
{
//Clean out the game info box
m_editGameInfo.SetSel(0, -1);
m_editGameInfo.Clear();
//Put the info for a game up in the game info box
//msg Format: "<channel> :<topic>"
//topic format: "GameName\nserverIP\nServerIRCName\nSongHash"
std::vector<String> vecGameParams;
const char* p1 = pmsg->parameters[2].c_str();
const char* p2 = p1;
//Extract all of the topic params
while( *p1 )
{
// seek end of name
while( *p2 && *p2!=' ' ) p2++;
//add name to the list
vecGameParams.push_back(String(p1, p2 - p1));
// eat white space
while( *p2 && *p2==' ' ) p2++;
p1 = p2;
}
//somehow we lost some game info
if (vecGameParams.size() != 4) 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());
return true;
}
bool CSmlobbyDlg::OnIrc_RPL_NAMREPLY(const CIrcMessage *pmsg)
{
//Reset the names list
m_listUsers.ResetContent();
//now dump all of the users into the user list
//msg format: "<channel> :[[@|+]<nick> [[@|+]<nick> [...]]]"
const char* p1 = pmsg->parameters[3].c_str();
const char* p2 = p1;
//keep trying to read off names while the list isn't null
while( *p1 )
{
// seek end of name
while( *p2 && !isspace(*p2) ) p2++;
//add name to the list
m_listUsers.AddString(String(p1, p2 - p1).c_str());
// eat white space
while( *p2 && isspace(*p2) ) p2++;
p1 = p2;
}
return true;
}
void CSmlobbyDlg::OnIrcDefault(const CIrcMessage* pmsg)
{
CIrcDefaultMonitor::OnIrcDefault(pmsg);
if( pmsg && m_session.GetInfo().sServerName.length() )
{
UpdateChatMessages( pmsg );
}
}
void CSmlobbyDlg::OnIrcDisconnected()
{
AfxGetMainWnd()->PostMessage(WM_COMMAND, ID_FILE_CLOSE);
}
void CSmlobbyDlg::OnDestroy()
{
CDialog::OnDestroy();
g_ircSession.Disconnect();
g_ircSession.RemoveMonitor(this);
//Close the parent application
AfxGetApp()->ExitInstance();
}
void CSmlobbyDlg::UpdateChatMessages( const CIrcMessage* p )
{
if( p )
{
m_editChatMessages.SetSel(-1, 0);
m_editChatMessages.SendMessage(EM_SCROLLCARET);
#ifdef _DEBUG
m_editChatMessages.ReplaceSel((p->sCommand + " ").c_str());
#endif
if (p->sCommand == "NOTICE")
{
String param = p->parameters[1];
const char *c_param = param.c_str();
p=p;
}
if( p->prefix.sNick.length() )
{
m_editChatMessages.ReplaceSel(("<" + p->prefix.sNick + "> ").c_str());
}
for(int i=1; i < p->parameters.size(); i++)
{
m_editChatMessages.ReplaceSel((p->parameters[i] + " ").c_str());
}
m_editChatMessages.ReplaceSel("\r\n");
}
}
void CSmlobbyDlg::OnDblclkListGames()
{
//Get the game name that was currently selected
int nIndex = m_listGames.GetCurSel();
CString strGameName;
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);
}
}
void CSmlobbyDlg::OnSelchangeListGames()
{
//Get the game name that was currently selected
int nIndex = m_listGames.GetCurSel();
char szGameName[128];
int nDummy;
if (nIndex != LB_ERR)
{
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("topic ") + CString(szGameName));
}
}
void CSmlobbyDlg::OnButtonCreateGame()
{
//Strip all non alphanumeric characters from the name
// so irc will be ok with it as a chat room name
CString gameName;
char szRawGameName[256];
m_editGameName.GetLine(0, szRawGameName, 255);
for (int i = 0; i < strlen(szRawGameName); i++)
{
if ( isalnum(szRawGameName[i]) )
gameName += szRawGameName[i];
}
//Make sure user has given us a game name
if (gameName.GetLength() <= 0)
{
MessageBox("You need some letters or numbers in your name!");
return;
}
//Make sure no one else has this name
if (!IsUniqueGameName(gameName))
{
MessageBox("Game already exists with that name!");
return;
}
//Tell the server that we wanted to create a chat room
g_ircSession << irc::CIrcMessage(CString("join ") + "#" + gameName);
//Get the IP address of our machine
IPaddress ipaddr;
char szHostName[256];
gethostname(szHostName, 256);
SDLNet_ResolveHost(&ipaddr, szHostName, 0);
unsigned char *ip = (unsigned char *)&(ipaddr.host);
char host_ip_str[20];
sprintf(host_ip_str, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]);
//Insert song name/hash code here
char songHash[12] = "0x00000000";
//Now tell the server our game info
g_ircSession << irc::CIrcMessage(CString("topic #") + gameName + CString(" :")
+ gameName + CString(" ")
+ CString(host_ip_str) + CString(" ")
+ CString(g_ircSession.GetInfo().sNick.c_str()) + CString(" ")
+ CString(songHash));
}
bool CSmlobbyDlg::IsUniqueGameName(const CString GameName)
{
CString aName;
//Search list of games to make sure ours is unique
for (int i = 0; i < m_listGames.GetCount(); i++)
{
m_listGames.GetText(i, aName);
if (aName == GameName)
return false;
}
return true;
}
+86
View File
@@ -0,0 +1,86 @@
// smlobbyDlg.h : header file
//
#if !defined(AFX_SmlobbyDLG_H__B8E7A228_8094_4516_894C_9E613B74B27F__INCLUDED_)
#define AFX_SmlobbyDLG_H__B8E7A228_8094_4516_894C_9E613B74B27F__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "irc.h"
#include "EditChat.h"
#include <vector>
using namespace irc;
/////////////////////////////////////////////////////////////////////////////
// CSmlobbyDlg dialog
class CSmlobbyDlg : public CDialog, public CIrcDefaultMonitor
{
// Construction
public:
CSmlobbyDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CSmlobbyDlg)
enum { IDD = IDD_SMLOBBY_DIALOG };
CEdit m_editGameName;
CEdit m_editGameInfo;
CListBox m_listUsers;
CEditChat m_editEntry;
CEdit m_editChatMessages;
CListBox m_listGames;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSmlobbyDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CSmlobbyDlg)
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg HCURSOR OnQueryDragIcon();
virtual BOOL OnInitDialog();
virtual void OnPaint();
virtual void OnDestroy();
afx_msg void OnDblclkListGames();
afx_msg void OnSelchangeListGames();
afx_msg void OnButtonCreateGame();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
bool OnIrc_YOURHOST(const CIrcMessage* pmsg);
bool OnIrc_NICK(const CIrcMessage* pmsg);
bool OnIrc_PRIVMSG(const CIrcMessage* pmsg);
bool OnIrc_JOIN(const CIrcMessage* pmsg);
bool OnIrc_PART(const CIrcMessage* pmsg);
bool OnIrc_KICK(const CIrcMessage* pmsg);
bool OnIrc_MODE(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_RECV(const CIrcMessage *pmsg);
bool OnIrc_IgnoreMesg(const CIrcMessage *pmsg) { return true; }
virtual void OnIrcDefault(const CIrcMessage* pmsg);
virtual void OnIrcDisconnected();
void UpdateChatMessages( const CIrcMessage* p );
bool IsUniqueGameName(const CString GameName);
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SmlobbyDLG_H__B8E7A228_8094_4516_894C_9E613B74B27F__INCLUDED_)
+127
View File
@@ -0,0 +1,127 @@
// socket.cpp
#include "StdAfx.h"
#include <stdio.h>
#include "socket.h"
//////////////////////////////////////////////////////////////////////////
NetworkInit::NetworkInit()
{
if (-1==SDL_Init(0))
{
printf("SDL_Init: %s\n", SDL_GetError());
exit(1);
}
if (-1==SDLNet_Init())
{
printf("SDLNet_Init: %s\n", SDLNet_GetError());
exit(2);
}
}
NetworkInit::~NetworkInit()
{
SDLNet_Quit();
SDL_Quit();
}
//////////////////////////////////////////////////////////////////////////
InetAddr::InetAddr(short wPort)
{
host = 0xFFFFFFFFL;
port = wPort;
}
InetAddr::InetAddr(const char* lpszAddress, short wPort)
{
Resolve(lpszAddress, wPort);
}
InetAddr& InetAddr::operator = (char* lpszAddress)
{
Resolve(lpszAddress);
return *this;
}
void InetAddr::Resolve(const char* lpszAddress, short wPort)
{
SDLNet_ResolveHost((IPaddress*)this, (char *)lpszAddress, wPort);
}
//////////////////////////////////////////////////////////////////////////
Socket::Socket()
: m_sock(NULL), m_bOwnSocket(false)
{
}
Socket::Socket(const Socket& s)
: m_sock(s.m_sock), m_bOwnSocket(false)
{
}
Socket::Socket(TCPsocket s)
: m_sock(s), m_bOwnSocket(false)
{
}
Socket::~Socket()
{
if( m_bOwnSocket && m_sock != NULL )
Close();
}
void Socket::Close()
{
if (m_sock) SDLNet_TCP_Close(m_sock);
m_sock = NULL;
}
bool Socket::Bind(const InetAddr& addr)
{
m_bind_addr = addr;
return true;
}
bool Socket::Connect(const InetAddr& ip)
{
m_sock = SDLNet_TCP_Open((IPaddress *)&ip);
return m_sock != NULL;
}
bool Socket::Listen()
{
m_sock = SDLNet_TCP_Open((IPaddress *)&m_bind_addr);
return m_sock != NULL;
}
Socket Socket::Accept()
{
return Socket(SDLNet_TCP_Accept(m_sock));
}
int Socket::Send(const unsigned char* buf, int cbBuf)
{
return SDLNet_TCP_Send(m_sock, (void *)buf, cbBuf);
}
int Socket::Send(const char* fmt, ...)
{
va_list marker;
va_start(marker, fmt);
char szBuf[1024*4];
vsprintf(szBuf, fmt, marker);
va_end(marker);
return Send((unsigned char*)szBuf, strlen(szBuf));
}
int Socket::Receive(unsigned char* buf, int cbBuf)
{
return SDLNet_TCP_Recv(m_sock, (char*)buf, cbBuf);
}
+71
View File
@@ -0,0 +1,71 @@
// socket.h
#ifndef SOCKET_H
#define SOCKET_H
#pragma comment(lib, "sdl_net/lib/SDL.lib")
#pragma comment(lib, "sdl_net/lib/SDL_net.lib")
#include "sdl_net/include/SDL_net.h"
//HACK: SDL_net doesn't appear to have a way to get the host name
// which I need to resolve the machine's ip address
// (no. using "localhost" doesn't work. you'll get 127.0.0.1 @_@)
#ifdef WIN32
//int FAR PASCAL gethostname(char FAR * name, int namelen);
#undef INADDR_ANY
#undef INADDR_NONE
#include <winsock2.h>
#elif UNIX
#include <unistd.h>
#include <arpa/inet.h>
#endif
class NetworkInit
{
public :
NetworkInit();
~NetworkInit();
};
class InetAddr : public IPaddress
{
public :
InetAddr(short wPort = 0);
InetAddr(const char* lpszAddress, short wPort = 0);
InetAddr& operator = (char* lpszAddress);
protected :
void Resolve(const char* lpszAddress, short wPort = 0);
};
class Socket
{
public :
Socket();
Socket(TCPsocket s);
Socket(const Socket& s);
virtual ~Socket();
void Close();
bool Bind(const InetAddr& addr);
bool Connect(const InetAddr& addr);
bool Listen();
Socket Accept();
int Send(const unsigned char* buf, int cbBuf);
int Send(const char* fmt, ...);
int Receive(unsigned char* buf, int cbBuf);
operator TCPsocket& () const { return (TCPsocket&)m_sock; }
operator bool() const { return m_sock != NULL; }
protected:
InetAddr m_bind_addr;
TCPsocket m_sock;
private :
bool m_bOwnSocket;
};
#endif