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

📄 vmapbuilder.cpp

📁 hl2 source code. Do not use it illegal.
💻 CPP
📖 第 1 页 / 共 2 页
字号:

// This program is meant to be left running on a machine.

// It sits in a while loop doing these steps:
// -	Read the vmapbuilder.cfg file, which has a list of .vmf files, their matching .bsp files,
//		and .vmf file dates telling the last time vmapbuilder built the file.
// -	Grab the top filename, move it to the bottom, and re-save the cfg file.
// -	Grab the .VMF file. If its date does not match the one from the .cfg file, then proceed,
//		otherwise, start back at step 1.
// -	Grab the HL2 or TF2 trees.
// -	Run vbsp, vrad, and vvis on the map.
// -	Checks out and checks in the .bsp.

// Note: the way the program reads and writes the .cfg file allows there to be any
// number of machines processing the list of maps, as long as they all are reading
// from the same vmapbuilder.cfg file. This can reduce turnaround time greatly.

#include "stdafx.h"
#include "utlvector.h"


#define MAX_FILENAME_LEN	256


HANDLE g_hOutputFile = 0;


// -------------------------------------------------------------------------------- //
// Config file reader.
// -------------------------------------------------------------------------------- //

class CConfigFile
{
public:

	class EMailAddress
	{
	public:
		char		m_EMailAddress[MAX_FILENAME_LEN];
	};

	class Entry
	{
	public:
		enum {MAX_EMAIL_ADDRESSES=128};

						Entry()
						{
							m_nEMailAddresses = 0;
							m_bFastVis = false;
						}

		EMailAddress	m_EMailAddresses[MAX_EMAIL_ADDRESSES];
		int				m_nEMailAddresses;

		char			m_Filename[MAX_FILENAME_LEN];
		char			m_VMFPath[MAX_FILENAME_LEN];
		long			m_VMFTime;	// Last time the VMF file was successfully reprocessed.
		bool			m_bFastVis;
	};


public:

	void			Term();	
	bool			Read( char const *pFilename );
	bool			Write( char const *pFilename );
	Entry*			FindEntryByFilename( char const *pFilename );



public:
	
	char			m_SSDatabase[MAX_FILENAME_LEN];			// \\jeeves\hl2vss
	char			m_SSResourcePath[MAX_FILENAME_LEN];		// $/HL2/Release/Dev
	char			m_SSBSPPath[MAX_FILENAME_LEN];			// $/HL2/Release/Dev/hl2/maps

	CUtlVector<Entry>	m_Entries;


private:

	// Fill in pDest with the next token. Return false if there is no next token.
	bool			GetNextToken( FILE *fp, char *pDest, int destLen );
	
	// Return true if the next token is equal to pTest.
	bool			VerifyNextToken( FILE *fp, char const *pTest );

	bool			IsWhitespace( char ch );
};


void CConfigFile::Term()
{	
	m_Entries.Purge();
	m_SSDatabase[0] = m_SSResourcePath[0] = m_SSBSPPath[0] = 0;	
}


bool CConfigFile::Read( char const *pFilename )
{
	Term();

	// Read in the whole file.
	FILE *fp = fopen( pFilename, "rt" );
	if( !fp )
		return false;

	int iCurPos = 0;
	if( !VerifyNextToken( fp, "ssdatabase" ) || 
		!GetNextToken( fp, m_SSDatabase, sizeof(m_SSDatabase) ) )
	{
		fclose( fp );
		return false;
	}

	if( !VerifyNextToken( fp, "resourcepath" )  || 
		!GetNextToken( fp, m_SSResourcePath, sizeof(m_SSResourcePath) ) )
	{
		fclose( fp );
		return false;
	}

	if( !VerifyNextToken( fp, "bsppath" ) ||
		!GetNextToken( fp, m_SSBSPPath, sizeof(m_SSBSPPath) ) )
	{
		fclose( fp );
		return false;
	}

	while( VerifyNextToken( fp, "file" ) )
	{
		CConfigFile::Entry entry;
		char timeStr[512];
		if( !GetNextToken( fp, entry.m_Filename, sizeof(entry.m_Filename) ) ||
			!GetNextToken( fp, entry.m_VMFPath, sizeof(entry.m_VMFPath) ) ||
			!GetNextToken( fp, timeStr, sizeof(timeStr) ) 
		)
		{
			fclose( fp );
			return false;
		}
		
		entry.m_VMFTime = atoi( timeStr );

		// Read the email addresses.
		while(1)
		{		 
			char token[1024];

			int curPos = ftell( fp );
			if( entry.m_nEMailAddresses < CConfigFile::Entry::MAX_EMAIL_ADDRESSES && 
				GetNextToken( fp, token, sizeof(token) ) )
			{
				if( stricmp( token, "-email" ) == 0 )
				{
					CConfigFile::EMailAddress *addr = &entry.m_EMailAddresses[entry.m_nEMailAddresses];
					if( !GetNextToken( fp, addr->m_EMailAddress, sizeof(addr->m_EMailAddress) ) )
					{
						delete addr;
						fclose( fp );
						return false;
					}

					++entry.m_nEMailAddresses;
					continue;
				}
				else if( stricmp( token, "-fast" ) == 0 )
				{
					entry.m_bFastVis = true;
					continue;
				}
			}
			
			// No more options..
			fseek( fp, curPos, SEEK_SET );
			break;
		}

		m_Entries.AddToTail( entry );
	}

	fclose( fp );
	return true;
}


