mirror of
https://github.com/Detanup01/gbe_fork.git
synced 2025-03-28 14:56:24 +01:00
fix gamestats + write to json instead of csv
This commit is contained in:
parent
e492aec54b
commit
72f21e479d
2 changed files with 124 additions and 124 deletions
|
@ -37,7 +37,10 @@ private:
|
|||
|
||||
struct Attribute_t
|
||||
{
|
||||
const AttributeType_t type;
|
||||
private:
|
||||
AttributeType_t type;
|
||||
|
||||
public:
|
||||
union {
|
||||
int32 n_data;
|
||||
std::string s_data;
|
||||
|
@ -45,10 +48,16 @@ private:
|
|||
int64 ll_data;
|
||||
};
|
||||
|
||||
Attribute_t() = delete;
|
||||
Attribute_t(AttributeType_t type);
|
||||
Attribute_t(const Attribute_t &other);
|
||||
Attribute_t(Attribute_t &&other);
|
||||
~Attribute_t();
|
||||
|
||||
Attribute_t& operator=(const Attribute_t &other);
|
||||
Attribute_t& operator=(Attribute_t &&other);
|
||||
|
||||
AttributeType_t get_type() const noexcept;
|
||||
};
|
||||
|
||||
struct Row_t
|
||||
|
@ -87,13 +96,12 @@ private:
|
|||
|
||||
|
||||
uint64 create_session_id() const;
|
||||
bool valid_stats_account_type(int8 nAccountType);
|
||||
bool valid_stats_account_type(int8 nAccountType) const noexcept;
|
||||
Table_t *get_or_create_session_table(Session_t &session, const char *table_name);
|
||||
Attribute_t *get_or_create_session_att(const char *att_name, Session_t &session, AttributeType_t type_if_create);
|
||||
Attribute_t *get_or_create_row_att(uint64 ulRowID, const char *att_name, Table_t &table, AttributeType_t type_if_create);
|
||||
Session_t* get_last_active_session();
|
||||
|
||||
std::string sanitize_csv_value(std::string_view value);
|
||||
void save_session_to_disk(Steam_GameStats::Session_t &session, uint64 session_id);
|
||||
void steam_run_callback();
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ Steam_GameStats::Attribute_t::Attribute_t(AttributeType_t type)
|
|||
}
|
||||
|
||||
Steam_GameStats::Attribute_t::Attribute_t(const Attribute_t &other)
|
||||
:type(type)
|
||||
:type(other.type)
|
||||
{
|
||||
switch (other.type)
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ Steam_GameStats::Attribute_t::Attribute_t(const Attribute_t &other)
|
|||
}
|
||||
|
||||
Steam_GameStats::Attribute_t::Attribute_t(Attribute_t &&other)
|
||||
:type(type)
|
||||
:type(other.type)
|
||||
{
|
||||
switch (other.type)
|
||||
{
|
||||
|
@ -65,15 +65,46 @@ Steam_GameStats::Attribute_t::Attribute_t(Attribute_t &&other)
|
|||
|
||||
default: PRINT_DEBUG("[X] invalid type %i", (int)other.type); break;
|
||||
}
|
||||
|
||||
other.type = AttributeType_t::Int;
|
||||
}
|
||||
|
||||
|
||||
Steam_GameStats::Attribute_t& Steam_GameStats::Attribute_t::operator=(const Attribute_t &other)
|
||||
{
|
||||
if (&other != this) {
|
||||
this->~Attribute_t();
|
||||
new (this) Attribute_t(other);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Steam_GameStats::Attribute_t& Steam_GameStats::Attribute_t::operator=(Attribute_t &&other)
|
||||
{
|
||||
if (&other != this) {
|
||||
this->~Attribute_t();
|
||||
new (this) Attribute_t(std::move(other));
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Steam_GameStats::Attribute_t::~Attribute_t()
|
||||
{
|
||||
if (type == AttributeType_t::Str) {
|
||||
if (AttributeType_t::Str == type) {
|
||||
s_data.~basic_string();
|
||||
type = AttributeType_t::Int;
|
||||
}
|
||||
}
|
||||
|
||||
Steam_GameStats::AttributeType_t Steam_GameStats::Attribute_t::get_type() const noexcept
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
void Steam_GameStats::steam_gamestats_network_low_level(void *object, Common_Message *msg)
|
||||
{
|
||||
|
@ -119,7 +150,7 @@ uint64 Steam_GameStats::create_session_id() const
|
|||
return session_id;
|
||||
}
|
||||
|
||||
bool Steam_GameStats::valid_stats_account_type(int8 nAccountType)
|
||||
bool Steam_GameStats::valid_stats_account_type(int8 nAccountType) const noexcept
|
||||
{
|
||||
switch ((EGameStatsAccountType)nAccountType) {
|
||||
case EGameStatsAccountType::k_EGameStatsAccountType_Steam:
|
||||
|
@ -137,8 +168,9 @@ Steam_GameStats::Table_t *Steam_GameStats::get_or_create_session_table(Session_t
|
|||
{
|
||||
auto table_it = std::find_if(session.tables.rbegin(), session.tables.rend(), [=](const std::pair<std::string, Table_t> &item){ return item.first == table_name; });
|
||||
if (session.tables.rend() == table_it) {
|
||||
auto& [key, val] = session.tables.emplace_back(std::pair<std::string, Table_t>{});
|
||||
table = &val;
|
||||
auto& [new_name, new_table] = session.tables.emplace_back(std::pair<std::string, Table_t>{});
|
||||
new_name = table_name && table_name[0] ? table_name : "<EMPTY>";
|
||||
table = &new_table;
|
||||
} else {
|
||||
table = &table_it->second;
|
||||
}
|
||||
|
@ -149,13 +181,19 @@ Steam_GameStats::Table_t *Steam_GameStats::get_or_create_session_table(Session_t
|
|||
|
||||
Steam_GameStats::Attribute_t *Steam_GameStats::get_or_create_session_att(const char *att_name, Session_t &session, AttributeType_t type_if_create)
|
||||
{
|
||||
if (!att_name || !att_name[0]) {
|
||||
att_name = "<EMPTY>";
|
||||
}
|
||||
auto [ele_it, _] = session.attributes.emplace(att_name, type_if_create);
|
||||
return &ele_it->second;
|
||||
}
|
||||
|
||||
Steam_GameStats::Attribute_t *Steam_GameStats::get_or_create_row_att(uint64 ulRowID, const char *att_name, Table_t &table, AttributeType_t type_if_create)
|
||||
{
|
||||
auto &row = table.rows[static_cast<unsigned>(ulRowID)];
|
||||
if (!att_name || !att_name[0]) {
|
||||
att_name = "<EMPTY>";
|
||||
}
|
||||
auto& row = table.rows[static_cast<size_t>(ulRowID)];
|
||||
auto [ele_it, _] = row.attributes.emplace(att_name, type_if_create);
|
||||
return &ele_it->second;
|
||||
}
|
||||
|
@ -270,7 +308,7 @@ EResult Steam_GameStats::AddSessionAttributeInt( uint64 ulSessionID, const char*
|
|||
if (session.ended) return EResult::k_EResultExpired; // TODO is this correct?
|
||||
|
||||
auto att = get_or_create_session_att(pstrName, session, AttributeType_t::Int);
|
||||
if (att->type != AttributeType_t::Int) return EResult::k_EResultFail; // TODO is this correct?
|
||||
if (att->get_type() != AttributeType_t::Int) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
att->n_data = nData;
|
||||
PRINT_DEBUG("added successfully");
|
||||
|
@ -289,9 +327,9 @@ EResult Steam_GameStats::AddSessionAttributeString( uint64 ulSessionID, const ch
|
|||
if (session.ended) return EResult::k_EResultExpired; // TODO is this correct?
|
||||
|
||||
auto att = get_or_create_session_att(pstrName, session, AttributeType_t::Str);
|
||||
if (att->type != AttributeType_t::Str) return EResult::k_EResultFail; // TODO is this correct?
|
||||
if (att->get_type() != AttributeType_t::Str) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
att->s_data = pstrData;
|
||||
att->s_data = pstrData ? pstrData : "";
|
||||
PRINT_DEBUG("added successfully");
|
||||
return EResult::k_EResultOK;
|
||||
}
|
||||
|
@ -308,7 +346,7 @@ EResult Steam_GameStats::AddSessionAttributeFloat( uint64 ulSessionID, const cha
|
|||
if (session.ended) return EResult::k_EResultExpired; // TODO is this correct?
|
||||
|
||||
auto att = get_or_create_session_att(pstrName, session, AttributeType_t::Float);
|
||||
if (att->type != AttributeType_t::Float) return EResult::k_EResultFail; // TODO is this correct?
|
||||
if (att->get_type() != AttributeType_t::Float) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
att->f_data = fData;
|
||||
PRINT_DEBUG("added successfully");
|
||||
|
@ -321,6 +359,8 @@ EResult Steam_GameStats::AddNewRow( uint64 *pulRowID, uint64 ulSessionID, const
|
|||
PRINT_DEBUG("%p, %llu, ['%s']", pulRowID, ulSessionID, pstrTableName);
|
||||
std::lock_guard lock(global_mutex);
|
||||
|
||||
if (pulRowID) *pulRowID = 0;
|
||||
|
||||
auto session_it = sessions.find(ulSessionID);
|
||||
if (sessions.end() == session_it) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
|
@ -329,7 +369,9 @@ EResult Steam_GameStats::AddNewRow( uint64 *pulRowID, uint64 ulSessionID, const
|
|||
|
||||
auto table = get_or_create_session_table(session, pstrTableName);
|
||||
table->rows.emplace_back(Row_t{});
|
||||
if (pulRowID) *pulRowID = (uint64)(table->rows.size() - 1);
|
||||
// sending row id = 0 is considered a failure
|
||||
if (pulRowID) *pulRowID = (uint64)table->rows.size();
|
||||
|
||||
PRINT_DEBUG("added successfully");
|
||||
return EResult::k_EResultOK;
|
||||
}
|
||||
|
@ -344,10 +386,10 @@ EResult Steam_GameStats::CommitRow( uint64 ulRowID )
|
|||
if (active_session->tables.empty()) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
auto &table = active_session->tables.back().second;
|
||||
if (ulRowID >= table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
if (0 == ulRowID || ulRowID > table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
// TODO what if it was already committed ?
|
||||
auto& row = table.rows[static_cast<unsigned>(ulRowID)];
|
||||
auto& row = table.rows[static_cast<size_t>(ulRowID - 1)];
|
||||
row.committed = true;
|
||||
|
||||
PRINT_DEBUG("committed successfully");
|
||||
|
@ -379,17 +421,15 @@ EResult Steam_GameStats::AddRowAttributeInt( uint64 ulRowID, const char *pstrNam
|
|||
PRINT_DEBUG("%llu, '%s'=%i", ulRowID, pstrName, nData);
|
||||
std::lock_guard lock(global_mutex);
|
||||
|
||||
if (!pstrName) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
auto active_session = get_last_active_session();
|
||||
if (!active_session) return EResult::k_EResultFail; // TODO is this correct?
|
||||
if (active_session->tables.empty()) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
auto &table = active_session->tables.back().second;
|
||||
if (ulRowID >= table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
if (0 == ulRowID || ulRowID > table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
auto att = get_or_create_row_att(ulRowID, pstrName, table, AttributeType_t::Int);
|
||||
if (att->type != AttributeType_t::Int) return EResult::k_EResultFail; // TODO is this correct?
|
||||
auto att = get_or_create_row_att(ulRowID - 1, pstrName, table, AttributeType_t::Int);
|
||||
if (att->get_type() != AttributeType_t::Int) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
att->n_data = nData;
|
||||
PRINT_DEBUG("added successfully");
|
||||
|
@ -401,19 +441,17 @@ EResult Steam_GameStats::AddRowAtributeString( uint64 ulRowID, const char *pstrN
|
|||
PRINT_DEBUG("%llu, '%s'='%s'", ulRowID, pstrName, pstrData);
|
||||
std::lock_guard lock(global_mutex);
|
||||
|
||||
if (!pstrName || !pstrData) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
auto active_session = get_last_active_session();
|
||||
if (!active_session) return EResult::k_EResultFail; // TODO is this correct?
|
||||
if (active_session->tables.empty()) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
auto &table = active_session->tables.back().second;
|
||||
if (ulRowID >= table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
if (0 == ulRowID || ulRowID > table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
auto att = get_or_create_row_att(ulRowID, pstrName, table, AttributeType_t::Str);
|
||||
if (att->type != AttributeType_t::Str) return EResult::k_EResultFail; // TODO is this correct?
|
||||
auto att = get_or_create_row_att(ulRowID - 1, pstrName, table, AttributeType_t::Str);
|
||||
if (att->get_type() != AttributeType_t::Str) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
att->s_data = pstrData;
|
||||
att->s_data = pstrData ? pstrData : "";
|
||||
PRINT_DEBUG("added successfully");
|
||||
return EResult::k_EResultOK;
|
||||
}
|
||||
|
@ -423,17 +461,15 @@ EResult Steam_GameStats::AddRowAttributeFloat( uint64 ulRowID, const char *pstrN
|
|||
PRINT_DEBUG("%llu, '%s'=%f", ulRowID, pstrName, fData);
|
||||
std::lock_guard lock(global_mutex);
|
||||
|
||||
if (!pstrName) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
auto active_session = get_last_active_session();
|
||||
if (!active_session) return EResult::k_EResultFail; // TODO is this correct?
|
||||
if (active_session->tables.empty()) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
auto &table = active_session->tables.back().second;
|
||||
if (ulRowID >= table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
if (0 == ulRowID || ulRowID > table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
auto att = get_or_create_row_att(ulRowID, pstrName, table, AttributeType_t::Float);
|
||||
if (att->type != AttributeType_t::Float) return EResult::k_EResultFail; // TODO is this correct?
|
||||
auto att = get_or_create_row_att(ulRowID - 1, pstrName, table, AttributeType_t::Float);
|
||||
if (att->get_type() != AttributeType_t::Float) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
att->f_data = fData;
|
||||
PRINT_DEBUG("added successfully");
|
||||
|
@ -453,7 +489,7 @@ EResult Steam_GameStats::AddSessionAttributeInt64( uint64 ulSessionID, const cha
|
|||
if (session.ended) return EResult::k_EResultExpired; // TODO is this correct?
|
||||
|
||||
auto att = get_or_create_session_att(pstrName, session, AttributeType_t::Int64);
|
||||
if (att->type != AttributeType_t::Int64) return EResult::k_EResultFail; // TODO is this correct?
|
||||
if (att->get_type() != AttributeType_t::Int64) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
att->ll_data = llData;
|
||||
PRINT_DEBUG("added successfully");
|
||||
|
@ -465,17 +501,15 @@ EResult Steam_GameStats::AddRowAttributeInt64( uint64 ulRowID, const char *pstrN
|
|||
PRINT_DEBUG("%llu, '%s'=%lli", ulRowID, pstrName, llData);
|
||||
std::lock_guard lock(global_mutex);
|
||||
|
||||
if (!pstrName) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
auto active_session = get_last_active_session();
|
||||
if (!active_session) return EResult::k_EResultFail; // TODO is this correct?
|
||||
if (active_session->tables.empty()) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
auto &table = active_session->tables.back().second;
|
||||
if (ulRowID >= table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
if (0 == ulRowID || ulRowID > table.rows.size()) return EResult::k_EResultInvalidParam; // TODO is this correct?
|
||||
|
||||
auto att = get_or_create_row_att(ulRowID, pstrName, table, AttributeType_t::Int64);
|
||||
if (att->type != AttributeType_t::Int64) return EResult::k_EResultFail; // TODO is this correct?
|
||||
auto att = get_or_create_row_att(ulRowID - 1, pstrName, table, AttributeType_t::Int64);
|
||||
if (att->get_type() != AttributeType_t::Int64) return EResult::k_EResultFail; // TODO is this correct?
|
||||
|
||||
att->ll_data = llData;
|
||||
PRINT_DEBUG("added successfully");
|
||||
|
@ -486,111 +520,67 @@ EResult Steam_GameStats::AddRowAttributeInt64( uint64 ulRowID, const char *pstrN
|
|||
|
||||
// --- steam callbacks
|
||||
|
||||
std::string Steam_GameStats::sanitize_csv_value(std::string_view value)
|
||||
{
|
||||
// ref: https://en.wikipedia.org/wiki/Comma-separated_values
|
||||
// double quotes must be represented by a pair of double quotes
|
||||
auto val_str = common_helpers::str_replace_all(value, "\"", "\"\"");
|
||||
// multiline values aren't supported by all parsers
|
||||
val_str = common_helpers::str_replace_all(val_str, "\r\n", "\n");
|
||||
val_str = common_helpers::str_replace_all(val_str, "\n", " ");
|
||||
return val_str;
|
||||
}
|
||||
|
||||
void Steam_GameStats::save_session_to_disk(Steam_GameStats::Session_t &session, uint64 session_id)
|
||||
{
|
||||
auto folder = std::to_string(session.account_id) + "_" + std::to_string(session.rtTimeStarted) + "_" + std::to_string(session_id);
|
||||
auto folder_p = std::filesystem::u8path(settings->steam_game_stats_reports_dir) / std::filesystem::u8path(folder);
|
||||
auto folder_u8_str = folder_p.u8string();
|
||||
auto report_file =
|
||||
"session_[" + std::to_string(session_id) + "]" +
|
||||
"-started_" + std::to_string(session.rtTimeStarted) +
|
||||
"-steamid_" + std::to_string(session.account_id) +
|
||||
"-rnd_" + std::to_string(common_helpers::rand_number(UINT32_MAX)) +
|
||||
".json";
|
||||
auto fullpath_p = std::filesystem::u8path(settings->steam_game_stats_reports_dir) / std::filesystem::u8path(report_file);
|
||||
nlohmann::json jout{};
|
||||
|
||||
// save session attributes
|
||||
if (session.attributes.size()) {
|
||||
std::stringstream ss{};
|
||||
ss << "Session attribute,Value\n";
|
||||
for (const auto& [name, val] : session.attributes) {
|
||||
std::string val_str{};
|
||||
switch (val.type) {
|
||||
case AttributeType_t::Int: val_str = std::to_string(val.n_data); break;
|
||||
case AttributeType_t::Str: val_str = val.s_data; break;
|
||||
case AttributeType_t::Float: val_str = std::to_string(val.f_data); break;
|
||||
case AttributeType_t::Int64: val_str = std::to_string(val.ll_data); break;
|
||||
}
|
||||
if (!session.attributes.empty()) {
|
||||
auto &jsession_att = jout["session_attributes"];
|
||||
|
||||
val_str = sanitize_csv_value(val_str);
|
||||
auto name_str = sanitize_csv_value(name);
|
||||
ss << "\"" << name_str << "\",\"" << val_str << "\"\n";
|
||||
for (const auto& [name, val] : session.attributes) {
|
||||
auto &jatt_name = jsession_att[name];
|
||||
switch (val.get_type()) {
|
||||
case AttributeType_t::Int: jatt_name = val.n_data; break;
|
||||
case AttributeType_t::Str: jatt_name = val.s_data; break;
|
||||
case AttributeType_t::Float: jatt_name = val.f_data; break;
|
||||
case AttributeType_t::Int64: jatt_name = val.ll_data; break;
|
||||
}
|
||||
}
|
||||
auto ss_str = ss.str();
|
||||
Local_Storage::store_file_data(folder_u8_str, "session_attributes.csv", ss_str.c_str(), (unsigned int)ss_str.size());
|
||||
}
|
||||
|
||||
// save each table
|
||||
for (const auto& [table_name, table_data] : session.tables) {
|
||||
bool rows_has_attributes = std::any_of(table_data.rows.begin(), table_data.rows.end(), [](const Steam_GameStats::Row_t &item) {
|
||||
return item.attributes.size() > 0;
|
||||
return !item.attributes.empty();
|
||||
});
|
||||
|
||||
if (!rows_has_attributes) continue;
|
||||
|
||||
// convert the data representation to be column oriented
|
||||
// key=column header/title
|
||||
// value = list of column values
|
||||
std::unordered_map<std::string, std::vector<const Attribute_t*>> columns{};
|
||||
// save rows attributes
|
||||
auto &jthis_table = jout["tables"][table_name];
|
||||
for (size_t row_idx = 0; row_idx < table_data.rows.size(); ++row_idx) {
|
||||
const auto &row = table_data.rows[row_idx];
|
||||
auto &jthis_row = jthis_table[row_idx];
|
||||
for (const auto& [att_name, att_val] : row.attributes) {
|
||||
auto [column_it, new_column] = columns.emplace(att_name, std::vector<const Attribute_t*>{});
|
||||
auto &column_values = column_it->second;
|
||||
// when adding new column make sure we have correct rows count
|
||||
if (new_column) {
|
||||
column_values.assign(table_data.rows.size(), nullptr);
|
||||
}
|
||||
// add the row value in its correct place
|
||||
column_values[row_idx] = &att_val;
|
||||
}
|
||||
}
|
||||
|
||||
std::stringstream ss_table{};
|
||||
// write header
|
||||
bool first_header_atom = true;
|
||||
for (const auto& [col_name, _] : columns) {
|
||||
auto csv_col_name = sanitize_csv_value(col_name);
|
||||
if (first_header_atom) {
|
||||
first_header_atom = false;
|
||||
ss_table << "\"" << csv_col_name << "\"";
|
||||
} else {
|
||||
ss_table << ",\"" << csv_col_name << "\"";
|
||||
}
|
||||
}
|
||||
ss_table << "\n";
|
||||
// write values
|
||||
for (size_t row_idx = 0; row_idx < table_data.rows.size(); ++row_idx) {
|
||||
bool first_col_cell = true;
|
||||
for (const auto& [_, col_values] : columns) {
|
||||
auto &cell_val = col_values[row_idx];
|
||||
|
||||
std::string val_str{};
|
||||
switch (cell_val->type) {
|
||||
case AttributeType_t::Int: val_str = std::to_string(cell_val->n_data); break;
|
||||
case AttributeType_t::Str: val_str = cell_val->s_data; break;
|
||||
case AttributeType_t::Float: val_str = std::to_string(cell_val->f_data); break;
|
||||
case AttributeType_t::Int64: val_str = std::to_string(cell_val->ll_data); break;
|
||||
}
|
||||
|
||||
val_str = sanitize_csv_value(val_str);
|
||||
if (first_col_cell) {
|
||||
first_col_cell = false;
|
||||
ss_table << "\"" << val_str << "\"";
|
||||
} else {
|
||||
ss_table << ",\"" << val_str << "\"";
|
||||
auto &jthis_row_att = jthis_row[att_name];
|
||||
switch (att_val.get_type()) {
|
||||
case AttributeType_t::Int: jthis_row_att = att_val.n_data; break;
|
||||
case AttributeType_t::Str: jthis_row_att = att_val.s_data; break;
|
||||
case AttributeType_t::Float: jthis_row_att = att_val.f_data; break;
|
||||
case AttributeType_t::Int64: jthis_row_att = att_val.ll_data; break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ss_table << "\n";
|
||||
auto ss_str = ss_table.str();
|
||||
Local_Storage::store_file_data(folder_u8_str, table_name.c_str(), ss_str.c_str(), (unsigned int)ss_str.size());
|
||||
|
||||
}
|
||||
|
||||
if (!jout.empty()) {
|
||||
if (std::filesystem::create_directories(fullpath_p.parent_path())) {
|
||||
auto fwrite = std::ofstream(fullpath_p, std::ios::out | std::ios::binary | std::ios::trunc);
|
||||
if (fwrite) {
|
||||
fwrite << std::setw(2) << jout;
|
||||
fwrite.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Steam_GameStats::steam_run_callback()
|
||||
|
@ -607,8 +597,10 @@ void Steam_GameStats::steam_run_callback()
|
|||
if (session.ended) {
|
||||
if (!session.saved_to_disk) {
|
||||
session.saved_to_disk = true;
|
||||
if (settings->steam_game_stats_reports_dir.size()) {
|
||||
save_session_to_disk(session, session_it->first);
|
||||
if (!settings->steam_game_stats_reports_dir.empty()) {
|
||||
try {
|
||||
save_session_to_disk(session, session_it->first);
|
||||
} catch(...){}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue