///////////////////////////////////////////////////////////////
//
// CServerIdManagerImpl::StaticSaveServerIdMap
//
//
//
///////////////////////////////////////////////////////////////
void CServerIdManagerImpl::StaticSaveServerIdMap ( void )
{
    CXMLFile* pConfigFile = g_pCore->GetXML ()->CreateXML ( CalcMTASAPath ( MTA_SERVERID_LOOKUP_XML ) );
    if ( !pConfigFile )
        return;
    pConfigFile->Reset ();

    CXMLNode* pRoot = pConfigFile->GetRootNode ();
    if ( !pRoot )
        pRoot = pConfigFile->CreateRootNode ( "root" );

    // Transfer each item from m_ServerIdMap into the file
    for ( std::map < CServerIdKey, CServerIdInfo >::iterator it = ms_ServerIdMap.begin () ; it != ms_ServerIdMap.end () ; ++it )
    {
        const SString& strId = it->first.strId;
        const SString& strDir = it->second.strDir;

        CXMLNode* pSubNode = pRoot->CreateSubNode ( "id" );
        pSubNode->SetTagContent ( strId );
        pSubNode->GetAttributes().Create ( "dir" )->SetValue ( strDir );
    }

    pConfigFile->Write ();
    delete pConfigFile;
}
///////////////////////////////////////////////////////////////
//
// CServerIdManagerImpl::LoadServerIdMap
//
// Load server id data from xml file
//
///////////////////////////////////////////////////////////////
bool CServerIdManagerImpl::LoadServerIdMap ( void )
{
    // Load config XML file
    CXMLFile* pConfigFile = g_pCore->GetXML ()->CreateXML ( CalcMTASAPath ( MTA_SERVERID_LOOKUP_XML ) );
    if ( !pConfigFile )
        return false;
    pConfigFile->Parse ();

    CXMLNode* pRoot = pConfigFile->GetRootNode ();
    if ( !pRoot )
        pRoot = pConfigFile->CreateRootNode ( "root" );

    m_ServerIdMap.clear ();

    // Read each node
    for ( uint i = 0 ; i < pRoot->GetSubNodeCount () ; i++ )
    {
        CXMLNode* pSubNode = pRoot->GetSubNode ( i );

        CServerIdKey key;
        CServerIdInfo info;
        key.strId = pSubNode->GetTagContent ();
        if ( CXMLAttribute* pAttribute = pSubNode->GetAttributes().Find ( "dir" ) )
            info.strDir = pAttribute->GetValue ();

        if ( !info.strDir.empty () )
            MapSet ( m_ServerIdMap, key, info );
    }

    // Maybe one day remove unwanted directories

    delete pConfigFile;
    return true;
}
Example #3
0
//////////////////////////////////////////////////////////
//
// HandleNotUsedMainMenu
//
// Called when a problem occured before the main menu was used by user
// If fullscreen, then maybe change fullscreen mode
//
//////////////////////////////////////////////////////////
void HandleNotUsedMainMenu ( void )
{
    AddReportLog( 9310, "Loader - HandleNotUsedMainMenu" );
    {
        // Slighty hacky way of checking in-game settings
        SString strCoreConfigFilename = CalcMTASAPath( PathJoin( "mta", "config", "coreconfig.xml" ) );
        SString strCoreConfig;
        FileLoad( strCoreConfigFilename, strCoreConfig );
        SString strWindowed        = strCoreConfig.SplitRight( "<display_windowed>" ).Left( 1 );
        SString strFullscreenStyle = strCoreConfig.SplitRight( "<display_fullscreen_style>" ).Left( 1 );
        if ( strFullscreenStyle == "1" )
        {
            AddReportLog( 9315, "Loader - HandleNotUsedMainMenu - Already Borderless window" );
        }
        else
        if ( !strWindowed.empty() && !strFullscreenStyle.empty())
        {
            if ( strWindowed == "0" && strFullscreenStyle == "0" )   // 0=FULLSCREEN_STANDARD
            {
                // Inform user
                SString strMessage = _("Are you having problems running MTA:SA?.\n\nDo you want to change the following setting?");
                strMessage += "\n" + _("Fullscreen mode:") + " -> " + _("Borderless window");
                HideSplash();
                int iResponse = MessageBoxUTF8 ( NULL, strMessage, "MTA: San Andreas", MB_YESNO | MB_ICONQUESTION | MB_TOPMOST );
                if ( iResponse == IDYES )
                {
                    // Very hacky way of changing in-game settings
                    strCoreConfig = strCoreConfig.Replace( "<display_fullscreen_style>0", "<display_fullscreen_style>1" );
                    FileSave( strCoreConfigFilename, strCoreConfig );
                    AddReportLog( 9311, "Loader - HandleNotUsedMainMenu - User change to Borderless window" );
                }
                else
                    AddReportLog( 9313, "Loader - HandleNotUsedMainMenu - User said no" );
            }
            else
                AddReportLog( 9314, "Loader - HandleNotUsedMainMenu - Mode not fullscreen standard" );
        }
        else
        {
            // If no valid settings file yet, do the change without asking
            strCoreConfig = "<mainconfig><settings><display_fullscreen_style>1</display_fullscreen_style></settings></mainconfig>";
            FileSave( strCoreConfigFilename, strCoreConfig );
            AddReportLog( 9312, "Loader - HandleNotUsedMainMenu - Set Borderless window" );
        }
    }

    // Check if Evolve is active
    for ( auto processId : MyEnumProcesses( true ) )
    {
        SString strFilename = ExtractFilename( GetProcessPathFilename( processId ) );
        if ( strFilename.BeginsWithI( "Evolve" ) )
        {
            SString strMessage = _("Are you having problems running MTA:SA?.\n\nTry disabling the following products for GTA and MTA:");
            strMessage += "\n\nEvolve";
            DisplayErrorMessageBox ( strMessage, _E("CL43"), "not-used-menu-evolve" );
            break;
        }
    }
}
Example #4
0
bool CWebCore::Initialise ()
{
    CefMainArgs mainArgs;
    void* sandboxInfo = nullptr;
    CefRefPtr<CCefApp> app { new CCefApp };

#if CEF_ENABLE_SANDBOX
    CefScopedSandboxInfo scopedSandbox;
    sandboxInfo = scopedSandbox.sandbox_info();
#endif

    if ( CefExecuteProcess ( mainArgs, app, sandboxInfo ) >= 0 )
        return false;

    CefSettings settings;
#if !CEF_ENABLE_SANDBOX
    settings.no_sandbox = true;
#endif

    // Specifiy sub process executable path
#ifndef MTA_DEBUG
    CefString ( &settings.browser_subprocess_path ).FromWString( FromUTF8( CalcMTASAPath ( "MTA\\CEF\\CEFLauncher.exe" ) ) );
#else
    CefString ( &settings.browser_subprocess_path ).FromWString( FromUTF8( CalcMTASAPath ( "MTA\\CEF\\CEFLauncher_d.exe" ) ) );
#endif
    CefString ( &settings.resources_dir_path ).FromWString ( FromUTF8( CalcMTASAPath( "MTA\\CEF") ) );
    CefString ( &settings.locales_dir_path ).FromWString( FromUTF8( CalcMTASAPath( "MTA\\CEF\\locales" ) ) );
    CefString ( &settings.log_file ).FromWString ( FromUTF8( CalcMTASAPath ( "MTA\\CEF\\cefdebug.txt" ) ) );
#ifdef MTA_DEBUG
    settings.log_severity = cef_log_severity_t::LOGSEVERITY_INFO;
#else
    settings.log_severity = cef_log_severity_t::LOGSEVERITY_WARNING;
#endif

    settings.multi_threaded_message_loop = true;
    settings.windowless_rendering_enabled = true;

    bool state = CefInitialize ( mainArgs, settings, app, sandboxInfo );
    
    // Register custom scheme handler factory
    CefRegisterSchemeHandlerFactory ( "mtalocal", "", app );
    CefRegisterSchemeHandlerFactory ( "http", "mta", app );

    return state;
}
Example #5
0
int WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, PVOID pvNothing)
{
    CFilePathTranslator     FileTranslator;
    std::string             WorkingDirectory;

    if ( dwReason == DLL_PROCESS_ATTACH )
    {
        WriteDebugEvent( SString( "DLL_PROCESS_ATTACH %08x", pvNothing ) );
        if ( IsGTAProcess() )
        {
            WriteDebugEvent( SString( "ModuleFileName: %s", *GetLaunchPathFilename() ) );

            AddUtf8FileHooks();

            // Set low frag heap for XP
            ULONG heapInfo = 2 ;
            HeapSetInformation( GetProcessHeap(), HeapCompatibilityInformation, &heapInfo, sizeof( heapInfo ) );

            FileTranslator.GetGTARootDirectory ( WorkingDirectory );
            SetCurrentDirectory ( WorkingDirectory.c_str ( ) );

            // For dll searches, this call replaces the current directory entry and turns off 'SafeDllSearchMode'
            // Meaning it will search the supplied path before the system and windows directory.
            // http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx
            SetDllDirectory( CalcMTASAPath ( "MTA" ) );

            g_pCore = new CCore;

            FileTranslator.GetGTARootDirectory ( WorkingDirectory );
            SetCurrentDirectory ( WorkingDirectory.c_str ( ) );
        }
    } 
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        WriteDebugEvent( SString( "DLL_PROCESS_DETACH %08x", pvNothing ) );
        if ( IsGTAProcess () )
        {
            RemoveUtf8FileHooks();

            AddReportLog( 7102, "Core - PROCESS_DETACH" );
            // For now, TerminateProcess if any destruction is attempted (or we'll crash)
            TerminateProcess ( GetCurrentProcess (), 0 );

            if ( g_pCore )
            {
                delete g_pCore;
                g_pCore = NULL;
            }
        }
    }

    return TRUE;
}
Example #6
0
//////////////////////////////////////////////////////////
//
// CheckLibVersions
//
// Ensure DLLs are the correct version
//
//////////////////////////////////////////////////////////
void CheckLibVersions( void )
{
#if MTASA_VERSION_TYPE == VERSION_TYPE_RELEASE

    const char* moduleList [] =     { "MTA\\loader.dll"
                                     ,"MTA\\cgui.dll"
                                     ,"MTA\\core.dll"
                                     ,"MTA\\game_sa.dll"
                                     ,"MTA\\multiplayer_sa.dll"
                                     ,"MTA\\netc.dll"
                                     ,"MTA\\xmll.dll"
                                     ,"MTA\\game_sa.dll"
                                     ,"mods\\deathmatch\\client.dll"
                                     ,"mods\\deathmatch\\pcre3.dll"
                                    };
    SString strReqFileVersion;
    for ( uint i = 0 ; i < NUMELMS( moduleList ) ; i++ )
    {
        SString strFilename = moduleList[i];
#ifdef MTA_DEBUG
        strFilename = ExtractBeforeExtension( strFilename ) + "_d." + ExtractExtension( strFilename );
#endif
        SLibVersionInfo fileInfo;
        if ( FileExists( CalcMTASAPath( strFilename ) ) )
        {
            SString strFileVersion = "0.0.0.0";
            if ( GetLibVersionInfo( CalcMTASAPath( strFilename ), &fileInfo ) )
                strFileVersion = SString( "%d.%d.%d.%d", fileInfo.dwFileVersionMS >> 16, fileInfo.dwFileVersionMS & 0xFFFF
                                                       , fileInfo.dwFileVersionLS >> 16, fileInfo.dwFileVersionLS & 0xFFFF );
            if ( strReqFileVersion.empty() )
                strReqFileVersion = strFileVersion;
            else
            if ( strReqFileVersion != strFileVersion )
            {
                DisplayErrorMessageBox ( SStringX(_( "File version mismatch error."
                                            " Reinstall MTA:SA if you experience problems.\n" )
                                            + SString( "\n[%s %s/%s]\n", *strFilename, *strFileVersion, *strReqFileVersion )
                                            ), _E("CL40"), "bad-file-version" );
                break;
            }
        }
        else
        {
            DisplayErrorMessageBox ( SStringX(_( "Some files are missing."
                                        " Reinstall MTA:SA if you experience problems.\n" )
                                        + SString( "\n[%s]\n", *strFilename )
                                        ), _E("CL41"), "missing-file" );
            break;
        }
    }
///////////////////////////////////////////////////////////////
//
// CServerIdManagerImpl::CServerIdManagerImpl
//
//
//
///////////////////////////////////////////////////////////////
CServerIdManagerImpl::CServerIdManagerImpl ( void )
{
    // Calc private dir root
    m_strServerIdLookupBaseDir = CalcMTASAPath ( MTA_SERVERID_LOOKUP_DIR );
    MakeSureDirExists ( PathJoin ( m_strServerIdLookupBaseDir, "" ) );

    // Calc temp dir path incase of server id error
    m_strTempErrorDir = PathJoin ( m_strServerIdLookupBaseDir, "_error" );

    // If temp dir has been used, clean it
    if ( DirectoryExists ( m_strTempErrorDir ) )
        DelTree ( m_strTempErrorDir, m_strServerIdLookupBaseDir );

    LoadServerIdMap ();
}
//////////////////////////////////////////////////////////
//
// RequiresAltTabFix
//
// Return true if there might be an alt-tab black screen problem when using gta_sa.exe
//
//////////////////////////////////////////////////////////
bool RequiresAltTabFix( void )
{
    // Exception for optimus because of better hi-perf detection when using gta_sa.exe
    if ( GetApplicationSettingInt( "nvhacks", "optimus" ) )
        return false;

    // Check for problem combo of: Windows 10 + NVidia card + full screen
    if ( IsWindows10OrGreater() && GetApplicationSettingInt( "nvhacks", "nvidia" ) )
    {
        // Slighty hacky way of checking in-game settings
        SString strCoreConfig;
        FileLoad( CalcMTASAPath( PathJoin( "mta", "config", "coreconfig.xml" ) ), strCoreConfig );
        int iWindowed        = atoi( strCoreConfig.SplitRight( "<display_windowed>" ) );
        int iFullscreenStyle = atoi( strCoreConfig.SplitRight( "<display_fullscreen_style>" ) );
        if ( iWindowed == 0 && iFullscreenStyle == 0 )   // 0=FULLSCREEN_STANDARD
            return true;        
    }
    return false;
}
Example #9
0
int WINAPI DllMain(HINSTANCE hModule, DWORD dwReason, PVOID pvNothing)
{
    CFilePathTranslator     FileTranslator;
    std::string             WorkingDirectory;

    if ( dwReason == DLL_PROCESS_ATTACH )
    {
        WriteDebugEvent( SString( "DLL_PROCESS_ATTACH %08x", pvNothing ) );
        if ( IsRealDeal () )
        {
            FileTranslator.GetGTARootDirectory ( WorkingDirectory );
            SetCurrentDirectory ( WorkingDirectory.c_str ( ) );

            // For dll searches, this call replaces the current directory entry and turns off 'SafeDllSearchMode'
            // Meaning it will search the supplied path before the system and windows directory.
            // http://msdn.microsoft.com/en-us/library/ms682586%28VS.85%29.aspx
            SetDllDirectory( CalcMTASAPath ( "MTA" ) );

            g_pCore = new CCore;

            FileTranslator.GetGTARootDirectory ( WorkingDirectory );
            SetCurrentDirectory ( WorkingDirectory.c_str ( ) );
        }
    } 
    else if (dwReason == DLL_PROCESS_DETACH)
    {
        WriteDebugEvent( SString( "DLL_PROCESS_DETACH %08x", pvNothing ) );
        if ( IsRealDeal () )
        {
            // For now, TerminateProcess if any destruction is attempted (or we'll crash)
            TerminateProcess ( GetCurrentProcess (), 0 );

            if ( g_pCore )
            {
                delete g_pCore;
                g_pCore = NULL;
            }
        }
    }

    return TRUE;
}
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();    
}
void CCrashDumpWriter::DumpCoreLog ( CExceptionInformation* pExceptionInformation )
{
    // Write crash flag for next launch (Simple flag in case of double faults later)
    fclose( fopen ( CalcMTASAPath ( "mta\\core.log.flag" ), "w" ) );

    // Write a log with the generic exception information
    FILE* pFile = fopen ( CalcMTASAPath ( "mta\\core.log" ), "a+" );
    if ( pFile )
    {
        // Header
        fprintf ( pFile, "%s", "** -- Unhandled exception -- **\n\n" );

        // Write the time
        time_t timeTemp;
        time ( &timeTemp );

        SString strMTAVersionFull = SString ( "%s.%s", MTA_DM_BUILDTAG_LONG, *GetApplicationSetting ( "mta-version-ext" ).SplitRight ( ".", NULL, -2 ) );

        SString strInfo;
        strInfo += SString ( "Version = %s\n", strMTAVersionFull.c_str () );
        strInfo += SString ( "Time = %s", ctime ( &timeTemp ) );

        strInfo += SString ( "Module = %s\n", pExceptionInformation->GetModulePathName () );

        // Write the basic exception information
        strInfo += SString ( "Code = 0x%08X\n", pExceptionInformation->GetCode () );
        strInfo += SString ( "Offset = 0x%08X\n\n", pExceptionInformation->GetAddressModuleOffset () );

        // Write the register info
        strInfo += SString ( "EAX=%08X  EBX=%08X  ECX=%08X  EDX=%08X  ESI=%08X\n" \
                         "EDI=%08X  EBP=%08X  ESP=%08X  EIP=%08X  FLG=%08X\n" \
                         "CS=%04X   DS=%04X  SS=%04X  ES=%04X   " \
                         "FS=%04X  GS=%04X\n\n",
                         pExceptionInformation->GetEAX (),
                         pExceptionInformation->GetEBX (),
                         pExceptionInformation->GetECX (),
                         pExceptionInformation->GetEDX (),
                         pExceptionInformation->GetESI (),
                         pExceptionInformation->GetEDI (),
                         pExceptionInformation->GetEBP (),
                         pExceptionInformation->GetESP (),
                         pExceptionInformation->GetEIP (),
                         pExceptionInformation->GetEFlags (),
                         pExceptionInformation->GetCS (),
                         pExceptionInformation->GetDS (),
                         pExceptionInformation->GetSS (),
                         pExceptionInformation->GetES (),
                         pExceptionInformation->GetFS (),
                         pExceptionInformation->GetGS () );


        fprintf ( pFile, "%s", strInfo.c_str () );

        // End of unhandled exception
        fprintf ( pFile, "%s", "** -- End of unhandled exception -- **\n\n\n" );
        
        // Close the file
        fclose ( pFile );

        // For the crash dialog
        SetApplicationSetting ( "diagnostics", "last-crash-info", strInfo );
        WriteDebugEvent ( strInfo.Replace( "\n", " " ) );
    }
}
Example #12
0
bool CWebCore::MakeSureXMLNodesExist ()
{
    // Check xml file
    if ( !m_pXmlConfig )
    {
        SString browserDataPath = CalcMTASAPath ( MTA_BROWSERDATA_PATH );
        bool exists = FileExists ( browserDataPath );

        m_pXmlConfig = g_pCore->GetXML ()->CreateXML ( browserDataPath );

        if ( !m_pXmlConfig || ( exists && !m_pXmlConfig->Parse () ) )
            return false;
    }

    CXMLNode* pRootNode = m_pXmlConfig->GetRootNode ();
    if ( !pRootNode )
    {
        pRootNode = m_pXmlConfig->CreateRootNode ( "browserdata" );
        if ( !pRootNode )
            return false;
    }

    if ( !pRootNode->FindSubNode ( "lastupdate" ) )
    {
        CXMLNode* pNode = pRootNode->CreateSubNode ( "lastupdate" );
        if ( !pNode )
            return false;

        pNode->SetTagContent ( 0 );
    }

    if ( !pRootNode->FindSubNode ( "whitelistrev" ) )
    {
        if ( !pRootNode->CreateSubNode ( "whitelistrev" ) )
            return false;
    }

    if ( !pRootNode->FindSubNode ( "blacklistrev" ) )
    {
        if ( !pRootNode->CreateSubNode ( "blacklistrev" ) )
            return false;
    }

    if ( !pRootNode->FindSubNode ( "globalwhitelist" ) )
    {
        if ( !pRootNode->CreateSubNode ( "globalwhitelist" ) )
            return false;
    }

    if ( !pRootNode->FindSubNode ( "globalblacklist" ) )
    {
        if ( !pRootNode->CreateSubNode ( "globalblacklist" ) )
            return false;
    }

    if ( !pRootNode->FindSubNode ( "customblacklist" ) )
    {
        if ( !pRootNode->CreateSubNode ( "customblacklist" ) )
            return false;
    }

    if ( !pRootNode->FindSubNode ( "customwhitelist" ) )
    {
        if ( !pRootNode->CreateSubNode ( "customwhitelist" ) )
            return false;
    }

    return true;
}
Example #13
0
//////////////////////////////////////////////////////////
//
// PreLaunchWatchDogs
//
//
//
//////////////////////////////////////////////////////////
void PreLaunchWatchDogs ( void )
{
    assert ( !CreateSingleInstanceMutex () );

    //
    // "L0" is opened before the launch sequence and is closed if MTA shutsdown with no error
    // "L1" is opened before the launch sequence and is closed if GTA is succesfully started
    // "CR1" is a counter which is incremented if GTA was not started and MTA shutsdown with an error
    //
    // "L2" is opened before the launch sequence and is closed if the GTA loading screen is shown
    // "CR2" is a counter which is incremented at startup, if the previous run didn't make it to the loading screen
    //
    // "L3" is opened before the launch sequence and is closed if the GTA loading screen is shown, or a startup problem is handled elsewhere
    //

    // Check for unclean stop on previous run
#ifndef MTA_DEBUG
    if ( WatchDogIsSectionOpen ( "L0" ) )
        WatchDogSetUncleanStop ( true );    // Flag to maybe do things differently if MTA exit code on last run was not 0
    else
#endif
        WatchDogSetUncleanStop ( false );

    SString strCrashFlagFilename = CalcMTASAPath( "mta\\core.log.flag" );
    if ( FileExists( strCrashFlagFilename ) )
    {
        FileDelete( strCrashFlagFilename );
        WatchDogSetLastRunCrash( true );    // Flag to maybe do things differently if MTA crashed last run
    }
    else
        WatchDogSetLastRunCrash( false );

    // Reset counter if gta game was run last time
    if ( !WatchDogIsSectionOpen ( "L1" ) )
        WatchDogClearCounter ( "CR1" );

    // If crashed 3 times in a row before starting the game, do something
    if ( WatchDogGetCounter ( "CR1" ) >= 3 )
    {
        WatchDogReset ();
        HandleTrouble ();
    }

    // Check for possible gta_sa.set problems
    if ( WatchDogIsSectionOpen ( "L2" ) )
    {
        WatchDogIncCounter ( "CR2" );       // Did not reach loading screen last time
        WatchDogCompletedSection ( "L2" );
    }
    else
        WatchDogClearCounter ( "CR2" );

    // If didn't reach loading screen 5 times in a row, do something
    if ( WatchDogGetCounter ( "CR2" ) >= 5 )
    {
        WatchDogClearCounter ( "CR2" );
        HandleResetSettings ();
    }

    // Clear down freeze on quit detection
    WatchDogCompletedSection( "Q0" );

    WatchDogBeginSection ( "L0" );      // Gets closed if MTA exits with a return code of 0
    WatchDogBeginSection ( "L1" );      // Gets closed when online game has started
    SetApplicationSetting ( "diagnostics", "gta-fopen-fail", "" );
    SetApplicationSetting ( "diagnostics", "last-crash-reason", "" );
    SetApplicationSetting ( "diagnostics", "gta-fopen-last", "" );
}
Example #14
0
//////////////////////////////////////////////////////////
//
// CInstallManager::_ProcessLayoutChecks
//
// Make sure new reg/dir structure is ok
//
//////////////////////////////////////////////////////////
SString CInstallManager::_ProcessLayoutChecks ( void )
{
    //
    // Validation
    //

    // Check data dir exists
    {
        if ( !DirectoryExists ( GetMTADataPath () ) )
            ShowLayoutError ( "[Data directory not present]" );   // Can't find directory
    }

    // Check reg key exists
    //{
    //    if ( GetRegistryValue ( "", "Last Install Location" ).empty () )
    //        ShowLayoutError ( "[Registry key not present]" );   // Can't find reg key
    //}

    // Check data dir writable
    {
        SString strTestFilePath = PathJoin ( GetMTADataPath (), "testdir", "testfile.txt" );

        FileDelete ( strTestFilePath );
        RemoveDirectory ( ExtractPath ( strTestFilePath ) );

        SString strContent = "test";
        if ( !FileSave ( strTestFilePath, strContent ) )
            ShowLayoutError ( "[Data directory not writable]" );   // Can't save file

        FileDelete ( strTestFilePath );
        RemoveDirectory ( ExtractPath ( strTestFilePath ) );
    }

    // Check reg key writable
    {
        RemoveRegistryKey ( "testkeypath" );

        SString strValue = GetTimeString( true, true );
        SetRegistryValue ( "testkeypath", "testname", strValue );
        SString strValueCheck = GetRegistryValue ( "testkeypath", "testname" );
        if ( strValueCheck != strValue )
            ShowLayoutError ( "[Registry key not writable]" );   // Can't write reg key

        RemoveRegistryKey ( "testkeypath" );
    }

    // Check install dir writable
    {
        SString strTestFilePath = CalcMTASAPath ( PathJoin ( "mta", "writetest.txt" ) );

        FileDelete ( strTestFilePath );

        SString strContent = "test";
        if ( !FileSave ( strTestFilePath, strContent ) )
            ShowLayoutError ( "[Install directory not writable]" );   // Can't save file

        FileDelete ( strTestFilePath );
    }

    //
    // Migration
    //

    // If news/temp/upcache folder doesn't exist in new, but does in old place, move it
    {
        const char* folders[] = { "news", "temp", "upcache" };
        for ( uint i = 0 ; i < NUMELMS( folders ) ; i++ )
        {
            SString strSrc = PathJoin ( GetSystemLocalAppDataPath (), "MTA San Andreas " + GetMajorVersionString (), folders[i] );
            SString strDest = PathJoin ( GetMTADataPath (), folders[i] );
            if ( !DirectoryExists ( strDest ) && DirectoryExists ( strSrc ) )
                MoveFile ( strSrc, strDest );
        }
    }

    // If aero option reg entry doesn't exist in new, but does in old place, move it
    {
        if ( GetApplicationSetting ( "aero-enabled" ).empty () )
        {
            SString strLegacyValue = GetVersionRegistryValueLegacy ( GetMajorVersionString (), PathJoin ( "Settings", "general" ), "aero-enabled" );
            if ( !strLegacyValue.empty () )
                SetApplicationSettingInt ( "aero-enabled", atoi ( strLegacyValue ) );
            else
                SetApplicationSettingInt ( "aero-enabled", 1 );
        }
    }

    return "ok";
}
Example #15
0
///////////////////////////////////////////////////////////////
//
// CCompressorJobQueueImpl::ThreadProc
//
// Job service loop
//
///////////////////////////////////////////////////////////////
void* CCompressorJobQueueImpl::ThreadProc()
{
    shared.m_Mutex.Lock();
    while (!shared.m_bTerminateThread)
    {
        // Temp debug code to cause crash with key combo
        static bool bEnableKeyCrash2 = false;
        static bool bEnableKeyCrash2Init = false;
        if (!bEnableKeyCrash2Init)
        {
            bEnableKeyCrash2Init = true;
            bEnableKeyCrash2 = FileExists(CalcMTASAPath("debug.txt"));
        }

        bool bEnableKeyCrash = (g_pCore && g_pCore->GetDiagnosticDebug() == EDiagnosticDebug::LUA_TRACE_0000);
        if (bEnableKeyCrash || bEnableKeyCrash2)
        {
            bool bHoldingCtrlL = (GetAsyncKeyState(VK_LCONTROL) & 0x8000) != 0;
            bool bHoldingCtrlR = (GetAsyncKeyState(VK_RCONTROL) & 0x8000) != 0;
            if (bHoldingCtrlL && bHoldingCtrlR)
            {
                // Cause crash dump generation
                int* ptr = NULL;
                *ptr = 0;
            }
        }

        // Is there a waiting command?
        if (shared.m_CommandQueue.empty())
        {
            if (bEnableKeyCrash)
                shared.m_Mutex.Wait(10);
            else
                shared.m_Mutex.Wait(1000);
        }
        else
        {
            // Get next command
            CCompressJobData* pJobData = shared.m_CommandQueue.front();
            pJobData->stage = EJobStage::PROCCESSING;
            shared.m_Mutex.Unlock();

            // Process command
            ProcessCommand(pJobData);

            // Store result
            shared.m_Mutex.Lock();
            // Check command has not been cancelled (this should not be possible)
            if (!shared.m_CommandQueue.empty() && pJobData == shared.m_CommandQueue.front())
            {
                // Remove command
                shared.m_CommandQueue.pop_front();
                // Add result
                pJobData->stage = EJobStage::RESULT;
                shared.m_ResultQueue.push_back(pJobData);
            }
            shared.m_Mutex.Signal();
        }
    }

    shared.m_bThreadTerminated = true;
    shared.m_Mutex.Unlock();

    return NULL;
}
///////////////////////////////////////////////////////////////
//
// CClientPerfStatLibMemoryImpl::GetLibMemoryStats
//
//
//
///////////////////////////////////////////////////////////////
void CClientPerfStatLibMemoryImpl::GetLibMemoryStats ( CClientPerfStatResult* pResult, const std::map < SString, int >& strOptionMap, const SString& strFilter )
{
    //
    // Set option flags
    //
    bool bHelp = MapContains ( strOptionMap, "h" );
    bool bMoreInfo = MapContains ( strOptionMap, "i" );
    bool bTopTags = MapContains ( strOptionMap, "t" );

    //
    // Process help
    //
    if ( bHelp )
    {
        pResult->AddColumn ( "Lib memory help" );
        pResult->AddRow ()[0] ="Option h - This help";
        pResult->AddRow ()[0] ="Option t - Top allocations";
        pResult->AddRow ()[0] ="Option i - More information";
        return;
    }


    // Fetch mem stats from dlls
    {
        if ( m_LibraryList.size () == 0 )
        {
            struct {
                bool bModDir;
                const char* szName;
            } libs [] = {
                            { false,  "cgui", },
                            { false,  "core", },
                            { true,   "client", },
                            { false,  "game_sa", },
                            { false,  "multiplayer_sa", },
                            { false,  "netc", },
                            { false,  "xmll", },
                        };

            for ( unsigned int i = 0 ; i < NUMELMS ( libs ) ; i++ )
            {
                CLibraryInfo info;
                bool bModDir = libs[i].bModDir;
                info.strName = libs[i].szName;
                #if MTA_DEBUG
                    info.strName += "_d";
                #endif
                #ifdef WIN32
                    info.strName += ".dll";
                #else
                    info.strName += ".so";
                #endif
                info.pLibrary = new CDynamicLibrary();

                SString strPathFilename;
                if ( bModDir )
                    strPathFilename = CalcMTASAPath( PathJoin( "mods", "deathmatch", info.strName ) );
                else
                    strPathFilename = CalcMTASAPath( PathJoin( "mta", info.strName ) );

                if ( info.pLibrary->Load ( strPathFilename ) )
                {
                    info.pfnGetAllocStats = reinterpret_cast< PFNGETALLOCSTATS > ( info.pLibrary->GetProcedureAddress ( "GetAllocStats" ) );
                    if ( info.pfnGetAllocStats )
                    {
                        m_LibraryList.push_back ( info );
                        continue;
                    }
                }
                delete info.pLibrary;
            }
        }

        for ( unsigned int i = 0 ; i < m_LibraryList.size () ; i++ )
        {
            CLibraryInfo& info = m_LibraryList[i];
            unsigned long stats[9];
            unsigned long numgot = info.pfnGetAllocStats ( 0, stats, NUMELMS ( stats ) );
            if ( numgot >= 2 )
                UpdateLibMemory ( info.strName, ( stats[0] + 1023 ) / 1024, ( stats[1] + 1023 ) / 1024 );
        }
    }


    pResult->AddColumn ( "name" );
    pResult->AddColumn ( "change" );
    pResult->AddColumn ( "current" );
    pResult->AddColumn ( "max" );

    if ( bMoreInfo )
    {
        pResult->AddColumn ( "ActiveAllocs" );
        pResult->AddColumn ( "DupeAllocs" );
        pResult->AddColumn ( "UniqueAllocs" );
        pResult->AddColumn ( "ReAllocs" );
        pResult->AddColumn ( "Frees" );
        pResult->AddColumn ( "UnmatchedFrees" );
        pResult->AddColumn ( "DupeMem" );
    }
    else
    if ( bTopTags )
    {
        pResult->AddColumn ( "1" );
        pResult->AddColumn ( "2" );
        pResult->AddColumn ( "3" );
        pResult->AddColumn ( "4" );
        pResult->AddColumn ( "5" );
    }

    // Calc totals
    if ( strFilter == "" )
    {
        int calcedCurrent = 0;
        int calcedDelta = 0;
        int calcedMax = 0;
        for ( CLibMemoryMap::iterator iter = AllLibMemory.LibMemoryMap.begin () ; iter != AllLibMemory.LibMemoryMap.end () ; ++iter )
        {
            CLibMemory& LibMemory = iter->second;
            calcedCurrent += LibMemory.Current;
            calcedDelta += LibMemory.Delta;
            calcedMax += LibMemory.Max;
        }

        // Add row
        SString* row = pResult->AddRow ();

        int c = 0;
        row[c++] = "Lib totals";

        if ( labs(calcedDelta) >= 1 )
        {
            row[c] = SString ( "%d KB", calcedDelta );
            calcedDelta = 0;
        }
        c++;

        row[c++] = SString ( "%d KB", calcedCurrent );
        row[c++] = SString ( "%d KB", calcedMax );
    }


    // For each lib
    for ( CLibMemoryMap::iterator iter = AllLibMemory.LibMemoryMap.begin () ; iter != AllLibMemory.LibMemoryMap.end () ; ++iter )
    {
        CLibMemory& LibMemory = iter->second;
        const SString& strName = iter->first;

        // Apply filter
        if ( strFilter != "" && strName.find ( strFilter ) == SString::npos )
            continue;

        SString* row = pResult->AddRow ();

        int c = 0;
        row[c++] = strName;

        if ( labs(LibMemory.Delta) >= 1 )
        {
            row[c] = SString ( "%d KB", LibMemory.Delta );
            LibMemory.Delta = 0;
        }
        c++;

        row[c++] = SString ( "%d KB", LibMemory.Current );
        row[c++] = SString ( "%d KB", LibMemory.Max );

        if ( bMoreInfo )
        {
            for ( unsigned int i = 0 ; i < m_LibraryList.size () ; i++ )
            {
                CLibraryInfo& info = m_LibraryList[i];
                if ( strName == info.strName )
                {
                    unsigned long stats[9];
                    unsigned long numgot = info.pfnGetAllocStats ( 0, stats, NUMELMS(stats) );
                    if ( numgot >= 9 )
                    {
                        row[c++] = SString ( "%d", stats[2] );
                        row[c++] = SString ( "%d", stats[3]  );
                        row[c++] = SString ( "%d", stats[4]  );
                        row[c++] = SString ( "%d", stats[5]  );
                        row[c++] = SString ( "%d", stats[6]  );
                        row[c++] = SString ( "%d", stats[7]  );
                        row[c++] = SString ( "%d KB", ( stats[8] + 1023 ) / 1024  );
                    }
                    break;
                }
            }
        }
        else
        if ( bTopTags )
        {
            for ( unsigned int i = 0 ; i < m_LibraryList.size () ; i++ )
            {
                CLibraryInfo& info = m_LibraryList[i];
                if ( strName == info.strName )
                {
                    SAllocTrackingTagInfo stats[5];
                    unsigned long numgot = info.pfnGetAllocStats ( 1, stats, NUMELMS ( stats ) );
                    for ( uint i = 0 ; i < numgot && i < 5 ; i++ )
                    {
                        const SAllocTrackingTagInfo& info = stats[i];
                        row[c++] = SString ( "[%d KB (%d) {%s}]", info.size/ 1024, info.countAllocs, info.tag );
                    }
                    break;
                }
            }
        }
    }
}