mirror of
https://github.com/BeamMP/BeamMP-Server.git
synced 2025-08-17 16:57:05 +00:00
Add JsonDeserialize
This commit is contained in:
parent
95b417bb36
commit
b52677e585
@ -22,7 +22,7 @@ namespace MP {
|
|||||||
bool IsPlayerConnected(int ID);
|
bool IsPlayerConnected(int ID);
|
||||||
void Sleep(size_t Ms);
|
void Sleep(size_t Ms);
|
||||||
void PrintRaw(sol::variadic_args);
|
void PrintRaw(sol::variadic_args);
|
||||||
std::string JsonSerialize(sol::table object);
|
std::string JsonSerialize(const sol::table& object);
|
||||||
}
|
}
|
||||||
namespace FS {
|
namespace FS {
|
||||||
std::pair<bool, std::string> CreateDirectory(const std::string& Path);
|
std::pair<bool, std::string> CreateDirectory(const std::string& Path);
|
||||||
|
@ -190,6 +190,7 @@ private:
|
|||||||
std::string Lua_GetPlayerName(int ID);
|
std::string Lua_GetPlayerName(int ID);
|
||||||
sol::table Lua_GetPlayerVehicles(int ID);
|
sol::table Lua_GetPlayerVehicles(int ID);
|
||||||
sol::table Lua_HttpCreateConnection(const std::string& host, uint16_t port);
|
sol::table Lua_HttpCreateConnection(const std::string& host, uint16_t port);
|
||||||
|
sol::table Lua_JsonDeserialize(const std::string& str);
|
||||||
int Lua_GetPlayerIDByName(const std::string& Name);
|
int Lua_GetPlayerIDByName(const std::string& Name);
|
||||||
|
|
||||||
std::string mName;
|
std::string mName;
|
||||||
|
@ -354,7 +354,11 @@ std::string LuaAPI::FS::ConcatPaths(sol::variadic_args Args) {
|
|||||||
return Result;
|
return Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void JsonSerializeRecursive(nlohmann::json& json, sol::object left, sol::object right) {
|
static void JsonSerializeRecursive(nlohmann::json& json, const sol::object& left, const sol::object& right, size_t depth = 0) {
|
||||||
|
if (depth > 100) {
|
||||||
|
beammp_lua_error("json serialize will not go deeper than 100 nested tables, internal references assumed, aborted this path");
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::string key;
|
std::string key;
|
||||||
bool is_array = false;
|
bool is_array = false;
|
||||||
switch (left.get_type()) {
|
switch (left.get_type()) {
|
||||||
@ -384,31 +388,31 @@ static void JsonSerializeRecursive(nlohmann::json& json, sol::object left, sol::
|
|||||||
return;
|
return;
|
||||||
case sol::type::poly:
|
case sol::type::poly:
|
||||||
beammp_lua_warn("unsure what to do with poly type in JsonSerialize, ignoring");
|
beammp_lua_warn("unsure what to do with poly type in JsonSerialize, ignoring");
|
||||||
break;
|
return;
|
||||||
case sol::type::boolean:
|
case sol::type::boolean:
|
||||||
value = right.as<bool>();
|
value = right.as<bool>();
|
||||||
break;
|
break;
|
||||||
case sol::type::lightuserdata:
|
case sol::type::lightuserdata:
|
||||||
beammp_lua_warn("unsure what to do with lightuserdata in JsonSerialize, ignoring");
|
beammp_lua_warn("unsure what to do with lightuserdata in JsonSerialize, ignoring");
|
||||||
break;
|
return;
|
||||||
case sol::type::userdata:
|
case sol::type::userdata:
|
||||||
beammp_lua_warn("unsure what to do with userdata in JsonSerialize, ignoring");
|
beammp_lua_warn("unsure what to do with userdata in JsonSerialize, ignoring");
|
||||||
break;
|
return;
|
||||||
case sol::type::thread:
|
case sol::type::thread:
|
||||||
beammp_lua_warn("unsure what to do with thread in JsonSerialize, ignoring");
|
beammp_lua_warn("unsure what to do with thread in JsonSerialize, ignoring");
|
||||||
break;
|
return;
|
||||||
case sol::type::string:
|
case sol::type::string:
|
||||||
value = right.as<std::string>();
|
value = right.as<std::string>();
|
||||||
break;
|
break;
|
||||||
case sol::type::number:
|
case sol::type::number:
|
||||||
value = right.as<intmax_t>();
|
value = right.as<double>();
|
||||||
break;
|
break;
|
||||||
case sol::type::function:
|
case sol::type::function:
|
||||||
beammp_lua_warn("unsure what to do with function in JsonSerialize, ignoring");
|
beammp_lua_warn("unsure what to do with function in JsonSerialize, ignoring");
|
||||||
break;
|
return;
|
||||||
case sol::type::table:
|
case sol::type::table:
|
||||||
for (const auto& pair : right.as<sol::table>()) {
|
for (const auto& pair : right.as<sol::table>()) {
|
||||||
JsonSerializeRecursive(value, pair.first, pair.second);
|
JsonSerializeRecursive(value, pair.first, pair.second, depth + 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -419,7 +423,7 @@ static void JsonSerializeRecursive(nlohmann::json& json, sol::object left, sol::
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LuaAPI::MP::JsonSerialize(sol::table object) {
|
std::string LuaAPI::MP::JsonSerialize(const sol::table& object) {
|
||||||
nlohmann::json json;
|
nlohmann::json json;
|
||||||
// table
|
// table
|
||||||
for (const auto& entry : object) {
|
for (const auto& entry : object) {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <httplib.h>
|
#include <httplib.h>
|
||||||
|
#include <nlohmann/json.hpp>
|
||||||
#include <random>
|
#include <random>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
@ -473,6 +474,80 @@ sol::table TLuaEngine::StateThreadData::Lua_HttpCreateConnection(const std::stri
|
|||||||
return table;
|
return table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
static void AddToTable(sol::table& table, const std::string& left, const T& value) {
|
||||||
|
if (left.empty()) {
|
||||||
|
table[table.size() + 1] = value;
|
||||||
|
} else {
|
||||||
|
table[left] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void JsonDeserializeRecursive(sol::state_view& StateView, sol::table& table, const std::string& left, const nlohmann::json& right) {
|
||||||
|
switch (right.type()) {
|
||||||
|
case nlohmann::detail::value_t::null:
|
||||||
|
return;
|
||||||
|
case nlohmann::detail::value_t::object: {
|
||||||
|
auto value = table.create();
|
||||||
|
value.clear();
|
||||||
|
for (const auto& entry : right.items()) {
|
||||||
|
JsonDeserializeRecursive(StateView, value, entry.key(), entry.value());
|
||||||
|
}
|
||||||
|
AddToTable(table, left, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case nlohmann::detail::value_t::array: {
|
||||||
|
auto value = table.create();
|
||||||
|
value.clear();
|
||||||
|
for (const auto& entry : right.items()) {
|
||||||
|
JsonDeserializeRecursive(StateView, value, "", entry.value());
|
||||||
|
}
|
||||||
|
AddToTable(table, left, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case nlohmann::detail::value_t::string:
|
||||||
|
AddToTable(table, left, right.get<std::string>());
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::boolean:
|
||||||
|
AddToTable(table, left, right.get<bool>());
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::number_integer:
|
||||||
|
AddToTable(table, left, right.get<int64_t>());
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::number_unsigned:
|
||||||
|
AddToTable(table, left, right.get<uint64_t>());
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::number_float:
|
||||||
|
AddToTable(table, left, right.get<double>());
|
||||||
|
break;
|
||||||
|
case nlohmann::detail::value_t::binary:
|
||||||
|
beammp_lua_error("JsonDeserialize can't handle binary blob in json, ignoring");
|
||||||
|
return;
|
||||||
|
case nlohmann::detail::value_t::discarded:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::table TLuaEngine::StateThreadData::Lua_JsonDeserialize(const std::string& str) {
|
||||||
|
sol::state_view StateView(mState);
|
||||||
|
auto table = StateView.create_table();
|
||||||
|
// TODO: try / catch
|
||||||
|
nlohmann::json json = nlohmann::json::parse(str);
|
||||||
|
if (json.is_object()) {
|
||||||
|
for (const auto& entry : json.items()) {
|
||||||
|
JsonDeserializeRecursive(StateView, table, entry.key(), entry.value());
|
||||||
|
}
|
||||||
|
} else if (json.is_array()) {
|
||||||
|
for (const auto& entry : json) {
|
||||||
|
JsonDeserializeRecursive(StateView, table, "", entry);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
beammp_lua_error("JsonDeserialize expected array or object json, instead got " + std::string(json.type_name()));
|
||||||
|
return sol::nil;
|
||||||
|
}
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
|
||||||
TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomic_bool& Shutdown, TLuaStateId StateId, TLuaEngine& Engine)
|
TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomic_bool& Shutdown, TLuaStateId StateId, TLuaEngine& Engine)
|
||||||
: mName(Name)
|
: mName(Name)
|
||||||
, mShutdown(Shutdown)
|
, mShutdown(Shutdown)
|
||||||
@ -557,13 +632,15 @@ TLuaEngine::StateThreadData::StateThreadData(const std::string& Name, std::atomi
|
|||||||
});
|
});
|
||||||
MPTable.set_function("Set", &LuaAPI::MP::Set);
|
MPTable.set_function("Set", &LuaAPI::MP::Set);
|
||||||
MPTable.set_function("JsonSerialize", &LuaAPI::MP::JsonSerialize);
|
MPTable.set_function("JsonSerialize", &LuaAPI::MP::JsonSerialize);
|
||||||
|
MPTable.set_function("JsonDeserialize", [this](const std::string& str) {
|
||||||
|
return Lua_JsonDeserialize(str);
|
||||||
|
});
|
||||||
|
|
||||||
auto HttpTable = StateView.create_named_table("Http");
|
auto HttpTable = StateView.create_named_table("Http");
|
||||||
HttpTable.set_function("CreateConnection", [this](const std::string& host, uint16_t port) {
|
HttpTable.set_function("CreateConnection", [this](const std::string& host, uint16_t port) {
|
||||||
return Lua_HttpCreateConnection(host, port);
|
return Lua_HttpCreateConnection(host, port);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
MPTable.create_named("Settings",
|
MPTable.create_named("Settings",
|
||||||
"Debug", 0,
|
"Debug", 0,
|
||||||
"Private", 1,
|
"Private", 1,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user