You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
PlumberUltimateAds/Assets/GoogleSigninSDK/PlayerPrefsSyncManager.cs

228 lines
5.7 KiB
C#

using UnityEngine;
using PlayFab;
using PlayFab.ClientModels;
using System.Collections;
using System.Collections.Generic;
public class PlayerPrefsSyncManager : MonoBehaviour
{
public static PlayerPrefsSyncManager instance;
private const int MaxKeysPerRequest = 10;
private static float syncDelay = 3f;
private static float syncTimer = 0f;
private static bool syncPending = false;
private Coroutine periodicSyncCoroutine;
private void Awake()
{
if (instance == null)
{
instance = this;
DontDestroyOnLoad(this.gameObject);
Application.wantsToQuit += OnWantsToQuit;
}
else
{
Destroy(gameObject);
}
}
private void Start()
{
periodicSyncCoroutine = StartCoroutine(PeriodicSyncCoroutine());
}
private void Update()
{
if (syncPending)
{
syncTimer -= Time.unscaledDeltaTime;
if (syncTimer <= 0f)
{
syncPending = false;
Debug.Log("🌀 Debounced sync triggered.");
StartCoroutine(SyncCoroutine());
}
}
}
public static void RequestSync()
{
if (!instance) return;
syncTimer = syncDelay;
syncPending = true;
}
private bool OnWantsToQuit()
{
if (PlayFabClientAPI.IsClientLoggedIn())
{
StartCoroutine(SyncThenQuit());
return false;
}
return true;
}
private void OnApplicationPause(bool pause)
{
if (pause)
{
Debug.Log("📱 App paused — syncing.");
StartCoroutine(SyncCoroutine());
}
}
private IEnumerator PeriodicSyncCoroutine()
{
float interval = 120f; // 3 minutes
while (true)
{
yield return new WaitForSecondsRealtime(interval);
if (PlayFabClientAPI.IsClientLoggedIn())
{
Debug.Log("⏰ Periodic sync triggered.");
yield return SyncCoroutine();
}
}
}
private IEnumerator SyncThenQuit()
{
bool isDone = false;
SyncPlayerPrefsToPlayFab(() =>
{
isDone = true;
});
float timeout = 5f;
float timer = 0f;
while (!isDone && timer < timeout)
{
timer += Time.unscaledDeltaTime;
yield return null;
}
#if UNITY_EDITOR
UnityEditor.EditorApplication.isPlaying = false;
#else
Application.Quit();
#endif
}
private IEnumerator SyncCoroutine()
{
bool isDone = false;
SyncPlayerPrefsToPlayFab(() =>
{
isDone = true;
});
float timeout = 5f;
float timer = 0f;
while (!isDone && timer < timeout)
{
timer += Time.unscaledDeltaTime;
yield return null;
}
}
public void SyncPlayerPrefsToPlayFab(System.Action onComplete = null)
{
if (!PlayFabClientAPI.IsClientLoggedIn())
{
onComplete?.Invoke();
return;
}
var keys = PlayerPrefsKeys.GetAllKeys();
if (keys.Count == 0)
{
Debug.Log("No PlayerPrefs keys registered, skipping sync.");
onComplete?.Invoke();
return;
}
Dictionary<string, string> allPrefs = new Dictionary<string, string>();
foreach (var key in keys)
{
string strVal = PlayerPrefs.GetString(key, "__MISSING__");
if (strVal != "__MISSING__")
{
allPrefs[key] = "string:" + strVal;
continue;
}
int intVal = PlayerPrefs.GetInt(key, int.MinValue + 1);
if (intVal != int.MinValue + 1)
{
allPrefs[key] = "int:" + intVal;
continue;
}
float floatVal = PlayerPrefs.GetFloat(key, float.MinValue + 1);
if (floatVal != float.MinValue + 1)
{
allPrefs[key] = "float:" + floatVal.ToString("R");
}
}
// Batch in chunks of 10
var batches = new List<Dictionary<string, string>>();
var currentBatch = new Dictionary<string, string>();
foreach (var pair in allPrefs)
{
currentBatch[pair.Key] = pair.Value;
if (currentBatch.Count == MaxKeysPerRequest)
{
batches.Add(currentBatch);
currentBatch = new Dictionary<string, string>();
}
}
if (currentBatch.Count > 0)
{
batches.Add(currentBatch);
}
UploadPlayerPrefsBatches(batches, 0, onComplete);
}
private void UploadPlayerPrefsBatches(List<Dictionary<string, string>> batches, int index, System.Action onComplete)
{
if (index >= batches.Count)
{
Debug.Log("✅ All PlayerPrefs batches synced to PlayFab.");
onComplete?.Invoke();
return;
}
var request = new UpdateUserDataRequest
{
Data = batches[index],
Permission = UserDataPermission.Public
};
PlayFabClientAPI.UpdateUserData(request,
result =>
{
Debug.Log($"✅ Synced batch {index + 1}/{batches.Count}");
UploadPlayerPrefsBatches(batches, index + 1, onComplete);
},
error =>
{
Debug.LogError($"❌ Failed to sync batch {index + 1}/{batches.Count}: {error.GenerateErrorReport()}");
onComplete?.Invoke(); // Fail fast or add retry logic
});
}
}