125 lines
4.4 KiB
C#
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);
|
|
}
|
|
}
|
|
} |