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

📄 filteringtable.cpp

📁 墨香最新私服
💻 CPP
字号:
// FilteringTable.cpp: implementation of the CFilteringTable class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "FilteringTable.h"
#include "MHFile.h"

CFilteringTable::CFilteringTable()
{

}

CFilteringTable::~CFilteringTable()
{
	Release();
}

void CFilteringTable::Init()
{
#ifdef _FILTER_TEST_
	m_nMemory = 0;
#endif
	
#ifdef _FILE_BIN_
	LoadFilterWordBinary( "./Resource/FilterWord.bin" );
#else
	LoadFilterWord( FILEPATH_FILTERWORD );
#endif
}

void CFilteringTable::Release()
{
	for( int i = 0 ; i < eFilter_Count ; ++i )
	{
		if( m_RootNode[i].pChild )
			DeleteNode( m_RootNode[i].pChild );
	}
}

void CFilteringTable::DeleteNode( FILTER_NODE* pNode )
{
	if( pNode->pChild )
	{
		DeleteNode( pNode->pChild );
		pNode->pChild = NULL;
	}

	if( pNode->pSibling )
	{
		DeleteNode( pNode->pSibling );
		pNode->pSibling = NULL;
	}
	
	delete pNode;
}

void CFilteringTable::CleanNode( FILTER_NODE* pNode )
{
	if( pNode->pChild )
	{
		CleanNode( pNode->pChild );
	}

	if( pNode->pSibling )
	{
		CleanNode( pNode->pSibling );
	}
	
	pNode->bSpread = FALSE;
}

void CFilteringTable::AddWord( char *pWord, int nKind )
{
	AddNode( &m_RootNode[nKind], pWord );
}

void CFilteringTable::AddNode( FILTER_NODE* pNode, char* pWord )
{
	if( *pWord == NULL )
	{
		pNode->bEndFlag = TRUE;
		return;
	}

	if( pNode->pChild )
	{
		pNode = pNode->pChild;

		while( pNode )
		{
			if( pNode->cChar == *pWord )
			{
				if( IsDBCSLeadByte( pNode->cChar ) )
				{
					if( pNode->cExChar == *(pWord+1) )
					{
						pWord += 2;
						AddNode( pNode, pWord );
						return;
					}
				}
				else
				{
					++pWord;
					AddNode( pNode, pWord );
					return;
				}
			}
			
			if( pNode->pSibling == NULL )
			{
				FILTER_NODE* pSibling	= new FILTER_NODE;
#ifdef _FILTER_TEST_
				m_nMemory += sizeof( FILTER_NODE );
#endif
				pSibling->cChar			= *pWord++;
				if( IsDBCSLeadByte( pSibling->cChar ) )
				{
					pSibling->cExChar	= *pWord++;
				}
				
				pNode->pSibling			= pSibling;
				pSibling->pParent		= pNode->pParent;
				
				AddNode( pSibling, pWord );
				return;
			}

			pNode = pNode->pSibling;
		}
	}
	else
	{
		FILTER_NODE* pChild = new FILTER_NODE;
#ifdef _FILTER_TEST_
		m_nMemory += sizeof( FILTER_NODE );
#endif
		pChild->cChar		= *pWord++;
		if( IsDBCSLeadByte( pChild->cChar ) )
		{
			pChild->cExChar	= *pWord++;
		}

		pNode->pChild		= pChild;
		pChild->pParent		= pNode;

		AddNode( pChild, pWord );
	}
}

BOOL CFilteringTable::FilterWordInString( char* pStr, int nKind, int nMethod )
{
	//檬扁拳 持扁(spread甫 葛滴 钱扁)
	for( int i = 0 ; i < eFilter_Count ; ++i )
	{
		if( m_RootNode[i].pChild )
			CleanNode( m_RootNode[i].pChild );
	}

	m_bSearched = FALSE;

	switch( nMethod )
	{
	case eFM_WHOLE_MATCH:
		return FM_WholeMatch( pStr, nKind );

	case eFM_INCLUDE:
		return FM_Include( pStr, nKind );

	case eFM_ALLOWSPACE:
		return FM_AllowSpace( pStr, nKind, 8 );
	}

	return FALSE;
}

BOOL CFilteringTable::FM_WholeMatch( char* pStr, int nKind )
{
	m_nStrPos = 0;
	
	while( *pStr )
	{
		m_bSpread = FALSE;

		if( IsDBCSLeadByte( *pStr ) )
		{
			SearchNode( m_RootNode[nKind].pChild, pStr, 0, TRUE );
			pStr += 2;
		}
		else
		{
			SearchNode( m_RootNode[nKind].pChild, pStr, 0, FALSE );
			++pStr;
		}

		++m_nStrPos;

		if( m_bSearched )
		{
			if( *pStr ) m_bSearched = FALSE;
			else		return TRUE;
		}
		if( m_bSpread == FALSE ) return FALSE;
	}

	return FALSE;
}

