From 9f96b0df330aa4507019680368bb0f7f7ac3beff Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 21 Mar 2022 22:56:21 +0000 Subject: [PATCH] Separate map.change and map.changed events Also fix network plugin logic. --- distribution/openrct2.d.ts | 3 ++- src/openrct2-ui/title/TitleSequencePlayer.cpp | 2 ++ .../windows/EditorObjectSelection.cpp | 1 + src/openrct2-ui/windows/ServerStart.cpp | 7 ++++-- src/openrct2-ui/windows/TitleMenu.cpp | 1 + src/openrct2-ui/windows/TopToolbar.cpp | 1 + src/openrct2/Game.cpp | 25 ++++++++++++++++++- src/openrct2/Game.h | 1 + src/openrct2/network/NetworkBase.cpp | 8 ++++++ src/openrct2/scripting/HookEngine.cpp | 3 ++- src/openrct2/scripting/HookEngine.h | 1 + src/openrct2/scripting/ScriptEngine.cpp | 23 +++++++++++++++-- src/openrct2/scripting/ScriptEngine.h | 1 + 13 files changed, 70 insertions(+), 7 deletions(-) diff --git a/distribution/openrct2.d.ts b/distribution/openrct2.d.ts index fbf5bc9d95..583e90b330 100644 --- a/distribution/openrct2.d.ts +++ b/distribution/openrct2.d.ts @@ -292,6 +292,7 @@ declare global { subscribe(hook: "guest.generation", callback: (e: GuestGenerationArgs) => void): IDisposable; subscribe(hook: "vehicle.crash", callback: (e: VehicleCrashArgs) => void): IDisposable; subscribe(hook: "map.save", callback: () => void): IDisposable; + subscribe(hook: "map.change", callback: () => void): IDisposable; /** * Can only be used in intransient plugins. @@ -405,7 +406,7 @@ declare global { "interval.tick" | "interval.day" | "network.chat" | "network.action" | "network.join" | "network.leave" | "ride.ratings.calculate" | "action.location" | "vehicle.crash" | - "map.changed" | "map.save"; + "map.change" | "map.changed" | "map.save"; type ExpenditureType = "ride_construction" | diff --git a/src/openrct2-ui/title/TitleSequencePlayer.cpp b/src/openrct2-ui/title/TitleSequencePlayer.cpp index 8050409ade..fe4c314004 100644 --- a/src/openrct2-ui/title/TitleSequencePlayer.cpp +++ b/src/openrct2-ui/title/TitleSequencePlayer.cpp @@ -286,6 +286,7 @@ private: auto parkHandle = TitleSequenceGetParkHandle(*_sequence, saveIndex); if (parkHandle != nullptr) { + game_notify_map_change(); loadSuccess = LoadParkFromStream(parkHandle->Stream.get(), parkHandle->HintPath); } if (loadSuccess) @@ -309,6 +310,7 @@ private: auto scenario = GetScenarioRepository()->GetByInternalName(command.Scenario); if (scenario != nullptr) { + game_notify_map_change(); loadSuccess = LoadParkFromFile(scenario->path); } if (loadSuccess) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index f78617e643..47dc405c7e 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -337,6 +337,7 @@ public: } if (gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER) { + game_notify_map_change(); game_unload_scripts(); title_load(); } diff --git a/src/openrct2-ui/windows/ServerStart.cpp b/src/openrct2-ui/windows/ServerStart.cpp index c1765171e5..b64be43961 100644 --- a/src/openrct2-ui/windows/ServerStart.cpp +++ b/src/openrct2-ui/windows/ServerStart.cpp @@ -126,7 +126,7 @@ static void WindowServerStartClose(rct_window* w) static void WindowServerStartScenarioselectCallback(const utf8* path) { - network_set_password(_password); + game_notify_map_change(); if (context_load_park_from_file(path)) { network_begin_server(gConfigNetwork.default_port, gConfigNetwork.listen_address.c_str()); @@ -135,8 +135,10 @@ static void WindowServerStartScenarioselectCallback(const utf8* path) static void WindowServerStartLoadsaveCallback(int32_t result, const utf8* path) { - if (result == MODAL_RESULT_OK && context_load_park_from_file(path)) + if (result == MODAL_RESULT_OK) { + game_notify_map_change(); + context_load_park_from_file(path); network_begin_server(gConfigNetwork.default_port, gConfigNetwork.listen_address.c_str()); } } @@ -185,6 +187,7 @@ static void WindowServerStartMouseup(rct_window* w, rct_widgetindex widgetIndex) w->Invalidate(); break; case WIDX_START_SERVER: + network_set_password(_password); WindowScenarioselectOpen(WindowServerStartScenarioselectCallback, false); break; case WIDX_LOAD_SERVER: diff --git a/src/openrct2-ui/windows/TitleMenu.cpp b/src/openrct2-ui/windows/TitleMenu.cpp index 1cc73987f0..285435ffbc 100644 --- a/src/openrct2-ui/windows/TitleMenu.cpp +++ b/src/openrct2-ui/windows/TitleMenu.cpp @@ -117,6 +117,7 @@ rct_window* WindowTitleMenuOpen() static void WindowTitleMenuScenarioselectCallback(const utf8* path) { + game_notify_map_change(); OpenRCT2::GetContext()->LoadParkFromFile(path, false, true); game_load_scripts(); game_notify_map_changed(); diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 117071df2f..cd0feb9a25 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -535,6 +535,7 @@ static void WindowTopToolbarMousedown(rct_window* w, rct_widgetindex widgetIndex static void WindowTopToolbarScenarioselectCallback(const utf8* path) { window_close_by_class(WC_EDITOR_OBJECT_SELECTION); + game_notify_map_change(); GetContext()->LoadParkFromFile(path, false, true); game_load_scripts(); game_notify_map_changed(); diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp index 85bfb40460..03492494ca 100644 --- a/src/openrct2/Game.cpp +++ b/src/openrct2/Game.cpp @@ -89,6 +89,10 @@ uint32_t gCurrentRealTimeTicks; rct_string_id gGameCommandErrorTitle; rct_string_id gGameCommandErrorText; +#ifdef ENABLE_SCRIPTING +static bool _mapChangedExpected; +#endif + using namespace OpenRCT2; void game_reset_speed() @@ -513,6 +517,22 @@ void game_unload_scripts() #endif } +void game_notify_map_change() +{ +#ifdef ENABLE_SCRIPTING + // Ensure we don't get a two lots of change events + if (_mapChangedExpected) + return; + + using namespace OpenRCT2::Scripting; + + auto& scriptEngine = GetContext()->GetScriptEngine(); + auto& hookEngine = scriptEngine.GetHookEngine(); + hookEngine.Call(HOOK_TYPE::MAP_CHANGE, false); + _mapChangedExpected = true; +#endif +} + void game_notify_map_changed() { #ifdef ENABLE_SCRIPTING @@ -520,7 +540,8 @@ void game_notify_map_changed() auto& scriptEngine = GetContext()->GetScriptEngine(); auto& hookEngine = scriptEngine.GetHookEngine(); - hookEngine.Call(HOOK_TYPE::MAP_CHANGE, false); + hookEngine.Call(HOOK_TYPE::MAP_CHANGED, false); + _mapChangedExpected = false; #endif } @@ -703,6 +724,7 @@ static void game_load_or_quit_no_save_prompt_callback(int32_t result, const utf8 { if (result == MODAL_RESULT_OK) { + game_notify_map_change(); game_unload_scripts(); window_close_by_class(WC_EDITOR_OBJECT_SELECTION); context_load_park_from_file(path); @@ -748,6 +770,7 @@ void game_load_or_quit_no_save_prompt() } gGameSpeed = 1; gFirstTimeSaving = true; + game_notify_map_change(); game_unload_scripts(); title_load(); break; diff --git a/src/openrct2/Game.h b/src/openrct2/Game.h index 1e8465e114..6439e18ba9 100644 --- a/src/openrct2/Game.h +++ b/src/openrct2/Game.h @@ -160,6 +160,7 @@ void load_from_sv6(const char* path); void game_load_init(); void game_load_scripts(); void game_unload_scripts(); +void game_notify_map_change(); void game_notify_map_changed(); void pause_toggle(); bool game_is_paused(); diff --git a/src/openrct2/network/NetworkBase.cpp b/src/openrct2/network/NetworkBase.cpp index 026cfc27c9..3f5abeac91 100644 --- a/src/openrct2/network/NetworkBase.cpp +++ b/src/openrct2/network/NetworkBase.cpp @@ -203,6 +203,11 @@ void NetworkBase::Close() _pendingPlayerLists.clear(); _pendingPlayerInfo.clear(); +# ifdef ENABLE_SCRIPTING + auto& scriptEngine = GetContext().GetScriptEngine(); + scriptEngine.RemoveNetworkPlugins(); +# endif + gfx_invalidate_screen(); _requireClose = false; @@ -2681,6 +2686,9 @@ void NetworkBase::Client_Handle_MAP([[maybe_unused]] NetworkConnection& connecti GameActions::ResumeQueue(); context_force_close_window_by_class(WC_NETWORK_STATUS); + game_unload_scripts(); + game_notify_map_change(); + bool has_to_free = false; uint8_t* data = &chunk_buffer[0]; size_t data_size = size; diff --git a/src/openrct2/scripting/HookEngine.cpp b/src/openrct2/scripting/HookEngine.cpp index a1f9d2302d..19412f2148 100644 --- a/src/openrct2/scripting/HookEngine.cpp +++ b/src/openrct2/scripting/HookEngine.cpp @@ -32,6 +32,7 @@ static const EnumMap HooksLookupTable({ { "guest.generation", HOOK_TYPE::GUEST_GENERATION }, { "vehicle.crash", HOOK_TYPE::VEHICLE_CRASH }, { "map.change", HOOK_TYPE::MAP_CHANGE }, + { "map.changed", HOOK_TYPE::MAP_CHANGED }, { "map.save", HOOK_TYPE::MAP_SAVE }, }); @@ -100,7 +101,7 @@ bool HookEngine::HasSubscriptions(HOOK_TYPE type) const bool HookEngine::IsValidHookForPlugin(HOOK_TYPE type, Plugin& plugin) const { - if (type == HOOK_TYPE::MAP_CHANGE && plugin.GetMetadata().Type != PluginType::Intransient) + if (type == HOOK_TYPE::MAP_CHANGED && plugin.GetMetadata().Type != PluginType::Intransient) { return false; } diff --git a/src/openrct2/scripting/HookEngine.h b/src/openrct2/scripting/HookEngine.h index 832388ace2..c2667b5fe3 100644 --- a/src/openrct2/scripting/HookEngine.h +++ b/src/openrct2/scripting/HookEngine.h @@ -41,6 +41,7 @@ namespace OpenRCT2::Scripting GUEST_GENERATION, VEHICLE_CRASH, MAP_CHANGE, + MAP_CHANGED, MAP_SAVE, COUNT, UNDEFINED = -1, diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp index af76646e45..7d91c10924 100644 --- a/src/openrct2/scripting/ScriptEngine.cpp +++ b/src/openrct2/scripting/ScriptEngine.cpp @@ -455,7 +455,10 @@ void ScriptEngine::RefreshPlugins() std::vector addedPlugins; for (const auto& plugin : _plugins) { - plugins.push_back(std::string(plugin->GetPath())); + if (plugin->HasPath()) + { + plugins.push_back(std::string(plugin->GetPath())); + } } std::set_difference( plugins.begin(), plugins.end(), pluginFiles.begin(), pluginFiles.end(), std::back_inserter(removedPlugins)); @@ -919,7 +922,23 @@ void ScriptEngine::AddNetworkPlugin(std::string_view code) { auto plugin = std::make_shared(_context, std::string()); plugin->SetCode(code); - LoadPlugin(plugin); + _plugins.push_back(plugin); +} + +void ScriptEngine::RemoveNetworkPlugins() +{ + auto it = _plugins.begin(); + while (it != _plugins.end()) + { + if (!(*it)->HasPath()) + { + it = _plugins.erase(it); + } + else + { + it++; + } + } } GameActions::Result ScriptEngine::QueryOrExecuteCustomGameAction(std::string_view id, std::string_view args, bool isExecute) diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h index 2b4208ed72..67709c8a64 100644 --- a/src/openrct2/scripting/ScriptEngine.h +++ b/src/openrct2/scripting/ScriptEngine.h @@ -232,6 +232,7 @@ namespace OpenRCT2::Scripting } void AddNetworkPlugin(std::string_view code); + void RemoveNetworkPlugins(); [[nodiscard]] GameActions::Result QueryOrExecuteCustomGameAction( std::string_view id, std::string_view args, bool isExecute);