Files
Exterrata 9bb4f85802 CVR Manager 1.0.0
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 02:46:35 -04:00

59 lines
2.3 KiB
C#

using System.Xml;
using System.Xml.Linq;
using CVRManager.Models;
namespace CVRManager.Services;
public static class AccountService
{
const string ProfilePrefix = "cvrm-";
public record Found(string Name, string Username, string UserId, string AccessKey);
public static string ProfileName(GameAccount a) => ProfilePrefix + a.Id;
static string ProfilePath(string gameDir, GameAccount a) => Path.Combine(gameDir, "ChilloutVR_Data", $"autologin-{ProfileName(a)}.profile");
public static string WriteProfile(string gameDir, GameAccount a)
{
var key = TokenVault.Unprotect(a.AccessKey);
if (key.Length == 0) throw new InvalidOperationException($"The access key for {a.Name} could not be read; add the account again.");
var doc = new XElement("LoginProfile",
new XElement("UserId", a.UserId),
new XElement("Username", a.Username),
new XElement("AccessKey", key));
File.WriteAllText(ProfilePath(gameDir, a), doc.ToString());
return ProfileName(a);
}
public static IEnumerable<Found> Scan(IEnumerable<string> gameDirs)
{
foreach (var dir in gameDirs)
{
var data = Path.Combine(dir, "ChilloutVR_Data");
if (!Directory.Exists(data)) continue;
foreach (var file in Directory.EnumerateFiles(data, "autologin*.profile"))
{
if (Path.GetFileName(file).StartsWith("autologin-" + ProfilePrefix, StringComparison.OrdinalIgnoreCase)) continue;
if (Read(file) is { } found) yield return found;
}
}
}
static Found? Read(string path)
{
try
{
var root = XDocument.Load(path).Root;
if (root == null || root.Name != "LoginProfile") return null;
string Value(string name) => root.Element(name)?.Value.Trim() ?? "";
var username = Value("Username");
var key = Value("AccessKey");
if (username.Length == 0 || key.Length == 0) return null;
var stem = Path.GetFileNameWithoutExtension(path)["autologin".Length..].TrimStart('_', '-');
return new Found(stem.Length > 0 ? stem : username, username, Value("UserId"), key);
}
catch (Exception e) when (e is IOException or UnauthorizedAccessException or XmlException) { return null; }
}
}