📄 vmapbuilder.cpp
字号:
NULL, // implicit session.
0, // parent window.
¬e, // the message.
0, // flags
0 // reserved.
) == SUCCESS_SUCCESS;
// MAPISendMail screws with your working directory, so restore it here.
SetCurrentDirectory( workingDir );
FreeLibrary( hMAPI );
return !!bRet;
}
char const* FindArg( char const *pName )
{
for( int i=1; i < __argc; i++ )
if( stricmp( pName, __argv[i] ) == 0 )
return (i+1) < __argc ? __argv[i+1] : "";
return NULL;
}
int PrintUsage()
{
printf( "vmapbuilder <cfg filename> <-noget>\n" );
return 1;
}
void AppPrint( char const *pMsg, ... )
{
char msg[8192];
va_list marker;
va_start( marker, pMsg );
_vsnprintf( msg, sizeof(msg), pMsg, marker );
va_end( marker );
printf( "%s", msg );
// Write to the output file too...
DWORD dwNumBytesWritten = 0;
WriteFile( g_hOutputFile, msg, strlen(msg)+1, &dwNumBytesWritten, NULL );
}
void BuildTimeDurationString( DWORD elapsed, char timeStr[256] )
{
DWORD seconds = elapsed / 1000;
DWORD minutes = seconds / 60;
seconds -= minutes * 60;
DWORD hours = minutes / 60;
minutes -= hours * 60;
_snprintf( timeStr, 256, "(%d hr, %d min, %d sec)", hours, minutes, seconds );
}
DWORD RunProcess( char *pCmdLine )
{
STARTUPINFO si;
memset( &si, 0, sizeof(si) );
si.cb = sizeof(si);
si.dwFlags |= STARTF_USESTDHANDLES;
si.hStdError = g_hOutputFile;
si.hStdOutput = g_hOutputFile;
si.hStdInput = GetStdHandle( STD_INPUT_HANDLE );
PROCESS_INFORMATION pi;
if( !CreateProcess(
NULL,
pCmdLine,
NULL,
NULL,
TRUE, // bInheritHandles
CREATE_NO_WINDOW | IDLE_PRIORITY_CLASS,
NULL,
NULL,
&si,
&pi ) )
{
return false;
}
// Wait for it to complete..
DWORD dwExitCode = 1;
WaitForSingleObject( pi.hProcess, INFINITE );
GetExitCodeProcess( pi.hProcess, &dwExitCode );
CloseHandle( pi.hThread );
CloseHandle( pi.hProcess );
return dwExitCode;
}
int main(int argc, char* argv[])
{
char cmd[512];
int ret;
if( argc < 2 )
{
return PrintUsage();
}
// All output gets redirected to this file.
SECURITY_ATTRIBUTES fileAttribs;
fileAttribs.nLength = sizeof(fileAttribs);
fileAttribs.lpSecurityDescriptor = NULL;
fileAttribs.bInheritHandle = TRUE;
g_hOutputFile = CreateFile(
"vmapbuilder.out",
GENERIC_WRITE,
FILE_SHARE_READ,
&fileAttribs,
CREATE_ALWAYS,
FILE_FLAG_WRITE_THROUGH|FILE_ATTRIBUTE_NORMAL,
NULL );
// Low priority..
SetPriorityClass( GetCurrentProcess(), IDLE_PRIORITY_CLASS );
bool bSave = !FindArg( "-nosave" );
bool bNoVis = !!FindArg( "-novis" );
bool bNoRad = !!FindArg( "-norad" );
char const *pCFGFile = argv[1];
while( 1 )
{
DWORD startTime = GetTickCount();
CConfigFile file;
if( file.Read( pCFGFile ) && file.m_Entries.Size() > 0 )
{
// Move the first entry in the file to the end.
CConfigFile::Entry entry = file.m_Entries[0];
file.m_Entries.Remove( 0 );
file.m_Entries.AddToTail( entry );
if( bSave )
{
file.Write( pCFGFile );
}
char ssCmd[256];
_snprintf( ssCmd, sizeof(ssCmd), "%s\\win32\\ss.exe", file.m_SSDatabase );
// Grab the SourceSafe tree.
AppPrint( "\n\n-------------------------------------------------------------\n" );
AppPrint( "Processing %s\n", entry.m_Filename );
AppPrint( "-------------------------------------------------------------\n" );
AppPrint( "Grabbing resources in %s\n", file.m_SSDatabase );
sprintf( cmd, "ssdir=%s", file.m_SSDatabase );
ret = _putenv( cmd );
// Get the VMF.
char vmfFilename[512];
sprintf( vmfFilename, "%s/%s.vmf", entry.m_VMFPath, entry.m_Filename );
sprintf( cmd, "%s get %s -I-", ssCmd, vmfFilename );
ret = RunProcess( cmd );
// Check the timestamp (don't reprocess if it's up-to-date).
sprintf( vmfFilename, "%s.vmf", entry.m_Filename );
struct _stat fileStat;
ret = _stat( vmfFilename, &fileStat );
long vmfTime = fileStat.st_mtime;
if( vmfTime == entry.m_VMFTime )
{
AppPrint( "%s is up-to-date\n", vmfFilename );
}
else
{
char localBSPFilename[512];
sprintf( localBSPFilename, "%s.bsp", entry.m_Filename );
// Attrib the bsp if it exists.
sprintf( cmd, "attrib -r %s", localBSPFilename );
RunProcess( cmd );
sprintf( cmd, "%s cp %s", ssCmd, file.m_SSResourcePath );
ret = RunProcess( cmd );
if( !FindArg( "-noget" ) )
{
sprintf( cmd, "%s get * -R -I-", ssCmd );
ret = RunProcess( cmd );
}
// run each tool.
char vbspCommand[256], vradCommand[256], vvisCommand[256];
sprintf( vbspCommand, "bin\\vbsp -low %s", entry.m_Filename );
if( entry.m_bFastVis )
sprintf( vvisCommand, "bin\\vvis -fast -low %s", entry.m_Filename );
else
sprintf( vvisCommand, "bin\\vvis -low %s", entry.m_Filename );
sprintf( vradCommand, "bin\\vrad -low %s", entry.m_Filename );
if( !RunProcess( vbspCommand ) &&
(bNoVis || !RunProcess( vvisCommand )) &&
(bNoRad || !RunProcess( vradCommand )) )
{
// Check in the BSP file.
char bspFilename[512];
sprintf( bspFilename, "%s/%s.bsp", file.m_SSBSPPath, entry.m_Filename );
// First, try to add it to SS because it may not exist yet.
sprintf( cmd, "%s cp %s", ssCmd, file.m_SSBSPPath );
RunProcess(cmd);
sprintf( cmd, "%s add %s.bsp -I-", ssCmd, entry.m_Filename );
ret = RunProcess(cmd);
// Store off the BSP file temporarily..
char tempFilename[512];
sprintf( localBSPFilename, "%s.bsp", entry.m_Filename );
sprintf( tempFilename, "%s.TEMP", entry.m_Filename );
sprintf( cmd, "del /f %s", tempFilename );
system( cmd );
sprintf( cmd, "attrib -r %s", localBSPFilename );
system( cmd );
ret = MoveFile( localBSPFilename, tempFilename );
if( ret )
{
char undoCmd[512];
sprintf( undoCmd, "%s undocheckout %s -I-", ssCmd, bspFilename );
sprintf( cmd, "%s checkout %s -I-", ssCmd, bspFilename );
ret = RunProcess( cmd );
if( !ret )
{
// Copy the new BSP file over.
DeleteFile( localBSPFilename );
ret = MoveFile( tempFilename, localBSPFilename );
if( ret )
{
sprintf( cmd, "%s checkin %s -I-", ssCmd, bspFilename );
ret = RunProcess( cmd );
if( !ret )
{
while( !file.Read( pCFGFile ) )
{
Sleep( 300 );
}
if( bSave )
{
CConfigFile::Entry *pEntry = file.FindEntryByFilename( entry.m_Filename );
if( pEntry )
{
pEntry->m_VMFTime = vmfTime;
while( !file.Write( pCFGFile ) )
{
Sleep( 300 );
}
}
}
// Update the timestamp in the config file.
AppPrint( "Completed '%s' successfully!\n", entry.m_Filename );
// Send emails.
char computerName[256] = {0};
DWORD len = sizeof(computerName);
GetComputerName( computerName, &len );
DWORD elapsed = GetTickCount() - startTime;
char timeStr[256];
BuildTimeDurationString( elapsed, timeStr );
char subject[1024];
_snprintf( subject, sizeof(subject), "[vmapbuilder] completed '%s' on '%s' in %s", entry.m_Filename, computerName, timeStr );
for( int e=0; e < entry.m_nEMailAddresses; e++ )
{
char *pAddr = entry.m_EMailAddresses[e].m_EMailAddress;
if( !SendMail( pAddr, subject, subject ) )
{
AppPrint( "Unable to send confirmation email to %s\n", pAddr );
}
}
}
else
{
AppPrint( "ERROR: Can't checkin %s\n", bspFilename );
RunProcess( undoCmd );
}
}
else
{
AppPrint( "ERROR: Can't copy back the BSP file %s\n", localBSPFilename );
RunProcess( undoCmd );
}
}
else
{
AppPrint( "ERROR: Can't checkout %s\n", bspFilename );
}
}
else
{
AppPrint( "ERROR: Can't create temporary file %s\n", tempFilename );
}
}
else
{
AppPrint( "Command '%s' failed\n", cmd );
}
}
}
else
{
AppPrint( "Can't read maplist file: %s\n", pCFGFile );
}
// Sleep for a bit in case all maps are processed so we don't kill the network.
Sleep( 2000 );
}
CloseHandle( g_hOutputFile );
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -