⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmapbuilder.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		NULL,			// implicit session.
		0,				// parent window.
		&note,			// 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 + -