/// <summary> /// Returns a cached package. Ensure this cache is synchronized if across threads or you may end up saving two different instances of files to the same location /// </summary> /// <param name="packageName"></param> /// <returns></returns> public override IMEPackage GetCachedPackage(string packageName, bool openIfNotInCache = true) { // May need way to set maximum size of dictionary so we don't hold onto too much memory. packageName = Path.GetFileName(packageName); // Ensure we only use filename if (Cache.TryGetValue(packageName, out var package)) { return(package); } if (openIfNotInCache) { var file = MERFileSystem.GetPackageFile(packageName, false); if (file != null && File.Exists(file)) { int i = 3; while (i > 0) { try { i--; package = MERFileSystem.OpenMEPackage(file); } catch (IOException e) { // This is a cheap hack around potential multithreading issues Log.Warning($@"I/O Exception opening {file}: {e.Message}. We have {i} attempts remaining to open this package"); Thread.Sleep(1000); } } if (package == null) { return(null); } Cache[packageName] = package; return(package); } } return(null); //Package could not be found }
public static bool RandomizeSquadmateFaces(RandomizationOption option) { var henchFiles = MERFileSystem.LoadedFiles.Where(x => x.Key.StartsWith("BioH_") || x.Key.StartsWith("BioP_ProCer") || x.Key.StartsWith("BioD_ProCer") || x.Key == "BioD_EndGm1_110ROMJacob.pcc"); foreach (var h in henchFiles) { var hPackage = MERFileSystem.OpenMEPackage(MERFileSystem.GetPackageFile(h.Key)); foreach (var smhp in SquadmateMorphHeadPaths) { var mf = hPackage.FindExport(smhp); if (mf != null) { RandomizeInternal(mf, henchFaceOption); } } MERFileSystem.SavePackage(hPackage); } return(true); }
public static bool PortPawnIntoPackage(PortablePawn pawn, IMEPackage targetPackage) { if (IsPawnAssetInPackageAlready(pawn, targetPackage)) { return(true); // Pawn asset to port in already ported in } IMEPackage pawnPackage = null; if (pawn.IsCorrectedPackage) { // DEBUG //if (pawn.PackageFilename == "BioPawn_Collector_Batarian.pcc") //{ // pawnPackage = MEPackageHandler.OpenMEPackage(@"C:\Users\mgame\source\repos\ME2Randomizer\ME2Randomizer\staticfiles\binary\correctedpawns\" + pawn.PackageFilename); //} //else //{ var correctedPawnData = MERUtilities.GetEmbeddedStaticFilesBinaryFile($"correctedpawns.{pawn.PackageFilename}"); pawnPackage = MEPackageHandler.OpenMEPackageFromStream(new MemoryStream(correctedPawnData)); //} } else { var pF = MERFileSystem.GetPackageFile(pawn.PackageFilename); if (pF != null) { pawnPackage = MERFileSystem.OpenMEPackage(pF); } else { Debug.WriteLine("Pawn package not found: {pawn.PackageFilename}"); } } if (pawnPackage != null) { PackageTools.PortExportIntoPackage(targetPackage, pawnPackage.FindExport(pawn.AssetToPortIn), useMemorySafeImport: !pawn.IsCorrectedPackage); // Ensure the assets are too as they may not be directly referenced except in the level instance foreach (var asset in pawn.AssetPaths) { if (targetPackage.FindExport(asset) == null) { PackageTools.PortExportIntoPackage(targetPackage, pawnPackage.FindExport(asset), useMemorySafeImport: !pawn.IsCorrectedPackage); } } if (pawn.TextureUpdates != null) { foreach (var tu in pawn.TextureUpdates) { var targetTextureExp = targetPackage.FindExport(tu.TextureInstancedFullPath); TFCBuilder.InstallTexture(tu, targetTextureExp); } } return(true); } return(false); }