1
0
mirror of https://github.com/alliedmodders/hl2sdk.git synced 2025-09-21 04:56:01 +08:00

Update from SDK 2013

This commit is contained in:
Kenzzer
2025-02-19 18:39:00 -05:00
committed by Nicholas Hastings
parent 6d5c024820
commit 94b660e16e
7474 changed files with 2597282 additions and 1254065 deletions

View File

@ -0,0 +1,22 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#ifndef MESSAGERECVMGR_H
#define MESSAGERECVMGR_H
#ifdef _WIN32
#pragma once
#endif
class IMessageRecvMgr
{
public:
};
#endif // MESSAGERECVMGR_H

View File

@ -0,0 +1,77 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// MessageWatch.cpp : Defines the class behaviors for the application.
//
#include "stdafx.h"
#include "MessageWatch.h"
#include "MessageWatchDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMessageWatchApp
BEGIN_MESSAGE_MAP(CMessageWatchApp, CWinApp)
//{{AFX_MSG_MAP(CMessageWatchApp)
// 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()
/////////////////////////////////////////////////////////////////////////////
// CMessageWatchApp construction
CMessageWatchApp::CMessageWatchApp()
{
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}
/////////////////////////////////////////////////////////////////////////////
// The one and only CMessageWatchApp object
CMessageWatchApp theApp;
/////////////////////////////////////////////////////////////////////////////
// CMessageWatchApp initialization
BOOL CMessageWatchApp::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
CMessageWatchDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
// TODO: Place code here to handle when the dialog is
// dismissed with OK
}
else if (nResponse == IDCANCEL)
{
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
}
return FALSE;
}

View File

@ -0,0 +1,56 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// MessageWatch.h : main header file for the MESSAGEWATCH application
//
#if !defined(AFX_MESSAGEWATCH_H__72A09EC9_2B19_4AC5_A281_5FAD41F6DFCA__INCLUDED_)
#define AFX_MESSAGEWATCH_H__72A09EC9_2B19_4AC5_A281_5FAD41F6DFCA__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 "resource.h" // main symbols
/////////////////////////////////////////////////////////////////////////////
// CMessageWatchApp:
// See MessageWatch.cpp for the implementation of this class
//
class CMessageWatchApp : public CWinApp
{
public:
CMessageWatchApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMessageWatchApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CMessageWatchApp)
// 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_MESSAGEWATCH_H__72A09EC9_2B19_4AC5_A281_5FAD41F6DFCA__INCLUDED_)

View File

@ -0,0 +1,194 @@
//Microsoft Developer Studio generated resource script.
//
#include "resource.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
"resource.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\\MessageWatch.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\\MessageWatch.ico"
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MESSAGEWATCH_DIALOG DIALOGEX 0, 0, 232, 147
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "MessageWatch"
FONT 8, "MS Sans Serif"
BEGIN
PUSHBUTTON "Quit",IDCANCEL,175,126,50,14
LISTBOX IDC_MACHINES,7,7,218,114,LBS_SORT | LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&Show All",IDSHOWALL,7,126,50,14
PUSHBUTTON "&Hide All",IDHIDEALL,91,126,50,14
END
IDD_OUTPUT DIALOG DISCARDABLE 0, 0, 320, 225
STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Output"
FONT 8, "MS Sans Serif"
BEGIN
EDITTEXT IDC_DEBUG_OUTPUT,7,7,306,211,ES_MULTILINE | ES_READONLY |
WS_VSCROLL
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", "MessageWatch MFC Application\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "MessageWatch\0"
VALUE "LegalCopyright", "Copyright (C) 2002\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "MessageWatch.EXE\0"
VALUE "ProductName", "MessageWatch 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_MESSAGEWATCH_DIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 225
TOPMARGIN, 7
BOTTOMMARGIN, 140
END
IDD_OUTPUT, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 313
TOPMARGIN, 7
BOTTOMMARGIN, 218
END
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) 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\MessageWatch.rc2" // non-Microsoft Visual C++ edited resources
#include "afxres.rc" // Standard components
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,324 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// MessageWatchDlg.cpp : implementation file
//
#include "stdafx.h"
#include "MessageWatch.h"
#include "MessageWatchDlg.h"
#include "messagemgr.h"
#include "tier1/strtools.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_STARTIDLE (WM_USER + 565)
// --------------------------------------------------------------------------- //
// CSender.
// --------------------------------------------------------------------------- //
CSender::CSender()
{
m_pSocket = NULL;
m_pConsoleWnd = NULL;
}
CSender::~CSender()
{
if ( m_pSocket )
m_pSocket->Release();
if ( m_pConsoleWnd )
m_pConsoleWnd->Release();
}
/////////////////////////////////////////////////////////////////////////////
// CMessageWatchDlg dialog
CMessageWatchDlg::CMessageWatchDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMessageWatchDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMessageWatchDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_pListenSocket = NULL;
}
CMessageWatchDlg::~CMessageWatchDlg()
{
// destroy the sender objects.
if ( m_pListenSocket )
m_pListenSocket->Release();
}
void CMessageWatchDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMessageWatchDlg)
DDX_Control(pDX, IDC_MACHINES, m_Machines);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMessageWatchDlg, CDialog)
//{{AFX_MSG_MAP(CMessageWatchDlg)
ON_MESSAGE(WM_STARTIDLE, OnStartIdle)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_LBN_DBLCLK(IDC_MACHINES, OnDblclkMachines)
ON_BN_CLICKED(IDSHOWALL, OnShowall)
ON_BN_CLICKED(IDHIDEALL, OnHideall)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CMessageWatchDlg message handlers
BOOL CMessageWatchDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// 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
// Setup our listen socket and thread.
m_pListenSocket = CreateIPSocket();
m_pListenSocket->BindToAny( MSGMGR_BROADCAST_PORT );
m_cWinIdle.StartIdle( GetSafeHwnd(), WM_STARTIDLE, 0, 0, 100 );
m_cWinIdle.NextIdle();
return TRUE; // return TRUE unless you set the focus to a control
}
LONG CMessageWatchDlg::OnStartIdle( UINT, LONG )
{
MSG msg;
if (!PeekMessage(&msg, GetSafeHwnd(), 0,0, PM_NOREMOVE))
OnIdle();
m_cWinIdle.NextIdle();
return 0;
}
void CMessageWatchDlg::OnIdle()
{
// Kill dead connections.
int iNext;
for ( int iSender=m_Senders.Head(); iSender != m_Senders.InvalidIndex(); iSender = iNext )
{
iNext = m_Senders.Next( iSender );
CSender *pSender = m_Senders[iSender];
if ( pSender->m_pSocket && !pSender->m_pSocket->IsConnected() )
{
// Just release the socket so the text stays there.
pSender->m_pSocket->Release();
pSender->m_pSocket = NULL;
}
}
// Look for new connections.
while ( 1 )
{
CIPAddr ipFrom;
char data[16];
int len = m_pListenSocket->RecvFrom( data, sizeof( data ), &ipFrom );
if ( len == -1 )
break;
if ( data[0] == MSGMGR_PACKETID_ANNOUNCE_PRESENCE &&
*((int*)&data[1]) == MSGMGR_VERSION )
{
int iPort = *((int*)&data[5]);
// See if we have a machine with this info yet.
CIPAddr connectAddr = ipFrom;
connectAddr.port = iPort;
// NOTE: we'll accept connections from machines we were connected to earlier but
// lost the connection to.
CSender *pSender = FindSenderByAddr( ipFrom.ip );
if ( !pSender || !pSender->m_pSocket )
{
// 'nitiate the connection.
ITCPSocket *pNew = CreateTCPSocket();
if ( pNew->BindToAny( 0 ) && TCPSocket_Connect( pNew, &connectAddr, 1000 ) )
{
char nameStr[256];
char title[512];
if ( !ConvertIPAddrToString( &ipFrom, nameStr, sizeof( nameStr ) ) )
Q_snprintf( nameStr, sizeof( nameStr ), "%d.%d.%d.%d", ipFrom.ip[0], ipFrom.ip[1], ipFrom.ip[2], ipFrom.ip[3] );
Q_snprintf( title, sizeof( title ), "%s:%d", nameStr, iPort );
// If the sender didn't exist yet, add a new one.
if ( !pSender )
{
pSender = new CSender;
IConsoleWnd *pWnd = CreateConsoleWnd(
AfxGetInstanceHandle(),
IDD_OUTPUT,
IDC_DEBUG_OUTPUT,
false
);
pSender->m_pConsoleWnd = pWnd;
pWnd->SetTitle( title );
Q_strncpy( pSender->m_Name, title, sizeof( pSender->m_Name ) );
m_Senders.AddToTail( pSender );
m_Machines.AddString( pSender->m_Name );
}
pSender->m_Addr = connectAddr;
pSender->m_pSocket = pNew;
}
else
{
pNew->Release();
}
}
}
}
// Read input from our current connections.
FOR_EACH_LL( m_Senders, i )
{
CSender *pSender = m_Senders[i];
while ( 1 )
{
if ( !pSender->m_pSocket )
break;
CUtlVector<unsigned char> data;
if ( !pSender->m_pSocket->Recv( data ) )
break;
if ( data[0] == MSGMGR_PACKETID_MSG )
{
char *pMsg = (char*)&data[1];
pSender->m_pConsoleWnd->PrintToConsole( pMsg );
OutputDebugString( pMsg );
}
}
}
}
void CMessageWatchDlg::OnDestroy()
{
// Stop the idling thread
m_cWinIdle.EndIdle();
CDialog::OnDestroy();
}
CSender* CMessageWatchDlg::FindSenderByAddr( const unsigned char ip[4] )
{
FOR_EACH_LL( m_Senders, i )
{
if ( memcmp( m_Senders[i]->m_Addr.ip, ip, 4 ) == 0 )
return m_Senders[i];
}
return NULL;
}
CSender* CMessageWatchDlg::FindSenderByName( const char *pName )
{
FOR_EACH_LL( m_Senders, i )
{
if ( stricmp( pName, m_Senders[i]->m_Name ) == 0 )
return m_Senders[i];
}
return NULL;
}
// 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 CMessageWatchDlg::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 CMessageWatchDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}
void CMessageWatchDlg::OnDblclkMachines()
{
int index = m_Machines.GetCurSel();
if ( index != LB_ERR )
{
CString str;
m_Machines.GetText( index, str );
CSender *pSender = FindSenderByName( str );
if ( pSender )
pSender->m_pConsoleWnd->SetVisible( true );
}
}
void CMessageWatchDlg::OnShowall()
{
FOR_EACH_LL( m_Senders, i )
{
m_Senders[i]->m_pConsoleWnd->SetVisible( true );
}
}
void CMessageWatchDlg::OnHideall()
{
FOR_EACH_LL( m_Senders, i )
{
m_Senders[i]->m_pConsoleWnd->SetVisible( false );
}
}

View File

@ -0,0 +1,100 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// MessageWatchDlg.h : header file
//
#if !defined(AFX_MESSAGEWATCHDLG_H__AB9CEAF4_0166_4CCA_9DEC_77C0918F78C4__INCLUDED_)
#define AFX_MESSAGEWATCHDLG_H__AB9CEAF4_0166_4CCA_9DEC_77C0918F78C4__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "iphelpers.h"
#include "tcpsocket.h"
#include "threadhelpers.h"
#include "consolewnd.h"
#include "win_idle.h"
/////////////////////////////////////////////////////////////////////////////
// CMessageWatchDlg dialog
class CSender
{
public:
CSender();
~CSender();
public:
CIPAddr m_Addr;
ITCPSocket *m_pSocket;
IConsoleWnd *m_pConsoleWnd;
char m_Name[128];
};
class CMessageWatchDlg : public CDialog
{
// Construction
public:
CMessageWatchDlg(CWnd* pParent = NULL); // standard constructor
~CMessageWatchDlg();
// Listen for broadcasts on this socket.
ISocket *m_pListenSocket;
// Connections we've made.
CUtlLinkedList<CSender*,int> m_Senders;
CCriticalSection m_SocketsCS;
CWinIdle m_cWinIdle;
CSender* FindSenderByAddr( const unsigned char ip[4] );
CSender* FindSenderByName( const char *pName );
// Dialog Data
//{{AFX_DATA(CMessageWatchDlg)
enum { IDD = IDD_MESSAGEWATCH_DIALOG };
CListBox m_Machines;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMessageWatchDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
void OnIdle();
// Generated message map functions
//{{AFX_MSG(CMessageWatchDlg)
afx_msg void OnDestroy();
afx_msg LONG OnStartIdle(UINT, LONG);
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnDblclkMachines();
afx_msg void OnShowall();
afx_msg void OnHideall();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_MESSAGEWATCHDLG_H__AB9CEAF4_0166_4CCA_9DEC_77C0918F78C4__INCLUDED_)

View File

@ -0,0 +1,15 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// stdafx.cpp : source file that includes just the standard includes
// MessageWatch.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"

View File

