From 98faa15d6277dbc9256841bda08edf9ee38f7c7d Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 27 Apr 2016 21:20:27 +0100 Subject: [PATCH 1/2] Add an opt-out prompt for system information collection. --- OpenRA.Game/Settings.cs | 1 + .../Widgets/Logic/MainMenuLogic.cs | 102 ++++++++++++++---- mods/cnc/chrome/mainmenu.yaml | 60 +++++++++++ mods/d2k/chrome/mainmenu.yaml | 55 ++++++++++ mods/ra/chrome/mainmenu.yaml | 55 ++++++++++ 5 files changed, 250 insertions(+), 23 deletions(-) diff --git a/OpenRA.Game/Settings.cs b/OpenRA.Game/Settings.cs index 5e1109e49e..ac080a5706 100644 --- a/OpenRA.Game/Settings.cs +++ b/OpenRA.Game/Settings.cs @@ -101,6 +101,7 @@ namespace OpenRA public int Samples = 25; public bool IgnoreVersionMismatch = false; public bool SendSystemInformation = true; + public int SystemInformationVersionPrompt = 0; public string UUID = System.Guid.NewGuid().ToString(); } diff --git a/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs index 835df544d2..ff0a6aa02e 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MainMenuLogic.cs @@ -12,16 +12,20 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.IO; using System.Linq; using System.Net; +using OpenRA.Primitives; using OpenRA.Widgets; namespace OpenRA.Mods.Common.Widgets.Logic { + [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1203:ConstantsMustAppearBeforeFields", + Justification = "SystemInformation version should be defined next to the dictionary it refers to.")] public class MainMenuLogic : ChromeLogic { - protected enum MenuType { Main, Singleplayer, Extras, MapEditor, None } + protected enum MenuType { Main, Singleplayer, Extras, MapEditor, SystemInfoPrompt, None } protected MenuType menuType = MenuType.Main; readonly Widget rootMenu; @@ -32,6 +36,22 @@ namespace OpenRA.Mods.Common.Widgets.Logic // Update news once per game launch static bool fetchedNews; + // Increment the version number when adding new stats + const int SystemInformationVersion = 1; + Dictionary> GetSystemInformation() + { + var lang = System.Globalization.CultureInfo.InstalledUICulture.TwoLetterISOLanguageName; + return new Dictionary>() + { + { "id", Pair.New("Anonymous ID", Game.Settings.Debug.UUID) }, + { "platform", Pair.New("OS Type", Platform.CurrentPlatform.ToString()) }, + { "os", Pair.New("OS Version", Environment.OSVersion.ToString()) }, + { "runtime", Pair.New(".NET Runtime", Platform.RuntimeVersion) }, + { "gl", Pair.New("OpenGL Version", Game.Renderer.GLVersion) }, + { "lang", Pair.New("System Language", lang) } + }; + } + void SwitchMenu(MenuType type) { menuType = type; @@ -201,7 +221,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var newsBG = widget.GetOrNull("NEWS_BG"); if (newsBG != null) { - newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None; + newsBG.IsVisible = () => Game.Settings.Game.FetchNews && menuType != MenuType.None && menuType != MenuType.SystemInfoPrompt; newsPanel = Ui.LoadWidget("NEWS_PANEL", null, new WidgetArgs()); newsTemplate = newsPanel.Get("NEWS_ITEM_TEMPLATE"); @@ -209,26 +229,79 @@ namespace OpenRA.Mods.Common.Widgets.Logic newsStatus = newsPanel.Get("NEWS_STATUS"); SetNewsStatus("Loading news"); + } + Game.OnRemoteDirectConnect += OnRemoteDirectConnect; + + // System information opt-out prompt + var sysInfoPrompt = widget.Get("SYSTEM_INFO_PROMPT"); + sysInfoPrompt.IsVisible = () => menuType == MenuType.SystemInfoPrompt; + if (Game.Settings.Debug.SystemInformationVersionPrompt < SystemInformationVersion) + { + menuType = MenuType.SystemInfoPrompt; + + var sysInfoCheckbox = sysInfoPrompt.Get("SYSINFO_CHECKBOX"); + sysInfoCheckbox.IsChecked = () => Game.Settings.Debug.SendSystemInformation; + sysInfoCheckbox.OnClick = () => Game.Settings.Debug.SendSystemInformation ^= true; + + var sysInfoData = sysInfoPrompt.Get("SYSINFO_DATA"); + var template = sysInfoData.Get("DATA_TEMPLATE"); + sysInfoData.RemoveChildren(); + + foreach (var info in GetSystemInformation().Values) + { + var label = template.Clone() as LabelWidget; + var text = info.First + ": " + info.Second; + label.GetText = () => text; + sysInfoData.AddChild(label); + } + + sysInfoPrompt.Get("BACK_BUTTON").OnClick = () => + { + Game.Settings.Debug.SystemInformationVersionPrompt = SystemInformationVersion; + Game.Settings.Save(); + SwitchMenu(MenuType.Main); + LoadAndDisplayNews(newsBG); + }; + } + else + LoadAndDisplayNews(newsBG); + } + + void LoadAndDisplayNews(Widget newsBG) + { + if (newsBG != null) + { var cacheFile = Platform.ResolvePath("^", "news.yaml"); var currentNews = ParseNews(cacheFile); if (currentNews != null) DisplayNews(currentNews); var newsButton = newsBG.GetOrNull("NEWS_BUTTON"); - if (newsButton != null) { if (!fetchedNews) - new Download(Game.Settings.Game.NewsUrl + SysInfoQuery(), cacheFile, e => { }, + { + // Send the mod and engine version to support version-filtered news (update prompts) + var newsURL = Game.Settings.Game.NewsUrl + "?version={0}&mod={1}&modversion={2}".F( + Uri.EscapeUriString(ModMetadata.AllMods["modchooser"].Version), + Uri.EscapeUriString(Game.ModData.Manifest.Mod.Id), + Uri.EscapeUriString(Game.ModData.Manifest.Mod.Version)); + + // Append system profile data if the player has opted in + if (Game.Settings.Debug.SendSystemInformation) + newsURL += "&" + GetSystemInformation() + .Select(kv => kv.Key + "=" + Uri.EscapeUriString(kv.Value.Second)) + .JoinWith("&"); + + new Download(newsURL, cacheFile, e => { }, (e, c) => NewsDownloadComplete(e, cacheFile, currentNews, () => newsButton.AttachPanel(newsPanel))); + } newsButton.OnClick = () => newsButton.AttachPanel(newsPanel); } } - - Game.OnRemoteDirectConnect += OnRemoteDirectConnect; } void OnRemoteDirectConnect(string host, int port) @@ -252,23 +325,6 @@ namespace OpenRA.Mods.Common.Widgets.Logic () => { Game.CloseServer(); SwitchMenu(MenuType.MapEditor); }); } - string SysInfoQuery() - { - if (!Game.Settings.Debug.SendSystemInformation) - return null; - - return "?id={0}&platform={1}&os={2}&runtime={3}&gl={4}&lang={5}&version={6}&mod={7}&modversion={8}".F( - Uri.EscapeUriString(Game.Settings.Debug.UUID), - Uri.EscapeUriString(Platform.CurrentPlatform.ToString()), - Uri.EscapeUriString(Environment.OSVersion.ToString()), - Uri.EscapeUriString(Platform.RuntimeVersion), - Uri.EscapeUriString(Game.Renderer.GLVersion), - Uri.EscapeUriString(System.Globalization.CultureInfo.InstalledUICulture.TwoLetterISOLanguageName), - Uri.EscapeUriString(ModMetadata.AllMods["modchooser"].Version), - Uri.EscapeUriString(Game.ModData.Manifest.Mod.Id), - Uri.EscapeUriString(Game.ModData.Manifest.Mod.Version)); - } - void SetNewsStatus(string message) { message = WidgetUtils.WrapText(message, newsStatus.Bounds.Width, Game.Renderer.Fonts[newsStatus.Font]); diff --git a/mods/cnc/chrome/mainmenu.yaml b/mods/cnc/chrome/mainmenu.yaml index 8595450618..9641b6e1d1 100644 --- a/mods/cnc/chrome/mainmenu.yaml +++ b/mods/cnc/chrome/mainmenu.yaml @@ -226,6 +226,66 @@ Container@MENU_BACKGROUND: Text: Back Font: Bold Key: escape + Container@SYSTEM_INFO_PROMPT: + X: (WINDOW_RIGHT - WIDTH)/2 + Y: (WINDOW_BOTTOM - HEIGHT)/2 + Width: 490 + Height: 222 + Children: + Label@TITLE: + Width: PARENT_RIGHT + Y: 0-25 + Font: BigBold + Contrast: true + Align: Center + Text: System Information + Background@bg: + Width: PARENT_RIGHT + Height: PARENT_BOTTOM + Background: panel-black + Children: + Label@PROMPT_TEXT_A: + X: 15 + Y: 15 + Width: PARENT_RIGHT - 30 + Height: 16 + Align: Center + Text: We would like to collect some details that will help us optimize OpenRA. + Label@PROMPT_TEXT_B: + X: 15 + Y: 33 + Width: PARENT_RIGHT - 30 + Height: 16 + Align: Center + Text: With your permission, the following anonymous system data will be sent: + ScrollPanel@SYSINFO_DATA: + X: 15 + Y: 63 + Width: PARENT_RIGHT - 30 + TopBottomSpacing: 4 + ItemSpacing: 4 + Height: 110 + Children: + Label@DATA_TEMPLATE: + X: 8 + Height: 13 + VAlign: Top + Font: Small + Checkbox@SYSINFO_CHECKBOX: + X: PARENT_RIGHT - 15 - WIDTH + Y: PARENT_BOTTOM - 35 + Width: 190 + Height: 20 + Font: Regular + Text: Send System Information + Button@BACK_BUTTON: + X: PARENT_RIGHT - WIDTH + Y: PARENT_BOTTOM - 1 + Width: 140 + Height: 35 + Text: Continue + Font: Bold + Key: return Container@NEWS_BG: Children: DropDownButton@NEWS_BUTTON: diff --git a/mods/d2k/chrome/mainmenu.yaml b/mods/d2k/chrome/mainmenu.yaml index e1bd9fb749..5b363c01fd 100644 --- a/mods/d2k/chrome/mainmenu.yaml +++ b/mods/d2k/chrome/mainmenu.yaml @@ -190,6 +190,61 @@ Container@MAINMENU: Height: 30 Text: Back Font: Bold + Background@SYSTEM_INFO_PROMPT: + X: (WINDOW_RIGHT - WIDTH)/2 + Y: (WINDOW_BOTTOM - HEIGHT)/2 + Width: 520 + Height: 260 + Children: + Label@PROMPT_TITLE: + Width: PARENT_RIGHT + Y: 20 + Height: 25 + Font: Bold + Align: Center + Text: System Information + Label@PROMPT_TEXT_A: + X: 15 + Y: 50 + Width: PARENT_RIGHT - 30 + Height: 16 + Align: Center + Text: We would like to collect some details that will help us optimize OpenRA. + Label@PROMPT_TEXT_B: + X: 15 + Y: 68 + Width: PARENT_RIGHT - 30 + Height: 16 + Align: Center + Text: With your permission, the following anonymous system data will be sent: + ScrollPanel@SYSINFO_DATA: + X: 20 + Y: 98 + Width: PARENT_RIGHT - 40 + TopBottomSpacing: 4 + ItemSpacing: 4 + Height: 110 + Children: + Label@DATA_TEMPLATE: + X: 8 + Height: 13 + VAlign: Top + Font: Small + Checkbox@SYSINFO_CHECKBOX: + X: 40 + Y: PARENT_BOTTOM - 42 + Width: 200 + Height: 20 + Font: Regular + Text: Send System Information + Button@BACK_BUTTON: + X: PARENT_RIGHT - WIDTH - 20 + Y: PARENT_BOTTOM - 45 + Width: 120 + Height: 25 + Text: Continue + Font: Bold + Key: return Background@NEWS_BG: X: (WINDOW_RIGHT - WIDTH)/2 Y: 35 diff --git a/mods/ra/chrome/mainmenu.yaml b/mods/ra/chrome/mainmenu.yaml index 66ea1fcd87..cc978ce808 100644 --- a/mods/ra/chrome/mainmenu.yaml +++ b/mods/ra/chrome/mainmenu.yaml @@ -203,6 +203,61 @@ Container@MAINMENU: Height: 30 Text: Back Font: Bold + Background@SYSTEM_INFO_PROMPT: + X: (WINDOW_RIGHT - WIDTH)/2 + Y: (WINDOW_BOTTOM - HEIGHT)/2 + Width: 520 + Height: 260 + Children: + Label@PROMPT_TITLE: + Width: PARENT_RIGHT + Y: 20 + Height: 25 + Font: Bold + Align: Center + Text: System Information + Label@PROMPT_TEXT_A: + X: 15 + Y: 50 + Width: PARENT_RIGHT - 30 + Height: 16 + Align: Center + Text: We would like to collect some details that will help us optimize OpenRA. + Label@PROMPT_TEXT_B: + X: 15 + Y: 68 + Width: PARENT_RIGHT - 30 + Height: 16 + Align: Center + Text: With your permission, the following anonymous system data will be sent: + ScrollPanel@SYSINFO_DATA: + X: 20 + Y: 98 + Width: PARENT_RIGHT - 40 + TopBottomSpacing: 4 + ItemSpacing: 4 + Height: 110 + Children: + Label@DATA_TEMPLATE: + X: 8 + Height: 13 + VAlign: Top + Font: Small + Checkbox@SYSINFO_CHECKBOX: + X: 40 + Y: PARENT_BOTTOM - 42 + Width: 200 + Height: 20 + Font: Regular + Text: Send System Information + Button@BACK_BUTTON: + X: PARENT_RIGHT - WIDTH - 20 + Y: PARENT_BOTTOM - 45 + Width: 120 + Height: 25 + Text: Continue + Font: Bold + Key: return Container@PERFORMANCE_INFO: Logic: PerfDebugLogic Children: From 25a1c0c283ee027f6255ad1430fc31e0b1ac977e Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 27 Apr 2016 21:43:31 +0100 Subject: [PATCH 2/2] Include version/mod/modversion in the game list query. --- OpenRA.Mods.Common/Widgets/Logic/MultiplayerLogic.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/OpenRA.Mods.Common/Widgets/Logic/MultiplayerLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/MultiplayerLogic.cs index 40a39c5cdd..89a89cc753 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/MultiplayerLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/MultiplayerLogic.cs @@ -315,7 +315,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic Game.RunAfterTick(() => RefreshServerListInner(games)); }; - currentQuery = new Download(Game.Settings.Server.MasterServer + "games", _ => { }, onComplete); + var queryURL = Game.Settings.Server.MasterServer + "games?version={0}&mod={1}&modversion={2}".F( + Uri.EscapeUriString(ModMetadata.AllMods["modchooser"].Version), + Uri.EscapeUriString(Game.ModData.Manifest.Mod.Id), + Uri.EscapeUriString(Game.ModData.Manifest.Mod.Version)); + + currentQuery = new Download(queryURL, _ => { }, onComplete); } int GroupSortOrder(GameServer testEntry)