Merge branch 'new-script-api' of https://github.com/TES3MP/openmw-tes3mp into new-script-api

new-script-api
David Cernat 7 years ago
commit 878294e4fe

@ -80,16 +80,6 @@ LuaState::LuaState()
configEnv = sol::environment(*lua, sol::create, lua->globals()); configEnv = sol::environment(*lua, sol::create, lua->globals());
lua->set("Config", configEnv); // plain global environment for mod configuration lua->set("Config", configEnv); // plain global environment for mod configuration
// errors in sol::functions are caught only in Debug or RelWithDebInfo builds for better performance
#ifdef SOL_SAFE_FUNCTIONS
lua->set_function("ErrorHandler", [](sol::object error_msg) {
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, ("Lua: " + error_msg.as<string>()).c_str());
});
sol::reference errHandler = (*lua)["ErrorHandler"];
sol::protected_function::set_default_handler(errHandler);
#endif
sol::table Constants = lua->create_named_table("Constants"); sol::table Constants = lua->create_named_table("Constants");
Constants.set_function("getAttributeCount", []() { Constants.set_function("getAttributeCount", []() {
@ -163,6 +153,14 @@ LuaState::LuaState()
LOG_APPEND(level, "%s", message); LOG_APPEND(level, "%s", message);
}); });
lua->new_enum("Log",
"LOG_FATAL", Log::LOG_FATAL,
"LOG_ERROR", Log::LOG_ERROR,
"LOG_WARN", Log::LOG_WARN,
"LOG_INFO", Log::LOG_INFO,
"LOG_VERBOSE", Log::LOG_VERBOSE,
"LOG_TRACE", Log::LOG_TRACE);
lua->set_function("stopServer", [](int code) { lua->set_function("stopServer", [](int code) {
mwmp::Networking::getPtr()->stopServer(code); mwmp::Networking::getPtr()->stopServer(code);
}); });
@ -450,7 +448,7 @@ vector<vector<ServerPluginInfo>::iterator> loadOrderSolver(vector<ServerPluginIn
break; break;
} }
return move(result); return result;
} }
void LuaState::loadMods(const std::string &modDir, std::vector<std::string> *list) void LuaState::loadMods(const std::string &modDir, std::vector<std::string> *list)
@ -471,7 +469,7 @@ void LuaState::loadMods(const std::string &modDir, std::vector<std::string> *lis
ServerPluginInfo modInfo; ServerPluginInfo modInfo;
modInfo.path = std::make_pair(homePath.string(), modDir.path().filename().string()); modInfo.path = make_pair(homePath.string(), modDir.path().filename().string());
modInfo.author = pt.get<string>("author"); modInfo.author = pt.get<string>("author");
modInfo.version = pt.get<string>("version"); modInfo.version = pt.get<string>("version");

@ -139,8 +139,25 @@ boost::program_options::variables_map launchOptions(int argc, char *argv[], File
return variables; return variables;
} }
#include "stacktrace.hpp"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
set_terminate([]() {
try
{
rethrow_exception(current_exception());
}
catch (const exception &e)
{
LOG_MESSAGE_SIMPLE(Log::LOG_FATAL, " Woops, something wrong! Exception:\n\t%s", e.what());
}
stacktrace();
abort();
});
Settings::Manager mgr; Settings::Manager mgr;
Files::ConfigurationManager cfgMgr; Files::ConfigurationManager cfgMgr;
@ -153,8 +170,6 @@ int main(int argc, char *argv[])
auto version = Version::getOpenmwVersion(variables["resources"].as<Files::EscapeHashString>().toStdString()); auto version = Version::getOpenmwVersion(variables["resources"].as<Files::EscapeHashString>().toStdString());
int logLevel = mgr.getInt("logLevel", "General"); int logLevel = mgr.getInt("logLevel", "General");
if (logLevel < Log::LOG_VERBOSE || logLevel > Log::LOG_FATAL)
logLevel = Log::LOG_VERBOSE;
// Some objects used to redirect cout and cerr // Some objects used to redirect cout and cerr
// Scope must be here, so this still works inside the catch block for logging exceptions // Scope must be here, so this still works inside the catch block for logging exceptions
@ -212,9 +227,6 @@ int main(int argc, char *argv[])
RakNet::SocketDescriptor sd((unsigned short) port, addr.c_str()); RakNet::SocketDescriptor sd((unsigned short) port, addr.c_str());
//try
{
switch (peer->Startup((unsigned) players, &sd, 1)) switch (peer->Startup((unsigned) players, &sd, 1))
{ {
case RakNet::RAKNET_STARTED: case RakNet::RAKNET_STARTED:
@ -254,7 +266,8 @@ int main(int argc, char *argv[])
for (int i = 0;; ++i) for (int i = 0;; ++i)
list.push_back(mgr.getString("Plugin" + to_string(i), "Plugins")); list.push_back(mgr.getString("Plugin" + to_string(i), "Plugins"));
} }
catch (...) {} // Manager::getString throws runtime_error exception if setting is not exist catch (...)
{} // Manager::getString throws runtime_error exception if setting is not exist
networking.getState().loadMods(plugin_home, &list); networking.getState().loadMods(plugin_home, &list);
} }
@ -284,12 +297,6 @@ int main(int argc, char *argv[])
code = networking.mainLoop(); code = networking.mainLoop();
networking.getMasterClient()->Stop(); networking.getMasterClient()->Stop();
}
/*catch (std::exception &e)
{
LOG_MESSAGE_SIMPLE(Log::LOG_ERROR, e.what());
throw; //fall through
}*/
RakNet::RakPeerInterface::DestroyInstance(peer); RakNet::RakPeerInterface::DestroyInstance(peer);

