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;
        }
Esempio n. 2
0
        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;
        }