/// <summary> /// Instantiate a new <see cref="WebhookController"/> class. /// </summary> /// <param name="config"><see cref="WhConfig"/> configuration class.</param> public WebhookController(WhConfigHolder config) { _logger.Trace($"WebhookManager::WebhookManager [Config={config}, Port={config.Instance.WebhookPort}, Servers={config.Instance.Servers.Count:N0}]"); _gyms = new Dictionary <string, GymDetailsData>(); _weather = new Dictionary <long, GameplayWeather.Types.WeatherCondition>(); _alarms = new Dictionary <ulong, AlarmList>(); _config = config; _config.Reloaded += OnConfigReloaded; LoadGeofences(); LoadAlarms(); _http = new HttpServer(_config.Instance.ListeningHost, _config.Instance.WebhookPort, _config.Instance.DespawnTimeMinimumMinutes); _http.PokemonReceived += Http_PokemonReceived; _http.RaidReceived += Http_RaidReceived; _http.QuestReceived += Http_QuestReceived; _http.PokestopReceived += Http_PokestopReceived; _http.GymReceived += Http_GymReceived; _http.GymDetailsReceived += Http_GymDetailsReceived; _http.WeatherReceived += Http_WeatherReceived; _http.IsDebug = _config.Instance.Debug; new Thread(() => { LoadAlarmsOnChange(); LoadGeofencesOnChange(); }).Start(); }
public SubscriptionManager(WhConfigHolder whConfig) { _logger.Trace($"SubscriptionManager::SubscriptionManager"); _whConfig = whConfig; if (_whConfig.Instance?.Database?.Main == null) { var err = "Main database is not configured in config.json file."; _logger.Error(err); throw new NullReferenceException(err); } if (_whConfig.Instance?.Database?.Scanner == null) { var err = "Scanner database is not configured in config.json file."; _logger.Error(err); throw new NullReferenceException(err); } if (_whConfig.Instance?.Database?.Nests == null) { _logger.Warn("Nest database is not configured in config.json file, nest alarms and commands will not work."); } _connFactory = new OrmLiteConnectionFactory(_whConfig.Instance.Database.Main.ToString(), MySqlDialect.Provider); // Reload subscriptions every minute x 60 seconds to account for UI changes _reloadTimer = new Timer(_whConfig.Instance.ReloadSubscriptionChangesMinutes * 60 * 1000); _reloadTimer.Elapsed += (sender, e) => ReloadSubscriptions(); _reloadTimer.Start(); ReloadSubscriptions(); }
public Dependencies(InteractivityModule interactivity, WebhookController whm, SubscriptionProcessor subProcessor, WhConfigHolder whConfig, StripeService stripe) { Interactivity = interactivity; Whm = whm; SubscriptionProcessor = subProcessor; _configHolder = whConfig; Stripe = stripe; OsmManager = new OsmManager(); }
/// <summary> /// Instantiate a new <see cref="SubscriptionProcessor"/> class. /// </summary> /// <param name="servers">Discord servers dictionary</param> /// <param name="config">Configuration file</param> /// <param name="whm">Webhook controller class</param> public SubscriptionProcessor(Dictionary <ulong, DiscordClient> servers, WhConfigHolder config, WebhookController whm) { _logger.Trace($"SubscriptionProcessor::SubscriptionProcessor"); _servers = servers; _whConfig = config; _whm = whm; _queue = new NotificationQueue(); Manager = new SubscriptionManager(_whConfig); ProcessQueue(); }
/// <summary> /// Discord bot class /// </summary> /// <param name="whConfig">Configuration settings</param> public Bot(WhConfigHolder whConfig) { _logger.Trace($"WhConfig [Servers={whConfig.Instance.Servers.Count}, Port={whConfig.Instance.WebhookPort}]"); _servers = new Dictionary <ulong, DiscordClient>(); _whConfig = whConfig; _whm = new WebhookController(_whConfig); // Build form lists for icons IconFetcher.Instance.SetIconStyles(_whConfig.Instance.IconStyles); // Set translation language Translator.Instance.SetLocale(_whConfig.Instance.Locale); // Set database connection strings to static properties so we can access within our extension classes DataAccessLayer.ConnectionString = _whConfig.Instance.Database.Main.ToString(); DataAccessLayer.ScannerConnectionString = _whConfig.Instance.Database.Scanner.ToString(); // Set unhandled exception event handler AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionHandler; // Initialize and start midnight reset timer var midnight = new DandTSoftware.Timers.MidnightTimer(); midnight.TimeReached += async(e) => await OnMidnightTimer(); midnight.Start(); // Initialize the subscription processor if at least one Discord server wants custom notifications // and start database migrator if (_whConfig.Instance.Servers.Values.ToList().Exists(x => x.Subscriptions.Enabled)) { // Start database migrator var migrator = new DatabaseMigrator(); while (!migrator.Finished) { Thread.Sleep(50); } _subProcessor = new SubscriptionProcessor(_servers, _whConfig, _whm); } // Create a DiscordClient object per Discord server in config foreach (var(guildId, serverConfig) in _whConfig.Instance.Servers) { serverConfig.LoadDmAlerts(); var client = new DiscordClient(new DiscordConfiguration { AutomaticGuildSync = true, AutoReconnect = true, EnableCompression = true, Token = serverConfig.Token, TokenType = TokenType.Bot, UseInternalLogHandler = true }); // If you are on Windows 7 and using .NETFX, install // DSharpPlus.WebSocket.WebSocket4Net from NuGet, // add appropriate usings, and uncomment the following // line //client.SetWebSocketClient<WebSocket4NetClient>(); // If you are on Windows 7 and using .NET Core, install // DSharpPlus.WebSocket.WebSocket4NetCore from NuGet, // add appropriate usings, and uncomment the following // line //client.SetWebSocketClient<WebSocket4NetCoreClient>(); // If you are using Mono, install // DSharpPlus.WebSocket.WebSocketSharp from NuGet, // add appropriate usings, and uncomment the following // line //client.SetWebSocketClient<WebSocketSharpClient>(); client.Ready += Client_Ready; client.GuildAvailable += Client_GuildAvailable; client.GuildMemberUpdated += Client_GuildMemberUpdated; //_client.MessageCreated += Client_MessageCreated; client.ClientErrored += Client_ClientErrored; client.DebugLogger.LogMessageReceived += DebugLogger_LogMessageReceived; // Configure Discord interactivity module var interactivity = client.UseInteractivity ( new InteractivityConfiguration { // default pagination behaviour to just ignore the reactions PaginationBehaviour = TimeoutBehaviour.Ignore, // default pagination timeout to 5 minutes PaginationTimeout = TimeSpan.FromMinutes(5), // default timeout for other actions to 2 minutes Timeout = TimeSpan.FromMinutes(2) } ); // Build the dependency collection which will contain our objects that can be globally used within each command module DependencyCollection dep; using (var d = new DependencyCollectionBuilder()) { d.AddInstance(new Dependencies(interactivity, _whm, _subProcessor, _whConfig, new StripeService(_whConfig.Instance.StripeApiKey))); dep = d.Build(); } // Discord commands configuration var commands = client.UseCommandsNext ( new CommandsNextConfiguration { StringPrefix = serverConfig.CommandPrefix?.ToString(), EnableDms = true, // If command prefix is null, allow for mention prefix EnableMentionPrefix = string.IsNullOrEmpty(serverConfig.CommandPrefix), // Use DSharpPlus's built-in help formatter EnableDefaultHelp = true, CaseSensitive = false, IgnoreExtraArguments = true, Dependencies = dep } ); commands.CommandExecuted += Commands_CommandExecuted; commands.CommandErrored += Commands_CommandErrored; // Register Discord command handler classes commands.RegisterCommands <Owner>(); commands.RegisterCommands <Event>(); commands.RegisterCommands <Nests>(); commands.RegisterCommands <ShinyStats>(); commands.RegisterCommands <Gyms>(); commands.RegisterCommands <Quests>(); commands.RegisterCommands <Settings>(); if (serverConfig.Subscriptions.Enabled) { commands.RegisterCommands <Notifications>(); } if (serverConfig.EnableCities) { commands.RegisterCommands <Feeds>(); } _logger.Info($"Configured Discord server {guildId}"); if (!_servers.ContainsKey(guildId)) { _servers.Add(guildId, client); } // Wait 3 seconds between initializing Discord clients Task.Delay(3000).GetAwaiter().GetResult(); } RegisterConfigMonitor(); }