forfeiture, abandoning, entry_fee_collection at start

This commit is contained in:
2026-08-14 11:13:01 +05:30
parent 9970488938
commit 74d9fae6e6
54 changed files with 6214 additions and 2576 deletions
+157 -1
View File
@@ -53,7 +53,13 @@ public class LoginManager : MonoBehaviour
[SerializeField] private TMP_Text serverWarningMessageTxt;
[SerializeField] private Button btnWarningClose;
const float KeepaliveIntervalSeconds = 10f;
bool _authInProgress;
Coroutine _keepaliveRoutine;
bool _appPaused;
bool _appFocused = true;
bool _handlingKeepaliveUnauthorized;
public static string AuthToken { get; private set; }
@@ -117,6 +123,10 @@ public class LoginManager : MonoBehaviour
if (string.IsNullOrEmpty(AuthToken))
ClearLocalUserProfile();
#if !UNITY_EDITOR
else
StartKeepalive();
#endif
}
void Start()
@@ -139,13 +149,16 @@ public class LoginManager : MonoBehaviour
if (!mayContinue)
{
// Blocked by update or error panel — keep login UI disabled.
// Blocked by update or error panel — keep login UI disabled, but hold the session.
if (!string.IsNullOrEmpty(AuthToken))
StartKeepalive();
SetBusy(false);
yield break;
}
#if UNITY_EDITOR
// Dev: log in with clone-aware credentials instead of resuming a saved session.
StopKeepalive();
AuthToken = "";
PlayerPrefs.DeleteKey(PlayerPrefsAuthKey);
PlayerPrefs.Save();
@@ -161,7 +174,10 @@ public class LoginManager : MonoBehaviour
SetBusy(false);
#else
if (!string.IsNullOrEmpty(AuthToken))
{
StartKeepalive();
yield return StartCoroutine(ResumeSessionCoroutine());
}
else
SetBusy(false);
#endif
@@ -217,6 +233,8 @@ public class LoginManager : MonoBehaviour
/// <summary>Removes auth token from memory and disk and clears cached profile (login screen recovery).</summary>
static void InvalidateStoredSession()
{
if (instance != null)
instance.StopKeepalive();
AuthToken = "";
ClearLocalUserProfile();
ClearMatchYourTeam();
@@ -224,6 +242,18 @@ public class LoginManager : MonoBehaviour
PlayerPrefs.Save();
}
/// <summary>Clears session state and all PlayerPrefs (full logout).</summary>
public static void Logout()
{
if (instance != null)
instance.StopKeepalive();
AuthToken = "";
ClearLocalUserProfile();
ClearMatchYourTeam();
PlayerPrefs.DeleteAll();
PlayerPrefs.Save();
}
static void ProceedToMainMenu()
{
if (LevelLoadManager.instance != null)
@@ -242,6 +272,7 @@ public class LoginManager : MonoBehaviour
void OnLogin()
{
if (_authInProgress) return;
if (_keepaliveRoutine != null && !string.IsNullOrEmpty(AuthToken)) return;
string username = usernameInputLogin.text;
string password = passwordInputLogin.text;
@@ -270,6 +301,7 @@ public class LoginManager : MonoBehaviour
void OnRegister()
{
if (_authInProgress) return;
if (_keepaliveRoutine != null && !string.IsNullOrEmpty(AuthToken)) return;
string username = usernameInputRegister.text;
string email = emailInputRegister != null ? emailInputRegister.text : "";
@@ -374,6 +406,7 @@ public class LoginManager : MonoBehaviour
AuthToken = resp.token;
PlayerPrefs.SetString(PlayerPrefsAuthKey, resp.token);
PlayerPrefs.Save();
StartKeepalive();
bool profileOk = false;
string profileErr = null;
@@ -799,4 +832,127 @@ public class LoginManager : MonoBehaviour
}
}
bool IsAppInForeground => !_appPaused && _appFocused;
void OnApplicationPause(bool paused)
{
_appPaused = paused;
}
void OnApplicationFocus(bool hasFocus)
{
_appFocused = hasFocus;
}
void OnDestroy()
{
if (instance == this)
StopKeepalive();
}
void StartKeepalive()
{
if (string.IsNullOrEmpty(AuthToken)) return;
if (_keepaliveRoutine != null) return;
_handlingKeepaliveUnauthorized = false;
_keepaliveRoutine = StartCoroutine(KeepaliveLoopCoroutine());
}
void StopKeepalive()
{
if (_keepaliveRoutine == null) return;
StopCoroutine(_keepaliveRoutine);
_keepaliveRoutine = null;
}
IEnumerator KeepaliveLoopCoroutine()
{
while (!string.IsNullOrEmpty(AuthToken))
{
while (!IsAppInForeground && !string.IsNullOrEmpty(AuthToken))
yield return null;
if (string.IsNullOrEmpty(AuthToken))
break;
yield return KeepalivePingCoroutine();
if (string.IsNullOrEmpty(AuthToken))
break;
float elapsed = 0f;
while (elapsed < KeepaliveIntervalSeconds && !string.IsNullOrEmpty(AuthToken))
{
if (!IsAppInForeground)
{
while (!IsAppInForeground && !string.IsNullOrEmpty(AuthToken))
yield return null;
break;
}
elapsed += Time.unscaledDeltaTime;
yield return null;
}
}
_keepaliveRoutine = null;
}
IEnumerator KeepalivePingCoroutine()
{
if (string.IsNullOrEmpty(AuthToken))
yield break;
string url = AuthBaseUrl + "/auth/keepalive";
using (var request = new UnityWebRequest(url, UnityWebRequest.kHttpVerbPOST))
{
request.uploadHandler = new UploadHandlerRaw(Array.Empty<byte>());
request.downloadHandler = new DownloadHandlerBuffer();
request.SetRequestHeader("Content-Type", "application/json");
request.SetRequestHeader("Authorization", "Bearer " + AuthToken);
yield return request.SendWebRequest();
if (request.responseCode == 401)
{
string text = request.downloadHandler != null ? request.downloadHandler.text : "";
string err = "Session expired. Please sign in again.";
if (!string.IsNullOrEmpty(text))
{
AuthApiResponse resp = JsonUtility.FromJson<AuthApiResponse>(text);
if (resp != null && !string.IsNullOrEmpty(resp.error))
err = resp.error;
}
HandleKeepaliveUnauthorized(err);
yield break;
}
if (request.result != UnityWebRequest.Result.Success &&
request.result != UnityWebRequest.Result.ProtocolError)
{
Logger.Log("auth/keepalive network error: " + (string.IsNullOrEmpty(request.error) ? "Network error" : request.error));
yield break;
}
if (request.responseCode < 200 || request.responseCode >= 300)
Logger.Log("auth/keepalive failed: HTTP " + request.responseCode);
}
}
void HandleKeepaliveUnauthorized(string message)
{
if (_handlingKeepaliveUnauthorized) return;
_handlingKeepaliveUnauthorized = true;
InvalidateStoredSession();
SetBusy(false);
if (error_txt != null)
error_txt.text = string.IsNullOrEmpty(message) ? "Session expired. Please sign in again." : message;
Scene active = SceneManager.GetActiveScene();
if (active.buildIndex != 0 && active.name != "Intro")
SceneManager.LoadScene(0);
}
}