Index: ps/trunk/binaries/data/config/default.cfg =================================================================== --- ps/trunk/binaries/data/config/default.cfg +++ ps/trunk/binaries/data/config/default.cfg @@ -476,7 +476,7 @@ debug = false ; Print error messages each time a translation for an English string is not found. [userreport] ; Opt-in online user reporting system -url_upload = "http://feedback.wildfiregames.com/report/upload/v1/" ; URL where UserReports are uploaded to +url_upload = "https://feedback.wildfiregames.com/report/upload/v1/" ; URL where UserReports are uploaded to url_publication = "http://feedback.wildfiregames.com/" ; URL where UserReports were analyzed and published terms = "0" ; Version (hash) of the UserReporter Terms that the user has accepted Index: ps/trunk/binaries/data/mods/mod/gui/common/terms.js =================================================================== --- ps/trunk/binaries/data/mods/mod/gui/common/terms.js +++ ps/trunk/binaries/data/mods/mod/gui/common/terms.js @@ -10,6 +10,7 @@ Engine.PushGuiPage("page_termsdialog.xml", { "file": g_Terms[page].file, "title": g_Terms[page].title, + "sprintf": g_Terms[page].sprintf, "urlButtons": g_Terms[page].urlButtons || [], "page": page, "callback": "acceptTerms" Index: ps/trunk/binaries/data/mods/mod/gui/termsdialog/termsdialog.js =================================================================== --- ps/trunk/binaries/data/mods/mod/gui/termsdialog/termsdialog.js +++ ps/trunk/binaries/data/mods/mod/gui/termsdialog/termsdialog.js @@ -1,10 +1,12 @@ var g_TermsPage; var g_TermsFile; +var g_TermsSprintf; function init(data) { g_TermsPage = data.page; g_TermsFile = data.file; + g_TermsSprintf = data.sprintf; Engine.GetGUIObjectByName("title").caption = data.title; initURLButtons(data.urlButtons); @@ -53,9 +55,11 @@ languageDropdown.onSelectionChange = () => { Engine.GetGUIObjectByName("mainText").caption = - languageDropdown.selected == 1 ? - Engine.TranslateLines(Engine.ReadFile(g_TermsFile)) : - Engine.ReadFile(g_TermsFile); + sprintf( + languageDropdown.selected == 1 ? + Engine.TranslateLines(Engine.ReadFile(g_TermsFile)) : + Engine.ReadFile(g_TermsFile), + g_TermsSprintf); }; languageDropdown.selected = languageDropdown.list.length - 1; Index: ps/trunk/binaries/data/mods/public/gui/manual/userreport.txt =================================================================== --- ps/trunk/binaries/data/mods/public/gui/manual/userreport.txt +++ ps/trunk/binaries/data/mods/public/gui/manual/userreport.txt @@ -1,11 +0,0 @@ -As a free, open source game, we don't have the resources to test on a wide range of systems, but we want to provide the best quality experience to as many players as possible. When you enable automatic feedback, we'll receive data to help us understand the hardware we should focus on supporting, and to identify performance problems we should fix. - -The following data will be sent to our server: - -• A random user ID (stored in %APPDATA%\\0ad\\config\\user.cfg on Windows, ~/.config/0ad/config/user.cfg on Unix), to let us detect repeated reports from the same user. -• Game version number and basic build settings (optimisation mode, CPU architecture, timestamp, compiler version). -• Hardware details: OS version, graphics driver version, OpenGL capabilities, screen size, CPU details, RAM size. - -The data will only be a few kilobytes each time you run the game, so bandwidth usage is minimal. - -We will store the submitted data on our server, and may publish statistics or non-user-identifiable details to help other game developers with similar questions. We will store the IP address that submitted the data, to help detect abuse of the service, but will not publish it. The published data can be seen at http://feedback.wildfiregames.com/ Index: ps/trunk/binaries/data/mods/public/gui/pregame/userreport/userreport.js =================================================================== --- ps/trunk/binaries/data/mods/public/gui/pregame/userreport/userreport.js +++ ps/trunk/binaries/data/mods/public/gui/pregame/userreport/userreport.js @@ -2,7 +2,11 @@ "TermsAndConditions": { "title": translateWithContext("UserReporter Terms and Conditions", "Terms"), "instruction": translate("Please read and accept the UserReporter Terms and Conditions."), - "file": "gui/manual/userreport.txt", + "file": "gui/userreport/Terms_and_Conditions.txt", + "sprintf": { + "logPath": setStringTags(Engine.GetUserReportLogPath(), { "font": "sans-bold-12" }), + "configPath": setStringTags(Engine.GetUserReportConfigPath(), { "font": "sans-bold-12" }) + }, "config": "userreport.terms", "callback": data => { setUserReportEnabled(data.accepted); Index: ps/trunk/binaries/data/mods/public/gui/userreport/Terms_and_Conditions.txt =================================================================== --- ps/trunk/binaries/data/mods/public/gui/userreport/Terms_and_Conditions.txt +++ ps/trunk/binaries/data/mods/public/gui/userreport/Terms_and_Conditions.txt @@ -0,0 +1,69 @@ +[font="sans-bold-18"]0 A.D. Empires Ascendant UserReporter Terms and Conditions[/font] + +[font="sans-bold-14"]Document Date:[/font] 2018-10-05 + +The 0 A.D. UserReporter is a tool that allows you, the 0 A.D. player, to automatically upload hardware- and software-system details in order to help Wildfire Games and community developers to improve the performance and compatibility of 0 A.D. + +[font="sans-bold-14"]Purpose of the UserReport:[/font] +The UserReports indicate which system features (for example CPU instruction sets and OpenGL capabilities) are widely supported by the computer systems of 0 A.D. players. +This allows developers to decide which 0 A.D. program code is safe to use and which optimizations are most feasible to implement next. +If the UserReporter is enabled, the UserReport containing that information is uploaded to Wildfire Games once per program launch (GDPR 13.1.c, GDPR 15.1.a). + +[font="sans-bold-14"]UserReport data:[/font] + 1. Hardware Details, for example the screen size, CPU clock rate, memory capacity and the sound card manufacturer. + 2. System Software Details, for example the operating system version, graphics driver version, OpenGL capabilities. + 3. Application Details, for example the 0 A.D. version and build number. + 4. The UserID. This is a pseudonym generated by the UserReporter the first time it is used (GDPR 4.5, GDPR 25.1, GDPR 32.1.a). + The UserID enables developers to count how many 0 A.D. players use a specific set of hardware or system software without allowing them to attribute the data to any person. + 5. The date of the upload of the UserReport. This allows focus on recent UserReports and disregard old reports. + +The UserReport does not include any specially protected categories of personal data (GDPR 9, GDPR 10). +The transmission is secured with SSL. Data is protected against unintentional loss in encrypted backups for additional time (GDPR 30.1.g, GDPR 32). + +[font="sans-bold-14"]Wildfire Games reserves the right to:[/font] + 1. Publish UserReport data, excluding the UserID pseudonym, so that community developers may help contribute to 0 A.D. development using this data (GDPR 4.5). + At the time of the document, Wildfire Games published the most recent UserReport analysis at http://feedback.wildfiregames.com/ (GDPR 13.1.e, GDPR 15.1.c). + 2. Erase any UserReports for any reason, except where a user has objected to the erasure of his or her data for one of the reasons specified by the GDPR (GDPR 18, GDPR 21). + 3. Store the users IP address to protect against cyberattacks, for no longer than 4 months (EU Court of Justice Press Release No 112/16). + 4. Change this document. The document date indicates the version of the Terms and Conditions. + The UserReport is disabled with each version update and only enabled if the user agreed to the new document (GDPR 13.3). + +[font="sans-bold-14"]User rights (GDPR 13):[/font] + 1. Contact Wildfire Games, by sending an email to webmaster at wildfiregames dot com (GDPR 13.1.a, GDPR 13.1.b). + 2. Right of access to UserReport data concerning him or her (GDPR 15). + The UserID pseudonym can be found in the user.cfg file of the configuration folder of 0 A.D. + The current configuration folder is %(configPath)s. + The user obtains a machine-readable and human-readable copy of the UserReport data in the logs folder of 0 A.D. (GDPR 20). + The data can be reviewed before the UserReporter is enabled. + The current logfolder is %(logPath)s. + If you wish to access further UserReport data, contact Wildfire Games and provide your UserID pseudonym (GDPR 11). Only with that we may identify your data and process requests (GDPR 13.2.e). + Data may be obtained in a portable, machine-readable format (GDPR 20). + 3. Right to rectification of inaccurate UserReport data (GDPR 16). + 4. Right to erasure of your UserReports if they are not relevant to the development of 0 A.D., if the data was processed unlawfully or if the user objects to the processing and has overriding legitimate grounds (GDPR 17). + 5. Right to restriction of processing of UserReports if the accuracy of the data is contested by the user, if the data was processed unlawfully or if the user requires the data for a legal claim (GDPR 18). + 6. Right to object to the processing of UserReports concerning him or her on grounds relating to their particular situation (GDPR 21). + 7. Right to lodge a complaint with a supervisory authority (GDPR 13.2.d, GDPR 77). +Requests that are manifestly unfounded or excessive are not responded to or may be charged (GDPR 12.4, GDPR 12.5). + +[font="sans-bold-14"]Legal grounds of processing (GDPR 13.1.c):[/font] + 1. The processing is necessary for the performance of the service defined in this document (GDPR 6.1.b). + 2. Wildfire Games has legitimate interests in the development of 0 A.D and protection against cyberattacks (GDPR 6.1.f). + 3. Wildfire Games does not process any further data for the UserReporter and does not ask for consent to further data processing (GDPR 6.1.a, GDPR 7, GDPR 8, GDPR 13.2.c). + +[font="sans-bold-14"]Wildfire Games obligations (GDPR 5, GDPR 13):[/font] + 1. Wildfire Games demonstrates compliance with GDPR (GDPR 5.2 "accountability"). + 2. Wildfire Games documents their processing activities appropriately, in particular the categories of processed personal data and security measures to protect it (GDPR 30). + 3. Wildfire Games processes personal data lawfully, fairly and transparently (GDPR 5.1.a, GDPR 12.1). + 4. Wildfire Games informs users of the purposes, legal grounds, legitimate interests and retention periods of personal data processing at the time it is processed, recipients of personal data and where applicable, transfer of personal data to third countries and automated decision-making (GDPR 13.1.c-f, GDPR 13.2.a, GDPR 13.2.e, GDPR 13.2.f, GDPR 15.1, GDPR 15.4). + 5. Wildfire Games does not processes personal data for purposes other than the specified ones (GDPR 5.1.b, "purpose limitation", GDPR 13.3). + 6. Wildfire Games does not process personal data that is not neeeded for the specified purposes (GDPR 5.1.c, "data minimisation"). + 7. Wildfire Games uses a storage form that does not allow identification of natural persons for longer than necessary (GDPR 5.1.e "storage limitation"). + 8. Wildfire Games secures personal data processing to prevent unauthorised or unlawful processing and accidental loss (GDPR 5.1.f. "integrity and confidentiality"). + 9. Wildfire Games informs users of their right to access, to rectify, to erase personal data and the right to restrict, to withdraw consent to, to object to personal data processing and to complain at a supervisory authority (GDPR 13.2.b, GDPR 13.2.c, GDPR 13.2.d). +10. Wildfire Games facilitates the exercise of user rights where possible (GDPR 12.2), without undue delay (GDPR 12.3). +12. Wildfire Games informs the users that to exercise their rights, users might need to provide additional information to identify the natural person or the data (GDPR 12.6, GDPR 13.2.e). + +Wildfire Games obtains all UserReport data exclusively from the user (GDPR 14). +Wildfire Games does not perform any automated decision making affecting natural persons (GDPR 22). + +For further information on Wildfire Games Privacy Policies, visit https://trac.wildfiregames.com/wiki/UserDataProtection Index: ps/trunk/binaries/data/mods/public/l10n/messages.json =================================================================== --- ps/trunk/binaries/data/mods/public/l10n/messages.json +++ ps/trunk/binaries/data/mods/public/l10n/messages.json @@ -218,8 +218,23 @@ { "extractor": "txt", "filemasks": [ - "gui/manual/intro.txt", - "gui/manual/userreport.txt" + "gui/manual/intro.txt" + ], + "options": { + } + } + ] + }, + { + "output": "public-gui-userreport.pot", + "inputRoot": "..", + "project": "0 A.D. — Empires Ascendant", + "copyrightHolder": "Wildfire Games", + "rules": [ + { + "extractor": "txt", + "filemasks": [ + "gui/userreport/**.txt", ], "options": { } Index: ps/trunk/source/ps/scripting/JSInterface_UserReport.h =================================================================== --- ps/trunk/source/ps/scripting/JSInterface_UserReport.h +++ ps/trunk/source/ps/scripting/JSInterface_UserReport.h @@ -27,6 +27,8 @@ bool IsUserReportEnabled(ScriptInterface::CxPrivate* pCxPrivate); void SetUserReportEnabled(ScriptInterface::CxPrivate* pCxPrivate, bool enabled); std::string GetUserReportStatus(ScriptInterface::CxPrivate* pCxPrivate); + std::string GetUserReportLogPath(ScriptInterface::CxPrivate* pCxPrivate); + std::string GetUserReportConfigPath(ScriptInterface::CxPrivate* pCxPrivate); void RegisterScriptFunctions(const ScriptInterface& ScriptInterface); } Index: ps/trunk/source/ps/scripting/JSInterface_UserReport.cpp =================================================================== --- ps/trunk/source/ps/scripting/JSInterface_UserReport.cpp +++ ps/trunk/source/ps/scripting/JSInterface_UserReport.cpp @@ -19,6 +19,8 @@ #include "JSInterface_UserReport.h" +#include "ps/Filesystem.h" +#include "ps/Pyrogenesis.h" #include "ps/UserReport.h" #include "scriptinterface/ScriptInterface.h" @@ -39,9 +41,23 @@ return g_UserReporter.GetStatus(); } +std::string JSI_UserReport::GetUserReportLogPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +{ + return psLogDir().string8(); +} + +std::string JSI_UserReport::GetUserReportConfigPath(ScriptInterface::CxPrivate* UNUSED(pCxPrivate)) +{ + OsPath configPath; + WARN_IF_ERR(g_VFS->GetDirectoryRealPath("config/", configPath)); + return configPath.string8(); +} + void JSI_UserReport::RegisterScriptFunctions(const ScriptInterface& scriptInterface) { scriptInterface.RegisterFunction("IsUserReportEnabled"); scriptInterface.RegisterFunction("SetUserReportEnabled"); scriptInterface.RegisterFunction("GetUserReportStatus"); + scriptInterface.RegisterFunction("GetUserReportLogPath"); + scriptInterface.RegisterFunction("GetUserReportConfigPath"); }