public PackagePack(Stream output, string sourceFolder, PleaseWait progress) { NameRegistry.Files.UsedHashes = new List<UInt32>(); var group_dirs = Directory.GetDirectories(sourceFolder); var file_query = from d in group_dirs where d != sourceFolder + "\\sporemaster\\" from f in Directory.GetFileSystemEntries(d) where !f.EndsWith(".search_index") // < these might appear in group directories if there are indexable files in subdirectories select f; var files = file_query.ToList(); files.Add(sourceFolder + "\\sporemaster\\names.txt"); if (progress != null) progress.beginTask(1.0, files.Count); DatabasePackedFile dbf = new DatabasePackedFile(); dbf.Version = new Version(2, 0); dbf.WriteHeader(output, 0, 0); var rw4_hash = NameRegistry.Types.toHash("rw4"); uint size, start = (uint)output.Position; foreach( var f in files ) { string relativePath = f.Substring(sourceFolder.Length + 1); bool additionalOutputFiles; byte[] autoLocale = null; do { additionalOutputFiles = false; var parts = relativePath.Split(new char[] { '\\' }); if (parts.Length != 2) continue; var group = parts[0]; parts = parts[1].Split(new char[] { '.' }, 2); var instance = parts[0]; var extension = parts[1]; var index = new DatabaseIndex(); index.GroupId = NameRegistry.Groups.toHash(group); index.InstanceId = NameRegistry.Files.toHash(instance); try { if (relativePath == "sporemaster\\names.txt") { writeNamesFile(output); } else if (autoLocale != null) { output.Write(autoLocale, 0, autoLocale.Length); } else if (extension == "prop.xml") { extension = "prop"; writePropFile(group, instance, f, output, out autoLocale); if (autoLocale.Length != 0) { additionalOutputFiles = true; relativePath = "locale~\\auto_" + group + "_" + instance + ".locale"; } } else if (NameRegistry.Types.toHash(extension)==rw4_hash && Directory.Exists(f)) { writeRW4File(f, output); } else writeBinaryFile(f, output); } catch (Exception e) { throw new Exception("Error packing file '" + relativePath + "'.", e); } size = (uint)output.Position - start; index.TypeId = NameRegistry.Types.toHash(extension); index.Compressed = false; index.Flags = 1; index.DecompressedSize = size; index.CompressedSize = size | 0x80000000; index.Offset = start; dbf.Indices.Add(index); start += size; } while (additionalOutputFiles); progress.addProgress(1.0); } dbf.WriteIndex(output); size = (uint)output.Position - start; output.Seek(0, SeekOrigin.Begin); dbf.WriteHeader(output, (int)start, (int)size); output.Close(); if (progress != null) progress.endTask(); }
public DatabaseIndex(DatabasePackedFile owner) { this.Owner = owner; }
public static DatabasePackedFile Create() { DatabasePackedFile file = new DatabasePackedFile(); return(file); }
public PackageUnpack(Stream[] packageFiles, string destinationFolder, PleaseWait progress) { double e = 0.0; FullTextIndex.ResetPath(destinationFolder); if (Directory.Exists(destinationFolder)) { if (progress != null) progress.beginTask(e = 0.25, 1.0); Directory.Delete(destinationFolder, true); if (progress != null) progress.endTask(); } Directory.CreateDirectory(destinationFolder); double totalSize = 0; for (int i = 0; i < packageFiles.Length; i++) { totalSize += packageFiles[i].Length; } if (progress != null) progress.beginTask(1.0 - e, totalSize); foreach (var filestream in packageFiles) { DatabasePackedFile db = new DatabasePackedFile(); db.Read(filestream); var DatabaseFiles = db.Indices.ToArray(); var group_sporemaster = "sporemaster".FNV(); var instance_names = "names".FNV(); foreach (var dbf in DatabaseFiles) { if (dbf.GroupId == group_sporemaster && dbf.InstanceId == instance_names) { byte[] data = unpack(filestream, dbf); readNamesFile(data); } } var locale_type = NameRegistry.Types.toHash("locale"); var prop_type = NameRegistry.Types.toHash("prop"); var rw4_type = NameRegistry.Types.toHash("rw4"); foreach (var dbf in DatabaseFiles) { // skip over automatically generated locale files if (!(dbf.TypeId == locale_type && ( NameRegistry.Groups.toName(dbf.InstanceId).StartsWith("auto_") || NameRegistry.Groups.toName(dbf.InstanceId).EndsWith("_auto")))) { var fn = Path.Combine(destinationFolder, NameRegistry.getFileName(dbf.GroupId, dbf.InstanceId, dbf.TypeId)); Directory.CreateDirectory(Path.GetDirectoryName(fn)); byte[] data = unpack(filestream, dbf); if (dbf.TypeId == prop_type) writePropFile(data, fn); else if (dbf.TypeId == rw4_type) writeRW4File(data, fn); else writeBinaryFile(data, fn); } if (progress != null) progress.addProgress(dbf.CompressedSize); } filestream.Close(); } if (progress != null) progress.endTask(); }
public static void SaveAs(string fileName, List <DatabaseIndex> selectedIndices) { DatabasePackedFile newPackage = new DatabasePackedFile(); newPackage.Version = new Version(3, 0); newPackage.Indices = new ObservableList <DatabaseIndex>(); newPackage.Indices.AddRange(selectedIndices); using (FileStream fileStream = File.Create(fileName)) { newPackage.WriteHeader(fileStream, 0, 0); int totalSize = 0; foreach (DatabaseIndex subIndex in newPackage.Indices) { byte[] data; if (subIndex.IsModified) { data = subIndex.ModifiedData.GetData(); subIndex.Offset = fileStream.Position; subIndex.CompressedSize = (uint)data.Length; subIndex.Compressed = false; subIndex.CompressedFlags = 0; subIndex.DecompressedSize = (uint)data.Length; subIndex.TypeId = subIndex.TypeId; subIndex.GroupContainer = subIndex.GroupContainer; subIndex.InstanceId = subIndex.InstanceId; fileStream.Write(data, 0, data.Length); } else { data = subIndex.GetIndexData(false); if (data.Length != subIndex.CompressedSize) { throw new Exception("error"); } subIndex.Offset = fileStream.Position; fileStream.Write(data, 0, data.Length); } totalSize += data.Length; } long positionBeforeIndex = fileStream.Position; newPackage.WriteIndex(fileStream); int indexOffset = 96 + totalSize; totalSize = (int)fileStream.Position; fileStream.Seek(0, SeekOrigin.Begin); newPackage.WriteHeader(fileStream, indexOffset, totalSize - (int)positionBeforeIndex); } }