Fix saving issue.

This commit is contained in:
Ottermandias 2023-01-09 16:14:32 +01:00
parent e65b7454fe
commit 4ecad9a5d2
3 changed files with 156 additions and 134 deletions

View file

@ -342,7 +342,7 @@ public class CharacterSave
WriteEquipment = oldEquip;
}
public void Load(string base64)
public void Load(string base64, out bool oldVersion)
{
var bytes = Convert.FromBase64String(base64);
switch (bytes[0])
@ -350,12 +350,14 @@ public class CharacterSave
case 1:
CheckSize(bytes.Length, TotalSizeVersion1);
CheckRange(2, bytes[1], 0, 1);
Alpha = 1.0f;
bytes[0] = CurrentVersion;
Alpha = 1.0f;
bytes[0] = CurrentVersion;
oldVersion = true;
break;
case 2:
CheckSize(bytes.Length, TotalSizeVersion2);
CheckRange(2, bytes[1], 0, 0x3F);
oldVersion = false;
break;
default: throw new Exception($"Can not parse Base64 string into CharacterSave:\n\tInvalid Version {bytes[0]}.");
}
@ -364,13 +366,16 @@ public class CharacterSave
bytes.CopyTo(_bytes, 0);
}
public static CharacterSave FromString(string base64)
public static CharacterSave FromString(string base64, out bool oldVersion)
{
var ret = new CharacterSave();
ret.Load(base64);
ret.Load(base64, out oldVersion);
return ret;
}
public static CharacterSave FromString(string base64)
=> FromString(base64, out _);
public unsafe ref CharacterCustomization Customizations
{
get

View file

@ -5,155 +5,172 @@ using System.Linq;
using Dalamud.Logging;
using Glamourer.FileSystem;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
namespace Glamourer.Designs
namespace Glamourer.Designs;
public class DesignManager
{
public class DesignManager
public const string FileName = "Designs.json";
private readonly FileInfo _saveFile;
public SortedList<string, CharacterSave> Designs = null!;
public FileSystem.FileSystem FileSystem { get; } = new();
public DesignManager()
{
public const string FileName = "Designs.json";
private readonly FileInfo _saveFile;
var saveFolder = new DirectoryInfo(Dalamud.PluginInterface.GetPluginConfigDirectory());
if (!saveFolder.Exists)
Directory.CreateDirectory(saveFolder.FullName);
public SortedList<string, CharacterSave> Designs = null!;
public FileSystem.FileSystem FileSystem { get; } = new();
_saveFile = new FileInfo(Path.Combine(saveFolder.FullName, FileName));
public DesignManager()
{
var saveFolder = new DirectoryInfo(Dalamud.PluginInterface.GetPluginConfigDirectory());
if (!saveFolder.Exists)
Directory.CreateDirectory(saveFolder.FullName);
LoadFromFile();
}
_saveFile = new FileInfo(Path.Combine(saveFolder.FullName, FileName));
LoadFromFile();
}
private void BuildStructure()
{
FileSystem.Clear();
var anyChanges = false;
foreach (var (path, save) in Designs.ToArray())
{
try
{
var (folder, name) = FileSystem.CreateAllFolders(path);
var design = new Design(folder, name) { Data = save };
folder.FindOrAddChild(design);
var fixedPath = design.FullName();
if (string.Equals(fixedPath, path, StringComparison.InvariantCultureIgnoreCase))
continue;
Designs.Remove(path);
Designs[fixedPath] = save;
anyChanges = true;
PluginLog.Debug($"Problem loading saved designs, {path} was renamed to {fixedPath}.");
}
catch (Exception e)
{
PluginLog.Error($"Problem loading saved designs, {path} was removed because:\n{e}");
Designs.Remove(path);
}
}
if (anyChanges)
SaveToFile();
}
private bool UpdateRoot(string oldPath, Design child)
{
var newPath = child.FullName();
if (string.Equals(newPath, oldPath, StringComparison.InvariantCultureIgnoreCase))
return false;
Designs.Remove(oldPath);
Designs[child.FullName()] = child.Data;
return true;
}
private void UpdateChild(string oldRootPath, string newRootPath, Design child)
{
var newPath = child.FullName();
var oldPath = $"{oldRootPath}{newPath.Remove(0, newRootPath.Length)}";
Designs.Remove(oldPath);
Designs[newPath] = child.Data;
}
public void DeleteAllChildren(IFileSystemBase root, bool deleteEmpty)
{
if (root is Folder f)
foreach (var child in f.AllLeaves(SortMode.Lexicographical))
Designs.Remove(child.FullName());
var fullPath = root.FullName();
root.Parent.RemoveChild(root, deleteEmpty);
Designs.Remove(fullPath);
SaveToFile();
}
public void UpdateAllChildren(string oldPath, IFileSystemBase root)
{
var changes = false;
switch (root)
{
case Design d:
changes |= UpdateRoot(oldPath, d);
break;
case Folder f:
{
var newRootPath = root.FullName();
if (!string.Equals(oldPath, newRootPath, StringComparison.InvariantCultureIgnoreCase))
{
changes = true;
foreach (var descendant in f.AllLeaves(SortMode.Lexicographical).Where(l => l is Design).Cast<Design>())
UpdateChild(oldPath, newRootPath, descendant);
}
break;
}
}
if (changes)
SaveToFile();
}
public void SaveToFile()
private void BuildStructure()
{
FileSystem.Clear();
var anyChanges = false;
foreach (var (path, save) in Designs.ToArray())
{
try
{
var data = JsonConvert.SerializeObject(Designs, Formatting.Indented);
File.WriteAllText(_saveFile.FullName, data);
var (folder, name) = FileSystem.CreateAllFolders(path);
var design = new Design(folder, name) { Data = save };
folder.FindOrAddChild(design);
var fixedPath = design.FullName();
if (string.Equals(fixedPath, path, StringComparison.InvariantCultureIgnoreCase))
continue;
Designs.Remove(path);
Designs[fixedPath] = save;
anyChanges = true;
PluginLog.Debug($"Problem loading saved designs, {path} was renamed to {fixedPath}.");
}
catch (Exception e)
{
PluginLog.Error($"Could not write to save file {_saveFile.FullName}:\n{e}");
PluginLog.Error($"Problem loading saved designs, {path} was removed because:\n{e}");
Designs.Remove(path);
}
}
public void LoadFromFile()
if (anyChanges)
SaveToFile();
}
private bool UpdateRoot(string oldPath, Design child)
{
var newPath = child.FullName();
if (string.Equals(newPath, oldPath, StringComparison.InvariantCultureIgnoreCase))
return false;
Designs.Remove(oldPath);
Designs[child.FullName()] = child.Data;
return true;
}
private void UpdateChild(string oldRootPath, string newRootPath, Design child)
{
var newPath = child.FullName();
var oldPath = $"{oldRootPath}{newPath.Remove(0, newRootPath.Length)}";
Designs.Remove(oldPath);
Designs[newPath] = child.Data;
}
public void DeleteAllChildren(IFileSystemBase root, bool deleteEmpty)
{
if (root is Folder f)
foreach (var child in f.AllLeaves(SortMode.Lexicographical))
Designs.Remove(child.FullName());
var fullPath = root.FullName();
root.Parent.RemoveChild(root, deleteEmpty);
Designs.Remove(fullPath);
SaveToFile();
}
public void UpdateAllChildren(string oldPath, IFileSystemBase root)
{
var changes = false;
switch (root)
{
_saveFile.Refresh();
SortedList<string, CharacterSave>? designs = null;
if (_saveFile.Exists)
try
case Design d:
changes |= UpdateRoot(oldPath, d);
break;
case Folder f:
{
var newRootPath = root.FullName();
if (!string.Equals(oldPath, newRootPath, StringComparison.InvariantCultureIgnoreCase))
{
var data = File.ReadAllText(_saveFile.FullName);
designs = JsonConvert.DeserializeObject<SortedList<string, CharacterSave>>(data);
}
catch (Exception e)
{
PluginLog.Error($"Could not load save file {_saveFile.FullName}:\n{e}");
changes = true;
foreach (var descendant in f.AllLeaves(SortMode.Lexicographical).Where(l => l is Design).Cast<Design>())
UpdateChild(oldPath, newRootPath, descendant);
}
if (designs == null)
{
Designs = new SortedList<string, CharacterSave>();
SaveToFile();
}
else
{
Designs = designs;
break;
}
}
BuildStructure();
if (changes)
SaveToFile();
}
public void SaveToFile()
{
try
{
var data = JsonConvert.SerializeObject(Designs, Formatting.Indented);
File.WriteAllText(_saveFile.FullName, data);
}
catch (Exception e)
{
PluginLog.Error($"Could not write to save file {_saveFile.FullName}:\n{e}");
}
}
public void LoadFromFile()
{
_saveFile.Refresh();
Designs = new SortedList<string, CharacterSave>();
var changes = false;
if (_saveFile.Exists)
try
{
var data = File.ReadAllText(_saveFile.FullName);
var json = JsonConvert.DeserializeObject<Dictionary<string, string>>(data);
if (json == null)
{
PluginLog.Error($"Save file {_saveFile.FullName} corrupted.");
json = new Dictionary<string, string>();
}
foreach (var (name, saveString) in json)
{
try
{
var save = CharacterSave.FromString(saveString, out var oldVersion);
changes |= oldVersion;
changes |= !Designs.TryAdd(name, save);
}
catch (Exception e)
{
PluginLog.Error($"Character Save for {name} is invalid:\n{e}");
changes = true;
}
}
}
catch (Exception e)
{
PluginLog.Error($"Could not load save file {_saveFile.FullName}:\n{e}");
changes = true;
}
else
changes = true;
if (changes)
SaveToFile();
BuildStructure();
}
}

View file

@ -55,7 +55,7 @@ namespace Glamourer.Gui
try
{
_selection!.Data = CharacterSave.FromString(text);
_selection!.Data.Load(text, out _);
_designs.SaveToFile();
}
catch (Exception e)