Exemplo n.º 1
0
        /// <summary>
        /// Saves the ERF file under the specified name.
        /// </summary>
        /// <param name="fileName">The name of the file.</param>
        public void SaveAs(string fileName)
        {
            NWNLogger.Log(0, "module.SaveAs entering [{0}]", fileName);
            // The ERF must be decompressed first unless it is a new ERF.
            if (keys.Length > 0 && string.Empty == decompressedPath)
                throw new NWNException("ERF must be decompressed to recreate");

            // Copy all of the modified files into the temp directory
            StringCollection replacedFiles = ReplacedFiles;
            NWNLogger.Log(0, "module.SaveAs copying {0} modified files into temp directory", replacedFiles.Count);
            foreach (string file in replacedFiles)
                File.Copy(file, Path.Combine(decompressedPath,
                    Path.GetFileName(file)), true);

            // Figure out the new number of files in the ERF and create new
            // key/resource arrays of the proper size.
            int fileCount = keys.Length + addedFileHash.Count - removedFiles.Count;
            NWNLogger.Log(0, "module.SaveAs {0} total files, allocating key/resource arrays", fileCount);
            ErfKey[] newKeys = new ErfKey[fileCount];
            ErfResource[] newResources = new ErfResource[fileCount];

            // Create a buffer to store the data.
            NWNLogger.Log(0, "module.SaveAs creating memory stream");
            MemoryStream buffer = new MemoryStream();

            // Copy all of the existing not-removed files into the new key/resource
            // arrays.
            int index = 0;
            for (int i = 0; i < keys.Length; i++)
            {
                string file = keys[i].FileName;
                if (string.Empty == file || removedFiles.Contains(file)) continue;

                // Copy the key/resource pair over.
            NWNLogger.Log(1, "module.SaveAs copying file[{0}] '{1}'", i, file);
                newKeys[index] = keys[i];
                newResources[index] = resources[i];

                // Read the file into the buffer.
                ReadFileIntoStream(Path.Combine(decompressedPath, file),
                    ref newResources[index], buffer);

                index++;
            }

            // Add all of the new files to the key/resource arrays.
            StringCollection addedFiles = AddedFiles;
            foreach (string file in addedFiles)
            {
            NWNLogger.Log(1, "module.SaveAs adding new file '{0}'", file);
                // SBH - depends on mode (NWN1 uses 1.0, 2 uses 1.1)
                if (NWNInfo.ModeNWN1)
                    newKeys[index] = new ErfKey(file, 1.0);
                else
                    newKeys[index] = new ErfKey(file, 1.1);

                newResources[index] = new ErfResource();

                // Read the file into the buffer.
                ReadFileIntoStream(file, ref newResources[index], buffer);
                index++;
            }

            // Figure out how big our descriptions are going to be.
            NWNLogger.Log(0, "module.SaveAs calcing description size");
            int descriptionsCount = 0;
            for (int i = 0; i < descriptions.Length; i++)
                descriptionsCount += descriptions[i].SizeInStream;

            // Create a new resource header and calculate the new offsets.
            NWNLogger.Log(0, "module.SaveAs creating header");
            ErfHeader newHeader = header;
            newHeader.OffsetToLocalizedString = Marshal.SizeOf(typeof(ErfHeader));
            newHeader.OffsetToKeyList = newHeader.OffsetToLocalizedString + descriptionsCount;
            newHeader.EntryCount = fileCount;
            //SBH - depends on mode
            if (NWNInfo.ModeNWN1)
                newHeader.OffsetToResourceList = newHeader.OffsetToKeyList +
                    (fileCount * ErfKey.SizeOf(1.0));
            else
                newHeader.OffsetToResourceList = newHeader.OffsetToKeyList +
                    (fileCount * ErfKey.SizeOf(1.1));

            // Calculate the offset to the beginning of the resource data and adjust
            // the offsets in the resource array to take this into account.
            NWNLogger.Log(0, "module.SaveAs calcing offsets");
            int offsetToData = newHeader.OffsetToResourceList +
                (fileCount * Marshal.SizeOf(typeof(ErfResource)));
            for (int i = 0; i < newResources.Length; i++)
                newResources[i].OffsetToResource += offsetToData;

            // Create the new file and write the data to it.
            NWNLogger.Log(0, "module.SaveAs creating output file");
            string newName = fileName + ".New";
            using (FileStream writer = new FileStream(newName, FileMode.Create,
                       FileAccess.Write, FileShare.Write))
            {
            NWNLogger.Log(0, "module.SaveAs writing header");
                newHeader.Serialize(writer);
            NWNLogger.Log(0, "module.SaveAs writing strings");
                ErfString.Serialize(writer, descriptions);
            NWNLogger.Log(0, "module.SaveAs writing keys");
                ErfKey.Serlialize(writer, newKeys);
            NWNLogger.Log(0, "module.SaveAs writing resources");
                ErfResource.Serlialize(writer, newResources);
            NWNLogger.Log(0, "module.SaveAs writing raw data");
                writer.Write(buffer.GetBuffer(), 0, (int) buffer.Length);

            NWNLogger.Log(0, "module.SaveAs flushing and closing");
                writer.Flush();
                writer.Close();
            }

            // Delete the old file and rename the new file to the proper name.
            NWNLogger.Log(0, "module.SaveAs copying over current file");
            File.Copy(newName, fileName, true);
            NWNLogger.Log(0, "module.SaveAs deleting");
            File.Delete(newName);

            // Update the ERF's field's with the new values.
            NWNLogger.Log(0, "module.SaveAs updating object definition");
            header = newHeader;
            keys = newKeys;
            resources = newResources;

            // Clear our string collections.
            replacedFileHash.Clear();
            addedFileHash.Clear();
            removedFiles.Clear();

            fileInfo = new FileInfo(fileName);
        }
Exemplo n.º 2
0
 public static ErfKey[] Deserialize(Stream s, int count, double version)
 {
     // Create an array of ErfKeys from the stream.
     ErfKey[] keys = new ErfKey[count];
     for (int i = 0; i < count; i++)
         keys[i] = new ErfKey(s, version);
     return keys;
 }
Exemplo n.º 3
0
 public static void Serlialize(Stream s, ErfKey[] keys)
 {
     foreach(ErfKey key in keys)
     {
         key.Serlialize(s);
     }
 }
Exemplo n.º 4
0
 /// <summary>
 /// Serializes an ErfKey array to the stream.
 /// </summary>
 /// <param name="s">The stream</param>
 /// <param name="keys">The array to serialize</param>
 public static void Serlialize(Stream s, ErfKey[] keys)
 {
     // Loop through the keys, assigning them a resource ID
     // (it's just the array index) and then serializing them.
     for (int i = 0; i < keys.Length; i++)
     {
         keys[i].resourceID = i;
         keys[i].Serialize(s);
     }
 }