Files
TheVVaS-Assets/RPGCore/Runtime/GlobalModules/ProfileManagerGlobalModule/ProfileManagerModule.cs
T
2026-04-25 23:37:10 +02:00

125 lines
4.4 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using RPGCore.Core;
using UnityEngine;
namespace RPGCore.GlobalModules.ProfileManagerGlobalModule
{
[Serializable]
public class ProfileManagerModule : GlobalModule
{
// Paths
private static string directoryPath => Path.Combine(Application.persistentDataPath, "profiles");
private static string fileNameTemplate => "{0}_{1}.profile";
private static string fileNameMask => "*.profile";
private static string fileNameWithDefaultProfile => "default";
// Runtime
private Profile _activeProfile;
public event Action<Profile> OnProfileChange;
public Profile<T> LoadDefault<T>() where T : class
{
var defaultPath = Path.Combine(directoryPath, fileNameWithDefaultProfile);
// Default file not found
if (!File.Exists(defaultPath)) return null;
var guid = File.ReadAllText(defaultPath);
// Profile not found, by guid from default file
var file = Directory.GetFiles(directoryPath, string.Format(fileNameTemplate, "*", guid)).FirstOrDefault();
if (file == null) return null;
return JsonUtility.FromJson<Profile<T>>(File.ReadAllText(file));
}
/// <summary>
/// Gets currently active profile
/// </summary>
public Profile<T> Get<T>() where T : class
{
return _activeProfile as Profile<T>;
}
/// <summary>
/// Parse all profiles from files and returns them.
/// There is no caching, it will scan files everytime it is called.
/// </summary>
public List<Profile<T>> LoadAll<T>() where T : class
{
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
return Directory.GetFiles(directoryPath, fileNameMask)
.Select(File.ReadAllText)
.Select(JsonUtility.FromJson<Profile<T>>)
.ToList();
}
/// <summary>
/// Creates new profile with given name and saves it as file.
/// </summary>
public Profile<T> Create<T>(string name) where T : class
{
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
var newProfile = Activator.CreateInstance<Profile<T>>();
newProfile.name = name;
Save(newProfile);
return newProfile;
}
/// <summary>
/// Removes given profile from files and if its currently active unselects it.
/// </summary>
/// <param name="playerProfile"></param>
public void Delete<T>(Profile<T> playerProfile) where T : class
{
if (playerProfile == _activeProfile) Select<T>(null);
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
File.Delete(GetFullPathFor(playerProfile));
}
/// <summary>
/// Saves currently active profile as file.
/// </summary>
public void Save()
{
Save(_activeProfile);
}
/// <summary>
/// Saves given profile as file.
/// </summary>
private void Save(Profile profile)
{
if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath);
File.WriteAllText(GetFullPathFor(profile), JsonUtility.ToJson(profile, true));
}
/// <summary>
/// Set active given profile. Will be selected automatically next time.
/// </summary>
public void Select<T>(Profile<T> playerProfile) where T : class
{
_activeProfile = playerProfile;
OnProfileChange?.Invoke(_activeProfile);
// No profile found - create it for user
_activeProfile ??= Create<T>("New Profile");
// Our selected profile will be default one when starting game again
File.WriteAllText(Path.Combine(directoryPath, fileNameWithDefaultProfile), _activeProfile.guid);
}
private string GetFullPathFor(Profile playerProfile)
{
var fileName = string.Format(fileNameTemplate, playerProfile.name, playerProfile.guid);
return Path.Combine(directoryPath, fileName);
}
}
}