private InstallationStatus WriteToFile(ModAction <WriteToFileAction> modAction) { foreach (var content in modAction.action.Content) { var physicalTargetPath = ResolvePath(modAction.action.TargetFile, modAction.mod, configuration); string filePath = null; if (!File.Exists(physicalTargetPath)) { throw new Exception($"Unable to find target path: {physicalTargetPath}"); } if (!string.IsNullOrEmpty(content.DataFilePath)) { filePath = ResolvePath(content.DataFilePath, modAction.mod, configuration); } var dataToWrite = content.Text ?? File.ReadAllText(filePath); if (ModCollisionTracker.HasEditCollision(modAction.mod, physicalTargetPath, content, fileWriter, modifications, out var collision)) { return(HandleCollision(collision)); } if (IsReservedFile(physicalTargetPath)) { modifications.Add(new EditFileModification(physicalTargetPath, true, modAction.mod.Config.ModID)); BackupFile(physicalTargetPath); } else { modifications.Add(new EditFileModification(physicalTargetPath, false, modAction.mod.Config.ModID)); } if (content.EndOffset.HasValue) { fileWriter.WriteToFileRange(physicalTargetPath, dataToWrite, content.StartOffset, content.EndOffset.Value, false); } else { fileWriter.WriteToFile(physicalTargetPath, dataToWrite, content.StartOffset, !content.Replace, false); } } return(InstallationStatus.Success); }
public static async Task ApplyChanges(Configuration configuration, CharacterModification[] data) { var tempFolder = FileWriterUtility.CreateTempFolder(); // Start with a blank canvas RemoveAllChanges(configuration); if (data.Length == 0) { return; } try { await ExtractFiles(configuration, tempFolder); var json = GenerateCharacterJson(data); var virtualreaderFile = Path.Combine(tempFolder, "presentation", "virtualreaderpc_data.lua"); var virtualreaderDecompiledFile = Path.Combine(tempFolder, "virtualreaderpc_data_decomp.lua"); var igpLocksFile = Path.Combine(tempFolder, "igp", "locks__lua.chd"); await UnluacUtility.Decompile(virtualreaderFile, virtualreaderDecompiledFile); // Write any data as required to the virtualreader file, make sure to offset by bytesWritten if needed int bytesWritten = 0; FileWriterUtility.WriteToFile(virtualreaderDecompiledFile, json, 0x0000A5C6, true, out bytesWritten); foreach (var character in data.Where(c => !string.IsNullOrEmpty(c.ReplacementCharacter))) { var offset = FindReplacementOffset(igpLocksFile, character.ReplacementCharacter); FileWriterUtility.WriteToFile(igpLocksFile, character.Config.PresentationData.Name, offset, false, out bytesWritten); } } catch (Exception ex) { Directory.Delete(tempFolder, true); return; } CopyFiles(configuration, tempFolder); Directory.Delete(tempFolder, true); }