This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions

View File

@ -0,0 +1,210 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <windows.h>
#include "CreateModWizard.h"
#include "sdklauncher_main.h"
#include "filesystem_tools.h"
#include "sdklauncherdialog.h"
#include "configs.h"
#include <vgui_controls/WizardSubPanel.h>
#include <vgui_controls/DirectorySelectDialog.h>
#include <vgui/ivgui.h>
#include <vgui/iinput.h>
#include <ctype.h>
#include <io.h>
#include <direct.h>
#include "ModWizard_Intro.h"
#include "ModWizard_GetModInfo.h"
#include "ModWizard_CopyFiles.h"
#include "ModWizard_Finished.h"
#include "ModWizard_TemplateOptions.h"
extern char g_engineDir[50];
using namespace vgui;
// Set to true when the mod wizard completes successfully.
bool g_bModWizardFinished = false;
bool CreateFullDirectory( const char *pDirName )
{
CUtlVector<char*> dirs;
const char *separators[2] = {"\\", "/"};
Q_SplitString2( pDirName, separators, ARRAYSIZE( separators ), dirs );
if ( dirs.Count() == 0 )
return false;
char dirName[512];
Q_strncpy( dirName, dirs[0], sizeof( dirName ) );
for ( int i=1; i < dirs.Count(); i++ )
{
Q_AppendSlash( dirName, sizeof( dirName ) );
Q_strncat( dirName, dirs[i], sizeof( dirName ), COPY_ALL_CHARACTERS );
if ( _access( dirName, 0 ) != 0 )
if ( _mkdir( dirName ) != 0 )
return false;
}
dirs.PurgeAndDeleteElements();
return true;
}
bool CreateSubdirectory( const char *pDirName, const char *pSubdirName )
{
char str[512];
Q_strncpy( str, pDirName, sizeof( str ) );
Q_AppendSlash( str, sizeof( str ) );
Q_strncat( str, pSubdirName, sizeof( str ), COPY_ALL_CHARACTERS );
return CreateFullDirectory( str );
}
void RunCreateModWizard( bool bRunFromCommandLine )
{
CCreateModWizard *pWizard = new CCreateModWizard( g_pMainFrame, "CreateModWizard", NULL, bRunFromCommandLine );
pWizard->Run();
}
bool DoCopyFile( const char *pInputFilename, const char *pOutputFilename )
{
return CopyWithReplacements( pInputFilename, NULL, 0, "%s", pOutputFilename );
}
void SetModWizardStatusCode( unsigned long inputCode )
{
DWORD code = inputCode;
HKEY hKey;
// Changed to HKEY_CURRENT_USER from HKEY_LOCAL_MACHINE
if ( RegCreateKeyEx( HKEY_CURRENT_USER, "Software\\Valve\\SourceSDK", 0, 0, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL ) == ERROR_SUCCESS )
{
RegSetValueEx( hKey, "ModWizard_StatusCode", 0, REG_DWORD, (unsigned char*)&code, sizeof( code ) );
RegCloseKey( hKey );
}
}
void NoteModWizardFinished()
{
g_bModWizardFinished = true;
}
// --------------------------------------------------------------------------------------------------------------------- //
// CFinalStatusWindow
// --------------------------------------------------------------------------------------------------------------------- //
class CFinalStatusWindow : public vgui::Frame
{
public:
typedef vgui::Frame BaseClass;
CFinalStatusWindow( vgui::Panel *parent, const char *pName, const char *pOutputDirName, const char *pOutputModGamedirName )
: BaseClass( parent, pName )
{
m_pLabel = new vgui::Label( this, "MessageLabel", "" );
LoadControlSettings( "FinalStatusWindow.res" );
char msg[512];
Q_snprintf( msg, sizeof( msg ), "Files copied successfully!\n\n"
"- The source code is in '%ssrc'.\n"
"- You can run the base mod by running '%srunmod.bat'.\n"
"- You can run the HL2 mod by running '%srunhl2.bat'.\n"
"- There is also a new item in your game list."
, pOutputDirName, pOutputDirName, pOutputDirName );
m_pLabel->SetText( msg );
}
private:
vgui::Label *m_pLabel;
};
// --------------------------------------------------------------------------------------------------------------------- //
// CreateModWizard implementation.
// --------------------------------------------------------------------------------------------------------------------- //
CCreateModWizard::CCreateModWizard( vgui::Panel *parent, const char *name, KeyValues *pKeyValues, bool bRunFromCommandLine )
: BaseClass( parent, name )
{
m_bRunFromCommandLine = bRunFromCommandLine;
m_pKeyValues = pKeyValues;
SetBounds(0, 0, 480, 360);
WizardSubPanel *subPanel = new CModWizardSubPanel_Intro( this, "CModWizardSubPanel_Intro" );
subPanel->SetVisible( false );
subPanel = new CModWizardSubPanel_GetModInfo( this, "CModWizardSubPanel_GetModInfo" );
subPanel->SetVisible( false );
subPanel = new CModWizardSubPanel_TemplateOptions( this, "CModWizardSubPanel_TemplateOptions" );
subPanel->SetVisible( false );
// Tell the config manager which games to put in the config by default
if ( !V_strcmp( g_engineDir, "orangebox" ) )
{
subPanel = new CModWizardSubPanel_CopyFiles_Source2009( this, "CModWizardSubPanel_CopyFiles" );
}
else if ( !V_strcmp( g_engineDir, "source2007" ) )
{
subPanel = new CModWizardSubPanel_CopyFiles_Source2007( this, "CModWizardSubPanel_CopyFiles" );
}
else
{
subPanel = new CModWizardSubPanel_CopyFiles_Source2006( this, "CModWizardSubPanel_CopyFiles" );
}
subPanel->SetVisible( false );
subPanel = new CModWizardSubPanel_Finished( this, "CModWizardSubPanel_Finished" );
subPanel->SetVisible( false );
}
CCreateModWizard::~CCreateModWizard()
{
if ( m_bRunFromCommandLine )
{
g_bAppQuit = true;
if ( g_bModWizardFinished )
SetModWizardStatusCode( 2 );
else
SetModWizardStatusCode( 3 );
}
}
void CCreateModWizard::Run()
{
// Set the CompletionCode in the registry to say that we've started.
g_bModWizardFinished = false;
SetModWizardStatusCode( 1 );
CModWizardSubPanel_Intro *pIntro = (CModWizardSubPanel_Intro*)FindChildByName( "CModWizardSubPanel_Intro" );
if ( !pIntro )
Error( "Missing CModWizardSubPanel_Intro panel." );
if ( g_bAutoHL2Mod )
{
pIntro->m_pModHL2Button->SetSelected( true );
BaseClass::Run( dynamic_cast<WizardSubPanel *>( FindChildByName( "CModWizardSubPanel_GetModInfo" ) ) );
}
else
{
BaseClass::Run( dynamic_cast<WizardSubPanel *>(pIntro) );
}
MoveToCenterOfScreen();
Activate();
vgui::input()->SetAppModalSurface( GetVPanel() );
}

View File

@ -0,0 +1,61 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef CREATEMODWIZARD_H
#define CREATEMODWIZARD_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Frame.h>
#include <vgui_controls/ImageList.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/SectionedListPanel.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/PHandle.h>
#include <vgui_controls/WizardPanel.h>
#include <FileSystem.h>
#include "vgui/mousecode.h"
#include "vgui/IScheme.h"
class CCreateModWizard : public vgui::WizardPanel
{
typedef vgui::WizardPanel BaseClass;
public:
CCreateModWizard( vgui::Panel *parent, const char *name, KeyValues *pKeyValues, bool bRunFromCommandLine );
virtual ~CCreateModWizard();
void Run();
protected:
KeyValues *m_pKeyValues; // These come from inside the CreateMod command in the medialist.txt file.
bool m_bRunFromCommandLine;
private:
//DECLARE_PANELMAP();
};
// Utility functions.
bool CreateFullDirectory( const char *pDirName );
bool CreateSubdirectory( const char *pDirName, const char *pSubdirName );
bool DoCopyFile( const char *pInputFilename, const char *pOutputFilename );
void RunCreateModWizard( bool bRunFromCommandLine );
// Sets a value in the registry that other apps (like the VS Express edition) can look at.
void SetModWizardStatusCode( unsigned long code );
// Called when they get to the "finished!" dialog.
void NoteModWizardFinished();
#endif // CREATEMODWIZARD_H

684
sdklauncher/Main.cpp Normal file
View File

