Exemple #1
0
//----------------------------------------------------------------------------
CharString ProcessServer::searchLogFiles( CharString sFilemask, CharString sSearch, bool bRegExp, char nSearchLevel,
									 bool bResolveClients )
{
	CharString sResult;
	
	RegExpM rxSearch;
	RegExpM rxClientId, rxLogin;
	Tree< unsigned int, String > trClientLookup;

	sSearch.lower();	// all search is performed case insensitive

	if( bRegExp )
		rxSearch.regComp( sSearch );

	if( bResolveClients )
		rxClientId.regComp( STR("[Cc]lient ([0-9]+)[, ]") );
	

	FindFile ff;
	CharString sMask = CharString().format("./Logs/%s.log",sFilemask.cstr());
	ff.findFiles( sMask, false, false );	// sorted by date

	int nTotalFoundSize = 0;
	int nTotalSearchedSize = 0;
	int nTotalFilesSearched = 0;
	CharString sLine;
	dword tStart = Time::seconds();
	bool bAbort = false;

	// search through all found files
	for( int i = 0 ; i < ff.fileCount() && !bAbort ; i++ )
	{
		CharString sLocalFile( ff.file( i ) );

		if( nSearchLevel == 2 )		// only list the files, not search them ?
		{
			CharString sFile = CharString().format("./Logs/%s", sLocalFile.cstr()) ;
			sResult += String().format("*** [%s] *** %s\r\n", Time::format( FileDisk::fileDate( sFile ),"%c").cstr(), sLocalFile.cstr() );

			continue;
		}
		
		bool fileNamePrintedYet = false;
		CharString sText;
		CharString sTextOrig;
		int nCurPos = 0;
		try {
			CharString sFile = CharString().format("./Logs/%s",sLocalFile.cstr() );
			char * pTemp = FileDisk::loadTextFile( sFile );
			sText.copy( pTemp ).lower();	// pText is all lowercase, as it's used for case insensitive search
			sTextOrig = CharString().format("%s", pTemp );		// pTextOrig is orig-case, as it's used to build sResult
			delete pTemp;

			int nTextLen = sText.length();
			nTotalSearchedSize += nTextLen;
			nTotalFilesSearched++;

			int pos = -1;
			// loop to find all occurences of the string
			while( nCurPos < nTextLen && ( pos = findString( sText, nCurPos, sSearch, &rxSearch, bRegExp )  ) >= 0 )
			{
				if( !fileNamePrintedYet )
				{
					if( nSearchLevel == 0 )
						sResult += STR("\r\n\r\n");

					CharString sFile = CharString().format("./Logs/%s", sLocalFile.cstr()) ;
					sResult += String().format("*** [%s] *** %s\r\n", Time::format( FileDisk::fileDate( sFile ),"%c").cstr(), sLocalFile.cstr() );

					fileNamePrintedYet = true;
				}
				
				if( nSearchLevel == 1 )		// only check if there is a match in the file at all ?
					break;
				
				// find the matching line, this time in the original-case text
				nCurPos = findMatchingLine( sTextOrig, nCurPos + pos, sLine );	
				
				// need to resolve clientIds when found ?
				if( bResolveClients )
				{
					int nClientIdPos = rxClientId.regFind( sLine );
					if( nClientIdPos >= 0 )		// line holds a clientId ?
					{
						int nClientIdLen = rxClientId.getFindLen() - 8;	// match length - static chars

						// extract the clientId
						CharString sClientId = sLine;
						sClientId.right( sClientId.length() - ( nClientIdPos + 7 ) );
						sClientId.left( nClientIdLen );
						
						int nClientId = CharString::strint(sClientId);
						CharString sResolvedClient(STR(""));
						if( trClientLookup.find( nClientId ).valid() )	// know this clientId already ?
						{
							sResolvedClient = trClientLookup[ nClientId ];
						}
						else
						{
							// haven't seen it yet. Look it up.
							rxLogin.regComp( String().format( STR("\n../../.. ..:..:.. : Login client %d user ([^,\n]+), userId = ([0-9]+), "), nClientId ) );
							if( rxLogin.regFind( sTextOrig ) >= 0 )
							{
								sResolvedClient = rxLogin.getReplaceString( STR(" ( \\1 @\\2 )") );
							}
							else
							{
								// not found yet ? Try alternate way to resolve it
								rxLogin.regComp( String().format( STR("\n../../.. ..:..:.. : Client %d login, id = ([^\r]+)"), nClientId ) );
								if( rxLogin.regFind( sTextOrig ) >= 0 )
								{
									sResolvedClient = rxLogin.getReplaceString( STR(" ( \\1 )") );
								}	// no further "else". If it's not found the result is left blank
							}	

							trClientLookup[ nClientId ] = sResolvedClient;
						}

						if( sResolvedClient != "" )		// got something to insert ?
							sLine.insert( sResolvedClient, nClientIdPos + nClientIdLen + 7 );
					}
				}	// done resolving clientId

				// add the found line to the result
				nTotalFoundSize += sLine.length();
				sResult += sLine;
				
				// abort conditions
				if( nTotalFoundSize > 300000 )
				{
					sResult += STR("\r\n\r\n*** Result too large, search aborted");
					bAbort = true;
					break;
				}

			}
		}
		catch( ... )
		{
			return STR("Failed");
		}
	}

	if( sResult.length() == 0 )
		sResult = STR("No results");
	else
		sResult += STR("\r\nDone...");
	
	sResult += CharString().format( STR("\r\nSearched %d file(s) containing %d bytes within %d seconds. Result is %d bytes."),
		nTotalFilesSearched, nTotalSearchedSize, Time::seconds() - tStart, nTotalFoundSize );
	
	return sResult;
}
void ButtonContact::onRender( RenderContext & context, const RectInt & window )
{
	WindowButton::onRender( context, window );

	DisplayDevice * pDisplay = context.display();
	ASSERT( pDisplay );
	GameDocument * pDoc = (GameDocument *)document();
	ASSERT( pDoc );
	NounShip * pShip = pDoc->ship();
	if (! pShip )
		return;
	WindowStyle * pStyle = windowStyle();
	ASSERT( pStyle );
	Font * pFont = pStyle->font();
	ASSERT( pFont );

	// get a pointer to our gadget
	Noun * pContact = m_Noun;
	if (! pContact )
		return;

	RectInt iconBox( PointInt( window.left, window.top ), SizeInt( 16, 16 ) );

	Color iconColor( YELLOW );
	if ( pShip->isFriend( pContact ) )
		iconColor = GREEN;
	else if ( pShip->isEnemy( pContact ) )
		iconColor = RED;

	// draw the gadget icon
	Material::push( context, m_Icon );
	PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, iconColor );

	if ( WidgetCast<NounShip>( pContact ) 
		&& ((NounShip *)pContact)->canOrder( pShip ) )
	{
		Material::push( context, WidgetCast<Material>( resource("team") ) );
		iconBox += PointInt( 16, 0 );
		PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, WHITE );
	}
	else if ( m_IsObjective )
	{
		Material::push( context, WidgetCast<Material>( resource("objective") ) );
		iconBox += PointInt( 16, 0 );
		PrimitiveWindow::push( pDisplay, iconBox, WINDOW_UV, WHITE );
	}

	// display status text
	CharString sStatus = pContact->displayName( false );
	if ( m_HotKey != 0 )
		sStatus = CharString().format("%c:%s", m_HotKey, sStatus );
	if ( sStatus.length() > 0 )
	{
		SizeInt stringSize( pFont->size( sStatus ) );
		// make sure the text fits on the label
		while( stringSize.width > (BUTTON_WIDTH - 5 ) )
		{
			// remove the right most character and check the width again
			sStatus.left( sStatus.length() - 1 );
			stringSize = pFont->size( sStatus );
		}

		PointInt stringPos( window.m_Right - stringSize.width, window.m_Bottom - stringSize.height );
		Font::push( pDisplay, pFont, stringPos, sStatus, m_bGroupLeader ? YELLOW : (m_bGroupPending ? GREY : WHITE) );
	}

	// display the damage bar
	if ( WidgetCast<NounShip>( pContact ) )
	{
		if ( ((NounShip *)pContact)->damage() > 0 )
		{
			float damage = ((NounShip *)pContact)->damageRatioInv();
			RectInt bar( window.m_Left, window.m_Bottom + 1, 
				window.m_Right - (window.width() * (1.0f - damage)), window.m_Bottom + 3 );

			Color barColor( 255 * (1.0f - damage), 255 * damage,0,255 );
			PrimitiveMaterial::push( pDisplay, PrimitiveMaterial::NONE );
			PrimitiveWindow::push( pDisplay, bar, WINDOW_UV, barColor );
		}
	}

	// render additional border if this contact is our current target
	if ( pDoc->rootTarget() == m_Noun && (pDoc->tick() % 10) < 6 )
		renderGlow( context );
}