Skip to content

Commit fd6e2f8

Browse files
committed
Added emergency backup restore functionality for completely broken index files.
1 parent af858e6 commit fd6e2f8

File tree

2 files changed

+88
-30
lines changed

2 files changed

+88
-30
lines changed

xivModdingFramework/Helpers/ProblemChecker.cs

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,12 @@ public Task RepairIndexDatCounts(XivDataFile dataFile)
138138
});
139139
}
140140

141+
/// <summary>
142+
/// This function returns TRUE if the backups should be used, and FALSE if they should not.
143+
/// </summary>
144+
/// <param name="dataFile"></param>
145+
/// <param name="backupsDirectory"></param>
146+
/// <returns></returns>
141147
public Task<bool> CheckForOutdatedBackups(XivDataFile dataFile, DirectoryInfo backupsDirectory)
142148
{
143149
return Task.Run(() =>
@@ -149,10 +155,32 @@ public Task<bool> CheckForOutdatedBackups(XivDataFile dataFile, DirectoryInfo ba
149155

150156
// Since the material addition directly adds to section 1 we can no longer check for outdated using that section header
151157
// so instead compare the hashes of sections 2 and 3
152-
var backupHashSection2 = _index.GetIndexSection2Hash(backupDataFile);
153-
var currentHashSection2 = _index.GetIndexSection2Hash(currentDataFile);
154-
var backupHashSection3 = _index.GetIndexSection3Hash(backupDataFile);
155-
var currentHashSection3 = _index.GetIndexSection3Hash(currentDataFile);
158+
byte[] currentHashSection2;
159+
byte[] currentHashSection3;
160+
byte[] backupHashSection2;
161+
byte[] backupHashSection3;
162+
try
163+
{
164+
currentHashSection2 = _index.GetIndexSection2Hash(currentDataFile);
165+
currentHashSection3 = _index.GetIndexSection3Hash(currentDataFile);
166+
}
167+
catch
168+
{
169+
// Base files are fucked, use *any* backups.
170+
return true;
171+
}
172+
173+
try
174+
{
175+
backupHashSection2 = _index.GetIndexSection2Hash(backupDataFile);
176+
backupHashSection3 = _index.GetIndexSection3Hash(backupDataFile);
177+
}
178+
catch
179+
{
180+
// Backups are fucked, can't use those.
181+
return false;
182+
}
183+
156184

157185
return backupHashSection2.SequenceEqual(currentHashSection2) && backupHashSection3.SequenceEqual(currentHashSection3);
158186
});
@@ -288,11 +316,18 @@ public Task<bool> RestoreBackups(DirectoryInfo backupsDirectory)
288316

289317
if (!File.Exists(backupFile.FullName)) continue;
290318

291-
var outdatedCheck = await CheckForOutdatedBackups(xivDataFile, backupsDirectory);
292-
293-
if (!outdatedCheck)
319+
try
294320
{
295-
outdated = true;
321+
var outdatedCheck = await CheckForOutdatedBackups(xivDataFile, backupsDirectory);
322+
323+
if (!outdatedCheck)
324+
{
325+
outdated = true;
326+
}
327+
}
328+
catch {
329+
// If the outdated check errored out, we likely have completely broken internal dat files.
330+
// ( Either deleted or 0 byte files ), so replacing them with *anything* is an improvement.
296331
}
297332
}
298333

xivModdingFramework/SqPack/FileTypes/Index.cs

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -83,21 +83,26 @@ public void UpdateIndexDatCount(XivDataFile dataFile, int datNum)
8383
Path.Combine(_gameDirectory.FullName, $"{dataFile.GetDataFileName()}{Index2Extension}")
8484
};
8585

86-
for (var i = 0; i < indexPaths.Length; i++)
86+
_semaphoreSlim.Wait();
87+
try
8788
{
88-
_semaphoreSlim.Wait();
89-
using (var br = new BinaryReader(File.OpenRead(indexPaths[i])))
89+
for (var i = 0; i < indexPaths.Length; i++)
9090
{
91-
br.BaseStream.Seek(1104, SeekOrigin.Begin);
92-
if (i == 0)
93-
{
94-
index1 = br.ReadByte();
95-
}
96-
else
91+
using (var br = new BinaryReader(File.OpenRead(indexPaths[i])))
9792
{
98-
index2 = br.ReadByte();
93+
br.BaseStream.Seek(1104, SeekOrigin.Begin);
94+
if (i == 0)
95+
{
96+
index1 = br.ReadByte();
97+
}
98+
else
99+
{
100+
index2 = br.ReadByte();
101+
}
99102
}
100103
}
104+
} finally
105+
{
101106
_semaphoreSlim.Release();
102107
}
103108

@@ -114,12 +119,18 @@ public byte[] GetIndexSection1Hash(DirectoryInfo indexPath)
114119
byte[] sha1Bytes;
115120

116121
_semaphoreSlim.Wait();
117-
using (var br = new BinaryReader(File.OpenRead(indexPath.FullName)))
122+
try
118123
{
119-
br.BaseStream.Seek(1040, SeekOrigin.Begin);
120-
sha1Bytes = br.ReadBytes(20);
124+
using (var br = new BinaryReader(File.OpenRead(indexPath.FullName)))
125+
{
126+
br.BaseStream.Seek(1040, SeekOrigin.Begin);
127+
sha1Bytes = br.ReadBytes(20);
128+
}
129+
}
130+
finally
131+
{
132+
_semaphoreSlim.Release();
121133
}
122-
_semaphoreSlim.Release();
123134

124135
return sha1Bytes;
125136
}
@@ -134,12 +145,18 @@ public byte[] GetIndexSection2Hash(DirectoryInfo indexPath)
134145
byte[] sha1Bytes;
135146

136147
_semaphoreSlim.Wait();
137-
using (var br = new BinaryReader(File.OpenRead(indexPath.FullName)))
148+
try
138149
{
139-
br.BaseStream.Seek(1116, SeekOrigin.Begin);
140-
sha1Bytes = br.ReadBytes(20);
150+
using (var br = new BinaryReader(File.OpenRead(indexPath.FullName)))
151+
{
152+
br.BaseStream.Seek(1116, SeekOrigin.Begin);
153+
sha1Bytes = br.ReadBytes(20);
154+
}
155+
}
156+
finally
157+
{
158+
_semaphoreSlim.Release();
141159
}
142-
_semaphoreSlim.Release();
143160

144161
return sha1Bytes;
145162
}
@@ -154,12 +171,18 @@ public byte[] GetIndexSection3Hash(DirectoryInfo indexPath)
154171
byte[] sha1Bytes;
155172

156173
_semaphoreSlim.Wait();
157-
using (var br = new BinaryReader(File.OpenRead(indexPath.FullName)))
174+
try
158175
{
159-
br.BaseStream.Seek(1188, SeekOrigin.Begin);
160-
sha1Bytes = br.ReadBytes(20);
176+
using (var br = new BinaryReader(File.OpenRead(indexPath.FullName)))
177+
{
178+
br.BaseStream.Seek(1188, SeekOrigin.Begin);
179+
sha1Bytes = br.ReadBytes(20);
180+
}
181+
}
182+
finally
183+
{
184+
_semaphoreSlim.Release();
161185
}
162-
_semaphoreSlim.Release();
163186

164187

165188
return sha1Bytes;

0 commit comments

Comments
 (0)