public AlternateFile(string alternateFileText, ModJob associatedJob, Mod modForValidating) { var properties = StringStructParser.GetCommaSplitValues(alternateFileText); if (properties.TryGetValue(@"FriendlyName", out string friendlyName)) { FriendlyName = friendlyName; } if (modForValidating.ModDescTargetVersion >= 6 && string.IsNullOrWhiteSpace(FriendlyName)) { //Cannot be null. Log.Error(@"Alternate File does not specify FriendlyName. Mods targeting moddesc >= 6.0 cannot have empty FriendlyName"); ValidAlternate = false; LoadFailedReason = M3L.GetString(M3L.string_validation_altfile_oneAltDlcMissingFriendlyNameCmm6); return; } if (!Enum.TryParse(properties[@"Condition"], out Condition)) { Log.Error($@"Alternate File specifies unknown/unsupported condition: {properties[@"Condition"]}"); //do not localize ValidAlternate = false; LoadFailedReason = $@"{M3L.GetString(M3L.string_validation_altfile_unknownCondition)} {properties[@"Condition"]}"; return; } if (properties.TryGetValue(@"ConditionalDLC", out string conditionalDlc)) { var conditionalList = StringStructParser.GetSemicolonSplitList(conditionalDlc); foreach (var dlc in conditionalList) { //if (modForValidating.Game == Mod.MEGame.ME3) //{ if (Enum.TryParse(dlc, out ModJob.JobHeader header) && ModJob.GetHeadersToDLCNamesMap(modForValidating.Game).TryGetValue(header, out var foldername)) { ConditionalDLC.Add(foldername); continue; } //} if (!dlc.StartsWith(@"DLC_")) { Log.Error(@"An item in Alternate Files's ConditionalDLC doesn't start with DLC_"); LoadFailedReason = M3L.GetString(M3L.string_validation_altfile_conditionalDLCInvalidValue, FriendlyName); return; } else { ConditionalDLC.Add(dlc); } } } if (!Enum.TryParse(properties[@"ModOperation"], out Operation)) { Log.Error(@"Alternate File specifies unknown/unsupported operation: " + properties[@"ModOperation"]); ValidAlternate = false; LoadFailedReason = $@"{M3L.GetString(M3L.string_validation_altfile_unknownOperation)} { properties[@"ModOperation"]}"; return; } if (properties.TryGetValue(@"Description", out string description)) { Description = description; } if (modForValidating.ModDescTargetVersion >= 6 && string.IsNullOrWhiteSpace(Description)) { //Cannot be null. Log.Error($@"Alternate File {FriendlyName} with mod targeting moddesc >= 6.0 cannot have empty Description or missing description"); ValidAlternate = false; LoadFailedReason = M3L.GetString(M3L.string_interp_validation_altfile_cmmver6RequiresDescription, FriendlyName); return; } if (Operation != AltFileOperation.OP_NOTHING) { if (properties.TryGetValue(@"ModFile", out string modfile)) { ModFile = modfile.TrimStart('\\', '/').Replace('/', '\\'); } else { Log.Error($@"Alternate file in-mod target (ModFile) required but not specified. This value is required for all Alternate files. Friendlyname: {FriendlyName}"); ValidAlternate = false; LoadFailedReason = M3L.GetString(M3L.string_interp_validation_altfile_noModFileDeclared, FriendlyName); return; } if (associatedJob.Header == ModJob.JobHeader.CUSTOMDLC) { var modFilePath = FilesystemInterposer.PathCombine(modForValidating.IsInArchive, modForValidating.ModPath, ModFile); var pathSplit = ModFile.Split('\\'); if (pathSplit.Length > 0) { var dlcName = pathSplit[0]; var jobKey = associatedJob.CustomDLCFolderMapping.FirstOrDefault(x => x.Value.Equals(dlcName, StringComparison.InvariantCultureIgnoreCase)); if (jobKey.Key != null) { //if (associatedJob.CustomDLCFolderMapping.TryGetValue(ModFile, out var sourceFile)) //{ //} } else { Log.Error($@"Alternate file {FriendlyName} in-mod target (ModFile) does not appear to target a DLC target this mod will (always) install: {ModFile}"); ValidAlternate = false; LoadFailedReason = "Dummy placeholder"; //LoadFailedReason = M3L.GetString(M3L.string_interp_validation_altfile_couldNotFindModFile, FriendlyName, ModFile); return; } } } else { if (!associatedJob.FilesToInstall.TryGetValue(ModFile, out var sourceFile)) { Log.Error($@"Alternate file {FriendlyName} in-mod target (ModFile) specified but does not exist in job: {ModFile}"); ValidAlternate = false; LoadFailedReason = M3L.GetString(M3L.string_interp_validation_altfile_couldNotFindModFile, FriendlyName, ModFile); return; } } //todo: implement multimap if (properties.TryGetValue(@"MultiMappingFile", out string multifilemapping)) { MultiMappingFile = multifilemapping.TrimStart('\\', '/'); } if (properties.TryGetValue(@"AltFile", out string altfile)) { AltFile = altfile; } else if (AltFile == null && properties.TryGetValue(@"ModAltFile", out string maltfile)) { AltFile = maltfile; } properties.TryGetValue(@"SubstituteFile", out SubstituteFile); //Only used in 4.5. In 5.0 and above this became AltFile. //workaround for 4.5 if (modForValidating.ModDescTargetVersion == 4.5 && Operation == AltFileOperation.OP_SUBSTITUTE && SubstituteFile != null) { AltFile = SubstituteFile; } if (!string.IsNullOrEmpty(AltFile)) { AltFile = AltFile.Replace('/', '\\'); //Standardize paths } //This needs reworked from java's hack implementation //Need to identify mods using substitution features if (Operation == AltFileOperation.OP_INSTALL || Operation == AltFileOperation.OP_SUBSTITUTE) { if (MultiMappingFile == null) { //Validate file var altPath = FilesystemInterposer.PathCombine(modForValidating.IsInArchive, modForValidating.ModPath, AltFile); var altFileSourceExists = FilesystemInterposer.FileExists(altPath, modForValidating.Archive); if (!altFileSourceExists) { Log.Error(@"Alternate file source (AltFile) does not exist: " + AltFile); ValidAlternate = false; LoadFailedReason = M3L.GetString(M3L.string_interp_validation_altfile_specifiedAltFileDoesntExist, Operation.ToString(), AltFile); return; } //Ensure it is not part of DLC directory itself. var modFile = FilesystemInterposer.PathCombine(modForValidating.IsInArchive, modForValidating.ModPath, ModFile); //Todo } else { //Multimapping, Todo } } } ApplicableAutoText = properties.TryGetValue(@"ApplicableAutoText", out string applicableText) ? applicableText : M3L.GetString(M3L.string_autoApplied); NotApplicableAutoText = properties.TryGetValue(@"NotApplicableAutoText", out string notApplicableText) ? notApplicableText : M3L.GetString(M3L.string_notApplicable); if (modForValidating.ModDescTargetVersion >= 6.0) { GroupName = properties.TryGetValue(@"OptionGroup", out string groupName) ? groupName : null; } if (Condition == AltFileCondition.COND_MANUAL && properties.TryGetValue(@"CheckedByDefault", out string checkedByDefault) && bool.TryParse(checkedByDefault, out bool cbd)) { CheckedByDefault = cbd; } CLog.Information($@"Alternate file loaded and validated: {FriendlyName}", Settings.LogModStartup); ValidAlternate = true; }
public AlternateFile(string alternateFileText, Mod modForValidating) { var properties = StringStructParser.GetCommaSplitValues(alternateFileText); if (properties.TryGetValue("FriendlyName", out string friendlyName)) { FriendlyName = friendlyName; } if (modForValidating.ModDescTargetVersion >= 6 && string.IsNullOrWhiteSpace(FriendlyName)) { //Cannot be null. Log.Error($"Alternate File does not specify FriendlyName. Mods targeting moddesc >= 6.0 cannot have empty FriendlyName"); ValidAlternate = false; LoadFailedReason = $"At least one specified Alternate File does not specify a FriendlyName, which is required for mods targeting cmmver >= 6.0."; return; } if (!Enum.TryParse(properties["Condition"], out Condition)) { Log.Error("Alternate File specifies unknown/unsupported condition: " + properties["Condition"]); ValidAlternate = false; LoadFailedReason = "Alternate File specifies unknown/unsupported condition: " + properties["Condition"]; return; } if (properties.TryGetValue("ConditionalDLC", out string conditionalDlc)) { var conditionalList = StringStructParser.GetSemicolonSplitList(conditionalDlc); foreach (var dlc in conditionalList) { //if (modForValidating.Game == Mod.MEGame.ME3) //{ if (Enum.TryParse(dlc, out ModJob.JobHeader header) && ModJob.GetHeadersToDLCNamesMap(modForValidating.Game).TryGetValue(header, out var foldername)) { ConditionalDLC.Add(foldername); continue; } //} if (!dlc.StartsWith("DLC_")) { Log.Error("An item in Alternate Files's ConditionalDLC doesn't start with DLC_"); LoadFailedReason = $"Alternate File ({FriendlyName}) specifies conditional DLC but no values match the allowed headers or start with DLC_."; return; } else { ConditionalDLC.Add(dlc); } } } if (!Enum.TryParse(properties["ModOperation"], out Operation)) { Log.Error("Alternate File specifies unknown/unsupported operation: " + properties["ModOperation"]); ValidAlternate = false; LoadFailedReason = "Alternate File specifies unknown/unsupported operation: " + properties["ModOperation"]; return; } if (properties.TryGetValue("Description", out string description)) { Description = description; } if (modForValidating.ModDescTargetVersion >= 6 && string.IsNullOrWhiteSpace(Description)) { //Cannot be null. Log.Error($"Alternate File {FriendlyName} with mod targeting moddesc >= 6.0 cannot have empty Description or missing description"); ValidAlternate = false; LoadFailedReason = $"Alternate File {FriendlyName} does not specify a Description, which is required for mods targeting cmmver >= 6.0."; return; } if (properties.TryGetValue("ModFile", out string modfile)) { ModFile = modfile.TrimStart('\\', '/'); } else { Log.Error("Alternate file in-mod target (ModFile) required but not specified. This value is required for all Alternate files"); ValidAlternate = false; LoadFailedReason = $"Alternate file {FriendlyName} does not declare ModFile but it is required for all Alternate Files."; return; } if (properties.TryGetValue("MultiMappingFile", out string multifilemapping)) { MultiMappingFile = multifilemapping.TrimStart('\\', '/'); } if (properties.TryGetValue("AltFile", out string altfile)) { AltFile = altfile; } else if (AltFile == null && properties.TryGetValue("ModAltFile", out string maltfile)) { AltFile = maltfile; } properties.TryGetValue("SubstituteFile", out SubstituteFile); //Only used in 4.5. In 5.0 and above this became AltFile. //workaround for 4.5 if (modForValidating.ModDescTargetVersion == 4.5 && Operation == AltFileOperation.OP_SUBSTITUTE && SubstituteFile != null) { AltFile = SubstituteFile; } if (!string.IsNullOrEmpty(AltFile)) { AltFile = AltFile.Replace('/', '\\'); //Standardize paths } //This needs reworked from java's hack implementation //Need to identify mods using substitution features if (Operation == AltFileOperation.OP_INSTALL || Operation == AltFileOperation.OP_SUBSTITUTE) { if (MultiMappingFile == null) { //Validate file var altPath = FilesystemInterposer.PathCombine(modForValidating.IsInArchive, modForValidating.ModPath, AltFile); var altFileSourceExists = FilesystemInterposer.FileExists(altPath, modForValidating.Archive); if (!altFileSourceExists) { Log.Error("Alternate file source (AltFile) does not exist: " + AltFile); ValidAlternate = false; LoadFailedReason = $"Alternate file is specified with operation {Operation}, but required file doesn't exist: {AltFile}"; return; } //Ensure it is not part of DLC directory itself. var modFile = FilesystemInterposer.PathCombine(modForValidating.IsInArchive, modForValidating.ModPath, ModFile); //Todo } else { //Multimapping, Todo } } if (properties.TryGetValue("ApplicableAutoText", out string applicableText)) { ApplicableAutoText = applicableText; } else { ApplicableAutoText = "Auto Applied"; } if (properties.TryGetValue("NotApplicableAutoText", out string notApplicableText)) { NotApplicableAutoText = notApplicableText; } else { NotApplicableAutoText = "Not applicable"; } if (Condition == AltFileCondition.COND_MANUAL && properties.TryGetValue("CheckedByDefault", out string checkedByDefault) && bool.TryParse(checkedByDefault, out bool cbd)) { CheckedByDefault = cbd; } CLog.Information($"Alternate file loaded and validated: {FriendlyName}", Settings.LogModStartup); ValidAlternate = true; }