Beispiel #1
0
        /* Save out our material mappings archive */
        public override PAKReturnType Save()
        {
            try
            {
                //Re-write out to the PAK
                ExtraBinaryUtils BinaryUtils   = new ExtraBinaryUtils();
                BinaryWriter     ArchiveWriter = new BinaryWriter(File.OpenWrite(FilePathPAK));
                ArchiveWriter.BaseStream.SetLength(0);
                ArchiveWriter.Write(FileHeaderJunk);
                ArchiveWriter.Write(MaterialMappingEntries.Count);
                foreach (EntryMaterialMappingsPAK ThisMatRemap in MaterialMappingEntries)
                {
                    ArchiveWriter.Write(ThisMatRemap.MapHeader);
                    ArchiveWriter.Write(ThisMatRemap.MapEntryCoupleCount);
                    ArchiveWriter.Write(ThisMatRemap.MapJunk);
                    ArchiveWriter.Write(ThisMatRemap.MapFilename.Length);
                    BinaryUtils.WriteString(ThisMatRemap.MapFilename, ArchiveWriter);
                    foreach (string MaterialName in ThisMatRemap.MapMatEntries)
                    {
                        ArchiveWriter.Write(MaterialName.Length);
                        BinaryUtils.WriteString(MaterialName, ArchiveWriter);
                    }
                }
                ArchiveWriter.Close();

                return(PAKReturnType.SUCCESS);
            }
            catch (IOException) { return(PAKReturnType.FAIL_COULD_NOT_ACCESS_FILE); }
            catch (Exception) { return(PAKReturnType.FAIL_UNKNOWN); }
        }
Beispiel #2
0
        /* Replace an existing file in the TexturePAK archive */
        public override PAKReturnType ReplaceFile(string PathToNewFile, string FileName)
        {
            try
            {
                //Get the texture entry & parse new DDS
                int EntryIndex = GetFileIndex(FileName);
                if (EntryIndex == -1)
                {
                    return(PAKReturnType.FAIL_GENERAL_LOGIC_ERROR);                  //CHANGED FOR OPENCAGE
                }
                TEX4      TextureEntry = TextureEntries[EntryIndex];
                DDSReader NewTexture   = new DDSReader(PathToNewFile);

                //Currently we only apply the new texture to the "biggest", some have lower mips that we don't edit (TODO)
                TEX4_Part BiggestPart = TextureEntry.Texture_V2;
                if (BiggestPart.HeaderPos == -1 || !BiggestPart.Saved)
                {
                    BiggestPart = TextureEntry.Texture_V1;
                }
                if (BiggestPart.HeaderPos == -1 || !BiggestPart.Saved)
                {
                    return(PAKReturnType.FAIL_REQUEST_IS_UNSUPPORTED); //Shouldn't reach this.
                }

                //CATHODE seems to ignore texture header information regarding size, so as default, resize any imported textures to the original size.
                //An option is provided in the toolkit to write size information to the header (done above) however, so don't resize if that's the case.
                //More work needs to be done to figure out why CATHODE doesn't honour the header's size value.
                int OriginalLength = BiggestPart.Length;
                Array.Resize(ref NewTexture.DataBlock, OriginalLength);

                //Update our internal knowledge of the textures
                BiggestPart.Length  = (int)NewTexture.DataBlock.Length;
                BiggestPart.Width   = (Int16)NewTexture.Width;
                BiggestPart.Height  = (Int16)NewTexture.Height;
                TextureEntry.Format = NewTexture.Format;
                //TODO: Update smallest here too if it exists!
                //Will need to be written into the PAK at "Pull PAK sections before/after V2" too - headers are handled already.

                //Load the BIN and write out updated BIN texture header
                BinaryWriter     ArchiveFileBinWriter = new BinaryWriter(File.OpenWrite(FilePathBIN));
                ExtraBinaryUtils BinaryUtils          = new ExtraBinaryUtils();
                ArchiveFileBinWriter.BaseStream.Position = TextureEntry.HeaderPos;
                BinaryUtils.WriteString(TextureEntry.Magic, ArchiveFileBinWriter);
                ArchiveFileBinWriter.Write(BitConverter.GetBytes((int)TextureEntry.Format));
                ArchiveFileBinWriter.Write((TextureEntry.Texture_V2.Length == -1) ? 0 : TextureEntry.Texture_V2.Length);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V1.Length);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V1.Width);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V1.Height);
                ArchiveFileBinWriter.Write(TextureEntry.Unk_V1);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V2.Width);
                ArchiveFileBinWriter.Write(TextureEntry.Texture_V2.Height);
                ArchiveFileBinWriter.Write(TextureEntry.Unk_V2);
                ArchiveFileBinWriter.Write(TextureEntry.UnknownHeaderBytes);
                ArchiveFileBinWriter.Close();

                //Update headers for V1+2 in PAK if they exist
                BinaryWriter   ArchiveFileWriter = new BinaryWriter(File.OpenWrite(FilePathPAK));
                BigEndianUtils BigEndian         = new BigEndianUtils();
                if (TextureEntry.Texture_V1.HeaderPos != -1)
                {
                    ArchiveFileWriter.BaseStream.Position = TextureEntry.Texture_V1.HeaderPos;
                    ArchiveFileWriter.Write(TextureEntry.Texture_V1.UnknownHeaderLead);
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes(TextureEntry.Texture_V1.Length)));
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes(TextureEntry.Texture_V1.Length)));
                    ArchiveFileWriter.Write(TextureEntry.Texture_V1.UnknownHeaderTrail_1);
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes((Int16)EntryIndex)));
                    ArchiveFileWriter.Write(TextureEntry.Texture_V1.UnknownHeaderTrail_2);
                }
                if (TextureEntry.Texture_V2.HeaderPos != -1)
                {
                    ArchiveFileWriter.BaseStream.Position = TextureEntry.Texture_V2.HeaderPos;
                    ArchiveFileWriter.Write(TextureEntry.Texture_V2.UnknownHeaderLead);
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes(TextureEntry.Texture_V2.Length)));
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes(TextureEntry.Texture_V2.Length)));
                    ArchiveFileWriter.Write(TextureEntry.Texture_V2.UnknownHeaderTrail_1);
                    ArchiveFileWriter.Write(BigEndian.FlipEndian(BitConverter.GetBytes((Int16)EntryIndex)));
                    ArchiveFileWriter.Write(TextureEntry.Texture_V2.UnknownHeaderTrail_2);
                }
                ArchiveFileWriter.Close();

                //Pull PAK sections before/after V2
                BinaryReader ArchiveFile = new BinaryReader(File.OpenRead(FilePathPAK));
                byte[]       PAK_Pt1     = ArchiveFile.ReadBytes(BiggestPart.StartPos);
                ArchiveFile.BaseStream.Position += OriginalLength;
                byte[] PAK_Pt2 = ArchiveFile.ReadBytes((int)ArchiveFile.BaseStream.Length - (int)ArchiveFile.BaseStream.Position);
                ArchiveFile.Close();

                //Write the PAK back out with new content
                ArchiveFileWriter = new BinaryWriter(File.OpenWrite(FilePathPAK));
                ArchiveFileWriter.BaseStream.SetLength(0);
                ArchiveFileWriter.Write(PAK_Pt1);
                ArchiveFileWriter.Write(NewTexture.DataBlock);
                ArchiveFileWriter.Write(PAK_Pt2);
                ArchiveFileWriter.Close();

                return(PAKReturnType.SUCCESS);
            }
            catch (IOException) { return(PAKReturnType.FAIL_COULD_NOT_ACCESS_FILE); }
            catch (Exception) { return(PAKReturnType.FAIL_UNKNOWN); }
        }
