ME3Explorer.Unreal.DLCPackage.AddFileQuick C# (CSharp) Method

AddFileQuick() public method

public AddFileQuick ( string filein, string path ) : void
filein string
path string
return void
        public void AddFileQuick(string filein, string path)
        {
            
            string DLCPath = FileName;
            FileStream fs = new FileStream(DLCPath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            byte[] FileIN = File.ReadAllBytes(filein);            
            //Create Entry
            List<FileEntryStruct> tmp = new List<FileEntryStruct>(Files);
            FileEntryStruct e = new FileEntryStruct();
            e.FileName = path;
            e.BlockOffsets = new long[0];
            e.Hash = ComputeHash(path);
            e.BlockSizeIndex = 0xFFFFFFFF;
            e.UncompressedSize = (uint)FileIN.Length;
            e.UncompressedSizeAdder = 0;
            tmp.Add(e);
            e = new FileEntryStruct();
            Files = tmp.ToArray();
            //
            //Find TOC
            DebugOutput.PrintLn("Searching TOC...");
            int f = FindTOC();
            if (f == -1)
                return;            
            DebugOutput.PrintLn("Found TOC, adding line...");
            MemoryStream m = DecompressEntry(f, fs);
            //
            //Update TOC
            WriteString(m, path);
            m.WriteByte(0xD);
            m.WriteByte(0xA);
            //
            //Append new FileTable
            int count = (int)Header.FileCount +1;
            long oldsize = fs.Length;
            long offset  = oldsize;
            DebugOutput.PrintLn("File End Offset : 0x" + offset.ToString("X10"));
            fs.Seek(oldsize, 0);
            Header.EntryOffset = (uint)offset;
            for (int i = 0; i < count; i++) 
            {
                e = Files[i];
                fs.Write(e.Hash, 0, 16);
                fs.Write(BitConverter.GetBytes(e.BlockSizeIndex), 0, 4);
                fs.Write(BitConverter.GetBytes(e.UncompressedSize), 0, 4);
                fs.WriteByte(e.UncompressedSizeAdder);
                fs.Write(BitConverter.GetBytes(e.DataOffset), 0, 4);
                fs.WriteByte(e.DataOffsetAdder);
            }
            offset += count * 0x1E;
            DebugOutput.PrintLn("Table End Offset : 0x" + offset.ToString("X10"));
            Header.BlockTableOffset = (uint)offset;
            //
            //Append blocktable
            for (int i = 0; i < count; i++)
            {
                e = Files[i];
                if (e.BlockSizeIndex != 0xFFFFFFFF && i != f)
                    foreach(ushort u in e.BlockSizes)
                        fs.Write(BitConverter.GetBytes(u), 0, 2);
            }
            offset = fs.Length;
            DebugOutput.PrintLn("Block Table End Offset : 0x" + offset.ToString("X10"));
            long dataoffset = offset;
            fs.Write(FileIN, 0, FileIN.Length);
            offset += FileIN.Length;
            DebugOutput.PrintLn("New Data End Offset : 0x" + offset.ToString("X10"));
            //
            //Append TOC
            long tocoffset = offset;
            fs.Write(m.ToArray(), 0, (int)m.Length);
            offset = fs.Length;
            DebugOutput.PrintLn("New TOC Data End Offset : 0x" + offset.ToString("X10"));
            //update filetable
            fs.Seek(oldsize, 0);
            uint blocksizeindex = 0;
            for (int i = 0; i < count; i++)
            {
                e = Files[i];
                fs.Write(e.Hash, 0, 16);
                if (e.BlockSizeIndex == 0xFFFFFFFF || i==f)
                    fs.Write(BitConverter.GetBytes(-1), 0, 4);
                else
                {
                    fs.Write(BitConverter.GetBytes(blocksizeindex), 0, 4);
                    e.BlockSizeIndex = blocksizeindex;
                    blocksizeindex += (uint)e.BlockSizes.Length;                    
                    Files[i] = e;
                }
                if (i == f)
                {
                    fs.Write(BitConverter.GetBytes(m.Length), 0, 4);
                    fs.WriteByte(0);
                    fs.Write(BitConverter.GetBytes(tocoffset), 0, 4);
                    byte b = (byte)((tocoffset & 0xFF00000000) >> 32);
                    fs.WriteByte(b);
                }
                else if (i == count - 1)
                {
                    fs.Write(BitConverter.GetBytes(e.UncompressedSize), 0, 4);
                    fs.WriteByte(0);
                    fs.Write(BitConverter.GetBytes(dataoffset), 0, 4);
                    byte b = (byte)((dataoffset & 0xFF00000000) >> 32);
                    fs.WriteByte(b);
                }
                else
                {
                    fs.Write(BitConverter.GetBytes(e.UncompressedSize), 0, 4);
                    fs.WriteByte(e.UncompressedSizeAdder);
                    fs.Write(BitConverter.GetBytes(e.DataOffset), 0, 4);
                    fs.WriteByte(e.DataOffsetAdder);
                }
            }
            //Update Header
            fs.Seek(0xC, 0);
            fs.Write(BitConverter.GetBytes(Header.EntryOffset), 0, 4);
            fs.Write(BitConverter.GetBytes(count), 0, 4);
            fs.Write(BitConverter.GetBytes(Header.BlockTableOffset), 0, 4);
            //
            fs.Close();
        }

Usage Example

示例#1
0
        private bool HandleCommandLineArgs(string[] args, out int exitCode)
        {
            if (args.Length < 2)
            {
                exitCode = 0;
                return false;
            }
            //automation
            try
            {
                if (args[1].Equals("-dlcinject"))
                {
                    if (args.Length % 2 != 1 || args.Length < 5)
                    {
                        MessageBox.Show("Wrong number of arguments for the -dlcinject switch.:\nSyntax is: <exe> -dlcinject SFARPATH SEARCHTERM NEWFILEPATH [SEARCHTERM2 NEWFILEPATH2]...", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        exitCode = 1;
                        return true;
                    }
                    string dlcFileName = args[2];
                    int numfiles = (args.Length - 3) / 2;

                    string[] filesToReplace = new string[numfiles];
                    string[] newFiles = new string[numfiles];

                    int argnum = 3; //starts at 3
                    for (int i = 0; i < filesToReplace.Length; i++)
                    {
                        filesToReplace[i] = args[argnum];
                        argnum++;
                        newFiles[i] = args[argnum];
                        argnum++;
                    }
                    if (File.Exists(dlcFileName))
                    {
                        DLCPackage dlc = new DLCPackage(dlcFileName);
                        for (int i = 0; i < numfiles; i++)
                        {
                            int idx = dlc.FindFileEntry(filesToReplace[i]);
                            if (idx == -1)
                            {
                                MessageBox.Show("DLCEditor2 automator encountered an error: the file to replace does not exist.", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                                exitCode = 1;
                                return true;
                            }
                            dlc.ReplaceEntry(newFiles[i], idx);
                        }
                        exitCode = 0;
                        return true;
                    }
                    MessageBox.Show("Failed to autoinject: DLC file does not exist: " + dlcFileName, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    exitCode = 1;
                    return true;
                }
                else if (args[1].Equals("-dlcextract"))
                {
                    if (args.Length != 5)
                    {
                        //-2 for me3explorer & -dlcextract
                        MessageBox.Show("Wrong number of arguments for the -dlcextract switch.:\nSyntax is: <exe> -dlcextract SFARPATH SEARCHTERM EXTRACTIONPATH", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        exitCode = 1;
                        return true;
                    }
                    string dlcFileName = args[2];
                    string searchTerm = args[3];
                    string extractionPath = args[4];
                    if (File.Exists(dlcFileName))
                    {
                        DLCPackage dlc = new DLCPackage(dlcFileName);
                        int idx = dlc.FindFileEntry(searchTerm);
                        if (idx == -1)
                        {
                            MessageBox.Show("DLCEditor2 extraction automator encountered an error:\nThe file to replace does not exist or the tree has not been initialized.", "DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                            exitCode = 1;
                            return true;
                        }
                        using (FileStream fs = new FileStream(extractionPath, FileMode.Create, FileAccess.Write, FileShare.None, 4096, useAsync: true))
                        {
                            dlc.DecompressEntryAsync(idx, fs).Wait();
                        }
                        exitCode = 0;
                        return true;
                    }
                    MessageBox.Show("Failed to autoextract: DLC file does not exist: " + dlcFileName, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    exitCode = 1;
                    return true;

                }
                else if (args[1].Equals("-dlcaddfiles"))
                {
                    if (args.Length % 2 != 1 || args.Length < 5)
                    {
                        MessageBox.Show("Wrong number of arguments for the -dlcaddfiles switch.:\nSyntax is: <exe> -dlcinject SFARPATH INTERNALPATH NEWFILEPATH [INTERNALPATH2 NEWFILEPATH2]...", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        exitCode = 1;
                        return true;
                    }
                    
                    string dlcFileName = args[2];
                    int numfiles = (args.Length - 3) / 2;
                    string[] internalPaths = new string[numfiles];
                    string[] sourcePaths = new string[numfiles];

                    int argnum = 3; //starts at 3
                    for (int i = 0; i < internalPaths.Length; i++)
                    {
                        internalPaths[i] = args[argnum];
                        argnum++;
                        sourcePaths[i] = args[argnum];
                        argnum++;
                    }

                    if (File.Exists(dlcFileName))
                    {
                        DLCPackage dlc = new DLCPackage(dlcFileName);
                        for (int i = 0; i < internalPaths.Length; i++)
                        {
                            dlc.AddFileQuick(sourcePaths[i], internalPaths[i]);
                        }
                        exitCode = 0;
                        return true;
                    }
                    MessageBox.Show("Failed to autoadd: DLC file does not exist: " + dlcFileName, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    exitCode = 1;
                    return true;
                }
                else if (args[1].Equals("-dlcremovefiles"))
                {
                    if (args.Length < 4)
                    {
                        //-2 for me3explorer & -dlcextract
                        MessageBox.Show("Wrong number of arguments for the -dlcremovefiles switch.:\nSyntax is: <exe> -dlcinject SFARPATH INTERNALPATH [INTERNALPATH2]...", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        exitCode = 1;
                        return true;
                    }
                    string dlcFileName = args[2];
                    int numfiles = (args.Length - 3);
                    string[] filesToRemove = new string[numfiles];
                    int argnum = 3; //starts at 3
                    for (int i = 0; i < filesToRemove.Length; i++)
                    {
                        filesToRemove[i] = args[argnum];
                        argnum++;
                    }

                    if (File.Exists(dlcFileName))
                    {
                        DLCPackage dlc = new DLCPackage(dlcFileName);
                        for (int i = 0; i < filesToRemove.Length; i++)
                        {
                            int idx = dlc.FindFileEntry(filesToRemove[i]);
                            if (idx == -1)
                            {
                                MessageBox.Show("DLCEditor2 file removal automator encountered an error:\nThe file to remove does not exist or the tree has not been initialized.", "DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                                exitCode = 1;
                                return true;
                            }
                            dlc.DeleteEntry(idx);
                        }
                        exitCode = 0;
                        return true;
                    }
                    MessageBox.Show("Failed to autoremove: DLC file does not exist: " + dlcFileName, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                    exitCode = 1;
                    return true;

                }
                else if (args[1].Equals("-dlcunpack") || args[1].Equals("-dlcunpack-nodebug"))
                {
                    if (args.Length != 4)
                    {
                        MessageBox.Show("Wrong number of arguments for automated DLC unpacking:\nSyntax is: <exe> -dlcunpack SFARPATH EXTRACTIONPATH", "ME3 DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        exitCode = 1;
                        return true;
                    }

                    string sfarPath = args[2];
                    string autoUnpackFolder = args[3];
                    
                    if (File.Exists(sfarPath))
                    {
                        DLCPackage dlc = new DLCPackage(sfarPath);
                        if (args[1].Equals("-dlcunpack"))
                        {
                            //open debugging window since this operation takes a long time.
                            KFreonLib.Debugging.DebugOutput.StartDebugger("DLC Editor 2");
                        }
                        //Simulate Unpack operation click.
                        SFAREditor2.unpackSFAR(dlc);
                        exitCode = 0;
                        return true;
                    }
                    else
                    {
                        MessageBox.Show("Failed to autounpack: DLC file does not exist: " + sfarPath, "ME3Explorer DLCEditor2 Error", MessageBoxButton.OK, MessageBoxImage.Error);
                        exitCode = 1;
                        return true;
                    }
                }
                else if (args[1].Equals("-toceditorupdate"))
                {
                    //Legacy command requested by FemShep
                    TOCeditor toc = new TOCeditor();
                    exitCode = toc.updateTOCFromCommandLine(args.Skip(2).ToList());
                    return true;
                }
                else if (args[1].Equals("-autotoc"))
                {
                    if (args.Length == 2)
                    {
                        AutoTOC.GenerateAllTOCs();
                    }
                    else
                    {
                        AutoTOC.prepareToCreateTOC(args[2]);
                    }
                    exitCode = 0;
                    return true;
                }
                else if (args[1].Equals("-sfarautotoc"))
                {
                    if (args.Length != 3)
                    {
                        MessageBox.Show("-sfarautotoc command line argument requires at least 1 parameter:\nSFARFILE.sfar", "Automated SFAR TOC Update Fail", MessageBoxButton.OK, MessageBoxImage.Error);
                        exitCode = 1;
                        return true;
                    }
                    
                    var result = Parallel.For(2, args.Length, i =>
                    {
                        if (args[i].EndsWith(".sfar") && File.Exists(args[i]))
                        {
                            DLCPackage DLC = new DLCPackage(args[2]);
                            DLC.UpdateTOCbin(true); 
                        }
                    });
                    exitCode = result.IsCompleted ? 0 : 1;
                    return true;
                }
                else if (args[1].Equals("-decompresspcc"))
                {
                    if (args.Length != 4)
                    {
                        MessageBox.Show("-decompresspcc command line argument requires 2 parameters:\ninputfile.pcc outputfile.pcc\nBoth arguments can be the same.", "Auto Decompression Error", MessageBoxButton.OK, MessageBoxImage.Error);

                        exitCode = 1;
                        return true;
                    }
                    exitCode = PCCRepack.autoDecompressPcc(args[2], args[3]);
                    return true;
                }
                else if (args[1].Equals("-compresspcc"))
                {
                    if (args.Length != 4)
                    {
                        MessageBox.Show("-compresspcc command line argument requires 2 parameters:\ninputfile.pcc outputfile.pcc\nBoth arguments can be the same.", "Auto Compression Error", MessageBoxButton.OK, MessageBoxImage.Error);

                        exitCode = 1;
                        return true;
                    }
                    exitCode = PCCRepack.autoCompressPcc(args[2], args[3]);
                    return true;
                }
            }
            catch
            {
                exitCode = 1;
                return true;
            }

            string ending = Path.GetExtension(args[1]).ToLower();
            switch (ending)
            {
                case ".pcc":
                    PackageEditor editor = new PackageEditor();
                    editor.Show();
                    editor.LoadFile(args[1]);
                    break;
            }
            exitCode = 0;
            return false;
        }