Skip to content

Commit 95dafa0

Browse files
authored
Merge pull request #153 from TaloDev/develop
Release 0.46.0
2 parents 113f927 + 932ae05 commit 95dafa0

39 files changed

+1007
-120
lines changed

.github/workflows/claude-code-review.yml

Lines changed: 11 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,14 @@ jobs:
1717
# github.event.pull_request.user.login == 'external-contributor' ||
1818
# github.event.pull_request.user.login == 'new-developer' ||
1919
# github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR'
20-
20+
2121
runs-on: ubuntu-latest
2222
permissions:
2323
contents: read
2424
pull-requests: read
2525
issues: read
2626
id-token: write
27-
27+
2828
steps:
2929
- name: Checkout repository
3030
uses: actions/checkout@v4
@@ -33,15 +33,10 @@ jobs:
3333

3434
- name: Run Claude Code Review
3535
id: claude-review
36-
uses: anthropics/claude-code-action@beta
36+
uses: anthropics/claude-code-action@v1
3737
with:
3838
claude_code_oauth_token: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
39-
40-
# Optional: Specify model (defaults to Claude Sonnet 4, uncomment for Claude Opus 4.1)
41-
# model: "claude-opus-4-1-20250805"
42-
43-
# Direct prompt for automated review (no @claude mention needed)
44-
direct_prompt: |
39+
prompt: |
4540
Please review this pull request and provide feedback on:
4641
- Code quality and best practices
4742
- Potential bugs or issues
@@ -53,28 +48,11 @@ jobs:
5348
Be constructive and helpful in your feedback but do not repeat yourself - only summarise potential issues.
5449
Test coverage is currently not a priority.
5550
Prefix section headers with emojis and use dividers for better readability.
56-
57-
use_sticky_comment: true
51+
52+
Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
53+
Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
5854
59-
# Optional: Customize review based on file types
60-
# direct_prompt: |
61-
# Review this PR focusing on:
62-
# - For TypeScript files: Type safety and proper interface usage
63-
# - For API endpoints: Security, input validation, and error handling
64-
# - For React components: Performance, accessibility, and best practices
65-
# - For tests: Coverage, edge cases, and test quality
66-
67-
# Optional: Different prompts for different authors
68-
# direct_prompt: |
69-
# ${{ github.event.pull_request.author_association == 'FIRST_TIME_CONTRIBUTOR' &&
70-
# 'Welcome! Please review this PR from a first-time contributor. Be encouraging and provide detailed explanations for any suggestions.' ||
71-
# 'Please provide a thorough code review focusing on our coding standards and best practices.' }}
72-
73-
# Optional: Add specific tools for running tests or linting
74-
# allowed_tools: "Bash(npm run test),Bash(npm run lint),Bash(npm run typecheck)"
75-
76-
# Optional: Skip review for certain conditions
77-
# if: |
78-
# !contains(github.event.pull_request.title, '[skip-review]') &&
79-
# !contains(github.event.pull_request.title, '[WIP]')
80-
55+
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
56+
# or https://docs.anthropic.com/en/docs/claude-code/sdk#command-line for available options
57+
claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
58+
use_sticky_comment: true

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.45.0";
12+
private const string ClientVersion = "0.46.0";
1313

1414
protected string baseUrl;
1515

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

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,30 @@ public string ToQueryString()
3737
}
3838
}
3939

40+
public class GetMembersOptions
41+
{
42+
public int page = 0;
43+
public string playerId = "";
44+
public int aliasId = -1;
45+
public string identifier = "";
46+
public string propKey = "";
47+
public string propValue = "";
48+
public string playerGroupId = "";
49+
50+
public string ToQueryString()
51+
{
52+
var query = new Dictionary<string, string> { ["page"] = page.ToString() };
53+
if (!string.IsNullOrEmpty(playerId)) query["playerId"] = playerId;
54+
if (aliasId != -1) query["aliasId"] = aliasId.ToString();
55+
if (!string.IsNullOrEmpty(identifier)) query["identifier"] = identifier;
56+
if (!string.IsNullOrEmpty(propKey)) query["propKey"] = propKey;
57+
if (!string.IsNullOrEmpty(propValue)) query["propValue"] = propValue;
58+
if (!string.IsNullOrEmpty(playerGroupId)) query["playerGroupId"] = playerGroupId;
59+
60+
return string.Join("&", query.Select((param) => $"{param.Key}={param.Value}"));
61+
}
62+
}
63+
4064
public class CreateChannelOptions
4165
{
4266
public string name;
@@ -273,15 +297,17 @@ public async Task Invite(int channelId, int playerAliasId)
273297
await Call(uri, "POST", content);
274298
}
275299

