/// <summary> /// Don't forget to get a new ILogger after adding a new ILoggerProvider /// </summary> public static IServiceCollection AddSerilogLoggerProvider(this MBSubModuleBase subModule, string filename, IEnumerable <string>?filter = null, Action <LoggerConfiguration>?configure = null) { filter ??= new List <string> { $"{subModule.GetType().Assembly.GetName().Name}.*" }; var filterList = filter.ToList(); var services = subModule.GetServices(); if (services is null) { throw new Exception("Past Configuration stage."); } var builder = new LoggerConfiguration() .Enrich.FromLogContext() .Filter.ByIncludingOnly(FromSources(filterList)) .WriteTo.File( outputTemplate: OutputTemplate, path: Path.Combine(ModLogsPath, filename), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7); configure?.Invoke(builder); var logger = builder.CreateLogger(); services.AddSingleton <ILoggerProvider, SerilogLoggerProvider>(_ => new SerilogLoggerProvider(logger, true)); return(services); }
public static void OnSubModuleUnloadedPostfix(MBSubModuleBase __instance) { if (__instance is SubModuleV300) { OnSubModuleLoad(); } }
public static void OnSubModuleLoadPostfix(MBSubModuleBase __instance) { if (!(__instance is SandBoxSubModule)) { return; } SandBoxSubModuleOnSubModuleLoad(); _loaded = true; }
public MBSubModuleBaseWrapper(MBSubModuleBase subModule) { SubModule = subModule; OnSubModuleLoadInstance = AccessTools2.GetDelegate <OnSubModuleLoadDelegate, MBSubModuleBase>(subModule, "OnSubModuleLoad"); OnSubModuleUnloadedInstance = AccessTools2.GetDelegate <OnSubModuleUnloadedDelegate, MBSubModuleBase>(subModule, "OnSubModuleUnloaded"); OnBeforeInitialModuleScreenSetAsRootInstance = AccessTools2.GetDelegate <OnBeforeInitialModuleScreenSetAsRootDelegate, MBSubModuleBase>(subModule, "OnBeforeInitialModuleScreenSetAsRoot"); OnGameStartInstance = AccessTools2.GetDelegate <OnGameStartDelegate, MBSubModuleBase>(subModule, "OnGameStart"); OnApplicationTickInstance = AccessTools2.GetDelegate <OnApplicationTickDelegate, MBSubModuleBase>(subModule, "OnApplicationTick"); OnServiceRegistrationInstance = AccessTools2.GetDelegate <OnServiceRegistrationDelegate, MBSubModuleBase>(subModule, "OnServiceRegistration"); }
internal static IServiceCollection?AddDefaultSerilogLogger(this MBSubModuleBase subModule) { var services = subModule.GetServices(); var serviceProvider = services.BuildServiceProvider(); var butterLibOptions = serviceProvider.GetService <IOptions <ButterLibOptions> >(); var logger = new LoggerConfiguration() .MinimumLevel.Is((LogEventLevel)butterLibOptions.Value.MinLogLevel) .Enrich.FromLogContext() .WriteTo.File( outputTemplate: OutputTemplate, path: Path.Combine(ModLogsPath, "default.log"), rollingInterval: RollingInterval.Day, retainedFileCountLimit: 7) .CreateLogger(); services.AddLogging(loggingBuilder => loggingBuilder.AddSerilog(logger, dispose: true)); return(services); }
static CommunityPatchSubModule() { // catch and record exceptions AppDomain.CurrentDomain.FirstChanceException += (sender, args) => { if (RecordFirstChanceExceptions) { RecordedFirstChanceExceptions.AddLast(args.Exception); } }; AppDomain.CurrentDomain.UnhandledException += (sender, args) => { RecordedUnhandledExceptions.AddLast((Exception)args.ExceptionObject); CopyDiagnosticsToClipboard(); }; // TODO: /* * AppDomain.CurrentDomain.TypeResolve += (sender, args) => { * return null; * }; */ // help delay loaded libs refer to mods they depend on AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { MBSubModuleBase reqSm = null; foreach (var sm in Module.CurrentModule.SubModules) { var smAsm = sm.GetType().Assembly; if (smAsm == args.RequestingAssembly) { reqSm = sm; } } if (reqSm == null) { return(null); } var resolvable = new LinkedList <(ModuleInfo Mod, SubModuleInfo SubMod)>(); ModuleInfo reqMi = null; SubModuleInfo reqSmi = null; var modules = ModuleInfo.GetModules(); foreach (var mi in modules) { foreach (var smi in mi.SubModules) { if (smi.Assemblies.Contains(args.Name)) { resolvable.AddLast((mi, smi)); } if (smi.SubModuleClassType != reqSm.GetType().FullName) { continue; } reqMi = mi; reqSmi = smi; } } if (reqSmi == null) { return(null); } foreach (var modId in reqMi.DependedModuleIds) { foreach (var resolution in resolvable) { if (modId != resolution.Mod.Id) { continue; } var modDir = Path.GetDirectoryName(ModuleInfo.GetPath(modId)); if (modDir == null) { continue; } var modPath = Path.Combine(modDir, "bin", Common.ConfigName, args.Name + ".dll"); if (File.Exists(modPath)) { return(Assembly.LoadFile(modPath)); } } } return(null); }; }
static public ModSettingsViewModel ConfigureSettings(this MBSubModuleBase module, string modName) { return(ConfigureSettings(module, modName, new ModSettingsViewModel())); }
static public ModSettingsViewModel ConfigureSettings <T>(this MBSubModuleBase module, string modName, T viewModel) where T : ModSettingsViewModel { return(viewModel as ModSettingsViewModel); }
/// <summary> /// Don't forget to get a new ILogger after adding a new ILoggerProvider /// </summary> public static IServiceCollection AddSerilogLoggerProvider(this MBSubModuleBase subModule, string filename, IEnumerable <Assembly> filter) => subModule.AddSerilogLoggerProvider(filename, filter.Select(x => x.GetName().Name ?? string.Empty));
/// <summary> /// For Stage 2. /// </summary> public static IServiceProvider?GetTempServiceProvider(this MBSubModuleBase _) => ButterLibSubModule.Services?.BuildServiceProvider();
/// <summary> /// For Stage 2. /// </summary> public static IServiceCollection?GetServices(this MBSubModuleBase _) => ButterLibSubModule.Services;
/// <summary> /// For Stage 3. /// </summary> public static IServiceProvider?GetServiceProvider(this MBSubModuleBase _) => ButterLibSubModule.ServiceProvider;
private static Assembly OnResolve(object sender, ResolveEventArgs args) { try { var name = new AssemblyName(args.Name); // handle ambiguous resolve requests by checking all mod bin dirs // TODO: recursive scan module dirs if (args.RequestingAssembly == null) { foreach (var modInfo in ModuleInfo.GetModules()) { if (!modInfo.IsSelected) { continue; } var modDir = Path.GetDirectoryName(ModuleInfo.GetPath(modInfo.Id)); if (modDir == null) { continue; } var modPath = Path.Combine(modDir, "bin", Common.ConfigName, name.Name + ".dll"); if (!File.Exists(modPath)) { continue; } var absPath = new Uri(Path.Combine(Environment.CurrentDirectory, modPath)).LocalPath; if (SecurityHelpers.UnblockFile(absPath)) { Console.WriteLine("Unblocked: " + absPath); } Console.WriteLine("Resolved: " + absPath); return(Assembly.LoadFrom(absPath)); } return(null); } MBSubModuleBase reqSm = null; foreach (var sm in Module.CurrentModule.SubModules) { var smAsm = sm.GetType().Assembly; if (smAsm == args.RequestingAssembly) { reqSm = sm; } } if (reqSm == null) { return(null); } var resolvable = new LinkedList <(ModuleInfo Mod, SubModuleInfo SubMod)>(); ModuleInfo reqMi = null; SubModuleInfo reqSmi = null; var modules = ModuleInfo.GetModules(); foreach (var mi in modules) { if (!mi.IsSelected) { continue; } foreach (var smi in mi.SubModules) { if (smi.Assemblies.Contains(args.Name)) { resolvable.AddLast((mi, smi)); } if (smi.SubModuleClassType != reqSm.GetType().FullName) { continue; } reqMi = mi; reqSmi = smi; } } if (reqSmi == null) { return(null); } foreach (var modId in reqMi.DependedModuleIds) { foreach (var resolution in resolvable) { if (modId != resolution.Mod.Id) { continue; } var modDir = Path.GetDirectoryName(ModuleInfo.GetPath(modId)); if (modDir == null) { continue; } var modPath = Path.Combine(modDir, "bin", Common.ConfigName, name.Name + ".dll"); if (!File.Exists(modPath)) { continue; } var absPath = new Uri(Path.Combine(Environment.CurrentDirectory, modPath)).LocalPath; if (SecurityHelpers.UnblockFile(absPath)) { Console.WriteLine("Unblocked: " + absPath); } Console.WriteLine("Resolved: " + absPath); return(Assembly.LoadFrom(absPath)); } } } catch { // TODO: log? } return(null); }