public static List<ModFpkEntry> BuildFpk(string FpkFolder, string rootDir) { string FpkName = FpkFolder.Substring(FpkFolder.LastIndexOf("\\") + 1).Replace("_fpk", ".fpk"); string FpkBuildFolder = FpkFolder.Substring(0, FpkFolder.TrimEnd('\\').LastIndexOf("\\")); string FpkXmlFile = FpkBuildFolder + "\\" + FpkName + ".xml"; string FpkFile = FpkBuildFolder + "\\" + FpkName; string FpkType = FpkFolder.Substring(FpkFolder.LastIndexOf("_") + 1); FpkFile gzsFpk = new SnakeBite.GzsTool.FpkFile(); List<ModFpkEntry> fpkList = new List<ModFpkEntry>(); if (FpkType == "fpk") { gzsFpk.FpkType = "Fpk"; } else if (FpkType == "fpkd") { gzsFpk.FpkType = "Fpkd"; } gzsFpk.Name = FpkName; gzsFpk.FpkEntries = new List<FpkEntry>(); foreach (string FileName in Directory.GetFiles(FpkFolder, "*.*", SearchOption.AllDirectories)) { string xmlFileName = FileName.Substring(FpkFolder.Length).Replace("\\", "/"); gzsFpk.FpkEntries.Add(new FpkEntry() { FilePath = xmlFileName }); fpkList.Add(new ModFpkEntry() { FilePath = xmlFileName, FpkFile = Tools.ToQarPath(FpkFile.Substring(rootDir.Length)), ContentHash = Tools.HashFile(FileName) }); } gzsFpk.WriteToFile(FpkXmlFile); SnakeBite.GzsTool.GzsTool.Run(FpkXmlFile); File.Delete(FpkXmlFile); return fpkList; }
public static bool InstallMod(string ModFile) { if (!ModManager.ValidInstallPath) return false; // no valid install specified if (!File.Exists(GameArchivePath)) return false; // extract existing DAT file ExtractGameArchive(); // import existing DAT xml QarFile qarXml = new QarFile(); qarXml.LoadFromFile(GameArchiveXmlPath); // extract mod files to temp folder if (Directory.Exists("_temp")) Directory.Delete("_temp", true); FastZip unzipper = new FastZip(); unzipper.ExtractZip(ModFile, "_temp", "(.*?)"); // load mod metadata ModEntry modMetadata = new ModEntry(); modMetadata.ReadFromFile("_temp\\metadata.xml"); File.Delete("_temp\\metadata.xml"); // check for fpk merges List<ModFpkEntry> installedFpkFiles = new List<ModFpkEntry>(); foreach (QarEntry gzsQar in qarXml.QarEntries) { string qarExt = gzsQar.FilePath.Substring(gzsQar.FilePath.LastIndexOf(".") + 1).ToLower(); if (qarExt == "fpk" || qarExt == "fpkd") { // extract FPK and add files to list string fpkFile = GameArchiveDir + "\\" + gzsQar.FilePath; string fpkDir = fpkFile.Replace(".", "_"); GzsTool.GzsTool.Run(fpkFile); List<string> fpkFiles = Directory.GetFiles(fpkDir, "*.*", SearchOption.AllDirectories).ToList(); foreach (string file in fpkFiles) { string fpkFilePath = fpkFile.Substring(GameArchiveDir.Length); fpkFilePath = fpkFilePath.Replace("\\", "/"); string fpkPath = file.Substring(file.LastIndexOf("Assets\\")); fpkPath = "/" + fpkPath.Replace("\\", "/"); installedFpkFiles.Add(new ModFpkEntry() { FilePath = fpkFilePath, FpkFile = fpkPath }); } } } // compare lists and build merge fpk list List<string> mergeFpks = new List<string>(); foreach (ModFpkEntry installedFpk in installedFpkFiles) { foreach (ModEntry mod in GetInstalledMods()) { if (mod.ModFpkEntries.Find(entry => entry.FpkFile == installedFpk.FpkFile) != null) // if the mod has an fpk that should be merged with an installed fpk { if (!mergeFpks.Contains(installedFpk.FpkFile)) { mergeFpks.Add(installedFpk.FpkFile); } } } } if (mergeFpks.Count > 0) { // merge fpks foreach (string fpkFile in mergeFpks) { string fpkPath = Tools.ToQarPath(fpkFile); string gameFpkPath = GameArchiveDir + fpkPath; string gameFpkDir = GameArchiveDir + "\\master\\0\\01\\" + fpkPath.Replace(".", "_"); string modFpkPath = "_temp\\" + fpkPath; string modFpkDir = "_temp\\" + fpkPath.Replace(".", "_"); GzsTool.GzsTool.Run(gameFpkPath); GzsTool.GzsTool.Run(modFpkPath); // load existing xml data FpkFile fpkXml = new FpkFile(); fpkXml.LoadFromFile(gameFpkPath + ".xml"); // generate list of files to move and add to xml List<string> filesToMove = new List<string>(); foreach (ModFpkEntry file in modMetadata.ModFpkEntries.FindAll(entry => entry.FpkFile == fpkFile)) { filesToMove.Add(file.FilePath.Replace("/", "\\")); if (fpkXml.FpkEntries.Count(entry => entry.FilePath == file.FilePath) == 0) { // insert new fpk entries as required fpkXml.FpkEntries.Add(new FpkEntry() { FilePath = fpkFile }); } } // create directories and move files foreach (string file in filesToMove) { string fileDir = (gameFpkDir + file).Substring(0, (gameFpkDir + file).LastIndexOf("\\")); if (!Directory.Exists(fileDir)) { Directory.CreateDirectory(fileDir); } File.Copy(modFpkDir + file, gameFpkDir + file, true); } fpkXml.WriteToFile(gameFpkPath + ".xml"); GzsTool.GzsTool.Run(gameFpkPath + ".xml"); } } // copy files for new DAT foreach (ModQarEntry modQarFile in modMetadata.ModQarEntries) { string fileName = "/" + modQarFile.FilePath.Replace("\\", "/"); string fileDir = (GameArchiveDir + modQarFile.FilePath.Replace("/", "\\")).Substring(0, (GameArchiveDir + modQarFile.FilePath).LastIndexOf("/")); // if file is not already in QAR, add it if (qarXml.QarEntries.Count(entry => entry.FilePath == modQarFile.FilePath) == 0) { qarXml.QarEntries.Add(new QarEntry() { FilePath = modQarFile.FilePath, Compressed = modQarFile.Compressed, Hash = modQarFile.Hash }); } // copy all files that weren't merged FPKS if (!mergeFpks.Contains(fileName)) { if (!Directory.Exists(fileDir)) { Directory.CreateDirectory(fileDir); } File.Copy("_temp\\" + modQarFile.FilePath.Replace("/", "\\"), ModManager.GameArchiveDir + modQarFile.FilePath.Replace("/", "\\"), true); } } // build XML for new DAT qarXml.WriteToFile(GameArchiveXmlPath); // build new DAT GzsTool.GzsTool.Run(GameArchiveXmlPath); // remove temp files Directory.Delete("_temp", true); Directory.Delete(GameArchiveDir, true); File.Delete(GameArchiveXmlPath); UpdateDatHash(); return true; }
internal static List<ModFpkEntry> BuildFpkList(string SearchDir) { // build list of all files in directory List<string> allFiles = Directory.GetFiles(SearchDir, "*.*", SearchOption.AllDirectories).ToList(); List<string> fpkFiles = new List<string>(); List<ModFpkEntry> BuildFpkList = new List<ModFpkEntry>(); // find fpk/fpkd files foreach (string file in allFiles) { string fileType = GetFileType(file); if (fileType == "fpk" || fileType == "fpkd") { fpkFiles.Add(file); } } // unpack each archive and add to file list foreach (string fpkFile in fpkFiles) { GzsTool.GzsTool.Run(fpkFile); // unpack fpk FpkFile gzsFpkXml = new FpkFile(); gzsFpkXml.LoadFromFile(fpkFile + ".xml"); string fpkFileName = fpkFile.Substring(GameArchiveDir.Length).Replace("\\", "/"); // name of fpk for fpk list foreach (FpkEntry fpkFileEntry in gzsFpkXml.FpkEntries) { BuildFpkList.Add(new ModFpkEntry() { FilePath = fpkFileEntry.FilePath, FpkFile = fpkFileName }); } } return BuildFpkList; }
public static bool UninstallMod(ModEntry mod) { // extract 01.dat if (!ModManager.ValidInstallPath) return false; // no valid install specified if (!File.Exists(GameArchivePath)) return false; ExtractGameArchive(); // load xml data QarFile datXml = new QarFile(); datXml.LoadFromFile(GameArchiveXmlPath); // check for fpks List<string> modFpks = new List<string>(); foreach (ModFpkEntry modFpkFile in mod.ModFpkEntries) { if (datXml.QarEntries.Count(entry => entry.FilePath == modFpkFile.FpkFile) > 0 && !modFpks.Contains(modFpkFile.FpkFile)) { modFpks.Add(modFpkFile.FpkFile); } } // do the fpks thing // unpack fpk foreach (string fpkFile in modFpks) { // check if fpk file exists in game data if (File.Exists(GameArchiveDir + fpkFile.Replace("/", "\\"))) { // extract fpk GzsTool.GzsTool.Run(GameArchiveDir + Tools.ToWinPath(fpkFile)); string fpkDir = GameArchiveDir + Tools.ToWinPath(fpkFile.Replace(".", "_")); FpkFile fpkXml = new FpkFile(); fpkXml.LoadFromFile(GameArchiveDir + fpkFile + ".xml"); // check if any files left in fpk List<FpkEntry> fpkFiles = fpkXml.FpkEntries.ToList(); foreach (FpkEntry fpkSubFile in fpkXml.FpkEntries) { fpkFiles.RemoveAll(entry => entry.FilePath == fpkSubFile.FilePath); } // if not, remove it if (fpkFiles.Count == 0) { // delete fpk from dat XML datXml.QarEntries.RemoveAll(entry => entry.FilePath == fpkFile); } } } // remove mod files from xml foreach (ModQarEntry modQEntry in mod.ModQarEntries) { // delete files, fpks that were de-merged will be ignored if (!modFpks.Contains(modQEntry.FilePath)) { datXml.QarEntries.RemoveAll(entry => entry.FilePath == modQEntry.FilePath); } } // rebuild 01.dat datXml.WriteToFile(GameArchiveXmlPath); GzsTool.GzsTool.Run(GameArchiveXmlPath); DeleteGameArchive(); UpdateDatHash(); return true; }