From b177301af93e28f033cdc49177a38719f95d0433 Mon Sep 17 00:00:00 2001 From: Andrei Dabija Date: Fri, 22 Aug 2025 10:23:37 +0300 Subject: [PATCH 1/3] rename remote configs members --- source/gameanalytics/GAState.cpp | 12 ++++++------ source/gameanalytics/GAState.h | 8 +++++--- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/source/gameanalytics/GAState.cpp b/source/gameanalytics/GAState.cpp index 01a4c912..d8fe464c 100644 --- a/source/gameanalytics/GAState.cpp +++ b/source/gameanalytics/GAState.cpp @@ -411,7 +411,7 @@ namespace gameanalytics out["user_id"] = getUserId(); // remote configs configurations - if(getInstance()._configurations.is_object() && !getInstance()._configurations.empty()) + if(getInstance()._gameRemoteConfigsJson.is_object() && !getInstance()._gameRemoteConfigsJson.empty()) { out["configurations_v3"] = getInstance().getRemoteConfigAnnotations(); } @@ -895,7 +895,7 @@ namespace gameanalytics json contents; - for(auto& obj : getInstance()._configurations) + for(auto& obj : getInstance()._gameRemoteConfigsJson) { if(obj.contains("key") && obj.contains("value")) { @@ -913,7 +913,7 @@ namespace gameanalytics void GAState::populateConfigurations(json& sdkConfig) { std::lock_guard guard(_mtx); - _configurations = {}; + _gameRemoteConfigsJson = {}; try { @@ -933,7 +933,7 @@ namespace gameanalytics if (!key.empty() && configuration.contains("value") && client_ts_adjusted > start_ts && client_ts_adjusted < end_ts) { - _configurations[key] = configuration; + _gameRemoteConfigsJson[key] = configuration; logging::GALogger::d("configuration added: %s", configuration.dump(JSON_PRINT_INDENT).c_str()); } } @@ -942,7 +942,7 @@ namespace gameanalytics _remoteConfigsIsReady = true; - std::string const configStr = _configurations.dump(); + std::string const configStr = _gameRemoteConfigsJson.dump(); for (auto& listener : _remoteConfigsListeners) { listener->onRemoteConfigsUpdated(configStr); @@ -1161,7 +1161,7 @@ namespace gameanalytics json GAState::getRemoteConfigAnnotations() { json configs; - for(json& obj : _configurations) + for(json& obj : _gameRemoteConfigsJson) { json cfg; cfg["vsn"] = utilities::getOptionalValue(obj, "vsn", 0); diff --git a/source/gameanalytics/GAState.h b/source/gameanalytics/GAState.h index b2da9593..d476c844 100644 --- a/source/gameanalytics/GAState.h +++ b/source/gameanalytics/GAState.h @@ -150,9 +150,9 @@ namespace gameanalytics inline static T getRemoteConfigsValue(std::string const& key, T const& defaultValue) { std::lock_guard lg(getInstance()._mtx); - if(getInstance()._configurations.contains(key)) + if(getInstance()._gameRemoteConfigsJson.contains(key)) { - json& config = getInstance()._configurations[key]; + json& config = getInstance()._gameRemoteConfigsJson[key]; T value = utilities::getOptionalValue(config, "value", defaultValue); return value; } @@ -271,7 +271,9 @@ namespace gameanalytics bool _enableIdTracking = true; - json _configurations; + json _gameRemoteConfigsJson; + json _trackingRemoteConfigsJson; + bool _remoteConfigsIsReady; std::vector> _remoteConfigsListeners; std::recursive_mutex _mtx; From 0130e81323f2456fe8383b05ae37ebc5cffe63e5 Mon Sep 17 00:00:00 2001 From: Andrei Dabija Date: Fri, 22 Aug 2025 11:22:07 +0300 Subject: [PATCH 2/3] split remote configs in game and annotation cfgs --- source/gameanalytics/GAState.cpp | 47 +++++++++++++++++++++----------- source/gameanalytics/GAState.h | 2 ++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/source/gameanalytics/GAState.cpp b/source/gameanalytics/GAState.cpp index d8fe464c..ae3ba089 100644 --- a/source/gameanalytics/GAState.cpp +++ b/source/gameanalytics/GAState.cpp @@ -411,7 +411,7 @@ namespace gameanalytics out["user_id"] = getUserId(); // remote configs configurations - if(getInstance()._gameRemoteConfigsJson.is_object() && !getInstance()._gameRemoteConfigsJson.empty()) + if(getInstance()._trackingRemoteConfigsJson.is_array() && !getInstance()._trackingRemoteConfigsJson.empty()) { out["configurations_v3"] = getInstance().getRemoteConfigAnnotations(); } @@ -910,10 +910,34 @@ namespace gameanalytics return contents.dump(JSON_PRINT_INDENT); } + void GAState::buildRemoteConfigsJsons(const json& remoteCfgs) + { + _gameRemoteConfigsJson = json::array(); + _trackingRemoteConfigsJson = json::array(); + + for (const auto& configuration : remoteCfgs) + { + _gameRemoteConfigsJson.push_back({ + {"key", configuration["key"]}, + {"value", configuration["value"]} + }); + + _trackingRemoteConfigsJson.push_back({ + {"key", configuration["key"]}, + {"id", configuration["id"]}, + {"vsn", configuration["vsn"]} + }); + } + + logging::GALogger::d("Remote configs: %s", _gameRemoteConfigsJson.dump(JSON_PRINT_INDENT).c_str()); + logging::GALogger::d("Remote configs for tracking: %s", _trackingRemoteConfigsJson.dump(JSON_PRINT_INDENT).c_str()); + logging::GALogger::i("Remote configs ready with %zu configurations", _gameRemoteConfigsJson.size()); + } + void GAState::populateConfigurations(json& sdkConfig) { - std::lock_guard guard(_mtx); - _gameRemoteConfigsJson = {}; + + json _tempRemoteConfigsJson = {}; try { @@ -933,13 +957,15 @@ namespace gameanalytics if (!key.empty() && configuration.contains("value") && client_ts_adjusted > start_ts && client_ts_adjusted < end_ts) { - _gameRemoteConfigsJson[key] = configuration; + _tempRemoteConfigsJson[key] = configuration; logging::GALogger::d("configuration added: %s", configuration.dump(JSON_PRINT_INDENT).c_str()); } } } } + buildRemoteConfigsJsons(_tempRemoteConfigsJson); + _remoteConfigsIsReady = true; std::string const configStr = _gameRemoteConfigsJson.dump(); @@ -1160,18 +1186,7 @@ namespace gameanalytics json GAState::getRemoteConfigAnnotations() { - json configs; - for(json& obj : _gameRemoteConfigsJson) - { - json cfg; - cfg["vsn"] = utilities::getOptionalValue(obj, "vsn", 0); - cfg["key"] = utilities::getOptionalValue(obj, "key", ""); - cfg["id"] = utilities::getOptionalValue(obj, "id", ""); - - configs.push_back(cfg); - } - - return configs; + return _trackingRemoteConfigsJson; } } } diff --git a/source/gameanalytics/GAState.h b/source/gameanalytics/GAState.h index d476c844..346a0b86 100644 --- a/source/gameanalytics/GAState.h +++ b/source/gameanalytics/GAState.h @@ -210,6 +210,8 @@ namespace gameanalytics void addErrorEvent(EGAErrorSeverity severity, std::string const& message); + void buildRemoteConfigsJsons(const json& remoteCfgs); + threading::GAThreading _gaThread; events::GAEvents _gaEvents; device::GADevice _gaDevice; From e16f7d4c011cdc0d9bd2dfd5b1d4b2bdd2d99e01 Mon Sep 17 00:00:00 2001 From: Andrei Dabija Date: Fri, 22 Aug 2025 11:39:27 +0300 Subject: [PATCH 3/3] add 5.0.0 release notes --- CHANGELOG.md | 7 +++++++ source/gameanalytics/GACommon.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4329e0f3..27975727 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 5.0.0 + +### Added + +- **Remote Configs With JSON**: Remote Configs now support JSON values, allowing for more complex configurations. +- **Playtime Metrics API**: Introduced new API to get total playtime and playtime in the current session. + ## 4.1.0 ### Added diff --git a/source/gameanalytics/GACommon.h b/source/gameanalytics/GACommon.h index e761edb8..37f533c6 100644 --- a/source/gameanalytics/GACommon.h +++ b/source/gameanalytics/GACommon.h @@ -85,7 +85,7 @@ namespace gameanalytics class GAState; } - constexpr const char* GA_VERSION_STR = "cpp 4.1.0"; + constexpr const char* GA_VERSION_STR = "cpp 5.0.0"; constexpr int MAX_CUSTOM_FIELDS_COUNT = 50; constexpr int MAX_CUSTOM_FIELDS_KEY_LENGTH = 64;