예제 #1
0
        // 00 non-snakebite Files to 01,  01 lua files unchanged,   01 textures -> t7,   01 chunkfiles -> c7, 
        private static void MoveDatFilesDirty(SettingsManager manager)
        {
            var modQarFiles = manager.GetModQarFiles();

            string sourceName = null;
            string destName = null;
            string destFolder = null;

            Debug.LogLine("[DatMerge] Dispersing files from 00 to 01, and then from 01 to a_chunk7 and a_texture7 if necessary.", Debug.LogLevel.Debug);
            List<string> oneFiles = GzsLib.ExtractArchive<QarFile>(OnePath, "_extr");
            List<string> zeroList = new List<string>();
            int moveCount = 0;

            try
            {
                zeroList = GzsLib.ListArchiveContents<QarFile>(ZeroPath);
            } catch (Exception e)
            {
                Debug.LogLine(String.Format("[Error] GzsLib.ListArchiveContents exception: {0}", e.ToString()), Debug.LogLevel.Debug);
                throw e;
            }

            foreach (string zeroFile in zeroList)
            {
                if (zeroFile == "foxpatch.dat") continue;
                if (modQarFiles.Contains(Tools.ToQarPath(zeroFile)) || oneFiles.Contains(zeroFile)) continue;
                if (oneFiles.Contains(zeroFile)) continue;
                moveCount++;
            }
            if (moveCount > 0) //if any non-snakebite files exist in 00, move them to 01.
            {
                Debug.LogLine("[DatMerge] Moving files to 01.dat.", Debug.LogLevel.Debug);
                List<string> zeroFiles = GzsLib.ExtractArchive<QarFile>(ZeroPath, "_working1");
                List<string> zeroOut = zeroFiles.ToList();

                foreach (string zeroFile in zeroFiles)
                {
                    if (zeroFile == "foxpatch.dat") continue;
                    if (modQarFiles.Contains(Tools.ToQarPath(zeroFile))) continue;
                    if (oneFiles.Contains(zeroFile)) { zeroOut.Remove(zeroFile); continue; } //if it already exists in 01 then there's nowhere for it to go.

                    sourceName = Path.Combine("_working1", Tools.ToWinPath(zeroFile));
                    destName = Path.Combine("_extr", Tools.ToWinPath(zeroFile));

                    oneFiles.Add(zeroFile); // 00 -> 01
                    zeroOut.Remove(zeroFile);

                    destFolder = Path.GetDirectoryName(destName);
                    if (!Directory.Exists(destFolder)) Directory.CreateDirectory(destFolder);
                    if (!File.Exists(destName)) File.Move(sourceName, destName);
                }

                GzsLib.WriteQarArchive(ZeroPath + build_ext, "_working1", zeroOut, GzsLib.zeroFlags); // rebuild 00 archive


                Directory.Delete("_working1", true); // clean up _working1, to be used by texture7
                while (Directory.Exists("_working1"))
                    Thread.Sleep(100);
            }

            moveCount = 0; // check if any files need to be moved to C7/T7
            int textureCount = 0;
            List<string> chunk7List = new List<string>();
            List<string> tex7List = new List<string>();
            
            try
            {
                if (File.Exists(t7Path)) tex7List = GzsLib.ListArchiveContents<QarFile>(t7Path);
                if (File.Exists(c7Path)) chunk7List = GzsLib.ListArchiveContents<QarFile>(c7Path);
            } catch (Exception e)
            {
                Debug.LogLine(String.Format("[Error] GzsLib.ListArchiveContents exception: {0}", e.ToString()), Debug.LogLevel.Debug);
                throw e;
            }

            foreach (string oneFile in oneFiles)
            {
                if (modQarFiles.Contains(Tools.ToQarPath(oneFile)) || tex7List.Contains(oneFile) || chunk7List.Contains(oneFile)) continue;
                if (oneFile.Contains(".lua")) continue; // vanilla lua files must stay in 01
                if (oneFile.Contains(".ftex")) textureCount++;
                moveCount++;
            }
            if (moveCount > 0)
            {
                List<string> oneOut = oneFiles.ToList();

                if (textureCount > 0) // if non-snakebite textures exist, move them to t7
                {
                    Debug.LogLine("[DatMerge] Moving files to a_texture7.dat.", Debug.LogLevel.Debug);
                    List<string> texture7Files = new List<string>();
                    if (File.Exists(t7Path)) texture7Files = GzsLib.ExtractArchive<QarFile>(t7Path, "_working1");

                    foreach (string oneFile in oneFiles) // once 00 files have been moved, move 01 files into t7, c7.
                    {
                        if (modQarFiles.Contains(Tools.ToQarPath(oneFile))) continue;
                        if (oneFile.Contains(".ftex"))
                        {
                            sourceName = Path.Combine("_extr", Tools.ToWinPath(oneFile));
                            destName = Path.Combine("_working1", Tools.ToWinPath(oneFile)); // 01 -> texture7
                            destFolder = Path.GetDirectoryName(destName);

                            if (!texture7Files.Contains(oneFile)) texture7Files.Add(oneFile);
                            oneOut.Remove(oneFile);
                            if (!Directory.Exists(destFolder)) Directory.CreateDirectory(destFolder);
                            if (!File.Exists(destName)) File.Move(sourceName, destName);
                        }
                    }
                    GzsLib.WriteQarArchive(t7Path + build_ext, "_working1", texture7Files, GzsLib.texture7Flags);
                }

                oneFiles = oneOut.ToList(); // update oneFiles to remove any .ftex already found
                if (oneFiles.Count > 0) // if any other files need to be moved, they go in chunk7
                {
                    Debug.LogLine("[DatMerge] Moving files to a_chunk7.dat.", Debug.LogLevel.Debug);
                    List<string> chunk7Files = new List<string>();
                    if (File.Exists(c7Path)) chunk7Files = GzsLib.ExtractArchive<QarFile>(c7Path, "_working2");

                    foreach (string oneFile in oneFiles) // once 00 files have been moved, move 01 files into t7, c7.
                    {
                        if (modQarFiles.Contains(Tools.ToQarPath(oneFile))) continue;
                        if (oneFile.Contains(".lua")) continue;

                        sourceName = Path.Combine("_extr", Tools.ToWinPath(oneFile));
                        destName = Path.Combine("_working2", Tools.ToWinPath(oneFile)); // 00 -> chunk7
                        destFolder = Path.GetDirectoryName(destName);

                        if (!chunk7Files.Contains(oneFile)) chunk7Files.Add(oneFile);
                        oneOut.Remove(oneFile);


                        if (!Directory.Exists(destFolder)) Directory.CreateDirectory(destFolder);
                        if (!File.Exists(destName)) File.Move(sourceName, destName);
                    }
                    GzsLib.WriteQarArchive(c7Path + build_ext, "_working2", chunk7Files, GzsLib.chunk7Flags); // rebuild chunk7 archive
                }
                GzsLib.WriteQarArchive(OnePath + build_ext, "_extr", oneOut, GzsLib.oneFlags); // rebuild 01 archive
            }
        }
