我可以在等待用户的云数据同步完成的Xbox游戏中编写保留点吗? [英] Can I program a hold point into an Xbox game that waits for a user's cloud data sync to complete?

查看:75
本文介绍了我可以在等待用户的云数据同步完成的Xbox游戏中编写保留点吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

是否可以将启动保留程序编程到Xbox游戏程序包中,以等待用户的云存储同步后再继续?我有一个HTML5游戏包,需要从Xbox Live加载要保存的数据,然后从本地存储(以JSON格式)读取数据以在启动时填充加载屏幕,而且我还必须考虑到任何错误消息,用户可能必须做出响应.同步完成后,游戏本身就会启动(但显然要等到处理好法律问题之后,因此徽标飞溅,引擎品牌,扣押咨询以及可能的FBI和ESRB通知也必须考虑在内) .如果它也有助于调查,那么在活动会话期间,数据将被正确保存,并且我可以成功地将其复制到本地应用程序存储中.另一方面,Xbox Live副本现在似乎有问题.

Is it possible to program a startup hold into an Xbox game package that waits for the user's cloud saves to sync before continuing? I have an HTML5 game package for which I require save data to be loaded from Xbox Live which is then read from local storage (in JSON format) to populate the load screen at startup, and I also have to account for any error messages for which the user may have to respond. The game itself is started up once sync is done (but obviously not until after the legal stuff has been taken care of, so logo splash, engine branding, seizure advisory and possibly also the FBI and ESRB notices also have to be taken into account). If it also helps to investigate, data is being saved properly while there's an active session and I can successfully copy it to local app storage. The Xbox Live copy, on the other hand, seems to be at issue right now.

我也没有在游戏文件中保存那么多数据-仅有五个保存位置,不包括全局配置和用户设置.基本上,我试图将每个用户的存储空间保持在创作者项目的64MB上限以下(更不用说我最初对ID @ Xbox的请求没有奏效),我希望能够实现 前提条件是,考虑到通过Bing和Google请求收到的所有相互冲突的信息,这当然是有可能的.

I'm not holding that much data in the game files, either - just five save slots not including global config and user settings. Basically I'm trying to keep the per-user storage well under the 64MB cap on creator's projects (not to mention that my initial request for ID@Xbox didn't work out) and I'm hoping to have this implemented before I even dare to resubmit. This is provided that it's even possible of course, considering all of the conflicting information I've been receiving through my Bing and Google requests.

与我最接近的是以下代码,该代码主要基于Microsoft Docs示例.这第一个块是假定,用于加载Xbox数据并将其复制到磁盘,为此,我首先需要延迟:

The closest I have come is with the following code, which is based largely on Microsoft Docs samples. This first block is what's supposed to load the Xbox data and copy it to disk, and for which I require the delay in the first place:

    public void doStartup()
    {
        getData(-1);
        for (int i = 0; i <= 5; i++)
        {
            getData(i);
        }
    }
    public async void getData(int savefileId)
    {
        var users = await Windows.System.User.FindAllAsync();

        string c_saveBlobName = "Advent";
        //string c_saveContainerDisplayName = "GameSave";
        string c_saveContainerName = "file" + savefileId;
        if (savefileId <= 0) c_saveContainerName = "config";
        if (savefileId == 0) c_saveContainerName = "global";
        GameSaveProvider gameSaveProvider;

        GameSaveProviderGetResult gameSaveTask = await GameSaveProvider.GetForUserAsync(users[0], "00000000-0000-0000-0000-00006d0be05f");
        //Parameters
        //Windows.System.User user
        //string SCID

        if (gameSaveTask.Status == GameSaveErrorStatus.Ok)
        {
            gameSaveProvider = gameSaveTask.Value;
        }
        else
        {
            return;
            //throw new Exception("Game Save Provider Initialization failed");;
        }

        //Now you have a GameSaveProvider
        //Next you need to call CreateContainer to get a GameSaveContainer

        GameSaveContainer gameSaveContainer = gameSaveProvider.CreateContainer(c_saveContainerName);
        //Parameter
        //string name (name of the GameSaveContainer Created)

        //form an array of strings containing the blob names you would like to read.
        string[] blobsToRead = new string[] { c_saveBlobName };

        // GetAsync allocates a new Dictionary to hold the retrieved data. You can also use ReadAsync
        // to provide your own preallocated Dictionary.
        GameSaveBlobGetResult result = await gameSaveContainer.GetAsync(blobsToRead);

        string loadedData = "";

        //Check status to make sure data was read from the container
        if (result.Status == GameSaveErrorStatus.Ok)
        {
            //prepare a buffer to receive blob
            IBuffer loadedBuffer;

            //retrieve the named blob from the GetAsync result, place it in loaded buffer.
            result.Value.TryGetValue(c_saveBlobName, out loadedBuffer);

            if (loadedBuffer == null)
            {

                //throw new Exception(String.Format("Didn't find expected blob \"{0}\" in the loaded data.", c_saveBlobName));

            }
            DataReader reader = DataReader.FromBuffer(loadedBuffer);
            loadedData = reader.ReadString(loadedBuffer.Length);
            if (savefileId <= 0)
            {
                try
                {
                    System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\config.json", loadedData);
                }
                catch { }
            }
            else if (savefileId == 0)
            {
                try
                {
                    System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\global.json", loadedData);
                }
                catch { }
            }
            else
            {
                try
                {
                    System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\file"+savefileId+".json", loadedData);
                }
                catch { }

            }

        }
    }

这是HTML5部分调用时应该读取的数据:

And this is what's supposed to read the data when called by the HTML5 portion:

    public string getSaveFile(int savefileId)
    {
        string data;
        if (savefileId == 0)
        {
            try
            {
                data = System.IO.File.ReadAllText(ApplicationData.Current.LocalFolder.Path + "\\global.json");
                if (data == null) data = "";
                Debug.WriteLine(data);
            }
            catch { data = ""; }
            return data;
        } else
        {
            try
            {
                data = System.IO.File.ReadAllText(ApplicationData.Current.LocalFolder.Path + "\\file" + savefileId + ".json");
                if (data == null) data = "";
                Debug.WriteLine(data);
            }
            catch { data = ""; }
            return data;
        }
    }
    public string getConfig()
    {
        string data;
        try
        {
            data = System.IO.File.ReadAllText(ApplicationData.Current.LocalFolder.Path + "\\config.json");
            if (data == null) data = "";
            Debug.WriteLine(data);
        }
        catch { data = ""; }
        return data;
    }

这是WinRT端的保存代码:

And this is the save code on the WinRT side:

    public async void doSave(int key, string data)
    {
        //Get The User
        var users = await Windows.System.User.FindAllAsync();

        string c_saveBlobName = "Advent";
        string c_saveContainerDisplayName = "GameSave";
        string c_saveContainerName = "file"+key;
        if (key == -1) c_saveContainerName = "config";
        if (key == 0) c_saveContainerName = "global";
        GameSaveProvider gameSaveProvider;

        GameSaveProviderGetResult gameSaveTask = await GameSaveProvider.GetForUserAsync(users[0], "00000000-0000-0000-0000-00006d0be05f");
        //Parameters
        //Windows.System.User user
        //string SCID

        if (gameSaveTask.Status == GameSaveErrorStatus.Ok)
        {
            gameSaveProvider = gameSaveTask.Value;
        }
        else
        {
            return;
            //throw new Exception("Game Save Provider Initialization failed");
        }

        //Now you have a GameSaveProvider (formerly ConnectedStorageSpace)
        //Next you need to call CreateContainer to get a GameSaveContainer (formerly ConnectedStorageContainer)

        GameSaveContainer gameSaveContainer = gameSaveProvider.CreateContainer(c_saveContainerName); // this will create a new named game save container with the name = to the input name
                                                                                                     //Parameter
                                                                                                     //string name

        // To store a value in the container, it needs to be written into a buffer, then stored with
        // a blob name in a Dictionary.

        DataWriter writer = new DataWriter();

        writer.WriteString(data); //some number you want to save, in this case 23.

        IBuffer dataBuffer = writer.DetachBuffer();

        var blobsToWrite = new Dictionary<string, IBuffer>();

        blobsToWrite.Add(c_saveBlobName, dataBuffer);

        GameSaveOperationResult gameSaveOperationResult = await gameSaveContainer.SubmitUpdatesAsync(blobsToWrite, null, c_saveContainerDisplayName);
        int i;
        for (i = 1; i <= 90000; i++) {}
        Debug.WriteLine("SaveProcessed");
        //IReadOnlyDictionary<String, IBuffer> blobsToWrite
        //IEnumerable<string> blobsToDelete
        //string displayName        
    }

我刚刚在主项目中添加了用户检测代码.

And I have just recently added the user detection code to the main project.

    public static async void InitializeXboxGamer(TextBlock gamerTagTextBlock)
    {
        try
        {
            XboxLiveUser user = new XboxLiveUser();
            SignInResult result = await user.SignInSilentlyAsync(Window.Current.Dispatcher);
            if (result.Status == SignInStatus.UserInteractionRequired)
            {
                result = await user.SignInAsync(Window.Current.Dispatcher);
            }
            System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\curUser.txt", user.Gamertag);
        }
        catch (Exception ex)
        {
            // TODO: log an error here
        }
    }

推荐答案

笨拙的...我发现了我的代码存在的问题.加载全局配置时,会将getData传递给负数;但是由于某种原因,它改写了应用程序数据文件,因此在我将验证更改为更加具体之后,它开始按预期工作.

Big dumb... I figured out the problem with my code. When loading the global config, getData is passed a negative one; however for some reason it was writing the app data file instead so after I changed the verification to be a little more specific it started to work as expected.

    public void doStartup()
{
    getData(-1);
    for (int i = 0; i <= 5; i++)
    {
        getData(i);
    }
}
public async void getData(int savefileId)
{
    var users = await Windows.System.User.FindAllAsync();

    string c_saveBlobName = "Advent";
    //string c_saveContainerDisplayName = "GameSave";
    string c_saveContainerName = "file" + savefileId;
    if (savefileId <= 0) c_saveContainerName = "config";
    if (savefileId == 0) c_saveContainerName = "global";
    GameSaveProvider gameSaveProvider;

    GameSaveProviderGetResult gameSaveTask = await GameSaveProvider.GetForUserAsync(users[0], "00000000-0000-0000-0000-00006d0be05f");
    //Parameters
    //Windows.System.User user
    //string SCID

    if (gameSaveTask.Status == GameSaveErrorStatus.Ok)
    {
        gameSaveProvider = gameSaveTask.Value;
    }
    else
    {
        return;
        //throw new Exception("Game Save Provider Initialization failed");;
    }

    //Now you have a GameSaveProvider
    //Next you need to call CreateContainer to get a GameSaveContainer

    GameSaveContainer gameSaveContainer = gameSaveProvider.CreateContainer(c_saveContainerName);
    //Parameter
    //string name (name of the GameSaveContainer Created)

    //form an array of strings containing the blob names you would like to read.
    string[] blobsToRead = new string[] { c_saveBlobName };

    // GetAsync allocates a new Dictionary to hold the retrieved data. You can also use ReadAsync
    // to provide your own preallocated Dictionary.
    GameSaveBlobGetResult result = await gameSaveContainer.GetAsync(blobsToRead);

    string loadedData = "";

    //Check status to make sure data was read from the container
    if (result.Status == GameSaveErrorStatus.Ok)
    {
        //prepare a buffer to receive blob
        IBuffer loadedBuffer;

        //retrieve the named blob from the GetAsync result, place it in loaded buffer.
        result.Value.TryGetValue(c_saveBlobName, out loadedBuffer);

        if (loadedBuffer == null)
        {

            //throw new Exception(String.Format("Didn't find expected blob \"{0}\" in the loaded data.", c_saveBlobName));

        }
        DataReader reader = DataReader.FromBuffer(loadedBuffer);
        loadedData = reader.ReadString(loadedBuffer.Length);
        if (savefileId <= 0)
        {
            try
            {
                System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\config.json", loadedData);
            }
            catch { }
        }
        else if (savefileId == 0)
        {
            try
            {
                System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\global.json", loadedData);
            }
            catch { }
        }
        else
        {
            try
            {
                System.IO.File.WriteAllText(ApplicationData.Current.LocalFolder.Path + "\\file"+savefileId+".json", loadedData);
            }
            catch { }

        }

    }
}

虽然我仍然需要执行延迟,但这是我讨论

I still need the execution delay though, but that's for an entirely different reason that I discuss over here.

这篇关于我可以在等待用户的云数据同步完成的Xbox游戏中编写保留点吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