@ -0,0 +1,33 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// 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__70653A1B_FB34_4AD9_861C_580071240D6F__INCLUDED_)
#define AFX_STDAFX_H__70653A1B_FB34_4AD9_861C_580071240D6F__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__70653A1B_FB34_4AD9_861C_580071240D6F__INCLUDED_)

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

View File

@ -0,0 +1,13 @@
//
// MESSAGEWATCH.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...
/////////////////////////////////////////////////////////////////////////////

View File

@ -0,0 +1,29 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by MessageWatch.rc
//
#define IDSHOWALL 3
#define IDHIDEALL 4
#define IDD_MESSAGEWATCH_DIALOG 102
#define IDR_MAINFRAME 128
#define IDD_OUTPUT 129
#define IDC_MACHINES 1000
#define IDC_DEBUG_OUTPUT 1000
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 129
#define _APS_NEXT_COMMAND_VALUE 32771
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@ -0,0 +1,123 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// Class for sending idle messages to a window
#include "stdafx.h"
#include "win_idle.h"
// Stub function to get into the object's main thread loop
DWORD WINAPI CWinIdle::ThreadStub(LPVOID pIdle)
{
return ((CWinIdle *)pIdle)->RunIdle();
}
CWinIdle::CWinIdle() :
m_hIdleThread(NULL),
m_hIdleEvent(NULL),
m_hStopEvent(NULL),
m_hWnd(0),
m_uMsg(0),
m_dwDelay(0)
{
}
CWinIdle::~CWinIdle()
{
if (m_hIdleThread)
OutputDebugString("!!CWinIdle Warning!! Idle thread not shut down!\n");
}
DWORD CWinIdle::RunIdle()
{
// Set up an event list
HANDLE aEvents[2];
aEvents[0] = m_hStopEvent;
aEvents[1] = m_hIdleEvent;
// Wait for a stop or idle event
while (WaitForMultipleObjects(2, aEvents, FALSE, INFINITE) != WAIT_OBJECT_0)
{
// Send an idle message
PostMessage(m_hWnd, m_uMsg, m_wParam, m_lParam);
// Wait for a bit...
Sleep(m_dwDelay);
}
return 0;
}
BOOL CWinIdle::StartIdle(HWND hWnd, UINT uMessage, WPARAM wParam, LPARAM lParam, DWORD dwDelay)
{
// Make sure it's not already running
if (m_hIdleThread)
return FALSE;
// Make sure they send in a valid handle..
if (!hWnd)
return FALSE;
// Create the events
m_hIdleEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
m_hStopEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
// Make sure the events got created
if ((!m_hIdleEvent) || (!m_hStopEvent))
return FALSE;
// Create the thread
DWORD dwThreadID;
m_hIdleThread = CreateThread(NULL, 0, CWinIdle::ThreadStub, (void *)this, 0, &dwThreadID);
if (m_hIdleThread)
{
SetThreadPriority(m_hIdleThread, THREAD_PRIORITY_IDLE);
m_hWnd = hWnd;
m_uMsg = uMessage;
m_wParam = wParam;
m_lParam = lParam;
m_dwDelay = dwDelay;
}
return m_hIdleThread != 0;
}
BOOL CWinIdle::EndIdle()
{
// Make sure it's running
if (!m_hIdleThread)
return FALSE;
// Stop the idle thread
SetEvent(m_hStopEvent);
WaitForSingleObject(m_hIdleThread, INFINITE);
CloseHandle(m_hIdleThread);
// Get rid of the event objects
CloseHandle(m_hIdleEvent);
CloseHandle(m_hStopEvent);
// Set everything back to 0
m_hIdleEvent = 0;
m_hStopEvent = 0;
m_hIdleThread = 0;
return TRUE;
}
void CWinIdle::NextIdle()
{
// Make sure the thread's running
if (!m_hIdleThread)
return;
// Signal an idle message
SetEvent(m_hIdleEvent);
}

View File

@ -0,0 +1,78 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// WinIdle.h - Defines a class for sending idle messages to a window from a secondary thread
#ifndef __WINIDLE_H__
#define __WINIDLE_H__
class CWinIdle
{
protected:
HANDLE m_hIdleEvent, m_hStopEvent;
HWND m_hWnd;
UINT m_uMsg;
WPARAM m_wParam;
LPARAM m_lParam;
DWORD m_dwDelay;
HANDLE m_hIdleThread;
// The thread calling stub
static DWORD WINAPI ThreadStub(LPVOID pIdle);
// The actual idle loop
virtual DWORD RunIdle();
public:
CWinIdle();
virtual ~CWinIdle();
inline DWORD GetDelay() {return m_dwDelay;}
inline void SetDelay(DWORD delay) {m_dwDelay = delay;}
// Member access
virtual HANDLE GetThreadHandle() const { return m_hIdleThread; };
// Start idling, and define the message and window to use
// Returns TRUE on success
virtual BOOL StartIdle(HWND hWnd, UINT uMessage, WPARAM wParam = 0, LPARAM lParam = 0, DWORD dwDelay = 0);
// Stop idling
// Returns TRUE on success
virtual BOOL EndIdle();
// Notify the idle process that the message was received.
// Note : If this function is not called, the idle thread will not send any messages
virtual void NextIdle();
};
// Used to slow down the idle thread while dialogs are up.
class IdleChanger
{
public:
IdleChanger(CWinIdle *pIdle, DWORD msDelay)
{
m_pIdle = pIdle;
m_OldDelay = pIdle->GetDelay();
pIdle->SetDelay(msDelay);
}
~IdleChanger()
{
m_pIdle->SetDelay(m_OldDelay);
}
CWinIdle *m_pIdle;
DWORD m_OldDelay;
};
#endif //__WINIDLE_H__

View File

@ -0,0 +1,15 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// stdafx.cpp : source file that includes just the standard includes
// ThreadedTCPSocketTest.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,31 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// 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__AA10D99C_786F_4324_86C6_4D7CDE546561__INCLUDED_)
#define AFX_STDAFX_H__AA10D99C_786F_4324_86C6_4D7CDE546561__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <windows.h>
#include <conio.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__AA10D99C_786F_4324_86C6_4D7CDE546561__INCLUDED_)

View File

