private ModInstallCompletedStatus InstallAttachedRCWMod() { CLog.Information(@"Installing attached RCW mod. Checking Coalesced.ini first to make sure this mod can be safely applied", Settings.LogModInstallation); ME2Coalesced me2c = new ME2Coalesced(ME2Directory.CoalescedPath(gameTarget)); RCWMod rcw = ModBeingInstalled.GetJob(ModJob.JobHeader.ME2_RCWMOD).RCW; foreach (var rcwF in rcw.Files) { var me2cF = me2c.Inis.FirstOrDefault(x => x.Key == rcwF.FileName); if (me2cF.Key == null) { Log.Error(@"RCW mod specifies a file in coalesced that does not exist in the local one: " + rcwF); return(ModInstallCompletedStatus.INSTALL_FAILED_MALFORMED_RCW_FILE); } foreach (var rcwS in rcwF.Sections) { var section = me2cF.Value.Sections.FirstOrDefault(x => x.Header == rcwS.SectionName); if (section == null) { Log.Error($@"RCW mod specifies a section in {rcwF.FileName} that does not exist in the local coalesced: {rcwS.SectionName}"); return(ModInstallCompletedStatus.INSTALL_FAILED_MALFORMED_RCW_FILE); } } //Apply mod foreach (var rcwS in rcwF.Sections) { var section = me2cF.Value.Sections.FirstOrDefault(x => x.Header == rcwS.SectionName); Dictionary <string, int> keyCount = new Dictionary <string, int>(); foreach (var key in section.Entries) { if (keyCount.TryGetValue(key.Key, out var existingCount)) { keyCount[key.Key] = existingCount + 1; } else { keyCount[key.Key] = 1; } } Dictionary <string, bool> keysSupportingMulti = keyCount.ToDictionary(x => x.Key, x => x.Value > 1); //Remove items foreach (var itemToDelete in rcwS.KeysToDelete) { for (int i = section.Entries.Count - 1; i > 0; i--) { var entry = section.Entries[i]; if (entry.Key == itemToDelete.Key && entry.Value == itemToDelete.Value) { CLog.Information($@"Removing ini entry {entry.RawText} in section {section.Header} of file {me2cF.Key}", Settings.LogModInstallation); section.Entries.RemoveAt(i); } } } foreach (var itemToAdd in rcwS.KeysToAdd) { var existingEntries = section.Entries.Where(x => x.Key == itemToAdd.Key).ToList(); if (existingEntries.Count <= 0) { //just add it CLog.Information($@"Adding ini entry {itemToAdd.RawText} in section {section.Header} of file {me2cF.Key}", Settings.LogModInstallation); section.Entries.Add(itemToAdd); } else if (existingEntries.Count > 1) { //Supports multi. Add this key - but making sure the data doesn't already exist! if (existingEntries.Any(x => x.Value == itemToAdd.Value)) { //Duplicate. CLog.Information($@"Not adding duplicate ini entry {itemToAdd.RawText} in section {section.Header} of file {me2cF.Key}", Settings.LogModInstallation); } else { //Not duplicate - installing key CLog.Information($@"Adding ini entry {itemToAdd.RawText} in section {section.Header} of file {me2cF.Key}", Settings.LogModInstallation); section.Entries.Add(itemToAdd); } } else { //Only one key exists currently. We need to check multi lookup to choose how to install if (keysSupportingMulti[itemToAdd.Key]) { //Supports multi. Add this key - but making sure the data doesn't already exist! if (existingEntries.Any(x => x.Value == itemToAdd.Value)) { //Duplicate. CLog.Information($@"Not adding duplicate ini entry {itemToAdd.RawText} in section {section.Header} of file {me2cF.Key}", Settings.LogModInstallation); } else { //Not duplicate - installing key CLog.Information($@"Adding ini entry {itemToAdd.RawText} in section {section.Header} of file {me2cF.Key}", Settings.LogModInstallation); section.Entries.Add(itemToAdd); } } else { //Replace existing key existingEntries[0].Value = itemToAdd.Value; } } } } } me2c.Serialize(); return(ModInstallCompletedStatus.INSTALL_SUCCESSFUL); }