source: OniSplit/InstanceFileManager.cs@ 1194

Last change on this file since 1194 was 1114, checked in by iritscen, 5 years ago

Adding OniSplit source code (v0.9.99.0). Many thanks to Neo for all his work over the years.

File size: 6.2 KB
Line 
1using System;
2using System.Collections.Generic;
3using System.IO;
4using Oni.Collections;
5
6namespace Oni
7{
8 internal sealed class InstanceFileManager
9 {
10 private readonly List<string> searchPaths = new List<string>();
11 private readonly Dictionary<string, InstanceFile> loadedFiles = new Dictionary<string, InstanceFile>(StringComparer.OrdinalIgnoreCase);
12 private Dictionary<string, string> files;
13
14 public InstanceFile OpenFile(string filePath)
15 {
16 InstanceFile file;
17
18 if (!loadedFiles.TryGetValue(filePath, out file))
19 {
20 try
21 {
22 file = InstanceFile.Read(this, filePath);
23 }
24 catch (Exception ex)
25 {
26 Console.Error.WriteLine("Error opening file {0}: {1}", filePath, ex.Message);
27 throw;
28 }
29
30 loadedFiles.Add(filePath, file);
31 }
32
33 return file;
34 }
35
36 public List<InstanceFile> OpenDirectories(string[] dirPaths)
37 {
38 var files = new List<InstanceFile>();
39 var seenFileNames = new Set<string>(StringComparer.Ordinal);
40
41 Array.Reverse(dirPaths);
42
43 foreach (string dirPath in dirPaths)
44 {
45 var filePaths = FindFiles(dirPath);
46
47 foreach (string filePath in filePaths)
48 {
49 if (!seenFileNames.Contains(Path.GetFileName(filePath)))
50 files.Add(OpenFile(filePath));
51 }
52
53 foreach (string filePath in filePaths)
54 seenFileNames.Add(Path.GetFileName(filePath));
55 }
56
57 return files;
58 }
59
60 public List<InstanceFile> OpenDirectory(string dirPath)
61 {
62 var files = new List<InstanceFile>();
63
64 foreach (string filePath in FindFiles(dirPath))
65 files.Add(OpenFile(filePath));
66
67 return files;
68 }
69
70 public void AddSearchPath(string path)
71 {
72 if (Directory.Exists(path))
73 searchPaths.Add(path);
74 }
75
76 public InstanceFile FindInstance(string instanceName)
77 {
78 if (files == null)
79 {
80 files = new Dictionary<string, string>(StringComparer.Ordinal);
81
82 foreach (string searchPath in searchPaths)
83 {
84 foreach (string filePath in FindFiles(searchPath))
85 {
86 string name = Importer.DecodeFileName(filePath);
87
88 if (!files.ContainsKey(name))
89 files[name] = filePath;
90 }
91 }
92 }
93
94 string instanceFilePath;
95
96 if (!files.TryGetValue(instanceName, out instanceFilePath))
97 return null;
98
99 var file = OpenFile(instanceFilePath);
100
101 if (file == null)
102 return null;
103
104 var descriptor = file.Descriptors[0];
105
106 if (file.Header.Version != InstanceFileHeader.Version32)
107 return null;
108
109 if (descriptor == null || !descriptor.HasName || descriptor.FullName != instanceName)
110 return null;
111
112 return file;
113 }
114
115 public InstanceFile FindInstance(string instanceName, InstanceFile baseFile)
116 {
117 if (files == null)
118 {
119 files = new Dictionary<string, string>(StringComparer.Ordinal);
120
121 foreach (string filePath in FindFiles(Path.GetDirectoryName(baseFile.FilePath)))
122 files[Importer.DecodeFileName(filePath)] = filePath;
123
124 foreach (string searchPath in searchPaths)
125 {
126 foreach (string filePath in FindFiles(searchPath))
127 {
128 string name = Importer.DecodeFileName(filePath);
129
130 if (!files.ContainsKey(name))
131 files[name] = filePath;
132 }
133 }
134 }
135
136 string instanceFilePath;
137
138 if (!files.TryGetValue(instanceName, out instanceFilePath))
139 {
140 if (instanceName.Length > 4)
141 instanceName = instanceName.Substring(4);
142
143 if (!files.TryGetValue(instanceName, out instanceFilePath))
144 {
145 string level0FilePath = Path.Combine(Path.GetDirectoryName(baseFile.FilePath), "level0_Final.dat");
146
147 if (!File.Exists(level0FilePath))
148 return null;
149
150 return OpenFile(level0FilePath);
151 }
152 }
153
154 var file = OpenFile(instanceFilePath);
155
156 if (file == null || file == baseFile)
157 return null;
158
159 var descriptor = file.Descriptors[0];
160
161 if (file.Header.Version == InstanceFileHeader.Version32)
162 return file;
163
164 if (descriptor == null || !descriptor.HasName || descriptor.FullName != instanceName)
165 return null;
166
167 return file;
168 }
169
170 private static List<string> FindFiles(string dirPath)
171 {
172 var files = new List<string>();
173
174 if (Directory.Exists(dirPath))
175 FindFilesRecursive(dirPath, files);
176
177 return files;
178 }
179
180 private static void FindFilesRecursive(string dirPath, List<string> files)
181 {
182 files.AddRange(Directory.GetFiles(dirPath, "*.oni"));
183
184 foreach (string childDirPath in Directory.GetDirectories(dirPath))
185 {
186 string name = Path.GetFileName(childDirPath);
187
188 if (!string.Equals(name, "_noimport", StringComparison.OrdinalIgnoreCase)
189 && !string.Equals(name, "noimport", StringComparison.OrdinalIgnoreCase))
190 {
191 FindFilesRecursive(childDirPath, files);
192 }
193 }
194 }
195 }
196}
Note: See TracBrowser for help on using the repository browser.