forked from mirror/openmw-tes3mp
[Server] Add --debug option to launch options.
Add Soft-Mode Debugger for Mono.
This commit is contained in:
parent
f37c252dbe
commit
6cbf6f05a1
9 changed files with 100 additions and 9 deletions
|
@ -292,3 +292,13 @@ void LangLua::AddPackageCPath(const std::string& path)
|
||||||
{
|
{
|
||||||
packageCPath.emplace(path);
|
packageCPath.emplace(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LangLua::Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LangLua::Free()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -48,6 +48,9 @@ public:
|
||||||
private:
|
private:
|
||||||
static std::set<std::string> packageCPath;
|
static std::set<std::string> packageCPath;
|
||||||
static std::set<std::string> packagePath;
|
static std::set<std::string> packagePath;
|
||||||
|
|
||||||
|
static void Init();
|
||||||
|
static void Free();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -8,8 +8,9 @@
|
||||||
#include <mono/jit/jit.h>
|
#include <mono/jit/jit.h>
|
||||||
#include <mono/metadata/assembly.h>
|
#include <mono/metadata/assembly.h>
|
||||||
#include <mono/metadata/mono-config.h>
|
#include <mono/metadata/mono-config.h>
|
||||||
#include <apps/openmw-mp/Script/ScriptFunctions.hpp>
|
#include <mono/metadata/mono-debug.h>
|
||||||
#include <apps/openmw-mp/Script/API/TimerAPI.hpp>
|
#include <Script/ScriptFunctions.hpp>
|
||||||
|
#include <Script/API/TimerAPI.hpp>
|
||||||
#include "LangMono.hpp"
|
#include "LangMono.hpp"
|
||||||
|
|
||||||
static MonoDomain *domain = nullptr; // shared domain
|
static MonoDomain *domain = nullptr; // shared domain
|
||||||
|
@ -114,13 +115,10 @@ lib_t LangMono::GetInterface()
|
||||||
LangMono::LangMono()
|
LangMono::LangMono()
|
||||||
{
|
{
|
||||||
instance = new MonoInstance;
|
instance = new MonoInstance;
|
||||||
|
|
||||||
Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LangMono::LangMono(MonoInstance *instance) : instance(instance)
|
LangMono::LangMono(MonoInstance *instance) : instance(instance)
|
||||||
{
|
{
|
||||||
Init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LangMono::~LangMono()
|
LangMono::~LangMono()
|
||||||
|
@ -133,12 +131,37 @@ void LangMono::Init()
|
||||||
if (domain != nullptr)
|
if (domain != nullptr)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
domain = mono_jit_init("TES3MP Mono VM"); // will leak :P
|
if (Script::IsDebugMode())
|
||||||
|
{
|
||||||
|
std::string debugServerAddress = "127.0.0.1:10000";
|
||||||
|
LOG_MESSAGE_SIMPLE(Log::LOG_INFO, "Waiting for debugger on %s...", debugServerAddress.c_str());
|
||||||
|
std::string connectionString = "--debugger-agent=transport=dt_socket,server=y,address=" + debugServerAddress;
|
||||||
|
std::vector<const char*> options {
|
||||||
|
"--soft-breakpoints",
|
||||||
|
connectionString.c_str()
|
||||||
|
};
|
||||||
|
mono_jit_parse_options(options.size(), (char**) options.data());
|
||||||
|
|
||||||
|
mono_debug_init(MONO_DEBUG_FORMAT_MONO);
|
||||||
|
}
|
||||||
|
|
||||||
|
domain = mono_jit_init("TES3MP Mono VM");
|
||||||
|
|
||||||
|
if (Script::IsDebugMode())
|
||||||
|
{
|
||||||
|
mono_debug_domain_create(domain);
|
||||||
|
}
|
||||||
|
|
||||||
mono_add_internal_call("TES3MPSharp.TES3MP::CreateTimerEx", (void*) &LangMono::CreateTimerEx);
|
mono_add_internal_call("TES3MPSharp.TES3MP::CreateTimerEx", (void*) &LangMono::CreateTimerEx);
|
||||||
mono_add_internal_call("TES3MPSharp.TES3MP::MakePublic", (void*) &LangMono::MakePublic);
|
mono_add_internal_call("TES3MPSharp.TES3MP::MakePublic", (void*) &LangMono::MakePublic);
|
||||||
mono_add_internal_call("TES3MPSharp.TES3MP::CallPublic", (void*) &LangMono::CallPublic);
|
mono_add_internal_call("TES3MPSharp.TES3MP::CallPublic", (void*) &LangMono::CallPublic);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LangMono::Free()
|
||||||
|
{
|
||||||
|
mono_domain_free(domain, 0);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<MonoClass *> getInstanceClassList(MonoImage *image, const std::string &parentName)
|
std::vector<MonoClass *> getInstanceClassList(MonoImage *image, const std::string &parentName)
|
||||||
{
|
{
|
||||||
std::vector<MonoClass *> classes;
|
std::vector<MonoClass *> classes;
|
||||||
|
|
|
@ -67,6 +67,6 @@ public:
|
||||||
static void MakePublic(MonoObject *delegate, const char *name) noexcept;
|
static void MakePublic(MonoObject *delegate, const char *name) noexcept;
|
||||||
static MonoObject *CallPublic(const char *name, MonoArray *args);
|
static MonoObject *CallPublic(const char *name, MonoArray *args);
|
||||||
|
|
||||||
private:
|
static void Init();
|
||||||
void Init();
|
static void Free();
|
||||||
};
|
};
|
||||||
|
|
|
@ -100,3 +100,13 @@ LangNative::~LangNative()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void LangNative::Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void LangNative::Free()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ public:
|
||||||
virtual boost::any Call(const char *name, const char *argl, int buf, ...) override;
|
virtual boost::any Call(const char *name, const char *argl, int buf, ...) override;
|
||||||
virtual boost::any Call(const char *name, const char *argl, const std::vector<boost::any> &args) override;
|
virtual boost::any Call(const char *name, const char *argl, const std::vector<boost::any> &args) override;
|
||||||
|
|
||||||
|
static void Init();
|
||||||
|
static void Free();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ using namespace std;
|
||||||
|
|
||||||
Script::ScriptList Script::scripts;
|
Script::ScriptList Script::scripts;
|
||||||
std::string Script::moddir;
|
std::string Script::moddir;
|
||||||
|
bool Script::debugMode = false;
|
||||||
|
|
||||||
inline bool Load(Language *lang, const std::string &path)
|
inline bool Load(Language *lang, const std::string &path)
|
||||||
{
|
{
|
||||||
|
@ -133,3 +134,35 @@ const char* Script::GetModDir()
|
||||||
{
|
{
|
||||||
return moddir.c_str();
|
return moddir.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Script::IsDebugMode()
|
||||||
|
{
|
||||||
|
return debugMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::EnableDebugMode()
|
||||||
|
{
|
||||||
|
debugMode = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::Init()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_MONO
|
||||||
|
LangMono::Init();
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_LUA
|
||||||
|
LangLua::Init();
|
||||||
|
#endif
|
||||||
|
LangNative::Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Script::Free()
|
||||||
|
{
|
||||||
|
#ifdef ENABLE_MONO
|
||||||
|
LangMono::Free();
|
||||||
|
#endif
|
||||||
|
#ifdef ENABLE_LUA
|
||||||
|
LangLua::Free();
|
||||||
|
#endif
|
||||||
|
LangNative::Free();
|
||||||
|
}
|
||||||
|
|
|
@ -57,9 +57,14 @@ private:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static std::string moddir;
|
static std::string moddir;
|
||||||
|
static bool debugMode;
|
||||||
public:
|
public:
|
||||||
~Script();
|
~Script();
|
||||||
|
|
||||||
|
static void Init();
|
||||||
|
static void Free();
|
||||||
|
static bool IsDebugMode();
|
||||||
|
static void EnableDebugMode();
|
||||||
static void LoadScript(const char *script, const char* base);
|
static void LoadScript(const char *script, const char* base);
|
||||||
static void LoadScripts(char* scripts, const char* base);
|
static void LoadScripts(char* scripts, const char* base);
|
||||||
static void UnloadScripts();
|
static void UnloadScripts();
|
||||||
|
|
|
@ -134,6 +134,7 @@ boost::program_options::variables_map launchOptions(int argc, char *argv[], File
|
||||||
|
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("resources", bpo::value<Files::EscapeHashString>()->default_value("resources"), "set resources directory")
|
("resources", bpo::value<Files::EscapeHashString>()->default_value("resources"), "set resources directory")
|
||||||
|
("debug", bpo::value<bool>()->implicit_value(true)->default_value(false), "Enable debug mode for scripts (if supported)")
|
||||||
("no-logs", bpo::value<bool>()->implicit_value(true)->default_value(false),
|
("no-logs", bpo::value<bool>()->implicit_value(true)->default_value(false),
|
||||||
"Do not write logs. Useful for daemonizing.");
|
"Do not write logs. Useful for daemonizing.");
|
||||||
|
|
||||||
|
@ -264,6 +265,9 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
if (variables["debug"].as<bool>())
|
||||||
|
Script::EnableDebugMode();
|
||||||
|
Script::Init();
|
||||||
for (auto plugin : plugins)
|
for (auto plugin : plugins)
|
||||||
Script::LoadScript(plugin.c_str(), plugin_home.c_str());
|
Script::LoadScript(plugin.c_str(), plugin_home.c_str());
|
||||||
|
|
||||||
|
@ -331,6 +335,7 @@ int main(int argc, char *argv[])
|
||||||
code = networking.mainLoop();
|
code = networking.mainLoop();
|
||||||
|
|
||||||
networking.getMasterClient()->Stop();
|
networking.getMasterClient()->Stop();
|
||||||
|
Script::Free();
|
||||||
}
|
}
|
||||||
catch (std::exception &e)
|
catch (std::exception &e)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue