Пример #1
0
// Remove base path from the start of abs path
SString SharedUtil::PathMakeRelative ( const SString& strInBasePath, const SString& strInAbsPath )
{
    SString strBasePath = PathConform ( strInBasePath );
    SString strAbsPath = PathConform ( strInAbsPath );
    if ( strAbsPath.BeginsWithI ( strBasePath ) )
    {
        return strAbsPath.SubStr ( strBasePath.length () ).TrimStart ( PATH_SEPERATOR );
    }
    return strAbsPath;
}
Пример #2
0
std::vector<SString> SharedUtil::FindFiles(const SString& strMatch, bool bFiles, bool bDirectories, bool bSortByDate)
{
    std::vector<SString>           strResult;
    std::multimap<uint64, SString> sortMap;

    DIR*           Dir;
    struct dirent* DirEntry;

    // Extract any filename matching characters
    SString strFileMatch;
    SString strSearchDirectory = PathJoin(PathConform(strMatch).SplitLeft("/", &strFileMatch, -1), "/");

    if ((Dir = opendir(strSearchDirectory)))
    {
        while ((DirEntry = readdir(Dir)) != NULL)
        {
            // Skip dotted entries
            if (strcmp(DirEntry->d_name, ".") && strcmp(DirEntry->d_name, ".."))
            {
                struct stat Info;
                bool        bIsDir = false;

                // Do wildcard matching if required
                if (!strFileMatch.empty() && !WildcardMatch(strFileMatch, DirEntry->d_name))
                {
                    continue;
                }

                SString strPath = PathJoin(strSearchDirectory, DirEntry->d_name);

                // Determine the file stats
                if (lstat(strPath, &Info) != -1)
                    bIsDir = S_ISDIR(Info.st_mode);

                if (bIsDir ? bDirectories : bFiles)
                {
                    if (bSortByDate)
                    {
                        SString     strAbsPath = strSearchDirectory + DirEntry->d_name;
                        struct stat attrib;
                        stat(strAbsPath, &attrib);
                        MapInsert(sortMap, (uint64)attrib.st_mtime, SStringX(DirEntry->d_name));
                    }
                    else
                        strResult.push_back(DirEntry->d_name);
                }
            }
        }
        closedir(Dir);
    }

    // Resolve sorted map if required
    if (!sortMap.empty())
    {
        for (std::multimap<uint64, SString>::iterator iter = sortMap.begin(); iter != sortMap.end(); ++iter)
            strResult.push_back(iter->second);
    }

    return strResult;
}
Пример #3
0
void SharedUtil::ExtractFilename ( const SString& strInPathFilename, SString* strPath, SString* strFilename )
{
    const SString strPathFilename = PathConform ( strInPathFilename );
    if ( !strPathFilename.Split ( PATH_SEPERATOR, strPath, strFilename, -1 ) )
        if ( strFilename )
            *strFilename = strPathFilename;
}
Пример #4
0
SString SharedUtil::MakeUniquePath ( const SString& strInPathFilename )
{
    const SString strPathFilename = PathConform ( strInPathFilename );

    SString strBeforeUniqueChar, strAfterUniqueChar;

    SString strPath, strFilename;
    ExtractFilename ( strPathFilename, &strPath, &strFilename );

    SString strMain, strExt;
    if ( ExtractExtension ( strFilename, &strMain, &strExt ) )
    {
        strBeforeUniqueChar = PathJoin ( strPath, strMain );
        strAfterUniqueChar = "." + strExt;
    }
    else
    {
        strBeforeUniqueChar = strPathFilename;
        strAfterUniqueChar = "";
    }

    SString strTest = strPathFilename;
    int iCount = 1;
#ifdef WIN32
    while ( GetFileAttributes ( strTest ) != INVALID_FILE_ATTRIBUTES )
#else
    while ( DirectoryExists ( strTest ) || FileExists ( strTest ) )
#endif
    {
        strTest = SString ( "%s_%d%s", strBeforeUniqueChar.c_str (), iCount++, strAfterUniqueChar.c_str () );
    }
    return strTest;
}
Пример #5
0
//
// Ensure all directories exist to the file
//
void SharedUtil::MakeSureDirExists ( const SString& strPath )
{
    std::vector < SString > parts;
    PathConform ( strPath ).Split ( PATH_SEPERATOR, parts );

    // Find first dir that already exists
    int idx = parts.size () - 1;
    for ( ; idx >= 0 ; idx-- )
    {
        SString strTemp = SString::Join ( PATH_SEPERATOR, parts, 0, idx );
        if ( DirectoryExists ( strTemp ) )
            break;        
    }

    // Make non existing dirs only
    idx++;
    for ( ; idx < (int)parts.size () ; idx++ )
    {
        SString strTemp = SString::Join ( PATH_SEPERATOR, parts, 0, idx );
        // Call mkdir on this path
        #ifdef WIN32
            mkdir ( strTemp );
        #else
            mkdir ( strTemp ,0775 );
        #endif
    }
}
Пример #6
0
SString SharedUtil::PathJoin ( const SString& str1, const SString& str2, const SString& str3, const SString& str4, const SString& str5 )
{
    SString strResult = str1 + PATH_SEPERATOR + str2 + PATH_SEPERATOR + str3;
    if ( str4.length () )
       strResult += PATH_SEPERATOR + str4; 
    if ( str5.length () )
       strResult += PATH_SEPERATOR + str5;
    return PathConform ( strResult );
}
    void DefaultResourceProvider::loadRawDataContainer(const String& filename, RawDataContainer& output, const String& resourceGroup)
    {
        if (filename.empty() || (filename == (utf8*)""))
        {
            throw InvalidRequestException((utf8*)
                "DefaultResourceProvider::load - Filename supplied for data loading must be valid");
        }


        std::wstring strFilename1 = filename.c_wstring ();
        std::wstring strFilename2 = System::getSingleton ().GetGuiWorkingDirectory().c_wstring () + strFilename1;

        // If supplied filename looks like it is absolute, try that first
        bool bIsAbsolutePath = false;
        {
            SString strTemp = PathConform ( filename.c_str () );
            if ( strTemp.Contains ( ":" ) || strTemp.BeginsWith ( "\\" ) )
                std::swap ( strFilename1, strFilename2 );
        }


        std::ifstream dataFile;
        dataFile.open(strFilename2.c_str (), std::ios::binary|std::ios::ate);

        if( dataFile.fail())
        {
            dataFile.clear();
            dataFile.open(strFilename1.c_str (), std::ios::binary|std::ios::ate);
            if( dataFile.fail())
            {
                throw InvalidRequestException((utf8*)
                    "DefaultResourceProvider::load - " + filename + " does not exist");
            }
        }
        std::streampos size = dataFile.tellg();
        dataFile.seekg (0, std::ios::beg);

        unsigned char* buffer = new unsigned char [(uint)size];

        try {
            dataFile.read(reinterpret_cast<char*>(buffer), size);
        }
        catch(std::ifstream::failure e) {
            delete [] buffer;
            throw GenericException((utf8*)
                "DefaultResourceProvider::loadRawDataContainer - Problem reading " + filename);
        }

        dataFile.close();

        //memcpy(container->getDataPtr(), buffer, size);
        output.setData(buffer);
        output.setSize((size_t)size);
        //delete [] buffer;
    }