BOOL CFilteringTable::FM_Include( char* pStr, int nKind )
{
	m_nStrPos = 0;

	while( *pStr )
	{
		m_bSpread = FALSE;

		if( IsDBCSLeadByte( *pStr ) )
		{
			SearchNode( m_RootNode[nKind].pChild, pStr, 0, TRUE );
			pStr += 2;
		}
		else
		{
			SearchNode( m_RootNode[nKind].pChild, pStr, 0, FALSE );
			++pStr;
		}

		++m_nStrPos;

		if( m_bSearched ) return TRUE;
		if( m_bSpread == FALSE ) m_nStrPos = 0;
	}

	return FALSE;
}

BOOL CFilteringTable::FM_AllowSpace( char* pStr, int nKind, int nAllowSpace )
{
	while( *pStr )
	{
		if( IsDBCSLeadByte( *pStr ) )
		{
			SearchNode_AllowSpace( m_RootNode[nKind].pChild, pStr, TRUE );
			pStr += 2;
		}
		else
		{
			SearchNode_AllowSpace( m_RootNode[nKind].pChild, pStr, FALSE );
			++pStr;
		}

		if( m_bSearched ) return TRUE;
	}

	return FALSE;
}

void CFilteringTable::SearchNode( FILTER_NODE* pNode, char* pStr, int nDepth, BOOL bDBC )
{
	if( pNode == NULL )	return;

	if( pNode->bSpread )
	{
		SearchNode( pNode->pChild, pStr, nDepth + 1, bDBC );
	}
	else
	{
		if( bDBC )		//confirm
		{
			if( pNode->cChar == *pStr && pNode->cExChar == *(pStr+1) && m_nStrPos == nDepth )
			{
				pNode->bSpread	= TRUE;
				m_bSpread		= TRUE;

				if( pNode->bEndFlag == TRUE )
					m_bSearched = TRUE;

				return;
			}
		}
		else
		{
			if( pNode->cChar == *pStr && m_nStrPos == nDepth )
			{
				pNode->bSpread	= TRUE;
				m_bSpread		= TRUE;	

				if( pNode->bEndFlag == TRUE )
					m_bSearched = TRUE;

				return;
			}
		}
	}

	SearchNode( pNode->pSibling, pStr, nDepth, bDBC );
}

void CFilteringTable::SearchNode_AllowSpace( FILTER_NODE* pNode, char* pStr, BOOL bDBC )
{
	if( pNode == NULL )	return;

	if( pNode->bSpread )
	{
		SearchNode_AllowSpace( pNode->pChild, pStr, bDBC );
	}
	else
	{
		if( bDBC )		//confirm
		{
			if( pNode->cChar == *pStr && pNode->cExChar == *(pStr+1) )
			{
				if( pNode->bEndFlag == TRUE )
					m_bSearched = TRUE;

				pNode->bSpread	= TRUE;

				return;
			}
		}
		else
		{
			if( pNode->cChar == *pStr )
			{
				if( pNode->bEndFlag == TRUE )
					m_bSearched = TRUE;

				pNode->bSpread	= TRUE;

				return;
			}
		}
	}

	SearchNode_AllowSpace( pNode->pSibling, pStr, bDBC );
}

BOOL CFilteringTable::FilterChat( char* pChat )
{
//	strcpy( m_strBuf, pChat );
	SafeStrCpy( m_strBuf, pChat, 256 );
	strupr( m_strBuf );
	
	if( FilterWordInString( m_strBuf, eFilter_Slang, eFM_ALLOWSPACE ) ) //eFM_ALLOWSPACE
	{
		return TRUE;
	}

	return FALSE;
}

BOOL CFilteringTable::IsUsableName( char* pName )
{
//	strcpy( m_strBuf, pName );
	SafeStrCpy( m_strBuf, pName, 256 );

	strupr( m_strBuf );

	if( FilterWordInString( m_strBuf, eFilter_System, eFM_WHOLE_MATCH ) )
		return FALSE;

	if( FilterWordInString( m_strBuf, eFilter_GM, eFM_INCLUDE ) )
		return FALSE;

	if( FilterWordInString( m_strBuf, eFilter_Slang, eFM_ALLOWSPACE ) )
		return FALSE;

	return TRUE;
}

