174 lines
4.7 KiB
C#
174 lines
4.7 KiB
C#
using System.Text.Json;
|
|
using System.Text.Json.Serialization;
|
|
|
|
namespace Roboto.Core;
|
|
|
|
public sealed class ProfileManager
|
|
{
|
|
private static readonly JsonSerializerOptions JsonOpts = new()
|
|
{
|
|
WriteIndented = true,
|
|
Converters = { new JsonStringEnumConverter() },
|
|
};
|
|
|
|
private readonly string _profilesDir;
|
|
private readonly string _assignmentsFile;
|
|
private readonly object _lock = new();
|
|
private Dictionary<string, string> _assignments = new(); // charName → profileName
|
|
|
|
public ProfileManager(string profilesDir = "profiles")
|
|
{
|
|
_profilesDir = Path.GetFullPath(profilesDir);
|
|
_assignmentsFile = Path.Combine(_profilesDir, "_assignments.json");
|
|
EnsureDirectory();
|
|
LoadAssignments();
|
|
}
|
|
|
|
public CharacterProfile LoadForCharacter(string charName)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
if (_assignments.TryGetValue(charName, out var profileName))
|
|
{
|
|
var profile = LoadProfile(profileName);
|
|
if (profile is not null)
|
|
return profile;
|
|
}
|
|
|
|
// Create default profile for this character
|
|
var defaultName = $"{charName}_Default";
|
|
var defaultProfile = new CharacterProfile { Name = defaultName };
|
|
SaveProfile(defaultProfile);
|
|
_assignments[charName] = defaultName;
|
|
SaveAssignments();
|
|
return defaultProfile;
|
|
}
|
|
}
|
|
|
|
public void Save(CharacterProfile profile)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
profile.LastModified = DateTime.UtcNow;
|
|
SaveProfile(profile);
|
|
}
|
|
}
|
|
|
|
public CharacterProfile? Duplicate(string profileName, string newName)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
var source = LoadProfile(profileName);
|
|
if (source is null) return null;
|
|
|
|
source.Name = newName;
|
|
source.CreatedAt = DateTime.UtcNow;
|
|
source.LastModified = DateTime.UtcNow;
|
|
SaveProfile(source);
|
|
return source;
|
|
}
|
|
}
|
|
|
|
public void AssignToCharacter(string charName, string profileName)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_assignments[charName] = profileName;
|
|
SaveAssignments();
|
|
}
|
|
}
|
|
|
|
public void Delete(string profileName)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
var path = ProfilePath(profileName);
|
|
if (File.Exists(path))
|
|
File.Delete(path);
|
|
|
|
// Remove any assignments pointing to this profile
|
|
var toRemove = _assignments
|
|
.Where(kv => kv.Value == profileName)
|
|
.Select(kv => kv.Key)
|
|
.ToList();
|
|
foreach (var key in toRemove)
|
|
_assignments.Remove(key);
|
|
if (toRemove.Count > 0)
|
|
SaveAssignments();
|
|
}
|
|
}
|
|
|
|
public List<string> ListProfiles()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
EnsureDirectory();
|
|
return Directory.GetFiles(_profilesDir, "*.json")
|
|
.Select(Path.GetFileNameWithoutExtension)
|
|
.Where(n => n is not null && !n.StartsWith("_"))
|
|
.Cast<string>()
|
|
.OrderBy(n => n)
|
|
.ToList();
|
|
}
|
|
}
|
|
|
|
public string? GetAssignment(string charName)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
return _assignments.GetValueOrDefault(charName);
|
|
}
|
|
}
|
|
|
|
private CharacterProfile? LoadProfile(string name)
|
|
{
|
|
var path = ProfilePath(name);
|
|
if (!File.Exists(path)) return null;
|
|
|
|
try
|
|
{
|
|
var json = File.ReadAllText(path);
|
|
return JsonSerializer.Deserialize<CharacterProfile>(json, JsonOpts);
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private void SaveProfile(CharacterProfile profile)
|
|
{
|
|
EnsureDirectory();
|
|
var json = JsonSerializer.Serialize(profile, JsonOpts);
|
|
File.WriteAllText(ProfilePath(profile.Name), json);
|
|
}
|
|
|
|
private void LoadAssignments()
|
|
{
|
|
if (!File.Exists(_assignmentsFile)) return;
|
|
try
|
|
{
|
|
var json = File.ReadAllText(_assignmentsFile);
|
|
_assignments = JsonSerializer.Deserialize<Dictionary<string, string>>(json, JsonOpts) ?? new();
|
|
}
|
|
catch
|
|
{
|
|
_assignments = new();
|
|
}
|
|
}
|
|
|
|
private void SaveAssignments()
|
|
{
|
|
EnsureDirectory();
|
|
var json = JsonSerializer.Serialize(_assignments, JsonOpts);
|
|
File.WriteAllText(_assignmentsFile, json);
|
|
}
|
|
|
|
private void EnsureDirectory()
|
|
{
|
|
if (!Directory.Exists(_profilesDir))
|
|
Directory.CreateDirectory(_profilesDir);
|
|
}
|
|
|
|
private string ProfilePath(string name) => Path.Combine(_profilesDir, $"{name}.json");
|
|
}
|