mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
refactor(json): migrate from nlohmann to rapidjson
Replace nlohmann::json with rapidjson across localization, hitbox manager, server world, and sensitive filter. Add json_utils helper for converting rapidjson documents to maps, and improve parse error handling.
This commit is contained in:
8
include/Cubed/tools/json_utils.hpp
Normal file
8
include/Cubed/tools/json_utils.hpp
Normal file
@@ -0,0 +1,8 @@
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
namespace Tools {
|
||||
std::unordered_map<std::string, std::string>
|
||||
doc_to_map(const rapidjson::Document& doc);
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <rapidjson/document.h>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
namespace Cubed {
|
||||
class SensitiveFilter {
|
||||
public:
|
||||
SensitiveFilter();
|
||||
void load(const nlohmann::json& j);
|
||||
void load(const rapidjson::Document& doc);
|
||||
std::string filter(std::string_view text);
|
||||
|
||||
private:
|
||||
|
||||
@@ -103,4 +103,5 @@ target_sources(${PROJECT_NAME}
|
||||
gameplay/server_entity_manager.cpp
|
||||
gameplay/client_entity_manager.cpp
|
||||
gameplay/systems/wander_ai_system.cpp
|
||||
tools/json_utils.cpp
|
||||
)
|
||||
@@ -5,9 +5,10 @@
|
||||
#include "Cubed/tools/log.hpp"
|
||||
#include "Cubed/tools/name_space.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/istreamwrapper.h>
|
||||
namespace fs = std::filesystem;
|
||||
using nlohmann::json;
|
||||
using namespace rapidjson;
|
||||
namespace Cubed {
|
||||
HitboxManager::HitboxManager() {
|
||||
|
||||
@@ -84,21 +85,30 @@ HitboxManager::Handle HitboxManager::load(std::string_view name) {
|
||||
glm::vec3 center;
|
||||
glm::vec3 half;
|
||||
std::ifstream s{p};
|
||||
json j = json::parse(s);
|
||||
if (j.contains("boxes")) {
|
||||
const json* box = &j["boxes"];
|
||||
if (box->is_array() && !box->empty()) {
|
||||
box = &(*box)[0];
|
||||
}
|
||||
if (box->contains("center")) {
|
||||
center.x = (*box)["center"].at(0).get<float>();
|
||||
center.y = (*box)["center"].at(1).get<float>();
|
||||
center.z = (*box)["center"].at(2).get<float>();
|
||||
}
|
||||
if (box->contains("half")) {
|
||||
half.x = (*box)["half"].at(0).get<float>();
|
||||
half.y = (*box)["half"].at(1).get<float>();
|
||||
half.z = (*box)["half"].at(2).get<float>();
|
||||
IStreamWrapper isw(s);
|
||||
Document doc;
|
||||
doc.ParseStream(isw);
|
||||
if (doc.HasParseError()) {
|
||||
auto code = doc.GetParseError();
|
||||
|
||||
throw std::runtime_error(
|
||||
std::format("Parse {} failed, error code {}", p.string(),
|
||||
static_cast<int>(code)));
|
||||
}
|
||||
if (doc.HasMember("boxes")) {
|
||||
const Value& box = doc["boxes"];
|
||||
if (box.IsArray()) {
|
||||
const Value& b = box[0];
|
||||
if (b.HasMember("center")) {
|
||||
center.x = b["center"][0].GetFloat();
|
||||
center.y = b["center"][1].GetFloat();
|
||||
center.z = b["center"][2].GetFloat();
|
||||
}
|
||||
if (b.HasMember("half")) {
|
||||
half.x = b["half"][0].GetFloat();
|
||||
half.y = b["half"][1].GetFloat();
|
||||
half.z = b["half"][2].GetFloat();
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
|
||||
@@ -8,14 +8,15 @@
|
||||
#include "Cubed/tools/net_utils.hpp"
|
||||
#include "Cubed/tools/uuid.hpp"
|
||||
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <ranges>
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/istreamwrapper.h>
|
||||
#include <utility>
|
||||
using namespace std::chrono;
|
||||
using namespace std::chrono_literals;
|
||||
using namespace google::protobuf;
|
||||
using namespace rapidjson;
|
||||
namespace fs = std::filesystem;
|
||||
using nlohmann::json;
|
||||
namespace Cubed {
|
||||
ServerWorld::ServerWorld(Config& config)
|
||||
: m_config(config), m_entity_manager(*this) {}
|
||||
@@ -212,8 +213,13 @@ void ServerWorld::init_world() {
|
||||
try {
|
||||
fs::path path = std::format("{}SensitiveLexicon.json", ASSETS_PATH);
|
||||
std::ifstream s{path};
|
||||
json j = json::parse(s);
|
||||
m_filter.load(j);
|
||||
if (!s.is_open()) {
|
||||
throw std::runtime_error("can't open SensitiveLexicon.json");
|
||||
}
|
||||
IStreamWrapper isw(s);
|
||||
Document doc;
|
||||
doc.ParseStream(isw);
|
||||
m_filter.load(doc);
|
||||
} catch (const std::exception& e) {
|
||||
Logger::error("Load SensitiveLexicon.json Fail");
|
||||
m_enable_filter = false;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#include "Cubed/localization.hpp"
|
||||
|
||||
#include "Cubed/tools/cubed_assert.hpp"
|
||||
#include "Cubed/tools/json_utils.hpp"
|
||||
#include "Cubed/tools/log.hpp"
|
||||
|
||||
#include <fstream>
|
||||
#include <nlohmann/json.hpp>
|
||||
using json = nlohmann::json;
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/istreamwrapper.h>
|
||||
namespace fs = std::filesystem;
|
||||
using namespace rapidjson;
|
||||
namespace Cubed {
|
||||
Localization::Localization() {}
|
||||
Localization& Localization::instance() {
|
||||
@@ -25,10 +27,19 @@ void Localization::load_language(std::string_view language) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
json j = json::parse(file);
|
||||
IStreamWrapper isw(file);
|
||||
Document doc;
|
||||
doc.ParseStream(isw);
|
||||
if (doc.HasParseError()) {
|
||||
auto code = doc.GetParseError();
|
||||
|
||||
throw std::runtime_error(
|
||||
std::format("Parse {} failed, error code {}", path,
|
||||
static_cast<int>(code)));
|
||||
}
|
||||
m_translations.clear();
|
||||
j.get_to(m_translations);
|
||||
} catch (const json::parse_error& e) {
|
||||
m_translations = Tools::doc_to_map(doc);
|
||||
} catch (const std::exception& e) {
|
||||
Logger::error("JSON syntax error: {}", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
54
src/tools/json_utils.cpp
Normal file
54
src/tools/json_utils.cpp
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "Cubed/tools/json_utils.hpp"
|
||||
|
||||
#include <rapidjson/document.h>
|
||||
#include <rapidjson/stringbuffer.h>
|
||||
#include <rapidjson/writer.h>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
namespace Tools {
|
||||
|
||||
using rapidjson::Document;
|
||||
using rapidjson::Value;
|
||||
|
||||
namespace {
|
||||
std::string serialize_value(const Value& v, rapidjson::StringBuffer& buf) {
|
||||
rapidjson::Writer<rapidjson::StringBuffer> w(buf);
|
||||
v.Accept(w);
|
||||
return buf.GetString();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::unordered_map<std::string, std::string> doc_to_map(const Document& doc) {
|
||||
std::unordered_map<std::string, std::string> m;
|
||||
if (!doc.IsObject())
|
||||
return m;
|
||||
|
||||
for (auto it = doc.MemberBegin(); it != doc.MemberEnd(); ++it) {
|
||||
const std::string KEY(it->name.GetString(), it->name.GetStringLength());
|
||||
const Value& v = it->value;
|
||||
std::string val;
|
||||
if (v.IsString()) {
|
||||
val.assign(v.GetString(), v.GetStringLength());
|
||||
} else if (v.IsInt()) {
|
||||
val = std::to_string(v.GetInt());
|
||||
} else if (v.IsUint()) {
|
||||
val = std::to_string(v.GetUint());
|
||||
} else if (v.IsInt64()) {
|
||||
val = std::to_string(v.GetInt64());
|
||||
} else if (v.IsUint64()) {
|
||||
val = std::to_string(v.GetUint64());
|
||||
} else if (v.IsDouble()) {
|
||||
val = std::to_string(v.GetDouble());
|
||||
} else if (v.IsBool()) {
|
||||
val = v.GetBool() ? "true" : "false";
|
||||
} else if (v.IsNull()) {
|
||||
val = "null";
|
||||
} else {
|
||||
rapidjson::StringBuffer buf;
|
||||
val = serialize_value(v, buf);
|
||||
}
|
||||
m.emplace(KEY, val);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
} // namespace Tools
|
||||
@@ -2,18 +2,25 @@
|
||||
|
||||
#include <queue>
|
||||
#include <utf8cpp/utf8.h>
|
||||
using nlohmann::json;
|
||||
using namespace rapidjson;
|
||||
namespace Cubed {
|
||||
SensitiveFilter::SensitiveFilter() {
|
||||
|
||||
};
|
||||
|
||||
void SensitiveFilter::load(const nlohmann::json& j) {
|
||||
void SensitiveFilter::load(const Document& doc) {
|
||||
trie.clear();
|
||||
trie.emplace_back();
|
||||
for (const auto& item : j["words"]) {
|
||||
|
||||
auto str = item.get<std::string>();
|
||||
if (!doc.HasMember("words")) {
|
||||
return;
|
||||
}
|
||||
const Value& words = doc["words"];
|
||||
for (SizeType i = 0; i < words.Size(); ++i) {
|
||||
const auto& w = words[i];
|
||||
if (!w.IsString()) {
|
||||
continue;
|
||||
}
|
||||
std::string str(w.GetString(), w.GetStringLength());
|
||||
std::u32string word;
|
||||
utf8::utf8to32(str.begin(), str.end(), std::back_inserter(word));
|
||||
insert(word);
|
||||
|
||||
Reference in New Issue
Block a user