@ -0,0 +1,684 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//===========================================================================//
#include <vgui/ILocalize.h>
#include <vgui/IScheme.h>
#include <vgui/ISurface.h>
#include <vgui/IVGui.h>
#include <vgui/IInput.h>
#include <vgui/isystem.h>
#include <vgui_controls/MessageBox.h>
#include <vgui_controls/Controls.h>
#include <vgui_controls/Panel.h>
#include "SDKLauncherDialog.h"
#include "appframework/tier3app.h"
#include "tier0/icommandline.h"
#include "filesystem_tools.h"
#include "sdklauncher_main.h"
#include "configs.h"
#include "min_footprint_files.h"
#include "CreateModWizard.h"
#include "inputsystem/iinputsystem.h"
#include <io.h>
#include <stdio.h>
// Since windows redefines MessageBox.
typedef vgui::MessageBox vguiMessageBox;
#include <winsock2.h>
#include "steam/steam_api.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
HANDLE g_dwChangeHandle = NULL;
#define DEFAULTGAMEDIR_KEYNAME "DefaultGameDir"
// Dummy window
static WNDCLASS staticWndclass = { NULL };
static ATOM staticWndclassAtom = 0;
static HWND staticHwnd = 0;
CSteamAPIContext g_SteamAPIContext;
CSteamAPIContext *steamapicontext = &g_SteamAPIContext;
// This is the base engine + mod-specific game dir (e.g. "c:\tf2\mytfmod\")
char gamedir[1024];
extern char g_engineDir[50];
CSDKLauncherDialog *g_pMainFrame = 0;
bool g_bAutoHL2Mod = false;
bool g_bModWizard_CmdLineFields = false;
char g_ModWizard_CmdLine_ModDir[MAX_PATH];
char g_ModWizard_CmdLine_ModName[256];
bool g_bAppQuit = false;
//-----------------------------------------------------------------------------
// Purpose: Message handler for dummy app
//-----------------------------------------------------------------------------
static LRESULT CALLBACK messageProc( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
// See if we've gotten a VPROJECT change
if ( msg == WM_SETTINGCHANGE )
{
if ( g_pMainFrame != NULL )
{
char szCurrentGame[MAX_PATH];
// Get VCONFIG from the registry
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szCurrentGame, sizeof( szCurrentGame ) );
g_pMainFrame->SetCurrentGame( szCurrentGame );
}
}
return ::DefWindowProc(hwnd,msg,wparam,lparam);
}
const char* GetLastWindowsErrorString()
{
static char err[2048];
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
strncpy( err, (char*)lpMsgBuf, sizeof( err ) );
LocalFree( lpMsgBuf );
err[ sizeof( err ) - 1 ] = 0;
return err;
}
//-----------------------------------------------------------------------------
// Purpose: Creates a dummy window that handles windows messages
//-----------------------------------------------------------------------------
void CreateMessageWindow( void )
{
// Make and register a very simple window class
memset(&staticWndclass, 0, sizeof(staticWndclass));
staticWndclass.style = 0;
staticWndclass.lpfnWndProc = messageProc;
staticWndclass.hInstance = GetModuleHandle(NULL);
staticWndclass.lpszClassName = "SDKLauncher_Window";
staticWndclassAtom = ::RegisterClass( &staticWndclass );
// Create an empty window just for message handling
staticHwnd = CreateWindowEx(0, "SDKLauncher_Window", "Hidden Window", 0, 0, 0, 1, 1, NULL, NULL, GetModuleHandle(NULL), NULL);
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void ShutdownMessageWindow( void )
{
// Kill our windows instance
::DestroyWindow( staticHwnd );
::UnregisterClass("VConfig_Window", ::GetModuleHandle(NULL));
}
SpewRetval_t SDKLauncherSpewOutputFunc( SpewType_t spewType, char const *pMsg )
{
#ifdef _WIN32
OutputDebugString( pMsg );
#endif
if (spewType == SPEW_ERROR)
{
// In Windows vgui mode, make a message box or they won't ever see the error.
#ifdef _WIN32
MessageBox( NULL, pMsg, "Error", MB_OK | MB_TASKMODAL );
TerminateProcess( GetCurrentProcess(), 1 );
#elif _LINUX
_exit(1);
#else
#error "Implement me"
#endif
return SPEW_ABORT;
}
if (spewType == SPEW_ASSERT)
{
if ( CommandLine()->FindParm( "-noassert" ) == 0 )
return SPEW_DEBUGGER;
else
return SPEW_CONTINUE;
}
return SPEW_CONTINUE;
}
const char* GetSDKLauncherBinDirectory()
{
static char path[MAX_PATH] = {0};
if ( path[0] == 0 )
{
GetModuleFileName( (HMODULE)GetAppInstance(), path, sizeof( path ) );
Q_StripLastDir( path, sizeof( path ) ); // Get rid of the filename.
Q_StripTrailingSlash( path );
}
return path;
}
const char* GetSDKToolsBinDirectory( )
{
static char path[MAX_PATH] = {0};
if ( path[0] == 0 )
{
GetModuleFileName( (HMODULE)GetAppInstance(), path, sizeof( path ) );
Q_StripLastDir( path, sizeof( path ) ); // Get rid of the filename.
V_strncat( path, g_engineDir, sizeof( path ) );
V_strncat( path, "\\bin", sizeof( path ) );
}
return path;
}
const char* GetSDKLauncherBaseDirectory()
{
static char basedir[512] = {0};
if ( basedir[0] == 0 )
{
Q_strncpy( basedir, GetSDKLauncherBinDirectory(), sizeof( basedir ) );
Q_StripLastDir( basedir, sizeof( basedir ) ); // Get rid of the bin directory.
Q_StripTrailingSlash( basedir );
}
return basedir;
}
void SubstituteBaseDir( const char *pIn, char *pOut, int outLen )
{
Q_StrSubst( pIn, "%basedir%", GetSDKLauncherBaseDirectory(), pOut, outLen );
}
CUtlVector<char> g_FileData;
CUtlVector<char> g_ReplacementData[2];
CUtlVector<char>* GetFileStringWithReplacements(
const char *pInputFilename,
const char **ppReplacements, int nReplacements,
int &dataWriteLen )
{
Assert( nReplacements % 2 == 0 );
// Read in the file data.
FileHandle_t hFile = g_pFullFileSystem->Open( pInputFilename, "rb" );
if ( !hFile )
{
return false;
}
g_FileData.SetSize( g_pFullFileSystem->Size( hFile ) );
g_pFullFileSystem->Read( g_FileData.Base(), g_FileData.Count(), hFile );
g_pFullFileSystem->Close( hFile );
CUtlVector<char> *pCurData = &g_FileData;
dataWriteLen = g_FileData.Count();
if ( nReplacements )
{
// Null-terminate it.
g_FileData.AddToTail( 0 );
// Apply all the string substitutions.
int iCurCount = g_FileData.Count() * 2;
g_ReplacementData[0].EnsureCount( iCurCount );
g_ReplacementData[1].EnsureCount( iCurCount );
for ( int i=0; i < nReplacements/2; i++ )
{
for ( int iTestCount=0; iTestCount < 64; iTestCount++ )
{
if ( Q_StrSubst( pCurData->Base(), ppReplacements[i*2], ppReplacements[i*2+1], g_ReplacementData[i&1].Base(), g_ReplacementData[i&1].Count() ) )
break;
// Ok, we would overflow the string.. add more space to do the string substitution into.
iCurCount += 2048;
g_ReplacementData[0].EnsureCount( iCurCount );
g_ReplacementData[1].EnsureCount( iCurCount );
}
pCurData = &g_ReplacementData[i&1];
dataWriteLen = strlen( pCurData->Base() );
}
}
return pCurData;
}
bool CopyWithReplacements(
const char *pInputFilename,
const char **ppReplacements, int nReplacements,
const char *pOutputFilenameFormat, ... )
{
int dataWriteLen;
CUtlVector<char> *pCurData = GetFileStringWithReplacements( pInputFilename, ppReplacements, nReplacements, dataWriteLen );
if ( !pCurData )
{
char msg[512];
Q_snprintf( msg, sizeof( msg ), "Can't open %s for reading.", pInputFilename );
::MessageBox( NULL, msg, "Error", MB_OK );
return false;
}
// Get the output filename.
char outFilename[MAX_PATH];
va_list marker;
va_start( marker, pOutputFilenameFormat );
Q_vsnprintf( outFilename, sizeof( outFilename ), pOutputFilenameFormat, marker );
va_end( marker );
// Write it out. I'd like to use IFileSystem, but Steam lowercases all filenames, which screws case-sensitive linux
// (since the linux makefiles are tuned to the casing in Perforce).
FILE *hFile = fopen( outFilename, "wb" );
if ( !hFile )
{
char msg[512];
Q_snprintf( msg, sizeof( msg ), "Can't open %s for writing.", outFilename );
::MessageBox( NULL, msg, "Error", MB_OK );
return false;
}
fwrite( pCurData->Base(), 1, dataWriteLen, hFile );
fclose( hFile );
return true;
}
int InitializeVGui()
{
vgui::ivgui()->SetSleep(false);
// find our configuration directory
char szConfigDir[512];
const char *steamPath = getenv("SteamInstallPath");
if (steamPath)
{
// put the config dir directly under steam
Q_snprintf(szConfigDir, sizeof(szConfigDir), "%s/config", steamPath);
}
else
{
// we're not running steam, so just put the config dir under the platform
Q_strncpy( szConfigDir, "platform/config", sizeof(szConfigDir));
}
g_pFullFileSystem->CreateDirHierarchy("config", "PLATFORM");
g_pFullFileSystem->AddSearchPath(szConfigDir, "CONFIG", PATH_ADD_TO_HEAD);
// initialize the user configuration file
vgui::system()->SetUserConfigFile("DedicatedServerDialogConfig.vdf", "CONFIG");
// Init the surface
vgui::Panel *pPanel = new vgui::Panel(NULL, "TopPanel");
pPanel->SetVisible(true);
vgui::surface()->SetEmbeddedPanel(pPanel->GetVPanel());
// load the scheme
vgui::scheme()->LoadSchemeFromFile("Resource/sdklauncher_scheme.res", NULL);
// localization
g_pVGuiLocalize->AddFile( "resource/platform_english.txt" );
g_pVGuiLocalize->AddFile( "vgui/resource/vgui_english.txt" );
g_pVGuiLocalize->AddFile( "sdklauncher_english.txt" );
// Start vgui
vgui::ivgui()->Start();
// add our main window
g_pMainFrame = new CSDKLauncherDialog(pPanel, "SDKLauncherDialog");
// show main window
g_pMainFrame->MoveToCenterOfScreen();
g_pMainFrame->Activate();
return 0;
}
void ShutdownVGui()
{
delete g_pMainFrame;
}
KeyValues* LoadGameDirsFile()
{
char filename[MAX_PATH];
Q_snprintf( filename, sizeof( filename ), "%ssdklauncher_gamedirs.txt", gamedir );
KeyValues *dataFile = new KeyValues("gamedirs");
dataFile->UsesEscapeSequences( true );
dataFile->LoadFromFile( g_pFullFileSystem, filename, NULL );
return dataFile;
}
bool SaveGameDirsFile( KeyValues *pFile )
{
char filename[MAX_PATH];
Q_snprintf( filename, sizeof( filename ), "%ssdklauncher_gamedirs.txt", gamedir );
return pFile->SaveToFile( g_pFullFileSystem, filename );
}
class CModalPreserveMessageBox : public vguiMessageBox
{
public:
CModalPreserveMessageBox(const char *title, const char *text, vgui::Panel *parent)
: vguiMessageBox( title, text, parent )
{
m_PrevAppFocusPanel = vgui::input()->GetAppModalSurface();
}
~CModalPreserveMessageBox()
{
vgui::input()->SetAppModalSurface( m_PrevAppFocusPanel );
}
public:
vgui::VPANEL m_PrevAppFocusPanel;
};
void VGUIMessageBox( vgui::Panel *pParent, const char *pTitle, const char *pMsg, ... )
{
char msg[4096];
va_list marker;
va_start( marker, pMsg );
Q_vsnprintf( msg, sizeof( msg ), pMsg, marker );
va_end( marker );
vguiMessageBox *dlg = new CModalPreserveMessageBox( pTitle, msg, pParent );
dlg->DoModal();
dlg->RequestFocus();
}
//-----------------------------------------------------------------------------
// Purpose: Startup our file watch
//-----------------------------------------------------------------------------
void UpdateConfigsStatus_Init( void )
{
// Watch our config file for changes
if ( g_dwChangeHandle == NULL)
{
char szConfigDir[MAX_PATH];
Q_strncpy( szConfigDir, GetSDKLauncherBinDirectory(), sizeof( szConfigDir ) );
Q_strncat ( szConfigDir, "\\", MAX_PATH );
Q_strncat ( szConfigDir, g_engineDir, MAX_PATH );
Q_strncat ( szConfigDir, "\\bin", MAX_PATH );
g_dwChangeHandle = FindFirstChangeNotification(
szConfigDir, // directory to watch
false, // watch the subtree
(FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_LAST_WRITE|FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_ATTRIBUTES)); // watch file and dir name changes
if ( g_dwChangeHandle == INVALID_HANDLE_VALUE )
{
// FIXME: Unable to watch the file
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Update our status
//-----------------------------------------------------------------------------
void UpdateConfigsStatus( void )
{
// Wait for notification.
DWORD dwWaitStatus = WaitForSingleObject( g_dwChangeHandle, 0 );
if ( dwWaitStatus == WAIT_OBJECT_0 )
{
// Something in the watched folder changed!
if ( g_pMainFrame != NULL )
{
g_pMainFrame->RefreshConfigs();
}
// Start the next update
if ( FindNextChangeNotification( g_dwChangeHandle ) == FALSE )
{
// This means that something unknown happened to our search handle!
Assert( 0 );
return;
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Stop watching the file
//-----------------------------------------------------------------------------
void UpdateConfigsStatus_Shutdown( void )
{
FindCloseChangeNotification( g_dwChangeHandle );
}
void QuickLaunchCommandLine( char *pCommandLine )
{
STARTUPINFO si;
memset( &si, 0, sizeof( si ) );
si.cb = sizeof( si );
PROCESS_INFORMATION pi;
memset( &pi, 0, sizeof( pi ) );
DWORD dwFlags = 0;
if ( !CreateProcess(
0,
pCommandLine,
NULL, // security
NULL,
TRUE,
dwFlags, // flags
NULL, // environment
GetSDKLauncherBaseDirectory(), // current directory
&si,
&pi ) )
{
::MessageBoxA( NULL, GetLastWindowsErrorString(), "Error", MB_OK | MB_ICONINFORMATION | MB_APPLMODAL );
}
}
bool RunQuickLaunch()
{
char cmdLine[512];
if ( CommandLine()->FindParm( "-runhammer" ) )
{
Q_snprintf( cmdLine, sizeof( cmdLine ), "\"%s\\%s\\bin\\hammer.exe\"", GetSDKLauncherBinDirectory(), g_engineDir );
QuickLaunchCommandLine( cmdLine );
return true;
}
else if ( CommandLine()->FindParm( "-runmodelviewer" ) )
{
Q_snprintf( cmdLine, sizeof( cmdLine ), "\"%s\\%s\\bin\\hlmv.exe\"", GetSDKLauncherBinDirectory(), g_engineDir );
QuickLaunchCommandLine( cmdLine );
return true;
}
else if ( CommandLine()->FindParm( "-runfaceposer" ) )
{
Q_snprintf( cmdLine, sizeof( cmdLine ), "\"%s\\%s\\bin\\hlfaceposer.exe\"", GetSDKLauncherBinDirectory(), g_engineDir );
QuickLaunchCommandLine( cmdLine );
return true;
}
return false;
}
void CheckCreateModParameters()
{
if ( CommandLine()->FindParm( "-AutoHL2Mod" ) )
g_bAutoHL2Mod = true;
int iParm = CommandLine()->FindParm( "-CreateMod" );
if ( iParm == 0 )
return;
if ( (iParm + 2) < CommandLine()->ParmCount() )
{
// Set it up so the mod wizard can skip the mod dir/mod name panel.
g_bModWizard_CmdLineFields = true;
Q_strncpy( g_ModWizard_CmdLine_ModDir, CommandLine()->GetParm( iParm + 1 ), sizeof( g_ModWizard_CmdLine_ModDir ) );
Q_strncpy( g_ModWizard_CmdLine_ModName, CommandLine()->GetParm( iParm + 2 ), sizeof( g_ModWizard_CmdLine_ModName ) );
RunCreateModWizard( true );
}
}
//-----------------------------------------------------------------------------
// The application object
//-----------------------------------------------------------------------------
class CSDKLauncherApp : public CVguiSteamApp
{
typedef CVguiSteamApp BaseClass;
public:
// Methods of IApplication
virtual bool Create();
virtual bool PreInit();
virtual int Main();
virtual void PostShutdown();
virtual void Destroy() {}
};
DEFINE_WINDOWED_STEAM_APPLICATION_OBJECT( CSDKLauncherApp );
//-----------------------------------------------------------------------------
// The application object
//-----------------------------------------------------------------------------
bool CSDKLauncherApp::Create()
{
SpewOutputFunc( SDKLauncherSpewOutputFunc );
AppSystemInfo_t appSystems[] =
{
{ "inputsystem.dll", INPUTSYSTEM_INTERFACE_VERSION },
{ "vgui2.dll", VGUI_IVGUI_INTERFACE_VERSION },
{ "", "" } // Required to terminate the list
};
return AddSystems( appSystems );
}
//-----------------------------------------------------------------------------
// Purpose: Entry point
//-----------------------------------------------------------------------------
bool CSDKLauncherApp::PreInit()
{
if ( !BaseClass::PreInit() )
return false;
// Make sure we're using the proper environment variable
ConvertObsoleteVConfigRegistrySetting( GAMEDIR_TOKEN );
if ( !CommandLine()->ParmValue( "-game" ) )
{
Error( "SDKLauncher requires -game on the command line." );
return false;
}
// winsock aware
WSAData wsaData;
WSAStartup( MAKEWORD(2,0), &wsaData );
// Create a window to capture messages
CreateMessageWindow();
FileSystem_SetErrorMode( FS_ERRORMODE_AUTO );
if ( !BaseClass::SetupSearchPaths( NULL, false, true ) )
{
::MessageBox( NULL, "Error", "Unable to initialize file system\n", MB_OK );
return false;
}
// Set gamedir.
Q_MakeAbsolutePath( gamedir, sizeof( gamedir ), GetGameInfoPath() );
Q_AppendSlash( gamedir, sizeof( gamedir ) );
// the "base dir" so we can scan mod name
g_pFullFileSystem->AddSearchPath(GetSDKLauncherBaseDirectory(), SDKLAUNCHER_MAIN_PATH_ID);
// the main platform dir
g_pFullFileSystem->AddSearchPath("platform","PLATFORM", PATH_ADD_TO_HEAD);
return true;
}
void CSDKLauncherApp::PostShutdown()
{
// Stop our message window
ShutdownMessageWindow();
::WSACleanup();
BaseClass::PostShutdown();
}
//-----------------------------------------------------------------------------
// Purpose: Entry point
//-----------------------------------------------------------------------------
int CSDKLauncherApp::Main()
{
SetVConfigRegistrySetting( "sourcesdk", GetSDKLauncherBaseDirectory() );
// If they just want to run Hammer or hlmv, just do that and exit.
if ( RunQuickLaunch() )
return 1;
// Run app frame loop
int ret = InitializeVGui();
if ( ret != 0 )
return ret;
DumpMinFootprintFiles( false );
SteamAPI_InitSafe();
SteamAPI_SetTryCatchCallbacks( false ); // We don't use exceptions, so tell steam not to use try/catch in callback handlers
g_SteamAPIContext.Init();
// Start looking for file updates
// UpdateConfigsStatus_Init();
// Check if they want to run the Create Mod wizard right off the bat.
CheckCreateModParameters();
while ( vgui::ivgui()->IsRunning() && !g_bAppQuit )
{
Sleep( 10 );
// UpdateConfigsStatus();
vgui::ivgui()->RunFrame();
}
ShutdownVGui();
// UpdateConfigsStatus_Shutdown();
return 1;
}

View File

@ -0,0 +1,99 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
/**
* Utility class for providing some basic capabilities for enumerating and specifying MOD
* directories.
*
* \version 1.0
*
* \date 07-18-2006
*
* \author mdurand
*
* \todo
*
* \bug
*
*/
#include "ModConfigsHelper.h"
#include <windows.h>
ModConfigsHelper::ModConfigsHelper()
{
setSourceModBaseDir();
EnumerateModDirs();
}
/**
* Default destructor.
*/
ModConfigsHelper::~ModConfigsHelper()
{
// Empty the vector of directory names
m_ModDirs.PurgeAndDeleteElements();
}
/**
* Getter method that provides the parent directory for all MODs.
* \return parent directory for all MODs
*/
const char *ModConfigsHelper::getSourceModBaseDir()
{
return m_sourceModBaseDir;
}
/**
* Getter method that provides a vector of the names of each MOD found.
* \return vector of the names of each MOD found
*/
const CUtlVector<char *> &ModConfigsHelper::getModDirsVector()
{
return m_ModDirs;
}
/**
* Determines and sets the base directory for all MODs
*/
void ModConfigsHelper::setSourceModBaseDir()
{
Q_strncpy( m_sourceModBaseDir, GetSDKLauncherBaseDirectory(), sizeof( m_sourceModBaseDir) ); // Start with the base directory
Q_StripLastDir( m_sourceModBaseDir, sizeof( m_sourceModBaseDir ) ); // Get rid of the 'sourcesdk' directory.
Q_StripLastDir( m_sourceModBaseDir, sizeof( m_sourceModBaseDir ) ); // Get rid of the '%USER%' directory.
Q_strncat( m_sourceModBaseDir, "SourceMods", sizeof( m_sourceModBaseDir ), COPY_ALL_CHARACTERS ); // Add 'SourceMods'
}
/**
* Searches the parent MOD directory for child MODs and puts their names in the member vector
*/
void ModConfigsHelper::EnumerateModDirs()
{
char szWildCardPath[MAX_PATH];
WIN32_FIND_DATA wfd;
Q_strncpy( szWildCardPath, m_sourceModBaseDir, sizeof( szWildCardPath ) );
Q_AppendSlash( szWildCardPath, sizeof( szWildCardPath ) );
Q_strncat( szWildCardPath, "*.*", sizeof( szWildCardPath ), COPY_ALL_CHARACTERS );
HANDLE ff = FindFirstFile( szWildCardPath, &wfd );
do
{
if ( wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
{
if ( wfd.cFileName[ 0 ] == '.' )
{
continue;
}
else
{
// They are directories not named '.' or '..' so add them to the list of mod directories
char *dirName = new char[ strlen( wfd.cFileName ) + 1 ];
Q_strncpy( dirName, wfd.cFileName, strlen( wfd.cFileName ) + 1 );
m_ModDirs.AddToTail( dirName );
}
}
} while ( FindNextFile( ff, &wfd ) );
}

View File

@ -0,0 +1,71 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
/**
* Utility class for providing some basic capabilities for enumerating and specifying MOD
* directories.
*
* \version 1.0
*
* \date 07-18-2006
*
* \author mdurand
*
* \todo
*
* \bug
*
*/
#ifndef MODCONFIGSHELPER_H
#define MODCONFIGSHELPER_H
#ifdef _WIN32
#pragma once
#endif
#include "utlvector.h"
#include "sdklauncher_main.h"
class ModConfigsHelper
{
public:
/**
* Default constructor which automatically finds and sets the base directory for all MODs
* and populates a vector of MOD directory names.
*/
ModConfigsHelper();
/**
* Default destructor.
*/
~ModConfigsHelper();
/**
* Getter method that provides the parent directory for all MODs.
* \return parent directory for all MODs
*/
const char *getSourceModBaseDir();
/**
* Getter method that provides a vector of the names of each MOD found.
* \return vector of the names of each MOD found
*/
const CUtlVector<char *> &getModDirsVector();
protected:
/**
* Determines and sets the base directory for all MODs
*/
void setSourceModBaseDir();
/**
* Searches the parent MOD directory for child MODs and puts their names in the member vector
*/
void EnumerateModDirs();
private:
// Member that holds the base directory of MODs
char m_sourceModBaseDir[MAX_PATH];
// Member that holds the child MOD names
CUtlVector<char *> m_ModDirs;
};
#endif // MODCONFIGSHELPER_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,149 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef MODWIZARD_COPYFILES_H
#define MODWIZARD_COPYFILES_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/WizardSubPanel.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/ProgressBar.h>
#include "utlvector.h"
#include "configs.h"
// --------------------------------------------------------------------------------------------------------------------- //
// CreateModWizard sub panel 3.
// This panel asks for the directory to install in and the mod name.
// --------------------------------------------------------------------------------------------------------------------- //
namespace vgui
{
class CModWizardSubPanel_CopyFiles : public WizardSubPanel
{
public:
typedef WizardSubPanel BaseClass;
public:
CModWizardSubPanel_CopyFiles( Panel *parent, const char *panelName );
// Called to store the settings it'll use to copy all the files over.
void GetReady( const char *pOutputDirName, const char *pOutputModGamedirName, const char *modName ) ;
virtual WizardSubPanel* GetNextSubPanel();
virtual void OnDisplayAsNext();
virtual void OnTick();
protected:
class CFileCopyInfo
{
public:
CFileCopyInfo( const char *pIn, const char *pOut )
{
Q_strncpy( m_InFilename, pIn, sizeof( m_InFilename ) );
Q_strncpy( m_OutFilename, pOut, sizeof( m_OutFilename ) );
}
char m_InFilename[MAX_PATH];
char m_OutFilename[MAX_PATH];
};
protected:
bool BuildCopyFiles_R( const char *pSourceDir, const char *pMask, const char *pOutputDirName );
bool BuildCopyFilesForMappings( char **pMappings, int nMappings );
bool HandleSpecialFileCopy( CFileCopyInfo *pInfo, bool &bErrorStatus );
bool HandleReplacements_GenericVCProj( CFileCopyInfo *pInfo, bool &bErrorStatus );
virtual bool BuildCopyFilesForMod_HL2() = 0;
virtual bool BuildCopyFilesForMod_HL2MP() = 0;
virtual bool BuildCopyFilesForMod_FromScratch() = 0;
virtual bool BuildCopyFilesForMod_SourceCodeOnly() = 0;
virtual bool HandleReplacements_GameProjectFiles( CFileCopyInfo *pInfo, bool &bErrorStatus ) = 0;
virtual bool HandleReplacements_Solution( CFileCopyInfo *pInfo, bool &bErrorStatus ) = 0;
// Right now only one of these files gets modified, but keeping it here for expansion in the future.
virtual bool HandleReplacements_TemplateOptions( CFileCopyInfo *pInfo, bool &bErrorStatus ) = 0;
protected:
CUtlVector<CFileCopyInfo> m_FileCopyInfos;
int m_iCurCopyFile; // -1 at the beginning.
Label *m_pLabel;
Label *m_pFinishedLabel;
ProgressBar *m_pProgressBar;
char m_OutputDirName[MAX_PATH]; // c:\mymod
char m_OutModGamedirName[MAX_PATH]; // c:\mymod\mymod
char m_ModName[MAX_PATH]; // mymod
ModType_t m_ModType;
};
class CModWizardSubPanel_CopyFiles_Source2006 : public CModWizardSubPanel_CopyFiles
{
public:
CModWizardSubPanel_CopyFiles_Source2006( Panel *parent, const char *panelName );
private:
bool BuildCopyFilesForMod_HL2();
bool BuildCopyFilesForMod_HL2MP();
bool BuildCopyFilesForMod_FromScratch();
bool BuildCopyFilesForMod_SourceCodeOnly();
bool HandleReplacements_GameProjectFiles( CFileCopyInfo *pInfo, bool &bErrorStatus );
bool HandleReplacements_Solution( CFileCopyInfo *pInfo, bool &bErrorStatus );
bool HandleReplacements_TemplateOptions( CFileCopyInfo *pInfo, bool &bErrorStatus ) { return false; } // Ep1 will never do this.
};
class CModWizardSubPanel_CopyFiles_Source2007 : public CModWizardSubPanel_CopyFiles
{
public:
CModWizardSubPanel_CopyFiles_Source2007( Panel *parent, const char *panelName );
private:
bool BuildCopyFilesForMod_HL2();
bool BuildCopyFilesForMod_HL2MP();
bool BuildCopyFilesForMod_FromScratch();
bool BuildCopyFilesForMod_SourceCodeOnly();
bool HandleReplacements_GameProjectFiles( CFileCopyInfo *pInfo, bool &bErrorStatus );
bool HandleReplacements_Solution( CFileCopyInfo *pInfo, bool &bErrorStatus );
// Right now only one of these files gets modified, but keeping it here for expansion in the future.
bool HandleReplacements_TemplateOptions( CFileCopyInfo *pInfo, bool &bErrorStatus );
};
class CModWizardSubPanel_CopyFiles_Source2009 : public CModWizardSubPanel_CopyFiles
{
public:
CModWizardSubPanel_CopyFiles_Source2009( Panel *parent, const char *panelName );
private:
bool BuildCopyFilesForMod_HL2();
bool BuildCopyFilesForMod_HL2MP();
bool BuildCopyFilesForMod_FromScratch();
bool BuildCopyFilesForMod_SourceCodeOnly();
bool HandleReplacements_GameProjectFiles( CFileCopyInfo *pInfo, bool &bErrorStatus );
bool HandleReplacements_Solution( CFileCopyInfo *pInfo, bool &bErrorStatus );
// Right now only one of these files gets modified, but keeping it here for expansion in the future.
bool HandleReplacements_TemplateOptions( CFileCopyInfo *pInfo, bool &bErrorStatus );
};
}
#endif // MODWIZARD_COPYFILES_H

View File

@ -0,0 +1,80 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "ModWizard_Finished.h"
#include "CreateModWizard.h"
#include <vgui_controls/WizardPanel.h>
#include <vgui/ILocalize.h>
#include <vgui/ISystem.h>
extern void OpenLocalizedURL( const char *lpszLocalName );
using namespace vgui;
CModWizardSubPanel_Finished::CModWizardSubPanel_Finished( Panel *parent, const char *panelName )
: BaseClass( parent, panelName )
{
m_pFinishedText = new Label( this, "FinishedText", "" );
m_pOpenReadme = new CheckButton( this, "OpenReadme", "" );
m_OutputDirName[0] = 0;
LoadControlSettings( "ModWizardSubPanel_Finished.res");
m_pOpenReadme->SetSelected( true );
}
void CModWizardSubPanel_Finished::GetReady( const char *pOutputDirName )
{
wchar_t *formatStr = g_pVGuiLocalize->Find( "ModWizard_FinishedText" );
if ( formatStr )
{
wchar_t tempStr[4096], labelStr[4096];
Q_strncpy( m_OutputDirName, pOutputDirName, sizeof( m_OutputDirName ) );
int len = strlen( m_OutputDirName );
if ( len > 0 )
{
if ( m_OutputDirName[len-1] == '/' || m_OutputDirName[len-1] == '\\' )
m_OutputDirName[len-1] = 0;
}
g_pVGuiLocalize->ConvertANSIToUnicode( m_OutputDirName, tempStr, sizeof( tempStr ) );
g_pVGuiLocalize->ConstructString( labelStr, sizeof( labelStr ), formatStr, 1, tempStr );
m_pFinishedText->SetText( labelStr );
}
}
WizardSubPanel *CModWizardSubPanel_Finished::GetNextSubPanel()
{
return NULL;
}
void CModWizardSubPanel_Finished::PerformLayout()
{
BaseClass::PerformLayout();
GetWizardPanel()->SetFinishButtonEnabled( true );
GetWizardPanel()->SetPrevButtonEnabled( false );
}
void CModWizardSubPanel_Finished::OnDisplayAsNext()
{
GetWizardPanel()->SetTitle( "#ModWizard_Finished_Title", true );
NoteModWizardFinished();
}
bool CModWizardSubPanel_Finished::OnFinishButton()
{
if ( m_pOpenReadme->IsSelected() )
{
// ShellExecute.. to the site.
OpenLocalizedURL( "URL_Create_Mod_Finished" );
}
return true;
}

View File

@ -0,0 +1,51 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef MODWIZARD_FINISHED_H
#define MODWIZARD_FINISHED_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/WizardSubPanel.h>
#include <vgui_controls/Label.h>
#include <vgui_controls/CheckButton.h>
// --------------------------------------------------------------------------------------------------------------------- //
// CreateModWizard sub panel 1.
// This panel just tells them about the wizard and what it's going to do, and gives them a chance to cancel.
// --------------------------------------------------------------------------------------------------------------------- //
namespace vgui
{
class CModWizardSubPanel_Finished : public WizardSubPanel
{
public:
typedef WizardSubPanel BaseClass;
public:
CModWizardSubPanel_Finished( Panel *parent, const char *panelName );
void GetReady( const char *pOutputDirName );
virtual WizardSubPanel* GetNextSubPanel();
virtual void OnDisplayAsNext();
virtual void PerformLayout();
virtual bool OnFinishButton();
private:
Label *m_pFinishedText;
CheckButton *m_pOpenReadme;
char m_OutputDirName[MAX_PATH]; // c:\mymod
};
}
#endif // MODWIZARD_FINISHED_H

View File

@ -0,0 +1,219 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "ModWizard_GetModInfo.h"
#include <vgui_controls/DirectorySelectDialog.h>
#include <vgui/IInput.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/WizardPanel.h>
#include "sdklauncher_main.h"
#include <ctype.h>
#include "CreateModWizard.h"
#include "ModWizard_CopyFiles.h"
using namespace vgui;
extern char g_engineDir[50];
// ---------------------------------------------------------------------------------------- //
// Directory select dialog that preserves the modalness of the previous dialog.
// ---------------------------------------------------------------------------------------- //
class CModalPreserveDirectorySelectDialog : public DirectorySelectDialog
{
public:
typedef vgui::DirectorySelectDialog BaseClass;
CModalPreserveDirectorySelectDialog(vgui::Panel *pParent, const char *title)
: BaseClass( pParent, title )
{
m_PrevAppFocusPanel = vgui::input()->GetAppModalSurface();
vgui::input()->SetAppModalSurface( GetVPanel() );
}
~CModalPreserveDirectorySelectDialog()
{
vgui::input()->SetAppModalSurface( m_PrevAppFocusPanel );
}
public:
vgui::VPANEL m_PrevAppFocusPanel;
};
CModWizardSubPanel_GetModInfo::CModWizardSubPanel_GetModInfo( Panel *parent, const char *panelName )
: BaseClass( parent, panelName )
{
m_pModPath = new vgui::TextEntry( this, "ModPath" );
m_pModName = new vgui::TextEntry( this, "ModName" );
new vgui::Button( this, "SearchButton", "", this, "SearchButton" );
m_pModNameInfoLabel = new Label( this, "ModNameInfoLabel", "" );
LoadControlSettings( "ModWizardSubPanel_GetModInfo.res");
if ( g_bModWizard_CmdLineFields )
{
m_pModPath->SetText( g_ModWizard_CmdLine_ModDir );
m_pModPath->SetEditable( false );
m_pModPath->SetEnabled( false );
m_pModName->SetText( g_ModWizard_CmdLine_ModName );
m_pModName->SetEditable( false );
m_pModName->SetEnabled( false );
}
}
WizardSubPanel *CModWizardSubPanel_GetModInfo::GetNextSubPanel()
{
// In scratch/template, go to the template options panel - orange box only!
if ( m_ModType == ModType_FromScratch && !V_strcmp( g_engineDir, "source2007" ) )
return dynamic_cast<WizardSubPanel *>(GetWizardPanel()->FindChildByName("CModWizardSubPanel_TemplateOptions"));
else
return dynamic_cast<WizardSubPanel *>(GetWizardPanel()->FindChildByName("CModWizardSubPanel_CopyFiles"));
}
void CModWizardSubPanel_GetModInfo::PerformLayout()
{
BaseClass::PerformLayout();
GetWizardPanel()->SetFinishButtonEnabled(false);
}
void CModWizardSubPanel_GetModInfo::OnDisplayAsNext()
{
GetWizardPanel()->SetTitle( "#ModWizard_GetModInfo_Title", true );
}
bool CModWizardSubPanel_GetModInfo::OnNextButton()
{
char modPath[512];
m_pModPath->GetText( modPath, sizeof( modPath ) );
Q_AppendSlash( modPath, sizeof( modPath ) );
char modName[512];
m_pModName->GetText( modName, sizeof( modName ) );
// Validate the path they passed in.
if ( modPath[0] == 0 )
{
VGUIMessageBox( GetWizardPanel(), "Error", "#PleaseEnterModPath" );
return false;
}
else if ( !Q_IsAbsolutePath( modPath ) )
{
VGUIMessageBox( this, "Error", "Please enter a full path (like C:\\MyMod) to install the mod." );
return false;
}
// Validate the mod name.
char outputModGamedirName[MAX_PATH];
if ( m_ModType == ModType_SourceCodeOnly )
{
outputModGamedirName[0] = 0;
modName[0] = 0;
}
else
{
if ( modName[0] == 0 )
{
VGUIMessageBox( this, "Error", "#PleaseEnterModName" );
m_pModName->RequestFocus();
return false;
}
int modNameLen = strlen( modName );
for ( int i=0; i < modNameLen; i++ )
{
if ( !isalnum( modName[i] ) && modName[i] != '-' && modName[i] != '_' && modName[i] != ' ' )
{
VGUIMessageBox( this, "Error", "#ModNameInvalidCharacters" );
return false;
}
}
//Tony; after the other check for invalid characters, make the actual outputModGamedirName lowercase with spaces stripped out.
char strippedModName[512]; //this is what gets thrown on below!
//Tony; reuse modNameLen when I copy it to the new string.
//I could have sworn there was an easier way to do this, but it completely escapes me.
int i,j;
modNameLen = strlen( modName );
for (i=0, j=0;i < modNameLen; i++ )
{
if (modName[i] == ' ') continue;
strippedModName[j++] = modName[i];
}
strippedModName[j] = '\0'; //Null terminate.
// Q_strncpy( strippedModName, ModName, sizeof( strippedModName ) );
Q_strlower( strippedModName ); //Tony; convert it to lower case
// Build the name of the content directory (c:\steam\steamapps\sourcemods\modname).
Q_strncpy( outputModGamedirName, GetSDKLauncherBaseDirectory(), sizeof( outputModGamedirName ) ); // steamapps\username\sourcesdk
Q_StripLastDir( outputModGamedirName, sizeof( outputModGamedirName ) ); // steamapps\username
Q_StripLastDir( outputModGamedirName, sizeof( outputModGamedirName ) ); // steamapps
Q_AppendSlash( outputModGamedirName, sizeof( outputModGamedirName ) );
Q_strncat( outputModGamedirName, "SourceMods", sizeof( outputModGamedirName ), COPY_ALL_CHARACTERS ); // steamapps\sourcemods
Q_AppendSlash( outputModGamedirName, sizeof( outputModGamedirName ) );
Q_strncat( outputModGamedirName, strippedModName, sizeof( outputModGamedirName ), COPY_ALL_CHARACTERS ); // steamapps\sourcemods\modname
Q_AppendSlash( outputModGamedirName, sizeof( outputModGamedirName ) );
if ( !CreateFullDirectory( outputModGamedirName ) ||
!CreateSubdirectory( outputModGamedirName, "resource" ) ||
!CreateSubdirectory( outputModGamedirName, "resource\\ui" ) ||
!CreateSubdirectory( outputModGamedirName, "maps" ) ||
!CreateSubdirectory( outputModGamedirName, "cfg" ) ||
!CreateSubdirectory( outputModGamedirName, "scripts" )
)
{
VGUIMessageBox( this, "Error", "Unable to create directory '%s' or one if its subdirectories.", modPath );
return false;
}
}
// Setup all the data for the copy panel.
CModWizardSubPanel_CopyFiles *pCopyPanel = dynamic_cast<CModWizardSubPanel_CopyFiles *>(GetWizardPanel()->FindChildByName("CModWizardSubPanel_CopyFiles"));
if ( !pCopyPanel )
{
VGUIMessageBox( this, "Error", "Can't find copy panel!" );
return false;
}
pCopyPanel->GetReady( modPath, outputModGamedirName, modName );
return true;
}
void CModWizardSubPanel_GetModInfo::OnCommand( const char *command )
{
if ( Q_stricmp( command, "SearchButton" ) == 0 )
{
CModalPreserveDirectorySelectDialog *pDlg = vgui::SETUP_PANEL( new CModalPreserveDirectorySelectDialog( this, "#SelectInstallDirectory" ) );
pDlg->SetStartDirectory( "C:\\" );
char szPath[MAX_PATH];
m_pModPath->GetText( szPath, sizeof(szPath) );
pDlg->ExpandTreeToPath( szPath );
pDlg->SetDefaultCreateDirectoryName( "MyMod" );
pDlg->MoveToCenterOfScreen();
pDlg->DoModal();
pDlg->AddActionSignalTarget( this );
}
BaseClass::OnCommand( command );
}
void CModWizardSubPanel_GetModInfo::OnChooseDirectory( const char *dir )
{
m_pModPath->SetText( dir );
}

View File

@ -0,0 +1,53 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef MODWIZARD_GETMODINFO_H
#define MODWIZARD_GETMODINFO_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/WizardSubPanel.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/Label.h>
#include "configs.h"
// --------------------------------------------------------------------------------------------------------------------- //
// CreateModWizard sub panel 2.
// This panel asks for the directory to install in and the mod name.
// --------------------------------------------------------------------------------------------------------------------- //
namespace vgui
{
class CModWizardSubPanel_GetModInfo : public WizardSubPanel
{
public:
DECLARE_CLASS_SIMPLE( CModWizardSubPanel_GetModInfo, vgui::WizardSubPanel );
public:
CModWizardSubPanel_GetModInfo( Panel *parent, const char *panelName );
virtual WizardSubPanel* GetNextSubPanel();
virtual void OnDisplayAsNext();
virtual void PerformLayout();
virtual void OnCommand( const char *command );
virtual bool OnNextButton();
MESSAGE_FUNC_CHARPTR( OnChooseDirectory, "DirectorySelected", dir );
public:
TextEntry *m_pModPath;
TextEntry *m_pModName;
Label *m_pModNameInfoLabel;
ModType_t m_ModType;
};
}
#endif // MODWIZARD_GETMODINFO_H

View File

@ -0,0 +1,156 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "ModWizard_Intro.h"
#include <vgui_controls/WizardPanel.h>
#include <vgui/ILocalize.h>
#include "ModWizard_GetModInfo.h"
#include "filesystem_tools.h"
#include "SourceAppInfo.h"
#include "steam/steam_api.h"
using namespace vgui;
extern CSteamAPIContext *steamapicontext;
extern char g_engineDir[50];
//-----------------------------------------------------------------------------
// Purpose: Determines whether the specified game is subscribed to
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
bool IsGameSubscribed( int nSteamAppId )
{
bool bIsSubscribed = false;
if ( g_pFullFileSystem != NULL && g_pFullFileSystem->IsSteam() && steamapicontext->SteamApps() )
{
// See if specified app is installed
bIsSubscribed = steamapicontext->SteamApps()->BIsSubscribedApp( nSteamAppId );
}
return bIsSubscribed;
}
CModWizardSubPanel_Intro::CModWizardSubPanel_Intro( Panel *parent, const char *panelName )
: BaseClass( parent, panelName )
{
m_pModHL2Button = new RadioButton( this, "ModHL2Button", "" );
m_pModHL2MPButton = new RadioButton( this, "ModHL2MPButton", "" );
m_pModFromScratchButton = new RadioButton( this, "ModFromScratchButton", "" );
m_pSourceCodeOnlyButton = new RadioButton( this, "ModSourceCodeOnlyButton", "" );
LoadControlSettings( "ModWizardSubPanel_Intro.res");
// We presently don't support SDK scratch configuration using the "orangebox" codebase
if ( !V_strcmp( g_engineDir, "orangebox" ) )
{
m_pModFromScratchButton->SetVisible( false );
}
//
// Enable and select the appropriate mod types
//
if ( !V_strcmp( g_engineDir, "orangebox" ) || !V_strcmp( g_engineDir, "source2007" ) )
m_pModHL2Button->SetEnabled( IsGameSubscribed( GetAppSteamAppId( k_App_HL2_EP2 ) ) );
else
{
// do it without nesting.
if ( ( IsGameSubscribed( GetAppSteamAppId( k_App_HL2 ) ) || IsGameSubscribed( GetAppSteamAppId( k_App_HL2_EP1 ) ) ) )
m_pModHL2Button->SetEnabled( true );
else
m_pModHL2Button->SetEnabled( false );
}
m_pModHL2MPButton->SetEnabled( IsGameSubscribed( GetAppSteamAppId( k_App_HL2MP ) ) );
// De-select all
m_pModHL2Button->SetSelected( false );
m_pModHL2MPButton->SetSelected( false );
m_pModFromScratchButton->SetSelected( false );
// Select the most common possible option
if ( m_pModHL2Button->IsEnabled() )
{
m_pModHL2Button->SetSelected( true );
}
else if ( m_pModHL2MPButton->IsEnabled() )
{
m_pModHL2Button->SetSelected( true );
}
else if ( m_pModFromScratchButton->IsVisible() )
{
m_pModFromScratchButton->SetSelected( true );
}
}
WizardSubPanel *CModWizardSubPanel_Intro::GetNextSubPanel()
{
return dynamic_cast<WizardSubPanel *>(GetWizardPanel()->FindChildByName("CModWizardSubPanel_GetModInfo"));
}
void CModWizardSubPanel_Intro::PerformLayout()
{
BaseClass::PerformLayout();
// Update the scratch button text - in orange box, the text is different, but it's the same button.
if ( !V_strcmp( g_engineDir, "source2007" ) )
SetDialogVariable( "ScratchLabel", g_pVGuiLocalize->Find( "#StartFromTemplate" ) );
else
SetDialogVariable( "ScratchLabel", g_pVGuiLocalize->Find( "#StartFromScratch" ) );
GetWizardPanel()->SetFinishButtonEnabled(false);
}
void CModWizardSubPanel_Intro::OnDisplayAsNext()
{
GetWizardPanel()->SetTitle( "#ModWizard_Intro_Title", true );
}
ModType_t CModWizardSubPanel_Intro::GetModType()
{
if ( m_pModHL2Button && m_pModHL2Button->IsSelected() )
{
return ModType_HL2;
}
else if ( m_pModHL2MPButton && m_pModHL2MPButton->IsSelected() )
{
return ModType_HL2_Multiplayer;
}
else if ( m_pSourceCodeOnlyButton && m_pSourceCodeOnlyButton->IsSelected() )
{
return ModType_SourceCodeOnly;
}
else
{
return ModType_FromScratch;
}
}
bool CModWizardSubPanel_Intro::OnNextButton()
{
// If we're only installing the source code, then we don't care about the game directory.
bool bShowModName = true;
if ( GetModType() == ModType_SourceCodeOnly )
bShowModName = false;
CModWizardSubPanel_GetModInfo *pNextPanel = dynamic_cast<CModWizardSubPanel_GetModInfo*>(GetWizardPanel()->FindChildByName("CModWizardSubPanel_GetModInfo"));
if ( pNextPanel )
{
if ( pNextPanel->m_pModName )
pNextPanel->m_pModName->SetVisible( bShowModName );
if ( pNextPanel->m_pModNameInfoLabel )
pNextPanel->m_pModNameInfoLabel->SetVisible( bShowModName );
pNextPanel->m_ModType = GetModType();
}
return true;
}

View File

@ -0,0 +1,52 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef MODWIZARD_INTRO_H
#define MODWIZARD_INTRO_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/WizardSubPanel.h>
#include <vgui_controls/RadioButton.h>
#include "configs.h"
// --------------------------------------------------------------------------------------------------------------------- //
// CreateModWizard sub panel 1.
// This panel just tells them about the wizard and what it's going to do, and gives them a chance to cancel.
// --------------------------------------------------------------------------------------------------------------------- //
namespace vgui
{
class CModWizardSubPanel_Intro : public WizardSubPanel
{
public:
typedef WizardSubPanel BaseClass;
public:
CModWizardSubPanel_Intro( Panel *parent, const char *panelName );
virtual WizardSubPanel* GetNextSubPanel();
virtual void OnDisplayAsNext();
virtual void PerformLayout();
virtual bool OnNextButton();
ModType_t GetModType();
RadioButton *m_pModHL2Button;
RadioButton *m_pModHL2MPButton;
RadioButton *m_pModFromScratchButton;
RadioButton *m_pSourceCodeOnlyButton;
};
}
#endif // MODWIZARD_INTRO_H

View File

@ -0,0 +1,169 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include "ModWizard_TemplateOptions.h"
#include <vgui_controls/DirectorySelectDialog.h>
#include <vgui/IInput.h>
#include <vgui_controls/Button.h>
#include <vgui_controls/WizardPanel.h>
#include <vgui_controls/CheckButton.h>
#include "sdklauncher_main.h"
#include <ctype.h>
#include "CreateModWizard.h"
#include "ModWizard_GetModInfo.h"
#include "ModWizard_CopyFiles.h"
using namespace vgui;
// If the option is disabled, throw this on the front of it.
#define OPTION_DISABLED_PREFIX "//"
// The option strings for the replace
static const char *g_szOptions[] =
{
"#define SDK_USE_TEAMS", //TPOPTION_TEAMS,
"#define SDK_USE_PLAYERCLASSES", //TPOPTION_CLASSES,
"#define SDK_USE_STAMINA", //TPOPTION_STAMINA,
"#define SDK_USE_SPRINTING", //TPOPTION_SPRINTING,
"#define SDK_USE_PRONE", //TPOPTION_PRONE,
"#define SDK_SHOOT_WHILE_SPRINTING", //TPOPTION_SHOOTSPRINTING,
"#define SDK_SHOOT_ON_LADDERS", //TPOPTION_SHOOTLADDERS,
"#define SDK_SHOOT_WHILE_JUMPING", //TPOPTION_SHOOTJUMPING,
};
char *VarArgs( PRINTF_FORMAT_STRING const char *format, ... )
{
va_list argptr;
static char string[1024];
va_start (argptr, format);
Q_vsnprintf(string, sizeof(string), format,argptr);
va_end (argptr);
return string;
}
CModWizardSubPanel_TemplateOptions::CModWizardSubPanel_TemplateOptions( Panel *parent, const char *panelName )
: BaseClass( parent, panelName )
{
m_pOptionTeams = new CheckButton(this, "OptionTeamsButton", "" );
m_pOptionClasses = new CheckButton( this, "OptionClassesButton", "" );
m_pOptionStamina = new CheckButton( this, "OptionStaminaButton", "" );
m_pOptionSprinting = new CheckButton( this, "OptionSprintingButton", "" );
m_pOptionProne = new CheckButton(this, "OptionProneButton", "" );
m_pOptionShootSprinting = new CheckButton( this, "OptionShootSprintingButton", "" );
m_pOptionShootOnLadders = new CheckButton( this, "OptionShootLaddersButton", "" );
m_pOptionShootJumping = new CheckButton( this, "OptionShootJumpingButton", "" );
LoadControlSettings( "ModWizardSubPanel_TemplateOptions.res");
// Sets everything off
SetDefaultOptions();
}
void CModWizardSubPanel_TemplateOptions::SetDefaultOptions()
{
// default everything to off.
for ( int i = 0;i < TPOPTIONS_TOTAL; i++ )
m_bOptions[i] = false;
if ( m_pOptionTeams )
m_pOptionTeams->SetSelected( false );
if ( m_pOptionClasses )
m_pOptionClasses->SetSelected( false );
if ( m_pOptionStamina )
m_pOptionStamina->SetSelected( false );
if ( m_pOptionSprinting )
m_pOptionSprinting->SetSelected( false );
if ( m_pOptionProne )
m_pOptionProne->SetSelected( false );
if ( m_pOptionShootSprinting )
m_pOptionShootSprinting->SetSelected( false );
if ( m_pOptionShootOnLadders )
m_pOptionShootOnLadders->SetSelected( false );
if ( m_pOptionShootJumping )
m_pOptionShootJumping->SetSelected( false );
}
char *CModWizardSubPanel_TemplateOptions::GetOption( int optionType )
{
// Option is enabled, just pass the string back unaltered.
if ( true == m_bOptions[optionType] )
{
return (char*)g_szOptions[optionType];
}
else
{
// Option is disabled, tack the comment '//' infront of the string, must strdup this
return strdup(VarArgs( "//%s", g_szOptions[optionType] ));
}
}
// Update all the options based on the check boxes.
void CModWizardSubPanel_TemplateOptions::UpdateOptions()
{
if ( m_pOptionTeams && m_pOptionTeams->IsSelected() )
m_bOptions[TPOPTION_TEAMS] = true;
if ( m_pOptionClasses && m_pOptionClasses->IsSelected() )
m_bOptions[TPOPTION_CLASSES] = true;
if ( m_pOptionStamina && m_pOptionStamina->IsSelected() )
m_bOptions[TPOPTION_STAMINA] = true;
// if sprinting is enabled, so is stamina no matter what.
if ( m_pOptionSprinting && m_pOptionSprinting->IsSelected() )
{
m_bOptions[TPOPTION_SPRINTING] = true;
m_bOptions[TPOPTION_STAMINA] = true;
}
if ( m_pOptionProne && m_pOptionProne->IsSelected() )
m_bOptions[TPOPTION_PRONE] = true;
if ( m_pOptionShootSprinting && m_pOptionShootSprinting->IsSelected() )
m_bOptions[TPOPTION_SHOOTSPRINTING] = true;
if ( m_pOptionShootOnLadders && m_pOptionShootOnLadders->IsSelected() )
m_bOptions[TPOPTION_SHOOTLADDERS] = true;
if ( m_pOptionShootJumping && m_pOptionShootJumping->IsSelected() )
m_bOptions[TPOPTION_SHOOTJUMPING] = true;
}
WizardSubPanel *CModWizardSubPanel_TemplateOptions::GetNextSubPanel()
{
return dynamic_cast<WizardSubPanel *>(GetWizardPanel()->FindChildByName("CModWizardSubPanel_CopyFiles"));
}
void CModWizardSubPanel_TemplateOptions::PerformLayout()
{
BaseClass::PerformLayout();
GetWizardPanel()->SetFinishButtonEnabled(false);
}
void CModWizardSubPanel_TemplateOptions::OnDisplayAsNext()
{
GetWizardPanel()->SetTitle( "#ModWizard_TemplateOptions_Title", true );
}
bool CModWizardSubPanel_TemplateOptions::OnNextButton()
{
// Update all the options
UpdateOptions();
// nothing else needs to be done here
return true;
}
void CModWizardSubPanel_TemplateOptions::OnCommand( const char *command )
{
BaseClass::OnCommand( command );
}

View File

@ -0,0 +1,74 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef MODWIZARD_TEMPLATEOPTIONS_H
#define MODWIZARD_TEMPLATEOPTIONS_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/WizardSubPanel.h>
#include <vgui_controls/TextEntry.h>
#include <vgui_controls/Label.h>
#include "configs.h"
enum numOptions_e
{
TPOPTION_TEAMS,
TPOPTION_CLASSES,
TPOPTION_STAMINA,
TPOPTION_SPRINTING,
TPOPTION_PRONE,
TPOPTION_SHOOTSPRINTING,
TPOPTION_SHOOTLADDERS,
TPOPTION_SHOOTJUMPING,
TPOPTIONS_TOTAL,
};
// --------------------------------------------------------------------------------------------------------------------- //
// CreateModWizard sub panel 2b (only when scratch / template sdk is chosen!)
// This panel asks for options
// --------------------------------------------------------------------------------------------------------------------- //
namespace vgui
{
class CModWizardSubPanel_TemplateOptions : public WizardSubPanel
{
public:
DECLARE_CLASS_SIMPLE( CModWizardSubPanel_TemplateOptions, vgui::WizardSubPanel );
public:
CModWizardSubPanel_TemplateOptions( Panel *parent, const char *panelName );
virtual WizardSubPanel* GetNextSubPanel();
virtual void OnDisplayAsNext();
virtual void PerformLayout();
virtual void OnCommand( const char *command );
virtual bool OnNextButton();
virtual void SetDefaultOptions();
virtual void UpdateOptions(); // Must be called before GetOption is used!!!
virtual char *GetOption( int optionType );
public:
CheckButton *m_pOptionTeams;
CheckButton *m_pOptionClasses;
CheckButton *m_pOptionStamina;
CheckButton *m_pOptionSprinting;
CheckButton *m_pOptionProne;
CheckButton *m_pOptionShootSprinting;
CheckButton *m_pOptionShootOnLadders;
CheckButton *m_pOptionShootJumping;
bool m_bOptions[TPOPTIONS_TOTAL];
};
}
#endif // MODWIZARD_TEMPLATEOPTIONS_H

View File

@ -0,0 +1,82 @@
//-----------------------------------------------------------------------------
// SDKLAUNCHER.VPC
//
// Project Script
//-----------------------------------------------------------------------------
$Macro SRCDIR ".."
$Macro OUTBINDIR "$SRCDIR\..\game\bin"
$Include "$SRCDIR\vpc_scripts\source_exe_win_win32_base.vpc"
$Configuration
{
$Compiler
{
$AdditionalIncludeDirectories "$BASE,$SRCDIR\utils\common"
$PreprocessorDefinitions "$BASE;VERSION_SAFE_STEAM_API_INTERFACES"
}
$Linker
{
$AdditionalDependencies "$BASE odbc32.lib odbccp32.lib WS2_32.LIB"
}
}
$Project "SDKLauncher"
{
$Folder "Source Files"
{
$File "$SRCDIR\common\ConfigManager.cpp"
$File "$SRCDIR\common\SourceAppInfo.cpp"
$File "configs.cpp"
$File "CreateModWizard.cpp"
$File "CreateModWizard.h"
$File "$SRCDIR\public\filesystem_init.cpp"
$File "$SRCDIR\public\registry.cpp"
$File "Main.cpp"
$File "min_footprint_files.cpp"
$File "ModConfigsHelper.cpp"
$File "ModWizard_CopyFiles.cpp"
$File "ModWizard_Finished.cpp"
$File "ModWizard_GetModInfo.cpp"
$File "ModWizard_Intro.cpp"
$File "ModWizard_TemplateOptions.cpp"
$File "$SRCDIR\public\registry.cpp"
$File "sdklauncher_main.h"
$File "SDKLauncherDialog.cpp"
$File "$SRCDIR\public\vgui_controls\vgui_controls.cpp"
}
$Folder "Header Files"
{
$File "$SRCDIR\common\ConfigManager.h"
$File "configs.h"
$File "$SRCDIR\public\filesystem_init.h"
$File "$SRCDIR\public\tier1\interface.h"
$File "min_footprint_files.h"
$File "ModConfigsHelper.h"
$File "ModWizard_CopyFiles.h"
$File "ModWizard_GetModInfo.h"
$File "ModWizard_Intro.h"
$File "ModWizard_TemplateOptions.h"
$File "SDKLauncherDialog.h"
}
$Folder "Resource Files"
{
$File "icon2.ico"
$File "Script1.rc"
$File "steam.ico"
}
$Folder "Link Libraries"
{
$Lib appframework
$ImpLib steam_api
$Lib tier2
$Lib tier3
$Lib vgui_controls
$Lib mathlib
}
}

View File

@ -0,0 +1,838 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#include <windows.h>
#include "SDKLauncherDialog.h"
#include "configs.h"
#include <vgui_controls/ComboBox.h>
#include <vgui_controls/ListPanel.h>
#include <vgui_controls/ProgressBox.h>
#include <vgui_controls/MessageBox.h>
#include <vgui_controls/HTML.h>
#include <vgui_controls/CheckButton.h>
#include <vgui_controls/Divider.h>
#include <vgui_controls/menu.h>
#include <vgui/ISurface.h>
#include <vgui/ILocalize.h>
#include "vgui_controls/button.h"
#include <vgui/ISystem.h>
#include <vgui/IVGui.h>
#include <vgui/iinput.h>
#include <KeyValues.h>
#include <FileSystem.h>
#include <io.h>
#include "CreateModWizard.h"
#include "filesystem_tools.h"
#include "min_footprint_files.h"
#include "ConfigManager.h"
#include "filesystem_tools.h"
#include <iregistry.h>
#include <sys/stat.h>
#include "sdklauncher_main.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
using namespace vgui;
CSDKLauncherDialog *g_pSDKLauncherDialog = NULL;
CGameConfigManager g_ConfigManager;
char g_engineDir[50];
//-----------------------------------------------------------------------------
// Purpose: Retrieves a URL out of the external localization file and opens it in a
// web browser.
// Input : *lpszLocalName - Localized name of the URL to open via shell execution
//-----------------------------------------------------------------------------
void OpenLocalizedURL( const char *lpszLocalName )
{
// Find and convert the localized unicode string
char pURLStr[MAX_PATH];
wchar_t *pURLUni = g_pVGuiLocalize->Find( lpszLocalName );
g_pVGuiLocalize->ConvertUnicodeToANSI( pURLUni, pURLStr, sizeof( pURLStr ) );
// Open the URL through the shell
vgui::system()->ShellExecute( "open", pURLStr );
}
class CResetConfirmationMessageBox : public vgui::Frame
{
public:
typedef vgui::Frame BaseClass;
CResetConfirmationMessageBox( Panel *pParent, const char *pPanelName )
: BaseClass( pParent, pPanelName )
{
SetSize( 200, 200 );
SetMinimumSize( 250, 100 );
SetSizeable( false );
LoadControlSettings( "resetconfirmbox.res" );
}
void OnCommand( const char *command )
{
if ( Q_stricmp( command, "ResetConfigs" ) == 0 )
{
Close();
if ( GetVParent() )
{
PostMessage( GetVParent(), new KeyValues( "Command", "command", "ResetConfigs"));
}
}
else if ( Q_stricmp( command, "MoreInfo" ) == 0 )
{
OpenLocalizedURL( "URL_Reset_Config" );
}
BaseClass::OnCommand( command );
}
};
class CConversionInfoMessageBox : public vgui::Frame
{
public:
typedef vgui::Frame BaseClass;
CConversionInfoMessageBox( Panel *pParent, const char *pPanelName )
: BaseClass( pParent, pPanelName )
{
SetSize( 200, 200 );
SetMinimumSize( 250, 100 );
SetSizeable( false );
LoadControlSettings( "convinfobox.res" );
}
virtual void OnCommand( const char *command )
{
BaseClass::OnCommand( command );
// For some weird reason, this dialog can
if ( Q_stricmp( command, "ShowFAQ" ) == 0 )
{
OpenLocalizedURL( "URL_Convert_INI" );
}
}
};
class CGameInfoMessageBox : public vgui::Frame
{
public:
typedef vgui::Frame BaseClass;
CGameInfoMessageBox( Panel *pParent, const char *pPanelName )
: BaseClass( pParent, pPanelName )
{
SetSize( 200, 200 );
SetMinimumSize( 250, 100 );
LoadControlSettings( "hl2infobox.res" );
}
virtual void OnCommand( const char *command )
{
BaseClass::OnCommand( command );
// For some weird reason, this dialog can
if ( Q_stricmp( command, "RunAnyway" ) == 0 )
{
m_pDialog->Launch( m_iActiveItem, true );
MarkForDeletion();
}
else if ( Q_stricmp( command, "Troubleshooting" ) == 0 )
{
OpenLocalizedURL( "URL_SDK_FAQ" );
MarkForDeletion();
}
}
CSDKLauncherDialog *m_pDialog;
int m_iActiveItem;
};
class CMinFootprintRefreshConfirmationDialog : public vgui::Frame
{
public:
typedef vgui::Frame BaseClass;
CMinFootprintRefreshConfirmationDialog( Panel *pParent, const char *pPanelName )
: BaseClass( pParent, pPanelName )
{
SetSizeable( false );
LoadControlSettings( "min_footprint_confirm_box.res" );
m_hOldModalSurface = input()->GetAppModalSurface();
input()->SetAppModalSurface( GetVPanel() );
}
~CMinFootprintRefreshConfirmationDialog()
{
input()->SetAppModalSurface( m_hOldModalSurface );
}
void OnCommand( const char *command )
{
BaseClass::OnCommand( command );
if ( Q_stricmp( command, "Continue" ) == 0 )
{
PostMessage( g_pSDKLauncherDialog, new KeyValues( "Command", "command", "RefreshMinFootprint" ) );
MarkForDeletion();
}
else if ( Q_stricmp( command, "Close" ) == 0 )
{
MarkForDeletion();
}
}
VPANEL m_hOldModalSurface;
};
//-----------------------------------------------------------------------------
// Purpose: Constructor
//-----------------------------------------------------------------------------
CSDKLauncherDialog::CSDKLauncherDialog(vgui::Panel *parent, const char *name) : BaseClass(parent, name)
{
Assert( !g_pSDKLauncherDialog );
g_pSDKLauncherDialog = this;
SetSize(384, 480);
SetMinimumSize(250, 200);
SetMinimizeButtonVisible( true );
m_pImageList = new ImageList( true );
m_pMediaList = new SectionedListPanel(this, "MediaList");
m_pMediaList->AddActionSignalTarget( this );
m_pMediaList->SetImageList( m_pImageList, true );
m_pContextMenu = new Menu( m_pMediaList, "AppsContextMenu" );
m_pCurrentGameCombo = new ComboBox( this, "CurrentGameList", 8, false );
m_pCurrentGameCombo->AddActionSignalTarget( this );
m_pCurrentEngineCombo = new ComboBox( this, "CurrentEngineList", 4, false );
m_pCurrentEngineCombo->AddActionSignalTarget( this );
PopulateMediaList();
LoadControlSettings( "SDKLauncherDialog.res" );
GetEngineVersion( g_engineDir, sizeof( g_engineDir ) );
PopulateCurrentEngineCombo( false );
RefreshConfigs();
}
CSDKLauncherDialog::~CSDKLauncherDialog()
{
delete m_pMediaList;
g_pSDKLauncherDialog = NULL;
}
//-----------------------------------------------------------------------------
// Purpose: kills the whole app on close
//-----------------------------------------------------------------------------
void CSDKLauncherDialog::OnClose()
{
BaseClass::OnClose();
ivgui()->Stop();
}
//-----------------------------------------------------------------------------
// Purpose: loads media list from file
//-----------------------------------------------------------------------------
void CSDKLauncherDialog::PopulateMediaList()
{
KeyValues *dataFile = new KeyValues("Media");
dataFile->UsesEscapeSequences( true );
if (dataFile->LoadFromFile( g_pFullFileSystem, "MediaList.txt", NULL ) )
{
// Load all the images.
KeyValues *pImages = dataFile->FindKey( "Images" );
if ( !pImages )
Error( "MediaList.txt missing Images key." );
for ( KeyValues *pCur=pImages->GetFirstTrueSubKey(); pCur; pCur=pCur->GetNextTrueSubKey() )
{
IImage *pImage = scheme()->GetImage( pCur->GetString( "Image", "" ), false );
int iIndex = pCur->GetInt( "Index", -1 );
if ( pImage && iIndex != -1 )
{
m_pImageList->SetImageAtIndex( iIndex, pImage );
}
}
// Load all the sections.
KeyValues *pSections = dataFile->FindKey( "Sections" );
if ( !pSections )
Error( "MediaList.txt missing Sections key." );
for ( KeyValues *pSection=pSections->GetFirstTrueSubKey(); pSection; pSection=pSection->GetNextTrueSubKey() )
{
int id = pSection->GetInt( "id" );
const char *pName = pSection->GetString( "Name" );
m_pMediaList->AddSection( id, pName );
m_pMediaList->AddColumnToSection( id, "Image", "", SectionedListPanel::COLUMN_IMAGE, 20 );
m_pMediaList->AddColumnToSection( id, "Text", pName, 0, 200 );
// Set all the rows.
for ( KeyValues *kv = pSection->GetFirstTrueSubKey(); kv != NULL; kv=kv->GetNextTrueSubKey() )
{
m_pMediaList->AddItem( id, kv );
}
}
}
dataFile->deleteThis();
}
void CSDKLauncherDialog::Launch( int hActiveListItem, bool bForce )
{
if (!m_pMediaList->IsItemIDValid(hActiveListItem))
return;
// display the file
KeyValues *item = m_pMediaList->GetItemData( hActiveListItem );
if ( !item )
return;
// Is this a ShellExecute or a program they want to run?
const char *pStr = item->GetString( "InlineProgram", NULL );
if ( pStr )
{
if ( Q_stricmp( pStr, "CreateMod" ) == 0 )
{
if ( !V_stricmp( g_engineDir, "ep1" ) || !V_stricmp( g_engineDir, "source2007" ) )
{
RunCreateModWizard( false );
}
else
{
VGUIMessageBox( this, "Unable to Run 'Create A Mod' Wizard", "Support for creating total conversions are not available using this engine versions." );
}
}
else if ( Q_stricmp( pStr, "refresh_min_footprint" ) == 0 )
{
CMinFootprintRefreshConfirmationDialog *pDlg = new CMinFootprintRefreshConfirmationDialog( this, "RefreshConfirmation" );
pDlg->RequestFocus();
pDlg->SetVisible( true );
pDlg->MoveToCenterOfScreen();
}
else if ( Q_stricmp( pStr, "reset_configs" ) == 0 )
{
CResetConfirmationMessageBox *pDlg = new CResetConfirmationMessageBox( this, "ResetConfirmation" );
pDlg->RequestFocus();
pDlg->SetVisible( true );
pDlg->MoveToCenterOfScreen();
input()->SetAppModalSurface( pDlg->GetVPanel() );
}
else
{
Error( "Unknown InlineProgram value: %s", pStr );
}
return;
}
pStr = item->GetString( "ShellExecute", NULL );
if ( pStr )
{
// Replace tokens we know about like %basedir%.
system()->ShellExecute( "open", pStr );
return;
}
pStr = item->GetString( "Program", NULL );
if ( pStr )
{
// Get our current config.
KeyValues *kv = m_pCurrentGameCombo->GetActiveItemUserData();
if ( !kv )
{
VGUIMessageBox( this, "Error", "No game configurations to run with." );
return;
}
const char *pModDir = kv->GetString( "ModDir", NULL );
if ( !pModDir )
{
VGUIMessageBox( this, "Error", "Missing 'ModDir' key/value." );
return;
}
bool bRun = true;
if ( !bForce && Q_stristr( pStr, "%gamedir%" ) )
{
// Make sure the currently-selected gamedir is valid and has a gameinfo.txt in it.
char testStr[MAX_PATH];
Q_strncpy( testStr, pModDir, sizeof( testStr ) );
Q_AppendSlash( testStr, sizeof( testStr ) );
Q_strncat( testStr, "gameinfo.txt", sizeof( testStr ), COPY_ALL_CHARACTERS );
if ( _access( testStr, 0 ) != 0 )
{
CGameInfoMessageBox *dlg = new CGameInfoMessageBox( this, "GameInfoMessageBox" );
dlg->m_pDialog = this;
dlg->m_iActiveItem = hActiveListItem;
dlg->RequestFocus();
dlg->SetVisible( true );
dlg->MoveToCenterOfScreen();
input()->SetAppModalSurface( dlg->GetVPanel() );
bRun = false;
}
}
if ( bRun )
{
// Get the program name and its arguments.
char programNameTemp[1024], programName[1024], launchDirectory[1024];
SubstituteBaseDir( pStr, programNameTemp, sizeof( programNameTemp ) );
V_StrSubst( programNameTemp, "%gamedir%", pModDir, programName, sizeof( programName ) );
V_strncpy( programNameTemp, programName, sizeof( programNameTemp ) );
V_StrSubst( programNameTemp, "%enginedir%", g_engineDir , programName, sizeof( programName ) );
V_strncpy( launchDirectory, GetSDKLauncherBaseDirectory(), sizeof( launchDirectory ) );
V_strncat( launchDirectory, "\\bin\\", sizeof( launchDirectory ) );
V_strncat( launchDirectory, g_engineDir, sizeof( launchDirectory ) );
// Check to see if we're running in tools mode
if ( NULL != V_strstr( programName, "-tools" ) )
{
// We can't run tools mode in engine versions earlier than OB
if ( !V_strcmp( g_engineDir, "ep1" ) )
{
VGUIMessageBox( this, "Error", "Source Engine Tools is not compatible with the selected engine version." );
return;
}
// If we are running the engine tools then change our launch directory to the game directory
V_strncpy( launchDirectory, pModDir, sizeof( launchDirectory ) );
V_StripLastDir( launchDirectory, sizeof( launchDirectory ) );
V_strncat( launchDirectory, "bin", sizeof( launchDirectory ) );
}
STARTUPINFO si;
memset( &si, 0, sizeof( si ) );
si.cb = sizeof( si );
PROCESS_INFORMATION pi;
memset( &pi, 0, sizeof( pi ) );
DWORD dwFlags = 0;
if ( !CreateProcess(
0,
programName,
NULL, // security
NULL,
TRUE,
dwFlags, // flags
NULL, // environment
launchDirectory, // current directory
&si,
&pi ) )
{
::MessageBoxA( NULL, GetLastWindowsErrorString(), "Error", MB_OK | MB_ICONINFORMATION | MB_APPLMODAL );
}
}
}
}
void CSDKLauncherDialog::OnCommand( const char *command )
{
if ( Q_stricmp( command, "LaunchButton" ) == 0 )
{
Launch( m_pMediaList->GetSelectedItem(), false );
}
else if ( Q_stricmp( command, "ResetConfigs" ) == 0 )
{
ResetConfigs();
}
else if ( Q_stricmp( command, "RefreshMinFootprint" ) == 0 )
{
DumpMinFootprintFiles( true );
}
BaseClass::OnCommand( command );
}
void CSDKLauncherDialog::OnItemDoubleLeftClick( int iItem )
{
Launch( iItem, false );
}
void CSDKLauncherDialog::OnItemContextMenu( int hActiveListItem )
{
if (!m_pMediaList->IsItemIDValid(hActiveListItem))
return;
// display the file
KeyValues *item = m_pMediaList->GetItemData( hActiveListItem );
if ( !item )
return;
// Build the context menu.
m_pContextMenu->DeleteAllItems();
// Is this a ShellExecute or a program they want to run?
const char *pStr = item->GetString( "ShellExecute", NULL );
if ( pStr )
m_pContextMenu->AddMenuItem( "RunGame", "Open In Web Browser", new KeyValues("ItemDoubleLeftClick", "itemID", hActiveListItem), this);
else
m_pContextMenu->AddMenuItem( "RunGame", "Launch", new KeyValues("ItemDoubleLeftClick", "itemID", hActiveListItem), this);
int menuWide, menuTall;
m_pContextMenu->SetVisible(true);
m_pContextMenu->InvalidateLayout(true);
m_pContextMenu->GetSize(menuWide, menuTall);
// work out where the cursor is and therefore the best place to put the menu
int wide, tall;
surface()->GetScreenSize(wide, tall);
int cx, cy;
input()->GetCursorPos(cx, cy);
if (wide - menuWide > cx)
{
// menu hanging right
if (tall - menuTall > cy)
{
// menu hanging down
m_pContextMenu->SetPos(cx, cy);
}
else
{
// menu hanging up
m_pContextMenu->SetPos(cx, cy - menuTall);
}
}
else
{
// menu hanging left
if (tall - menuTall > cy)
{
// menu hanging down
m_pContextMenu->SetPos(cx - menuWide, cy);
}
else
{
// menu hanging up
m_pContextMenu->SetPos(cx - menuWide, cy - menuTall);
}
}
m_pContextMenu->RequestFocus();
m_pContextMenu->MoveToFront();
}
bool CSDKLauncherDialog::ParseConfigs( CUtlVector<CGameConfig*> &configs )
{
if ( !g_ConfigManager.IsLoaded() )
return false;
// Find the games block of the keyvalues
KeyValues *gameBlock = g_ConfigManager.GetGameBlock();
if ( gameBlock == NULL )
{
return false;
}
// Iterate through all subkeys
for ( KeyValues *pGame=gameBlock->GetFirstTrueSubKey(); pGame; pGame=pGame->GetNextTrueSubKey() )
{
const char *pName = pGame->GetName();
const char *pDir = pGame->GetString( TOKEN_GAME_DIRECTORY );
CGameConfig *newConfig = new CGameConfig();
UtlStrcpy( newConfig->m_Name, pName );
UtlStrcpy( newConfig->m_ModDir, pDir );
configs.AddToTail( newConfig );
}
return true;
}
void CSDKLauncherDialog::PopulateCurrentEngineCombo( bool bSelectLast )
{
int nActiveEngine = 0;
m_pCurrentEngineCombo->DeleteAllItems();
// Add ep1 engine
KeyValues *kv = new KeyValues( "values" );
kv = new KeyValues( "values" );
kv->SetString( "EngineVer", "ep1" );
m_pCurrentEngineCombo->AddItem( "Source Engine 2006", kv );
kv->deleteThis();
if ( !V_strcmp( g_engineDir, "ep1" ) )
{
nActiveEngine = 0;
}
// Add ep2 engine
kv = new KeyValues( "values" );
kv->SetString( "EngineVer", "source2007" );
m_pCurrentEngineCombo->AddItem( "Source Engine 2007", kv );
kv->deleteThis();
if ( !V_strcmp( g_engineDir, "source2007" ) )
{
nActiveEngine = 1;
}
// Add SP engine
kv = new KeyValues( "values" );
kv->SetString( "EngineVer", "source2009" );
m_pCurrentEngineCombo->AddItem( "Source Engine 2009", kv );
kv->deleteThis();
if ( !V_strcmp( g_engineDir, "source2009" ) )
{
nActiveEngine = 2;
}
// Add MP engine
kv = new KeyValues( "values" );
kv->SetString( "EngineVer", "orangebox" );
m_pCurrentEngineCombo->AddItem( "Source Engine MP", kv );
kv->deleteThis();
if ( !V_strcmp( g_engineDir, "orangebox" ) )
{
nActiveEngine = 3;
}
// Determine active configuration
m_pCurrentEngineCombo->ActivateItem( nActiveEngine );
}
void CSDKLauncherDialog::SetCurrentGame( const char* pcCurrentGame )
{
int activeConfig = -1;
for ( int i=0; i < m_pCurrentGameCombo->GetItemCount(); i++ )
{
KeyValues *kv = m_pCurrentGameCombo->GetItemUserData( i );
// Check to see if this is our currently active game
if ( Q_stricmp( kv->GetString( "ModDir" ), pcCurrentGame ) == 0 )
{
activeConfig = i;
continue;
}
}
if ( activeConfig > -1 )
{
// Activate our currently selected game
m_pCurrentGameCombo->ActivateItem( activeConfig );
}
else
{
// If the VCONFIG value for the game is not found then repopulate
PopulateCurrentGameCombo( false );
}
}
void CSDKLauncherDialog::PopulateCurrentGameCombo( bool bSelectLast )
{
m_pCurrentGameCombo->DeleteAllItems();
CUtlVector<CGameConfig*> configs;
ParseConfigs( configs );
char szGame[MAX_PATH];
GetVConfigRegistrySetting( GAMEDIR_TOKEN, szGame, sizeof( szGame ) );
int activeConfig = -1;
CUtlVector<int> itemIDs;
itemIDs.SetSize( configs.Count() );
for ( int i=0; i < configs.Count(); i++ )
{
KeyValues *kv = new KeyValues( "values" );
kv->SetString( "ModDir", configs[i]->m_ModDir.Base() );
kv->SetPtr( "panel", m_pCurrentGameCombo );
// Check to see if this is our currently active game
if ( Q_stricmp( configs[i]->m_ModDir.Base(), szGame ) == 0 )
{
activeConfig = i;
}
itemIDs[i] = m_pCurrentGameCombo->AddItem( configs[i]->m_Name.Base(), kv );
kv->deleteThis();
}
// Activate the correct entry if valid
if ( itemIDs.Count() > 0 )
{
m_pCurrentGameCombo->SetEnabled( true );
if ( bSelectLast )
{
m_pCurrentGameCombo->ActivateItem( itemIDs[itemIDs.Count()-1] );
}
else
{
if ( activeConfig > -1 )
{
// Activate our currently selected game
m_pCurrentGameCombo->ActivateItem( activeConfig );
}
else
{
// Always default to the first otherwise
m_pCurrentGameCombo->ActivateItem( 0 );
}
}
}
else
{
m_pCurrentGameCombo->SetEnabled( false );
}
configs.PurgeAndDeleteElements();
}
//-----------------------------------------------------------------------------
// Purpose: Selection has changed in the active config drop-down, set the environment
//-----------------------------------------------------------------------------
void CSDKLauncherDialog::OnTextChanged( KeyValues *pkv )
{
const vgui::ComboBox* combo = (vgui::ComboBox*)pkv->GetPtr("panel");
if ( combo == m_pCurrentGameCombo)
{
KeyValues *kv = m_pCurrentGameCombo->GetActiveItemUserData();
if ( kv )
{
const char *modDir = kv->GetString( "ModDir" );
SetVConfigRegistrySetting( GAMEDIR_TOKEN, modDir, true );
}
}
else if ( combo == m_pCurrentEngineCombo )
{
KeyValues *kv = m_pCurrentEngineCombo->GetActiveItemUserData();
if ( kv )
{
const char *engineDir = kv->GetString( "EngineVer" );
SetEngineVersion( engineDir );
RefreshConfigs();
}
}
}
//-----------------------------------------------------------------------------
// Purpose: Refresh our configs after a file change outside our process
//-----------------------------------------------------------------------------
void CSDKLauncherDialog::RefreshConfigs( void )
{
char szGameConfigDir[MAX_PATH];
V_strcpy_safe( szGameConfigDir, GetSDKLauncherBinDirectory() );
V_AppendSlash( szGameConfigDir, MAX_PATH );
V_strncat( szGameConfigDir, g_engineDir, MAX_PATH );
V_AppendSlash( szGameConfigDir, MAX_PATH );
V_strncat( szGameConfigDir, "bin", MAX_PATH );
// Set directory in which GameConfig.txt is found
g_ConfigManager.SetBaseDirectory( szGameConfigDir );
// Tell the config manager which games to put in the config by default
if ( !stricmp( g_engineDir, "ep1" ) )
{
g_ConfigManager.SetSDKEpoch( EP1 );
}
else if ( !stricmp( g_engineDir, "source2007" ) )
{
g_ConfigManager.SetSDKEpoch( EP2 );
}
else if ( !stricmp( g_engineDir, "source2009" ) )
{
g_ConfigManager.SetSDKEpoch( SP2009 );
}
else
{
g_ConfigManager.SetSDKEpoch( MP2009 );
}
// Load configurations
if ( g_ConfigManager.LoadConfigs( szGameConfigDir ) == false )
{
m_pCurrentGameCombo->DeleteAllItems();
m_pCurrentGameCombo->SetEnabled( false );
}
else
{
m_pCurrentGameCombo->SetEnabled( true );
if ( g_ConfigManager.WasConvertedOnLoad() )
{
// Notify of a conversion
CConversionInfoMessageBox *pDlg = new CConversionInfoMessageBox( this, "ConversionInfo" );
pDlg->RequestFocus();
pDlg->SetVisible( true );
pDlg->MoveToCenterOfScreen();
input()->SetAppModalSurface( pDlg->GetVPanel() );
}
}
// Dump the current settings and reparse the change
PopulateCurrentGameCombo( false );
}
//-----------------------------------------------------------------------------
// Purpose: Reset our config files
//-----------------------------------------------------------------------------
void CSDKLauncherDialog::ResetConfigs( void )
{
// Reset the configs
g_ConfigManager.ResetConfigs();
// Refresh the listing
PopulateCurrentGameCombo( false );
// Notify the user
VGUIMessageBox( this, "Complete", "Your game configurations have successfully been reset to their default values." );
}
void CSDKLauncherDialog::GetEngineVersion(char* pcEngineVer, int nSize)
{
IRegistry *reg = InstanceRegistry( "Source SDK" );
Assert( reg );
V_strncpy( pcEngineVer, reg->ReadString( "EngineVer", "orangebox" ), nSize );
ReleaseInstancedRegistry( reg );
}
void CSDKLauncherDialog::SetEngineVersion(const char *pcEngineVer)
{
IRegistry *reg = InstanceRegistry( "Source SDK" );
Assert( reg );
reg->WriteString( "EngineVer", pcEngineVer );
ReleaseInstancedRegistry( reg );
// Set the global to the same value as the registry
V_strncpy( g_engineDir, pcEngineVer, sizeof( g_engineDir ) );
}

View File

@ -0,0 +1,71 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef MEDIABROWSERDIALOG_H
#define MEDIABROWSERDIALOG_H
#ifdef _WIN32
#pragma once
#endif
#include <vgui_controls/Frame.h>
#include <vgui_controls/ImageList.h>
#include <vgui_controls/SectionedListPanel.h>
#include <vgui_controls/PHandle.h>
#include <FileSystem.h>
#include "vgui/mousecode.h"
#include "vgui/IScheme.h"
#include "configs.h"
//-----------------------------------------------------------------------------
// Purpose: Main dialog for media browser
//-----------------------------------------------------------------------------
class CSDKLauncherDialog : public vgui::Frame
{
typedef vgui::Frame BaseClass;
public:
DECLARE_CLASS_SIMPLE( CSDKLauncherDialog, vgui::Frame );
CSDKLauncherDialog(vgui::Panel *parent, const char *name);
virtual ~CSDKLauncherDialog();
void PopulateCurrentGameCombo( bool bSelectLast );
void PopulateCurrentEngineCombo( bool bSelectLast );
void Launch( int hActiveListItem, bool bForce );
void RefreshConfigs( void );
void SetCurrentGame( const char* pcCurrentGame );
protected:
virtual void OnClose();
virtual void OnCommand( const char *command );
private:
void ResetConfigs( void );
bool ParseConfigs( CUtlVector<CGameConfig*> &configs );
void PopulateMediaList();
void GetEngineVersion(char* pcEngineVer, int nSize);
void SetEngineVersion(const char *pcEngineVer);
MESSAGE_FUNC_INT( OnItemDoubleLeftClick, "ItemDoubleLeftClick", itemID );
MESSAGE_FUNC_INT( OnItemContextMenu, "ItemContextMenu", itemID );
MESSAGE_FUNC_PARAMS( OnTextChanged, "TextChanged", pkv );
private:
vgui::ImageList *m_pImageList;
vgui::SectionedListPanel *m_pMediaList;
vgui::Menu *m_pContextMenu;
vgui::ComboBox *m_pCurrentGameCombo;
vgui::ComboBox *m_pCurrentEngineCombo;
};
extern CSDKLauncherDialog *g_pSDKLauncherDialog;
#endif // MEDIABROWSERDIALOG_H

110
sdklauncher/configs.cpp Normal file
View File

@ -0,0 +1,110 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose: Handle addition and editing of game configurations
//
//=====================================================================================//
#include <windows.h>
#include "interface.h"
#include "tier0/icommandline.h"
#include "filesystem_tools.h"
#include "sdklauncher_main.h"
#include "ConfigManager.h"
#include "KeyValues.h"
#include <io.h>
#include <stdio.h>
#include "configs.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
extern CGameConfigManager g_ConfigManager;
//-----------------------------------------------------------------------------
// Purpose: Copy a character string into a utlvector of characters
//-----------------------------------------------------------------------------
void UtlStrcpy( CUtlVector<char> &dest, const char *pSrc )
{
dest.EnsureCount( strlen( pSrc ) + 1 );
Q_strncpy( dest.Base(), pSrc, dest.Count() );
}
//-----------------------------------------------------------------------------
// Purpose: Return the path for the gamecfg.INI file
//-----------------------------------------------------------------------------
const char *GetIniFilePath( void )
{
static char iniFilePath[MAX_PATH] = {0};
if ( iniFilePath[0] == 0 )
{
Q_strncpy( iniFilePath, GetSDKLauncherBinDirectory(), sizeof( iniFilePath ) );
Q_strncat( iniFilePath, "\\gamecfg.ini", sizeof( iniFilePath ), COPY_ALL_CHARACTERS );
}
return iniFilePath;
}
//-----------------------------------------------------------------------------
// Purpose: Add a new configuration with proper paths
// Output : Returns true on success, false on failure.
//-----------------------------------------------------------------------------
// NOTE: This code is fairly fragile, it'd be a lot better to have a solid solution for adding in a new config
bool AddConfig( const char *pModName, const char *pModDirectory, ModType_t modType )
{
// Manager must be loaded
if ( g_ConfigManager.IsLoaded() == false )
return false;
// Set to defaults
defaultConfigInfo_t newInfo;
memset( &newInfo, 0, sizeof( newInfo ) );
// Mod name
Q_strncpy( newInfo.gameName, pModName, sizeof( newInfo.gameName ) );
// Basic FGD
if ( modType == ModType_HL2 )
{
Q_strncpy( newInfo.FGD, "halflife2.fgd", sizeof( newInfo.FGD ) );
}
else if ( modType == ModType_HL2_Multiplayer )
{
Q_strncpy( newInfo.FGD, "hl2mp.fgd", sizeof( newInfo.FGD ) );
}
else
{
Q_strncpy( newInfo.FGD, "base.fgd", sizeof( newInfo.FGD ) );
}
// Get the base directory
Q_FileBase( pModDirectory, newInfo.gameDir, sizeof( newInfo.gameDir ) );
KeyValues *gameBlock = g_ConfigManager.GetGameBlock();
// Default executable
Q_strncpy( newInfo.exeName, "hl2.exe", sizeof( newInfo.exeName ) );
char szPath[MAX_PATH];
Q_strncpy( szPath, pModDirectory, sizeof( szPath ) );
Q_StripLastDir( szPath, sizeof( szPath ) );
Q_StripTrailingSlash( szPath );
char fullDir[MAX_PATH];
g_ConfigManager.GetRootGameDirectory( fullDir, sizeof( fullDir ), g_ConfigManager.GetRootDirectory() );
// Add the config into our file
g_ConfigManager.AddDefaultConfig( newInfo, gameBlock, szPath, fullDir );
// Set this as the currently active configuration
SetVConfigRegistrySetting( GAMEDIR_TOKEN, pModDirectory );
// Save and reload our configs
g_ConfigManager.SaveConfigs();
g_ConfigManager.LoadConfigs();
return true;
}

45
sdklauncher/configs.h Normal file
View File

@ -0,0 +1,45 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef CONFIGS_H
#define CONFIGS_H
#ifdef _WIN32
#pragma once
#endif
#include "utlvector.h"
enum ModType_t
{
ModType_HL2,
ModType_HL2_Multiplayer,
ModType_FromScratch,
ModType_SourceCodeOnly
};
class CGameConfig
{
public:
CUtlVector<char> m_Name;
CUtlVector<char> m_ModDir;
};
const char* GetIniFilePath();
void UtlStrcpy( CUtlVector<char> &dest, const char *pSrc );
void LoadGameConfigs( CUtlVector<CGameConfig*> &configs );
bool AddConfigToGameIni( const char *pModName, const char *pModDirectory, const char *pSourceIniFilename="new_mod_config.ini" );
void AddDefaultHalfLife2Config( bool bForce );
void AddDefaultHL2MPConfig( bool bForce );
void AddDefaultHammerIniFile();
bool AddConfig( const char *pModName, const char *pModDirectory, ModType_t modType );
#endif // CONFIGS_H

BIN
sdklauncher/icon2.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,467 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#include <windows.h>
#include <io.h>
#include <sys/stat.h>
#include <vgui/isystem.h>
#include "min_footprint_files.h"
#include "filesystem_tools.h"
#include "KeyValues.h"
#include "sdklauncher_main.h"
#include "ModConfigsHelper.h"
#include "vgui_controls/Frame.h"
#include <vgui_controls/Label.h>
#include <vgui_controls/MessageBox.h>
#include <vgui_controls/ProgressBar.h>
#include <vgui/iinput.h>
#include <vgui/ivgui.h>
#include "SourceAppInfo.h"
extern void OpenLocalizedURL( const char *lpszLocalName );
extern FSReturnCode_t LoadGameInfoFile( const char *pDirectoryName,
KeyValues *&pMainFile,
KeyValues *&pFileSystemInfo,
KeyValues *&pSearchPaths );
using namespace vgui;
#define SHOW_MIGRATION_MARKER "show_migration_marker.txt"
#define SHOW_DEPRECATED_APP_ID_MARKER "show_deprecatedappid_marker.txt"
#define MIN_FOOTPRINT_VERSION_FILENAME "min_footprint_version.txt"
#define MIN_FOOTPRINT_FILES_FILENAME "min_footprint_file_list.txt"
#define WRITABLE_PREFIX "[make_writable]"
#define ALWAYS_COPY_PREFIX "[always_copy]"
class CTempDirName
{
public:
char m_SrcDirName[MAX_PATH];
char m_DestDirName[MAX_PATH];
};
#define MF_MAKE_WRITABLE 0x0001
#define MF_ALWAYS_COPY 0x0002
class CMinFootprintFilename
{
public:
char m_SrcFilename[MAX_PATH];
char m_DestFilename[MAX_PATH];
int m_Flags; // Combination of MF_ flags.
};
void SafeCopy( const char *pSrcFilename, const char *pDestFilename )
{
FileHandle_t fpSrc = g_pFullFileSystem->Open( pSrcFilename, "rb" );
if ( fpSrc )
{
FILE *fpDest = fopen( pDestFilename, "wb" );
if ( fpDest )
{
while ( 1 )
{
char tempData[4096];
int nBytesRead = g_pFullFileSystem->Read( tempData, sizeof( tempData ), fpSrc );
if ( nBytesRead )
fwrite( tempData, 1, nBytesRead, fpDest );
if ( nBytesRead < sizeof( tempData ) )
break;
}
fclose( fpDest );
}
else
{
Warning( "SafeCopy: can't open %s for writing.", pDestFilename );
}
g_pFullFileSystem->Close( fpSrc );
}
else
{
Warning( "SafeCopy: can't open %s for reading.", pSrcFilename );
}
}
class CMinFootprintFilesPanel : public Frame
{
public:
typedef Frame BaseClass;
CMinFootprintFilesPanel( Panel *parent, const char *panelName )
: BaseClass( parent, panelName )
{
m_pProgressBar = new ProgressBar( this, "CopyProgressBar" );
m_pProgressBar->SetProgress( 0 );
LoadControlSettings( "MinFootprintFilesPanel.res");
SetSizeable( false );
SetMenuButtonVisible( false );
SetMenuButtonResponsive( false );
SetCloseButtonVisible( false );
// Take the focus.
m_PrevAppFocusPanel = input()->GetAppModalSurface();
input()->SetAppModalSurface( GetVPanel() );
}
~CMinFootprintFilesPanel()
{
input()->SetAppModalSurface( m_PrevAppFocusPanel );
}
void StartDumpingFiles()
{
m_pProgressBar->SetProgress( 0 );
m_iCurCopyFile = 0;
ivgui()->AddTickSignal( GetVPanel() );
MoveToCenterOfScreen();
Activate();
}
void OnTick()
{
int nCopied = 0;
while ( nCopied < 10 )
{
if ( m_iCurCopyFile >= m_Filenames.Count() )
{
// Done! Write the output version and disappear.
OnFinished();
return;
}
CMinFootprintFilename *pFilename = &m_Filenames[m_iCurCopyFile++];
// If the dest file doesn't exist or it's read-only, copy our file over it.
if ( (pFilename->m_Flags & MF_ALWAYS_COPY) || (_access( pFilename->m_DestFilename, 2 ) != 0) )
{
// Get rid of the old version of the file.
_chmod( pFilename->m_DestFilename, _S_IWRITE | _S_IREAD ); // Read-only.
_unlink( pFilename->m_DestFilename );
// Copy the new version in.
SafeCopy( pFilename->m_SrcFilename, pFilename->m_DestFilename );
// Set its access permissions.
if ( pFilename->m_Flags & MF_MAKE_WRITABLE )
_chmod( pFilename->m_DestFilename, _S_IREAD | _S_IWRITE );
else
_chmod( pFilename->m_DestFilename, _S_IREAD ); // Read-only.
}
++nCopied;
}
m_pProgressBar->SetProgress( (float)m_iCurCopyFile / m_Filenames.Count() );
}
void OnFinished()
{
m_pProgressBar->SetProgress( 1 );
//
// Write out that we are at the latest version.
//
KeyValues *pVersionKV = new KeyValues( MIN_FOOTPRINT_VERSION_FILENAME );
pVersionKV->SetInt( "Version", m_iOutputVersionNumber );
pVersionKV->SaveToFile( g_pFullFileSystem, MIN_FOOTPRINT_VERSION_FILENAME );
pVersionKV->deleteThis();
// Don't tick any more.
ivgui()->RemoveTickSignal( GetVPanel() );
// Remove our panel.
PostMessage(this, new KeyValues("Close"));
ShowDeprecatedAppIDNotice();
ShowContentMigrationNotice();
}
void ShowDeprecatedAppIDNotice()
{
// Try to open the file that indicates that we've already been through this check
FileHandle_t fp = g_pFullFileSystem->Open( SHOW_DEPRECATED_APP_ID_MARKER, "rb" );
// If the file exists then we've run the check already, don't do anything.
if ( fp )
{
g_pFullFileSystem->Close( fp );
}
// We have not checked for outdated mods yet...
else
{
// Write file that ensures we never perform this check again
fp = g_pFullFileSystem->Open( SHOW_DEPRECATED_APP_ID_MARKER, "wb" );
g_pFullFileSystem->Close( fp );
//
// Look for all of the mods under 'SourceMods', check if the SteamAppId is out of date, and warn the user if
// this is the case
//
ModConfigsHelper mch;
const CUtlVector<char *> &modDirs = mch.getModDirsVector();
vgui::MessageBox *alert = NULL;
char szProblemMods[5*MAX_PATH];
bool bProblemModExists = false;
// Set up the error string
Q_strncpy(szProblemMods, "The SteamAppId values for the following mods should be changed from 220 to 215:\r\n\r\n", 5*MAX_PATH);
// Iterate through the mods and check which ones have outdated SteamAppIds
for ( int i = 0; i < modDirs.Count(); i++ )
{
// Construct full path to mod directory
char szDirPath[MAX_PATH];
char szGameConfigPath[MAX_PATH];
Q_strncpy( szDirPath, mch.getSourceModBaseDir(), MAX_PATH );
Q_strncat( szDirPath, "\\", MAX_PATH , COPY_ALL_CHARACTERS );
Q_strncat( szDirPath, modDirs[i], MAX_PATH , COPY_ALL_CHARACTERS );
// Check for the existence of gameinfo.txt
Q_strncpy( szGameConfigPath, szDirPath, MAX_PATH );
Q_strncat( szGameConfigPath, "\\gameinfo.txt", MAX_PATH , COPY_ALL_CHARACTERS );
FileHandle_t fpGameInfo = g_pFullFileSystem->Open( szGameConfigPath, "rb" );
// GameInfo.txt exists so let's inspect it...
if ( fpGameInfo )
{
// Close the file handle
g_pFullFileSystem->Close( fpGameInfo );
// Load up the "gameinfo.txt"
KeyValues *pMainFile, *pFileSystemInfo, *pSearchPaths;
LoadGameInfoFile( szDirPath, pMainFile, pFileSystemInfo, pSearchPaths );
//!! bug? check return code of loadgameinfofile??
if (NULL != pFileSystemInfo)
{
const int iAppId = pFileSystemInfo->GetInt( "SteamAppId", -1 );
// This is the one that needs replacing add this mod to the list of suspect mods
if ( GetAppSteamAppId( k_App_HL2 ) == iAppId)
{
bProblemModExists = true;
Q_strncat( szProblemMods, modDirs[i], MAX_PATH , COPY_ALL_CHARACTERS );
Q_strncat( szProblemMods, "\r\n", MAX_PATH , COPY_ALL_CHARACTERS );
}
}
}
}
// If necessary, pop up a message box informing the user that
if (bProblemModExists)
{
// Amend the warning message text
Q_strncat( szProblemMods, "\r\nIf you did not author any of the above mods you can ignore this message.\r\nIf you did author any of the above mods you should change the SteamAppId\nvalue in the gameinfo.txt file for each mod listed above.\r\n", 5*MAX_PATH , COPY_ALL_CHARACTERS );
// Pop up a message box
alert = new vgui::MessageBox( "Warning", szProblemMods );
alert->SetOKButtonText("Close");
alert->DoModal();
}
}
}
void ShowContentMigrationNotice()
{
// If we've shown it already, don't do anything.
FileHandle_t fp = g_pFullFileSystem->Open( SHOW_MIGRATION_MARKER, "rb" );
if ( fp )
{
g_pFullFileSystem->Close( fp );
return;
}
// Remember that we showed it.
fp = g_pFullFileSystem->Open( SHOW_MIGRATION_MARKER, "wb" );
g_pFullFileSystem->Close( fp );
OpenLocalizedURL( "URL_Content_Migration_Notice" );
}
public:
CUtlVector<CMinFootprintFilename> m_Filenames;
int m_iOutputVersionNumber;
private:
vgui::VPANEL m_PrevAppFocusPanel;
ProgressBar *m_pProgressBar;
int m_iCurCopyFile;
};
void AddMinFootprintFile( CUtlVector<CMinFootprintFilename> &filenames, const char *pSrcFilename, const char *pDestFilename, int flags )
{
// Just copy this one file.
CMinFootprintFilename *pOutputFilename = &filenames[filenames.AddToTail()];
Q_strncpy( pOutputFilename->m_SrcFilename, pSrcFilename, sizeof( pOutputFilename->m_SrcFilename ) );
Q_strncpy( pOutputFilename->m_DestFilename, pDestFilename, sizeof( pOutputFilename->m_DestFilename ) );
pOutputFilename->m_Flags = flags;
}
void GetMinFootprintFiles_R( CUtlVector<CMinFootprintFilename> &filenames, const char *pSrcDirName, const char *pDestDirName )
{
// pDirName\*.*
char wildcard[MAX_PATH];
Q_strncpy( wildcard, pSrcDirName, sizeof( wildcard ) );
Q_AppendSlash( wildcard, sizeof( wildcard ) );
Q_strncat( wildcard, "*.*", sizeof( wildcard ), COPY_ALL_CHARACTERS );
CUtlVector<CTempDirName> subDirs;
// Make sure the dest directory exists for when we're copying files into it.
CreateDirectory( pDestDirName, NULL );
// Look at all the files.
FileFindHandle_t findHandle;
const char *pFilename = g_pFullFileSystem->FindFirstEx( wildcard, SDKLAUNCHER_MAIN_PATH_ID, &findHandle );
while ( pFilename )
{
if ( Q_stricmp( pFilename, "." ) != 0 && Q_stricmp( pFilename, ".." ) != 0 )
{
char fullSrcFilename[MAX_PATH], fullDestFilename[MAX_PATH];
Q_snprintf( fullSrcFilename, sizeof( fullSrcFilename ), "%s%c%s", pSrcDirName, CORRECT_PATH_SEPARATOR, pFilename );
Q_snprintf( fullDestFilename, sizeof( fullDestFilename ), "%s%c%s", pDestDirName, CORRECT_PATH_SEPARATOR, pFilename );
if ( g_pFullFileSystem->FindIsDirectory( findHandle ) )
{
CTempDirName *pOut = &subDirs[subDirs.AddToTail()];
Q_strncpy( pOut->m_SrcDirName, fullSrcFilename, sizeof( pOut->m_SrcDirName ) );
Q_strncpy( pOut->m_DestDirName, fullDestFilename, sizeof( pOut->m_DestDirName ) );
}
else
{
AddMinFootprintFile( filenames, fullSrcFilename, fullDestFilename, 0 );
}
}
pFilename = g_pFullFileSystem->FindNext( findHandle );
}
g_pFullFileSystem->FindClose( findHandle );
// Recurse.
for ( int i=0; i < subDirs.Count(); i++ )
{
GetMinFootprintFiles_R( filenames, subDirs[i].m_SrcDirName, subDirs[i].m_DestDirName );
}
}
void DumpMinFootprintFiles( bool bForceRefresh )
{
if ( !g_pFullFileSystem->IsSteam() )
return;
// What version are we at now?
int curVersion = 0;
if ( !bForceRefresh )
{
KeyValues *kv = new KeyValues( "" );
if ( kv->LoadFromFile( g_pFullFileSystem, MIN_FOOTPRINT_VERSION_FILENAME ) )
{
curVersion = kv->GetInt( "Version", 0 );
}
kv->deleteThis();
}
// What is the current version?
int latestVersion = 0;
KeyValues *kv = new KeyValues( "" );
bool bValidFile = true;
if ( !kv->LoadFromFile( g_pFullFileSystem, MIN_FOOTPRINT_FILES_FILENAME ) )
bValidFile = false;
KeyValues *pFileList = NULL;
if ( bValidFile && (pFileList = kv->FindKey( "files" )) == NULL )
bValidFile = false;
if ( !bValidFile )
{
VGUIMessageBox( (vgui::Frame *) g_pMainFrame, "#Warning", "#CantLoadMinFootprintFiles" );
kv->deleteThis();
return;
}
latestVersion = kv->GetInt( "Version", 0 );
bool bVersionChanged = ( curVersion != latestVersion );
CMinFootprintFilesPanel *pDisplay = new CMinFootprintFilesPanel( (vgui::Frame *) g_pMainFrame, "MinFootprintFilesPanel" );
pDisplay->m_iOutputVersionNumber = latestVersion;
// Our version is out of date, let's copy out all the min footprint files.
// NOTE: copy files that are set to always_copy whether the version changed or not.
for ( KeyValues *pCur=pFileList->GetFirstSubKey(); pCur; pCur=pCur->GetNextKey() )
{
if ( ( Q_stricmp( pCur->GetName(), "mapping" ) == 0 ) && bVersionChanged )
{
const char *pSrcMapping = pCur->GetString( "src" );
const char *pDestMapping = pCur->GetString( "dest" );
char destDir[MAX_PATH], destDirTemp[MAX_PATH];
Q_snprintf( destDirTemp, sizeof( destDirTemp ), "%s%c%s", GetSDKLauncherBaseDirectory(), CORRECT_PATH_SEPARATOR, pDestMapping );
Q_MakeAbsolutePath( destDir, sizeof( destDir ), destDirTemp );
GetMinFootprintFiles_R( pDisplay->m_Filenames, pSrcMapping, destDir );
}
else if ( Q_stricmp( pCur->GetName(), "single_file" ) == 0 )
{
const char *pDestMapping = pCur->GetString();
// If the filename is preceded by the right prefix, then make it writable.
int flags = 0;
if ( Q_stristr( pDestMapping, WRITABLE_PREFIX ) == pDestMapping )
{
flags |= MF_MAKE_WRITABLE;
pDestMapping += strlen( WRITABLE_PREFIX );
}
// Check for [always_copy]
if ( Q_stristr( pDestMapping, ALWAYS_COPY_PREFIX ) == pDestMapping )
{
flags |= MF_ALWAYS_COPY;
pDestMapping += strlen( ALWAYS_COPY_PREFIX );
}
char destFile[MAX_PATH], destFileTemp[MAX_PATH];
Q_snprintf( destFileTemp, sizeof( destFileTemp ), "%s%c%s", GetSDKLauncherBaseDirectory(), CORRECT_PATH_SEPARATOR, pDestMapping );
Q_MakeAbsolutePath( destFile, sizeof( destFile ), destFileTemp );
if ( bVersionChanged || ( flags & MF_ALWAYS_COPY ) )
{
AddMinFootprintFile( pDisplay->m_Filenames, pDestMapping, destFile, flags );
}
}
else if ( ( Q_stricmp( pCur->GetName(), "create_directory" ) == 0 ) && bVersionChanged )
{
// Create an empty directory?
char destFile[MAX_PATH], destFileTemp[MAX_PATH];
Q_snprintf( destFileTemp, sizeof( destFileTemp ), "%s%c%s", GetSDKLauncherBaseDirectory(), CORRECT_PATH_SEPARATOR, pCur->GetString() );
Q_MakeAbsolutePath( destFile, sizeof( destFile ), destFileTemp );
CreateDirectory( destFile, NULL );
}
}
pDisplay->StartDumpingFiles();
}

View File

@ -0,0 +1,19 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================
#ifndef MIN_FOOTPRINT_FILES_H
#define MIN_FOOTPRINT_FILES_H
#ifdef _WIN32
#pragma once
#endif
// If bForceRefresh is true, then it will dump out all the files
// regardless of what version we think we currently have.
void DumpMinFootprintFiles( bool bForceRefresh );
#endif // MIN_FOOTPRINT_FILES_H

24
sdklauncher/resource.h Normal file
View File

@ -0,0 +1,24 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//
//=============================================================================//
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by Script1.rc
//
#define IDI_ICON1 101
#define IDI_ICON2 128
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 102
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1000
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

73
sdklauncher/script1.rc Normal file
View File

@ -0,0 +1,73 @@
//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
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1 ICON DISCARDABLE "steam.ico"
IDI_ICON2 ICON DISCARDABLE "icon2.ico"
#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
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,62 @@
//========= Copyright Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
//=============================================================================//
#ifndef SDKLAUNCHER_MAIN_H
#define SDKLAUNCHER_MAIN_H
#ifdef _WIN32
#pragma once
#endif
#include "tier2/vconfig.h"
#include <vgui_controls/Frame.h>
// This points at the root sourcesdk directory.
#define SDKLAUNCHER_MAIN_PATH_ID "MAIN"
const char* GetSDKLauncherBinDirectory();
const char* GetSDKToolsBinDirectory();
const char* GetSDKLauncherBaseDirectory();
const char* GetLastWindowsErrorString();
// Replace all occurences of %basedir% with the actual base dir.
void SubstituteBaseDir( const char *pIn, char *pOut, int outLen );
// Copy a file, applying replacements you specify.
// ppReplacments must come in pairs - the first one is the string to match and
// the second is the string to replace it with.
bool CopyWithReplacements(
const char *pInputFilename,
const char **ppReplacements, int nReplacements,
const char *pOutputFilenameFormat, ... );
// Open the file, read it in, and do some replacements. Returns a pointer to
// a string with the contents replaced. dataWriteLen specifies how much
// data should be written to an output file if you write the string out
// (since it may have added a null terminator).
CUtlVector<char>* GetFileStringWithReplacements(
const char *pInputFilename,
const char **ppReplacements, int nReplacements,
int &dataWriteLen );
void VGUIMessageBox( vgui::Panel *pParent, const char *pTitle, PRINTF_FORMAT_STRING const char *pMsg, ... );
class CSDKLauncherDialog;
extern CSDKLauncherDialog *g_pMainFrame;
extern bool g_bAutoHL2Mod; // skip modwizard_intro...
extern bool g_bModWizard_CmdLineFields;
extern char g_ModWizard_CmdLine_ModDir[MAX_PATH];
extern char g_ModWizard_CmdLine_ModName[256];
// Set this to make the app exit.
extern bool g_bAppQuit;
#endif // SDKLAUNCHER_MAIN_H

BIN
sdklauncher/steam.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB