95 lines
3.3 KiB
C#
95 lines
3.3 KiB
C#
using Fusion;
|
|
using Hallucinate.Game;
|
|
using Hallucinate.UI;
|
|
using System.Collections.Generic;
|
|
using System.Threading.Tasks;
|
|
using UnityEngine;
|
|
|
|
namespace Hallucinate.Network
|
|
{
|
|
/// <summary>
|
|
/// Orchestrates the Elo calculation and persistence on the Host.
|
|
/// Broadcasts results to all clients.
|
|
/// </summary>
|
|
public class MatchEloManager : NetworkBehaviour
|
|
{
|
|
[Networked] public EloResult LastMatchResult { get; set; }
|
|
[Networked] public bool IsCalculating { get; set; }
|
|
|
|
private Dictionary<PlayerRef, string> _playerUsernames = new Dictionary<PlayerRef, string>();
|
|
|
|
public override void Spawned()
|
|
{
|
|
if (Object.HasStateAuthority)
|
|
{
|
|
// In a real scenario, you'd collect usernames as players join.
|
|
// For now, we assume they are provided or stored in PlayerRef custom data.
|
|
// Placeholder: Use a mock or collect from Session properties.
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Registers a player's username when they join.
|
|
/// </summary>
|
|
[Rpc(RpcSources.All, RpcTargets.StateAuthority)]
|
|
public void RPC_RegisterUsername(PlayerRef player, string username)
|
|
{
|
|
if (!_playerUsernames.ContainsKey(player))
|
|
{
|
|
_playerUsernames.Add(player, username);
|
|
Debug.Log($"[EloManager] Registered {username} for {player}");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Called by GameManager on Host when match ends.
|
|
/// </summary>
|
|
public async void ProcessMatchResult(PlayerRef winner, PlayerRef loser, bool isDraw = false)
|
|
{
|
|
if (!Object.HasStateAuthority) return;
|
|
|
|
IsCalculating = true;
|
|
|
|
string nameA = _playerUsernames.GetValueOrDefault(winner, "Unknown_A");
|
|
string nameB = _playerUsernames.GetValueOrDefault(loser, "Unknown_B");
|
|
|
|
// 1. Fetch from Firebase
|
|
var dataA = await FirebaseService.GetPlayerData(nameA);
|
|
var dataB = await FirebaseService.GetPlayerData(nameB);
|
|
|
|
// 2. Calculate
|
|
float resultA = isDraw ? 0.5f : 1.0f;
|
|
var result = EloSystem.Calculate(dataA.Rating, dataB.Rating, dataA.GamesPlayed, dataB.GamesPlayed, resultA);
|
|
|
|
// 3. Update Data Objects
|
|
dataA.Rating = result.NewRatingA;
|
|
dataA.GamesPlayed++;
|
|
|
|
dataB.Rating = result.NewRatingB;
|
|
dataB.GamesPlayed++;
|
|
|
|
// 4. Save to Firebase
|
|
await Task.WhenAll(
|
|
FirebaseService.SavePlayerData(nameA, dataA),
|
|
FirebaseService.SavePlayerData(nameB, dataB)
|
|
);
|
|
|
|
// 5. Broadcast
|
|
LastMatchResult = result;
|
|
IsCalculating = false;
|
|
|
|
Debug.Log($"[EloManager] Match Processed. Winner: {nameA} (+{result.DeltaA}), Loser: {nameB} ({result.DeltaB})");
|
|
|
|
// Send RPC to show UI
|
|
RPC_NotifyClients(result);
|
|
}
|
|
|
|
[Rpc(RpcSources.StateAuthority, RpcTargets.All)]
|
|
private void RPC_NotifyClients(EloResult result)
|
|
{
|
|
// This is where you'd trigger the Post-Match Rive/UI
|
|
Debug.Log($"[Client] Received Elo Update: {result.DeltaA} / {result.DeltaB}");
|
|
}
|
|
}
|
|
}
|