807 lines
31 KiB
C#
Raw Normal View History

2025-09-19 14:56:58 +05:00
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;
using static BulletHellTemplate.FirebaseManager;
namespace BulletHellTemplate
{
/// <summary>
/// Handles saving and retrieving player local data such as name, icon, frame, and character upgrades using PlayerPrefs.
/// </summary>
public class PlayerSave : MonoBehaviour
{
//Account
private const string PlayerNamePrefix = "PLAYERNAME_";
private const string PlayerIconPrefix = "PLAYERICON_";
private const string PlayerFramePrefix = "PLAYERFRAME_";
private const string PlayerAccountLevelPrefix = "PLAYERACCOUNTLEVEL_";
private const string PlayerAccountCurrentExpPrefix = "PLAYERACCOUNTCURRENTEXP_";
private const string TutorialIsDonePrefix = "TUTORIALISDONE_";
//Character
private const string PlayerSelectedCharacterPrefix = "PLAYERSELECTEDCHARACTER_";
private const string PlayerFavouriteCharacterPrefix = "PLAYERFAVOURITECHARACTER_";
private const string CharacterMasteryLevelPrefix = "CHARACTERMASTERYLEVEL_";
private const string CharacterMasteryCurrentExpPrefix = "CHARACTERMASTERYCURRENTEXP_";
private const string CharacterLevelPrefix = "CHARACTERLEVEL_";
private const string CharacterCurrentExpPrefix = "CHARACTERCURRENTEXP_";
private const string CharacterSlotPrefix = "ITEMSLOT_";
private const string ItemLevelPrefix = "ITEMLEVEL_";
private const string CharacterUpgradeLevelPrefix = "CHARACTERUPGRADELEVEL_";
private const string CharacterSkinPrefix = "CHARACTERSKIN_";
private const string CharacterUnlockedSkinsPrefix = "CHARACTERUNLOCKEDSKINS_";
//Progress
private const string UnlockedMapsKey = "UNLOCKED_MAPS";
private const string QuestProgressPrefix = "QUEST_PROGRESS_";
private const string QuestCompletionPrefix = "QUEST_COMPLETED_";
private const string UsedCouponsKey = "USED_COUPONS_";
private const string DailyRewardsKey = "LOCAL_DAILYREWARDS_DATA";
private const string NewPlayerRewardsKey = "LOCAL_NEWPLAYERREWARDS_DATA";
private const string NextDailyResetKey = "NEXTDAILYRESETTIME";
private static bool isLoading = false;
public static void SetLoadingState(bool state)
{
isLoading = state;
}
#region Account Functions
/// <summary>
/// Sets the player's name in PlayerPrefs.
/// </summary>
/// <param name="playerName">The name of the player.</param>
public static void SetPlayerName(string playerName)
{
PlayerPrefs.SetString(PlayerNamePrefix, playerName);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the player's name from PlayerPrefs.
/// </summary>
/// <returns>The name of the player.</returns>
public static string GetPlayerName()
{
return PlayerPrefs.GetString(PlayerNamePrefix);
}
/// <summary>
/// Sets the player's icon in PlayerPrefs.
/// </summary>
/// <param name="playerIcon">The icon of the player.</param>
public static void SetPlayerIcon(string playerIcon)
{
PlayerPrefs.SetString(PlayerIconPrefix, playerIcon);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the player's icon from PlayerPrefs.
/// </summary>
/// <returns>The icon of the player.</returns>
public static string GetPlayerIcon()
{
return PlayerPrefs.GetString(PlayerIconPrefix);
}
/// <summary>
/// Sets the player's frame in PlayerPrefs.
/// </summary>
/// <param name="playerFrame">The frame of the player.</param>
public static void SetPlayerFrame(string playerFrame)
{
PlayerPrefs.SetString(PlayerFramePrefix, playerFrame);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the player's frame from PlayerPrefs.
/// </summary>
/// <returns>The frame of the player.</returns>
public static string GetPlayerFrame()
{
return PlayerPrefs.GetString(PlayerFramePrefix);
}
public static void SetAccountLevel(int level)
{
PlayerPrefs.SetInt(PlayerAccountLevelPrefix, level);
PlayerPrefs.Save();
}
public static int GetAccountLevel()
{
return PlayerPrefs.GetInt(PlayerAccountLevelPrefix, 1);
}
public static void SetAccountCurrentExp(int currentExp)
{
PlayerPrefs.SetInt(PlayerAccountCurrentExpPrefix, currentExp);
PlayerPrefs.Save();
}
public static int GetAccountCurrentExp()
{
return PlayerPrefs.GetInt(PlayerAccountCurrentExpPrefix, 0);
}
#endregion
#region Characters Functions
/// <summary>
/// Sets the selected character's ID in PlayerPrefs.
/// </summary>
/// <param name="characterId">The ID of the selected character.</param>
public static void SetSelectedCharacter(int characterId)
{
PlayerPrefs.SetInt(PlayerSelectedCharacterPrefix, characterId);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the selected character's ID from PlayerPrefs.
/// If no character is selected, returns the first unlocked character's ID.
/// </summary>
/// <returns>The ID of the selected or first unlocked character.</returns>
public static int GetSelectedCharacter()
{
if (PlayerPrefs.HasKey(PlayerSelectedCharacterPrefix))
{
return PlayerPrefs.GetInt(PlayerSelectedCharacterPrefix);
}
else
{
if (GameInstance.Singleton != null && GameInstance.Singleton.characterData != null)
{
foreach (CharacterData character in GameInstance.Singleton.characterData)
{
if (character.CheckUnlocked)
{
return character.characterId;
}
}
}
Debug.LogError("No unlocked characters available to select.");
return -1;
}
}
/// <summary>
/// Sets the favourite character's ID in PlayerPrefs.
/// </summary>
/// <param name="characterId">The ID of the favourite character.</param>
public static void SetFavouriteCharacter(int characterId)
{
PlayerPrefs.SetInt(PlayerFavouriteCharacterPrefix, characterId);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the favourite character's ID from PlayerPrefs.
/// If no favourite character is set, returns 0.
/// </summary>
/// <returns>The ID of the favourite character or 0 if not set.</returns>
public static int GetFavouriteCharacter()
{
if (PlayerPrefs.HasKey(PlayerFavouriteCharacterPrefix))
{
return PlayerPrefs.GetInt(PlayerFavouriteCharacterPrefix);
}
return 0;
}
/// <summary>
/// Sets the level for the specified character.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <param name="level">The level to set.</param>
public static void SetCharacterLevel(int characterId, int level)
{
PlayerPrefs.SetInt(CharacterLevelPrefix + characterId, level);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the level of the specified character.
/// Returns 1 if the key does not exist.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <returns>The character level.</returns>
public static int GetCharacterLevel(int characterId)
{
return PlayerPrefs.GetInt(CharacterLevelPrefix + characterId, 1);
}
/// <summary>
/// Sets the current experience for the specified character.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <param name="currentExp">The current experience to set.</param>
public static void SetCharacterCurrentExp(int characterId, int currentExp)
{
PlayerPrefs.SetInt(CharacterCurrentExpPrefix + characterId, currentExp);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the current experience of the specified character.
/// Returns 0 if the key does not exist.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <returns>The current experience.</returns>
public static int GetCharacterCurrentExp(int characterId)
{
return PlayerPrefs.GetInt(CharacterCurrentExpPrefix + characterId, 0);
}
/// <summary>
/// Sets the mastery level for the specified character.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <param name="masteryLevel">The mastery level to set.</param>
public static void SetCharacterMasteryLevel(int characterId, int masteryLevel)
{
PlayerPrefs.SetInt(CharacterMasteryLevelPrefix + characterId, masteryLevel);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the mastery level of the specified character.
/// Returns 0 if the key does not exist.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <returns>The mastery level.</returns>
public static int GetCharacterMasteryLevel(int characterId)
{
return PlayerPrefs.GetInt(CharacterMasteryLevelPrefix + characterId, 0);
}
/// <summary>
/// Sets the current mastery experience for the specified character.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <param name="masteryCurrentExp">The current mastery experience to set.</param>
public static void SetCharacterCurrentMasteryExp(int characterId, int masteryCurrentExp)
{
PlayerPrefs.SetInt(CharacterMasteryCurrentExpPrefix + characterId, masteryCurrentExp);
PlayerPrefs.Save();
}
/// <summary>
/// Gets the current mastery experience of the specified character.
/// Returns 0 if the key does not exist.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <returns>The current mastery experience.</returns>
public static int GetCharacterCurrentMasteryExp(int characterId)
{
return PlayerPrefs.GetInt(CharacterMasteryCurrentExpPrefix + characterId, 0);
}
/// <summary>
/// Sets the unique GUID of the item equipped in a specific slot of a given character.
/// Example key: "CharSlot_{characterId}_{slotName}"
/// </summary>
/// <param name="characterId">The ID of the character.</param>
/// <param name="slotName">The slot name (e.g. "WeaponSlot").</param>
/// <param name="uniqueItemGuid">The unique ID of the item, or empty to unequip.</param>
public static void SetCharacterSlotItem(int characterId, string slotName, string uniqueItemGuid)
{
string key = $"{CharacterSlotPrefix}{characterId}_{slotName}";
PlayerPrefs.SetString(key, uniqueItemGuid);
PlayerPrefs.Save();
}
/// <summary>
/// Returns the unique GUID of the item equipped in the specified slot for the given character.
/// Returns an empty string if none is equipped.
/// </summary>
/// <param name="characterId">The ID of the character.</param>
/// <param name="slotName">The slot name.</param>
/// <returns>The unique item GUID, or empty if none.</returns>
public static string GetCharacterSlotItem(int characterId, string slotName)
{
string key = $"{CharacterSlotPrefix}{characterId}_{slotName}";
return PlayerPrefs.GetString(key, string.Empty);
}
/// <summary>
/// Saves the upgrade level for a purchased item identified by its unique GUID.
/// Example key: "ItemLevel_{uniqueItemGuid}"
/// </summary>
/// <param name="uniqueItemGuid">Unique identifier of the purchased item.</param>
/// <param name="level">Current upgrade level.</param>
public static void SetItemUpgradeLevel(string uniqueItemGuid, int level)
{
string key = $"{ItemLevelPrefix}{uniqueItemGuid}";
PlayerPrefs.SetInt(key, level);
PlayerPrefs.Save();
}
/// <summary>
/// Retrieves the upgrade level for a purchased item identified by its unique GUID.
/// Returns 0 if not found.
/// </summary>
/// <param name="uniqueItemGuid">Unique identifier of the purchased item.</param>
/// <returns>Upgrade level if present, otherwise 0.</returns>
public static int GetItemUpgradeLevel(string uniqueItemGuid)
{
string key = $"{ItemLevelPrefix}{uniqueItemGuid}";
return PlayerPrefs.GetInt(key, 0);
}
public static void SetCharacterSkin(int characterId, int skinIndex)
{
PlayerPrefs.SetInt(CharacterSkinPrefix + characterId, skinIndex);
PlayerPrefs.Save();
}
public static int GetCharacterSkin(int characterId)
{
string key = CharacterSkinPrefix + characterId;
return PlayerPrefs.HasKey(key) ? PlayerPrefs.GetInt(key) : -1;
}
/// <summary>
/// Saves the unlocked skins for a character locally.
/// </summary>
/// <param name="characterId">Unique identifier for the character.</param>
/// <param name="unlockedSkins">List of unlocked skin indices.</param>
public static void SaveCharacterUnlockedSkins(int characterId, List<int> unlockedSkins)
{
UnlockedSkinsData data = new UnlockedSkinsData { unlockedSkins = unlockedSkins };
string json = JsonUtility.ToJson(data);
PlayerPrefs.SetString(CharacterUnlockedSkinsPrefix + characterId, json);
PlayerPrefs.Save();
}
/// <summary>
/// Loads the unlocked skins for a character from local storage.
/// </summary>
/// <param name="characterId">Unique identifier for the character.</param>
/// <returns>List of unlocked skin indices. Returns an empty list if no data is found.</returns>
public static List<int> LoadCharacterUnlockedSkins(int characterId)
{
string key = CharacterUnlockedSkinsPrefix + characterId;
if (PlayerPrefs.HasKey(key))
{
string json = PlayerPrefs.GetString(key);
UnlockedSkinsData data = JsonUtility.FromJson<UnlockedSkinsData>(json);
if (data != null && data.unlockedSkins != null)
{
return data.unlockedSkins;
}
}
return new List<int>();
}
/// <summary>
/// Saves the initial upgrade level (0) for the specified character's stat type.
/// </summary>
/// <param name="characterId">The character identifier.</param>
/// <param name="statType">The stat type.</param>
public static void SaveInitialCharacterUpgradeLevel(int characterId, StatType statType)
{
string key = $"{CharacterUpgradeLevelPrefix}{characterId}_{statType}";
PlayerPrefs.SetInt(key, 0);
PlayerPrefs.Save();
}
public static void SaveCharacterUpgradeLevel(int characterId, StatType statType, int level)
{
string key = $"{CharacterUpgradeLevelPrefix}{characterId}_{statType}";
PlayerPrefs.SetInt(key, level);
PlayerPrefs.Save();
if (!isLoading && BackendManager.Singleton.CheckInitialized())
{
BackendManager.Singleton.StartCoroutine(SaveCharacterUpgradesAsyncCoroutine(characterId));
}
}
private static IEnumerator SaveCharacterUpgradesAsyncCoroutine(int characterId)
{
var upgrades = LoadAllCharacterUpgradeLevels(characterId);
var task = BackendManager.Singleton.SaveCharacterUpgradesAsync(characterId.ToString(), upgrades);
yield return new WaitUntil(() => task.IsCompleted);
if (task.Exception != null)
{
Debug.LogError($"Failed to save character upgrades for {characterId}: {task.Exception}");
}
}
public static int LoadCharacterUpgradeLevel(int characterId, StatType statType)
{
string key = $"{CharacterUpgradeLevelPrefix}{characterId}_{statType}";
return PlayerPrefs.GetInt(key, 0);
}
public static Dictionary<StatType, int> LoadAllCharacterUpgradeLevels(int characterId)
{
Dictionary<StatType, int> upgradeLevels = new Dictionary<StatType, int>();
foreach (StatType statType in System.Enum.GetValues(typeof(StatType)))
{
upgradeLevels[statType] = LoadCharacterUpgradeLevel(characterId, statType);
}
return upgradeLevels;
}
public static void ResetCharacterUpgrades(int characterId)
{
foreach (StatType statType in System.Enum.GetValues(typeof(StatType)))
{
string key = $"{CharacterUpgradeLevelPrefix}{characterId}_{statType}";
if (PlayerPrefs.HasKey(key))
{
PlayerPrefs.DeleteKey(key);
}
}
PlayerPrefs.Save();
}
#endregion
/// <summary>
/// Clears the unlocked maps in PlayerPrefs.
/// </summary>
public static void ClearUnlockedMaps()
{
PlayerPrefs.DeleteKey(UnlockedMapsKey);
PlayerPrefs.Save();
Debug.Log("Local unlocked maps have been cleared.");
}
/// <summary>
/// Sets the unlocked maps in PlayerPrefs and optionally saves them to the database if initialized.
/// </summary>
/// <param name="unlockedMapIds">A list of map IDs that are unlocked.</param>
public static void SetUnlockedMaps(List<int> unlockedMapIds)
{
string mapIdsString = string.Join(",", unlockedMapIds);
PlayerPrefs.SetString(UnlockedMapsKey, mapIdsString);
PlayerPrefs.Save();
if (BackendManager.Singleton.CheckInitialized())
{
BackendManager.Singleton.SaveUnlockedMapsAsync().ContinueWith(task =>
{
if (task.IsFaulted)
{
Debug.LogError("Failed to save unlocked maps to backend: " + task.Exception);
}
});
}
}
/// <summary>
/// Gets the unlocked maps from PlayerPrefs.
/// </summary>
/// <returns>A list of map IDs that are unlocked.</returns>
public static List<int> GetUnlockedMaps()
{
string mapIdsString = PlayerPrefs.GetString(UnlockedMapsKey, "");
if (string.IsNullOrEmpty(mapIdsString))
{
return new List<int>();
}
string[] mapIdsArray = mapIdsString.Split(',');
List<int> unlockedMapIds = new List<int>();
foreach (string id in mapIdsArray)
{
if (int.TryParse(id, out int mapId))
{
unlockedMapIds.Add(mapId);
}
}
return unlockedMapIds;
}
/// <summary>
/// Saves the progress of a quest both locally and in backend if initialized.
/// </summary>
/// <param name="questId">The ID of the quest.</param>
/// <param name="progress">The progress value to save.</param>
public static void SaveQuestProgress(int questId, int progress)
{
// Save the quest progress locally
PlayerPrefs.SetInt($"{QuestProgressPrefix}{questId}", progress);
PlayerPrefs.Save();
if (BackendManager.Singleton.CheckInitialized())
{
BackendManager.Singleton.StartCoroutine(SaveQuestProgressToBackendCoroutine(questId, progress));
}
}
/// <summary>
/// Coroutine to save quest progress to Backend.
/// </summary>
/// <param name="questId">The ID of the quest.</param>
/// <param name="progress">The progress value to save.</param>
/// <returns>IEnumerator for coroutine execution.</returns>
private static IEnumerator SaveQuestProgressToBackendCoroutine(int questId, int progress)
{
var task = BackendManager.Singleton.SaveQuestProgressAsync(questId, progress);
yield return new WaitUntil(() => task.IsCompleted);
if (task.Exception != null)
{
Debug.LogError($"Failed to save quest progress for {questId}: {task.Exception}");
}
}
/// <summary>
/// Loads the progress of a quest.
/// </summary>
/// <param name="questId">The ID of the quest.</param>
/// <returns>The saved progress value.</returns>
public static int LoadQuestProgress(int questId)
{
return PlayerPrefs.GetInt($"{QuestProgressPrefix}{questId}", 0); // Default to 0 if not set
}
/// <summary>
/// Saves the completion status of a quest both locally and in Backend if initialized.
/// </summary>
/// <param name="questId">The ID of the quest.</param>
public static void SaveQuestCompletion(int questId)
{
// Save the quest completion status locally
PlayerPrefs.SetInt($"{QuestCompletionPrefix}{questId}", 1);
PlayerPrefs.Save();
if (BackendManager.Singleton.CheckInitialized())
{
BackendManager.Singleton.StartCoroutine(SaveQuestCompletionToBackendCoroutine(questId));
}
}
/// <summary>
/// Coroutine to save quest completion to Backend.
/// </summary>
/// <param name="questId">The ID of the quest.</param>
/// <returns>IEnumerator for coroutine execution.</returns>
private static IEnumerator SaveQuestCompletionToBackendCoroutine(int questId)
{
var task = BackendManager.Singleton.SaveQuestCompletionAsync(questId);
yield return new WaitUntil(() => task.IsCompleted);
if (task.Exception != null)
{
Debug.LogError($"Failed to save quest completion for {questId}: {task.Exception}");
}
}
/// <summary>
/// Checks if a quest is completed.
/// </summary>
/// <param name="questId">The ID of the quest.</param>
/// <returns>True if the quest is completed, false otherwise.</returns>
public static bool IsQuestCompleted(int questId)
{
return PlayerPrefs.GetInt($"{QuestCompletionPrefix}{questId}", 0) == 1;
}
/// <summary>
/// Clears the local progress and completion status of daily quests stored in PlayerPrefs.
/// </summary>
public static void ClearLocalDayleQuestProgress()
{
QuestItem[] quests = GameInstance.Singleton.questData;
foreach (var quest in quests)
{
if (quest.questType == QuestType.Daily)
{
// Clear progress for the daily quest
PlayerPrefs.DeleteKey($"{QuestProgressPrefix}{quest.questId}");
// Clear completion status for the daily quest
PlayerPrefs.DeleteKey($"{QuestCompletionPrefix}{quest.questId}");
}
}
PlayerPrefs.Save();
Debug.Log("Local daily quest progress and completion status cleared.");
}
/// <summary>
/// Saves the completion time of a quest locally in PlayerPrefs using a provided server time.
/// </summary>
/// <param name="questId">The ID of the quest.</param>
/// <param name="completionTime">The completion time of the quest, provided by the server.</param>
public static void SaveQuestCompletionTime(int questId, DateTime completionTime)
{
string key = $"QUEST_COMPLETION_TIME_{questId}";
// Save the provided completion time as a string in the format "yyyy-MM-dd HH:mm:ss"
string formattedTime = completionTime.ToString("yyyy-MM-dd HH:mm:ss");
PlayerPrefs.SetString(key, formattedTime);
PlayerPrefs.Save();
Debug.Log($"Quest {questId} completion time saved locally: {formattedTime}");
}
/// <summary>
/// Marks a coupon as used by saving its ID in PlayerPrefs and in the backend if initialized.
/// </summary>
/// <param name="couponId">The unique ID of the coupon.</param>
public static void MarkCouponAsUsed(string couponId)
{
List<string> usedCoupons = GetUsedCoupons();
if (!usedCoupons.Contains(couponId))
{
usedCoupons.Add(couponId);
SaveUsedCoupons(usedCoupons);
if (BackendManager.Singleton.CheckInitialized())
{
BackendManager.Singleton.StartCoroutine(SaveUsedCouponCoroutine(couponId));
}
}
}
/// <summary>
/// Coroutine to save the used coupon via the BackendManager.
/// </summary>
/// <param name="couponId">The unique ID of the coupon.</param>
/// <returns>IEnumerator for coroutine execution.</returns>
private static IEnumerator SaveUsedCouponCoroutine(string couponId)
{
Task saveTask = BackendManager.Singleton.SaveUsedCouponAsync(couponId);
yield return new WaitUntil(() => saveTask.IsCompleted);
if (saveTask.Exception != null)
{
Debug.LogError($"Failed to save used coupon {couponId} via BackendManager: {saveTask.Exception}");
}
else
{
Debug.Log($"Coupon {couponId} marked as used and saved via BackendManager successfully.");
}
}
/// <summary>
/// Checks if a coupon has already been used.
/// </summary>
/// <param name="couponId">The unique ID of the coupon.</param>
/// <returns>True if the coupon has been used, false otherwise.</returns>
public static bool IsCouponUsed(string couponId)
{
List<string> usedCoupons = GetUsedCoupons();
return usedCoupons.Contains(couponId);
}
/// <summary>
/// Saves the list of used coupons locally using PlayerPrefs.
/// </summary>
/// <param name="usedCoupons">A list of used coupon IDs.</param>
public static void SaveUsedCoupons(List<string> usedCoupons)
{
string couponsString = string.Join(",", usedCoupons);
PlayerPrefs.SetString(UsedCouponsKey, couponsString);
PlayerPrefs.Save();
}
/// <summary>
/// Retrieves the list of used coupons from PlayerPrefs.
/// </summary>
/// <returns>A list of used coupon IDs.</returns>
public static List<string> GetUsedCoupons()
{
string couponsString = PlayerPrefs.GetString(UsedCouponsKey, string.Empty);
return new List<string>(couponsString.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
}
/// <summary>
/// Saves daily rewards data locally in JSON form.
/// </summary>
public static void SetDailyRewardsLocal(DailyRewardsData data)
{
string json = JsonUtility.ToJson(data);
PlayerPrefs.SetString(DailyRewardsKey, json);
PlayerPrefs.Save();
}
/// <summary>
/// Retrieves the locally saved daily rewards data. Returns defaults if not found.
/// </summary>
public static DailyRewardsData GetDailyRewardsLocal()
{
if (!PlayerPrefs.HasKey(DailyRewardsKey))
{
return new DailyRewardsData();
}
string json = PlayerPrefs.GetString(DailyRewardsKey);
DailyRewardsData data = JsonUtility.FromJson<DailyRewardsData>(json);
return data ?? new DailyRewardsData();
}
/// <summary>
/// Saves new player rewards data locally in JSON form.
/// </summary>
public static void SetNewPlayerRewardsLocal(NewPlayerRewardsData data)
{
string json = JsonUtility.ToJson(data);
PlayerPrefs.SetString(NewPlayerRewardsKey, json);
PlayerPrefs.Save();
}
/// <summary>
/// Retrieves the locally saved new player rewards data. Returns defaults if not found.
/// </summary>
public static NewPlayerRewardsData GetNewPlayerRewardsLocal()
{
if (!PlayerPrefs.HasKey(NewPlayerRewardsKey))
{
return new NewPlayerRewardsData();
}
string json = PlayerPrefs.GetString(NewPlayerRewardsKey);
NewPlayerRewardsData data = JsonUtility.FromJson<NewPlayerRewardsData>(json);
return data ?? new NewPlayerRewardsData();
}
/// <summary>
/// Saves the next daily reset DateTime as a string.
/// </summary>
public static void SetNextDailyReset(DateTime nextReset)
{
// Convert to ticks or string
long ticks = nextReset.Ticks;
PlayerPrefs.SetString(NextDailyResetKey, ticks.ToString());
PlayerPrefs.Save();
}
/// <summary>
/// Retrieves the next daily reset DateTime.
/// </summary>
public static DateTime GetNextDailyReset()
{
if (!PlayerPrefs.HasKey(NextDailyResetKey))
return DateTime.MinValue;
string ticksString = PlayerPrefs.GetString(NextDailyResetKey);
if (long.TryParse(ticksString, out long ticks))
{
return new DateTime(ticks);
}
return DateTime.MinValue;
}
/// <summary>
/// Simple data structure to hold daily rewards info for local save.
/// </summary>
[Serializable]
public class DailyRewardsData
{
public DateTime firstClaimDate;
public List<int> claimedRewards = new List<int>();
}
/// <summary>
/// Simple data structure to hold new player rewards info for local save.
/// </summary>
[Serializable]
public class NewPlayerRewardsData
{
public DateTime accountCreationDate;
public List<int> claimedRewards = new List<int>();
}
[Serializable]
private class UnlockedSkinsData
{
public List<int> unlockedSkins;
}
}
}