BOOL CFilteringTable::IsInvalidCharInclude( unsigned char* pStr )
{
	while( *pStr )
	{
		BOOL bOk = FALSE;

		if( IsDBCSLeadByte( *pStr ) )
		{
#ifdef TAIWAN_LOCAL
			///////////
			bOk = TRUE;
			///////////
#else
			if( pStr[0] >= 0xb0 && pStr[0] <=0xc8 && pStr[1] >= 0xa1 && pStr[1] <= 0xfe )//0xB0A1~0xC8FE
			{
				bOk = TRUE;
			}
			else if( pStr[0] >= 0x81 && pStr[0] <= 0xc6 && pStr[1] >= 0x41 && pStr[1] <= 0xfe )
			{
				bOk = TRUE;
			}
			if( pStr[0] >= 0xa1 && pStr[0] <= 0xac && pStr[1] >= 0x80 && pStr[1] <= 0xfe )
			{
				bOk = FALSE;
			}
/*
			//--何龋老窜哗扁 confirm
			if( pStr[0] >= 0xa1 && pStr[0] <= 0xac && pStr[1] >= 0x80 && pStr[1] <= 0xff )
			{
				bOk = FALSE;
			}
*/
#endif
			++pStr;
		}
		else
		{
			//康巩
			if( ( *pStr >= 'A' && *pStr <= 'Z' ) || ( *pStr >= 'a' && *pStr <= 'z' ) )
				bOk = TRUE;
			//箭磊
			else if( *pStr >= '0' && *pStr <= '9' )
				bOk = TRUE;
//#ifdef TAIWAN_LOCAL			
//			//扁龋甸
//			else if( *pStr >= 32 && *pStr < 127 )
//				bOk = TRUE;
//#endif	
		}

		++pStr;

		if( bOk == FALSE )
			return TRUE;
	}

	return FALSE;
}

BOOL CFilteringTable::LoadFilterWord( char* strFile )
{
	HANDLE	hFile;

	hFile = CreateFile( strFile, GENERIC_READ, 0, NULL,
						OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

	if( hFile == INVALID_HANDLE_VALUE )
		return FALSE;

	DWORD dwFileSize = GetFileSize( hFile, NULL );
	if( dwFileSize == -1 ) return FALSE;

	char* buf = new char[dwFileSize + 1];

	DWORD dwRead;
	if( !ReadFile( hFile, buf, dwFileSize, &dwRead, NULL ) )
	{
		CloseHandle( hFile );
		delete[] buf;
		return FALSE;
	}

	buf[dwFileSize] = NULL;
	SettingFilterWord( buf, dwFileSize );
	
	CloseHandle( hFile );
	delete[] buf;
	return TRUE;	
}

BOOL CFilteringTable::LoadFilterWordBinary( char* strFile )
{
	CMHFile file;
	if( file.OpenBin( strFile ) )
	{
		DWORD dwFileSize = file.GetDataSize();
		char* buf = new char[dwFileSize + 1];
		memcpy( buf, file.GetData(), dwFileSize+1);
		buf[dwFileSize] = NULL;
		SettingFilterWord( buf, dwFileSize );
		delete[] buf;

		file.Release();

		return TRUE;
	}
	return FALSE;
}

void CFilteringTable::SettingFilterWord( char* pStr, DWORD bufLen )
{
	m_strFile = pStr;
	int nKind = 0;

	char seps[] = ",\t\n\r";
	char* token;
	char OutBuf[256];
	
	token = strtok( pStr, seps );
	RemoveSpace( token, OutBuf );
	strupr( OutBuf );
	
	while( token != NULL )
	{
		if( token[0] != '@' )	//@吧矾郴绊..
		{
			if( token[0] == '#' )
			{
				if( strcmp( token, "#SLANG" ) == 0 )
				{
					nKind = eFilter_Slang;
				}
				else if( strcmp( token, "#GM" ) == 0 )
				{
					nKind = eFilter_GM;
				}
				else if( strcmp( token, "#SYSTEM" ) == 0 )
				{
					nKind = eFilter_System;
				}
			}
			else
			{
				AddWord( OutBuf, nKind );
			}
		}

		token = strtok( NULL, seps );	//get next token
		RemoveSpace( token, OutBuf );
		strupr( OutBuf );
	}
}

int CFilteringTable::RemoveSpace( char* pStrIn, char* pStrOut )
{
	if( pStrIn == NULL ) return 0;
	
	int nLen = 0;

	while( *pStrIn )
	{
		if( *pStrIn != ' ' )
		{
			*pStrOut = *pStrIn;
			++pStrOut;
			++nLen;
		}

		++pStrIn;
	}

	*pStrOut = 0;

	return nLen;
}

⌨️ 快捷键说明

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