Skip to content

Commit 9aa5206

Browse files
committed
- Bugfixes for Delete and Add file descriptor functions - Check for file access for both indices *BEFORE* writing to either index.
- Change StartOver function to begin with attempt to restore indexes, rather than start with attempt to disable mods. (Massive perf improvement on start overs)
1 parent 30a45fc commit 9aa5206

File tree

2 files changed

+77
-31
lines changed

2 files changed

+77
-31
lines changed

xivModdingFramework/Helpers/ProblemChecker.cs

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,6 @@ public Task PerformStartOver(DirectoryInfo backupsDirectory, IProgress<string> p
162162
{
163163
return Task.Run(async () =>
164164
{
165-
progress?.Report("Deleting mods...");
166-
167165
var modding = new Modding(_gameDirectory);
168166
var backupsRestored = false;
169167

@@ -173,45 +171,30 @@ public Task PerformStartOver(DirectoryInfo backupsDirectory, IProgress<string> p
173171

174172
try
175173
{
176-
// Try to restore the index entries to their original values by deleting any files added by TexTools
177-
// and setting mods to disabled
178-
await modding.DeleteAllFilesAddedByTexTools();
179-
await modding.ToggleAllMods(false);
180-
progress?.Report("Restoring index file backups...");
181-
}
182-
catch(Exception ex)
183-
{
184-
// If an exception occurred due to a corrupted modlist which couldn't be deserealized restore the backup index
185-
// files by force
174+
// Try restoring the indexes FIRST.
186175
backupsRestored = await RestoreBackups(backupsDirectory);
176+
progress?.Report("Restoring index file backups...");
187177

188178
if (!backupsRestored)
189179
{
190180
throw new Exception("Start Over Failed: Index backups missing/outdated.");
191181
}
192182
}
193-
finally
183+
catch(Exception ex)
194184
{
195-
// If no exception occured, restore the backups anyway just to be safe but don't throw an exception if it fails
196-
// due to outdated or missing backups since setting back the original index values should be enough hopefully
197-
if (!backupsRestored)
185+
try
198186
{
199-
backupsRestored = await RestoreBackups(backupsDirectory);
200-
201-
// If backups were not restored that means they were missing/outdated so try to make new backups now
202-
if (!backupsRestored)
203-
{
204-
try
205-
{
206-
await BackupIndexFiles(backupsDirectory);
207-
}
208-
catch (Exception ex)
209-
{
210-
throw new Exception("Start Over Failed: Failed to update outdated backups.\n\n" + ex.Message);
211-
}
212-
}
187+
// If the index restore failed, try just disabling.
188+
await modding.DeleteAllFilesAddedByTexTools();
189+
await modding.ToggleAllMods(false);
190+
progress?.Report("Index restore failed, attempting to delete all mods instead...");
191+
} catch
192+
{
193+
throw new Exception("Start Over Failed: Index Backups Invalid and Unable to Disable all mods.");
213194
}
214-
195+
}
196+
finally
197+
{
215198
progress?.Report("Deleting modded dat files...");
216199

217200
var dat = new Dat(_gameDirectory);

xivModdingFramework/SqPack/FileTypes/Index.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -776,6 +776,38 @@ public async Task<bool> DeleteFileDescriptor(string fullPath, XivDataFile dataFi
776776
var oldChildren = await XivCache.GetChildFiles(fullPath);
777777

778778
await _semaphoreSlim.WaitAsync();
779+
780+
// Test both index files for write access.
781+
try
782+
{
783+
var indexPath = Path.Combine(_gameDirectory.FullName, $"{dataFile.GetDataFileName()}{IndexExtension}");
784+
using (var fs = new FileStream(indexPath, FileMode.Open))
785+
{
786+
var canRead = fs.CanRead;
787+
var canWrite = fs.CanWrite;
788+
if (!canRead || !canWrite)
789+
{
790+
throw new Exception();
791+
}
792+
}
793+
var index2Path = Path.Combine(_gameDirectory.FullName, $"{dataFile.GetDataFileName()}{Index2Extension}");
794+
using (var fs = new FileStream(index2Path, FileMode.Open))
795+
{
796+
var canRead = fs.CanRead;
797+
var canWrite = fs.CanWrite;
798+
if (!canRead || !canWrite)
799+
{
800+
throw new Exception();
801+
}
802+
}
803+
}
804+
catch
805+
{
806+
_semaphoreSlim.Release();
807+
throw new Exception("Unable to update Index files. File(s) are currently in use.");
808+
}
809+
810+
779811
fullPath = fullPath.Replace("\\", "/");
780812
var pathHash = HashGenerator.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/", StringComparison.Ordinal)));
781813
var fileHash = HashGenerator.GetHash(Path.GetFileName(fullPath));
@@ -1048,6 +1080,37 @@ public async Task<bool> DeleteFileDescriptor(string fullPath, XivDataFile dataFi
10481080
public async Task<bool> AddFileDescriptor(string fullPath, int dataOffset, XivDataFile dataFile)
10491081
{
10501082
await _semaphoreSlim.WaitAsync();
1083+
1084+
// Test both index files for write access.
1085+
try
1086+
{
1087+
var indexPath = Path.Combine(_gameDirectory.FullName, $"{dataFile.GetDataFileName()}{IndexExtension}");
1088+
using (var fs = new FileStream(indexPath, FileMode.Open))
1089+
{
1090+
var canRead = fs.CanRead;
1091+
var canWrite = fs.CanWrite;
1092+
if (!canRead || !canWrite)
1093+
{
1094+
throw new Exception();
1095+
}
1096+
}
1097+
var index2Path = Path.Combine(_gameDirectory.FullName, $"{dataFile.GetDataFileName()}{Index2Extension}");
1098+
using (var fs = new FileStream(index2Path, FileMode.Open))
1099+
{
1100+
var canRead = fs.CanRead;
1101+
var canWrite = fs.CanWrite;
1102+
if (!canRead || !canWrite)
1103+
{
1104+
throw new Exception();
1105+
}
1106+
}
1107+
}
1108+
catch
1109+
{
1110+
_semaphoreSlim.Release();
1111+
throw new Exception("Unable to update Index files. File(s) are currently in use.");
1112+
}
1113+
10511114
fullPath = fullPath.Replace("\\", "/");
10521115
var pathHash = HashGenerator.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/", StringComparison.Ordinal)));
10531116
var fileHash = HashGenerator.GetHash(Path.GetFileName(fullPath));

0 commit comments

Comments
 (0)