@@ -201,7 +201,7 @@ public byte[] GetIndexSection3Hash(DirectoryInfo indexPath)
201
201
public async Task < long > GetDataOffset ( string fullPath )
202
202
{
203
203
var dataFile = IOUtil . GetDataFileFromPath ( fullPath ) ;
204
- var index = await GetIndexFile ( dataFile ) ;
204
+ var index = await GetIndexFile ( dataFile , false , true ) ;
205
205
return index . Get8xDataOffset ( fullPath ) ;
206
206
}
207
207
@@ -565,8 +565,8 @@ public Task<long> GetDataOffset(int hashedFolder, int hashedFile, XivDataFile da
565
565
public async Task < List < int > > GetFolderExistsList ( Dictionary < int , int > hashNumDictionary , XivDataFile dataFile )
566
566
{
567
567
var ret = new List < int > ( ) ;
568
- var index = await GetIndexFile ( dataFile ) ;
569
- foreach ( var hashKv in hashNumDictionary )
568
+ var index = await GetIndexFile ( dataFile , false , true ) ;
569
+ foreach ( var hashKv in hashNumDictionary )
570
570
{
571
571
if ( index . FolderExists ( ( uint ) hashKv . Key ) ) {
572
572
ret . Add ( hashKv . Value ) ;
@@ -610,7 +610,7 @@ public async Task<bool> FileExists(string fullPath)
610
610
/// <returns>True if it exists, False otherwise</returns>
611
611
public async Task < bool > FileExists ( string filePath , XivDataFile dataFile )
612
612
{
613
- var index = await GetIndexFile ( dataFile ) ;
613
+ var index = await GetIndexFile ( dataFile , false , true ) ;
614
614
return index . FileExists ( filePath ) ;
615
615
}
616
616
@@ -622,7 +622,7 @@ public async Task<bool> FileExists(string filePath, XivDataFile dataFile)
622
622
/// <returns>True if it exists, False otherwise</returns>
623
623
public async Task < bool > FolderExists ( string folder , XivDataFile dataFile )
624
624
{
625
- var index = await GetIndexFile ( dataFile ) ;
625
+ var index = await GetIndexFile ( dataFile , false , true ) ;
626
626
return index . FolderExists ( folder ) ;
627
627
}
628
628
@@ -634,7 +634,7 @@ public async Task<bool> FolderExists(string folder, XivDataFile dataFile)
634
634
/// <returns>A list of all of the offsets in the given folder</returns>
635
635
public async Task < List < long > > GetAllFileOffsetsInFolder ( int hashedFolder , XivDataFile dataFile )
636
636
{
637
- var index = await GetIndexFile ( dataFile ) ;
637
+ var index = await GetIndexFile ( dataFile , false , true ) ;
638
638
var entries = index . GetEntriesInFolder ( ( uint ) hashedFolder ) ;
639
639
640
640
var hashes = entries . Select ( x => ( ( long ) x . RawOffset ) * 8L ) ;
@@ -649,7 +649,7 @@ public async Task<List<long>> GetAllFileOffsetsInFolder(int hashedFolder, XivDat
649
649
/// <returns>A list containing the hashed values of the files in the given folder</returns>
650
650
public async Task < List < int > > GetAllHashedFilesInFolder ( int hashedFolder , XivDataFile dataFile )
651
651
{
652
- var index = await GetIndexFile ( dataFile ) ;
652
+ var index = await GetIndexFile ( dataFile , false , true ) ;
653
653
var entries = index . GetEntriesInFolder ( ( uint ) hashedFolder ) ;
654
654
655
655
var hashes = entries . Select ( x => ( int ) x . FileNameHash ) ;
@@ -661,7 +661,7 @@ public async Task<List<int>> GetAllHashedFilesInFolder(int hashedFolder, XivData
661
661
/// </summary>
662
662
public async Task < Dictionary < uint , HashSet < uint > > > GetAllHashes ( XivDataFile dataFile )
663
663
{
664
- var index = await GetIndexFile ( dataFile ) ;
664
+ var index = await GetIndexFile ( dataFile , false , true ) ;
665
665
return index . GetAllHashes ( ) ;
666
666
}
667
667
@@ -696,12 +696,14 @@ public async Task<bool> DeleteFileDescriptor(string fullPath, XivDataFile dataFi
696
696
private static Dictionary < XivDataFile , long > _IndexLastModifiedTime = new Dictionary < XivDataFile , long > ( ) ;
697
697
private static Dictionary < XivDataFile , IndexFile > _CachedIndexFiles = new Dictionary < XivDataFile , IndexFile > ( ) ;
698
698
699
+ private static Dictionary < XivDataFile , long > _ReadOnlyIndexLastModifiedTime = new Dictionary < XivDataFile , long > ( ) ;
700
+ private static Dictionary < XivDataFile , IndexFile > _CachedReadOnlyIndexFiles = new Dictionary < XivDataFile , IndexFile > ( ) ;
699
701
/// <summary>
700
702
/// Creates an Index File object from the game index files.
701
703
/// </summary>
702
704
/// <param name="dataFile"></param>
703
705
/// <returns></returns>
704
- public async Task < IndexFile > GetIndexFile ( XivDataFile dataFile , bool alreadySemaphoreLocked = false )
706
+ public async Task < IndexFile > GetIndexFile ( XivDataFile dataFile , bool alreadySemaphoreLocked = false , bool allowReadOnly = false )
705
707
{
706
708
var index1Path = Path . Combine ( _gameDirectory . FullName , $ "{ dataFile . GetDataFileName ( ) } { IndexExtension } ") ;
707
709
var index2Path = Path . Combine ( _gameDirectory . FullName , $ "{ dataFile . GetDataFileName ( ) } { Index2Extension } ") ;
@@ -725,19 +727,45 @@ public async Task<IndexFile> GetIndexFile(XivDataFile dataFile, bool alreadySema
725
727
// If we don't have the file cached or the write time doesn't match exactly.
726
728
if ( ! _IndexLastModifiedTime . ContainsKey ( dataFile ) || lastTime != _IndexLastModifiedTime [ dataFile ] || lastTime == creationTime || lastTime == 0 )
727
729
{
728
- using ( var index1Stream = new BinaryReader ( File . Open ( index1Path , FileMode . Open ) ) )
730
+ using ( var index1Stream = new BinaryReader ( File . OpenRead ( index1Path ) ) )
729
731
{
730
- using ( var index2Stream = new BinaryReader ( File . Open ( index2Path , FileMode . Open ) ) )
732
+ using ( var index2Stream = new BinaryReader ( File . OpenRead ( index2Path ) ) )
731
733
{
732
734
index = new IndexFile ( dataFile , index1Stream , index2Stream ) ;
733
735
}
734
736
}
735
737
736
738
_IndexLastModifiedTime [ dataFile ] = lastTime ;
737
739
_CachedIndexFiles [ dataFile ] = index ;
740
+ _ReadOnlyIndexLastModifiedTime [ dataFile ] = lastTime ;
741
+ _CachedReadOnlyIndexFiles [ dataFile ] = index ;
738
742
return index ;
739
743
}
740
744
}
745
+ catch ( Exception ex )
746
+ {
747
+ // The index2 file may be read/write locked.
748
+ if ( ! allowReadOnly ) throw ;
749
+ var lastTime = File . GetLastWriteTimeUtc ( index1Path ) . Ticks ;
750
+ var creationTime = File . GetCreationTimeUtc ( index1Path ) . Ticks ;
751
+
752
+ // If we don't have the file cached or the write time doesn't match exactly.
753
+ if ( ! _IndexLastModifiedTime . ContainsKey ( dataFile ) || lastTime != _ReadOnlyIndexLastModifiedTime [ dataFile ] || lastTime == creationTime || lastTime == 0 )
754
+ {
755
+ using ( var index1Stream = new BinaryReader ( File . OpenRead ( index1Path ) ) )
756
+ {
757
+ index = new IndexFile ( dataFile , index1Stream , null ) ;
758
+ }
759
+
760
+ _ReadOnlyIndexLastModifiedTime [ dataFile ] = lastTime ;
761
+ _CachedReadOnlyIndexFiles [ dataFile ] = index ;
762
+ return index ;
763
+ } else
764
+ {
765
+ return _CachedReadOnlyIndexFiles [ dataFile ] ;
766
+ }
767
+
768
+ }
741
769
finally
742
770
{
743
771
if ( ! alreadySemaphoreLocked )
0 commit comments