/// <summary> /// Evals the definition priority internal. /// </summary> /// <param name="definitions">The definitions.</param> /// <returns>IPriorityDefinitionResult.</returns> protected virtual IPriorityDefinitionResult EvalDefinitionPriorityInternal(IEnumerable <IDefinition> definitions) { var game = GameService.GetSelected(); var result = GetModelInstance <IPriorityDefinitionResult>(); if (game != null && definitions?.Count() > 1) { // Handle localizations differently var file = definitions.FirstOrDefault().File ?? string.Empty; if (file.StartsWith(Shared.Constants.LocalizationDirectory)) { IEnumerable <IDefinition> filtered = null; if (definitions.Any(p => p.FileCI.Contains(Shared.Constants.LocalizationReplaceDirectory, StringComparison.OrdinalIgnoreCase))) { if (definitions.GroupBy(p => p.CustomPriorityOrder).Count() == 1) { filtered = definitions.Where(p => p.FileCI.Contains(Shared.Constants.LocalizationReplaceDirectory, StringComparison.OrdinalIgnoreCase)); } else { filtered = definitions.OrderByDescending(p => p.CustomPriorityOrder).Where(p => p.FileCI.Contains(Shared.Constants.LocalizationReplaceDirectory, StringComparison.OrdinalIgnoreCase)); } } else { if (definitions.GroupBy(p => p.CustomPriorityOrder).Count() == 1) { filtered = definitions.ToList(); } else { filtered = definitions.Where(p => p.CustomPriorityOrder == definitions.OrderByDescending(p => p.CustomPriorityOrder).FirstOrDefault().CustomPriorityOrder); } } var uniqueDefinitions = filtered.GroupBy(p => p.ModName).Select(p => p.OrderBy(f => Path.GetFileNameWithoutExtension(f.File), StringComparer.Ordinal).Last()); if (uniqueDefinitions.Count() == 1) { result.Definition = uniqueDefinitions.First(); } else if (uniqueDefinitions.Count() > 1) { result.Definition = uniqueDefinitions.OrderBy(p => Path.GetFileNameWithoutExtension(p.File), StringComparer.Ordinal).Last(); } } else { var validDefinitions = definitions.Where(p => p.ExistsInLastFile).ToList(); if (validDefinitions.Count == 1) { result.Definition = validDefinitions.FirstOrDefault(); // If it's the only valid one assume load order is responsible result.PriorityType = DefinitionPriorityType.ModOrder; } else if (validDefinitions.Count > 1) { var definitionEvals = new List <DefinitionEval>(); var provider = DefinitionInfoProviders.FirstOrDefault(p => p.CanProcess(game.Type)); bool isFios = false; if (provider != null) { bool overrideSkipped = false; isFios = provider.DefinitionUsesFIOSRules(validDefinitions.First()); foreach (var item in validDefinitions) { var fileName = isFios ? item.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).First() : item.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).Last(); var hasOverrides = validDefinitions.Any(p => !p.IsCustomPatch && p.Dependencies != null && p.Dependencies.Any(d => d.Equals(item.ModName)) && (isFios ? p.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).First().Equals(fileName) : p.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).Last().Equals(fileName))); if (hasOverrides) { overrideSkipped = true; continue; } definitionEvals.Add(new DefinitionEval() { Definition = item, FileName = fileName }); } IEnumerable <DefinitionEval> uniqueDefinitions; if (isFios) { uniqueDefinitions = definitionEvals.GroupBy(p => p.Definition.ModName).Select(p => p.OrderBy(f => Path.GetFileNameWithoutExtension(f.FileName), StringComparer.Ordinal).First()); } else { uniqueDefinitions = definitionEvals.GroupBy(p => p.Definition.ModName).Select(p => p.OrderBy(f => Path.GetFileNameWithoutExtension(f.FileName), StringComparer.Ordinal).Last()); } if (uniqueDefinitions.Count() == 1 && overrideSkipped) { result.Definition = definitionEvals.First().Definition; result.PriorityType = DefinitionPriorityType.ModOverride; } else if (uniqueDefinitions.Count() > 1) { // Has same filenames? if (uniqueDefinitions.GroupBy(p => p.FileNameCI).Count() == 1) { if (uniqueDefinitions.Any(p => p.Definition.IsCustomPatch)) { result.Definition = uniqueDefinitions.FirstOrDefault(p => p.Definition.IsCustomPatch).Definition; result.PriorityType = DefinitionPriorityType.ModOrder; } else { result.Definition = uniqueDefinitions.Last().Definition; result.PriorityType = DefinitionPriorityType.ModOrder; } } else { // Using FIOS or LIOS? if (isFios) { result.Definition = uniqueDefinitions.OrderBy(p => Path.GetFileNameWithoutExtension(p.FileName), StringComparer.Ordinal).First().Definition; result.PriorityType = DefinitionPriorityType.FIOS; } else { result.Definition = uniqueDefinitions.OrderBy(p => Path.GetFileNameWithoutExtension(p.FileName), StringComparer.Ordinal).Last().Definition; result.PriorityType = DefinitionPriorityType.LIOS; } } } } } } } if (result.Definition == null) { result.Definition = definitions?.FirstOrDefault(); } return(result); }
/// <summary> /// Evals the definition priority internal. /// </summary> /// <param name="definitions">The definitions.</param> /// <returns>IPriorityDefinitionResult.</returns> protected virtual IPriorityDefinitionResult EvalDefinitionPriorityInternal(IEnumerable <IDefinition> definitions) { var game = GameService.GetSelected(); var result = GetModelInstance <IPriorityDefinitionResult>(); if (game != null && definitions?.Count() > 1) { var definitionEvals = new List <DefinitionEval>(); var provider = DefinitionInfoProviders.FirstOrDefault(p => p.CanProcess(game.Type)); bool isFios = false; if (provider != null) { bool overrideSkipped = false; isFios = provider.DefinitionUsesFIOSRules(definitions.First()); foreach (var item in definitions) { var hasOverrides = definitions.Any(p => (p.Dependencies?.Any(p => p.Equals(item.ModName))).GetValueOrDefault()); if (hasOverrides) { overrideSkipped = true; continue; } if (isFios) { definitionEvals.Add(new DefinitionEval() { Definition = item, FileName = item.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).First() }); } else { definitionEvals.Add(new DefinitionEval() { Definition = item, FileName = item.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).Last() }); } } var uniqueDefinitions = definitionEvals.GroupBy(p => p.Definition.ModName).Select(p => p.First()); if (uniqueDefinitions.Count() == 1 && overrideSkipped) { result.Definition = definitionEvals.First().Definition; result.PriorityType = DefinitionPriorityType.ModOverride; } else if (uniqueDefinitions.Count() > 1) { // Has same filenames? if (uniqueDefinitions.GroupBy(p => p.FileNameCI).Count() == 1) { result.Definition = uniqueDefinitions.Last().Definition; result.PriorityType = DefinitionPriorityType.ModOrder; } else { // Using FIOS or LIOS? if (isFios) { result.Definition = uniqueDefinitions.OrderBy(p => Path.GetFileNameWithoutExtension(p.FileName), StringComparer.Ordinal).First().Definition; result.PriorityType = DefinitionPriorityType.FIOS; } else { result.Definition = uniqueDefinitions.OrderBy(p => Path.GetFileNameWithoutExtension(p.FileName), StringComparer.Ordinal).Last().Definition; result.PriorityType = DefinitionPriorityType.LIOS; } } } } } if (result.Definition == null) { result.Definition = definitions?.FirstOrDefault(); } return(result); }
/// <summary> /// Evals the definition priority internal. /// </summary> /// <param name="definitions">The definitions.</param> /// <returns>IPriorityDefinitionResult.</returns> protected virtual IPriorityDefinitionResult EvalDefinitionPriorityInternal(IEnumerable <IDefinition> definitions) { // We're expecting properly ordered definitions based on load order. // In case of game being included this should be done by the calling method as well, // though there should not be any problems since it's all based on a list of strings modOrder.IndexOf(modName). // And the game is never a mod. If this changes this is going to be bad for me. var game = GameService.GetSelected(); var result = GetModelInstance <IPriorityDefinitionResult>(); if (game != null && definitions?.Count() > 1) { // Handle localizations differently var file = definitions.FirstOrDefault().File ?? string.Empty; if (file.StartsWith(Shared.Constants.LocalizationDirectory)) { IEnumerable <IDefinition> filtered = null; if (definitions.Any(p => p.FileCI.Contains(Shared.Constants.LocalizationReplaceDirectory, StringComparison.OrdinalIgnoreCase))) { var replaceDefinitions = definitions.Where(p => p.FileCI.Contains(Shared.Constants.LocalizationReplaceDirectory, StringComparison.OrdinalIgnoreCase)); if (replaceDefinitions.GroupBy(p => p.CustomPriorityOrder).Count() == 1) { filtered = replaceDefinitions.ToList(); } else { var topPriority = replaceDefinitions.OrderByDescending(p => p.CustomPriorityOrder).FirstOrDefault().CustomPriorityOrder; filtered = replaceDefinitions.Where(p => p.CustomPriorityOrder == topPriority); } } else { if (definitions.GroupBy(p => p.CustomPriorityOrder).Count() == 1) { filtered = definitions.ToList(); } else { var topPriority = definitions.OrderByDescending(p => p.CustomPriorityOrder).FirstOrDefault().CustomPriorityOrder; filtered = definitions.Where(p => p.CustomPriorityOrder == topPriority); } } var uniqueDefinitions = filtered.GroupBy(p => p.ModName).Select(p => p.OrderBy(f => Path.GetFileNameWithoutExtension(f.File), StringComparer.Ordinal).Last()); if (uniqueDefinitions.Count() == 1) { var definition = uniqueDefinitions.FirstOrDefault(p => !p.IsFromGame); if (definition == null) { definition = uniqueDefinitions.FirstOrDefault(); } result.Definition = definition; } else if (uniqueDefinitions.Count() > 1) { var modDefinitions = uniqueDefinitions.Where(p => !p.IsFromGame); if (!modDefinitions.Any()) { definitions = uniqueDefinitions; } result.Definition = modDefinitions.OrderBy(p => Path.GetFileNameWithoutExtension(p.File), StringComparer.Ordinal).Last(); } } else { var validDefinitions = definitions.Where(p => p.ExistsInLastFile).ToList(); if (validDefinitions.Count == 1) { result.Definition = validDefinitions.FirstOrDefault(); // If it's the only valid one assume load order is responsible result.PriorityType = DefinitionPriorityType.ModOrder; } else if (validDefinitions.Count > 1) { var definitionEvals = new List <DefinitionEval>(); var provider = DefinitionInfoProviders.FirstOrDefault(p => p.CanProcess(game.Type)); bool isFios = false; if (provider != null) { bool overrideSkipped = false; isFios = provider.DefinitionUsesFIOSRules(validDefinitions.First()); foreach (var item in validDefinitions) { var fileName = isFios ? item.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).First() : item.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).Last(); var hasOverrides = validDefinitions.Any(p => !p.IsCustomPatch && p.Dependencies != null && p.Dependencies.Any(d => d.Equals(item.ModName)) && (isFios ? p.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).First().Equals(fileName) : p.AdditionalFileNames.OrderBy(p => Path.GetFileNameWithoutExtension(p), StringComparer.Ordinal).Last().Equals(fileName))); if (hasOverrides) { overrideSkipped = true; continue; } definitionEvals.Add(new DefinitionEval() { Definition = item, FileName = fileName }); } List <DefinitionEval> uniqueDefinitions; if (isFios) { uniqueDefinitions = definitionEvals.GroupBy(p => p.Definition.ModName).Select(p => p.OrderBy(f => Path.GetFileNameWithoutExtension(f.FileName), StringComparer.Ordinal).First()).ToList(); } else { uniqueDefinitions = definitionEvals.GroupBy(p => p.Definition.ModName).Select(p => p.OrderBy(f => Path.GetFileNameWithoutExtension(f.FileName), StringComparer.Ordinal).Last()).ToList(); } // Filter out game definitions which might have the same filename var filteredGameDefinitions = false; var gameDefinitions = uniqueDefinitions.GroupBy(p => p.FileNameCI).Where(p => p.Any(a => a.Definition.IsFromGame)).SelectMany(p => p.Where(w => w.Definition.IsFromGame)); if (gameDefinitions.Any()) { filteredGameDefinitions = true; foreach (var gameDef in gameDefinitions) { uniqueDefinitions.Remove(gameDef); } } if (uniqueDefinitions.Count == 1 && (overrideSkipped || filteredGameDefinitions)) { var definition = definitionEvals.FirstOrDefault(p => !p.Definition.IsFromGame); if (definition == null) { definition = definitionEvals.FirstOrDefault(); } result.Definition = definition.Definition; if (overrideSkipped) { result.PriorityType = DefinitionPriorityType.ModOverride; } else if (filteredGameDefinitions) { result.PriorityType = DefinitionPriorityType.ModOrder; } } else if (uniqueDefinitions.Count > 1) { // Has same filenames? if (uniqueDefinitions.GroupBy(p => p.FileNameCI).Count() == 1) { if (uniqueDefinitions.Any(p => p.Definition.IsCustomPatch)) { result.Definition = uniqueDefinitions.FirstOrDefault(p => p.Definition.IsCustomPatch).Definition; result.PriorityType = DefinitionPriorityType.ModOrder; } else { result.Definition = uniqueDefinitions.Last().Definition; result.PriorityType = DefinitionPriorityType.ModOrder; } } else { // Using FIOS or LIOS? if (isFios) { result.Definition = uniqueDefinitions.OrderBy(p => Path.GetFileNameWithoutExtension(p.FileName), StringComparer.Ordinal).First().Definition; result.PriorityType = DefinitionPriorityType.FIOS; } else { result.Definition = uniqueDefinitions.OrderBy(p => Path.GetFileNameWithoutExtension(p.FileName), StringComparer.Ordinal).Last().Definition; result.PriorityType = DefinitionPriorityType.LIOS; } } } } } } } if (result.Definition == null) { var definition = definitions?.FirstOrDefault(p => !p.IsFromGame); if (definition == null && (definitions?.Any()).GetValueOrDefault()) { definition = definitions.FirstOrDefault(); } result.Definition = definition; } return(result); }