Modified Inventory to match steam's implementation

This commit is contained in:
Nemirtingas 2019-07-14 19:22:30 +02:00
parent 06f88d4687
commit 5c66c21f53
3 changed files with 76 additions and 30 deletions

View File

@ -19,10 +19,8 @@
#include <fstream> #include <fstream>
#include "json.hpp" #include "json.hpp"
std::map<SteamItemDef_t, std::map<std::string, std::string>> read_items_db(std::string const& items_db) void read_items_db(std::string items_db, std::map<SteamItemDef_t, std::map<std::string, std::string>> *items, bool *is_loadedb)
{ {
std::map<SteamItemDef_t, std::map<std::string, std::string>> items;
std::ifstream items_file(items_db); std::ifstream items_file(items_db);
// If there is a file and we opened it // If there is a file and we opened it
if( items_file ) if( items_file )
@ -51,13 +49,12 @@ std::map<SteamItemDef_t, std::map<std::string, std::string>> read_items_db(std::
} }
} }
items.swap(tmp); items->swap(tmp);
} }
catch (std::exception& e) catch (std::exception& e)
{ {
PRINT_DEBUG("Error while parsing json: %s", e.what()); PRINT_DEBUG("Error while parsing json: %s", e.what());
} }
} }
*is_loadedb = true;
return items;
} }

View File

@ -18,6 +18,6 @@
#include "base.h" // For SteamItemDef_t #include "base.h" // For SteamItemDef_t
std::map<SteamItemDef_t, std::map<std::string, std::string>> read_items_db(std::string const& items_db); void read_items_db(std::string items_db, std::map<SteamItemDef_t, std::map<std::string, std::string>> *items, bool *is_loaded);
#endif//__ITEM_DB_LOADER_INCLUDED__ #endif//__ITEM_DB_LOADER_INCLUDED__

View File

