无法在Google Play游戏服务中保存快照

时间:2016-03-19 12:33:23

标签: c++ ios google-play-games

我在iOS上实现savedgame。

https://developers.google.com/games/services/cpp/savedgames

但无法保存快照,前提是在Google Play控制台上启用保存的游戏并成功登录过程。

2016-03-19 20:27:15.512 Ojichu[6912:2130626] Creating new snapshot
2016-03-19 20:27:28.106 Ojichu[6912:2130626] new snapshot name is: ojimon_19700101090000
2016-03-19 20:27:28.107 Ojichu[6912:2130626] Saving Snapshot ojimon_19700101090000
2016-03-19 20:27:28.107 Ojichu[6912:2130626] desc
2016-03-19 20:27:28.108 Ojichu[6912:2130626] ERROR: Invalid filename ojimon_19700101090000: not opening.
2016-03-19 20:27:28.116 Ojichu[6912:2130626] Creating new snapshot
2016-03-19 20:27:35.164 Ojichu[6912:2130626] new snapshot name is: ojimon_19700101090000
2016-03-19 20:27:35.165 Ojichu[6912:2130626] Saving Snapshot ojimon_19700101090000
2016-03-19 20:27:35.166 Ojichu[6912:2130626] desc
2016-03-19 20:27:35.166 Ojichu[6912:2130626] ERROR: Invalid filename ojimon_19700101090000: not opening.
2016-03-19 20:27:37.632 Ojichu[6912:2130626] ERROR_INTERNAL
2016-03-19 20:27:41.663 Ojichu[6912:2130626] ERROR_INTERNAL
2016-03-19 20:27:41.664 Ojichu[6912:2131093] VERBOSE: Snapshot cache fully expired: refreshing all.
2016-03-19 20:27:43.590 Ojichu[6912:2131155] VERBOSE: Download file request: <NSMutableURLRequest: 0x175612630> { URL: https://doc-10-5c-docs.googleusercontent.com/docs/securesc/33he8l9b76c43lgcbshrpvv8v4q7ph0p/h1d7ha0sijr8a0afqi58e1vk50sb1c0d/1458381600000/14598062468829450291/14598062468829450291/1MBK837eoIA8e6iQ4iYtRW-cNgLJCXDGUb7ntuIxfqO__SOPtJjYI_ubJzQuyCbBjo7zYxsk?e=download&gd=true }
2016-03-19 20:27:43.591 Ojichu[6912:2131155] VERBOSE: Download file response: <NSHTTPURLResponse: 0x17623dfc0> { URL: https://doc-10-5c-docs.googleusercontent.com/docs/securesc/33he8l9b76c43lgcbshrpvv8v4q7ph0p/h1d7ha0sijr8a0afqi58e1vk50sb1c0d/1458381600000/14598062468829450291/14598062468829450291/1MBK837eoIA8e6iQ4iYtRW-cNgLJCXDGUb7ntuIxfqO__SOPtJjYI_ubJzQuyCbBjo7zYxsk?e=download&gd=true } { status code: 200, headers {
"Access-Control-Allow-Origin" = "*";
"Cache-Control" = "private, max-age=0";
"Content-Disposition" = "attachment;filename=\"save_19700101090000\";filename*=UTF-8''save_19700101090000";
"Content-Length" = 0;
"Content-Type" = "application/vnd.google-play-games.snapshot-initial";
Date = "Sat, 19 Mar 2016 11:27:43 GMT";
Expires = "Sat, 19 Mar 2016 11:27:43 GMT";
Server = UploadServer;
"access-control-allow-credentials" = false;
"access-control-allow-headers" = "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, GData-Version, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-ClientDetails, X-GData-Client, X-GData-Key, X-Goog-AuthUser, X-Goog-PageId, X-Goog-Encode-Response-If-Executable, X-Goog-Correlation-Id, X-Goog-Request-Info, X-Goog-Experiments, x-goog-iam-authority-selector, x-goog-iam-authorization-token, X-Goog-Spatula, X-Goog-Upload-Command, X-Goog-Upload-Content-Disposition, X-Goog-Upload-Content-Length, X-Goog-Upload-Content-Type, X-Goog-Upload-File-Name, X-Goog-Upload-Offset, X-Goog-Upload-Protocol, X-Goog-Visitor-Id, X-HTTP-Method-Override, X-JavaScript-User-Agent, X-Pan-Versionid, X-Origin, X-Referer, X-Upload-Content-Length, X-Upload-Content-Type, X-Use-HTTP-Status-Code-Override, X-YouTube-VVT, X-YouTube-Page-CL, X-YouTube-Page-Timestamp";
"access-control-allow-methods" = "GET,OPTIONS";
"alt-svc" = "quic=\":443\"; ma=2592000; v=\"31,30,29,28,27,26,25\"";
"alternate-protocol" = "443:quic,p=1";
"x-guploader-uploadid" = "AEnB2Urbfr6ZC5ugHKhy7J4rRs991A5BWbqobZzKEBPRBIhnY-fL5j4dGLouLw60b1URXquBsNm-1LTP0FRM-aGxqN9Vh-OVWg";
} }
2016-03-19 20:27:43.593 Ojichu[6912:2131155] VERBOSE: Download file file name: /var/mobile/Containers/Data/Application/3FC79FFD-1D7A-4827-9A62-08FDD8B15361/Library/Application Support/jp.usaya.Ojichu/snapshots/fe3b73dcc261e238df050ffc3a02fe24
2016-03-19 20:27:43.599 Ojichu[6912:2131093] VERBOSE: Merging new snapshot: no entry for save_19700101090000.
2016-03-19 20:27:51.235 Ojichu[6912:2130626] ERROR_INTERNAL

