mirror of
https://gitlab.com/Mr_Goldberg/goldberg_emulator.git
synced 2024-11-14 10:50:13 +01:00
Some cleanups.
Load items json only if there's an inventory request. Launch callbacks only when loading is done. Copy over original unformatted json.hpp
This commit is contained in:
parent
f56503fcd0
commit
59a9fcee0d
6 changed files with 17345 additions and 17416 deletions
12
README.md
12
README.md
|
@ -16,18 +16,6 @@ If your game has an original steam_api(64).dll or libsteam_api.so older than may
|
|||
|
||||
For more information see: [The Release Readme](Readme_release.txt)
|
||||
|
||||
## How to add items to your steam inventory
|
||||
|
||||
Create a folder named steam_settings right beside steam_api.dll if there isn't one already. In that folder, create a file named items.json which will contain every item you want to have in your game.
|
||||
|
||||
An example can be found in steam_settings.EXAMPLE that works with Killing Floor 2.
|
||||
|
||||
The items.json syntax is simple, you SHOULD validate your .json file before trying to run your game or you won't have any item in your inventory. Just look for "online json validator" on your web brower to valide your file.
|
||||
|
||||
You can use https://steamdb.info/ to list items and attributes they have and put them into your .json.
|
||||
|
||||
Keep in mind that some item are not valid to have in your inventory. For example, in PayDay2 all items below item_id 50000 will make your game crash.
|
||||
|
||||
## Download Binaries
|
||||
|
||||
You can download the latest git builds for Linux and Windows on [the Gitlab pages website](https://mr_goldberg.gitlab.io/goldberg_emulator/) and the stable releases in the [release section](https://gitlab.com/Mr_Goldberg/goldberg_emulator/releases) of this repo.
|
||||
|
|
|
@ -65,6 +65,14 @@ If you want to set custom ips (or domains) which the emulator will send broadcas
|
|||
If the custom ips/domains are specific for one game only you can put the custom_broadcasts.txt in the steam_settings\ folder.
|
||||
An example is provided in steam_settings.EXAMPLE\custom_broadcasts.EXAMPLE.txt
|
||||
|
||||
Items or Inventory:
|
||||
Create a folder named steam_settings right beside steam_api.dll if there isn't one already. In that folder, create a file named items.json which will contain every item you want to have in your game.
|
||||
An example can be found in steam_settings.EXAMPLE that works with Killing Floor 2.
|
||||
The items.json syntax is simple, you SHOULD validate your .json file before trying to run your game or you won't have any item in your inventory. Just look for "online json validator" on your web brower to valide your file.
|
||||
You can use https://steamdb.info/ to list items and attributes they have and put them into your .json.
|
||||
Keep in mind that some item are not valid to have in your inventory. For example, in PayDay2 all items below item_id 50000 will make your game crash.
|
||||
|
||||
|
||||
Support for CPY steam_api(64).dll cracks: See the build in the experimental folder.
|
||||
|
||||
|
||||
|
|
|
@ -53,8 +53,10 @@ void read_items_db(std::string items_db, std::map<SteamItemDef_t, std::map<std::
|
|||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
PRINT_DEBUG("Error while parsing json: %s", e.what());
|
||||
PRINT_DEBUG("Error while parsing json: %s\n", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
PRINT_DEBUG("Loaded json. Loaded %u items.\n", items->size());
|
||||
*is_loadedb = true;
|
||||
}
|
|
@ -291,6 +291,8 @@ Steam_Client::Steam_Client()
|
|||
}
|
||||
}
|
||||
|
||||
std::string items_db_file_path = (Local_Storage::get_game_settings_path() + "items.json");
|
||||
|
||||
network = new Networking(settings_server->get_local_steam_id(), appid, port, &custom_broadcasts);
|
||||
|
||||
callback_results_client = new SteamCallResults();
|
||||
|
@ -318,7 +320,7 @@ Steam_Client::Steam_Client()
|
|||
steam_music = new Steam_Music(callbacks_client);
|
||||
steam_musicremote = new Steam_MusicRemote();
|
||||
steam_HTMLsurface = new Steam_HTMLsurface(settings_client, network, callback_results_client, callbacks_client);
|
||||
steam_inventory = new Steam_Inventory(settings_client, callback_results_client, callbacks_client);
|
||||
steam_inventory = new Steam_Inventory(settings_client, callback_results_client, callbacks_client, run_every_runcb, items_db_file_path);
|
||||
steam_video = new Steam_Video();
|
||||
steam_parental = new Steam_Parental();
|
||||
steam_networking_sockets = new Steam_Networking_Sockets(settings_client, network, callback_results_client, callbacks_client, run_every_runcb);
|
||||
|
@ -335,7 +337,7 @@ Steam_Client::Steam_Client()
|
|||
steam_gameserverstats = new Steam_GameServerStats(settings_server, network, callback_results_server, callbacks_server);
|
||||
steam_gameserver_networking = new Steam_Networking(settings_server, network, callbacks_server, run_every_runcb);
|
||||
steam_gameserver_http = new Steam_HTTP(settings_server, network, callback_results_server, callbacks_server);
|
||||
steam_gameserver_inventory = new Steam_Inventory(settings_server, callback_results_server, callbacks_server);
|
||||
steam_gameserver_inventory = new Steam_Inventory(settings_server, callback_results_server, callbacks_server, run_every_runcb, items_db_file_path);
|
||||
steam_gameserver_ugc = new Steam_UGC(settings_server, callback_results_server, callbacks_server);
|
||||
steam_gameserver_apps = new Steam_Apps(settings_server, callback_results_server);
|
||||
steam_gameserver_networking_sockets = new Steam_Networking_Sockets(settings_server, network, callback_results_server, callbacks_server, run_every_runcb);
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
|
||||
struct Steam_Inventory_Requests {
|
||||
double timeout = 0.1;
|
||||
bool done = false;
|
||||
bool full_query;
|
||||
|
||||
SteamInventoryResult_t inventory_result;
|
||||
std::chrono::system_clock::time_point time_created;
|
||||
|
@ -27,7 +29,7 @@ struct Steam_Inventory_Requests {
|
|||
std::vector<SteamItemInstanceID_t> instance_ids;
|
||||
|
||||
bool result_done() {
|
||||
return std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::system_clock::now() - time_created).count() > timeout;
|
||||
return done;
|
||||
}
|
||||
|
||||
uint32 timestamp() {
|
||||
|
@ -43,30 +45,30 @@ class Steam_Inventory :
|
|||
class Settings *settings;
|
||||
class SteamCallResults *callback_results;
|
||||
class SteamCallBacks *callbacks;
|
||||
class RunEveryRunCB *run_every_runcb;
|
||||
|
||||
std::vector<struct Steam_Inventory_Requests> inventory_requests;
|
||||
|
||||
static std::once_flag items_loading;
|
||||
static std::atomic_bool items_loaded;
|
||||
static std::map<SteamItemDef_t, std::map<std::string, std::string>> items;
|
||||
std::map<SteamItemDef_t, std::map<std::string, std::string>> items;
|
||||
// Like typedefs
|
||||
using item_iterator = std::map<SteamItemDef_t, std::map<std::string, std::string>>::iterator;
|
||||
using attr_iterator = std::map<std::string, std::string>::iterator;
|
||||
|
||||
// Set this to false when we have cached everything,
|
||||
// reset to true if something changed in the item db.
|
||||
// Could use inotify on linux
|
||||
// Could use FindFirstChangeNotificationA + WaitForSingleObject + FindNextChangeNotification on Windows to monitor the db file
|
||||
// Or find a server somewhere to hold the data for us then cache on local settings.
|
||||
bool need_load_definitions = true;
|
||||
std::atomic_bool items_loaded;
|
||||
std::string items_db_file;
|
||||
std::once_flag load_items_flag;
|
||||
bool call_definition_update;
|
||||
bool definition_update_called;
|
||||
bool full_update_called;
|
||||
|
||||
struct Steam_Inventory_Requests* new_inventory_result(const SteamItemInstanceID_t* pInstanceIDs = NULL, uint32 unCountInstanceIDs = 0)
|
||||
struct Steam_Inventory_Requests* new_inventory_result(bool full_query=true, const SteamItemInstanceID_t* pInstanceIDs = NULL, uint32 unCountInstanceIDs = 0)
|
||||
{
|
||||
static SteamInventoryResult_t result;
|
||||
++result;
|
||||
|
||||
struct Steam_Inventory_Requests request;
|
||||
request.inventory_result = result;
|
||||
request.full_query = full_query;
|
||||
if (pInstanceIDs && unCountInstanceIDs) {
|
||||
for (int i = 0; i < unCountInstanceIDs; ++i)
|
||||
request.instance_ids.push_back(pInstanceIDs[i]);
|
||||
|
@ -89,19 +91,34 @@ struct Steam_Inventory_Requests *get_inventory_result(SteamInventoryResult_t res
|
|||
|
||||
public:
|
||||
|
||||
Steam_Inventory(class Settings *settings, class SteamCallResults *callback_results, class SteamCallBacks *callbacks)
|
||||
static void run_every_runcb_cb(void *object)
|
||||
{
|
||||
std::call_once(items_loading, [&]()
|
||||
PRINT_DEBUG("Steam_Inventory::run_every_runcb\n");
|
||||
|
||||
Steam_Inventory *obj = (Steam_Inventory *)object;
|
||||
obj->RunCallbacks();
|
||||
}
|
||||
|
||||
Steam_Inventory(class Settings *settings, class SteamCallResults *callback_results, class SteamCallBacks *callbacks, class RunEveryRunCB *run_every_runcb, std::string items_db_file_path)
|
||||
{
|
||||
std::string items_db_file(Local_Storage::get_game_settings_path() + "items.json");
|
||||
items_db_file = items_db_file_path;
|
||||
PRINT_DEBUG("Items file path: %s\n", items_db_file.c_str());
|
||||
std::thread items_load_thread(read_items_db, items_db_file, &items, &items_loaded);
|
||||
items_load_thread.detach();
|
||||
});
|
||||
items_loaded = false;
|
||||
|
||||
this->settings = settings;
|
||||
this->callbacks = callbacks;
|
||||
this->callback_results = callback_results;
|
||||
this->run_every_runcb = run_every_runcb;
|
||||
this->run_every_runcb->add(&Steam_Inventory::run_every_runcb_cb, this);
|
||||
|
||||
call_definition_update = false;
|
||||
definition_update_called = false;
|
||||
full_update_called = false;
|
||||
}
|
||||
|
||||
~Steam_Inventory()
|
||||
{
|
||||
this->run_every_runcb->remove(&Steam_Inventory::run_every_runcb_cb, this);
|
||||
}
|
||||
|
||||
// INVENTORY ASYNC RESULT MANAGEMENT
|
||||
|
@ -147,6 +164,8 @@ bool GetResultItems( SteamInventoryResult_t resultHandle,
|
|||
if (pOutItemsArray != nullptr)
|
||||
{
|
||||
uint32 max_items = *punOutItemsArraySize;
|
||||
|
||||
if (request->full_query) {
|
||||
// We end if we reached the end of items or the end of buffer
|
||||
for( auto i = items.begin(); i != items.end() && max_items; ++i, --max_items )
|
||||
{
|
||||
|
@ -157,6 +176,17 @@ bool GetResultItems( SteamInventoryResult_t resultHandle,
|
|||
++pOutItemsArray;
|
||||
}
|
||||
*punOutItemsArraySize = std::min(*punOutItemsArraySize, static_cast<uint32>(items.size()));
|
||||
} else {
|
||||
for (auto &itemid : request->instance_ids) {
|
||||
if (!max_items) break;
|
||||
pOutItemsArray->m_iDefinition = itemid;
|
||||
pOutItemsArray->m_itemId = itemid;
|
||||
pOutItemsArray->m_unQuantity = 1;
|
||||
pOutItemsArray->m_unFlags = k_ESteamItemNoTrade;
|
||||
++pOutItemsArray;
|
||||
--max_items;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (punOutItemsArraySize != nullptr)
|
||||
{
|
||||
|
@ -248,48 +278,10 @@ bool GetAllItems( SteamInventoryResult_t *pResultHandle )
|
|||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
struct Steam_Inventory_Requests* request = new_inventory_result();
|
||||
|
||||
// Can't call LoadItemDefinitions because it sends a SteamInventoryResultReady_t.
|
||||
if( need_load_definitions )
|
||||
{
|
||||
if (items_loaded)
|
||||
{
|
||||
need_load_definitions = false;
|
||||
SteamInventoryDefinitionUpdate_t data = {};
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
|
||||
}
|
||||
}
|
||||
|
||||
if (!need_load_definitions)
|
||||
{
|
||||
{
|
||||
// SteamInventoryFullUpdate_t callbacks are triggered when GetAllItems
|
||||
// successfully returns a result which is newer / fresher than the last
|
||||
// known result.
|
||||
//TODO: should this always be returned for each get all item calls?
|
||||
struct SteamInventoryFullUpdate_t data;
|
||||
data.m_handle = request->inventory_result;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout);
|
||||
}
|
||||
{
|
||||
struct SteamInventoryResultReady_t data;
|
||||
data.m_handle = request->inventory_result;
|
||||
data.m_result = k_EResultOK;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout);
|
||||
}
|
||||
if (!definition_update_called) call_definition_update = true;
|
||||
|
||||
if (pResultHandle != nullptr)
|
||||
*pResultHandle = request->inventory_result;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct SteamInventoryResultReady_t data;
|
||||
data.m_handle = request->inventory_result;
|
||||
data.m_result = k_EResultPending;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout);
|
||||
|
||||
if (pResultHandle != nullptr)
|
||||
*pResultHandle = request->inventory_result;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -309,14 +301,7 @@ bool GetItemsByID( SteamInventoryResult_t *pResultHandle, STEAM_ARRAY_COUNT( unC
|
|||
PRINT_DEBUG("GetItemsByID\n");
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
if (pResultHandle) {
|
||||
struct Steam_Inventory_Requests *request = new_inventory_result(pInstanceIDs, unCountInstanceIDs);
|
||||
{
|
||||
struct SteamInventoryResultReady_t data;
|
||||
data.m_handle = request->inventory_result;
|
||||
data.m_result = k_EResultOK;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout);
|
||||
}
|
||||
|
||||
struct Steam_Inventory_Requests *request = new_inventory_result(false, pInstanceIDs, unCountInstanceIDs);
|
||||
*pResultHandle = request->inventory_result;
|
||||
return true;
|
||||
}
|
||||
|
@ -393,14 +378,7 @@ bool DeserializeResult( SteamInventoryResult_t *pOutResultHandle, STEAM_BUFFER_C
|
|||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
//TODO
|
||||
if (pOutResultHandle) {
|
||||
struct Steam_Inventory_Requests *request = new_inventory_result();
|
||||
{
|
||||
struct SteamInventoryResultReady_t data;
|
||||
data.m_handle = request->inventory_result;
|
||||
data.m_result = k_EResultOK;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout);
|
||||
}
|
||||
|
||||
struct Steam_Inventory_Requests *request = new_inventory_result(false);
|
||||
*pOutResultHandle = request->inventory_result;
|
||||
return true;
|
||||
}
|
||||
|
@ -551,32 +529,12 @@ STEAM_METHOD_DESC(LoadItemDefinitions triggers the automatic load and refresh of
|
|||
bool LoadItemDefinitions()
|
||||
{
|
||||
PRINT_DEBUG("LoadItemDefinitions\n");
|
||||
|
||||
if (need_load_definitions)
|
||||
{
|
||||
if (!items_loaded)
|
||||
{
|
||||
SteamInventoryResultReady_t data;
|
||||
data.m_result = k_EResultPending;
|
||||
data.m_handle = new_inventory_result()->inventory_result;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
|
||||
}
|
||||
else
|
||||
{
|
||||
need_load_definitions = false;
|
||||
{
|
||||
SteamInventoryDefinitionUpdate_t data = {};
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
|
||||
}
|
||||
{
|
||||
SteamInventoryResultReady_t data = {};
|
||||
data.m_result = k_EResultOK;
|
||||
data.m_handle = new_inventory_result()->inventory_result;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
|
||||
}
|
||||
}
|
||||
if (!definition_update_called) {
|
||||
call_definition_update = true;
|
||||
}
|
||||
|
||||
//real steam launches a SteamInventoryResultReady_t which is why I create a new inventory result
|
||||
new_inventory_result(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -817,4 +775,52 @@ bool SubmitUpdateProperties( SteamInventoryUpdateHandle_t handle, SteamInventory
|
|||
PRINT_DEBUG("SubmitUpdateProperties\n");
|
||||
}
|
||||
|
||||
void RunCallbacks()
|
||||
{
|
||||
if (call_definition_update || inventory_requests.size()) {
|
||||
std::call_once(load_items_flag, [&]() {
|
||||
std::thread items_load_thread(read_items_db, items_db_file, &items, &items_loaded);
|
||||
items_load_thread.detach();
|
||||
});
|
||||
}
|
||||
|
||||
if (items_loaded) {
|
||||
if (call_definition_update) {
|
||||
//call this callback even when 0 items?
|
||||
SteamInventoryDefinitionUpdate_t data = {};
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
|
||||
call_definition_update = false;
|
||||
definition_update_called = true;
|
||||
}
|
||||
|
||||
std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
|
||||
|
||||
for (auto & r : inventory_requests) {
|
||||
if (!r.done && std::chrono::duration_cast<std::chrono::duration<double>>(now - r.time_created).count() > r.timeout) {
|
||||
if (r.full_query) {
|
||||
if (!full_update_called) {
|
||||
// SteamInventoryFullUpdate_t callbacks are triggered when GetAllItems
|
||||
// successfully returns a result which is newer / fresher than the last
|
||||
// known result.
|
||||
//TODO: should this always be returned for each get all item calls?
|
||||
struct SteamInventoryFullUpdate_t data;
|
||||
data.m_handle = r.inventory_result;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
|
||||
full_update_called = true;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
struct SteamInventoryResultReady_t data;
|
||||
data.m_handle = r.inventory_result;
|
||||
data.m_result = k_EResultOK;
|
||||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data));
|
||||
}
|
||||
|
||||
r.done = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
131
json/json.hpp
131
json/json.hpp
|
@ -469,14 +469,6 @@ namespace nlohmann
|
|||
#endif
|
||||
#endif
|
||||
|
||||
// C++ language standard detection
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
||||
#define JSON_HAS_CPP_17
|
||||
#define JSON_HAS_CPP_14
|
||||
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
|
||||
#define JSON_HAS_CPP_14
|
||||
#endif
|
||||
|
||||
// disable float-equal warnings on GCC/clang
|
||||
#if defined(__clang__) || defined(__GNUC__) || defined(__GNUG__)
|
||||
#pragma GCC diagnostic push
|
||||
|
@ -501,11 +493,7 @@ namespace nlohmann
|
|||
// allow for portable nodiscard warnings
|
||||
#if defined(__has_cpp_attribute)
|
||||
#if __has_cpp_attribute(nodiscard)
|
||||
#if defined(__clang__) && !defined(JSON_HAS_CPP_17) // issue #1535
|
||||
#define JSON_NODISCARD
|
||||
#else
|
||||
#define JSON_NODISCARD [[nodiscard]]
|
||||
#endif
|
||||
#elif __has_cpp_attribute(gnu::warn_unused_result)
|
||||
#define JSON_NODISCARD [[gnu::warn_unused_result]]
|
||||
#else
|
||||
|
@ -558,6 +546,14 @@ namespace nlohmann
|
|||
#define JSON_UNLIKELY(x) x
|
||||
#endif
|
||||
|
||||
// C++ language standard detection
|
||||
#if (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464
|
||||
#define JSON_HAS_CPP_17
|
||||
#define JSON_HAS_CPP_14
|
||||
#elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1)
|
||||
#define JSON_HAS_CPP_14
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@brief macro to briefly define a mapping between an enum and JSON
|
||||
@def NLOHMANN_JSON_SERIALIZE_ENUM
|
||||
|
@ -1059,19 +1055,10 @@ namespace nlohmann
|
|||
using object_t = typename BasicJsonType::object_t;
|
||||
|
||||
static constexpr bool value =
|
||||
(std::is_default_constructible<ConstructibleObjectType>::value and
|
||||
(std::is_move_assignable<ConstructibleObjectType>::value or
|
||||
std::is_copy_assignable<ConstructibleObjectType>::value) and
|
||||
(std::is_constructible<typename ConstructibleObjectType::key_type,
|
||||
typename object_t::key_type>::value and
|
||||
std::is_same <
|
||||
typename object_t::mapped_type,
|
||||
typename ConstructibleObjectType::mapped_type >::value)) or
|
||||
(has_from_json<BasicJsonType,
|
||||
typename ConstructibleObjectType::mapped_type>::value or
|
||||
has_non_default_from_json <
|
||||
BasicJsonType,
|
||||
typename ConstructibleObjectType::mapped_type >::value);
|
||||
(std::is_constructible<typename ConstructibleObjectType::key_type, typename object_t::key_type>::value and
|
||||
std::is_same<typename object_t::mapped_type, typename ConstructibleObjectType::mapped_type>::value) or
|
||||
(has_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type>::value or
|
||||
has_non_default_from_json<BasicJsonType, typename ConstructibleObjectType::mapped_type >::value);
|
||||
};
|
||||
|
||||
template <typename BasicJsonType, typename ConstructibleObjectType>
|
||||
|
@ -1154,9 +1141,6 @@ namespace nlohmann
|
|||
BasicJsonType, ConstructibleArrayType,
|
||||
enable_if_t<not std::is_same<ConstructibleArrayType,
|
||||
typename BasicJsonType::value_type>::value and
|
||||
std::is_default_constructible<ConstructibleArrayType>::value and
|
||||
(std::is_move_assignable<ConstructibleArrayType>::value or
|
||||
std::is_copy_assignable<ConstructibleArrayType>::value) and
|
||||
is_detected<value_type_t, ConstructibleArrayType>::value and
|
||||
is_detected<iterator_t, ConstructibleArrayType>::value and
|
||||
is_complete_type<
|
||||
|
@ -1164,14 +1148,13 @@ namespace nlohmann
|
|||
{
|
||||
static constexpr bool value =
|
||||
// This is needed because json_reverse_iterator has a ::iterator type,
|
||||
// furthermore, std::back_insert_iterator (and other iterators) have a
|
||||
// base class `iterator`... Therefore it is detected as a
|
||||
// ConstructibleArrayType. The real fix would be to have an Iterable
|
||||
// concept.
|
||||
not is_iterator_traits<iterator_traits<ConstructibleArrayType>>::value and
|
||||
// furthermore, std::back_insert_iterator (and other iterators) have a base class `iterator`...
|
||||
// Therefore it is detected as a ConstructibleArrayType.
|
||||
// The real fix would be to have an Iterable concept.
|
||||
not is_iterator_traits <
|
||||
iterator_traits<ConstructibleArrayType >>::value and
|
||||
|
||||
(std::is_same<typename ConstructibleArrayType::value_type,
|
||||
typename BasicJsonType::array_t::value_type>::value or
|
||||
(std::is_same<typename ConstructibleArrayType::value_type, typename BasicJsonType::array_t::value_type>::value or
|
||||
has_from_json<BasicJsonType,
|
||||
typename ConstructibleArrayType::value_type>::value or
|
||||
has_non_default_from_json <
|
||||
|
@ -1424,7 +1407,6 @@ namespace nlohmann
|
|||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
}
|
||||
l.clear();
|
||||
std::transform(j.rbegin(), j.rend(),
|
||||
std::front_inserter(l), [](const BasicJsonType & i)
|
||||
{
|
||||
|
@ -1445,16 +1427,6 @@ namespace nlohmann
|
|||
std::copy(j.m_value.array->begin(), j.m_value.array->end(), std::begin(l));
|
||||
}
|
||||
|
||||
template <typename BasicJsonType, typename T, std::size_t N>
|
||||
auto from_json(const BasicJsonType& j, T(&arr)[N])
|
||||
-> decltype(j.template get<T>(), void())
|
||||
{
|
||||
for (std::size_t i = 0; i < N; ++i)
|
||||
{
|
||||
arr[i] = j.at(i).template get<T>();
|
||||
}
|
||||
}
|
||||
|
||||
template<typename BasicJsonType>
|
||||
void from_json_array_impl(const BasicJsonType& j, typename BasicJsonType::array_t& arr, priority_tag<3> /*unused*/)
|
||||
{
|
||||
|
@ -1481,16 +1453,14 @@ namespace nlohmann
|
|||
{
|
||||
using std::end;
|
||||
|
||||
ConstructibleArrayType ret;
|
||||
ret.reserve(j.size());
|
||||
arr.reserve(j.size());
|
||||
std::transform(j.begin(), j.end(),
|
||||
std::inserter(ret, end(ret)), [](const BasicJsonType& i)
|
||||
std::inserter(arr, end(arr)), [](const BasicJsonType & i)
|
||||
{
|
||||
// get<BasicJsonType>() returns *this, this won't call a from_json
|
||||
// method when value_type is BasicJsonType
|
||||
return i.template get<typename ConstructibleArrayType::value_type>();
|
||||
});
|
||||
arr = std::move(ret);
|
||||
}
|
||||
|
||||
template <typename BasicJsonType, typename ConstructibleArrayType>
|
||||
|
@ -1499,16 +1469,14 @@ namespace nlohmann
|
|||
{
|
||||
using std::end;
|
||||
|
||||
ConstructibleArrayType ret;
|
||||
std::transform(
|
||||
j.begin(), j.end(), std::inserter(ret, end(ret)),
|
||||
j.begin(), j.end(), std::inserter(arr, end(arr)),
|
||||
[](const BasicJsonType & i)
|
||||
{
|
||||
// get<BasicJsonType>() returns *this, this won't call a from_json
|
||||
// method when value_type is BasicJsonType
|
||||
return i.template get<typename ConstructibleArrayType::value_type>();
|
||||
});
|
||||
arr = std::move(ret);
|
||||
}
|
||||
|
||||
template <typename BasicJsonType, typename ConstructibleArrayType,
|
||||
|
@ -1542,17 +1510,15 @@ namespace nlohmann
|
|||
JSON_THROW(type_error::create(302, "type must be object, but is " + std::string(j.type_name())));
|
||||
}
|
||||
|
||||
ConstructibleObjectType ret;
|
||||
auto inner_object = j.template get_ptr<const typename BasicJsonType::object_t*>();
|
||||
using value_type = typename ConstructibleObjectType::value_type;
|
||||
std::transform(
|
||||
inner_object->begin(), inner_object->end(),
|
||||
std::inserter(ret, ret.begin()),
|
||||
std::inserter(obj, obj.begin()),
|
||||
[](typename BasicJsonType::object_t::value_type const & p)
|
||||
{
|
||||
return value_type(p.first, p.second.template get<typename ConstructibleObjectType::mapped_type>());
|
||||
});
|
||||
obj = std::move(ret);
|
||||
}
|
||||
|
||||
// overload for arithmetic types, not chosen for basic_json template arguments
|
||||
|
@ -1624,7 +1590,6 @@ namespace nlohmann
|
|||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
}
|
||||
m.clear();
|
||||
for (const auto& p : j)
|
||||
{
|
||||
if (JSON_UNLIKELY(not p.is_array()))
|
||||
|
@ -1644,7 +1609,6 @@ namespace nlohmann
|
|||
{
|
||||
JSON_THROW(type_error::create(302, "type must be array, but is " + std::string(j.type_name())));
|
||||
}
|
||||
m.clear();
|
||||
for (const auto& p : j)
|
||||
{
|
||||
if (JSON_UNLIKELY(not p.is_array()))
|
||||
|
@ -5368,7 +5332,8 @@ namespace nlohmann
|
|||
do
|
||||
{
|
||||
get();
|
||||
} while (current == 'N');
|
||||
}
|
||||
while (current == 'N');
|
||||
|
||||
return current;
|
||||
}
|
||||
|
@ -6948,7 +6913,8 @@ namespace nlohmann
|
|||
do
|
||||
{
|
||||
get();
|
||||
} while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
|
||||
}
|
||||
while (current == ' ' or current == '\t' or current == '\n' or current == '\r');
|
||||
|
||||
switch (current)
|
||||
{
|
||||
|
@ -7819,16 +7785,6 @@ namespace nlohmann
|
|||
to iterator is not defined.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@brief const copy constructor
|
||||
@param[in] other const iterator to copy from
|
||||
@note This copy constuctor had to be defined explicitely to circumvent a bug
|
||||
occuring on msvc v19.0 compiler (VS 2015) debug build. For more
|
||||
information refer to: https://github.com/nlohmann/json/issues/1608
|
||||
*/
|
||||
iter_impl(const iter_impl<const BasicJsonType>& other) noexcept
|
||||
: m_object(other.m_object), m_it(other.m_it) {}
|
||||
|
||||
/*!
|
||||
@brief converting constructor
|
||||
@param[in] other non-const iterator to copy from
|
||||
|
@ -9238,8 +9194,7 @@ namespace nlohmann
|
|||
pos != std::string::npos; // make sure f was found
|
||||
s.replace(pos, f.size(), t), // replace with t, and
|
||||
pos = s.find(f, pos + t.size())) // find next occurrence of f
|
||||
{
|
||||
}
|
||||
{}
|
||||
}
|
||||
|
||||
/// escape "~" to "~0" and "/" to "~1"
|
||||
|
@ -15494,19 +15449,6 @@ namespace nlohmann
|
|||
return v;
|
||||
}
|
||||
|
||||
template <
|
||||
typename T, std::size_t N,
|
||||
typename Array = T(&)[N],
|
||||
detail::enable_if_t <
|
||||
detail::has_from_json<basic_json_t, Array>::value, int > = 0 >
|
||||
Array get_to(T(&v)[N]) const
|
||||
noexcept(noexcept(JSONSerializer<Array>::from_json(
|
||||
std::declval<const basic_json_t&>(), v)))
|
||||
{
|
||||
JSONSerializer<Array>::from_json(*this, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
@brief get a pointer value (implicit)
|
||||
|
@ -16198,8 +16140,6 @@ namespace nlohmann
|
|||
@return copy of the element at key @a key or @a default_value if @a key
|
||||
is not found
|
||||
|
||||
@throw type_error.302 if @a default_value does not match the type of the
|
||||
value at @a key
|
||||
@throw type_error.306 if the JSON value is not an object; in that case,
|
||||
using `value()` with a key makes no sense.
|
||||
|
||||
|
@ -16273,8 +16213,6 @@ namespace nlohmann
|
|||
@return copy of the element at key @a key or @a default_value if @a key
|
||||
is not found
|
||||
|
||||
@throw type_error.302 if @a default_value does not match the type of the
|
||||
value at @a ptr
|
||||
@throw type_error.306 if the JSON value is not an object; in that case,
|
||||
using `value()` with a key makes no sense.
|
||||
|
||||
|
@ -20779,21 +20717,6 @@ namespace nlohmann
|
|||
|
||||
/// @}
|
||||
};
|
||||
|
||||
/*!
|
||||
@brief user-defined to_string function for JSON values
|
||||
|
||||
This function implements a user-defined to_string for JSON objects.
|
||||
|
||||
@param[in] j a JSON object
|
||||
@return a std::string object
|
||||
*/
|
||||
|
||||
NLOHMANN_BASIC_JSON_TPL_DECLARATION
|
||||
std::string to_string(const NLOHMANN_BASIC_JSON_TPL& j)
|
||||
{
|
||||
return j.dump();
|
||||
}
|
||||
} // namespace nlohmann
|
||||
|
||||
///////////////////////
|
||||
|
|
Loading…
Reference in a new issue