Проверенный
Пользователь
- Сообщения
- 1,031
- Реакции
- 827
- Помог
- 10 раз(а)
Пилю плагин для чека мониторингов по их хешим, и что-то мне кажется перемудрился =D
В общем хочу советы по коду, может что убрать или улучшить.
Имеет свою отдельную базу, задействует API Речекера.
Ищет неизвестные хеши, туп логирует название файлов и их хеш, затем по дефам можно понять чья контора
У одного админа произошел сбой, причину так и не смог выяснить
Зашел игрок Веня , как видим чекнуло файл voise_speex.dl и хеш 4b5f8a38
Вот только прикол в том, что этот хеш принадлежит файлу, согласно базе данных
А файл ../voise_speex.dll принадлежит вообще boostcs.ru с другим хешем
Получился такой вот переплет.
В чем прикол я так и не понял, залогировал динамический массив, все хеши там принадлежат правильным конторам, проверил массивые, все вроде верно записывается, так я и не понял в чем мог произойти сбой такой интересный.
В общем хочу советы по коду, может что убрать или улучшить.
Имеет свою отдельную базу, задействует API Речекера.
Ищет неизвестные хеши, туп логирует название файлов и их хеш, затем по дефам можно понять чья контора
C++:
#include < amxmodx >
#include < reapi >
#pragma semicolon 1
#define LOGS_MS_UNKNOWN // Ведение журналов для сбора неизвестных хешей
new const HASHES_DIRECTORY[ ] = "/addons/rechecker/dlls"; // Путь до директории хранилище данных
new const HASHES_FILE_NAME[ ] = "ms_hashes.ini"; // Наименование файла хранилище данных
new const LOGS_FOLDER_NAME[ ] = "ms_check"; // Наименование каталога ведение журналов
new const LOGS_FILE_NAME__MS_KNOWN[ ] = "ms_log"; // Наименование журналов для ведение информации известных хешей
#if defined LOGS_MS_UNKNOWN
new const LOGS_FILE_NAME__MS_UNKNOWN[ ] = "ms_unknown"; // Наименование журналов для ведение информации неизвестных хешей
#endif
new const MS_UNKNOWN[ ] = "[UNKNOWN]"; // МС UNKNOWN
new const MS_STEAM[ ] = "[STEAM]"; // МС Steam
new const MS_RECLIENT[ ] = "[RECLIENT]"; // МС ReClient
const MAX_REGISTER_QUERY_FILE = 32; // Максимальное количество зарегистрированных файлов
const ELLIPSES_ARG = 4;
const NULLED = 0;
const DP_PROTOCOL = 48;
const DP_AUTH_REVEMU = 4;
const MAX_LENGTH__PATH = 64;
const MAX_LENGTH__MS_CONTENT = 256;
const MAX_LENGTH__MS_FILE = 64;
const MAX_LENGTH__MS_HASH = 32;
const MAX_LENGTH__MS_NAME = 32;
const MAX_LENGTH__AUTHID = 64;
const MAX_LENGTH__NAME = 32;
const MAX_LENGTH__IP = 16;
const MAX_LENGTH__TIME = 32;
const MAX_LENGTH__MESSAGE = 512;
enum _: MS_KNOWN_DATA
{
MS_KNOWN__FILE[ MAX_LENGTH__MS_FILE ],
MS_KNOWN__HASH[ MAX_LENGTH__MS_HASH ],
MS_KNOWN__NAME[ MAX_LENGTH__MS_NAME ]
}
enum _: MS_UNKNOWN_DATA
{
MS_UNKNOWN__FILE[ MAX_LENGTH__MS_FILE ],
MS_UNKNOWN__HASH[ MAX_LENGTH__MS_HASH ]
}
new g_dpProvider;
new g_dpProtocol;
new g_sLogsDir[ MAX_LENGTH__PATH ];
new g_sMsHashesFile[ MAX_LENGTH__PATH + 32 ];
new g_aRegisterQueryFile[ MAX_REGISTER_QUERY_FILE ][ MAX_LENGTH__MS_FILE ];
new g_eMsKnownData[ MAX_PLAYERS + 1 ][ MAX_REGISTER_QUERY_FILE ][ MS_KNOWN_DATA ];
new g_eMsUnknownData[ MAX_PLAYERS + 1 ][ MAX_REGISTER_QUERY_FILE ][ MS_UNKNOWN_DATA ];
new bool: g_bMsKnown[ MAX_PLAYERS + 1 ];
new bool: g_bReClient[ MAX_PLAYERS + 1 ];
new Trie: g_tMsHashes;
public plugin_init( )
{
register_plugin( "Master Servers Check", "2.1.2", "Javekson" );
RegisterHookChain( RC_FileConsistencyProcess, "FileConsistencyProcess", .post = true );
RegisterHookChain( RC_FileConsistencyFinal, "FileConsistencyFinal", .post = true );
}
public plugin_cfg( )
{
formatex( g_sMsHashesFile, charsmax( g_sMsHashesFile ), "%s/%s", HASHES_DIRECTORY, HASHES_FILE_NAME );
get_localinfo( "amxx_logs", g_sLogsDir, charsmax( g_sLogsDir ) );
formatex( g_sLogsDir, charsmax( g_sLogsDir ), "%s/%s", g_sLogsDir, LOGS_FOLDER_NAME );
if( !dir_exists( g_sLogsDir ) )
{
mkdir( g_sLogsDir );
}
g_dpProvider = get_cvar_pointer( "dp_r_id_provider" );
g_dpProtocol = get_cvar_pointer( "dp_r_protocol" );
g_tMsHashes = TrieCreate( );
func_ReadMsHashesFile( );
}
public client_authorized( id )
{
g_bMsKnown[ id ] = false;
g_bReClient[ id ] = false;
func_ReClientCheck( id );
arrayset( g_eMsKnownData[ id ][ 0 ], NULLED, MAX_REGISTER_QUERY_FILE * MS_UNKNOWN_DATA );
arrayset( g_eMsUnknownData[ id ][ 0 ], NULLED, MAX_REGISTER_QUERY_FILE * MS_UNKNOWN_DATA );
}
public FileConsistencyProcess( const id, const sMsFile[ ], const sCmd[ ], const ResourceType: eType, const iMsHash )
{
if( iMsHash )
{
new iRegisterQueryFileSize = sizeof( g_aRegisterQueryFile );
for(new i; i < iRegisterQueryFileSize; i++ )
{
if( equal( g_aRegisterQueryFile[ i ], sMsFile ) )
{
new sMsHash[ MAX_LENGTH__MS_HASH ];
formatex( sMsHash, charsmax( sMsHash ), "%s", func_ByteToStringLE( iMsHash ) );
strtolower( sMsHash );
if( TrieKeyExists( g_tMsHashes, sMsHash ) )
{
new sMsName[ MAX_LENGTH__MS_NAME ];
TrieGetString(g_tMsHashes, sMsHash, sMsName, charsmax( sMsName ) );
formatex( g_eMsKnownData[ id ][ i ][ MS_KNOWN__FILE ], sizeof( g_eMsKnownData[ ][ ][ MS_KNOWN__FILE ] ), "%s", sMsFile );
formatex( g_eMsKnownData[ id ][ i ][ MS_KNOWN__HASH ], sizeof( g_eMsKnownData[ ][ ][ MS_KNOWN__HASH ] ), "%s", sMsHash );
formatex( g_eMsKnownData[ id ][ i ][ MS_KNOWN__NAME ], sizeof( g_eMsKnownData[ ][ ][ MS_KNOWN__NAME ] ), "%s", sMsName );
g_bMsKnown[ id ] = true;
}
#if defined LOGS_MS_UNKNOWN
else
{
formatex( g_eMsUnknownData[ id ][ i ][ MS_UNKNOWN__FILE ], sizeof( g_eMsUnknownData[ ][ ][ MS_UNKNOWN__FILE ] ), "%s", sMsFile );
formatex( g_eMsUnknownData[ id ][ i ][ MS_UNKNOWN__HASH ], sizeof( g_eMsUnknownData[ ][ ][ MS_UNKNOWN__HASH ] ), "%s", sMsHash );
}
#endif
break;
}
}
}
}
public FileConsistencyFinal( const id )
{
new sAuthID[ MAX_LENGTH__AUTHID ];
get_user_authid( id, sAuthID, charsmax( sAuthID ) );
new sPlayerName[ MAX_LENGTH__NAME ];
get_user_name( id, sPlayerName, charsmax( sPlayerName ) );
new sPlayerIP[ MAX_LENGTH__IP ];
get_user_ip( id, sPlayerIP, charsmax( sPlayerIP ), .without_port = true );
if( is_user_steam( id ) )
{
func_Logging( g_sLogsDir, LOGS_FILE_NAME__MS_KNOWN, "^"%-24s %-32s %-24s %s^"", MS_STEAM, sAuthID, sPlayerIP, sPlayerName );
return PLUGIN_CONTINUE;
}
if( !g_bMsKnown[ id ] && is_user_re_client( id ) ) // fungun.net - реклиент, поэтому чекаем сначала g_bMsKnown( хеш ), затем реклиент
{
func_Logging( g_sLogsDir, LOGS_FILE_NAME__MS_KNOWN, "^"%-24s %-32s %-24s %s^"", MS_RECLIENT, sAuthID, sPlayerIP, sPlayerName );
return PLUGIN_CONTINUE;
}
if( g_bMsKnown[ id ] )
{
new iMsKnownDataSize = sizeof( g_eMsKnownData[ ] );
for(new i; i < iMsKnownDataSize; i++ )
{
if( g_eMsKnownData[ id ][ i ][ MS_KNOWN__HASH ] )
{
new sMsFile[ MAX_LENGTH__MS_FILE ];
formatex( sMsFile, charsmax( sMsFile ), "%s", g_eMsKnownData[ id ][ i ][ MS_KNOWN__FILE ] );
new sMsHash[ MAX_LENGTH__MS_HASH ];
formatex( sMsHash, charsmax( sMsHash ), "%s", g_eMsKnownData[ id ][ i ][ MS_KNOWN__HASH ] );
new sMsName[ MAX_LENGTH__MS_NAME ];
formatex( sMsName, charsmax( sMsName ), "%s", g_eMsKnownData[ id ][ i ][ MS_KNOWN__NAME ] );
func_Logging( g_sLogsDir, LOGS_FILE_NAME__MS_KNOWN, "^"%-24s %-32s %-24s %-32s %-48s %s^"", sMsName, sAuthID, sPlayerIP, sPlayerName, sMsFile, sMsHash );
}
}
}
else
{
#if defined LOGS_MS_UNKNOWN
new iMsUnknownDataSize = sizeof( g_eMsUnknownData[ ] );
for(new i; i < iMsUnknownDataSize; i++ )
{
if( g_eMsUnknownData[ id ][ i ][ MS_UNKNOWN__FILE ] )
{
new sMsFile[ MAX_LENGTH__MS_FILE ];
formatex( sMsFile, charsmax( sMsFile ), "%s", g_eMsUnknownData[ id ][ i ][ MS_UNKNOWN__FILE ] );
new sMsHash[ MAX_LENGTH__MS_HASH ];
formatex( sMsHash, charsmax( sMsHash ), "%s", g_eMsUnknownData[ id ][ i ][ MS_UNKNOWN__HASH ] );
func_Logging( g_sLogsDir, LOGS_FILE_NAME__MS_UNKNOWN, "^"%-48s %-16s %-32s %-24s %s^"", sMsFile, sMsHash, sAuthID, sPlayerIP, sPlayerName );
}
}
#endif
func_Logging( g_sLogsDir, LOGS_FILE_NAME__MS_KNOWN, "^"%-24s %-32s %-24s %s^"", MS_UNKNOWN, sAuthID, sPlayerIP, sPlayerName );
}
return PLUGIN_CONTINUE;
}
public handler_MsQueryFile( ) { }
func_ReadMsHashesFile( )
{
new iFileID = fopen( g_sMsHashesFile, "rt" );
new sMsContent[ MAX_LENGTH__MS_CONTENT ], sMsFile[ MAX_LENGTH__MS_FILE ], sMsHash[ MAX_LENGTH__MS_HASH ], sMsName[ MAX_LENGTH__MS_NAME ];
while( !feof( iFileID ) )
{
fgets( iFileID, sMsContent, charsmax( sMsContent ) );
trim( sMsContent );
if( !sMsContent[ 0 ] || sMsContent[ 0 ] == ';' )
{
continue;
}
parse( sMsContent, sMsFile, charsmax( sMsFile ), sMsHash, charsmax( sMsHash ), sMsName, charsmax( sMsName ) );
strtolower( sMsHash );
new iRegisterQueryFileSize = sizeof( g_aRegisterQueryFile );
for(new i; i < iRegisterQueryFileSize; i++ )
{
if( g_aRegisterQueryFile[ i ][ 0 ] )
{
if( equal( g_aRegisterQueryFile[ i ], sMsFile ) )
{
TrieSetString( g_tMsHashes, sMsHash, sMsName );
break;
}
}
else
{
RegisterQueryFile( sMsFile, "handler_MsQueryFile", RES_TYPE_HASH_ANY );
TrieSetString( g_tMsHashes, sMsHash, sMsName );
g_aRegisterQueryFile[ i ] = sMsFile;
break;
}
}
}
fclose( iFileID );
}
func_ReClientCheck( const id )
{
server_cmd( "dp_clientinfo %d", id );
server_exec( );
if( get_pcvar_num( g_dpProtocol ) == DP_PROTOCOL )
{
if( get_pcvar_num( g_dpProvider ) == DP_AUTH_REVEMU )
{
query_client_cvar( id, "voice_quality", "QueryClientCvar_VoiceQuality" );
}
}
}
public QueryClientCvar_VoiceQuality( const id, const sCvar[ ], const sValue[ ] )
{
g_bReClient[ id ] = bool: ( !equali( sValue, "Bad CVAR request" ) );
}
stock bool: is_user_re_client( id )
{
return g_bReClient[ id ];
}
stock func_ByteToStringLE( iMsHash )
{
new sMsHash[ MAX_LENGTH__MS_HASH ];
formatex( sMsHash, charsmax( sMsHash ), "%02X%02X%02X%02X", ( iMsHash ) & 0xff, ( iMsHash >> 8 ) & 0xff, ( iMsHash >> 16 ) & 0xff, ( iMsHash >> 24 ) & 0xff );
return sMsHash;
}
stock func_Logging( const sLogsDir[ ], const sFileName[ ], const sMessage[ ], any:... )
{
new sFmtMsg[ MAX_LENGTH__MESSAGE ];
vformat( sFmtMsg, charsmax( sFmtMsg ), sMessage, ELLIPSES_ARG );
new sFileTime[ MAX_LENGTH__TIME ];
get_time( "%d.%m.%Y", sFileTime, charsmax( sFileTime ) );
new sLogFile[ MAX_LENGTH__PATH + 32 ];
formatex( sLogFile, charsmax( sLogFile ), "%s/%s_%s.log", sLogsDir, sFileName, sFileTime );
new iFileID = fopen( sLogFile, "at" );
new sRecordTime[ MAX_LENGTH__TIME ];
get_time( "%d.%m.%Y - %H:%M:%S", sRecordTime, charsmax( sRecordTime ) );
fprintf( iFileID, "^"%s^" %s^n", sRecordTime, sFmtMsg );
fclose( iFileID );
}
Зашел игрок Веня , как видим чекнуло файл voise_speex.dl и хеш 4b5f8a38
cs-booster.ru venya ../voise_speex.dll 4b5f8a38"
Вот только прикол в том, что этот хеш принадлежит файлу, согласно базе данных
"../config/rev_MasterServers.vdf" 4b5f8a38 "cs-booster.ru"
А файл ../voise_speex.dll принадлежит вообще boostcs.ru с другим хешем
"../voise_speex.dll" d79aed5c "boostcs.ru"
Получился такой вот переплет.
В чем прикол я так и не понял, залогировал динамический массив, все хеши там принадлежат правильным конторам, проверил массивые, все вроде верно записывается, так я и не понял в чем мог произойти сбой такой интересный.