qa report v2

This commit is contained in:
2026-09-06 21:36:26 +05:30
parent 78592e8d8e
commit 5ac8f92006
37 changed files with 507 additions and 223 deletions
+6
View File
@@ -31,6 +31,12 @@ public static class Cupid
public static int RoomPort = -1; public static int RoomPort = -1;
/// <summary>Clears auth/matchmaker session fields. Server address is left so the next login can <see cref="Init"/> again.</summary>
public static void ClearSession()
{
bearerToken = "";
RoomPort = -1;
}
public static async Task Init(string _serverAddress, int _port, string _bearerToken, string _settingsPassword) public static async Task Init(string _serverAddress, int _port, string _bearerToken, string _settingsPassword)
{ {
+6
View File
@@ -51,6 +51,12 @@ public class CupidLobby : MonoBehaviour
} }
public static CupidLobby instance; public static CupidLobby instance;
public static void ClearUsername()
{
m_username = "";
}
void Awake(){ void Awake(){
instance=this; instance=this;
} }
+52 -3
View File
@@ -6,6 +6,8 @@ public class Logger
{ {
public static bool Enabled = true; public static bool Enabled = true;
private static Logger m_instance = null; private static Logger m_instance = null;
private static readonly object FileLock = new object();
private static string ApplicationDirectory private static string ApplicationDirectory
{ {
get get
@@ -18,6 +20,12 @@ public class Logger
} }
string path = Application.dataPath; string path = Application.dataPath;
#if UNITY_EDITOR
// Never write under Assets/: the Editor importer locks those files, and
// File.AppendAllText then throws Sharing violation. Mirror treats that as a
// fatal RPC error and disconnects the client.
path = Path.GetFullPath(Path.Combine(path, ".."));
#else
if (Application.platform == RuntimePlatform.OSXPlayer) if (Application.platform == RuntimePlatform.OSXPlayer)
{ {
path = Path.Combine(path, "..", ".."); path = Path.Combine(path, "..", "..");
@@ -26,6 +34,7 @@ public class Logger
{ {
path = Path.Combine(path, ".."); path = Path.Combine(path, "..");
} }
#endif
return path; return path;
} }
} }
@@ -50,14 +59,14 @@ public class Logger
if(LogFilePath == null){ if(LogFilePath == null){
LogFilePath = Path.Combine(ApplicationDirectory, "Log.txt"); LogFilePath = Path.Combine(ApplicationDirectory, "Log.txt");
} }
File.WriteAllText(LogFilePath, "Logger initiated at " + DateTime.Now + "\n\n"); TryWriteFile(LogFilePath, "Logger initiated at " + DateTime.Now + "\n\n", append: false);
} }
public void log(string message){ public void log(string message){
if(!Enabled){return;} if(!Enabled){return;}
File.AppendAllText(LogFilePath,$"[{DateTime.Now}] {message}\n");
Debug.Log(message); Debug.Log(message);
TryWriteFile(LogFilePath, $"[{DateTime.Now}] {message}\n", append: true);
} }
public static void Log(string message){ public static void Log(string message){
@@ -86,4 +95,44 @@ public class Logger
public static void SetFilePath(string path){ public static void SetFilePath(string path){
instance.LogFilePath= path; instance.LogFilePath= path;
} }
}
/// <summary>
/// File I/O must never throw: callers include Mirror RPCs, and an exception there
/// disconnects the client. Sharing violations are expected if another process has
/// the file open; FileShare.ReadWrite plus a swallow keeps gameplay alive.
/// </summary>
static void TryWriteFile(string path, string contents, bool append)
{
if (string.IsNullOrEmpty(path) || contents == null)
return;
try
{
string dir = Path.GetDirectoryName(path);
if (!string.IsNullOrEmpty(dir))
EnsureDirectoryExists(dir);
}
catch (Exception e)
{
Debug.LogWarning("Logger: could not create log directory: " + e.Message);
return;
}
lock (FileLock)
{
try
{
FileMode mode = append ? FileMode.Append : FileMode.Create;
using (var stream = new FileStream(path, mode, FileAccess.Write, FileShare.ReadWrite))
using (var writer = new StreamWriter(stream))
{
writer.Write(contents);
}
}
catch (Exception e)
{
Debug.LogWarning("Logger: file write failed (" + path + "): " + e.Message);
}
}
}
}
+33 -35
View File
@@ -1,36 +1,34 @@
Logger initiated at 8/20/2026 7:16:47 PM Logger initiated at 8/27/2026 1:43:47 PM
[8/20/2026 7:16:47 PM] Cupid settings updated [8/27/2026 1:43:47 PM] Cupid settings updated
[8/20/2026 7:16:47 PM] Cupid settings updated [8/27/2026 1:43:48 PM] Cupid settings updated
[8/20/2026 7:16:49 PM] Starting matchmake as warlock [8/27/2026 1:43:50 PM] Starting matchmake as warlock
[8/20/2026 7:16:52 PM] Still waiting: {"ok":true,"entry_fee":21,"rc_prize":34,"for_red":{"Players":[{"Name":"warlock","LastSeen":1787233612635,"UserId":2,"l10_wins":4,"l10_losses":5}],"GameName":"soccar","Port":26226,"InitTime":1787233612635,"entry_fee":21,"match_id":566,"rc_prize":34,"your_team":"red"},"for_blue":null} [8/27/2026 1:43:51 PM] Starting matchmake as warlock2
[8/20/2026 7:16:54 PM] Got into a room [8/27/2026 1:43:53 PM] Still waiting: {"ok":true,"entry_fee":21,"rc_prize":34,"for_red":{"Players":[{"Name":"warlock","LastSeen":1787818433058,"UserId":2,"l10_wins":1,"l10_losses":8}],"GameName":"soccar","Port":26357,"InitTime":1787818433058,"entry_fee":21,"match_id":595,"rc_prize":34,"your_team":"red"},"for_blue":null}
[8/20/2026 7:16:54 PM] {"ok":true,"entry_fee":21,"rc_prize":34,"for_red":{"Players":[{"Name":"warlock","LastSeen":1787233613909,"UserId":2,"l10_wins":4,"l10_losses":5},{"Name":"warlock3","LastSeen":1787233612988,"UserId":6,"l10_wins":1,"l10_losses":9}],"GameName":"soccar","Port":26226,"InitTime":1787233612635,"entry_fee":21,"match_id":566,"instance_started":true,"rc_prize":34,"your_team":"red"},"for_blue":{"Players":[{"Name":"warlock","LastSeen":1787233613909,"UserId":2,"l10_wins":4,"l10_losses":5},{"Name":"warlock3","LastSeen":1787233612988,"UserId":6,"l10_wins":1,"l10_losses":9}],"GameName":"soccar","Port":26226,"InitTime":1787233612635,"entry_fee":21,"match_id":566,"instance_started":true,"rc_prize":34,"your_team":"blue"}} [8/27/2026 1:43:53 PM] Got into a room
[8/20/2026 7:16:54 PM] Configured dedicated match reporting for match id 566 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com [8/27/2026 1:43:53 PM] {"ok":true,"entry_fee":21,"rc_prize":34,"for_red":{"Players":[{"Name":"warlock","LastSeen":1787818433058,"UserId":2,"l10_wins":1,"l10_losses":8},{"Name":"warlock2","LastSeen":1787818433141,"UserId":3,"l10_wins":8,"l10_losses":2}],"GameName":"soccar","Port":26357,"InitTime":1787818433058,"entry_fee":21,"match_id":595,"instance_started":true,"rc_prize":34,"your_team":"red"},"for_blue":{"Players":[{"Name":"warlock","LastSeen":1787818433058,"UserId":2,"l10_wins":1,"l10_losses":8},{"Name":"warlock2","LastSeen":1787818433141,"UserId":3,"l10_wins":8,"l10_losses":2}],"GameName":"soccar","Port":26357,"InitTime":1787818433058,"entry_fee":21,"match_id":595,"instance_started":true,"rc_prize":34,"your_team":"blue"}}
[8/20/2026 7:16:54 PM] Setting cupid to load game scene [8/27/2026 1:43:53 PM] Configured dedicated match reporting for match id 595 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com
[8/20/2026 7:16:54 PM] Loading game scene [8/27/2026 1:43:53 PM] Setting cupid to load game scene
[8/20/2026 7:17:00 PM] Starting client at $kkapi.playpoolstudios.com:26226 [8/27/2026 1:43:53 PM] Loading game scene
[8/20/2026 7:17:01 PM] Client connected [8/27/2026 1:43:54 PM] Got into a room
[8/20/2026 7:17:01 PM] Dedicated join: team assigned Red isServer=False matchId=566 secretEmpty=False redJoin=False blueJoin=False collected=False [8/27/2026 1:43:54 PM] {"ok":true,"entry_fee":21,"rc_prize":34,"for_red":{"Players":[{"Name":"warlock","LastSeen":1787818434370,"UserId":2,"l10_wins":1,"l10_losses":8},{"Name":"warlock2","LastSeen":1787818433141,"UserId":3,"l10_wins":8,"l10_losses":2}],"GameName":"soccar","Port":26357,"InitTime":1787818433058,"entry_fee":21,"match_id":595,"instance_started":true,"rc_prize":34,"your_team":"red"},"for_blue":{"Players":[{"Name":"warlock","LastSeen":1787818434370,"UserId":2,"l10_wins":1,"l10_losses":8},{"Name":"warlock2","LastSeen":1787818433141,"UserId":3,"l10_wins":8,"l10_losses":2}],"GameName":"soccar","Port":26357,"InitTime":1787818433058,"entry_fee":21,"match_id":595,"instance_started":true,"rc_prize":34,"your_team":"blue"}}
[8/20/2026 7:17:16 PM] Selected team changed from Red to Blue [8/27/2026 1:43:54 PM] Configured dedicated match reporting for match id 595 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com
[8/20/2026 7:17:22 PM] Selected team changed from Blue to Red [8/27/2026 1:43:54 PM] Setting cupid to load game scene
[8/20/2026 7:17:33 PM] Selected team changed from Red to Blue [8/27/2026 1:43:54 PM] Loading game scene
[8/20/2026 7:17:37 PM] Selected team changed from Blue to Red [8/27/2026 1:43:59 PM] Starting client at $kkapi.playpoolstudios.com:26357
[8/20/2026 7:17:43 PM] Selected team changed from Red to Blue [8/27/2026 1:43:59 PM] Client connected
[8/20/2026 7:17:49 PM] Selected team changed from Blue to Red [8/27/2026 1:43:59 PM] Dedicated join: team assigned Blue isServer=False matchId=595 secretEmpty=False redJoin=False blueJoin=False collected=False
[8/20/2026 7:17:53 PM] Selected team changed from Red to Blue [8/27/2026 1:44:01 PM] Starting client at $kkapi.playpoolstudios.com:26357
[8/20/2026 7:17:55 PM] Score changed from 0 to 1 [8/27/2026 1:44:01 PM] Client connected
[8/20/2026 7:17:58 PM] Selected team changed from Blue to Red [8/27/2026 1:44:01 PM] Dedicated join: team assigned Red isServer=False matchId=595 secretEmpty=False redJoin=False blueJoin=False collected=False
[8/20/2026 7:18:03 PM] Selected team changed from Red to Blue [8/27/2026 1:44:17 PM] Selected team changed from Red to Blue
[8/20/2026 7:18:05 PM] Score changed from 1 to 2 [8/27/2026 1:44:17 PM] Selected team changed from Red to Blue
[8/20/2026 7:18:08 PM] Selected team changed from Blue to Red [8/27/2026 1:44:26 PM] Selected team changed from Blue to Red
[8/20/2026 7:18:13 PM] Selected team changed from Red to Blue [8/27/2026 1:44:26 PM] Selected team changed from Blue to Red
[8/20/2026 7:18:17 PM] Score changed from 2 to 3 [8/27/2026 1:45:01 PM] Configured dedicated match reporting for match id 596 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com
[8/20/2026 7:18:48 PM] Client disconnected [8/27/2026 1:45:01 PM] Client disconnected
[8/20/2026 7:18:53 PM] Cupid settings updated [8/27/2026 1:45:01 PM] Client disconnected
[8/20/2026 7:18:53 PM] Cupid settings updated [8/27/2026 1:45:05 PM] Starting client at $kkapi.playpoolstudios.com:26411
[8/20/2026 7:18:56 PM] Configured dedicated match reporting for match id 0 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com [8/27/2026 1:45:05 PM] Client connected
[8/20/2026 7:19:02 PM] Starting client at $kkapi.playpoolstudios.com:26226 [8/27/2026 1:45:05 PM] Dedicated join: team assigned Red isServer=False matchId=596 secretEmpty=False redJoin=False blueJoin=False collected=False
[8/20/2026 7:19:02 PM] Client disconnected [8/27/2026 1:45:31 PM] Client disconnected
[8/20/2026 7:19:02 PM] Mirror server exception logging enabled
[8/20/2026 7:19:02 PM] Game started On localhost, tutorial mode enabled
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 2cc4ee68f3294624c9898f706bab87a8
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+16
View File
@@ -0,0 +1,16 @@
[8/26/2026 10:21:50 PM] ReplayRecorder started (practice) id -1787763110 with 11 entities
[8/26/2026 10:21:50 PM] Client connected
[8/26/2026 10:21:51 PM] Dedicated join: team assigned Blue isServer=True matchId=0 secretEmpty=False redJoin=False blueJoin=False collected=False
[8/26/2026 10:21:51 PM] Dedicated join: skipping PATCH (matchId=0, secretEmpty=False)
[8/26/2026 10:21:51 PM] Selected team changed from Red to Blue
[8/26/2026 10:21:55 PM] Match: Blue forfeited by leave — Red wins
[8/26/2026 10:21:55 PM] ReplayRecorder wrote F:/Projects/Unity/soccar2d/Assets\Logs\-1787763110.json (218 frames, 0 events, duration 4.36s)
[8/26/2026 10:21:55 PM] Dedicated match: end winner=Red red_connected=False blue_connected=False red_score=0 blue_score=0 forfeit=True
[8/26/2026 10:21:55 PM] Mirror server: client disconnected (connId=0)
[8/26/2026 10:21:55 PM] Client disconnected
[8/26/2026 10:22:00 PM] Cupid settings updated
[8/26/2026 10:22:01 PM] Cupid settings updated
[8/26/2026 10:22:03 PM] Configured dedicated match reporting for match id 0 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com
[8/26/2026 10:22:10 PM] Invalid Room port
[8/26/2026 10:22:10 PM] Mirror server exception logging enabled
[8/26/2026 10:22:10 PM] Game started On localhost, tutorial mode enabled
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: eafec47de336f534da962bda68ab7dfb
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 62574c44b8b7522459dc1aebd641aa7f
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+16
View File
@@ -0,0 +1,16 @@
[8/26/2026 10:22:10 PM] ReplayRecorder started (practice) id -1787763130 with 11 entities
[8/26/2026 10:22:10 PM] Client connected
[8/26/2026 10:22:10 PM] Dedicated join: team assigned Blue isServer=True matchId=0 secretEmpty=False redJoin=False blueJoin=False collected=False
[8/26/2026 10:22:10 PM] Dedicated join: skipping PATCH (matchId=0, secretEmpty=False)
[8/26/2026 10:22:10 PM] Selected team changed from Red to Blue
[8/26/2026 10:22:14 PM] Match: Blue forfeited by leave — Red wins
[8/26/2026 10:22:14 PM] ReplayRecorder wrote F:/Projects/Unity/soccar2d/Assets\Logs\-1787763130.json (198 frames, 0 events, duration 3.96s)
[8/26/2026 10:22:14 PM] Dedicated match: end winner=Red red_connected=False blue_connected=False red_score=0 blue_score=0 forfeit=True
[8/26/2026 10:22:14 PM] Mirror server: client disconnected (connId=0)
[8/26/2026 10:22:14 PM] Client disconnected
[8/26/2026 10:22:19 PM] Cupid settings updated
[8/26/2026 10:22:19 PM] Cupid settings updated
[8/26/2026 10:22:22 PM] Configured dedicated match reporting for match id 0 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com
[8/26/2026 10:22:29 PM] Invalid Room port
[8/26/2026 10:22:29 PM] Mirror server exception logging enabled
[8/26/2026 10:22:29 PM] Game started On localhost, tutorial mode enabled
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 6e233967e946ccc4b921379b66b22740
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 5e168c91dfd19c748907045eef730143
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+16
View File
@@ -0,0 +1,16 @@
[8/26/2026 10:22:29 PM] ReplayRecorder started (practice) id -1787763149 with 11 entities
[8/26/2026 10:22:29 PM] Client connected
[8/26/2026 10:22:29 PM] Dedicated join: team assigned Blue isServer=True matchId=0 secretEmpty=False redJoin=False blueJoin=False collected=False
[8/26/2026 10:22:29 PM] Dedicated join: skipping PATCH (matchId=0, secretEmpty=False)
[8/26/2026 10:22:29 PM] Selected team changed from Red to Blue
[8/26/2026 10:22:32 PM] Match: Blue forfeited by leave — Red wins
[8/26/2026 10:22:32 PM] ReplayRecorder wrote F:/Projects/Unity/soccar2d/Assets\Logs\-1787763149.json (171 frames, 0 events, duration 3.42s)
[8/26/2026 10:22:32 PM] Dedicated match: end winner=Red red_connected=False blue_connected=False red_score=0 blue_score=0 forfeit=True
[8/26/2026 10:22:32 PM] Mirror server: client disconnected (connId=0)
[8/26/2026 10:22:32 PM] Client disconnected
[8/26/2026 10:22:36 PM] Cupid settings updated
[8/26/2026 10:22:37 PM] Cupid settings updated
[8/26/2026 10:22:38 PM] Configured dedicated match reporting for match id 0 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com
[8/26/2026 10:22:45 PM] Invalid Room port
[8/26/2026 10:22:45 PM] Mirror server exception logging enabled
[8/26/2026 10:22:45 PM] Game started On localhost, tutorial mode enabled
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: afd7819d04d262d42a80b619146a0acc
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
File diff suppressed because one or more lines are too long
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: f104f470c2a16344ea9b9aab39ff0f37
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+16
View File
@@ -0,0 +1,16 @@
[8/26/2026 10:22:45 PM] ReplayRecorder started (practice) id -1787763165 with 11 entities
[8/26/2026 10:22:45 PM] Client connected
[8/26/2026 10:22:45 PM] Dedicated join: team assigned Blue isServer=True matchId=0 secretEmpty=False redJoin=False blueJoin=False collected=False
[8/26/2026 10:22:45 PM] Dedicated join: skipping PATCH (matchId=0, secretEmpty=False)
[8/26/2026 10:22:45 PM] Selected team changed from Red to Blue
[8/26/2026 10:22:57 PM] Match: Blue forfeited by leave — Red wins
[8/26/2026 10:22:57 PM] ReplayRecorder wrote F:/Projects/Unity/soccar2d/Assets\Logs\-1787763165.json (605 frames, 0 events, duration 12.10s)
[8/26/2026 10:22:57 PM] Dedicated match: end winner=Red red_connected=False blue_connected=False red_score=0 blue_score=0 forfeit=True
[8/26/2026 10:22:57 PM] Mirror server: client disconnected (connId=0)
[8/26/2026 10:22:57 PM] Client disconnected
[8/26/2026 10:23:02 PM] Cupid settings updated
[8/26/2026 10:23:02 PM] Cupid settings updated
[8/26/2026 10:23:05 PM] Configured dedicated match reporting for match id 0 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com
[8/26/2026 10:23:11 PM] Invalid Room port
[8/26/2026 10:23:11 PM] Mirror server exception logging enabled
[8/26/2026 10:23:11 PM] Game started On localhost, tutorial mode enabled
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: b6b634e5c0a824d47b49e89290032735
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+1
View File
@@ -0,0 +1 @@
{"version":1,"matchId":-1787763191,"isPractice":true,"fixedDeltaTime":0.019999992102384568,"duration":0.0,"entities":[{"id":0,"type":"ball","team":""},{"id":1,"type":"puck","team":"Red"},{"id":2,"type":"puck","team":"Red"},{"id":3,"type":"puck","team":"Red"},{"id":4,"type":"puck","team":"Red"},{"id":5,"type":"puck","team":"Red"},{"id":6,"type":"puck","team":"Blue"},{"id":7,"type":"puck","team":"Blue"},{"id":8,"type":"puck","team":"Blue"},{"id":9,"type":"puck","team":"Blue"},{"id":10,"type":"puck","team":"Blue"}],"frames":[],"events":[]}
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: d1dd94f034d5fcc48a72276d45f82c83
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+8
View File
@@ -0,0 +1,8 @@
[8/26/2026 10:23:11 PM] ReplayRecorder started (practice) id -1787763191 with 11 entities
[8/26/2026 10:23:11 PM] Client connected
[8/26/2026 10:23:11 PM] Dedicated join: team assigned Blue isServer=True matchId=0 secretEmpty=False redJoin=False blueJoin=False collected=False
[8/26/2026 10:23:11 PM] Dedicated join: skipping PATCH (matchId=0, secretEmpty=False)
[8/26/2026 10:23:11 PM] Dedicated match: Blue disconnected (order count=1)
[8/26/2026 10:23:11 PM] Mirror server: client disconnected (connId=0)
[8/26/2026 10:23:11 PM] Client disconnected
[8/26/2026 10:23:11 PM] ReplayRecorder wrote F:/Projects/Unity/soccar2d/Assets\Logs\-1787763191.json (0 frames, 0 events, duration 0.00s)
+7
View File
@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 13d3b05348f90644b8f236f835efa4c2
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
+11
View File
@@ -437,3 +437,14 @@
[8/18/2026 2:02:56 AM] Failed to fetch red and blue names, isServer? [8/18/2026 2:02:56 AM] Failed to fetch red and blue names, isServer?
[8/18/2026 2:02:56 AM] Starting auto close watchdog [8/18/2026 2:02:56 AM] Starting auto close watchdog
[8/18/2026 2:02:56 AM] Active player connections: 0 [8/18/2026 2:02:56 AM] Active player connections: 0
[8/27/2026 1:12:53 PM] Starting server at port 7777
[8/27/2026 1:12:53 PM] Mirror server exception logging enabled
[8/27/2026 1:12:53 PM] Failed to fetch red and blue names, isServer?
[8/27/2026 1:12:53 PM] Starting auto close watchdog
[8/27/2026 1:12:53 PM] Active player connections: 0
[8/27/2026 1:12:59 PM] Server will be closed due to no players in, 60
[8/27/2026 1:42:51 PM] Starting server at port 7777
[8/27/2026 1:42:51 PM] Mirror server exception logging enabled
[8/27/2026 1:42:51 PM] Failed to fetch red and blue names, isServer?
[8/27/2026 1:42:51 PM] Starting auto close watchdog
[8/27/2026 1:42:51 PM] Active player connections: 0
+23 -23
View File
@@ -578,7 +578,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 0 m_IsActive: 1
--- !u!224 &4426299922493186842 --- !u!224 &4426299922493186842
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -595,7 +595,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -12, y: -301.3} m_AnchoredPosition: {x: -12, y: -289}
m_SizeDelta: {x: 396.3171, y: 206.1671} m_SizeDelta: {x: 396.3171, y: 206.1671}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &5777954290886970586 --- !u!222 &5777954290886970586
@@ -619,7 +619,7 @@ MonoBehaviour:
m_Name: m_Name:
m_EditorClassIdentifier: m_EditorClassIdentifier:
m_Material: {fileID: 0} m_Material: {fileID: 0}
m_Color: {r: 1, g: 1, b: 1, a: 1} m_Color: {r: 0.8349056, g: 0.93029827, b: 1, a: 1}
m_RaycastTarget: 1 m_RaycastTarget: 1
m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0}
m_Maskable: 1 m_Maskable: 1
@@ -671,7 +671,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 351.29, y: 619.50073} m_AnchoredPosition: {x: 291.99997, y: 619.50073}
m_SizeDelta: {x: 356.21, y: 79.8881} m_SizeDelta: {x: 356.21, y: 79.8881}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4299910807936819090 --- !u!222 &4299910807936819090
@@ -747,7 +747,7 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_Sprite: {fileID: -5110294184840258280, guid: b3993aed15d744d4bb390d5351cda423, type: 3} m_Sprite: {fileID: 0}
m_Type: 0 m_Type: 0
m_PreserveAspect: 0 m_PreserveAspect: 0
m_FillCenter: 1 m_FillCenter: 1
@@ -789,9 +789,9 @@ RectTransform:
m_Children: [] m_Children: []
m_Father: {fileID: 784446025213843339} m_Father: {fileID: 784446025213843339}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 349.8392, y: -415.53} m_AnchoredPosition: {x: 349.8392, y: 714.47}
m_SizeDelta: {x: 287.9087, y: 53.690674} m_SizeDelta: {x: 287.9087, y: 53.690674}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4680061499564276536 --- !u!222 &4680061499564276536
@@ -928,7 +928,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -351.29, y: 619.50073} m_AnchoredPosition: {x: -297.8, y: 619.50073}
m_SizeDelta: {x: 356.21, y: 79.8881} m_SizeDelta: {x: 356.21, y: 79.8881}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2120176914018994436 --- !u!222 &2120176914018994436
@@ -1198,8 +1198,8 @@ MonoBehaviour:
m_faceColor: m_faceColor:
serializedVersion: 2 serializedVersion: 2
rgba: 4294967295 rgba: 4294967295
m_fontSize: 49.1 m_fontSize: 46.1
m_fontSizeBase: 49.1 m_fontSizeBase: 46.1
m_fontWeight: 400 m_fontWeight: 400
m_enableAutoSizing: 0 m_enableAutoSizing: 0
m_fontSizeMin: 18 m_fontSizeMin: 18
@@ -1277,7 +1277,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -351.29, y: 619.50073} m_AnchoredPosition: {x: -297.8, y: 619.50073}
m_SizeDelta: {x: 356.21, y: 79.8881} m_SizeDelta: {x: 356.21, y: 79.8881}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &588061042461009508 --- !u!222 &588061042461009508
@@ -1456,9 +1456,9 @@ RectTransform:
m_Children: [] m_Children: []
m_Father: {fileID: 784446025213843339} m_Father: {fileID: 784446025213843339}
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 1} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 1} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -349.83923, y: -415.53} m_AnchoredPosition: {x: -349.83923, y: 714.47}
m_SizeDelta: {x: 287.9087, y: 53.690674} m_SizeDelta: {x: 287.9087, y: 53.690674}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &4305625922513859524 --- !u!222 &4305625922513859524
@@ -1868,7 +1868,7 @@ RectTransform:
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -0.0000059605, y: 619.1} m_AnchoredPosition: {x: -0.0000059605, y: 619.1}
m_SizeDelta: {x: 433.0019, y: 98.6273} m_SizeDelta: {x: 359.3, y: 98.6273}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &8725577243422270907 --- !u!222 &8725577243422270907
CanvasRenderer: CanvasRenderer:
@@ -2094,7 +2094,7 @@ RectTransform:
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: -6.8129, y: 711.5879} m_AnchoredPosition: {x: -6.8129, y: 711.5879}
m_SizeDelta: {x: 370.1125, y: 86.3439} m_SizeDelta: {x: 267.8, y: 86.3439}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &2040376918808009174 --- !u!222 &2040376918808009174
CanvasRenderer: CanvasRenderer:
@@ -2244,7 +2244,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0.5, y: 0.5} m_AnchorMin: {x: 0.5, y: 0.5}
m_AnchorMax: {x: 0.5, y: 0.5} m_AnchorMax: {x: 0.5, y: 0.5}
m_AnchoredPosition: {x: 351.29, y: 619.50073} m_AnchoredPosition: {x: 292, y: 619.50073}
m_SizeDelta: {x: 356.21, y: 79.8881} m_SizeDelta: {x: 356.21, y: 79.8881}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &3873575104506013387 --- !u!222 &3873575104506013387
@@ -2470,7 +2470,7 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_Sprite: {fileID: 8390053243822926539, guid: 511a187332d4a4d4db6f55f623e1de11, type: 3} m_Sprite: {fileID: 8390053243822926539, guid: 5b969ed0d82676d4890df6c74fd6f3c4, type: 3}
m_Type: 0 m_Type: 0
m_PreserveAspect: 0 m_PreserveAspect: 0
m_FillCenter: 1 m_FillCenter: 1
@@ -2728,7 +2728,7 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_Sprite: {fileID: 8390053243822926539, guid: 511a187332d4a4d4db6f55f623e1de11, type: 3} m_Sprite: {fileID: 8390053243822926539, guid: 5b969ed0d82676d4890df6c74fd6f3c4, type: 3}
m_Type: 0 m_Type: 0
m_PreserveAspect: 0 m_PreserveAspect: 0
m_FillCenter: 1 m_FillCenter: 1
@@ -3625,7 +3625,7 @@ MonoBehaviour:
p2_name: {fileID: 6139878670004169448} p2_name: {fileID: 6139878670004169448}
p1_l10: {fileID: 7658668847612786734} p1_l10: {fileID: 7658668847612786734}
p2_l10: {fileID: 8415686484963452604} p2_l10: {fileID: 8415686484963452604}
redIcon: {fileID: 7194123030578827194, guid: 809c8d780dc80f14e80fd92c6e42ed71, type: 3} redIcon: {fileID: 7609527126711406816, guid: 532bcbd7fabd63844ac75765ae25dcb9, type: 3}
blueIcon: {fileID: 7609527126711406816, guid: 8d015c6e4a5ab8540814b06ae5f85980, type: 3} blueIcon: {fileID: 7609527126711406816, guid: 8d015c6e4a5ab8540814b06ae5f85980, type: 3}
txtMiddle: {fileID: 2458004521057696282} txtMiddle: {fileID: 2458004521057696282}
txtRcPrize: {fileID: 8330661879995437874} txtRcPrize: {fileID: 8330661879995437874}
@@ -3953,7 +3953,7 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 0, y: 0} m_AnchorMin: {x: 0, y: 0}
m_AnchorMax: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: 1.326294, y: -53.300316} m_AnchoredPosition: {x: 1.326294, y: -53.300537}
m_SizeDelta: {x: 82.232544, y: 5.79937} m_SizeDelta: {x: 82.232544, y: 5.79937}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!222 &8345919255487113005 --- !u!222 &8345919255487113005
@@ -3984,7 +3984,7 @@ MonoBehaviour:
m_OnCullStateChanged: m_OnCullStateChanged:
m_PersistentCalls: m_PersistentCalls:
m_Calls: [] m_Calls: []
m_Sprite: {fileID: -7443756053782179069, guid: 0ec6ee71c3b91214284f88b794c2f1e7, type: 3} m_Sprite: {fileID: -1955448553306655712, guid: b9f492da50bba6a4cae145945abc32e8, type: 3}
m_Type: 0 m_Type: 0
m_PreserveAspect: 0 m_PreserveAspect: 0
m_FillCenter: 1 m_FillCenter: 1
+1 -1
View File
@@ -23699,7 +23699,7 @@ MonoBehaviour:
ballMoveTime: 5 ballMoveTime: 5
puckDragClampMax: 5 puckDragClampMax: 5
puckDragMinClamp: 0.75 puckDragMinClamp: 0.75
puckSelectMaxDistance: 2 puckSelectMaxDistance: 1
fieldSize: 3.25 fieldSize: 3.25
cameraStretchBoundaryExponent: 2.5 cameraStretchBoundaryExponent: 2.5
redScore: 0 redScore: 0
+7 -79
View File
@@ -9470,50 +9470,10 @@ PrefabInstance:
serializedVersion: 3 serializedVersion: 3
m_TransformParent: {fileID: 0} m_TransformParent: {fileID: 0}
m_Modifications: m_Modifications:
- target: {fileID: 2625666949678814403, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3} - target: {fileID: 2458004521057696282, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_IsActive propertyPath: m_enableAutoSizing
value: 1 value: 1
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 2855071711224960201, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3027208764083308819, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_IsActive
value: 0
objectReference: {fileID: 0}
- target: {fileID: 3465182817620600145, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_AnchorMax.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 3465182817620600145, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_AnchorMin.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 3465182817620600145, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_AnchoredPosition.y
value: 714.47
objectReference: {fileID: 0}
- target: {fileID: 3697438882816933721, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: redIcon
value:
objectReference: {fileID: 7609527126711406816, guid: 532bcbd7fabd63844ac75765ae25dcb9, type: 3}
- target: {fileID: 3749771552368919126, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Sprite
value:
objectReference: {fileID: 0}
- target: {fileID: 4426299922493186842, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_AnchoredPosition.y
value: -289
objectReference: {fileID: 0}
- target: {fileID: 4545260003495756882, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 5669134292471989017, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Sprite
value:
objectReference: {fileID: 8390053243822926539, guid: 5b969ed0d82676d4890df6c74fd6f3c4, type: 3}
- target: {fileID: 6417757714012981459, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3} - target: {fileID: 6417757714012981459, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Pivot.x propertyPath: m_Pivot.x
value: 0 value: 0
@@ -9594,54 +9554,22 @@ PrefabInstance:
propertyPath: m_LocalEulerAnglesHint.z propertyPath: m_LocalEulerAnglesHint.z
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 6519676147968598479, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Color.b
value: 1
objectReference: {fileID: 0}
- target: {fileID: 6519676147968598479, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Color.g
value: 0.93029827
objectReference: {fileID: 0}
- target: {fileID: 6519676147968598479, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Color.r
value: 0.8349056
objectReference: {fileID: 0}
- target: {fileID: 6610414990034145927, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3} - target: {fileID: 6610414990034145927, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_IsActive propertyPath: m_IsActive
value: 0 value: 0
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 6864964370409994597, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3} - target: {fileID: 7631130990449649942, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Sprite propertyPath: m_SizeDelta.y
value: value: -16.68
objectReference: {fileID: 8390053243822926539, guid: 5b969ed0d82676d4890df6c74fd6f3c4, type: 3}
- target: {fileID: 8202105634251418107, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_AnchorMax.y
value: 0.5
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8202105634251418107, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3} - target: {fileID: 7631130990449649942, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_AnchorMin.y
value: 0.5
objectReference: {fileID: 0}
- target: {fileID: 8202105634251418107, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_AnchoredPosition.y propertyPath: m_AnchoredPosition.y
value: 714.47 value: 5.16
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8269240558470408597, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Sprite
value:
objectReference: {fileID: -1955448553306655712, guid: b9f492da50bba6a4cae145945abc32e8, type: 3}
- target: {fileID: 8578419198713715619, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3} - target: {fileID: 8578419198713715619, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_Name propertyPath: m_Name
value: LevelLoader value: LevelLoader
objectReference: {fileID: 0} objectReference: {fileID: 0}
- target: {fileID: 8578419198713715619, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_IsActive
value: 1
objectReference: {fileID: 0}
- target: {fileID: 8986273419714486717, guid: 169bd8967120a614da3d7b0e9c71557c, type: 3}
propertyPath: m_AnchoredPosition.y
value: -53.300537
objectReference: {fileID: 0}
m_RemovedComponents: [] m_RemovedComponents: []
m_RemovedGameObjects: [] m_RemovedGameObjects: []
m_AddedGameObjects: [] m_AddedGameObjects: []
+6 -6
View File
@@ -8135,7 +8135,7 @@ GameObject:
m_Icon: {fileID: 0} m_Icon: {fileID: 0}
m_NavMeshLayer: 0 m_NavMeshLayer: 0
m_StaticEditorFlags: 0 m_StaticEditorFlags: 0
m_IsActive: 1 m_IsActive: 0
--- !u!224 &840893991 --- !u!224 &840893991
RectTransform: RectTransform:
m_ObjectHideFlags: 0 m_ObjectHideFlags: 0
@@ -9765,7 +9765,7 @@ MonoBehaviour:
m_enableAutoSizing: 0 m_enableAutoSizing: 0
m_fontSizeMin: 18 m_fontSizeMin: 18
m_fontSizeMax: 72 m_fontSizeMax: 72
m_fontStyle: 0 m_fontStyle: 16
m_HorizontalAlignment: 1 m_HorizontalAlignment: 1
m_VerticalAlignment: 256 m_VerticalAlignment: 256
m_textAlignment: 65535 m_textAlignment: 65535
@@ -10114,7 +10114,7 @@ MonoBehaviour:
m_margin: {x: 0, y: 0, z: 0, w: 0} m_margin: {x: 0, y: 0, z: 0, w: 0}
m_isUsingLegacyAnimationComponent: 0 m_isUsingLegacyAnimationComponent: 0
m_isVolumetricText: 0 m_isVolumetricText: 0
m_hasFontAssetChanged: 1 m_hasFontAssetChanged: 0
m_baseMaterial: {fileID: 0} m_baseMaterial: {fileID: 0}
m_maskOffset: {x: 0, y: 0, z: 0, w: 0} m_maskOffset: {x: 0, y: 0, z: 0, w: 0}
--- !u!222 &991656204 --- !u!222 &991656204
@@ -16702,8 +16702,8 @@ RectTransform:
m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0}
m_AnchorMin: {x: 1, y: 1} m_AnchorMin: {x: 1, y: 1}
m_AnchorMax: {x: 1, y: 1} m_AnchorMax: {x: 1, y: 1}
m_AnchoredPosition: {x: -314.68228, y: -213.59998} m_AnchoredPosition: {x: -357.5037, y: -220.18799}
m_SizeDelta: {x: 134.3185, y: 74.7677} m_SizeDelta: {x: 157.3761, y: 87.9436}
m_Pivot: {x: 0.5, y: 0.5} m_Pivot: {x: 0.5, y: 0.5}
--- !u!114 &1636876511 --- !u!114 &1636876511
MonoBehaviour: MonoBehaviour:
@@ -19187,7 +19187,7 @@ MonoBehaviour:
m_enableAutoSizing: 0 m_enableAutoSizing: 0
m_fontSizeMin: 18 m_fontSizeMin: 18
m_fontSizeMax: 72 m_fontSizeMax: 72
m_fontStyle: 0 m_fontStyle: 16
m_HorizontalAlignment: 1 m_HorizontalAlignment: 1
m_VerticalAlignment: 256 m_VerticalAlignment: 256
m_textAlignment: 65535 m_textAlignment: 65535
+86 -35
View File
@@ -16,15 +16,43 @@ public class GameManager : NetworkBehaviour
public static MatchmadePlayer BluePlayer { get; set; } public static MatchmadePlayer BluePlayer { get; set; }
/// <summary>Coin units from matchmaker <c>rc_prize</c>; used for in-game prize UI.</summary> /// <summary>Coin units from matchmaker <c>rc_prize</c>; used for in-game prize UI.</summary>
public static int MatchRcPrizeCoins { get; set; } public static int MatchRcPrizeCoins { get; set; }
/// <summary>Clears match roster/team statics that survive scene unload (logout).</summary>
public static void ClearMatchSession()
{
MyTeam = default;
RedPlayer = null;
BluePlayer = null;
MatchRcPrizeCoins = 0;
RedFinishedMatch = true;
BlueFinishedMatch = true;
MatchWinningTeam = default;
MatchEndedByForfeit = false;
}
/// <summary>Participation CC amount shown on game over. Actual credit is decided by the winner PATCH.</summary> /// <summary>Participation CC amount shown on game over. Actual credit is decided by the winner PATCH.</summary>
public const int ParticipationCcAmount = 100; public const int ParticipationCcAmount = 100;
/// <summary>Server-reported: red was still connected when the match ended (eligible for participation CC).</summary> /// <summary>Server-reported: red was still connected when the match ended. Not inferred from winner.</summary>
public static bool RedFinishedMatch { get; private set; } = true; public static bool RedFinishedMatch { get; private set; } = true;
/// <summary>Server-reported: blue was still connected when the match ended (eligible for participation CC).</summary> /// <summary>Server-reported: blue was still connected when the match ended. Not inferred from winner.</summary>
public static bool BlueFinishedMatch { get; private set; } = true; public static bool BlueFinishedMatch { get; private set; } = true;
/// <summary>Local player stayed connected through match end and should see +CC on game over.</summary> /// <summary>Winning side at settle. Used with <see cref="MatchEndedByForfeit"/> for game-over CC display.</summary>
public static bool LocalPlayerEarnedParticipationCc => public static Team MatchWinningTeam { get; private set; }
MyTeam == Team.Blue ? BlueFinishedMatch : RedFinishedMatch; /// <summary>True for leave, disconnect, last-disconnect, and skip/auto-forfeit. Not shown in player UI.</summary>
public static bool MatchEndedByForfeit { get; private set; }
/// <summary>Local player should see +CC on game over: connected, and not the forfeit loser.</summary>
public static bool LocalPlayerEarnedParticipationCc
{
get
{
bool connected = MyTeam == Team.Blue ? BlueFinishedMatch : RedFinishedMatch;
if (!connected)
return false;
if (!MatchEndedByForfeit)
return true;
return MyTeam == MatchWinningTeam;
}
}
/// <summary>Set by dedicated server startup (e.g. CupidConnector parsing <c>-matchId</c>). PATCH is skipped if id ≤ 0 or secret is empty.</summary> /// <summary>Set by dedicated server startup (e.g. CupidConnector parsing <c>-matchId</c>). PATCH is skipped if id ≤ 0 or secret is empty.</summary>
public static int DedicatedMatchId { get; private set; } public static int DedicatedMatchId { get; private set; }
/// <summary>Sent as <c>X-Dedicated-Server-Secret</c>. From <c>-dedicatedSecret</c> arg or <c>DEDICATED_SERVER_SECRET</c> env.</summary> /// <summary>Sent as <c>X-Dedicated-Server-Secret</c>. From <c>-dedicatedSecret</c> arg or <c>DEDICATED_SERVER_SECRET</c> env.</summary>
@@ -437,7 +465,7 @@ public class GameManager : NetworkBehaviour
// Both gone → last player who disconnected wins immediately. // Both gone → last player who disconnected wins immediately.
if (!_redConnected && !_blueConnected && _disconnectOrder.Count > 0) if (!_redConnected && !_blueConnected && _disconnectOrder.Count > 0)
EndMatch(_disconnectOrder[_disconnectOrder.Count - 1]); EndMatch(_disconnectOrder[_disconnectOrder.Count - 1], forfeit: true);
} }
IEnumerator CoDedicatedMatchJoinPatch(string baseUrl, int matchId, string secret, string json, bool collectAttempt) IEnumerator CoDedicatedMatchJoinPatch(string baseUrl, int matchId, string secret, string json, bool collectAttempt)
@@ -578,12 +606,12 @@ public class GameManager : NetworkBehaviour
} }
} }
public IEnumerator DedicatedMatchPatchWinner(string baseUrl, int matchId, string secret, string winnerLower, bool redConnected, bool blueConnected) public IEnumerator DedicatedMatchPatchWinner(string baseUrl, int matchId, string secret, string winnerLower, bool redConnected, bool blueConnected, int redScore, int blueScore, bool forfeit)
{ {
if (matchId <= 0 || string.IsNullOrEmpty(secret)) if (matchId <= 0 || string.IsNullOrEmpty(secret))
yield break; yield break;
string jsonBody = DedicatedMatschInternalApi.BuildWinnerPatchJson(winnerLower, redConnected, blueConnected); string jsonBody = DedicatedMatschInternalApi.BuildWinnerPatchJson(winnerLower, redConnected, blueConnected, redScore, blueScore, forfeit);
using (var req = DedicatedMatschInternalApi.BuildWinnerRequest(baseUrl, matchId, secret, jsonBody)) using (var req = DedicatedMatschInternalApi.BuildWinnerRequest(baseUrl, matchId, secret, jsonBody))
{ {
yield return req.SendWebRequest(); yield return req.SendWebRequest();
@@ -591,7 +619,7 @@ public class GameManager : NetworkBehaviour
} }
} }
void ReportDedicatedMatchGameOver(Team winningTeam, bool redConnected, bool blueConnected) void ReportDedicatedMatchGameOver(Team winningTeam, bool redConnected, bool blueConnected, bool forfeit)
{ {
if (!isServer || DedicatedMatchId <= 0 || string.IsNullOrEmpty(DedicatedMatchSecret) || _winnerSettled) if (!isServer || DedicatedMatchId <= 0 || string.IsNullOrEmpty(DedicatedMatchSecret) || _winnerSettled)
return; return;
@@ -601,30 +629,32 @@ public class GameManager : NetworkBehaviour
return; return;
} }
_winnerSettled = true; _winnerSettled = true;
StartCoroutine(CoReportDedicatedMatchGameOver(winningTeam, redConnected, blueConnected)); StartCoroutine(CoReportDedicatedMatchGameOver(winningTeam, redConnected, blueConnected, forfeit));
} }
IEnumerator CoReportDedicatedMatchGameOver(Team winningTeam, bool redConnected, bool blueConnected) IEnumerator CoReportDedicatedMatchGameOver(Team winningTeam, bool redConnected, bool blueConnected, bool forfeit)
{ {
yield return DedicatedMatchPatch(DedicatedInternalApiBase, DedicatedMatchId, DedicatedMatchSecret, "{\"status\":3}"); yield return DedicatedMatchPatch(DedicatedInternalApiBase, DedicatedMatchId, DedicatedMatchSecret, "{\"status\":3}");
string winner = winningTeam == Team.Red ? "red" : "blue"; string winner = winningTeam == Team.Red ? "red" : "blue";
yield return DedicatedMatchPatchWinner(DedicatedInternalApiBase, DedicatedMatchId, DedicatedMatchSecret, winner, redConnected, blueConnected); yield return DedicatedMatchPatchWinner(DedicatedInternalApiBase, DedicatedMatchId, DedicatedMatchSecret, winner, redConnected, blueConnected, redScore, blueScore, forfeit);
} }
/// <summary>Score or forfeit end: latch game over, report winner if escrowed, notify clients.</summary> /// <summary>Score or forfeit end: latch game over, report winner if escrowed, notify clients.</summary>
void EndMatch(Team winningTeam) void EndMatch(Team winningTeam, bool forfeit)
{ {
if (!isServer || isGameEnded) if (!isServer || isGameEnded)
return; return;
isGameEnded = true; isGameEnded = true;
ReplayRecorder.StopAndFlush(); ReplayRecorder.StopAndFlush();
if (GameTutorialManager.tutorialModeEnabled)
GameTutorialManager.RecordCpuL10Result(winningTeam != MyTeam);
bool redConnected = IsSideConnectedForParticipation(Team.Red); bool redConnected = IsSideConnectedForParticipation(Team.Red);
bool blueConnected = IsSideConnectedForParticipation(Team.Blue); bool blueConnected = IsSideConnectedForParticipation(Team.Blue);
Logger.Log($"Dedicated match: end winner={winningTeam} red_connected={redConnected} blue_connected={blueConnected}"); Logger.Log($"Dedicated match: end winner={winningTeam} red_connected={redConnected} blue_connected={blueConnected} red_score={redScore} blue_score={blueScore} forfeit={forfeit}");
ApplyParticipationCcFlags(redConnected, blueConnected); ApplyParticipationCcFlags(redConnected, blueConnected, winningTeam, forfeit);
ReportDedicatedMatchGameOver(winningTeam, redConnected, blueConnected); ReportDedicatedMatchGameOver(winningTeam, redConnected, blueConnected, forfeit);
RpcGameOver(winningTeam, redConnected, blueConnected); RpcGameOver(winningTeam, redConnected, blueConnected, forfeit);
gameOver(winningTeam); gameOver(winningTeam);
} }
@@ -665,10 +695,12 @@ public class GameManager : NetworkBehaviour
return false; return false;
} }
static void ApplyParticipationCcFlags(bool redConnected, bool blueConnected) static void ApplyParticipationCcFlags(bool redConnected, bool blueConnected, Team winningTeam, bool forfeit)
{ {
RedFinishedMatch = redConnected; RedFinishedMatch = redConnected;
BlueFinishedMatch = blueConnected; BlueFinishedMatch = blueConnected;
MatchWinningTeam = winningTeam;
MatchEndedByForfeit = forfeit;
} }
void HandleDisconnectForfeitTimers() void HandleDisconnectForfeitTimers()
@@ -681,14 +713,14 @@ public class GameManager : NetworkBehaviour
if (!_redConnected && _blueConnected && _redForfeitDeadline > 0f && now >= _redForfeitDeadline) if (!_redConnected && _blueConnected && _redForfeitDeadline > 0f && now >= _redForfeitDeadline)
{ {
Logger.Log("Dedicated match: red forfeit grace expired — blue wins"); Logger.Log("Dedicated match: red forfeit grace expired — blue wins");
EndMatch(Team.Blue); EndMatch(Team.Blue, forfeit: true);
return; return;
} }
if (!_blueConnected && _redConnected && _blueForfeitDeadline > 0f && now >= _blueForfeitDeadline) if (!_blueConnected && _redConnected && _blueForfeitDeadline > 0f && now >= _blueForfeitDeadline)
{ {
Logger.Log("Dedicated match: blue forfeit grace expired — red wins"); Logger.Log("Dedicated match: blue forfeit grace expired — red wins");
EndMatch(Team.Red); EndMatch(Team.Red, forfeit: true);
return; return;
} }
@@ -699,7 +731,7 @@ public class GameManager : NetworkBehaviour
{ {
Team winner = _disconnectOrder[_disconnectOrder.Count - 1]; Team winner = _disconnectOrder[_disconnectOrder.Count - 1];
Logger.Log("Dedicated match: both forfeit graces expired — last disconnect wins: " + winner); Logger.Log("Dedicated match: both forfeit graces expired — last disconnect wins: " + winner);
EndMatch(winner); EndMatch(winner, forfeit: true);
} }
} }
@@ -727,9 +759,10 @@ public class GameManager : NetworkBehaviour
bool blueConnected = IsSideConnectedForParticipation(Team.Blue); bool blueConnected = IsSideConnectedForParticipation(Team.Blue);
_winnerSettled = true; _winnerSettled = true;
isGameEnded = true; isGameEnded = true;
ApplyParticipationCcFlags(redConnected, blueConnected); ApplyParticipationCcFlags(redConnected, blueConnected, winningTeam, forfeit: true);
Logger.Log("Dedicated match: blocking winner settle before shutdown → " + winningTeam Logger.Log("Dedicated match: blocking winner settle before shutdown → " + winningTeam
+ " red_connected=" + redConnected + " blue_connected=" + blueConnected); + " red_connected=" + redConnected + " blue_connected=" + blueConnected
+ " red_score=" + redScore + " blue_score=" + blueScore + " forfeit=true");
using (var statusReq = DedicatedMatschInternalApi.BuildRequest( using (var statusReq = DedicatedMatschInternalApi.BuildRequest(
DedicatedInternalApiBase, DedicatedMatchId, DedicatedMatchSecret, "{\"status\":3}")) DedicatedInternalApiBase, DedicatedMatchId, DedicatedMatchSecret, "{\"status\":3}"))
@@ -741,7 +774,7 @@ public class GameManager : NetworkBehaviour
} }
string winner = winningTeam == Team.Red ? "red" : "blue"; string winner = winningTeam == Team.Red ? "red" : "blue";
string jsonBody = DedicatedMatschInternalApi.BuildWinnerPatchJson(winner, redConnected, blueConnected); string jsonBody = DedicatedMatschInternalApi.BuildWinnerPatchJson(winner, redConnected, blueConnected, redScore, blueScore, forfeit: true);
using (var winReq = DedicatedMatschInternalApi.BuildWinnerRequest( using (var winReq = DedicatedMatschInternalApi.BuildWinnerRequest(
DedicatedInternalApiBase, DedicatedMatchId, DedicatedMatchSecret, jsonBody)) DedicatedInternalApiBase, DedicatedMatchId, DedicatedMatchSecret, jsonBody))
{ {
@@ -1100,7 +1133,7 @@ public class GameManager : NetworkBehaviour
Team winner = GetOpposingTeam(skippingTeam); Team winner = GetOpposingTeam(skippingTeam);
Logger.Log($"Match: {skippingTeam} forfeited for skipping two consecutive turns — {winner} wins"); Logger.Log($"Match: {skippingTeam} forfeited for skipping two consecutive turns — {winner} wins");
RpcHideSkipForfeitWarning(skippingTeam); RpcHideSkipForfeitWarning(skippingTeam);
EndMatch(winner); EndMatch(winner, forfeit: true);
return; return;
} }
@@ -1294,9 +1327,9 @@ public class GameManager : NetworkBehaviour
if(blueScore >= 3){ if(blueScore >= 3){
EndMatch(Team.Blue); EndMatch(Team.Blue, forfeit: false);
}else if(redScore >= 3){ }else if(redScore >= 3){
EndMatch(Team.Red); EndMatch(Team.Red, forfeit: false);
}else{ }else{
StartCoroutine(CoroutineOnGoal(team)); StartCoroutine(CoroutineOnGoal(team));
} }
@@ -1344,8 +1377,8 @@ public class GameManager : NetworkBehaviour
} }
[ClientRpc] [ClientRpc]
void RpcGameOver(Team team, bool redConnected, bool blueConnected){ void RpcGameOver(Team team, bool redConnected, bool blueConnected, bool forfeit){
ApplyParticipationCcFlags(redConnected, blueConnected); ApplyParticipationCcFlags(redConnected, blueConnected, team, forfeit);
gameOver(team); gameOver(team);
} }
@@ -1488,7 +1521,7 @@ public class GameManager : NetworkBehaviour
Team winner = GetOpposingTeam(leavingTeam); Team winner = GetOpposingTeam(leavingTeam);
Logger.Log($"Match: {leavingTeam} forfeited by leave — {winner} wins"); Logger.Log($"Match: {leavingTeam} forfeited by leave — {winner} wins");
EndMatch(winner); EndMatch(winner, forfeit: true);
} }
IEnumerator CoLeaveIfThirdPlayer() IEnumerator CoLeaveIfThirdPlayer()
@@ -1522,17 +1555,23 @@ public class GameManager : NetworkBehaviour
if (my == null || opp == null) if (my == null || opp == null)
yield break; yield break;
if (GameTutorialManager.tutorialModeEnabled)
GameTutorialManager.ApplyCpuL10(opp);
string baseUrl = (DedicatedInternalApiBase ?? "").TrimEnd('/'); string baseUrl = (DedicatedInternalApiBase ?? "").TrimEnd('/');
if (string.IsNullOrEmpty(baseUrl)) if (string.IsNullOrEmpty(baseUrl))
{
LevelLoadManager.myPlayer = my;
LevelLoadManager.opponentPlayer = opp;
yield break; yield break;
}
if (my.UserId > 0){ if (my.UserId > 0){
yield return CoFetchPlayerL10Apply(baseUrl, my); yield return CoFetchPlayerL10Apply(baseUrl, my);
} }
if (opp.UserId > 0 && opp.UserId != my.UserId){ if (!GameTutorialManager.tutorialModeEnabled && opp.UserId > 0 && opp.UserId != my.UserId){
yield return CoFetchPlayerL10Apply(baseUrl, opp); yield return CoFetchPlayerL10Apply(baseUrl, opp);
} }
LevelLoadManager.myPlayer = my; LevelLoadManager.myPlayer = my;
LevelLoadManager.opponentPlayer = opp; LevelLoadManager.opponentPlayer = opp;
@@ -1645,13 +1684,16 @@ static class DedicatedMatschInternalApi
return BuildPatchJson(url, secret, jsonBody); return BuildPatchJson(url, secret, jsonBody);
} }
public static string BuildWinnerPatchJson(string winnerLower, bool redConnected, bool blueConnected) public static string BuildWinnerPatchJson(string winnerLower, bool redConnected, bool blueConnected, int redScore, int blueScore, bool forfeit)
{ {
return JsonUtility.ToJson(new DedicatedWinnerPatchRequest return JsonUtility.ToJson(new DedicatedWinnerPatchRequest
{ {
winner = winnerLower, winner = winnerLower,
red_connected = redConnected, red_connected = redConnected,
blue_connected = blueConnected blue_connected = blueConnected,
red_score = redScore,
blue_score = blueScore,
forfeit = forfeit
}); });
} }
@@ -1709,7 +1751,10 @@ static class DedicatedMatschInternalApi
Logger.Log("Dedicated winner PATCH economy: rc_prize=" + parsed.economy.rc_prize Logger.Log("Dedicated winner PATCH economy: rc_prize=" + parsed.economy.rc_prize
+ " participant_cc=" + parsed.economy.participant_cc + " participant_cc=" + parsed.economy.participant_cc
+ " cc_awarded_red=" + parsed.economy.cc_awarded_red + " cc_awarded_red=" + parsed.economy.cc_awarded_red
+ " cc_awarded_blue=" + parsed.economy.cc_awarded_blue); + " cc_awarded_blue=" + parsed.economy.cc_awarded_blue
+ " mmr_delta=" + parsed.mmr_delta
+ " forfeit=" + parsed.forfeit
+ " already_settled=" + parsed.already_settled);
} }
} }
catch (Exception e) catch (Exception e)
@@ -1748,6 +1793,9 @@ class DedicatedWinnerPatchRequest
public string winner; public string winner;
public bool red_connected; public bool red_connected;
public bool blue_connected; public bool blue_connected;
public int red_score;
public int blue_score;
public bool forfeit;
} }
[Serializable] [Serializable]
@@ -1766,7 +1814,10 @@ class DedicatedWinnerPatchResponse
public bool ok; public bool ok;
public int id; public int id;
public int winner_id; public int winner_id;
public bool already_settled;
public DedicatedWinnerPatchEconomy economy; public DedicatedWinnerPatchEconomy economy;
public int mmr_delta;
public bool forfeit;
} }
[Serializable] [Serializable]
+2 -2
View File
@@ -56,7 +56,7 @@ public class GameOverCanvas : MonoBehaviour
public Button btnBetLimitAdjustCancel; public Button btnBetLimitAdjustCancel;
const string PersonalBetLimitPrefsKey = "WalkInvest.PersonalBetLimit"; const string PersonalBetLimitPrefsKey = "WalkInvest.PersonalBetLimit";
const int BetLimitMin = 2; const int BetLimitMin = 8;
const int BetLimitMax = 500; const int BetLimitMax = 500;
const int BetLimitUnlimited = 500; const int BetLimitUnlimited = 500;
@@ -455,7 +455,7 @@ public class GameOverCanvas : MonoBehaviour
yield return new WaitForSeconds(scaleTime * 0.5f); yield return new WaitForSeconds(scaleTime * 0.5f);
//Rewards — participation CC only if this client stayed connected through match end // Rewards — +CC only if this client was actually awarded it (connected non-forfeit, or forfeit winner)
float ccReward = GameTutorialManager.tutorialModeEnabled || !GameManager.LocalPlayerEarnedParticipationCc float ccReward = GameTutorialManager.tutorialModeEnabled || !GameManager.LocalPlayerEarnedParticipationCc
? 0f ? 0f
: GameManager.ParticipationCcAmount; : GameManager.ParticipationCcAmount;
+48 -2
View File
@@ -10,6 +10,8 @@ public class GameTutorialManager : MonoBehaviour
{ {
public const string CpuOpponentName = "CPU"; public const string CpuOpponentName = "CPU";
public const string DefaultGameSceneName = "Game"; public const string DefaultGameSceneName = "Game";
public const string CpuL10PrefsKey = "practice_cpu_l10";
const int L10Window = 10;
public static bool tutorialModeTrigger = false; public static bool tutorialModeTrigger = false;
public bool isTutorial = false; public bool isTutorial = false;
@@ -241,14 +243,58 @@ public class GameTutorialManager : MonoBehaviour
public static MatchmadePlayer CreateCpuOpponent() public static MatchmadePlayer CreateCpuOpponent()
{ {
GetCpuL10(out int wins, out int losses);
return new MatchmadePlayer return new MatchmadePlayer
{ {
Name = CpuOpponentName, Name = CpuOpponentName,
l10_wins = 10, l10_wins = wins,
l10_losses = 0 l10_losses = losses
}; };
} }
public static void GetCpuL10(out int wins, out int losses)
{
CountL10(PlayerPrefs.GetString(CpuL10PrefsKey, string.Empty), out wins, out losses);
}
public static void ApplyCpuL10(MatchmadePlayer cpu)
{
if (cpu == null)
return;
GetCpuL10(out int wins, out int losses);
cpu.l10_wins = wins;
cpu.l10_losses = losses;
}
/// <summary>
/// Records one practice result from the CPU's perspective (rolling last 10).
/// Cleared on logout because <see cref="LoginManager.Logout"/> calls PlayerPrefs.DeleteAll.
/// </summary>
public static void RecordCpuL10Result(bool cpuWon)
{
string history = PlayerPrefs.GetString(CpuL10PrefsKey, string.Empty) ?? string.Empty;
history += cpuWon ? 'W' : 'L';
if (history.Length > L10Window)
history = history.Substring(history.Length - L10Window);
PlayerPrefs.SetString(CpuL10PrefsKey, history);
PlayerPrefs.Save();
}
static void CountL10(string history, out int wins, out int losses)
{
wins = 0;
losses = 0;
if (string.IsNullOrEmpty(history))
return;
for (int i = 0; i < history.Length; i++)
{
if (history[i] == 'W')
wins++;
else if (history[i] == 'L')
losses++;
}
}
public static MatchmadePlayer CreateMyPlayerFromUser(UserData user) public static MatchmadePlayer CreateMyPlayerFromUser(UserData user)
{ {
return new MatchmadePlayer return new MatchmadePlayer
+27 -16
View File
@@ -110,16 +110,20 @@ public class LoginManager : MonoBehaviour
void Awake() void Awake()
{ {
HideServerMessagePanels(); HideServerMessagePanels();
AuthToken = PlayerPrefs.GetString(PlayerPrefsAuthKey, "");
if(instance !=null){ if (instance != null && instance != this)
Destroy(gameObject); {
return; instance.StopKeepalive();
SceneManager.sceneLoaded -= instance.OnSceneLoaded;
Destroy(instance.gameObject);
} }
instance = this; instance = this;
DontDestroyOnLoad(gameObject); DontDestroyOnLoad(gameObject);
SceneManager.sceneLoaded += OnSceneLoaded; SceneManager.sceneLoaded += OnSceneLoaded;
AuthToken = PlayerPrefs.GetString(PlayerPrefsAuthKey, "");
if (string.IsNullOrEmpty(AuthToken)) if (string.IsNullOrEmpty(AuthToken))
ClearLocalUserProfile(); ClearLocalUserProfile();
#if !UNITY_EDITOR #if !UNITY_EDITOR
@@ -248,10 +252,23 @@ public class LoginManager : MonoBehaviour
AuthToken = ""; AuthToken = "";
ClearLocalUserProfile(); ClearLocalUserProfile();
ClearMatchYourTeam(); ClearMatchYourTeam();
OnUserDataUpdated = null;
Cupid.ClearSession();
CupidLobby.ClearUsername();
GameManager.ClearMatchSession();
NetPlayer.RedPlayer = null;
NetPlayer.BluePlayer = null;
PlayerPrefs.DeleteAll(); PlayerPrefs.DeleteAll();
PlayerPrefs.Save(); PlayerPrefs.Save();
} }
/// <summary>Full logout, then reload the login scene so a fresh <see cref="LoginManager"/> can bind UI.</summary>
public static void LogoutAndReturnToLogin()
{
Logout();
SceneManager.LoadScene(0);
}
static void ProceedToMainMenu() static void ProceedToMainMenu()
{ {
if (LevelLoadManager.instance != null) if (LevelLoadManager.instance != null)
@@ -419,7 +436,7 @@ public class LoginManager : MonoBehaviour
if (request.result != UnityWebRequest.Result.Success && if (request.result != UnityWebRequest.Result.Success &&
request.result != UnityWebRequest.Result.ProtocolError) request.result != UnityWebRequest.Result.ProtocolError)
{ {
ShowAuthMessage(string.IsNullOrEmpty(request.error) ? "Network error" : request.error); ShowAuthMessage("Network Error, Please try again.");
SetBusy(false); SetBusy(false);
yield break; yield break;
} }
@@ -457,7 +474,7 @@ public class LoginManager : MonoBehaviour
} }
else else
{ {
ShowAuthMessage(string.IsNullOrEmpty(resp.error) ? "Request failed" : resp.error); ShowAuthMessage("Login failed. Please try again.");
} }
} }
@@ -878,11 +895,10 @@ public class LoginManager : MonoBehaviour
void OnDestroy() void OnDestroy()
{ {
SceneManager.sceneLoaded -= OnSceneLoaded;
StopKeepalive();
if (instance == this) if (instance == this)
{ instance = null;
SceneManager.sceneLoaded -= OnSceneLoaded;
StopKeepalive();
}
} }
void StartKeepalive() void StartKeepalive()
@@ -979,14 +995,9 @@ public class LoginManager : MonoBehaviour
if (_handlingKeepaliveUnauthorized) return; if (_handlingKeepaliveUnauthorized) return;
_handlingKeepaliveUnauthorized = true; _handlingKeepaliveUnauthorized = true;
InvalidateStoredSession();
SetBusy(false); SetBusy(false);
ShowAuthMessage(string.IsNullOrEmpty(message) ? "Session expired. Please sign in again." : message); ShowAuthMessage(string.IsNullOrEmpty(message) ? "Session expired. Please sign in again." : message);
LogoutAndReturnToLogin();
Scene active = SceneManager.GetActiveScene();
if (active.buildIndex != 0 && active.name != "Intro")
SceneManager.LoadScene(0);
} }
} }
+39 -18
View File
@@ -108,7 +108,11 @@ public class MainMenuManager : MonoBehaviour
inputCryptoAddress.onValueChanged.AddListener(OnCryptoAddressChanged); inputCryptoAddress.onValueChanged.AddListener(OnCryptoAddressChanged);
} }
UpdateWithdrawalStatus(); if (txtWithdrawStatus != null)
txtWithdrawStatus.gameObject.SetActive(false);
if (btnWithdrawal != null)
btnWithdrawal.onClick.AddListener(OnWithdrawalPressed);
if (btnPaste != null) if (btnPaste != null)
btnPaste.onClick.AddListener(OnPasteFromClipboard); btnPaste.onClick.AddListener(OnPasteFromClipboard);
@@ -138,6 +142,8 @@ public class MainMenuManager : MonoBehaviour
btnTutorial.onClick.RemoveListener(OnPlayTutorial); btnTutorial.onClick.RemoveListener(OnPlayTutorial);
if (btnLogout != null) if (btnLogout != null)
btnLogout.onClick.RemoveListener(OnLogout); btnLogout.onClick.RemoveListener(OnLogout);
if (btnWithdrawal != null)
btnWithdrawal.onClick.RemoveListener(OnWithdrawalPressed);
} }
void OnLogout() void OnLogout()
@@ -160,8 +166,7 @@ public class MainMenuManager : MonoBehaviour
void ConfirmLogout() void ConfirmLogout()
{ {
LoginManager.Logout(); LoginManager.LogoutAndReturnToLogin();
SceneManager.LoadScene(0);
} }
void OnToggleSfx(bool isOn) void OnToggleSfx(bool isOn)
@@ -234,33 +239,52 @@ public class MainMenuManager : MonoBehaviour
{ {
PlayerPrefs.SetString(CryptoAddressPrefsKey, value ?? string.Empty); PlayerPrefs.SetString(CryptoAddressPrefsKey, value ?? string.Empty);
PlayerPrefs.Save(); PlayerPrefs.Save();
UpdateWithdrawalStatus();
} }
void UpdateWithdrawalStatus(UserData user = null) void OnWithdrawalPressed()
{ {
if (txtWithdrawStatus == null) UserData user = LoginManager.CurrentUser;
return; if (user == null)
UserData u = user ?? LoginManager.CurrentUser; {
if (u == null) ShowWithdrawalMessage("Could not load your profile. Try again.", false);
return; return;
}
if (inputCryptoAddress != null && string.IsNullOrWhiteSpace(inputCryptoAddress.text)) if (inputCryptoAddress != null && string.IsNullOrWhiteSpace(inputCryptoAddress.text))
{ {
txtWithdrawStatus.text = "Enter a valid wallet address to withdraw safely."; ShowWithdrawalMessage("Enter a valid wallet address to withdraw safely.", true);
return; return;
} }
if (u.rc < MinimumWithdrawalRcCoins)
if (user.rc < MinimumWithdrawalRcCoins)
{ {
txtWithdrawStatus.text = "Your RC balance is below the minimum withdrawal amount ($20 USD / 20.0 RC)."; ShowWithdrawalMessage("Your RC balance is below the minimum withdrawal amount ($20 USD / 20.0 RC).", false);
return; return;
} }
if (u.cc < WithdrawalFeeCc)
if (user.cc < WithdrawalFeeCc)
{ {
txtWithdrawStatus.text = "Withdrawal costs 500 CC. Your CC balance is below 500 CC."; ShowWithdrawalMessage("Withdrawal costs 500 CC. Your CC balance is below 500 CC.", false);
return; return;
} }
txtWithdrawStatus.text = string.Empty; }
void ShowWithdrawalMessage(string message, bool basic)
{
if (MessageBoxDialog.IsAvailable)
{
if (basic)
MessageBoxDialog.ShowBasic(message);
else
MessageBoxDialog.Show("Can't withdraw", message);
return;
}
if (txtWithdrawStatus != null)
{
txtWithdrawStatus.gameObject.SetActive(true);
txtWithdrawStatus.text = message;
}
} }
void OnPasteFromClipboard() void OnPasteFromClipboard()
@@ -317,8 +341,6 @@ public class MainMenuManager : MonoBehaviour
rcPlayText.text = ""; rcPlayText.text = "";
if (btnPlay != null) if (btnPlay != null)
btnPlay.interactable = true; btnPlay.interactable = true;
UpdateWithdrawalStatus(user);
} }
/// <summary>Called by <see cref="LevelLoadManager"/> so the loading overlay stays until matchmaker settings are refreshed.</summary> /// <summary>Called by <see cref="LevelLoadManager"/> so the loading overlay stays until matchmaker settings are refreshed.</summary>
@@ -422,7 +444,6 @@ public class MainMenuManager : MonoBehaviour
dummyBuyScreen.SetActive(false); dummyBuyScreen.SetActive(false);
withdrawalScreen.SetActive(true); withdrawalScreen.SetActive(true);
settingsScreen.SetActive(false); settingsScreen.SetActive(false);
UpdateWithdrawalStatus();
} }
public void ShowSettingsScreen(){ public void ShowSettingsScreen(){
+4 -2
View File
@@ -50,19 +50,21 @@ public class TutorialManagerMainMenu : MonoBehaviour
if(!forceShow){ if(!forceShow){
if(PlayerPrefs.HasKey(TUTORIAL_PREF_KEY)){ if(PlayerPrefs.HasKey(TUTORIAL_PREF_KEY)){
tutorialPanel.SetActive(false); tutorialPanel.SetActive(false);
Debug.Log("Tutorial pref key is available, stopping;");
return; return;
} }
if(LoginManager.CurrentUser.rc > 0){ if(LoginManager.CurrentUser.rc > 0){
tutorialPanel.SetActive(false); tutorialPanel.SetActive(false);
Debug.Log("User has rc, stopping;");
return; return;
} }
} }
tutorialPanel.SetActive(true); tutorialPanel.SetActive(true);
screen1.SetActive(true); screen1.SetActive(true);
PlayerPrefs.SetInt(TUTORIAL_PREF_KEY, 1);
PlayerPrefs.Save();
} }
void OnNext1(){ void OnNext1(){
+8
View File
@@ -0,0 +1,8 @@
Logger initiated at 9/6/2026 9:17:41 PM
[9/6/2026 9:17:41 PM] Cupid settings updated
[9/6/2026 9:17:42 PM] Cupid settings updated
[9/6/2026 9:17:47 PM] Configured dedicated match reporting for match id 0 with secret 38516e39d3406225b7c3015a66e5d25c54e9b2024c0755212122bdcea3e3a328 and internal api base https://kkapi.playpoolstudios.com
[9/6/2026 9:17:53 PM] Invalid Room port
[9/6/2026 9:17:53 PM] Mirror server exception logging enabled
[9/6/2026 9:17:53 PM] Game started On localhost, tutorial mode enabled
+1 -1
View File
@@ -141,7 +141,7 @@ PlayerSettings:
loadStoreDebugModeEnabled: 0 loadStoreDebugModeEnabled: 0
visionOSBundleVersion: 1.0 visionOSBundleVersion: 1.0
tvOSBundleVersion: 1.0 tvOSBundleVersion: 1.0
bundleVersion: 1.34 bundleVersion: 1.37
preloadedAssets: preloadedAssets:
- {fileID: -944628639613478452, guid: 2bcd2660ca9b64942af0de543d8d7100, type: 3} - {fileID: -944628639613478452, guid: 2bcd2660ca9b64942af0de543d8d7100, type: 3}
metroInputSource: 0 metroInputSource: 0