88using System . Text ;
99using BattleTech ;
1010using HBS . Logging ;
11+ using Mono . CSharp ;
1112
1213namespace DynModLib
1314{
1415 public static class Main
1516 {
1617 internal static Mod lib ;
18+ internal static Assembly compilerAssembly ;
1719
1820 public static void Start ( string modDirectory , string json )
1921 {
@@ -23,17 +25,16 @@ public static void Start(string modDirectory, string json)
2325 lib . SetupLogging ( ) ;
2426 try
2527 {
26- var compilerAssembly = Assembly . LoadFrom ( Path . Combine ( lib . Directory , "Mono.CSharp.dll" ) ) ;
28+ compilerAssembly = Assembly . LoadFrom ( Path . Combine ( lib . Directory , "Mono.CSharp.dll" ) ) ;
2729
28- {
29- // fix for misbehaving of AssemblyDefinition CheckReferencesPublicToken
30- var harmony = HarmonyInstance . Create ( "DynModLib.CSharp" ) ;
31- var mOriginal = compilerAssembly . GetType ( "Mono.CSharp.AssemblyDefinition" ) . GetMethod ( "CheckReferencesPublicToken" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
32- var mPrefix = typeof ( Main ) . GetMethod ( nameof ( Prefix ) , BindingFlags . Static | BindingFlags . Public ) ;
33- harmony . Patch ( mOriginal , new HarmonyMethod ( mPrefix ) ) ;
34- }
30+ HarmonyInstance . Create ( "DynModLib.CSharp" ) . PatchAll ( ) ;
3531
3632 var references = CollectReferences ( ) ;
33+ lib . Logger . LogDebug ( $ "Found references:") ;
34+ foreach ( var reference in references )
35+ {
36+ lib . Logger . LogDebug ( $ "\t { reference } ") ;
37+ }
3738 var compiler = new ModCompiler ( compilerAssembly , references ) ;
3839
3940 foreach ( var d in Directory . GetDirectories ( lib . ModsPath )
@@ -54,16 +55,12 @@ public static void Start(string modDirectory, string json)
5455 }
5556 }
5657
57- public static bool Prefix ( )
58- {
59- return false ;
60- }
61-
6258 private static List < string > CollectReferences ( )
6359 {
6460 var references = GetManagedAssemblyPaths ( ) ;
6561 references . Add ( Assembly . GetExecutingAssembly ( ) . Location ) ;
66- references . Add ( GetAssemblyByName ( "0Harmony" ) . Location ) ;
62+ references . RemoveAll ( x=> x . Contains ( "System.Runtime." ) ) ;
63+ references . RemoveAll ( x=> x . Contains ( "System.ValueTuple." ) ) ;
6764 return references ;
6865 }
6966
@@ -85,15 +82,51 @@ public static void Reset()
8582 }
8683 }
8784
85+ [ HarmonyPatch ( typeof ( MetadataImporter ) , nameof ( MetadataImporter . GetAssemblyDefinition ) ) ]
86+ internal static class MetadataImporter_GetAssemblyDefinition_Patch
87+ {
88+ private static Assembly lastLoadingAssembly ;
89+ public static void Prefix ( Assembly assembly )
90+ {
91+ lastLoadingAssembly = assembly ;
92+ }
93+
94+ public static void Postfix ( )
95+ {
96+ lastLoadingAssembly = null ;
97+ }
98+
99+ internal static void LogIfError ( )
100+ {
101+ if ( lastLoadingAssembly != null )
102+ {
103+ Main . lib . Logger . LogError ( $ "Couldn't load { lastLoadingAssembly } from { lastLoadingAssembly . Location } !") ;
104+ }
105+ }
106+ }
107+
108+ [ HarmonyPatch ]
109+ internal static class AssemblyDefinition_CheckReferencesPublicToken_Patch
110+ {
111+ public static MethodInfo TargetMethod ( )
112+ {
113+ return Main . compilerAssembly . GetType ( "Mono.CSharp.AssemblyDefinition" )
114+ . GetMethod ( "CheckReferencesPublicToken" , BindingFlags . Instance | BindingFlags . NonPublic ) ;
115+ }
116+
117+ public static bool Prefix ( )
118+ {
119+ return false ;
120+ }
121+ }
122+
88123 internal class ModCompiler
89124 {
90- private readonly Assembly compilerAssembly ;
91125 private readonly List < string > references ;
92126 private readonly DateTime lastestAssemblyWriteTime ;
93127
94128 internal ModCompiler ( Assembly compilerAssembly , List < string > references )
95129 {
96- this . compilerAssembly = compilerAssembly ;
97130 this . references = references ;
98131
99132 var latestWriteTime = DateTime . MinValue ;
@@ -131,7 +164,7 @@ internal void CheckAndCompile(string modDirectory)
131164 }
132165
133166 Compile ( ) ;
134-
167+
135168 sw . Stop ( ) ;
136169 Main . lib . Logger . Log ( $ "{ mod . Name } : prepared assembly in { sw . Elapsed . TotalMilliseconds } ms") ;
137170 }
@@ -162,19 +195,25 @@ private void CompileAssembly(string outPath, List<string> refPaths, List<string>
162195
163196 try
164197 {
165- var arguments = new List < string > ( ) ;
166- arguments . Add ( "/target:library" ) ;
167- arguments . Add ( "/nostdlib+" ) ;
168- arguments . Add ( "/noconfig" ) ;
169- arguments . Add ( "/debug-" ) ;
170- arguments . Add ( "/optimize+" ) ;
171- arguments . Add ( "/out:" + outPath ) ;
198+ var arguments = new List < string >
199+ {
200+ "/target:library" ,
201+ "/nostdlib+" ,
202+ "/noconfig" ,
203+ "/debug-" ,
204+ "/optimize+" ,
205+ // "/platform:anycpu",
206+ "/langversion:latest" ,
207+ // "/unsafe+",
208+ // "/checked-",
209+ "/out:" + outPath
210+ } ;
172211 refPaths . ForEach ( r => arguments . Add ( "/r:" + r ) ) ;
173212 srcPaths . ForEach ( s => arguments . Add ( s ) ) ;
174213
175214 var memory = new MemoryStream ( ) ;
176215 var writer = new StreamWriter ( memory , Encoding . UTF8 ) ;
177- var type = compilerAssembly . GetType ( "Mono.CSharp.CompilerCallableEntryPoint" ) ;
216+ var type = Main . compilerAssembly . GetType ( "Mono.CSharp.CompilerCallableEntryPoint" ) ;
178217 var method = type . GetMethod ( "InvokeCompiler" ) ;
179218 // CompilerCallableEntryPoint.InvokeCompiler(arguments.ToArray(), writer)
180219 var result = ( bool ) method . Invoke ( method , new object [ ] { arguments . ToArray ( ) , writer } ) ;
@@ -193,6 +232,7 @@ private void CompileAssembly(string outPath, List<string> refPaths, List<string>
193232 }
194233 catch ( Exception e )
195234 {
235+ MetadataImporter_GetAssemblyDefinition_Patch . LogIfError ( ) ;
196236 throw new Exception ( "DynModLib: Could not call Mono.CSharp compiler" , e ) ;
197237 }
198238 }
@@ -249,7 +289,7 @@ public void LoadSettings<T>(T settings) where T : ModSettings
249289 {
250290 return ;
251291 }
252-
292+
253293 using ( var reader = new StreamReader ( SettingsPath ) )
254294 {
255295 var json = reader . ReadToEnd ( ) ;
@@ -273,7 +313,7 @@ public void SaveSettings<T>(T settings) where T : ModSettings
273313 writer . Write ( json ) ;
274314 }
275315 }
276-
316+
277317 internal bool DependsOnDynModLib => ModTekInfo . DependsOn . Contains ( Main . lib . Name ) ;
278318 internal string AssemblyPath => string . IsNullOrEmpty ( ModTekInfo . DLL ) ? null : Path . Combine ( Directory , ModTekInfo . DLL ) ;
279319
0 commit comments