@ -0,0 +1,198 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// ThreadedTCPSocketTest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "IThreadedTCPSocket.h"
#include "threadhelpers.h"
#include "vstdlib/random.h"
CCriticalSection g_MsgCS;
IThreadedTCPSocket *g_pClientSocket = NULL;
IThreadedTCPSocket *g_pServerSocket = NULL;
CEvent g_ClientPacketEvent;
CUtlVector<char> g_ClientPacket;
SpewRetval_t MySpewFunc( SpewType_t type, char const *pMsg )
{
CCriticalSectionLock csLock( &g_MsgCS );
csLock.Lock();
printf( "%s", pMsg );
OutputDebugString( pMsg );
csLock.Unlock();
if( type == SPEW_ASSERT )
return SPEW_DEBUGGER;
else if( type == SPEW_ERROR )
return SPEW_ABORT;
else
return SPEW_CONTINUE;
}
class CHandler_Server : public ITCPSocketHandler
{
public:
virtual void Init( IThreadedTCPSocket *pSocket )
{
}
virtual void OnPacketReceived( CTCPPacket *pPacket )
{
// Echo the data back.
g_pServerSocket->Send( pPacket->GetData(), pPacket->GetLen() );
pPacket->Release();
}
virtual void OnError( int errorCode, const char *pErrorString )
{
Msg( "Server error: %s\n", pErrorString );
}
};
class CHandler_Client : public ITCPSocketHandler
{
public:
virtual void Init( IThreadedTCPSocket *pSocket )
{
}
virtual void OnPacketReceived( CTCPPacket *pPacket )
{
if ( g_ClientPacket.Count() < pPacket->GetLen() )
g_ClientPacket.SetSize( pPacket->GetLen() );
memcpy( g_ClientPacket.Base(), pPacket->GetData(), pPacket->GetLen() );
g_ClientPacketEvent.SetEvent();
pPacket->Release();
}
virtual void OnError( int errorCode, const char *pErrorString )
{
Msg( "Client error: %s\n", pErrorString );
}
};
class CHandlerCreator_Server : public IHandlerCreator
{
public:
virtual ITCPSocketHandler* CreateNewHandler()
{
return new CHandler_Server;
}
};
class CHandlerCreator_Client : public IHandlerCreator
{
public:
virtual ITCPSocketHandler* CreateNewHandler()
{
return new CHandler_Client;
}
};
int main(int argc, char* argv[])
{
SpewOutputFunc( MySpewFunc );
// Figure out a random port to use.
CCycleCount cnt;
cnt.Sample();
CUniformRandomStream randomStream;
randomStream.SetSeed( cnt.GetMicroseconds() );
int iPort = randomStream.RandomInt( 20000, 30000 );
g_ClientPacketEvent.Init( false, false );
// Setup the "server".
CHandlerCreator_Server serverHandler;
CIPAddr addr( 127, 0, 0, 1, iPort );
ITCPConnectSocket *pListener = ThreadedTCP_CreateListener(
&serverHandler,
(unsigned short)iPort );
// Setup the "client".
CHandlerCreator_Client clientCreator;
ITCPConnectSocket *pConnector = ThreadedTCP_CreateConnector(
CIPAddr( 127, 0, 0, 1, iPort ),
CIPAddr(),
&clientCreator );
// Wait for them to connect.
while ( !g_pClientSocket )
{
if ( !pConnector->Update( &g_pClientSocket ) )
{
Error( "Error in client connector!\n" );
}
}
pConnector->Release();
while ( !g_pServerSocket )
{
if ( !pListener->Update( &g_pServerSocket ) )
Error( "Error in server connector!\n" );
}
pListener->Release();
// Send some data.
__int64 totalBytes = 0;
CCycleCount startTime;
int iPacket = 1;
startTime.Sample();
CUtlVector<char> buf;
while ( (GetAsyncKeyState( VK_SHIFT ) & 0x8000) == 0 )
{
int size = randomStream.RandomInt( 1024*0, 1024*320 );
if ( buf.Count() < size )
buf.SetSize( size );
if ( g_pClientSocket->Send( buf.Base(), size ) )
{
// Server receives the data and echoes it back. Verify that the data is good.
WaitForSingleObject( g_ClientPacketEvent.GetEventHandle(), INFINITE );
Assert( memcmp( g_ClientPacket.Base(), buf.Base(), size ) == 0 );
totalBytes += size;
CCycleCount curTime, elapsed;
curTime.Sample();
CCycleCount::Sub( curTime, startTime, elapsed );
double flSeconds = elapsed.GetSeconds();
Msg( "Packet %d, %d bytes, %dk/sec\n", iPacket++, size, (int)(((totalBytes+511)/1024) / flSeconds) );
}
}
g_pClientSocket->Release();
g_pServerSocket->Release();
return 0;
}

View File

@ -0,0 +1,15 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// stdafx.cpp : source file that includes just the standard includes
// pingpong.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,29 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// 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__13A3CFA6_6BF8_45A8_A2CD_91444DCFF7C0__INCLUDED_)
#define AFX_STDAFX_H__13A3CFA6_6BF8_45A8_A2CD_91444DCFF7C0__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__13A3CFA6_6BF8_45A8_A2CD_91444DCFF7C0__INCLUDED_)

View File

