From 756ef25639be2445c717193b305cdb1152622a86 Mon Sep 17 00:00:00 2001 From: tudor <7089284+tudddorrr@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:48:35 +0100 Subject: [PATCH 1/5] fix session refresh loop and stale token clearing --- .../Talo/Runtime/Utils/SessionManager.cs | 15 ++-- .../Talo/Tests/SessionManager.meta | 8 +++ .../Tests/SessionManager/ClearSessionTest.cs | 68 +++++++++++++++++++ .../SessionManager/ClearSessionTest.cs.meta | 2 + 4 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 Assets/Talo Game Services/Talo/Tests/SessionManager.meta create mode 100644 Assets/Talo Game Services/Talo/Tests/SessionManager/ClearSessionTest.cs create mode 100644 Assets/Talo Game Services/Talo/Tests/SessionManager/ClearSessionTest.cs.meta diff --git a/Assets/Talo Game Services/Talo/Runtime/Utils/SessionManager.cs b/Assets/Talo Game Services/Talo/Runtime/Utils/SessionManager.cs index 5b59c3a..bc63a8c 100644 --- a/Assets/Talo Game Services/Talo/Runtime/Utils/SessionManager.cs +++ b/Assets/Talo Game Services/Talo/Runtime/Utils/SessionManager.cs @@ -42,21 +42,22 @@ private void SaveSession(string sessionToken, string refreshToken) public async Task ClearSession(bool resetSocket = true) { - if (!Talo.HasIdentity()) - { - return false; - } + var hadIdentity = Talo.HasIdentity(); _sessionToken = null; Talo.CurrentAlias = null; - PlayerAlias.DeleteOfflineAlias(); + + if (hadIdentity) + { + PlayerAlias.DeleteOfflineAlias(); + } PlayerPrefs.DeleteKey("TaloRefreshToken"); Talo.Events.ClearQueue(); Talo.Continuity.ClearRequests(); - if (resetSocket) + if (resetSocket && hadIdentity) { try { @@ -68,7 +69,7 @@ public async Task ClearSession(bool resetSocket = true) } } - return true; + return hadIdentity; } public string GetSessionToken() diff --git a/Assets/Talo Game Services/Talo/Tests/SessionManager.meta b/Assets/Talo Game Services/Talo/Tests/SessionManager.meta new file mode 100644 index 0000000..0089562 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/SessionManager.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 76889c6ae82f4481d9a66ab1d43213ca +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Talo Game Services/Talo/Tests/SessionManager/ClearSessionTest.cs b/Assets/Talo Game Services/Talo/Tests/SessionManager/ClearSessionTest.cs new file mode 100644 index 0000000..9dada0c --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/SessionManager/ClearSessionTest.cs @@ -0,0 +1,68 @@ +using System.Collections; +using NUnit.Framework; +using UnityEngine; +using UnityEngine.TestTools; + +namespace TaloGameServices.Test +{ + internal class ClearSessionTest + { + [OneTimeSetUp] + public void Setup() + { + var tm = new GameObject().AddComponent(); + tm.settings = ScriptableObject.CreateInstance(); + tm.settings.autoConnectSocket = false; + tm.settings.autoStartSession = false; + + Talo.CurrentAlias = null; + PlayerPrefs.DeleteAll(); + } + + [UnityTest] + public IEnumerator ClearSession_WithoutIdentity_DeletesStoredToken() + { + Talo.CurrentAlias = null; + PlayerPrefs.SetString("TaloRefreshToken", "stale-token"); + + // TestMode makes HasIdentity() always return true, which would mask + // the no-identity path this test exercises + TestModeFlag.IsEnabled = false; + try + { + var task = Talo.PlayerAuth.SessionManager.ClearSession(false); + while (!task.IsCompleted) + { + yield return null; + } + + Assert.IsFalse(task.Result); + Assert.IsEmpty(PlayerPrefs.GetString("TaloRefreshToken")); + } + finally + { + TestModeFlag.IsEnabled = true; + } + } + + [UnityTest] + public IEnumerator ClearSession_WithIdentity_ReturnsTrue() + { + Talo.CurrentAlias = new PlayerAlias() { + player = new Player() { + id = "uuid" + } + }; + PlayerPrefs.SetString("TaloRefreshToken", "some-token"); + + var task = Talo.PlayerAuth.SessionManager.ClearSession(false); + while (!task.IsCompleted) + { + yield return null; + } + + Assert.IsTrue(task.Result); + Assert.IsEmpty(PlayerPrefs.GetString("TaloRefreshToken")); + } + } +} diff --git a/Assets/Talo Game Services/Talo/Tests/SessionManager/ClearSessionTest.cs.meta b/Assets/Talo Game Services/Talo/Tests/SessionManager/ClearSessionTest.cs.meta new file mode 100644 index 0000000..9acc3a3 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Tests/SessionManager/ClearSessionTest.cs.meta @@ -0,0 +1,2 @@ +fileFormatVersion: 2 +guid: 38f2590b27f9047cca88a3eb81c2c470 \ No newline at end of file From 8517f92a04c45d86f4f67d0177fc47885923f42e Mon Sep 17 00:00:00 2001 From: tudor <7089284+tudddorrr@users.noreply.github.com> Date: Mon, 31 Aug 2026 22:49:06 +0100 Subject: [PATCH 2/5] remove review workflow --- .opencode/agents/code-review-verifier.md | 59 ------------------- .opencode/agents/code-reviewer.md | 72 ------------------------ .opencode/commands/review.md | 19 ------- 3 files changed, 150 deletions(-) delete mode 100644 .opencode/agents/code-review-verifier.md delete mode 100644 .opencode/agents/code-reviewer.md delete mode 100644 .opencode/commands/review.md diff --git a/.opencode/agents/code-review-verifier.md b/.opencode/agents/code-review-verifier.md deleted file mode 100644 index 966ec52..0000000 --- a/.opencode/agents/code-review-verifier.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -description: Review code for quality, bugs and security -mode: subagent -model: opencode-go/deepseek-v4-flash -temperature: 0.1 -permission: - edit: deny ---- - -Your job is to act as a rigorous fact-checker and quality gate for code reviews and to output the finalized review. - -## Input - -You will receive: -1. **The original code** (files, snippets, or diff) -2. **A "final" review** from the code-reviewer agent containing a list of findings, suggestions and critiques - -## Your task - -Verify **every single point** in the code-reviewer’s report. Do not accept claims at face value. You must independently confirm or refute each finding by examining the actual code. - -### Verification criteria - -For each point in the review, determine: - -1. **Is it factually correct?** - - Does the issue actually exist in the code? - - Are line numbers, function names, variable names, and file paths accurate? - - Is the described behavior truly present, or is it a misreading? - -2. **Is the severity appropriate?** - - Is a "critical" bug actually critical? - - Is a "minor" suggestion truly minor? - - Are there false positives (reported issues that aren't real problems)? - -3. **Is the recommendation sound?** - - Would the suggested fix actually resolve the issue? - - Is the proposed solution idiomatic and safe? - - Are there better alternatives the reviewer missed? - -4. **Are there additional issues?** - - Did the reviewer miss any bugs, security issues, or quality problems? - - Only report additional problems if you can point to specific code demonstrating them. - -### Output format - -After completing your verification, modify the original review based on your findings. - -You must only output a finalized review. - -Do not include references to your verification process or meta commentary about what changed from the original review (assume it was never seen). - -## Rules - -- **Be skeptical.** If the reviewer claims "this will cause an exception", trace the code to see if null is actually possible. -- **Be precise.** Quote the exact code that proves or disproves a claim. -- **Be constructive.** If a point is wrong, drop it. If it's right but the fix is bad, suggest a better one. -- **Do not invent issues.** Only report additional problems if you can point to specific code demonstrating them. -- **Output only the finalized review.** No separate verification summary, no meta-commentary about the process. diff --git a/.opencode/agents/code-reviewer.md b/.opencode/agents/code-reviewer.md deleted file mode 100644 index 0b4b89f..0000000 --- a/.opencode/agents/code-reviewer.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -description: Review code for quality, bugs and security -mode: subagent -model: opencode-go/deepseek-v4-pro -temperature: 0.1 -permission: - edit: deny ---- - -You are a pragmatic code reviewer. Review this pull request and provide feedback using the guidance below. - -# Process - -1. **Diffs alone are not enough.** After getting the diff, read the entire file(s) being modified to understand the full context. Code that looks wrong in isolation may be correct given surrounding logic—and vice versa. -2. Follow the review workflow steps. -3. Output your final review. - -## Categories to check - -1. Code quality and best practices -2. Potential bugs -3. Performance -4. Security -5. Backwards compatibility - -## Issue categories - -- If an issue spans multiple categories, list it only once. -- Prioritize by severity: 🔴 Critical → 🟡 Major → 🔵 Minor. -- Focus only on changes introduced in this PR. - -## Review workflow steps - -1. **Analysis Phase**: Review the PR diff and identify potential issues -2. **Validation Phase**: For each issue you find, verify it by: - - Re-reading the relevant code carefully - - Checking if your suggested fix is actually different from the current code - - Checking if existing tests demonstrate the code handles this case -3. **Draft Phase**: Write your review only after validating all issues -4. **Quality Check**: Before posting, remove any issues where: - - Your "before" and "after" code snippets are identical - - You're uncertain or use phrases like "appears", "might", "should verify" - - The issue is theoretical without clear impact -5. **Final Output Phase**: Output your complete, validated review text. Do NOT post it yourself. - -## Edge case policy - -Only flag edge cases that meet ALL of these criteria: - -1. Realistic: Could happen in normal usage or common error scenarios. -2. Impactful: Would cause bugs, security issues, or data problems (not just "it's not perfect"). -3. Actionable: Can be fixed with reasonable effort in this PR's scope. - -Ignore theoretical issues that require multiple unlikely conditions or malicious input patterns. -Use the "would this bother a pragmatic senior developer?" test. - -# Things to avoid - -1. Running tests just to check output: these kinds of errors will be caught by CI. -2. Flattery: do not give any comments that are not helpful to the reader. - -# Feedback style - -- Number each issue so that it can be easily referenced. -- Provide specific code examples or line references showing the issue. -- Suggest fixes with code snippets where helpful. -- Be pragmatic, don't force criticism. -- Ensure feedback is actionable. - -# Output format - -Output ONLY the final review text. diff --git a/.opencode/commands/review.md b/.opencode/commands/review.md deleted file mode 100644 index f970a65..0000000 --- a/.opencode/commands/review.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -name: review -description: Review the current branch ---- - -## Determining what to review - -- Run: `git log develop..HEAD` for commits to the current branch -- Run: `git diff` for unstaged changes -- Run: `git diff --cached` for staged changes -- Run: `git status --short` to identify untracked (net new) files - -## Performing the code review - -Follow these steps: - -1. Use the **code-reviewer** subagent to review the diff. -2. Pass the finished review to the **code-review-verifier** subagent. -3. Output the verified final review. From 65185a8735bb3af61bbae7cc9647599fa98b4839 Mon Sep 17 00:00:00 2001 From: tudor <7089284+tudddorrr@users.noreply.github.com> Date: Thu, 10 Sep 2026 21:25:39 +0100 Subject: [PATCH 3/5] add gettopentries method to leaderboardsapi --- .../Talo/Runtime/APIs/LeaderboardsAPI.cs | 10 ++++++++++ .../Responses/LeaderboardTopEntriesResponse.cs | 9 +++++++++ .../Responses/LeaderboardTopEntriesResponse.cs.meta | 11 +++++++++++ 3 files changed, 30 insertions(+) create mode 100644 Assets/Talo Game Services/Talo/Runtime/Responses/LeaderboardTopEntriesResponse.cs create mode 100644 Assets/Talo Game Services/Talo/Runtime/Responses/LeaderboardTopEntriesResponse.cs.meta diff --git a/Assets/Talo Game Services/Talo/Runtime/APIs/LeaderboardsAPI.cs b/Assets/Talo Game Services/Talo/Runtime/APIs/LeaderboardsAPI.cs index 9f3b54e..0fba357 100644 --- a/Assets/Talo Game Services/Talo/Runtime/APIs/LeaderboardsAPI.cs +++ b/Assets/Talo Game Services/Talo/Runtime/APIs/LeaderboardsAPI.cs @@ -75,6 +75,16 @@ public async Task GetEntries(string internalName, Ge return res; } + public async Task GetTopEntries(string internalName, int limit) + { + Talo.IdentityCheck(); + + var uri = new Uri($"{baseUrl}/{internalName}/entries/top?limit={limit}"); + var json = await Call(uri, "GET"); + + return JsonUtility.FromJson(json); + } + public async Task AddEntry(string internalName, float score, params (string, string)[] propTuples) { Talo.IdentityCheck(); diff --git a/Assets/Talo Game Services/Talo/Runtime/Responses/LeaderboardTopEntriesResponse.cs b/Assets/Talo Game Services/Talo/Runtime/Responses/LeaderboardTopEntriesResponse.cs new file mode 100644 index 0000000..d6b8892 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Runtime/Responses/LeaderboardTopEntriesResponse.cs @@ -0,0 +1,9 @@ +namespace TaloGameServices +{ + [System.Serializable] + public class LeaderboardTopEntriesResponse + { + public LeaderboardEntry[] topEntries; + public LeaderboardEntry[] playerEntries; + } +} diff --git a/Assets/Talo Game Services/Talo/Runtime/Responses/LeaderboardTopEntriesResponse.cs.meta b/Assets/Talo Game Services/Talo/Runtime/Responses/LeaderboardTopEntriesResponse.cs.meta new file mode 100644 index 0000000..db06f47 --- /dev/null +++ b/Assets/Talo Game Services/Talo/Runtime/Responses/LeaderboardTopEntriesResponse.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 3d25e39b15304f978bc713a30c1e2f36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: From 391758a1dd94e0566bc80338729b1a8267291d5a Mon Sep 17 00:00:00 2001 From: tudor <7089284+tudddorrr@users.noreply.github.com> Date: Thu, 10 Sep 2026 21:33:53 +0100 Subject: [PATCH 4/5] skip pre-commit hook for worktrees --- .github/hooks/pre-commit | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/hooks/pre-commit b/.github/hooks/pre-commit index 6780968..9221c9a 100644 --- a/.github/hooks/pre-commit +++ b/.github/hooks/pre-commit @@ -1,5 +1,10 @@ #!/bin/bash +# VERSION is only bumped in the main worktree, so skip linked worktrees +if [ "$(git rev-parse --git-dir)" != "$(git rev-parse --git-common-dir)" ]; then + exit 0 +fi + cd "Assets/Talo Game Services/Talo" VERSION_FILE="VERSION" From 85c85d8ae72fb06efb566ac2ff7a19984d84fcb0 Mon Sep 17 00:00:00 2001 From: tudor <7089284+tudddorrr@users.noreply.github.com> Date: Fri, 11 Sep 2026 06:30:31 +0100 Subject: [PATCH 5/5] 1.1.0 --- Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs | 2 +- Assets/Talo Game Services/Talo/VERSION | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs b/Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs index 88ad0da..4c30c30 100644 --- a/Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs +++ b/Assets/Talo Game Services/Talo/Runtime/APIs/BaseAPI.cs @@ -9,7 +9,7 @@ namespace TaloGameServices public class BaseAPI { // automatically updated with a pre-commit hook - private const string ClientVersion = "1.0.0"; + private const string ClientVersion = "1.1.0"; protected string baseUrl; diff --git a/Assets/Talo Game Services/Talo/VERSION b/Assets/Talo Game Services/Talo/VERSION index 3eefcb9..9084fa2 100644 --- a/Assets/Talo Game Services/Talo/VERSION +++ b/Assets/Talo Game Services/Talo/VERSION @@ -1 +1 @@ -1.0.0 +1.1.0