/// <summary> /// Adds a file from a file path on disk /// </summary> public LotdFile AddFileOnDisk(string filePath, string rootDir) { if (File.Exists(filePath)) { string relativePath = GetRelativeFilePathOnDisk(filePath, rootDir); LotdFile existingFile = FindFile(relativePath); if (existingFile != null) { if (!existingFile.IsFileOnDisk) { // Already exists as an archive file or a placeholder // Set the file path (this will favor loading from the file rather than the archive) existingFile.FilePathOnDisk = filePath; } return(existingFile); } string[] splitted = SplitPath(relativePath); if (splitted.Length > 0) { LotdDirectory directory = ResolveDirectory(splitted, true, true); if (directory != null) { LotdFile file = new LotdFile(); file.Name = splitted[splitted.Length - 1]; file.Directory = directory; file.FilePathOnDisk = filePath; return(file); } } } return(null); }
private LotdDirectory ResolveDirectory(string[] path, bool isFilePath, bool create) { LotdDirectory directory = this; int pathCount = path.Length + (isFilePath ? -1 : 0); for (int i = 0; i < pathCount; i++) { if (path[i] == "..") { directory = directory.Parent; if (directory == null) { return(null); } } else { LotdDirectory subDir; if (directory.Directories.TryGetValue(path[i], out subDir)) { directory = subDir; } else { subDir = new LotdDirectory(); subDir.Name = path[i]; subDir.Parent = directory; directory = subDir; } } } return(directory); }
public void CreateDirectory(string path) { LotdDirectory directory = ResolveDirectory(path, false, true); if (directory == null) { throw new Exception("Invalid path '" + path + "'"); } }
public LotdFile FindFile(string path) { string[] splitted = SplitPath(path); if (splitted.Length > 0) { LotdDirectory directory = ResolveDirectory(splitted, true, false); LotdFile file; if (directory != null && directory.Files.TryGetValue(splitted[splitted.Length - 1], out file)) { return(file); } } return(null); }
public LotdFile AddFile(string path, long offset, long length) { string[] splitted = SplitPath(path); if (splitted.Length > 0) { LotdDirectory directory = ResolveDirectory(splitted, true, true); if (directory != null) { LotdFile file = new LotdFile(); file.Name = splitted[splitted.Length - 1]; file.Directory = directory; file.ArchiveOffset = offset; file.ArchiveLength = length; return(file); } } return(null); }
public void Load() { if (string.IsNullOrEmpty(InstallDirectory) || !Directory.Exists(InstallDirectory)) { throw new Exception("Couldn't find the install directory for Legacy of the Duelist '" + InstallDirectory + "'"); } string tocPath = Path.Combine(InstallDirectory, TocFileName); string datPath = Path.Combine(InstallDirectory, DatFileName); if (!File.Exists(tocPath) || !File.Exists(datPath)) { throw new Exception("Failed to find data files"); } if (Reader != null) { Reader.Close(); Reader = null; } Root = new LotdDirectory(); Root.Archive = this; Root.IsRoot = true; List <string> filePaths = new List <string>(); try { long offset = 0; string[] lines = File.ReadAllLines(tocPath); for (int i = 0; i < lines.Length; i++) { string line = lines[i]; if (!line.StartsWith("UT")) { int offsetStart = -1; for (int charIndex = 0; charIndex < line.Length; charIndex++) { if (line[charIndex] != ' ') { offsetStart = charIndex; break; } } int offsetEnd = offsetStart == -1 ? -1 : line.IndexOf(' ', offsetStart); int unknownStart = offsetEnd == -1 ? -1 : offsetEnd + 1; int unknownEnd = unknownStart == -1 ? -1 : line.IndexOf(' ', unknownStart + 1); bool validLine = unknownEnd >= 0; if (validLine) { string lengthStr = line.Substring(offsetStart, offsetEnd - offsetStart); string filePathLengthStr = line.Substring(unknownStart, unknownEnd - unknownStart); string filePath = line.Substring(unknownEnd + 1); long length; int filePathLength; if (long.TryParse(lengthStr, NumberStyles.HexNumber, null, out length) && int.TryParse(filePathLengthStr, NumberStyles.HexNumber, null, out filePathLength) && filePathLength == filePath.Length) { Root.AddFile(filePath, offset, length); offset += length; // Add the offset for the data alignment const int align = 4; if (length % align != 0) { offset += align - (length % align); } filePaths.Add(filePath); } else { validLine = false; } } if (!validLine) { throw new Exception("Failed to parse line in toc file " + line); } } } } catch (Exception e) { throw new Exception("Error when reading .toc file: " + e); } try { if (WriteAccess) { Reader = new BinaryReader(File.Open(datPath, FileMode.Open, FileAccess.ReadWrite)); } else { Reader = new BinaryReader(File.OpenRead(datPath)); } } catch (Exception e) { throw new Exception("Error when opening .dat file: " + e); } // Validate all file paths foreach (string filePath in filePaths) { LotdFile file = Root.FindFile(filePath); if (file == null) { throw new Exception("Archive loader is broken. File path not found in archive structure: '" + filePath + "'"); } } }