Пример #8
0
// Return true if path is not relative
bool SharedUtil::IsAbsolutePath ( const SString& strInPath )
{
    const SString strPath = PathConform ( strInPath );

    if ( strPath.BeginsWith( PATH_SEPERATOR ) )
        return true;
#ifdef WIN32
    if ( strPath.length() > 0 && strPath[1] == ':' )
        return true;
#endif
    return false;
}
Пример #9
0
void CAccountManager::ReconnectToDatabase(void)
{
    if (m_hDbConnection != INVALID_DB_HANDLE)
    {
        m_pDatabaseManager->Disconnect(m_hDbConnection);
    }

    //Load internal.db
    SString strOptions;
#ifdef WITH_ACCOUNT_QUERY_LOGGING
    g_pGame->GetDatabaseManager ()->SetLogLevel ( EJobLogLevel::ALL, g_pGame->GetConfig ()->GetDbLogFilename () );
    SetOption < CDbOptionsMap > ( strOptions, "log", 1 );
    SetOption < CDbOptionsMap > ( strOptions, "tag", "accounts" );
#endif
    SetOption < CDbOptionsMap > ( strOptions, "queue", DB_SQLITE_QUEUE_NAME_INTERNAL );
    m_hDbConnection = m_pDatabaseManager->Connect ( "sqlite", PathConform ( m_strDbPathFilename ), "", "", strOptions );
}
Пример #10
0
///////////////////////////////////////////////////////////////
//
// FindFiles
//
// Find all files or directories at a path
// If sorted by date, returns last modified last
//
///////////////////////////////////////////////////////////////
std::vector < SString > SharedUtil::FindFiles ( const SString& strInMatch, bool bFiles, bool bDirectories, bool bSortByDate )
{
    std::vector < SString > strResult;
    std::multimap < uint64, SString > sortMap;

    SString strMatch = PathConform ( strInMatch );
    if ( strMatch.Right ( 1 ) == PATH_SEPERATOR )
        strMatch += "*";

    WIN32_FIND_DATAW findData;
    HANDLE hFind = FindFirstFileW ( FromUTF8( strMatch ), &findData );
    if( hFind != INVALID_HANDLE_VALUE )
    {
        do
        {
            if ( ( findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ? bDirectories : bFiles )
                if ( wcscmp ( findData.cFileName, L"." ) && wcscmp ( findData.cFileName, L".." ) )
                {
                    if ( bSortByDate )
                        MapInsert( sortMap, (uint64&)findData.ftLastWriteTime, ToUTF8( findData.cFileName ) );
                    else
                        strResult.push_back ( ToUTF8( findData.cFileName ) );
                }
        }
        while( FindNextFileW( hFind, &findData ) );
        FindClose( hFind );
    }

    // Resolve sorted map if required
    if ( !sortMap.empty() )
    {
        for ( std::multimap < uint64, SString >::iterator iter = sortMap.begin() ; iter != sortMap.end() ; ++iter )
            strResult.push_back ( iter->second );
    }

    return strResult;
}
Пример #11
0
// Conform a path string for sorting
SString SharedUtil::ConformPathForSorting ( const SString& strPathFilename )
{
    return PathConform ( strPathFilename ).ToLower ();
}
Пример #12
0
void CCrashDumpWriter::DumpMiniDump ( _EXCEPTION_POINTERS* pException, CExceptionInformation* pExceptionInformation )
{
    WriteDebugEvent ( "CCrashDumpWriter::DumpMiniDump" );

    // Try to load the DLL in our directory
    HMODULE hDll = NULL;
    char szDbgHelpPath [MAX_PATH];
    if ( GetModuleFileNameA ( NULL, szDbgHelpPath, MAX_PATH ) )
    {
        char* pSlash = _tcsrchr ( szDbgHelpPath, '\\' );
        if ( pSlash )
        {
            _tcscpy ( pSlash + 1, "DBGHELP.DLL" );
            hDll = LoadLibrary ( szDbgHelpPath );
        }
    }

    // If we couldn't load the one in our dir, load any version available
    if ( !hDll )
    {
        hDll = LoadLibrary( "DBGHELP.DLL" );
    }

    if ( !hDll )
        AddReportLog( 9201, "CCrashDumpWriter::DumpMiniDump - Could not load DBGHELP.DLL" );

    // We could load a dll?
    if ( hDll )
    {
        // Grab the MiniDumpWriteDump proc address
        MINIDUMPWRITEDUMP pDump = reinterpret_cast < MINIDUMPWRITEDUMP > ( GetProcAddress( hDll, "MiniDumpWriteDump" ) );
        if ( !pDump )
            AddReportLog( 9202, "CCrashDumpWriter::DumpMiniDump - Could not find MiniDumpWriteDump" );

        if ( pDump )
        {
            // Create the file
            HANDLE hFile = CreateFile ( CalcMTASAPath ( "mta\\core.dmp" ), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
            if ( hFile == INVALID_HANDLE_VALUE )
                AddReportLog( 9203, SString( "CCrashDumpWriter::DumpMiniDump - Could not create '%s'", *CalcMTASAPath ( "mta\\core.dmp" ) ) );

            if ( hFile != INVALID_HANDLE_VALUE )
            {
                // Create an exception information struct
                _MINIDUMP_EXCEPTION_INFORMATION ExInfo;
                ExInfo.ThreadId = GetCurrentThreadId ();
                ExInfo.ExceptionPointers = pException;
                ExInfo.ClientPointers = FALSE;

                // Write the dump
                BOOL bResult = pDump ( GetCurrentProcess(), GetCurrentProcessId(), hFile, (MINIDUMP_TYPE)( MiniDumpNormal | MiniDumpWithIndirectlyReferencedMemory ), &ExInfo, NULL, NULL );

                if ( !bResult )
                    AddReportLog( 9204, SString( "CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump failed (%08x)", GetLastError() ) );
                else
                    WriteDebugEvent ( "CCrashDumpWriter::DumpMiniDump - MiniDumpWriteDump succeeded" );

                // Close the dumpfile
                CloseHandle ( hFile );

                // Grab the current time
                // Ask windows for the system time.
                SYSTEMTIME SystemTime;
                GetLocalTime ( &SystemTime );

                // Create the dump directory
                CreateDirectory ( CalcMTASAPath ( "mta\\dumps" ), 0 );
                CreateDirectory ( CalcMTASAPath ( "mta\\dumps\\private" ), 0 );

                SString strModuleName = pExceptionInformation->GetModuleBaseName ();
                strModuleName = strModuleName.ReplaceI ( ".dll", "" ).Replace ( ".exe", "" ).Replace ( "_", "" ).Replace ( ".", "" ).Replace ( "-", "" );
                if ( strModuleName.length () == 0 )
                    strModuleName = "unknown";

                SString strMTAVersionFull = SString ( "%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting ( "mta-version-ext" ).SplitRight ( ".", NULL, -2 ) );
                SString strSerialPart = GetApplicationSetting ( "serial" ).substr ( 0, 5 );
                uint uiServerIP = GetApplicationSettingInt ( "last-server-ip" );
                uint uiServerPort = GetApplicationSettingInt ( "last-server-port" );
                int uiServerTime = GetApplicationSettingInt ( "last-server-time" );
                int uiServerDuration = _time32 ( NULL ) - uiServerTime;
                uiServerDuration = Clamp ( 0, uiServerDuration + 1, 0xfff );

                // Get path to mta dir
                SString strPathCode;
                {
                    std::vector < SString > parts;
                    PathConform ( CalcMTASAPath ( "" ) ).Split ( PATH_SEPERATOR, parts );
                    for ( uint i = 0 ; i < parts.size () ; i++ )
                    {
                        if ( parts[i].CompareI ( "Program Files" ) )
                            strPathCode += "Pr";
                        else
                        if ( parts[i].CompareI ( "Program Files (x86)" ) )
                            strPathCode += "Px";
                        else
                        if ( parts[i].CompareI ( "MTA San Andreas" ) )
                            strPathCode += "Mt";
                        else
                        if ( parts[i].BeginsWithI ( "MTA San Andreas" ) )
                            strPathCode += "Mb";
                        else
                            strPathCode += parts[i].Left ( 1 ).ToUpper ();
                    }
                }

                // Ensure filename parts match up with EDumpFileNameParts
                SString strFilename ( "mta\\dumps\\private\\client_%s_%s_%08x_%x_%s_%08X_%04X_%03X_%s_%04d%02d%02d_%02d%02d.dmp",
                                             strMTAVersionFull.c_str (),
                                             strModuleName.c_str (),
                                             pExceptionInformation->GetAddressModuleOffset (),
                                             pExceptionInformation->GetCode () & 0xffff,
                                             strPathCode.c_str (),
                                             uiServerIP,
                                             uiServerPort,
                                             uiServerDuration,
                                             strSerialPart.c_str (),
                                             SystemTime.wYear,
                                             SystemTime.wMonth,
                                             SystemTime.wDay,
                                             SystemTime.wHour,
                                             SystemTime.wMinute
                                           );

                SString strPathFilename = CalcMTASAPath ( strFilename );

                // Copy the file
                CopyFile ( CalcMTASAPath ( "mta\\core.dmp" ), strPathFilename, false );

                // For the dump uploader
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "none" );
                SetApplicationSetting ( "diagnostics", "last-dump-save", strPathFilename );

                // Try to append pool sizes info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-pools" );
                CBuffer poolInfo;
                GetPoolInfo ( poolInfo );
                AppendToDumpFile ( strPathFilename, poolInfo, 'POLs', 'POLe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-pools" );

                // Try to append d3d state info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-d3d" );
                CBuffer d3dInfo;
                GetD3DInfo ( d3dInfo );
                AppendToDumpFile ( strPathFilename, d3dInfo, 'D3Ds', 'D3De' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-d3d" );

                // Try to append crash averted stats to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-crash-averted" );
                CBuffer crashAvertedStats;
                GetCrashAvertedStats ( crashAvertedStats );
                AppendToDumpFile ( strPathFilename, crashAvertedStats, 'CASs', 'CASe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-crash-averted" );

                // Try to append log info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-log" );
                CBuffer logInfo;
                GetLogInfo ( logInfo );
                AppendToDumpFile ( strPathFilename, logInfo, 'LOGs', 'LOGe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-log" );

                // Try to append dx info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-misc" );
                CBuffer dxInfo;
                GetDxInfo ( dxInfo );
                AppendToDumpFile ( strPathFilename, dxInfo, 'DXIs', 'DXIe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-misc" );

                // Try to append misc info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-misc" );
                CBuffer miscInfo;
                GetMiscInfo ( miscInfo );
                AppendToDumpFile ( strPathFilename, miscInfo, 'MSCs', 'MSCe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-misc" );

                // Try to append memory info to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-mem" );
                CBuffer memInfo;
                GetMemoryInfo ( memInfo );
                AppendToDumpFile ( strPathFilename, memInfo, 'MEMs', 'MEMe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-mem" );

                // Try to logfile.txt to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-logfile" );
                CBuffer logfileContent;
                logfileContent.LoadFromFile( CalcMTASAPath( PathJoin( "mta", "logs", "logfile.txt" ) ) );
                AppendToDumpFile ( strPathFilename, logfileContent, 'LOGs', 'LOGe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-logfile" );

                // Try to report.log to dump file
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "try-report" );
                CBuffer reportLogContent;
                reportLogContent.LoadFromFile( PathJoin( GetMTADataPath(), "report.log" ) );
                AppendToDumpFile ( strPathFilename, reportLogContent, 'REPs', 'REPe' );
                SetApplicationSetting ( "diagnostics", "last-dump-extra", "added-report" );
            }
        }

        // Free the DLL again
        FreeLibrary ( hDll );
    }

    // Auto-fixes

    // Check if crash was in volumetric shadow code
    if ( ms_uiInCrashZone == 1 || ms_uiInCrashZone == 2 )
    {
        CVARS_SET( "volumetric_shadows", false );
        CCore::GetSingleton().SaveConfig();
        AddReportLog( 9205, "Disabled volumetric shadows" );
    }

    CNet* pNet = CCore::GetSingleton().GetNetwork();
    if ( pNet )
        pNet->PostCrash();    
}
Пример #13
0
bool CAccountManager::IntegrityCheck ()
{
    // Check database integrity
    {
        CRegistryResult result;
        bool bOk = m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "PRAGMA integrity_check" );

        // Get result as a string
        SString strResult;
        if ( result->nRows && result->nColumns )
        {
            CRegistryResultCell& cell = result->Data.front()[0];
            if ( cell.nType == SQLITE_TEXT )
                strResult = std::string ( (const char *)cell.pVal, cell.nLength - 1 );
        }

        // Process result
        if ( !bOk || !strResult.BeginsWithI ( "ok" ) )
        {
            CLogger::ErrorPrintf ( "%s", *strResult );
            CLogger::ErrorPrintf ( "%s\n", *m_pDatabaseManager->GetLastErrorMessage () );
            CLogger::ErrorPrintf ( "Errors were encountered loading '%s' database\n", *ExtractFilename ( PathConform ( "internal.db" ) ) );
            CLogger::ErrorPrintf ( "Maybe now is the perfect time to panic.\n" );
            CLogger::ErrorPrintf ( "See - http://wiki.multitheftauto.com/wiki/fixdb\n" );
            CLogger::ErrorPrintf ( "************************\n" );
            // Allow server to continue
        }
    }

    // Check can update file
    {
        m_pDatabaseManager->Execf ( m_hDbConnection, "DROP TABLE IF EXISTS write_test" );
        m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE TABLE IF NOT EXISTS write_test (id INTEGER PRIMARY KEY, value INTEGER)" );
        m_pDatabaseManager->Execf ( m_hDbConnection, "INSERT OR IGNORE INTO write_test (id, value) VALUES(1,2)" ) ;
        bool bOk = m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, NULL, "UPDATE write_test SET value=3 WHERE id=1" );
        if ( !bOk )
        {
            CLogger::ErrorPrintf ( "%s\n", *m_pDatabaseManager->GetLastErrorMessage () );
            CLogger::ErrorPrintf ( "Errors were encountered updating '%s' database\n", *ExtractFilename ( PathConform ( "internal.db" ) ) );
            CLogger::ErrorPrintf ( "Database might have incorrect file permissions, or locked by another process, or damaged.\n" );
            CLogger::ErrorPrintf ( "See - http://wiki.multitheftauto.com/wiki/fixdb\n" );
            CLogger::ErrorPrintf ( "************************\n" );
            return false;
        }
        m_pDatabaseManager->Execf ( m_hDbConnection, "DROP TABLE write_test" );
    }

    // Do compact if required
    if ( g_pGame->GetConfig()->ShouldCompactInternalDatabases() )
    {
        CLogger::LogPrintf ( "Compacting accounts database '%s' ...\n", *ExtractFilename ( PathConform ( "internal.db" ) ) );

        CRegistryResult result;
        bool bOk = m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "VACUUM" );

        // Get result as a string
        SString strResult;
        if ( result->nRows && result->nColumns )
        {
            CRegistryResultCell& cell = result->Data.front()[0];
            if ( cell.nType == SQLITE_TEXT )
                strResult = std::string ( (const char *)cell.pVal, cell.nLength - 1 );
        }

        // Process result
        if ( !bOk )
        {
            CLogger::ErrorPrintf ( "%s", *strResult );
            CLogger::ErrorPrintf ( "%s\n", *m_pDatabaseManager->GetLastErrorMessage () );
            CLogger::ErrorPrintf ( "Errors were encountered compacting '%s' database\n", *ExtractFilename ( PathConform ( "internal.db" ) ) );
            CLogger::ErrorPrintf ( "Maybe now is the perfect time to panic.\n" );
            CLogger::ErrorPrintf ( "See - http://wiki.multitheftauto.com/wiki/fixdb\n" );
            CLogger::ErrorPrintf ( "************************\n" );
            // Allow server to continue
        }
    }
    return true;
}
Пример #14
0
///////////////////////////////////////////////////////////////
//
// DoInstallFiles
//
// Copy directory tree at current dirctory to GetMTASAPath ()
//
///////////////////////////////////////////////////////////////
bool DoInstallFiles ( void )
{
    SString strCurrentDir = PathConform ( GetSystemCurrentDirectory () );

    const SString strMTASAPath = PathConform ( GetMTASAPath () );

    SString path1, path2;
    strCurrentDir.Split ( "\\", &path1, &path2, -1 );

    SString strDestRoot = strMTASAPath;
    SString strSrcRoot = strCurrentDir;
    SString strBakRoot = MakeUniquePath ( strCurrentDir + "_bak_" );

    // Clean backup dir
    if ( !MkDir ( strBakRoot ) )
    {
        AddReportLog ( 5020, SString ( "InstallFiles: Couldn't make dir '%s'", strBakRoot.c_str () ) );
        return false;
    }

    // Get list of files to install
    std::vector < SFileItem > itemList;
    {
        std::vector < SString > fileList;
        FindFilesRecursive ( PathJoin ( strCurrentDir, "*" ), fileList );
        for ( unsigned int i = 0 ; i < fileList.size () ; i++ )
        {
            SFileItem item;
            item.strSrcPathFilename = PathConform ( fileList[i] );
            item.strDestPathFilename = PathConform ( fileList[i].Replace ( strSrcRoot, strDestRoot ) );
            item.strBackupPathFilename = PathConform ( fileList[i].Replace ( strSrcRoot, strBakRoot ) );
            itemList.push_back ( item );
        }
    }

    // See if any files to be updated are running.
    // If so, terminate them
    for ( unsigned int i = 0 ; i < itemList.size () ; i++ )
    {
        SString strFile = itemList[i].strDestPathFilename;
        if ( strFile.EndsWithI( ".exe" ) )
            TerminateProcessFromPathFilename ( strFile );
    }

    // Copy current(old) files into backup location
    for ( unsigned int i = 0 ; i < itemList.size () ; i++ )
    {
        const SFileItem& item = itemList[i];
        if ( !FileCopy ( item.strDestPathFilename, item.strBackupPathFilename ) )
        {
            if ( FileExists ( item.strDestPathFilename ) )
            {
                AddReportLog ( 5021, SString ( "InstallFiles: Couldn't backup '%s' to '%s'", *item.strDestPathFilename, *item.strBackupPathFilename ) );
                return false;
            }
            AddReportLog ( 4023, SString ( "InstallFiles: Couldn't backup '%s' as it does not exist", *item.strDestPathFilename ) );
        }
    }

    // Try copy new files
    bool bOk = true;
    std::vector < SFileItem > fileListSuccess;
    for (  unsigned int i = 0 ; i < itemList.size () ; i++ )
    {
        const SFileItem& item = itemList[i];
        if ( !FileCopy ( item.strSrcPathFilename, item.strDestPathFilename ) )
        {
            // If copy failed, check if we really need to copy the file
            if ( GenerateSha256HexStringFromFile( item.strSrcPathFilename ) != GenerateSha256HexStringFromFile( item.strDestPathFilename ) )
            {
                AddReportLog ( 5022, SString ( "InstallFiles: Couldn't copy '%s' to '%s'", *item.strSrcPathFilename, *item.strDestPathFilename ) );
                bOk = false;
                break;
            }
        }
        fileListSuccess.push_back ( item );
    }

    // If fail, copy back old files
    if ( !bOk )
    {
        bool bPossibleDisaster = false;
        for ( unsigned int i = 0 ; i < fileListSuccess.size () ; i++ )
        {
            const SFileItem& item = fileListSuccess[i];
            int iRetryCount = 3;
            while ( true )
            {
                if ( FileCopy ( item.strBackupPathFilename, item.strDestPathFilename ) )
                    break;

                // If copy failed, check if we really need to copy the file
                if ( GenerateSha256HexStringFromFile( item.strBackupPathFilename ) != GenerateSha256HexStringFromFile( item.strDestPathFilename ) )
                    break;

                if ( !--iRetryCount )
                {
                    AddReportLog ( 5023, SString ( "InstallFiles: Possible disaster restoring '%s' to '%s'", *item.strBackupPathFilename, *item.strDestPathFilename ) );
                    bPossibleDisaster = true;
                    break;
                }
            }
        }

        //if ( bPossibleDisaster )
        //    MessageBox ( NULL, _("Installation may be corrupt. Please redownload from www.mtasa.com"), _("Error"), MB_OK | MB_ICONERROR );
        //else 
        //    MessageBox ( NULL, _("Could not update due to file conflicts."), _("Error"), MB_OK | MB_ICONERROR );
    }

    // Launch MTA_EXE_NAME
    return bOk;
}
Пример #15
0
CAccountManager::CAccountManager ( const SString& strDbPathFilename )
    : m_AccountProtect( 6, 30000, 60000 * 1 )     // Max of 6 attempts per 30 seconds, then 1 minute ignore
{
    m_llLastTimeSaved = GetTickCount64_ ();
    m_bChangedSinceSaved = false;
    m_iAccounts = 1;
    m_pDatabaseManager = g_pGame->GetDatabaseManager ();

    //Load internal.db
    SString strOptions;
#ifdef WITH_ACCOUNT_QUERY_LOGGING
    g_pGame->GetDatabaseManager ()->SetLogLevel ( EJobLogLevel::ALL, g_pGame->GetConfig ()->GetDbLogFilename () );
    SetOption < CDbOptionsMap > ( strOptions, "log", 1 );
    SetOption < CDbOptionsMap > ( strOptions, "tag", "accounts" );
#endif
    SetOption < CDbOptionsMap > ( strOptions, "queue", DB_SQLITE_QUEUE_NAME_INTERNAL );
    m_hDbConnection = m_pDatabaseManager->Connect ( "sqlite", PathConform ( strDbPathFilename ), "", "", strOptions );

    // Check if new installation
    CRegistryResult result;
	m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "SELECT name FROM sqlite_master WHERE type='table' AND name='accounts'" );
    bool bNewInstallation = ( result->nRows == 0 );

    //Create all our tables (Don't echo the results)
    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE TABLE IF NOT EXISTS accounts (id INTEGER PRIMARY KEY, name TEXT, password TEXT, ip TEXT, serial TEXT)" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE TABLE IF NOT EXISTS userdata (id INTEGER PRIMARY KEY, userid INTEGER, key TEXT, value TEXT, type INTEGER)" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE TABLE IF NOT EXISTS serialusage (id INTEGER PRIMARY KEY, userid INTEGER, "
                                                                                                "serial TEXT, "
                                                                                                "added_ip TEXT, "
                                                                                                "added_date INTEGER, "
                                                                                                "auth_who INTEGER, "
                                                                                                "auth_date INTEGER, "
                                                                                                "last_login_ip TEXT, "
                                                                                                "last_login_date INTEGER, "
                                                                                                "last_login_http_date INTEGER )" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE INDEX IF NOT EXISTS IDX_SERIALUSAGE_USERID on serialusage(userid)" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE UNIQUE INDEX IF NOT EXISTS IDX_SERIALUSAGE_USERID_SERIAL_U on serialusage(userid,serial)" );

    // Check if unique index on accounts exists
	m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "SELECT name FROM sqlite_master WHERE type='index' AND name='IDX_ACCOUNTS_NAME_U'" );
    if ( result->nRows == 0 )
    {
        // Need to add unique index on accounts
        if ( !bNewInstallation )
            CLogger::LogPrintNoStamp ( "Updating accounts table...\n" );

        // Make sure we have a non-unique index to speed up the duplication removal
	    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE INDEX IF NOT EXISTS IDX_ACCOUNTS_NAME on accounts(name)" );
        // Remove any duplicate name entries
	    m_pDatabaseManager->Execf ( m_hDbConnection, "DELETE FROM accounts WHERE rowid in "
						                                " (SELECT A.rowid"
						                                " FROM accounts A, accounts B"
						                                " WHERE A.rowid > B.rowid AND A.name = B.name)" );
        // Remove non-unique index
        m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_ACCOUNTS_NAME" );
        // Add unique index
	    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE UNIQUE INDEX IF NOT EXISTS IDX_ACCOUNTS_NAME_U on accounts(name)" );
    }

    // Check if unique index on userdata exists
	m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "SELECT name FROM sqlite_master WHERE type='index' AND name='IDX_USERDATA_USERID_KEY_U'" );
    if ( result->nRows == 0 )
    {
        // Need to add unique index on userdata
        if ( !bNewInstallation )
            CLogger::LogPrintNoStamp ( "Updating userdata table...\n" );

        // Make sure we have a non-unique index to speed up the duplication removal
	    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE INDEX IF NOT EXISTS IDX_USERDATA_USERID_KEY on userdata(userid,key)" );
        // Remove any duplicate userid+key entries
	    m_pDatabaseManager->Execf ( m_hDbConnection, "DELETE FROM userdata WHERE rowid in "
						                                " (SELECT A.rowid"
						                                " FROM userdata A, userdata B"
						                                " WHERE A.rowid > B.rowid AND A.userid = B.userid AND A.key = B.key)" );
        // Remove non-unique index
        m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_USERDATA_USERID_KEY" );
        // Add unique index
	    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE UNIQUE INDEX IF NOT EXISTS IDX_USERDATA_USERID_KEY_U on userdata(userid,key)" );
    }
    
    // Ensure old indexes are removed
    m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_ACCOUNTS_NAME" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_USERDATA_USERID" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_USERDATA_USERID_KEY" );
}
Пример #16
0
///////////////////////////////////////////////////////////////
//
// MkDir
//
// Returns true if the directory is created or already exists
// TODO: Make bTree off option work
//
///////////////////////////////////////////////////////////////
bool SharedUtil::MkDir ( const SString& strInPath, bool bTree )
{
    SString strPath = PathConform ( strInPath );
    MakeSureDirExists ( strPath + PATH_SEPERATOR );
    return DirectoryExists ( strPath );
}
Пример #17
0
bool CRegistry::IntegrityCheck ( void )
{
    // Check database integrity
    {
        CRegistryResult result;
        bool bOk = Query( &result, "PRAGMA integrity_check" );

        // Get result as a string
        SString strResult;
        if ( result->nRows && result->nColumns )
        {
            CRegistryResultCell& cell = result->Data.front()[0];
            if ( cell.nType == SQLITE_TEXT )
                strResult = std::string ( (const char *)cell.pVal, cell.nLength - 1 );
        }

        // Process result
        if ( !bOk || !strResult.BeginsWithI ( "ok" ) )
        {
            CLogger::ErrorPrintf ( "%s", *strResult );
            CLogger::ErrorPrintf ( "%s\n", GetLastError ().c_str() );
            CLogger::ErrorPrintf ( "Errors were encountered loading '%s' database\n", *ExtractFilename ( PathConform ( m_strFileName ) ) );
            CLogger::ErrorPrintf ( "Maybe now is the perfect time to panic.\n" );
            CLogger::ErrorPrintf ( "See - http://wiki.multitheftauto.com/wiki/fixdb\n" );
            CLogger::ErrorPrintf ( "************************\n" );
            return false;
        }
    }

    // Do compact if required
    if ( g_pGame->GetConfig()->ShouldCompactInternalDatabases() )
    {
        CLogger::LogPrintf ( "Compacting database '%s' ...\n", *ExtractFilename ( PathConform ( m_strFileName ) ) );

        CRegistryResult result;
        bool bOk = Query( &result, "VACUUM" );

        // Get result as a string
        SString strResult;
        if ( result->nRows && result->nColumns )
        {
            CRegistryResultCell& cell = result->Data.front()[0];
            if ( cell.nType == SQLITE_TEXT )
                strResult = std::string ( (const char *)cell.pVal, cell.nLength - 1 );
        }

        // Process result
        if ( !bOk )
        {
            CLogger::ErrorPrintf ( "%s", *strResult );
            CLogger::ErrorPrintf ( "%s\n", GetLastError ().c_str() );
            CLogger::ErrorPrintf ( "Errors were encountered compacting '%s' database\n", *ExtractFilename ( PathConform ( m_strFileName ) ) );
            CLogger::ErrorPrintf ( "Maybe now is the perfect time to panic.\n" );
            CLogger::ErrorPrintf ( "See - http://wiki.multitheftauto.com/wiki/fixdb\n" );
            CLogger::ErrorPrintf ( "************************\n" );
            // Allow server to continue
        }
    }

    return true;
}
Пример #18
0
CAccountManager::CAccountManager ( const char* szFileName, SString strBuffer ): CXMLConfig ( szFileName )
    , m_AccountProtect( 6, 30000, 60000 * 1 )     // Max of 6 attempts per 30 seconds, then 1 minute ignore
{
    m_bAutoLogin = false;
    m_llLastTimeSaved = GetTickCount64_ ();
    m_bChangedSinceSaved = false;
    //set loadXML to false
    m_bLoadXML = false;
    m_iAccounts = 1;

    //Load internal.db
    m_pDatabaseManager = g_pGame->GetDatabaseManager ();
    m_hDbConnection = m_pDatabaseManager->Connect ( "sqlite", PathConform ( strBuffer ) );

    // Check if new installation
    CRegistryResult result;
    m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "SELECT name FROM sqlite_master WHERE type='table' AND name='accounts'" );
    bool bNewInstallation = ( result->nRows == 0 );

    //Create all our tables (Don't echo the results)
    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE TABLE IF NOT EXISTS accounts (id INTEGER PRIMARY KEY, name TEXT, password TEXT, ip TEXT, serial TEXT)" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE TABLE IF NOT EXISTS userdata (id INTEGER PRIMARY KEY, userid INTEGER, key TEXT, value TEXT, type INTEGER)" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE TABLE IF NOT EXISTS settings (id INTEGER PRIMARY KEY, key TEXT, value INTEGER)" );

    // Check if unique index on accounts exists
    m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "SELECT name FROM sqlite_master WHERE type='index' AND name='IDX_ACCOUNTS_NAME_U'" );
    if ( result->nRows == 0 )
    {
        // Need to add unique index on accounts
        if ( !bNewInstallation )
            CLogger::LogPrintNoStamp ( "Updating accounts table...\n" );

        // Make sure we have a non-unique index to speed up the duplication removal
        m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE INDEX IF NOT EXISTS IDX_ACCOUNTS_NAME on accounts(name)" );
        // Remove any duplicate name entries
        m_pDatabaseManager->Execf ( m_hDbConnection, "DELETE FROM accounts WHERE rowid in "
                                    " (SELECT A.rowid"
                                    " FROM accounts A, accounts B"
                                    " WHERE A.rowid > B.rowid AND A.name = B.name)" );
        // Remove non-unique index
        m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_ACCOUNTS_NAME" );
        // Add unique index
        m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE UNIQUE INDEX IF NOT EXISTS IDX_ACCOUNTS_NAME_U on accounts(name)" );
    }

    // Check if unique index on userdata exists
    m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "SELECT name FROM sqlite_master WHERE type='index' AND name='IDX_USERDATA_USERID_KEY_U'" );
    if ( result->nRows == 0 )
    {
        // Need to add unique index on userdata
        if ( !bNewInstallation )
            CLogger::LogPrintNoStamp ( "Updating userdata table...\n" );

        // Make sure we have a non-unique index to speed up the duplication removal
        m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE INDEX IF NOT EXISTS IDX_USERDATA_USERID_KEY on userdata(userid,key)" );
        // Remove any duplicate userid+key entries
        m_pDatabaseManager->Execf ( m_hDbConnection, "DELETE FROM userdata WHERE rowid in "
                                    " (SELECT A.rowid"
                                    " FROM userdata A, userdata B"
                                    " WHERE A.rowid > B.rowid AND A.userid = B.userid AND A.key = B.key)" );
        // Remove non-unique index
        m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_USERDATA_USERID_KEY" );
        // Add unique index
        m_pDatabaseManager->Execf ( m_hDbConnection, "CREATE UNIQUE INDEX IF NOT EXISTS IDX_USERDATA_USERID_KEY_U on userdata(userid,key)" );
    }

    // Ensure old indexes are removed
    m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_ACCOUNTS_NAME" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_USERDATA_USERID" );
    m_pDatabaseManager->Execf ( m_hDbConnection, "DROP INDEX IF EXISTS IDX_USERDATA_USERID_KEY" );

    //Pull our settings
    m_pDatabaseManager->QueryWithResultf ( m_hDbConnection, &result, "SELECT key, value from settings" );

    //Did we get any results
    if ( result->nRows == 0 )
    {
        //Set our settings and clear the accounts/userdata tables just in case
        m_pDatabaseManager->Execf ( m_hDbConnection, "INSERT INTO settings (key, value) VALUES(?,?)", SQLITE_TEXT, "XMLParsed", SQLITE_INTEGER, 0 );
        //Tell the Server to load the xml file rather than the SQL
        m_bLoadXML = true;
    }
    else
    {
        bool bLoadXMLMissing = true;
        for ( CRegistryResultIterator iter = result->begin() ; iter != result->end() ; ++iter )
        {
            const CRegistryResultRow& row = *iter;
            SString strSetting = (const char *)row[0].pVal;

            //Do we have a result for XMLParsed
            if ( strSetting == "XMLParsed" )
            {
                //Is XMLParsed zero
                if ( row[1].nVal == 0 )
                {
                    //Tell the Server to load the xml file rather than the SQL
                    m_bLoadXML = true;
                }
                bLoadXMLMissing = false;
            }
        }
        //if we didn't load the XMLParsed variable
        if ( bLoadXMLMissing )
        {
            //Insert it
            m_pDatabaseManager->Execf ( m_hDbConnection, "INSERT INTO settings (key, value) VALUES(?,?)", SQLITE_TEXT, "XMLParsed", SQLITE_INTEGER, 0 );
            //Tell the Server to load the xml file rather than the SQL
            m_bLoadXML = true;
        }
    }

    //Check whether autologin was enabled in the main config
    m_bAutoLogin = g_pGame->GetConfig()->IsAutoLoginEnabled();
}
Пример #19
0
SString SharedUtil::PathJoin ( const SString& str1, const SString& str2 )
{
    return PathConform ( str1 + PATH_SEPERATOR + str2 );
}