276-
public async Task<PlayerAlias[]> GetMembers(int channelId)
300+
public async Task<ChannelsMembersResponse> GetMembers(int channelId, GetMembersOptions options = null)
277301
{
278302
Talo.IdentityCheck();
279303

280-
var uri = new Uri($"{baseUrl}/{channelId}/members");
304+
options ??= new GetMembersOptions();
305+
306+
var uri = new Uri($"{baseUrl}/{channelId}/members?{options.ToQueryString()}");
281307
var json = await Call(uri, "GET");
282308

283309
var res = JsonUtility.FromJson<ChannelsMembersResponse>(json);
284-
return res.members;
310+
return res;
285311
}
286312

287313
public async Task<ChannelStorageProp> GetStorageProp(int channelId, string propKey, bool bustCache = false)

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

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ public class EventsAPI : BaseAPI
1010
{
1111
public event Action OnFlushed;
1212

13-
private List<Event> queue = new ();
13+
internal List<Event> queue = new ();
1414
private readonly int minQueueSize = 10;
1515

16-
private List<Event> eventsToFlush = new ();
16+
internal List<Event> eventsToFlush = new ();
1717
private bool lockFlushes;
1818
private bool flushAttemptedDuringLock;
1919

@@ -107,9 +107,9 @@ public async Task Flush()
107107
eventsToFlush.Clear();
108108
lockFlushes = false;
109109
}
110-
catch (Exception err)
110+
catch (Exception ex)
111111
{
112-
Debug.LogError(err.Message);
112+
Debug.LogError(ex.Message);
113113
}
114114

115115
if (flushAttemptedDuringLock)
@@ -118,5 +118,13 @@ public async Task Flush()
118118
await Flush();
119119
}
120120
}
121+
122+
public void ClearQueue()
123+
{
124+
queue.Clear();
125+
eventsToFlush.Clear();
126+
lockFlushes = false;
127+
flushAttemptedDuringLock = false;
128+
}
121129
}
122130
}

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

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,49 @@ public GameConfigAPI() : base("v1/game-config") {
1414
if (response.GetResponseType() == "v1.live-config.updated")
1515
{
1616
var data = response.GetData<GameConfigResponse>();
17-
OnLiveConfigUpdated?.Invoke(new LiveConfig(data.config));
17+
SetLiveConfig(new LiveConfig(data.config), true);
1818
}
1919
};
2020
}
2121

2222
public async Task<LiveConfig> Get()
2323
{
24+
if (Talo.IsOffline())
25+
{
26+
return GetOfflineConfig();
27+
}
28+
2429
var uri = new Uri(baseUrl);
2530
var json = await Call(uri, "GET");
2631

2732
var res = JsonUtility.FromJson<GameConfigResponse>(json);
28-
Talo.LiveConfig = new LiveConfig(res.config);
29-
OnLiveConfigLoaded?.Invoke(Talo.LiveConfig);
30-
33+
SetLiveConfig(new LiveConfig(res.config));
3134
return Talo.LiveConfig;
3235
}
36+
37+
public LiveConfig GetOfflineConfig()
38+
{
39+
var offlineConfig = LiveConfig.GetOfflineConfig();
40+
if (offlineConfig != null)
41+
{
42+
SetLiveConfig(offlineConfig);
43+
}
44+
return offlineConfig;
45+
}
46+
47+
private void SetLiveConfig(LiveConfig liveConfig, bool isUpdate = false)
48+
{
49+
Talo.LiveConfig = liveConfig;
50+
liveConfig.WriteOfflineConfig();
51+
52+
if (isUpdate)
53+
{
54+
OnLiveConfigUpdated?.Invoke(liveConfig);
55+
}
56+
else
57+
{
58+
OnLiveConfigLoaded?.Invoke(liveConfig);
59+
}
60+
}
3361
}
3462
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ public class PlayerGroupsAPI : BaseAPI
88
{
99
public PlayerGroupsAPI() : base("v1/player-groups") { }
1010

11-
public async Task<Group> Get(string groupId)
11+
public async Task<PlayerGroupsGetResponse> Get(string groupId, int page = 0)
1212
{
13-
var uri = new Uri($"{baseUrl}/{groupId}");
13+
var uri = new Uri($"{baseUrl}/{groupId}?page={page}");
1414
var json = await Call(uri, "GET");
1515

1616
var res = JsonUtility.FromJson<PlayerGroupsGetResponse>(json);
17-
return res.group;
17+
return res;
1818
}
1919
}
2020
}

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

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ public class PlayersAPI : BaseAPI
1010
public event Action<Player> OnIdentified;
1111
public event Action OnIdentificationStarted;
1212
public event Action OnIdentificationFailed;
13+
public event Action OnIdentityCleared;
1314

