Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions StarMap.API/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,3 +220,31 @@ Methods marked with this attribute will be called after `KSA.Program.OnFrame` is
[StarMapAfterOnFrame]
public void ModMethod(double currentPlayerTime, double dtPlayer);
```

#### StarMapAfterSave

Namespace: `StarMap.API`
Assembly: `StarMap.API`
Target: Method

Methods marked with this attribute will be called after KSA has written a save, with the directory
it was written to. A mod that keeps per-save state can write its own file beside `universe.xml`.

```csharp
[StarMapAfterSave]
public void ModMethod(System.IO.DirectoryInfo saveDirectory);
```

#### StarMapAfterLoad

Namespace: `StarMap.API`
Assembly: `StarMap.API`
Target: Method

Methods marked with this attribute will be called after KSA has loaded a save, with the directory
it was read from.

```csharp
[StarMapAfterLoad]
public void ModMethod(System.IO.DirectoryInfo saveDirectory);
```
75 changes: 75 additions & 0 deletions StarMap.API/SaveAttributes.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
using System.IO;
using System.Reflection;

namespace StarMap.API
{
/// <summary>
/// Methods marked with this attribute will be called after KSA has written a save.
/// </summary>
/// <remarks>
/// Methods using this attribute must match the following signature:
///
/// <code>
/// public void MethodName(System.IO.DirectoryInfo saveDirectory);
/// </code>
///
/// Parameter requirements:
/// <list type="bullet">
/// <item>
/// <description>
/// <paramref name="saveDirectory"/> is the folder the save was written to.
/// </description>
/// </item>
/// </list>
///
/// Requirements:
/// <list type="bullet">
/// <item><description>Return type must be <see cref="void"/>.</description></item>
/// <item><description>Method must be an instance method (non-static).</description></item>
/// </list>
/// </remarks>
public sealed class StarMapAfterSaveAttribute : StarMapMethodAttribute
{
public override bool IsValidSignature(MethodInfo method)
{
return method.ReturnType == typeof(void) &&
method.GetParameters().Length == 1 &&
method.GetParameters()[0].ParameterType == typeof(DirectoryInfo);
}
}

/// <summary>
/// Methods marked with this attribute will be called after KSA has loaded a save.
/// </summary>
/// <remarks>
/// Methods using this attribute must match the following signature:
///
/// <code>
/// public void MethodName(System.IO.DirectoryInfo saveDirectory);
/// </code>
///
/// Parameter requirements:
/// <list type="bullet">
/// <item>
/// <description>
/// <paramref name="saveDirectory"/> is the folder the save was read from.
/// </description>
/// </item>
/// </list>
///
/// Requirements:
/// <list type="bullet">
/// <item><description>Return type must be <see cref="void"/>.</description></item>
/// <item><description>Method must be an instance method (non-static).</description></item>
/// </list>
/// </remarks>
public sealed class StarMapAfterLoadAttribute : StarMapMethodAttribute
{
public override bool IsValidSignature(MethodInfo method)
{
return method.ReturnType == typeof(void) &&
method.GetParameters().Length == 1 &&
method.GetParameters()[0].ParameterType == typeof(DirectoryInfo);
}
}
}
42 changes: 42 additions & 0 deletions StarMap.Core/Patches/UniverseDataPatcher.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System.IO;
using HarmonyLib;
using KSA;
using StarMap.API;

namespace StarMap.Core.Patches
{
/// <summary>
/// Tells mods when a save is written or read, and which directory it is in.
/// </summary>
[HarmonyPatch(typeof(UniverseData))]
internal static class UniverseDataPatcher
{
private const string WriteToMethodName = "WriteTo";
private const string LoadFromMethodName = "LoadFrom";

// WriteTo is overloaded; the DirectoryInfo one is the save on disk.
[HarmonyPatch(WriteToMethodName, [typeof(DirectoryInfo)])]
[HarmonyPostfix]
public static void AfterWriteTo(DirectoryInfo directory)
{
var methods = StarMapCore.Instance?.Loader.ModRegistry.Get<StarMapAfterSaveAttribute>() ?? [];

foreach (var (_, @object, method) in methods)
{
method.Invoke(@object, [directory]);
}
}

[HarmonyPatch(LoadFromMethodName)]
[HarmonyPostfix]
public static void AfterLoadFrom(UncompressedSave uncompressedSave)
{
var methods = StarMapCore.Instance?.Loader.ModRegistry.Get<StarMapAfterLoadAttribute>() ?? [];

foreach (var (_, @object, method) in methods)
{
method.Invoke(@object, [uncompressedSave.Directory]);
}
}
}
}