Skip to content

Commit 2ff771b

Browse files
authored
Merge pull request #178 from TaloDev/develop
Release 0.52.0
2 parents 75c4c06 + 74bf1bf commit 2ff771b

20 files changed

Lines changed: 246 additions & 38 deletions

Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace TaloGameServices
99
public class BaseAPI
1010
{
1111
// automatically updated with a pre-commit hook
12-
private const string ClientVersion = "0.51.0";
12+
private const string ClientVersion = "0.52.0";
1313

1414
protected string baseUrl;
1515

Assets/Talo Game Services/Talo/Runtime/APIs/DebouncedAPI.cs

Lines changed: 66 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,52 @@ public abstract class DebouncedAPI<TOperation> : BaseAPI where TOperation : Enum
99
{
1010
private class DebouncedOperation
1111
{
12-
public float nextUpdateTime;
13-
public bool hasPending;
12+
public float windowEndTime;
13+
public bool windowOpen;
14+
public bool hasTrailingCallQueued;
15+
public bool isExecuting;
1416
}
1517

1618
private readonly Dictionary<TOperation, DebouncedOperation> operations = new();
1719

1820
protected DebouncedAPI(string service) : base(service) { }
1921

22+
private void OpenWindow(DebouncedOperation op)
23+
{
24+
op.windowOpen = true;
25+
op.windowEndTime = Time.realtimeSinceStartup + Talo.Settings.debounceTimerSeconds;
26+
}
27+
2028
protected void Debounce(TOperation operation)
2129
{
2230
if (!operations.ContainsKey(operation))
2331
{
2432
operations[operation] = new DebouncedOperation();
2533
}
2634

27-
operations[operation].nextUpdateTime = Time.realtimeSinceStartup + Talo.Settings.debounceTimerSeconds;
28-
operations[operation].hasPending = true;
35+
var op = operations[operation];
36+
37+
if (!op.windowOpen && !op.isExecuting)
38+
{
39+
// leading call: fire immediately and open the debounce window
40+
op.hasTrailingCallQueued = false;
41+
op.isExecuting = true;
42+
OpenWindow(op);
43+
44+
ExecuteDebouncedOperation(operation).ContinueWith((t) => {
45+
op.isExecuting = false;
46+
if (t.IsFaulted)
47+
{
48+
Debug.LogError(t.Exception);
49+
}
50+
}, TaskScheduler.FromCurrentSynchronizationContext());
51+
}
52+
else
53+
{
54+
// window open or request in-flight: queue a trailing call and extend the window
55+
op.hasTrailingCallQueued = true;
56+
OpenWindow(op);
57+
}
2958
}
3059

3160
public async Task ProcessPendingUpdates()
@@ -34,16 +63,45 @@ public async Task ProcessPendingUpdates()
3463

3564
foreach (var kvp in operations)
3665
{
37-
if (kvp.Value.hasPending && Time.realtimeSinceStartup >= kvp.Value.nextUpdateTime)
66+
var op = kvp.Value;
67+
var windowClosed = Time.realtimeSinceStartup >= op.windowEndTime;
68+
if (windowClosed)
3869
{
39-
keysToProcess.Add(kvp.Key);
70+
if (op.hasTrailingCallQueued)
71+
{
72+
if (!op.isExecuting)
73+
{
74+
// window closed with a trailing call pending: execute it
75+
keysToProcess.Add(kvp.Key);
76+
}
77+
else
78+
{
79+
// leading call still in-flight: delay trailing until it completes
80+
OpenWindow(op);
81+
}
82+
}
83+
else if (op.windowOpen)
84+
{
85+
// window closed with no trailing call: reset for the next leading call
86+
op.windowOpen = false;
87+
}
4088
}
4189
}
4290

4391
foreach (var key in keysToProcess)
4492
{
45-
operations[key].hasPending = false;
46-
await ExecuteDebouncedOperation(key);
93+
var op = operations[key];
94+
op.hasTrailingCallQueued = false;
95+
op.isExecuting = true;
96+
try
97+
{
98+
await ExecuteDebouncedOperation(key);
99+
}
100+
finally
101+
{
102+
op.isExecuting = false;
103+
op.windowOpen = false;
104+
}
47105
}
48106
}
49107

Assets/Talo Game Services/Talo/Runtime/APIs/LeaderboardsAPI.cs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class GetEntriesOptions
1010
{
1111
public int page = 0;
1212
public int aliasId = -1;
13+
public string playerId = "";
1314
public bool includeArchived = false;
1415
public string propKey = "";
1516
public string propValue = "";
@@ -20,6 +21,7 @@ public string ToQueryString()
2021
{
2122
var query = new Dictionary<string, string> { ["page"] = page.ToString() };
2223
if (aliasId != -1) query["aliasId"] = aliasId.ToString();
24+
if (!string.IsNullOrEmpty(playerId)) query["playerId"] = playerId;
2325
if (includeArchived) query["withDeleted"] = "1";
2426
if (!string.IsNullOrEmpty(propKey)) query["propKey"] = propKey;
2527
if (!string.IsNullOrEmpty(propValue)) query["propValue"] = propValue;
@@ -32,7 +34,7 @@ public string ToQueryString()
3234

3335
public class LeaderboardsAPI : BaseAPI
3436
{
35-
private LeaderboardEntriesManager _entriesManager = new();
37+
private readonly LeaderboardEntriesManager _entriesManager = new();
3638

3739
public LeaderboardsAPI() : base("v1/leaderboards") { }
3840

@@ -65,6 +67,7 @@ public async Task<LeaderboardEntriesResponse> GetEntries(string internalName, Ge
6567
return res;
6668
}
6769

70+
[Obsolete("Use GetEntries(string internalName, GetEntriesOptions options) with the aliasId or playerId option instead.")]
6871
public async Task<LeaderboardEntriesResponse> GetEntriesForCurrentPlayer(string internalName, GetEntriesOptions options = null)
6972
{
7073
Talo.IdentityCheck();
@@ -86,7 +89,7 @@ public async Task<LeaderboardEntriesResponse> GetEntries(string internalName, in
8689
});
8790
}
8891

89-
[Obsolete("Use GetEntriesForCurrentPlayer(string internalName, GetEntriesOptions options) instead.")]
92+
[Obsolete("Use GetEntries(string internalName, GetEntriesOptions options) with the aliasId or playerId option instead.")]
9093
public async Task<LeaderboardEntriesResponse> GetEntriesForCurrentPlayer(string internalName, int page, bool includeArchived = false)
9194
{
9295
Talo.IdentityCheck();

Assets/Talo Game Services/Talo/Runtime/APIs/PlayerAuthAPI.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace TaloGameServices
66
{
77
public class PlayerAuthAPI : BaseAPI
88
{
9-
private SessionManager _sessionManager = new();
9+
private readonly SessionManager _sessionManager = new();
1010

1111
public SessionManager SessionManager => _sessionManager;
1212

@@ -114,6 +114,19 @@ public async Task ChangeEmail(string currentPassword, string newEmail)
114114
await Call(uri, "POST", content);
115115
}
116116

117+
public async Task ChangeIdentifier(string currentPassword, string newIdentifier)
118+
{
119+
var uri = new Uri($"{baseUrl}/change_identifier");
120+
string content = JsonUtility.ToJson(new PlayerAuthChangeIdentifierRequest {
121+
currentPassword = currentPassword,
122+
newIdentifier = newIdentifier
123+
});
124+
var json = await Call(uri, "POST", content);
125+
126+
var res = JsonUtility.FromJson<PlayerAuthChangeIdentifierResponse>(json);
127+
_sessionManager.HandleIdentifierUpdated(res);
128+
}
129+
117130
public async Task ForgotPassword(string email)
118131
{
119132
var uri = new Uri($"{baseUrl}/forgot_password");

Assets/Talo Game Services/Talo/Runtime/APIs/PlayersAPI.cs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ public enum DebouncedOperation
2222
public event Action OnIdentificationFailed;
2323
public event Action OnIdentityCleared;
2424

25-
private readonly string offlineDataPath = Application.persistentDataPath + "/ta.bin";
25+
public static readonly string offlineDataPath = Application.persistentDataPath + "/ta.bin";
2626

2727
public PlayersAPI() : base("v1/players")
2828
{
@@ -83,7 +83,7 @@ public async Task<Player> Identify(string service, string identifier)
8383

8484
var res = JsonUtility.FromJson<PlayersIdentifyResponse>(json);
8585
var alias = res.alias;
86-
WriteOfflineAlias(alias);
86+
alias.WriteOfflineAlias();
8787
return await HandleIdentifySuccess(alias, res.socketToken);
8888
}
8989
catch
@@ -133,7 +133,7 @@ public async Task<Player> Update()
133133

134134
var res = JsonUtility.FromJson<PlayersUpdateResponse>(json);
135135
Talo.CurrentPlayer = res.player;
136-
WriteOfflineAlias(Talo.CurrentAlias);
136+
Talo.CurrentAlias.WriteOfflineAlias();
137137

138138
return Talo.CurrentPlayer;
139139
}
@@ -191,13 +191,6 @@ private async Task<Player> IdentifyOffline(string service, string identifier)
191191
}
192192
}
193193

194-
private void WriteOfflineAlias(PlayerAlias alias)
195-
{
196-
if (!Talo.Settings.cachePlayerOnIdentify) return;
197-
var content = JsonUtility.ToJson(alias);
198-
Talo.Crypto.WriteFileContent(offlineDataPath, content);
199-
}
200-
201194
private PlayerAlias GetOfflineAlias()
202195
{
203196
if (!Talo.Settings.cachePlayerOnIdentify || !File.Exists(offlineDataPath)) return null;

Assets/Talo Game Services/Talo/Runtime/Entities/PlayerAlias.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace TaloGameServices
1+
using UnityEngine;
2+
3+
namespace TaloGameServices
24
{
35
[System.Serializable]
46
public class PlayerAlias
@@ -12,5 +14,16 @@ public bool MatchesIdentifyRequest(string service, string identifier)
1214
{
1315
return this.service == service && this.identifier == identifier;
1416
}
17+
18+
public void WriteOfflineAlias()
19+
{
20+
if (!Talo.Settings.cachePlayerOnIdentify)
21+
{
22+
return;
23+
}
24+
25+
var content = JsonUtility.ToJson(this);
26+
Talo.Crypto.WriteFileContent(PlayersAPI.offlineDataPath, content);
27+
}
1528
}
1629
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace TaloGameServices
2+
{
3+
[System.Serializable]
4+
public class PlayerAuthChangeIdentifierRequest
5+
{
6+
public string currentPassword;
7+
public string newIdentifier;
8+
}
9+
}

Assets/Talo Game Services/Talo/Runtime/Requests/PlayerAuthChangeIdentifierRequest.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace TaloGameServices
2+
{
3+
[System.Serializable]
4+
public class PlayerAuthChangeIdentifierResponse
5+
{
6+
public PlayerAlias alias;
7+
}
8+
}

Assets/Talo Game Services/Talo/Runtime/Responses/PlayerAuthChangeIdentifierResponse.cs.meta

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)