playgameservices / play-games-plugin-for-unity

Google Play Games plugin for Unity
Other
3.47k stars 966 forks source link

GMPM Saved Games issue #1531

Open vidicunt opened 7 years ago

vidicunt commented 7 years ago

Whenever I try to upload saved game, I get this error in logcat:

Uploading is not possible. App measurement disabled

claywilkinson commented 7 years ago

Can you share more of the log? It will help diagnose the issue.

vidicunt commented 7 years ago

That's all the log will show me, just this one error.

EDIT: @claywilkinson 12-24 00:58:50.190 I/GMPM (8164): App measurement is starting up 12-24 00:58:50.220 E/GMPM (8164): getGoogleAppId failed with status: 10 12-24 00:58:50.225 E/GMPM (8164): Uploading is not possible. App measurement disabled

claywilkinson commented 7 years ago

What about when you sign in? Did you authenticate successfully? This message has nothing to do with SaveGamesAPI.

vidicunt commented 7 years ago

@claywilkinson Yes, I'm 100% sure signing in is working fine. This error ONLY appears when I try to upload saved games.

claywilkinson commented 7 years ago

Can you share the complete log? This message has nothing to do with Saved Games.

ColmLeonard commented 7 years ago

I've been trying to get cloud saving working for a few weeks now and at one point it seemed to be working and it hasn't worked since. I am no programming wiz and I have no idea how to fix the problem. I have taken snippets from the how to on this and from some other places and I just cant figure it out. It signs in fine and still does now but wont save or load anymore.

An error ive gotten from my phone recently: Failed to read binary data: System.runtime.serializationException: serializationStream supports seeking, but its length is 0

As I said im no expert and ive used code examples from the how to and all over the place..

Code:

using GooglePlayGames; using GooglePlayGames.BasicApi; using GooglePlayGames.BasicApi.SavedGame; using System; using System.Collections; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using UnityEngine; using UnityEngine.UI;

[Serializable] public class CloudData {

public int Level = 0;
public int Score = 0;
public int Dragons = 0;

// Convert class instance to byte array
public static byte[] ToBytes(CloudData data)
{

    var formatter = new BinaryFormatter();

    using (var stream = new MemoryStream())
    {

        formatter.Serialize(stream, data);
        return stream.ToArray();
    }
}

// Convert byte array to class instance
public static CloudData FromBytes(byte[] data)
{

    using (var stream = new MemoryStream())
    {

        var formatter = new BinaryFormatter();
        stream.Write(data, 0, data.Length);
        stream.Seek(0, SeekOrigin.Begin);

        CloudData block = (CloudData)formatter.Deserialize(stream);
        return block;
    }
}

}

public class CloudSaver : MonoBehaviour {

// Variables
bool userSignedIn = false;
ISavedGameMetadata currentGame = null;

public static CloudSaver singleton;

public Text UserT, DebugT, LevelT, ScoreT, DragonsT;
private string saveString = "GPGStestSave2";

public int level = 0, score = 0, dragons = 0;

void GetUI()
{
    UserT = GameObject.Find("UserName").GetComponent<Text>();
    DebugT = GameObject.Find("DebugInfo").GetComponent<Text>();
    LevelT = GameObject.Find("Level").GetComponent<Text>();
    ScoreT = GameObject.Find("Score").GetComponent<Text>();
    DragonsT = GameObject.Find("Dragons").GetComponent<Text>();
}
void Awake()
{
    Environment.SetEnvironmentVariable("MONO_REFLECTION_SERIALIZER", "yes");
    GetUI();
}

// Use this for initialization
void Start()
{

    InitPlayServices();
    singleton = this;

    PlayGamesPlatform.Instance.Authenticate(CallbackSignInUser,true);
}

void Update()
{
    LevelT.text = level.ToString();
    ScoreT.text = score.ToString();
    DragonsT.text = dragons.ToString();
}

// Initialize google play services
void InitPlayServices()
{

    PlayGamesClientConfiguration config = new PlayGamesClientConfiguration.Builder()
        .EnableSavedGames()
        .Build();

    PlayGamesPlatform.InitializeInstance(config);
    PlayGamesPlatform.DebugLogEnabled = true;
    PlayGamesPlatform.Activate();
}

// Sign in the user
public void SignInUser()
{

    if (!userSignedIn)
        PlayGamesPlatform.Instance.Authenticate(CallbackSignInUser);
    else
    {

        PlayGamesPlatform.Instance.SignOut();

    }
}

// The sign in callback
void CallbackSignInUser(bool success)
{

    if (success)
    {
        userSignedIn = true;
        UserT.text = "Signed In As: " + Social.localUser.userName;
        LoadGame();
    }
    else { userSignedIn = false; UserT.text = "Failed To Log In!"; }

}

// Read the save game
void ReadSaveGame(string filename, Action<SavedGameRequestStatus, ISavedGameMetadata> callback)
{

    // Check if signed in
    if (userSignedIn)
    {

        ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;

        savedGameClient.OpenWithAutomaticConflictResolution(filename,
            DataSource.ReadCacheOrNetwork,
            ConflictResolutionStrategy.UseLongestPlaytime,
            callback);
    }
}

// Write the save game
void WriteSaveGame(ISavedGameMetadata game, byte[] savedData, Action<SavedGameRequestStatus, ISavedGameMetadata> callback)
{

    // Check if signed in
    if (userSignedIn)
    {

        SavedGameMetadataUpdate updatedMetadata = new SavedGameMetadataUpdate.Builder()
            .WithUpdatedPlayedTime(TimeSpan.FromMinutes(game.TotalTimePlayed.Minutes + 1))
            .WithUpdatedDescription("Saved at: " + DateTime.Now)
            .Build();

        ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.CommitUpdate(game, updatedMetadata, savedData, callback);
    }
}

// Save the game
public void SaveGame()
{

    // Check if signed in
    if (userSignedIn)
    {

        // Save game callback
        Action<SavedGameRequestStatus, ISavedGameMetadata> writeCallback =
            (SavedGameRequestStatus status, ISavedGameMetadata game) => {

            };

        // Read binary callback
        Action<SavedGameRequestStatus, byte[]> readBinaryCallback =
            (SavedGameRequestStatus status, byte[] data) => {

                // Create new save data
                CloudData CloudSaveData = CloudData.FromBytes(data);

                // These values are hard coded for the purpose of this tutorial.
                // Normally, you would replace these values with whatever you want to save.
                CloudSaveData.Level += 1;
                CloudSaveData.Score += 10;
                CloudSaveData.Dragons += 2;

                WriteSaveGame(currentGame, CloudData.ToBytes(CloudSaveData), writeCallback);

            };

        // Read game callback
        Action<SavedGameRequestStatus, ISavedGameMetadata> readCallback =
            (SavedGameRequestStatus status, ISavedGameMetadata game) => {

                // Check if read was successful
                if (status == SavedGameRequestStatus.Success)
                {

                    currentGame = game;
                    PlayGamesPlatform.Instance.SavedGame.ReadBinaryData(game, readBinaryCallback);
                }
            };

        // Replace "MySaveGame" with whatever you would like to save file to be called
        ReadSaveGame(saveString, readCallback);

    }
}

// Load the game
public void LoadGame()
{

    // Check if signed in
    if (userSignedIn)
    {

        // Read binary callback
        Action<SavedGameRequestStatus, byte[]> readBinaryCallback =
            (SavedGameRequestStatus status, byte[] data) => {

                // Check if read was successful
                if (status == SavedGameRequestStatus.Success)
                {

                    // Load game data
                    try
                    {

                        CloudData CloudData = CloudData.FromBytes(data);

                        // We are displaying these values for the purpose of the tutorial.
                        // Normally you would set the values here.
                        level = CloudData.Level;
                        score = CloudData.Score;
                        dragons = CloudData.Dragons;
                    }

                    catch (Exception e)
                    {

                        DebugT.text = ("Failed to read binary data: " + e.ToString());
                    }
                }
            };

        // Read game callback
        Action<SavedGameRequestStatus, ISavedGameMetadata> readCallback =
            (SavedGameRequestStatus status, ISavedGameMetadata game) => {

                // Check if read was successful
                if (status == SavedGameRequestStatus.Success)
                {

                    currentGame = game;
                    PlayGamesPlatform.Instance.SavedGame.ReadBinaryData(game, readBinaryCallback);
                }else
                {
                    currentGame = game;
                    PlayGamesPlatform.Instance.SavedGame.ReadBinaryData(game, readBinaryCallback);
                }
            };

        // Replace "MySaveGame" with whatever you would like to save file to be called
        ReadSaveGame(saveString, readCallback);
    }
}

//delete save
public void DeleteGameData()
{

    // Open the file to get the metadata.
    ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
    savedGameClient.OpenWithAutomaticConflictResolution(saveString, DataSource.ReadCacheOrNetwork,
        ConflictResolutionStrategy.UseLongestPlaytime, DeleteSavedGame);
}

void DeleteSavedGame(SavedGameRequestStatus status, ISavedGameMetadata game)
{
    if (status == SavedGameRequestStatus.Success)
    {
        ISavedGameClient savedGameClient = PlayGamesPlatform.Instance.SavedGame;
        savedGameClient.Delete(game);
        DebugT.text = "Save Deleted!";
    }
    else
    {
        // handle error
        DebugT.text = "Error Deleting Save!";
    }
}

}

Please some help would be appreciated

claywilkinson commented 7 years ago

@ColmLeonard - can you open a separate issue and include the log from when you are authenticating on the device to when it tries to read your saved game?

Can you check for success in readBinaryCallback before reading the bytes? From the error message your getting it looks like that is failing, or it is reading an empty save game.