Skip to content

Commit

Permalink
Patcher API implementation (with a bug)
Browse files Browse the repository at this point in the history
  • Loading branch information
jan-bures committed Jan 11, 2024
1 parent 639dcbe commit 59bdd47
Show file tree
Hide file tree
Showing 41 changed files with 369 additions and 133 deletions.
12 changes: 11 additions & 1 deletion SpaceWarp.sln
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.UI", "src/SpaceWa
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.VersionChecking", "src/SpaceWarp.VersionChecking/SpaceWarp.VersionChecking.csproj", "{6B76C415-5BC2-4AB0-8862-760D9DC8F485}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.Patcher", "src\SpaceWarp.Patcher\SpaceWarp.Patcher.csproj", "{2EF642D0-F66D-461C-A5B0-953E39307B76}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.Preload", "src\SpaceWarp.Preload\SpaceWarp.Preload.csproj", "{2EF642D0-F66D-461C-A5B0-953E39307B76}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarpTest", "src/SpaceWarpTest/SpaceWarpTest.csproj", "{8DB42693-9177-40B9-AC6A-B6D7A4823FAD}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.Patches", "src\SpaceWarp.Patches\SpaceWarp.Patches.csproj", "{88F73A97-3D47-4ED3-8381-177EED4451AC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down Expand Up @@ -108,6 +110,14 @@ Global
{4B509D31-4C02-4D6E-8508-8417F0745776}.Deploy|Any CPU.Build.0 = Deploy|Any CPU
{4B509D31-4C02-4D6E-8508-8417F0745776}.DeployAndRun|Any CPU.ActiveCfg = DeployAndRun|Any CPU
{4B509D31-4C02-4D6E-8508-8417F0745776}.DeployAndRun|Any CPU.Build.0 = DeployAndRun|Any CPU
{88F73A97-3D47-4ED3-8381-177EED4451AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{88F73A97-3D47-4ED3-8381-177EED4451AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{88F73A97-3D47-4ED3-8381-177EED4451AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{88F73A97-3D47-4ED3-8381-177EED4451AC}.Release|Any CPU.Build.0 = Release|Any CPU
{88F73A97-3D47-4ED3-8381-177EED4451AC}.Deploy|Any CPU.ActiveCfg = Deploy|Any CPU
{88F73A97-3D47-4ED3-8381-177EED4451AC}.Deploy|Any CPU.Build.0 = Deploy|Any CPU
{88F73A97-3D47-4ED3-8381-177EED4451AC}.DeployAndRun|Any CPU.ActiveCfg = DeployAndRun|Any CPU
{88F73A97-3D47-4ED3-8381-177EED4451AC}.DeployAndRun|Any CPU.Build.0 = DeployAndRun|Any CPU
EndGlobalSection
EndGlobal

2 changes: 1 addition & 1 deletion src/SpaceWarp.Core/API/Mods/PluginList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
using JetBrains.Annotations;
using SpaceWarp.API.Mods.JSON;
using SpaceWarp.API.Versions;
using SpaceWarp.Patcher.API;
using SpaceWarp.Preload.API;

// Disable obsolete warning for Chainloader.Plugins
#pragma warning disable CS0618
Expand Down
4 changes: 1 addition & 3 deletions src/SpaceWarp.Core/Backend/Modding/PluginRegister.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@
using SpaceWarp.API.Mods;
using SpaceWarp.API.Mods.JSON;
using SpaceWarp.API.Versions;
using SpaceWarp.Patcher;
using SpaceWarp.Patcher.API;
using SpaceWarp.Patcher.Patches;
using SpaceWarp.Preload.API;

namespace SpaceWarp.Backend.Modding;

Expand Down
3 changes: 1 addition & 2 deletions src/SpaceWarp.Core/Patching/Mods/ModLoaderPatch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
using SpaceWarp.API.Mods.JSON;
using SpaceWarp.Backend.Modding;
using SpaceWarp.InternalUtilities;
using SpaceWarp.Patcher;
using SpaceWarp.Patcher.API;
using SpaceWarp.Preload.API;
using UnityEngine;
using File = System.IO.File;

Expand Down
2 changes: 1 addition & 1 deletion src/SpaceWarp.Core/SpaceWarp.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<PackageReference Include="UnityEngine.Modules" Version="2022.3.5" Publicize="true"/>
</ItemGroup>
<ItemGroup Label="Project references">
<ProjectReference Include="..\SpaceWarp.Patcher\SpaceWarp.Patcher.csproj">
<ProjectReference Include="..\SpaceWarp.Preload\SpaceWarp.Preload.csproj">
<Private>false</Private>
<PrivateAssets>all</PrivateAssets>
</ProjectReference>
Expand Down
72 changes: 0 additions & 72 deletions src/SpaceWarp.Patcher/Patcher.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
using System.Security.Cryptography;
using System.Text;
using BepInEx;
using Newtonsoft.Json.Linq;
using SpaceWarp.Preload.API;

namespace SpaceWarp.Patcher.Backend;
namespace SpaceWarp.Patches.Backend;

internal static class SwinfoTransformer
internal static class ModInfoGenerator
{
public static void TransformModSwinfos()
public static void TransformSwinfosToModInfos()
{
var dir = new DirectoryInfo(Path.Combine(Paths.GameRootPath, "GameData", "Mods"));
var dir = new DirectoryInfo(Path.Combine(CommonPaths.GameRootPath, "GameData", "Mods"));
if (!dir.Exists)
{
return;
Expand Down Expand Up @@ -43,11 +43,11 @@ public static void TransformModSwinfos()
continue;
}

File.WriteAllText(target,TransformSwinfo(swinfoData,hash, directory).ToString());
File.WriteAllText(target,TransformSwinfoToModInfo(swinfoData,hash, directory).ToString());
}
}

private static JObject TransformSwinfo(JObject swinfo, string hash, DirectoryInfo directoryInfo)
private static JObject TransformSwinfoToModInfo(JObject swinfo, string hash, DirectoryInfo directoryInfo)
{
var addressables = Path.Combine(directoryInfo.FullName, "addressables");
string catalog = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Newtonsoft.Json.Linq;
using SpaceWarp.Preload.API;

namespace SpaceWarp.Patcher.Backend;
namespace SpaceWarp.Patches.Backend;

internal static class PathsGenerator
{
Expand Down Expand Up @@ -46,7 +47,7 @@ private static bool IsDisabled(FileInfo jsonFile, string[] allDisabled)

internal static void GenerateSpaceWarpPathsDLL(bool changed, ManualLogSource trueLogger)
{
var cacheLocation = Path.Combine(Paths.BepInExRootPath, "AssemblyCache");
var cacheLocation = Path.Combine(CommonPaths.BepInExRootPath, "AssemblyCache");

try
{
Expand All @@ -56,7 +57,7 @@ internal static void GenerateSpaceWarpPathsDLL(bool changed, ManualLogSource tru
// Preload newtonsoft.json
try
{
Assembly.LoadFile(Path.Combine(Paths.ManagedPath, "Newtonsoft.Json.dll"));
Assembly.LoadFile(Path.Combine(CommonPaths.ManagedPath, "Newtonsoft.Json.dll"));
}
catch (Exception e)
{
Expand Down Expand Up @@ -114,18 +115,18 @@ internal static void GenerateSpaceWarpPathsDLL(bool changed, ManualLogSource tru

private static string GetSpaceWarpPathsCode()
{
var disabledPluginsFilepath = Path.Combine(Paths.BepInExRootPath, "disabled_plugins.cfg");
var disabledPluginsFilepath = Path.Combine(CommonPaths.BepInExRootPath, "disabled_plugins.cfg");
var allDisabled = File.ReadAllText(disabledPluginsFilepath)
.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
var allSwinfoPaths = new DirectoryInfo(Path.Combine(Paths.BepInExRootPath, "plugins"))
var allSwinfoPaths = new DirectoryInfo(Path.Combine(CommonPaths.BepInExRootPath, "plugins"))
.EnumerateFiles("swinfo.json", SearchOption.AllDirectories)
.Where(x => IsDisabled(x, allDisabled));

var gameDataMods = new DirectoryInfo(Path.Combine(Paths.GameRootPath, "GameData", "Mods"));
var gameDataMods = new DirectoryInfo(Path.Combine(CommonPaths.GameRootPath, "GameData", "Mods"));
if (gameDataMods.Exists)
{
allSwinfoPaths = allSwinfoPaths.Concat(
new DirectoryInfo(Path.Combine(Paths.GameRootPath, "GameData", "Mods"))
new DirectoryInfo(Path.Combine(CommonPaths.GameRootPath, "GameData", "Mods"))
.EnumerateFiles("swinfo.json", SearchOption.AllDirectories)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@
using BepInEx.Logging;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using SpaceWarp.Patcher.API;
using SpaceWarp.Preload.API;

namespace SpaceWarp.Patcher.Backend;
namespace SpaceWarp.Patches.Backend;

internal static class RoslynCompiler
{
Expand Down Expand Up @@ -36,18 +36,18 @@ public static bool CompileMods(ManualLogSource trueLogger)
"System.Numerics.Vectors"
];

var loc = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent!.FullName;
var loc = new DirectoryInfo(Assembly.GetExecutingAssembly().Location).Parent!.Parent!.FullName;
foreach (var file in toLoad)
{
trueLogger.LogInfo($"Loading: {file}");
Assembly.LoadFile(Path.Combine(loc, "lib", $"{file}.dll"));
}

var cacheLocation = Path.Combine(Paths.BepInExRootPath, "AssemblyCache");
var modListHash = Path.Combine(Paths.BepInExRootPath, "ModListHash.txt");
var disabledPluginsFilepath = Path.Combine(Paths.BepInExRootPath, "disabled_plugins.cfg");
var cacheLocation = Path.Combine(CommonPaths.BepInExRootPath, "AssemblyCache");
var modListHash = Path.Combine(CommonPaths.BepInExRootPath, "ModListHash.txt");
var disabledPluginsFilepath = Path.Combine(CommonPaths.BepInExRootPath, "disabled_plugins.cfg");

var allPluginsSwinfo = string.Join("", new DirectoryInfo(Path.Combine(Paths.BepInExRootPath, "plugins"))
var allPluginsSwinfo = string.Join("", new DirectoryInfo(Path.Combine(CommonPaths.BepInExRootPath, "plugins"))
.EnumerateFiles("swinfo.json", SearchOption.AllDirectories)
.Select(x => File.ReadAllText(x.FullName)));
allPluginsSwinfo += File.ReadAllText(disabledPluginsFilepath);
Expand Down Expand Up @@ -100,7 +100,7 @@ public static bool CompileMods(ManualLogSource trueLogger)

trueLogger.LogInfo("Loaded assemblies");
// So now we can compile roslyn based mods by first importing every precompiled DLL
var pluginsFilePath = new DirectoryInfo(Path.Combine(Paths.BepInExRootPath, "plugins"));
var pluginsFilePath = new DirectoryInfo(Path.Combine(CommonPaths.BepInExRootPath, "plugins"));
// So now we do a loop and generate a reference table to every plugin name that does not start with "roslyn-"
// And we keep track of every folder that contains a src folder

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,35 @@
using HarmonyLib;
using Mono.Cecil.Cil;
using MonoMod.Cil;
using SpaceWarp.Patcher.API;
using SpaceWarp.Patcher.Backend;
using SpaceWarp.Patches.Backend;
using SpaceWarp.Preload;
using SpaceWarp.Preload.API;

namespace SpaceWarp.Patcher.Patches;
namespace SpaceWarp.Patches;

/// <summary>
/// Patches the Chainloader.Start method to disable plugins.
/// Patches BepInEx's Chainloader.Start method to disable plugins, generate the mod paths DLL, compile Roslyn mods
/// and transform swinfo files to modinfo files.
/// </summary>
[HarmonyPatch]
public static class ChainloaderPatch
internal static class ChainloaderPatch
{
[HarmonyPrefix]
[HarmonyPatch(typeof(Chainloader), nameof(Chainloader.Start))]
private static void PreStartActions()
{
var trueLogger = Logger.CreateLogSource("Roslyn Compiler");

// Compile Roslyn mods
var changed = RoslynCompiler.CompileMods(trueLogger);

// Generate the mod paths DLL
PathsGenerator.GenerateSpaceWarpPathsDLL(changed, trueLogger);

try
{
SwinfoTransformer.TransformModSwinfos();
// Transform swinfo files in the internal mod loader folder to modinfo files
ModInfoGenerator.TransformSwinfosToModInfos();
}
catch (Exception e)
{
Expand All @@ -41,7 +49,8 @@ private static void DisablePluginsIL(ILContext il)
ILLabel continueLabel = default;
c.GotoNext(
MoveType.After,
x => x.MatchBrfalse(out continueLabel), // this is from a continue, we use this to start the next iteration
// this is from a continue, we use this to start the next iteration:
x => x.MatchBrfalse(out continueLabel),
x => x.MatchLdcI4(0), // false
x => x.MatchStloc(24) // someBool = false
);
Expand All @@ -58,7 +67,7 @@ private static void DisablePluginsIL(ILContext il)

deniedSet.Add(plugin.Metadata.GUID);
ModList.DisabledPlugins.Add(plugin);
Patcher.LogSource.LogInfo($"{plugin.Metadata.GUID} was disabled, skipping loading...");
Entrypoint.LogSource.LogInfo($"{plugin.Metadata.GUID} was disabled, skipping loading...");
return false;

});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,28 @@
using Mono.Collections.Generic;
using MonoMod.Cil;
using MonoMod.Utils;
using SpaceWarp.Preload.API;

namespace SpaceWarp.Patcher.Patches;
namespace SpaceWarp.Patches;

/// <summary>
/// Patcher for the game's main DLL
/// Patches the game so that parts can register their own resource flow requests.
/// </summary>
[UsedImplicitly]
public class ResourceFlowPatch
internal class ResourceFlowPatch : BasePatcher
{
/// <summary>
/// The target DLLs to patch
/// </summary>
[UsedImplicitly]
public static IEnumerable<string> TargetDLLs => new[] { "Assembly-CSharp.dll" };
public override IEnumerable<string> DLLsToPatch => ["Assembly-CSharp.dll"];

/// <summary>
/// Patches the target DLL
/// </summary>
/// <param name="assemblyDefinition">The assembly definition to patch</param>
[UsedImplicitly]
public static void Patch(ref AssemblyDefinition assemblyDefinition)
public override void ApplyPatch(ref AssemblyDefinition assemblyDefinition)
{
var firstTargetType = assemblyDefinition.MainModule.Types.First(t => t.Name == "PartOwnerComponent");
var boolType = firstTargetType.Fields
Expand Down
12 changes: 12 additions & 0 deletions src/SpaceWarp.Patches/SpaceWarp.Patches.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<!-- References -->
<ItemGroup Label="NuGet package references">
<PackageReference Include="HarmonyX" Version="2.10.1"/>
<PackageReference Include="JetBrains.Annotations" Version="2023.3.0" PrivateAssets="all"/>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3"/>
</ItemGroup>
<ItemGroup Label="Project references">
<ProjectReference Include="$(SolutionDir)/src/SpaceWarp.Preload/SpaceWarp.Preload.csproj" Private="false"/>
</ItemGroup>
</Project>
Loading

0 comments on commit 59bdd47

Please sign in to comment.