2024-11-17 19:10:01 +08:00
using System ;
using System.Collections.Generic ;
using System.Globalization ;
using UnityEngine ;
public class LocalPlayerData
{
2024-11-17 22:05:04 +08:00
/// <summary>
/// queue of the best online scores,
/// used in user rating calculation and accuracy display stats
/// </summary>
public Queue < Score > BestOnlineScores = new ( 30 ) ;
2024-11-17 19:10:01 +08:00
/// <summary>
/// last known email used
/// </summary>
public string LastKnownEmail = "" ;
2024-11-17 22:05:04 +08:00
2024-11-17 19:10:01 +08:00
/// <summary>
/// last known username used
/// </summary>
public string LastKnownUsername = "Guest" ;
2024-11-17 22:05:04 +08:00
2024-11-17 19:10:01 +08:00
/// <summary>
/// queue of the 10 most recent local scores
/// </summary>
public Queue < Score > RecentLocalScores = new ( 10 ) ;
2024-11-17 22:05:04 +08:00
2024-11-17 19:10:01 +08:00
/// <summary>
/// queue of the 10 most recent online scores,
/// used in user rating calculation and accuracy display stats
/// </summary>
public Queue < Score > RecentOnlineScores = new ( 10 ) ;
/// <summary>
/// loads player data from player prefs and database
/// </summary>
2024-11-18 00:16:53 +08:00
public void LoadFromTheWorld ( Action < LocalPlayerData > callback )
2024-11-17 19:10:01 +08:00
{
// load user data, possibly from the backend
var possibleUser = GameManager . Instance . Backend . GetUser ( ) ;
var currentKnownEmail = string . Empty ;
var currentKnownUsername = string . Empty ;
if ( possibleUser ! = null )
{
currentKnownEmail = possibleUser . Email ;
currentKnownUsername = GameManager . Instance . Backend . GetUsername ( ) ;
}
2024-11-17 22:05:04 +08:00
2024-11-17 19:10:01 +08:00
var lastStoredEmail = PlayerPrefs . GetString ( "LastKnownEmail" , "" ) ;
var lastStoredUsername = PlayerPrefs . GetString ( "LastKnownUsername" , "Guest" ) ;
LastKnownEmail = string . IsNullOrEmpty ( currentKnownEmail ) ? lastStoredEmail : currentKnownEmail ;
LastKnownUsername = string . IsNullOrEmpty ( currentKnownUsername ) ? lastStoredUsername : currentKnownUsername ;
// load local scores
RecentLocalScores . Clear ( ) ;
for ( var idx = 0 ; idx < 10 ; idx + + )
{
var timestampRaw = PlayerPrefs . GetString ( $"RecentLocalScores_{idx}_Timestamp" , "" ) ;
if ( timestampRaw = = "" ) continue ;
var timestamp = DateTime . TryParseExact ( timestampRaw ,
"s" ,
CultureInfo . InvariantCulture ,
DateTimeStyles . None ,
out var t )
? t
: DateTime . MinValue ;
if ( timestamp = = DateTime . MinValue ) continue ;
var noOfRounds = PlayerPrefs . GetInt ( $"RecentLocalScores_{idx}_NoOfRounds" , - 1 ) ;
var l = PlayerPrefs . GetFloat ( $"RecentLocalScores_{idx}_AvgLightnessAccuracy" , - 1f ) ;
var c = PlayerPrefs . GetFloat ( $"RecentLocalScores_{idx}_AvgChromaAccuracy" , - 1f ) ;
var h = PlayerPrefs . GetFloat ( $"RecentLocalScores_{idx}_AvgHueAccuracy" , - 1f ) ;
// if any of the values are invalid, don't add the score
if ( noOfRounds < 0 | | l < 0 | | c < 0 | | h < 0 ) continue ;
2024-11-17 21:32:14 +08:00
2024-11-17 21:32:26 +08:00
RegisterLocalScore ( new Score ( timestamp , noOfRounds , l , c , h ) ) ;
}
2024-11-17 22:05:04 +08:00
2024-11-17 19:10:01 +08:00
// load online scores
RecentOnlineScores . Clear ( ) ;
2024-11-17 22:05:04 +08:00
GameManager . Instance . Backend . GetRecentScores ( ( _ , recentOnlineScores ) = >
2024-11-17 19:10:01 +08:00
{
foreach ( var onlineScore in recentOnlineScores )
{
if ( RecentOnlineScores . Count > 10 ) RecentOnlineScores . Dequeue ( ) ;
RecentOnlineScores . Enqueue ( onlineScore ) ;
}
2024-11-17 21:32:26 +08:00
2024-11-17 22:31:03 +08:00
Debug . Log (
2024-11-18 00:16:53 +08:00
$"loaded lpdata from the world ({LastKnownUsername} <{LastKnownEmail}> with RLS.Count={RecentLocalScores.Count}, ROS.Count={RecentOnlineScores.Count}" ) ;
callback ( this ) ;
2024-11-17 22:05:04 +08:00
} ) ;
2024-11-17 19:10:01 +08:00
}
/// <summary>
/// saves player data to player prefs
/// </summary>
public void SaveToTheWorld ( )
{
PlayerPrefs . SetString ( "LastKnownEmail" , LastKnownEmail ) ;
PlayerPrefs . SetString ( "LastKnownUsername" , LastKnownUsername ) ;
var idx = 0 ;
foreach ( var score in RecentLocalScores )
{
PlayerPrefs . SetString ( $"RecentLocalScores_{idx}_Timestamp" ,
score . Timestamp . ToString ( "s" , CultureInfo . InvariantCulture ) ) ;
PlayerPrefs . SetInt ( $"RecentLocalScores_{idx}_NoOfRounds" , score . NoOfRounds ) ;
PlayerPrefs . SetFloat ( $"RecentLocalScores_{idx}_AvgLightnessAccuracy" , score . AvgLightnessAccuracy ) ;
PlayerPrefs . SetFloat ( $"RecentLocalScores_{idx}_AvgChromaAccuracy" , score . AvgChromaAccuracy ) ;
PlayerPrefs . SetFloat ( $"RecentLocalScores_{idx}_AvgHueAccuracy" , score . AvgHueAccuracy ) ;
idx + + ;
}
2024-11-17 22:31:03 +08:00
Debug . Log ( "saved lpdata to playerprefs" ) ; // online scores are already saved in the backend
2024-11-17 19:10:01 +08:00
}
2024-11-17 22:05:04 +08:00
/// <summary>
/// registers a score to the player's local data
/// </summary>
/// <param name="score">the score to register</param>
public void RegisterLocalScore ( Score score )
{
if ( RecentLocalScores . Count > 10 ) RecentLocalScores . Dequeue ( ) ;
RecentLocalScores . Enqueue ( score ) ;
}
2024-11-17 19:10:01 +08:00
public struct Score
{
/// <summary>
/// timestamp of the score
/// </summary>
public DateTime Timestamp ;
/// <summary>
/// number of rounds played (0-100)
/// </summary>
public int NoOfRounds ;
/// <summary>
/// average lightness accuracy across all rounds (0-100)
/// </summary>
public float AvgLightnessAccuracy ;
/// <summary>
/// average chroma accuracy across all rounds (0-100)
/// </summary>
public float AvgChromaAccuracy ;
/// <summary>
/// average hue accuracy across all rounds (0-100)
/// </summary>
public float AvgHueAccuracy ;
/// <summary>
/// constructor for the score struct
/// </summary>
/// <param name="timestamp">timestamp of the score</param>
/// <param name="noOfRounds">number of rounds played (0-100)</param>
/// <param name="l">average lightness accuracy across all rounds (0-100)</param>
/// <param name="c">average chroma accuracy across all rounds (0-100)</param>
/// <param name="h">average hue accuracy across all rounds (0-100)</param>
public Score ( DateTime timestamp = new ( ) , int noOfRounds = 1 , float l = 100.0f , float c = 100.0f ,
float h = 100.0f )
{
Timestamp = timestamp ;
NoOfRounds = noOfRounds ;
AvgLightnessAccuracy = l ;
AvgChromaAccuracy = c ;
AvgHueAccuracy = h ;
}
}
}