Result MultiplayerSessionMember::Deserialize()

in Source/Services/Multiplayer/multiplayer_session_member.cpp [335:517]


Result<XblMultiplayerSessionMember> MultiplayerSessionMember::Deserialize(
    _In_ const JsonValue& json
)
{
    XblMultiplayerSessionMember returnResult{};
    if (json.IsNull())
    {
        return returnResult;
    }
    auto returnResultInternal = Make<MultiplayerSessionMember>();
    returnResult.Internal = returnResultInternal;

    bool reserved = false;
    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonBool(json, "reserved", reserved));
    bool active = false;
    bool ready = false;


    returnResultInternal->m_customConstantsJson = "";
    returnResult.Xuid = 0;
    returnResult.InitializeRequested = false;
    returnResultInternal->m_teamId = "";
    returnResultInternal->m_initialTeam = "";
    returnResultInternal->m_matchmakingResultServerMeasurementsJson = "";

    if (json.IsObject() && json.HasMember("constants"))
    {
        const JsonValue& constantsJson = json["constants"];

        RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonFieldAsString(constantsJson, "custom", returnResultInternal->m_customConstantsJson, false));
        
        if (constantsJson.IsObject() && constantsJson.HasMember("custom"))
        {
            const JsonValue& constantsCustomJson = constantsJson["custom"];
            if (constantsCustomJson.IsObject() && constantsCustomJson.HasMember("matchmakingResult"))
            {
                const JsonValue& constantsCustomMatchmakingResultJson = constantsCustomJson["matchmakingResult"];
                RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(constantsCustomMatchmakingResultJson, "initialTeam", returnResultInternal->m_initialTeam, false));                
            }
        }

        if (constantsJson.IsObject() && constantsJson.HasMember("system"))
        {
            const JsonValue& constantsSystemJson = constantsJson["system"];

            xsapi_internal_string xuid;
            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(constantsSystemJson, "xuid", xuid));
            returnResult.Xuid = utils::internal_string_to_uint64(xuid);
            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonBool(constantsSystemJson, "initialize", returnResult.InitializeRequested));
            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(constantsSystemJson, "team", returnResultInternal->m_teamId));
            
            if (constantsSystemJson.IsObject() && constantsSystemJson.HasMember("matchmakingResult"))
            {
                const JsonValue& constantsSystemMatchmakingResultJson = constantsSystemJson["matchmakingResult"];
                RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonFieldAsString(constantsSystemMatchmakingResultJson, "serverMeasurements", returnResultInternal->m_matchmakingResultServerMeasurementsJson, false));
            }
        }
        else
        {
            //required
            return WEB_E_INVALID_JSON_STRING;
        }
    }
    else
    {
        //required
        return WEB_E_INVALID_JSON_STRING;
    }

    returnResult.CustomConstantsJson = returnResultInternal->m_customConstantsJson.data();
    returnResult.InitialTeam = returnResultInternal->m_initialTeam.data();
    returnResult.MatchmakingResultServerMeasurementsJson = returnResultInternal->m_matchmakingResultServerMeasurementsJson.data();

    returnResultInternal->m_secureDeviceAddressBase64 = "";
    returnResultInternal->m_serverMeasurementsJson = "";
    returnResultInternal->m_qosMeasurementsJson = "";
    returnResultInternal->m_customPropertiesString = "";

    if (json.IsObject() && json.HasMember("properties"))
    {
        const JsonValue& propertiesJson = json["properties"];
        if (propertiesJson.IsObject() && propertiesJson.HasMember("custom"))
        {
            JsonUtils::CopyFrom(returnResultInternal->m_customPropertiesJson, propertiesJson["custom"]);
            returnResultInternal->m_customPropertiesString = JsonUtils::SerializeJson(returnResultInternal->m_customPropertiesJson);
        }

        if (propertiesJson.IsObject() && propertiesJson.HasMember("system"))
        {
            const JsonValue& propertiesSystemJson = propertiesJson["system"];

            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(propertiesSystemJson, "secureDeviceAddress", returnResultInternal->m_secureDeviceAddressBase64));
            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonFieldAsString(propertiesSystemJson, "serverMeasurements", returnResultInternal->m_serverMeasurementsJson, false));
            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonFieldAsString(propertiesSystemJson, "measurements", returnResultInternal->m_qosMeasurementsJson, false));
            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonVector<uint32_t>(JsonUtils::JsonIntExtractor, propertiesSystemJson, "initializationGroup", returnResultInternal->m_membersInGroupIds, false));
            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonBool(propertiesSystemJson, "active", active));
            RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonBool(propertiesSystemJson, "ready", ready));

            if (propertiesSystemJson.IsObject() && propertiesSystemJson.HasMember("subscription"))
            {
                const JsonValue& propertiesSystemSubscriptionJson = propertiesSystemJson["subscription"];

                xsapi_internal_vector<xsapi_internal_string> changeTypes;
                RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonVector<xsapi_internal_string>(JsonUtils::JsonStringExtractor, propertiesSystemSubscriptionJson, "changeTypes", changeTypes, false));
                returnResultInternal->m_subscribedChangeTypes = Serializers::MultiplayerSessionChangeTypesFromStringVector(changeTypes);
            }
        }
        else
        {
            //required
            return WEB_E_INVALID_JSON_STRING;
        }
    }
    else
    {
        //required
        return WEB_E_INVALID_JSON_STRING;
    }

    returnResult.SecureDeviceBaseAddress64 = returnResultInternal->m_secureDeviceAddressBase64.data();
    returnResult.ServerMeasurementsJson = returnResultInternal->m_serverMeasurementsJson.data();
    returnResult.QosMeasurementsJson = returnResultInternal->m_qosMeasurementsJson.data();
    returnResult.MembersInGroupIds = returnResultInternal->m_membersInGroupIds.data();
    returnResult.MembersInGroupCount = static_cast<uint32_t>(returnResultInternal->m_membersInGroupIds.size());
    returnResult.CustomPropertiesJson = returnResultInternal->m_customPropertiesString.data();

    if (active)
    {
        returnResult.Status = XblMultiplayerSessionMemberStatus::Active;
    }
    else if (ready)
    {
        returnResult.Status = XblMultiplayerSessionMemberStatus::Ready;
    }
    else if (reserved)
    {
        returnResult.Status = XblMultiplayerSessionMemberStatus::Reserved;
    }
    else
    {
        returnResult.Status = XblMultiplayerSessionMemberStatus::Inactive;
    }
    xsapi_internal_string gamertag, deviceToken, nat;
    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "gamertag", gamertag));
    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "deviceToken", deviceToken));
    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "nat", nat));
    utils::strcpy(returnResult.Gamertag, sizeof(returnResult.Gamertag), gamertag.c_str());
    utils::strcpy(returnResult.DeviceToken.Value, sizeof(returnResult.DeviceToken.Value), deviceToken.c_str());
    returnResult.Nat = Serializers::MultiplayerNatSettingFromString(nat);
    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonBool(json, "turn", returnResult.IsTurnAvailable));

    if (json.IsObject() && json.HasMember("roles"))
    {
        const JsonValue& rolesJson = json["roles"];
        if (!rolesJson.IsNull() && rolesJson.IsObject())
        {
            for (const auto& rolePair : rolesJson.GetObject())
            {
                XblMultiplayerSessionMemberRole role{};
                role.roleTypeName = Make(rolePair.name.GetString());
                role.roleName = Make(rolePair.value.GetString());
                returnResultInternal->m_roles.push_back(std::move(role));
            }
            returnResult.Roles = returnResultInternal->m_roles.data();
            returnResult.RolesCount = returnResultInternal->m_roles.size();
        }
    }

    xsapi_internal_string titleIdString;
    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "activeTitleId", titleIdString));
    if (!titleIdString.empty())
    {
        returnResult.ActiveTitleId = utils::internal_string_to_uint32(titleIdString);
    }

    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonTimeT(json, "joinTime", returnResult.JoinTime));
    xsapi_internal_string initializationFailure;
    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonString(json, "initializationFailure", initializationFailure))
    returnResult.InitializationFailureCause = Serializers::MultiplayerMeasurementFailureFromString(initializationFailure);
    RETURN_HR_IF_FAILED(JsonUtils::ExtractJsonInt(json, "initializationEpisode", returnResult.InitializationEpisode));

    return returnResult;
}