diff --git a/.clang-format b/.clang-format
new file mode 100644
index 00000000..897542b9
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,4 @@
+---
+BasedOnStyle: Microsoft
+
+...
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 9464c6ee..cd420baf 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,10 +13,10 @@ set(CMAKE_PREFIX_PATH ${ROR_DEPENDENCY_DIR} ${CMAKE_PREFIX_PATH})
set(CMAKE_THREAD_PREFER_PTHREAD YES)
find_package(Threads REQUIRED)
-find_package(Angelscript)
-find_package(jsoncpp REQUIRED)
+find_package(Poco REQUIRED COMPONENTS Foundation JSON)
find_package(SocketW REQUIRED)
find_package(CURL)
+find_package(Angelscript)
cmake_dependent_option(RORSERVER_WITH_ANGELSCRIPT "Adds scripting support" ON "TARGET Angelscript::angelscript" OFF)
cmake_dependent_option(RORSERVER_WITH_CURL "Adds CURL request support (needs AngelScript)" ON "TARGET CURL::libcurl" OFF)
diff --git a/conanfile.py b/conanfile.py
index 2865c957..fc556acb 100644
--- a/conanfile.py
+++ b/conanfile.py
@@ -7,13 +7,17 @@ class RoRServer(ConanFile):
name = "RoRServer"
settings = "os", "compiler", "build_type", "arch"
generators = "CMakeToolchain", "CMakeDeps"
+ default_options = {
+ "poco*:enable_pagecompiler": True,
+ "poco*:enable_data_mysql": False,
+ }
def layout(self):
self.folders.generators = os.path.join(self.folders.build, "generators")
def requirements(self):
self.requires("angelscript/2.37.0")
- self.requires("jsoncpp/1.9.5")
+ self.requires("poco/1.13.3")
self.requires("openssl/3.3.2", override=True)
self.requires("socketw/3.11.0@anotherfoxguy/stable")
self.requires("libcurl/8.10.1")
\ No newline at end of file
diff --git a/source/server/CMakeLists.txt b/source/server/CMakeLists.txt
index f4e8348d..eb56ccb2 100644
--- a/source/server/CMakeLists.txt
+++ b/source/server/CMakeLists.txt
@@ -20,7 +20,12 @@ if (RORSERVER_WITH_CURL)
target_link_libraries(${PROJECT_NAME} PRIVATE CURL::libcurl)
endif ()
-target_link_libraries(${PROJECT_NAME} PRIVATE Threads::Threads SocketW::SocketW jsoncpp_lib)
+target_link_libraries(${PROJECT_NAME} PRIVATE
+ Poco::Foundation
+ Poco::JSON
+ Threads::Threads
+ SocketW::SocketW
+)
IF (WIN32)
target_compile_definitions(${PROJECT_NAME} PRIVATE WIN32_LEAN_AND_MEAN NOMINMAX)
diff --git a/source/server/blacklist.cpp b/source/server/blacklist.cpp
index 474501d6..f7707c2c 100644
--- a/source/server/blacklist.cpp
+++ b/source/server/blacklist.cpp
@@ -24,11 +24,21 @@ along with Rigs of Rods Server. If not, see .
#include "sequencer.h"
#include "utils.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace Poco;
+using namespace Poco::JSON;
+using namespace Poco::Dynamic;
+
#include
-#include
-Blacklist::Blacklist(Sequencer* database)
- : m_database(database)
+Blacklist::Blacklist(Sequencer *database) : m_database(database)
{
}
@@ -38,31 +48,29 @@ void Blacklist::SaveBlacklistToFile()
f.open(Config::getBlacklistFile(), std::ios::out);
if (!f.is_open() || !f.good())
{
- Logger::Log(LogLevel::LOG_WARN,
- "Couldn't open the local blacklist file ('%s'). Bans were not saved.",
- Config::getBlacklistFile().c_str());
+ Logger::Log(LogLevel::LOG_WARN, "Couldn't open the local blacklist file ('%s'). Bans were not saved.",
+ Config::getBlacklistFile().c_str());
return;
}
- Json::Value j_bans(Json::arrayValue);
+ JSON::Array j_bans;
std::vector bans = m_database->GetBanListCopy();
- for (ban_t& ban : bans)
+ for (ban_t &ban : bans)
{
- Json::Value j_ban(Json::objectValue);
- j_ban["bid"] = ban.bid;
+ DynamicStruct j_ban;
+ j_ban["bid"] = ban.bid;
j_ban["ip"] = ban.ip;
j_ban["nickname"] = ban.nickname;
j_ban["banned_by_nickname"] = ban.bannedby_nick;
j_ban["message"] = ban.banmsg;
- j_bans.append(j_ban);
+ j_bans.add(j_ban);
}
- Json::Value j_doc(Json::objectValue);
+ DynamicStruct j_doc;
j_doc["bans"] = j_bans;
- Json::StyledStreamWriter j_writer;
- j_writer.write(f, j_doc);
+ Poco::JSON::Stringifier::stringify(j_doc, f, 1);
}
bool Blacklist::LoadBlacklistFromFile()
@@ -71,8 +79,7 @@ bool Blacklist::LoadBlacklistFromFile()
f.open(Config::getBlacklistFile(), std::ios::in);
if (!f.is_open() || !f.good())
{
- Logger::Log(LogLevel::LOG_WARN,
- "Couldn't open the local blacklist file ('%s'). No bans were loaded.",
+ Logger::Log(LogLevel::LOG_WARN, "Couldn't open the local blacklist file ('%s'). No bans were loaded.",
Config::getBlacklistFile().c_str());
return false;
}
@@ -80,32 +87,41 @@ bool Blacklist::LoadBlacklistFromFile()
if (Utils::IsEmptyFile(f))
{
f.close();
- Logger::Log(LogLevel::LOG_WARN,
- "Local blacklist file ('%s') is empty.",
- Config::getBlacklistFile().c_str());
+ Logger::Log(LogLevel::LOG_WARN, "Local blacklist file ('%s') is empty.", Config::getBlacklistFile().c_str());
return false;
}
- Json::Value j_doc;
- Json::Reader j_reader;
- j_reader.parse(f, j_doc);
- if (!j_reader.good())
+ Parser parser;
+ Var result;
+
+ try
{
- Logger::Log(LogLevel::LOG_WARN,
- "Couldn't parse blacklist file, messages:\n%s",
- j_reader.getFormattedErrorMessages());
+ result = parser.parse(f);
+ }
+ catch (JSONException &jsonException)
+ {
+ Logger::Log(LogLevel::LOG_WARN, "Couldn't parse blacklist file, messages:\n%s",
+ jsonException.message().c_str());
return false;
}
- for (Json::Value& j_ban: j_doc["bans"])
+ try
{
- m_database->RecordBan(
- // ban IDs are reset to start at 1 on every start/restart
- j_ban["ip"].asString(),
- j_ban["nickname"].asString(),
- j_ban["banned_by_nickname"].asString(),
- j_ban["message"].asString());
+ Poco::JSON::Object::Ptr root = result.extract();
+ JSON::Array::Ptr bans = root->getArray("bans");
+
+ for (int i = 0; i < bans->size(); ++i)
+ {
+ auto j_ban = bans->getObject(i);
+ m_database->RecordBan(j_ban->getValue("ip"),
+ j_ban->getValue("nickname"),
+ j_ban->getValue("banned_by_nickname"),
+ j_ban->getValue("message"));
+ }
+ }
+ catch (Exception e)
+ {
+ Logger::Log(LogLevel::LOG_WARN, "Couldn't parse blacklist file, messages:\n%s", e.message().c_str());
}
-
return true;
}
diff --git a/source/server/master-server.cpp b/source/server/master-server.cpp
index 10e7e85c..d2826b72 100644
--- a/source/server/master-server.cpp
+++ b/source/server/master-server.cpp
@@ -24,10 +24,22 @@ along with Foobar. If not, see .
#include "rornet.h"
#include "logger.h"
#include "http.h"
-#include "json/json.h"
+#include "utils.h"
#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace Poco;
+using namespace Poco::JSON;
+using namespace Poco::Dynamic;
+
namespace MasterServer {
Client::Client() :
@@ -35,7 +47,7 @@ namespace MasterServer {
m_is_registered(false) {}
bool Client::Register() {
- Json::Value data(Json::objectValue);
+ DynamicStruct data;
data["ip"] = Config::getIPAddr();
data["port"] = Config::getListenPort();
data["name"] = Config::getServerName();
@@ -46,9 +58,11 @@ namespace MasterServer {
m_server_path = "/" + Config::GetServerlistPath() + "/server-list";
+ auto json_str = JsonToString(data);
+
Logger::Log(LOG_INFO, "Attempting to register on serverlist (%s)", m_server_path.c_str());
Http::Response response;
- int result_code = this->HttpRequest(Http::METHOD_POST, data.toStyledString().c_str(), &response);
+ int result_code = this->HttpRequest(Http::METHOD_POST, json_str.c_str(), &response);
if (result_code < 0) {
Logger::Log(LOG_ERROR, "Registration failed, result code: %d", result_code);
return false;
@@ -58,33 +72,34 @@ namespace MasterServer {
return false;
}
- Json::Value root;
- Json::Reader reader;
- if (!reader.parse(response.GetBody().c_str(), root)) {
- Logger::Log(LOG_ERROR, "Registration failed, invalid server response (JSON parsing failed)");
- Logger::Log(LOG_DEBUG, "Raw response: %s", response.GetBody().c_str());
- return false;
- }
+ Parser parser;
+ Var result;
- Json::Value trust_level = root["verified-level"];
- Json::Value challenge = root["challenge"];
- if (!root.isObject() || !trust_level.isNumeric() || !challenge.isString()) {
- Logger::Log(LOG_ERROR, "Registration failed, incorrect response from server");
+ try
+ {
+ result = parser.parse(response.GetBody());
+ }
+ catch(JSONException& jsonException)
+ {
+ Logger::Log(LOG_ERROR, "Registration failed, invalid server response (%s)", jsonException.message().c_str());
Logger::Log(LOG_DEBUG, "Raw response: %s", response.GetBody().c_str());
return false;
}
- m_token = challenge.asString();
- m_trust_level = trust_level.asInt();
+ DynamicStruct root = result.extract