Index: common/mptOS.cpp =================================================================== --- common/mptOS.cpp (revision 10963) +++ common/mptOS.cpp (working copy) @@ -589,6 +589,20 @@ } +std::vector GetSupportedProcessArchitectures(Architecture host) +{ + std::vector result; + for(const auto & entry : hostArchitectureCanRun) + { + if(entry.Host == host) + { + result.push_back(entry.Process); + } + } + return result; +} + + #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS @@ -629,6 +643,18 @@ #endif // MPT_OS_WINDOWS +uint64 GetSystemMemorySize() +{ + MEMORYSTATUSEX memoryStatus; + MemsetZero(memoryStatus); + memoryStatus.dwLength = sizeof(MEMORYSTATUSEX); + if(GlobalMemoryStatusEx(&memoryStatus) == 0) + { + return 0; + } + return memoryStatus.ullTotalPhys; +} + static bool SystemIsWine(bool allowDetection = true) { #if MPT_OS_WINDOWS Index: common/mptOS.h =================================================================== --- common/mptOS.h (revision 10963) +++ common/mptOS.h (working copy) @@ -183,11 +183,15 @@ EmulationLevel HostCanRun(Architecture host, Architecture process) noexcept; +std::vector GetSupportedProcessArchitectures(Architecture host); + #endif // MODPLUG_TRACKER && MPT_OS_WINDOWS #if defined(MODPLUG_TRACKER) +uint64 GetSystemMemorySize(); + void PreventWineDetection(); bool IsOriginal(); Index: common/versionNumber.h =================================================================== --- common/versionNumber.h (revision 10963) +++ common/versionNumber.h (working copy) @@ -21,7 +21,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 28 #define VER_MINOR 00 -#define VER_MINORMINOR 37 +#define VER_MINORMINOR 38 //Numerical value of the version. #define MPT_VERSION_CURRENT MAKE_VERSION_NUMERIC(VER_MAJORMAJOR,VER_MAJOR,VER_MINOR,VER_MINORMINOR) Index: mptrack/Mptrack.cpp =================================================================== --- mptrack/Mptrack.cpp (revision 10963) +++ mptrack/Mptrack.cpp (working copy) @@ -1071,8 +1071,25 @@ font.size = Clamp(Util::GetDPIy(m_pMainWnd->m_hWnd) / 96 - 1, 0, 9); TrackerSettings::Instance().patternFont = font; new WelcomeDlg(m_pMainWnd); + + TrackerSettings::Instance().UpdateStatisticsConsentAsked = true; + } else { + + // ask if user wants to contribute system statistics + if(!TrackerSettings::Instance().UpdateStatisticsConsentAsked) + { + TrackerSettings::Instance().UpdateStatistics = (ConfirmAnswer::cnfYes == Reporting::Confirm( + MPT_USTRING("Do you want to contribute to OpenMPT by providing system statistics?\r\n") + + MPT_USTRING("\r\n") + + mpt::String::Replace(CUpdateCheck::GetStatisticsUserInformation(false), MPT_USTRING("\n"), MPT_USTRING("\r\n")) + MPT_USTRING("\r\n") + + MPT_USTRING("\r\n") + + mpt::format(MPT_USTRING("This option was previously %1 on your system.\r\n"))(TrackerSettings::Instance().UpdateStatistics ? MPT_USTRING("enabled") : MPT_USTRING("disabled")), + false, !TrackerSettings::Instance().UpdateStatistics.Get())); + TrackerSettings::Instance().UpdateStatisticsConsentAsked = true; + } + // Update check CUpdateCheck::DoAutoUpdateCheck(); Index: mptrack/mptrack.rc =================================================================== --- mptrack/mptrack.rc (revision 10963) +++ mptrack/mptrack.rc (working copy) @@ -244,22 +244,25 @@ CAPTION "Update" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - GROUPBOX "Check for Updates",IDC_STATIC,6,6,276,66 - CONTROL "&Never",IDC_RADIO1,"Button",BS_AUTORADIOBUTTON,12,18,240,8 - CONTROL "&Daily",IDC_RADIO2,"Button",BS_AUTORADIOBUTTON,12,30,240,8 - CONTROL "&Weekly (recommended)",IDC_RADIO3,"Button",BS_AUTORADIOBUTTON,12,42,240,8 - CONTROL "&Monthly",IDC_RADIO4,"Button",BS_AUTORADIOBUTTON,12,54,240,8 - GROUPBOX "Privacy Settings",IDC_STATIC,6,78,276,54 - CONTROL "&Allow us to collect basic update statistics",IDC_CHECK1, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,90,246,12 - LTEXT "If enabled, a randomized user ID is created and transmitted with every update check. This ID can not be linked to you or your computer in any way.",IDC_STATIC,12,102,264,24 - GROUPBOX "Advanced Settings",IDC_STATIC,6,138,276,60 - LTEXT "&Update server URL:",IDC_STATIC,12,150,186,8 - EDITTEXT IDC_EDIT1,12,162,264,12,ES_AUTOHSCROLL - PUSHBUTTON "&Reset",IDC_BUTTON2,222,146,54,12 - LTEXT "Do not change this unless you are absolutely sure of what you are doing.",IDC_STATIC,12,180,264,12 - PUSHBUTTON "&Check for Updates",IDC_BUTTON1,6,204,84,18 - LTEXT "",IDC_LASTUPDATE,6,228,276,48 + CONTROL "Enable online Update &Check",IDC_CHECK_UPDATEENABLED, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,6,105,10 + GROUPBOX "Update Channel",IDC_STATIC_UDATECHANNEL,6,18,276,54 + CONTROL "release: official stable released versions only (recommended)",IDC_RADIO1, + "Button",BS_AUTORADIOBUTTON,12,30,211,10 + CONTROL "next: previews of the next official stable release",IDC_RADIO2, + "Button",BS_AUTORADIOBUTTON,12,42,171,10 + CONTROL "development: bleeding-edge development versions",IDC_RADIO3, + "Button",BS_AUTORADIOBUTTON,12,54,179,10 + GROUPBOX "Check for Updates",IDC_STATIC_UPDATECHECK,6,72,276,48 + LTEXT "&Automatically check on program start:",IDC_STATIC_UPDATEFREQUENCY,12,84,126,12,SS_CENTERIMAGE + COMBOBOX IDC_COMBO_UPDATEFREQUENCY,138,84,42,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + PUSHBUTTON "&Check now...",IDC_BUTTON1,216,84,60,12 + LTEXT "",IDC_LASTUPDATE,12,102,264,12 + GROUPBOX "Privacy Settings",IDC_STATIC_UPDATEPRIVACY,6,120,276,156 + CONTROL "&Allow OpenMPT to collect basic statistics about your system configuration",IDC_CHECK1, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,12,132,264,12 + LTEXT "",IDC_STATIC_UPDATEPRIVACYTEXT,12,144,264,36 + EDITTEXT IDC_EDIT_STATISTICS,12,180,264,90,ES_MULTILINE | ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | WS_VSCROLL | WS_HSCROLL END IDD_CLOSEDOCUMENTS DIALOGEX 0, 0, 370, 197 @@ -374,23 +377,26 @@ PUSHBUTTON "&Cancel",IDCANCEL,138,24,50,14 END -IDD_WECLOME DIALOGEX 0, 0, 256, 137 +IDD_WECLOME DIALOGEX 0, 0, 257, 261 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Welcome to OpenMPT!" FONT 8, "MS Shell Dlg", 400, 0, 0x1 BEGIN - DEFPUSHBUTTON "&OK",IDOK,198,116,50,14 + DEFPUSHBUTTON "&OK",IDOK,198,236,50,14 LTEXT "Please review the following settings before using this software:",IDC_STATIC,6,6,246,8 CONTROL "&Automatically check for new versions of OpenMPT",IDC_CHECK1, "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,24,246,10 + CONTROL "Help OpenMPT development by providing basic s&tatistics",IDC_CHECK3, + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,18,42,234,10 + LTEXT "Static",IDC_STATIC_WELCOME_STATISTICS,30,54,216,102 CONTROL "&Use a big font in the pattern editor",IDC_CHECK2, - "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,42,246,10 - LTEXT "&Default keyboard scheme:",IDC_STATIC,6,63,108,8 - COMBOBOX IDC_COMBO1,114,60,132,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - LTEXT "Scan for existing VST plugins in the following location:",IDC_STATIC,6,82,172,8 - PUSHBUTTON "&Scan",IDC_BUTTON2,198,79,50,14 - EDITTEXT IDC_EDIT1,6,95,240,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER - PUSHBUTTON "&More Settings",IDC_BUTTON1,6,116,60,14 + "Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,162,246,10 + LTEXT "&Default keyboard scheme:",IDC_STATIC,6,183,108,8 + COMBOBOX IDC_COMBO1,114,180,132,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + LTEXT "Scan for existing VST plugins in the following location:",IDC_STATIC,6,202,172,8 + PUSHBUTTON "&Scan",IDC_BUTTON2,198,199,50,14 + EDITTEXT IDC_EDIT1,6,215,240,12,ES_AUTOHSCROLL | ES_READONLY | NOT WS_BORDER + PUSHBUTTON "&More Settings",IDC_BUTTON1,6,236,60,14 END IDD_UPDATE DIALOGEX 0, 0, 196, 138 @@ -751,9 +757,9 @@ IDD_WECLOME, DIALOG BEGIN LEFTMARGIN, 7 - RIGHTMARGIN, 249 + RIGHTMARGIN, 250 TOPMARGIN, 7 - BOTTOMMARGIN, 130 + BOTTOMMARGIN, 254 END IDD_UPDATE, DIALOG @@ -931,7 +937,17 @@ 0, 100, 100, 0 END +IDD_OPTIONS_UPDATE AFX_DIALOG_LAYOUT +BEGIN + 0 +END +IDD_WECLOME AFX_DIALOG_LAYOUT +BEGIN + 0 +END + + ///////////////////////////////////////////////////////////////////////////// // // Dialog Info Index: mptrack/resource.h =================================================================== --- mptrack/resource.h (revision 10963) +++ mptrack/resource.h (working copy) @@ -975,6 +975,14 @@ #define IDC_BUTTON_TUNING_REMOVE 2501 #define IDC_STATIC_WINE_RTAUDIO 2502 #define IDC_COMBO_WINE_RTAUDIO 2503 +#define IDC_STATIC_UPDATECHECK 2504 +#define IDC_STATIC_UPDATEPRIVACY 2505 +#define IDC_STATIC_UDATECHANNEL 2506 +#define IDC_COMBO_UPDATEFREQUENCY 2507 +#define IDC_STATIC_UPDATEFREQUENCY 2508 +#define IDC_CHECK_UPDATEENABLED 2509 +#define IDC_STATIC_UPDATEPRIVACYTEXT 2510 +#define IDC_STATIC_WELCOME_STATISTICS 2511 #define ID_FILE_NEWMOD 32771 #define ID_FILE_NEWXM 32772 #define ID_FILE_NEWS3M 32773 @@ -1269,9 +1277,9 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_3D_CONTROLS 1 -#define _APS_NEXT_RESOURCE_VALUE 542 +#define _APS_NEXT_RESOURCE_VALUE 544 #define _APS_NEXT_COMMAND_VALUE 44646 -#define _APS_NEXT_CONTROL_VALUE 2504 +#define _APS_NEXT_CONTROL_VALUE 2512 #define _APS_NEXT_SYMED_VALUE 901 #endif #endif Index: mptrack/TrackerSettings.cpp =================================================================== --- mptrack/TrackerSettings.cpp (revision 10963) +++ mptrack/TrackerSettings.cpp (working copy) @@ -331,10 +331,19 @@ , vstHostVendorString(conf, MPT_USTRING("VST Plugins"), MPT_USTRING("HostVendorString"), "OpenMPT project") , vstHostVendorVersion(conf, MPT_USTRING("VST Plugins"), MPT_USTRING("HostVendorVersion"), Version::Current().GetRawVersion()) // Update + , UpdateEnabled(conf, MPT_USTRING("Update"), MPT_USTRING("Enabled"), true) , UpdateLastUpdateCheck(conf, MPT_USTRING("Update"), MPT_USTRING("LastUpdateCheck"), mpt::Date::Unix(time_t())) - , UpdateUpdateCheckPeriod(conf, MPT_USTRING("Update"), MPT_USTRING("UpdateCheckPeriod"), 7) - , UpdateUpdateURL(conf, MPT_USTRING("Update"), MPT_USTRING("UpdateURL"), CUpdateCheck::GetDefaultUpdateURL()) - , UpdateSendGUID(conf, MPT_USTRING("Update"), MPT_USTRING("SendGUID"), true) + , UpdateUpdateCheckPeriod_DEPRECATED(conf, MPT_USTRING("Update"), MPT_USTRING("UpdateCheckPeriod"), 7) + , UpdateIntervalDays(conf, MPT_USTRING("Update"), MPT_USTRING("UpdateCheckPeriodDays"), 7) + , UpdateChannel(conf, MPT_USTRING("Update"), MPT_USTRING("Channel"), UpdateChannelRelease) + , UpdateUpdateURL_DEPRECATED(conf, MPT_USTRING("Update"), MPT_USTRING("UpdateURL"), CUpdateCheck::GetDefaultChannelReleaseURL()) + , UpdateChannelReleaseURL(conf, MPT_USTRING("Update"), MPT_USTRING("ChannelReleaseURL"), CUpdateCheck::GetDefaultChannelReleaseURL()) + , UpdateChannelNextURL(conf, MPT_USTRING("Update"), MPT_USTRING("ChannelStableURL"), CUpdateCheck::GetDefaultChannelNextURL()) + , UpdateChannelDevelopmentURL(conf, MPT_USTRING("Update"), MPT_USTRING("ChannelDevelopmentURL"), CUpdateCheck::GetDefaultChannelDevelopmentURL()) + , UpdateAPIURL(conf, MPT_USTRING("Update"), MPT_USTRING("APIURL"), CUpdateCheck::GetDefaultAPIURL()) + , UpdateStatisticsConsentAsked(conf, MPT_USTRING("Update"), MPT_USTRING("StatistisConsentAsked"), false) + , UpdateStatistics(conf, MPT_USTRING("Update"), MPT_USTRING("Statistis"), false) + , UpdateSendGUID_DEPRECATED(conf, MPT_USTRING("Update"), MPT_USTRING("SendGUID"), false) , UpdateShowUpdateHint(conf, MPT_USTRING("Update"), MPT_USTRING("ShowUpdateHint"), true) , UpdateSuggestDifferentBuildVariant(conf, MPT_USTRING("Update"), MPT_USTRING("SuggestDifferentBuildVariant"), true) , UpdateIgnoreVersion(conf, MPT_USTRING("Update"), MPT_USTRING("IgnoreVersion"), _T("")) @@ -644,6 +653,47 @@ m_dwPatternSetup &= ~0x200; } + // Update + if(storedVersion < MAKE_VERSION_NUMERIC(1,28,00,38)) + { + if(UpdateUpdateCheckPeriod_DEPRECATED <= 0) + { + UpdateEnabled = true; + UpdateIntervalDays = -1; + } else + { + UpdateEnabled = true; + UpdateIntervalDays = UpdateUpdateCheckPeriod_DEPRECATED.Get(); + } + if(UpdateUpdateURL_DEPRECATED.Get() == MPT_USTRING("")) + { + UpdateChannel = UpdateChannelRelease; + } else if(UpdateUpdateURL_DEPRECATED.Get() == MPT_USTRING("http://www.soal.org/openmpt/OpenMPTversionCheck.php5")) + { + UpdateChannel = UpdateChannelRelease; + } else if(UpdateUpdateURL_DEPRECATED.Get() == MPT_USTRING("http://update.openmpt.org/check/$VERSION/$GUID")) + { + UpdateChannel = UpdateChannelRelease; + } else if(UpdateUpdateURL_DEPRECATED.Get() == MPT_USTRING("https://update.openmpt.org/check/$VERSION/$GUID")) + { + UpdateChannel = UpdateChannelRelease; + } else if(UpdateUpdateURL_DEPRECATED.Get() == MPT_USTRING("http://update.openmpt.org/check/testing/$VERSION/$GUID")) + { + UpdateChannel = UpdateChannelDevelopment; + } else if(UpdateUpdateURL_DEPRECATED.Get() == MPT_USTRING("https://update.openmpt.org/check/testing/$VERSION/$GUID")) + { + UpdateChannel = UpdateChannelDevelopment; + } else + { + UpdateChannel = UpdateChannelDevelopment; + UpdateChannelDevelopmentURL = UpdateUpdateURL_DEPRECATED.Get(); + } + UpdateStatistics = UpdateSendGUID_DEPRECATED.Get(); + conf.Forget(UpdateUpdateCheckPeriod_DEPRECATED.GetPath()); + conf.Forget(UpdateUpdateURL_DEPRECATED.GetPath()); + conf.Forget(UpdateSendGUID_DEPRECATED.GetPath()); + } + // Effects #ifndef NO_EQ FixupEQ(m_EqSettings); Index: mptrack/TrackerSettings.h =================================================================== --- mptrack/TrackerSettings.h (revision 10963) +++ mptrack/TrackerSettings.h (working copy) @@ -817,10 +817,19 @@ // Update + Setting UpdateEnabled; Setting UpdateLastUpdateCheck; - Setting UpdateUpdateCheckPeriod; - Setting UpdateUpdateURL; - Setting UpdateSendGUID; + Setting UpdateUpdateCheckPeriod_DEPRECATED; + Setting UpdateIntervalDays; + Setting UpdateChannel; + Setting UpdateUpdateURL_DEPRECATED; + Setting UpdateChannelReleaseURL; + Setting UpdateChannelNextURL; + Setting UpdateChannelDevelopmentURL; + Setting UpdateAPIURL; + Setting UpdateStatisticsConsentAsked; + Setting UpdateStatistics; + Setting UpdateSendGUID_DEPRECATED; Setting UpdateShowUpdateHint; Setting UpdateSuggestDifferentBuildVariant; Setting UpdateIgnoreVersion; Index: mptrack/UpdateCheck.cpp =================================================================== --- mptrack/UpdateCheck.cpp (revision 10963) +++ mptrack/UpdateCheck.cpp (working copy) @@ -13,6 +13,7 @@ #include "BuildVariants.h" #include "../common/version.h" #include "../common/misc_util.h" +#include "../common/mptStringBuffer.h" #include "Mptrack.h" #include "TrackerSettings.h" // Setup dialog stuff @@ -19,6 +20,7 @@ #include "Mainfrm.h" #include "../common/mptThread.h" #include "HTTP.h" +#include "../misc/JSON.h" OPENMPT_NAMESPACE_BEGIN @@ -83,13 +85,46 @@ +mpt::ustring CUpdateCheck::GetStatisticsUserInformation(bool shortText) +{ + if(shortText) + { + return MPT_USTRING("A randomized user ID is created and transmitted alongside. This ID can only be linked to you or your computer by this very ID, which is stored solely on your computer. OpenMPT will use this information to gather usage statistics and to plan removal of support for older systems. The following information will be sent:"); + } else + { + return MPT_USTRING("") + + MPT_USTRING("When checking for updates, OpenMPT can additionally collect some basic statistical information.") + MPT_USTRING("\n") + + MPT_USTRING("A randomized user ID is created and transmitted alongside the update check. This ID can only be linked to you or your computer by this very ID, which is stored solely on your computer.") + MPT_USTRING("\n") + + MPT_USTRING("OpenMPT will use this information to gather usage statistics and to plan removal of support for older systems.") + MPT_USTRING("\n") + + MPT_USTRING("Without this statistical information, the OpenMPT developers would be blind with respect to what systems are used to run OpenMPT. This makes deciding where to focus development plain guesswork.") + MPT_USTRING("\n") + + MPT_USTRING("OpenMPT collects the following statistical data points: OpenMPT version, Windows version, type of CPU, amount of RAM, configured update check frequency of OpenMPT.") + ; + } +} -mpt::ustring CUpdateCheck::GetDefaultUpdateURL() + +mpt::ustring CUpdateCheck::GetDefaultChannelReleaseURL() { return MPT_USTRING("https://update.openmpt.org/check/$VERSION/$GUID"); } +mpt::ustring CUpdateCheck::GetDefaultChannelNextURL() +{ + return MPT_USTRING("https://update.openmpt.org/check/next/$VERSION/$GUID"); +} +mpt::ustring CUpdateCheck::GetDefaultChannelDevelopmentURL() +{ + return MPT_USTRING("https://update.openmpt.org/check/testing/$VERSION/$GUID"); +} + + +mpt::ustring CUpdateCheck::GetDefaultAPIURL() +{ + return MPT_USTRING("https://update.openmpt.org/api/v3/"); +} + + std::atomic CUpdateCheck::s_InstanceCount(0); @@ -104,11 +139,15 @@ { if(isAutoUpdate) { - int updateCheckPeriod = TrackerSettings::Instance().UpdateUpdateCheckPeriod; - if(updateCheckPeriod == 0) + if(!TrackerSettings::Instance().UpdateEnabled) { return; } + int updateCheckPeriod = TrackerSettings::Instance().UpdateIntervalDays; + if(updateCheckPeriod < 0) + { + return; + } // Do we actually need to run the update check right now? const time_t now = time(nullptr); if(difftime(now, TrackerSettings::Instance().UpdateLastUpdateCheck.Get()) < (double)(updateCheckPeriod * 86400)) @@ -121,7 +160,7 @@ { TrackerSettings::Instance().UpdateShowUpdateHint = false; CString msg; - msg.Format(_T("OpenMPT would like to check for updates now, proceed?\n\nNote: In the future, OpenMPT will check for updates every %u days. If you do not want this, you can disable update checks in the setup."), TrackerSettings::Instance().UpdateUpdateCheckPeriod.Get()); + msg.Format(_T("OpenMPT would like to check for updates now, proceed?\n\nNote: In the future, OpenMPT will check for updates every %u days. If you do not want this, you can disable update checks in the setup."), TrackerSettings::Instance().UpdateIntervalDays.Get()); if(Reporting::Confirm(msg, _T("OpenMPT Internet Update")) == cnfNo) { TrackerSettings::Instance().UpdateLastUpdateCheck = mpt::Date::Unix(now); @@ -128,6 +167,15 @@ return; } } + } else + { + if(!TrackerSettings::Instance().UpdateEnabled) + { + if(Reporting::Confirm(_T("Update Check is disabled. Do you want to check anyway?"), _T("OpenMPT Internet Update")) != cnfYes) + { + return; + } + } } TrackerSettings::Instance().UpdateShowUpdateHint = false; @@ -137,22 +185,33 @@ return; } - CUpdateCheck::Settings settings; - settings.window = CMainFrame::GetMainFrame(); - settings.msgProgress = MPT_WM_APP_UPDATECHECK_PROGRESS; - settings.msgSuccess = MPT_WM_APP_UPDATECHECK_SUCCESS; - settings.msgFailure = MPT_WM_APP_UPDATECHECK_FAILURE; - settings.autoUpdate = isAutoUpdate; - settings.updateBaseURL = TrackerSettings::Instance().UpdateUpdateURL; - settings.sendStatistics = TrackerSettings::Instance().UpdateSendGUID; - settings.statisticsUUID = TrackerSettings::Instance().VersionInstallGUID; - settings.suggestDifferentBuilds = TrackerSettings::Instance().UpdateSuggestDifferentBuildVariant; - std::thread(CUpdateCheck::ThreadFunc(settings)).detach(); + CUpdateCheck::Context context; + context.window = CMainFrame::GetMainFrame(); + context.msgProgress = MPT_WM_APP_UPDATECHECK_PROGRESS; + context.msgSuccess = MPT_WM_APP_UPDATECHECK_SUCCESS; + context.msgFailure = MPT_WM_APP_UPDATECHECK_FAILURE; + context.autoUpdate = isAutoUpdate; + std::thread(CUpdateCheck::ThreadFunc(CUpdateCheck::Settings(), context)).detach(); } -CUpdateCheck::ThreadFunc::ThreadFunc(const CUpdateCheck::Settings &settings) +CUpdateCheck::Settings::Settings() + : periodDays(TrackerSettings::Instance().UpdateIntervalDays) + , channel(TrackerSettings::Instance().UpdateChannel) + , channelReleaseURL(TrackerSettings::Instance().UpdateChannelReleaseURL) + , channelNextURL(TrackerSettings::Instance().UpdateChannelNextURL) + , channelDevelopmentURL(TrackerSettings::Instance().UpdateChannelDevelopmentURL) + , apiURL(TrackerSettings::Instance().UpdateAPIURL) + , sendStatistics(TrackerSettings::Instance().UpdateStatistics) + , statisticsUUID(TrackerSettings::Instance().VersionInstallGUID) + , suggestDifferentBuilds(TrackerSettings::Instance().UpdateSuggestDifferentBuildVariant) +{ +} + + +CUpdateCheck::ThreadFunc::ThreadFunc(const CUpdateCheck::Settings &settings, const CUpdateCheck::Context &context) : settings(settings) + , context(context) { return; } @@ -160,27 +219,103 @@ void CUpdateCheck::ThreadFunc::operator () () { - mpt::SetCurrentThreadPriority(settings.autoUpdate ? mpt::ThreadPriorityLower : mpt::ThreadPriorityNormal); - CUpdateCheck::CheckForUpdate(settings); + mpt::SetCurrentThreadPriority(context.autoUpdate ? mpt::ThreadPriorityLower : mpt::ThreadPriorityNormal); + CUpdateCheck::CheckForUpdate(settings, context); } -// Run update check (independent thread) -CUpdateCheck::Result CUpdateCheck::SearchUpdate(const CUpdateCheck::Settings &settings) +std::string CUpdateCheck::GetStatisticsDataV3(const Settings &settings) { - - HTTP::InternetSession internet(Version::Current().GetOpenMPTVersionString()); + JSON::value j; + j["OpenMPT"]["Version"] = mpt::ufmt::val(Version::Current()); + j["OpenMPT"]["BuildVariant"] = BuildVariants().GuessCurrentBuildName(); + j["OpenMPT"]["Architecture"] = mpt::Windows::Name(mpt::Windows::GetProcessArchitecture()); + j["Update"]["PeriodDays"] = settings.periodDays; + j["System"]["Windows"]["Version"]["Name"] = mpt::Windows::Version::Current().GetName(); + j["System"]["Windows"]["Version"]["Major"] = mpt::Windows::Version::Current().GetSystem().Major; + j["System"]["Windows"]["Version"]["Minor"] = mpt::Windows::Version::Current().GetSystem().Minor; + j["System"]["Windows"]["ServicePack"]["Major"] = mpt::Windows::Version::Current().GetServicePack().Major; + j["System"]["Windows"]["ServicePack"]["Minor"] = mpt::Windows::Version::Current().GetServicePack().Minor; + j["System"]["Windows"]["Build"] = mpt::Windows::Version::Current().GetBuild(); + j["System"]["Windows"]["Architecture"] = mpt::Windows::Name(mpt::Windows::GetHostArchitecture()); + j["System"]["Windows"]["IsWine"] = mpt::Windows::IsWine(); + std::vector architectures = mpt::Windows::GetSupportedProcessArchitectures(mpt::Windows::GetHostArchitecture()); + for(const auto & arch : architectures) + { + j["System"]["Windows"]["ProcessArchitectures"][mpt::ToCharset(mpt::CharsetUTF8, mpt::Windows::Name(arch))] = true; + } + j["System"]["Memory"] = mpt::Windows::GetSystemMemorySize() / 1024 / 1024; // MB + if(mpt::Windows::IsWine()) + { + mpt::Wine::VersionContext v; + j["System"]["Windows"]["Wine"]["Version"]["Raw"] = v.RawVersion(); + if(v.Version().IsValid()) + { + j["System"]["Windows"]["Wine"]["Version"]["Major"] = v.Version().GetMajor(); + j["System"]["Windows"]["Wine"]["Version"]["Minor"] = v.Version().GetMinor(); + j["System"]["Windows"]["Wine"]["Version"]["Update"] = v.Version().GetUpdate(); + } + j["System"]["Windows"]["Wine"]["HostSysName"] = v.RawHostSysName(); + } + #ifdef ENABLE_ASM + j["System"]["Processor"]["Vendor"] = std::string(mpt::String::ReadAutoBuf(ProcVendorID)); + j["System"]["Processor"]["Brand"] = std::string(mpt::String::ReadAutoBuf(ProcBrandID)); + j["System"]["Processor"]["Id"]["Family"] = ProcFamily; + j["System"]["Processor"]["Id"]["Model"] = ProcModel; + j["System"]["Processor"]["Id"]["Stepping"] = ProcStepping; + j["System"]["Processor"]["Features"]["lm"] = ((GetRealProcSupport() & PROCSUPPORT_LM) ? true : false); + j["System"]["Processor"]["Features"]["cmov"] = ((GetRealProcSupport() & PROCSUPPORT_CMOV) ? true : false); + j["System"]["Processor"]["Features"]["mmx"] = ((GetRealProcSupport() & PROCSUPPORT_MMX) ? true : false); + j["System"]["Processor"]["Features"]["mmxext"] = ((GetRealProcSupport() & PROCSUPPORT_AMD_MMXEXT) ? true : false); + j["System"]["Processor"]["Features"]["3dnow"] = ((GetRealProcSupport() & PROCSUPPORT_AMD_3DNOW) ? true : false); + j["System"]["Processor"]["Features"]["3dnowext"] = ((GetRealProcSupport() & PROCSUPPORT_AMD_3DNOWEXT) ? true : false); + j["System"]["Processor"]["Features"]["sse"] = ((GetRealProcSupport() & PROCSUPPORT_SSE) ? true : false); + j["System"]["Processor"]["Features"]["sse2"] = ((GetRealProcSupport() & PROCSUPPORT_SSE2) ? true : false); + j["System"]["Processor"]["Features"]["sse3"] = ((GetRealProcSupport() & PROCSUPPORT_SSE3) ? true : false); + j["System"]["Processor"]["Features"]["ssse3"] = ((GetRealProcSupport() & PROCSUPPORT_SSSE3) ? true : false); + j["System"]["Processor"]["Features"]["sse4_1"] = ((GetRealProcSupport() & PROCSUPPORT_SSE4_1) ? true : false); + j["System"]["Processor"]["Features"]["sse4_2"] = ((GetRealProcSupport() & PROCSUPPORT_SSE4_2) ? true : false); + #endif + return j.dump(1, '\t'); +} - mpt::ustring updateURL = settings.updateBaseURL; - if(updateURL.empty()) + +mpt::ustring CUpdateCheck::GetUpdateURLV2(const CUpdateCheck::Settings &settings) +{ + mpt::ustring updateURL; + if(settings.channel == UpdateChannelRelease) { - updateURL = GetDefaultUpdateURL(); + updateURL = settings.channelReleaseURL; + if(updateURL.empty()) + { + updateURL = GetDefaultChannelReleaseURL(); + } + } else if(settings.channel == UpdateChannelNext) + { + updateURL = settings.channelNextURL; + if(updateURL.empty()) + { + updateURL = GetDefaultChannelNextURL(); + } + } else if(settings.channel == UpdateChannelDevelopment) + { + updateURL = settings.channelDevelopmentURL; + if(updateURL.empty()) + { + updateURL = GetDefaultChannelDevelopmentURL(); + } + } else + { + updateURL = settings.channelReleaseURL; + if(updateURL.empty()) + { + updateURL = GetDefaultChannelReleaseURL(); + } } if(updateURL.find(MPT_USTRING("://")) == mpt::ustring::npos) { updateURL = MPT_USTRING("https://") + updateURL; } - // Build update URL updateURL = mpt::String::Replace(updateURL, MPT_USTRING("$VERSION"), mpt::uformat(MPT_USTRING("%1-%2-%3")) ( Version::Current() @@ -188,15 +323,44 @@ , settings.sendStatistics ? mpt::Windows::Version::Current().GetNameShort() : MPT_USTRING("unknown") )); updateURL = mpt::String::Replace(updateURL, MPT_USTRING("$GUID"), settings.sendStatistics ? mpt::ufmt::val(settings.statisticsUUID) : MPT_USTRING("anonymous")); + return updateURL; +} + +// Run update check (independent thread) +CUpdateCheck::Result CUpdateCheck::SearchUpdate(const CUpdateCheck::Settings &settings) +{ + + HTTP::InternetSession internet(Version::Current().GetOpenMPTVersionString()); + // Establish a connection. HTTP::Request request; - request.SetURI(ParseURI(updateURL)); + request.SetURI(ParseURI(GetUpdateURLV2(settings))); request.method = HTTP::Method::Get; request.flags = HTTP::NoCache; HTTP::Result resultHTTP = internet(request.InsecureTLSDowngradeWindowsXP()); + if(settings.sendStatistics) + { + HTTP::Request requestStatistics; + if(settings.statisticsUUID.IsValid()) + { + requestStatistics.SetURI(ParseURI(settings.apiURL + mpt::format(MPT_USTRING("statistics/%1"))(settings.statisticsUUID))); + requestStatistics.method = HTTP::Method::Put; + } else + { + requestStatistics.SetURI(ParseURI(settings.apiURL + MPT_USTRING("statistics/"))); + requestStatistics.method = HTTP::Method::Post; + } + requestStatistics.dataMimeType = HTTP::MimeType::JSON(); + requestStatistics.acceptMimeTypes = HTTP::MimeTypes::JSON(); + std::string jsondata = GetStatisticsDataV3(settings); + MPT_LOG(LogInformation, "Update", mpt::ToUnicode(mpt::CharsetUTF8, jsondata)); + requestStatistics.data = mpt::byte_cast(mpt::as_span(jsondata)); + internet(requestStatistics.InsecureTLSDowngradeWindowsXP()); + } + // Retrieve HTTP status code. if(resultHTTP.Status >= 400) { @@ -244,12 +408,12 @@ } -void CUpdateCheck::CheckForUpdate(const CUpdateCheck::Settings &settings) +void CUpdateCheck::CheckForUpdate(const CUpdateCheck::Settings &settings, const CUpdateCheck::Context &context) { // íncremented before starting the thread MPT_ASSERT(s_InstanceCount.load() >= 1); CUpdateCheck::Result result; - settings.window->SendMessage(settings.msgProgress, settings.autoUpdate ? 1 : 0, s_InstanceCount.load()); + context.window->SendMessage(context.msgProgress, context.autoUpdate ? 1 : 0, s_InstanceCount.load()); try { try @@ -264,12 +428,12 @@ } } catch(const CUpdateCheck::Error &e) { - settings.window->SendMessage(settings.msgFailure, settings.autoUpdate ? 1 : 0, reinterpret_cast(&e)); + context.window->SendMessage(context.msgFailure, context.autoUpdate ? 1 : 0, reinterpret_cast(&e)); s_InstanceCount.fetch_sub(1); MPT_ASSERT(s_InstanceCount.load() >= 0); return; } - settings.window->SendMessage(settings.msgSuccess, settings.autoUpdate ? 1 : 0, reinterpret_cast(&result)); + context.window->SendMessage(context.msgSuccess, context.autoUpdate ? 1 : 0, reinterpret_cast(&result)); s_InstanceCount.fetch_sub(1); MPT_ASSERT(s_InstanceCount.load() >= 0); } @@ -347,14 +511,13 @@ // CUpdateSetupDlg BEGIN_MESSAGE_MAP(CUpdateSetupDlg, CPropertyPage) - ON_COMMAND(IDC_BUTTON1, &CUpdateSetupDlg::OnCheckNow) - ON_COMMAND(IDC_BUTTON2, &CUpdateSetupDlg::OnResetURL) - ON_COMMAND(IDC_RADIO1, &CUpdateSetupDlg::OnSettingsChanged) - ON_COMMAND(IDC_RADIO2, &CUpdateSetupDlg::OnSettingsChanged) - ON_COMMAND(IDC_RADIO3, &CUpdateSetupDlg::OnSettingsChanged) - ON_COMMAND(IDC_RADIO4, &CUpdateSetupDlg::OnSettingsChanged) - ON_COMMAND(IDC_CHECK1, &CUpdateSetupDlg::OnSettingsChanged) - ON_EN_CHANGE(IDC_EDIT1, &CUpdateSetupDlg::OnSettingsChanged) + ON_COMMAND(IDC_CHECK_UPDATEENABLED, &CUpdateSetupDlg::OnSettingsChanged) + ON_COMMAND(IDC_RADIO1, &CUpdateSetupDlg::OnSettingsChanged) + ON_COMMAND(IDC_RADIO2, &CUpdateSetupDlg::OnSettingsChanged) + ON_COMMAND(IDC_RADIO3, &CUpdateSetupDlg::OnSettingsChanged) + ON_COMMAND(IDC_BUTTON1, &CUpdateSetupDlg::OnCheckNow) + ON_CBN_SELCHANGE(IDC_COMBO_UPDATEFREQUENCY, &CUpdateSetupDlg::OnSettingsChanged) + ON_COMMAND(IDC_CHECK1, &CUpdateSetupDlg::OnSettingsChanged) END_MESSAGE_MAP() @@ -366,29 +529,82 @@ } +void CUpdateSetupDlg::DoDataExchange(CDataExchange *pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO_UPDATEFREQUENCY, m_CbnUpdateFrequency); +} + + BOOL CUpdateSetupDlg::OnInitDialog() { CPropertyPage::OnInitDialog(); + CheckDlgButton(IDC_CHECK_UPDATEENABLED, TrackerSettings::Instance().UpdateEnabled ? BST_CHECKED : BST_UNCHECKED); + int radioID = 0; - int periodDays = TrackerSettings::Instance().UpdateUpdateCheckPeriod; - if(periodDays >= 30) + int updateChannel = TrackerSettings::Instance().UpdateChannel; + if(updateChannel == UpdateChannelRelease) { - radioID = IDC_RADIO4; - } else if(periodDays >= 7) + radioID = IDC_RADIO1; + } else if(updateChannel == UpdateChannelNext) { + radioID = IDC_RADIO2; + } else if(updateChannel == UpdateChannelDevelopment) + { radioID = IDC_RADIO3; - } else if(periodDays >= 1) - { - radioID = IDC_RADIO2; } else { radioID = IDC_RADIO1; } - CheckRadioButton(IDC_RADIO1, IDC_RADIO4, radioID); - CheckDlgButton(IDC_CHECK1, TrackerSettings::Instance().UpdateSendGUID ? BST_CHECKED : BST_UNCHECKED); - SetDlgItemText(IDC_EDIT1, mpt::ToCString(TrackerSettings::Instance().UpdateUpdateURL.Get())); + CheckRadioButton(IDC_RADIO1, IDC_RADIO3, radioID); + int32 periodDays = TrackerSettings::Instance().UpdateIntervalDays; + int ndx; + + ndx = m_CbnUpdateFrequency.AddString(_T("always")); + m_CbnUpdateFrequency.SetItemData(ndx, 0); + if(periodDays >= 30) + { + m_CbnUpdateFrequency.SetCurSel(ndx); + } + + ndx = m_CbnUpdateFrequency.AddString(_T("daily")); + m_CbnUpdateFrequency.SetItemData(ndx, 1); + if(periodDays >= 30) + { + m_CbnUpdateFrequency.SetCurSel(ndx); + } + + ndx = m_CbnUpdateFrequency.AddString(_T("weekly")); + m_CbnUpdateFrequency.SetItemData(ndx, 7); + if(periodDays >= 7) + { + m_CbnUpdateFrequency.SetCurSel(ndx); + } + + ndx = m_CbnUpdateFrequency.AddString(_T("monthly")); + m_CbnUpdateFrequency.SetItemData(ndx, 30); + if(periodDays >= 0) + { + m_CbnUpdateFrequency.SetCurSel(ndx); + } + + ndx = m_CbnUpdateFrequency.AddString(_T("never")); + m_CbnUpdateFrequency.SetItemData(ndx, ~(DWORD_PTR)0); + if(periodDays < 0) + { + m_CbnUpdateFrequency.SetCurSel(ndx); + } + + CheckDlgButton(IDC_CHECK1, TrackerSettings::Instance().UpdateStatistics ? BST_CHECKED : BST_UNCHECKED); + + GetDlgItem(IDC_STATIC_UPDATEPRIVACYTEXT)->SetWindowText(mpt::ToCString(CUpdateCheck::GetStatisticsUserInformation(true))); + + UpdateStatistics(); + + EnableDisableDialog(); + m_SettingChangedNotifyGuard.Register(this); SettingChanged(TrackerSettings::Instance().UpdateLastUpdateCheck.GetPath()); @@ -396,6 +612,43 @@ } +void CUpdateSetupDlg::UpdateStatistics() +{ + CUpdateCheck::Settings settings; + + int updateChannel = TrackerSettings::Instance().UpdateChannel; + if(IsDlgButtonChecked(IDC_RADIO1)) updateChannel = UpdateChannelRelease; + if(IsDlgButtonChecked(IDC_RADIO2)) updateChannel = UpdateChannelNext; + if(IsDlgButtonChecked(IDC_RADIO3)) updateChannel = UpdateChannelDevelopment; + + int updateCheckPeriod = (m_CbnUpdateFrequency.GetItemData(m_CbnUpdateFrequency.GetCurSel()) == ~(DWORD_PTR)0) ? -1 : static_cast(m_CbnUpdateFrequency.GetItemData(m_CbnUpdateFrequency.GetCurSel())); + + CString updateURL; + GetDlgItemText(IDC_EDIT1, updateURL); + + settings.periodDays = updateCheckPeriod; + settings.channel = updateChannel; + settings.sendStatistics = (IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED); + + mpt::ustring statistics; + statistics += MPT_USTRING("GET ") + CUpdateCheck::GetUpdateURLV2(settings) + MPT_ULITERAL("\n"); + statistics += MPT_ULITERAL("\n"); + if(settings.sendStatistics) + { + if(settings.statisticsUUID.IsValid()) + { + statistics += MPT_USTRING("PUT ") + settings.apiURL + mpt::format(MPT_USTRING("statistics/%1"))(settings.statisticsUUID) + MPT_ULITERAL("\n"); + } else + { + statistics += MPT_USTRING("POST ") + settings.apiURL + MPT_USTRING("statistics/") + MPT_ULITERAL("\n"); + } + statistics += mpt::String::Replace(mpt::ToUnicode(mpt::CharsetUTF8, CUpdateCheck::GetStatisticsDataV3(settings)), MPT_USTRING("\t"), MPT_USTRING(" ")); + statistics += MPT_ULITERAL("\n"); + } + SetDlgItemText(IDC_EDIT_STATISTICS, mpt::ToCString(mpt::String::Replace(statistics, MPT_USTRING("\n"), MPT_USTRING("\r\n")))); +} + + void CUpdateSetupDlg::SettingChanged(const SettingPath &changedPath) { if(changedPath == TrackerSettings::Instance().UpdateLastUpdateCheck.GetPath()) @@ -420,20 +673,61 @@ } +void CUpdateSetupDlg::EnableDisableDialog() +{ + + BOOL status = ((IsDlgButtonChecked(IDC_CHECK_UPDATEENABLED) != BST_UNCHECKED) ? TRUE : FALSE); + + GetDlgItem(IDC_STATIC_UDATECHANNEL)->EnableWindow(status); + GetDlgItem(IDC_RADIO1)->EnableWindow(status); + GetDlgItem(IDC_RADIO2)->EnableWindow(status); + GetDlgItem(IDC_RADIO3)->EnableWindow(status); + + GetDlgItem(IDC_STATIC_UPDATECHECK)->EnableWindow(status); + GetDlgItem(IDC_STATIC_UPDATEFREQUENCY)->EnableWindow(status); + GetDlgItem(IDC_COMBO_UPDATEFREQUENCY)->EnableWindow(status); + GetDlgItem(IDC_BUTTON1)->EnableWindow(status); + GetDlgItem(IDC_LASTUPDATE)->EnableWindow(status); + + GetDlgItem(IDC_STATIC_UPDATEPRIVACY)->EnableWindow(status); + GetDlgItem(IDC_CHECK1)->EnableWindow(status); + GetDlgItem(IDC_STATIC_UPDATEPRIVACYTEXT)->EnableWindow(status); + GetDlgItem(IDC_EDIT_STATISTICS)->EnableWindow(status); + + // disabled features + GetDlgItem(IDC_CHECK_UPDATEENABLED)->EnableWindow(FALSE); + GetDlgItem(IDC_RADIO2)->EnableWindow(FALSE); + +} + + +void CUpdateSetupDlg::OnSettingsChanged() +{ + EnableDisableDialog(); + UpdateStatistics(); + SetModified(TRUE); +} + + void CUpdateSetupDlg::OnOK() { - int updateCheckPeriod = TrackerSettings::Instance().UpdateUpdateCheckPeriod; - if(IsDlgButtonChecked(IDC_RADIO1)) updateCheckPeriod = 0; - if(IsDlgButtonChecked(IDC_RADIO2)) updateCheckPeriod = 1; - if(IsDlgButtonChecked(IDC_RADIO3)) updateCheckPeriod = 7; - if(IsDlgButtonChecked(IDC_RADIO4)) updateCheckPeriod = 31; + int updateChannel = TrackerSettings::Instance().UpdateChannel; + if(IsDlgButtonChecked(IDC_RADIO1)) updateChannel = UpdateChannelRelease; + if(IsDlgButtonChecked(IDC_RADIO2)) updateChannel = UpdateChannelNext; + if(IsDlgButtonChecked(IDC_RADIO3)) updateChannel = UpdateChannelDevelopment; + int updateCheckPeriod = (m_CbnUpdateFrequency.GetItemData(m_CbnUpdateFrequency.GetCurSel()) == ~(DWORD_PTR)0) ? -1 : static_cast(m_CbnUpdateFrequency.GetItemData(m_CbnUpdateFrequency.GetCurSel())); + CString updateURL; GetDlgItemText(IDC_EDIT1, updateURL); - TrackerSettings::Instance().UpdateUpdateCheckPeriod = updateCheckPeriod; - TrackerSettings::Instance().UpdateUpdateURL = mpt::ToUnicode(updateURL); - TrackerSettings::Instance().UpdateSendGUID = (IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED); + if(GetDlgItem(IDC_CHECK_UPDATEENABLED)->IsWindowEnabled() != FALSE) + { + TrackerSettings::Instance().UpdateEnabled = (IsDlgButtonChecked(IDC_CHECK_UPDATEENABLED) != BST_UNCHECKED); + } + TrackerSettings::Instance().UpdateIntervalDays = updateCheckPeriod; + TrackerSettings::Instance().UpdateChannel = updateChannel; + TrackerSettings::Instance().UpdateStatistics = (IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED); CPropertyPage::OnOK(); } @@ -452,10 +746,4 @@ } -void CUpdateSetupDlg::OnResetURL() -{ - SetDlgItemText(IDC_EDIT1, mpt::ToCString(CUpdateCheck::GetDefaultUpdateURL())); -} - - OPENMPT_NAMESPACE_END Index: mptrack/UpdateCheck.h =================================================================== --- mptrack/UpdateCheck.h (revision 10963) +++ mptrack/UpdateCheck.h (working copy) @@ -24,6 +24,13 @@ OPENMPT_NAMESPACE_BEGIN +enum UpdateChannel +{ + UpdateChannelRelease = 1, + UpdateChannelNext = 2, + UpdateChannelDevelopment = 3, +}; + class CUpdateCheck { @@ -33,7 +40,13 @@ public: - static mpt::ustring GetDefaultUpdateURL(); + static mpt::ustring GetStatisticsUserInformation(bool shortText); + + static mpt::ustring GetDefaultChannelReleaseURL(); + static mpt::ustring GetDefaultChannelNextURL(); + static mpt::ustring GetDefaultChannelDevelopmentURL(); + + static mpt::ustring GetDefaultAPIURL(); int32 GetNumCurrentRunningInstances(); @@ -42,7 +55,7 @@ public: - struct Settings + struct Context { CWnd *window; UINT msgProgress; @@ -49,10 +62,20 @@ UINT msgSuccess; UINT msgFailure; bool autoUpdate; - mpt::ustring updateBaseURL; // URL where the version check should be made. + }; + + struct Settings + { + int32 periodDays; + uint32 channel; + mpt::ustring channelReleaseURL; + mpt::ustring channelNextURL; + mpt::ustring channelDevelopmentURL; + mpt::ustring apiURL; bool sendStatistics; mpt::UUID statisticsUUID; bool suggestDifferentBuilds; + Settings(); }; class Error @@ -86,6 +109,14 @@ static void ShowSuccessGUI(WPARAM wparam, LPARAM lparam); static void ShowFailureGUI(WPARAM wparam, LPARAM lparam); +public: + + // v2 + static mpt::ustring GetUpdateURLV2(const Settings &settings); + + // v3 + static std::string GetStatisticsDataV3(const Settings &settings); // UTF8 + protected: static void StartUpdateCheckAsync(bool autoUpdate); @@ -93,11 +124,12 @@ struct ThreadFunc { CUpdateCheck::Settings settings; - ThreadFunc(const CUpdateCheck::Settings &settings); + CUpdateCheck::Context context; + ThreadFunc(const CUpdateCheck::Settings &settings, const CUpdateCheck::Context &context); void operator () (); }; - static void CheckForUpdate(const CUpdateCheck::Settings &settings); + static void CheckForUpdate(const CUpdateCheck::Settings &settings, const CUpdateCheck::Context &context); static CUpdateCheck::Result SearchUpdate(const CUpdateCheck::Settings &settings); // may throw @@ -111,17 +143,20 @@ CUpdateSetupDlg(); protected: + virtual void DoDataExchange(CDataExchange *pDX); virtual BOOL OnInitDialog(); virtual void OnOK(); virtual BOOL OnSetActive(); - afx_msg void OnSettingsChanged() { SetModified(TRUE); } + afx_msg void OnSettingsChanged(); afx_msg void OnCheckNow(); - afx_msg void OnResetURL(); virtual void SettingChanged(const SettingPath &changedPath); + void EnableDisableDialog(); + void UpdateStatistics(); DECLARE_MESSAGE_MAP() private: SettingChangedNotifyGuard m_SettingChangedNotifyGuard; + CComboBox m_CbnUpdateFrequency; }; Index: mptrack/WelcomeDialog.cpp =================================================================== --- mptrack/WelcomeDialog.cpp (revision 10963) +++ mptrack/WelcomeDialog.cpp (working copy) @@ -119,6 +119,8 @@ combo->SetItemDataPtr(combo->AddString(_T("FastTracker 2")), (void*)("US_mpt-ft2_classic")); CheckDlgButton(IDC_CHECK1, BST_CHECKED); + CheckDlgButton(IDC_CHECK3, BST_UNCHECKED); + GetDlgItem(IDC_STATIC_WELCOME_STATISTICS)->SetWindowText(mpt::ToCString(mpt::String::Replace(CUpdateCheck::GetStatisticsUserInformation(false), MPT_USTRING("\n"), MPT_USTRING(" ")))); CheckDlgButton(IDC_CHECK2, (TrackerSettings::Instance().patternFont.Get().name == PATTERNFONT_LARGE) ? BST_CHECKED : BST_UNCHECKED); ShowWindow(SW_SHOW); @@ -147,7 +149,8 @@ CDialog::OnOK(); bool runUpdates = IsDlgButtonChecked(IDC_CHECK1) != BST_UNCHECKED; - TrackerSettings::Instance().UpdateUpdateCheckPeriod = (runUpdates ? 7 : 0); + TrackerSettings::Instance().UpdateIntervalDays = (runUpdates ? 7 : 0); + TrackerSettings::Instance().UpdateStatistics = (IsDlgButtonChecked(IDC_CHECK3) != BST_UNCHECKED); if(IsDlgButtonChecked(IDC_CHECK2) != BST_UNCHECKED) { FontSetting font = TrackerSettings::Instance().patternFont;