mirror of
https://github.com/Ottermandias/Glamourer.git
synced 2025-12-15 13:14:17 +01:00
Fix saving issue.
This commit is contained in:
parent
e65b7454fe
commit
4ecad9a5d2
3 changed files with 156 additions and 134 deletions
|
|
@ -342,7 +342,7 @@ public class CharacterSave
|
||||||
WriteEquipment = oldEquip;
|
WriteEquipment = oldEquip;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Load(string base64)
|
public void Load(string base64, out bool oldVersion)
|
||||||
{
|
{
|
||||||
var bytes = Convert.FromBase64String(base64);
|
var bytes = Convert.FromBase64String(base64);
|
||||||
switch (bytes[0])
|
switch (bytes[0])
|
||||||
|
|
@ -350,12 +350,14 @@ public class CharacterSave
|
||||||
case 1:
|
case 1:
|
||||||
CheckSize(bytes.Length, TotalSizeVersion1);
|
CheckSize(bytes.Length, TotalSizeVersion1);
|
||||||
CheckRange(2, bytes[1], 0, 1);
|
CheckRange(2, bytes[1], 0, 1);
|
||||||
Alpha = 1.0f;
|
Alpha = 1.0f;
|
||||||
bytes[0] = CurrentVersion;
|
bytes[0] = CurrentVersion;
|
||||||
|
oldVersion = true;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
CheckSize(bytes.Length, TotalSizeVersion2);
|
CheckSize(bytes.Length, TotalSizeVersion2);
|
||||||
CheckRange(2, bytes[1], 0, 0x3F);
|
CheckRange(2, bytes[1], 0, 0x3F);
|
||||||
|
oldVersion = false;
|
||||||
break;
|
break;
|
||||||
default: throw new Exception($"Can not parse Base64 string into CharacterSave:\n\tInvalid Version {bytes[0]}.");
|
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);
|
bytes.CopyTo(_bytes, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CharacterSave FromString(string base64)
|
public static CharacterSave FromString(string base64, out bool oldVersion)
|
||||||
{
|
{
|
||||||
var ret = new CharacterSave();
|
var ret = new CharacterSave();
|
||||||
ret.Load(base64);
|
ret.Load(base64, out oldVersion);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static CharacterSave FromString(string base64)
|
||||||
|
=> FromString(base64, out _);
|
||||||
|
|
||||||
public unsafe ref CharacterCustomization Customizations
|
public unsafe ref CharacterCustomization Customizations
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
|
|
|
||||||
|
|
@ -5,155 +5,172 @@ using System.Linq;
|
||||||
using Dalamud.Logging;
|
using Dalamud.Logging;
|
||||||
using Glamourer.FileSystem;
|
using Glamourer.FileSystem;
|
||||||
using Newtonsoft.Json;
|
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";
|
var saveFolder = new DirectoryInfo(Dalamud.PluginInterface.GetPluginConfigDirectory());
|
||||||
private readonly FileInfo _saveFile;
|
if (!saveFolder.Exists)
|
||||||
|
Directory.CreateDirectory(saveFolder.FullName);
|
||||||
|
|
||||||
public SortedList<string, CharacterSave> Designs = null!;
|
_saveFile = new FileInfo(Path.Combine(saveFolder.FullName, FileName));
|
||||||
public FileSystem.FileSystem FileSystem { get; } = new();
|
|
||||||
|
|
||||||
public DesignManager()
|
LoadFromFile();
|
||||||
{
|
}
|
||||||
var saveFolder = new DirectoryInfo(Dalamud.PluginInterface.GetPluginConfigDirectory());
|
|
||||||
if (!saveFolder.Exists)
|
|
||||||
Directory.CreateDirectory(saveFolder.FullName);
|
|
||||||
|
|
||||||
_saveFile = new FileInfo(Path.Combine(saveFolder.FullName, FileName));
|
private void BuildStructure()
|
||||||
|
{
|
||||||
LoadFromFile();
|
FileSystem.Clear();
|
||||||
}
|
var anyChanges = false;
|
||||||
|
foreach (var (path, save) in Designs.ToArray())
|
||||||
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()
|
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var data = JsonConvert.SerializeObject(Designs, Formatting.Indented);
|
var (folder, name) = FileSystem.CreateAllFolders(path);
|
||||||
File.WriteAllText(_saveFile.FullName, data);
|
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)
|
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();
|
case Design d:
|
||||||
SortedList<string, CharacterSave>? designs = null;
|
changes |= UpdateRoot(oldPath, d);
|
||||||
if (_saveFile.Exists)
|
break;
|
||||||
try
|
case Folder f:
|
||||||
|
{
|
||||||
|
var newRootPath = root.FullName();
|
||||||
|
if (!string.Equals(oldPath, newRootPath, StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
var data = File.ReadAllText(_saveFile.FullName);
|
changes = true;
|
||||||
designs = JsonConvert.DeserializeObject<SortedList<string, CharacterSave>>(data);
|
foreach (var descendant in f.AllLeaves(SortMode.Lexicographical).Where(l => l is Design).Cast<Design>())
|
||||||
}
|
UpdateChild(oldPath, newRootPath, descendant);
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
PluginLog.Error($"Could not load save file {_saveFile.FullName}:\n{e}");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (designs == null)
|
break;
|
||||||
{
|
|
||||||
Designs = new SortedList<string, CharacterSave>();
|
|
||||||
SaveToFile();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Designs = designs;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ namespace Glamourer.Gui
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_selection!.Data = CharacterSave.FromString(text);
|
_selection!.Data.Load(text, out _);
|
||||||
_designs.SaveToFile();
|
_designs.SaveToFile();
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue