public void RemoveFile(LotdFile file) { if (file.Directory == this) { file.Directory = null; } }
/// <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); }
public void RemoveFile(string path) { LotdFile file = FindFile(path); if (file != null) { file.Directory = 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); }
/// <summary> /// Adds all files on disk within a given directory /// </summary> public LotdFile[] AddFilesOnDisk(string directory, string rootDir, bool recursive) { List <LotdFile> files = new List <LotdFile>(); if (Directory.Exists(directory)) { SearchOption searchOption = recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly; foreach (string filePath in Directory.GetFiles(directory, "*.*", searchOption)) { LotdFile file = AddFileOnDisk(filePath, rootDir); if (file != null) { files.Add(file); } } } return(files.ToArray()); }
public Dictionary <Language, byte[]> LoadLocalizedBuffer(string search, bool startsWithElseContains) { Dictionary <Language, byte[]> result = new Dictionary <Language, byte[]>(); search = search.ToLower(); List <LotdFile> files = Root.GetAllFiles(); foreach (LotdFile file in files) { if (file.FileType == LotdFileType.Zib) { ZibData zibData = file.LoadData <ZibData>(); foreach (ZibFile zibFile in zibData.Files.Values) { Language language = LotdFile.GetLanguageFromFileName(zibFile.FileName); if (language != Language.Unknown) { if ((startsWithElseContains && zibFile.FileName.ToLower().StartsWith(search)) || (!startsWithElseContains && zibFile.FileName.ToLower().Contains(search))) { result.Add(language, zibFile.LoadBuffer()); } } } } else { Language language = LotdFile.GetLanguageFromFileName(file.Name); if (language != Language.Unknown) { if ((startsWithElseContains && file.Name.ToLower().StartsWith(search)) || (!startsWithElseContains && file.Name.ToLower().Contains(search))) { result.Add(language, file.LoadBuffer()); } } } } return(result); }
public T LoadLocalizedFile <T>() where T : FileData, new() { LotdFileType targetFileType = LotdFile.GetFileType(typeof(T)); T result = new T(); if (!result.IsLocalized) { throw new InvalidOperationException("Attempted to load a file with localization which has none"); } List <LotdFile> files = Root.GetAllFiles(); foreach (LotdFile file in files) { if (file.FileType == LotdFileType.Zib) { ZibData zibData = file.LoadData <ZibData>(); foreach (ZibFile zibFile in zibData.Files.Values) { if (zibFile.FileType == targetFileType) { result.File = null; result.ZibFile = zibFile; result.Load(); } } } else if (file.FileType == targetFileType) { result.File = file; result.ZibFile = null; result.Load(); } } return(result); }
public List <T> LoadFiles <T>() where T : FileData { LotdFileType targetFileType = LotdFile.GetFileType(typeof(T)); List <T> result = new List <T>(); List <LotdFile> files = Root.GetAllFiles(); foreach (LotdFile file in files) { if (file.FileType == LotdFileType.Zib) { ZibData zibData = file.LoadData <ZibData>(); foreach (ZibFile zibFile in zibData.Files.Values) { if (zibFile.FileType == targetFileType) { T data = zibFile.LoadData <T>(); if (data != null) { result.Add(data); } } } } else if (file.FileType == targetFileType) { T data = file.LoadData <T>(); if (data != null) { result.Add(data); } } } return(result); }
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 + "'"); } } }
/// <summary> /// Testing changes to CARD_Named.bin /// </summary> private static void TestModifyCardNamedBin(GameVersion version) { LotdArchive archive = new LotdArchive(version); archive.WriteAccess = true; archive.Load(); Dictionary <CardNameType, List <short> > cardNameTypes = new Dictionary <CardNameType, List <short> >(); BinaryWriter writer = new BinaryWriter(archive.Reader.BaseStream, Encoding.Default, true); LotdFile file = archive.Root.FindFile("bin/CARD_Named.bin"); /*foreach (byte b in file.LoadBuffer()) * { * Console.Write(b.ToString("X2") + " "); * }*/ using (BinaryReader reader = new BinaryReader(new MemoryStream(file.LoadBuffer()))) { ushort numArchetypes = reader.ReadUInt16(); ushort numCards = reader.ReadUInt16(); long cardsStartOffset = 4 + (numArchetypes * 4); long cardsEndOffset = cardsStartOffset + (numCards * 2); System.Diagnostics.Debug.Assert(reader.BaseStream.Length == cardsEndOffset); for (int i = 0; i < numArchetypes; i++) { int offset = reader.ReadInt16(); // The offset of the cards for this named group (starts at 0) int count = reader.ReadInt16(); // The number of cards for this named group List <short> cardIds; if (!cardNameTypes.TryGetValue((CardNameType)i, out cardIds)) { cardNameTypes.Add((CardNameType)i, cardIds = new List <short>()); } long tempOffset = reader.BaseStream.Position; reader.BaseStream.Position = cardsStartOffset + (offset * 2); for (int j = 0; j < count; j++) { short cardId = reader.ReadInt16(); cardIds.Add(cardId); } reader.BaseStream.Position = tempOffset; } } int totalCards = 0; int cardsOffset = 0; foreach (KeyValuePair <CardNameType, List <short> > cards in cardNameTypes) { totalCards += cards.Value.Count; } writer.BaseStream.Position = file.ArchiveOffset; writer.Write((ushort)cardNameTypes.Count); writer.Write((ushort)totalCards);// total num cards foreach (KeyValuePair <CardNameType, List <short> > cards in cardNameTypes) { writer.Write((ushort)cardsOffset); // The offset of the cards for this named group (starts at 0) writer.Write((ushort)cards.Value.Count); // The number of cards for this named group cardsOffset += cards.Value.Count; } foreach (KeyValuePair <CardNameType, List <short> > cards in cardNameTypes) { if (cards.Key == CardNameType.UA) { //cards.Value.Remove(11637); cards.Value.Add(11641); cards.Value.Sort(); } //bool first = true; foreach (short cardId in cards.Value) //.OrderBy(x => x)) { if ((cards.Key == CardNameType.UA /* && first*/)) // || cards.Key > CardNameType.PendDragon) { /*if (cardId == 11637)//(cards.Key == CardNameType.UA && first)) * { * Console.WriteLine(cardId); * writer.Write((short)5380); * } * else*/ { writer.Write(cardId); } } else { writer.Write(cardId); } //first = false; } } writer.Close(); System.Diagnostics.Debugger.Break(); }