@ -15,7 +15,7 @@
License along with the Goldberg Emulator; if not, see License along with the Goldberg Emulator; if not, see
<http://www.gnu.org/licenses/>. */ <http://www.gnu.org/licenses/>. */
#include "item_db_loader.h" #include "item_db_loader.h"
struct Steam_Inventory_Requests { struct Steam_Inventory_Requests {
double timeout = 0.1; double timeout = 0.1;
@ -57,6 +57,8 @@ class Steam_Inventory :
// Or find a server somewhere to hold the data for us then cache on local settings. // Or find a server somewhere to hold the data for us then cache on local settings.
bool need_load_definitions = true; bool need_load_definitions = true;
bool items_loaded = false;
struct Steam_Inventory_Requests* new_inventory_result(const SteamItemInstanceID_t* pInstanceIDs = NULL, uint32 unCountInstanceIDs = 0) struct Steam_Inventory_Requests* new_inventory_result(const SteamItemInstanceID_t* pInstanceIDs = NULL, uint32 unCountInstanceIDs = 0)
{ {
static SteamInventoryResult_t result; static SteamInventoryResult_t result;
@ -86,9 +88,11 @@ struct Steam_Inventory_Requests *get_inventory_result(SteamInventoryResult_t res
public: public:
Steam_Inventory(class Settings *settings, class SteamCallResults *callback_results, class SteamCallBacks *callbacks): Steam_Inventory(class Settings *settings, class SteamCallResults *callback_results, class SteamCallBacks *callbacks)
items(std::move(read_items_db(Local_Storage::get_program_path() + PATH_SEPARATOR + "steam_items.json")))
{ {
std::thread items_load_thread(read_items_db, Local_Storage::get_program_path() + PATH_SEPARATOR + "steam_items.json", &items, &items_loaded);
items_load_thread.detach();
this->settings = settings; this->settings = settings;
this->callbacks = callbacks; this->callbacks = callbacks;
this->callback_results = callback_results; this->callback_results = callback_results;
@ -230,8 +234,21 @@ bool GetAllItems( SteamInventoryResult_t *pResultHandle )
{ {
PRINT_DEBUG("GetAllItems\n"); PRINT_DEBUG("GetAllItems\n");
std::lock_guard<std::recursive_mutex> lock(global_mutex); std::lock_guard<std::recursive_mutex> lock(global_mutex);
if (pResultHandle) { struct Steam_Inventory_Requests* request = new_inventory_result();
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 // SteamInventoryFullUpdate_t callbacks are triggered when GetAllItems
// successfully returns a result which is newer / fresher than the last // successfully returns a result which is newer / fresher than the last
@ -248,22 +265,21 @@ bool GetAllItems( SteamInventoryResult_t *pResultHandle )
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout); callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout);
} }
*pResultHandle = request->inventory_result; if (pResultHandle != nullptr)
return true; *pResultHandle = request->inventory_result;
} }
else else
{ {
//Steam_Client::RegisterCallback : SteamInventoryResultReady_t
//Steam_Client::RegisterCallback : SteamInventoryDefinitionUpdate_t
//Steam_Client::RegisterCallback : DownloadItemResult_t
struct Steam_Inventory_Requests* request = new_inventory_result();
struct SteamInventoryResultReady_t data; struct SteamInventoryResultReady_t data;
data.m_handle = request->inventory_result; data.m_handle = request->inventory_result;
data.m_result = k_EResultOK; data.m_result = k_EResultPending;
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout); callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout);
if (pResultHandle != nullptr)
*pResultHandle = request->inventory_result;
} }
return false; return true;
} }
@ -526,9 +542,27 @@ bool LoadItemDefinitions()
if (need_load_definitions) if (need_load_definitions)
{ {
need_load_definitions = false; if (!items_loaded)
SteamInventoryDefinitionUpdate_t data; {
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data)); 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));
}
}
} }
return true; return true;
@ -592,17 +626,25 @@ bool GetItemDefinitionProperty( SteamItemDef_t iDefinition, const char *pchPrope
{ {
std::string const& val = attr->second; std::string const& val = attr->second;
if (pchValueBuffer != nullptr) if (pchValueBuffer != nullptr)
{
// copy what we can // copy what we can
strncpy(pchValueBuffer, val.c_str(), *punValueBufferSizeOut); strncpy(pchValueBuffer, val.c_str(), *punValueBufferSizeOut);
}
// Set punValueBufferSizeOut to the property size // Set punValueBufferSizeOut to the property size
*punValueBufferSizeOut = val.length() + 1; *punValueBufferSizeOut = std::min(static_cast<uint32>(val.length() + 1), *punValueBufferSizeOut);
if (pchValueBuffer != nullptr)
{
// Make sure we have a null terminator
pchValueBuffer[*punValueBufferSizeOut-1] = '\0';
}
} }
// Property not found // Property not found
else else
{ {
*punValueBufferSizeOut = 0; *punValueBufferSizeOut = 0;
PRINT_DEBUG("Attr %s not found for item %d", pchPropertyName, iDefinition); PRINT_DEBUG("Attr %s not found for item %d\n", pchPropertyName, iDefinition);
} }
} }
else // Pass a NULL pointer for pchPropertyName to get a comma - separated list of available property names. else // Pass a NULL pointer for pchPropertyName to get a comma - separated list of available property names.
@ -617,17 +659,24 @@ bool GetItemDefinitionProperty( SteamItemDef_t iDefinition, const char *pchPrope
} }
else else
{ {
uint32_t len = *punValueBufferSizeOut; // strncat always add the null terminator, so remove 1 to the string length
uint32_t len = *punValueBufferSizeOut-1;
*punValueBufferSizeOut = 0;
memset(pchValueBuffer, 0, len); memset(pchValueBuffer, 0, len);
for( auto i = item->second.begin(); i != item->second.end() && len > 0; ++i ) for( auto i = item->second.begin(); i != item->second.end() && len > 0; ++i )
{ {
strncat(pchValueBuffer, i->first.c_str(), len); strncat(pchValueBuffer, i->first.c_str(), len);
len -= i->first.length(); // Count how many chars we copied
if (len <= 0) // Check if we reached the end of the buffer // Either the string length or the buffer size if its too small
break; uint32 x = std::min(len, static_cast<uint32>(i->first.length()));
*punValueBufferSizeOut += x;
len -= x;
if (std::distance(i, item->second.end()) != 1) // If this is not the last item, add a comma if (len && std::distance(i, item->second.end()) != 1) // If this is not the last item, add a comma
strncat(pchValueBuffer, ",", len--); strncat(pchValueBuffer, ",", len--);
// Always add 1, its a comma or the null terminator
++*punValueBufferSizeOut;
} }
} }
} }