@ -0,0 +1,308 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// pingpong.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <assert.h>
#include <stdlib.h>
#include "tcpsocket.h"
#include "tier0/fasttimer.h"
#include "vmpi.h"
#include "tcpsocket_helpers.h"
//#define USE_MPI
#if defined( USE_MPI )
#include "mpi/mpi.h"
#include "vmpi.h"
#include "tier1/bitbuf.h"
int myProcId = -1;
#else
IChannel *g_pSocket = NULL;
int g_iPortNum = 27141;
#endif
int PrintUsage()
{
printf( "pingpong <-server or -client ip>\n" );
return 1;
}
void DoClientConnect( const char *pIP )
{
#if defined( USE_MPI )
int argc = 1;
char *testargv[1] = { "-nounc" };
char **argv = testargv;
if ( MPI_Init( &argc, &argv ) )
{
assert( false );
}
MPI_Comm_rank( MPI_COMM_WORLD, &myProcId );
int nProcs;
MPI_Comm_size( MPI_COMM_WORLD, &nProcs );
if ( nProcs != 2 )
{
assert( false );
}
#else
// Try to connect, or listen.
ITCPSocket *pTCPSocket = CreateTCPSocket();
if ( !pTCPSocket->BindToAny( 0 ) )
{
assert( false );
}
CIPAddr addr;
if ( !ConvertStringToIPAddr( pIP, &addr ) )
{
assert( false );
}
addr.port = g_iPortNum;
printf( "Client connecting to %d.%d.%d.%d:%d\n", addr.ip[0], addr.ip[1], addr.ip[2], addr.ip[3], addr.port );
if ( !TCPSocket_Connect( pTCPSocket, &addr, 50000 ) )
{
assert( false );
}
printf( "Client connected...\n ");
g_pSocket = pTCPSocket;
#endif
}
void DoServerConnect()
{
#if defined( USE_MPI )
ISocket *pSocket = CreateIPSocket();
if ( !pSocket )
{
printf( "Error creating a socket.\n" );
assert( false );
return;
}
else if ( !pSocket->BindToAny( VMPI_SERVICE_PORT ) )
{
printf( "Error binding a socket to port %d.\n", VMPI_SERVICE_PORT );
assert( false );
return;
}
printf( "Waiting for jobs...\n" );
while ( 1 )
{
// Any incoming packets?
char data[2048];
CIPAddr ipFrom;
int len = pSocket->RecvFrom( data, sizeof( data ), &ipFrom );
if ( len > 3 )
{
bf_read buf( data, len );
if ( buf.ReadByte() == VMPI_PROTOCOL_VERSION )
{
if ( buf.ReadByte() == VMPI_LOOKING_FOR_WORKERS )
{
// Read the listen port.
int iListenPort = buf.ReadLong();
static char ipString[128];
_snprintf( ipString, sizeof( ipString ), "%d.%d.%d.%d:%d", ipFrom.ip[0], ipFrom.ip[1], ipFrom.ip[2], ipFrom.ip[3], iListenPort );
int argc = 3;
char *testargv[3];
testargv[0] = "<supposedly the executable name!>";
testargv[1] = "-mpi_worker";
testargv[2] = ipString;
char **argv = testargv;
if ( MPI_Init( &argc, &argv ) )
{
assert( false );
}
MPI_Comm_rank( MPI_COMM_WORLD, &myProcId );
int nProcs;
MPI_Comm_size( MPI_COMM_WORLD, &nProcs );
if ( nProcs != 2 )
{
assert( false );
}
break;
}
}
}
Sleep( 100 );
}
pSocket->Release();
#else
// Try to connect, or listen.
ITCPListenSocket *pListen = CreateTCPListenSocket( g_iPortNum );
if ( !pListen )
{
assert( false );
}
printf( "Server listening...\n" );
CIPAddr addr;
ITCPSocket *pTCPSocket = TCPSocket_ListenForOneConnection( pListen, &addr, 50000 );
if ( !pTCPSocket )
{
assert( false );
}
pListen->Release();
printf( "Server connected...\n ");
g_pSocket = pTCPSocket;
#endif
}
void SendData( const void *pBuf, int size )
{
#if defined( USE_MPI )
MPI_Send( (void*)pBuf, size, MPI_BYTE, !myProcId, 0, MPI_COMM_WORLD );
#else
g_pSocket->Send( pBuf, size );
#endif
}
void RecvData( CUtlVector<unsigned char> &recvBuf )
{
#if defined( USE_MPI )
MPI_Status stat;
MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat);
recvBuf.SetCount( stat.count );
MPI_Recv( recvBuf.Base(), stat.count, MPI_BYTE, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &stat);
#else
if ( !g_pSocket->Recv( recvBuf, 50000 ) )
{
g_pSocket->Release();
g_pSocket = NULL;
}
#endif
}
int main( int argc, char* argv[] )
{
if ( argc < 2 )
{
return PrintUsage();
}
const char *pClientOrServer = argv[1];
const char *pIP = NULL;
bool bClient = false;
if ( stricmp( pClientOrServer, "-client" ) == 0 )
{
if ( argc < 3 )
{
return PrintUsage();
}
bClient = true;
pIP = argv[2];
}
CUtlVector<unsigned char> recvBuf;
if ( bClient )
{
DoClientConnect( pIP );
// Ok, now start blasting packets of different sizes and measure how long it takes to get an ack back.
int nIterations = 30;
for ( int size=350; size <= 350000; size += 512 )
{
CUtlVector<unsigned char> buf;
buf.SetCount( size );
double flTotalRoundTripTime = 0;
CFastTimer throughputTimer;
throughputTimer.Start();
for ( int i=0; i < nIterations; i++ )
{
for ( int z=0; z < size; z++ )
buf[z] = (char)rand();
SendData( buf.Base(), buf.Count() );
CFastTimer timer;
timer.Start();
RecvData( recvBuf );
timer.End();
// Make sure we got the same data back.
assert( recvBuf.Count() == buf.Count() );
for ( z=0; z < size; z++ )
{
assert( recvBuf[z] == buf[z] );
}
//if ( i % 100 == 0 )
// printf( "%05d\n", i );
printf( "%d\n", i );
flTotalRoundTripTime += timer.GetDuration().GetMillisecondsF();
}
throughputTimer.End();
double flTotalSeconds = throughputTimer.GetDuration().GetSeconds();
double flAvgRoundTripTime = flTotalRoundTripTime / nIterations;
printf( "%d: %.2f ms per roundtrip (%d bytes/sec) sec: %.2f megs: %.2f\n",
size,
flAvgRoundTripTime,
(int)((size*nIterations)/flTotalSeconds),
flTotalSeconds,
(double)(size*nIterations) / (1024*1024) );
}
// Send an 'end' message to the server.
int val = -1;
SendData( &val, sizeof( val ) );
}
else
{
// Wait for a connection.
DoServerConnect();
// Wait for packets and ack them.
while ( 1 )
{
RecvData( recvBuf );
if ( !g_pSocket )
break;
if ( recvBuf.Count() < 4 )
{
assert( false );
}
SendData( recvBuf.Base(), recvBuf.Count() );
}
}
return 0;
}

View File

@ -0,0 +1,15 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// stdafx.cpp : source file that includes just the standard includes
// socket_stresstest.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,33 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// 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__7E382B26_1CB4_461A_8087_762358153941__INCLUDED_)
#define AFX_STDAFX_H__7E382B26_1CB4_461A_8087_762358153941__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <stdio.h>
#include "tcpsocket.h"
#include <conio.h>
#include <stdlib.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__7E382B26_1CB4_461A_8087_762358153941__INCLUDED_)

View File

