diff --git a/ModuleManager/Cats/CatAnimator.cs b/ModuleManager/Cats/CatAnimator.cs index ed5b2c70..7806d4aa 100644 --- a/ModuleManager/Cats/CatAnimator.cs +++ b/ModuleManager/Cats/CatAnimator.cs @@ -1,4 +1,5 @@ using System.Collections; +using System.Diagnostics.CodeAnalysis; using UnityEngine; namespace ModuleManager.Cats @@ -12,9 +13,10 @@ class CatAnimator : MonoBehaviour private SpriteRenderer spriteRenderer; private int spriteIdx; + [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] void Start() { - spriteRenderer = this.GetComponent(); + spriteRenderer = GetComponent(); spriteRenderer.sortingOrder = 3; StartCoroutine(Animate()); } diff --git a/ModuleManager/Cats/CatManager.cs b/ModuleManager/Cats/CatManager.cs index 744a0ca8..05f671d6 100644 --- a/ModuleManager/Cats/CatManager.cs +++ b/ModuleManager/Cats/CatManager.cs @@ -14,7 +14,7 @@ public static void LaunchCat() InitCats(); GameObject cat = LaunchCat(scale); - CatMover catMover = cat.AddComponent(); + cat.AddComponent(); } public static void LaunchCats() diff --git a/ModuleManager/Cats/CatMover.cs b/ModuleManager/Cats/CatMover.cs index 2e37ac9a..d97a3f7c 100644 --- a/ModuleManager/Cats/CatMover.cs +++ b/ModuleManager/Cats/CatMover.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Diagnostics.CodeAnalysis; using UnityEngine; namespace ModuleManager.Cats @@ -24,12 +24,13 @@ public class CatMover : MonoBehaviour private bool clearTrail = false; // Use this for initialization + [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] void Start() { - trail = this.GetComponent(); + trail = GetComponent(); trail.sortingOrder = 2; - spriteRenderer = this.GetComponent(); + spriteRenderer = GetComponent(); offsetY = Mathf.FloorToInt(0.2f * Screen.height); @@ -41,6 +42,7 @@ void Start() clearTrail = true; } + [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] void Update() { if (trail.time <= 0f) diff --git a/ModuleManager/Cats/CatOrbiter.cs b/ModuleManager/Cats/CatOrbiter.cs index 17621c6f..34b1f6e8 100644 --- a/ModuleManager/Cats/CatOrbiter.cs +++ b/ModuleManager/Cats/CatOrbiter.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using KSP.UI; using UnityEngine; using Random = UnityEngine.Random; @@ -8,7 +9,7 @@ namespace ModuleManager.Cats { class CatOrbiter : MonoBehaviour { - private static List orbiters = new List(); + private static readonly List orbiters = new List(); private static CatOrbiter sun; @@ -20,7 +21,7 @@ class CatOrbiter : MonoBehaviour private Vector2d force; private float scale = 1; - private double G = 6.67408E-11; + private const double G = 6.67408E-11; public double Mass { @@ -113,13 +114,14 @@ private void DoForces() } } - + [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] void OnDestroy() { orbiters.Remove(this); TimingManager.FixedUpdateRemove(TimingManager.TimingStage.Earlyish, DoForces); } + [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] void FixedUpdate() { //if (this == sun) diff --git a/ModuleManager/Collections/ImmutableStack.cs b/ModuleManager/Collections/ImmutableStack.cs index 5d181567..d710c423 100644 --- a/ModuleManager/Collections/ImmutableStack.cs +++ b/ModuleManager/Collections/ImmutableStack.cs @@ -8,7 +8,7 @@ public class ImmutableStack : IEnumerable { public struct Enumerator : IEnumerator { - private ImmutableStack head; + private readonly ImmutableStack head; private ImmutableStack currentStack; public Enumerator(ImmutableStack stack) diff --git a/ModuleManager/CustomConfigsManager.cs b/ModuleManager/CustomConfigsManager.cs index e2b8689c..d7444363 100644 --- a/ModuleManager/CustomConfigsManager.cs +++ b/ModuleManager/CustomConfigsManager.cs @@ -16,16 +16,6 @@ internal void Start() Log("Setting modded tech tree as the active one"); HighLogic.CurrentGame.Parameters.Career.TechTreeUrl = techTreeFile; } - - if (PhysicsGlobals.PhysicsDatabaseFilename != physicsFile && File.Exists(physicsPath)) - { - Log("Setting modded physics as the active one"); - - PhysicsGlobals.PhysicsDatabaseFilename = physicsFile; - - if (!PhysicsGlobals.Instance.LoadDatabase()) - Log("Something went wrong while setting the active physics config."); - } } public static void Log(String s) diff --git a/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs b/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs index 6cd3dcd0..471b1fa8 100644 --- a/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs +++ b/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs @@ -16,10 +16,9 @@ class InterceptLogHandler : ILogHandler public static string Warnings { get; private set; } = ""; - public InterceptLogHandler() + public InterceptLogHandler(ILogHandler baseLogHandler) { - baseLogHandler = Debug.unityLogger.logHandler; - Debug.unityLogger.logHandler = this; + this.baseLogHandler = baseLogHandler ?? throw new ArgumentNullException(nameof(baseLogHandler)); gamePathLength = Path.GetFullPath(KSPUtil.ApplicationRootPath).Length; } diff --git a/ModuleManager/Extensions/StringExtensions.cs b/ModuleManager/Extensions/StringExtensions.cs index c4190045..634fab7a 100644 --- a/ModuleManager/Extensions/StringExtensions.cs +++ b/ModuleManager/Extensions/StringExtensions.cs @@ -18,11 +18,20 @@ public static bool IsBracketBalanced(this string s) return level == 0; } - private static Regex whitespaceRegex = new Regex(@"\s+"); + private static readonly Regex whitespaceRegex = new Regex(@"\s+"); public static string RemoveWS(this string withWhite) { return whitespaceRegex.Replace(withWhite, ""); } + + public static bool Contains(this string str, string value, out int index) + { + if (str == null) throw new ArgumentNullException(nameof(str)); + if (value == null) throw new ArgumentNullException(nameof(value)); + + index = str.IndexOf(value, StringComparison.CurrentCultureIgnoreCase); + return index != -1; + } } } diff --git a/ModuleManager/FilePathRepository.cs b/ModuleManager/FilePathRepository.cs index db15419e..0d1448d7 100644 --- a/ModuleManager/FilePathRepository.cs +++ b/ModuleManager/FilePathRepository.cs @@ -5,20 +5,21 @@ namespace ModuleManager { internal static class FilePathRepository { - internal static readonly string cachePath = Path.Combine(KSPUtil.ApplicationRootPath, "GameData", "ModuleManager.ConfigCache"); + internal static readonly string normalizedRootPath = Path.GetFullPath(KSPUtil.ApplicationRootPath); + internal static readonly string cachePath = Path.Combine(normalizedRootPath, "GameData", "ModuleManager.ConfigCache"); internal static readonly string techTreeFile = Path.Combine("GameData", "ModuleManager.TechTree"); - internal static readonly string techTreePath = Path.Combine(KSPUtil.ApplicationRootPath, techTreeFile); + internal static readonly string techTreePath = Path.Combine(normalizedRootPath, techTreeFile); internal static readonly string physicsFile = Path.Combine("GameData", "ModuleManager.Physics"); - internal static readonly string physicsPath = Path.Combine(KSPUtil.ApplicationRootPath, physicsFile); - internal static readonly string defaultPhysicsPath = Path.Combine(KSPUtil.ApplicationRootPath, "Physics.cfg"); + internal static readonly string physicsPath = Path.Combine(normalizedRootPath, physicsFile); + internal static readonly string defaultPhysicsPath = Path.Combine(normalizedRootPath, "Physics.cfg"); - internal static readonly string partDatabasePath = Path.Combine(KSPUtil.ApplicationRootPath, "PartDatabase.cfg"); + internal static readonly string partDatabasePath = Path.Combine(normalizedRootPath, "PartDatabase.cfg"); - internal static readonly string shaPath = Path.Combine(KSPUtil.ApplicationRootPath, "GameData", "ModuleManager.ConfigSHA"); + internal static readonly string shaPath = Path.Combine(normalizedRootPath, "GameData", "ModuleManager.ConfigSHA"); - internal static readonly string logsDirPath = Path.Combine(KSPUtil.ApplicationRootPath, "Logs", "ModuleManager"); + internal static readonly string logsDirPath = Path.Combine(normalizedRootPath, "Logs", "ModuleManager"); internal static readonly string logPath = Path.Combine(logsDirPath, "ModuleManager.log"); internal static readonly string patchLogPath = Path.Combine(logsDirPath, "MMPatch.log"); } diff --git a/ModuleManager/Fix16.cs b/ModuleManager/Fix16.cs index ab20e6ae..b567eb56 100644 --- a/ModuleManager/Fix16.cs +++ b/ModuleManager/Fix16.cs @@ -1,9 +1,11 @@ using System.Collections; +using System.Diagnostics.CodeAnalysis; namespace ModuleManager { class Fix16 : LoadingSystem { + [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] private void Awake() { if (Instance != null) diff --git a/ModuleManager/Logging/StreamLogger.cs b/ModuleManager/Logging/StreamLogger.cs index 74115d3e..d020f64c 100644 --- a/ModuleManager/Logging/StreamLogger.cs +++ b/ModuleManager/Logging/StreamLogger.cs @@ -5,14 +5,11 @@ namespace ModuleManager.Logging { public sealed class StreamLogger : IBasicLogger, IDisposable { - private readonly Stream stream; private readonly StreamWriter streamWriter; private bool disposed = false; public StreamLogger(Stream stream) { - this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); - if (!stream.CanWrite) throw new ArgumentException("must be writable", nameof(stream)); streamWriter = new StreamWriter(stream); } diff --git a/ModuleManager/Logging/UnityLogger.cs b/ModuleManager/Logging/UnityLogger.cs index b31c1003..d51063c4 100644 --- a/ModuleManager/Logging/UnityLogger.cs +++ b/ModuleManager/Logging/UnityLogger.cs @@ -5,7 +5,7 @@ namespace ModuleManager.Logging { public class UnityLogger : IBasicLogger { - private ILogger logger; + private readonly ILogger logger; public UnityLogger(ILogger logger) { diff --git a/ModuleManager/MMPatchLoader.cs b/ModuleManager/MMPatchLoader.cs index 1cffe055..5278758b 100644 --- a/ModuleManager/MMPatchLoader.cs +++ b/ModuleManager/MMPatchLoader.cs @@ -8,8 +8,6 @@ using System.Reflection; using System.Text; using System.Text.RegularExpressions; -using UnityEngine; -using Debug = UnityEngine.Debug; using ModuleManager.Collections; using ModuleManager.Logging; @@ -24,8 +22,6 @@ namespace ModuleManager { - [SuppressMessage("ReSharper", "StringLastIndexOfIsCultureSpecific.1")] - [SuppressMessage("ReSharper", "StringIndexOfIsCultureSpecific.1")] public class MMPatchLoader { private const string PHYSICS_NODE_NAME = "PHYSICSGLOBALS"; @@ -235,6 +231,9 @@ public IEnumerable Run() } } + if (KSP.Localization.Localizer.Instance != null) + KSP.Localization.Localizer.SwitchToLanguage(KSP.Localization.Localizer.CurrentLanguage); + logger.Info(status + "\n" + errors); patchSw.Stop(); @@ -568,7 +567,7 @@ private void StatusUpdate(IPatchProgress progress, string activity = null) #region Applying Patches // Name is group 1, index is group 2, vector related filed is group 3, vector separator is group 4, operator is group 5 - private static readonly Regex parseValue = new Regex(@"([\w\&\-\.\?\*+/^!\(\) ]+(?:,[^*\d][\w\&\-\.\?\*\(\) ]*)*)(?:,(-?[0-9\*]+))?(?:\[((?:[0-9\*]+)+)(?:,(.))?\])?"); + private static readonly Regex parseValue = new Regex(@"([\w\&\-\.\?\*\#+/^!\(\) ]+(?:,[^*\d][\w\&\-\.\?\*\(\) ]*)*)(?:,(-?[0-9\*]+))?(?:\[((?:[0-9\*]+)+)(?:,(.))?\])?"); // ModifyNode applies the ConfigNode mod as a 'patch' to ConfigNode original, then returns the patched ConfigNode. // it uses FindConfigNodeIn(src, nodeType, nodeName, nodeTag) to recurse. @@ -924,7 +923,7 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon ConfigNode newSubMod = new ConfigNode(toPaste.name); newSubMod = ModifyNode(nodeStack.Push(newSubMod), toPaste, context); - if (subName.LastIndexOf(",") > 0 && int.TryParse(subName.Substring(subName.LastIndexOf(",") + 1), out int index)) + if (subName.LastIndexOf(',') > 0 && int.TryParse(subName.Substring(subName.LastIndexOf(',') + 1), out int index)) { // In this case insert the node at position index InsertNode(newNode, newSubMod, index); @@ -947,11 +946,10 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon // NODE,n will match the nth node (NODE is the same as NODE,0) // NODE,* will match ALL nodes // NODE:HAS[condition] will match ALL nodes with condition - if (subName.Contains(":HAS[")) + if (subName.Contains(":HAS[", out int hasStart)) { - int start = subName.IndexOf(":HAS["); - constraints = subName.Substring(start + 5, subName.LastIndexOf(']') - start - 5); - subName = subName.Substring(0, start); + constraints = subName.Substring(hasStart + 5, subName.LastIndexOf(']') - hasStart - 5); + subName = subName.Substring(0, hasStart); } if (subName.Contains(",")) @@ -1119,11 +1117,10 @@ private static ConfigNode RecurseNodeSearch(string path, NodeStack nodeStack, Pa string constraint = ""; int index = 0; - if (subName.Contains(":HAS[")) + if (subName.Contains(":HAS[", out int hasStart)) { - int start = subName.IndexOf(":HAS["); - constraint = subName.Substring(start + 5, subName.LastIndexOf(']') - start - 5); - subName = subName.Substring(0, start); + constraint = subName.Substring(hasStart + 5, subName.LastIndexOf(']') - hasStart - 5); + subName = subName.Substring(0, hasStart); } else if (subName.Contains(",")) { @@ -1292,13 +1289,12 @@ private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nod string constraint = ""; string nodeType, nodeName; int index = 0; - if (subName.Contains(":HAS[")) + if (subName.Contains(":HAS[", out int hasStart)) { - int start = subName.IndexOf(":HAS["); - constraint = subName.Substring(start + 5, subName.LastIndexOf(']') - start - 5); - subName = subName.Substring(0, start); + constraint = subName.Substring(hasStart + 5, subName.LastIndexOf(']') - hasStart - 5); + subName = subName.Substring(0, hasStart); } - else if (subName.Contains(",")) + else if (subName.Contains(',')) { string tag = subName.Split(',')[1]; subName = subName.Split(',')[0]; @@ -1553,11 +1549,11 @@ public static bool CheckConstraints(ConfigNode node, string constraints) constraints = constraintList[0]; string remainingConstraints = ""; - if (constraints.Contains("HAS[")) + if (constraints.Contains(":HAS[", out int hasStart)) { - int start = constraints.IndexOf("HAS[") + 4; - remainingConstraints = constraints.Substring(start, constraintList[0].LastIndexOf(']') - start); - constraints = constraints.Substring(0, start - 5); + hasStart += 5; + remainingConstraints = constraints.Substring(hasStart, constraintList[0].LastIndexOf(']') - hasStart); + constraints = constraints.Substring(0, hasStart - 5); } string[] splits = constraints.Split(contraintSeparators, 3); @@ -1719,19 +1715,26 @@ public static ConfigNode FindConfigNodeIn( string nodeName = null, int index = 0) { - ConfigNode[] nodes = src.GetNodes(nodeType); - if (nodes.Length == 0) + List nodes = new List(); + int c = src.nodes.Count; + for(int i = 0; i < c; ++i) + { + if (WildcardMatch(src.nodes[i].name, nodeType)) + nodes.Add(src.nodes[i]); + } + int nodeCount = nodes.Count; + if (nodeCount == 0) return null; if (nodeName == null) { if (index >= 0) - return nodes[Math.Min(index, nodes.Length - 1)]; - return nodes[Math.Max(0, nodes.Length + index)]; + return nodes[Math.Min(index, nodeCount - 1)]; + return nodes[Math.Max(0, nodeCount + index)]; } ConfigNode last = null; if (index >= 0) { - for (int i = 0; i < nodes.Length; ++i) + for (int i = 0; i < nodeCount; ++i) { if (nodes[i].HasValue("name") && WildcardMatch(nodes[i].GetValue("name"), nodeName)) { @@ -1742,7 +1745,7 @@ public static ConfigNode FindConfigNodeIn( } return last; } - for (int i = nodes.Length - 1; i >= 0; --i) + for (int i = nodeCount - 1; i >= 0; --i) { if (nodes[i].HasValue("name") && WildcardMatch(nodes[i].GetValue("name"), nodeName)) { diff --git a/ModuleManager/MMPatchRunner.cs b/ModuleManager/MMPatchRunner.cs index 739ecd82..6c3d63a0 100644 --- a/ModuleManager/MMPatchRunner.cs +++ b/ModuleManager/MMPatchRunner.cs @@ -2,7 +2,6 @@ using System.Collections; using System.Collections.Generic; using System.IO; -using UnityEngine; using ModuleManager.Collections; using ModuleManager.Extensions; using ModuleManager.Logging; @@ -14,8 +13,6 @@ namespace ModuleManager { public class MMPatchRunner { - private const float TIME_TO_WAIT_FOR_LOGS = 0.05f; - private readonly IBasicLogger kspLogger; public string Status { get; private set; } = ""; @@ -38,12 +35,10 @@ public IEnumerator Run() QueueLogRunner logRunner = new QueueLogRunner(mmLogQueue); ITaskStatus loggingThreadStatus = BackgroundTask.Start(delegate { - using (StreamLogger streamLogger = new StreamLogger(new FileStream(logPath, FileMode.Create))) - { - streamLogger.Info("Log started at " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); - logRunner.Run(streamLogger); - streamLogger.Info("Done!"); - } + using StreamLogger streamLogger = new StreamLogger(new FileStream(logPath, FileMode.Create)); + streamLogger.Info("Log started at " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); + logRunner.Run(streamLogger); + streamLogger.Info("Done!"); }); // Wait for game database to be initialized for the 2nd time and wait for any plugins to initialize @@ -80,12 +75,14 @@ public IEnumerator Run() { kspLogger.Exception("The patching thread threw an exception", patchingThreadStatus.Exception); FatalErrorHandler.HandleFatalError("The patching thread threw an exception"); + yield break; } if (loggingThreadStatus.IsExitedWithError) { kspLogger.Exception("The logging thread threw an exception", loggingThreadStatus.Exception); FatalErrorHandler.HandleFatalError("The logging thread threw an exception"); + yield break; } if (databaseConfigs == null) diff --git a/ModuleManager/ModuleManager.cs b/ModuleManager/ModuleManager.cs index 361cb540..dd5e04e5 100644 --- a/ModuleManager/ModuleManager.cs +++ b/ModuleManager/ModuleManager.cs @@ -38,8 +38,6 @@ public class ModuleManager : MonoBehaviour private MMPatchRunner patchRunner; - private InterceptLogHandler interceptLogHandler; - #endregion state private static bool loadedInScene; @@ -80,8 +78,8 @@ internal void Awake() } totalTime.Start(); - - interceptLogHandler = new InterceptLogHandler(); + + Debug.unityLogger.logHandler = new InterceptLogHandler(Debug.unityLogger.logHandler); // Allow loading the background in the loading screen Application.runInBackground = true; diff --git a/ModuleManager/ModuleManager.csproj b/ModuleManager/ModuleManager.csproj index d58d8d14..20fe0da1 100644 --- a/ModuleManager/ModuleManager.csproj +++ b/ModuleManager/ModuleManager.csproj @@ -33,6 +33,9 @@ False false + + 8.0 + @@ -121,33 +124,42 @@ False + False False + False False + False False + False False + False False + False False + False False + False False + False diff --git a/ModuleManager/NeedsChecker.cs b/ModuleManager/NeedsChecker.cs index 7e452642..94f2ad29 100644 --- a/ModuleManager/NeedsChecker.cs +++ b/ModuleManager/NeedsChecker.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using ModuleManager.Extensions; using ModuleManager.Logging; @@ -20,6 +21,7 @@ public class NeedsChecker : INeedsChecker private readonly IEnumerable mods; private readonly UrlDir gameData; private readonly IPatchProgress progress; + [SuppressMessage("CodeQuality", "IDE0052", Justification = "Reserved for future use")] private readonly IBasicLogger logger; public NeedsChecker(IEnumerable mods, UrlDir gameData, IPatchProgress progress, IBasicLogger logger) diff --git a/ModuleManager/NodeMatcher.cs b/ModuleManager/NodeMatcher.cs index 5c3a59ca..8777de97 100644 --- a/ModuleManager/NodeMatcher.cs +++ b/ModuleManager/NodeMatcher.cs @@ -10,11 +10,9 @@ public interface INodeMatcher public class NodeMatcher : INodeMatcher { - private static readonly char[] sep = { '[', ']' }; - - private string type; - private string[] namePatterns = null; - private string constraints = ""; + private readonly string type; + private readonly string[] namePatterns = null; + private readonly string constraints = ""; public NodeMatcher(string type, string name, string constraints) { diff --git a/ModuleManager/PatchExtractor.cs b/ModuleManager/PatchExtractor.cs index cf476a64..6c8765f4 100644 --- a/ModuleManager/PatchExtractor.cs +++ b/ModuleManager/PatchExtractor.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using ModuleManager.Extensions; using ModuleManager.Logging; using ModuleManager.Patches; @@ -10,6 +11,7 @@ namespace ModuleManager public class PatchExtractor { private readonly IPatchProgress progress; + [SuppressMessage("CodeQuality", "IDE0052", Justification = "Reserved for future use")] private readonly IBasicLogger logger; private readonly INeedsChecker needsChecker; private readonly ITagListParser tagListParser; diff --git a/ModuleManager/PatchList.cs b/ModuleManager/PatchList.cs index 9716de22..d3990540 100644 --- a/ModuleManager/PatchList.cs +++ b/ModuleManager/PatchList.cs @@ -1,8 +1,6 @@ using System; using System.Collections; using System.Collections.Generic; -using System.Linq; -using ModuleManager.Collections; using ModuleManager.Patches; using ModuleManager.Patches.PassSpecifiers; using ModuleManager.Progress; @@ -37,52 +35,25 @@ public ModPass(string name) public void AddLastPatch(IPatch patch) => lastPass.Add(patch ?? throw new ArgumentNullException(nameof(patch))); } - private class ModPassCollection : IEnumerable - { - private readonly ModPass[] passesArray; - private readonly Dictionary passesDict; - - public ModPassCollection(IEnumerable modList) - { - int count = modList.Count(); - passesArray = new ModPass[count]; - passesDict = new Dictionary(count); - - int i = 0; - foreach (string mod in modList) - { - ModPass pass = new ModPass(mod); - passesArray[i] = pass; - passesDict.Add(mod.ToLowerInvariant(), pass); - i++; - } - } - - public ModPass this[string name] => passesDict[name.ToLowerInvariant()]; - public ModPass this[int index] => passesArray[index]; - - public bool HasMod(string name) => passesDict.ContainsKey(name.ToLowerInvariant()); - - public int Count => passesArray.Length; - - public ArrayEnumerator GetEnumerator() => new ArrayEnumerator(passesArray); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } - private readonly Pass insertPatches = new Pass(":INSERT (initial)"); private readonly Pass firstPatches = new Pass(":FIRST"); private readonly Pass legacyPatches = new Pass(":LEGACY (default)"); private readonly Pass finalPatches = new Pass(":FINAL"); - private readonly ModPassCollection modPasses; + private readonly SortedDictionary modPasses = new SortedDictionary(StringComparer.InvariantCultureIgnoreCase); + private readonly SortedDictionary lastPasses = new SortedDictionary(StringComparer.InvariantCultureIgnoreCase); public PatchList(IEnumerable modList, IEnumerable patches, IPatchProgress progress) { - modPasses = new ModPassCollection(modList ?? throw new ArgumentNullException(nameof(modList))); + if (modList == null) throw new ArgumentNullException(nameof(modList)); if (patches == null) throw new ArgumentNullException(nameof(patches)); if (progress == null) throw new ArgumentNullException(nameof(progress)); + foreach (string mod in modList) + { + modPasses.Add(mod, new ModPass(mod)); + } + foreach (IPatch patch in patches) { if (patch.PassSpecifier is InsertPassSpecifier) @@ -114,8 +85,12 @@ public PatchList(IEnumerable modList, IEnumerable patches, IPatc } else if (patch.PassSpecifier is LastPassSpecifier lastPassSpecifier) { - EnsureMod(lastPassSpecifier.mod); - modPasses[lastPassSpecifier.mod].AddLastPatch(patch); + if (!lastPasses.TryGetValue(lastPassSpecifier.mod, out Pass thisPass)) + { + thisPass = new Pass($":LAST[{lastPassSpecifier.mod.ToUpperInvariant()}]"); + lastPasses.Add(lastPassSpecifier.mod.ToLowerInvariant(), thisPass); + } + thisPass.Add(patch); } else if (patch.PassSpecifier is FinalPassSpecifier) { @@ -136,16 +111,16 @@ public IEnumerator GetEnumerator() yield return firstPatches; yield return legacyPatches; - foreach (ModPass modPass in modPasses) + foreach (ModPass modPass in modPasses.Values) { yield return modPass.beforePass; yield return modPass.forPass; yield return modPass.afterPass; } - foreach (ModPass modPass in modPasses) + foreach (Pass lastPass in lastPasses.Values) { - yield return modPass.lastPass; + yield return lastPass; } yield return finalPatches; @@ -157,7 +132,7 @@ private void EnsureMod(string mod) { if (mod == null) throw new ArgumentNullException(nameof(mod)); if (mod == string.Empty) throw new ArgumentException("can't be empty", nameof(mod)); - if (!modPasses.HasMod(mod)) throw new KeyNotFoundException($"Mod '{mod}' not found"); + if (!modPasses.ContainsKey(mod)) throw new KeyNotFoundException($"Mod '{mod}' not found"); } } } diff --git a/ModuleManager/Patches/PatchCompiler.cs b/ModuleManager/Patches/PatchCompiler.cs index 67387372..6c7e7f30 100644 --- a/ModuleManager/Patches/PatchCompiler.cs +++ b/ModuleManager/Patches/PatchCompiler.cs @@ -13,23 +13,14 @@ public IPatch CompilePatch(ProtoPatch protoPatch) { if (protoPatch == null) throw new ArgumentNullException(nameof(protoPatch)); - switch (protoPatch.command) + return protoPatch.command switch { - case Command.Insert: - return new InsertPatch(protoPatch.urlConfig, protoPatch.nodeType, protoPatch.passSpecifier); - - case Command.Edit: - return new EditPatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier); - - case Command.Copy: - return new CopyPatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier); - - case Command.Delete: - return new DeletePatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier); - - default: - throw new ArgumentException("has an invalid command for a root node: " + protoPatch.command, nameof(protoPatch)); - } + Command.Insert => new InsertPatch(protoPatch.urlConfig, protoPatch.nodeType, protoPatch.passSpecifier), + Command.Edit => new EditPatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier), + Command.Copy => new CopyPatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier), + Command.Delete => new DeletePatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier), + _ => throw new ArgumentException("has an invalid command for a root node: " + protoPatch.command, nameof(protoPatch)), + }; } } } diff --git a/ModuleManager/PostPatchLoader.cs b/ModuleManager/PostPatchLoader.cs index f92f1fad..1bccce78 100644 --- a/ModuleManager/PostPatchLoader.cs +++ b/ModuleManager/PostPatchLoader.cs @@ -9,6 +9,7 @@ using ModuleManager.Logging; using static ModuleManager.FilePathRepository; +using System.Diagnostics.CodeAnalysis; namespace ModuleManager { @@ -34,6 +35,7 @@ public static void AddPostPatchCallback(ModuleManagerPostPatchCallback callback) postPatchCallbacks.Add(callback); } + [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] private void Awake() { if (Instance != null) @@ -128,6 +130,8 @@ private IEnumerator Run() logger.Info("Reloading Part Upgrades"); PartUpgradeManager.Handler.FillUpgrades(); + LoadModdedPhysics(); + yield return null; progressTitle = "ModuleManager: Running post patch callbacks"; @@ -207,5 +211,21 @@ private IEnumerator Run() ready = true; } + + private void LoadModdedPhysics() + { + if (!File.Exists(physicsPath)) + { + logger.Error("Physics file not found"); + return; + } + + logger.Info("Setting modded physics as the active one"); + + PhysicsGlobals.PhysicsDatabaseFilename = physicsPath; + + if (!PhysicsGlobals.Instance.LoadDatabase()) + logger.Error("Something went wrong while setting the active physics config."); + } } } diff --git a/ModuleManager/Progress/PatchProgress.cs b/ModuleManager/Progress/PatchProgress.cs index 3cebf994..61fd0d33 100644 --- a/ModuleManager/Progress/PatchProgress.cs +++ b/ModuleManager/Progress/PatchProgress.cs @@ -8,7 +8,7 @@ public class PatchProgress : IPatchProgress { public ProgressCounter Counter { get; private set; } - private IBasicLogger logger; + private readonly IBasicLogger logger; public float ProgressFraction { diff --git a/ModuleManager/Properties/AssemblyInfo.cs b/ModuleManager/Properties/AssemblyInfo.cs index cf5d1a0c..12a660e1 100644 --- a/ModuleManager/Properties/AssemblyInfo.cs +++ b/ModuleManager/Properties/AssemblyInfo.cs @@ -17,7 +17,7 @@ // The form "{Major}.{Minor}.*" will automatically update the build and revision, // and "{Major}.{Minor}.{Build}.*" will update just the revision. -[assembly: AssemblyVersion("4.1.3")] +[assembly: AssemblyVersion("4.2.3")] [assembly: KSPAssembly("ModuleManager", 2, 5)] // The following attributes are used to specify the signing key for the assembly, diff --git a/ModuleManager/Threading/TaskStatus.cs b/ModuleManager/Threading/TaskStatus.cs index 92f8c237..1d2c6b67 100644 --- a/ModuleManager/Threading/TaskStatus.cs +++ b/ModuleManager/Threading/TaskStatus.cs @@ -4,12 +4,10 @@ namespace ModuleManager.Threading { public class TaskStatus : ITaskStatus { - private bool isRunning = true; - private Exception exception = null; - private object lockObject = new object(); + private readonly object lockObject = new object(); - public bool IsRunning => isRunning; - public Exception Exception => exception; + public bool IsRunning { get; private set; } = true; + public Exception Exception { get; private set; } = null; public bool IsFinished { @@ -17,7 +15,7 @@ public bool IsFinished { lock (lockObject) { - return !isRunning && exception == null; + return !IsRunning && Exception == null; } } } @@ -28,7 +26,7 @@ public bool IsExitedWithError { lock (lockObject) { - return !isRunning && exception != null; + return !IsRunning && Exception != null; } } } @@ -37,8 +35,8 @@ public void Finished() { lock (lockObject) { - if (!isRunning) throw new InvalidOperationException("Task is not running"); - isRunning = false; + if (!IsRunning) throw new InvalidOperationException("Task is not running"); + IsRunning = false; } } @@ -46,9 +44,9 @@ public void Error(Exception exception) { lock(lockObject) { - if (!isRunning) throw new InvalidOperationException("Task is not running"); - this.exception = exception ?? throw new ArgumentNullException(nameof(exception)); - isRunning = false; + if (!IsRunning) throw new InvalidOperationException("Task is not running"); + this.Exception = exception ?? throw new ArgumentNullException(nameof(exception)); + IsRunning = false; } } } diff --git a/ModuleManager/Threading/TaskStatusWrapper.cs b/ModuleManager/Threading/TaskStatusWrapper.cs index eff24f78..1750633c 100644 --- a/ModuleManager/Threading/TaskStatusWrapper.cs +++ b/ModuleManager/Threading/TaskStatusWrapper.cs @@ -4,7 +4,7 @@ namespace ModuleManager.Threading { public class TaskStatusWrapper : ITaskStatus { - private ITaskStatus inner; + private readonly ITaskStatus inner; public TaskStatusWrapper(ITaskStatus inner) { diff --git a/ModuleManager/Utils/FileUtils.cs b/ModuleManager/Utils/FileUtils.cs index e069e14c..fcf04482 100644 --- a/ModuleManager/Utils/FileUtils.cs +++ b/ModuleManager/Utils/FileUtils.cs @@ -11,15 +11,9 @@ public static string FileSHA(string filename) { if (!File.Exists(filename)) throw new FileNotFoundException("File does not exist", filename); - byte[] data = null; - - using (SHA256 sha = SHA256.Create()) - { - using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read)) - { - data = sha.ComputeHash(fs); - } - } + using SHA256 sha = SHA256.Create(); + using FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + byte[] data = sha.ComputeHash(fs); return data.ToHex(); } diff --git a/ModuleManagerTests/Collections/MessageQueueTest.cs b/ModuleManagerTests/Collections/MessageQueueTest.cs index 83bf1217..baf35d20 100644 --- a/ModuleManagerTests/Collections/MessageQueueTest.cs +++ b/ModuleManagerTests/Collections/MessageQueueTest.cs @@ -8,7 +8,7 @@ public class MessageQueueTest { private class TestClass { } - private MessageQueue queue = new MessageQueue(); + private readonly MessageQueue queue = new MessageQueue(); [Fact] public void Test__Empty() diff --git a/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs b/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs index f6c1fad7..74e82d88 100644 --- a/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs +++ b/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs @@ -1,7 +1,6 @@ using System; using Xunit; using NSubstitute; -using UnityEngine; using ModuleManager.Logging; using ModuleManager.Extensions; @@ -9,12 +8,7 @@ namespace ModuleManagerTests.Extensions { public class IBasicLoggerExtensionsTest { - private IBasicLogger logger; - - public IBasicLoggerExtensionsTest() - { - logger = Substitute.For(); - } + private readonly IBasicLogger logger = Substitute.For(); [Fact] public void TestInfo() diff --git a/ModuleManagerTests/Extensions/StringExtensionsTest.cs b/ModuleManagerTests/Extensions/StringExtensionsTest.cs index fdf3b33f..acf9274e 100644 --- a/ModuleManagerTests/Extensions/StringExtensionsTest.cs +++ b/ModuleManagerTests/Extensions/StringExtensionsTest.cs @@ -39,5 +39,35 @@ public void TestRemoveWS() { Assert.Equal("abcdef", " abc \tdef\r\n\t ".RemoveWS()); } + + + [InlineData("abc", "b", true, 1)] + [InlineData("abc", "x", false, -1)] + [Theory] + public void TestContains(string str, string test, bool expectedResult, int expectedIndex) + { + bool result = str.Contains(test, out int index); + Assert.Equal(expectedResult, result); + Assert.Equal(expectedIndex, index); + } + + [Fact] + public void TestContains__NullStr() + { + string s = null; + Assert.Throws(delegate + { + s.Contains("x", out int _x); + }); + } + + [Fact] + public void TestContains__NullValue() + { + Assert.Throws(delegate + { + "abc".Contains(null, out int _x); + }); + } } } diff --git a/ModuleManagerTests/Logging/PrefixLoggerTest.cs b/ModuleManagerTests/Logging/PrefixLoggerTest.cs index 28a82edc..5aaf0113 100644 --- a/ModuleManagerTests/Logging/PrefixLoggerTest.cs +++ b/ModuleManagerTests/Logging/PrefixLoggerTest.cs @@ -8,12 +8,11 @@ namespace ModuleManagerTests.Logging { public class PrefixLoggerTest { - private IBasicLogger innerLogger; - private PrefixLogger logger; + private readonly IBasicLogger innerLogger = Substitute.For(); + private readonly PrefixLogger logger; public PrefixLoggerTest() { - innerLogger = Substitute.For(); logger = new PrefixLogger("MyMod", innerLogger); } diff --git a/ModuleManagerTests/Logging/QueueLoggerTest.cs b/ModuleManagerTests/Logging/QueueLoggerTest.cs index dc8a1dfd..25e1abbe 100644 --- a/ModuleManagerTests/Logging/QueueLoggerTest.cs +++ b/ModuleManagerTests/Logging/QueueLoggerTest.cs @@ -8,12 +8,11 @@ namespace ModuleManagerTests.Logging { public class QueueLoggerTest { - private IMessageQueue queue; - private QueueLogger logger; + private readonly IMessageQueue queue = Substitute.For>(); + private readonly QueueLogger logger; public QueueLoggerTest() { - queue = Substitute.For>(); logger = new QueueLogger(queue); } diff --git a/ModuleManagerTests/Logging/StreamLoggerTest.cs b/ModuleManagerTests/Logging/StreamLoggerTest.cs index bc613038..296eeac2 100644 --- a/ModuleManagerTests/Logging/StreamLoggerTest.cs +++ b/ModuleManagerTests/Logging/StreamLoggerTest.cs @@ -11,12 +11,10 @@ public class StreamLoggerTest [Fact] public void TestConstructor__StreamNull() { - ArgumentNullException ex = Assert.Throws(delegate + Assert.Throws(delegate { new StreamLogger(null); }); - - Assert.Equal("stream", ex.ParamName); } [Fact] @@ -24,13 +22,10 @@ public void TestConstructor__CantWrite() { using (MemoryStream stream = new MemoryStream(new byte[0], false)) { - ArgumentException ex = Assert.Throws(delegate + Assert.Throws(delegate { new StreamLogger(stream); }); - - Assert.Equal("stream", ex.ParamName); - Assert.Contains("must be writable", ex.Message); } } diff --git a/ModuleManagerTests/Logging/UnityLoggerTest.cs b/ModuleManagerTests/Logging/UnityLoggerTest.cs index 5d820c25..7c4dc4a1 100644 --- a/ModuleManagerTests/Logging/UnityLoggerTest.cs +++ b/ModuleManagerTests/Logging/UnityLoggerTest.cs @@ -9,12 +9,11 @@ namespace ModuleManagerTests.Logging { public class UnityLoggerTest { - private ILogger innerLogger; - private UnityLogger logger; + private readonly ILogger innerLogger = Substitute.For(); + private readonly UnityLogger logger; public UnityLoggerTest() { - innerLogger = Substitute.For(); logger = new UnityLogger(innerLogger); } diff --git a/ModuleManagerTests/ModuleManagerTests.csproj b/ModuleManagerTests/ModuleManagerTests.csproj index b4fafe96..f3afbbf5 100644 --- a/ModuleManagerTests/ModuleManagerTests.csproj +++ b/ModuleManagerTests/ModuleManagerTests.csproj @@ -1,8 +1,8 @@  - + - + Debug @@ -37,23 +37,26 @@ 4 false + + 8.0 + - ..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll + ..\packages\Castle.Core.4.4.1\lib\net45\Castle.Core.dll - - ..\packages\NSubstitute.3.1.0\lib\net46\NSubstitute.dll + + ..\packages\NSubstitute.4.2.2\lib\net46\NSubstitute.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll - - ..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll @@ -156,10 +159,10 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + \ No newline at end of file diff --git a/ModuleManagerTests/NeedsCheckerTest.cs b/ModuleManagerTests/NeedsCheckerTest.cs index d0414a0b..4d3540b9 100644 --- a/ModuleManagerTests/NeedsCheckerTest.cs +++ b/ModuleManagerTests/NeedsCheckerTest.cs @@ -5,7 +5,6 @@ using ModuleManager; using ModuleManager.Logging; using ModuleManager.Progress; -using NodeStack = ModuleManager.Collections.ImmutableStack; namespace ModuleManagerTests { @@ -13,17 +12,13 @@ public class NeedsCheckerTest { private readonly UrlDir gameData; - private readonly IPatchProgress progress; - private readonly IBasicLogger logger; - private NeedsChecker needsChecker; + private readonly IPatchProgress progress = Substitute.For(); + private readonly IBasicLogger logger = Substitute.For(); + private readonly NeedsChecker needsChecker; public NeedsCheckerTest() { gameData = UrlBuilder.CreateGameData(); - - progress = Substitute.For(); - logger = Substitute.For(); - needsChecker = new NeedsChecker(new[] { "mod1", "mod2", "mod/2" }, gameData, progress, logger); } diff --git a/ModuleManagerTests/PassTest.cs b/ModuleManagerTests/PassTest.cs index d2cce882..bc829816 100644 --- a/ModuleManagerTests/PassTest.cs +++ b/ModuleManagerTests/PassTest.cs @@ -2,7 +2,6 @@ using System.Linq; using Xunit; using NSubstitute; -using TestUtils; using ModuleManager; using ModuleManager.Patches; @@ -10,13 +9,6 @@ namespace ModuleManagerTests { public class PassTest { - private UrlDir.UrlFile file; - - public PassTest() - { - file = UrlBuilder.CreateFile("abc/def.cfg"); - } - [Fact] public void TestConstructor__NameNull() { diff --git a/ModuleManagerTests/PatchExtractorTest.cs b/ModuleManagerTests/PatchExtractorTest.cs index 4106486e..49a12583 100644 --- a/ModuleManagerTests/PatchExtractorTest.cs +++ b/ModuleManagerTests/PatchExtractorTest.cs @@ -1,5 +1,4 @@ using System; -using System.Linq; using Xunit; using NSubstitute; using TestUtils; @@ -386,10 +385,5 @@ private void AssertNoErrors() progress.DidNotReceiveWithAnyArgs().Exception(null, null); progress.DidNotReceiveWithAnyArgs().Exception(null, null, null); } - - private void AssertConfigNodesEqual(ConfigNode expected, ConfigNode observed) - { - Assert.Equal(expected.ToString(), observed.ToString()); - } } } diff --git a/ModuleManagerTests/PatchListTest.cs b/ModuleManagerTests/PatchListTest.cs index 09b1c1dc..4dc5c751 100644 --- a/ModuleManagerTests/PatchListTest.cs +++ b/ModuleManagerTests/PatchListTest.cs @@ -113,6 +113,7 @@ public void Test__Lifecycle() Substitute.For(), Substitute.For(), Substitute.For(), + Substitute.For(), }; UrlDir.UrlConfig urlConfig = UrlBuilder.CreateConfig("abc/def", new ConfigNode("NODE")); @@ -139,8 +140,9 @@ public void Test__Lifecycle() patches[19].PassSpecifier.Returns(new AfterPassSpecifier("MOD2", urlConfig)); patches[20].PassSpecifier.Returns(new LastPassSpecifier("mod2")); patches[21].PassSpecifier.Returns(new LastPassSpecifier("MOD2")); - patches[22].PassSpecifier.Returns(new FinalPassSpecifier()); + patches[22].PassSpecifier.Returns(new LastPassSpecifier("mod3")); patches[23].PassSpecifier.Returns(new FinalPassSpecifier()); + patches[24].PassSpecifier.Returns(new FinalPassSpecifier()); patches[00].CountsAsPatch.Returns(false); patches[01].CountsAsPatch.Returns(false); @@ -166,6 +168,7 @@ public void Test__Lifecycle() patches[21].CountsAsPatch.Returns(true); patches[22].CountsAsPatch.Returns(true); patches[23].CountsAsPatch.Returns(true); + patches[24].CountsAsPatch.Returns(true); IPatchProgress progress = Substitute.For(); @@ -173,7 +176,7 @@ public void Test__Lifecycle() IPass[] passes = patchList.ToArray(); - Assert.Equal(12, passes.Length); + Assert.Equal(13, passes.Length); Assert.Equal(":INSERT (initial)", passes[0].Name); Assert.Equal(new[] { patches[0], patches[1] }, passes[0]); @@ -208,10 +211,13 @@ public void Test__Lifecycle() Assert.Equal(":LAST[MOD2]", passes[10].Name); Assert.Equal(new[] { patches[20], patches[21] }, passes[10]); - Assert.Equal(":FINAL", passes[11].Name); - Assert.Equal(new[] { patches[22], patches[23] }, passes[11]); + Assert.Equal(":LAST[MOD3]", passes[11].Name); + Assert.Equal(new[] { patches[22] }, passes[11]); + + Assert.Equal(":FINAL", passes[12].Name); + Assert.Equal(new[] { patches[23], patches[24] }, passes[12]); - progress.Received(22).PatchAdded(); + progress.Received(23).PatchAdded(); } } } diff --git a/ModuleManagerTests/Progress/PatchProgressTest.cs b/ModuleManagerTests/Progress/PatchProgressTest.cs index 8cde86c2..c78964e3 100644 --- a/ModuleManagerTests/Progress/PatchProgressTest.cs +++ b/ModuleManagerTests/Progress/PatchProgressTest.cs @@ -1,7 +1,6 @@ using System; using Xunit; using NSubstitute; -using UnityEngine; using TestUtils; using ModuleManager; using ModuleManager.Logging; @@ -11,12 +10,11 @@ namespace ModuleManagerTests { public class PatchProgressTest { - private IBasicLogger logger; - private PatchProgress progress; + private readonly IBasicLogger logger = Substitute.For(); + private readonly PatchProgress progress; public PatchProgressTest() { - logger = Substitute.For(); progress = new PatchProgress(logger); } diff --git a/ModuleManagerTests/app.config b/ModuleManagerTests/app.config index 1d152980..fe205877 100644 --- a/ModuleManagerTests/app.config +++ b/ModuleManagerTests/app.config @@ -4,11 +4,11 @@ - + - + diff --git a/ModuleManagerTests/packages.config b/ModuleManagerTests/packages.config index dc5635be..b159434d 100644 --- a/ModuleManagerTests/packages.config +++ b/ModuleManagerTests/packages.config @@ -1,9 +1,9 @@  - - - - + + + + @@ -11,6 +11,6 @@ - - + + \ No newline at end of file diff --git a/TestUtils/TestUtils.csproj b/TestUtils/TestUtils.csproj index 10073bd0..5c53b27c 100644 --- a/TestUtils/TestUtils.csproj +++ b/TestUtils/TestUtils.csproj @@ -32,6 +32,9 @@ 4 false + + 8.0 + diff --git a/TestUtilsTests/TestUtilsTests.csproj b/TestUtilsTests/TestUtilsTests.csproj index 619e6bb4..cfe71bf2 100644 --- a/TestUtilsTests/TestUtilsTests.csproj +++ b/TestUtilsTests/TestUtilsTests.csproj @@ -1,8 +1,8 @@  - + - + Debug @@ -37,6 +37,9 @@ 4 false + + 8.0 + @@ -86,10 +89,10 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - - + + \ No newline at end of file diff --git a/TestUtilsTests/packages.config b/TestUtilsTests/packages.config index bbb4cb82..8cf69e4f 100644 --- a/TestUtilsTests/packages.config +++ b/TestUtilsTests/packages.config @@ -7,6 +7,6 @@ - - + + \ No newline at end of file