diff --git a/Assets/Talo Game Services/Talo/Runtime/APIs/EventsAPI.cs b/Assets/Talo Game Services/Talo/Runtime/APIs/EventsAPI.cs index 040212d..a1fea15 100644 --- a/Assets/Talo Game Services/Talo/Runtime/APIs/EventsAPI.cs +++ b/Assets/Talo Game Services/Talo/Runtime/APIs/EventsAPI.cs @@ -10,10 +10,10 @@ public class EventsAPI : BaseAPI { public event Action OnFlushed; - private List queue = new (); + internal List queue = new (); private readonly int minQueueSize = 10; - private List eventsToFlush = new (); + internal List eventsToFlush = new (); private bool lockFlushes; private bool flushAttemptedDuringLock; @@ -118,5 +118,13 @@ public async Task Flush() await Flush(); } } + + public void ClearQueue() + { + queue.Clear(); + eventsToFlush.Clear(); + lockFlushes = false; + flushAttemptedDuringLock = false; + } } } diff --git a/Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs b/Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs index 16b3551..31a606d 100644 --- a/Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs +++ b/Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs @@ -10,6 +10,7 @@ public class PlayersAPI : BaseAPI public event Action OnIdentified; public event Action OnIdentificationStarted; public event Action OnIdentificationFailed; + public event Action OnIdentityCleared; private readonly string _offlineDataPath = Application.persistentDataPath + "/ta.bin"; @@ -82,6 +83,8 @@ public async Task IdentifySteam(string ticket, string identity = "") public async Task Update() { + Talo.IdentityCheck(); + var uri = new Uri($"{baseUrl}/{Talo.CurrentPlayer.id}"); var content = JsonUtility.ToJson(Talo.CurrentPlayer); var json = await Call(uri, "PATCH", Prop.SanitiseJson(content)); @@ -146,6 +149,50 @@ private PlayerAlias GetOfflineAlias() return JsonUtility.FromJson(Talo.Crypto.ReadFileContent(_offlineDataPath)); } + private void DeleteOfflineAlias() + { + if (File.Exists(_offlineDataPath)) + { + try + { + File.Delete(_offlineDataPath); + } + catch (Exception e) + { + Debug.LogWarning($"Failed to delete offline player data: {e.Message}"); + } + } + } + + public async Task ClearIdentity() + { + Talo.IdentityCheck(); + + try + { + DeleteOfflineAlias(); + } + catch (Exception e) + { + Debug.LogWarning($"Error deleting offline alias: {e.Message}"); + } + + try + { + // clears the alias and resets the socket (doesn't require auth) + await Talo.PlayerAuth.SessionManager.ClearSession(); + } + catch (Exception ex) + { + Debug.LogWarning($"Error clearing session: {ex.Message}"); + } + + Talo.Events.ClearQueue(); + Talo.Continuity.ClearRequests(); + + OnIdentityCleared?.Invoke(); + } + public async Task Search(string query) { var encodedQuery = Uri.EscapeDataString(query.Trim()); diff --git a/Assets/Talo Game Services/Talo/Runtime/Utils/ContinuityManager.cs b/Assets/Talo Game Services/Talo/Runtime/Utils/ContinuityManager.cs index 450b1e3..a775cce 100644 --- a/Assets/Talo Game Services/Talo/Runtime/Utils/ContinuityManager.cs +++ b/Assets/Talo Game Services/Talo/Runtime/Utils/ContinuityManager.cs @@ -116,5 +116,11 @@ public async void ProcessRequests() throw new ContinuityReplayException(exceptions); } } + + public void ClearRequests() + { + _requests.Clear(); + WriteRequests(); + } } } diff --git a/Assets/Talo Game Services/Talo/Tests/PlayersAPI.meta b/Assets/Talo Game Services/Talo/Tests/PlayersAPI.meta new file mode 100644 index 0000000..599a9ad --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/PlayersAPI.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c816a5a6b8ada4ac79eb218804974767 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Talo Game Services/Talo/Tests/PlayersAPI/ClearIdentityTest.cs b/Assets/Talo Game Services/Talo/Tests/PlayersAPI/ClearIdentityTest.cs new file mode 100644 index 0000000..4618cc5 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/PlayersAPI/ClearIdentityTest.cs @@ -0,0 +1,54 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine.TestTools; +using UnityEngine; +using System.Threading.Tasks; + +namespace TaloGameServices.Test +{ + internal class IdentityClearedEventMock + { + public bool identityCleared = false; + + public void Invoke() + { + identityCleared = true; + } + } + + internal class ClearIdentityTest + { + [OneTimeSetUp] + public void Setup() + { + var tm = new GameObject().AddComponent(); + tm.settings = ScriptableObject.CreateInstance(); + tm.settings.autoConnectSocket = false; + + Talo.CurrentAlias = new PlayerAlias() { + player = new Player() { + id = "uuid" + } + }; + } + + [UnityTest] + public IEnumerator ClearIdentity_ShouldClearAliasData() + { + var eventMock = new IdentityClearedEventMock(); + Talo.Players.OnIdentityCleared += eventMock.Invoke; + + yield return Talo.Events.Track("test-event"); + Assert.IsNotEmpty(Talo.Events.queue); + + Talo.Players.ClearIdentity(); + Assert.IsNull(Talo.CurrentAlias); + Assert.IsTrue(eventMock.identityCleared); + Assert.IsEmpty(Talo.Events.queue); + Assert.IsEmpty(Talo.Events.eventsToFlush); + Assert.IsFalse(Talo.Continuity.HasRequests()); + + Talo.Players.OnIdentityCleared -= eventMock.Invoke; + } + } +} \ No newline at end of file diff --git a/Assets/Talo Game Services/Talo/Tests/PlayersAPI/ClearIdentityTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/PlayersAPI/ClearIdentityTest.cs.meta new file mode 100644 index 0000000..9fc9497 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/PlayersAPI/ClearIdentityTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 0205d8a1513404df3b96bd2f31b471ad \ No newline at end of file