using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.ExceptionServices;
using System.Security;
using System.Text.RegularExpressions;
using System.Threading;
#if SMAPI_FOR_WINDOWS
using System.Windows.Forms;
#endif
using Newtonsoft.Json;
using StardewModdingAPI.Events;
using StardewModdingAPI.Framework;
using StardewModdingAPI.Framework.Events;
using StardewModdingAPI.Framework.Exceptions;
using StardewModdingAPI.Framework.Logging;
using StardewModdingAPI.Framework.ModData;
using StardewModdingAPI.Framework.Models;
using StardewModdingAPI.Framework.ModHelpers;
using StardewModdingAPI.Framework.ModLoading;
using StardewModdingAPI.Framework.Reflection;
using StardewModdingAPI.Framework.Serialisation;
using StardewModdingAPI.Framework.Utilities;
using StardewModdingAPI.Internal;
using StardewModdingAPI.Internal.Models;
using StardewValley;
using Monitor = StardewModdingAPI.Framework.Monitor;
using SObject = StardewValley.Object;
using ThreadState = System.Threading.ThreadState;
namespace StardewModdingAPI
{
/// <summary>The main entry point for SMAPI, responsible for hooking into and launching the game.</summary>
internal class Program : IDisposable
{
/*********
** Properties
*********/
/// <summary>The log file to which to write messages.</summary>
private readonly LogFileManager LogFile;
/// <summary>Manages console output interception.</summary>
private readonly ConsoleInterceptionManager ConsoleManager = new ConsoleInterceptionManager();
/// <summary>The core logger and monitor for SMAPI.</summary>
private readonly Monitor Monitor;
/// <summary>Tracks whether the game should exit immediately and any pending initialisation should be cancelled.</summary>
private readonly CancellationTokenSource CancellationTokenSource = new CancellationTokenSource();
/// <summary>Simplifies access to private game code.</summary>
private readonly Reflector Reflection = new Reflector();
/// <summary>The SMAPI configuration settings.</summary>
private readonly SConfig Settings;
/// <summary>The underlying game instance.</summary>
private SGame GameInstance;
/// <summary>The underlying content manager.</summary>
private ContentCoordinator ContentCore => this.GameInstance.ContentCore;
/// <summary>Tracks the installed mods.</summary>
/// <remarks>This is initialised after the game starts.</remarks>
private readonly ModRegistry ModRegistry = new ModRegistry();
/// <summary>Manages deprecation warnings.</summary>
/// <remarks>This is initialised after the game starts.</remarks>
private DeprecationManager DeprecationManager;
/// <summary>Manages console commands.</summary>
/// <remarks>This is initialised after the game starts.</remarks>
private CommandManager CommandManager;
/// <summary>Manages SMAPI events for mods.</summary>
private readonly EventManager EventManager;
/// <summary>Whether the game is currently running.</summary>
private bool IsGameRunning;
/// <summary>Whether the program has been disposed.</summary>
private bool IsDisposed;
/// <summary>Regex patterns which match console messages to suppress from the console and log.</summary>
private readonly Regex[] SuppressConsolePatterns =
{
new Regex(@"^TextBox\.Selected is now '(?:True|False)'\.$", RegexOptions.Compiled | RegexOptions.CultureInvariant),
new Regex(@"^(?:FRUIT )?TREE: IsClient:(?:True|False) randomOutput: \d+$", RegexOptions.Compiled | RegexOptions.CultureInvariant),
new Regex(@"^loadPreferences\(\); begin", RegexOptions.Compiled | RegexOptions.CultureInvariant),
new Regex(@"^savePreferences\(\); async=", RegexOptions.Compiled | RegexOptions.CultureInvariant),
new Regex(@"^Multiplayer auth success$", RegexOptions.Compiled | RegexOptions.CultureInvariant),
new Regex(@"^DebugOutput: added CLOUD", RegexOptions.Compiled | RegexOptions.CultureInvariant)
};
/// <summary>Encapsulates SMAPI's JSON file parsing.</summary>
private readonly JsonHelper JsonHelper = new