Feature: opt-in survey when exiting a game

On first start-up, the game will ask if you want to participate
in our automated survey. You have to opt-in, and can easily opt-out
(via the Options) at any time.

When opt-in, whenever you exit a game, a JSON blob will be send
to the survey server hosted by OpenTTD. This JSON blob contains
information that gives a global picture of the game just played:
- What settings were used
- How many humans vs AIs
- How long the game has been played
- Basic information about the OS / CPU

All this information is kept very generic, so there is no
chance we send private information to our survey server.
Nothing in the JSON blob could identify you as a person; it
mostly tells about the game played. At any time you can see
what the JSON blob includes, by pressing the "Preview Survey
Results" button in-game.
This commit is contained in:
Patric Stout
2023-04-25 19:43:45 +02:00
committed by Patric Stout
parent 021c45c4f6
commit 7634553d22
54 changed files with 1018 additions and 53 deletions

View File

@@ -31,9 +31,11 @@
#include "town_kdtree.h"
#include "viewport_kdtree.h"
#include "newgrf_profiling.h"
#include "3rdparty/md5/md5.h"
#include "safeguards.h"
std::string _savegame_id; ///< Unique ID of the current savegame.
extern TileIndex _cur_tileloop_tile;
extern void MakeNewgameSettingsLive();
@@ -56,6 +58,40 @@ void InitializeCheats();
void InitializeNPF();
void InitializeOldNames();
/**
* Generate an unique ID.
*
* It isn't as much of an unique ID as we would like, but our random generator
* can only produce 32bit random numbers.
* That is why we combine InteractiveRandom with the current (steady) clock.
* The first to add a bit of randomness, the second to ensure you can't get
* the same unique ID when you run it twice from the same state at different
* times.
*
* This makes it unlikely that two users generate the same ID for different
* subjects. But as this is not an UUID, so it can't be ruled out either.
*/
std::string GenerateUid(std::string_view subject)
{
auto current_time = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()).count();
std::string coding_string = fmt::format("{}{}{}", InteractiveRandom(), current_time, subject);
Md5 checksum;
uint8 digest[16];
checksum.Append(coding_string.c_str(), coding_string.length());
checksum.Finish(digest);
return MD5SumToString(digest);
}
/**
* Generate an unique savegame ID.
*/
void GenerateSavegameId()
{
_savegame_id = GenerateUid("OpenTTD Savegame ID");
}
void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settings)
{
/* Make sure there isn't any window that can influence anything