예제 #2
0
        }//InstallGameDirFiles

        private static void AddToSettingsFpk(List <ModEntry> installEntryList, SettingsManager manager, List <Dictionary <ulong, GameFile> > allQarGameFiles, out List <string> PullFromVanillas, out List <string> pullFromMods, out Dictionary <string, bool> pathUpdatesExist)
        {
            GameData gameData = manager.GetGameData();

            pathUpdatesExist = new Dictionary <string, bool>();

            List <string> newModQarEntries = new List <string>();
            List <string> modQarFiles      = manager.GetModQarFiles();

            pullFromMods = new List <string>();
            foreach (ModEntry modToInstall in installEntryList)
            {
                Dictionary <string, string> newNameDictionary = new Dictionary <string, string>();
                int foundUpdate = 0;
                foreach (ModQarEntry modQar in modToInstall.ModQarEntries.Where(entry => !entry.FilePath.StartsWith("/Assets/")))
                {
                    //Debug.LogLine(string.Format("Attempting to update Qar filename: {0}", modQar.FilePath), Debug.LogLevel.Basic);
                    string unhashedName = HashingExtended.UpdateName(modQar.FilePath);
                    if (unhashedName != null)
                    {
                        //Debug.LogLine(string.Format("Success: {0}", unhashedName), Debug.LogLevel.Basic);
                        newNameDictionary.Add(modQar.FilePath, unhashedName);
                        foundUpdate++;

                        modQar.FilePath = unhashedName;
                        if (!pathUpdatesExist.ContainsKey(modToInstall.Name))
                        {
                            pathUpdatesExist.Add(modToInstall.Name, true);
                        }
                        else
                        {
                            pathUpdatesExist[modToInstall.Name] = true;
                        }
                    }
                }
                if (foundUpdate > 0)
                {
                    foreach (ModFpkEntry modFpkEntry in modToInstall.ModFpkEntries)
                    {
                        string unHashedName;
                        if (newNameDictionary.TryGetValue(modFpkEntry.FpkFile, out unHashedName))
                        {
                            modFpkEntry.FpkFile = unHashedName;
                        }
                    }
                }
                else if (!pathUpdatesExist.ContainsKey(modToInstall.Name))
                {
                    pathUpdatesExist.Add(modToInstall.Name, false);
                }

                manager.AddMod(modToInstall);
                //foreach (ModQarEntry modqar in modToInstall.ModQarEntries) Debug.LogLine("Mod Qar in modToInstall: " + modqar.FilePath);
                foreach (ModQarEntry modQarEntry in modToInstall.ModQarEntries) // add qar entries (fpk, fpkd) to GameData if they don't already exist
                {
                    string modQarFilePath = modQarEntry.FilePath;
                    if (!(modQarFilePath.EndsWith(".fpk") || modQarFilePath.EndsWith(".fpkd")))
                    {
                        continue;                                                                         // only pull for Qar's with Fpk's
                    }
                    if (modQarFiles.Any(entry => entry == modQarFilePath))
                    {
                        pullFromMods.Add(modQarFilePath);
                        //Debug.LogLine("Pulling from 00.dat: {0} " + modQarFilePath);
                    }
                    else if (!newModQarEntries.Contains(modQarFilePath))
                    {
                        newModQarEntries.Add(modQarFilePath);
                        //Debug.LogLine("Pulling from base archives: {0} " + modQarFilePath);
                    }
                }
            }
            //Debug.LogLine(string.Format("Foreach nest 1 complete"));
            List <ModFpkEntry> newModFpkEntries = new List <ModFpkEntry>();

            foreach (ModEntry modToInstall in installEntryList)
            {
                foreach (ModFpkEntry modFpkEntry in modToInstall.ModFpkEntries)
                {
                    //Debug.LogLine(string.Format("Checking out {0} from {1}", modFpkEntry.FilePath, modFpkEntry.FpkFile));

                    if (newModQarEntries.Contains(modFpkEntry.FpkFile)) // it isn't already part of the snakebite environment
                    {
                        //Debug.LogLine(string.Format("seeking repair files around {0}", modFpkEntry.FilePath));
                        newModFpkEntries.Add(modFpkEntry);
                    }
                    else
                    {
                        //Debug.LogLine(string.Format("Removing {0} from gameFpkEntries so it will only be listed in the mod's entries", modFpkEntry.FilePath));
                        int indexToRemove = gameData.GameFpkEntries.FindIndex(m => m.FilePath == Tools.ToWinPath(modFpkEntry.FilePath)); // this will remove the gamedata's listing of the file under fpkentries (repair entries), so the filepath will only be listed in the modentry
                        if (indexToRemove >= 0)
                        {
                            gameData.GameFpkEntries.RemoveAt(indexToRemove);
                        }
                    }
                }
            }
            //Debug.LogLine(string.Format("Foreach nest 2 complete"));
            HashSet <ulong> mergeFpkHashes = new HashSet <ulong>();

            PullFromVanillas = new List <string>();
            var repairFpkEntries = new List <ModFpkEntry>();

            foreach (ModFpkEntry newFpkEntry in newModFpkEntries) // this will add the fpkentry listings (repair entries) to the settings xml
            {
                //Debug.LogLine(string.Format("checking {0} for repairs", newFpkEntry.FilePath));
                ulong packHash = Tools.NameToHash(newFpkEntry.FpkFile);
                if (mergeFpkHashes.Contains(packHash))
                {
                    continue;                                        // the process has already plucked this particular qar file
                }
                foreach (var archiveQarGameFiles in allQarGameFiles) // check every archive (except 00) to see if the particular qar file already exists
                {
                    //Debug.LogLine(string.Format("checking archive for an existing qar file"));
                    if (archiveQarGameFiles.Count > 0)
                    {
                        GameFile existingPack = null;
                        archiveQarGameFiles.TryGetValue(packHash, out existingPack);
                        if (existingPack != null) // the qar file is found
                        {
                            //Debug.LogLine(string.Format("Qar file {0} found in {1}. adding to gameqarentries", newFpkEntry.FpkFile, existingPack.QarFile));
                            mergeFpkHashes.Add(packHash);
                            gameData.GameQarEntries.Add(new ModQarEntry {
                                FilePath   = newFpkEntry.FpkFile,
                                SourceType = FileSource.Merged,
                                SourceName = existingPack.QarFile,
                                Hash       = existingPack.FileHash
                            });
                            PullFromVanillas.Add(newFpkEntry.FpkFile);

                            string windowsFilePath = Tools.ToWinPath(newFpkEntry.FpkFile); // Extract the pack file from the vanilla game files, place into _gamefpk for future use
                            string sourceArchive   = Path.Combine(GameDir, "master\\" + existingPack.QarFile);
                            string workingPath     = Path.Combine("_gameFpk", windowsFilePath);
                            if (!Directory.Exists(Path.GetDirectoryName(workingPath)))
                            {
                                Directory.CreateDirectory(Path.GetDirectoryName(workingPath));
                            }

                            GzsLib.ExtractFileByHash <QarFile>(sourceArchive, existingPack.FileHash, workingPath); // extracts the specific .fpk from the game data
                            foreach (string listedFile in GzsLib.ListArchiveContents <FpkFile>(workingPath))
                            {
                                repairFpkEntries.Add(new ModFpkEntry {
                                    FpkFile    = newFpkEntry.FpkFile,
                                    FilePath   = listedFile,
                                    SourceType = FileSource.Merged,
                                    SourceName = existingPack.QarFile
                                });
                                //Debug.LogLine(string.Format("File Listed: {0} in {1}", extractedFile, newFpkEntry.FpkFile));
                            }
                            break;
                        }
                    }
                }
            }
            //Debug.LogLine(string.Format("Foreach nest 3 complete"));
            foreach (ModFpkEntry newFpkEntry in newModFpkEntries) // finally, strip away the modded entries from the repair entries
            {
                //Debug.LogLine(string.Format("checking to remove {0} from gamefpkentries", Tools.ToWinPath(newFpkEntry.FilePath)));
                int indexToRemove = repairFpkEntries.FindIndex(m => m.FilePath == Tools.ToWinPath(newFpkEntry.FilePath));
                if (indexToRemove >= 0)
                {
                    repairFpkEntries.RemoveAt(indexToRemove);
                }
            }
            gameData.GameFpkEntries = gameData.GameFpkEntries.Union(repairFpkEntries).ToList();
            manager.SetGameData(gameData);
        }
