1using PM.horizOn.Cloud.Objects.Network.Requests;
2using UnityEngine;
3using PM.horizOn.Cloud.Core;
4using PM.horizOn.Cloud.Manager;
5
6// Existing SDK/project configuration and authenticated player session required.
7// Call RunReviewedAction explicitly after reviewing this example and its data.
8// 먼저 스냅샷을 읽고 재시도 시 같은 작업 ID와 원래 보고를 유지하세요. 만료되거나 불확실한 결과는 확인이 필요하며 새 ID를
9// 자동으로 생성하면 안 됩니다.
10// This explicit action reports the shown persisted batch.
11public sealed class StatisticsDemo : MonoBehaviour
12{
13 public async void RunReviewedAction()
14 {
15 var sessionUser = UserManager.Instance.CurrentUser;
16 if (sessionUser == null || !sessionUser.IsValid()) return;
17 var manager = StatisticsManager.Instance;
18 var snapshot = await manager.GetStatistics();
19 if (snapshot == null) { Debug.LogWarning(manager.LastErrorCode); return; }
20 string pendingKey = "horizOn_statistics_pending_" + snapshot.userId;
21 var pending = PlayerPrefs.HasKey(pendingKey)
22 ? JsonUtility.FromJson<UpdateStatisticsRequest>(PlayerPrefs.GetString(pendingKey))
23 : new UpdateStatisticsRequest {
24 userId = snapshot.userId, operationId = manager.CreateOperationId(),
25 updates = new[] { new StatisticUpdate("kills", 3), new StatisticUpdate("best_score", 250) }
26 };
27 string originalJson = JsonUtility.ToJson(pending);
28 PlayerPrefs.SetString(pendingKey, originalJson);
29 PlayerPrefs.Save();
30 var result = await manager.UpdateStatistics(pending.updates, pending.operationId);
31 if (result == null) {
32 // Keep the saved ID and batch. Reconcile OPERATION_EXPIRED before a new logical report.
33 Debug.LogWarning(manager.LastErrorCode);
34 return;
35 }
36 // A late success for O1 must never acknowledge a newer pending O2.
37 if (PlayerPrefs.GetString(pendingKey, null) == originalJson) {
38 PlayerPrefs.DeleteKey(pendingKey);
39 PlayerPrefs.Save();
40 }
41 foreach (var counter in result.values) Debug.Log(counter.key + "=" + counter.value);
42 }
43}