This repository has been archived on 2024-11-20. You can view files and clone it, but cannot push or open issues or pull requests.
colourmeok/ColourMeOKGame/Assets/Scripts/LocalPlayerData.cs

177 lines
No EOL
6.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using UnityEngine;
public class LocalPlayerData
{
/// <summary>
/// queue of the best online scores,
/// used in user rating calculation and accuracy display stats
/// </summary>
public Queue<Score> BestOnlineScores = new(30);
/// <summary>
/// last known email used
/// </summary>
public string LastKnownEmail = "";
/// <summary>
/// last known username used
/// </summary>
public string LastKnownUsername = "Guest";
/// <summary>
/// queue of the 10 most recent local scores
/// </summary>
public Queue<Score> RecentLocalScores = new(10);
/// <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>
public void LoadFromTheWorld()
{
// 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();
}
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;
RegisterLocalScore(new Score(timestamp, noOfRounds, l, c, h));
}
// load online scores
RecentOnlineScores.Clear();
GameManager.Instance.Backend.GetRecentScores((_, recentOnlineScores) =>
{
foreach (var onlineScore in recentOnlineScores)
{
if (RecentOnlineScores.Count > 10) RecentOnlineScores.Dequeue();
RecentOnlineScores.Enqueue(onlineScore);
}
Debug.Log("loaded online scores from backend");
});
}
/// <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++;
}
Debug.Log("saved lpdata to playerprefs");
// online scores are already saved in the backend
}
/// <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);
}
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;
}
}
}