playgameservices / play-games-plugin-for-unity

Google Play Games plugin for Unity
Other
3.46k stars 964 forks source link

Save only update to cloud if i delete the current one before. #3070

Open ShiverPurple opened 3 years ago

ShiverPurple commented 3 years ago

Here's how my code works: I open the game for the first time > save the local data > make a copy of this data > send the new copied data to cloud. I open the game for the second time > make a copy from the cloud to local save > load the local data.

When i immediately uninstall the game after the first save and download it again, it works just fine. The problem begins after the first save, although it ovewrites the data locally, the new one won't update to the cloud service, so if the game saves multiple times, only the first save - the first ever - counts when loading data from cloud in a fresh install.

As soon as i delete the copy that'll be sent to the cloud, and a new save is created instead of ovewriting the old one on the temporary local file, the new one updates to the cloud.

Here's the code:

Save method

public void SaveToCloud()
    {

        PlayService.Instance.OpenCloudSave(OnSaveResponse);

    }

public void OpenCloudSave(Action<SavedGameRequestStatus,ISavedGameMetadata> callback)
    {

        PlayGamesPlatform platform = (PlayGamesPlatform)Social.Active;
        platform.SavedGame.OpenWithAutomaticConflictResolution(cloudSaveName, dataSource, ConflictResolutionStrategy.UseMostRecentlySaved, callback);

    }

private void OnSaveResponse(SavedGameRequestStatus status, ISavedGameMetadata meta)
    {
        if (status == SavedGameRequestStatus.Success)
        {
            byte[] data = SerializeState();
            SavedGameMetadataUpdate update = new SavedGameMetadataUpdate.Builder()
                .WithUpdatedDescription("Last save : " + DateTime.Now.ToString())
                .Build();

            var platform = (PlayGamesPlatform)Social.Active;
            platform.SavedGame.CommitUpdate(meta, update, data, SaveCallback);

        }
        else
        {
            OnSave?.Invoke(status);
        }

    }

private byte[] SerializeState()
    {
        if (File.Exists(Path.Combine(Application.persistentDataPath, "savetest.k")))
        {

            File.Copy(Path.Combine(Application.persistentDataPath, "savetest.k"), Path.Combine(Application.persistentDataPath, "savetestcloud.k"), true);
            file = File.Open(Path.Combine(Application.persistentDataPath, "savetestcloud.k"), FileMode.Open);
            state = formatter.Deserialize(file) as PlayerData;

            using (MemoryStream ms = new MemoryStream())
            {

                formatter.Serialize(ms, state);
                return ms.GetBuffer();

            }
        }
        else 
            return null;

    }
private void SaveCallback(SavedGameRequestStatus status, ISavedGameMetadata meta)
    {

        OnSave?.Invoke(status);

    }
lamington-david commented 3 years ago

I'm just chiming in that one of my players is encountering this issue.

It seems like the call to OpenWithAutomaticConflictResolution works the first time it's called in a session, but every subsequent call fails to work.

I suspect there's some kind of native android error that's being thrown. Logs around the second call aren't printing, but no errors are being logged from unity. Unfortunately I'm unable to get the adb logs because I don't have access to the device.