예제 #3
0
        public static void MoveDatFiles()
        {
            Debug.LogLine("[DatMerge] System data merge started", Debug.LogLevel.Debug);

            var zeroList    = GzsLib.ListArchiveContents <QarFile>(ZeroPath);
            var modQarFiles = SettingsManager.GetModQarFiles();

            int mc = 0;

            foreach (string zeroFile in zeroList)
            {
                if (zeroFile == "foxpatch.dat")
                {
                    continue;
                }
                if (modQarFiles.Contains(Tools.ToQarPath(zeroFile)))
                {
                    continue;
                }
                mc++;
            }

            if (mc > 0)
            {
                CleanupFolders();

                // Extract 00.dat
                var zeroFiles = GzsLib.ExtractArchive <QarFile>(ZeroPath, "_extr");
                // Extract 01.dat
                var oneFiles = GzsLib.ExtractArchive <QarFile>(OnePath, "_working");

                var zeroOut = zeroFiles.ToList();

                Debug.LogLine(string.Format("[DatMerge] Moving {0} system files", mc), Debug.LogLevel.Debug);
                // Move files from 00 to 01 (excluding foxpatch.dat)
                foreach (string zeroFile in zeroFiles)
                {
                    if (zeroFile == "foxpatch.dat")
                    {
                        continue;
                    }
                    if (modQarFiles.Contains(Tools.ToQarPath(zeroFile)))
                    {
                        continue;
                    }
                    string sourceName = Path.Combine("_extr", Tools.ToWinPath(zeroFile));
                    string destName   = Path.Combine("_working", Tools.ToWinPath(zeroFile));
                    string destFolder = Path.GetDirectoryName(destName);

                    Debug.LogLine(string.Format("[DatMerge] Moving system file {0}", zeroFile));
                    if (!Directory.Exists(destFolder))
                    {
                        Directory.CreateDirectory(destFolder);
                    }
                    File.Move(sourceName, destName);

                    zeroOut.Remove(zeroFile);
                    oneFiles.Add(zeroFile);
                }

                Debug.LogLine("[DatMerge] Rebuilding game archives", Debug.LogLevel.Debug);

                // Rebuild 01.dat with files
                GzsLib.WriteQarArchive(OnePath, "_working", oneFiles, 3150048);

                // Rebuild 00.dat
                GzsLib.WriteQarArchive(ZeroPath, "_extr", zeroOut, 3150304);

                SettingsManager.UpdateDatHash();

                CleanupFolders();

                Debug.LogLine("[DatMerge] Merge finished", Debug.LogLevel.Debug);
            }
            else
            {
                Debug.LogLine("[DatMerge] No files to merge, aborting", Debug.LogLevel.Debug);
            }
        }