-
Posts
28 -
Joined
-
Last visited
-
Feedback
0%
About KoMaR1911

Informations
-
Gender
Male
-
Country
Poland
-
Nationality
Polish
Development
- Github
Recent Profile Visitors
7329 profile views
KoMaR1911's Achievements
-
I mean i dont modify gr2 files and yeah vertex i handle that in c++ directly i check bone count at runtime if it fits registers i use gpu if not i fallback to cpu i remap them in memory (GetDefaultBoneIndices) from local to global ids before uploading to vb so it works out of the box for standard assets
-
hi i was working on my packing system that will be secure and fast and it was main challenge i used XXH3 and SSE2/AVX2 functions for decrypting keys inside my pack system VFS and for security features and decided to make LRU Cache system for smaller files than 1-2 MBs i was making client unpacks in past so i knew where was weak points inside all VFS in this game and i made it far better than standard EterPack / FoxFS Here is presentation how it works in game on clean martysama source yeah i know it uses more ram than standard eterpack/foxfs but its not bug thats how LRU Cache works https://streamable.com/0b3br5 how my PackMaker looks like: If you have any sugestions what to add im open
-
- 2
-
-
-
Hello due to i was working on optimalization and my new pack system with xxh3 hash and LRU cache system (after first files load i can use this files directly from RAM so its far faster than getting every 1 file who was small from disc) on 1 pserver i decided to recode a lot of c++98 code in Metin2 but when i looked at TextFileLoader i got terrified so... i decided to fix all bugs and do recode there was a lot of "possible" bugs in TextFileLoader from my test that seems to be 5-8x times faster and far more stable my limitations was to dont change structure (if i will change structure ofc it will be far better but i want to dont recode whole game) so its ready to copy and paste in c++20 u can do more but its not needed with that version (only if u want +5-10% faster) if you finds any bugs post it here i will try to fix it and send here TextFileLoader.h #pragma once #include "../eterBase/FileLoader.h" #include "../eterBase/MappedFile.h" #include "../eterLib/Util.h" #include "../eterLib/Pool.h" class CTextFileLoader { public: typedef struct SGroupNode { static DWORD GenNameKey(const char* c_szGroupName, size_t uGroupNameLen); static DWORD GenNameKey(std::string_view sv); void SetGroupName(const std::string& c_rstGroupName); bool IsGroupNameKey(DWORD dwGroupNameKey); const std::string& GetGroupName(); CTokenVector* GetTokenVector(DWORD dwGroupNameKey); CTokenVector* GetTokenVector(const std::string& c_rstGroupName); bool IsExistTokenVector(DWORD dwGroupNameKey); bool IsExistTokenVector(const std::string& c_rstGroupName); void InsertTokenVector(const std::string& c_rstGroupName, const CTokenVector& c_rkVct_stToken); DWORD m_dwGroupNameKey; std::string m_strGroupName; std::map < DWORD, CTokenVector > m_kMap_dwKey_kVct_stToken; SGroupNode* pParentNode; std::vector < SGroupNode* > ChildNodeVector; static SGroupNode* New(); static void Delete(SGroupNode* pkNode); static void DestroySystem(); static CDynamicPool < SGroupNode > ms_kPool; } TGroupNode; typedef std::vector < TGroupNode* > TGroupNodeVector; class CGotoChild { public: CGotoChild(CTextFileLoader* pOwner, const char* c_szKey) : m_pOwner(pOwner) { m_pOwner->SetChildNode(c_szKey); } CGotoChild(CTextFileLoader* pOwner, DWORD dwIndex) : m_pOwner(pOwner) { m_pOwner->SetChildNode(dwIndex); } ~CGotoChild() { m_pOwner->SetParentNode(); } CTextFileLoader* m_pOwner; }; public: static void DestroySystem(); static void SetCacheMode(); static CTextFileLoader* Cache(const char* c_szFileName); public: CTextFileLoader(); virtual~CTextFileLoader(); void Destroy(); bool Load(const char* c_szFileName); const char* GetFileName(); bool IsEmpty(); void SetTop() { m_pcurNode = &m_GlobalNode; } DWORD GetChildNodeCount() { if (!m_pcurNode) return 0; return (DWORD)m_pcurNode->ChildNodeVector.size(); } BOOL SetChildNode(const char* c_szKey) { if (!m_pcurNode) return FALSE; DWORD dwKey = SGroupNode::GenNameKey(c_szKey, strlen(c_szKey)); for (TGroupNode* node : m_pcurNode->ChildNodeVector) { if (node->IsGroupNameKey(dwKey)) { m_pcurNode = node; return TRUE; } } return FALSE; } BOOL SetChildNode(DWORD dwIndex) { if (!m_pcurNode) return FALSE; if (dwIndex >= m_pcurNode->ChildNodeVector.size()) return FALSE; m_pcurNode = m_pcurNode->ChildNodeVector[dwIndex]; return TRUE; } BOOL SetChildNode(const std::string& c_rstrKeyHead, DWORD dwIndex); BOOL SetParentNode() { if (!m_pcurNode || !m_pcurNode->pParentNode) return FALSE; m_pcurNode = m_pcurNode->pParentNode; return TRUE; } BOOL GetCurrentNodeName(std::string* pstrName) { if (!m_pcurNode) return FALSE; *pstrName = m_pcurNode->GetGroupName(); return TRUE; } BOOL IsToken(const char* c_szKey) { if (!m_pcurNode) return FALSE; return m_pcurNode->IsExistTokenVector(SGroupNode::GenNameKey(c_szKey, strlen(c_szKey))); } BOOL IsToken(const std::string& c_rstrKey) { if (!m_pcurNode) return FALSE; return m_pcurNode->IsExistTokenVector(c_rstrKey); } BOOL GetTokenVector(const char* c_szKey, CTokenVector** ppTokenVector) { if (!m_pcurNode) return FALSE; CTokenVector* pkRet = m_pcurNode->GetTokenVector(SGroupNode::GenNameKey(c_szKey, strlen(c_szKey))); if (!pkRet) return FALSE; *ppTokenVector = pkRet; return TRUE; } BOOL GetTokenVector(const std::string& c_rstrKey, CTokenVector** ppTokenVector) { if (!m_pcurNode) return FALSE; CTokenVector* pkRet = m_pcurNode->GetTokenVector(c_rstrKey); if (!pkRet) return FALSE; *ppTokenVector = pkRet; return TRUE; } BOOL GetTokenBoolean(const char* c_szKey, BOOL* pData); BOOL GetTokenByte(const char* c_szKey, BYTE* pData); BOOL GetTokenWord(const char* c_szKey, WORD* pData); BOOL GetTokenInteger(const char* c_szKey, int* pData); BOOL GetTokenDoubleWord(const char* c_szKey, DWORD* pData); BOOL GetTokenFloat(const char* c_szKey, float* pData); BOOL GetTokenBoolean(const std::string& c_rstrKey, BOOL* pData); BOOL GetTokenByte(const std::string& c_rstrKey, BYTE* pData); BOOL GetTokenWord(const std::string& c_rstrKey, WORD* pData); BOOL GetTokenInteger(const std::string& c_rstrKey, int* pData); BOOL GetTokenDoubleWord(const std::string& c_rstrKey, DWORD* pData); BOOL GetTokenFloat(const std::string& c_rstrKey, float* pData); BOOL GetTokenVector2(const char* c_szKey, D3DXVECTOR2* pVector2); BOOL GetTokenVector3(const char* c_szKey, D3DXVECTOR3* pVector3); BOOL GetTokenVector4(const char* c_szKey, D3DXVECTOR4* pVector4); BOOL GetTokenPosition(const char* c_szKey, D3DXVECTOR3* pVector); BOOL GetTokenQuaternion(const char* c_szKey, D3DXQUATERNION* pQ); BOOL GetTokenDirection(const char* c_szKey, D3DVECTOR* pVector); BOOL GetTokenColor(const char* c_szKey, D3DXCOLOR* pColor); BOOL GetTokenColor(const char* c_szKey, D3DCOLORVALUE* pColor); BOOL GetTokenString(const char* c_szKey, std::string* pString); BOOL GetTokenVector2(const std::string& k, D3DXVECTOR2* v) { return GetTokenVector2(k.c_str(), v); } BOOL GetTokenVector3(const std::string& k, D3DXVECTOR3* v) { return GetTokenVector3(k.c_str(), v); } BOOL GetTokenVector4(const std::string& k, D3DXVECTOR4* v) { return GetTokenVector4(k.c_str(), v); } BOOL GetTokenPosition(const std::string& k, D3DXVECTOR3* v) { return GetTokenPosition(k.c_str(), v); } BOOL GetTokenQuaternion(const std::string& k, D3DXQUATERNION* q) { return GetTokenQuaternion(k.c_str(), q); } BOOL GetTokenDirection(const std::string& k, D3DVECTOR* v) { return GetTokenDirection(k.c_str(), v); } BOOL GetTokenColor(const std::string& k, D3DXCOLOR* c) { return GetTokenColor(k.c_str(), c); } BOOL GetTokenColor(const std::string& k, D3DCOLORVALUE* c) { return GetTokenColor(k.c_str(), c); } BOOL GetTokenString(const std::string& k, std::string* s) { return GetTokenString(k.c_str(), s); } protected: void __DestroyGroupNodeVector(); bool LoadGroup(TGroupNode* pGroupNode); protected: std::string m_strFileName; std::unique_ptr < char[] > m_acBufData; DWORD m_dwBufSize; DWORD m_dwBufCapacity; DWORD m_dwcurLineIndex; CMemoryTextFileLoader m_textFileLoader; TGroupNode m_GlobalNode; TGroupNode* m_pcurNode; std::vector < SGroupNode* > m_kVct_pkNode; protected: static std::map < DWORD, CTextFileLoader* > ms_kMap_dwNameKey_pkTextFileLoader; static bool ms_isCacheMode; }; // KoMaR1911 Recode contact: discord komar1911 TextFileLoader.cpp #include "StdAfx.h" #include "../eterBase/CRC32.h" #include "../EterPack/EterPackManager.h" #include "Pool.h" #include "TextFileLoader.h" #include <string> #include <algorithm> #include <memory> #include <vector> #include <string_view> #include <cerrno> #include <cctype> #include <cstdlib> std::map< DWORD, CTextFileLoader* > CTextFileLoader::ms_kMap_dwNameKey_pkTextFileLoader; bool CTextFileLoader::ms_isCacheMode = false; CDynamicPool< CTextFileLoader::SGroupNode > CTextFileLoader::SGroupNode::ms_kPool; static bool SafeParseFloat( const std::string& str, float* outVal ) { if ( str.empty( ) ) return false; char* end; errno = 0; *outVal = std::strtof( str.c_str( ), &end ); return ( end == str.c_str( ) + str.size( ) && errno == 0 ); } static bool SafeParseInt( const std::string& str, int* outVal ) { if ( str.empty( ) ) return false; char* end; errno = 0; *outVal = std::strtol( str.c_str( ), &end, 10 ); return ( end == str.c_str( ) + str.size( ) && errno == 0 ); } static void FastSplitLine( const char* line, size_t len, std::vector< std::string_view >& outTokens ) { outTokens.clear( ); if ( !line || len == 0 ) return; const char* ptr = line; const char* end = line + len; while ( ptr < end ) { while ( ptr < end && ( unsigned char )*ptr <= ' ' ) ++ptr; if ( ptr >= end ) break; if ( *ptr == '"' ) { ++ptr; const char* startToken = ptr; while ( ptr < end && *ptr != '"' ) ++ptr; outTokens.emplace_back( startToken, ptr - startToken ); if ( ptr < end ) ++ptr; } else { const char* startToken = ptr; while ( ptr < end && ( unsigned char )*ptr > ' ' ) ++ptr; outTokens.emplace_back( startToken, ptr - startToken ); } } } template< size_t N > static bool IsEqualLower( std::string_view sv, const char ( &literal )[N] ) { constexpr size_t len = N - 1; if ( sv.length( ) != len ) return false; for ( size_t i = 0; i < len; ++i ) { if ( std::tolower( ( unsigned char )sv[i] ) != literal[i] ) return false; } return true; } DWORD CTextFileLoader::SGroupNode::GenNameKey( const char* c_szGroupName, size_t uGroupNameLen ) { return GetCRC32( c_szGroupName, uGroupNameLen ); } DWORD CTextFileLoader::SGroupNode::GenNameKey( std::string_view sv ) { return GetCRC32( sv.data( ), sv.length( ) ); } CTokenVector* CTextFileLoader::SGroupNode::GetTokenVector( const std::string& c_rstGroupName ) { return GetTokenVector( GenNameKey( c_rstGroupName.c_str( ), c_rstGroupName.length( ) ) ); } CTokenVector* CTextFileLoader::SGroupNode::GetTokenVector( DWORD dwGroupNameKey ) { auto it = m_kMap_dwKey_kVct_stToken.find( dwGroupNameKey ); if ( it != m_kMap_dwKey_kVct_stToken.end( ) ) return &it->second; return nullptr; } bool CTextFileLoader::SGroupNode::IsExistTokenVector( const std::string& c_rstGroupName ) { return IsExistTokenVector( GenNameKey( c_rstGroupName.c_str( ), c_rstGroupName.length( ) ) ); } bool CTextFileLoader::SGroupNode::IsExistTokenVector( DWORD dwGroupNameKey ) { return m_kMap_dwKey_kVct_stToken.find( dwGroupNameKey ) != m_kMap_dwKey_kVct_stToken.end( ); } void CTextFileLoader::SGroupNode::InsertTokenVector( const std::string& c_rstGroupName, const CTokenVector& c_rkVct_stToken ) { DWORD dwGroupNameKey = GenNameKey( c_rstGroupName.c_str( ), c_rstGroupName.length( ) ); m_kMap_dwKey_kVct_stToken.emplace( dwGroupNameKey, c_rkVct_stToken ); } const std::string& CTextFileLoader::SGroupNode::GetGroupName( ) { return m_strGroupName; } bool CTextFileLoader::SGroupNode::IsGroupNameKey( DWORD dwGroupNameKey ) { return dwGroupNameKey == m_dwGroupNameKey; } void CTextFileLoader::SGroupNode::SetGroupName( const std::string& c_rstGroupName ) { m_strGroupName = c_rstGroupName; stl_lowers( m_strGroupName ); m_dwGroupNameKey = GenNameKey( m_strGroupName.c_str( ), m_strGroupName.length( ) ); } CTextFileLoader::SGroupNode* CTextFileLoader::SGroupNode::New( ) { return ms_kPool.Alloc( ); } void CTextFileLoader::SGroupNode::Delete( SGroupNode* pkNode ) { pkNode->m_kMap_dwKey_kVct_stToken.clear( ); pkNode->ChildNodeVector.clear( ); pkNode->m_strGroupName.clear( ); pkNode->m_dwGroupNameKey = 0; ms_kPool.Free( pkNode ); } void CTextFileLoader::SGroupNode::DestroySystem( ) { ms_kPool.Destroy( ); } CTextFileLoader* CTextFileLoader::Cache( const char* c_szFileName ) { DWORD dwNameKey = GetCRC32( c_szFileName, strlen( c_szFileName ) ); if ( auto f = ms_kMap_dwNameKey_pkTextFileLoader.find( dwNameKey ); f != ms_kMap_dwNameKey_pkTextFileLoader.end( ) ) { if ( !ms_isCacheMode ) { CTextFileLoader* pkNewTextFileLoader = new CTextFileLoader; if ( !pkNewTextFileLoader->Load( c_szFileName ) ) { delete pkNewTextFileLoader; f->second->SetTop( ); return f->second; } delete f->second; f->second = pkNewTextFileLoader; } f->second->SetTop( ); return f->second; } CTextFileLoader* pkNewTextFileLoader = new CTextFileLoader; if ( !pkNewTextFileLoader->Load( c_szFileName ) ) { delete pkNewTextFileLoader; return nullptr; } ms_kMap_dwNameKey_pkTextFileLoader.emplace( dwNameKey, pkNewTextFileLoader ); return pkNewTextFileLoader; } void CTextFileLoader::SetCacheMode( ) { ms_isCacheMode = true; } void CTextFileLoader::DestroySystem( ) { for ( auto& pair : ms_kMap_dwNameKey_pkTextFileLoader ) delete pair.second; ms_kMap_dwNameKey_pkTextFileLoader.clear( ); SGroupNode::DestroySystem( ); } void CTextFileLoader::Destroy( ) { __DestroyGroupNodeVector( ); m_GlobalNode.m_kMap_dwKey_kVct_stToken.clear( ); m_GlobalNode.ChildNodeVector.clear( ); } CTextFileLoader::CTextFileLoader( ) { m_GlobalNode.m_strGroupName = "global"; m_GlobalNode.pParentNode = nullptr; SetTop( ); m_dwBufSize = 0; m_dwBufCapacity = 0; m_kVct_pkNode.reserve( 128 ); } CTextFileLoader::~CTextFileLoader( ) { Destroy( ); } void CTextFileLoader::__DestroyGroupNodeVector( ) { for ( auto* node : m_kVct_pkNode ) SGroupNode::Delete( node ); m_kVct_pkNode.clear( ); } const char* CTextFileLoader::GetFileName( ) { return m_strFileName.c_str( ); } bool CTextFileLoader::IsEmpty( ) { return m_strFileName.empty( ); } bool CTextFileLoader::Load( const char* c_szFileName ) { __DestroyGroupNodeVector( ); m_GlobalNode.m_kMap_dwKey_kVct_stToken.clear( ); m_GlobalNode.ChildNodeVector.clear( ); m_strFileName.clear( ); CMappedFile kFile; LPCVOID pData = nullptr; if ( !CEterPackManager::Instance( ).Get( kFile, c_szFileName, &pData ) ) return false; m_dwBufSize = kFile.Size( ); if ( m_dwBufCapacity < m_dwBufSize ) { m_dwBufCapacity = m_dwBufSize; m_acBufData = std::make_unique< char[] >( m_dwBufCapacity ); } if ( m_dwBufSize > 0 && pData != nullptr ) { memcpy( m_acBufData.get( ), pData, m_dwBufSize ); } else { TraceError( "CTextFileLoader::Load: File %s found but empty", c_szFileName ); return false; } m_strFileName = c_szFileName; m_dwcurLineIndex = 0; m_textFileLoader.Bind( m_dwBufSize, m_acBufData.get( ) ); return LoadGroup( &m_GlobalNode ); } bool CTextFileLoader::LoadGroup( TGroupNode* pGroupNode ) { std::vector< std::string_view > tokens; tokens.reserve( 32 ); CTokenVector stTempValues; stTempValues.reserve( 32 ); int nLocalGroupDepth = 0; DWORD lineCount = m_textFileLoader.GetLineCount( ); for ( ; m_dwcurLineIndex < lineCount; ++m_dwcurLineIndex ) { const std::string& lineStr = m_textFileLoader.GetLineString( m_dwcurLineIndex ); if ( lineStr.empty( ) ) continue; FastSplitLine( lineStr.c_str( ), lineStr.length( ), tokens ); if ( tokens.empty( ) ) continue; std::string_view keyToken = tokens[0]; if ( keyToken.empty( ) ) continue; if ( keyToken[0] == '{' ) { nLocalGroupDepth++; continue; } if ( keyToken[0] == '}' ) { nLocalGroupDepth--; break; } if ( IsEqualLower( keyToken, "group" ) ) { if ( tokens.size( ) < 2 ) { TraceError( "CTextFileLoader::LoadGroup: Missing group name in %s:%u", m_strFileName.c_str( ), m_dwcurLineIndex ); continue; } TGroupNode* pNewNode = TGroupNode::New( ); pNewNode->pParentNode = pGroupNode; pNewNode->SetGroupName( std::string( tokens[1] ) ); ++m_dwcurLineIndex; if ( !LoadGroup( pNewNode ) ) { TGroupNode::Delete( pNewNode ); return false; } m_kVct_pkNode.push_back( pNewNode ); pGroupNode->ChildNodeVector.push_back( pNewNode ); } else if ( IsEqualLower( keyToken, "list" ) ) { if ( tokens.size( ) < 2 ) { TraceError( "CTextFileLoader::LoadGroup: Missing list name in %s:%u", m_strFileName.c_str( ), m_dwcurLineIndex ); continue; } std::string listKey( tokens[1] ); stl_lowers( listKey ); stTempValues.clear( ); ++m_dwcurLineIndex; for ( ; m_dwcurLineIndex < lineCount; ++m_dwcurLineIndex ) { const std::string& subLineStr = m_textFileLoader.GetLineString( m_dwcurLineIndex ); FastSplitLine( subLineStr.c_str( ), subLineStr.length( ), tokens ); if ( tokens.empty( ) ) continue; char firstChar = tokens[0][0]; if ( firstChar == '{' ) continue; if ( firstChar == '}' ) break; for ( auto& sv : tokens ) stTempValues.emplace_back( sv ); } pGroupNode->InsertTokenVector( listKey, stTempValues ); } else { if ( tokens.size( ) < 2 ) continue; stTempValues.clear( ); for ( size_t i = 1; i < tokens.size( ); ++i ) stTempValues.emplace_back( tokens[i] ); std::string keyStr( keyToken ); stl_lowers( keyStr ); pGroupNode->InsertTokenVector( keyStr, stTempValues ); } } return ( nLocalGroupDepth == 0 ); } BOOL CTextFileLoader::SetChildNode( const std::string& c_rstrKeyHead, DWORD dwIndex ) { char szKey[64]; _snprintf( szKey, sizeof( szKey ), "%s%02u", c_rstrKeyHead.c_str( ), dwIndex ); return SetChildNode( szKey ); } BOOL CTextFileLoader::GetTokenBoolean( const char* c_szKey, BOOL* pData ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->empty( ) ) return FALSE; int val; if ( SafeParseInt( pTokenVector->at( 0 ), &val ) ) { *pData = ( val != 0 ); return TRUE; } return FALSE; } BOOL CTextFileLoader::GetTokenByte( const char* c_szKey, BYTE* pData ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->empty( ) ) return FALSE; int val; if ( SafeParseInt( pTokenVector->at( 0 ), &val ) ) { *pData = ( BYTE )val; return TRUE; } return FALSE; } BOOL CTextFileLoader::GetTokenWord( const char* c_szKey, WORD* pData ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->empty( ) ) return FALSE; int val; if ( SafeParseInt( pTokenVector->at( 0 ), &val ) ) { *pData = ( WORD )val; return TRUE; } return FALSE; } BOOL CTextFileLoader::GetTokenInteger( const char* c_szKey, int* pData ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->empty( ) ) return FALSE; return SafeParseInt( pTokenVector->at( 0 ), pData ); } BOOL CTextFileLoader::GetTokenDoubleWord( const char* c_szKey, DWORD* pData ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->empty( ) ) return FALSE; int val; if ( SafeParseInt( pTokenVector->at( 0 ), &val ) ) { *pData = ( DWORD )val; return TRUE; } return FALSE; } BOOL CTextFileLoader::GetTokenFloat( const char* c_szKey, float* pData ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->empty( ) ) return FALSE; return SafeParseFloat( pTokenVector->at( 0 ), pData ); } BOOL CTextFileLoader::GetTokenBoolean( const std::string& c_rstrKey, BOOL* pData ) { return GetTokenBoolean( c_rstrKey.c_str( ), pData ); } BOOL CTextFileLoader::GetTokenByte( const std::string& c_rstrKey, BYTE* pData ) { return GetTokenByte( c_rstrKey.c_str( ), pData ); } BOOL CTextFileLoader::GetTokenWord( const std::string& c_rstrKey, WORD* pData ) { return GetTokenWord( c_rstrKey.c_str( ), pData ); } BOOL CTextFileLoader::GetTokenInteger( const std::string& c_rstrKey, int* pData ) { return GetTokenInteger( c_rstrKey.c_str( ), pData ); } BOOL CTextFileLoader::GetTokenDoubleWord( const std::string& c_rstrKey, DWORD* pData ) { return GetTokenDoubleWord( c_rstrKey.c_str( ), pData ); } BOOL CTextFileLoader::GetTokenFloat( const std::string& c_rstrKey, float* pData ) { return GetTokenFloat( c_rstrKey.c_str( ), pData ); } BOOL CTextFileLoader::GetTokenVector2( const char* c_szKey, D3DXVECTOR2* pVector2 ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->size( ) != 2 ) return FALSE; if ( !SafeParseFloat( pTokenVector->at( 0 ), &pVector2->x ) || !SafeParseFloat( pTokenVector->at( 1 ), &pVector2->y ) ) return FALSE; return TRUE; } BOOL CTextFileLoader::GetTokenVector3( const char* c_szKey, D3DXVECTOR3* pVector3 ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->size( ) != 3 ) return FALSE; if ( !SafeParseFloat( pTokenVector->at( 0 ), &pVector3->x ) || !SafeParseFloat( pTokenVector->at( 1 ), &pVector3->y ) || !SafeParseFloat( pTokenVector->at( 2 ), &pVector3->z ) ) return FALSE; return TRUE; } BOOL CTextFileLoader::GetTokenVector4( const char* c_szKey, D3DXVECTOR4* pVector4 ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->size( ) != 4 ) return FALSE; if ( !SafeParseFloat( pTokenVector->at( 0 ), &pVector4->x ) || !SafeParseFloat( pTokenVector->at( 1 ), &pVector4->y ) || !SafeParseFloat( pTokenVector->at( 2 ), &pVector4->z ) || !SafeParseFloat( pTokenVector->at( 3 ), &pVector4->w ) ) return FALSE; return TRUE; } BOOL CTextFileLoader::GetTokenPosition( const char* c_szKey, D3DXVECTOR3* pVector ) { return GetTokenVector3( c_szKey, pVector ); } BOOL CTextFileLoader::GetTokenQuaternion( const char* c_szKey, D3DXQUATERNION* pQ ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->size( ) != 4 ) return FALSE; if ( !SafeParseFloat( pTokenVector->at( 0 ), &pQ->x ) || !SafeParseFloat( pTokenVector->at( 1 ), &pQ->y ) || !SafeParseFloat( pTokenVector->at( 2 ), &pQ->z ) || !SafeParseFloat( pTokenVector->at( 3 ), &pQ->w ) ) return FALSE; return TRUE; } BOOL CTextFileLoader::GetTokenDirection( const char* c_szKey, D3DVECTOR* pVector ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->size( ) != 3 ) return FALSE; if ( !SafeParseFloat( pTokenVector->at( 0 ), &pVector->x ) || !SafeParseFloat( pTokenVector->at( 1 ), &pVector->y ) || !SafeParseFloat( pTokenVector->at( 2 ), &pVector->z ) ) return FALSE; return TRUE; } BOOL CTextFileLoader::GetTokenColor( const char* c_szKey, D3DXCOLOR* pColor ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->size( ) != 4 ) return FALSE; if ( !SafeParseFloat( pTokenVector->at( 0 ), &pColor->r ) || !SafeParseFloat( pTokenVector->at( 1 ), &pColor->g ) || !SafeParseFloat( pTokenVector->at( 2 ), &pColor->b ) || !SafeParseFloat( pTokenVector->at( 3 ), &pColor->a ) ) return FALSE; return TRUE; } BOOL CTextFileLoader::GetTokenColor( const char* c_szKey, D3DCOLORVALUE* pColor ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->size( ) != 4 ) return FALSE; if ( !SafeParseFloat( pTokenVector->at( 0 ), &pColor->r ) || !SafeParseFloat( pTokenVector->at( 1 ), &pColor->g ) || !SafeParseFloat( pTokenVector->at( 2 ), &pColor->b ) || !SafeParseFloat( pTokenVector->at( 3 ), &pColor->a ) ) return FALSE; return TRUE; } BOOL CTextFileLoader::GetTokenString( const char* c_szKey, std::string* pString ) { CTokenVector* pTokenVector; if ( !GetTokenVector( c_szKey, &pTokenVector ) ) return FALSE; if ( pTokenVector->empty( ) ) return FALSE; *pString = pTokenVector->at( 0 ); return TRUE; } // KoMaR1911 Recode contact: discord komar1911 //credits @ martysama0134 - based on his source
-
- 12
-
-
-
-
-
[Hidden Content] Here is dx8 implementation for imgui for dx8
- 12 replies
-
- 16
-
-
-
-
-
thats a complete misunderstanding of how cheats work now XD you think cheat devs still hardcode offsets and cry when you change a struct? maybe in 2005 today every good cheat just uses pattern scanning to find what it needs they find the function then use something like zydis/capstone to literally read the machine code and pull the offset out automatically your struct change does nothing the signature is the same the whole process takes a millisecond when the cheat loads or even faster cheat dev sees your patch he dumps the player class from memory into ReClass.NET and it spits out a ready to use c++ header he copy pastes and compiles and its done in 2-5 minutes you spend hours updating and testing he runs a script X D youre losing this race before you even start and the real point is YOU DONT DETECT ANYONE you just break the cheat for a bit no ban no consequences they just wait for an update so stop pushing these dead ideas from 15 years ago its a waste of everyone's time XDD
-
i analysed cshield many times and in my opinion this "AC" is weak if someone really knows whats he is doing it can be 5/10 against some biggests cheats but this have problems too with detecting all of these biggest cheats and please dont tell people to make their own AC if they are not cheat developers / dont have 5+ years exp. in C++/RE because it always end bad and project with FindWindow / search strings in memory starts XDD " i need something better, to block every cheat on the market" - is impossible there is a some of cheats with small user-bases (1-100 users) / slots
-
KoMaR1911 started following [Source] Detect Macros and Pixel Bots using Keyboard / Mouse_event
-
Macro Detector for Metin2 (Mouse and Keyboard) GitHub: [Hidden Content] M2DL: [Hidden Content] Please read readme.md on Github PLEASE DONT BAN PEOPLE AFTER DETECTION! VERIFY MANUAL THAT PLAYER IS CHEATING! Sometimes it can do false positives from Mouse / Keyboard software (but 90% of them do it from their Kernel Driver) add in UserInterface.cpp #include "Detect.h" in Main HANDLE hThread = CreateThread(nullptr, 0, hookThread, nullptr, 0, nullptr); if (hThread) { CloseHandle(hThread); }
-
- 112
-
-
-
-
-
Metin2 Cheat Python Dumper - PyRun_SimpleStringFlags
KoMaR1911 replied to KoMaR1911's topic in Tools & Programs
Sometimes pattern is different (when someone use for example optimalization or different compiler than visual studio) 1. Start IDA Pro then install Sig Maker to IDA Pro 2. check how PyRun_SimpleStringFlags looks for example on github [Hidden Content] as you can see function PyRun_SimpleStringFlags have string "__main__" and 1 function upper (PyRun_SimpleFileExFlags) "python: Can't reopen .pyc file\n" 3. find "python: Can't reopen .pyc file\n" 4. skip this function and go to next function new functions in 90% starts with PUSH ebp MOV ebp, esp (i know sometimes its different but im trying to explain it for newbies only!!!) 5. if next functions have string "__main__" probably its your PyRun_SimpleStringFlags 6. Make new pattern and paste it to source i dont know how to explain it better for people who don't have any experience with Reverse Engineering so if you have any questions how to do it just ask ?- 11 replies
-
- 84
-
-
-
-
-
-
-
-
-
-
-
-
-
Metin2 Cheat Python Dumper - PyRun_SimpleStringFlags
KoMaR1911 replied to KoMaR1911's topic in Tools & Programs
16.09.2021 Changelog: - Added Pattern Scanner - Adder support for Static linked python27.lib in .exe! [Hidden Content]- 11 replies
-
- 101
-
-
-
-
-
-
-
-
-
-
-
-
i just post some ss from they forum "Created by RealTeam" - XD source : https://github.com/B3akers/LeagueSkinChanger it looks like the same right? they only changed title and dont added author to credits 2. Original Webiste: Metin2M**.t* Again stolen cheat without any credits if you google more u can find "they" all cheats / apps on google / github RealUI - Loader to all stolen apps if they stole app / cheat from someone website they block this website in hosts XD 200 IQ now they can say "THIS IS OUR STUFF"
- 1 reply
-
- 1
-
-
Metin2 Cheat Python Dumper - PyRun_SimpleStringFlags
KoMaR1911 replied to KoMaR1911's topic in Tools & Programs
pyrun_simplestringflags is never used by game -
Metin2 Cheat Python Dumper - PyRun_SimpleStringFlags
KoMaR1911 replied to KoMaR1911's topic in Tools & Programs
here is m2bob dump : [Hidden Content] as i see they load python everytime they want to use feature like expbot etc thats why dump is 4mb and looks like this : probably thats why m2bob crashs after 20-40 minutes XD- 11 replies
-
- 85
-
-
-
-
-
-
-
-
-
-
