Skip to content

Commit

Permalink
Use MMRD 25x for nuget package
Browse files Browse the repository at this point in the history
  • Loading branch information
SignatureBeef committed Jan 4, 2025
1 parent 0d14774 commit 7c0a6e8
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 50 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
runs-on: ubuntu-latest,
},
{
name: macOS,
name: MacOS,
runs-on: macos-latest,
}
]
Expand Down
48 changes: 0 additions & 48 deletions OTAPI.Client.Launcher/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,11 @@ You should have received a copy of the GNU General Public License
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Markup.Xaml;
using Mono.Cecil;
using Mono.Cecil.Cil;
using OTAPI.Client.Launcher.Targets;
using OTAPI.Common;
using OTAPI.Patcher.Targets;
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading.Tasks;

Expand Down Expand Up @@ -82,8 +79,6 @@ public MainWindow()

if (Program.ConsoleWriter is not null)
Program.ConsoleWriter.LineReceived += OnConsoleLineReceived;

PatchMonoMod();
}

private void OnConsoleLineReceived(string line)
Expand Down Expand Up @@ -246,47 +241,4 @@ public void OnInstall(object sender, RoutedEventArgs e)
}
});
}

/// <summary>
/// Current MonoMod is outdated, and the new reorg is not ready yet, however we need v25 RD for NET9, yet Patcher v22 is the latest, and is not compatible with v25.
/// Ultimately the problem is OTAPI Client using both at once, unlike the server setup which doesnt.
/// For now, the intention is to replace the entire both with "return new string[0];" to prevent the GAC IL from being used (which it isn't anyway)
/// </summary>
void PatchMonoMod()
{
var bin = File.ReadAllBytes("MonoMod.dll");
using MemoryStream ms = new(bin);
var asm = AssemblyDefinition.ReadAssembly(ms);
var modder = asm.MainModule.Types.Single(x => x.FullName == "MonoMod.MonoModder");
var gacPaths = modder.Methods.Single(m => m.Name == "get_GACPaths");
var il = gacPaths.Body.GetILProcessor();
if (il.Body.Instructions.Count != 3)
{
il.Body.Instructions.Clear();
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Newarr, asm.MainModule.ImportReference(typeof(string)));
il.Emit(OpCodes.Ret);

// clear MonoModder.MatchingConditionals(cap, asmName), with "return false;"
var mc = modder.Methods.Single(m => m.Name == "MatchingConditionals" && m.Parameters.Count == 2 && m.Parameters[1].ParameterType.Name == "AssemblyNameReference");
il = mc.Body.GetILProcessor();
mc.Body.Instructions.Clear();
mc.Body.Variables.Clear();
mc.Body.ExceptionHandlers.Clear();
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ret);

var writerParams = modder.Methods.Single(m => m.Name == "get_WriterParameters");
il = writerParams.Body.GetILProcessor();
var get_Current = writerParams.Body.Instructions.Single(x => x.Operand is MethodReference mref && mref.Name == "get_Current");
// replace get_Current with a number, and remove the bitwise checks
il.Remove(get_Current.Next);
il.Remove(get_Current.Next);
il.Replace(get_Current, Instruction.Create(
OpCodes.Ldc_I4, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 37 : 0
));

asm.Write("MonoMod.dll");
}
}
}
2 changes: 1 addition & 1 deletion OTAPI.Patcher/NugetPackageBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public void Build(ModFwModder modder)
{
(typeof(ModFwModder).Assembly.GetName().Name, Version: GetNugetVersionFromAssembly<ModFwModder>()),
(typeof(MonoMod.MonoModder).Assembly.GetName().Name, Version: typeof(MonoMod.MonoModder).Assembly.GetName().Version.ToString()),
(typeof(MonoMod.RuntimeDetour.Detour).Assembly.GetName().Name, Version: typeof(MonoMod.RuntimeDetour.Detour).Assembly.GetName().Version.ToString()),
(typeof(MonoMod.RuntimeDetour.DetourBase).Assembly.GetName().Name, Version: typeof(MonoMod.RuntimeDetour.DetourBase).Assembly.GetName().Version.ToString()),
(steamworks.Name, Version: steamworks.Version.ToString()),
(newtonsoft.Name, Version: GetNugetVersionFromAssembly<Newtonsoft.Json.JsonConverter>().Split('+')[0] ),
};
Expand Down
1 change: 1 addition & 0 deletions OTAPI.Patcher/OTAPI.Patcher.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<PackageReference Include="ModFramework.Modules.Lua" Version="1.1.13" />
<PackageReference Include="Steamworks.NET" Version="2024.8.0" />
<PackageReference Include="MonoMod.RuntimeDetour.HookGen" Version="22.7.31.1" />
<PackageReference Include="MonoMod.RuntimeDetour" Version="25.2.2" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.Private.Uri" Version="4.3.2" />
<PackageReference Include="System.Security.Permissions" Version="9.0.0" />
Expand Down
49 changes: 49 additions & 0 deletions OTAPI.Patcher/Targets/PatchTargets.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ You should have received a copy of the GNU General Public License
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using Mono.Cecil;
using Mono.Cecil.Cil;

namespace OTAPI.Patcher.Targets;

Expand Down Expand Up @@ -68,4 +73,48 @@ public static IPatchTarget DeterminePatchTarget()

return new PCServerTarget();
}

static PatchTargets() => PatchMonoMod();
/// <summary>
/// Current MonoMod is outdated, and the new reorg is not ready yet, however we need v25 RD for NET9, yet Patcher v22 is the latest, and is not compatible with v25.
/// Ultimately the problem is OTAPI using both relinker+rd at once.
/// For now, the intention is to replace the entire both with "return new string[0];" to prevent the GAC IL from being used (which it isn't anyway)
/// </summary>
public static void PatchMonoMod()
{
var bin = File.ReadAllBytes("MonoMod.dll");
using MemoryStream ms = new(bin);
var asm = AssemblyDefinition.ReadAssembly(ms);
var modder = asm.MainModule.Types.Single(x => x.FullName == "MonoMod.MonoModder");
var gacPaths = modder.Methods.Single(m => m.Name == "get_GACPaths");
var il = gacPaths.Body.GetILProcessor();
if (il.Body.Instructions.Count != 3)
{
il.Body.Instructions.Clear();
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Newarr, asm.MainModule.ImportReference(typeof(string)));
il.Emit(OpCodes.Ret);

// clear MonoModder.MatchingConditionals(cap, asmName), with "return false;"
var mc = modder.Methods.Single(m => m.Name == "MatchingConditionals" && m.Parameters.Count == 2 && m.Parameters[1].ParameterType.Name == "AssemblyNameReference");
il = mc.Body.GetILProcessor();
mc.Body.Instructions.Clear();
mc.Body.Variables.Clear();
mc.Body.ExceptionHandlers.Clear();
il.Emit(OpCodes.Ldc_I4_1);
il.Emit(OpCodes.Ret);

var writerParams = modder.Methods.Single(m => m.Name == "get_WriterParameters");
il = writerParams.Body.GetILProcessor();
var get_Current = writerParams.Body.Instructions.Single(x => x.Operand is MethodReference mref && mref.Name == "get_Current");
// replace get_Current with a number, and remove the bitwise checks
il.Remove(get_Current.Next);
il.Remove(get_Current.Next);
il.Replace(get_Current, Instruction.Create(
OpCodes.Ldc_I4, RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? 37 : 0
));

asm.Write("MonoMod.dll");
}
}
}

0 comments on commit 7c0a6e8

Please sign in to comment.