mirror of
https://gitlab.com/Mr_Goldberg/goldberg_emulator.git
synced 2025-12-05 11:44:53 +01:00
Merge branch 'issue_#5' of https://gitlab.com/Nemirtingas/goldberg_emulator into inventory_pr
This commit is contained in:
commit
f56503fcd0
7 changed files with 21300 additions and 21 deletions
60
dll/item_db_loader.cpp
Normal file
60
dll/item_db_loader.cpp
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* Copyright (C) 2019 Nemirtingas (Maxime P)
|
||||
This file is part of the Goldberg Emulator
|
||||
|
||||
The Goldberg Emulator is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
The Goldberg Emulator is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the Goldberg Emulator; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
#include "item_db_loader.h"
|
||||
|
||||
#include <fstream>
|
||||
#include "../json/json.hpp"
|
||||
|
||||
void read_items_db(std::string items_db, std::map<SteamItemDef_t, std::map<std::string, std::string>> *items, std::atomic_bool *is_loadedb)
|
||||
{
|
||||
std::ifstream items_file(items_db);
|
||||
// If there is a file and we opened it
|
||||
if( items_file )
|
||||
{
|
||||
items_file.seekg(0, std::ios::end);
|
||||
size_t size = items_file.tellg();
|
||||
std::string buffer(size, '\0');
|
||||
items_file.seekg(0);
|
||||
// Read it entirely, if the .json file gets too big,
|
||||
// I should look into this and split reads into smaller parts.
|
||||
items_file.read(&buffer[0], size);
|
||||
items_file.close();
|
||||
|
||||
try
|
||||
{
|
||||
std::map<SteamItemDef_t, std::map<std::string, std::string>> tmp;
|
||||
nlohmann::json json = nlohmann::json::parse(buffer);
|
||||
|
||||
for (auto& i : json.items())
|
||||
{
|
||||
SteamItemDef_t key = std::stoi((*i).key());
|
||||
nlohmann::json& value = (*i).value();
|
||||
for (auto& j : value.items())
|
||||
{
|
||||
tmp[key][(*j).key()] = (*j).value();
|
||||
}
|
||||
}
|
||||
|
||||
items->swap(tmp);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
PRINT_DEBUG("Error while parsing json: %s", e.what());
|
||||
}
|
||||
}
|
||||
*is_loadedb = true;
|
||||
}
|
||||
24
dll/item_db_loader.h
Normal file
24
dll/item_db_loader.h
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
/* Copyright (C) 2019 Nemirtingas (Maxime P)
|
||||
This file is part of the Goldberg Emulator
|
||||
|
||||
The Goldberg Emulator is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 3 of the License, or (at your option) any later version.
|
||||
|
||||
The Goldberg Emulator is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with the Goldberg Emulator;*/
|
||||
#ifndef __ITEM_DB_LOADER_INCLUDED__
|
||||
#define __ITEM_DB_LOADER_INCLUDED__
|
||||
|
||||
#include "base.h" // For SteamItemDef_t
|
||||
|
||||
#include <atomic>
|
||||
void read_items_db(std::string items_db, std::map<SteamItemDef_t, std::map<std::string, std::string>> *items, std::atomic_bool *is_loaded);
|
||||
|
||||
#endif//__ITEM_DB_LOADER_INCLUDED__
|
||||
5
dll/steam_inventory.cpp
Normal file
5
dll/steam_inventory.cpp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
#include "steam_inventory.h"
|
||||
|
||||
std::once_flag Steam_Inventory::items_loading;
|
||||
std::atomic_bool Steam_Inventory::items_loaded(false);
|
||||
std::map<SteamItemDef_t, std::map<std::string, std::string>> Steam_Inventory::items;
|
||||
|
|
@ -15,7 +15,8 @@
|
|||
License along with the Goldberg Emulator; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "base.h"
|
||||
#include "item_db_loader.h"
|
||||
#include <thread>
|
||||
|
||||
struct Steam_Inventory_Requests {
|
||||
double timeout = 0.1;
|
||||
|
|
@ -34,11 +35,10 @@ struct Steam_Inventory_Requests {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
class Steam_Inventory :
|
||||
public ISteamInventory001,
|
||||
public ISteamInventory002,
|
||||
public ISteamInventory
|
||||
public ISteamInventory001,
|
||||
public ISteamInventory002,
|
||||
public ISteamInventory
|
||||
{
|
||||
class Settings *settings;
|
||||
class SteamCallResults *callback_results;
|
||||
|
|
@ -46,7 +46,21 @@ public ISteamInventory
|
|||
|
||||
std::vector<struct Steam_Inventory_Requests> inventory_requests;
|
||||
|
||||
struct Steam_Inventory_Requests *new_inventory_result(const SteamItemInstanceID_t *pInstanceIDs=NULL, uint32 unCountInstanceIDs=0)
|
||||
static std::once_flag items_loading;
|
||||
static std::atomic_bool items_loaded;
|
||||
static 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;
|
||||
|
||||
struct Steam_Inventory_Requests* new_inventory_result(const SteamItemInstanceID_t* pInstanceIDs = NULL, uint32 unCountInstanceIDs = 0)
|
||||
{
|
||||
static SteamInventoryResult_t result;
|
||||
++result;
|
||||
|
|
@ -77,6 +91,14 @@ public:
|
|||
|
||||
Steam_Inventory(class Settings *settings, class SteamCallResults *callback_results, class SteamCallBacks *callbacks)
|
||||
{
|
||||
std::call_once(items_loading, [&]()
|
||||
{
|
||||
std::string items_db_file(Local_Storage::get_game_settings_path() + "items.json");
|
||||
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();
|
||||
});
|
||||
|
||||
this->settings = settings;
|
||||
this->callbacks = callbacks;
|
||||
this->callback_results = callback_results;
|
||||
|
|
@ -122,7 +144,25 @@ bool GetResultItems( SteamInventoryResult_t resultHandle,
|
|||
if (!request) return false;
|
||||
if (!request->result_done()) return false;
|
||||
|
||||
if (punOutItemsArraySize) *punOutItemsArraySize = 0;
|
||||
if (pOutItemsArray != nullptr)
|
||||
{
|
||||
uint32 max_items = *punOutItemsArraySize;
|
||||
// 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 )
|
||||
{
|
||||
pOutItemsArray->m_iDefinition = i->first;
|
||||
pOutItemsArray->m_itemId = i->first;
|
||||
pOutItemsArray->m_unQuantity = 1;
|
||||
pOutItemsArray->m_unFlags = k_ESteamItemNoTrade;
|
||||
++pOutItemsArray;
|
||||
}
|
||||
*punOutItemsArraySize = std::min(*punOutItemsArraySize, static_cast<uint32>(items.size()));
|
||||
}
|
||||
else if (punOutItemsArraySize != nullptr)
|
||||
{
|
||||
*punOutItemsArraySize = items.size();
|
||||
}
|
||||
|
||||
PRINT_DEBUG("GetResultItems good\n");
|
||||
return true;
|
||||
}
|
||||
|
|
@ -206,8 +246,21 @@ bool GetAllItems( SteamInventoryResult_t *pResultHandle )
|
|||
{
|
||||
PRINT_DEBUG("GetAllItems\n");
|
||||
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
|
||||
// successfully returns a result which is newer / fresher than the last
|
||||
|
|
@ -224,11 +277,21 @@ bool GetAllItems( SteamInventoryResult_t *pResultHandle )
|
|||
callbacks->addCBResult(data.k_iCallback, &data, sizeof(data), request->timeout);
|
||||
}
|
||||
|
||||
*pResultHandle = request->inventory_result;
|
||||
return 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 false;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -488,6 +551,32 @@ 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -502,18 +591,24 @@ bool GetItemDefinitionIDs(
|
|||
STEAM_DESC(Size of array is passed in and actual size used is returned in this param) uint32 *punItemDefIDsArraySize )
|
||||
{
|
||||
PRINT_DEBUG("GetItemDefinitionIDs\n");
|
||||
if (!punItemDefIDsArraySize) {
|
||||
if (!punItemDefIDsArraySize)
|
||||
return false;
|
||||
}
|
||||
|
||||
PRINT_DEBUG("array_size %u\n", *punItemDefIDsArraySize);
|
||||
/*
|
||||
if (pItemDefIDs) {
|
||||
*pItemDefIDs = 0;
|
||||
|
||||
if (pItemDefIDs == nullptr)
|
||||
{
|
||||
*punItemDefIDsArraySize = items.size();
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
//*punItemDefIDsArraySize = 0;
|
||||
return false;
|
||||
|
||||
if (*punItemDefIDsArraySize < items.size())
|
||||
return false;
|
||||
|
||||
for (auto& i : items)
|
||||
*pItemDefIDs++ = i.first;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -530,6 +625,75 @@ bool GetItemDefinitionProperty( SteamItemDef_t iDefinition, const char *pchPrope
|
|||
STEAM_OUT_STRING_COUNT(punValueBufferSizeOut) char *pchValueBuffer, uint32 *punValueBufferSizeOut )
|
||||
{
|
||||
PRINT_DEBUG("GetItemDefinitionProperty\n");
|
||||
|
||||
item_iterator item;
|
||||
if ((item = items.find(iDefinition)) != items.end())
|
||||
{
|
||||
attr_iterator attr;
|
||||
if (pchPropertyName != nullptr)
|
||||
{
|
||||
// Should I check for punValueBufferSizeOut == nullptr ?
|
||||
// Try to get the property
|
||||
if ((attr = item->second.find(pchPropertyName)) != items[iDefinition].end())
|
||||
{
|
||||
std::string const& val = attr->second;
|
||||
if (pchValueBuffer != nullptr)
|
||||
{
|
||||
// copy what we can
|
||||
strncpy(pchValueBuffer, val.c_str(), *punValueBufferSizeOut);
|
||||
}
|
||||
|
||||
// Set punValueBufferSizeOut to the property size
|
||||
*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
|
||||
else
|
||||
{
|
||||
*punValueBufferSizeOut = 0;
|
||||
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.
|
||||
{
|
||||
// If pchValueBuffer is NULL, *punValueBufferSize will contain the suggested buffer size
|
||||
if (pchValueBuffer == nullptr)
|
||||
{
|
||||
// Should I check for punValueBufferSizeOut == nullptr ?
|
||||
*punValueBufferSizeOut = 0;
|
||||
for (auto& i : item->second)
|
||||
*punValueBufferSizeOut += i.first.length() + 1; // Size of key + comma, and the last is not a comma but null char
|
||||
}
|
||||
else
|
||||
{
|
||||
// strncat always add the null terminator, so remove 1 to the string length
|
||||
uint32_t len = *punValueBufferSizeOut-1;
|
||||
*punValueBufferSizeOut = 0;
|
||||
memset(pchValueBuffer, 0, len);
|
||||
for( auto i = item->second.begin(); i != item->second.end() && len > 0; ++i )
|
||||
{
|
||||
strncat(pchValueBuffer, i->first.c_str(), len);
|
||||
// Count how many chars we copied
|
||||
// Either the string length or the buffer size if its too small
|
||||
uint32 x = std::min(len, static_cast<uint32>(i->first.length()));
|
||||
*punValueBufferSizeOut += x;
|
||||
len -= x;
|
||||
|
||||
if (len && std::distance(i, item->second.end()) != 1) // If this is not the last item, add a comma
|
||||
strncat(pchValueBuffer, ",", len--);
|
||||
|
||||
// Always add 1, its a comma or the null terminator
|
||||
++*punValueBufferSizeOut;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -653,4 +817,4 @@ bool SubmitUpdateProperties( SteamInventoryUpdateHandle_t handle, SteamInventory
|
|||
PRINT_DEBUG("SubmitUpdateProperties\n");
|
||||
}
|
||||
|
||||
};
|
||||
};
|
||||
Loading…
Add table
Add a link
Reference in a new issue