@ -0,0 +1,274 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// socket_stresstest.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "utllinkedlist.h"
class CSocketInfo
{
public:
bool IsValid()
{
return m_pSocket != 0;
}
void Term();
void ThreadFn();
public:
ITCPSocket *m_pSocket;
int m_iListenPort;
DWORD m_CreateTime; // When this socket was created.
DWORD m_ExpireTime;
};
CSocketInfo g_Infos[132];
CRITICAL_SECTION g_CS, g_PrintCS;
HANDLE g_hThreads[ ARRAYSIZE( g_Infos ) ];
bool g_bShouldExit = false;
CUtlLinkedList<int,int> g_ListenPorts;
SpewRetval_t StressTestSpew( SpewType_t type, char const *pMsg )
{
EnterCriticalSection( &g_PrintCS );
printf( "%s", pMsg );
LeaveCriticalSection( &g_PrintCS );
if( type == SPEW_ASSERT )
return SPEW_DEBUGGER;
else if( type == SPEW_ERROR )
return SPEW_ABORT;
else
return SPEW_CONTINUE;
}
void CSocketInfo::Term()
{
if ( m_pSocket )
{
m_pSocket->Release();
m_pSocket = 0;
}
}
CSocketInfo* FindOldestSocketInfo( CSocketInfo *pInfos, int nInfos )
{
int iOldest = 0;
DWORD oldestTime = 0xFFFFFFFF;
for ( int i=0; i < nInfos; i++ )
{
if ( !pInfos[i].IsValid() )
return &pInfos[i];
if ( pInfos[i].m_CreateTime < oldestTime )
{
oldestTime = pInfos[i].m_CreateTime;
iOldest = i;
}
}
return &pInfos[iOldest];
}
int g_iNextExpire = -1;
void CSocketInfo::ThreadFn()
{
int iInfo = this - g_Infos;
while ( !g_bShouldExit )
{
DWORD curTime = GetTickCount();
// Break the connection after a certain amount of time.
if ( m_pSocket && curTime >= m_ExpireTime )
{
Term();
Msg( "%02d: expire.\n", iInfo, m_iListenPort );
}
if ( m_pSocket )
{
EnterCriticalSection( &g_CS );
if ( g_iNextExpire == -1 )
{
g_iNextExpire = iInfo;
LeaveCriticalSection( &g_CS );
Msg( "%02d: forcing an expire.\n", iInfo, m_iListenPort );
Sleep( 16000 );
EnterCriticalSection( &g_CS );
g_iNextExpire = -1;
}
LeaveCriticalSection( &g_CS );
if ( m_pSocket->IsConnected() )
{
// Receive whatever data it has waiting for it.
CUtlVector<unsigned char> data;
while ( m_pSocket->Recv( data ) )
{
Msg( "%02d: recv %d.\n", iInfo, data.Count() );
}
// Send some data.
int size = rand() % 8192;
data.SetSize( size );
m_pSocket->Send( data.Base(), data.Count() );
//Msg( "%02d: send %d.\n", iInfo, data.Count() );
}
else
{
Term();
}
}
else
{
// Not initialized.. either listen or connect.
int iConnectPort = -1;
if ( rand() > VALVE_RAND_MAX/2 )
{
if ( rand() % 100 < 50 )
Sleep( 500 );
EnterCriticalSection( &g_CS );
int iHead = g_ListenPorts.Head();
if ( iHead != g_ListenPorts.InvalidIndex() )
iConnectPort = g_ListenPorts[iHead];
LeaveCriticalSection( &g_CS );
}
if ( iConnectPort != -1 )
{
CIPAddr addr( 127, 0, 0, 1, iConnectPort );
m_pSocket = CreateTCPSocket();
m_pSocket->BindToAny( 0 );
m_CreateTime = curTime;
m_ExpireTime = curTime + rand() % 5000;
if ( !TCPSocket_Connect( m_pSocket, &addr, 3.0f ) )
{
Term();
}
}
else
{
for ( int iTry=0; iTry < 32; iTry++ )
{
m_iListenPort = 100 + rand() % (VALVE_RAND_MAX/2);
ITCPListenSocket *pListenSocket = CreateTCPListenSocket( m_iListenPort );
if ( pListenSocket )
{
Msg( "%02d: listen on %d.\n", iInfo, m_iListenPort );
// Add us to the list of ports to connect to.
EnterCriticalSection( &g_CS );
g_ListenPorts.AddToTail( m_iListenPort );
LeaveCriticalSection( &g_CS );
// Listen for a connection.
CIPAddr connectedAddr;
m_pSocket = TCPSocket_ListenForOneConnection( pListenSocket, &connectedAddr, 4.0 );
// Remove us from the list of ports to connect to.
EnterCriticalSection( &g_CS );
g_ListenPorts.Remove( g_ListenPorts.Find( m_iListenPort ) );
LeaveCriticalSection( &g_CS );
pListenSocket->Release();
if ( m_pSocket )
{
Msg( "%02d: listen found connection.\n", iInfo );
m_CreateTime = curTime;
m_ExpireTime = curTime + rand() % 5000;
}
break;
}
}
}
}
Sleep( 1 );
}
g_hThreads[iInfo] = 0;
}
DWORD WINAPI ThreadFn( LPVOID lpParameter )
{
CSocketInfo *pInfo = (CSocketInfo*)lpParameter;
pInfo->ThreadFn();
return 0;
}
void AllocError( unsigned long size )
{
Assert( false );
}
int main(int argc, char* argv[])
{
memset( g_Infos, 0, sizeof( g_Infos ) );
memset( g_hThreads, 0, sizeof( g_hThreads ) );
InitializeCriticalSection( &g_CS );
InitializeCriticalSection( &g_PrintCS );
SpewOutputFunc( StressTestSpew );
Plat_SetAllocErrorFn( AllocError );
SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
for ( int i=0; i < ARRAYSIZE( g_Infos ); i++ )
{
DWORD dwThreadID = 0;
g_hThreads[i] = CreateThread(
NULL,
0,
ThreadFn,
&g_Infos[i],
0,
&dwThreadID );
}
while ( !kbhit() )
{
}
g_bShouldExit = true;
HANDLE hZeroArray[ ARRAYSIZE( g_Infos ) ];
memset( hZeroArray, 0, sizeof( hZeroArray ) );
while ( memcmp( hZeroArray, g_hThreads, sizeof( hZeroArray ) ) != 0 )
{
Sleep( 10 );
}
return 0;
}

View File

@ -0,0 +1,15 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// stdafx.cpp : source file that includes just the standard includes
// vmpi_launch.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,30 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// 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__00616BF6_B7E2_4D94_8DC8_3F85BEBD1834__INCLUDED_)
#define AFX_STDAFX_H__00616BF6_B7E2_4D94_8DC8_3F85BEBD1834__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <stdio.h>
#include <windows.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__00616BF6_B7E2_4D94_8DC8_3F85BEBD1834__INCLUDED_)

View File