@ -0,0 +1,73 @@
//
// Created by koncord on 25.10.17.
//
#include "stacktrace.hpp"
#include <components/openmw-mp/Log.hpp>
#ifndef _WIN32
#include <execinfo.h>
void stacktrace()
{
LOG_MESSAGE_SIMPLE(Log::LOG_FATAL, "Stacktrace:");
void *array[50];
int size = backtrace(array, 50);
auto messages = backtrace_symbols(array, size);
size_t funcnamesize = 256;
auto funcname = (char *) malloc(funcnamesize);
//skip first stack frame (points here)
for (int i = 1; i < size && messages != nullptr; ++i)
{
char *beginName = nullptr, *beginOffset = nullptr, *endOffset = nullptr;
for (char *p = messages[i]; *p; ++p)
{
if (*p == '(')
beginName = p;
else if (*p == '+')
beginOffset = p;
else if (*p == ')' && beginOffset)
{
endOffset = p;
break;
}
}
if (beginName && beginOffset && endOffset && beginName < beginOffset)
{
*beginName++ = '\0';
*beginOffset++ = '\0';
*endOffset = '\0';
// mangled name is now in [beginName, beginOffset) and caller offset in [beginOffset, endOffset).
int status;
char *ret = abi::__cxa_demangle(beginName, funcname, &funcnamesize, &status);
if (status == 0)
{
funcname = ret; // use possibly realloc()-ed string
LOG_APPEND(Log::LOG_FATAL, "\t%s : %s+%s", messages[i], funcname, beginOffset);
}
else // demangling failed.
LOG_APPEND(Log::LOG_FATAL, "\t%s : %s()+%s", messages[i], beginName, beginOffset);
}
else
LOG_APPEND(Log::LOG_FATAL, "\t%s", messages[i]);
}
free(messages);
free(funcname);
}
#else
void stacktrace()
{
}
#endif

@ -0,0 +1,10 @@
//
// Created by koncord on 25.10.17.
//
#ifndef OPENMW_STACKTRACE_HPP
#define OPENMW_STACKTRACE_HPP
void stacktrace();
#endif //OPENMW_STACKTRACE_HPP

