From 588d4d94fa63198fec2a7b861ecea17cf2085cee Mon Sep 17 00:00:00 2001 From: Jesse Plamondon-Willard Date: Sun, 11 Mar 2018 20:30:57 -0400 Subject: fix some content managers not replaced early enough (#453, #413) --- src/SMAPI/Framework/SGame.cs | 39 ++++++++++++++++++++++----------------- src/SMAPI/Program.cs | 2 ++ 2 files changed, 24 insertions(+), 17 deletions(-) (limited to 'src/SMAPI') diff --git a/src/SMAPI/Framework/SGame.cs b/src/SMAPI/Framework/SGame.cs index aeaab9ea..47bc40e6 100644 --- a/src/SMAPI/Framework/SGame.cs +++ b/src/SMAPI/Framework/SGame.cs @@ -25,7 +25,7 @@ using StardewValley.Tools; using xTile.Dimensions; #if !STARDEW_VALLEY_1_3 using xTile.Layers; - #endif +#endif namespace StardewModdingAPI.Framework { @@ -35,6 +35,16 @@ namespace StardewModdingAPI.Framework /********* ** Properties *********/ + /**** + ** Constructor hack + ****/ + /// A static instance of to use while is initialising, which happens before the constructor runs. + internal static IMonitor MonitorDuringInitialisation; + + /// A static instance of to use while is initialising, which happens before the constructor runs. + internal static Reflector ReflectorDuringInitialisation; + + /**** ** SMAPI state ****/ @@ -161,7 +171,7 @@ namespace StardewModdingAPI.Framework ** Accessors *********/ /// SMAPI's content manager. - public ContentCore ContentCore { get; } + public ContentCore ContentCore { get; private set; } /// Whether SMAPI should log more information about the game context. public bool VerboseLogging { get; set; } @@ -184,18 +194,18 @@ namespace StardewModdingAPI.Framework SGame.Instance = this; SGame.Reflection = reflection; this.OnGameInitialised = onGameInitialised; + if (this.ContentCore == null) // shouldn't happen since CreateContentManager is called first, but let's init here just in case + this.ContentCore = new ContentCore(this.Content.ServiceProvider, this.Content.RootDirectory, Thread.CurrentThread.CurrentUICulture, null, this.Monitor, reflection); // set XNA option required by Stardew Valley Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef; - // override content manager +#if !STARDEW_VALLEY_1_3 + // replace already-created content managers this.Monitor?.Log("Overriding content manager...", LogLevel.Trace); - this.ContentCore = new ContentCore(this.Content.ServiceProvider, this.Content.RootDirectory, Thread.CurrentThread.CurrentUICulture, null, this.Monitor, reflection); this.Content = this.ContentCore.CreateContentManager("SGame.Content"); - Game1.content = this.ContentCore.CreateContentManager("Game1.content"); - - // replace already-created temporary content managers reflection.GetField(typeof(Game1), "_temporaryContent").SetValue(this.ContentCore.CreateContentManager("Game1._temporaryContent")); // regenerate value with new content manager +#endif } /**** @@ -206,19 +216,14 @@ namespace StardewModdingAPI.Framework /// The root directory to search for content. protected override LocalizedContentManager CreateContentManager(IServiceProvider serviceProvider, string rootDirectory) { - // return default if SMAPI's content manager isn't initialised yet + // NOTE: this method is called from the Game1 constructor, before the SGame constructor runs. + // Don't depend on anything being initialised at this point. if (this.ContentCore == null) { - this.Monitor?.Log("SMAPI's content manager isn't initialised; skipping content manager interception.", LogLevel.Trace); - return base.CreateContentManager(serviceProvider, rootDirectory); + this.ContentCore = new ContentCore(serviceProvider, rootDirectory, Thread.CurrentThread.CurrentUICulture, null, SGame.MonitorDuringInitialisation, SGame.ReflectorDuringInitialisation); + SGame.MonitorDuringInitialisation = null; } - - // return single instance if valid - if (serviceProvider != this.Content.ServiceProvider) - throw new InvalidOperationException("SMAPI uses a single content manager internally. You can't get a new content manager with a different service provider."); - if (rootDirectory != this.Content.RootDirectory) - throw new InvalidOperationException($"SMAPI uses a single content manager internally. You can't get a new content manager with a different root directory (current is {this.Content.RootDirectory}, requested {rootDirectory})."); - return this.ContentCore.CreateContentManager("(generated instance)"); + return this.ContentCore.CreateContentManager("(generated)", rootDirectory); } /// The method called when the game is updating its state. This happens roughly 60 times per second. diff --git a/src/SMAPI/Program.cs b/src/SMAPI/Program.cs index 39a5754b..e713add5 100644 --- a/src/SMAPI/Program.cs +++ b/src/SMAPI/Program.cs @@ -190,6 +190,8 @@ namespace StardewModdingAPI AppDomain.CurrentDomain.UnhandledException += (sender, e) => this.Monitor.Log($"Critical app domain exception: {e.ExceptionObject}", LogLevel.Error); // override game + SGame.MonitorDuringInitialisation = this.Monitor; + SGame.ReflectorDuringInitialisation = this.Reflection; this.GameInstance = new SGame(this.Monitor, this.Reflection, this.EventManager, this.InitialiseAfterGameStart); StardewValley.Program.gamePtr = this.GameInstance; -- cgit