@ -0,0 +1,256 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// vmpi_launch.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iphelpers.h"
#include "bitbuf.h"
#include "vmpi.h"
bool g_bBroadcast = false;
int PrintUsage()
{
printf( "vmpi_launch -machine <remote machine> -priority <priority> [-mpi_pw <password>] -command \"command line...\"\n" );
printf( "-command must be the last switch..\n" );
return 1;
}
int GetCurMicrosecondsAndSleep( int sleepLen )
{
Sleep( sleepLen );
int retVal;
__asm
{
rdtsc
mov retVal, eax
}
return retVal;
}
const char* FindArg( int argc, char **argv, const char *pName, const char *pDefault )
{
for ( int i=0; i < argc; i++ )
{
if ( stricmp( argv[i], pName ) == 0 )
{
if ( (i+1) < argc )
return argv[i+1];
else
return pDefault;
}
}
return NULL;
}
int ParseArgs( int argc, char **argv, CIPAddr &remoteIP, int &iPriority, int &iFirstArg )
{
if ( FindArg( argc, argv, "-broadcast", "1" ) )
g_bBroadcast = true;
if ( g_bBroadcast == false )
{
const char *pRemoteIPStr = FindArg( argc, argv, "-machine", NULL );
if ( !pRemoteIPStr || !ConvertStringToIPAddr( pRemoteIPStr, &remoteIP ) )
{
printf( "%s is not a valid machine name or IP address.\n", pRemoteIPStr );
return PrintUsage();
}
}
iPriority = 0;
const char *pPriorityStr = FindArg( argc, argv, "-priority", NULL );
if ( pPriorityStr )
iPriority = atoi( pPriorityStr );
if ( iPriority < 0 || iPriority > 1000 )
{
printf( "%s is not a valid priority.\n", pPriorityStr );
return PrintUsage();
}
const char *pCommand = FindArg( argc, argv, "-command", NULL );
if ( !pCommand )
{
return PrintUsage();
}
for ( iFirstArg=1; iFirstArg < argc; iFirstArg++ )
{
if ( argv[iFirstArg] == pCommand )
break;
}
return 0;
}
void SendJobRequest(
ISocket *pSocket,
int argc,
char **argv,
CIPAddr &remoteIP,
int &iPriority,
int &iFirstArg,
int jobID[4] )
{
// Build the packet to send out the job.
char packetData[4096];
bf_write packetBuf;
// Come up with a unique job ID.
jobID[0] = GetCurMicrosecondsAndSleep( 1 );
jobID[1] = GetCurMicrosecondsAndSleep( 1 );
jobID[2] = GetCurMicrosecondsAndSleep( 1 );
jobID[3] = GetCurMicrosecondsAndSleep( 1 );
// Broadcast out to tell all the machines we want workers.
packetBuf.StartWriting( packetData, sizeof( packetData ) );
packetBuf.WriteByte( VMPI_PROTOCOL_VERSION );
const char *pPassword = FindArg( argc, argv, "-mpi_pw", "" );
packetBuf.WriteString( pPassword );
packetBuf.WriteByte( VMPI_LOOKING_FOR_WORKERS );
packetBuf.WriteShort( 0 ); // Tell the port that we're listening on.
// In this case, there is no VMPI master waiting for the app to connect, so
// this parameter doesn't matter.
packetBuf.WriteShort( iPriority );
packetBuf.WriteLong( jobID[0] );
packetBuf.WriteLong( jobID[1] );
packetBuf.WriteLong( jobID[2] );
packetBuf.WriteLong( jobID[3] );
packetBuf.WriteWord( argc-iFirstArg ); // 1 command line argument..
// Write the alternate exe name.
for ( int iArg=iFirstArg; iArg < argc; iArg++ )
packetBuf.WriteString( argv[iArg] );
for ( int iBroadcastPort=VMPI_SERVICE_PORT; iBroadcastPort <= VMPI_LAST_SERVICE_PORT; iBroadcastPort++ )
{
remoteIP.port = iBroadcastPort;
if ( g_bBroadcast == false )
pSocket->SendTo( &remoteIP, packetBuf.GetBasePointer(), packetBuf.GetNumBytesWritten() );
else
pSocket->Broadcast( packetBuf.GetBasePointer(), packetBuf.GetNumBytesWritten(), iBroadcastPort );
}
if ( g_bBroadcast == false )
printf( "Sent command, waiting for reply...\n" );
else
printf( "Sent command\n" );
}
bool WaitForJobStart( ISocket *pSocket, const CIPAddr &remoteIP, const int jobID[4] )
{
while ( 1 )
{
CIPAddr senderAddr;
char data[4096];
int len = -1;
if ( g_bBroadcast == false )
pSocket->RecvFrom( data, sizeof( data ), &senderAddr );
else
pSocket->RecvFrom( data, sizeof( data ), NULL );
if ( len == 19 &&
memcmp( senderAddr.ip, remoteIP.ip, sizeof( senderAddr.ip ) ) == 0 &&
data[1] == VMPI_NOTIFY_START_STATUS &&
memcmp( &data[2], jobID, 16 ) == 0 )
{
if ( data[18] == 0 )
{
// Wasn't able to run.
printf( "Wasn't able to run on target machine.\n" );
return false;
}
else
{
// Ok, the process is running now.
printf( "Process running, waiting for completion...\n" );
return true;
}
}
Sleep( 100 );
}
}
void WaitForJobEnd( ISocket *pSocket, const CIPAddr &remoteIP, const int jobID[4] )
{
while ( 1 )
{
CIPAddr senderAddr;
char data[4096];
int len = pSocket->RecvFrom( data, sizeof( data ), &senderAddr );
if ( len == 18 &&
memcmp( senderAddr.ip, remoteIP.ip, sizeof( senderAddr.ip ) ) == 0 &&
data[1] == VMPI_NOTIFY_END_STATUS &&
memcmp( &data[2], jobID, 16 ) == 0 )
{
int ret = *((int*)&data[2]);
printf( "Finished [%d].\n", ret );
break;
}
Sleep( 100 );
}
}
int main(int argc, char* argv[])
{
if ( argc < 4 )
{
return PrintUsage();
}
// Parse the command line.
CIPAddr remoteIP;
int iFirstArg, iPriority;
int jobID[4];
int ret = ParseArgs( argc, argv, remoteIP, iPriority, iFirstArg );
if ( ret != 0 )
return ret;
// Now send the command to the vmpi service on that machine.
ISocket *pSocket = CreateIPSocket();
if ( !pSocket->BindToAny( 0 ) )
{
printf( "Error binding a socket.\n" );
return 1;
}
SendJobRequest( pSocket, argc, argv, remoteIP, iPriority, iFirstArg, jobID );
// Wait for a reply, positive or negative.
if ( g_bBroadcast == false )
{
if ( !WaitForJobStart( pSocket, remoteIP, jobID ) )
return 2;
WaitForJobEnd( pSocket, remoteIP, jobID );
}
pSocket->Release();
return 0;
}

