diff options
Diffstat (limited to 'StardewModdingAPI/Program.cs')
-rw-r--r-- | StardewModdingAPI/Program.cs | 399 |
1 files changed, 133 insertions, 266 deletions
diff --git a/StardewModdingAPI/Program.cs b/StardewModdingAPI/Program.cs index 000ddab0..3e267af5 100644 --- a/StardewModdingAPI/Program.cs +++ b/StardewModdingAPI/Program.cs @@ -1,29 +1,18 @@ -using System; -using System.CodeDom.Compiler; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI.Events;
+using StardewModdingAPI.Inheritance; +using StardewModdingAPI.Inheritance.Menus; +using StardewValley; +using StardewValley.Menus; +using System; 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; -using StardewModdingAPI.Events;
namespace StardewModdingAPI { @@ -32,7 +21,7 @@ namespace StardewModdingAPI public static string ExecutionPath { get; private set; } public static string DataPath = Path.Combine(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley")); public static List<string> ModPaths = new List<string>(); - public static List<string> ModContentPaths = new List<string>(); + public static List<string> ModContentPaths = new List<string>();
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; } @@ -51,25 +40,22 @@ namespace StardewModdingAPI public static Thread consoleInputThread; public const string Version = "0.36 Alpha"; - public const bool debug = false; - public static bool disableLogging { get; private set; } public static bool StardewInjectorLoaded { get; private set; } public static Mod StardewInjectorMod { 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 + Console.Title += " - Version " + Version;
+#if DEBUG + Console.Title += " - DEBUG IS NOT FALSE, AUTHOUR NEEDS TO REUPLOAD THIS VERSION";
+#endif
+
+ //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")); @@ -88,7 +74,7 @@ namespace StardewModdingAPI } catch (Exception ex) { - LogError("Could not create a missing ModPath: " + ModPath + "\n\n" + ex); + Log.Error("Could not create a missing ModPath: " + ModPath + "\n\n" + ex); } } //Same for content @@ -101,7 +87,7 @@ namespace StardewModdingAPI } catch (Exception ex) { - LogError("Could not create a missing ModContentPath: " + ModContentPath + "\n\n" + ex); + Log.Error("Could not create a missing ModContentPath: " + ModContentPath + "\n\n" + ex); } } //And then make sure we have an errorlog dir @@ -112,32 +98,15 @@ namespace StardewModdingAPI } 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"); + Log.Error("Could not create the missing ErrorLogs path: " + LogPath + "\n\n" + ex); } - - LogInfo("Initializing SDV Assembly..."); + Log.Info("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."); + Log.Error("Could not find: " + ExecutionPath + "\\Stardew Valley.exe"); + Log.Error("The API will now terminate."); Console.ReadKey(); Environment.Exit(-4); } @@ -153,16 +122,16 @@ namespace StardewModdingAPI { foreach (String s in Directory.GetFiles(ModPath, "StardewInjector.dll")) { - LogColour(ConsoleColor.Green, "Found Stardew Injector DLL: " + s); + Log.Success(ConsoleColor.Green, "Found Stardew Injector DLL: " + s); try { Assembly mod = Assembly.UnsafeLoadFrom(s); //to combat internet-downloaded DLLs - if (mod.DefinedTypes.Count(x => x.BaseType == typeof (Mod)) > 0) + if (mod.DefinedTypes.Count(x => x.BaseType == typeof(Mod)) > 0) { - LogColour(ConsoleColor.Green, "Loading Injector DLL..."); - TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof (Mod)); - Mod m = (Mod) mod.CreateInstance(tar.ToString()); + Log.Success("Loading Injector DLL..."); + TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof(Mod)); + Mod m = (Mod)mod.CreateInstance(tar.ToString()); Console.WriteLine("LOADED: {0} by {1} - Version {2} | Description: {3}", m.Name, m.Authour, m.Version, m.Description); m.Entry(false); StardewInjectorLoaded = true; @@ -170,12 +139,12 @@ namespace StardewModdingAPI } else { - LogError("Invalid Mod DLL"); + Log.Error("Invalid Mod DLL"); } } catch (Exception ex) { - LogError("Failed to load mod '{0}'. Exception details:\n" + ex, s); + Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); } } } @@ -190,7 +159,7 @@ namespace StardewModdingAPI { //Stardew_Injector Mode StardewInjectorLoaded = true; - Program.LogInfo("STARDEW_INJECTOR DETECTED, LAUNCHING USING INJECTOR CALLS"); + Program.Log.LogInfo("STARDEW_INJECTOR DETECTED, LAUNCHING USING INJECTOR CALLS"); Assembly inj = Assembly.UnsafeLoadFrom(ExecutionPath + "\\Stardew_Injector.exe"); Type prog = inj.GetType("Stardew_Injector.Program", true); FieldInfo hooker = prog.GetField("hooker", BindingFlags.NonPublic | BindingFlags.Static); @@ -221,27 +190,27 @@ namespace StardewModdingAPI #endregion //Change the game's version - LogInfo("Injecting New SDV Version..."); + Log.Info("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..."); + Log.Info("Starting SDV..."); gameThread.Start(); //I forget. - SGame.GetStaticFields(); - + SGame.GetStaticFields();
+
while (!ready) { //Wait for the game to load up } //SDV is running - Log("SDV Loaded Into Memory"); + Log.Comment("SDV Loaded Into Memory"); //Create definition to listen for input - LogInfo("Initializing Console Input Thread..."); + Log.Verbose("Initializing Console Input Thread..."); consoleInputThread = new Thread(ConsoleInputThread); //The only command in the API (at least it should be, for now)\ @@ -251,29 +220,29 @@ namespace StardewModdingAPI //Subscribe to events Events.ControlEvents.KeyPressed += Events_KeyPressed; - Events.GameEvents.LoadContent += Events_LoadContent; - //Events.MenuChanged += Events_MenuChanged; //Idk right now - if (debug) - { - //Experimental - //Events.LocationsChanged += Events_LocationsChanged; - //Events.CurrentLocationChanged += Events_CurrentLocationChanged; - } + Events.GameEvents.LoadContent += Events_LoadContent;
+ //Events.MenuChanged += Events_MenuChanged; //Idk right now
+
+#if DEBUG
+ //Experimental
+ //Events.LocationsChanged += Events_LocationsChanged;
+ //Events.CurrentLocationChanged += Events_CurrentLocationChanged;
+#endif //Do tweaks using winforms invoke because I'm lazy - LogInfo("Applying Final SDV Tweaks..."); + Log.Verbose("Applying Final SDV Tweaks..."); StardewInvoke(() => - { - gamePtr.IsMouseVisible = false; - gamePtr.Window.Title = "Stardew Valley - Version " + Game1.version; - StardewForm.Resize += Events.GraphicsEvents.InvokeResize; + {
+ gamePtr.IsMouseVisible = false;
+ gamePtr.Window.Title = "Stardew Valley - Version " + Game1.version;
+ StardewForm.Resize += Events.GraphicsEvents.InvokeResize; }); //Game's in memory now, send the event - LogInfo("Game Loaded"); + Log.Verbose("Game Loaded"); Events.GameEvents.InvokeGameLoaded(); - LogColour(ConsoleColor.Cyan, "Type 'help' for help, or 'help <cmd>' for a command's usage"); + Log.Comment(ConsoleColor.Cyan, "Type 'help' for help, or 'help <cmd>' for a command's usage"); //Begin listening to input consoleInputThread.Start(); @@ -288,8 +257,8 @@ namespace StardewModdingAPI if (consoleInputThread != null && consoleInputThread.ThreadState == ThreadState.Running) consoleInputThread.Abort(); - LogInfo("Game Execution Finished"); - LogInfo("Shutting Down..."); + Log.Verbose("Game Execution Finished"); + Log.Verbose("Shutting Down..."); Thread.Sleep(100); /* int time = 0; @@ -307,26 +276,22 @@ namespace StardewModdingAPI } */ Environment.Exit(0); - } - - - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - + }
+
+
+
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
public static void RunGame() { - //Does this even do anything??? - Application.ThreadException += Application_ThreadException; + Application.ThreadException += Log.Application_ThreadException; Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); - AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException; - //I've yet to see it called :| + AppDomain.CurrentDomain.UnhandledException += Log.CurrentDomain_UnhandledException; try { gamePtr = new SGame(); - LogInfo("Patching SDV Graphics Profile..."); + Log.Verbose("Patching SDV Graphics Profile..."); Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef; LoadMods(); @@ -356,7 +321,7 @@ namespace StardewModdingAPI } catch (Exception ex) { - LogError("Game failed to start: " + ex); + Log.Error("Game failed to start: " + ex); } } @@ -375,7 +340,7 @@ namespace StardewModdingAPI public static void LoadMods() { - LogColour(ConsoleColor.Green, "LOADING MODS"); + Log.Verbose("LOADING MODS"); int loadedMods = 0; foreach (string ModPath in ModPaths) { @@ -383,32 +348,32 @@ namespace StardewModdingAPI { if (s.Contains("StardewInjector")) continue; - LogColour(ConsoleColor.Green, "Found DLL: " + s); + Log.Success("Found DLL: " + s); try { Assembly mod = Assembly.UnsafeLoadFrom(s); //to combat internet-downloaded DLLs - if (mod.DefinedTypes.Count(x => x.BaseType == typeof (Mod)) > 0) + 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()); + Log.Verbose("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"); + Log.Error("Invalid Mod DLL"); } } catch (Exception ex) { - LogError("Failed to load mod '{0}'. Exception details:\n" + ex, s); + Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); } } } - LogColour(ConsoleColor.Green, "LOADED {0} MODS", loadedMods); + Log.Success("LOADED {0} MODS", loadedMods); } public static void ConsoleInputThread() @@ -423,190 +388,92 @@ namespace StardewModdingAPI static void Events_LoadContent(object o, EventArgs e) { - LogInfo("Initializing Debug Assets..."); + Log.Info("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"); + DebugPixel.SetData(new Color[] { Color.White });
+
+#if DEBUG + Log.Verbose("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; + Log.Verbose("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so)); + + Log.Verbose("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; + Log.Verbose("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so2)); + + Command.CallCommand("load"); +#endif } static void Events_KeyPressed(object o, EventArgsKeyPressed e) - { - + {
+
} static void Events_MenuChanged(IClickableMenu newMenu) { - LogInfo("NEW MENU: " + newMenu.GetType()); + Log.Verbose("NEW MENU: " + newMenu.GetType()); if (newMenu is GameMenu) { Game1.activeClickableMenu = SGameMenu.ConstructFromBaseClass(Game1.activeClickableMenu as GameMenu); } } + static void Events_LocationsChanged(List<GameLocation> newLocations) - { - if (debug) - { - SGame.ModLocations = SGameLocation.ConstructFromBaseClasses(Game1.locations); - } + {
+#if DEBUG + SGame.ModLocations = SGameLocation.ConstructFromBaseClasses(Game1.locations); +#endif } 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); - } + {
+ //SGame.CurrentLocation = null;
+ //System.Threading.Thread.Sleep(10);
+#if DEBUG + Console.WriteLine(newLocation.name); + SGame.CurrentLocation = SGame.LoadOrCreateSGameLocationFromName(newLocation.name); +#endif //Game1.currentLocation = SGame.CurrentLocation; - //LogInfo(((SGameLocation) newLocation).name); - //LogInfo("LOC CHANGED: " + SGame.currentLocation.name); + //Log.LogComment(((SGameLocation) newLocation).name); + //Log.LogComment("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 o, EventArgsCommand e) - { - if (e.Command.CalledArgs.Length > 0) - { - Command fnd = Command.FindCommand(e.Command.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("<value> must be specified"); - } - - public static void LogObjectValueNotSpecified() - { - LogError("<object> and <value> must be specified"); - } - - public static void LogValueInvalid() - { - LogError("<value> is invalid"); - } - - public static void LogObjectInvalid() - { - LogError("<object> is invalid"); - } - - public static void LogValueNotInt32() - { - LogError("<value> must be a whole number (Int32)"); - } - - #endregion + }
+
+ static void help_CommandFired(object o, EventArgsCommand e)
+ {
+ if (e.Command.CalledArgs.Length > 0)
+ {
+ Command fnd = Command.FindCommand(e.Command.CalledArgs[0]);
+ if (fnd == null)
+ Log.Error("The command specified could not be found");
+ else
+ {
+ if (fnd.CommandArgs.Length > 0)
+ Log.Info("{0}: {1} - {2}", fnd.CommandName, fnd.CommandDesc, fnd.CommandArgs.ToSingular());
+ else
+ Log.Info("{0}: {1}", fnd.CommandName, fnd.CommandDesc);
+ }
+ }
+ else
+ Log.Info("Commands: " + Command.RegisteredCommands.Select(x => x.CommandName).ToSingular());
+ }
} }
\ No newline at end of file |