Example #1
0
        public static void AddModsToXml(params PreinstallEntry[] modsArrary)
        {
            HashingExtended.ReadDictionary();
            foreach (PreinstallEntry mod in modsArrary)
            {
                FastZip unzipper = new FastZip();
                unzipper.ExtractZip(mod.filename, "_extr", "metadata.xml");
                ModEntry metaData = new ModEntry("_extr\\metadata.xml");

                Dictionary <string, string> newNameDictionary = new Dictionary <string, string>();
                int foundUpdate = 0;

                Debug.LogLine(string.Format("[PreinstallCheck] Checking for Qar path updates: {0}", metaData.Name), Debug.LogLevel.Basic);
                foreach (ModQarEntry modQar in metaData.ModQarEntries.Where(entry => !entry.FilePath.StartsWith("/Assets/")))
                {
                    string unhashedName = HashingExtended.UpdateName(modQar.FilePath);
                    if (unhashedName != null)
                    {
                        Debug.LogLine(string.Format("[PreinstallCheck] Update successful: {0} -> {1}", modQar.FilePath, unhashedName), Debug.LogLevel.Basic);
                        newNameDictionary.Add(modQar.FilePath, unhashedName);
                        modQar.FilePath = unhashedName;
                        foundUpdate++;
                    }
                }
                if (foundUpdate > 0)
                {
                    foreach (ModFpkEntry modFpkEntry in metaData.ModFpkEntries)
                    {
                        string unHashedName;
                        if (newNameDictionary.TryGetValue(modFpkEntry.FpkFile, out unHashedName))
                        {
                            modFpkEntry.FpkFile = unHashedName;
                        }
                    }
                }

                new SettingsManager("_extr\\buildInfo.xml").AddMod(metaData);
                mod.modInfo = metaData;
            }
        }
        internal void updateQarFileNames() // snakebite supports automatically updating filenames before they're installed, but will need to update old game settings from the prior version. 1-time-check per SB update
        {
            Settings settings = new Settings();

            settings.LoadFrom(xmlFilePath);
            HashingExtended.ReadDictionary();
            List <string> noUpdateQars = new List <string>();
            Dictionary <string, string> newNameDictionary = new Dictionary <string, string>();

            int foundUpdate = 0;

            foreach (ModQarEntry QarEntry in settings.GameData.GameQarEntries)
            {
                if (QarEntry.FilePath.StartsWith("/Assets/"))
                {
                    noUpdateQars.Add(QarEntry.FilePath);  continue;
                }
                string unhashedName = HashingExtended.UpdateName(QarEntry.FilePath);
                if (unhashedName != null)
                {
                    newNameDictionary.Add(QarEntry.FilePath, unhashedName);
                    foundUpdate++;

                    QarEntry.FilePath = unhashedName;
                }
                else
                {
                    noUpdateQars.Add(QarEntry.FilePath);
                }
            }
            if (foundUpdate > 0)
            {
                foreach (ModFpkEntry modFpkEntry in settings.GameData.GameFpkEntries.Where(entry => !noUpdateQars.Contains(entry.FpkFile)))
                {
                    string unHashedName;
                    if (newNameDictionary.TryGetValue(modFpkEntry.FpkFile, out unHashedName))
                    {
                        modFpkEntry.FpkFile = unHashedName;
                    }
                }
            }
            foreach (ModEntry mod in settings.ModEntries)
            {
                noUpdateQars.Clear();
                foreach (ModQarEntry modQar in mod.ModQarEntries)
                {
                    if (modQar.FilePath.StartsWith("/Assets/"))
                    {
                        noUpdateQars.Add(modQar.FilePath); continue;
                    }
                    string unHashedName;
                    if (newNameDictionary.TryGetValue(modQar.FilePath, out unHashedName))
                    {
                        modQar.FilePath = unHashedName;
                    }
                    else
                    {
                        unHashedName = HashingExtended.UpdateName(modQar.FilePath);
                        if (unHashedName != null)
                        {
                            newNameDictionary.Add(modQar.FilePath, unHashedName);
                            modQar.FilePath = unHashedName;
                            foundUpdate++;
                        }
                        else
                        {
                            noUpdateQars.Add(modQar.FilePath);
                        }
                    }
                }
                if (foundUpdate > 0)
                {
                    foreach (ModFpkEntry modFpkEntry in mod.ModFpkEntries.Where(entry => !noUpdateQars.Contains(entry.FpkFile)))
                    {
                        string unHashedName;
                        if (newNameDictionary.TryGetValue(modFpkEntry.FpkFile, out unHashedName))
                        {
                            modFpkEntry.FpkFile = unHashedName;
                        }
                    }
                }
            }
            settings.SaveTo(xmlFilePath);
        }
