BattletechModders / BattleTechModLoader

A simple mod loader and injector for HBS's PC game BattleTech.
The Unlicense
48 stars 10 forks source link

OSX Support #5

Closed ffaristocrat closed 6 years ago

ffaristocrat commented 6 years ago

Obviously don't expect this to be a priority but wanted to put it on the radar.

I'm going to take a stab at compiling this and report back.

Tyler-IN commented 6 years ago

looking forward to your feedback

ffaristocrat commented 6 years ago

Alright, this took a while to narrow down. I don't know a ton about C#, Mono or Visual Studio so I'm not sure how to fix the issue. But I've at least been able to figure out what works & what doesn't.

Running OSX High Sierra 10.13.4

So putting the current release's files in the BattleTech.app package and running mono BattleTechModLoaderInjector.exe

results in

BattleTechModLoader Injector
----------------------------
An exception occured: System.MissingMethodException: !!0 System.Linq.Enumerable.First<!0>(System.Collections.Generic.IEnumerable`1<!!0>,System.Func`2<!!0, bool>)
  at BattleTechModLoader.BTMLInjector.Main (System.String[] args) [0x00067] in <dee73dca3dba496696680c1c266c6c33>:0

I figured there might be some OSX compilation issue, etc. Anyways, I got it to build in OSX after making a couple tweaks to the project files (VS2017 really does not like referencing DLLs outside the project directory). My first couple runs from the editor didn't work out well until I realized it wasn't in the same directory as the file it was patching, lol.

I moved the Assembly-CSharp.dll and Assembly-CSharp-firstpass.dll into the directory. This time I get

