summaryrefslogtreecommitdiff
path: root/utils/vmpi/vmpi_job_search
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /utils/vmpi/vmpi_job_search
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'utils/vmpi/vmpi_job_search')
-rw-r--r--utils/vmpi/vmpi_job_search/JobSearchDlg.cpp473
-rw-r--r--utils/vmpi/vmpi_job_search/JobSearchDlg.h86
-rw-r--r--utils/vmpi/vmpi_job_search/StdAfx.cpp15
-rw-r--r--utils/vmpi/vmpi_job_search/StdAfx.h36
-rw-r--r--utils/vmpi/vmpi_job_search/res/vmpi_browser_job_search.icobin0 -> 1078 bytes
-rw-r--r--utils/vmpi/vmpi_job_search/res/vmpi_browser_job_search.rc213
-rw-r--r--utils/vmpi/vmpi_job_search/resource.h32
-rw-r--r--utils/vmpi/vmpi_job_search/vmpi_browser_job_search.cpp75
-rw-r--r--utils/vmpi/vmpi_job_search/vmpi_browser_job_search.h56
-rw-r--r--utils/vmpi/vmpi_job_search/vmpi_browser_job_search.rc184
-rw-r--r--utils/vmpi/vmpi_job_search/vmpi_job_search.vpc97
11 files changed, 1067 insertions, 0 deletions
diff --git a/utils/vmpi/vmpi_job_search/JobSearchDlg.cpp b/utils/vmpi/vmpi_job_search/JobSearchDlg.cpp
new file mode 100644
index 0000000..e98b726
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/JobSearchDlg.cpp
@@ -0,0 +1,473 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+// JobSearchDlg.cpp : implementation file
+//
+
+#include "stdafx.h"
+#include "JobSearchDlg.h"
+#include "imysqlwrapper.h"
+#include "tier1/strtools.h"
+#include "utllinkedlist.h"
+#include "vmpi_browser_helpers.h"
+#include "vmpi_defs.h"
+#include "net_view_thread.h"
+
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+
+// These are stored with jobs to help with sorting and to remember the job ID.
+class CJobInfo
+{
+public:
+ unsigned long m_JobID;
+ CString m_StartTimeUnformatted;
+ CString m_MachineName;
+ CString m_BSPFilename;
+ DWORD m_RunningTimeMS;
+};
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CJobSearchDlg dialog
+
+
+CJobSearchDlg::CJobSearchDlg(CWnd* pParent /*=NULL*/)
+ : CDialog(CJobSearchDlg::IDD, pParent)
+{
+ //{{AFX_DATA_INIT(CJobSearchDlg)
+ //}}AFX_DATA_INIT
+ m_pSQL = NULL;
+ m_hMySQLDLL = NULL;
+}
+
+
+CJobSearchDlg::~CJobSearchDlg()
+{
+ if ( m_pSQL )
+ {
+ m_pSQL->Release();
+ }
+
+ if ( m_hMySQLDLL )
+ {
+ Sys_UnloadModule( m_hMySQLDLL );
+ }
+}
+
+
+void CJobSearchDlg::DoDataExchange(CDataExchange* pDX)
+{
+ CDialog::DoDataExchange(pDX);
+ //{{AFX_DATA_MAP(CJobSearchDlg)
+ DDX_Control(pDX, IDC_WORKER_LIST, m_WorkerList);
+ DDX_Control(pDX, IDC_USER_LIST, m_UserList);
+ DDX_Control(pDX, IDC_JOBS_LIST, m_JobsList);
+ //}}AFX_DATA_MAP
+}
+
+
+BEGIN_MESSAGE_MAP(CJobSearchDlg, CDialog)
+ //{{AFX_MSG_MAP(CJobSearchDlg)
+ ON_NOTIFY(NM_DBLCLK, IDC_JOBS_LIST, OnDblclkJobsList)
+ ON_LBN_DBLCLK(IDC_USER_LIST, OnDblclkUserList)
+ ON_LBN_DBLCLK(IDC_WORKER_LIST, OnDblclkWorkerList)
+ ON_BN_CLICKED(IDC_QUIT, OnQuit)
+ ON_WM_SIZE()
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+int CJobSearchDlg::GetSelectedJobIndex()
+{
+ POSITION pos = m_JobsList.GetFirstSelectedItemPosition();
+ if ( pos )
+ return m_JobsList.GetNextSelectedItem( pos );
+ else
+ return -1;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CJobSearchDlg message handlers
+
+void CJobSearchDlg::OnDblclkJobsList(NMHDR* pNMHDR, LRESULT* pResult)
+{
+ int iItem = GetSelectedJobIndex();
+ if ( iItem != -1 )
+ {
+ CJobInfo *pInfo = (CJobInfo*)m_JobsList.GetItemData( iItem );
+
+ CString cmdLine;
+ cmdLine.Format( "vmpi_job_watch -JobID %d -dbname \"%s\" -hostname \"%s\" -username \"%s\"",
+ pInfo->m_JobID, (const char*)m_DBName, (const char*)m_HostName, (const char*)m_UserName );
+
+ STARTUPINFO si;
+ memset( &si, 0, sizeof( si ) );
+ si.cb = sizeof( si );
+
+ PROCESS_INFORMATION pi;
+ memset( &pi, 0, sizeof( pi ) );
+
+ if ( !CreateProcess(
+ NULL,
+ (char*)(const char*)cmdLine,
+ NULL, // security
+ NULL,
+ TRUE,
+ 0, // flags
+ NULL, // environment
+ NULL, // current directory
+ &si,
+ &pi ) )
+ {
+ CString errStr;
+ errStr.Format( "Error launching '%s'", cmdLine.GetBuffer() );
+ MessageBox( errStr, "Error", MB_OK );
+ }
+ }
+
+ *pResult = 0;
+}
+
+
+static int CALLBACK JobsSortFn( LPARAM iItem1, LPARAM iItem2, LPARAM lpParam )
+{
+ CJobInfo *pInfo1 = (CJobInfo*)iItem1;
+ CJobInfo *pInfo2 = (CJobInfo*)iItem2;
+
+ return strcmp( pInfo2->m_StartTimeUnformatted, pInfo1->m_StartTimeUnformatted );
+}
+
+
+void CJobSearchDlg::ClearJobsList()
+{
+ // First, delete all the JobInfo structures we have in it.
+ int nItems = m_JobsList.GetItemCount();
+ for ( int i=0; i < nItems; i++ )
+ {
+ CJobInfo *pInfo = (CJobInfo*)m_JobsList.GetItemData( i );
+ delete pInfo;
+ }
+
+ m_JobsList.DeleteAllItems();
+}
+
+
+void CJobSearchDlg::RepopulateJobsList()
+{
+ // It's assumed coming into this routine that the caller just executed a query that we can iterate over.
+ ClearJobsList();
+
+ CUtlLinkedList<CJobInfo*, int> jobInfos;
+ while ( GetMySQL()->NextRow() )
+ {
+ CJobInfo *pInfo = new CJobInfo;
+ pInfo->m_StartTimeUnformatted = GetMySQL()->GetColumnValue( "StartTime" ).String();
+ pInfo->m_JobID = GetMySQL()->GetColumnValue( "JobID" ).Int32();
+ pInfo->m_MachineName = GetMySQL()->GetColumnValue( "MachineName" ).String();
+ pInfo->m_BSPFilename = GetMySQL()->GetColumnValue( "BSPFilename" ).String();
+ pInfo->m_RunningTimeMS = GetMySQL()->GetColumnValue( "RunningTimeMS" ).Int32();
+
+ jobInfos.AddToTail( pInfo );
+ }
+
+
+ FOR_EACH_LL( jobInfos, j )
+ {
+ CJobInfo *pInfo = jobInfos[j];
+
+ // Add the item.
+ int iItem = m_JobsList.InsertItem( 0, "", NULL );
+
+ // Associate it with the job structure.
+ m_JobsList.SetItemData( iItem, (DWORD)pInfo );
+
+ char dateStr[128];
+ const char *pDate = pInfo->m_StartTimeUnformatted;
+ if ( strlen( pDate ) == 14 ) // yyyymmddhhmmss
+ {
+ Q_snprintf( dateStr, sizeof( dateStr ), "%c%c/%c%c %c%c:%c%c:00",
+ pDate[4], pDate[5],
+ pDate[6], pDate[7],
+ pDate[8], pDate[9],
+ pDate[10], pDate[11] );
+ }
+
+ m_JobsList.SetItemText( iItem, 0, dateStr );
+ m_JobsList.SetItemText( iItem, 1, pInfo->m_MachineName );
+ m_JobsList.SetItemText( iItem, 2, pInfo->m_BSPFilename );
+
+ char timeStr[512];
+ if ( pInfo->m_RunningTimeMS == RUNNINGTIME_MS_SENTINEL )
+ {
+ Q_strncpy( timeStr, "?", sizeof( timeStr ) );
+ }
+ else
+ {
+ FormatTimeString( pInfo->m_RunningTimeMS / 1000, timeStr, sizeof( timeStr ) );
+ }
+ m_JobsList.SetItemText( iItem, 3, timeStr );
+
+ char jobIDStr[512];
+ Q_snprintf( jobIDStr, sizeof( jobIDStr ), "%d", pInfo->m_JobID );
+ m_JobsList.SetItemText( iItem, 4, jobIDStr );
+ }
+
+ m_JobsList.SortItems( JobsSortFn, (LPARAM)&m_JobsList );
+}
+
+
+void CJobSearchDlg::OnDblclkUserList()
+{
+ int sel = m_UserList.GetCurSel();
+ if ( sel != LB_ERR )
+ {
+ CString computerName;
+ m_UserList.GetText( sel, computerName );
+
+ // Look for jobs that this user initiated.
+ char query[4096];
+ Q_snprintf( query, sizeof( query ), "select RunningTimeMS, JobID, BSPFilename, StartTime, MachineName from job_master_start where MachineName=\"%s\"", (const char*)computerName );
+ GetMySQL()->Execute( query );
+
+ RepopulateJobsList();
+ }
+}
+
+void CJobSearchDlg::OnDblclkWorkerList()
+{
+ int sel = m_WorkerList.GetCurSel();
+ if ( sel != LB_ERR )
+ {
+ CString computerName;
+ m_WorkerList.GetText( sel, computerName );
+
+ // This query does:
+ // 1. Take the workers with the specified MachineName.
+ // 2. Only use IsMaster = 0.
+ // 3. Now get all the job_master_start records with the same JobID.
+ char query[4096];
+ Q_snprintf( query, sizeof( query ), "select job_master_start.RunningTimeMS, job_master_start.JobID, job_master_start.BSPFilename, job_master_start.StartTime, job_master_start.MachineName "
+ "from job_master_start, job_worker_start "
+ "where job_worker_start.MachineName = \"%s\" and "
+ "IsMaster = 0 and "
+ "job_master_start.JobID = job_worker_start.JobID",
+ (const char*)computerName );
+ GetMySQL()->Execute( query );
+
+ RepopulateJobsList();
+ }
+}
+
+bool ReadStringFromFile( FILE *fp, char *pStr, int strSize )
+{
+ int i=0;
+ for ( i; i < strSize-2; i++ )
+ {
+ if ( fread( &pStr[i], 1, 1, fp ) != 1 ||
+ pStr[i] == '\n' )
+ {
+ break;
+ }
+ }
+
+ pStr[i] = 0;
+ return i != 0;
+}
+
+const char* FindArg( const char *pArgName, const char *pDefault="" )
+{
+ for ( int i=1; i < __argc; i++ )
+ {
+ if ( Q_stricmp( pArgName, __argv[i] ) == 0 )
+ {
+ if ( (i+1) < __argc )
+ return __argv[i+1];
+ else
+ return pDefault;
+ }
+ }
+ return NULL;
+}
+
+BOOL CJobSearchDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+
+ m_JobsList.SetExtendedStyle( LVS_EX_FULLROWSELECT );
+
+ char str[512];
+
+ // Init the mysql database.
+ const char *pDBName = FindArg( "-dbname", NULL );
+ const char *pHostName = FindArg( "-hostname", NULL );
+ const char *pUserName = FindArg( "-username", NULL );
+
+ if ( pDBName && pHostName && pUserName )
+ {
+ m_DBName = pDBName;
+ m_HostName = pHostName;
+ m_UserName = pUserName;
+ }
+ else
+ {
+ // Load the dbinfo_browser.txt file to get the database information.
+ const char *pFilename = FindArg( "-dbinfo", NULL );
+ if ( !pFilename )
+ pFilename = "dbinfo_job_search.txt";
+
+ FILE *fp = fopen( pFilename, "rt" );
+ if ( !fp )
+ {
+ Q_snprintf( str, sizeof( str ), "Can't open '%s' for database info.", pFilename );
+ MessageBox( str, "Error", MB_OK );
+ EndDialog( 0 );
+ return FALSE;
+ }
+
+ char hostName[512], dbName[512], userName[512];
+ if ( !ReadStringFromFile( fp, hostName, sizeof( hostName ) ) ||
+ !ReadStringFromFile( fp, dbName, sizeof( dbName ) ) ||
+ !ReadStringFromFile( fp, userName, sizeof( userName ) )
+ )
+ {
+ fclose( fp );
+ Q_snprintf( str, sizeof( str ), "'%s' has invalid format.", pFilename );
+ MessageBox( str, "Error", MB_OK );
+ EndDialog( 0 );
+ return FALSE;
+ }
+
+ m_DBName = dbName;
+ m_HostName = hostName;
+ m_UserName = userName;
+
+ fclose( fp );
+ }
+
+ // Get the mysql interface.
+ if ( !Sys_LoadInterface( "mysql_wrapper", MYSQL_WRAPPER_VERSION_NAME, &m_hMySQLDLL, (void**)&m_pSQL ) )
+ return false;
+
+ if ( !m_pSQL->InitMySQL( m_DBName, m_HostName, m_UserName ) )
+ {
+ Q_snprintf( str, sizeof( str ), "Can't init MYSQL db (db = '%s', host = '%s', user = '%s')", (const char*)m_DBName, (const char*)m_HostName, (const char*)m_UserName );
+ MessageBox( str, "Error", MB_OK );
+ EndDialog( 0 );
+ return FALSE;
+ }
+
+ // Setup the headers for the job info list.
+ struct
+ {
+ char *pText;
+ int width;
+ } titles[] =
+ {
+ {"Date", 100},
+ {"User", 100},
+ {"BSP Filename", 100},
+ {"Running Time", 100},
+ {"Job ID", 100}
+ };
+ for ( int i=0; i < ARRAYSIZE( titles ); i++ )
+ {
+ m_JobsList.InsertColumn( i, titles[i].pText, LVCFMT_LEFT, titles[i].width, i );
+ }
+
+
+ CUtlVector<char*> computerNames;
+ CNetViewThread netView;
+ netView.Init();
+ DWORD startTime = GetTickCount();
+ while ( 1 )
+ {
+ netView.GetComputerNames( computerNames );
+ if ( computerNames.Count() > 0 )
+ break;
+
+ Sleep( 30 );
+ if ( GetTickCount() - startTime > 5000 )
+ {
+ Q_snprintf( str, sizeof( str ), "Unable to get computer names Can't init MYSQL db (db = '%s', host = '%s', user = '%s')", (const char*)m_DBName, (const char*)m_HostName, (const char*)m_UserName );
+ MessageBox( str, "Error", MB_OK );
+ EndDialog( 0 );
+ return FALSE;
+ }
+ }
+
+ PopulateWorkerList( computerNames );
+ PopulateUserList( computerNames );
+
+
+ // Auto-select a worker?
+ const char *pSelectWorker = FindArg( "-SelectWorker", NULL );
+ if ( pSelectWorker )
+ {
+ int index = m_WorkerList.FindString( -1, pSelectWorker );
+ if ( index != LB_ERR )
+ {
+ m_WorkerList.SetCurSel( index );
+ OnDblclkWorkerList();
+ }
+ }
+
+
+ // Setup our anchors.
+ m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_SEARCH_BY_USER_PANEL ), ANCHOR_LEFT, ANCHOR_TOP, ANCHOR_WIDTH_PERCENT, ANCHOR_HEIGHT_PERCENT );
+ m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_USER_LIST ), ANCHOR_LEFT, ANCHOR_TOP, ANCHOR_WIDTH_PERCENT, ANCHOR_HEIGHT_PERCENT );
+
+ m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_WORKER_PANEL ), ANCHOR_WIDTH_PERCENT, ANCHOR_TOP, ANCHOR_RIGHT, ANCHOR_HEIGHT_PERCENT );
+ m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_WORKER_LIST ), ANCHOR_WIDTH_PERCENT, ANCHOR_TOP, ANCHOR_RIGHT, ANCHOR_HEIGHT_PERCENT );
+
+ m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_JOBS_PANEL ), ANCHOR_LEFT, ANCHOR_HEIGHT_PERCENT, ANCHOR_RIGHT, ANCHOR_BOTTOM );
+ m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_JOBS_LIST ), ANCHOR_LEFT, ANCHOR_HEIGHT_PERCENT, ANCHOR_RIGHT, ANCHOR_BOTTOM );
+
+ m_AnchorMgr.AddAnchor( this, GetDlgItem( IDC_QUIT ), ANCHOR_WIDTH_PERCENT, ANCHOR_BOTTOM, ANCHOR_WIDTH_PERCENT, ANCHOR_BOTTOM );
+
+ return TRUE; // return TRUE unless you set the focus to a control
+ // EXCEPTION: OCX Property Pages should return FALSE
+}
+
+void CJobSearchDlg::PopulateWorkerList( CUtlVector<char*> &computerNames )
+{
+ m_WorkerList.ResetContent();
+ for ( int i=0; i < computerNames.Count(); i++ )
+ {
+ m_WorkerList.AddString( computerNames[i] );
+ }
+}
+
+void CJobSearchDlg::PopulateUserList( CUtlVector<char*> &computerNames )
+{
+ m_UserList.ResetContent();
+ for ( int i=0; i < computerNames.Count(); i++ )
+ {
+ m_UserList.AddString( computerNames[i] );
+ }
+}
+
+
+
+void CJobSearchDlg::OnQuit()
+{
+ EndDialog( 0 );
+}
+
+void CJobSearchDlg::OnSize(UINT nType, int cx, int cy)
+{
+ CDialog::OnSize(nType, cx, cy);
+
+ m_AnchorMgr.UpdateAnchors( this );
+}
diff --git a/utils/vmpi/vmpi_job_search/JobSearchDlg.h b/utils/vmpi/vmpi_job_search/JobSearchDlg.h
new file mode 100644
index 0000000..6430b8b
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/JobSearchDlg.h
@@ -0,0 +1,86 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#if !defined(AFX_JOBSEARCHDLG_H__833A83FF_35CC_42B5_AEB3_AE31C7FDF492__INCLUDED_)
+#define AFX_JOBSEARCHDLG_H__833A83FF_35CC_42B5_AEB3_AE31C7FDF492__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+// JobSearchDlg.h : header file
+//
+
+#include "resource.h"
+#include "imysqlwrapper.h"
+#include "window_anchor_mgr.h"
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CJobSearchDlg dialog
+
+class CJobSearchDlg : public CDialog
+{
+// Construction
+public:
+ CJobSearchDlg(CWnd* pParent = NULL); // standard constructor
+ virtual ~CJobSearchDlg();
+
+// Dialog Data
+ //{{AFX_DATA(CJobSearchDlg)
+ enum { IDD = IDD_VMPI_JOB_SEARCH };
+ CListBox m_WorkerList;
+ CListBox m_UserList;
+ CListCtrl m_JobsList;
+ //}}AFX_DATA
+
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CJobSearchDlg)
+ protected:
+ virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
+ //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+ void ClearJobsList();
+ void RepopulateJobsList();
+
+ void PopulateWorkerList( CUtlVector<char*> &computerNames );
+ void PopulateUserList( CUtlVector<char*> &computerNames );
+
+ int GetSelectedJobIndex();
+
+
+ // Info on how we connected to the database so we can pass it to apps we launch.
+ CString m_DBName, m_HostName, m_UserName;
+
+
+ IMySQL* GetMySQL() { return m_pSQL; }
+ IMySQL *m_pSQL;
+ CSysModule *m_hMySQLDLL;
+
+ CWindowAnchorMgr m_AnchorMgr;
+
+
+ // Generated message map functions
+ //{{AFX_MSG(CJobSearchDlg)
+ afx_msg void OnDblclkJobsList(NMHDR* pNMHDR, LRESULT* pResult);
+ afx_msg void OnDblclkUserList();
+ afx_msg void OnDblclkWorkerList();
+ virtual BOOL OnInitDialog();
+ afx_msg void OnQuit();
+ afx_msg void OnSize(UINT nType, int cx, int cy);
+ //}}AFX_MSG
+ DECLARE_MESSAGE_MAP()
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_JOBSEARCHDLG_H__833A83FF_35CC_42B5_AEB3_AE31C7FDF492__INCLUDED_)
diff --git a/utils/vmpi/vmpi_job_search/StdAfx.cpp b/utils/vmpi/vmpi_job_search/StdAfx.cpp
new file mode 100644
index 0000000..de47b55
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/StdAfx.cpp
@@ -0,0 +1,15 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+// stdafx.cpp : source file that includes just the standard includes
+// vmpi_browser_job_search.pch will be the pre-compiled header
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+
+
diff --git a/utils/vmpi/vmpi_job_search/StdAfx.h b/utils/vmpi/vmpi_job_search/StdAfx.h
new file mode 100644
index 0000000..88ecf03
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/StdAfx.h
@@ -0,0 +1,36 @@
+//========= 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__2CCE1890_EB30_4887_B493_6CAB022977E4__INCLUDED_)
+#define AFX_STDAFX_H__2CCE1890_EB30_4887_B493_6CAB022977E4__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers
+
+#include "tier0/basetypes.h"
+
+#include <afxwin.h> // MFC core and standard components
+#include <afxext.h> // MFC extensions
+#include <afxdisp.h> // MFC Automation classes
+#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__2CCE1890_EB30_4887_B493_6CAB022977E4__INCLUDED_)
diff --git a/utils/vmpi/vmpi_job_search/res/vmpi_browser_job_search.ico b/utils/vmpi/vmpi_job_search/res/vmpi_browser_job_search.ico
new file mode 100644
index 0000000..7eef0bc
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/res/vmpi_browser_job_search.ico
Binary files differ
diff --git a/utils/vmpi/vmpi_job_search/res/vmpi_browser_job_search.rc2 b/utils/vmpi/vmpi_job_search/res/vmpi_browser_job_search.rc2
new file mode 100644
index 0000000..03d7a3c
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/res/vmpi_browser_job_search.rc2
@@ -0,0 +1,13 @@
+//
+// VMPI_BROWSER_JOB_SEARCH.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...
+
+/////////////////////////////////////////////////////////////////////////////
diff --git a/utils/vmpi/vmpi_job_search/resource.h b/utils/vmpi/vmpi_job_search/resource.h
new file mode 100644
index 0000000..0fceaed
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/resource.h
@@ -0,0 +1,32 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+//{{NO_DEPENDENCIES}}
+// Microsoft Developer Studio generated include file.
+// Used by vmpi_browser_job_search.rc
+//
+#define IDD_VMPI_BROWSER_JOB_SEARCH_DIALOG 102
+#define IDR_MAINFRAME 128
+#define IDD_VMPI_JOB_SEARCH 136
+#define IDC_QUIT 1000
+#define IDC_SEARCH_BY_USER_PANEL 1001
+#define IDC_WORKER_PANEL 1002
+#define IDC_JOBS_PANEL 1003
+#define IDC_USER_LIST 1015
+#define IDC_WORKER_LIST 1016
+#define IDC_JOBS_LIST 1017
+
+// 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 1004
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.cpp b/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.cpp
new file mode 100644
index 0000000..c6fd4a1
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.cpp
@@ -0,0 +1,75 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+// vmpi_browser_job_search.cpp : Defines the class behaviors for the application.
+//
+
+#include "stdafx.h"
+#include "vmpi_browser_job_search.h"
+#include "JobSearchDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#undef THIS_FILE
+static char THIS_FILE[] = __FILE__;
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// CVMPIBrowserJobSearchApp
+
+BEGIN_MESSAGE_MAP(CVMPIBrowserJobSearchApp, CWinApp)
+ //{{AFX_MSG_MAP(CVMPIBrowserJobSearchApp)
+ // 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()
+
+/////////////////////////////////////////////////////////////////////////////
+// CVMPIBrowserJobSearchApp construction
+
+CVMPIBrowserJobSearchApp::CVMPIBrowserJobSearchApp()
+{
+ // TODO: add construction code here,
+ // Place all significant initialization in InitInstance
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// The one and only CVMPIBrowserJobSearchApp object
+
+CVMPIBrowserJobSearchApp theApp;
+
+/////////////////////////////////////////////////////////////////////////////
+// CVMPIBrowserJobSearchApp initialization
+
+BOOL CVMPIBrowserJobSearchApp::InitInstance()
+{
+ AfxEnableControlContainer();
+
+ // 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.
+
+ CJobSearchDlg 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
+ }
+
+ // Since the dialog has been closed, return FALSE so that we exit the
+ // application, rather than start the application's message pump.
+ return FALSE;
+}
diff --git a/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.h b/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.h
new file mode 100644
index 0000000..721b41c
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.h
@@ -0,0 +1,56 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+// vmpi_browser_job_search.h : main header file for the VMPI_BROWSER_JOB_SEARCH application
+//
+
+#if !defined(AFX_VMPI_BROWSER_JOB_SEARCH_H__96197957_586A_4F10_ACEA_EBBB9E6FD619__INCLUDED_)
+#define AFX_VMPI_BROWSER_JOB_SEARCH_H__96197957_586A_4F10_ACEA_EBBB9E6FD619__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
+
+/////////////////////////////////////////////////////////////////////////////
+// CVMPIBrowserJobSearchApp:
+// See vmpi_browser_job_search.cpp for the implementation of this class
+//
+
+class CVMPIBrowserJobSearchApp : public CWinApp
+{
+public:
+ CVMPIBrowserJobSearchApp();
+
+// Overrides
+ // ClassWizard generated virtual function overrides
+ //{{AFX_VIRTUAL(CVMPIBrowserJobSearchApp)
+ public:
+ virtual BOOL InitInstance();
+ //}}AFX_VIRTUAL
+
+// Implementation
+
+ //{{AFX_MSG(CVMPIBrowserJobSearchApp)
+ // 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_VMPI_BROWSER_JOB_SEARCH_H__96197957_586A_4F10_ACEA_EBBB9E6FD619__INCLUDED_)
diff --git a/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.rc b/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.rc
new file mode 100644
index 0000000..4ed763a
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/vmpi_browser_job_search.rc
@@ -0,0 +1,184 @@
+//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\\vmpi_browser_job_search.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\\vmpi_browser_job_search.ico"
+
+#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", "vmpi_browser_job_search MFC Application\0"
+ VALUE "FileVersion", "1, 0, 0, 1\0"
+ VALUE "InternalName", "vmpi_browser_job_search\0"
+ VALUE "LegalCopyright", "Copyright (C) 2003\0"
+ VALUE "LegalTrademarks", "\0"
+ VALUE "OriginalFilename", "vmpi_browser_job_search.EXE\0"
+ VALUE "ProductName", "vmpi_browser_job_search 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_VMPI_JOB_SEARCH, DIALOG
+ BEGIN
+ LEFTMARGIN, 7
+ RIGHTMARGIN, 400
+ TOPMARGIN, 7
+ BOTTOMMARGIN, 338
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_VMPI_JOB_SEARCH DIALOGEX 0, 0, 407, 345
+STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_POPUP |
+ WS_VISIBLE | WS_CAPTION | WS_SYSMENU
+EXSTYLE WS_EX_APPWINDOW
+CAPTION "Job Search"
+FONT 8, "MS Sans Serif"
+BEGIN
+ GROUPBOX "Jobs",IDC_JOBS_PANEL,7,153,393,169
+ LISTBOX IDC_USER_LIST,13,17,180,128,LBS_SORT |
+ LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Search By User",IDC_SEARCH_BY_USER_PANEL,7,7,192,143
+ LISTBOX IDC_WORKER_LIST,211,17,183,128,LBS_SORT |
+ LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Search By Worker",IDC_WORKER_PANEL,205,7,195,143
+ CONTROL "List3",IDC_JOBS_LIST,"SysListView32",LVS_REPORT |
+ LVS_SHOWSELALWAYS | WS_BORDER | WS_TABSTOP,14,164,380,
+ 153
+ PUSHBUTTON "&Quit",IDC_QUIT,192,327,23,14
+END
+
+#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\vmpi_browser_job_search.rc2" // non-Microsoft Visual C++ edited resources
+#include "afxres.rc" // Standard components
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/utils/vmpi/vmpi_job_search/vmpi_job_search.vpc b/utils/vmpi/vmpi_job_search/vmpi_job_search.vpc
new file mode 100644
index 0000000..01dba8b
--- /dev/null
+++ b/utils/vmpi/vmpi_job_search/vmpi_job_search.vpc
@@ -0,0 +1,97 @@
+//-----------------------------------------------------------------------------
+// vmpi_job_search.VPC
+//
+// Project Script
+//-----------------------------------------------------------------------------
+
+$Macro SRCDIR "..\..\.."
+$Macro OUTBINDIR "$SRCDIR\..\game\bin"
+$Macro OUTBINNAME "vmpi_job_search"
+
+$Include "$SRCDIR\vpc_scripts\source_exe_base.vpc"
+
+$Configuration
+{
+ $Compiler
+ {
+ $AdditionalIncludeDirectories "$BASE,..\,..\mysql\include"
+ $PreprocessorDefinitions "$BASE;PROTECTED_THINGS_DISABLE;WINVER=0x501;NO_WARN_MBCS_MFC_DEPRECATION"
+ $Create/UsePrecompiledHeader "Use Precompiled Header (/Yu)"
+ $PrecompiledHeaderFile "Debug/vmpi_browser_job_search.pch"
+ $EnableC++Exceptions "Yes (/EHsc)"
+ }
+}
+
+$Configuration "Debug"
+{
+ $Linker
+ {
+ // Deprecated MBCS MFC libraries for VS 2013 (nafxcw.lib and nafxcwd.lib) can be downloaded from http://go.microsoft.com/?linkid=9832071
+ $AdditionalDependencies "$BASE nafxcwd.lib"
+ $IgnoreSpecificLibrary "nafxcw.lib libcmt.lib"
+ }
+}
+
+$Configuration "Release"
+{
+ $Linker
+ {
+ // Deprecated MBCS MFC libraries for VS 2013 (nafxcw.lib and nafxcwd.lib) can be downloaded from http://go.microsoft.com/?linkid=9832071
+ $AdditionalDependencies "$BASE nafxcw.lib libcmt.lib"
+ $IgnoreSpecificLibrary "nafxcwd.lib libcmtd.lib"
+ }
+}
+
+$Project "vmpi_job_search"
+{
+ $Folder "Source Files"
+ {
+ -$File "$SRCDIR\public\tier0\memoverride.cpp"
+
+ $File "..\net_view_thread.cpp"
+ $File "vmpi_browser_job_search.cpp"
+ $File "vmpi_browser_job_search.rc"
+ $File "..\window_anchor_mgr.cpp"
+
+ $File "JobSearchDlg.cpp" \
+ "..\vmpi_browser_helpers.cpp"
+ {
+ $Configuration
+ {
+ $Compiler
+ {
+ $Create/UsePrecompiledHeader "Not Using Precompiled Headers"
+ }
+ }
+ }
+
+ $File "StdAfx.cpp"
+ {
+ $Configuration
+ {
+ $Compiler
+ {
+ $Create/UsePrecompiledHeader "Create Precompiled Header (/Yc)"
+ }
+ }
+ }
+ }
+
+ $Folder "Header Files"
+ {
+ $File "JobSearchDlg.h"
+ $File "..\mysql_wrapper.h"
+ $File "..\net_view_thread.h"
+ $File "Resource.h"
+ $File "StdAfx.h"
+ $File "..\vmpi_browser_helpers.h"
+ $File "vmpi_browser_job_search.h"
+ $File "..\window_anchor_mgr.h"
+ }
+
+ $Folder "Resource Files"
+ {
+ $File "res\vmpi_browser_job_search.ico"
+ $File "res\vmpi_browser_job_search.rc2"
+ }
+}