Beispiel #3
0
        /* Save out our PAK2 archive */
        public override PAKReturnType Save()
        {
            try
            {
                //Open/create PAK2 for writing
                BinaryWriter ArchiveFileWrite;
                if (File.Exists(FilePathPAK))
                {
                    ArchiveFileWrite = new BinaryWriter(File.OpenWrite(FilePathPAK));
                    ArchiveFileWrite.BaseStream.SetLength(0);
                }
                else
                {
                    ArchiveFileWrite = new BinaryWriter(File.Create(FilePathPAK));
                }
                ExtraBinaryUtils BinaryUtils = new ExtraBinaryUtils();

                //Write header
                BinaryUtils.WriteString("PAK2", ArchiveFileWrite);
                int OffsetListBegin_New = 0;
                for (int i = 0; i < Pak2Files.Count; i++)
                {
                    OffsetListBegin_New += Pak2Files[i].Filename.Length + 1;
                }
                ArchiveFileWrite.Write(OffsetListBegin_New);
                ArchiveFileWrite.Write(Pak2Files.Count);
                ArchiveFileWrite.Write(4);

                //Write filenames
                for (int i = 0; i < Pak2Files.Count; i++)
                {
                    BinaryUtils.WriteString(Pak2Files[i].Filename.Replace("\\", "/"), ArchiveFileWrite);
                    ArchiveFileWrite.Write((byte)0x00);
                }

                //Write placeholder offsets for now, we'll correct them after writing the content
                OffsetListBegin = (int)ArchiveFileWrite.BaseStream.Position;
                for (int i = 0; i < Pak2Files.Count; i++)
                {
                    ArchiveFileWrite.Write(0);
                }

                //Write files
                for (int i = 0; i < Pak2Files.Count; i++)
                {
                    while (ArchiveFileWrite.BaseStream.Position % 4 != 0)
                    {
                        ArchiveFileWrite.Write((byte)0x00);
                    }
                    ArchiveFileWrite.Write(Pak2Files[i].Content);
                    Pak2Files[i].Offset = (int)ArchiveFileWrite.BaseStream.Position;
                }

                //Re-write offsets with correct values
                ArchiveFileWrite.BaseStream.Position = OffsetListBegin;
                for (int i = 0; i < Pak2Files.Count; i++)
                {
                    ArchiveFileWrite.Write(Pak2Files[i].Offset);
                }

                ArchiveFileWrite.Close();
                return(PAKReturnType.SUCCESS);
            }
            catch (IOException) { return(PAKReturnType.FAIL_COULD_NOT_ACCESS_FILE); }
            catch (Exception) { return(PAKReturnType.FAIL_UNKNOWN); }
        }