bool CConfigFile::Write( char const *pFilename )
{
	FILE *fp = fopen( pFilename, "wt" );
	if( !fp )
		return false;

	fprintf( fp, "ssdatabase %s\n", m_SSDatabase );
	fprintf( fp, "resourcepath %s\n", m_SSResourcePath );
	fprintf( fp, "bsppath %s\n", m_SSBSPPath );

	for( int i=0; i < m_Entries.Size(); i++ )
	{
		CConfigFile::Entry *pEntry = &m_Entries[i];
		fprintf( fp, "file %s %s %d", pEntry->m_Filename, pEntry->m_VMFPath, pEntry->m_VMFTime );
		
		for( int e=0; e < pEntry->m_nEMailAddresses; e++ )
			fprintf( fp, " -email %s", pEntry->m_EMailAddresses[e].m_EMailAddress );
		
		if( pEntry->m_bFastVis )
			fprintf( fp, " -fast" );

		fprintf( fp, "\n" );
	}

	fclose( fp );
	return true;
}


CConfigFile::Entry* CConfigFile::FindEntryByFilename( char const *pFilename )
{
	for( int i=0; i < m_Entries.Size(); i++ )
	{
		if( stricmp( m_Entries[i].m_Filename, pFilename ) == 0 )
			return &m_Entries[i];
	}

	return NULL;
}


bool CConfigFile::GetNextToken( FILE *fp, char *pDest, int destLen )
{
	// Eat up whitespace..
	char ch = 0;
	while( IsWhitespace( ch = fgetc(fp) )  )
	{
		;
	}

	if( ch == EOF )
		return false;

	int iDestPos = 0;
	while( iDestPos < destLen )
	{
		pDest[iDestPos] = ch;
		++iDestPos;
		
		ch = fgetc( fp );
		if( IsWhitespace( ch ) || ch == EOF )
		{
			pDest[iDestPos] = 0;
			return true;
		}
	}

	return false;
}


bool CConfigFile::VerifyNextToken( FILE *fp, char const *pTest )
{
	char token[2048];
	if( !GetNextToken( fp, token, sizeof(token) ) )
		return false;

	return stricmp( token, pTest ) == 0;
}


bool CConfigFile::IsWhitespace( char ch )
{
	return ch == '\n' || ch == '\r' || ch == ' ' || ch == '\t';
}


// -------------------------------------------------------------------------------- //
// Global code.
// -------------------------------------------------------------------------------- //

// Send an email to someone..
typedef ULONG (FAR PASCAL *MAPISendMailFn)(
  LHANDLE lhSession,         
  ULONG ulUIParam,           
  lpMapiMessage lpMessage,   
  FLAGS flFlags,             
  ULONG ulReserved           
); 

bool SendMail( char *pTo, char *pSubject, char *pText )
{
	char const *pLib = "MAPI32.DLL";

	char to[1024];
	_snprintf( to, sizeof(to), "SMTP:%s", pTo );

	HINSTANCE hMAPI = LoadLibrary( pLib );
	if( !hMAPI )
		return false;

	MAPISendMailFn fn = (MAPISendMailFn)GetProcAddress( hMAPI, "MAPISendMail" );
	if( !fn )
	{
		FreeLibrary( hMAPI );
		return false;
	}

	MapiRecipDesc recip =
	{
		0,			// reserved
		MAPI_TO,	// who it goes to
		to,
		to,
		0,
		0
	};	 	

	MapiMessage note = {0,            // reserved, must be 0
						(char*)pSubject,     // subject
						(char*)pText,        // note text
						NULL,         // NULL = interpersonal message
						NULL,         // no date; MAPISendMail ignores it
						NULL,         // no conversation ID
						0L,           // no flags, MAPISendMail ignores it
						NULL,         // no originator, this is ignored too
						1,            // one recipient
						&recip,       // NULL recipient array
						0,            // no attachment
						NULL };		  // the attachment structure

	// Store this off..
	char workingDir[256];
	GetCurrentDirectory( sizeof(workingDir), workingDir );
 
	long bRet = fn( 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -