ذخیره ابری بازی

ذخیره اطلاعات، پیشرفت و امتیازات کاربر بین هربار بازی کردن امری معمول در تمامی بازی هاست. اما مشکلی که ممکن است پیش بیاید این است که اگر کاربر بازی را پاک کند یا روی یک دستگاه دیگر بخواهد از ادامه آن روند یا مرحله ای که رفته است بازی کند غیر ممکن می شود. اما با استفاده از بخش ذخیره ابری بازی در گیم سرویس میتوانید این اطلاعات را در فضای ابری و متصل به حساب کاربر نگهداری کنید. بدین صورت این اطلاعات همیشه و در تمامی دستگاه ها دردسترس خواهد بود. در ادامه به توابع کار با ذخیره ابری بازی با استفاده از گیم سرویس میپردازیم:

نکات
  • این سرویس به شما کمک می کند تا هر نوع داده ای تا سقف 128 کیلوبایت را به ازای هر کاربر ذخیره کنید.
  • هر کاربر می تواند تا سقف ۳ سیو با نام های مختلف ذخیره کند. اگر تعداد سیو با نام جدید بیشتر شود خطای save_limited را دریافت خواهید کرد.
ذخیره کردن (Save)

با استفاده از این تابع می توانید یک مدل یا نوع داده ای یا کلاس را به راحتی سیو کنید.

توجه کنید که هر بار که یک کاربر سیو را انجام می دهد، سیو قبلی پاک خواهد شد و این سیو به جای آن قرار خواهد گرفت.

await GameService.Save.SaveGame(saveName,saveObj)
ورودی ها
  1. saveName: نام سیو (اجباری)
  2. saveObj: شی مورد نظر جهت سیو (اجباری)
خروجی

در نتیجه هم کلاس SaveDetails که شامل اطلاعات سیو است به شما برگرداننده می شود.

/// <summary>
///     With this command you can save your Current Status in Game
/// </summary>
/// <param name="saveName">saveGameName</param>
/// <param name="saveObj">the Object that you Want To Save it</param>
/// <value> return SaveDetails </value>
Task<SaveDetails> SaveGame(string saveName, object saveObj);
دریافت ذخیره بازی

با این تابع می توانید ذخیره بازی کاربر را دریافت کنید. در نتیجه این دستور مقادیر مربوط به ذخیره بازخواهد گشت. برای دریافت کلاسی که در هنگامی ذخیره سازی به تابع وارد کرده اید میتوانید با مشخص کردن کلاس مورد نظر در قسمت T همان کلاس را دریافت کنید.

await GameService.Save.GetSaveGame<T>(saveName);
ورودی
  1. saveName: نام سیو (اجباری)
خروجی

در خروجی همان کلاسی که در T تعریف کرده اید به شما برگرداننده می شود. توجه کنید که مقدار T در اصل تایپ همان کلاسی است که یک مقدار از آن را در مرحله قبل سیو کرده اید.

/// <summary>
///     This command will get you save by Name
/// </summary>
/// <param name="saveName">(NOTNULL)the Name that you want to get it</param>
/// <value> return Player Save </value>
Task<T> GetSaveGame<T>(string saveName);
پاکسازی ذخیره بازی

با این دستور می توانید ذخیره کاربر فعلی را حذف کنید.

await GameService.Save.RemoveSave(saveName);
ورودی
  1. saveName: نام سیو (اجباری)
خروجی

درصورتیکه عملیات حذف موفقیت آمیز باشد ، مقدار true بازخواهد گشت.

/// <summary>
///     This command will remove save
/// </summary>
/// <param name="saveName">(NOTNULL)the Name that you want to remove it</param>
/// <value> return true if Remove Successfully </value>
Task<bool> RemoveSave(string saveName);
نمونه کد

در این نمونه قصد داریم امتیاز کاربر فعلی را دریافت کنیم و یک مقدار به آن اضافه کرده و آن را مجددا سیو کنیم.

ابتدا یک مدل به نام SaveModel به صورت زیر می سازیم:

[Serializable]
class SaveModel
{
  [JsonProperty("n")]
  public string name;
         
  [JsonProperty("s")]
  public int? score;
 }
نکات
  • بهتر است تمامی پروپرتی ها به صورت Nullable تعریف شوند. چون زمانی که نیاز است که فقط نام بروز شود اگر مقدار امتیاز ست نشود، زمانی که سیو می کنید مقدار آن ۰ خواهد شد. ولی اگر به صورت Nullable تعریف شود مقدار آن تغییر نخواهد کرد. توجه کنید که string ذاتا Nullable است. اما مقدایر دیگر باید با علامت ؟ تنظیم شوند. به عنوان مثال به score دقت کنید که مقدار عدد int به صورت Nullable تعریف شده است.
  • بهتر است کلاسی که برای سیو استفاده می شود از SerializableAttribute استفاده کند.
  • پلاگین از کتابخانه Newtonsoft.Json استفاده می کند. برای همین شما می توانید برای هر یک از پروپرتی های داخل کلاس یک نام دیگر قرار دهید تا در سرور با نام های دیگر سیو شود(برای افزایش امنیت و کاهش حجم). به عنوان مثال شی ذخیره شده کد پایین به صورت زیر خواهد بود:
var saveFile = new SaveModel {name = "Ali", score = 10};

و شی سیو شده در سرور:

{
  "n": "Ali" , "s": 10
}

کل نمونه سیو به صورت زیر است:

private async Task TestSave()
    {
    try
     {
      var lastSave = 
     await GameService.Save.GetSaveGame<SaveModel>("save_main");
      
      lastSave.score += 1;
      
      await GameService.Save.SaveGame("save_main", lastSave);
      }
 catch (Exception e)
  {
    if (e is GameServiceException)
   {
     if (e.Message == GameServiceErrors.Http.Save.SaveNotfound)
       {
      var saveFile = new SaveModel {name = "Ali", score = 10};
      await GameService.Save.SaveGame("save_main", saveFile);
        }
    }
  }
 }

توجه کنید که ممکن است در اولین زمانی که سیو را دریافت می کنید به دلیل اینکه سیوی وجود ندارد خطا دریافت کنید. برای همین با توجه به بخش های قبلی، خطا را باید در بلاک try - catch هندل کنید. همچنین خطا های پلاگین تمامی از نوع GameServiceException هستند، پس اول چک می کنیم که خطا از آن نوع باشند.

سپس با چک کردن متن خطا با کلاس خطا های گیم سرویس (GameServiceErrors)، بخش Save، بررسی می کنیم که آیا خطا از نوع پیدا نکردن سیو است یا خیر. اگر از آن نوع بود یک سیو جدید با مقدار ۱۰ بوجود می آوریم.

در نتیجه در سیو های بعدی دیگر سیو وجود دارد و فقط مقدار قبلی خوانده شده و یک عدد به امتیاز کاربر اضافه شده و سیو خواهد شد.