protected override void Initialize() { base.Initialize(); this.InitializeSqm(); IServiceProvider serviceProvider = this; var activeSolutionBoundTracker = this.GetMefService <IActiveSolutionBoundTracker>(); var sonarQubeService = this.GetMefService <ISonarQubeService>(); var workspace = this.GetMefService <VisualStudioWorkspace>(); logger = this.GetMefService <ILogger>(); Debug.Assert(logger != null, "MEF composition error - failed to retrieve a logger"); var vsSolution = serviceProvider.GetService <SVsSolution, IVsSolution>(); this.sonarAnalyzerManager = new SonarAnalyzerManager(activeSolutionBoundTracker, sonarQubeService, workspace, vsSolution, logger); this.usageAnalyzer = new BoundSolutionAnalyzer(serviceProvider); this.commandManager = new PackageCommandManager(serviceProvider.GetService <IMenuCommandService>()); this.commandManager.Initialize(serviceProvider.GetMefService <ITeamExplorerController>(), serviceProvider.GetMefService <IProjectPropertyManager>()); this.deprecationManager = new DeprecationManager(this.GetMefService <IInfoBarManager>(), logger); }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="modID">The unique ID of the relevant mod.</param> /// <param name="modName">The mod name for error messages.</param> /// <param name="reflector">The underlying reflection helper.</param> /// <param name="deprecationManager">Manages deprecation warnings.</param> public ReflectionHelper(string modID, string modName, Reflector reflector, DeprecationManager deprecationManager) : base(modID) { this.ModName = modName; this.Reflector = reflector; this.DeprecationManager = deprecationManager; }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="modID">The mod's unique ID.</param> /// <param name="modDirectory">The full path to the mod's folder.</param> /// <param name="jsonHelper">Encapsulate SMAPI's JSON parsing.</param> /// <param name="inputState">Manages the game's input state.</param> /// <param name="events">Manages access to events raised by SMAPI.</param> /// <param name="contentHelper">An API for loading content assets.</param> /// <param name="commandHelper">An API for managing console commands.</param> /// <param name="dataHelper">An API for reading and writing persistent mod data.</param> /// <param name="modRegistry">an API for fetching metadata about loaded mods.</param> /// <param name="reflectionHelper">An API for accessing private game code.</param> /// <param name="multiplayer">Provides multiplayer utilities.</param> /// <param name="translationHelper">An API for reading translations stored in the mod's <c>i18n</c> folder.</param> /// <param name="contentPacks">The content packs loaded for this mod.</param> /// <param name="createContentPack">Create a transitional content pack.</param> /// <param name="deprecationManager">Manages deprecation warnings.</param> /// <exception cref="ArgumentNullException">An argument is null or empty.</exception> /// <exception cref="InvalidOperationException">The <paramref name="modDirectory"/> path does not exist on disk.</exception> public ModHelper(string modID, string modDirectory, JsonHelper jsonHelper, SInputState inputState, IModEvents events, IContentHelper contentHelper, ICommandHelper commandHelper, IDataHelper dataHelper, IModRegistry modRegistry, IReflectionHelper reflectionHelper, IMultiplayerHelper multiplayer, ITranslationHelper translationHelper, IEnumerable <IContentPack> contentPacks, Func <string, IManifest, IContentPack> createContentPack, DeprecationManager deprecationManager) : base(modID) { // validate directory if (string.IsNullOrWhiteSpace(modDirectory)) { throw new ArgumentNullException(nameof(modDirectory)); } if (!Directory.Exists(modDirectory)) { throw new InvalidOperationException("The specified mod directory does not exist."); } // initialise this.DirectoryPath = modDirectory; this.JsonHelper = jsonHelper ?? throw new ArgumentNullException(nameof(jsonHelper)); this.Content = contentHelper ?? throw new ArgumentNullException(nameof(contentHelper)); this.Data = dataHelper ?? throw new ArgumentNullException(nameof(dataHelper)); this.Input = new InputHelper(modID, inputState); this.ModRegistry = modRegistry ?? throw new ArgumentNullException(nameof(modRegistry)); this.ConsoleCommands = commandHelper ?? throw new ArgumentNullException(nameof(commandHelper)); this.Reflection = reflectionHelper ?? throw new ArgumentNullException(nameof(reflectionHelper)); this.Multiplayer = multiplayer ?? throw new ArgumentNullException(nameof(multiplayer)); this.Translation = translationHelper ?? throw new ArgumentNullException(nameof(translationHelper)); this.ContentPacks = contentPacks.ToArray(); this.CreateContentPack = createContentPack; this.DeprecationManager = deprecationManager; this.Events = events; }
protected override void Dispose(bool disposing) { base.Dispose(disposing); if (disposing) { this.sonarAnalyzerManager?.Dispose(); this.sonarAnalyzerManager = null; this.deprecationManager?.Dispose(); this.deprecationManager = null; } }
/// <summary>Construct an instance.</summary> /// <param name="writeToConsole">Whether to output log messages to the console.</param> /// <param name="logPath">The full file path to which to write log messages.</param> internal Program(bool writeToConsole, string logPath) { // load settings this.Settings = JsonConvert.DeserializeObject <SConfig>(File.ReadAllText(Constants.ApiConfigPath)); // initialise this.LogFile = new LogFileManager(logPath); this.Monitor = new Monitor("SMAPI", this.ConsoleManager, this.LogFile, this.ExitGameImmediately) { WriteToConsole = writeToConsole }; this.ModRegistry = new ModRegistry(this.Settings.ModCompatibility); this.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry); }
protected override void Initialize() { base.Initialize(); this.InitializeSqm(); IServiceProvider serviceProvider = this; this.sonarAnalyzerManager = new SonarAnalyzerManager(serviceProvider); this.suppressionManager = new SuppressionManager(serviceProvider); this.usageAnalyzer = new BoundSolutionAnalyzer(serviceProvider); this.commandManager = new PackageCommandManager(serviceProvider); this.commandManager.Initialize(); this.deprecationManager = new DeprecationManager(this.GetMefService <IInfoBarManager>(), this.GetMefService <ISonarLintOutput>()); this.deprecationManager.Initialize(VisualStudioHelpers.VisualStudioVersion); }
private async System.Threading.Tasks.Task InitOnUIThreadAsync() { Debug.Assert(ThreadHelper.CheckAccess(), "SonarLint package - expecteding to be called in the UI thread"); try { logger = await this.GetMefServiceAsync <ILogger>(); Debug.Assert(logger != null, "MEF composition error - failed to retrieve a logger"); logger.WriteLine(Resources.Strings.SL_Initializing); this.InitializeSqm(); IServiceProvider serviceProvider = this; var activeSolutionBoundTracker = await this.GetMefServiceAsync <IActiveSolutionBoundTracker>(); var sonarQubeService = await this.GetMefServiceAsync <ISonarQubeService>(); var workspace = await this.GetMefServiceAsync <VisualStudioWorkspace>(); var vsSolution = serviceProvider.GetService <SVsSolution, IVsSolution>(); this.sonarAnalyzerManager = new SonarAnalyzerManager(activeSolutionBoundTracker, sonarQubeService, workspace, vsSolution, logger); this.usageAnalyzer = new BoundSolutionAnalyzer(serviceProvider); this.commandManager = new PackageCommandManager(serviceProvider.GetService <IMenuCommandService>()); this.commandManager.Initialize(serviceProvider.GetMefService <ITeamExplorerController>(), serviceProvider.GetMefService <IProjectPropertyManager>()); this.deprecationManager = new DeprecationManager(this.GetMefService <IInfoBarManager>(), logger); logger.WriteLine(Resources.Strings.SL_InitializationComplete); } catch (Exception ex) when(!ErrorHandler.IsCriticalException(ex)) { // Suppress non-critical exceptions logger.WriteLine(Resources.Strings.SL_ERROR, ex.Message); } }
public void Dispose__WhenInitialized_CallsCloseOnTheBar() { // Arrange VisualStudioHelpers.VisualStudioVersion = "0.0.0.0"; var sonarLintOutputMock = new Mock <ILogger>(); var inforBarManagerMock = new Mock <IInfoBarManager>(); var infoBar = new Mock <IInfoBar>(); inforBarManagerMock .Setup(x => x.AttachInfoBar(DeprecationManager.DeprecationBarGuid, It.IsAny <string>(), It.IsAny <SonarLintImageMoniker>())) .Returns(infoBar.Object); var deprecationManager = new DeprecationManager(inforBarManagerMock.Object, sonarLintOutputMock.Object); // Act deprecationManager.Dispose(); // Assert infoBar.Verify(x => x.Close(), Times.Once); }
private void AssertShowsWarnings(string version, Times numberOfTimes) { // Arrange VisualStudioHelpers.VisualStudioVersion = version; var sonarLintOutputMock = new Mock <ILogger>(); var inforBarManagerMock = new Mock <IInfoBarManager>(); string expectedOutputMessage = "*****************************************************************************************\r\n" + "*** SonarLint for Visual Studio versions 4.0+ will no longer support this version ***\r\n" + "*** of Visual Studio. Please update to Visual Studio 2015 Update 3 or ***\r\n" + "*** Visual Studio 2017 to benefit from new features. ***\r\n" + "*****************************************************************************************"; string expectedBarMessage = "SonarLint for Visual Studio versions 4.0+ will no longer support this version of Visual " + "Studio. Please update to Visual Studio 2015 Update 3 or Visual Studio 2017 to benefit from new features."; // Act var deprecationManager = new DeprecationManager(inforBarManagerMock.Object, sonarLintOutputMock.Object); // Assert sonarLintOutputMock.Verify(x => x.WriteLine(expectedOutputMessage), numberOfTimes); inforBarManagerMock.Verify(x => x.AttachInfoBar(DeprecationManager.DeprecationBarGuid, expectedBarMessage, It.IsAny <SonarLintImageMoniker>()), numberOfTimes); }
/********* ** Public methods *********/ /// <summary>Injects types required for backwards compatibility.</summary> /// <param name="deprecationManager">Manages deprecation warnings.</param> internal static void Shim(DeprecationManager deprecationManager) { Mod.DeprecationManager = deprecationManager; }
/********* ** Public methods *********/ /**** ** Command ****/ /// <summary>Injects types required for backwards compatibility.</summary> /// <param name="commandManager">Manages console commands.</param> /// <param name="deprecationManager">Manages deprecation warnings.</param> /// <param name="modRegistry">Tracks the installed mods.</param> internal static void Shim(CommandManager commandManager, DeprecationManager deprecationManager, ModRegistry modRegistry) { Command.CommandManager = commandManager; Command.DeprecationManager = deprecationManager; Command.ModRegistry = modRegistry; }
/********* ** Public methods *********/ /// <summary>Injects types required for backwards compatibility.</summary> /// <param name="deprecationManager">Manages deprecation warnings.</param> /// <param name="monitor">The underlying logger.</param> /// <param name="modRegistry">Tracks the installed mods.</param> internal static void Shim(DeprecationManager deprecationManager, Monitor monitor, ModRegistry modRegistry) { Log.DeprecationManager = deprecationManager; Log.Monitor = monitor; Log.ModRegistry = modRegistry; }
/********* ** Internal methods *********/ /// <summary>Injects types required for backwards compatibility.</summary> /// <param name="deprecationManager">Manages deprecation warnings.</param> internal static void Shim(DeprecationManager deprecationManager) { PlayerEvents.DeprecationManager = deprecationManager; }
/// <summary>Initialise SMAPI and mods after the game starts.</summary> private void InitialiseAfterGameStart() { // load settings this.Settings = JsonConvert.DeserializeObject <SConfig>(File.ReadAllText(Constants.ApiConfigPath)); this.GameInstance.VerboseLogging = this.Settings.VerboseLogging; // load core components this.ModRegistry = new ModRegistry(); this.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry); this.CommandManager = new CommandManager(); #if SMAPI_1_x // inject compatibility shims #pragma warning disable 618 Command.Shim(this.CommandManager, this.DeprecationManager, this.ModRegistry); Config.Shim(this.DeprecationManager); Log.Shim(this.DeprecationManager, this.GetSecondaryMonitor("legacy mod"), this.ModRegistry); Mod.Shim(this.DeprecationManager); GameEvents.Shim(this.DeprecationManager); PlayerEvents.Shim(this.DeprecationManager); TimeEvents.Shim(this.DeprecationManager); #pragma warning restore 618 #endif // redirect direct console output { Monitor monitor = this.GetSecondaryMonitor("Console.Out"); if (monitor.WriteToConsole) { this.ConsoleManager.OnMessageIntercepted += message => this.HandleConsoleMessage(monitor, message); } } // add headers if (this.Settings.DeveloperMode) { this.Monitor.ShowTraceInConsole = true; #if !SMAPI_1_x this.Monitor.ShowFullStampInConsole = true; #endif this.Monitor.Log($"You configured SMAPI to run in developer mode. The console may be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info); } if (!this.Settings.CheckForUpdates) { this.Monitor.Log($"You configured SMAPI to not check for updates. Running an old version of SMAPI is not recommended. You can enable update checks by reinstalling SMAPI or editing {Constants.ApiConfigPath}.", LogLevel.Warn); } if (!this.Monitor.WriteToConsole) { this.Monitor.Log("Writing to the terminal is disabled because the --no-terminal argument was received. This usually means launching the terminal failed.", LogLevel.Warn); } if (this.Settings.VerboseLogging) { this.Monitor.Log("Verbose logging enabled.", LogLevel.Trace); } // validate XNB integrity if (!this.ValidateContentIntegrity()) { this.Monitor.Log("SMAPI found problems in your game's content files which are likely to cause errors or crashes. Consider uninstalling XNB mods or reinstalling the game.", LogLevel.Error); } // load mods { #if SMAPI_1_x this.Monitor.Log("Loading mod metadata..."); #else this.Monitor.Log("Loading mod metadata...", LogLevel.Trace); #endif ModResolver resolver = new ModResolver(); // load manifests IModMetadata[] mods = resolver.ReadManifests(Constants.ModPath, new JsonHelper(), this.Settings.ModCompatibility, this.Settings.DisabledMods).ToArray(); resolver.ValidateManifests(mods, Constants.ApiVersion); // check for deprecated metadata #if SMAPI_1_x IList <Action> deprecationWarnings = new List <Action>(); foreach (IModMetadata mod in mods.Where(m => m.Status != ModMetadataStatus.Failed)) { // missing fields that will be required in SMAPI 2.0 { List <string> missingFields = new List <string>(3); if (string.IsNullOrWhiteSpace(mod.Manifest.Name)) { missingFields.Add(nameof(IManifest.Name)); } if (mod.Manifest.Version == null || mod.Manifest.Version.ToString() == "0.0") { missingFields.Add(nameof(IManifest.Version)); } if (string.IsNullOrWhiteSpace(mod.Manifest.UniqueID)) { missingFields.Add(nameof(IManifest.UniqueID)); } if (missingFields.Any()) { deprecationWarnings.Add(() => this.Monitor.Log($"{mod.DisplayName} is missing some manifest fields ({string.Join(", ", missingFields)}) which will be required in an upcoming SMAPI version.", LogLevel.Warn)); } } // per-save directories if ((mod.Manifest as Manifest)?.PerSaveConfigs == true) { deprecationWarnings.Add(() => this.DeprecationManager.Warn(mod.DisplayName, $"{nameof(Manifest)}.{nameof(Manifest.PerSaveConfigs)}", "1.0", DeprecationLevel.PendingRemoval)); try { string psDir = Path.Combine(mod.DirectoryPath, "psconfigs"); Directory.CreateDirectory(psDir); if (!Directory.Exists(psDir)) { mod.SetStatus(ModMetadataStatus.Failed, "it requires per-save configuration files ('psconfigs') which couldn't be created for some reason."); } } catch (Exception ex) { mod.SetStatus(ModMetadataStatus.Failed, $"it requires per-save configuration files ('psconfigs') which couldn't be created: {ex.GetLogSummary()}"); } } } #endif // process dependencies mods = resolver.ProcessDependencies(mods).ToArray(); // load mods #if SMAPI_1_x this.LoadMods(mods, new JsonHelper(), this.ContentManager, deprecationWarnings); foreach (Action warning in deprecationWarnings) { warning(); } #else this.LoadMods(mods, new JsonHelper(), this.ContentManager); #endif } if (this.Monitor.IsExiting) { this.Monitor.Log("SMAPI shutting down: aborting initialisation.", LogLevel.Warn); return; } // update window titles int modsLoaded = this.ModRegistry.GetMods().Count(); this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} - running SMAPI {Constants.ApiVersion} with {modsLoaded} mods"; Console.Title = $"SMAPI {Constants.ApiVersion} - running Stardew Valley {Constants.GameVersion} with {modsLoaded} mods"; // start SMAPI console new Thread(this.RunConsoleLoop).Start(); }
public void TestsInitialize() { sonarLintOutputMock = new Mock <ISonarLintOutput>(); inforBarManagerMock = new Mock <IInfoBarManager>(); deprecationManager = new DeprecationManager(inforBarManagerMock.Object, sonarLintOutputMock.Object); }
/********* ** Private methods *********/ /// <summary>Initialise SMAPI and mods after the game starts.</summary> private void InitialiseAfterGameStart() { // load settings this.Settings = JsonConvert.DeserializeObject <SConfig>(File.ReadAllText(Constants.ApiConfigPath)); this.GameInstance.VerboseLogging = this.Settings.VerboseLogging; // load core components this.ModRegistry = new ModRegistry(this.Settings.ModCompatibility); this.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry); this.CommandManager = new CommandManager(); // inject compatibility shims #pragma warning disable 618 Command.Shim(this.CommandManager, this.DeprecationManager, this.ModRegistry); Config.Shim(this.DeprecationManager); InternalExtensions.Shim(this.ModRegistry); Log.Shim(this.DeprecationManager, this.GetSecondaryMonitor("legacy mod"), this.ModRegistry); Mod.Shim(this.DeprecationManager); ContentEvents.Shim(this.ModRegistry, this.Monitor); GameEvents.Shim(this.DeprecationManager); PlayerEvents.Shim(this.DeprecationManager); TimeEvents.Shim(this.DeprecationManager); #pragma warning restore 618 // redirect direct console output { Monitor monitor = this.GetSecondaryMonitor("Console.Out"); if (monitor.WriteToConsole) { this.ConsoleManager.OnMessageIntercepted += message => this.HandleConsoleMessage(monitor, message); } } // add headers if (this.Settings.DeveloperMode) { this.Monitor.ShowTraceInConsole = true; this.Monitor.Log($"You configured SMAPI to run in developer mode. The console may be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info); } if (!this.Settings.CheckForUpdates) { this.Monitor.Log($"You configured SMAPI to not check for updates. Running an old version of SMAPI is not recommended. You can enable update checks by reinstalling SMAPI or editing {Constants.ApiConfigPath}.", LogLevel.Warn); } if (!this.Monitor.WriteToConsole) { this.Monitor.Log("Writing to the terminal is disabled because the --no-terminal argument was received. This usually means launching the terminal failed.", LogLevel.Warn); } if (this.Settings.VerboseLogging) { this.Monitor.Log("Verbose logging enabled.", LogLevel.Trace); } // validate XNB integrity if (!this.ValidateContentIntegrity()) { this.Monitor.Log("SMAPI found problems in the game's XNB files which may cause errors or crashes while you're playing. Consider uninstalling XNB mods or reinstalling the game.", LogLevel.Warn); } // load mods int modsLoaded; { // load mods JsonHelper jsonHelper = new JsonHelper(); IList <Action> deprecationWarnings = new List <Action>(); ModMetadata[] mods = this.FindMods(Constants.ModPath, new JsonHelper(), deprecationWarnings); modsLoaded = this.LoadMods(mods, jsonHelper, (SContentManager)Game1.content, deprecationWarnings); // log deprecation warnings together foreach (Action warning in deprecationWarnings) { warning(); } } if (this.Monitor.IsExiting) { this.Monitor.Log("SMAPI shutting down: aborting initialisation.", LogLevel.Warn); return; } // update window titles this.GameInstance.Window.Title = $"Stardew Valley {Constants.GetGameDisplayVersion(Constants.GameVersion)} - running SMAPI {Constants.ApiVersion} with {modsLoaded} mods"; Console.Title = $"SMAPI {Constants.ApiVersion} - running Stardew Valley {Constants.GetGameDisplayVersion(Constants.GameVersion)} with {modsLoaded} mods"; // start SMAPI console new Thread(this.RunConsoleLoop).Start(); }
/********* ** Internal methods *********/ /// <summary>Injects types required for backwards compatibility.</summary> /// <param name="deprecationManager">Manages deprecation warnings.</param> internal static void Shim(DeprecationManager deprecationManager) { TimeEvents.DeprecationManager = deprecationManager; }
/// <summary>Initialise SMAPI and mods after the game starts.</summary> private void InitialiseAfterGameStart() { // load settings this.Settings = JsonConvert.DeserializeObject <SConfig>(File.ReadAllText(Constants.ApiConfigPath)); this.GameInstance.VerboseLogging = this.Settings.VerboseLogging; // load core components this.ModRegistry = new ModRegistry(); this.DeprecationManager = new DeprecationManager(this.Monitor, this.ModRegistry); this.CommandManager = new CommandManager(); // redirect direct console output { Monitor monitor = this.GetSecondaryMonitor("Console.Out"); if (monitor.WriteToConsole) { this.ConsoleManager.OnMessageIntercepted += message => this.HandleConsoleMessage(monitor, message); } } // add headers if (this.Settings.DeveloperMode) { this.Monitor.ShowTraceInConsole = true; this.Monitor.ShowFullStampInConsole = true; this.Monitor.Log($"You configured SMAPI to run in developer mode. The console may be much more verbose. You can disable developer mode by installing the non-developer version of SMAPI, or by editing {Constants.ApiConfigPath}.", LogLevel.Info); } if (!this.Settings.CheckForUpdates) { this.Monitor.Log($"You configured SMAPI to not check for updates. Running an old version of SMAPI is not recommended. You can enable update checks by reinstalling SMAPI or editing {Constants.ApiConfigPath}.", LogLevel.Warn); } if (!this.Monitor.WriteToConsole) { this.Monitor.Log("Writing to the terminal is disabled because the --no-terminal argument was received. This usually means launching the terminal failed.", LogLevel.Warn); } this.VerboseLog("Verbose logging enabled."); // validate XNB integrity if (!this.ValidateContentIntegrity()) { this.Monitor.Log("SMAPI found problems in your game's content files which are likely to cause errors or crashes. Consider uninstalling XNB mods or reinstalling the game.", LogLevel.Error); } // load mods { this.Monitor.Log("Loading mod metadata...", LogLevel.Trace); ModResolver resolver = new ModResolver(); // load manifests IModMetadata[] mods = resolver.ReadManifests(Constants.ModPath, new JsonHelper(), this.Settings.ModData).ToArray(); resolver.ValidateManifests(mods, Constants.ApiVersion, Constants.VendorModUrls); // process dependencies mods = resolver.ProcessDependencies(mods).ToArray(); // load mods this.LoadMods(mods, new JsonHelper(), this.ContentManager); // check for updates this.CheckForUpdatesAsync(mods); } if (this.Monitor.IsExiting) { this.Monitor.Log("SMAPI shutting down: aborting initialisation.", LogLevel.Warn); return; } // update window titles int modsLoaded = this.ModRegistry.GetMods().Count(); this.GameInstance.Window.Title = $"Stardew Valley {Constants.GameVersion} - running SMAPI {Constants.ApiVersion} with {modsLoaded} mods"; Console.Title = $"SMAPI {Constants.ApiVersion} - running Stardew Valley {Constants.GameVersion} with {modsLoaded} mods"; // start SMAPI console new Thread(this.RunConsoleLoop).Start(); }
/********* ** Public methods *********/ /// <summary>Injects types required for backwards compatibility.</summary> /// <param name="deprecationManager">Manages deprecation warnings.</param> internal static void Shim(DeprecationManager deprecationManager) { Config.DeprecationManager = deprecationManager; }