我的代码在

下面
/* Copyright (c) 2014 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "StateManager.h"

#ifdef __APPLE__
//
//Logging for CoreFoundation
//
#include <CoreFoundation/CoreFoundation.h>
extern "C" void NSLog(CFStringRef format, ...);
const int32_t BUFFER_SIZE = 256;
#define LOGI(...) {char c[BUFFER_SIZE];\
    snprintf(c,BUFFER_SIZE,__VA_ARGS__);\
    CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, c, kCFStringEncodingMacRoman);\
    NSLog(str);\
    CFRelease(str);\
    }
#else
#include "android/log.h"
#define DEBUG_TAG "TeapotNativeActivity"
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG, __VA_ARGS__))

#endif

StateManager* StateManager::_instance = nullptr;

void StateManager::onAuthActionFinished(gpg::AuthOperation op, gpg::AuthStatus status)
{
    LOGI("OnAuthActionFinished");
    switch (status) {
        case gpg::AuthStatus::VALID:
            LOGI("Signed In");
            break;
        case gpg::AuthStatus::ERROR_INTERNAL:
        case gpg::AuthStatus::ERROR_NOT_AUTHORIZED:
        case gpg::AuthStatus::ERROR_VERSION_UPDATE_REQUIRED:
        case gpg::AuthStatus::ERROR_TIMEOUT:
        default:
            LOGI("Sign-in failure");
            break;
    }
}

void StateManager::onAuthActionStarted(gpg::AuthOperation op)
{
    LOGI("OnAuthActionStarted");
    switch (op) {
        case gpg::AuthOperation::SIGN_IN:
            LOGI("Signing In");
            break;
        case gpg::AuthOperation::SIGN_OUT:
            LOGI("Signing Out");
            break;
    }
}

gpg::GameServices *StateManager::getGameServices()
{
    return _gameServices.get();
}

void StateManager::beginUserInitiatedSignIn()
{
    if (!_gameServices->IsAuthorized()) {
        LOGI("StartAuthorizationUI");
        _gameServices->StartAuthorizationUI();
    }
}

void StateManager::signOut()
{
    if (_gameServices->IsAuthorized()) {
        LOGI("SignOut");
        _gameServices->SignOut();
    }
}

void StateManager::initServices(gpg::PlatformConfiguration &pc)
{
    LOGI("Initializing Services");
    LOGI(pc.Valid()? "configuration is valid":"configuration is invalid");
    if (!_gameServices) {
        LOGI("Uninitialized services, so creating");
        _gameServices = gpg::GameServices::Builder()
        .SetOnAuthActionStarted([this]( gpg::AuthOperation op ){
            LOGI("Sign in started");
            this->onAuthActionStarted(op);
        })
        .SetOnAuthActionFinished([this](gpg::AuthOperation op, gpg::AuthStatus status){
            LOGI("Sign in finished with a result of %d", status);
            _isSignedIn = status == gpg::AuthStatus::VALID;
            this->onAuthActionFinished(op, status);
        })
        .SetDefaultOnLog(gpg::LogLevel::VERBOSE)
        .EnableSnapshots()
        .Create(pc);
    }
    LOGI("Created");
}

void StateManager::committedSnapshot(gpg::SnapshotManager::CommitResponse const & response)
{
    switch (response.status) {
        case gpg::ResponseStatus::VALID:
            LOGI("Snapshot CommitResponse VALID");
            break;
        case gpg::ResponseStatus::VALID_BUT_STALE:
            LOGI("Snapshot CommitResponse VALID_BUT_STALE");
            break;
        case gpg::ResponseStatus::ERROR_LICENSE_CHECK_FAILED:
            LOGI("Snapshot CommitResponse ERROR_LICENSE_CHECK_FAILED");
            break;
        case gpg::ResponseStatus::ERROR_INTERNAL:
            LOGI("Snapshot CommitResponse ERROR_INTERNAL");
            break;
        case gpg::ResponseStatus::ERROR_NOT_AUTHORIZED:
            LOGI("Snapshot CommitResponse ERROR_NOT_AUTHORIZED");
            break;
        case gpg::ResponseStatus::ERROR_VERSION_UPDATE_REQUIRED:
            LOGI("Snapshot CommitResponse ERROR_VERSION_UPDATE_REQUIRED");
            break;
        case gpg::ResponseStatus::ERROR_TIMEOUT:
            LOGI("Snapshot CommitResponse ERROR_TIMEOUT");
            break;
        default:
            break;
    }
}

void StateManager::loadedSnapshot(gpg::SnapshotManager::ReadResponse const & response)
{
    switch (response.status) {
        case gpg::ResponseStatus::VALID:
            LOGI("Snapshot CommitResponse VALID");
            break;
        case gpg::ResponseStatus::VALID_BUT_STALE:
            LOGI("Snapshot CommitResponse VALID_BUT_STALE");
            break;
        case gpg::ResponseStatus::ERROR_LICENSE_CHECK_FAILED:
            LOGI("Snapshot CommitResponse ERROR_LICENSE_CHECK_FAILED");
            break;
        case gpg::ResponseStatus::ERROR_INTERNAL:
            LOGI("Snapshot CommitResponse ERROR_INTERNAL");
            break;
        case gpg::ResponseStatus::ERROR_NOT_AUTHORIZED:
            LOGI("Snapshot CommitResponse ERROR_NOT_AUTHORIZED");
            break;
        case gpg::ResponseStatus::ERROR_VERSION_UPDATE_REQUIRED:
            LOGI("Snapshot CommitResponse ERROR_VERSION_UPDATE_REQUIRED");
            break;
        case gpg::ResponseStatus::ERROR_TIMEOUT:
            LOGI("Snapshot CommitResponse ERROR_TIMEOUT");
            break;
        default:
            break;
    }
}

void StateManager::selectedSnapshot(gpg::SnapshotManager::SnapshotSelectUIResponse const & response)
{
    switch (response.status) {
        case gpg::UIStatus::VALID:
        {
            if ( response.data.Valid() )
            {
                _currentSnapshot = response.data.FileName();
                if (_gameServices)
                {
                    LOGI("Loading Snapshot %s",_currentSnapshot.c_str());
                    _gameServices->Snapshots().Open(response.data.FileName(),
                                                    gpg::SnapshotConflictPolicy::LONGEST_PLAYTIME,
                                                    [this](gpg::SnapshotManager::OpenResponse const & response) {
                                                        LOGI("Reading file");
                                                        _gameServices->Snapshots().Read(response.data,
                                                                                        std::bind(&StateManager::loadedSnapshot, this,
                                                                                                  std::placeholders::_1));
                                                   });
                }
            } else {
                LOGI("Creating new snapshot");
                _currentSnapshot.clear();
                std::string str = "aaaaaaaaaaaa";
                auto tp = std::chrono::system_clock::now();
                auto d = tp.time_since_epoch();
                auto m = std::chrono::duration_cast<std::chrono::milliseconds>(d);
                std::vector<uint8_t> png;
                std::vector<uint8_t> data(str.begin(),str.end());
                saveSnapshot("desc", m, png, data);
            }
            break;
        }
        case gpg::UIStatus::ERROR_INTERNAL:
            LOGI("Snapshot SelectUIResponse ERROR_INTERNAL");
            break;
        case gpg::UIStatus::ERROR_NOT_AUTHORIZED:
            LOGI("Snapshot SelectUIResponse ERROR_NOT_AUTHORIZED");
            break;
        case gpg::UIStatus::ERROR_VERSION_UPDATE_REQUIRED:
            LOGI("Snapshot SelectUIResponse ERROR_VERSION_UPDATE_REQUIRED");
            break;
        case gpg::UIStatus::ERROR_TIMEOUT:
            LOGI("Snapshot SelectUIResponse ERROR_TIMEOUT");
            break;
        case gpg::UIStatus::ERROR_CANCELED:
            LOGI("Snapshot SelectUIResponse ERROR_CANCELED");
            break;
        case gpg::UIStatus::ERROR_UI_BUSY:
            LOGI("Snapshot SelectUIResponse ERROR_UI_BUSY");
            break;
        case gpg::UIStatus::ERROR_LEFT_ROOM:
            LOGI("Snapshot SelectUIResponse ERROR_LEFT_ROOM");
            break;
        default:
            break;
    }
}

void StateManager::saveSnapshot(std::string description,
                                std::chrono::milliseconds playtime,
                                std::vector<uint8_t> png_data,
                                std::vector<uint8_t> snapData)
{
    if (_gameServices)
    {
        //if we do not have current snapshot we generate the filename
        if (_currentSnapshot.empty())
        {

            std::chrono::system_clock::time_point today = std::chrono::system_clock::now();
            std::time_t tt = std::chrono::system_clock::to_time_t ( today );

            //using strftime
            time_t rawtime;
            struct tm * timeinfo;
            char buffer [32];

            time (&tt);
            timeinfo = localtime (&rawtime);

            strftime (buffer,32,"save_%Y%m%d%H%M%S",timeinfo);

            //put_time not available in GCC < 5.0
            //std::ostringstream snapshot_name;
            //snapshot_name << std::put_time(ctime(&tt),"save_%Y%m%d%H%M%S");
            _currentSnapshot.assign(buffer,32);
            LOGI("new snapshot name is: %s",_currentSnapshot.c_str());
        }

        LOGI("Saving Snapshot %s",_currentSnapshot.c_str());
        LOGI("%s",description.c_str());

        _gameServices->Snapshots().Open(_currentSnapshot,
                                       gpg::SnapshotConflictPolicy::LONGEST_PLAYTIME,
                                       [this, description, playtime, png_data, snapData](gpg::SnapshotManager::OpenResponse const &response)
                                       {
                                           gpg::SnapshotMetadata metadata;
                                           if (IsSuccess(response.status)) { // Always failure
                                               metadata = response.data;
                                               gpg::SnapshotMetadataChange::Builder builder;
                                               if ( description != metadata.Description())
                                               {
                                                   builder.SetDescription(description);
                                               }
                                               if ( playtime != metadata.PlayedTime())
                                               {
                                                   builder.SetPlayedTime(static_cast<gpg::Duration>(playtime));
                                               }
                                               if ( ! png_data.empty() )
                                               {
                                                   builder.SetCoverImageFromPngData(png_data);
                                               }
                                               gpg::SnapshotMetadataChange metadata_change = builder.Create();
                                               _gameServices->Snapshots().Commit(
                                                   metadata,
                                                   metadata_change,
                                                   snapData,
                                                   std::bind(&StateManager::committedSnapshot,this,std::placeholders::_1));

                                           }
                                       });
    }
}

void StateManager::selectSnapshot(std::string title, uint32_t max_snapshots, bool allow_create, bool allow_delete)
{
    if (_gameServices)
    {
        LOGI("Listing Snapshot");
        LOGI("%s",title.c_str());
        _gameServices->Snapshots().ShowSelectUIOperation(allow_create,
                                                         allow_delete,
                                                         max_snapshots,
                                                         title,
                                                         std::bind(&StateManager::selectedSnapshot, this,
                                                                   std::placeholders::_1));
    }
}

有没有人解决这个问题?

0 个答案:

没有答案
相关问题