//private Dictionary<string, Assembly> asm_find_cache = new Dictionary<string, Assembly>(); //public Assembly FindAsm(string name) //{ // try // { // if (!asm_find_cache.Keys.Contains(name)) // { // asm_find_cache.Add(name, Assembly.Load(name)); // } // return asm_find_cache[name]; // } // catch // { // asm_find_cache.Add(name, null); // return null; // } //} public SrvProvider() { AsmMap = new AsmContainer(this); TypeMap = new TypeContainer(); ModelMap = new ModelContainer(this); AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(GetAssembly); }
public bool Init(CacheFile target, int selectedIndex, string replacementFilePath) { //Todo: Make some reuseable helper functions to shorten this up. Ex: //Todo: - Copy file, parent, asm, and cpu/gpu sister file between caches //Todo: - Repack parent with edited file //Todo: - Update asm file with new values PegEntry selectedEntry = target.PegData.Entries[selectedIndex]; PegName = target.PegData.cpuFileName; SubTextureName = selectedEntry.Name; //Set TrackedByAsm and find asm name CacheFile asmFile = null; AsmContainer targetContainer = null; AsmPrimitive targetPrimitive = null; if (target.Parent.PackfileData.ContainsAsmFiles) { TrackedByAsm = true; foreach (var asm in target.Parent.PackfileData.AsmFiles) { foreach (var container in asm.Containers) { foreach (var primitive in container.Primitives) { if (primitive.Name != target.Filename) { continue; } AsmName = primitive.Name; targetContainer = container; targetPrimitive = primitive; } } } if (AsmName == null || targetContainer == null || targetPrimitive == null) { return(false); } } //Copy edited files to project cache if (!ProjectManager.CopyFileToProjectCache(target.PegData.cpuFileName, target.Parent, out CacheFile cpuFile)) { return(false); } if (!ProjectManager.CopyFileToProjectCache(target.PegData.gpuFileName, target.Parent, out CacheFile gpuFile)) { return(false); } if (TrackedByAsm && !ProjectManager.CopyFileToProjectCache(AsmName, target.Parent, out asmFile) || asmFile == null) { return(false); } //Update entry data selectedEntry = cpuFile.PegData.Entries[selectedIndex]; selectedEntry.Bitmap = new Bitmap(replacementFilePath); selectedEntry.Edited = true; selectedEntry.RawData = Utility.Helpers.ImageHelpers.ConvertBitmapToByteArray(selectedEntry.Bitmap); selectedEntry.width = (ushort)selectedEntry.Bitmap.Width; selectedEntry.height = (ushort)selectedEntry.Bitmap.Height; selectedEntry.source_height = (ushort)selectedEntry.Bitmap.Height; //source_width sometimes equals width and sometimes equals 36352. This is a quick hack for now until that behavior is understood. //Not properly setting this causes the game to improperly scale the texture selectedEntry.source_width = selectedEntry.source_width == selectedEntry.width ? (ushort)selectedEntry.Bitmap.Width : (ushort)36352; cpuFile.PegData.Write(cpuFile.FilePath, gpuFile.FilePath); //Update asm data if applicable if (TrackedByAsm) { var cpuFileInfo = new FileInfo(cpuFile.FilePath); var gpuFileInfo = new FileInfo(gpuFile.FilePath); int sizeDifference = (int)cpuFileInfo.Length - (int)targetPrimitive.HeaderSize; sizeDifference += (int)gpuFileInfo.Length - (int)targetPrimitive.DataSize; targetPrimitive.HeaderSize = (uint)cpuFileInfo.Length; targetPrimitive.DataSize = (uint)gpuFileInfo.Length; //Todo: Finish packfile writing code //Todo: Pack str2 and update CompressedSize var parentPackfile = cpuFile.Parent.PackfileData; parentPackfile.WriteToBinary(Path.GetDirectoryName(asmFile.FilePath), asmFile.Parent.FilePath, true, true, true); if (!cpuFile.Parent.PackfileData.TryGetSubfileEntry(cpuFile.Filename, out var cpuFileEntry)) { return(false); } if (!cpuFile.Parent.PackfileData.TryGetSubfileEntry(gpuFile.Filename, out var gpuFileEntry)) { return(false); } targetContainer.CompressedSize = parentPackfile.Header.CompressedDataSize; targetContainer.DataOffset = parentPackfile.DataStartOffset; targetPrimitive.HeaderSize = cpuFileEntry.DataSize; targetPrimitive.DataSize = gpuFileEntry.DataSize; //Todo: Update primitive sizes //Todo: Update DataOffset //Todo: Make sure to update other primitives in the same str2 if their offsets/values have changed asmFile.AsmData.WriteToBinary(); } //Todo: Generate modinfo.xml data for this UpdateDescription(); return(true); }
public void FromZip(byte[] buff) { using (ZipArchive zip = new ZipArchive(new MemoryStream(buff))) { ZipArchiveEntry iConfig = zip.GetEntry("config.json"); if (iConfig != null) { using (Stream s = iConfig.Open()) using (StreamReader sr = new StreamReader(s, Encoding.UTF8)) { Config = new Configuration(); Config.FromJson(sr.ReadToEnd()); } } AsmMap = new AsmContainer(this); for (int i = 0; i < Config.AssemblyCount; i++) { ZipArchiveEntry it = zip.GetEntry("assemblies/" + i.ToString() + ".dll"); if (it != null) { using (Stream s = it.Open()) { byte[] buffer = new byte[it.Length]; s.Read(buffer, 0, buffer.Length); AsmObj add = new AsmObj(); add.load(buffer); AsmMap.Add(add); } } } TypeMap = new TypeContainer(); foreach (AsmObj it in AsmMap) { TypeMap.Merge(it); } ModelMap = new ModelContainer(this); for (int i = 0; i < Config.ModelCount; i++) { ZipArchiveEntry it = zip.GetEntry("models/" + i.ToString() + ".json"); if (it != null) { using (Stream s = it.Open()) using (StreamReader sr = new StreamReader(s, Encoding.UTF8)) { ModelObj add = new ModelObj(this); add.FromJson(sr.ReadToEnd()); ModelMap.Add(add); } } } } //ZipArchiveEntry iModels = zip.GetEntry("models"); //if (iModels != null) //{ // using (MemoryStream ms = iModels.Open() as MemoryStream) // { // ModelMap = new ModelContainer(this); // ModelMap.FromZip(ms.ToArray()); // } //} //ZipArchiveEntry iAssemblies = zip.GetEntry("assemblies"); //if (iAssemblies != null) //{ // using (MemoryStream ms = iAssemblies.Open() as MemoryStream) // { // AsmMap = new AsmContainer(this); // AsmMap.FromZip(ms.ToArray()); // } //} }