diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index dda4bfb1c4..f5eec2847c 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -90,20 +90,20 @@ jobs: - name: Clang compiler: clang cxxcompiler: clang++ - libraries: libsdl2-dev nlohmann-json3-dev + libraries: libsdl2-dev - name: GCC - SDL2 compiler: gcc cxxcompiler: g++ - libraries: libsdl2-dev nlohmann-json3-dev + libraries: libsdl2-dev - name: GCC - SDL1.2 compiler: gcc cxxcompiler: g++ - libraries: libsdl1.2-dev nlohmann-json3-dev + libraries: libsdl1.2-dev - name: GCC - Dedicated compiler: gcc cxxcompiler: g++ extra-cmake-parameters: -DOPTION_DEDICATED=ON -DCMAKE_CXX_FLAGS_INIT="-DRANDOM_DEBUG" - # Compile without SDL / SDL2 / nlohmann-json, as that should compile fine too. + # Compile without SDL / SDL2, as that should compile fine too. name: Linux (${{ matrix.name }}) @@ -139,6 +139,7 @@ jobs: liblzma-dev \ libzstd-dev \ liblzo2-dev \ + nlohmann-json3-dev \ ${{ matrix.libraries }} \ zlib1g-dev \ # EOF diff --git a/.github/workflows/release-source.yml b/.github/workflows/release-source.yml index 4aac6414b8..e662f94caa 100644 --- a/.github/workflows/release-source.yml +++ b/.github/workflows/release-source.yml @@ -152,14 +152,18 @@ jobs: - name: Generate survey key id: survey_key run: | - #PAYLOAD='{"version":"${{ steps.metadata.outputs.version }}","type":"${{ vars.SURVEY_TYPE }}"}' - # - #echo "${{ secrets.SURVEY_SIGNING_KEY }}" > survey_signing_key.pem - #SIGNATURE=$(echo -n "${PAYLOAD}" | openssl dgst -sha256 -sign survey_signing_key.pem | base64 -w0) - #rm -f survey_signing_key.pem - # - #SURVEY_KEY=$(curl -f -s -X POST -d "${PAYLOAD}" -H "Content-Type: application/json" -H "X-Signature: ${SIGNATURE}" https://survey-participate.openttd.org/create-survey-key/${{ vars.SURVEY_TYPE }}) - SURVEY_KEY="" + if [ -z "${{ vars.SURVEY_TYPE }}" ]; then + echo "SURVEY_TYPE variable not found; most likely running in a fork. Skipping step." + SURVEY_KEY="" + else + PAYLOAD='{"version":"${{ steps.metadata.outputs.version }}","type":"${{ vars.SURVEY_TYPE }}"}' + + echo "${{ secrets.SURVEY_SIGNING_KEY }}" > survey_signing_key.pem + SIGNATURE=$(echo -n "${PAYLOAD}" | openssl dgst -sha256 -sign survey_signing_key.pem | base64 -w0) + rm -f survey_signing_key.pem + + SURVEY_KEY=$(curl -f -s -X POST -d "${PAYLOAD}" -H "Content-Type: application/json" -H "X-Signature: ${SIGNATURE}" https://survey-participate.openttd.org/create-survey-key/${{ vars.SURVEY_TYPE }}) + fi echo "survey_key=${SURVEY_KEY}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/release-windows.yml b/.github/workflows/release-windows.yml index 592ab3464b..7140c4a223 100644 --- a/.github/workflows/release-windows.yml +++ b/.github/workflows/release-windows.yml @@ -73,6 +73,13 @@ jobs: zstd \ # EOF + # arm64-windows-static is not (yet) supported for breakpad. + if [ "${{ matrix.arch }}" != "arm64" ]; then + vcpkg install --triplet=${{ matrix.arch }}-windows-static \ + breakpad \ + # EOF + fi + - name: Install MSVC problem matcher uses: ammaraskar/msvc-problem-matcher@master diff --git a/CMakeLists.txt b/CMakeLists.txt index e1f9705447..a0f6ca71d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -114,13 +114,14 @@ endif() set(CMAKE_THREAD_PREFER_PTHREAD YES) # Make sure we have Threads available. find_package(Threads REQUIRED) +# nlohmann is used for all our JSON needs. +find_package(nlohmann_json REQUIRED) find_package(ZLIB) find_package(LibLZMA) find_package(LZO) find_package(ZSTD 1.4) find_package(PNG) -find_package(nlohmann_json) if(WIN32 OR EMSCRIPTEN) # Windows uses WinHttp for HTTP requests. @@ -362,7 +363,7 @@ link_package(ZLIB TARGET ZLIB::ZLIB ENCOURAGED) link_package(LIBLZMA TARGET LibLZMA::LibLZMA ENCOURAGED) link_package(LZO) link_package(ZSTD TARGET ZSTD::ZSTD RECOMMENDED) -link_package(nlohmann_json ENCOURAGED) +link_package(nlohmann_json) if(NOT WIN32 AND NOT EMSCRIPTEN) link_package(CURL ENCOURAGED) diff --git a/COMPILING.md b/COMPILING.md index df2e961c71..178b1fbaae 100644 --- a/COMPILING.md +++ b/COMPILING.md @@ -4,7 +4,7 @@ OpenTTD makes use of the following external libraries: -- (encouraged) nlohmann-json: JSON handling +- (required) nlohmann-json: JSON handling - (encouraged) zlib: (de)compressing of old (0.3.0-1.0.5) savegames, content downloads, heightmaps - (encouraged) liblzma: (de)compressing of savegames (1.1.0 and later) diff --git a/os/emscripten/pre.js b/os/emscripten/pre.js index 31858b1894..8e46ae3460 100644 --- a/os/emscripten/pre.js +++ b/os/emscripten/pre.js @@ -1,4 +1,4 @@ -Module.arguments.push('-mnull', '-snull', '-vsdl:relative_mode'); +Module.arguments.push('-mnull', '-snull', '-vsdl'); Module['websocket'] = { url: function(host, port, proto) { /* openttd.org hosts a WebSocket proxy for the content service. */ if (host == "content.openttd.org" && port == 3978 && proto == "tcp") { @@ -30,46 +30,47 @@ Module.preRun.push(function() { Module.addRunDependency('syncfs'); FS.syncfs(true, function (err) { - /* FS.mkdir() tends to fail if parent folders do not exist. */ - if (!FS.analyzePath(content_download_dir).exists) { - FS.mkdir(content_download_dir); - } - if (!FS.analyzePath(content_download_dir + '/baseset').exists) { - FS.mkdir(content_download_dir + '/baseset'); - } - - /* Check if the OpenGFX baseset is already downloaded. */ - if (!FS.analyzePath(content_download_dir + '/baseset/opengfx-0.6.0.tar').exists) { - window.openttd_downloaded_opengfx = true; - FS.createPreloadedFile(content_download_dir + '/baseset', 'opengfx-0.6.0.tar', 'https://binaries.openttd.org/installer/emscripten/opengfx-0.6.0.tar', true, true); - } else { - /* Fake dependency increase, so the counter is stable. */ - Module.addRunDependency('opengfx'); - Module.removeRunDependency('opengfx'); - } - Module.removeRunDependency('syncfs'); }); window.openttd_syncfs_shown_warning = false; - window.openttd_syncfs = function() { + window.openttd_syncfs = function(callback) { /* Copy the virtual FS to the persistent storage. */ - FS.syncfs(false, function (err) { }); - - /* On first time, warn the user about the volatile behaviour of - * persistent storage. */ - if (!window.openttd_syncfs_shown_warning) { - window.openttd_syncfs_shown_warning = true; - Module.onWarningFs(); - } + FS.syncfs(false, function (err) { + /* On first time, warn the user about the volatile behaviour of + * persistent storage. */ + if (!window.openttd_syncfs_shown_warning) { + window.openttd_syncfs_shown_warning = true; + Module.onWarningFs(); + } + + if (callback) callback(); + }); } window.openttd_exit = function() { - Module.onExit(); + window.openttd_syncfs(Module.onExit); } window.openttd_abort = function() { - Module.onAbort(); + window.openttd_syncfs(Module.onAbort); + } + + window.openttd_bootstrap = function(current, total) { + Module.onBootstrap(current, total); + } + + window.openttd_bootstrap_failed = function() { + Module.onBootstrapFailed(); + } + + window.openttd_bootstrap_reload = function() { + window.openttd_syncfs(function() { + Module.onBootstrapReload(); + setTimeout(function() { + location.reload(); + }, 1000); + }); } window.openttd_server_list = function() { @@ -123,11 +124,3 @@ Module.preRun.push(function() { return ret; } }); - -Module.postRun.push(function() { - /* Check if we downloaded OpenGFX; if so, sync the virtual FS back to the - * IDBFS so OpenGFX is stored persistent. */ - if (window['openttd_downloaded_opengfx']) { - FS.syncfs(false, function (err) { }); - } -}); diff --git a/os/emscripten/shell.html b/os/emscripten/shell.html index af031c6df8..21f720e7e4 100644 --- a/os/emscripten/shell.html +++ b/os/emscripten/shell.html @@ -75,7 +75,6 @@ } #message { color: #101010; - height: 54px; padding: 4px 4px; } @@ -144,6 +143,8 @@ })(), setStatus: function(text) { + if (document.getElementById("canvas").style.display == "none") return; + var m = text.match(/^([^(]+)\((\d+(\.\d+)?)\/(\d+)\)$/); if (m) { @@ -171,6 +172,27 @@ document.getElementById("message").innerHTML = "Preparing game ..."; }, + onBootstrap: function(current, total) { + document.getElementById("canvas").style.display = "none"; + + document.getElementById("title").innerHTML = "Missing base graphics"; + document.getElementById("message").innerHTML = "OpenTTD is downloading base graphics.

