converted mod loading to a manifest structure. mods now go in ./Mods/<MODNAME>/ - in there you need a 'manifest.json' and your dll. See trainermod for example.

This commit is contained in:
Zoryn Aaron 2016-03-20 17:19:02 -04:00
parent cee85c8888
commit f0cb2c0e63
7 changed files with 102 additions and 40 deletions

View File

@ -0,0 +1,33 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StardewModdingAPI
{
public class Manifest
{
/// <summary>
/// The name of your mod.
/// </summary>
public virtual string Name { get; set; }
/// <summary>
/// The name of the mod's authour.
/// </summary>
public virtual string Authour { get; set; }
/// <summary>
/// The version of the mod.
/// </summary>
public virtual string Version { get; set; }
/// <summary>
/// A description of the mod.
/// </summary>
public virtual string Description { get; set; }
public string EntryDll { get; set; }
}
}

View File

@ -9,24 +9,9 @@ namespace StardewModdingAPI
public class Mod public class Mod
{ {
/// <summary> /// <summary>
/// The name of your mod. /// The mod's manifest
/// </summary> /// </summary>
public virtual string Name { get; protected set; } public Manifest Manifest { get; internal set; }
/// <summary>
/// The name of the mod's authour.
/// </summary>
public virtual string Authour { get; protected set; }
/// <summary>
/// The version of the mod.
/// </summary>
public virtual string Version { get; protected set; }
/// <summary>
/// A description of the mod.
/// </summary>
public virtual string Description { get; protected set; }
/// <summary> /// <summary>
/// Where the mod is located on the disk. /// Where the mod is located on the disk.

View File

@ -13,6 +13,7 @@ using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading; using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using Newtonsoft.Json;
namespace StardewModdingAPI namespace StardewModdingAPI
{ {
@ -131,7 +132,7 @@ namespace StardewModdingAPI
StardewModdingAPI.Log.Success("Loading Injector DLL..."); StardewModdingAPI.Log.Success("Loading Injector DLL...");
TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof(Mod)); TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof(Mod));
Mod m = (Mod)mod.CreateInstance(tar.ToString()); Mod m = (Mod)mod.CreateInstance(tar.ToString());
Console.WriteLine("LOADED: {0} by {1} - Version {2} | Description: {3} (@:{4})", m.Name, m.Authour, m.Version, m.Description, s); Console.WriteLine("LOADED: {0} by {1} - Version {2} | Description: {3} (@:{4})", m.Manifest.Name, m.Manifest.Authour, m.Manifest.Version, m.Manifest.Description, s);
m.PathOnDisk = Path.GetDirectoryName(s); m.PathOnDisk = Path.GetDirectoryName(s);
m.Entry(false); m.Entry(false);
StardewInjectorLoaded = true; StardewInjectorLoaded = true;
@ -312,14 +313,44 @@ namespace StardewModdingAPI
int loadedMods = 0; int loadedMods = 0;
foreach (string ModPath in _modPaths) foreach (string ModPath in _modPaths)
{ {
foreach (String s in Directory.GetFiles(ModPath, "*.dll")) foreach (String d in Directory.GetDirectories(ModPath))
{
foreach (String s in Directory.GetFiles(d, "manifest.json"))
{ {
if (s.Contains("StardewInjector")) if (s.Contains("StardewInjector"))
continue; continue;
StardewModdingAPI.Log.Success("Found DLL: " + s); StardewModdingAPI.Log.Success("Found Manifest: " + s);
Manifest manifest = new Manifest();
try try
{ {
Assembly mod = Assembly.UnsafeLoadFrom(s); //to combat internet-downloaded DLLs string t = File.ReadAllText(s);
if (string.IsNullOrEmpty(t))
{
StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. Manifest is empty!", s);
continue;
}
manifest = JsonConvert.DeserializeObject<Manifest>(t);
if (string.IsNullOrEmpty(manifest.EntryDll))
{
StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. EntryDll is empty!", s);
continue;
}
}
catch (Exception ex)
{
StardewModdingAPI.Log.Error("Failed to read mod manifest '{0}'. Exception details:\n" + ex, s);
continue;
}
try
{
string targDll = Path.Combine(Path.GetDirectoryName(s), manifest.EntryDll);
if (!File.Exists(targDll))
{
StardewModdingAPI.Log.Error("Failed to load mod '{0}'. File {1} does not exist!", s, targDll);
continue;
}
Assembly mod = Assembly.UnsafeLoadFrom(targDll);
if (mod.DefinedTypes.Count(x => x.BaseType == typeof (Mod)) > 0) if (mod.DefinedTypes.Count(x => x.BaseType == typeof (Mod)) > 0)
{ {
@ -327,7 +358,8 @@ namespace StardewModdingAPI
TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof (Mod)); TypeInfo tar = mod.DefinedTypes.First(x => x.BaseType == typeof (Mod));
Mod m = (Mod) mod.CreateInstance(tar.ToString()); Mod m = (Mod) mod.CreateInstance(tar.ToString());
m.PathOnDisk = Path.GetDirectoryName(s); m.PathOnDisk = Path.GetDirectoryName(s);
Console.WriteLine("LOADED MOD: {0} by {1} - Version {2} | Description: {3} (@{4})", m.Name, m.Authour, m.Version, m.Description, m.PathOnDisk); m.Manifest = manifest;
StardewModdingAPI.Log.Success("LOADED MOD: {0} by {1} - Version {2} | Description: {3} (@ {4})", m.Manifest.Name, m.Manifest.Authour, m.Manifest.Version, m.Manifest.Description, targDll);
loadedMods += 1; loadedMods += 1;
m.Entry(); m.Entry();
} }
@ -339,6 +371,8 @@ namespace StardewModdingAPI
catch (Exception ex) catch (Exception ex)
{ {
StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s); StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s);
continue;
}
} }
} }
} }
@ -400,7 +434,6 @@ namespace StardewModdingAPI
} }
} }
static void Events_LocationsChanged(List<GameLocation> newLocations) static void Events_LocationsChanged(List<GameLocation> newLocations)
{ {
#if DEBUG #if DEBUG

View File

@ -150,6 +150,7 @@
<Compile Include="Inheritance\SGameLocation.cs" /> <Compile Include="Inheritance\SGameLocation.cs" />
<Compile Include="Inheritance\SObject.cs" /> <Compile Include="Inheritance\SObject.cs" />
<Compile Include="Log.cs" /> <Compile Include="Log.cs" />
<Compile Include="Manifest.cs" />
<Compile Include="Mod.cs" /> <Compile Include="Mod.cs" />
<Compile Include="ModItem.cs" /> <Compile Include="ModItem.cs" />
<Compile Include="Program.cs" /> <Compile Include="Program.cs" />

View File

@ -16,6 +16,7 @@ namespace TrainerMod
{ {
public class TrainerMod : Mod public class TrainerMod : Mod
{ {
/*
public override string Name public override string Name
{ {
get { return "Trainer Mod"; } get { return "Trainer Mod"; }
@ -35,6 +36,7 @@ namespace TrainerMod
{ {
get { return "Registers several commands to use. Most commands are trainer-like in that they offer forms of cheating."; } get { return "Registers several commands to use. Most commands are trainer-like in that they offer forms of cheating."; }
} }
*/
public static int frozenTime; public static int frozenTime;
public static bool infHealth, infStamina, infMoney, freezeTime; public static bool infHealth, infStamina, infMoney, freezeTime;

View File

@ -85,6 +85,7 @@
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="manifest.json" />
<None Include="packages.config" /> <None Include="packages.config" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

7
TrainerMod/manifest.json Normal file
View File

@ -0,0 +1,7 @@
{
"Name": "Trainer Mod",
"Authour": "Zoryn",
"Version": "1.0",
"Description": "Registers several commands to use. Most commands are trainer-like in that they offer forms of cheating.",
"EntryDll": "TrainerMod.dll"
}