View File

@ -0,0 +1,38 @@
//-----------------------------------------------------------------------------
// VMPI_LAUNCH.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR "..\..\..\.."
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
$Include "$SRCDIR\vpc_scripts\source_exe_con_win32_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE,.\,..\.."
}
$Linker
{
$AdditionalDependencies "ws2_32.lib odbc32.lib odbccp32.lib"
}
}
$Project "Vmpi_launch"
{
$Folder "Source Files"
{
$File "..\..\iphelpers.cpp"
$File "StdAfx.cpp"
$File "vmpi_launch.cpp"
}
$Folder "Header Files"
{
$File "StdAfx.h"
}
}

View File

@ -0,0 +1,15 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// stdafx.cpp : source file that includes just the standard includes
// vmpi_ping.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

View File

@ -0,0 +1,30 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// 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__04B9E767_FE9B_4F2A_84A3_D6B85737214E__INCLUDED_)
#define AFX_STDAFX_H__04B9E767_FE9B_4F2A_84A3_D6B85737214E__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <stdio.h>
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__04B9E767_FE9B_4F2A_84A3_D6B85737214E__INCLUDED_)

View File

@ -0,0 +1,196 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
// vmpi_ping.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "iphelpers.h"
#include "vmpi.h"
#include "tier0/platform.h"
#include "bitbuf.h"
#include <conio.h>
#include <stdlib.h>
const char* FindArg( int argc, char **argv, const char *pName, const char *pDefault = "" )
{
for ( int i=0; i < argc; i++ )
{
if ( stricmp( argv[i], pName ) == 0 )
{
if ( (i+1) < argc )
return argv[i+1];
else
return pDefault;
}
}
return NULL;
}
int main(int argc, char* argv[])
{
CUtlVector<CIPAddr> addrs;
printf( "\n" );
printf( "vmpi_ping <option>\n" );
printf( "option can be:\n" );
printf( " -stop .. stop any VMPI services\n" );
printf( " -kill .. kill any processes being run by VMPI\n" );
printf( " -patch <timeout> .. stops VMPI services for <timeout> seconds\n" );
printf( " -mpi_pw <password> .. only talk to services with the specified password\n" );
printf( " -dns .. enable DNS lookups (slows the listing down)\n" );
printf( " -ShowConsole .. show the console window\n" );
printf( " -HideConsole .. hide the console window\n" );
//Scary to show these to users...
//printf( " -ShowCache .. show the cache directory and its capacity\n" );
//printf( " -FlushCache .. flush the cache of ALL VMPI services\n" );
printf( "\n" );
ISocket *pSocket = CreateIPSocket();
if ( !pSocket->BindToAny( 0 ) )
{
printf( "Error binding to a port!\n" );
return 1;
}
const char *pPassword = FindArg( argc, argv, "-mpi_pw" );
// Figure out which action they want to take.
int timeout = 0;
char cRequest = VMPI_PING_REQUEST;
if ( FindArg( argc, argv, "-Stop" ) )
{
cRequest = VMPI_STOP_SERVICE;
}
else if ( FindArg( argc, argv, "-Kill" ) )
{
cRequest = VMPI_KILL_PROCESS;
}
/*
else if ( FindArg( argc, argv, "-ShowConsole" ) )
{
cRequest = VMPI_SHOW_CONSOLE_WINDOW;
}
else if ( FindArg( argc, argv, "-HideConsole" ) )
{
cRequest = VMPI_HIDE_CONSOLE_WINDOW;
}
*/
else if ( FindArg( argc, argv, "-ShowCache" ) )
{
cRequest = VMPI_GET_CACHE_INFO;
}
else if ( FindArg( argc, argv, "-FlushCache" ) )
{
cRequest = VMPI_FLUSH_CACHE;
}
else
{
const char *pTimeout = FindArg( argc, argv, "-patch", "60" );
if ( pTimeout )
{
if ( isdigit( pTimeout[0] ) )
{
cRequest = VMPI_SERVICE_PATCH;
timeout = atoi( pTimeout );
printf( "Patching with timeout of %d seconds.\n", timeout );
}
else
{
printf( "-patch requires a timeout parameter.\n" );
return 1;
}
}
}
int nMachines = 0;
printf( "Pinging VMPI Services... press a key to stop.\n\n" );
while ( !kbhit() )
{
for ( int i=VMPI_SERVICE_PORT; i <= VMPI_LAST_SERVICE_PORT; i++ )
{
unsigned char data[256];
bf_write buf( data, sizeof( data ) );
buf.WriteByte( VMPI_PROTOCOL_VERSION );
buf.WriteString( pPassword );
buf.WriteByte( cRequest );
if ( cRequest == VMPI_SERVICE_PATCH )
buf.WriteLong( timeout );
pSocket->Broadcast( data, buf.GetNumBytesWritten(), i );
}
while ( 1 )
{
CIPAddr ipFrom;
char in[256];
int len = pSocket->RecvFrom( in, sizeof( in ), &ipFrom );
if ( len == -1 )
break;
if ( len >= 2 &&
in[0] == VMPI_PROTOCOL_VERSION &&
in[1] == VMPI_PING_RESPONSE &&
addrs.Find( ipFrom ) == -1 )
{
char *pStateString = "(unknown)";
if ( len >= 3 )
{
if ( in[2] )
pStateString = "(running)";
else
pStateString = "(idle) ";
}
++nMachines;
char nameStr[256];
if ( FindArg( argc, argv, "-dns" ) && ConvertIPAddrToString( &ipFrom, nameStr, sizeof( nameStr ) ) )
{
printf( "%02d. %s - %s:%d (%d.%d.%d.%d)",
nMachines, pStateString, nameStr, ipFrom.port,
ipFrom.ip[0], ipFrom.ip[1], ipFrom.ip[2], ipFrom.ip[3] );
}
else
{
printf( "%02d. %s - %d.%d.%d.%d:%d",
nMachines, pStateString, ipFrom.ip[0], ipFrom.ip[1], ipFrom.ip[2], ipFrom.ip[3], ipFrom.port );
}
if ( cRequest == VMPI_GET_CACHE_INFO )
{
// Next var is a 64-bit int with the size of the cache.
char *pCur = &in[3];
__int64 cacheSize = *((__int64*)pCur);
pCur += sizeof( __int64 );
char *pCacheDir = pCur;
__int64 nMegs = cacheSize / (1024*1024);
printf( "\n\tCache dir: %s, size: %d megs", pCur, nMegs );
}
printf( "\n" );
addrs.AddToTail( ipFrom );
}
}
Sleep( 1000 );
}
return 0;
}