SDKBOX How to read/parse updated sdkbox_config.json? After liveops change

@nite Hi,
On the local sdkbox_config.json I have typing error (bad achievement id aa11 with name A1).
In method onAchievementsLoaded we get the info about real achievement state(hidden) and id aa1, that’s great.

So I know that I have hidden achievement with realid aa1, and try to reveal it.
I parsed the sdkbox_config.json and trying to find aa1 and his name to unlock it with method reveal( const std::string& achievement_name ), nothig found (remember I have a typing error (aa11)).

No problem we have live ops. I made the correction (to aa1) and published to the cloud.
Game restarted twice to be sure that new sdkbox_config.json is downloaded.

Question is how to read the updated config to find the name for realid aa1. Don’t tell me unlock the name A1 :wink:

Updated config is encypted and name is “config” :wink: and there is some config_hash. How to read them?

Edit1:
File is base64, which contains xxtea encrypted string. To decrypt “config” with secret: base64 decode and xxtea decrypt with secret from live ops page.
Too complicated :wink: There is no method to get the updated config? Let me know.

My goal is to take the full advantage with liveops editing and read the onAchievementsLoaded info and unlock them with game logic.

Thank you for your time and help

Edit2:
Here is the method to read the updated config.

void decryptXxtea(std::string &value, std::string &secret){
    xxtea_long retLength = 0;
    unsigned char * decryptedData = xxtea_decrypt((unsigned char*)value.c_str(), (xxtea_long) value.size(), (unsigned char*)secret.c_str(), (xxtea_long)secret.size(), &retLength);
    value.clear();
    value.append(reinterpret_cast<char*>(decryptedData), retLength);
    free(decryptedData);
}

auto fu = cocos2d::FileUtils::getInstance();    
std::string remoteFile = fu->getWritablePath()+"config";
bool remoteConfigExist = fu->isFileExist(remoteFile);
if(remoteConfigExist){
    auto remoteSdkBoxConfig = fu->getStringFromFile(remoteFile);
    unsigned char * data = nullptr;
    int dataLen = cocos2d::base64Decode(reinterpret_cast<const unsigned char*>(remoteSdkBoxConfig.c_str()), (unsigned int)remoteSdkBoxConfig.size(), &data);
    remoteSdkBoxConfig.clear();
    remoteSdkBoxConfig.append(reinterpret_cast<const char*>(data), dataLen);
    free(data);
    std::string secret = "CHANGEYOURSECRET";
   decryptXxtea(remoteSdkBoxConfig, secret);
    CCLOG("remote config:%s" ,remoteSdkBoxConfig.c_str());
}

What kind of data, do you want to get from the sdkbox_config.json? A list of achievements? We can add new method getAchievements to SDKBOX play to achieve that.

Hi nite, I read the data from the config to get the mapping id to name. I know we have a local copy (well tested) of sdkbox_config.json. But imagine if we make a mistake in the local config (for example achievement name) and application is used by testers or live. There is no way how to fix it. Liveops is ideal solution how to edit and fix it (the achievement name). But for now there is no public way how to read it (the fresh remote copy with edited name). Is make a sense? Public async method getAchievements with callback will be great, this will solve many mistakes :wink: Another thing, is loadAchievements method. This method return list of achievements and their states, But without names. Is there a way to add names to have mapping with current state at one place? This will solve problem with mapping sdkbox_config id and loadachievements result id to get the actual state for the name, is it clear? Thank you for your time.

Yes we will add that in the next release

This will solve two issues, mapping at one place, and fresh names/ids from the fresh remote config. Great!

Hi @elensar,

What’s the names ?
I notice virtual void onAchievementsLoaded( bool reload_forced, const std::string& json_achievements_info ) {}; callback, every item has id, name.

/**
* Method invoked after calling plugin's `loadAchievements` method.
* The `json_achievements_info` parameter is a json array encoded string.
* #### Android fields:
* each array element is of the form:
* ```json
*   {
*      "id"                        : string,
*      "name"                      : string,
*      "xp_value"                  : string,   // experience value
*      "last_updated_timestamp"    : number,
*      "description"               : string,
*      "type"                      : number,   // 0 = standard, 1 = incremental
*      "state"                     : number,   // 0 = unlocked, 1 = revealed,   2 = hidden
*      "unlocked_image_uri"        : string,   // content:// protocol
*      "revealed_image_uri"        : string,   // content:// protocol
*   }
* ```
*   If the achievement is incremental, these fileds will also be available:
* ```json
*   {
*      "formatted_current_steps"   : string,
*      "formatted_total_steps"     : string,
*      current_steps"              : number,
*      "total_steps"               : number
*   }
* ```
* #### IOS fields:
* ```json
*   {
*      "id"                        : string,
*      "name"                      : string,
*      "xp_value"                  : number, int
*      "last_updated_timestamp"    : number,
*      "description"               : string,   // maybe empty if no achievemnt submission happened before.
*      "state"                     : number,   // 0 = unlocked, 1 = revealed,   2 = hidden
*      "type"                      : 1,        // on ios all achievemtns are incremental.
*      "current_steps"             : number,   // double value. percentage 0.0 .. 100.0
*      "total_steps"               : number,   // 100.0
*   }
*  ```
*  iOS only fields:
* ```json
*   {
*      "replayable"                : boolean,
*   }
* ```
*/

Thanks,
Jimmy

Hi yinjimmy, from the returned json file… the id is the real itunes/google id and the name is the real itunes/google name. So there is no way to directly get the name for Liveops. Liveops name is used as param in sdkbox achievements methods. So if I get the fresh json and for example try to unlock next achievement I need to parse local config. But here is the real problem. As I wrote 23 Jan (please read it)… if live ops is changed (for example corrected sdkbox namein liveops), I have no way to map fresh loaded json to the edited/remote config (loaded from server).

To avoid parsing local and fresh remote liveops config to get the sdkbox achi name is to add sdkbox achi name into loaded json file. So json will have all informations to report achievemnts real id,name, and fresh sdkbox achi name.

Let me know if you have another idea how to solve the problem after liveops achi name/id change for the live app.

Edit: now I must decrypt fresh remote configuration loaded by game to get the fresh liveops edited data(there is no public api) and map it to the fresh loaded json achievements, so I get the all the fresh informations (states, sdkbox names) together.

Hi @nite @yinjimmy
can you look into these two issues on github? I fell alone (whitegfx/elensar) on sdkbox issues :wink:
Some solutions/options? Let me know please.

these are important, others… I can live with them…


thank you for your time

I got you o(^_^)o

1 Like