OpenTTD Source  14.0-beta1
network_survey.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of OpenTTD.
3  * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4  * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5  * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
6  */
7 
10 #include "../stdafx.h"
11 #include "network_survey.h"
12 #include "settings_table.h"
13 #include "network.h"
14 #include "network_func.h"
15 #include "../debug.h"
16 #include "../survey.h"
17 #include "../3rdparty/fmt/chrono.h"
18 #include "../3rdparty/fmt/std.h"
19 
20 #include "../safeguards.h"
21 
22 extern std::string _savegame_id;
23 
24 NetworkSurveyHandler _survey = {};
25 
31 })
32 
40 std::string NetworkSurveyHandler::CreatePayload(Reason reason, bool for_preview)
41 {
42  nlohmann::json survey;
43 
44  survey["schema"] = NETWORK_SURVEY_VERSION;
45  survey["reason"] = reason;
46  survey["id"] = _savegame_id;
47  survey["date"] = fmt::format("{:%Y-%m-%d %H:%M:%S} (UTC)", fmt::gmtime(time(nullptr)));
48 
49 #ifdef SURVEY_KEY
50  /* We censor the key to avoid people trying to be "clever" and use it to send their own surveys. */
51  survey["key"] = for_preview ? "(redacted)" : SURVEY_KEY;
52 #else
53  survey["key"] = "";
54 #endif
55 
56  {
57  auto &info = survey["info"];
58  SurveyOS(info["os"]);
59  SurveyOpenTTD(info["openttd"]);
60  SurveyConfiguration(info["configuration"]);
61  SurveyFont(info["font"]);
62  SurveyCompiler(info["compiler"]);
63  SurveyLibraries(info["libraries"]);
64  SurveyPlugins(info["plugins"]);
65  }
66 
67  {
68  auto &game = survey["game"];
69  SurveyTimers(game["timers"]);
70  SurveyCompanies(game["companies"]);
71  SurveySettings(game["settings"], false);
72  SurveyGrfs(game["grfs"]);
73  SurveyGameScript(game["game_script"]);
74  }
75 
76  /* For preview, we indent with 4 whitespaces to make things more readable. */
77  int indent = for_preview ? 4 : -1;
78  return survey.dump(indent);
79 }
80 
87 void NetworkSurveyHandler::Transmit(Reason reason, bool blocking)
88 {
89  if constexpr (!NetworkSurveyHandler::IsSurveyPossible()) {
90  Debug(net, 4, "Survey: not possible to send survey; most likely due to missing JSON library at compile-time");
91  return;
92  }
93 
95  Debug(net, 5, "Survey: user is not participating in survey; skipping survey");
96  return;
97  }
98 
99  Debug(net, 1, "Survey: sending survey results");
100  NetworkHTTPSocketHandler::Connect(NetworkSurveyUriString(), this, this->CreatePayload(reason));
101 
102  if (blocking) {
103  std::unique_lock<std::mutex> lock(this->mutex);
104 
105  /* Block no longer than 2 seconds. If we failed to send the survey in that time, so be it. */
106  std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now() + std::chrono::seconds(2);
107 
108  while (!this->transmitted && std::chrono::steady_clock::now() < end) {
110  this->transmitted_cv.wait_for(lock, std::chrono::milliseconds(30));
111  }
112  }
113 }
114 
116 {
117  Debug(net, 1, "Survey: failed to send survey results");
118  this->transmitted = true;
119  this->transmitted_cv.notify_all();
120 }
121 
122 void NetworkSurveyHandler::OnReceiveData(std::unique_ptr<char[]> data, size_t)
123 {
124  if (data == nullptr) {
125  Debug(net, 1, "Survey: survey results sent");
126  this->transmitted = true;
127  this->transmitted_cv.notify_all();
128  }
129 }
SurveyConfiguration
void SurveyConfiguration(nlohmann::json &survey)
Convert generic game information to JSON.
Definition: survey.cpp:243
NetworkSurveyHandler::transmitted
std::atomic< bool > transmitted
Whether the survey has been transmitted.
Definition: network_survey.h:44
SurveyLibraries
void SurveyLibraries(nlohmann::json &survey)
Convert compiled libraries information to JSON.
Definition: survey.cpp:386
SurveyTimers
void SurveyTimers(nlohmann::json &survey)
Convert timer information to JSON.
Definition: survey.cpp:330
lock
std::mutex lock
synchronization for playback status fields
Definition: win32_m.cpp:35
_savegame_id
std::string _savegame_id
Unique ID of the current savegame.
Definition: misc.cpp:39
NetworkHTTPSocketHandler::Connect
static void Connect(const std::string &uri, HTTPCallback *callback, const std::string data="")
Connect to the given URI.
Definition: http_curl.cpp:93
_settings_client
ClientSettings _settings_client
The current settings for this game.
Definition: settings.cpp:54
NetworkBackgroundLoop
void NetworkBackgroundLoop()
We have to do some (simple) background stuff that runs normally, even when we are not in multiplayer.
Definition: network.cpp:1037
NetworkSurveyUriString
const char * NetworkSurveyUriString()
Get the URI string for the survey from the environment variable OTTD_SURVEY_URI, or when it has not b...
Definition: config.cpp:75
Debug
#define Debug(category, level, format_string,...)
Ouptut a line of debugging information.
Definition: debug.h:37
SurveySettings
void SurveySettings(nlohmann::json &survey, bool skip_if_default)
Convert settings to JSON.
Definition: survey.cpp:160
NetworkSurveyHandler::transmitted_cv
std::condition_variable transmitted_cv
Condition variable to inform changes to transmitted.
Definition: network_survey.h:45
NetworkSurveyHandler::mutex
std::mutex mutex
Mutex for the condition variable.
Definition: network_survey.h:43
SurveyOpenTTD
void SurveyOpenTTD(nlohmann::json &survey)
Convert generic OpenTTD information to JSON.
Definition: survey.cpp:206
SurveyCompanies
void SurveyCompanies(nlohmann::json &survey)
Convert company information to JSON.
Definition: survey.cpp:299
NetworkSurveyHandler::Reason::PREVIEW
@ PREVIEW
User is previewing the survey result.
SurveyGrfs
void SurveyGrfs(nlohmann::json &survey)
Convert GRF information to JSON.
Definition: survey.cpp:347
settings_table.h
NetworkSurveyHandler::Transmit
void Transmit(Reason reason, bool blocking=false)
Transmit the survey.
Definition: network_survey.cpp:87
NetworkSurveyHandler::OnFailure
void OnFailure() override
An error has occurred and the connection has been closed.
Definition: network_survey.cpp:115
NetworkSurveyHandler::Reason::LEAVE
@ LEAVE
User is leaving the game (but not exiting the application).
SurveyCompiler
void SurveyCompiler(nlohmann::json &survey)
Convert compiler information to JSON.
Definition: survey.cpp:178
network.h
NetworkSurveyHandler
Socket handler for the survey connection.
Definition: network_survey.h:20
NetworkSurveyHandler::OnReceiveData
void OnReceiveData(std::unique_ptr< char[]> data, size_t length) override
We're receiving data.
Definition: network_survey.cpp:122
ClientSettings::network
NetworkSettings network
settings related to the network
Definition: settings_type.h:637
network_survey.h
NetworkSurveyHandler::Reason::CRASH
@ CRASH
Game crashed.
SurveyGameScript
void SurveyGameScript(nlohmann::json &survey)
Convert game-script information to JSON.
Definition: survey.cpp:374
SurveyFont
void SurveyFont(nlohmann::json &survey)
Convert font information to JSON.
Definition: survey.cpp:286
SurveyPlugins
void SurveyPlugins(nlohmann::json &survey)
Convert plugin information to JSON.
Definition: survey.cpp:456
network_func.h
NetworkSurveyHandler::Reason::EXIT
@ EXIT
User is exiting the application.
NLOHMANN_JSON_SERIALIZE_ENUM
NLOHMANN_JSON_SERIALIZE_ENUM(NetworkSurveyHandler::Reason, { {NetworkSurveyHandler::Reason::PREVIEW, "preview"}, {NetworkSurveyHandler::Reason::LEAVE, "leave"}, {NetworkSurveyHandler::Reason::EXIT, "exit"}, {NetworkSurveyHandler::Reason::CRASH, "crash"}, }) std
Create the payload for the survey.
Definition: network_survey.cpp:26
NetworkSurveyHandler::Reason
Reason
Definition: network_survey.h:27
NetworkSettings::participate_survey
ParticipateSurvey participate_survey
Participate in the automated survey.
Definition: settings_type.h:335
NETWORK_SURVEY_VERSION
static const byte NETWORK_SURVEY_VERSION
What version of the survey do we use?
Definition: config.h:51