//////////////////////////////////////////////////////////
//
// GetExePatchRequirements
//
// Check which patches should be applied
//
//////////////////////////////////////////////////////////
SExePatchedStatus GetExePatchRequirements( void )
{
    SExePatchedStatus status;
    status.bTimestamp   = GetApplicationSettingInt ( "aero-enabled" ) ? true : false;
    status.bLargeMem    = true;
    status.bDep         = true;
    status.bNvightmare  = GetApplicationSettingInt( "nvhacks", "optimus-export-enablement" ) ? true : false;
    status.bAltModules  = GetPatchRequirementAltModules();

    return status;
}
//////////////////////////////////////////////////////////
//
// ShouldUseExeCopy
//
// Returns true if patches should be applied to exe copy
//
//////////////////////////////////////////////////////////
bool ShouldUseExeCopy( void )
{
    int iUseCopy;
    if ( GetApplicationSettingInt( "nvhacks", "optimus" ) )
        iUseCopy = GetApplicationSettingInt( "nvhacks", "optimus-rename-exe" );
    else
        iUseCopy = GetApplicationSettingInt( "driver-overrides-disabled" );

    if ( GetPatchRequirementAltModules() )
        iUseCopy = 1;

    return iUseCopy != 0;
}
Exemple #3
0
////////////////////////////////////////////////////
//
//  CNewsBrowser::SetVisible
//
//
//
////////////////////////////////////////////////////
void CNewsBrowser::SetVisible(bool bVisible)
{
    if (!bVisible && !m_pWindow)
        return;

    // HACK: Recreate GUI if left shift held (for editing)
    if ((GetAsyncKeyState(VK_LSHIFT) & 0x8000) != 0)
    {
        DestroyGUI();
        CreateGUI();
    }

    if (!m_pWindow)
        CreateGUI();

    // Hide / show the form
    m_pWindow->SetVisible(bVisible);

    if (bVisible)
    {
        // Bring it all forward
        m_pWindow->Activate();
        m_pWindow->SetAlwaysOnTop(true);
        m_pWindow->BringToFront();
        if (GetApplicationSettingInt("news-updated") == 1)
        {
            SetApplicationSettingInt("news-updated", 0);
            CreateHeadlines();
        }
    }
}
bool SharedUtil::WatchDogWasUncleanStop ( void )
{
    if ( !bWatchDogWasUncleanStopCached )
    {
        bWatchDogWasUncleanStopCached = true;
        bWatchDogWasUncleanStopValue = GetApplicationSettingInt ( "watchdog", "uncleanstop" ) != 0;
    }
    return bWatchDogWasUncleanStopValue;
}
//////////////////////////////////////////////////////////
//
// 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;
}
Exemple #6
0
////////////////////////////////////////////////////
//
//  CNewsBrowser::CreateHeadlines
//
//
//
////////////////////////////////////////////////////
void CNewsBrowser::CreateHeadlines(void)
{
    InitNewsItemList();
    bool bNewsUpdated = GetApplicationSettingInt("news-updated") == 1;

    uint i;
    // Process each news item
    for (i = 0; i < m_NewsitemList.size(); i++)
        CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->SetNewsHeadline(i, m_NewsitemList[i].strHeadline, m_NewsitemList[i].strDate, i < 1 && bNewsUpdated);

    // Clear unused slots
    for (; i < 3; i++)
        CCore::GetSingleton().GetLocalGUI()->GetMainMenu()->SetNewsHeadline(i, "", "", false);
}
//////////////////////////////////////////////////////////
//
// ShouldUseExeCopy
//
// Returns true if patches should be applied to exe copy
//
//////////////////////////////////////////////////////////
bool ShouldUseExeCopy( void )
{
    SString strUseCopyReason;
    if ( GetApplicationSettingInt( "nvhacks", "optimus" ) )
        strUseCopyReason = GetApplicationSettingInt( "nvhacks", "optimus-rename-exe" ) == 0 ? "" : "optimus-rename-exe";
    else
        strUseCopyReason = GetApplicationSettingInt( "driver-overrides-disabled" ) == 0 ? "" : "driver-overrides-disabled";

    if ( GetPatchRequirementAltModules() )
        strUseCopyReason += " AltModules";

    if ( RequiresAltTabFix() )
        strUseCopyReason += " AltTabFix";

    // Log reason for using proxy_sa
    static SString strUseCopyReasonPrevious;
    if ( strUseCopyReasonPrevious != strUseCopyReason )
    {
        WriteDebugEventAndReport( 3500, SString( "Using proxy_sa because: %s", *strUseCopyReason ) );
        strUseCopyReasonPrevious = strUseCopyReason;
    }
    return !strUseCopyReason.empty();
}
////////////////////////////////////////////////
//
// Hook CCore::OnPreCreateDevice
//
// Modify paramters
//
////////////////////////////////////////////////
void CCore::OnPreCreateDevice(IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD& BehaviorFlags,
                              D3DPRESENT_PARAMETERS* pPresentationParameters)
{
    assert(0);

    if (!UsingAltD3DSetup())
        return;

    WriteDebugEvent("CCore::OnPreCreateDevice");

    uint uiPrevResult = GetApplicationSettingInt("diagnostics", "last-create-device-result");
    if (uiPrevResult)
    {
        // Failed last time, so as a test for logging, try a create device with no modifications
        WriteDebugEvent(SString("Previous CreateDevice failed with: %08x", uiPrevResult));
        WriteDebugEvent("  Test unmodified:");
        WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters));
        IDirect3DDevice9* pReturnedDeviceInterface = NULL;
        HRESULT hResult = pDirect3D->CreateDevice(Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, &pReturnedDeviceInterface);
        SAFE_RELEASE(pReturnedDeviceInterface);
        WriteDebugEvent(SString("  Unmodified result is: %08x", hResult));
    }

    // Save original values for later
    BehaviorFlagsOrig = BehaviorFlags;
    presentationParametersOrig = *pPresentationParameters;

    WriteDebugEvent("  Original paramters:");
    WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters));

    // Make sure DirectX Get...() calls will work
    BehaviorFlags &= ~D3DCREATE_PUREDEVICE;

    // Enable the auto depth stencil parameter
    pPresentationParameters->EnableAutoDepthStencil = true;

    GetVideoModeManager()->PreCreateDevice(pPresentationParameters);

    WriteDebugEvent("  Modified paramters:");
    WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters));
}
///////////////////////////////////////////////////////////////
//
// CVideoModeManager::LoadCVars
//
// Loads to current
//
///////////////////////////////////////////////////////////////
void CVideoModeManager::LoadCVars ( void )
{
    // Upgrade display_alttab_handler
    bool bAltTabHandlerWasEnabled = CVARS_GET_VALUE < bool > ( "display_alttab_handler" );
    int iFullscreenStyle = CVARS_GET_VALUE < int > ( "display_fullscreen_style" );
    if ( bAltTabHandlerWasEnabled && iFullscreenStyle == 0 )
    {
        CVARS_SET ( "display_alttab_handler", false );
        CVARS_SET ( "display_fullscreen_style", FULLSCREEN_BORDERLESS );
    }

    // Apply override
    if ( GetApplicationSettingInt( "nvhacks", "optimus-force-windowed" ) )
    {
        SetApplicationSettingInt( "nvhacks", "optimus-force-windowed", 0 );
        CVARS_SET ( "display_windowed", true );
    }

    m_iCurrentVideoMode = m_pGameSettings->GetCurrentVideoMode ();
    CVARS_GET ( "display_windowed",             m_bCurrentWindowed );
    CVARS_GET ( "display_fullscreen_style",     m_iCurrentFullscreenStyle );
    CVARS_GET ( "multimon_fullscreen_minimize", m_bCurrentFullScreenMinimize );
}
Exemple #10
0
////////////////////////////////////////////////
//
// Hook CCore::OnPostCreateDevice
//
// Wrap device or log failure
//
////////////////////////////////////////////////
HRESULT CCore::OnPostCreateDevice(HRESULT hResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
                                  D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface)
{
    if (!UsingAltD3DSetup())
        return D3D_OK;

    //
    // - Allow create device with no changes
    // - Check caps and report diff with GTA caps
    // - Release device
    //
    WriteDebugEvent("CCore::OnPostCreateDevice - Alt startup used");

    if (hResult != D3D_OK)
        WriteDebugEvent(SString("Initial CreateDevice failed: %08x", hResult));
    else
        WriteDebugEvent("Initial CreateDevice succeeded");

    AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, false);

    SAFE_RELEASE(*ppReturnedDeviceInterface);

    //
    // - Create device with required changes
    // - Check caps and report diff with GTA caps
    // - Fix GTA caps if needed
    //

    // Save original values for later
    BehaviorFlagsOrig = BehaviorFlags;
    presentationParametersOrig = *pPresentationParameters;

    WriteDebugEvent("  Original paramters:");
    WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters));

    // Make sure DirectX Get...() calls will work
    BehaviorFlags &= ~D3DCREATE_PUREDEVICE;

    // Enable the auto depth stencil parameter
    pPresentationParameters->EnableAutoDepthStencil = true;

    GetVideoModeManager()->PreCreateDevice(pPresentationParameters);

    WriteDebugEvent("  Modified paramters:");
    WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters));

    hResult = CreateDeviceInsist(2, 1000, pDirect3D, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);

    if (hResult != D3D_OK)
        WriteDebugEvent(SString("MTA CreateDevice failed: %08x", hResult));
    else
        WriteDebugEvent("MTA CreateDevice succeeded");

    AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, true);

    // Change the window title to MTA: San Andreas
    #ifdef MTA_DEBUG
    SetWindowTextW(hFocusWindow, MbUTF8ToUTF16("MTA: San Andreas [DEBUG]").c_str());
    #else
    SetWindowTextW(hFocusWindow, MbUTF8ToUTF16("MTA: San Andreas").c_str());
    #endif

    // Log graphic card name
    D3DADAPTER_IDENTIFIER9 AdapterIdent;
    pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent);
    WriteDebugEvent(ToString(AdapterIdent));

    // Store the rendering window in the direct 3d data
    CDirect3DData::GetSingleton().StoreDeviceWindow(pPresentationParameters->hDeviceWindow);

    // Apply input hook
    CMessageLoopHook::GetSingleton().ApplyHook(hFocusWindow);

    // Make sure the object was created successfully.
    if (hResult == D3D_OK)
    {
        WriteDebugEvent("CreateDevice succeeded");
        GetVideoModeManager()->PostCreateDevice(*ppReturnedDeviceInterface, pPresentationParameters);

        // We must first store the presentation values.
        CDirect3DData::GetSingleton().StoreViewport(0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);

        // Calc and store readable depth format for shader use
        ERenderFormat ReadableDepthFormat = CDirect3DEvents9::DiscoverReadableDepthFormat(*ppReturnedDeviceInterface, pPresentationParameters->MultiSampleType,
                                                                                          pPresentationParameters->Windowed != 0);
        CGraphics::GetSingleton().GetRenderItemManager()->SetDepthBufferFormat(ReadableDepthFormat);

        // Now create the proxy device.
        *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(*ppReturnedDeviceInterface);

        // Debug output
        D3DDEVICE_CREATION_PARAMETERS parameters;
        (*ppReturnedDeviceInterface)->GetCreationParameters(&parameters);

        WriteDebugEvent("   Used creation parameters:");
        WriteDebugEvent(SString("    Adapter:%d  DeviceType:%d  BehaviorFlags:0x%x  ReadableDepth:%s", parameters.AdapterOrdinal, parameters.DeviceType,
                                parameters.BehaviorFlags, ReadableDepthFormat ? std::string((char*)&ReadableDepthFormat, 4).c_str() : "None"));
    }

    bool bDetectOptimus = (GetModuleHandle("nvd3d9wrap.dll") != NULL);

    // Calc log level to use
    uint uiDiagnosticLogLevel = 0;
    if (GetApplicationSettingInt("nvhacks", "optimus") || bDetectOptimus)
        uiDiagnosticLogLevel = 1;            // Log and continue
    if (hResult != D3D_OK)
        uiDiagnosticLogLevel = 2;            // Log and wait - If fail status

    // Do diagnostic log now if needed
    if (uiDiagnosticLogLevel)
    {
        // Prevent statup warning in loader
        WatchDogCompletedSection("L3");

        // Run diagnostic
        CCore::GetSingleton().GetNetwork()->ResetStub('dia3', *ms_strExtraLogBuffer, uiDiagnosticLogLevel);
    }
    ms_strExtraLogBuffer.clear();

    // Handle fatal error
    if (hResult != D3D_OK)
    {
        // Inform user
        SString strMessage;
        strMessage += "There was a problem starting MTA:SA\n\n";
        strMessage += SString("Direct3D CreateDevice error: %08x", hResult);
        BrowseToSolution("d3dcreatedevice-fail", EXIT_GAME_FIRST | ASK_GO_ONLINE, strMessage);
    }

    return hResult;
}
Exemple #11
0
////////////////////////////////////////////////
//
// HandleCreateDeviceResult
//
// Log result and possibly fix everything
//
////////////////////////////////////////////////
HRESULT HandleCreateDeviceResult(HRESULT hResult, IDirect3D9* pDirect3D, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow, DWORD BehaviorFlags,
                                 D3DPRESENT_PARAMETERS* pPresentationParameters, IDirect3DDevice9** ppReturnedDeviceInterface)
{
    // Log graphic card name
    D3DADAPTER_IDENTIFIER9 AdapterIdent;
    pDirect3D->GetAdapterIdentifier(Adapter, 0, &AdapterIdent);
    WriteDebugEvent(ToString(AdapterIdent));

    uint uiCurrentStatus = 0;            //  0-unknown  1-fail  2-success after retry  3-success

    if (hResult == D3D_OK)
    {
        // Log success and creation parameters
        WriteDebugEvent("CreateDevice success");
        uiCurrentStatus = CREATE_DEVICE_SUCCESS;
        WriteDebugEvent(ToString(Adapter, DeviceType, hFocusWindow, BehaviorFlags, *pPresentationParameters));
    }

    if (hResult != D3D_OK)
    {
        // Handle failure of initial create device call
        WriteDebugEvent(SString("CreateDevice failed #0: %08x", hResult));

        // Try create device again
        hResult = DoCreateDevice(pDirect3D, Adapter, DeviceType, hFocusWindow, BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);

        // Handle retry result
        if (hResult != D3D_OK)
        {
            WriteDebugEvent("--CreateDevice failed after retry");
            uiCurrentStatus = CREATE_DEVICE_FAIL;
        }
        else
        {
            WriteDebugEvent("++CreateDevice succeeded after retry");
            uiCurrentStatus = CREATE_DEVICE_RETRY_SUCCESS;

            // Apply input hook
            CMessageLoopHook::GetSingleton().ApplyHook(hFocusWindow);

            GetVideoModeManager()->PostCreateDevice(*ppReturnedDeviceInterface, pPresentationParameters);

            // We must first store the presentation values.
            CDirect3DData::GetSingleton().StoreViewport(0, 0, pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight);

            // Calc and store readable depth format for shader use
            ERenderFormat ReadableDepthFormat = CDirect3DEvents9::DiscoverReadableDepthFormat(
                *ppReturnedDeviceInterface, pPresentationParameters->MultiSampleType, pPresentationParameters->Windowed != 0);
            CGraphics::GetSingleton().GetRenderItemManager()->SetDepthBufferFormat(ReadableDepthFormat);

            // Now create the proxy device.
            *ppReturnedDeviceInterface = new CProxyDirect3DDevice9(*ppReturnedDeviceInterface);

            // Debug output
            D3DDEVICE_CREATION_PARAMETERS parameters;
            (*ppReturnedDeviceInterface)->GetCreationParameters(&parameters);

            WriteDebugEvent(SString("    Adapter:%d  DeviceType:%d  BehaviorFlags:0x%x  ReadableDepth:%s", parameters.AdapterOrdinal, parameters.DeviceType,
                                    parameters.BehaviorFlags, ReadableDepthFormat ? std::string((char*)&ReadableDepthFormat, 4).c_str() : "None"));
        }
    }

    uint uiLastStatus = GetApplicationSettingInt("diagnostics", "createdevice-last-status");
    SetApplicationSettingInt("diagnostics", "createdevice-last-status", uiCurrentStatus);

    // Calc log level to use
    uint uiDiagnosticLogLevel = 0;
    if (uiLastStatus == CREATE_DEVICE_FAIL && uiCurrentStatus != CREATE_DEVICE_FAIL)
        uiDiagnosticLogLevel = 1;            // Log and continue - If changing from fail status
    if (uiCurrentStatus == CREATE_DEVICE_FAIL)
        uiDiagnosticLogLevel = 2;            // Log and wait - If fail status

    bool bDetectOptimus = (GetModuleHandle("nvd3d9wrap.dll") != NULL);

    bool bFixCaps = false;
    if (GetApplicationSettingInt("nvhacks", "optimus") || bDetectOptimus)
    {
        bFixCaps = true;
        if (uiDiagnosticLogLevel == 0)
            uiDiagnosticLogLevel = 1;
    }

    AddCapsReport(Adapter, pDirect3D, *ppReturnedDeviceInterface, bFixCaps);

    if (uiDiagnosticLogLevel)
    {
        // Prevent statup warning in loader
        WatchDogCompletedSection("L3");
        CCore::GetSingleton().GetNetwork()->ResetStub('dia3', *ms_strExtraLogBuffer, uiDiagnosticLogLevel);
    }
    ms_strExtraLogBuffer.clear();

    if (hResult != D3D_OK)
    {
        // Handle fatal error
        SString strMessage;
        strMessage += "There was a problem starting MTA:SA\n\n";
        strMessage += SString("Direct3D CreateDevice error: %08x", hResult);
        BrowseToSolution("d3dcreatedevice-fail", EXIT_GAME_FIRST | ASK_GO_ONLINE, strMessage);
    }

    return hResult;
}
// Section
bool SharedUtil::WatchDogIsSectionOpen ( const SString& str )
{
    return GetApplicationSettingInt ( "watchdog", str ) != 0;
}
Exemple #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 ();
    }

    // Check for possible fullscreen problems
    if ( WatchDogIsSectionOpen( WD_SECTION_NOT_USED_MAIN_MENU ) )
    {
        int iChainLimit;
        if ( WatchDogIsSectionOpen( WD_SECTION_POST_INSTALL ) )
            iChainLimit = 1;
        else
        if ( GetApplicationSettingInt( "times-connected" ) == 0 )
            iChainLimit = 2;
        else
            iChainLimit = 3;
        WatchDogCompletedSection( WD_SECTION_NOT_USED_MAIN_MENU );
        WatchDogIncCounter( WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU );
        if ( WatchDogGetCounter( WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU ) >= iChainLimit )
        {
            WatchDogClearCounter( WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU );
            HandleNotUsedMainMenu();
        }
    }
    else
        WatchDogClearCounter( WD_COUNTER_CRASH_CHAIN_BEFORE_USED_MAIN_MENU );

    // 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", "" );
}
///////////////////////////////////////////////////////////////
//
// CModelCacheManagerImpl::PreLoad
//
// Cache all weapons and upgrades
//
// Peds KB:                64,832 KB         7-312     306  296 valid, 10 not so valid               219   KB/model             4.45/MB
// Weapons KB:             470               321-372   52   39 valid, 3 invalid(329,332,340)         470   KB all weapons
// Upgrades KB:            2,716             1000-1193 194  all valid                              2,716   KB all upgrades
// Vehicles(400-499) KB:   14,622                                                                    140   KB/model             7/MB
// Vehicles(500-599) KB:   14,888
//
///////////////////////////////////////////////////////////////
void CModelCacheManagerImpl::PreLoad ( void )
{
    if ( m_bDonePreLoad )
        return;

    m_bDonePreLoad = true;

    CTickCount startTicks = CTickCount::Now ();
#if 0
    for ( uint i = 321 ; i <= 372 ; i++ )
    {
        if ( CClientPedManager::IsValidWeaponModel ( i ) )
            AddModelRefCount ( i );
    }
#endif
    m_pGame->GetStreaming()->LoadAllRequestedModels ( false );

    // Get current limits
    int bSlowMethod = GetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_SLOW );
    int iLowestUnsafeUpgrade = GetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_LOWEST_UNSAFE );
    SetApplicationSetting( DIAG_CRASH_EXTRA_MSG, "** AUTO FIXING CRASH (Step 1/2) **\n\n** Please continue and connect to a server **" );

    // Crashed during previous PreLoad?
    if ( WatchDogIsSectionOpen( WD_SECTION_PRELOAD_UPGRADES ) )
    {
        AddReportLog( 8545, SString( "PreLoad Upgrades - Crash detect - bSlowMethod:%d  iLowestUnsafeUpgrade:%d", bSlowMethod, iLowestUnsafeUpgrade ) );
        iLowestUnsafeUpgrade = GetApplicationSettingInt( DIAG_PRELOAD_UPGRADE_ATTEMPT_ID );
        bSlowMethod = 1;
        SetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_LOWEST_UNSAFE, iLowestUnsafeUpgrade );
        SetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_SLOW, bSlowMethod );
        SetApplicationSetting( DIAG_CRASH_EXTRA_MSG, "** AUTO FIXING CRASH (Step 2/2) **\n\n** Please continue and connect to a server **" );
    }

    if ( iLowestUnsafeUpgrade == 0 )
        iLowestUnsafeUpgrade = 1194;

    // PreLoad upgrades
    WatchDogBeginSection( WD_SECTION_PRELOAD_UPGRADES );
    {
        for ( int i = 1000 ; i < iLowestUnsafeUpgrade ; i++ )
        {
            if ( bSlowMethod )
                SetApplicationSettingInt( DIAG_PRELOAD_UPGRADE_ATTEMPT_ID, i );
            AddModelRefCount ( i );
            if ( bSlowMethod )
                m_pGame->GetStreaming()->LoadAllRequestedModels ( false );
        }
        m_pGame->GetStreaming()->LoadAllRequestedModels ( false );
    }
    WatchDogCompletedSection( WD_SECTION_PRELOAD_UPGRADES );
    SetApplicationSetting( DIAG_CRASH_EXTRA_MSG, "" );

    // Report if LowestUnsafeUpgrade has fallen
    int iPrevHiScore = GetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_HISCORE );
    SetApplicationSettingInt( DIAG_PRELOAD_UPGRADES_HISCORE, iLowestUnsafeUpgrade );
    if ( iPrevHiScore > iLowestUnsafeUpgrade )
        AddReportLog( 8544, SString( "PreLoad Upgrades - LowestUnsafeUpgrade fallen from %d to %d", iPrevHiScore, iLowestUnsafeUpgrade ) );

    CTickCount deltaTicks = CTickCount::Now () - startTicks;
    OutputDebugLine ( SString ( "CModelCacheManagerImpl::PreLoad completed in %d ms", deltaTicks.ToInt () ) );
}
int SharedUtil::WatchDogGetCounter ( const SString& str )
{
    return GetApplicationSettingInt ( "watchdog", str );
}
Exemple #16
0
//////////////////////////////////////////////////////////
//
// BeginD3DStuff
//
// Look all busy and important in case any graphic drivers are looking
//
//////////////////////////////////////////////////////////
void BeginD3DStuff( void )
{
    pD3D9 = Direct3DCreate9( D3D_SDK_VERSION );

    if ( !pD3D9 )
    {
        WriteDebugEvent( "D3DStuff - Direct3DCreate9 failed" );
        return;
    }

    WriteDebugEvent( "D3DStuff -------------------------" );
    WriteDebugEvent( SString( "D3DStuff - Direct3DCreate9: 0x%08x", pD3D9 ) );

    bool bDetectedOptimus = false;
    bool bDetectedNVidia = false;
    // Get info about each connected adapter
    uint uiNumAdapters = pD3D9->GetAdapterCount();
    WriteDebugEvent( SString( "D3DStuff - %d Adapters", uiNumAdapters ) );

    for ( uint i = 0 ; i < uiNumAdapters ; i++ )
    {
        D3DADAPTER_IDENTIFIER9 Identifier;
        D3DDISPLAYMODE DisplayMode;
        D3DCAPS9 Caps9;

        HRESULT hr1 = pD3D9->GetAdapterIdentifier( i, 0, &Identifier );
        HRESULT hr2 = pD3D9->GetAdapterDisplayMode( i, &DisplayMode );
        HRESULT hr3 = pD3D9->GetDeviceCaps( i, D3DDEVTYPE_HAL, &Caps9 );
        UINT ModeCount = pD3D9->GetAdapterModeCount( i, D3DFMT_X8R8G8B8 );
        HMONITOR hMonitor = pD3D9->GetAdapterMonitor( i );

        if ( FAILED( hr1 ) || FAILED( hr2 ) || FAILED( hr3 ) )
        {
            WriteDebugEvent( SString( "D3DStuff %d Failed GetAdapterIdentifier(%x) GetAdapterDisplayMode(%x) GetDeviceCaps(%x) ", i, hr1, hr2, hr3 ) );
            continue;
        }

        // Detect Optimus combo
        if ( SStringX( Identifier.Driver ).BeginsWithI( "nv" )
            && SStringX( Identifier.Description ).BeginsWithI( "Intel" )
            )
        {
            bDetectedOptimus = true;
            WriteDebugEvent( SString( "D3DStuff %d - Detected Optimus Combo", i ) );
        }
        if ( GetModuleHandle( "nvd3d9wrap.dll" ) != NULL )
        {
            bDetectedOptimus = true;
            WriteDebugEvent( SString( "D3DStuff %d - Detected nvd3d9wrap", i ) );
        }
        if ( SStringX( Identifier.Driver ).BeginsWithI( "nv" ) )
        {
            bDetectedNVidia = true;
        }

        WriteDebugEvent( SString( "D3DStuff %d Identifier - %s", i, *ToString( Identifier ) ) );
        WriteDebugEvent( SString( "D3DStuff %d DisplayMode - %s", i, *ToString( DisplayMode ) ) );
        WriteDebugEvent( SString( "D3DStuff %d  hMonitor:0x%08x  ModeCount:%d", i, hMonitor, ModeCount ) );
        WriteDebugEvent( SString( "D3DStuff %d Caps9 - %s ", i, *ToString( Caps9 ) ) );
    }

    if ( GetApplicationSettingInt( "nvhacks", "optimus-force-detection" ) )
        bDetectedOptimus = true;

    if ( NvOptimusDetect() )
        bDetectedOptimus = true;

    SetApplicationSettingInt( "nvhacks", "optimus", bDetectedOptimus );
    SetApplicationSettingInt( "nvhacks", "nvidia", bDetectedNVidia );

    if ( bDetectedOptimus )
    {
        ShowOptimusDialog ( g_hInstance );
        HideOptimusDialog ();
    }
    else
    {
        SetApplicationSettingInt( "nvhacks", "optimus-alt-startup", 0 );
        SetApplicationSettingInt( "nvhacks", "optimus-rename-exe", 0 );
        SetApplicationSettingInt( "nvhacks", "optimus-export-enablement", 0 );
        SetApplicationSettingInt( "nvhacks", "optimus-force-windowed", 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();    
}
int SharedUtil::GetApplicationSettingInt ( const SString& strName )
{
    return GetApplicationSettingInt ( "general", strName );
}