diff --git a/src/script/dataStorage.cpp b/src/script/dataStorage.cpp index fac95bb86..87e1c4487 100644 --- a/src/script/dataStorage.cpp +++ b/src/script/dataStorage.cpp @@ -4,7 +4,7 @@ static string scriptstorage_path = "scriptstorage.json"; -std::unordered_map data; +static nlohmann::json data; static void initScriptStorage() { @@ -29,11 +29,7 @@ static void initScriptStorage() std::string err; if (auto parsed_json = sp::json::parse(s, err); parsed_json) { - auto json = parsed_json.value(); - for (const auto& [key, value] : json.items()) - { - data[key] = value.get(); - } + data = parsed_json.value(); } else { @@ -42,16 +38,100 @@ static void initScriptStorage() } } +static void luaPushJson(lua_State* L, const nlohmann::json& json) +{ + switch(json.type()) { + case nlohmann::json::value_t::null: + lua_pushnil(L); + break; + case nlohmann::json::value_t::object: + lua_newtable(L); + for(const auto& [key, value] : json.items()) { + luaPushJson(L, key); + luaPushJson(L, value); + lua_settable(L, -3); + } + break; + case nlohmann::json::value_t::array: + lua_newtable(L); + { + int index = 1; + for(const auto& value : json) { + luaPushJson(L, value); + lua_seti(L, -2, index++); + } + } + break; + case nlohmann::json::value_t::string: + lua_pushstring(L, static_cast(json).c_str()); + break; + case nlohmann::json::value_t::boolean: + lua_pushboolean(L, static_cast(json)); + break; + case nlohmann::json::value_t::number_integer: + case nlohmann::json::value_t::number_unsigned: + lua_pushnumber(L, static_cast(json)); + break; + case nlohmann::json::value_t::number_float: + lua_pushnumber(L, static_cast(json)); + break; + case nlohmann::json::value_t::binary: + lua_pushnil(L); + break; + case nlohmann::json::value_t::discarded: + lua_pushnil(L); + break; + } +} + +static nlohmann::json luaGetJson(lua_State* L, int index) +{ + nlohmann::json res{nullptr}; + switch(lua_type(L, index)) + { + case LUA_TBOOLEAN: + res = bool(lua_toboolean(L, index)); + break; + case LUA_TNUMBER: + res = lua_tonumber(L, index); + break; + case LUA_TSTRING: + res = lua_tostring(L, index); + break; + case LUA_TTABLE: + index = lua_absindex(L, index); + if (lua_rawlen(L, index) > 0) { + res = nlohmann::json::array(); + for(int n=1; n<=lua_rawlen(L, index); n++) { + lua_geti(L, index, n); + res.push_back(luaGetJson(L, -1)); + lua_pop(L, 1); + } + } else { + res = nlohmann::json::object(); + lua_pushnil(L); + while(lua_next(L, index)) { + auto key = luaGetJson(L, -2); + auto value = luaGetJson(L, -1); + if (key.is_string()) + res[key] = value; + lua_pop(L, 1); + } + } + break; + } + return res; +} + static int luaScriptDataStorageSet(lua_State* L) { string key = luaL_checkstring(L, 2); - string value = luaL_checkstring(L, 3); - if (data[key] == value) - return 0; - - data[key] = value; + if (lua_isnil(L, 3)) { + data.erase(key); + } else { + data[key] = luaGetJson(L, 3); + } FILE* f = fopen(scriptstorage_path.c_str(), "wt"); - if (f) { auto s = nlohmann::json(data).dump(); @@ -67,7 +147,8 @@ static int luaScriptDataStorageGet(lua_State* L) auto it = data.find(key); if (it == data.end()) return 0; - lua_pushstring(L, it->second.c_str()); + + luaPushJson(L, *it); return 1; }