From 4e26cb7abc6fb699f0df9ddf1d50bc3ef2fe01c6 Mon Sep 17 00:00:00 2001 From: ClxS Date: Thu, 3 Mar 2016 18:50:22 +0000 Subject: Resolved static analysis issues Standardised event handlers so there's less hassle with future changes --- StardewModdingAPI/Program.cs | 1026 +++++++++++++++++++++--------------------- 1 file changed, 513 insertions(+), 513 deletions(-) (limited to 'StardewModdingAPI/Program.cs') diff --git a/StardewModdingAPI/Program.cs b/StardewModdingAPI/Program.cs index 313fcbe5..0903a9b9 100644 --- a/StardewModdingAPI/Program.cs +++ b/StardewModdingAPI/Program.cs @@ -1,513 +1,513 @@ -using System; -using System.CodeDom.Compiler; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Reflection.Emit; -using System.Text; -using System.Threading; -using System.Threading.Tasks; -using System.Windows.Forms; -using Microsoft.CSharp; -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; -using Microsoft.Xna.Framework.Input; -using StardewModdingAPI.Inheritance; -using StardewModdingAPI.Inheritance.Menus; -using StardewValley; -using StardewValley.Menus; -using StardewValley.Minigames; -using StardewValley.Network; -using StardewValley.Tools; -using Keys = Microsoft.Xna.Framework.Input.Keys; -using Object = StardewValley.Object; - -namespace StardewModdingAPI -{ - public class Program - { - public static string ExecutionPath { get; private set; } - public static string DataPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")); - public static List ModPaths = new List(); - public static List ModContentPaths = new List(); - public static string LogPath = Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "ErrorLogs"); - public static string CurrentLog { get; private set; } - public static StreamWriter LogStream { get; private set; } - - public static Texture2D DebugPixel { get; private set; } - - public static SGame gamePtr; - public static bool ready; - - public static Assembly StardewAssembly; - public static Type StardewProgramType; - public static FieldInfo StardewGameInfo; - public static Form StardewForm; - - public static Thread gameThread; - public static Thread consoleInputThread; - - public const string Version = "0.36 Alpha"; - public const bool debug = true; - public static bool disableLogging { get; private set; } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - - private static void Main(string[] args) - { - Console.Title = "Stardew Modding API Console"; - - Console.Title += " - Version " + Version; - if (debug) - Console.Title += " - DEBUG IS NOT FALSE, AUTHOUR NEEDS TO REUPLOAD THIS VERSION"; - - //TODO: Have an app.config and put the paths inside it so users can define locations to load mods from - ExecutionPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); - ModPaths.Add(Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "Mods")); - ModPaths.Add(Path.Combine(ExecutionPath, "Mods")); - ModPaths.Add(Path.Combine(Path.Combine(ExecutionPath, "Mods"), "Content")); - ModContentPaths.Add(Path.Combine(Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "Mods"), "Content")); - - //Checks that all defined modpaths exist as directories - foreach (string ModPath in ModPaths) - { - try - { - if (File.Exists(ModPath)) - File.Delete(ModPath); - if (!Directory.Exists(ModPath)) - Directory.CreateDirectory(ModPath); - } - catch (Exception ex) - { - - LogError("Could not create a missing ModPath: " + ModPath + "\n\n" + ex); - } - } - //Same for content - foreach (string ModContentPath in ModContentPaths) - { - try - { - if (!Directory.Exists(ModContentPath)) - Directory.CreateDirectory(ModContentPath); - } - catch (Exception ex) - { - LogError("Could not create a missing ModContentPath: " + ModContentPath + "\n\n" + ex); - } - } - //And then make sure we have an errorlog dir - try - { - if (!Directory.Exists(LogPath)) - Directory.CreateDirectory(LogPath); - } - catch (Exception ex) - { - LogError("Could not create the missing ErrorLogs path: " + LogPath + "\n\n" + ex); - } - - //Define the path to the current log file - CurrentLog = LogPath + "\\MODDED_ProgramLog_LATEST"/* + System.DateTime.Now.Ticks + */ + ".txt"; - - Log(ExecutionPath, false); - - //Create a writer to the log file - try - { - LogStream = new StreamWriter(CurrentLog, false); - } - catch (Exception ex) - { - disableLogging = true; - LogError("Could not initialize LogStream - Logging is disabled"); - } - - - LogInfo("Initializing SDV Assembly..."); - if (!File.Exists(ExecutionPath + "\\Stardew Valley.exe")) - { - //If the api isn't next to SDV.exe then terminate. Though it'll crash before we even get here w/o sdv.exe. Perplexing. - LogError("Could not find: " + ExecutionPath + "\\Stardew Valley.exe"); - LogError("The API will now terminate."); - Console.ReadKey(); - Environment.Exit(-4); - } - - //Load in that assembly. Also, ignore security :D - StardewAssembly = Assembly.UnsafeLoadFrom(ExecutionPath + "\\Stardew Valley.exe"); - StardewProgramType = StardewAssembly.GetType("StardewValley.Program", true); - StardewGameInfo = StardewProgramType.GetField("gamePtr"); - - //Change the game's version - LogInfo("Injecting New SDV Version..."); - Game1.version += "-Z_MODDED | SMAPI " + Version; - - //Create the thread for the game to run in. - gameThread = new Thread(RunGame); - LogInfo("Starting SDV..."); - gameThread.Start(); - - //I forget. - SGame.GetStaticFields(); - - while (!ready) - { - //Wait for the game to load up - } - - //SDV is running - Log("SDV Loaded Into Memory"); - - //Create definition to listen for input - LogInfo("Initializing Console Input Thread..."); - consoleInputThread = new Thread(ConsoleInputThread); - - //The only command in the API (at least it should be, for now) - Command.RegisterCommand("help", "Lists all commands | 'help ' returns command description").CommandFired += help_CommandFired; - //Command.RegisterCommand("crash", "crashes sdv").CommandFired += delegate { Game1.player.draw(null); }; - - //Subscribe to events - Events.KeyPressed += Events_KeyPressed; - Events.LoadContent += Events_LoadContent; - //Events.MenuChanged += Events_MenuChanged; //Idk right now - if (debug) - { - //Experimental - //Events.LocationsChanged += Events_LocationsChanged; - //Events.CurrentLocationChanged += Events_CurrentLocationChanged; - } - - //Do tweaks using winforms invoke because I'm lazy - LogInfo("Applying Final SDV Tweaks..."); - StardewInvoke(() => - { - gamePtr.IsMouseVisible = false; - gamePtr.Window.Title = "Stardew Valley - Version " + Game1.version; - StardewForm.Resize += Events.InvokeResize; - }); - - //Game's in memory now, send the event - LogInfo("Game Loaded"); - Events.InvokeGameLoaded(); - - LogColour(ConsoleColor.Cyan, "Type 'help' for help, or 'help ' for a command's usage"); - //Begin listening to input - consoleInputThread.Start(); - - - while (ready) - { - //Check if the game is still running 10 times a second - Thread.Sleep(1000 / 10); - } - - //abort the thread, we're closing - if (consoleInputThread != null && consoleInputThread.ThreadState == ThreadState.Running) - consoleInputThread.Abort(); - - LogInfo("Game Execution Finished"); - LogInfo("Shutting Down..."); - Thread.Sleep(100); - /* - int time = 0; - int step = 100; - int target = 1000; - while (true) - { - time += step; - Thread.Sleep(step); - - Console.Write("."); - - if (time >= target) - break; - } - */ - Environment.Exit(0); - } - - - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - - - public static void RunGame() - { - //Does this even do anything??? - Application.ThreadException += Application_ThreadException; - Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - //I've yet to see it called :| - - try - { - gamePtr = new SGame(); - LogInfo("Patching SDV Graphics Profile..."); - Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef; - LoadMods(); - - StardewForm = Control.FromHandle(Program.gamePtr.Window.Handle).FindForm(); - StardewForm.Closing += StardewForm_Closing; - StardewGameInfo.SetValue(StardewProgramType, gamePtr); - - ready = true; - - gamePtr.Run(); - } - catch (Exception ex) - { - LogError("Game failed to start: " + ex); - } - } - - static void StardewForm_Closing(object sender, CancelEventArgs e) - { - e.Cancel = true; - gamePtr.Exit(); - gamePtr.Dispose(); - StardewForm.Hide(); - ready = false; - } - - public static void LoadMods() - { - LogColour(ConsoleColor.Green, "LOADING MODS"); - int loadedMods = 0; - foreach (string ModPath in ModPaths) - { - foreach (String s in Directory.GetFiles(ModPath, "*.dll")) - { - LogColour(ConsoleColor.Green, "Found DLL: " + s); - try - { - Assembly mod = Assembly.UnsafeLoadFrom(s); //to combat internet-downloaded DLLs - - if (mod.DefinedTypes.Count(x => x.BaseType == typeof (Mod)) > 0) - { - LogColour(ConsoleColor.Green, "Loading Mod DLL..."); - TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof (Mod)); - Mod m = (Mod) mod.CreateInstance(tar.ToString()); - Console.WriteLine("LOADED MOD: {0} by {1} - Version {2} | Description: {3}", m.Name, m.Authour, m.Version, m.Description); - loadedMods += 1; - m.Entry(); - } - else - { - LogError("Invalid Mod DLL"); - } - } - catch (Exception ex) - { - LogError("Failed to load mod '{0}'. Exception details:\n" + ex, s); - } - } - } - LogColour(ConsoleColor.Green, "LOADED {0} MODS", loadedMods); - } - - public static void ConsoleInputThread() - { - string input = string.Empty; - - while (true) - { - Command.CallCommand(Console.ReadLine()); - } - } - - static void Events_LoadContent() - { - LogInfo("Initializing Debug Assets..."); - DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1); - DebugPixel.SetData(new Color[] { Color.White }); - - if (debug) - { - LogColour(ConsoleColor.Magenta, "REGISTERING BASE CUSTOM ITEM"); - SObject so = new SObject(); - so.Name = "Mario Block"; - so.CategoryName = "SMAPI Test Mod"; - so.Description = "It's a block from Mario!\nLoaded in realtime by SMAPI."; - so.Texture = Texture2D.FromStream(Game1.graphics.GraphicsDevice, new FileStream(ModContentPaths[0] + "\\Test.png", FileMode.Open)); - so.IsPassable = true; - so.IsPlaceable = true; - LogColour(ConsoleColor.Cyan, "REGISTERED WITH ID OF: " + SGame.RegisterModItem(so)); - - LogColour(ConsoleColor.Magenta, "REGISTERING SECOND CUSTOM ITEM"); - SObject so2 = new SObject(); - so2.Name = "Mario Painting"; - so2.CategoryName = "SMAPI Test Mod"; - so2.Description = "It's a painting of a creature from Mario!\nLoaded in realtime by SMAPI."; - so2.Texture = Texture2D.FromStream(Game1.graphics.GraphicsDevice, new FileStream(ModContentPaths[0] + "\\PaintingTest.png", FileMode.Open)); - so2.IsPassable = true; - so2.IsPlaceable = true; - LogColour(ConsoleColor.Cyan, "REGISTERED WITH ID OF: " + SGame.RegisterModItem(so2)); - } - - if (debug) - Command.CallCommand("load"); - } - - static void Events_KeyPressed(Keys key) - { - - } - - static void Events_MenuChanged(IClickableMenu newMenu) - { - LogInfo("NEW MENU: " + newMenu.GetType()); - if (newMenu is GameMenu) - { - Game1.activeClickableMenu = SGameMenu.ConstructFromBaseClass(Game1.activeClickableMenu as GameMenu); - } - } - - static void Events_LocationsChanged(List newLocations) - { - if (debug) - { - SGame.ModLocations = SGameLocation.ConstructFromBaseClasses(Game1.locations); - } - } - - static void Events_CurrentLocationChanged(GameLocation newLocation) - { - //SGame.CurrentLocation = null; - //System.Threading.Thread.Sleep(10); - if (debug) - { - Console.WriteLine(newLocation.name); - SGame.CurrentLocation = SGame.LoadOrCreateSGameLocationFromName(newLocation.name); - } - //Game1.currentLocation = SGame.CurrentLocation; - //LogInfo(((SGameLocation) newLocation).name); - //LogInfo("LOC CHANGED: " + SGame.currentLocation.name); - } - - public static void StardewInvoke(Action a) - { - StardewForm.Invoke(a); - } - - static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) - { - Console.WriteLine("An exception has been caught"); - File.WriteAllText(Program.LogPath + "\\MODDED_ErrorLog_" + Extensions.Random.Next(100000000, 999999999) + ".txt", e.ExceptionObject.ToString()); - } - - static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) - { - Console.WriteLine("A thread exception has been caught"); - File.WriteAllText(Program.LogPath + "\\MODDED_ErrorLog_" + Extensions.Random.Next(100000000, 999999999) + ".txt", e.Exception.ToString()); - } - - static void help_CommandFired(Command cmd) - { - if (cmd.CalledArgs.Length > 0) - { - Command fnd = Command.FindCommand(cmd.CalledArgs[0]); - if (fnd == null) - LogError("The command specified could not be found"); - else - { - if (fnd.CommandArgs.Length > 0) - LogInfo("{0}: {1} - {2}", fnd.CommandName, fnd.CommandDesc, fnd.CommandArgs.ToSingular()); - else - LogInfo("{0}: {1}", fnd.CommandName, fnd.CommandDesc); - } - } - else - LogInfo("Commands: " + Command.RegisteredCommands.Select(x => x.CommandName).ToSingular()); - } - - #region Logging - - public static void Log(object o, params object[] format) - { - if (format.Length > 0) - { - if (format[0] is bool) - { - if ((bool)format[0] == false) - { - //suppress logging to file - Console.WriteLine("[{0}] {1}", System.DateTime.Now.ToLongTimeString(), String.Format(o.ToString(), format)); - return; - } - } - } - string toLog = string.Format("[{0}] {1}", System.DateTime.Now.ToLongTimeString(), String.Format(o.ToString(), format)); - Console.WriteLine(toLog); - - if (!disableLogging) - { - LogStream.WriteLine(toLog); - LogStream.Flush(); - } - } - - public static void LogColour(ConsoleColor c, object o, params object[] format) - { - Console.ForegroundColor = c; - Log(o.ToString(), format); - Console.ForegroundColor = ConsoleColor.Gray; - } - - public static void LogInfo(object o, params object[] format) - { - Console.ForegroundColor = ConsoleColor.Yellow; - Log(o.ToString(), format); - Console.ForegroundColor = ConsoleColor.Gray; - } - - public static void LogError(object o, params object[] format) - { - Console.ForegroundColor = ConsoleColor.Red; - Log(o.ToString(), format); - Console.ForegroundColor = ConsoleColor.Gray; - } - - public static void LogDebug(object o, params object[] format) - { - if (!debug) - return; - Console.ForegroundColor = ConsoleColor.DarkYellow; - Log(o.ToString(), format); - Console.ForegroundColor = ConsoleColor.Gray; - } - - public static void LogValueNotSpecified() - { - LogError(" must be specified"); - } - - public static void LogObjectValueNotSpecified() - { - LogError(" and must be specified"); - } - - public static void LogValueInvalid() - { - LogError(" is invalid"); - } - - public static void LogObjectInvalid() - { - LogError(" is invalid"); - } - - public static void LogValueNotInt32() - { - LogError(" must be a whole number (Int32)"); - } - - #endregion - } -} +using System; +using System.CodeDom.Compiler; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Reflection.Emit; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using System.Windows.Forms; +using Microsoft.CSharp; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework.Input; +using StardewModdingAPI.Inheritance; +using StardewModdingAPI.Inheritance.Menus; +using StardewValley; +using StardewValley.Menus; +using StardewValley.Minigames; +using StardewValley.Network; +using StardewValley.Tools; +using Keys = Microsoft.Xna.Framework.Input.Keys; +using Object = StardewValley.Object; + +namespace StardewModdingAPI +{ + public class Program + { + public static string ExecutionPath { get; private set; } + public static string DataPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")); + public static List ModPaths = new List(); + public static List ModContentPaths = new List(); + public static string LogPath = Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "ErrorLogs"); + public static string CurrentLog { get; private set; } + public static StreamWriter LogStream { get; private set; } + + public static Texture2D DebugPixel { get; private set; } + + public static SGame gamePtr; + public static bool ready; + + public static Assembly StardewAssembly; + public static Type StardewProgramType; + public static FieldInfo StardewGameInfo; + public static Form StardewForm; + + public static Thread gameThread; + public static Thread consoleInputThread; + + public const string Version = "0.36 Alpha"; + public const bool debug = true; + public static bool disableLogging { get; private set; } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + [STAThread] + private static void Main(string[] args) + { + Console.Title = "Stardew Modding API Console"; + + Console.Title += " - Version " + Version; + if (debug) + Console.Title += " - DEBUG IS NOT FALSE, AUTHOUR NEEDS TO REUPLOAD THIS VERSION"; + + //TODO: Have an app.config and put the paths inside it so users can define locations to load mods from + ExecutionPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); + ModPaths.Add(Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "Mods")); + ModPaths.Add(Path.Combine(ExecutionPath, "Mods")); + ModPaths.Add(Path.Combine(Path.Combine(ExecutionPath, "Mods"), "Content")); + ModContentPaths.Add(Path.Combine(Path.Combine(Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")), "Mods"), "Content")); + + //Checks that all defined modpaths exist as directories + foreach (string ModPath in ModPaths) + { + try + { + if (File.Exists(ModPath)) + File.Delete(ModPath); + if (!Directory.Exists(ModPath)) + Directory.CreateDirectory(ModPath); + } + catch (Exception ex) + { + + LogError("Could not create a missing ModPath: " + ModPath + "\n\n" + ex); + } + } + //Same for content + foreach (string ModContentPath in ModContentPaths) + { + try + { + if (!Directory.Exists(ModContentPath)) + Directory.CreateDirectory(ModContentPath); + } + catch (Exception ex) + { + LogError("Could not create a missing ModContentPath: " + ModContentPath + "\n\n" + ex); + } + } + //And then make sure we have an errorlog dir + try + { + if (!Directory.Exists(LogPath)) + Directory.CreateDirectory(LogPath); + } + catch (Exception ex) + { + LogError("Could not create the missing ErrorLogs path: " + LogPath + "\n\n" + ex); + } + + //Define the path to the current log file + CurrentLog = LogPath + "\\MODDED_ProgramLog_LATEST"/* + System.DateTime.Now.Ticks + */ + ".txt"; + + Log(ExecutionPath, false); + + //Create a writer to the log file + try + { + LogStream = new StreamWriter(CurrentLog, false); + } + catch (Exception ex) + { + disableLogging = true; + LogError("Could not initialize LogStream - Logging is disabled"); + } + + + LogInfo("Initializing SDV Assembly..."); + if (!File.Exists(ExecutionPath + "\\Stardew Valley.exe")) + { + //If the api isn't next to SDV.exe then terminate. Though it'll crash before we even get here w/o sdv.exe. Perplexing. + LogError("Could not find: " + ExecutionPath + "\\Stardew Valley.exe"); + LogError("The API will now terminate."); + Console.ReadKey(); + Environment.Exit(-4); + } + + //Load in that assembly. Also, ignore security :D + StardewAssembly = Assembly.UnsafeLoadFrom(ExecutionPath + "\\Stardew Valley.exe"); + StardewProgramType = StardewAssembly.GetType("StardewValley.Program", true); + StardewGameInfo = StardewProgramType.GetField("gamePtr"); + + //Change the game's version + LogInfo("Injecting New SDV Version..."); + Game1.version += "-Z_MODDED | SMAPI " + Version; + + //Create the thread for the game to run in. + gameThread = new Thread(RunGame); + LogInfo("Starting SDV..."); + gameThread.Start(); + + //I forget. + SGame.GetStaticFields(); + + while (!ready) + { + //Wait for the game to load up + } + + //SDV is running + Log("SDV Loaded Into Memory"); + + //Create definition to listen for input + LogInfo("Initializing Console Input Thread..."); + consoleInputThread = new Thread(ConsoleInputThread); + + //The only command in the API (at least it should be, for now) + Command.RegisterCommand("help", "Lists all commands | 'help ' returns command description").CommandFired += help_CommandFired; + //Command.RegisterCommand("crash", "crashes sdv").CommandFired += delegate { Game1.player.draw(null); }; + + //Subscribe to events + Events.KeyPressed += Events_KeyPressed; + Events.LoadContent += Events_LoadContent; + //Events.MenuChanged += Events_MenuChanged; //Idk right now + if (debug) + { + //Experimental + //Events.LocationsChanged += Events_LocationsChanged; + //Events.CurrentLocationChanged += Events_CurrentLocationChanged; + } + + //Do tweaks using winforms invoke because I'm lazy + LogInfo("Applying Final SDV Tweaks..."); + StardewInvoke(() => + { + gamePtr.IsMouseVisible = false; + gamePtr.Window.Title = "Stardew Valley - Version " + Game1.version; + StardewForm.Resize += Events.InvokeResize; + }); + + //Game's in memory now, send the event + LogInfo("Game Loaded"); + Events.InvokeGameLoaded(); + + LogColour(ConsoleColor.Cyan, "Type 'help' for help, or 'help ' for a command's usage"); + //Begin listening to input + consoleInputThread.Start(); + + + while (ready) + { + //Check if the game is still running 10 times a second + Thread.Sleep(1000 / 10); + } + + //abort the thread, we're closing + if (consoleInputThread != null && consoleInputThread.ThreadState == ThreadState.Running) + consoleInputThread.Abort(); + + LogInfo("Game Execution Finished"); + LogInfo("Shutting Down..."); + Thread.Sleep(100); + /* + int time = 0; + int step = 100; + int target = 1000; + while (true) + { + time += step; + Thread.Sleep(step); + + Console.Write("."); + + if (time >= target) + break; + } + */ + Environment.Exit(0); + } + + + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + + + public static void RunGame() + { + //Does this even do anything??? + Application.ThreadException += Application_ThreadException; + Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); + AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; + //I've yet to see it called :| + + try + { + gamePtr = new SGame(); + LogInfo("Patching SDV Graphics Profile..."); + Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef; + LoadMods(); + + StardewForm = Control.FromHandle(Program.gamePtr.Window.Handle).FindForm(); + StardewForm.Closing += StardewForm_Closing; + StardewGameInfo.SetValue(StardewProgramType, gamePtr); + + ready = true; + + gamePtr.Run(); + } + catch (Exception ex) + { + LogError("Game failed to start: " + ex); + } + } + + static void StardewForm_Closing(object sender, CancelEventArgs e) + { + e.Cancel = true; + gamePtr.Exit(); + gamePtr.Dispose(); + StardewForm.Hide(); + ready = false; + } + + public static void LoadMods() + { + LogColour(ConsoleColor.Green, "LOADING MODS"); + int loadedMods = 0; + foreach (string ModPath in ModPaths) + { + foreach (String s in Directory.GetFiles(ModPath, "*.dll")) + { + LogColour(ConsoleColor.Green, "Found DLL: " + s); + try + { + Assembly mod = Assembly.UnsafeLoadFrom(s); //to combat internet-downloaded DLLs + + if (mod.DefinedTypes.Count(x => x.BaseType == typeof (Mod)) > 0) + { + LogColour(ConsoleColor.Green, "Loading Mod DLL..."); + TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof (Mod)); + Mod m = (Mod) mod.CreateInstance(tar.ToString()); + Console.WriteLine("LOADED MOD: {0} by {1} - Version {2} | Description: {3}", m.Name, m.Authour, m.Version, m.Description); + loadedMods += 1; + m.Entry(); + } + else + { + LogError("Invalid Mod DLL"); + } + } + catch (Exception ex) + { + LogError("Failed to load mod '{0}'. Exception details:\n" + ex, s); + } + } + } + LogColour(ConsoleColor.Green, "LOADED {0} MODS", loadedMods); + } + + public static void ConsoleInputThread() + { + string input = string.Empty; + + while (true) + { + Command.CallCommand(Console.ReadLine()); + } + } + + static void Events_LoadContent(object sender, EventArgs e) + { + LogInfo("Initializing Debug Assets..."); + DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1); + DebugPixel.SetData(new Color[] { Color.White }); + + if (debug) + { + LogColour(ConsoleColor.Magenta, "REGISTERING BASE CUSTOM ITEM"); + SObject so = new SObject(); + so.Name = "Mario Block"; + so.CategoryName = "SMAPI Test Mod"; + so.Description = "It's a block from Mario!\nLoaded in realtime by SMAPI."; + so.Texture = Texture2D.FromStream(Game1.graphics.GraphicsDevice, new FileStream(ModContentPaths[0] + "\\Test.png", FileMode.Open)); + so.IsPassable = true; + so.IsPlaceable = true; + LogColour(ConsoleColor.Cyan, "REGISTERED WITH ID OF: " + SGame.RegisterModItem(so)); + + LogColour(ConsoleColor.Magenta, "REGISTERING SECOND CUSTOM ITEM"); + SObject so2 = new SObject(); + so2.Name = "Mario Painting"; + so2.CategoryName = "SMAPI Test Mod"; + so2.Description = "It's a painting of a creature from Mario!\nLoaded in realtime by SMAPI."; + so2.Texture = Texture2D.FromStream(Game1.graphics.GraphicsDevice, new FileStream(ModContentPaths[0] + "\\PaintingTest.png", FileMode.Open)); + so2.IsPassable = true; + so2.IsPlaceable = true; + LogColour(ConsoleColor.Cyan, "REGISTERED WITH ID OF: " + SGame.RegisterModItem(so2)); + } + + if (debug) + Command.CallCommand("load"); + } + + static void Events_KeyPressed(object key, EventArgs e) + { + + } + + static void Events_MenuChanged(IClickableMenu newMenu) + { + LogInfo("NEW MENU: " + newMenu.GetType()); + if (newMenu is GameMenu) + { + Game1.activeClickableMenu = SGameMenu.ConstructFromBaseClass(Game1.activeClickableMenu as GameMenu); + } + } + + static void Events_LocationsChanged(List newLocations) + { + if (debug) + { + SGame.ModLocations = SGameLocation.ConstructFromBaseClasses(Game1.locations); + } + } + + static void Events_CurrentLocationChanged(GameLocation newLocation) + { + //SGame.CurrentLocation = null; + //System.Threading.Thread.Sleep(10); + if (debug) + { + Console.WriteLine(newLocation.name); + SGame.CurrentLocation = SGame.LoadOrCreateSGameLocationFromName(newLocation.name); + } + //Game1.currentLocation = SGame.CurrentLocation; + //LogInfo(((SGameLocation) newLocation).name); + //LogInfo("LOC CHANGED: " + SGame.currentLocation.name); + } + + public static void StardewInvoke(Action a) + { + StardewForm.Invoke(a); + } + + static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) + { + Console.WriteLine("An exception has been caught"); + File.WriteAllText(Program.LogPath + "\\MODDED_ErrorLog_" + Extensions.Random.Next(100000000, 999999999) + ".txt", e.ExceptionObject.ToString()); + } + + static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) + { + Console.WriteLine("A thread exception has been caught"); + File.WriteAllText(Program.LogPath + "\\MODDED_ErrorLog_" + Extensions.Random.Next(100000000, 999999999) + ".txt", e.Exception.ToString()); + } + + static void help_CommandFired(object sender, EventArgs e) + { + Command cmd = sender as Command; + if (cmd.CalledArgs.Length > 0) + { + Command fnd = Command.FindCommand(cmd.CalledArgs[0]); + if (fnd == null) + LogError("The command specified could not be found"); + else + { + if (fnd.CommandArgs.Length > 0) + LogInfo("{0}: {1} - {2}", fnd.CommandName, fnd.CommandDesc, fnd.CommandArgs.ToSingular()); + else + LogInfo("{0}: {1}", fnd.CommandName, fnd.CommandDesc); + } + } + else + LogInfo("Commands: " + Command.RegisteredCommands.Select(x => x.CommandName).ToSingular()); + } + + #region Logging + + public static void Log(object o, params object[] format) + { + if (format.Length > 0) + { + if (format[0] is bool) + { + if ((bool)format[0] == false) + { + //suppress logging to file + Console.WriteLine("[{0}] {1}", System.DateTime.Now.ToLongTimeString(), String.Format(o.ToString(), format)); + return; + } + } + } + string toLog = string.Format("[{0}] {1}", System.DateTime.Now.ToLongTimeString(), String.Format(o.ToString(), format)); + Console.WriteLine(toLog); + + if (!disableLogging) + { + LogStream.WriteLine(toLog); + LogStream.Flush(); + } + } + + public static void LogColour(ConsoleColor c, object o, params object[] format) + { + Console.ForegroundColor = c; + Log(o.ToString(), format); + Console.ForegroundColor = ConsoleColor.Gray; + } + + public static void LogInfo(object o, params object[] format) + { + Console.ForegroundColor = ConsoleColor.Yellow; + Log(o.ToString(), format); + Console.ForegroundColor = ConsoleColor.Gray; + } + + public static void LogError(object o, params object[] format) + { + Console.ForegroundColor = ConsoleColor.Red; + Log(o.ToString(), format); + Console.ForegroundColor = ConsoleColor.Gray; + } + + public static void LogDebug(object o, params object[] format) + { + if (!debug) + return; + Console.ForegroundColor = ConsoleColor.DarkYellow; + Log(o.ToString(), format); + Console.ForegroundColor = ConsoleColor.Gray; + } + + public static void LogValueNotSpecified() + { + LogError(" must be specified"); + } + + public static void LogObjectValueNotSpecified() + { + LogError(" and must be specified"); + } + + public static void LogValueInvalid() + { + LogError(" is invalid"); + } + + public static void LogObjectInvalid() + { + LogError(" is invalid"); + } + + public static void LogValueNotInt32() + { + LogError(" must be a whole number (Int32)"); + } + + #endregion + } +} -- cgit