public RoleplayingDatabaseContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder <RoleplayingDatabaseContext>(); new SchemaAwareDbContextService(new ContentService(FileSystemFactory.CreateContentFileSystem())) .ConfigureSchemaAwareContext <RoleplayingDatabaseContext>(optionsBuilder); return(new RoleplayingDatabaseContext(optionsBuilder.Options)); }
/// <inheritdoc /> public CharactersDatabaseContext CreateDbContext(string[] args) { var optionsBuilder = new DbContextOptionsBuilder <CharactersDatabaseContext>(); new ContextConfigurationService(new ContentService(FileSystemFactory.CreateContentFileSystem())) .ConfigureSchemaAwareContext <CharactersDatabaseContext>(optionsBuilder); return(new CharactersDatabaseContext(optionsBuilder.Options)); }
/// <inheritdoc /> protected override void RegisterServices(IServiceCollection serviceCollection) { serviceCollection .AddDbContext <CoreDatabaseContext>(ConfigureOptions <CoreDatabaseContext>) .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddSingleton <DelayedActionService>() .AddScoped <ContentService>() .AddScoped <UserFeedbackService>() .AddScoped <PrivacyService>(); }
/// <inheritdoc /> protected override void RegisterServices(IServiceCollection serviceCollection) { serviceCollection.AddDbContext <CoreDatabaseContext>(ConfigureOptions <CoreDatabaseContext>); serviceCollection .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddSingleton <DelayedActionService>() .AddScoped <ContentService>() .AddScoped <UserFeedbackService>() .AddScoped <PrivacyService>() .AddLogging(c => c.AddProvider(NullLoggerProvider.Instance)); }
/// <inheritdoc /> protected override void RegisterServices(IServiceCollection serviceCollection) { serviceCollection .AddDbContext <CoreDatabaseContext>(ConfigureOptions <CoreDatabaseContext>) .AddDbContext <CharactersDatabaseContext>(ConfigureOptions <CharactersDatabaseContext>); serviceCollection .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddSingleton <PronounService>() .AddScoped <CommandService>() .AddScoped <ContentService>() .AddScoped <ServerService>() .AddScoped <UserService>() .AddScoped <OwnedEntityService>() .AddScoped <CharacterService>(); }
/// <inheritdoc /> protected override void RegisterServices(IServiceCollection serviceCollection) { serviceCollection .AddDbContext <CoreDatabaseContext>(ConfigureOptions <CoreDatabaseContext>) .AddDbContext <TransformationsDatabaseContext>(ConfigureOptions <TransformationsDatabaseContext>) .AddDbContext <CharactersDatabaseContext>(ConfigureOptions <CharactersDatabaseContext>); serviceCollection .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddSingleton <PronounService>() .AddSingleton <TransformationDescriptionBuilder>() .AddScoped <TransformationService>() .AddScoped <ContentService>() .AddScoped <UserService>() .AddScoped <ServerService>() .AddScoped <UserService>(); }
/// <inheritdoc /> protected override void RegisterServices(IServiceCollection serviceCollection) { serviceCollection .AddDbContext <CoreDatabaseContext>(o => ConfigureOptions(o, "Core")) .AddDbContext <CharactersDatabaseContext>(o => ConfigureOptions(o, "Characters")); serviceCollection .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddSingleton <PronounService>() .AddScoped <ContentService>() .AddScoped <ServerService>() .AddScoped <UserService>() .AddScoped <OwnedEntityService>() .AddScoped <CharacterService>() .AddScoped <ICharacterService>(s => s.GetRequiredService <CharacterService>()) .AddScoped <ICharacterEditor>(s => s.GetRequiredService <CharacterService>()) .AddLogging(c => c.AddProvider(NullLoggerProvider.Instance)); }
/// <inheritdoc /> protected override void RegisterServices(IServiceCollection serviceCollection) { serviceCollection.AddDbContext <CoreDatabaseContext>(o => ConfigureOptions(o, "Core")); var channelAPIMock = new Mock <IDiscordRestChannelAPI>(); var userAPIMock = new Mock <IDiscordRestUserAPI>(); var interactionAPIMock = new Mock <IDiscordRestInteractionAPI>(); serviceCollection .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddScoped <ContentService>() .AddScoped <FeedbackService>() .AddScoped <PrivacyService>() .AddScoped <ContextInjectionService>() .AddSingleton(FeedbackTheme.DiscordDark) .AddSingleton(channelAPIMock.Object) .AddSingleton(userAPIMock.Object) .AddSingleton(interactionAPIMock.Object) .AddLogging(c => c.AddProvider(NullLoggerProvider.Instance)); }
/// <inheritdoc /> protected override void RegisterServices(IServiceCollection serviceCollection) { serviceCollection .AddDbContext <CoreDatabaseContext>(ConfigureOptions <CoreDatabaseContext>) .AddDbContext <TransformationsDatabaseContext>(ConfigureOptions <TransformationsDatabaseContext>) .AddDbContext <CharactersDatabaseContext>(ConfigureOptions <CharactersDatabaseContext>); serviceCollection .AddSingleton(s => { var content = s.GetRequiredService <ContentService>(); return(content.GetTransformationMessages().Entity); }) .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddSingleton <PronounService>() .AddSingleton <TransformationDescriptionBuilder>() .AddScoped <TransformationService>() .AddScoped <ContentService>() .AddScoped <UserService>() .AddScoped <ServerService>() .AddScoped <UserService>(); }
/// <inheritdoc /> protected override void RegisterServices(IServiceCollection serviceCollection) { serviceCollection .AddDbContext <CoreDatabaseContext>(o => ConfigureOptions(o, "Core")) .AddDbContext <TransformationsDatabaseContext>(o => ConfigureOptions(o, "Transformations")) .AddDbContext <CharactersDatabaseContext>(o => ConfigureOptions(o, "Characters")); serviceCollection .AddSingleton(s => { var content = s.GetRequiredService <ContentService>(); return(content.GetTransformationMessages().Entity); }) .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddSingleton <PronounService>() .AddSingleton <TransformationDescriptionBuilder>() .AddScoped <TransformationService>() .AddScoped <ContentService>() .AddScoped <UserService>() .AddScoped <ServerService>() .AddScoped <UserService>() .AddLogging(c => c.AddProvider(NullLoggerProvider.Instance)); }
public ExecuteSnippetAsync() { _lua = new LuaService(new ContentService(FileSystemFactory.CreateContentFileSystem())); }
/// <summary> /// The main entry point of the program. /// </summary> /// <returns>A task.</returns> public static async Task Main() { var cancellationSource = new CancellationTokenSource(); Console.CancelKeyPress += (_, eventArgs) => { eventArgs.Cancel = true; cancellationSource.Cancel(); }; // Configure logging const string configurationName = "DIGOS.Ambassador.log4net.config"; var logConfig = new XmlDocument(); await using (var configStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(configurationName)) { if (configStream is null) { throw new InvalidOperationException("The log4net configuration stream could not be found."); } logConfig.Load(configStream); } var repo = LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(Hierarchy)); XmlConfigurator.Configure(repo, logConfig["log4net"]); var contentFileSystem = FileSystemFactory.CreateContentFileSystem(); var contentService = new ContentService(contentFileSystem); var getBotToken = await contentService.GetBotTokenAsync(); if (!getBotToken.IsSuccess) { throw new InvalidOperationException("No bot token available."); } var token = getBotToken.Entity.Trim(); var options = Options.Create(new PluginServiceOptions(Array.Empty <string>())); var pluginService = new PluginService(options); var plugins = pluginService.LoadPluginTree(); var hostBuilder = Host.CreateDefaultBuilder() .AddDiscordService(_ => token) .UseSystemd() .ConfigureServices(services => { services.Configure <DiscordGatewayClientOptions>(o => { o.Intents |= GatewayIntents.MessageContents; }); services.Configure <ServiceProviderOptions>(s => { s.ValidateScopes = true; s.ValidateOnBuild = true; }); services.Configure <CommandResponderOptions>(o => o.Prefix = "!"); services.AddSingleton <BehaviourService>(); services .AddSingleton(pluginService) .AddSingleton(contentService) .AddSingleton(contentFileSystem) .AddSingleton <Random>(); services .AddDiscordCommands(true) .AddDiscordCaching(); // Configure cache times services.Configure <CacheSettings>(settings => { settings.SetAbsoluteExpiration <IGuildMember>(TimeSpan.FromDays(1)); settings.SetAbsoluteExpiration <IMessage>(TimeSpan.FromDays(1)); }); // Set up the feedback theme var theme = (FeedbackTheme) FeedbackTheme.DiscordDark with { Secondary = Color.MediumPurple }; services.AddSingleton <IFeedbackTheme>(theme); // Add execution events services .AddPreExecutionEvent <ConsentCheckingPreExecutionEvent>() .AddPostExecutionEvent <MessageRelayingPostExecutionEvent>(); // Ensure we're automatically joining created threads services.AddResponder <ThreadJoinResponder>(); // Override the default responders services.Replace(ServiceDescriptor.Scoped <CommandResponder, AmbassadorCommandResponder>()); services.Replace(ServiceDescriptor.Scoped <InteractionResponder, AmbassadorInteractionResponder>()); services .AddParser <MessageReader>() .AddParser <HumanTimeSpanReader>(); var configurePlugins = plugins.ConfigureServices(services); if (!configurePlugins.IsSuccess) { throw new InvalidOperationException(); } }) .ConfigureLogging(l => { l.ClearProviders(); l.AddLog4Net() .AddFilter("Microsoft.EntityFrameworkCore.Infrastructure", LogLevel.Warning) .AddFilter("Microsoft.EntityFrameworkCore.Database.Command", LogLevel.Critical) .AddFilter("Microsoft.EntityFrameworkCore.Migrations", LogLevel.Warning) .AddFilter("Microsoft.EntityFrameworkCore.Update", LogLevel.Critical); }); var host = hostBuilder.Build(); var hostServices = host.Services; var log = hostServices.GetRequiredService <ILogger <Program> >(); log.LogInformation("Running on {Framework}", RuntimeInformation.FrameworkDescription); Snowflake?debugServer = null; var debugServerString = Environment.GetEnvironmentVariable("REMORA_DEBUG_SERVER"); if (debugServerString is not null) { if (!Snowflake.TryParse(debugServerString, out debugServer)) { log.LogWarning("Failed to parse debug server from environment"); } } var slashService = hostServices.GetRequiredService <SlashService>(); var checkSlashSupport = slashService.SupportsSlashCommands(); if (!checkSlashSupport.IsSuccess) { var error = checkSlashSupport.Error; if (error is UnsupportedFeatureError ufe) { var location = ufe.Node is not null ? GetCommandLocation(ufe.Node) : "unknown"; log.LogWarning ( "The registered commands of the bot don't support slash commands: {Reason} ({Location})", error.Message, location ); } else { log.LogError("Failed to check slash command compatibility: {Reason}", error.Message); return; } } else { var updateSlash = await slashService.UpdateSlashCommandsAsync(debugServer, ct : cancellationSource.Token); if (!updateSlash.IsSuccess) { log.LogWarning("Failed to update slash commands: {Reason}", updateSlash.Error.Message); } } log.LogInformation("Initializing plugins..."); var initializePlugins = await plugins.InitializeAsync(hostServices, cancellationSource.Token); if (!initializePlugins.IsSuccess) { log.LogError("Failed to initialize the plugin tree"); if (initializePlugins.Error is AggregateError a) { foreach (var error in a.Errors) { if (error.IsSuccess) { continue; } log.LogError("Initialization error: {Error}", error.Error !.Message); } } else { log.LogError("Initialization error: {Error}", initializePlugins.Error); } return; } log.LogInformation("Migrating plugins..."); var migratePlugins = await plugins.MigrateAsync(hostServices, cancellationSource.Token); if (!migratePlugins.IsSuccess) { log.LogError("Failed to initialize the plugin tree"); if (migratePlugins.Error is AggregateError a) { foreach (var error in a.Errors) { if (error.IsSuccess) { continue; } log.LogError("Migration error: {Error}", error.Error !.Message); } } else { log.LogError("Migration error: {Error}", migratePlugins.Error); } return; } var behaviourService = hostServices.GetRequiredService <BehaviourService>(); await behaviourService.StartBehavioursAsync(); await host.RunAsync(cancellationSource.Token); await behaviourService.StopBehavioursAsync(); }
/// <summary> /// Initializes the bot and its services. /// </summary> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task InitializeAsync() { var pluginService = new PluginService(); var serviceCollection = new ServiceCollection() .AddSingleton(this) .AddSingleton(_client) .AddSingleton <BaseSocketClient>(_client) .AddSingleton(_behaviours) .AddSingleton <ContentService>() .AddSingleton(_commands) .AddSingleton <DiscordService>() .AddSingleton <UserFeedbackService>() .AddSingleton <InteractivityService>() .AddSingleton <DelayedActionService>() .AddSingleton <HelpService>() .AddSingleton <Random>() .AddSingleton(pluginService) .AddSingleton <SchemaAwareDbContextService>() .AddSingleton(FileSystemFactory.CreateContentFileSystem()); var successfullyRegisteredPlugins = new List <IPluginDescriptor>(); var availablePlugins = pluginService.LoadAvailablePlugins(); foreach (var availablePlugin in availablePlugins) { if (!await availablePlugin.RegisterServicesAsync(serviceCollection)) { Log.Warn ( $"The plugin \"{availablePlugin.Name}\" (v{availablePlugin.Version}) failed to " + $"register its services. It will not be loaded." ); continue; } successfullyRegisteredPlugins.Add(availablePlugin); } _services = serviceCollection.BuildServiceProvider(); var contentService = _services.GetRequiredService <ContentService>(); await contentService.InitializeAsync(); // Create plugin databases foreach (var plugin in successfullyRegisteredPlugins) { if (!(plugin is IMigratablePlugin migratablePlugin)) { continue; } if (await migratablePlugin.IsDatabaseCreatedAsync(_services)) { continue; } if (!await migratablePlugin.MigratePluginAsync(_services)) { Log.Warn ( $"The plugin \"{plugin.Name}\"" + $" (v{plugin.Version}) failed to migrate its database. It may not " + $"be functional." ); } } // Then, run migrations in reverse foreach (var plugin in successfullyRegisteredPlugins.AsEnumerable().Reverse()) { if (!(plugin is IMigratablePlugin migratablePlugin)) { continue; } if (!await migratablePlugin.MigratePluginAsync(_services)) { Log.Warn ( $"The plugin \"{plugin.Name}\"" + $" (v{plugin.Version}) failed to migrate its database. It may not " + $"be functional." ); } } foreach (var plugin in successfullyRegisteredPlugins) { if (!await plugin.InitializeAsync(_services)) { Log.Warn ( $"The plugin \"{plugin.Name}\"" + $" (v{plugin.Version}) failed to initialize. It may not be functional." ); } } }
/// <summary> /// The main entry point of the program. /// </summary> /// <returns>A task.</returns> public static async Task Main() { // Configure logging const string configurationName = "DIGOS.Ambassador.log4net.config"; var logConfig = new XmlDocument(); await using (var configStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(configurationName)) { if (configStream is null) { throw new InvalidOperationException("The log4net configuration stream could not be found."); } logConfig.Load(configStream); } var repo = LogManager.CreateRepository(Assembly.GetEntryAssembly(), typeof(Hierarchy)); XmlConfigurator.Configure(repo, logConfig["log4net"]); var hostBuilder = Host.CreateDefaultBuilder() .UseSystemd() .ConfigureServices(services => { var pluginService = new PluginService(); services .AddHostedService <AmbassadorBotService>() .AddSingleton(pluginService) .AddSingleton ( provider => new DiscordSocketClient(new DiscordSocketConfig { MessageCacheSize = 100 }) ) .AddSingleton <IDiscordClient>(s => s.GetRequiredService <DiscordSocketClient>()) .AddSingleton <BaseSocketClient>(s => s.GetRequiredService <DiscordSocketClient>()) .AddSingleton <CommandService>() .AddSingleton <BehaviourService>() .AddSingleton <ContentService>() .AddSingleton <DiscordService>() .AddSingleton <UserFeedbackService>() .AddSingleton <InteractivityService>() .AddSingleton <DelayedActionService>() .AddSingleton <SchemaAwareDbContextService>() .AddSingleton <ContextConfigurationService>() .AddSingleton(FileSystemFactory.CreateContentFileSystem()) .AddSingleton <Random>(); var plugins = pluginService.LoadAvailablePlugins(); foreach (var plugin in plugins) { plugin.ConfigureServices(services); } }) .ConfigureLogging(l => { l.ClearProviders(); l.AddLog4Net() .AddFilter("Microsoft.EntityFrameworkCore.Infrastructure", LogLevel.Warning) .AddFilter("Microsoft.EntityFrameworkCore.Database.Command", LogLevel.Warning) .AddFilter("Microsoft.EntityFrameworkCore.Migrations", LogLevel.Warning); }); var host = hostBuilder.Build(); var logger = host.Services.GetRequiredService <ILogger <Program> >(); logger.LogInformation($"Running on {RuntimeInformation.FrameworkDescription}"); await host.RunAsync(); }