From b5abfb89548bcc46836a6a58021fa23c8af52290 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Wed, 13 Sep 2023 10:59:38 +0200 Subject: [PATCH] Codechange: move Survey-related functions to their own file In a later commit, this will be shared by the crashlog, as the crashlog too needs to survey the system. This makes it easier in the next commit to see what actually changes, and what is just a plain old move of code. --- src/CMakeLists.txt | 2 + src/network/network_survey.cpp | 311 +------------------------------- src/os/macosx/survey_osx.cpp | 4 +- src/os/unix/survey_unix.cpp | 5 +- src/os/windows/survey_win.cpp | 4 +- src/survey.cpp | 321 +++++++++++++++++++++++++++++++++ src/survey.h | 29 +++ 7 files changed, 358 insertions(+), 318 deletions(-) create mode 100644 src/survey.cpp create mode 100644 src/survey.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f62231b3c9..8c084c913f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -432,6 +432,8 @@ add_files( subsidy_func.h subsidy_gui.cpp subsidy_type.h + survey.cpp + survey.h tar_type.h terraform_cmd.cpp terraform_cmd.h diff --git a/src/network/network_survey.cpp b/src/network/network_survey.cpp index 297d4e6e05..9a83edfecb 100644 --- a/src/network/network_survey.cpp +++ b/src/network/network_survey.cpp @@ -12,26 +12,9 @@ #include "settings_table.h" #include "network.h" #include "../debug.h" -#include "../rev.h" -#include "../settings_type.h" -#include "../timer/timer_game_tick.h" - -#include "../currency.h" -#include "../fontcache.h" -#include "../language.h" - -#include "../ai/ai_info.hpp" -#include "../game/game.hpp" -#include "../game/game_info.hpp" - -#include "../music/music_driver.hpp" -#include "../sound/sound_driver.hpp" -#include "../video/video_driver.hpp" - -#include "../base_media_base.h" -#include "../blitter/factory.hpp" - -#include "../3rdparty/nlohmann/json.hpp" +#include "../survey.h" +#include "../3rdparty/fmt/chrono.h" +#include "../3rdparty/fmt/std.h" #include "../safeguards.h" @@ -46,294 +29,6 @@ NLOHMANN_JSON_SERIALIZE_ENUM(NetworkSurveyHandler::Reason, { {NetworkSurveyHandler::Reason::CRASH, "crash"}, }) -NLOHMANN_JSON_SERIALIZE_ENUM(GRFStatus, { - {GRFStatus::GCS_UNKNOWN, "unknown"}, - {GRFStatus::GCS_DISABLED, "disabled"}, - {GRFStatus::GCS_NOT_FOUND, "not found"}, - {GRFStatus::GCS_INITIALISED, "initialised"}, - {GRFStatus::GCS_ACTIVATED, "activated"}, -}) - -static const std::string _vehicle_type_to_string[] = { - "train", - "roadveh", - "ship", - "aircraft", -}; - -/* Defined in one of the os/ survey files. */ -extern void SurveyOS(nlohmann::json &json); - -/** - * List of all the generic setting tables. - * - * There are a few tables that are special and not processed like the rest: - * - _currency_settings - * - _misc_settings - * - _company_settings - * - _win32_settings - * As such, they are not part of this list. - */ -static auto &GenericSettingTables() -{ - static const SettingTable _generic_setting_tables[] = { - _difficulty_settings, - _economy_settings, - _game_settings, - _gui_settings, - _linkgraph_settings, - _locale_settings, - _multimedia_settings, - _network_settings, - _news_display_settings, - _pathfinding_settings, - _script_settings, - _world_settings, - }; - return _generic_setting_tables; -} - -/** - * Convert a settings table to JSON. - * - * @param survey The JSON object. - * @param table The settings table to convert. - * @param object The object to get the settings from. - */ -static void SurveySettingsTable(nlohmann::json &survey, const SettingTable &table, void *object) -{ - for (auto &desc : table) { - const SettingDesc *sd = GetSettingDesc(desc); - /* Skip any old settings we no longer save/load. */ - if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; - - auto name = sd->GetName(); - survey[name] = sd->FormatValue(object); - } -} - -/** - * Convert settings to JSON. - * - * @param survey The JSON object. - */ -static void SurveySettings(nlohmann::json &survey) -{ - SurveySettingsTable(survey, _misc_settings, nullptr); -#if defined(_WIN32) && !defined(DEDICATED) - SurveySettingsTable(survey, _win32_settings, nullptr); -#endif - for (auto &table : GenericSettingTables()) { - SurveySettingsTable(survey, table, &_settings_game); - } - SurveySettingsTable(survey, _currency_settings, &_custom_currency); - SurveySettingsTable(survey, _company_settings, &_settings_client.company); -} - -/** - * Convert generic OpenTTD information to JSON. - * - * @param survey The JSON object. - */ -static void SurveyOpenTTD(nlohmann::json &survey) -{ - survey["version"]["revision"] = std::string(_openttd_revision); - survey["version"]["modified"] = _openttd_revision_modified; - survey["version"]["tagged"] = _openttd_revision_tagged; - survey["version"]["hash"] = std::string(_openttd_revision_hash); - survey["version"]["newgrf"] = fmt::format("{:X}", _openttd_newgrf_version); - survey["version"]["content"] = std::string(_openttd_content_version); - survey["build_date"] = std::string(_openttd_build_date); - survey["bits"] = -#ifdef POINTER_IS_64BIT - 64 -#else - 32 -#endif - ; - survey["endian"] = -#if (TTD_ENDIAN == TTD_LITTLE_ENDIAN) - "little" -#else - "big" -#endif - ; - survey["dedicated_build"] = -#ifdef DEDICATED - "yes" -#else - "no" -#endif - ; -} - -/** - * Convert generic game information to JSON. - * - * @param survey The JSON object. - */ -static void SurveyConfiguration(nlohmann::json &survey) -{ - survey["network"] = _networking ? (_network_server ? "server" : "client") : "no"; - if (_current_language != nullptr) { - survey["language"]["filename"] = _current_language->file.filename().string(); - survey["language"]["name"] = _current_language->name; - survey["language"]["isocode"] = _current_language->isocode; - } - if (BlitterFactory::GetCurrentBlitter() != nullptr) { - survey["blitter"] = BlitterFactory::GetCurrentBlitter()->GetName(); - } - if (MusicDriver::GetInstance() != nullptr) { - survey["music_driver"] = MusicDriver::GetInstance()->GetName(); - } - if (SoundDriver::GetInstance() != nullptr) { - survey["sound_driver"] = SoundDriver::GetInstance()->GetName(); - } - if (VideoDriver::GetInstance() != nullptr) { - survey["video_driver"] = VideoDriver::GetInstance()->GetName(); - survey["video_info"] = VideoDriver::GetInstance()->GetInfoString(); - } - if (BaseGraphics::GetUsedSet() != nullptr) { - survey["graphics_set"] = fmt::format("{}.{}", BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet()->version); - } - if (BaseMusic::GetUsedSet() != nullptr) { - survey["music_set"] = fmt::format("{}.{}", BaseMusic::GetUsedSet()->name, BaseMusic::GetUsedSet()->version); - } - if (BaseSounds::GetUsedSet() != nullptr) { - survey["sound_set"] = fmt::format("{}.{}", BaseSounds::GetUsedSet()->name, BaseSounds::GetUsedSet()->version); - } -} - -/** - * Convert font information to JSON. - * - * @param survey The JSON object. - */ -static void SurveyFont(nlohmann::json &survey) -{ - survey["small"] = FontCache::Get(FS_SMALL)->GetFontName(); - survey["medium"] = FontCache::Get(FS_NORMAL)->GetFontName(); - survey["large"] = FontCache::Get(FS_LARGE)->GetFontName(); - survey["mono"] = FontCache::Get(FS_MONO)->GetFontName(); -} - -/** - * Convert company information to JSON. - * - * @param survey The JSON object. - */ -static void SurveyCompanies(nlohmann::json &survey) -{ - for (const Company *c : Company::Iterate()) { - auto &company = survey[std::to_string(c->index)]; - if (c->ai_info == nullptr) { - company["type"] = "human"; - } else { - company["type"] = "ai"; - company["script"] = fmt::format("{}.{}", c->ai_info->GetName(), c->ai_info->GetVersion()); - } - - for (VehicleType type = VEH_BEGIN; type < VEH_COMPANY_END; type++) { - uint amount = c->group_all[type].num_vehicle; - company["vehicles"][_vehicle_type_to_string[type]] = amount; - } - - company["infrastructure"]["road"] = c->infrastructure.GetRoadTotal(); - company["infrastructure"]["tram"] = c->infrastructure.GetTramTotal(); - company["infrastructure"]["rail"] = c->infrastructure.GetRailTotal(); - company["infrastructure"]["signal"] = c->infrastructure.signal; - company["infrastructure"]["water"] = c->infrastructure.water; - company["infrastructure"]["station"] = c->infrastructure.station; - company["infrastructure"]["airport"] = c->infrastructure.airport; - } -} - -/** - * Convert timer information to JSON. - * - * @param survey The JSON object. - */ -static void SurveyTimers(nlohmann::json &survey) -{ - survey["ticks"] = TimerGameTick::counter; - survey["seconds"] = std::chrono::duration_cast(std::chrono::steady_clock::now() - _switch_mode_time).count(); - - TimerGameCalendar::YearMonthDay ymd; - TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); - survey["calendar"] = fmt::format("{:04}-{:02}-{:02} ({})", ymd.year, ymd.month + 1, ymd.day, TimerGameCalendar::date_fract); -} - -/** - * Convert GRF information to JSON. - * - * @param survey The JSON object. - */ -static void SurveyGrfs(nlohmann::json &survey) -{ - for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { - auto grfid = fmt::format("{:08x}", BSWAP32(c->ident.grfid)); - auto &grf = survey[grfid]; - - grf["md5sum"] = FormatArrayAsHex(c->ident.md5sum); - grf["status"] = c->status; - - if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_UNSET) grf["palette"] = "unset"; - if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_DOS) grf["palette"] = "dos"; - if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_WINDOWS) grf["palette"] = "windows"; - if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_ANY) grf["palette"] = "any"; - - if ((c->palette & GRFP_BLT_MASK) == GRFP_BLT_UNSET) grf["blitter"] = "unset"; - if ((c->palette & GRFP_BLT_MASK) == GRFP_BLT_32BPP) grf["blitter"] = "32bpp"; - - grf["is_static"] = HasBit(c->flags, GCF_STATIC); - - std::vector parameters; - for (int i = 0; i < c->num_params; i++) { - parameters.push_back(c->param[i]); - } - grf["parameters"] = parameters; - } -} - -/** - * Convert game-script information to JSON. - * - * @param survey The JSON object. - */ -static void SurveyGameScript(nlohmann::json &survey) -{ - if (Game::GetInfo() == nullptr) return; - - survey = fmt::format("{}.{}", Game::GetInfo()->GetName(), Game::GetInfo()->GetVersion()); -} - -/** - * Change the bytes of memory into a textual version rounded up to the biggest unit. - * - * For example, 16751108096 would become 16 GiB. - * - * @param memory The bytes of memory. - * @return std::string A textual representation. - */ -std::string SurveyMemoryToText(uint64_t memory) -{ - memory = memory / 1024; // KiB - memory = CeilDiv(memory, 1024); // MiB - - /* Anything above 512 MiB we represent in GiB. */ - if (memory > 512) { - return fmt::format("{} GiB", CeilDiv(memory, 1024)); - } - - /* Anything above 64 MiB we represent in a multiplier of 128 MiB. */ - if (memory > 64) { - return fmt::format("{} MiB", Ceil(memory, 128)); - } - - /* Anything else in a multiplier of 4 MiB. */ - return fmt::format("{} MiB", Ceil(memory, 4)); -} - /** * Create the payload for the survey. * diff --git a/src/os/macosx/survey_osx.cpp b/src/os/macosx/survey_osx.cpp index 40839ea614..2a3999936b 100644 --- a/src/os/macosx/survey_osx.cpp +++ b/src/os/macosx/survey_osx.cpp @@ -10,7 +10,7 @@ #include "../../stdafx.h" #include "../../3rdparty/fmt/format.h" -#include "../../3rdparty/nlohmann/json.hpp" +#include "../../survey.h" #include "macos.h" #include @@ -18,8 +18,6 @@ #include "../../safeguards.h" -extern std::string SurveyMemoryToText(uint64_t memory); - void SurveyOS(nlohmann::json &json) { int ver_maj, ver_min, ver_bug; diff --git a/src/os/unix/survey_unix.cpp b/src/os/unix/survey_unix.cpp index ac1368f9a7..d1f07d116f 100644 --- a/src/os/unix/survey_unix.cpp +++ b/src/os/unix/survey_unix.cpp @@ -8,8 +8,7 @@ /** @file survey_unix.cpp Unix implementation of OS-specific survey information. */ #include "../../stdafx.h" - -#include "../../3rdparty/nlohmann/json.hpp" +#include "../../survey.h" #include #include @@ -17,8 +16,6 @@ #include "../../safeguards.h" -extern std::string SurveyMemoryToText(uint64_t memory); - void SurveyOS(nlohmann::json &json) { struct utsname name; diff --git a/src/os/windows/survey_win.cpp b/src/os/windows/survey_win.cpp index ace726b1ed..a5d21ea600 100644 --- a/src/os/windows/survey_win.cpp +++ b/src/os/windows/survey_win.cpp @@ -10,15 +10,13 @@ #include "../../stdafx.h" #include "../../3rdparty/fmt/format.h" -#include "../../3rdparty/nlohmann/json.hpp" +#include "../../survey.h" #include #include #include "../../safeguards.h" -extern std::string SurveyMemoryToText(uint64_t memory); - void SurveyOS(nlohmann::json &json) { _OSVERSIONINFOA os; diff --git a/src/survey.cpp b/src/survey.cpp new file mode 100644 index 0000000000..6d2a6ac312 --- /dev/null +++ b/src/survey.cpp @@ -0,0 +1,321 @@ +/* + * This file is part of OpenTTD. + * 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. + * 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. + * 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 . + */ + +/** @file survey.cpp Functions to survey the current game / system, for crashlog and network-survey. */ + +#include "stdafx.h" + +#include "survey.h" + +#include "settings_table.h" +#include "network/network.h" +#include "rev.h" +#include "settings_type.h" +#include "timer/timer_game_tick.h" + +#include "currency.h" +#include "fontcache.h" +#include "language.h" + +#include "ai/ai_info.hpp" +#include "game/game.hpp" +#include "game/game_info.hpp" + +#include "music/music_driver.hpp" +#include "sound/sound_driver.hpp" +#include "video/video_driver.hpp" + +#include "base_media_base.h" +#include "blitter/factory.hpp" + +#include "safeguards.h" + +NLOHMANN_JSON_SERIALIZE_ENUM(GRFStatus, { + {GRFStatus::GCS_UNKNOWN, "unknown"}, + {GRFStatus::GCS_DISABLED, "disabled"}, + {GRFStatus::GCS_NOT_FOUND, "not found"}, + {GRFStatus::GCS_INITIALISED, "initialised"}, + {GRFStatus::GCS_ACTIVATED, "activated"}, +}) + +/** Lookup table to convert a VehicleType to a string. */ +static const std::string _vehicle_type_to_string[] = { + "train", + "roadveh", + "ship", + "aircraft", +}; + +/** + * List of all the generic setting tables. + * + * There are a few tables that are special and not processed like the rest: + * - _currency_settings + * - _misc_settings + * - _company_settings + * - _win32_settings + * As such, they are not part of this list. + */ +static auto &GenericSettingTables() +{ + static const SettingTable _generic_setting_tables[] = { + _difficulty_settings, + _economy_settings, + _game_settings, + _gui_settings, + _linkgraph_settings, + _locale_settings, + _multimedia_settings, + _network_settings, + _news_display_settings, + _pathfinding_settings, + _script_settings, + _world_settings, + }; + return _generic_setting_tables; +} + +/** + * Convert a settings table to JSON. + * + * @param survey The JSON object. + * @param table The settings table to convert. + * @param object The object to get the settings from. + */ +static void SurveySettingsTable(nlohmann::json &survey, const SettingTable &table, void *object) +{ + for (auto &desc : table) { + const SettingDesc *sd = GetSettingDesc(desc); + /* Skip any old settings we no longer save/load. */ + if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; + + auto name = sd->GetName(); + survey[name] = sd->FormatValue(object); + } +} + +/** + * Convert settings to JSON. + * + * @param survey The JSON object. + */ +void SurveySettings(nlohmann::json &survey) +{ + SurveySettingsTable(survey, _misc_settings, nullptr); +#if defined(_WIN32) && !defined(DEDICATED) + SurveySettingsTable(survey, _win32_settings, nullptr); +#endif + for (auto &table : GenericSettingTables()) { + SurveySettingsTable(survey, table, &_settings_game); + } + SurveySettingsTable(survey, _currency_settings, &_custom_currency); + SurveySettingsTable(survey, _company_settings, &_settings_client.company); +} + +/** + * Convert generic OpenTTD information to JSON. + * + * @param survey The JSON object. + */ +void SurveyOpenTTD(nlohmann::json &survey) +{ + survey["version"]["revision"] = std::string(_openttd_revision); + survey["version"]["modified"] = _openttd_revision_modified; + survey["version"]["tagged"] = _openttd_revision_tagged; + survey["version"]["hash"] = std::string(_openttd_revision_hash); + survey["version"]["newgrf"] = fmt::format("{:X}", _openttd_newgrf_version); + survey["version"]["content"] = std::string(_openttd_content_version); + survey["build_date"] = std::string(_openttd_build_date); + survey["bits"] = +#ifdef POINTER_IS_64BIT + 64 +#else + 32 +#endif + ; + survey["endian"] = +#if (TTD_ENDIAN == TTD_LITTLE_ENDIAN) + "little" +#else + "big" +#endif + ; + survey["dedicated_build"] = +#ifdef DEDICATED + "yes" +#else + "no" +#endif + ; +} + +/** + * Convert generic game information to JSON. + * + * @param survey The JSON object. + */ +void SurveyConfiguration(nlohmann::json &survey) +{ + survey["network"] = _networking ? (_network_server ? "server" : "client") : "no"; + if (_current_language != nullptr) { + survey["language"]["filename"] = _current_language->file.filename().string(); + survey["language"]["name"] = _current_language->name; + survey["language"]["isocode"] = _current_language->isocode; + } + if (BlitterFactory::GetCurrentBlitter() != nullptr) { + survey["blitter"] = BlitterFactory::GetCurrentBlitter()->GetName(); + } + if (MusicDriver::GetInstance() != nullptr) { + survey["music_driver"] = MusicDriver::GetInstance()->GetName(); + } + if (SoundDriver::GetInstance() != nullptr) { + survey["sound_driver"] = SoundDriver::GetInstance()->GetName(); + } + if (VideoDriver::GetInstance() != nullptr) { + survey["video_driver"] = VideoDriver::GetInstance()->GetName(); + survey["video_info"] = VideoDriver::GetInstance()->GetInfoString(); + } + if (BaseGraphics::GetUsedSet() != nullptr) { + survey["graphics_set"] = fmt::format("{}.{}", BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet()->version); + } + if (BaseMusic::GetUsedSet() != nullptr) { + survey["music_set"] = fmt::format("{}.{}", BaseMusic::GetUsedSet()->name, BaseMusic::GetUsedSet()->version); + } + if (BaseSounds::GetUsedSet() != nullptr) { + survey["sound_set"] = fmt::format("{}.{}", BaseSounds::GetUsedSet()->name, BaseSounds::GetUsedSet()->version); + } +} + +/** + * Convert font information to JSON. + * + * @param survey The JSON object. + */ +void SurveyFont(nlohmann::json &survey) +{ + survey["small"] = FontCache::Get(FS_SMALL)->GetFontName(); + survey["medium"] = FontCache::Get(FS_NORMAL)->GetFontName(); + survey["large"] = FontCache::Get(FS_LARGE)->GetFontName(); + survey["mono"] = FontCache::Get(FS_MONO)->GetFontName(); +} + +/** + * Convert company information to JSON. + * + * @param survey The JSON object. + */ +void SurveyCompanies(nlohmann::json &survey) +{ + for (const Company *c : Company::Iterate()) { + auto &company = survey[std::to_string(c->index)]; + if (c->ai_info == nullptr) { + company["type"] = "human"; + } else { + company["type"] = "ai"; + company["script"] = fmt::format("{}.{}", c->ai_info->GetName(), c->ai_info->GetVersion()); + } + + for (VehicleType type = VEH_BEGIN; type < VEH_COMPANY_END; type++) { + uint amount = c->group_all[type].num_vehicle; + company["vehicles"][_vehicle_type_to_string[type]] = amount; + } + + company["infrastructure"]["road"] = c->infrastructure.GetRoadTotal(); + company["infrastructure"]["tram"] = c->infrastructure.GetTramTotal(); + company["infrastructure"]["rail"] = c->infrastructure.GetRailTotal(); + company["infrastructure"]["signal"] = c->infrastructure.signal; + company["infrastructure"]["water"] = c->infrastructure.water; + company["infrastructure"]["station"] = c->infrastructure.station; + company["infrastructure"]["airport"] = c->infrastructure.airport; + } +} + +/** + * Convert timer information to JSON. + * + * @param survey The JSON object. + */ +void SurveyTimers(nlohmann::json &survey) +{ + survey["ticks"] = TimerGameTick::counter; + survey["seconds"] = std::chrono::duration_cast(std::chrono::steady_clock::now() - _switch_mode_time).count(); + + TimerGameCalendar::YearMonthDay ymd; + TimerGameCalendar::ConvertDateToYMD(TimerGameCalendar::date, &ymd); + survey["calendar"] = fmt::format("{:04}-{:02}-{:02} ({})", ymd.year, ymd.month + 1, ymd.day, TimerGameCalendar::date_fract); +} + +/** + * Convert GRF information to JSON. + * + * @param survey The JSON object. + */ +void SurveyGrfs(nlohmann::json &survey) +{ + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { + auto grfid = fmt::format("{:08x}", BSWAP32(c->ident.grfid)); + auto &grf = survey[grfid]; + + grf["md5sum"] = FormatArrayAsHex(c->ident.md5sum); + grf["status"] = c->status; + + if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_UNSET) grf["palette"] = "unset"; + if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_DOS) grf["palette"] = "dos"; + if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_WINDOWS) grf["palette"] = "windows"; + if ((c->palette & GRFP_GRF_MASK) == GRFP_GRF_ANY) grf["palette"] = "any"; + + if ((c->palette & GRFP_BLT_MASK) == GRFP_BLT_UNSET) grf["blitter"] = "unset"; + if ((c->palette & GRFP_BLT_MASK) == GRFP_BLT_32BPP) grf["blitter"] = "32bpp"; + + grf["is_static"] = HasBit(c->flags, GCF_STATIC); + + std::vector parameters; + for (int i = 0; i < c->num_params; i++) { + parameters.push_back(c->param[i]); + } + grf["parameters"] = parameters; + } +} + +/** + * Convert game-script information to JSON. + * + * @param survey The JSON object. + */ +void SurveyGameScript(nlohmann::json &survey) +{ + if (Game::GetInfo() == nullptr) return; + + survey = fmt::format("{}.{}", Game::GetInfo()->GetName(), Game::GetInfo()->GetVersion()); +} + +/** + * Change the bytes of memory into a textual version rounded up to the biggest unit. + * + * For example, 16751108096 would become 16 GiB. + * + * @param memory The bytes of memory. + * @return std::string A textual representation. + */ +std::string SurveyMemoryToText(uint64_t memory) +{ + memory = memory / 1024; // KiB + memory = CeilDiv(memory, 1024); // MiB + + /* Anything above 512 MiB we represent in GiB. */ + if (memory > 512) { + return fmt::format("{} GiB", CeilDiv(memory, 1024)); + } + + /* Anything above 64 MiB we represent in a multiplier of 128 MiB. */ + if (memory > 64) { + return fmt::format("{} MiB", Ceil(memory, 128)); + } + + /* Anything else in a multiplier of 4 MiB. */ + return fmt::format("{} MiB", Ceil(memory, 4)); +} diff --git a/src/survey.h b/src/survey.h new file mode 100644 index 0000000000..d134b94482 --- /dev/null +++ b/src/survey.h @@ -0,0 +1,29 @@ +/* + * This file is part of OpenTTD. + * 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. + * 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. + * 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 . + */ + +/** @file survey.h Functions to survey the current game / system, for crashlog and network-survey. */ + +#ifndef SURVEY_H +#define SURVEY_H + +#include "3rdparty/nlohmann/json.hpp" + +std::string SurveyMemoryToText(uint64_t memory); + +void SurveyCompanies(nlohmann::json &survey); +void SurveyConfiguration(nlohmann::json &survey); +void SurveyFont(nlohmann::json &survey); +void SurveyGameScript(nlohmann::json &survey); +void SurveyGrfs(nlohmann::json &survey); +void SurveyOpenTTD(nlohmann::json &survey); +void SurveySettings(nlohmann::json &survey); +void SurveyTimers(nlohmann::json &survey); + +/* Defined in os//survey_.cpp. */ +void SurveyOS(nlohmann::json &json); + +#endif /* SURVEY_H */