Example #3
0
        public static void BuildArchive(string SourceDir, ModEntry metaData, string outputFilePath)
        {
            Debug.LogLine($"[BuildArchive] {SourceDir}.");
            HashingExtended.ReadDictionary();
            string buildDir = Directory.GetCurrentDirectory() + "\\_build";

            try
            {
                if (Directory.Exists(buildDir))
                {
                    Directory.Delete(buildDir, true);
                }
            }
            catch
            {
                Debug.LogLine(string.Format("[BuildArchive] preexisting _build directory could not be deleted: {0}", buildDir));
            }

            Directory.CreateDirectory("_build");

            List <string> fpkFiles = Directory.GetFiles(SourceDir, "*.fpk*", SearchOption.AllDirectories).ToList();

            for (int i = fpkFiles.Count - 1; i >= 0; i--)
            {
                string fpkFile = fpkFiles[i].Substring(SourceDir.Length + 1);
                if (!fpkFile.StartsWith("Assets"))
                {
                    string updatedFileName = HashingExtended.UpdateName(fpkFile);
                    if (updatedFileName != null)
                    {
                        updatedFileName = SourceDir + updatedFileName.Replace('/', '\\');
                        if (fpkFiles.Contains(updatedFileName))
                        {
                            fpkFiles.Remove(fpkFiles[i]);
                        }
                    }
                }
            }

            List <string> fpkFolders = ListFpkFolders(SourceDir);

            for (int i = fpkFolders.Count - 1; i >= 0; i--)
            {
                string fpkFolder = fpkFolders[i].Substring(SourceDir.Length + 1);
                if (!fpkFolder.StartsWith("Assets"))
                {
                    string updatedFileName = HashingExtended.UpdateName(fpkFolder.Replace("_fpk", ".fpk"));
                    if (updatedFileName != null)
                    {
                        updatedFileName = SourceDir + updatedFileName.Replace('/', '\\');
                        if (fpkFolders.Contains(updatedFileName.Replace(".fpk", "_fpk")) || fpkFiles.Contains(updatedFileName))
                        {
                            MessageBox.Show(string.Format("{0} was not packed or added to the build, because {1} (the unhashed filename of {0}) already exists in the mod directory.", Path.GetFileName(fpkFolders[i]), Path.GetFileName(updatedFileName)));
                            fpkFolders.Remove(fpkFolders[i]);
                        }
                    }
                }
            }

            // check for FPKs that must be built and build
            metaData.ModFpkEntries = new List <ModFpkEntry>();
            List <string> builtFpks = new List <string>();

            foreach (string FpkFullDir in fpkFolders)
            {
                foreach (ModFpkEntry fpkEntry in BuildFpk(FpkFullDir, SourceDir))
                {
                    metaData.ModFpkEntries.Add(fpkEntry);
                    if (!builtFpks.Contains(fpkEntry.FpkFile))
                    {
                        builtFpks.Add(fpkEntry.FpkFile);
                    }
                }
            }

            // check for other FPKs and build fpkentry data
            foreach (string SourceFile in Directory.GetFiles(SourceDir, "*.fpk*", SearchOption.AllDirectories))
            {
                //tex chunk0\Assets\tpp\pack\collectible\common\col_common_tpp_fpk\Assets\tpp\pack\resident\resident00.fpkl is the only fpkl, don't know what a fpkl is, but gzcore crashes on it.
                if (SourceFile.EndsWith(".fpkl") || SourceFile.EndsWith(".xml"))
                {
                    continue;
                }
                string FileName = Tools.ToQarPath(SourceFile.Substring(SourceDir.Length));
                if (!builtFpks.Contains(FileName))
                {
                    // unpack FPK and build FPK list
                    string fpkDir     = Tools.ToWinPath(FileName.Replace(".fpk", "_fpk"));
                    string fpkFullDir = Path.Combine(SourceDir, fpkDir);
                    if (!Directory.Exists(fpkFullDir))
                    {
                        GzsLib.ExtractArchive <FpkFile>(SourceFile, fpkFullDir);
                    }

                    var fpkContents = GzsLib.ListArchiveContents <FpkFile>(SourceFile);
                    foreach (string file in fpkContents)
                    {
                        if (!GzsLib.IsExtensionValidForArchive(file, fpkDir))
                        {
                            Debug.LogLine($"[BuildArchive] {file} is not a valid file for a {Path.GetExtension(fpkDir)} archive.");
                            continue;
                        }

                        metaData.ModFpkEntries.Add(new ModFpkEntry()
                        {
                            FilePath    = file,
                            FpkFile     = FileName,
                            ContentHash = Tools.GetMd5Hash(Path.Combine(SourceDir, fpkDir, Tools.ToWinPath(file)))
                        });
                    }
                }
            }

            // build QAR entries
            List <string> qarFiles = ListQarFiles(SourceDir);

            for (int i = qarFiles.Count - 1; i >= 0; i--)
            {
                string qarFile = qarFiles[i].Substring(SourceDir.Length + 1);
                if (!qarFile.StartsWith("Assets"))
                {
                    string updatedQarName = HashingExtended.UpdateName(qarFile);
                    if (updatedQarName != null)
                    {
                        updatedQarName = SourceDir + updatedQarName.Replace('/', '\\');
                        if (qarFiles.Contains(updatedQarName))
                        {
                            MessageBox.Show(string.Format("{0} was not added to the build, because {1} (the unhashed filename of {0}) already exists in the mod directory.", Path.GetFileName(qarFiles[i]), Path.GetFileName(updatedQarName)));
                            qarFiles.Remove(qarFiles[i]);
                        }
                    }
                }
            }

            metaData.ModQarEntries = new List <ModQarEntry>();
            foreach (string qarFile in qarFiles)
            {
                string subDir      = qarFile.Substring(0, qarFile.LastIndexOf("\\")).Substring(SourceDir.Length).TrimStart('\\'); // the subdirectory for XML output
                string qarFilePath = Tools.ToQarPath(qarFile.Substring(SourceDir.Length));

                if (!Directory.Exists(Path.Combine("_build", subDir)))
                {
                    Directory.CreateDirectory(Path.Combine("_build", subDir));                                                    // create file structure
                }
                File.Copy(qarFile, Path.Combine("_build", Tools.ToWinPath(qarFilePath)), true);

                ulong hash = Tools.NameToHash(qarFilePath);
                metaData.ModQarEntries.Add(new ModQarEntry()
                {
                    FilePath    = qarFilePath,
                    Compressed  = qarFile.EndsWith(".fpk") || qarFile.EndsWith(".fpkd") ? true : false,
                    ContentHash = Tools.GetMd5Hash(qarFile), Hash = hash
                });
            }

            //tex build external entries
            metaData.ModFileEntries = new List <ModFileEntry>();
            var externalFiles = ListExternalFiles(SourceDir);

            foreach (string externalFile in externalFiles)
            {
                string subDir           = externalFile.Substring(0, externalFile.LastIndexOf("\\")).Substring(SourceDir.Length).TrimStart('\\'); // the subdirectory for XML output
                string externalFilePath = Tools.ToQarPath(externalFile.Substring(SourceDir.Length));

                if (!Directory.Exists(Path.Combine("_build", subDir)))
                {
                    Directory.CreateDirectory(Path.Combine("_build", subDir));                                                    // create file structure
                }
                File.Copy(externalFile, Path.Combine("_build", Tools.ToWinPath(externalFilePath)), true);
                string strip = "/" + ExternalDirName;
                if (externalFilePath.StartsWith(strip))
                {
                    externalFilePath = externalFilePath.Substring(strip.Length);
                }
                //ulong hash = Tools.NameToHash(qarFilePath);
                metaData.ModFileEntries.Add(new ModFileEntry()
                {
                    FilePath = externalFilePath, ContentHash = Tools.GetMd5Hash(externalFile)
                });
            }

            metaData.SBVersion.Version = Application.ProductVersion;

            metaData.SaveToFile("_build\\metadata.xml");

            // build archive
            FastZip zipper = new FastZip();

            zipper.CreateZip(outputFilePath, "_build", true, "(.*?)");

            try
            {
                Directory.Delete("_build", true);
            }
            catch (Exception e)
            {
                Debug.LogLine(string.Format("[BuildArchive] _build directory could not be deleted: {0}", e.ToString()));
            }
        }