Allow scripting to be compile-disabled

This commit is contained in:
Ted John 2020-02-23 12:55:48 +00:00
parent 34078124cd
commit bac91cd563
17 changed files with 167 additions and 66 deletions

View file

@ -54,6 +54,7 @@
C4555: expression has no effect; expected expression with side-effect
-->
<PreprocessorDefinitions>__AVX2__;__SSE4_1__;OPENGL_NO_LINK;_CRT_SECURE_NO_WARNINGS;_USE_MATH_DEFINES;SDL_MAIN_HANDLED;_WINSOCK_DEPRECATED_NO_WARNINGS;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PreprocessorDefinitions>__ENABLE_SCRIPTING__;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary Condition="'$(UseSharedLibs)'!='true'">MultiThreaded</RuntimeLibrary>
<RuntimeLibrary Condition="'$(UseSharedLibs)'=='true'">MultiThreadedDLL</RuntimeLibrary>
<MultiProcessorCompilation>true</MultiProcessorCompilation>

View file

@ -120,8 +120,10 @@ public:
void Initialise() override
{
#ifdef __ENABLE_SCRIPTING__
auto& scriptEngine = GetContext()->GetScriptEngine();
UiScriptExtensions::Extend(scriptEngine);
#endif
}
void Update() override

View file

@ -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> plugin) -> void { RemoveMenuItems(plugin); });
}
} // namespace OpenRCT2::Scripting
#endif

View file

@ -9,12 +9,14 @@
#pragma once
#include <memory>
#include <openrct2/Context.h>
#include <openrct2/scripting/Duktape.hpp>
#include <openrct2/scripting/ScriptEngine.h>
#include <string>
#include <vector>
#ifdef __ENABLE_SCRIPTING__
# include <memory>
# include <openrct2/Context.h>
# include <openrct2/scripting/Duktape.hpp>
# include <openrct2/scripting/ScriptEngine.h>
# include <string>
# include <vector>
namespace OpenRCT2::Scripting
{
@ -50,3 +52,5 @@ namespace OpenRCT2::Scripting
void InitialiseCustomMenuItems(ScriptEngine& scriptEngine);
} // namespace OpenRCT2::Scripting
#endif

View file

@ -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 <limits>
#include <openrct2-ui/interface/Widget.h>
#include <openrct2-ui/windows/Window.h>
#include <openrct2/drawing/Drawing.h>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/localisation/StringIds.h>
#include <openrct2/scripting/Plugin.h>
#include <openrct2/world/Sprite.h>
#include <optional>
#include <string>
#include <vector>
# include "../interface/Dropdown.h"
# include "ScUi.hpp"
# include "ScWindow.hpp"
# include <limits>
# include <openrct2-ui/interface/Widget.h>
# include <openrct2-ui/windows/Window.h>
# include <openrct2/drawing/Drawing.h>
# include <openrct2/localisation/Localisation.h>
# include <openrct2/localisation/StringIds.h>
# include <openrct2/scripting/Plugin.h>
# include <openrct2/world/Sprite.h>
# include <optional>
# include <string>
# include <vector>
using namespace OpenRCT2;
using namespace OpenRCT2::Scripting;
@ -711,3 +713,5 @@ namespace OpenRCT2::Ui::Windows
}
} // namespace OpenRCT2::Ui::Windows
#endif

View file

@ -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 <openrct2/scripting/ScriptEngine.h>
# include "CustomMenu.h"
# include "ScUi.hpp"
# include "ScWidget.hpp"
# include "ScWindow.hpp"
# include <openrct2/scripting/ScriptEngine.h>
using namespace OpenRCT2::Scripting;
@ -31,3 +33,5 @@ void UiScriptExtensions::Extend(ScriptEngine& scriptEngine)
InitialiseCustomMenuItems(scriptEngine);
}
#endif

View file

@ -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<size_t>(dropdownIndex - customStartIndex);
if (customMenuItems.size() > customIndex)
{
customMenuItems[customIndex].Invoke();
}
#endif
}
}

View file

@ -103,7 +103,9 @@ namespace OpenRCT2
std::unique_ptr<DiscordService> _discordService;
#endif
StdInOutConsole _stdInOutConsole;
#ifdef __ENABLE_SCRIPTING__
ScriptEngine _scriptEngine;
#endif
// Game states
std::unique_ptr<TitleScreen> _titleScreen;
@ -138,7 +140,9 @@ namespace OpenRCT2
, _audioContext(audioContext)
, _uiContext(uiContext)
, _localisationService(std::make_unique<LocalisationService>(env))
#ifdef __ENABLE_SCRIPTING__
, _scriptEngine(_stdInOutConsole, *env)
#endif
, _painter(std::make_unique<Painter>(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();
}

View file

@ -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;

View file

@ -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
}
/**

View file

@ -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();

View file

@ -13,6 +13,7 @@
#include "../localisation/FormatCodes.h"
#include <future>
#include <queue>
#include <string>
struct rct_drawpixelinfo;
@ -50,9 +51,13 @@ public:
class StdInOutConsole final : public InteractiveConsole
{
private:
std::queue<std::tuple<std::promise<void>, std::string>> _evalQueue;
public:
void Start();
std::future<void> Eval(const std::string& s);
void ProcessEvalQueue();
void Clear() override;
void Close() override;

View file

@ -55,8 +55,35 @@ void StdInOutConsole::Start()
std::future<void> 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<void> 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()

View file

@ -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<NetworkPacket> 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<NetworkPacket> 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());

View file

@ -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 <unordered_map>
# include "ScriptEngine.h"
# include <unordered_map>
using namespace OpenRCT2::Scripting;
@ -171,3 +173,5 @@ const HookList& HookEngine::GetHookList(HOOK_TYPE type) const
auto index = static_cast<size_t>(type);
return _hookMap[index];
}
#endif

View file

@ -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 <iostream>
#include <stdexcept>
# 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 <iostream>
# include <stdexcept>
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

View file

@ -9,18 +9,20 @@
#pragma once
#include "../common.h"
#include "../core/FileWatcher.h"
#include "HookEngine.h"
#include "Plugin.h"
#ifdef __ENABLE_SCRIPTING__
#include <future>
#include <memory>
#include <mutex>
#include <queue>
#include <string>
#include <unordered_set>
#include <vector>
# include "../common.h"
# include "../core/FileWatcher.h"
# include "HookEngine.h"
# include "Plugin.h"
# include <future>
# include <memory>
# include <mutex>
# include <queue>
# include <string>
# include <unordered_set>
# include <vector>
struct duk_hthread;
typedef struct duk_hthread duk_context;
@ -168,3 +170,5 @@ namespace OpenRCT2::Scripting
void ThrowIfGameStateNotMutable();
} // namespace OpenRCT2::Scripting
#endif