@ -14,41 +14,25 @@
using namespace std; using namespace std;
Log *Log::sLog = nullptr;
Log::Log(int logLevel) : logLevel(logLevel) Log::Log(int logLevel) : logLevel(logLevel)
{ {
} }
void Log::Create(int logLevel) Log &Log::Get()
{
if (sLog != nullptr)
return;
sLog = new Log(logLevel);
}
void Log::Delete()
{
if (sLog == nullptr)
return;
delete sLog;
sLog = nullptr;
}
const Log &Log::Get()
{ {
return *sLog; static Log instance(1000);
return instance;
} }
void Log::SetLevel(int level) void Log::SetLevel(int level)
{ {
sLog->logLevel = level; logLevel = level;
} }
const char* getTime() const char* getTime()
{ {
time_t t = time(0); time_t t = time(nullptr);
struct tm *tm = localtime(&t); struct tm *tm = localtime(&t);
static char result[20]; static char result[20];
sprintf(result, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d", sprintf(result, "%.4d-%.2d-%.2d %.2d:%.2d:%.2d",
@ -59,7 +43,7 @@ const char* getTime()
void Log::print(int level, bool hasPrefix, const char *file, int line, const char *message, ...) const void Log::print(int level, bool hasPrefix, const char *file, int line, const char *message, ...) const
{ {
if (level < logLevel) return; if (level > logLevel || logLevel == LOG_OFF) return;
std::stringstream sstr; std::stringstream sstr;
if (hasPrefix) if (hasPrefix)
@ -67,7 +51,7 @@ void Log::print(int level, bool hasPrefix, const char *file, int line, const cha
sstr << "[" << getTime() << "] "; sstr << "[" << getTime() << "] ";
if (file != 0 && line != 0) if (file != nullptr && line != 0)
{ {
sstr << "[" << file << ":"; sstr << "[" << file << ":";
sstr << line << "] "; sstr << line << "] ";
@ -85,6 +69,13 @@ void Log::print(int level, bool hasPrefix, const char *file, int line, const cha
case LOG_FATAL: case LOG_FATAL:
sstr << "FATAL"; sstr << "FATAL";
break; break;
case LOG_TRACE:
sstr << "TRACE";
break;
case LOG_VERBOSE:
case LOG_INFO:
sstr << "INFO";
break;
default: default:
sstr << "INFO"; sstr << "INFO";
} }
@ -108,10 +99,9 @@ void Log::print(int level, bool hasPrefix, const char *file, int line, const cha
string Log::getFilenameTimestamp() string Log::getFilenameTimestamp()
{ {
time_t rawtime = time(0); time_t rawtime = time(nullptr);
struct tm *timeinfo = localtime(&rawtime); struct tm *timeinfo = localtime(&rawtime);
char buffer[25]; char buffer[25];
strftime(buffer, 25, "%Y-%m-%d-%H_%M_%S", timeinfo); strftime(buffer, 25, "%Y-%m-%d-%H_%M_%S", timeinfo);
std::string timestamp(buffer); return string(buffer);
return timestamp;
} }

@ -17,8 +17,8 @@
#define LOG_MESSAGE(level, msg, ...) #define LOG_MESSAGE(level, msg, ...)
#define LOG_MESSAGE_SIMPLE(level, msg, ...) #define LOG_MESSAGE_SIMPLE(level, msg, ...)
#else #else
#define LOG_INIT(logLevel) Log::Create(logLevel) #define LOG_INIT(logLevel) Log::Get().SetLevel(logLevel)
#define LOG_QUIT() Log::Delete() #define LOG_QUIT()
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define LOG_MESSAGE(level, msg, ...) Log::Get().print((level), (1), (__FILE__), (__LINE__), (msg), __VA_ARGS__) #define LOG_MESSAGE(level, msg, ...) Log::Get().print((level), (1), (__FILE__), (__LINE__), (msg), __VA_ARGS__)
#define LOG_MESSAGE_SIMPLE(level, msg, ...) Log::Get().print((level), (1), (0), (0), (msg), __VA_ARGS__) #define LOG_MESSAGE_SIMPLE(level, msg, ...) Log::Get().print((level), (1), (0), (0), (msg), __VA_ARGS__)
@ -35,16 +35,17 @@ class Log
public: public:
enum enum
{ {
LOG_VERBOSE = 0, LOG_OFF = 0,
LOG_INFO, LOG_FATAL,
LOG_WARN,
LOG_ERROR, LOG_ERROR,
LOG_FATAL LOG_WARN,
LOG_INFO,
LOG_VERBOSE,
LOG_TRACE,
}; };
static void Create(int logLevel);
static void Delete(); static Log &Get();
static const Log &Get(); void SetLevel(int level);
static void SetLevel(int level);
void print(int level, bool hasPrefix, const char *file, int line, const char *message, ...) const; void print(int level, bool hasPrefix, const char *file, int line, const char *message, ...) const;
static std::string getFilenameTimestamp(); static std::string getFilenameTimestamp();
@ -53,7 +54,6 @@ public:
Log &operator=(Log &) = delete; Log &operator=(Log &) = delete;
private: private:
explicit Log(int logLevel); explicit Log(int logLevel);
static Log *sLog;
int logLevel; int logLevel;
}; };

Loading…
Cancel
Save