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 OnProfileChange; public Profile LoadDefault() 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>(File.ReadAllText(file)); } /// /// Gets currently active profile /// public Profile Get() where T : class { return _activeProfile as Profile; } /// /// Parse all profiles from files and returns them. /// There is no caching, it will scan files everytime it is called. /// public List> LoadAll() where T : class { if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); return Directory.GetFiles(directoryPath, fileNameMask) .Select(File.ReadAllText) .Select(JsonUtility.FromJson>) .ToList(); } /// /// Creates new profile with given name and saves it as file. /// public Profile Create(string name) where T : class { if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); var newProfile = Activator.CreateInstance>(); newProfile.name = name; Save(newProfile); return newProfile; } /// /// Removes given profile from files and if its currently active unselects it. /// /// public void Delete(Profile playerProfile) where T : class { if (playerProfile == _activeProfile) Select(null); if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); File.Delete(GetFullPathFor(playerProfile)); } /// /// Saves currently active profile as file. /// public void Save() { Save(_activeProfile); } /// /// Saves given profile as file. /// private void Save(Profile profile) { if (!Directory.Exists(directoryPath)) Directory.CreateDirectory(directoryPath); File.WriteAllText(GetFullPathFor(profile), JsonUtility.ToJson(profile, true)); } /// /// Set active given profile. Will be selected automatically next time. /// public void Select(Profile playerProfile) where T : class { _activeProfile = playerProfile; OnProfileChange?.Invoke(_activeProfile); // No profile found - create it for user _activeProfile ??= Create("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); } } }