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
{
/// <summary>
/// The name of your mod.
/// The mod's manifest
/// </summary>
public virtual string Name { get; protected 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; }
public Manifest Manifest { get; internal set; }
/// <summary>
/// Where the mod is located on the disk.

View File

@ -13,6 +13,7 @@ using System.Linq;
using System.Reflection;
using System.Threading;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace StardewModdingAPI
{
@ -131,7 +132,7 @@ namespace StardewModdingAPI
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} (@:{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.Entry(false);
StardewInjectorLoaded = true;
@ -312,34 +313,67 @@ namespace StardewModdingAPI
int loadedMods = 0;
foreach (string ModPath in _modPaths)
{
foreach (String s in Directory.GetFiles(ModPath, "*.dll"))
foreach (String d in Directory.GetDirectories(ModPath))
{
if (s.Contains("StardewInjector"))
continue;
StardewModdingAPI.Log.Success("Found DLL: " + s);
try
foreach (String s in Directory.GetFiles(d, "manifest.json"))
{
Assembly mod = Assembly.UnsafeLoadFrom(s); //to combat internet-downloaded DLLs
if (s.Contains("StardewInjector"))
continue;
StardewModdingAPI.Log.Success("Found Manifest: " + s);
Manifest manifest = new Manifest();
try
{
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;
}
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());
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);
loadedMods += 1;
m.Entry();
Assembly mod = Assembly.UnsafeLoadFrom(targDll);
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());
m.PathOnDisk = Path.GetDirectoryName(s);
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;
m.Entry();
}
else
{
StardewModdingAPI.Log.Error("Invalid Mod DLL");
}
}
else
catch (Exception ex)
{
StardewModdingAPI.Log.Error("Invalid Mod DLL");
StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s);
continue;
}
}
catch (Exception ex)
{
StardewModdingAPI.Log.Error("Failed to load mod '{0}'. Exception details:\n" + ex, s);
}
}
}
StardewModdingAPI.Log.Success("LOADED {0} MODS", loadedMods);
@ -400,7 +434,6 @@ namespace StardewModdingAPI
}
}
static void Events_LocationsChanged(List<GameLocation> newLocations)
{
#if DEBUG

View File

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

View File

@ -16,6 +16,7 @@ namespace TrainerMod
{
public class TrainerMod : Mod
{
/*
public override string Name
{
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."; }
}
*/
public static int frozenTime;
public static bool infHealth, infStamina, infMoney, freezeTime;

View File

@ -85,6 +85,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="manifest.json" />
<None Include="packages.config" />
</ItemGroup>
<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"
}