" + current + " / " + total + " bytes downloaded."; + }, + + onBootstrapFailed: function(current, total) { + document.getElementById("canvas").style.display = "none"; + + document.getElementById("title").innerHTML = "Missing base graphics"; + document.getElementById("message").innerHTML = "Failed to download base graphics.
The game cannot start without base graphics.

Please check your Internet connection and/or the console log.
Reload your browser to try again."; + }, + + onBootstrapReload: function() { + document.getElementById("canvas").style.display = "none"; + + document.getElementById("title").innerHTML = "Missing base graphics"; + document.getElementById("message").innerHTML = "Downloading base graphics done.

Your browser will reload to start the game."; + }, + onExit: function() { document.getElementById("canvas").style.display = "none"; diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index 2399f318d4..2ebf6eab68 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.cpp @@ -285,6 +285,76 @@ public: #endif /* defined(WITH_FREETYPE) */ +#if defined(__EMSCRIPTEN__) +# include +# include "network/network.h" +# include "network/network_content.h" +# include "openttd.h" +# include "video/video_driver.hpp" + +class BootstrapEmscripten : public ContentCallback { + bool downloading{false}; + uint total_files{0}; + uint total_bytes{0}; + uint downloaded_bytes{0}; + +public: + BootstrapEmscripten() + { + _network_content_client.AddCallback(this); + _network_content_client.Connect(); + } + + ~BootstrapEmscripten() + { + _network_content_client.RemoveCallback(this); + } + + void OnConnect(bool success) override + { + if (!success) { + EM_ASM({ if (window["openttd_bootstrap_failed"]) openttd_bootstrap_failed(); }); + return; + } + + /* Once connected, request the metadata. */ + _network_content_client.RequestContentList(CONTENT_TYPE_BASE_GRAPHICS); + } + + void OnReceiveContentInfo(const ContentInfo *ci) override + { + if (this->downloading) return; + + /* And once the metadata is received, start downloading it. */ + _network_content_client.Select(ci->id); + _network_content_client.DownloadSelectedContent(this->total_files, this->total_bytes); + this->downloading = true; + + EM_ASM({ if (window["openttd_bootstrap"]) openttd_bootstrap($0, $1); }, this->downloaded_bytes, this->total_bytes); + } + + void OnDownloadProgress(const ContentInfo *ci, int bytes) override + { + /* A negative value means we are resetting; for example, when retrying or using a fallback. */ + if (bytes < 0) { + this->downloaded_bytes = 0; + } else { + this->downloaded_bytes += bytes; + } + + EM_ASM({ if (window["openttd_bootstrap"]) openttd_bootstrap($0, $1); }, this->downloaded_bytes, this->total_bytes); + } + + void OnDownloadComplete(ContentID cid) override + { + /* _exit_game is used to break out of the outer video driver's MainLoop. */ + _exit_game = true; + + delete this; + } +}; +#endif /* __EMSCRIPTEN__ */ + /** * Handle all procedures for bootstrapping OpenTTD without a base graphics set. * This requires all kinds of trickery that is needed to avoid the use of @@ -299,12 +369,15 @@ bool HandleBootstrap() if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() == 0) goto failure; /* If there is no network or no non-sprite font, then there is nothing we can do. Go straight to failure. */ -#if (defined(_WIN32) && defined(WITH_UNISCRIBE)) || (defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(__APPLE__))) || defined(WITH_COCOA) +#if defined(__EMSCRIPTEN__) || (defined(_WIN32) && defined(WITH_UNISCRIBE)) || (defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(__APPLE__))) || defined(WITH_COCOA) if (!_network_available) goto failure; /* First tell the game we're bootstrapping. */ _game_mode = GM_BOOTSTRAP; +#if defined(__EMSCRIPTEN__) + new BootstrapEmscripten(); +#else /* Initialise the font cache. */ InitializeUnicodeGlyphMap(); /* Next "force" finding a suitable non-sprite font as the local font is missing. */ @@ -323,6 +396,7 @@ bool HandleBootstrap() /* Finally ask the question. */ new BootstrapBackground(); new BootstrapAskForDownloadWindow(); +#endif /* __EMSCRIPTEN__ */ /* Process the user events. */ VideoDriver::GetInstance()->MainLoop(); diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index e2de39349c..733dbd40df 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -1187,7 +1187,7 @@ STR_TERRAIN_TYPE_CUSTOM :Alçada persona STR_TERRAIN_TYPE_CUSTOM_VALUE :Alçada personalitzada ({NUM}) ###length 4 -STR_CITY_APPROVAL_LENIENT :Tolerant +STR_CITY_APPROVAL_LENIENT :Indulgent STR_CITY_APPROVAL_TOLERANT :Tolerant STR_CITY_APPROVAL_HOSTILE :Hostil STR_CITY_APPROVAL_PERMISSIVE :Permissiva (les accions de les companyies no l'afecten) @@ -2651,6 +2651,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Commuta STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Commuta la transparència dels ponts. Ctrl+Clic per bloquejar STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Commuta la transparència de les estructures com ara fars i antenes. Ctrl+Clic per bloquejar STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Commuta la transparència de la catenària. CTRL+clic per bloquejar +STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Commuta la transparència dels indicadors de càrrega i el text de despesa/ingrés. Ctrl+Clic per a blocar. STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Alternar entre transparència i invisibilitat dels objectes # Linkgraph legend window diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 80f03de4a3..e23d49287b 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -2650,6 +2650,7 @@ STR_TRANSPARENT_BUILDINGS_TOOLTIP :{BLACK}Transpar STR_TRANSPARENT_BRIDGES_TOOLTIP :{BLACK}Transparantie voor bruggen aan-uit. Ctrl+klik om vast te zetten. STR_TRANSPARENT_STRUCTURES_TOOLTIP :{BLACK}Transparantie voor gebouwen zoals vuurtorens en zendmasten aan-uit. Ctrl+klik om vast te zetten. STR_TRANSPARENT_CATENARY_TOOLTIP :{BLACK}Transparantie voor bovenleiding aan-uit. Ctrl+klik om vast te zetten. +STR_TRANSPARENT_TEXT_TOOLTIP :{BLACK}Transparantie omschakelen voor teksten bij laden en kosten/inkomsten. Ctrl+klik om vast te zetten STR_TRANSPARENT_INVISIBLE_TOOLTIP :{BLACK}Maak objecten onzichtbaar in plaats van transparant # Linkgraph legend window diff --git a/src/network/network_survey.cpp b/src/network/network_survey.cpp index 1b173931a3..c3c2bd5753 100644 --- a/src/network/network_survey.cpp +++ b/src/network/network_survey.cpp @@ -37,9 +37,7 @@ #include "../base_media_base.h" #include "../blitter/factory.hpp" -#ifdef WITH_NLOHMANN_JSON #include -#endif /* WITH_NLOHMANN_JSON */ #include "../safeguards.h" @@ -47,8 +45,6 @@ extern std::string _savegame_id; NetworkSurveyHandler _survey = {}; -#ifdef WITH_NLOHMANN_JSON - NLOHMANN_JSON_SERIALIZE_ENUM(NetworkSurveyHandler::Reason, { {NetworkSurveyHandler::Reason::PREVIEW, "preview"}, {NetworkSurveyHandler::Reason::LEAVE, "leave"}, @@ -114,8 +110,12 @@ static void SurveySettings(nlohmann::json &survey) */ static void SurveyOpenTTD(nlohmann::json &survey) { - survey["version"] = std::string(_openttd_revision); - survey["newgrf_version"] = _openttd_newgrf_version; + 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 @@ -227,6 +227,21 @@ static void SurveyCompanies(nlohmann::json &survey) } } +/** + * Convert timer information to JSON. + * + * @param survey The JSON object. + */ +static void SurveyTimers(nlohmann::json &survey) +{ + survey["ticks"] = _scaled_tick_counter; + survey["seconds"] = std::chrono::duration_cast(std::chrono::steady_clock::now() - _switch_mode_time).count(); + + YearMonthDay ymd; + ConvertDateToYMD(_date, &ymd); + survey["calendar"] = fmt::format("{:04}-{:02}-{:02} ({})", ymd.year, ymd.month + 1, ymd.day, _date_fract); +} + /** * Convert GRF information to JSON. * @@ -298,8 +313,6 @@ std::string SurveyMemoryToText(uint64_t memory) return fmt::format("{} MiB", Ceil(memory, 4)); } -#endif /* WITH_NLOHMANN_JSON */ - /** * Create the payload for the survey. * @@ -309,9 +322,6 @@ std::string SurveyMemoryToText(uint64_t memory) */ std::string NetworkSurveyHandler::CreatePayload(Reason reason, bool for_preview) { -#ifndef WITH_NLOHMANN_JSON - return ""; -#else nlohmann::json survey; survey["schema"] = NETWORK_SURVEY_VERSION; @@ -335,8 +345,7 @@ std::string NetworkSurveyHandler::CreatePayload(Reason reason, bool for_preview) { auto &game = survey["game"]; - game["ticks"] = _scaled_tick_counter; - game["time"] = std::chrono::duration_cast(std::chrono::steady_clock::now() - _switch_mode_time).count(); + SurveyTimers(game["timers"]); SurveyCompanies(game["companies"]); SurveySettings(game["settings"]); SurveyGrfs(game["grfs"]); @@ -346,7 +355,6 @@ std::string NetworkSurveyHandler::CreatePayload(Reason reason, bool for_preview) /* For preview, we indent with 4 whitespaces to make things more readable. */ int indent = for_preview ? 4 : -1; return survey.dump(indent); -#endif /* WITH_NLOHMANN_JSON */ } /** diff --git a/src/network/network_survey.h b/src/network/network_survey.h index 59815c8006..a705c0143e 100644 --- a/src/network/network_survey.h +++ b/src/network/network_survey.h @@ -40,12 +40,12 @@ public: constexpr static bool IsSurveyPossible() { -#if !(defined(WITH_NLOHMANN_JSON) && defined(SURVEY_KEY)) - /* Without JSON library, we cannot send a payload; so we disable the survey. */ +#if !defined(SURVEY_KEY) + /* Without a survey key, we cannot send a payload; so we disable the survey. */ return false; #else return true; -#endif /* WITH_NLOHMANN_JSON */ +#endif /* SURVEY_KEY */ } private: diff --git a/src/openttd.cpp b/src/openttd.cpp index 7c4e91811e..ec5698c0c4 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -164,7 +164,6 @@ void CDECL usererror(const char *s, ...) /* In effect, the game ends here. As emscripten_set_main_loop() caused * the stack to be unwound, the code after MainLoop() in * openttd_main() is never executed. */ - EM_ASM(if (window["openttd_syncfs"]) openttd_syncfs()); EM_ASM(if (window["openttd_abort"]) openttd_abort()); #endif @@ -682,6 +681,22 @@ struct AfterNewGRFScan : NewGRFScanCallback { } }; +void PostMainLoop() +{ + WaitTillSaved(); + + /* only save config if we have to */ + if (_save_config) { + SaveToConfig(STCF_ALL); + SaveHotkeysToConfig(); + WindowDesc::SaveToConfig(); + SaveToHighScore(); + } + + /* Reset windowing system, stop drivers, free used memory, ... */ + ShutdownGame(); +} + #if defined(UNIX) extern void DedicatedFork(); #endif @@ -1040,18 +1055,7 @@ int openttd_main(int argc, char *argv[]) _general_worker_pool.Stop(); - WaitTillSaved(); - - /* only save config if we have to */ - if (_save_config) { - SaveToConfig(STCF_ALL); - SaveHotkeysToConfig(); - WindowDesc::SaveToConfig(); - SaveToHighScore(); - } - - /* Reset windowing system, stop drivers, free used memory, ... */ - ShutdownGame(); + PostMainLoop(); return ret; } diff --git a/src/os/macosx/survey_osx.cpp b/src/os/macosx/survey_osx.cpp index 8affddd34b..5f214906e8 100644 --- a/src/os/macosx/survey_osx.cpp +++ b/src/os/macosx/survey_osx.cpp @@ -7,8 +7,6 @@ /** @file survey_osx.cpp OSX implementation of OS-specific survey information. */ -#ifdef WITH_NLOHMANN_JSON - #include "../../stdafx.h" #include "../../core/format.hpp" @@ -38,5 +36,3 @@ void SurveyOS(nlohmann::json &json) json["memory"] = SurveyMemoryToText(MacOSGetPhysicalMemory()); json["hardware_concurrency"] = std::thread::hardware_concurrency(); } - -#endif /* WITH_NLOHMANN_JSON */ diff --git a/src/os/unix/survey_unix.cpp b/src/os/unix/survey_unix.cpp index d831a78390..fea37d89da 100644 --- a/src/os/unix/survey_unix.cpp +++ b/src/os/unix/survey_unix.cpp @@ -7,8 +7,6 @@ /** @file survey_unix.cpp Unix implementation of OS-specific survey information. */ -#ifdef WITH_NLOHMANN_JSON - #include "../../stdafx.h" #include @@ -38,5 +36,3 @@ void SurveyOS(nlohmann::json &json) json["memory"] = SurveyMemoryToText(pages * page_size); json["hardware_concurrency"] = std::thread::hardware_concurrency(); } - -#endif /* WITH_NLOHMANN_JSON */ diff --git a/src/os/windows/survey_win.cpp b/src/os/windows/survey_win.cpp index 07505f74e7..6476bcb1ab 100644 --- a/src/os/windows/survey_win.cpp +++ b/src/os/windows/survey_win.cpp @@ -7,8 +7,6 @@ /** @file survey_win.cpp Windows implementation of OS-specific survey information. */ -#ifdef WITH_NLOHMANN_JSON - #include "../../stdafx.h" #include "../../core/format.hpp" @@ -41,5 +39,3 @@ void SurveyOS(nlohmann::json &json) json["memory"] = SurveyMemoryToText(status.ullTotalPhys); json["hardware_concurrency"] = std::thread::hardware_concurrency(); } - -#endif /* WITH_NLOHMANN_JSON */ diff --git a/src/script/api/script_admin.cpp b/src/script/api/script_admin.cpp index 48b52bea9b..6c52df374c 100644 --- a/src/script/api/script_admin.cpp +++ b/src/script/api/script_admin.cpp @@ -130,7 +130,10 @@ } std::string json; - ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json); + if (!ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json)) { + sq_pushinteger(vm, 0); + return 1; + } if (json.length() > NETWORK_GAMESCRIPT_JSON_LENGTH) { ScriptLog::Error("You are trying to send a table that is too large to the AdminPort. No data sent."); diff --git a/src/script/api/script_admin.hpp b/src/script/api/script_admin.hpp index 95b7218eb0..8e07985d03 100644 --- a/src/script/api/script_admin.hpp +++ b/src/script/api/script_admin.hpp @@ -37,7 +37,7 @@ public: static bool Send(void *table); #endif /* DOXYGEN_API */ -private: +protected: /** * Convert a Squirrel structure into a JSON string. * @param vm The VM to operate on. diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index 2d388e8012..ff3fa70951 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.cpp @@ -220,11 +220,11 @@ const char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, const char *p) SKIP_EMPTY(p); if (strncmp(p, "false", 5) == 0) { - sq_pushinteger(vm, 0); + sq_pushbool(vm, 0); return p + 5; } if (strncmp(p, "true", 4) == 0) { - sq_pushinteger(vm, 1); + sq_pushbool(vm, 1); return p + 4; } if (strncmp(p, "null", 4) == 0) { diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index b865bac777..cee1a17ec7 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.hpp @@ -44,6 +44,7 @@ typedef bool (ScriptAsyncModeProc)(); class ScriptObject : public SimpleCountedObject { friend class ScriptInstance; friend class ScriptController; +friend class TestScriptController; protected: /** * A class that handles the current active instance. By instantiating it at diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp index 1431a4a5c1..962511aceb 100644 --- a/src/video/sdl2_v.cpp +++ b/src/video/sdl2_v.cpp @@ -947,13 +947,19 @@ void VideoDriver_SDL_Base::LoopOnce() * normally done at the end of the main loop for non-Emscripten. * After that, Emscripten just halts, and the HTML shows a nice * "bye, see you next time" message. */ + extern void PostMainLoop(); + PostMainLoop(); + emscripten_cancel_main_loop(); emscripten_exit_pointerlock(); /* In effect, the game ends here. As emscripten_set_main_loop() caused * the stack to be unwound, the code after MainLoop() in * openttd_main() is never executed. */ - EM_ASM(if (window["openttd_syncfs"]) openttd_syncfs()); - EM_ASM(if (window["openttd_exit"]) openttd_exit()); + if (_game_mode == GM_BOOTSTRAP) { + EM_ASM(if (window["openttd_bootstrap_reload"]) openttd_bootstrap_reload()); + } else { + EM_ASM(if (window["openttd_exit"]) openttd_exit()); + } #endif return; }