BattleTechModLoader Injector
----------------------------
Assembly-CSharp.dll backed up to Assembly-CSharp.dll.orig
Injecting Assembly-CSharp.dll with BattleTechModLoader.BTModLoader.Init at BattleTech.GameInstance..ctor
Writing back to Assembly-CSharp.dll...
An exception occured: Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'UnityEngine, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
  at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) [0x00105] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name) [0x00007] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.DefaultAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name) [0x0001d] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataResolver.Resolve (Mono.Cecil.TypeReference type) [0x00038] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Resolve (Mono.Cecil.TypeReference type) [0x00006] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.TypeReference.Resolve () [0x00006] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.Mixin.CheckedResolve (Mono.Cecil.TypeReference self) [0x00000] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.GetConstantType (Mono.Cecil.TypeReference constant_type, System.Object constant) [0x000a1] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddConstant (Mono.Cecil.IConstantProvider owner, Mono.Cecil.TypeReference type) [0x00007] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddParameter (System.UInt16 sequence, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.ParamTable table) [0x0005f] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddParameters (Mono.Cecil.MethodDefinition method) [0x00049] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddMethod (Mono.Cecil.MethodDefinition method) [0x0005a] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddMethods (Mono.Cecil.TypeDefinition type) [0x00013] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddType (Mono.Cecil.TypeDefinition type) [0x000a2] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddTypes () [0x00018] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.BuildTypes () [0x00014] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.BuildModule () [0x0009f] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.BuildMetadata () [0x00000] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleWriter+<>c.<BuildMetadata>b__2_0 (Mono.Cecil.MetadataBuilder builder, Mono.Cecil.MetadataReader _) [0x00000] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Read[TItem,TRet] (TItem item, System.Func`3[T1,T2,TResult] read) [0x00029] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleWriter.BuildMetadata (Mono.Cecil.ModuleDefinition module, Mono.Cecil.MetadataBuilder metadata) [0x0000f] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleWriter.Write (Mono.Cecil.ModuleDefinition module, Mono.Disposable`1[T] stream, Mono.Cecil.WriterParameters parameters) [0x000fb] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleWriter.WriteModule (Mono.Cecil.ModuleDefinition module, Mono.Disposable`1[T] stream, Mono.Cecil.WriterParameters parameters) [0x00002] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Write (System.IO.Stream stream, Mono.Cecil.WriterParameters parameters) [0x00019] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Write (Mono.Cecil.WriterParameters parameters) [0x0000e] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Write () [0x00006] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at BattleTechModLoader.BTMLInjector.Inject (System.String hookFilePath, System.String hookType, System.String hookMethod, System.String injectFilePath, System.String injectType, System.String injectMethod) [0x000ef] in <17ce556bf09d4b70adc18b505f1f1f72>:0 
  at BattleTechModLoader.BTMLInjector.Main () [0x00060] in <17ce556bf09d4b70adc18b505f1f1f72>:0

So I move UnityEngine.DLL into the directory, run and now it's

BattleTechModLoader Injector
----------------------------
Assembly-CSharp.dll backed up to Assembly-CSharp.dll.orig
Injecting Assembly-CSharp.dll with BattleTechModLoader.BTModLoader.Init at BattleTech.GameInstance..ctor
Writing back to Assembly-CSharp.dll...
An exception occured: Mono.Cecil.AssemblyResolutionException: Failed to resolve assembly: 'DOTween, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
  at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name, Mono.Cecil.ReaderParameters parameters) [0x00105] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.BaseAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name) [0x00007] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.DefaultAssemblyResolver.Resolve (Mono.Cecil.AssemblyNameReference name) [0x0001d] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataResolver.Resolve (Mono.Cecil.TypeReference type) [0x00038] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Resolve (Mono.Cecil.TypeReference type) [0x00006] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.TypeReference.Resolve () [0x00006] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.Mixin.CheckedResolve (Mono.Cecil.TypeReference self) [0x00000] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.GetConstantType (Mono.Cecil.TypeReference constant_type, System.Object constant) [0x000a1] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddConstant (Mono.Cecil.IConstantProvider owner, Mono.Cecil.TypeReference type) [0x00007] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddParameter (System.UInt16 sequence, Mono.Cecil.ParameterDefinition parameter, Mono.Cecil.ParamTable table) [0x0005f] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddParameters (Mono.Cecil.MethodDefinition method) [0x00049] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddMethod (Mono.Cecil.MethodDefinition method) [0x0005a] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddMethods (Mono.Cecil.TypeDefinition type) [0x00013] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddType (Mono.Cecil.TypeDefinition type) [0x000a2] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.AddTypes () [0x00018] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.BuildTypes () [0x00014] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.BuildModule () [0x0009f] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.MetadataBuilder.BuildMetadata () [0x00000] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleWriter+<>c.<BuildMetadata>b__2_0 (Mono.Cecil.MetadataBuilder builder, Mono.Cecil.MetadataReader _) [0x00000] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Read[TItem,TRet] (TItem item, System.Func`3[T1,T2,TResult] read) [0x00029] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleWriter.BuildMetadata (Mono.Cecil.ModuleDefinition module, Mono.Cecil.MetadataBuilder metadata) [0x0000f] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleWriter.Write (Mono.Cecil.ModuleDefinition module, Mono.Disposable`1[T] stream, Mono.Cecil.WriterParameters parameters) [0x000fb] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleWriter.WriteModule (Mono.Cecil.ModuleDefinition module, Mono.Disposable`1[T] stream, Mono.Cecil.WriterParameters parameters) [0x00002] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Write (System.IO.Stream stream, Mono.Cecil.WriterParameters parameters) [0x00019] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Write (Mono.Cecil.WriterParameters parameters) [0x0000e] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at Mono.Cecil.ModuleDefinition.Write () [0x00006] in <c7395fd07a6943a1a56fcca966c533fc>:0 
  at BattleTechModLoader.BTMLInjector.Inject (System.String hookFilePath, System.String hookType, System.String hookMethod, System.String injectFilePath, System.String injectType, System.String injectMethod) [0x000ef] in <17ce556bf09d4b70adc18b505f1f1f72>:0 
  at BattleTechModLoader.BTMLInjector.Main () [0x00060] in <17ce556bf09d4b70adc18b505f1f1f72>:0

Move DOTTween in there and finally

BattleTechModLoader Injector
----------------------------
Assembly-CSharp.dll backed up to Assembly-CSharp.dll.orig
Injecting Assembly-CSharp.dll with BattleTechModLoader.BTModLoader.Init at BattleTech.GameInstance..ctor
Writing back to Assembly-CSharp.dll...
Injection complete!

Success!

If I move all the DLLs from Managed, we're back to the System.MissingMethodException exception at the start.

After a lot of trial and error, the culprit is the System.Core.dll library. It doesn't work if it's in the same directory as the script, it works if it's not there. But the injector needs UnityEngine.DLL and DOTTween.DLL to be present.

ffaristocrat commented 6 years ago

Oh, just to be clear, I also tested this with the actual release instead of the one I compiled and it's the same behavior. Fun fun fun.

ffaristocrat commented 6 years ago

Next roadblock - BTML looks for the Mods folder with a relative path of ..\..\..\Mods and writes its logs there. Unfortunately, backslash isn't used for directory names on OSX so it ends up creating a folder literally named ..\..\..\Mods and looks there for dlls and mods. That said, putting ModTek.dll in there worked just fine so it's really just a matter of using doing the path in an OS agnostic way.

I'm going to close this issue since BTML does work with OSX once you have it setup but I'm going to file separate issues for these two specific problems.