public void Run(string className) { CTFConsole.PushTitle(); if (!_challenges.ContainsKey(className)) { throw new Exception($"Challenge class \"{className}\" was not found."); } var type = _challenges[className]; var challenge = (IChallenge)_services.GetService(type); var name = type.GetCustomAttribute <ChallengeAttribute>()?.Name ?? className; _logger.LogTrace("Running challange {name}", name); try { CTFConsole.SetTitle($"{CTFConsole.Title} - Running {name}"); challenge.Run(); _logger.LogTrace("Finished challenge {name}", name); } catch (Exception ex) { _logger.LogError(ex.Message, ex); } finally { CTFConsole.PopTitle(); } }
public static void Run(string[] args, Action <IServiceCollection> services = null) { var entryPoint = Assembly.GetEntryAssembly().EntryPoint; var ctf = entryPoint.GetCustomAttribute <CTFAttribute>() ?? new CTFAttribute(); if (ctf.MaximizeConsole) { CTFConsole.Maximize(); } var executingAssembly = Assembly.GetExecutingAssembly(); var version = executingAssembly.GetCustomAttribute <AssemblyInformationalVersionAttribute>().InformationalVersion; var challengeLogging = entryPoint.GetCustomAttribute <ChallengeLoggingAttribute>() ?? new ChallengeLoggingAttribute(); var title = $"{executingAssembly.GetName().Name} {version}"; Console.Title = title; foreach (var assemblyFile in Directory.GetFiles(Directory.GetCurrentDirectory(), "*.Template?.*.dll")) { Assembly.LoadFrom(assemblyFile); } new Turn() .WithParser(new Parser((settings) => { settings.HelpWriter = null; })) .ParseVerbs(args, (result) => { Console.WriteLine(HelpText.AutoBuild(result, h => { h.Heading = title; h.AdditionalNewLineAfterOption = false; h.Copyright = string.Empty; h.AddDashesToOption = true; return(HelpText.DefaultParsingErrorsHandler(result, h)); }, e => e, true)); }) .WithConfiguration(() => { if (ctf.UseEmbeddedAppSettings == false && File.Exists("appsettings.json")) { return(new ConfigurationBuilder() .AddJsonFile("appsettings.json", true) .Build()); } else { using var stream = new EmbeddedFileProvider(Assembly.GetExecutingAssembly(), typeof(CTF).Namespace) .GetFileInfo("CTF.appsettings.json").CreateReadStream(); return(new ConfigurationBuilder() .AddJsonStream(stream) .Build()); } }) .WithLogging((logging, turn) => { var loggerConfiguration = new LoggerConfiguration() .ReadFrom.Configuration(turn.Directions.Configuration()); var name = turn.Directions.TryGet <ITurnArgs>().TryGetOptions <IChallengeOptions>(out var options) ? options.Class : "CTF"; loggerConfiguration.WriteTo.File( path: Path.Combine( challengeLogging.LogDirectory ?? string.Empty, Assembly.GetEntryAssembly().GetName().Name, name, Path.ChangeExtension($"{name}-{DateTime.Now:yyyyMMddHHmmss}", challengeLogging.LogFileExtension ?? "log"))); logging.AddSerilog( loggerConfiguration.CreateLogger(), dispose: true); }) .WithServices((services) => services.AddChallengeServices()) .WithServices(services) .WithDirections() .WithUnhandledExceptionLogging() .Take((provider) => { var logger = provider.GetRequiredService <ILogger <CTF> >(); var directions = provider.GetRequiredService <ITurnDirections>(); if (!string.IsNullOrEmpty(ctf?.Name)) { logger.LogTrace("Started {name}", ctf.Name); } logger.LogTrace("Using {title}", title); switch (directions.Get <ITurnArgs>().Options) { case IChallengeOptions options: provider.GetRequiredService <IChallengeRunnerService>().Run(options); break; case IChallengePlayOptions options: provider.GetRequiredService <IChallengeRunnerService>().Run(options); break; case IChallengeTemplateOptions options: provider.GetRequiredService <IChallengeTemplateService>().AddChallenges(options); break; default: throw new NotImplementedException(); } ; }); }