14-
private readonly string _offlineDataPath = Application.persistentDataPath + "/ta.bin";
15+
private readonly string offlineDataPath = Application.persistentDataPath + "/ta.bin";
1516

1617
public PlayersAPI() : base("v1/players") { }
1718

@@ -82,6 +83,8 @@ public async Task<Player> IdentifySteam(string ticket, string identity = "")
8283

8384
public async Task<Player> Update()
8485
{
86+
Talo.IdentityCheck();
87+
8588
var uri = new Uri($"{baseUrl}/{Talo.CurrentPlayer.id}");
8689
var content = JsonUtility.ToJson(Talo.CurrentPlayer);
8790
var json = await Call(uri, "PATCH", Prop.SanitiseJson(content));
@@ -123,7 +126,7 @@ private async Task<Player> IdentifyOffline(string service, string identifier)
123126
{
124127
try
125128
{
126-
File.Delete(_offlineDataPath);
129+
File.Delete(offlineDataPath);
127130
}
128131
finally
129132
{
@@ -137,13 +140,67 @@ private void WriteOfflineAlias(PlayerAlias alias)
137140
{
138141
if (!Talo.Settings.cachePlayerOnIdentify) return;
139142
var content = JsonUtility.ToJson(alias);
140-
Talo.Crypto.WriteFileContent(_offlineDataPath, content);
143+
Talo.Crypto.WriteFileContent(offlineDataPath, content);
141144
}
142145

143146
private PlayerAlias GetOfflineAlias()
144147
{
145-
if (!Talo.Settings.cachePlayerOnIdentify || !File.Exists(_offlineDataPath)) return null;
146-
return JsonUtility.FromJson<PlayerAlias>(Talo.Crypto.ReadFileContent(_offlineDataPath));
148+
if (!Talo.Settings.cachePlayerOnIdentify || !File.Exists(offlineDataPath)) return null;
149+
return JsonUtility.FromJson<PlayerAlias>(Talo.Crypto.ReadFileContent(offlineDataPath));
150+
}
151+
152+
private void DeleteOfflineAlias()
153+
{
154+
if (File.Exists(offlineDataPath))
155+
{
156+
try
157+
{
158+
File.Delete(offlineDataPath);
159+
}
160+
catch (Exception ex)
161+
{
162+
Debug.LogWarning($"Failed to delete offline player data: {ex.Message}");
163+
}
164+
}
165+
}
166+
167+
public async Task ClearIdentity()
168+
{
169+
Talo.IdentityCheck();
170+
171+
try
172+
{
173+
DeleteOfflineAlias();
174+
}
175+
catch (Exception ex)
176+
{
177+
Debug.LogWarning($"Error deleting offline alias: {ex.Message}");
178+
}
179+
180+
try
181+
{
182+
// clears the alias and resets the socket (doesn't require auth)
183+
await Talo.PlayerAuth.SessionManager.ClearSession();
184+
}
185+
catch (Exception ex)
186+
{
187+
Debug.LogWarning($"Error clearing session: {ex.Message}");
188+
}
189+
190+
Talo.Events.ClearQueue();
191+
Talo.Continuity.ClearRequests();
192+
193+
OnIdentityCleared?.Invoke();
194+
}
195+
196+
public async Task<PlayersSearchResponse> Search(string query)
197+
{
198+
var encodedQuery = Uri.EscapeDataString(query.Trim());
199+
var uri = new Uri($"{baseUrl}/search?query={encodedQuery}");
200+
var json = await Call(uri, "GET");
201+
202+
var res = JsonUtility.FromJson<PlayersSearchResponse>(json);
203+
return res;
147204
}
148205
}
149206
}

0 commit comments

Comments
 (0)