mirror of
https://gitlab.com/Mr_Goldberg/goldberg_emulator.git
synced 2024-11-23 20:38:07 +01:00
Achievements support & inventory customization.
Added achievements support. Achievements are saved like real steam, see your inventory directory.(like items, uses a .json, tool can be used to dump achievements from steam public api). You will need a public apikey. (See https://steamcommunity.com/dev) Reworked item support to split inventory items to defined items.
This commit is contained in:
parent
46f2199cd2
commit
21e08ed220
9 changed files with 365 additions and 302 deletions
|
@ -1,62 +0,0 @@
|
|||
/* 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\n", e.what());
|
||||
}
|
||||
}
|
||||
|
||||
PRINT_DEBUG("Loaded json. Loaded %u items.\n", items->size());
|
||||
*is_loadedb = true;
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
/* 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__
|
|
@ -20,6 +20,7 @@
|
|||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <iomanip>
|
||||
|
||||
struct File_Data {
|
||||
std::string name;
|
||||
|
@ -52,6 +53,11 @@ std::string Local_Storage::get_global_settings_path()
|
|||
return "";
|
||||
}
|
||||
|
||||
std::string Local_Storage::get_global_inventory_path()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
Local_Storage::Local_Storage(std::string save_directory)
|
||||
{
|
||||
|
||||
|
@ -127,6 +133,16 @@ bool Local_Storage::update_save_filenames(std::string folder)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Local_Storage::load_inventory_file(nlohmann::json& json, std::string const&file)
|
||||
{
|
||||
return true
|
||||
}
|
||||
|
||||
bool Local_Storage::write_inventory_file(nlohmann::json const& json, std::string const&file)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> Local_Storage::get_filenames_path(std::string path)
|
||||
{
|
||||
return std::vector<std::string>();
|
||||
|
@ -378,7 +394,7 @@ std::string Local_Storage::get_program_path()
|
|||
|
||||
std::string Local_Storage::get_game_settings_path()
|
||||
{
|
||||
return get_program_path().append(GAME_SETTINGS_FOLDER).append(PATH_SEPARATOR);
|
||||
return get_program_path().append(game_settings_folder).append(PATH_SEPARATOR);
|
||||
}
|
||||
|
||||
#if defined(STEAM_WIN32)
|
||||
|
@ -508,7 +524,12 @@ std::string Local_Storage::get_path(std::string folder)
|
|||
|
||||
std::string Local_Storage::get_global_settings_path()
|
||||
{
|
||||
return save_directory + SETTINGS_STORAGE_FOLDER + PATH_SEPARATOR;
|
||||
return save_directory + settings_storage_folder + PATH_SEPARATOR;
|
||||
}
|
||||
|
||||
std::string Local_Storage::get_global_inventory_path()
|
||||
{
|
||||
return save_directory + inventory_storage_folder + PATH_SEPARATOR;
|
||||
}
|
||||
|
||||
std::vector<std::string> Local_Storage::get_filenames_path(std::string path)
|
||||
|
@ -680,4 +701,54 @@ bool Local_Storage::update_save_filenames(std::string folder)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool Local_Storage::load_inventory_file(nlohmann::json& json, std::string const&file)
|
||||
{
|
||||
std::string inv_path = std::move(get_global_inventory_path() + appid + file);
|
||||
std::ifstream inventory_file(inv_path);
|
||||
// If there is a file and we opened it
|
||||
if (inventory_file)
|
||||
{
|
||||
inventory_file.seekg(0, std::ios::end);
|
||||
size_t size = inventory_file.tellg();
|
||||
std::string buffer(size, '\0');
|
||||
inventory_file.seekg(0);
|
||||
// Read it entirely, if the .json file gets too big,
|
||||
// I should look into this and split reads into smaller parts.
|
||||
inventory_file.read(&buffer[0], size);
|
||||
inventory_file.close();
|
||||
|
||||
try {
|
||||
json = std::move(nlohmann::json::parse(buffer));
|
||||
PRINT_DEBUG("Loaded inventory \"%s\". Loaded %u items.\n", inv_path.c_str(), json.size());
|
||||
return true;
|
||||
} catch (std::exception& e) {
|
||||
PRINT_DEBUG("Error while parsing \"%s\" inventory json: %s\n", inv_path.c_str(), e.what());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT_DEBUG("Couldn't open file \"%s\" to read inventory\n", inv_path.c_str());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Local_Storage::write_inventory_file(nlohmann::json const& json, std::string const&file)
|
||||
{
|
||||
std::string inv_path = std::move(get_global_inventory_path() + appid);
|
||||
|
||||
create_directory(inv_path);
|
||||
|
||||
std::ofstream inventory_file(inv_path + file, std::ios::trunc | std::ios::out);
|
||||
if (inventory_file)
|
||||
{
|
||||
inventory_file << std::setw(2) << json;
|
||||
return true;
|
||||
}
|
||||
|
||||
PRINT_DEBUG("Couldn't open file \"%s\" to write inventory\n", inv_path.c_str());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -21,18 +21,21 @@
|
|||
#ifndef LOCAL_STORAGE_INCLUDE
|
||||
#define LOCAL_STORAGE_INCLUDE
|
||||
|
||||
#define SETTINGS_STORAGE_FOLDER "settings"
|
||||
#define REMOTE_STORAGE_FOLDER "remote"
|
||||
#define STATS_STORAGE_FOLDER "stats"
|
||||
#define USER_DATA_FOLDER "local"
|
||||
|
||||
#define GAME_SETTINGS_FOLDER "steam_settings"
|
||||
|
||||
#include <string>
|
||||
#include "../json/json.hpp"
|
||||
|
||||
#define MAX_FILENAME_LENGTH 300
|
||||
|
||||
class Local_Storage {
|
||||
public:
|
||||
static constexpr auto inventory_storage_folder = "inventory";
|
||||
static constexpr auto settings_storage_folder = "settings";
|
||||
static constexpr auto remote_storage_folder = "remote";
|
||||
static constexpr auto stats_storage_folder = "stats";
|
||||
static constexpr auto user_data_storage = "local";
|
||||
static constexpr auto game_settings_folder = "steam_settings";
|
||||
|
||||
private:
|
||||
std::string save_directory;
|
||||
std::string appid;
|
||||
public:
|
||||
|
@ -56,9 +59,13 @@ public:
|
|||
bool file_delete(std::string folder, std::string file);
|
||||
uint64_t file_timestamp(std::string folder, std::string file);
|
||||
std::string get_global_settings_path();
|
||||
std::string get_global_inventory_path();
|
||||
std::string get_path(std::string folder);
|
||||
|
||||
bool update_save_filenames(std::string folder);
|
||||
|
||||
bool load_inventory_file(nlohmann::json &json, std::string const&file);
|
||||
bool write_inventory_file(nlohmann::json const& json, std::string const&file);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -162,7 +162,7 @@ Steam_Client::Steam_Client()
|
|||
uint64 steam_id = 0;
|
||||
bool generate_new = false;
|
||||
//try to load steam id from game specific settings folder first
|
||||
if (local_storage->get_data(SETTINGS_STORAGE_FOLDER, "user_steam_id.txt", array_steam_id, sizeof(array_steam_id) - 1) > 0) {
|
||||
if (local_storage->get_data(Local_Storage::settings_storage_folder, "user_steam_id.txt", array_steam_id, sizeof(array_steam_id) - 1) > 0) {
|
||||
user_id = CSteamID((uint64)std::atoll(array_steam_id));
|
||||
if (!user_id.IsValid()) {
|
||||
generate_new = true;
|
||||
|
@ -335,9 +335,6 @@ Steam_Client::Steam_Client()
|
|||
}
|
||||
}
|
||||
|
||||
std::string achievements_db_file_path = (Local_Storage::get_game_settings_path() + "achievements.json");
|
||||
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();
|
||||
|
@ -353,7 +350,7 @@ Steam_Client::Steam_Client()
|
|||
steam_utils = new Steam_Utils(settings_client, callback_results_client);
|
||||
steam_matchmaking = new Steam_Matchmaking(settings_client, network, callback_results_client, callbacks_client, run_every_runcb);
|
||||
steam_matchmaking_servers = new Steam_Matchmaking_Servers(settings_client, network);
|
||||
steam_user_stats = new Steam_User_Stats(settings_client, local_storage, callback_results_client, callbacks_client, achievements_db_file_path);
|
||||
steam_user_stats = new Steam_User_Stats(settings_client, local_storage, callback_results_client, callbacks_client);
|
||||
steam_apps = new Steam_Apps(settings_client, callback_results_client);
|
||||
steam_networking = new Steam_Networking(settings_client, network, callbacks_client, run_every_runcb);
|
||||
steam_remote_storage = new Steam_Remote_Storage(settings_client, local_storage, callback_results_client);
|
||||
|
@ -365,7 +362,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, run_every_runcb, items_db_file_path);
|
||||
steam_inventory = new Steam_Inventory(settings_client, callback_results_client, callbacks_client, run_every_runcb, local_storage);
|
||||
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);
|
||||
|
@ -383,7 +380,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, run_every_runcb, items_db_file_path);
|
||||
steam_gameserver_inventory = new Steam_Inventory(settings_server, callback_results_server, callbacks_server, run_every_runcb, local_storage);
|
||||
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);
|
||||
|
|
|
@ -15,8 +15,8 @@
|
|||
License along with the Goldberg Emulator; if not, see
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include "item_db_loader.h"
|
||||
#include <thread>
|
||||
#include "base.h" // For SteamItemDef_t
|
||||
#include "../json/json.hpp"
|
||||
|
||||
struct Steam_Inventory_Requests {
|
||||
double timeout = 0.1;
|
||||
|
@ -42,22 +42,24 @@ class Steam_Inventory :
|
|||
public ISteamInventory002,
|
||||
public ISteamInventory
|
||||
{
|
||||
public:
|
||||
static constexpr auto items_user_file = "items.json";
|
||||
|
||||
private:
|
||||
class Settings *settings;
|
||||
class SteamCallResults *callback_results;
|
||||
class SteamCallBacks *callbacks;
|
||||
class RunEveryRunCB *run_every_runcb;
|
||||
class Local_Storage* local_storage;
|
||||
|
||||
std::vector<struct Steam_Inventory_Requests> inventory_requests;
|
||||
|
||||
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;
|
||||
nlohmann::json defined_items;
|
||||
nlohmann::json user_items;
|
||||
|
||||
std::atomic_bool items_loaded;
|
||||
std::string items_db_file;
|
||||
std::once_flag load_items_flag;
|
||||
bool inventory_loaded;
|
||||
bool call_definition_update;
|
||||
bool call_inventory_update;
|
||||
bool definition_update_called;
|
||||
bool full_update_called;
|
||||
|
||||
|
@ -89,6 +91,40 @@ struct Steam_Inventory_Requests *get_inventory_result(SteamInventoryResult_t res
|
|||
return &(*request);
|
||||
}
|
||||
|
||||
void read_items_db()
|
||||
{
|
||||
std::string items_db_path = Local_Storage::get_game_settings_path() + items_user_file;
|
||||
PRINT_DEBUG("Items file path: %s\n", items_db_path.c_str());
|
||||
std::ifstream inventory_file(items_db_path);
|
||||
// If there is a file and we opened it
|
||||
if (inventory_file)
|
||||
{
|
||||
inventory_file.seekg(0, std::ios::end);
|
||||
size_t size = inventory_file.tellg();
|
||||
std::string buffer(size, '\0');
|
||||
inventory_file.seekg(0);
|
||||
// Read it entirely, if the .json file gets too big,
|
||||
// I should look into this and split reads into smaller parts.
|
||||
inventory_file.read(&buffer[0], size);
|
||||
inventory_file.close();
|
||||
|
||||
try
|
||||
{
|
||||
defined_items = std::move(nlohmann::json::parse(buffer));
|
||||
PRINT_DEBUG("Loaded inventory. Loaded %u items.\n", defined_items.size());
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
PRINT_DEBUG("Error while parsing inventory json: %s\n", e.what());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void read_inventory_db()
|
||||
{
|
||||
local_storage->load_inventory_file(user_items, items_user_file);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static void run_every_runcb_cb(void *object)
|
||||
|
@ -99,21 +135,21 @@ static void run_every_runcb_cb(void *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)
|
||||
Steam_Inventory(class Settings *settings, class SteamCallResults *callback_results, class SteamCallBacks *callbacks, class RunEveryRunCB *run_every_runcb, class Local_Storage *local_storage):
|
||||
settings(settings),
|
||||
callback_results(callback_results),
|
||||
callbacks(callbacks),
|
||||
run_every_runcb(run_every_runcb),
|
||||
local_storage(local_storage),
|
||||
defined_items(nlohmann::json::object()),
|
||||
user_items(nlohmann::json::object()),
|
||||
inventory_loaded(false),
|
||||
call_definition_update(false),
|
||||
call_inventory_update(false),
|
||||
definition_update_called(false),
|
||||
full_update_called(false)
|
||||
{
|
||||
items_db_file = items_db_file_path;
|
||||
PRINT_DEBUG("Items file path: %s\n", items_db_file.c_str());
|
||||
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()
|
||||
|
@ -160,6 +196,7 @@ bool GetResultItems( SteamInventoryResult_t resultHandle,
|
|||
struct Steam_Inventory_Requests *request = get_inventory_result(resultHandle);
|
||||
if (!request) return false;
|
||||
if (!request->result_done()) return false;
|
||||
if (!inventory_loaded) return false;
|
||||
|
||||
if (pOutItemsArray != nullptr)
|
||||
{
|
||||
|
@ -167,21 +204,35 @@ bool GetResultItems( SteamInventoryResult_t resultHandle,
|
|||
|
||||
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 )
|
||||
for( auto i = user_items.begin(); i != user_items.end() && max_items; ++i, --max_items )
|
||||
{
|
||||
pOutItemsArray->m_iDefinition = i->first;
|
||||
pOutItemsArray->m_itemId = i->first;
|
||||
pOutItemsArray->m_unQuantity = 1;
|
||||
pOutItemsArray->m_iDefinition = std::stoi(i.key());
|
||||
pOutItemsArray->m_itemId = pOutItemsArray->m_iDefinition;
|
||||
try
|
||||
{
|
||||
pOutItemsArray->m_unQuantity = i.value().get<int>();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
pOutItemsArray->m_unQuantity = 0;
|
||||
}
|
||||
pOutItemsArray->m_unFlags = k_ESteamItemNoTrade;
|
||||
++pOutItemsArray;
|
||||
}
|
||||
*punOutItemsArraySize = std::min(*punOutItemsArraySize, static_cast<uint32>(items.size()));
|
||||
*punOutItemsArraySize = std::min(*punOutItemsArraySize, static_cast<uint32>(user_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;
|
||||
try
|
||||
{
|
||||
pOutItemsArray->m_unQuantity = user_items[itemid].get<int>();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
pOutItemsArray->m_unQuantity = 0;
|
||||
}
|
||||
pOutItemsArray->m_unFlags = k_ESteamItemNoTrade;
|
||||
++pOutItemsArray;
|
||||
--max_items;
|
||||
|
@ -190,7 +241,7 @@ bool GetResultItems( SteamInventoryResult_t resultHandle,
|
|||
}
|
||||
else if (punOutItemsArraySize != nullptr)
|
||||
{
|
||||
*punOutItemsArraySize = items.size();
|
||||
*punOutItemsArraySize = user_items.size();
|
||||
}
|
||||
|
||||
PRINT_DEBUG("GetResultItems good\n");
|
||||
|
@ -278,7 +329,7 @@ bool GetAllItems( SteamInventoryResult_t *pResultHandle )
|
|||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
struct Steam_Inventory_Requests* request = new_inventory_result();
|
||||
|
||||
if (!definition_update_called) call_definition_update = true;
|
||||
call_inventory_update = true;
|
||||
|
||||
if (pResultHandle != nullptr)
|
||||
*pResultHandle = request->inventory_result;
|
||||
|
@ -302,6 +353,7 @@ bool GetItemsByID( SteamInventoryResult_t *pResultHandle, STEAM_ARRAY_COUNT( unC
|
|||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
if (pResultHandle) {
|
||||
struct Steam_Inventory_Requests *request = new_inventory_result(false, pInstanceIDs, unCountInstanceIDs);
|
||||
//call_inventory_update = true;
|
||||
*pResultHandle = request->inventory_result;
|
||||
return true;
|
||||
}
|
||||
|
@ -559,15 +611,15 @@ bool GetItemDefinitionIDs(
|
|||
|
||||
if (pItemDefIDs == nullptr)
|
||||
{
|
||||
*punItemDefIDsArraySize = items.size();
|
||||
*punItemDefIDsArraySize = defined_items.size();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (*punItemDefIDsArraySize < items.size())
|
||||
if (*punItemDefIDsArraySize < defined_items.size())
|
||||
return false;
|
||||
|
||||
for (auto& i : items)
|
||||
*pItemDefIDs++ = i.first;
|
||||
for (auto i = defined_items.begin(); i != defined_items.end(); ++i)
|
||||
*pItemDefIDs++ = std::stoi(i.key());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -588,25 +640,38 @@ bool GetItemDefinitionProperty( SteamItemDef_t iDefinition, const char *pchPrope
|
|||
PRINT_DEBUG("GetItemDefinitionProperty %i %s\n", iDefinition, pchPropertyName);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
item_iterator item;
|
||||
if ((item = items.find(iDefinition)) != items.end())
|
||||
auto item = defined_items.find(std::to_string(iDefinition));
|
||||
if (item != defined_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())
|
||||
auto attr = item.value().find(pchPropertyName);
|
||||
if (attr != item.value().end())
|
||||
{
|
||||
std::string const& val = attr->second;
|
||||
std::string val;
|
||||
try
|
||||
{
|
||||
val = attr.value().get<std::string>();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
pchPropertyName = "";
|
||||
*punValueBufferSizeOut = 0;
|
||||
PRINT_DEBUG("Error, item: %d, attr: %s is not a string!", iDefinition, pchPropertyName);
|
||||
return true;
|
||||
}
|
||||
if (pchValueBuffer != nullptr)
|
||||
{
|
||||
// copy what we can
|
||||
strncpy(pchValueBuffer, val.c_str(), *punValueBufferSizeOut);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Set punValueBufferSizeOut to the property size
|
||||
*punValueBufferSizeOut = std::min(static_cast<uint32>(val.length() + 1), *punValueBufferSizeOut);
|
||||
*punValueBufferSizeOut = val.length() + 1;
|
||||
}
|
||||
|
||||
if (pchValueBuffer != nullptr)
|
||||
{
|
||||
|
@ -628,8 +693,8 @@ bool GetItemDefinitionProperty( SteamItemDef_t iDefinition, const char *pchPrope
|
|||
{
|
||||
// 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
|
||||
for (auto i = item.value().begin(); i != item.value().end(); ++i)
|
||||
*punValueBufferSizeOut += i.key().length() + 1; // Size of key + comma, and the last is not a comma but null char
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -637,16 +702,16 @@ bool GetItemDefinitionProperty( SteamItemDef_t iDefinition, const char *pchPrope
|
|||
uint32_t len = *punValueBufferSizeOut-1;
|
||||
*punValueBufferSizeOut = 0;
|
||||
memset(pchValueBuffer, 0, len);
|
||||
for( auto i = item->second.begin(); i != item->second.end() && len > 0; ++i )
|
||||
for( auto i = item.value().begin(); i != item.value().end() && len > 0; ++i )
|
||||
{
|
||||
strncat(pchValueBuffer, i->first.c_str(), len);
|
||||
strncat(pchValueBuffer, i.key().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()));
|
||||
uint32 x = std::min(len, static_cast<uint32>(i.key().length()));
|
||||
*punValueBufferSizeOut += x;
|
||||
len -= x;
|
||||
|
||||
if (len && std::distance(i, item->second.end()) != 1) // If this is not the last item, add a comma
|
||||
if (len && std::distance(i, item.value().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
|
||||
|
@ -781,24 +846,26 @@ bool SubmitUpdateProperties( SteamInventoryUpdateHandle_t handle, SteamInventory
|
|||
|
||||
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) {
|
||||
read_items_db();
|
||||
definition_update_called = true;
|
||||
|
||||
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();
|
||||
if (call_inventory_update) {
|
||||
read_inventory_db();
|
||||
inventory_loaded = true;
|
||||
|
||||
for (auto & r : inventory_requests) {
|
||||
call_inventory_update = false;
|
||||
}
|
||||
|
||||
if (definition_update_called && inventory_loaded)
|
||||
{
|
||||
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) {
|
||||
|
|
|
@ -69,7 +69,7 @@ Steam_Remote_Storage(class Settings *settings, Local_Storage *local_storage, cla
|
|||
this->local_storage = local_storage;
|
||||
this->callback_results = callback_results;
|
||||
steam_cloud_enabled = true;
|
||||
local_storage->update_save_filenames(REMOTE_STORAGE_FOLDER);
|
||||
local_storage->update_save_filenames(Local_Storage::remote_storage_folder);
|
||||
}
|
||||
|
||||
// NOTE
|
||||
|
@ -84,7 +84,7 @@ bool FileWrite( const char *pchFile, const void *pvData, int32 cubData )
|
|||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::FileWrite %s %u\n", pchFile, cubData);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
int data_stored = local_storage->store_data(REMOTE_STORAGE_FOLDER, pchFile, (char* )pvData, cubData);
|
||||
int data_stored = local_storage->store_data(Local_Storage::remote_storage_folder, pchFile, (char* )pvData, cubData);
|
||||
PRINT_DEBUG("Steam_Remote_Storage::Stored %i, %u\n", data_stored, data_stored == cubData);
|
||||
return data_stored == cubData;
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ int32 FileRead( const char *pchFile, void *pvData, int32 cubDataToRead )
|
|||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::FileRead %s %i\n", pchFile, cubDataToRead);
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
int read_data = local_storage->get_data(REMOTE_STORAGE_FOLDER, pchFile, (char* )pvData, cubDataToRead);
|
||||
int read_data = local_storage->get_data(Local_Storage::remote_storage_folder, pchFile, (char* )pvData, cubDataToRead);
|
||||
if (read_data < 0) read_data = 0;
|
||||
PRINT_DEBUG("Read %i\n", read_data);
|
||||
return read_data;
|
||||
|
@ -104,7 +104,7 @@ SteamAPICall_t FileWriteAsync( const char *pchFile, const void *pvData, uint32 c
|
|||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::FileWriteAsync\n");
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
bool success = local_storage->store_data(REMOTE_STORAGE_FOLDER, pchFile, (char* )pvData, cubData) == cubData;
|
||||
bool success = local_storage->store_data(Local_Storage::remote_storage_folder, pchFile, (char* )pvData, cubData) == cubData;
|
||||
RemoteStorageFileWriteAsyncComplete_t data;
|
||||
data.m_eResult = k_EResultOK;
|
||||
|
||||
|
@ -118,7 +118,7 @@ SteamAPICall_t FileReadAsync( const char *pchFile, uint32 nOffset, uint32 cubToR
|
|||
PRINT_DEBUG("Steam_Remote_Storage::FileReadAsync\n");
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
unsigned int size = local_storage->file_size(REMOTE_STORAGE_FOLDER, pchFile);
|
||||
unsigned int size = local_storage->file_size(Local_Storage::remote_storage_folder, pchFile);
|
||||
|
||||
RemoteStorageFileReadAsyncComplete_t data;
|
||||
if (size <= nOffset) {
|
||||
|
@ -153,7 +153,7 @@ bool FileReadAsyncComplete( SteamAPICall_t hReadCall, void *pvBuffer, uint32 cub
|
|||
return false;
|
||||
|
||||
char *temp = new char[a_read->size];
|
||||
int read_data = local_storage->get_data(REMOTE_STORAGE_FOLDER, a_read->file_name, (char* )temp, a_read->size);
|
||||
int read_data = local_storage->get_data(Local_Storage::remote_storage_folder, a_read->file_name, (char* )temp, a_read->size);
|
||||
if (read_data < a_read->to_read + a_read->offset) {
|
||||
delete[] temp;
|
||||
return false;
|
||||
|
@ -175,7 +175,7 @@ bool FileForget( const char *pchFile )
|
|||
bool FileDelete( const char *pchFile )
|
||||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::FileDelete\n");
|
||||
return local_storage->file_delete(REMOTE_STORAGE_FOLDER, pchFile);
|
||||
return local_storage->file_delete(Local_Storage::remote_storage_folder, pchFile);
|
||||
}
|
||||
|
||||
STEAM_CALL_RESULT( RemoteStorageFileShareResult_t )
|
||||
|
@ -184,7 +184,7 @@ SteamAPICall_t FileShare( const char *pchFile )
|
|||
PRINT_DEBUG("Steam_Remote_Storage::FileShare\n");
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
RemoteStorageFileShareResult_t data = {};
|
||||
if (local_storage->file_exists(REMOTE_STORAGE_FOLDER, pchFile)) {
|
||||
if (local_storage->file_exists(Local_Storage::remote_storage_folder, pchFile)) {
|
||||
data.m_eResult = k_EResultOK;
|
||||
data.m_hFile = generate_steam_api_call_id();
|
||||
strncpy(data.m_rgchFilename, pchFile, sizeof(data.m_rgchFilename) - 1);
|
||||
|
@ -237,7 +237,7 @@ bool FileWriteStreamClose( UGCFileWriteStreamHandle_t writeHandle )
|
|||
if (stream_writes.end() == request)
|
||||
return false;
|
||||
|
||||
local_storage->store_data(REMOTE_STORAGE_FOLDER, request->file_name, request->file_data.data(), request->file_data.size());
|
||||
local_storage->store_data(Local_Storage::remote_storage_folder, request->file_name, request->file_data.data(), request->file_data.size());
|
||||
stream_writes.erase(request);
|
||||
return true;
|
||||
}
|
||||
|
@ -258,25 +258,25 @@ bool FileWriteStreamCancel( UGCFileWriteStreamHandle_t writeHandle )
|
|||
bool FileExists( const char *pchFile )
|
||||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::FileExists %s\n", pchFile);
|
||||
return local_storage->file_exists(REMOTE_STORAGE_FOLDER, pchFile);
|
||||
return local_storage->file_exists(Local_Storage::remote_storage_folder, pchFile);
|
||||
}
|
||||
|
||||
bool FilePersisted( const char *pchFile )
|
||||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::FilePersisted\n");
|
||||
return local_storage->file_exists(REMOTE_STORAGE_FOLDER, pchFile);
|
||||
return local_storage->file_exists(Local_Storage::remote_storage_folder, pchFile);
|
||||
}
|
||||
|
||||
int32 GetFileSize( const char *pchFile )
|
||||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::GetFileSize %s\n", pchFile);
|
||||
return local_storage->file_size(REMOTE_STORAGE_FOLDER, pchFile);
|
||||
return local_storage->file_size(Local_Storage::remote_storage_folder, pchFile);
|
||||
}
|
||||
|
||||
int64 GetFileTimestamp( const char *pchFile )
|
||||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::GetFileTimestamp\n");
|
||||
return local_storage->file_timestamp(REMOTE_STORAGE_FOLDER, pchFile);
|
||||
return local_storage->file_timestamp(Local_Storage::remote_storage_folder, pchFile);
|
||||
}
|
||||
|
||||
ERemoteStoragePlatform GetSyncPlatforms( const char *pchFile )
|
||||
|
@ -290,7 +290,7 @@ ERemoteStoragePlatform GetSyncPlatforms( const char *pchFile )
|
|||
int32 GetFileCount()
|
||||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::GetFileCount\n");
|
||||
int32 num = local_storage->count_files(REMOTE_STORAGE_FOLDER);
|
||||
int32 num = local_storage->count_files(Local_Storage::remote_storage_folder);
|
||||
PRINT_DEBUG("Steam_Remote_Storage::File count: %i\n", num);
|
||||
return num;
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ const char *GetFileNameAndSize( int iFile, int32 *pnFileSizeInBytes )
|
|||
{
|
||||
PRINT_DEBUG("Steam_Remote_Storage::GetFileNameAndSize %i\n", iFile);
|
||||
static char output_filename[MAX_FILENAME_LENGTH];
|
||||
if (local_storage->iterate_file(REMOTE_STORAGE_FOLDER, iFile, output_filename, pnFileSizeInBytes)) {
|
||||
if (local_storage->iterate_file(Local_Storage::remote_storage_folder, iFile, output_filename, pnFileSizeInBytes)) {
|
||||
PRINT_DEBUG("Steam_Remote_Storage::Name: |%s|, size: %i\n", output_filename, pnFileSizeInBytes ? *pnFileSizeInBytes : 0);
|
||||
return output_filename;
|
||||
} else {
|
||||
|
@ -372,7 +372,7 @@ SteamAPICall_t UGCDownload( UGCHandle_t hContent, uint32 unPriority )
|
|||
data.m_eResult = k_EResultOK;
|
||||
data.m_hFile = hContent;
|
||||
data.m_nAppID = settings->get_local_game_id().AppID();
|
||||
data.m_nSizeInBytes = local_storage->file_size(REMOTE_STORAGE_FOLDER, shared_files[hContent]);
|
||||
data.m_nSizeInBytes = local_storage->file_size(Local_Storage::remote_storage_folder, shared_files[hContent]);
|
||||
shared_files[hContent].copy(data.m_pchFileName, sizeof(data.m_pchFileName) - 1);
|
||||
data.m_ulSteamIDOwner = settings->get_local_steam_id().ConvertToUint64();
|
||||
downloaded_files[hContent].file = shared_files[hContent];
|
||||
|
@ -426,7 +426,7 @@ int32 UGCRead( UGCHandle_t hContent, void *pvData, int32 cubDataToRead, uint32 c
|
|||
}
|
||||
|
||||
Downloaded_File f = downloaded_files[hContent];
|
||||
int read_data = local_storage->get_data(REMOTE_STORAGE_FOLDER, f.file, (char* )pvData, cubDataToRead, cOffset);
|
||||
int read_data = local_storage->get_data(Local_Storage::remote_storage_folder, f.file, (char* )pvData, cubDataToRead, cOffset);
|
||||
|
||||
if (eAction == k_EUGCRead_Close || (eAction == k_EUGCRead_ContinueReadingUntilFinished && (read_data < cubDataToRead || (cOffset + cubDataToRead) >= f.total_size))) {
|
||||
downloaded_files.erase(hContent);
|
||||
|
|
|
@ -149,7 +149,7 @@ bool GetUserDataFolder( char *pchBuffer, int cubBuffer )
|
|||
PRINT_DEBUG("GetUserDataFolder\n");
|
||||
if (!cubBuffer) return false;
|
||||
|
||||
std::string user_data = local_storage->get_path(USER_DATA_FOLDER);
|
||||
std::string user_data = local_storage->get_path(Local_Storage::user_data_storage);
|
||||
strncpy(pchBuffer, user_data.c_str(), cubBuffer - 1);
|
||||
pchBuffer[cubBuffer - 1] = 0;
|
||||
return true;
|
||||
|
|
|
@ -38,14 +38,19 @@ public ISteamUserStats009,
|
|||
public ISteamUserStats010,
|
||||
public ISteamUserStats
|
||||
{
|
||||
public:
|
||||
static constexpr auto achievements_user_file = "achievements.json";
|
||||
|
||||
private:
|
||||
|
||||
Local_Storage *local_storage;
|
||||
Settings *settings;
|
||||
SteamCallResults *callback_results;
|
||||
class SteamCallBacks *callbacks;
|
||||
std::vector<struct Steam_Leaderboard> leaderboards;
|
||||
|
||||
std::string db_file_path;
|
||||
nlohmann::json achievements;
|
||||
nlohmann::json defined_achievements;
|
||||
nlohmann::json user_achievements;
|
||||
|
||||
unsigned int find_leaderboard(std::string name)
|
||||
{
|
||||
|
@ -58,9 +63,10 @@ unsigned int find_leaderboard(std::string name)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void load_achievements()
|
||||
void load_achievements_db()
|
||||
{
|
||||
std::ifstream achs_file(db_file_path);
|
||||
std::string file_path = Local_Storage::get_game_settings_path() + achievements_user_file;
|
||||
std::ifstream achs_file(file_path);
|
||||
|
||||
if (achs_file)
|
||||
{
|
||||
|
@ -73,26 +79,34 @@ void load_achievements()
|
|||
achs_file.read(&buffer[0], size);
|
||||
achs_file.close();
|
||||
|
||||
try
|
||||
{
|
||||
achievements = nlohmann::json::parse(buffer);
|
||||
try {
|
||||
defined_achievements = std::move(nlohmann::json::parse(buffer));
|
||||
} catch (std::exception &e) {
|
||||
PRINT_DEBUG("Error while parsing json: \"%s\" : %s\n", file_path.c_str(), e.what());
|
||||
}
|
||||
catch (std::exception &e)
|
||||
{
|
||||
PRINT_DEBUG("(Achievements): Error while parsing json: %s\n", e.what());
|
||||
}
|
||||
else
|
||||
{
|
||||
PRINT_DEBUG("Couldn't open file \"%s\" to read achievements definition\n", file_path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void load_achievements()
|
||||
{
|
||||
local_storage->load_inventory_file(user_achievements, achievements_user_file);
|
||||
}
|
||||
|
||||
public:
|
||||
Steam_User_Stats(Settings *settings, Local_Storage *local_storage, class SteamCallResults *callback_results, class SteamCallBacks *callbacks, std::string const&achievements_db_file_path):
|
||||
Steam_User_Stats(Settings *settings, Local_Storage *local_storage, class SteamCallResults *callback_results, class SteamCallBacks *callbacks):
|
||||
settings(settings),
|
||||
local_storage(local_storage),
|
||||
callback_results(callback_results),
|
||||
callbacks(callbacks),
|
||||
db_file_path(achievements_db_file_path)
|
||||
defined_achievements(nlohmann::json::object()),
|
||||
user_achievements(nlohmann::json::object())
|
||||
{
|
||||
load_achievements();
|
||||
load_achievements_db(); // achievements db
|
||||
load_achievements(); // achievements per user
|
||||
}
|
||||
|
||||
// Ask the server to send down this user's data and achievements for this game
|
||||
|
@ -118,7 +132,7 @@ bool GetStat( const char *pchName, int32 *pData )
|
|||
if (!pchName || !pData) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
int read_data = local_storage->get_data(STATS_STORAGE_FOLDER, pchName, (char* )pData, sizeof(*pData));
|
||||
int read_data = local_storage->get_data(Local_Storage::stats_storage_folder, pchName, (char* )pData, sizeof(*pData));
|
||||
if (read_data == sizeof(int32))
|
||||
return true;
|
||||
|
||||
|
@ -131,7 +145,7 @@ bool GetStat( const char *pchName, float *pData )
|
|||
if (!pchName || !pData) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
int read_data = local_storage->get_data(STATS_STORAGE_FOLDER, pchName, (char* )pData, sizeof(*pData));
|
||||
int read_data = local_storage->get_data(Local_Storage::stats_storage_folder, pchName, (char* )pData, sizeof(*pData));
|
||||
if (read_data == sizeof(int32))
|
||||
return true;
|
||||
|
||||
|
@ -146,7 +160,7 @@ bool SetStat( const char *pchName, int32 nData )
|
|||
if (!pchName) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
return local_storage->store_data(STATS_STORAGE_FOLDER, pchName, (char* )&nData, sizeof(nData)) == sizeof(nData);
|
||||
return local_storage->store_data(Local_Storage::stats_storage_folder, pchName, (char* )&nData, sizeof(nData)) == sizeof(nData);
|
||||
}
|
||||
|
||||
bool SetStat( const char *pchName, float fData )
|
||||
|
@ -155,7 +169,7 @@ bool SetStat( const char *pchName, float fData )
|
|||
if (!pchName) return false;
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
return local_storage->store_data(STATS_STORAGE_FOLDER, pchName, (char* )&fData, sizeof(fData)) == sizeof(fData);
|
||||
return local_storage->store_data(Local_Storage::stats_storage_folder, pchName, (char* )&fData, sizeof(fData)) == sizeof(fData);
|
||||
}
|
||||
|
||||
bool UpdateAvgRateStat( const char *pchName, float flCountThisSession, double dSessionLength )
|
||||
|
@ -164,7 +178,7 @@ bool UpdateAvgRateStat( const char *pchName, float flCountThisSession, double dS
|
|||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
char data[sizeof(float) + sizeof(float) + sizeof(double)];
|
||||
int read_data = local_storage->get_data(STATS_STORAGE_FOLDER, pchName, (char* )data, sizeof(*data));
|
||||
int read_data = local_storage->get_data(Local_Storage::stats_storage_folder, pchName, (char* )data, sizeof(*data));
|
||||
float oldcount = 0;
|
||||
double oldsessionlength = 0;
|
||||
if (read_data == sizeof(data)) {
|
||||
|
@ -180,30 +194,28 @@ bool UpdateAvgRateStat( const char *pchName, float flCountThisSession, double dS
|
|||
memcpy(data + sizeof(float), &oldcount, sizeof(oldcount));
|
||||
memcpy(data + sizeof(float) * 2, &oldsessionlength, sizeof(oldsessionlength));
|
||||
|
||||
return local_storage->store_data(STATS_STORAGE_FOLDER, pchName, data, sizeof(data)) == sizeof(data);
|
||||
return local_storage->store_data(Local_Storage::stats_storage_folder, pchName, data, sizeof(data)) == sizeof(data);
|
||||
}
|
||||
|
||||
|
||||
// Achievement flag accessors
|
||||
bool GetAchievement( const char *pchName, bool *pbAchieved )
|
||||
{
|
||||
//TODO: these achievement functions need to load a list of achievements from somewhere, return false so that kf2 doesn't loop endlessly
|
||||
PRINT_DEBUG("GetAchievement %s\n", pchName);
|
||||
try
|
||||
{
|
||||
auto it = std::find_if(achievements.begin(), achievements.end(), [pchName]( nlohmann::json &item ) {
|
||||
return static_cast<std::string const&>(item["name"]) == pchName;
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
try {
|
||||
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName]( nlohmann::json &item ) {
|
||||
return item["name"].get<std::string>() == pchName;
|
||||
});
|
||||
if (it != achievements.end())
|
||||
{
|
||||
*pbAchieved = it.value()["earned"];
|
||||
auto ach = user_achievements.find(pchName);
|
||||
if (it != defined_achievements.end() && ach != user_achievements.end()) {
|
||||
if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
} catch (...) {}
|
||||
|
||||
}
|
||||
if (pbAchieved != nullptr)* pbAchieved = false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -211,21 +223,18 @@ bool GetAchievement( const char *pchName, bool *pbAchieved )
|
|||
bool SetAchievement( const char *pchName )
|
||||
{
|
||||
PRINT_DEBUG("SetAchievement %s\n", pchName);
|
||||
try
|
||||
{
|
||||
auto it = std::find_if(achievements.begin(), achievements.end(), [pchName](nlohmann::json& item) {
|
||||
return static_cast<std::string const&>(item["name"]) == pchName;
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
try {
|
||||
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) {
|
||||
return item["name"].get<std::string>() == pchName;
|
||||
});
|
||||
if (it != achievements.end())
|
||||
{
|
||||
it.value()["earned"] = 1;
|
||||
if (it != defined_achievements.end()) {
|
||||
user_achievements[pchName]["earned"] = true;
|
||||
user_achievements[pchName]["earned_time"] = static_cast<uint32>(std::time(nullptr));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -233,20 +242,18 @@ bool SetAchievement( const char *pchName )
|
|||
bool ClearAchievement( const char *pchName )
|
||||
{
|
||||
PRINT_DEBUG("ClearAchievement %s\n", pchName);
|
||||
try
|
||||
{
|
||||
auto it = std::find_if(achievements.begin(), achievements.end(), [pchName](nlohmann::json& item) {
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
try {
|
||||
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) {
|
||||
return static_cast<std::string const&>(item["name"]) == pchName;
|
||||
});
|
||||
if (it != achievements.end())
|
||||
{
|
||||
it.value()["earned"] = 0;
|
||||
if (it != defined_achievements.end()) {
|
||||
user_achievements[pchName]["earned"] = false;
|
||||
user_achievements[pchName]["earned_time"] = static_cast<uint32>(0);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
}
|
||||
} catch (...) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -258,26 +265,22 @@ bool ClearAchievement( const char *pchName )
|
|||
bool GetAchievementAndUnlockTime( const char *pchName, bool *pbAchieved, uint32 *punUnlockTime )
|
||||
{
|
||||
PRINT_DEBUG("GetAchievementAndUnlockTime\n");
|
||||
try
|
||||
{
|
||||
auto it = std::find_if(achievements.begin(), achievements.end(), [pchName](nlohmann::json& item) {
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
try {
|
||||
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) {
|
||||
return static_cast<std::string const&>(item["name"]) == pchName;
|
||||
});
|
||||
if (it != achievements.end())
|
||||
{
|
||||
*pbAchieved = it.value()["earned"].get<int>();
|
||||
*punUnlockTime = std::time(NULL);
|
||||
//*punUnlockTime = it.value()["time_earned"].get<uint32>();
|
||||
auto ach = user_achievements.find(pchName);
|
||||
if (it != defined_achievements.end() && ach != user_achievements.end()) {
|
||||
if(pbAchieved != nullptr) *pbAchieved = (*ach)["earned"];
|
||||
if(punUnlockTime != nullptr) *punUnlockTime = (*ach)["earned_time"];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
} catch (...) {}
|
||||
|
||||
}
|
||||
|
||||
*pbAchieved = false;
|
||||
*punUnlockTime = 0;
|
||||
if(pbAchieved != nullptr) *pbAchieved = false;
|
||||
if(punUnlockTime != nullptr) *punUnlockTime = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -294,11 +297,7 @@ bool StoreStats()
|
|||
PRINT_DEBUG("StoreStats\n");
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
std::ofstream achiev_file(db_file_path, std::ios::trunc | std::ios::out);
|
||||
if (achiev_file)
|
||||
{
|
||||
achiev_file << std::setw(2) << achievements;
|
||||
}
|
||||
local_storage->write_inventory_file(user_achievements, achievements_user_file);
|
||||
|
||||
UserStatsStored_t data;
|
||||
data.m_nGameID = settings->get_local_game_id().ToUint64();
|
||||
|
@ -317,6 +316,8 @@ bool StoreStats()
|
|||
int GetAchievementIcon( const char *pchName )
|
||||
{
|
||||
PRINT_DEBUG("GetAchievementIcon\n");
|
||||
if (pchName == nullptr) return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -327,56 +328,40 @@ int GetAchievementIcon( const char *pchName )
|
|||
const char * GetAchievementDisplayAttribute( const char *pchName, const char *pchKey )
|
||||
{
|
||||
PRINT_DEBUG("GetAchievementDisplayAttribute %s %s\n", pchName, pchKey);
|
||||
if (pchName == nullptr) return "";
|
||||
if (pchKey == nullptr) return "";
|
||||
|
||||
if (strcmp (pchKey, "name") == 0) {
|
||||
try
|
||||
{
|
||||
auto it = std::find_if(achievements.begin(), achievements.end(), [pchName](nlohmann::json& item) {
|
||||
try {
|
||||
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) {
|
||||
return static_cast<std::string const&>(item["name"]) == pchName;
|
||||
});
|
||||
if (it != achievements.end())
|
||||
{
|
||||
if (it != defined_achievements.end()) {
|
||||
return it.value()["displayName"].get<std::string>().c_str();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
if (strcmp (pchKey, "desc") == 0) {
|
||||
try
|
||||
{
|
||||
auto it = std::find_if(achievements.begin(), achievements.end(), [pchName](nlohmann::json& item) {
|
||||
try {
|
||||
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) {
|
||||
return static_cast<std::string const&>(item["name"]) == pchName;
|
||||
});
|
||||
if (it != achievements.end())
|
||||
{
|
||||
if (it != defined_achievements.end()) {
|
||||
return it.value()["description"].get<std::string>().c_str();
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
if (strcmp (pchKey, "hidden") == 0) {
|
||||
try
|
||||
{
|
||||
auto it = std::find_if(achievements.begin(), achievements.end(), [pchName](nlohmann::json& item) {
|
||||
try {
|
||||
auto it = std::find_if(defined_achievements.begin(), defined_achievements.end(), [pchName](nlohmann::json& item) {
|
||||
return static_cast<std::string const&>(item["name"]) == pchName;
|
||||
});
|
||||
if (it != achievements.end())
|
||||
{
|
||||
return (it.value()["hidden"].get<int>() ? "1" : "0");
|
||||
}
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
if (it != defined_achievements.end()) {
|
||||
return it.value()["description"].get<std::string>().c_str();
|
||||
}
|
||||
} catch (...) {}
|
||||
}
|
||||
|
||||
return "";
|
||||
|
@ -388,6 +373,8 @@ const char * GetAchievementDisplayAttribute( const char *pchName, const char *pc
|
|||
bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint32 nMaxProgress )
|
||||
{
|
||||
PRINT_DEBUG("IndicateAchievementProgress\n");
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -396,21 +383,16 @@ bool IndicateAchievementProgress( const char *pchName, uint32 nCurProgress, uint
|
|||
uint32 GetNumAchievements()
|
||||
{
|
||||
PRINT_DEBUG("GetNumAchievements\n");
|
||||
return achievements.size();
|
||||
return defined_achievements.size();
|
||||
}
|
||||
|
||||
// Get achievement name iAchievement in [0,GetNumAchievements)
|
||||
const char * GetAchievementName( uint32 iAchievement )
|
||||
{
|
||||
PRINT_DEBUG("GetAchievementName\n");
|
||||
try
|
||||
{
|
||||
return static_cast<std::string const&>(achievements[iAchievement]["name"]).c_str();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
|
||||
}
|
||||
try {
|
||||
return defined_achievements[iAchievement]["name"].get<std::string>().c_str();
|
||||
} catch (...) {}
|
||||
return "";
|
||||
}
|
||||
|
||||
|
@ -428,7 +410,10 @@ SteamAPICall_t RequestUserStats( CSteamID steamIDUser )
|
|||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
// Enable this to allow hot reload achievements status
|
||||
//load_achievements();
|
||||
//if (steamIDUser == settings->get_local_steam_id()) {
|
||||
// load_achievements();
|
||||
//}
|
||||
|
||||
|
||||
UserStatsReceived_t data;
|
||||
data.m_nGameID = settings->get_local_game_id().ToUint64();
|
||||
|
@ -442,6 +427,8 @@ SteamAPICall_t RequestUserStats( CSteamID steamIDUser )
|
|||
bool GetUserStat( CSteamID steamIDUser, const char *pchName, int32 *pData )
|
||||
{
|
||||
PRINT_DEBUG("GetUserStat %s %llu\n", pchName, steamIDUser.ConvertToUint64());
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
if (steamIDUser == settings->get_local_steam_id()) {
|
||||
|
@ -456,6 +443,8 @@ bool GetUserStat( CSteamID steamIDUser, const char *pchName, int32 *pData )
|
|||
bool GetUserStat( CSteamID steamIDUser, const char *pchName, float *pData )
|
||||
{
|
||||
PRINT_DEBUG("GetUserStat %s %llu\n", pchName, steamIDUser.ConvertToUint64());
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
std::lock_guard<std::recursive_mutex> lock(global_mutex);
|
||||
|
||||
if (steamIDUser == settings->get_local_steam_id()) {
|
||||
|
@ -470,6 +459,12 @@ bool GetUserStat( CSteamID steamIDUser, const char *pchName, float *pData )
|
|||
bool GetUserAchievement( CSteamID steamIDUser, const char *pchName, bool *pbAchieved )
|
||||
{
|
||||
PRINT_DEBUG("GetUserAchievement %s\n", pchName);
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
if (steamIDUser == settings->get_local_steam_id()) {
|
||||
return GetAchievement(pchName, pbAchieved);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -477,6 +472,11 @@ bool GetUserAchievement( CSteamID steamIDUser, const char *pchName, bool *pbAchi
|
|||
bool GetUserAchievementAndUnlockTime( CSteamID steamIDUser, const char *pchName, bool *pbAchieved, uint32 *punUnlockTime )
|
||||
{
|
||||
PRINT_DEBUG("GetUserAchievementAndUnlockTime %s\n", pchName);
|
||||
if (pchName == nullptr) return false;
|
||||
|
||||
if (steamIDUser == settings->get_local_steam_id()) {
|
||||
return GetAchievementAndUnlockTime(pchName, pbAchieved, punUnlockTime);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -486,6 +486,13 @@ bool ResetAllStats( bool bAchievementsToo )
|
|||
{
|
||||
PRINT_DEBUG("ResetAllStats\n");
|
||||
//TODO
|
||||
if (bAchievementsToo) {
|
||||
std::for_each(user_achievements.begin(), user_achievements.end(), [](nlohmann::json& v) {
|
||||
v["earned"] = false;
|
||||
v["earned_time"] = 0;
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue