From c50891a09367169f47c80d11ae5b5bcb0d3c50a2 Mon Sep 17 00:00:00 2001 From: Zoryn Aaron Date: Sun, 20 Mar 2016 15:43:31 -0400 Subject: [PATCH] Zoryn returns. Added JSON. Added Config.cs. --- .gitignore | 1 + StardewModdingAPI/Config.cs | 124 ++++ StardewModdingAPI/Mod.cs | 5 + StardewModdingAPI/Program.cs | 777 +++++++++++---------- StardewModdingAPI/StardewModdingAPI.csproj | 8 +- StardewModdingAPI/packages.config | 4 + TrainerMod/TrainerMod.csproj | 25 +- TrainerMod/packages.config | 4 + 8 files changed, 550 insertions(+), 398 deletions(-) create mode 100644 StardewModdingAPI/Config.cs create mode 100644 StardewModdingAPI/packages.config create mode 100644 TrainerMod/packages.config diff --git a/.gitignore b/.gitignore index f2fbbcd6..e6db76e6 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ TrainerMod/obj/ StardewInjector/bin/ StardewInjector/obj/ packages/ +steamapps/ *.symlink *.lnk diff --git a/StardewModdingAPI/Config.cs b/StardewModdingAPI/Config.cs new file mode 100644 index 00000000..67c13a14 --- /dev/null +++ b/StardewModdingAPI/Config.cs @@ -0,0 +1,124 @@ +/* + Copyright 2016 Zoey (Zoryn) +*/ + +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; + +namespace StardewModdingAPI +{ + public class Config + { + [JsonIgnore] + public virtual JObject JObject { get; protected set; } + + [JsonIgnore] + public virtual string ConfigLocation { get; protected set; } + + public static Config Instance + { + get { return new Config(); } + } + + public static Config InitializeConfig(string configLocation, Config baseConfig) + { + if (baseConfig == null) + { + Console.WriteLine("A config must be instantiated before being passed to Initialize.\n\t" + configLocation); + return null; + } + + baseConfig.ConfigLocation = configLocation; + return baseConfig.LoadConfig(baseConfig); + } + + public virtual Config GenerateBaseConfig(Config baseConfig) + { + //Must be implemented in sub-class + return null; + } + + public virtual Config LoadConfig(Config baseConfig) + { + if (!File.Exists(baseConfig.ConfigLocation)) + { + var v = (Config)baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] { baseConfig }); + v.WriteConfig(); + } + else + { + var p = baseConfig.ConfigLocation; + + try + { + var j = JObject.Parse(Encoding.UTF8.GetString(File.ReadAllBytes(baseConfig.ConfigLocation))); + baseConfig = (Config)j.ToObject(baseConfig.GetType()); + baseConfig.ConfigLocation = p; + baseConfig.JObject = j; + + baseConfig = UpdateConfig(baseConfig); + baseConfig.ConfigLocation = p; + baseConfig.JObject = j; + + baseConfig.WriteConfig(); + } + catch + { + Console.WriteLine("Invalid JSON Renamed: " + p); + if (File.Exists(p)) + File.Move(p, Path.Combine(Path.GetDirectoryName(p), Path.GetFileNameWithoutExtension(p) + "." + Guid.NewGuid() + ".json")); //Get it out of the way for a new one + var v = (Config)baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] { baseConfig }); + v.WriteConfig(); + } + } + + return baseConfig; + } + + public virtual Config UpdateConfig(Config baseConfig) + { + try + { + //default config with all standard values + var b = JObject.FromObject(baseConfig.GetType().GetMethod("GenerateBaseConfig", BindingFlags.Public | BindingFlags.Instance).Invoke(baseConfig, new object[] { baseConfig })); + //user config with their values + var u = baseConfig.JObject; + + b.Merge(u); + + return (Config)b.ToObject(baseConfig.GetType()); + } + catch (Exception ex) + { + Console.WriteLine(ex.ToString()); + } + return baseConfig; + } + + public static string GetBasePath(Mod theMod) + { + return theMod.PathOnDisk + "\\config.json"; + } + } + + public static class ConfigExtensions + { + public static void WriteConfig(this Config baseConfig) + { + var toWrite = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(baseConfig, baseConfig.GetType(), Formatting.Indented, new JsonSerializerSettings())); + if (!File.Exists(baseConfig.ConfigLocation) || !File.ReadAllBytes(baseConfig.ConfigLocation).SequenceEqual(toWrite)) + File.WriteAllBytes(baseConfig.ConfigLocation, toWrite); + toWrite = null; + } + + public static Config ReloadConfig(this Config baseConfig) + { + return baseConfig.UpdateConfig(baseConfig); + } + } +} \ No newline at end of file diff --git a/StardewModdingAPI/Mod.cs b/StardewModdingAPI/Mod.cs index eabdc539..a196c3a2 100644 --- a/StardewModdingAPI/Mod.cs +++ b/StardewModdingAPI/Mod.cs @@ -28,6 +28,11 @@ namespace StardewModdingAPI /// public virtual string Description { get; protected set; } + /// + /// Where the mod is located on the disk. + /// + public string PathOnDisk { get; internal set; } + /// /// A basic method that is the entry-point of your mod. It will always be called once when the mod loads. /// diff --git a/StardewModdingAPI/Program.cs b/StardewModdingAPI/Program.cs index 61770f8e..65bd185d 100644 --- a/StardewModdingAPI/Program.cs +++ b/StardewModdingAPI/Program.cs @@ -1,50 +1,50 @@ -using Microsoft.Xna.Framework; -using Microsoft.Xna.Framework.Graphics; +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.Threading; -using System.Windows.Forms; +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.Threading; +using System.Windows.Forms; + +namespace StardewModdingAPI +{ + public class Program + { + private static List _modPaths; + private static List _modContentPaths; + + 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 static bool StardewInjectorLoaded { get; private set; } + public static Mod StardewInjectorMod { get; private set; } + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -namespace StardewModdingAPI -{ - public class Program - { - private static List _modPaths; - private static List _modContentPaths; - - 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 static bool StardewInjectorLoaded { get; private set; } - public static Mod StardewInjectorMod { get; private set; } - - ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// /// Main method holding the API execution /// - /// - private static void Main(string[] args) - { + /// + private static void Main(string[] args) + { try { ConfigureUI(); @@ -62,16 +62,16 @@ namespace StardewModdingAPI StardewModdingAPI.Log.Comment("The API will now terminate. Press any key to continue..."); Console.ReadKey(); - } - + } + /// /// Set up the console properties - /// + /// private static void ConfigureUI() - { + { Console.Title = Constants.ConsoleTitle; - -#if DEBUG + +#if DEBUG Console.Title += " - DEBUG IS NOT FALSE, AUTHOUR NEEDS TO REUPLOAD THIS VERSION"; #endif } @@ -81,150 +81,151 @@ namespace StardewModdingAPI /// private static void ConfigurePaths() { - StardewModdingAPI.Log.Info("Validating api paths..."); + StardewModdingAPI.Log.Info("Validating api paths..."); _modPaths = new List(); _modContentPaths = new List(); //TODO: Have an app.config and put the paths inside it so users can define locations to load mods from - _modPaths.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley", "Mods")); - _modPaths.Add(Path.Combine(Constants.ExecutionPath, "Mods")); - _modContentPaths.Add(Path.Combine(Constants.ExecutionPath, "Mods", "Content")); - _modContentPaths.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley", "Mods", "Content")); - - //Checks that all defined modpaths exist as directories - _modPaths.ForEach(path => VerifyPath(path)); - _modContentPaths.ForEach(path => VerifyPath(path)); - VerifyPath(Constants.LogPath); - + _modPaths.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley", "Mods")); + _modPaths.Add(Path.Combine(Constants.ExecutionPath, "Mods")); + _modContentPaths.Add(Path.Combine(Constants.ExecutionPath, "Mods", "Content")); + _modContentPaths.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley", "Mods", "Content")); + + //Checks that all defined modpaths exist as directories + _modPaths.ForEach(path => VerifyPath(path)); + _modContentPaths.ForEach(path => VerifyPath(path)); + VerifyPath(Constants.LogPath); + StardewModdingAPI.Log.Initialize(Constants.LogPath); if (!File.Exists(Constants.ExecutionPath + "\\Stardew Valley.exe")) - { + { throw new FileNotFoundException(string.Format("Could not found: {0}\\Stardew Valley.exe", Constants.ExecutionPath)); - } - } - + } + } + /// /// Load the injector. - /// - /// + /// + /// /// This will load the injector before anything else if it sees it /// It doesn't matter though /// I'll leave it as a feature in case anyone in the community wants to tinker with it /// All you need is a DLL that inherits from mod and is called StardewInjector.dll with an Entry() method - /// + /// private static void ConfigureInjector() - { - foreach (string ModPath in _modPaths) - { - foreach (String s in Directory.GetFiles(ModPath, "StardewInjector.dll")) - { - StardewModdingAPI.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) - { - StardewModdingAPI.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; - StardewInjectorMod = m; - } - else - { - StardewModdingAPI.Log.Error("Invalid Mod DLL"); - } - } - catch (Exception ex) - { - StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); - } - } - } - } - + { + foreach (string ModPath in _modPaths) + { + foreach (String s in Directory.GetFiles(ModPath, "StardewInjector.dll")) + { + StardewModdingAPI.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) + { + StardewModdingAPI.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.PathOnDisk = Path.GetDirectoryName(ModPath); + m.Entry(false); + StardewInjectorLoaded = true; + StardewInjectorMod = m; + } + else + { + StardewModdingAPI.Log.Error("Invalid Mod DLL"); + } + } + catch (Exception ex) + { + StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); + } + } + } + } + /// /// Load Stardev Valley and control features - /// + /// private static void ConfigureSDV() - { - StardewModdingAPI.Log.Info("Initializing SDV Assembly..."); - - // Load in the assembly - ignores security - StardewAssembly = Assembly.UnsafeLoadFrom(Constants.ExecutionPath + "\\Stardew Valley.exe"); - StardewProgramType = StardewAssembly.GetType("StardewValley.Program", true); - StardewGameInfo = StardewProgramType.GetField("gamePtr"); - - // Change the game's version - StardewModdingAPI.Log.Verbose("Injecting New SDV Version..."); + { + StardewModdingAPI.Log.Info("Initializing SDV Assembly..."); + + // Load in the assembly - ignores security + StardewAssembly = Assembly.UnsafeLoadFrom(Constants.ExecutionPath + "\\Stardew Valley.exe"); + StardewProgramType = StardewAssembly.GetType("StardewValley.Program", true); + StardewGameInfo = StardewProgramType.GetField("gamePtr"); + + // Change the game's version + StardewModdingAPI.Log.Verbose("Injecting New SDV Version..."); Game1.version += string.Format("-Z_MODDED | SMAPI {0}", Constants.VersionString); - - // Create the thread for the game to run in. - gameThread = new Thread(RunGame); - StardewModdingAPI.Log.Info("Starting SDV..."); + + // Create the thread for the game to run in. + gameThread = new Thread(RunGame); + StardewModdingAPI.Log.Info("Starting SDV..."); gameThread.Start(); // Wait for the game to load up - while (!ready) ; - - //SDV is running - StardewModdingAPI.Log.Comment("SDV Loaded Into Memory"); - - //Create definition to listen for input - StardewModdingAPI.Log.Verbose("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.ControlEvents.KeyPressed += Events_KeyPressed; + while (!ready) ; + + //SDV is running + StardewModdingAPI.Log.Comment("SDV Loaded Into Memory"); + + //Create definition to listen for input + StardewModdingAPI.Log.Verbose("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.ControlEvents.KeyPressed += Events_KeyPressed; Events.GameEvents.LoadContent += Events_LoadContent; - //Events.MenuChanged += Events_MenuChanged; //Idk right now - - StardewModdingAPI.Log.Verbose("Applying Final SDV Tweaks..."); - StardewInvoke(() => + //Events.MenuChanged += Events_MenuChanged; //Idk right now + + StardewModdingAPI.Log.Verbose("Applying Final SDV Tweaks..."); + StardewInvoke(() => { gamePtr.IsMouseVisible = false; gamePtr.Window.Title = "Stardew Valley - Version " + Game1.version; - StardewForm.Resize += Events.GraphicsEvents.InvokeResize; - }); - } - + StardewForm.Resize += Events.GraphicsEvents.InvokeResize; + }); + } + /// /// Wrap the 'RunGame' method for console output - /// + /// private static void GameRunInvoker() - { - //Game's in memory now, send the event - StardewModdingAPI.Log.Verbose("Game Loaded"); - Events.GameEvents.InvokeGameLoaded(); - + { + //Game's in memory now, send the event + StardewModdingAPI.Log.Verbose("Game Loaded"); + Events.GameEvents.InvokeGameLoaded(); + StardewModdingAPI.Log.Comment("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(); - - StardewModdingAPI.Log.Verbose("Game Execution Finished"); - StardewModdingAPI.Log.Verbose("Shutting Down..."); - Thread.Sleep(100); - Environment.Exit(0); + //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(); + + StardewModdingAPI.Log.Verbose("Game Execution Finished"); + StardewModdingAPI.Log.Verbose("Shutting Down..."); + Thread.Sleep(100); + Environment.Exit(0); } /// @@ -241,186 +242,186 @@ namespace StardewModdingAPI } } catch (Exception ex) - { + { StardewModdingAPI.Log.Error("Could not create a path: " + path + "\n\n" + ex); - } + } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public static void RunGame() - { - Application.ThreadException += StardewModdingAPI.Log.Application_ThreadException; - Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); - AppDomain.CurrentDomain.UnhandledException += StardewModdingAPI.Log.CurrentDomain_UnhandledException; - - try - { - gamePtr = new SGame(); - StardewModdingAPI.Log.Verbose("Patching SDV Graphics Profile..."); - Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef; - LoadMods(); - - StardewForm = Control.FromHandle(Program.gamePtr.Window.Handle).FindForm(); - StardewForm.Closing += StardewForm_Closing; - - ready = true; - - StardewGameInfo.SetValue(StardewProgramType, gamePtr); - gamePtr.Run(); - - #region deprecated - if (false) - { - //Nope, I can't get it to work. I depend on Game1 being an SGame, and can't cast a parent to a child - //I'm leaving this here in case the community is interested - //StardewInjectorMod.Entry(true); - Type gt = StardewAssembly.GetType("StardewValley.Game1", true); - gamePtr = (SGame)Activator.CreateInstance(gt); - - ready = true; - - StardewGameInfo.SetValue(StardewProgramType, gamePtr); - gamePtr.Run(); - } - #endregion - } - catch (Exception ex) - { - StardewModdingAPI.Log.Error("Game failed to start: " + ex); - } - } - - static void StardewForm_Closing(object sender, CancelEventArgs e) - { - e.Cancel = true; - - if (true || MessageBox.Show("Are you sure you would like to quit Stardew Valley?\nUnsaved progress will be lost!", "Confirm Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes) - { - gamePtr.Exit(); - gamePtr.Dispose(); - StardewForm.Hide(); - ready = false; - } - } - - public static void LoadMods() - { - StardewModdingAPI.Log.Verbose("LOADING MODS"); - int loadedMods = 0; - foreach (string ModPath in _modPaths) - { - foreach (String s in Directory.GetFiles(ModPath, "*.dll")) - { - if (s.Contains("StardewInjector")) - continue; - StardewModdingAPI.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) - { - StardewModdingAPI.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 - { - StardewModdingAPI.Log.Error("Invalid Mod DLL"); - } - } - catch (Exception ex) - { - StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); - } - } - } - StardewModdingAPI.Log.Success("LOADED {0} MODS", loadedMods); - } - - public static void ConsoleInputThread() - { - string input = string.Empty; - - while (true) - { - Command.CallCommand(Console.ReadLine()); - } - } - - static void Events_LoadContent(object o, EventArgs e) - { - StardewModdingAPI.Log.Info("Initializing Debug Assets..."); - DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1); + + public static void RunGame() + { + Application.ThreadException += StardewModdingAPI.Log.Application_ThreadException; + Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException); + AppDomain.CurrentDomain.UnhandledException += StardewModdingAPI.Log.CurrentDomain_UnhandledException; + + try + { + gamePtr = new SGame(); + StardewModdingAPI.Log.Verbose("Patching SDV Graphics Profile..."); + Game1.graphics.GraphicsProfile = GraphicsProfile.HiDef; + LoadMods(); + + StardewForm = Control.FromHandle(Program.gamePtr.Window.Handle).FindForm(); + StardewForm.Closing += StardewForm_Closing; + + ready = true; + + StardewGameInfo.SetValue(StardewProgramType, gamePtr); + gamePtr.Run(); + + #region deprecated + if (false) + { + //Nope, I can't get it to work. I depend on Game1 being an SGame, and can't cast a parent to a child + //I'm leaving this here in case the community is interested + //StardewInjectorMod.Entry(true); + Type gt = StardewAssembly.GetType("StardewValley.Game1", true); + gamePtr = (SGame)Activator.CreateInstance(gt); + + ready = true; + + StardewGameInfo.SetValue(StardewProgramType, gamePtr); + gamePtr.Run(); + } + #endregion + } + catch (Exception ex) + { + StardewModdingAPI.Log.Error("Game failed to start: " + ex); + } + } + + static void StardewForm_Closing(object sender, CancelEventArgs e) + { + e.Cancel = true; + + if (true || MessageBox.Show("Are you sure you would like to quit Stardew Valley?\nUnsaved progress will be lost!", "Confirm Exit", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation) == DialogResult.Yes) + { + gamePtr.Exit(); + gamePtr.Dispose(); + StardewForm.Hide(); + ready = false; + } + } + + public static void LoadMods() + { + StardewModdingAPI.Log.Verbose("LOADING MODS"); + int loadedMods = 0; + foreach (string ModPath in _modPaths) + { + foreach (String s in Directory.GetFiles(ModPath, "*.dll")) + { + if (s.Contains("StardewInjector")) + continue; + StardewModdingAPI.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) + { + StardewModdingAPI.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 + { + StardewModdingAPI.Log.Error("Invalid Mod DLL"); + } + } + catch (Exception ex) + { + StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); + } + } + } + StardewModdingAPI.Log.Success("LOADED {0} MODS", loadedMods); + } + + public static void ConsoleInputThread() + { + string input = string.Empty; + + while (true) + { + Command.CallCommand(Console.ReadLine()); + } + } + + static void Events_LoadContent(object o, EventArgs e) + { + StardewModdingAPI.Log.Info("Initializing Debug Assets..."); + DebugPixel = new Texture2D(Game1.graphics.GraphicsDevice, 1, 1); DebugPixel.SetData(new Color[] { Color.White }); -#if DEBUG - StardewModdingAPI.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; - StardewModdingAPI.Log.Verbose("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so)); - - //StardewModdingAPI.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; - //StardewModdingAPI.Log.Verbose("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so2)); - - Command.CallCommand("load"); -#endif - } - - static void Events_KeyPressed(object o, EventArgsKeyPressed e) +#if DEBUG + StardewModdingAPI.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; + StardewModdingAPI.Log.Verbose("REGISTERED WITH ID OF: " + SGame.RegisterModItem(so)); + + //StardewModdingAPI.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; + //StardewModdingAPI.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) - { - StardewModdingAPI.Log.Verbose("NEW MENU: " + newMenu.GetType()); - if (newMenu is GameMenu) - { - Game1.activeClickableMenu = SGameMenu.ConstructFromBaseClass(Game1.activeClickableMenu as GameMenu); - } - } - - - static void Events_LocationsChanged(List newLocations) + } + + static void Events_MenuChanged(IClickableMenu newMenu) { -#if DEBUG - SGame.ModLocations = SGameLocation.ConstructFromBaseClasses(Game1.locations); -#endif - } - - static void Events_CurrentLocationChanged(GameLocation newLocation) + StardewModdingAPI.Log.Verbose("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); +#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); -#endif - //Game1.currentLocation = SGame.CurrentLocation; - //Log.LogComment(((SGameLocation) newLocation).name); - //Log.LogComment("LOC CHANGED: " + SGame.currentLocation.name); - } - - public static void StardewInvoke(Action a) - { - StardewForm.Invoke(a); +#if DEBUG + Console.WriteLine(newLocation.name); + SGame.CurrentLocation = SGame.LoadOrCreateSGameLocationFromName(newLocation.name); +#endif + //Game1.currentLocation = SGame.CurrentLocation; + //Log.LogComment(((SGameLocation) newLocation).name); + //Log.LogComment("LOC CHANGED: " + SGame.currentLocation.name); + } + + public static void StardewInvoke(Action a) + { + StardewForm.Invoke(a); } static void help_CommandFired(object o, EventArgsCommand e) @@ -442,66 +443,66 @@ namespace StardewModdingAPI StardewModdingAPI.Log.Info("Commands: " + Command.RegisteredCommands.Select(x => x.CommandName).ToSingular()); } - #region Logging - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void Log(object o, params object[] format) + #region Logging + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void Log(object o, params object[] format) { - StardewModdingAPI.Log.Info(o, format); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogColour(ConsoleColor c, object o, params object[] format) - { - StardewModdingAPI.Log.Info(o, format); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogInfo(object o, params object[] format) - { - StardewModdingAPI.Log.Info(o, format); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogError(object o, params object[] format) - { - StardewModdingAPI.Log.Error(o, format); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogDebug(object o, params object[] format) - { - StardewModdingAPI.Log.Debug(o, format); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogValueNotSpecified() - { - StardewModdingAPI.Log.Error(" must be specified"); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogObjectValueNotSpecified() - { - StardewModdingAPI.Log.Error(" and must be specified"); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogValueInvalid() - { - StardewModdingAPI.Log.Error(" is invalid"); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogObjectInvalid() - { - StardewModdingAPI.Log.Error(" is invalid"); - } - - [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] - public static void LogValueNotInt32() - { - StardewModdingAPI.Log.Error(" must be a whole number (Int32)"); + StardewModdingAPI.Log.Info(o, format); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogColour(ConsoleColor c, object o, params object[] format) + { + StardewModdingAPI.Log.Info(o, format); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogInfo(object o, params object[] format) + { + StardewModdingAPI.Log.Info(o, format); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogError(object o, params object[] format) + { + StardewModdingAPI.Log.Error(o, format); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogDebug(object o, params object[] format) + { + StardewModdingAPI.Log.Debug(o, format); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogValueNotSpecified() + { + StardewModdingAPI.Log.Error(" must be specified"); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogObjectValueNotSpecified() + { + StardewModdingAPI.Log.Error(" and must be specified"); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogValueInvalid() + { + StardewModdingAPI.Log.Error(" is invalid"); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogObjectInvalid() + { + StardewModdingAPI.Log.Error(" is invalid"); + } + + [Obsolete("This method is obsolete and will be removed in v0.39, please use the appropriate methods in the Log class")] + public static void LogValueNotInt32() + { + StardewModdingAPI.Log.Error(" must be a whole number (Int32)"); } #endregion - } + } } \ No newline at end of file diff --git a/StardewModdingAPI/StardewModdingAPI.csproj b/StardewModdingAPI/StardewModdingAPI.csproj index 6fb1c336..53045ecb 100644 --- a/StardewModdingAPI/StardewModdingAPI.csproj +++ b/StardewModdingAPI/StardewModdingAPI.csproj @@ -44,7 +44,7 @@ - ..\..\..\..\Games\SteamLibrary + ..\ @@ -91,6 +91,10 @@ + + ..\packages\Newtonsoft.Json.8.0.2\lib\net45\Newtonsoft.Json.dll + True + False $(SteamPath)\steamapps\common\Stardew Valley\Stardew Valley.exe @@ -111,6 +115,7 @@ + @@ -143,6 +148,7 @@ + diff --git a/StardewModdingAPI/packages.config b/StardewModdingAPI/packages.config new file mode 100644 index 00000000..2abc396b --- /dev/null +++ b/StardewModdingAPI/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TrainerMod/TrainerMod.csproj b/TrainerMod/TrainerMod.csproj index ddf1b317..2baa6a26 100644 --- a/TrainerMod/TrainerMod.csproj +++ b/TrainerMod/TrainerMod.csproj @@ -34,16 +34,16 @@ false - - - $(SteamInstallPath) + + + $(SteamInstallPath) - - - - ..\..\..\..\Games\SteamLibrary - - + + + + ..\ + + @@ -52,6 +52,10 @@ False + + ..\packages\Newtonsoft.Json.8.0.3\lib\net45\Newtonsoft.Json.dll + True + $(SteamPath)\steamapps\common\Stardew Valley\Stardew Valley.exe False @@ -80,6 +84,9 @@ False + + + diff --git a/TrainerMod/packages.config b/TrainerMod/packages.config new file mode 100644 index 00000000..583acbdf --- /dev/null +++ b/TrainerMod/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file