diff --git a/openrct2.common.props b/openrct2.common.props
index e62f3ea129..f8228d5e25 100644
--- a/openrct2.common.props
+++ b/openrct2.common.props
@@ -54,6 +54,7 @@
C4555: expression has no effect; expected expression with side-effect
-->
__AVX2__;__SSE4_1__;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions)
+ __ENABLE_SCRIPTING__;%(PreprocessorDefinitions)
MultiThreaded
MultiThreadedDLL
true
diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp
index 1f75eac344..78d8b9ee75 100644
--- a/src/openrct2-ui/UiContext.cpp
+++ b/src/openrct2-ui/UiContext.cpp
@@ -120,8 +120,10 @@ public:
void Initialise() override
{
+#ifdef __ENABLE_SCRIPTING__
auto& scriptEngine = GetContext()->GetScriptEngine();
UiScriptExtensions::Extend(scriptEngine);
+#endif
}
void Update() override
diff --git a/src/openrct2-ui/scripting/CustomMenu.cpp b/src/openrct2-ui/scripting/CustomMenu.cpp
index 63e79e3b67..542a0366b6 100644
--- a/src/openrct2-ui/scripting/CustomMenu.cpp
+++ b/src/openrct2-ui/scripting/CustomMenu.cpp
@@ -7,7 +7,9 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
-#include "CustomMenu.h"
+#ifdef __ENABLE_SCRIPTING__
+
+# include "CustomMenu.h"
namespace OpenRCT2::Scripting
{
@@ -34,3 +36,5 @@ namespace OpenRCT2::Scripting
scriptEngine.SubscribeToPluginStoppedEvent([](std::shared_ptr plugin) -> void { RemoveMenuItems(plugin); });
}
} // namespace OpenRCT2::Scripting
+
+#endif
diff --git a/src/openrct2-ui/scripting/CustomMenu.h b/src/openrct2-ui/scripting/CustomMenu.h
index 74f1a009bd..05300ac894 100644
--- a/src/openrct2-ui/scripting/CustomMenu.h
+++ b/src/openrct2-ui/scripting/CustomMenu.h
@@ -9,12 +9,14 @@
#pragma once
-#include
-#include
-#include
-#include
-#include
-#include
+#ifdef __ENABLE_SCRIPTING__
+
+# include
+# include
+# include
+# include
+# include
+# include
namespace OpenRCT2::Scripting
{
@@ -50,3 +52,5 @@ namespace OpenRCT2::Scripting
void InitialiseCustomMenuItems(ScriptEngine& scriptEngine);
} // namespace OpenRCT2::Scripting
+
+#endif
diff --git a/src/openrct2-ui/scripting/CustomWindow.cpp b/src/openrct2-ui/scripting/CustomWindow.cpp
index d93b512d13..28c5af6a66 100644
--- a/src/openrct2-ui/scripting/CustomWindow.cpp
+++ b/src/openrct2-ui/scripting/CustomWindow.cpp
@@ -7,21 +7,23 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
-#include "../interface/Dropdown.h"
-#include "ScUi.hpp"
-#include "ScWindow.hpp"
+#ifdef __ENABLE_SCRIPTING__
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
+# include "../interface/Dropdown.h"
+# include "ScUi.hpp"
+# include "ScWindow.hpp"
+
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+# include
+# include
using namespace OpenRCT2;
using namespace OpenRCT2::Scripting;
@@ -711,3 +713,5 @@ namespace OpenRCT2::Ui::Windows
}
} // namespace OpenRCT2::Ui::Windows
+
+#endif
diff --git a/src/openrct2-ui/scripting/UiExtensions.cpp b/src/openrct2-ui/scripting/UiExtensions.cpp
index 0eb68ea9d6..b70f9552fc 100644
--- a/src/openrct2-ui/scripting/UiExtensions.cpp
+++ b/src/openrct2-ui/scripting/UiExtensions.cpp
@@ -7,14 +7,16 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
-#include "UiExtensions.h"
+#ifdef __ENABLE_SCRIPTING__
-#include "CustomMenu.h"
-#include "ScUi.hpp"
-#include "ScWidget.hpp"
-#include "ScWindow.hpp"
+# include "UiExtensions.h"
-#include
+# include "CustomMenu.h"
+# include "ScUi.hpp"
+# include "ScWidget.hpp"
+# include "ScWindow.hpp"
+
+# include
using namespace OpenRCT2::Scripting;
@@ -31,3 +33,5 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine)
InitialiseCustomMenuItems(scriptEngine);
}
+
+#endif
diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp
index 48c81d0643..0ddd5ade53 100644
--- a/src/openrct2-ui/windows/TopToolbar.cpp
+++ b/src/openrct2-ui/windows/TopToolbar.cpp
@@ -3282,6 +3282,7 @@ static void top_toolbar_init_map_menu(rct_window* w, rct_widget* widget)
gDropdownItemsFormat[i++] = STR_MAPGEN_WINDOW_TITLE;
}
+#ifdef __ENABLE_SCRIPTING__
const auto& customMenuItems = OpenRCT2::Scripting::CustomMenuItems;
if (!customMenuItems.empty())
{
@@ -3293,6 +3294,7 @@ static void top_toolbar_init_map_menu(rct_window* w, rct_widget* widget)
i++;
}
}
+#endif
window_dropdown_show_text(
w->windowPos.x + widget->left, w->windowPos.y + widget->top, widget->bottom - widget->top + 1, w->colours[1] | 0x80, 0,
@@ -3325,12 +3327,14 @@ static void top_toolbar_map_menu_dropdown(int16_t dropdownIndex)
}
else
{
+#ifdef __ENABLE_SCRIPTING__
const auto& customMenuItems = OpenRCT2::Scripting::CustomMenuItems;
auto customIndex = static_cast(dropdownIndex - customStartIndex);
if (customMenuItems.size() > customIndex)
{
customMenuItems[customIndex].Invoke();
}
+#endif
}
}
diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp
index 7dd8edf040..0a04bea93b 100644
--- a/src/openrct2/Context.cpp
+++ b/src/openrct2/Context.cpp
@@ -103,7 +103,9 @@ namespace OpenRCT2
std::unique_ptr _discordService;
#endif
StdInOutConsole _stdInOutConsole;
+#ifdef __ENABLE_SCRIPTING__
ScriptEngine _scriptEngine;
+#endif
// Game states
std::unique_ptr _titleScreen;
@@ -138,7 +140,9 @@ namespace OpenRCT2
, _audioContext(audioContext)
, _uiContext(uiContext)
, _localisationService(std::make_unique(env))
+#ifdef __ENABLE_SCRIPTING__
, _scriptEngine(_stdInOutConsole, *env)
+#endif
, _painter(std::make_unique(uiContext))
{
// Can't have more than one context currently.
@@ -181,10 +185,12 @@ namespace OpenRCT2
return _uiContext;
}
+#ifdef __ENABLE_SCRIPTING__
Scripting::ScriptEngine& GetScriptEngine() override
{
return _scriptEngine;
}
+#endif
GameState* GetGameState() override
{
@@ -1026,7 +1032,10 @@ namespace OpenRCT2
Twitch::Update();
chat_update();
+#ifdef __ENABLE_SCRIPTING__
_scriptEngine.Update();
+#endif
+ _stdInOutConsole.ProcessEvalQueue();
_uiContext->Update();
}
diff --git a/src/openrct2/Context.h b/src/openrct2/Context.h
index c8ee6181ed..0ec9465f13 100644
--- a/src/openrct2/Context.h
+++ b/src/openrct2/Context.h
@@ -114,7 +114,9 @@ namespace OpenRCT2
virtual Localisation::LocalisationService& GetLocalisationService() abstract;
virtual IObjectManager& GetObjectManager() abstract;
virtual IObjectRepository& GetObjectRepository() abstract;
+#ifdef __ENABLE_SCRIPTING__
virtual Scripting::ScriptEngine& GetScriptEngine() abstract;
+#endif
virtual ITrackDesignRepository* GetTrackDesignRepository() abstract;
virtual IScenarioRepository* GetScenarioRepository() abstract;
virtual IReplayManager* GetReplayManager() abstract;
diff --git a/src/openrct2/Game.cpp b/src/openrct2/Game.cpp
index 7526bb5d2c..cdbf7ff8bc 100644
--- a/src/openrct2/Game.cpp
+++ b/src/openrct2/Game.cpp
@@ -592,12 +592,16 @@ void game_load_init()
void game_load_scripts()
{
+#ifdef __ENABLE_SCRIPTING__
GetContext()->GetScriptEngine().LoadPlugins();
+#endif
}
void game_finish()
{
+#ifdef __ENABLE_SCRIPTING__
GetContext()->GetScriptEngine().UnloadPlugins();
+#endif
}
/**
diff --git a/src/openrct2/GameState.cpp b/src/openrct2/GameState.cpp
index 568fdb2183..4e9de175a2 100644
--- a/src/openrct2/GameState.cpp
+++ b/src/openrct2/GameState.cpp
@@ -269,18 +269,22 @@ void GameState::UpdateLogic()
}
}
+#ifdef __ENABLE_SCRIPTING__
auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine();
hookEngine.Call(HOOK_TYPE::INTERVAL_TICK, true);
auto day = _date.GetDay();
+#endif
date_update();
_date = Date(gDateMonthsElapsed, gDateMonthTicks);
+#ifdef __ENABLE_SCRIPTING__
if (day != _date.GetDay())
{
hookEngine.Call(HOOK_TYPE::INTERVAL_DAY, true);
}
+#endif
scenario_update();
climate_update();
diff --git a/src/openrct2/interface/InteractiveConsole.h b/src/openrct2/interface/InteractiveConsole.h
index ce35d74e1d..136c135eb8 100644
--- a/src/openrct2/interface/InteractiveConsole.h
+++ b/src/openrct2/interface/InteractiveConsole.h
@@ -13,6 +13,7 @@
#include "../localisation/FormatCodes.h"
#include
+#include
#include
struct rct_drawpixelinfo;
@@ -50,9 +51,13 @@ public:
class StdInOutConsole final : public InteractiveConsole
{
+private:
+ std::queue, std::string>> _evalQueue;
+
public:
void Start();
std::future Eval(const std::string& s);
+ void ProcessEvalQueue();
void Clear() override;
void Close() override;
diff --git a/src/openrct2/interface/StdInOutConsole.cpp b/src/openrct2/interface/StdInOutConsole.cpp
index 9491b00cd7..9fc0ac896a 100644
--- a/src/openrct2/interface/StdInOutConsole.cpp
+++ b/src/openrct2/interface/StdInOutConsole.cpp
@@ -55,8 +55,35 @@ void StdInOutConsole::Start()
std::future StdInOutConsole::Eval(const std::string& s)
{
+#ifdef __ENABLE_SCRIPTING__
auto& scriptEngine = GetContext()->GetScriptEngine();
return scriptEngine.Eval(s);
+#else
+ // Push on-demand evaluations onto a queue so that it can be processed deterministically
+ // on the main thead at the right time.
+ std::promise barrier;
+ auto future = barrier.get_future();
+ _evalQueue.emplace(std::move(barrier), s);
+ return future;
+#endif
+}
+
+void StdInOutConsole::ProcessEvalQueue()
+{
+#ifndef __ENABLE_SCRIPTING__
+ while (_evalQueue.size() > 0)
+ {
+ auto item = std::move(_evalQueue.front());
+ _evalQueue.pop();
+ auto promise = std::move(std::get<0>(item));
+ auto command = std::move(std::get<1>(item));
+
+ Execute(command);
+
+ // Signal the promise so caller can continue
+ promise.set_value();
+ }
+#endif
}
void StdInOutConsole::Clear()
diff --git a/src/openrct2/network/Network.cpp b/src/openrct2/network/Network.cpp
index 10f36d33a6..8ced55ee05 100644
--- a/src/openrct2/network/Network.cpp
+++ b/src/openrct2/network/Network.cpp
@@ -1472,6 +1472,9 @@ void Network::Server_Send_OBJECTS(NetworkConnection& connection, const std::vect
void Network::Server_Send_SCRIPTS(NetworkConnection& connection) const
{
+ std::unique_ptr packet(NetworkPacket::Allocate());
+ *packet << (uint32_t)NETWORK_COMMAND_SCRIPTS;
+# ifdef __ENABLE_SCRIPTING__
using namespace OpenRCT2::Scripting;
auto& scriptEngine = GetContext()->GetScriptEngine();
@@ -1487,8 +1490,7 @@ void Network::Server_Send_SCRIPTS(NetworkConnection& connection) const
}
log_verbose("Server sends %u scripts", pluginsToSend.size());
- std::unique_ptr packet(NetworkPacket::Allocate());
- *packet << (uint32_t)NETWORK_COMMAND_SCRIPTS << (uint32_t)pluginsToSend.size();
+ *packet << (uint32_t)pluginsToSend.size();
for (const auto& plugin : pluginsToSend)
{
const auto& metadata = plugin->GetMetadata();
@@ -1498,6 +1500,9 @@ void Network::Server_Send_SCRIPTS(NetworkConnection& connection) const
*packet << (uint32_t)code.size();
packet->Write((const uint8_t*)code.c_str(), code.size());
}
+# else
+ *packet << (uint32_t)0;
+# endif
connection.QueuePacket(std::move(packet));
}
@@ -2437,10 +2442,11 @@ void Network::Client_Handle_OBJECTS(NetworkConnection& connection, NetworkPacket
void Network::Client_Handle_SCRIPTS(NetworkConnection& connection, NetworkPacket& packet)
{
- auto& scriptEngine = GetContext()->GetScriptEngine();
-
uint32_t numScripts{};
packet >> numScripts;
+
+# ifdef __ENABLE_SCRIPTING__
+ auto& scriptEngine = GetContext()->GetScriptEngine();
for (uint32_t i = 0; i < numScripts; i++)
{
uint32_t codeLength{};
@@ -2448,6 +2454,13 @@ void Network::Client_Handle_SCRIPTS(NetworkConnection& connection, NetworkPacket
auto code = std::string_view((const char*)packet.Read(codeLength), codeLength);
scriptEngine.AddNetworkPlugin(code);
}
+# else
+ if (numScripts > 0)
+ {
+ connection.SetLastDisconnectReason("The server requires plugin support.");
+ Close();
+ }
+# endif
}
void Network::Client_Handle_GAMESTATE(NetworkConnection& connection, NetworkPacket& packet)
@@ -2891,6 +2904,7 @@ void Network::Server_Handle_CHAT(NetworkConnection& connection, NetworkPacket& p
std::string text = szText;
if (connection.Player != nullptr)
{
+# ifdef __ENABLE_SCRIPTING__
auto& hookEngine = GetContext()->GetScriptEngine().GetHookEngine();
if (hookEngine.HasSubscriptions(OpenRCT2::Scripting::HOOK_TYPE::NETWORK_CHAT))
{
@@ -2920,6 +2934,7 @@ void Network::Server_Handle_CHAT(NetworkConnection& connection, NetworkPacket& p
return;
}
}
+# endif
}
const char* formatted = FormatChat(connection.Player, text.c_str());
diff --git a/src/openrct2/scripting/HookEngine.cpp b/src/openrct2/scripting/HookEngine.cpp
index 1e6801d189..ee554fd75a 100644
--- a/src/openrct2/scripting/HookEngine.cpp
+++ b/src/openrct2/scripting/HookEngine.cpp
@@ -1,5 +1,5 @@
/*****************************************************************************
- * Copyright (c) 2014-2018 OpenRCT2 developers
+ * Copyright (c) 2014-2020 OpenRCT2 developers
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
@@ -7,11 +7,13 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
-#include "HookEngine.h"
+#ifdef __ENABLE_SCRIPTING__
-#include "ScriptEngine.h"
+# include "HookEngine.h"
-#include
+# include "ScriptEngine.h"
+
+# include
using namespace OpenRCT2::Scripting;
@@ -171,3 +173,5 @@ const HookList& HookEngine::GetHookList(HOOK_TYPE type) const
auto index = static_cast(type);
return _hookMap[index];
}
+
+#endif
diff --git a/src/openrct2/scripting/ScriptEngine.cpp b/src/openrct2/scripting/ScriptEngine.cpp
index e067791114..796cb96e02 100644
--- a/src/openrct2/scripting/ScriptEngine.cpp
+++ b/src/openrct2/scripting/ScriptEngine.cpp
@@ -7,28 +7,30 @@
* OpenRCT2 is licensed under the GNU General Public License version 3.
*****************************************************************************/
-#include "ScriptEngine.h"
+#ifdef __ENABLE_SCRIPTING__
-#include "../PlatformEnvironment.h"
-#include "../config/Config.h"
-#include "../core/FileScanner.h"
-#include "../core/Path.hpp"
-#include "../interface/InteractiveConsole.h"
-#include "../platform/Platform2.h"
-#include "Duktape.hpp"
-#include "ScConsole.hpp"
-#include "ScContext.hpp"
-#include "ScDate.hpp"
-#include "ScDisposable.hpp"
-#include "ScMap.hpp"
-#include "ScNetwork.hpp"
-#include "ScPark.hpp"
-#include "ScRide.hpp"
-#include "ScThing.hpp"
-#include "ScTile.hpp"
+# include "ScriptEngine.h"
-#include
-#include
+# include "../PlatformEnvironment.h"
+# include "../config/Config.h"
+# include "../core/FileScanner.h"
+# include "../core/Path.hpp"
+# include "../interface/InteractiveConsole.h"
+# include "../platform/Platform2.h"
+# include "Duktape.hpp"
+# include "ScConsole.hpp"
+# include "ScContext.hpp"
+# include "ScDate.hpp"
+# include "ScDisposable.hpp"
+# include "ScMap.hpp"
+# include "ScNetwork.hpp"
+# include "ScPark.hpp"
+# include "ScRide.hpp"
+# include "ScThing.hpp"
+# include "ScTile.hpp"
+
+# include
+# include
using namespace OpenRCT2;
using namespace OpenRCT2::Scripting;
@@ -398,3 +400,5 @@ void OpenRCT2::Scripting::ThrowIfGameStateNotMutable()
duk_error(ctx, DUK_ERR_ERROR, "Game state is not mutable in this context.");
}
}
+
+#endif
diff --git a/src/openrct2/scripting/ScriptEngine.h b/src/openrct2/scripting/ScriptEngine.h
index da6517f699..6ebce0af41 100644
--- a/src/openrct2/scripting/ScriptEngine.h
+++ b/src/openrct2/scripting/ScriptEngine.h
@@ -9,18 +9,20 @@
#pragma once
-#include "../common.h"
-#include "../core/FileWatcher.h"
-#include "HookEngine.h"
-#include "Plugin.h"
+#ifdef __ENABLE_SCRIPTING__
-#include
-#include
-#include
-#include
-#include
-#include
-#include
+# include "../common.h"
+# include "../core/FileWatcher.h"
+# include "HookEngine.h"
+# include "Plugin.h"
+
+# include
+# include
+# include
+# include
+# include
+# include
+# include
struct duk_hthread;
typedef struct duk_hthread duk_context;
@@ -168,3 +170,5 @@ namespace OpenRCT2::Scripting
void ThrowIfGameStateNotMutable();
} // namespace OpenRCT2::Scripting
+
+#endif